Re: returning math answers given a string
Re: returning math answers given a string
- Subject: Re: returning math answers given a string
- From: Kai <email@hidden>
- Date: Mon, 27 Jan 2003 05:32:29 +0000
on Sat, 25 Jan 2003 20:05:16 -0700, Michael Glasser <email@hidden>
wrote:
>
I have come up with the following script. It handles numbers up to 20
>
quite well, though if you use "twenty one" or something like that it
>
gets rather confused.
That's because your script checks only one word at a time - so it will
change "twenty one" (2 words) to "201" ("20" & "1"). Even if you were
checking for multiple words, the script searches for numbers in ascending
numerical order, so it would find the word "twenty" before finding the words
"twenty one" - resulting in a similar anomaly.
>
Any ideas on how I can improve it?
You could get around the ascending number problem by reversing the order of
the search. You might also avoid repetitive if/then/else statements by
exploring techniques involving more lists and repeat loops.
It's worth checking editing methods that use AppleScript's text item
delimiters. They're an extremely fast and effective way of modifying text
strings.
Finally, try to watch out for evaluations that are performed more than once,
such as:
>
set theWords to every word in newCalc
>
repeat with loop from 1 to count of words in newCalc
...which could be streamlined by saying something like:
set theWords to every word in newCalc
repeat with loop from 1 to count theWords
- or even just:
repeat with loop from 1 to count newCalc's words
>
Any idea why it does not work with "/" unless I add the extra loop to
>
convert "/" to " divided "... which only gets converted back! I do not
>
understand that one at all...
What removes the "/" is the coercion from a text string to a list of words.
This is because the character "/" could also be regarded as a text separator
- as in:
-----------------------------------------
"lengthy if/then/else statements"'s words
--> {"lengthy", "if", "then", "else", "statements"}
-----------------------------------------
If you use the <option + "/"> key combination (ASCII character 214) instead,
there's no need to convert it twice. Since its purpose is less ambiguous,
AppleScript will use it quite happily in a division calculation.
BTW, you may not have noticed this yet, but the same problem can occur with
the "-" character (ASCII character 45). In this case, you need to substitute
the <option + "-"> key combination* (ASCII character 208).
* (That's the "-" on the main keyboard - not the numeric keypad.)
>
-------------------------------------------------------
>
>
set theText to text returned of (display dialog "Ask me a math
>
question:" default answer "What is 3 + 3?" buttons {"OK"})
>
set theAnswer to doMath(theText)
>
display dialog theAnswer
>
>
on doMath(theText)
>
set makeCalc to ""
>
set newCalc to ""
>
>
repeat with loop from 1 to count of characters in theText
>
set theChar to character loop of theText
>
if theChar = "/" then set theChar to " divided "
>
set newCalc to newCalc & theChar
>
end repeat
>
>
set validChars to "101121314151617181920+-*w().^/w"
>
try
>
set theWords to every word in newCalc
>
repeat with loop from 1 to count of words in newCalc
>
set theWord to word loop of newCalc
>
if theWord is "plus" then
>
set theWord to "+"
>
else if theWord is "minus" then
>
set theWord to "-"
>
else if theWord is "times" then
>
set theWord to "*"
>
else if theWord is "divided" then
>
set theWord to "/"
[snip: more if/else statements]
The following script should get close to what I think you're trying to do.
It also allows numbers up to "ninety nine" to be expressed as text:
==========================
property t : missing value
property o : missing value
property v : missing value
to setup()
if t is not missing value then return
set {p, d, m} to {{"one", "two", "three", "four", "five", [NO BREAK]
"six", "seven", "eight", "nine", "ten", "eleven", "twelve", [NO BREAK]
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen", [NO BREAK]
"eighteen", "nineteen", "twenty", "thirty", "forty", [NO BREAK]
"fifty", "sixty", "seventy", "eighty", "ninety"}, [NO BREAK]
ASCII character 214, ASCII character 208}
set {t, o, v} to {{"plus", "minus", "-", "times", [NO BREAK]
"multiplied", "divided", "/", "power"}, [NO BREAK]
{"+", m, m, "*", "*", d, d, "^"}, [NO BREAK]
(0 / 1 as string)'s character 2 & d & m & "+*^" & [NO BREAK]
"11314151617181920212242526272829303233536373" & [NO BREAK]
"8394043446474849505455758596065668697076779808788909910"}
set x to p's items 1 thru 19
repeat with y from 20 to 27
set n to p's item y
set x's end to n
repeat with z from 1 to 9
set x's end to n & space & p's item z
end repeat
end repeat
set t to t & x's reverse & "zero"
repeat with i from 99 to 0 by -1
set o's end to i
end repeat
end setup
to askQuestion()
set {tid, q, m} to {text item delimiters, "", "Ask me a math question:"}
repeat
set q to (display dialog m default answer q with icon 1)'s text returned
set {k, a} to (getAnswer to q)
set m to k & " = " & a & return & return & "Ask me another math question:"
end repeat
set text item delimiters to tid
end askQuestion
to getAnswer to q
set {q, a, text item delimiters} to {convertTerms from q, {}, space}
repeat with c in q's words
tell c's contents to if it is in v then set a's end to it
end repeat
set k to a as string
set a to run script k
try
set a to a as integer
end try
{k, a}
end getAnswer
to convertTerms from q
repeat with n from 1 to count t
set i to t's item n
if i is in q then
set text item delimiters to i
set {q, text item delimiters} to {q's text items, o's item n as string}
set q to q as string
end if
end repeat
q
end convertTerms
setup()
askQuestion()
==========================
Not tested exhaustively, but I'll leave any further refinements to you...
--
Kai
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.