AppleScript Calculator: Prendi l'equazione di testo selezionata e calcola il risultato

2

Voglio creare un servizio in grado di prendere il testo selezionato, eseguire automaticamente l'operazione matematica desiderata e quindi incollare il risultato direttamente dopo il testo selezionato. Questo servizio è simile alla funzione calcolatrice integrata di Ricerca Google, ma è più pratico.

Ecco alcuni esempi:

if this is selected text : then this is new text

43+957 : = 1000

763-9482 : = -8719

8*26 : = 208

83/23 : = 3.60869565217

Le operazioni di cui sopra includono addizione, sottrazione, moltiplicazione e divisione. Finora, questo script non è difficile da scrivere.

Ma vorrei anche la possibilità di utilizzare parentesi nei calcoli. Questo è dove la strada diventa rocciosa.

Ecco alcuni esempi di equazioni che includono parentesi:

(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

Yikes.

Va bene. Piccoli passi ...

Ecco il codice che ho scritto. Può gestire solo la prima serie di esempi:

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

Sono confuso su come affrontare l'intero concetto di parentesi in questo script. Qualcuno può dare una mano?

Ecco la mia idea approssimativa:

  1. Determina quante parentesi ci sono nella stringa.

  2. Dividi la stringa di input in segmenti. Il numero di segmenti si basa sul numero totale di parentesi nella stringa, meno uno. Il numero di segmenti dovrebbe essere un numero dispari.

  3. Verifica se uno qualsiasi dei segmenti contiene parentesi incorporate.

  4. Ripeti i passaggi da 1 a 4 finché non ci sono parentesi in nessun segmento.

  5. Ora che hai i tuoi segmenti, agisci come se ogni segmento fosse la sua stringa. Cioè, calcola il risultato di ogni segmento in modo indipendente, invece di utilizzare semplicemente il numero precedente nell'elenco per interagire con il seguente numero nell'elenco.

  6. Aggiungi tutti i risultati del segmento insieme.

Non sono sicuro di avere l'idea giusta.

Sono consapevole di aver completamente ignorato il concetto di ordine delle operazioni . Non so come implementarlo esattamente, neanche. La mia difesa è che questa è fondamentalmente una parte del codice parentesi. Ad esempio, 1 + 4 * 2 dovrebbe prima essere convertito in 1+ (4 * 2) prima che il risultato possa essere calcolato.

Nota:

Ho affermato che voglio che l'input per AppleScript sia il testo attualmente selezionato. Ma vedrai chiaramente che non ho scritto il codice in questo modo.

Ai fini della scrittura, del debug e della risoluzione di questo script, sto ignorando questo elemento dello script, perché questa è una parte molto facile da scrivere e rende più complicato testare il codice.

Una volta che lo script è stato perfezionato, imposterò semplicemente il Servizio per ricevere selected text in any application . Per l'output, dirò lo script al codice chiave e quindi incolleremo il risultato finale.

A proposito, se queste domande elaborate di AppleScript stanno diventando un po 'esagerate per Chiedi a , per favore fatemelo sapere e io le porterò su un altro sito incentrato su AppleScript (es. MacScripter.net). Non so se sto spingendo il mio limite qui.

    
posta rubik's sphere 13.03.2017 - 04:55
fonte

1 risposta

3

Over su StackOverflow troverai queste domande correlate:

Per una discussione sull'analisi delle espressioni, vedi:

The Burden of AppleScript

AppleScript non è un linguaggio per assaporare la scrittura di un parser. Il linguaggio è ottimo per molte cose ma non per la manipolazione del testo. La lingua è Turing Complete , quindi il tuo progetto è possibile, ma difficile.

AppleScript è un dialetto Open Scripting Architecture (OSA) e forse potresti prendere in considerazione un altro dialetto OSA per questo progetto, come JavaScript. Mentre JavaScript non è l'ideale, troverai più risorse e guide per aiutarti. È inoltre possibile combinare script Script Editor compilati con script AppleScript e JavaScript.

Utilizza bc

Considera il piping del testo selezionato su bc e restituendo il risultato:

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

Questo approccio evita di reinventare la ruota e utilizza il calcolatore integrato della riga di comando incluso in macOS, bc .

    
risposta data 13.03.2017 - 07:27
fonte

Leggi altre domande sui tag