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:
-
Determina cuántos paréntesis hay en la cadena.
-
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.
-
Compruebe si alguno de los segmentos contiene paréntesis incrustados.
-
Repita los pasos 1 a 4 hasta que no haya paréntesis en ningún segmento.
-
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.
-
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.
0 votos
Por favor, puede acotar su pregunta. Un parser completo en una pregunta es poco probable que atraiga buenas respuestas. En su lugar, pregunte sobre cómo iterar sobre los caracteres, mantener una pila de corchetes de apertura y cierre, u otros problemas más específicos a los que se enfrenta. Cada uno de ellos puede ser respondido individualmente y puede ser más útil para muchos otros que están aprendiendo AppleScript.
0 votos
@GrahamMiln El problema principal de la pregunta es que una discusión sobre cómo abordar el problema en general (desarrollar un analizador sintáctico, mantener una representación de árbol, etc.) está fuera del alcance de AD (Stackoverflow.com sería más adecuado). Así que si el OP está luchando con el diseño como tal, desglosar el problema en cuestiones específicas puede no ser posible todavía.
1 votos
stackoverflow.com/questions/28256/ ofrece una buena visión de las opciones de diseño disponibles, independientemente del lenguaje de implementación.
0 votos
@Graham Normalmente, cuando publico una pregunta como las que sugieres, recibo un comentario preguntando, "Bueno, ¿qué es exactamente lo que quieres conseguir? El objetivo final puede afectar a la respuesta". Entonces tendré que editar mi post para reflejar el código completo. En otras palabras, la capacidad de discernir y articular con precisión mi pregunta específica requiere una comprensión de la programación que excede mi comprensión personal. Además, presentar todo el alcance de un proyecto puede revelar métodos que "matan dos pájaros de un tiro", en lugar de averiguar cómo completar cada tarea una por una, de forma aislada.