3 votos

Calculadora AppleScript: Toma la ecuación del texto seleccionado y calcula el resultado

Quiero crear un Servicio que sea capaz de tomar el texto seleccionado, realizar automáticamente la operación matemática deseada, y luego pegar el resultado directamente después del texto seleccionado. Este Servicio es similar a la función de calculadora incorporada en la Búsqueda de Google, pero es más práctico.

He aquí algunos ejemplos:

si se trata de un texto seleccionado : entonces este es el nuevo texto

43+957 : = 1000

763-9482 : = -8719

8*26 : = 208

83/23 : = 3.60869565217

Las operaciones anteriores incluyen la suma, la resta, la multiplicación y la división. Hasta aquí, este script no es difícil de escribir.

Pero también me gustaría poder utilizar paréntesis en los cálculos. Aquí es donde el camino se vuelve rocoso.

Estos son algunos ejemplos de ecuaciones que incluyen paréntesis:

(4+55)/2 : = 29.5

352+((76.031*57/100)+(93.6*87/100)) : = 476.76967

(45+36+(64*0.04)+152+33+90)*(1/(1.98-425-(0.25*629)+431)) : = -2.40209017217

Vaya.

Bien. Pasos de bebé...

Aquí está el código que he escrito. Sólo puede manejar el primer conjunto de ejemplos:

set inputString to "43 + 555 /4 *122"

-- Remove any and all spaces from this string
set inputString to replace_chars(inputString, " ", "")

-- Convert every instance of "x" to "*"
if (inputString contains "x") then
    set inputString to replace_chars(inputString, "x", "*")
end if

-- Ensure that the string contains no foreign characters:
set supportedCharacters to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "-", "*", "/"}

set x to 1
set everyCharacterInInputStringIsValid to true

repeat until (x > (length of inputString))
    if supportedCharacters contains (character x of inputString) then
        set x to (x + 1)
    else
        set everyCharacterInInputStringIsValid to false
        display dialog "Input string contains invalid character: " & (character x of inputString)
        error number -128 (* user cancelled *)
    end if
end repeat

-- String is all good. Now for the "fun" part.

set AppleScript's text item delimiters to {"+", "-", "*", "/"}
set onlyTheNumbers to text items of inputString
set AppleScript's text item delimiters to {""}
-- return onlyTheNumbers -- {"43", "555", "4", "122"}

set AppleScript's text item delimiters to onlyTheNumbers
set onlyTheSymbols to text items of inputString
set AppleScript's text item delimiters to {""}
-- return onlyTheSymbols -- {"", "+", "/", "*", ""}

-- Remove the first and last items in the onlyTheSymbols list
-- post #3 from http://macscripter.net/viewtopic.php?id=43371/
set removeSpecificItemsFromList to {1, (count of onlyTheSymbols)}
repeat with i in removeSpecificItemsFromList
    set item i of onlyTheSymbols to null
end repeat
set onlyTheSymbols to every text of onlyTheSymbols

set calculatorBalance to ((0) as number)
set x to 1 as integer
set y to 2 as integer
set z to 1 as integer
set num1 to (((item x) of onlyTheNumbers) as number)
repeat until ((z) is greater than (count of onlyTheSymbols))

    set num2 to (((item (y)) of onlyTheNumbers) as number)
    set symbol to ((item z) of onlyTheSymbols)
    if (symbol is "+") then
        set calculatorBalance to (num1 + num2)
    else if (symbol is "-") then
        set calculatorBalance to (num1 - num2)
    else if (symbol is "*") then
        set calculatorBalance to (num1 * num2)
    else if (symbol is "/") then
        set calculatorBalance to (num1 / num2)
    end if

    set num1 to (calculatorBalance as number)

    set y to (y + 1)
    set z to (z + 1)
end repeat

display dialog " = " & calculatorBalance

on replace_chars(this_text, search_string, replacement_string)
    set AppleScript's text item delimiters to the search_string
    set the item_list to every text item of this_text
    set AppleScript's text item delimiters to the replacement_string
    set this_text to the item_list as string
    set AppleScript's text item delimiters to ""
    return this_text
end replace_chars

Estoy confundido en cuanto a cómo enfocar todo el concepto de paréntesis en este script. ¿Puede alguien echarme una mano?

Esta es mi idea aproximada:

  1. Determina cuántos paréntesis hay en la cadena.

  2. Divide la cadena de entrada en segmentos. El número de segmentos se basa en el número total de paréntesis de la cadena, menos uno. El número de segmentos debe ser un número impar.

  3. Compruebe si alguno de los segmentos contiene paréntesis incrustados.

  4. Repita los pasos 1 a 4 hasta que no haya paréntesis en ningún segmento.

  5. Ahora que tienes tus segmentos, actúa como si cada segmento fuera su propia cadena. Es decir, calcula el resultado de cada segmento de forma independiente, en lugar de utilizar simplemente el número anterior de la lista para interactuar con el siguiente número de la lista.

  6. Suma todos los resultados de los segmentos.

No estoy seguro de tener la idea correcta.

Soy consciente de que he ignorado por completo el concepto de orden de las operaciones . Tampoco sé cómo implementar esto exactamente. Mi defensa es que esto es básicamente una parte del código de paréntesis. Por ejemplo, 1+4*2 tendría que convertirse primero en 1+(4*2) antes de poder calcular el resultado.


Nota:

He dicho que quiero que la entrada para el AppleScript sea el texto actualmente seleccionado. Pero, usted verá claramente que no he escrito el código de esta manera.

Para los propósitos de escribir, depurar y solucionar problemas de este script, estoy ignorando ese elemento del script, porque esta es una parte muy fácil de escribir y hace que probar el código sea más complicado.

Una vez perfeccionado el script, simplemente configuraré el Servicio para recibir selected text in any application . Para la salida, le diré al script que teclee el código y luego pegar el resultado final.


Por cierto, si estas elaboradas preguntas de AppleScript se están volviendo un poco exageradas para Pregunta diferente Entonces, por favor, hágamelo saber y los llevaré a un sitio más centrado en AppleScript (por ejemplo, MacScripter.net). No sé si estoy llegando a mi límite aquí.

0 votos

El tema clave aquí es encontrar una manera de analizar las fórmulas de manera correcta y eficiente. AppleScript es sólo una herramienta para conseguirlo (probablemente no la mejor pero tiene todo lo necesario).

0 votos

¿Es un ejercicio académico para aprender más sobre AppleScript o necesitas crear este servicio para un uso práctico?

0 votos

@GrahamMiln No es un ejercicio académico en absoluto. Quiero usar realmente este AppleScript como mi calculadora de cabecera.

5voto

Steve Evans Puntos 155

En StackOverflow encontrarás estas preguntas relacionadas:

Para una discusión sobre el análisis sintáctico de las expresiones, véase:

La carga de AppleScript

AppleScript no es un lenguaje en el que se pueda disfrutar escribiendo un parser. El lenguaje es genial para muchas cosas, pero no para la manipulación de texto. El lenguaje es Turing Completo Así que su proyecto es posible, pero difícil.

AppleScript es un dialecto de la Open Scripting Architecture (OSA) y tal vez usted estaría dispuesto a considerar otro dialecto OSA para este proyecto, como JavaScript. Aunque JavaScript no es lo ideal, encontrarás más recursos y guías para ayudarte. También puedes mezclar y combinar script Editor compilado AppleScript y JavaScript script.

Utilice bc

Considere la posibilidad de pasar el texto seleccionado a bc y devolver el resultado:

set theInput to "(4.0+55.0)/2.0"
set myCalculation to "echo 'scale=1;" & (theInput) & "' | bc"
set myResult to do shell script myCalculation

Este enfoque evita reinventar la rueda y utiliza la calculadora de línea de comandos incorporada incluida en MacOS, bc .

2 votos

Vaya, qué práctico. Te agradezco que me hayas presentado a bc , ya que al usarlo drásticamente simplifica mi código. Usted advirtió que podría no atraer buenas respuestas... ¡Yo consideraría esto una muy buena respuesta!

0voto

Javaxpert Puntos 1107

Creación de un servicio en todo el sistema para sustituir una ecuación seleccionada por su resultado

[actualización 18.10.2019]

Me ha resultado útil mantener la ecuación y sumar el resultado en lugar de sustituir la ecuación por el resultado.

Aquí está el script que uso (el resto de la respuesta no se modifica):

on run {input, parameters}

    set myCalculation to "echo 'scale=1;" & (input) & "' | bc"
    set myResult to do shell script myCalculation
    set myResult to input & "=" & myResult

    set d to AppleScript's text item delimiters --get original delimiters
    set AppleScript's text item delimiters to {return & linefeed, return, linefeed}
    set fullResult to myResult's text items
    set AppleScript's text item delimiters to ""
    set fullResult to fullResult as text
    set AppleScript's text item delimiters to d --replace original delimite

    return fullResult
end run

Gracias a Nigel Garvey para la técnica de eliminación de los retornos de carro.

[respuesta original]

Basado en la respuesta de Graham Miln

Utilizando Automatizador crear un nuevo flujo de trabajo (que antes se llamaba Servicio).

Arrastre Ejecutar AppleScript del panel izquierdo al panel derecho y pegar el siguiente programa (sustituyendo lo que ya hay):

on run {input, parameters}
    set myCalculation to "echo 'scale=1;" & (input) & "' | bc"
    set myResult to do shell script myCalculation
    return myResult
end run

enter image description here

Verifique que los parámetros en la parte superior del panel derecho dicen:

Worflow receives current text in any application
Output replaces selected text

Salvar el flujo de trabajo. Ahora habrá un servicio en el menú de aplicaciones de cada app para evaluar el texto seleccionado y sustituirlo por el resultado.

PARA AÑADIR UN ATAJO DE TECLADO

En Preferencias del Sistema ' Teclado ' Accesos directos ' Servicios verifique que Calcular la selección está en la lista de Texto .

Hay que comprobarlo, pero no tienen un atajo:

enter image description here

Haga clic en Atajos de la aplicación en el panel izquierdo, y añade un nuevo acceso directo a Todas las aplicaciones para Calcular la selección :

enter image description here

Salir de Preferencias del Sistema.

Ahora debería tener un atajo de teclado en todo el sistema para reemplazar una ecuación seleccionada con su resultado.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X