Hello.
This script solves quadratic equations, also those with imaginary roots. You may get the coeffecients, and the roots that solves the equation pasted to the clipboard.
property scriptTitle : "Quadratic Equations Solver"
-- Copyright 2013-2015 McUsr: you may use it as you see fit but you must keep this notice.
property cliptextIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:ClippingText.icns")
property Debug : false
property listSep : missing value
property basicMessage : missing value
if listSep is missing value then
set listSep to listSeparator()
set basicMessage to "Input the coeffecients a " & listSep & "b " & listSep & "c," & return & "in order to solve the equation:" & return & return & "Æ’(x)=ax²+bx+c=0"
end if
set {theMessage, isWarning, l} to {basicMessage, false, {}}
repeat while true
set l to _LIST_INPUT(theMessage, l as text, isWarning, scriptTitle, false, "regular")
if length of l is not 3 then
set isWarning to true
set theMessage to "I need exactly three coeffecients, that is numbers!" & return & return & theMessage
else
set {a, b, c} to l
exit repeat
end if
end repeat
# needs three terms
if |abs|(a) < 1.0E-15 then
if |abs|(b) < 1.0E-15 then
if |abs|(c) < 1.0E-15 then
set status to "L ∈ R"
else
set status to "L ∈ Ø"
end if
else
set x1 to (-c / b)
if x1 < 0 then
else
set status to "xâ‚ and xâ‚‚ = " & x1
end if
end if
else
set x1 to (b ^ 2) - 4 * a * c
# removed bug, thanks to Adam Bell
if x1 ≥ 0 then
if b < 0 then
set x1 to -b + (x1 ^ 0.5)
else
set x1 to -b - (x1 ^ 0.5)
end if
set x1 to -x1 / 2 / a
set x2 to c / a / x1
set status to "xâ‚ = " & x1 & return & "xâ‚‚ = " & x2
else
set x2 to ((-x1) ^ 0.5) / 2 / a
set x1 to -b / 2 / a
if x2 < 0 then set x2 to -x2
set status to "" & x1 & " ± ί * " & x2
end if
end if
tell application (path to frontmost application as text)
if status is in {"L ∈ R", "L ∈ Ø"} then
display dialog return & status & return with title scriptTitle buttons {"Quit", "Ok"} cancel button 1 default button 2 with icon cliptextIcon giving up after 300
else
set btn to button returned of (display dialog return & status & return with title scriptTitle buttons {"Quit", "Clipboard", "Ok"} cancel button 1 default button 3 with icon cliptextIcon giving up after 300)
if btn = "Clipboard" then set the clipboard to ("a = " & item 1 of l & listSep & " b = " & item 2 of l & listSep & " c = " & item 3 of l & return & "Result: " & status)
end if
end tell
on listSeparator()
if text 2 of ((1 / 2) as text) is "," then
return "; "
else
return ","
end if
end listSeparator
on _LIST_INPUT(txt, defaAns, isWarning, scriptName, stayAlive, listType)
-- The core of the handler originally written by Nigel Garvey.
-- Parameters:
-- txt: Text: The message that is shown in the input dialog.
-- defaAns: Text: The default value that is show in the input field.
-- isWarning: Boolean: If set to true, then a caution icon is shown, not
-- a note icon which is default.
-- ScriptName: Text: Dialog box title, not necessarily a script name.
-- stayAlive: Boolean: If true the script returns missing value, otherwise
-- dies.
-- listType: Word: Word can be: "Regular", "PositiveDate", "EveryDate"
-- or "Triplet","Hours".
-- Returns:
-- A list with values on success.
-- Missing value if the user canceled and stayAlive is true.
-- {""} if the input was bad somehow.
-- Dies directly if the user cancelled and the stayalive was false.
--
-- If you have this handler in a tell block, then you want to wrap
-- That tell block into a try block to "smooth over" the error number -128 call.
local inpt, btnList, isNegative, astid, outpt, digits, param, listSep
-- Thanks to Yvan Koenig for tips on increasing robustness!
if listType is not in {"Regular", "PositiveDate", "EveryDate", "Triplet", "Hours"} then ¬
error "Bad value for listType" number 4015
set inpt to missing value
# Configures list separator based on decimal separator: ";" <-- "," and "," <-- "."
# A list separator always works, as do spaces between elements.
# A "-" works for dates , when dates are restricted to positive dates.
# A "." works for separatring elements of dates and times too.
# A "/" works for separating dates.
# A ":" works for separating hours.
# A list of regular numbers can only be separated with space and the designated list separator.
# Counting of the elements happens in the caller of this handler.
if text 2 of ((1 / 2) as text) is "," then
set listSep to ";"
else
set listSep to ","
end if
# Appropriate buttons for whether we shall stay alive or not.
if stayAlive then
set btnList to {"Cancel", "Ok"}
else
set btnList to {"Quit", "Ok"}
end if
with timeout of (10 * minutes) seconds
tell application (path to frontmost application as text)
if isWarning then
try
set inpt to text returned of (display dialog txt default answer defaAns with title scriptName buttons btnList with icon caution cancel button 1 default button 2)
end try
else
try
set inpt to text returned of (display dialog txt default answer defaAns with title scriptName buttons btnList with icon note cancel button 1 default button 2)
end try
end if
end tell
end timeout
if inpt is missing value then
if not my Debug and not stayAlive then -- Need to stay alive here, if we are entering the second date.
error number -128 -- User hit cancel.
else
return missing value -- Thanks to Yvan Koenig.
end if
end if
if inpt is "" then return {}
if listType is "Triplet" then
ignoring white space
set isNegative to (inpt begins with "-")
end ignoring
else if listType is "EveryDate" then
set isNegative to (inpt contains "-")
else
set isNegative to false
end if
log "" & inpt
set astid to AppleScript's text item delimiters
set titems to {"-", listSep, space}
if listType is not in {"PositiveDate", "Triplet"} then set titems to rest of titems
if listType is in {"PositiveDate", "EveryDate"} then set titems to titems & {".", "/"}
if listType is in {"Triplet", "Hours"} then set end of titems to ":"
set AppleScript's text item delimiters to titems
if listType is in {"Triplet", "EveryDate"} then
set outpt to inpt's words
else
set outpt to inpt's text items
end if
# set AppleScript's text item delimiters to " "
# set inpt to inpt as text
set AppleScript's text item delimiters to astid
set reslist to {}
# set outpt to inpt's words
set digits to "1234567890"
repeat with i from 1 to (count outpt)
set param to item i of outpt
if param is not "" and (character 1 of param is in digits or character 1 of param is "-") then
try -- Thanks to Yvan Koenig.
set param to param as number
on error
if listType is not in {"PositiveDate", "EveryDate"} then
# Can't have decimal fraction anyway
try
set AppleScript's text item delimiters to "."
set param to text items of param
set AppleScript's text item delimiters to ","
set param to param as text
set AppleScript's text item delimiters to astid
set param to param as number
on error
return {""} -- this must be resolved by caller
end try
else
return {""}
end if
end try
if (isNegative) then # This works only for triplets
if listType is in {"EveryDate", "Triplet"} then set param to -param
end if
set end of reslist to param
end if
end repeat
return reslist
end _LIST_INPUT
on |abs|(i)
-- absolute value, faster than from an Osax.
return i * (-1 + 2 * ((i > 0) as integer))
-- if i > 0 then we add two, and multiply with 1
-- if i < 0 then we add zero and multiply with -1
end |abs|