Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'AVCS Voice Calculator & Conversions (v1.0) -- Calculate expressions with up to 2 operations and 3 values "Any way you say it"
- 'by SemlerPDX Mar2020/Jan2021
- 'VETERANS-GAMING.COM
- 'When I say: *[divided by;divide by;divided that;divide that;divided;divide;multiply;times;multiplied by;multiply that;multiplied that;times that;add;add that;added that;plus;subtract;subtracted;minus;% of;to the power of;percent of;swear;square;square root of;square of;squared;cubed;cube;cuban;° c;° f;kelvin;celcius;celsius;centigrade;fahrenheit;kelvin;calvin;cm;centimeters;centimetres;inches;foot;feet;meters;metres;yards;yours;miles;km;kilometers;kilometres;feet per second;mph;miles per hour;kph;kilometers per hour;kilometres per hour;knots;mach;mock;mark]*
- 'Set text [~avcs_cmd] to '{TXTWORDTONUM:"{CMD}"}' (Trim) (Lower Case)
- Imports Microsoft.VisualBasic
- Imports System
- Imports System.Math
- Imports System.Globalization
- Public Class VAInline
- dim decimalSeparator as string = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
- dim decimalPlaces as Int32 = 3 'Default = 3 | rounds results -- change via voice command 'Set Decimal Places [to;] [0..16]'
- dim countHistory as integer = 1
- 'List Comparison Vars - must start and end with whitespace to check for whole word due to wildcard recognition
- dim OperatorsList as string = " divided divide times multiplied multiply add plus subtract subtracted minus - % percent power square squared squareroot cubed cubes cube cuban cuba "
- dim ConvertorsList as string = " c f k cm celsius celcius centigrade fahrenheit kelvin calvin inches centimeters centimetres foot feet m meters metres yards yours miles km kilometers kilometres fps feetpersecond mps meterspersecond metrespersecond mph milesperhour kph kilometersperhour kilometresperhour knots mach mark mock "
- dim OpsList as string = " per dif prd sum sub exp sqr "
- dim DoubleOpsList as string = " dif prd sum sub "
- dim SymbolsList as string = " ° # $ % ^ & * - + = : / "
- dim PiList as string = " pi pie tie high bye eye espy pine pied ply tie "
- 'Speech Parsing Vars
- dim cmd as string = ""
- dim charArray() as char
- dim cmdSegments() as string
- 'Values Decimal Vars
- dim operand1 as decimal?
- dim operand2 as decimal?
- dim operand3 as decimal?
- dim operandLast as decimal?
- dim result as decimal?
- dim resultLast as decimal?
- 'Operations String Vars
- dim operator1 as string
- dim operator2 as string
- dim operatorText1 as string = ""
- dim operatorText2 as string = ""
- dim equationText as string = ""
- dim operationsOrder as integer = 0
- dim faultCount as integer = 0
- dim randomText as string
- dim subReverse as boolean
- dim calcActive as boolean
- 'Function to fix large number separators by culture
- Private Function FixLargeNumberSeparator(ByRef cmd as string)
- 'ex. (7,000.32 into 7000.32) [or] (7.000,32 into 7000,32)
- if ((cmd.Contains(".")) or (cmd.Contains(",")))
- if (decimalSeparator <> ".")
- if (cmd.Contains("."))
- cmd = cmd.Replace(".", "")
- end if
- elseif (decimalSeparator <> ",")
- if (cmd.Contains(","))
- cmd = cmd.Replace(",", "")
- end if
- end if
- end if
- end function
- 'Function to transform large number words and concat with the number said just before
- Private Function FixLargeWordNum(ByRef largeType as string, ByRef lastNum as decimal?)
- select case largeType
- case "million"
- lastNum *= 1000000
- case "billion"
- lastNum *= 1000000000
- case "trillion"
- lastNum *= 1000000000000
- case "quadrillion"
- lastNum *= 1000000000000000
- case else
- largeType = "AVCS Calculation Error - unable to resolve '" + lastNum.ToString() + " " + largeType + "' as an opperand"
- end select
- end function
- 'Function to test for "by" as Pi in specific cases
- Private Function HasPi(ByVal operatorName as string)
- if (not((operatorName.Contains("root")) or (operatorName.StartsWith("square")) or (operatorName.StartsWith("cub"))))
- cmd = cmd.Replace(" "," ").Replace(" "," ").Replace("divided by","").Replace("divide by","").Replace("multiplied by","").Replace("multiply by","").Replace("that by","")
- if ((cmd.StartsWith("by ")) or (cmd.Contains(" by ")) or (cmd.EndsWith(" by")))
- Return true
- end if
- end if
- end function
- 'Function to set keyword and readable text/symbol for Operators
- Private Function SetOperator(ByRef operatorName as string, ByRef operatorText as string)
- if ((operatorName.Contains("%")) or (operatorName.Contains("percent")))
- operatorText = "% of"
- operatorName = "per"
- elseif (operatorName.StartsWith("divide"))
- operatorText = "/"
- operatorName = "dif"
- elseif ((operatorName.Contains("times")) or (operatorName.StartsWith("multipl")))
- operatorText = "x"
- operatorName = "prd"
- elseif ((operatorName.Contains("plus")) or (operatorName.StartsWith("add")))
- operatorText = "+"
- operatorName = "sum"
- elseif ((operatorName.StartsWith("subtract")) or (operatorName.Contains("minus")) or (operatorName.Contains("-")))
- operatorText = "-"
- operatorName = "sub"
- elseif (operatorName.Contains("power"))
- operatorText = "to the power of"
- operatorName = "exp"
- elseif (operatorName.Contains("squareroot"))
- operatorText = "the square root of"
- operatorName = "sqr"
- elseif (operatorName.StartsWith("square"))
- operatorText = "squared"
- operatorName = "exp"
- elseif (operatorName.StartsWith("cub"))
- operatorText = "cubed"
- operatorName = "exp"
- end if
- end function
- 'Function to set keyword and readable text/symbol for Conversions
- Private Function SetConvertor(ByRef operatorName as string, ByRef operatorText as string)
- 'VELOCITY CONVERSIONS==============
- if ((operatorName.Contains("fps")) or (operatorName.Contains("feetpersecond")))
- operatorText = "feet per second"
- operatorName = "fps2"
- elseif ((operatorName.Contains("mps")) or (operatorName.Contains("meterspersecond")) or (operatorName.Contains("metrespersecond")))
- operatorText = "meters per second"
- operatorName = "mps2"
- elseif ((operatorName.Contains("mph")) or (operatorName.Contains("milesperhour")))
- operatorText = "miles per hour"
- operatorName = "mph2"
- elseif ((operatorName.Contains("kph")) or (operatorName.Contains("kilometersperhour")) or (operatorName.Contains("kilometresperhour")))
- operatorText = "kilometers per hour"
- operatorName = "kph2"
- elseif (operatorName.Contains("knots"))
- operatorText = "knots"
- operatorName = "kts2"
- elseif ((operatorName.Contains("mach")) or (operatorName.Contains("mock")) or (operatorName.Contains("mark")))
- operatorText = "mach"
- operatorName = "mch2"
- 'DISTANCE CONVERSIONS==============
- elseif (operatorName.Contains("inches"))
- operatorText = "inches"
- operatorName = "in2"
- elseif ((operatorName.Contains("cm")) or (operatorName.Contains("centimeters")) or (operatorName.Contains("centimetres")))
- operatorText = "centimeters"
- operatorName = "cm2"
- elseif ((operatorName.Contains("feet")) or (operatorName.Contains("foot")))
- operatorText = "feet"
- operatorName = "ft2"
- elseif ((operatorName.Contains("yards")) or (operatorName.Contains("yours")))
- operatorText = "yards"
- operatorName = "yd2"
- elseif ((operatorName.Contains("km")) or (operatorName.Contains("kilometers")) or (operatorName.Contains("kilometres")))
- operatorText = "kilometers"
- operatorName = "km2"
- elseif ((operatorName.Contains("mi")) or (operatorName.Contains("miles")))
- operatorText = "miles"
- operatorName = "mi2"
- elseif ((operatorName.Contains("meters")) or (operatorName.Contains("metres")))
- operatorText = "meters"
- operatorName = "mt2"
- 'TEMPERATURE CONVERSIONS==============
- elseif (operatorName.Contains("fahrenheit"))
- operatorText = "degrees fahrenheit"
- operatorName = "f2"
- elseif ((operatorName.Contains("celcius")) or (operatorName.Contains("celsius")))
- operatorText = "degrees celcius"
- operatorName = "c2"
- elseif (operatorName.Contains("centigrade"))
- operatorText = "degrees centigrade"
- operatorName = "c2"
- elseif ((operatorName.Contains("kelvin")) or (operatorName.Contains("calvin")))
- operatorText = "kelvin"
- operatorName = "k2"
- end if
- end function
- 'Main Maths Function
- Private Function GetResult(ByVal ops as string, ByVal val1 as decimal?, Optional ByVal val2 as decimal? = 0)
- select case ops
- case "sum"
- val1 += val2
- case "sub"
- val1 -= val2
- case "prd"
- val1 *= val2
- case "dif"
- val1 /= val2
- case "per"
- val1 *= (operand2 / 100)
- case "exp"
- val1 = Math.Pow(val1, val2)
- case "sqr"
- val1 = Math.Sqrt(val1)
- case else
- val1 = nothing
- end select
- Return val1
- end function
- 'Main Conversions Function
- Private Function GetConversion(ByVal ops as string, ByVal val as decimal?)
- select case ops
- '==DISTANCE===========
- 'inches
- case "in2cm"
- val *= 0.393701
- case "in2ft"
- val *= 0.0833333
- case "in2mt"
- val *= 0.0254
- case "in2yd"
- val *= 0.0277778
- case "in2km"
- val /= 39370
- case "in2mi"
- val /= 63360
- 'cm
- case "cm2in"
- val *= 0.393701
- case "cm2ft"
- val *= 0.0328084
- case "cm2mt"
- val /= 100
- case "cm2yd"
- val *= 0.0109361
- case "cm2km"
- val /= 100000
- case "cm2mi"
- val /= 160934
- 'ft
- case "ft2in"
- val *= 12
- case "ft2cm"
- val *= 30.48
- case "ft2mt"
- val *= 0.3048
- case "ft2yd"
- val *= 0.333333
- case "ft2km"
- val /= 3280.84
- case "ft2mi"
- val /= 5280
- 'mt
- case "mt2in"
- val *= 39.3701
- case "mt2cm"
- val *= 100
- case "mt2ft"
- val *= 3.28084
- case "mt2yd"
- val *= 1.09361
- case "mt2km"
- val /= 1000
- case "mt2mi"
- val /= 1609
- 'yd
- case "yd2in"
- val *= 36
- case "yd2cm"
- val *= 91.44
- case "yd2ft"
- val *= 3
- case "yd2mt"
- val *= 0.9144
- case "yd2km"
- val /= 1093.61
- case "yd2mi"
- val /= 1760
- 'km
- case "km2in"
- val *= 39370.1
- case "km2cm"
- val *= 100000
- case "km2ft"
- val *= 3280.84
- case "km2mt"
- val *= 1000
- case "km2yd"
- val *= 1093.61
- case "km2mi"
- val *= 0.621371
- 'mi
- case "mi2in"
- val *= 63360
- case "mi2cm"
- val *= 160934.4
- case "mi2ft"
- val *= 5280
- case "mi2mt"
- val *= 1609.34
- case "mi2yd"
- val *= 1760
- case "mi2km"
- val *= 1.60934
- '==VELOCITY===========
- 'fps
- case "fps2mps"
- val *= 0.3048
- case "fps2kph"
- val *= 1.09728
- case "fps2mph"
- val *= 0.681818
- case "fps2kts"
- val *= 0.592484
- case "fps2mch"
- val *= 0.00088863
- 'mps
- case "mps2fps"
- val *= 3.28084
- case "mps2kph"
- val *= 3.6
- case "mps2mph"
- val *= 2.23694
- case "mps2kts"
- val *= 1.94384
- case "mps2mch"
- val *= 0.00291545
- 'kph
- case "kph2fps"
- val *= 0.911344
- case "kph2mps"
- val *= 0.277778
- case "kph2mph"
- val *= 0.6214
- case "kph2kts"
- val *= 1.852
- case "kph2mch"
- val *= 1234.8
- 'mph
- case "mph2fps"
- val *= 1.46667
- case "mph2mps"
- val *= 0.44704
- case "mph2kph"
- val *= 1.60934
- case "mph2kts"
- val *= 0.868976
- case "mph2mch"
- val *= 0.00130332
- 'kts
- case "kts2fps"
- val *= 1.68781
- case "kts2mps"
- val *= 0.514444
- case "kts2mph"
- val *= 1.15078
- case "kts2kph"
- val *= 1.852
- case "kts2mch"
- val *= 0.0015
- 'mch
- case "mch2fps"
- val *= 1125.33
- case "mch2mps"
- val *= 343
- case "mch2mph"
- val *= 767.269
- case "mch2kph"
- val *= 1234.8
- case "mch2kts"
- val *= 666.73866
- '==TEMPERATURE===========
- 'f
- case "f2c"
- val = ((val - 32) * 5) / 9
- case "f2k"
- val = ((val + 459.67) * 5) / 9
- 'c
- case "c2f"
- val = ((val * 9) / 5) + 32
- case "c2k"
- val = ((val * 9) / 5) + 32
- val = ((val + 459.67) * 5) / 9
- 'k
- case "k2f"
- val = ((val * 9) / 5) - 459.67
- case "k2c"
- val = ((val * 9) / 5) - 459.67
- val = ((val - 32) * 5) / 9
- case else
- val = nothing
- end select
- Return val
- end function
- Public Sub Main()
- VA.SetText("avcs_calc_return", nothing)
- 'Debugging and Testing Check (bypassed if called via spoken command)
- dim cmdTest as string = vaProxy.Utility.ParseTokens("{CMD}")
- if (cmdTest = "")
- 'VA.SetText("~avcs_cmd","what is 78° f in celcius")
- VA.SetText("~avcs_cmd","what is 3 zillion divided by 2")
- 'VA.SetText("~avcs_cmd","by the way what is 3 plus 3 times by")
- '---note: this expression does not work, because it has 3 operations!!
- 'VA.SetText("~avcs_cmd","what is the square root of 144 plus 3 cubed")
- VA.SetInt("AVCS_CALC_ResultsDecimalPlaces",3)
- cmdTest = VA.GetText("~avcs_cmd")
- else
- 'Check Calc Mode state, exit of off
- if ((VA.GetBoolean("AVCS_CALC_MODE_ON")) isNot nothing)
- calcActive = VA.GetBoolean("AVCS_CALC_MODE_ON")
- end if
- 'Provide Message for infrequent wildcard recognition when Calculator Mode OFF (prompt in case user does not known)
- if (not(calcActive))
- if ((VA.GetInt("AVCS_CALC_FAULT")) isNot nothing)
- faultCount = VA.GetInt("AVCS_CALC_FAULT")
- faultCount += 1
- if (faultCount >= 3)
- if (faultCount >= 15)
- VA.WriteToLog("Calculation recognized, but won't be computed (this is common when calculator is OFF)", "purple")
- VA.SetInt("AVCS_CALC_FAULT", nothing)
- faultCount = 0
- end if
- else
- randomText = "Calculator is OFF. To enable, say, '" + vaProxy.Utility.ParseTokens("{TXTRANDOM:Enable;Begin;Turn On}") + " Voice Calculator'"
- VA.WriteToLog(randomText, "purple")
- end if
- VA.SetInt("AVCS_CALC_FAULT", faultCount)
- else
- VA.SetInt("AVCS_CALC_FAULT", 1)
- end if
- 'Exit Calc Function when Mode OFF
- Exit Sub
- end if
- end if
- 'Get Custom Decimal Place Settings (if exists)
- if (VA.GetInt("AVCS_CALC_ResultsDecimalPlaces"))
- decimalPlaces = Convert.ToInt32(VA.GetInt("AVCS_CALC_ResultsDecimalPlaces"))
- end if
- 'Parse Spoken Command for Equation(s)
- if (VA.GetText("~avcs_cmd")) isNot nothing
- 'Remove large number separators & spaces from keywords and remove known "to" and "1" in operations
- cmd = VA.GetText("~avcs_cmd").Replace("swear ","square ").Replace("square root","squareroot").Replace("to the power","power").Replace("too value"," value").Replace("to value"," value").Replace("2 value"," value").Replace("value ","value").Replace(" per ","per").Replace(" ad ","add").Replace("add that 2","add that ").Replace("add that to","add that ")
- FixLargeNumberSeparator(cmd)
- if (cmd.StartsWith("fore to"))
- cmd = cmd.Substring(7, cmd.Length - 7)
- elseif (cmd.StartsWith("for to"))
- cmd = cmd.Substring(6, cmd.Length - 6)
- elseif (cmd.StartsWith("or to"))
- cmd = cmd.Substring(5, cmd.Length - 5)
- elseif (cmd.StartsWith("1 is"))
- cmd = cmd.Substring(4, cmd.Length - 4)
- end if
- 'Evaluate spoken command split at each character and space out symbols
- charArray = cmd.ToCharArray
- cmd = ""
- for each character as string in charArray
- if (SymbolsList.Contains(character))
- cmd += " " + character.ToString() + " "
- else
- cmd += character.ToString()
- end if
- next
- 'Evaluate all segments of speech split at {SPACE} and parse for operands and operators
- cmdSegments = cmd.Split(New String() {" "},StringSplitOptions.None)
- for each segment as string in cmdSegments
- if (not(segment = ""))
- 'Handle numbers recognized as homonym words
- select case segment
- case "too"
- segment = "2"
- case "to"
- segment = "2"
- case "trees"
- segment = "3"
- case "tree"
- segment = "3"
- case "fore"
- segment = "4"
- case "for"
- segment = "4"
- case "ate"
- segment = "8"
- case "ape"
- segment = "8"
- case "valuetoo"
- segment = "value2"
- case "valueto"
- segment = "value2"
- case "valuetrees"
- segment = "value3"
- case "valuetree"
- segment = "value3"
- case "valuefore"
- segment = "value4"
- case "valuefor"
- segment = "value4"
- case "valueate"
- segment = "value8"
- end select
- 'Handle short form of convertors
- select case segment
- case "c"
- segment = "celcius"
- case "f"
- segment = "fahrenheit"
- case "k"
- segment = "kelvin"
- case "m"
- segment = "meters"
- end select
- 'Handle "subtract A from B" order of operations error
- if (segment.Contains("from"))
- if ((operand2 is nothing) and(operand1 isNot nothing) and ((operator1 isNot nothing) and (operator1.Contains("subtract"))))
- subReverse = true
- end if
- end if
- 'Handle "that" reference to previous calculation result
- if (segment.Contains("that"))
- if ((VA.GetDecimal("AVCS_CALC_LastResult")) isNot nothing)
- segment = VA.GetDecimal("AVCS_CALC_LastResult").ToString()
- end if
- end if
- 'Handle MEM reference to previous calculation result
- if ((segment.StartsWith("value")) and (IsNumeric(segment.Substring(segment.Length - 1, 1))))
- if ((VA.GetDecimal(segment)) isNot nothing)
- segment = VA.GetDecimal(segment).ToString()
- else
- VA.WriteToLog(segment + " does not exist in memory", "red")
- Exit Sub
- end if
- end if
- 'Handle "pi" and homonym variants
- if (PiList.Contains(" " + segment + " "))
- if (operand1 is nothing)
- operand1 = Math.Pi
- elseif (operand2 is nothing)
- operand2 = Math.Pi
- elseif (operand3 is nothing)
- operand3 = Math.Pi
- end if
- 'Set Operands -------
- elseif ((IsNumeric(segment)) and (operand1 is nothing))
- try
- operand1 = Convert.ToDecimal(segment)
- operandLast = operand1
- if (operationsOrder = 0)
- operationsOrder = 1 'for edge case: (b = Pi)
- end if
- catch
- VA.WriteToLog("AVCS Calculation Error at Operand 1", "red")
- end try
- elseif ((IsNumeric(segment)) and (operand2 is nothing))
- try
- operand2 = Convert.ToDecimal(segment)
- operandLast = operand2
- catch
- VA.WriteToLog("AVCS Calculation Error at Operand 2", "red")
- end try
- elseif ((IsNumeric(segment)) and (operand3 is nothing))
- try
- operand3 = Convert.ToDecimal(segment)
- operandLast = operand3
- catch
- VA.WriteToLog("AVCS Calculation Error at Operand 3", "red")
- end try
- 'Set Operators -------
- elseif ((OperatorsList.Contains(" " + segment + " ")) and (operator1 is nothing))
- operator1 = segment
- if (operationsOrder = 0)
- operationsOrder = 2 'for edge case: (a = Pi)
- end if
- elseif ((OperatorsList.Contains(" " + segment + " ")) and (operator2 is nothing))
- operator2 = segment
- if ((operationsOrder = 1) and (operand2 isNot nothing))
- operationsOrder = 3 'for edge case: (c = b and b = Pi)
- elseif ((operationsOrder = 1) and (operand2 is nothing))
- operationsOrder = 4 'for edge case: (c = Pi)
- end if
- 'Set Convertors -------
- elseif ((ConvertorsList.Contains(" " + segment + " ")) and (operator1 is nothing))
- operator1 = segment
- operationsOrder = 5 'for edge case null: (no way Pi)
- elseif ((ConvertorsList.Contains(" " + segment + " ")) and (operator2 is nothing))
- operator2 = segment
- 'Handle "..illions" -------
- elseif (segment.EndsWith("illion"))
- if ((operand1 isNot nothing) and (operandLast = operand1))
- FixLargeWordNum(segment,operand1)
- elseif ((operand2 isNot nothing) and (operandLast = operand2))
- FixLargeWordNum(segment,operand2)
- elseif ((operand3 isNot nothing) and (operandLast = operand3))
- FixLargeWordNum(segment,operand3)
- end if
- if (segment.StartsWith("AVCS Calculation Error"))
- VA.WriteToLog(segment, "red")
- Exit Sub
- end if
- end if
- end if
- next
- 'Evaluate for Pi recognized as "by" (edge cases)
- if (operationsOrder < 5)
- '-- 1 operation catch
- if ((operator2 is nothing) and (operand2 is nothing))
- if (HasPi(operator1))
- if (operationsOrder = 1)
- operand2 = Math.Pi
- elseif (operationsOrder = 2)
- operand2 = operand1
- operand1 = Math.Pi
- end if
- end if
- '-- 2 operations catch
- elseif ((operator2 isNot nothing) and (operand3 is nothing))
- if ((HasPi(operator1)) or (HasPi(operator2)))
- if (operationsOrder = 4)
- operand3 = operand2
- operand2 = Math.Pi
- elseif (operationsOrder = 3)
- operand3 = Math.Pi
- elseif (operationsOrder = 2)
- operand3 = operand2
- operand2 = operand1
- operand1 = Math.Pi
- end if
- end if
- end if
- end if
- 'Evaluate Operator 1 ======
- if (operator1 isNot nothing)
- 'Handle null operands on Squared/Cubed operators
- if ((operator1.StartsWith("square")) and (not(operator1.Contains("root"))))
- operand2 = 2
- elseif (operator1.StartsWith("cub"))
- operand2 = 3
- 'Handle Reverse order of operations on Subtract
- elseif ((operator1.Contains("subtract")) and (subReverse))
- dim operand4 as decimal? = operand2
- operand2 = operand1
- operand1 = operand4
- end if
- 'Set Operator 1 keyword and get text form of Operator/Convertor
- if (not(OperatorsList.Contains(operator1)))
- SetConvertor(operator1,operatorText1)
- else
- SetOperator(operator1,operatorText1)
- end if
- else
- VA.WriteToLog("AVCS Calculation Error on Null Operator 1", "red")
- Exit Sub
- end if
- 'Evaluate Operator 2 ======
- if (operator2 isNot nothing)
- 'Handle null operands on Squared/Cubed operators
- if ((operator2.StartsWith("square")) and (not(operator2.Contains("root"))))
- operand3 = 2
- elseif (operator2.Contains("cub"))
- operand3 = 3
- end if
- 'Set Operator 2 keyword and get text form of Operator/Convertor
- if (not(OpsList.Contains(operator1)))
- SetConvertor(operator2,operatorText2)
- operator1 = operator1 + operator2.Substring(0, operator2.Length - 1)
- operator2 = nothing
- else
- SetOperator(operator2,operatorText2)
- 'Calculate Square Root on Multi-Part Equation to avoid errors on null operand3
- 'ex. 200 subtract square root of 128 = 188.69 = a-(Sqrt(b))
- if ((operator2 = "sqr") and (operand3 is nothing))
- equationText = operand1.ToString() + " " + operatorText1 + " " + operatorText2 + " " + operand2.ToString() + " "
- operand2 = Math.Sqrt(operand2)
- operator2 = nothing
- end if
- 'Calculate Percentage before to avoid order of operations and text display errors
- 'ex. 200 subtract 20 % = 160 = a-(b*(a/100))
- if ((operator2 = "per") and (operand3 is nothing))
- equationText = operand1.ToString() + " " + operatorText1 + " " + operand2.ToString() + " " + operatorText2 + " " + operand1.ToString() + " "
- operand3 = operand1
- operand2 = operand2*(operand3 / 100)
- operand3 = nothing
- operator2 = nothing
- 'ex. 200 subtract 20 % of 100 = 180 = a-(b*(c/100)
- elseif ((operator2 = "per") and (operand3 isNot nothing))
- equationText = operand1.ToString() + " " + operatorText1 + " " + operand2.ToString() + " " + operatorText2 + " " + operand3.ToString() + " "
- operand2 = operand2*(operand3 / 100)
- operand3 = nothing
- operator2 = nothing
- 'ex. 4 plus 7 to the power of 3 = 347 = a+(b^c)
- elseif (((operator2 = "exp") and (operatorText2.StartsWith("to"))) and (operand3 isNot nothing))
- equationText = operand1.ToString() + " " + operatorText1 + " " + operand2.ToString() + " " + operatorText2 + " " + operand3.ToString() + " "
- operand2 = Math.Pow(operand2, operand3)
- operand3 = nothing
- operator2 = nothing
- 'ex. 4 plus 7 cubed = 347 = a+b³ [or] 4 plus 7 squared = 53 = a+b²
- elseif (((operator2 = "exp") and (not(operatorText2.StartsWith("to")))) and (operand3 isNot nothing))
- equationText = operand1.ToString() + " " + operatorText1 + " " + operand2.ToString() + " " + operatorText2 + " "
- operand2 = Math.Pow(operand2, operand3)
- operand3 = nothing
- operator2 = nothing
- end if
- end if
- end if
- 'Final Evaluation for "8" recognized as "a"
- if ((DoubleOpsList.Contains(operator1)) and (operator2 is nothing) and (operand1 isNot nothing) and (operand2 is nothing))
- if ((cmd.Contains(" a ")) or (cmd.EndsWith(" a")))
- if (operationsOrder = 1)
- operand2 = 8
- else
- operand2 = operand1
- operand1 = 8
- end if
- end if
- end if
- '==EVALUATE RESULT==
- if (OpsList.Contains(operator1))
- if (equationText = "")
- 'Build Equation Text for display in VA Event log
- if (operand1 isNot nothing)
- equationText += operand1.ToString() + " "
- end if
- if (operator1 isNot nothing)
- equationText += operatorText1 + " "
- end if
- if (operand2 isNot nothing)
- equationText += operand2.ToString() + " "
- end if
- if (operator2 isNot nothing)
- equationText += operatorText2 + " "
- end if
- if (operand3 isNot nothing)
- equationText += operand3.ToString() + " "
- end if
- 'Calculate Square Root on Multi-Part Equation to avoid incorrect operations math and display text
- 'ex. square root of 144 times 7 = 84 = b*(Sqrt(a))
- if ((operator1 = "sqr") and ((operator2 isNot nothing) and (operand2 isNot nothing)))
- equationText = operatorText1 + " " + operand1.ToString() + " " + operatorText2 + " " + operand2.ToString() + " "
- end if
- 'Remove any whitespace between % and number(s)
- if (equationText.Contains(" %"))
- equationText = equationText.Replace(" %","%")
- end if
- end if
- 'MATHS BEGIN--------------------------------
- 'If there are 2 operations
- if (operator2 isNot nothing)
- 'If there are 2 operations with 3 values
- if (operand3 isNot nothing)
- if ((operand1 isNot nothing) and (operand2 isNot nothing))
- result = GetResult(operator1,operand1,operand2)
- end if
- if (result isNot nothing)
- result = GetResult(operator2,result,operand3)
- end if
- 'Else if there are 2 operations with 2 values
- elseif (operand2 isNot nothing)
- 'Handle Square Root on Second Operand
- if ((operator1 = "sqr") and (operand1 isNot nothing))
- result = Math.Sqrt(operand1)
- else
- result = nothing
- end if
- if ((operator1 = "sqr") and (result isNot nothing))
- result = GetResult(operator2,result,operand2)
- else
- if ((result isNot nothing) and (operand1 isNot nothing))
- result = GetResult(operator1,operand1,result)
- elseif (operand1 isNot nothing)
- result = GetResult(operator2,operand1,operand2)
- end if
- end if
- end if
- 'Else if there is 1 operations with up to 2 values
- elseif (operator1 isNot nothing)
- if ((operand1 isNot nothing) and (operand2 isNot nothing))
- result = GetResult(operator1,operand1,operand2)
- if ((operatorText1 = "cubed") or (operatorText1 = "squared"))
- equationText = equationText.Replace(" " + operand2.ToString() + " "," ")
- end if
- elseif ((operand1 isNot nothing) and (not(DoubleOpsList.Contains(operator1))))
- result = GetResult(operator1,operand1)
- equationText = equationText.Replace(operand1.ToString() + " ","") + operand1.ToString() + " "
- end if
- end if
- else
- 'Else this is a Unit Conversion with 1 value
- if (operator1 isNot nothing)
- if (operand1 isNot nothing)
- result = GetConversion(operator1,operand1)
- equationText = operand1.ToString() + " " + operatorText1 + " = "
- end if
- else
- VA.WriteToLog("AVCS Calculation Error on Null Operator 1", "red")
- end if
- end if
- 'Evaluate Result ======
- if (result isNot nothing)
- try
- 'Try to compare decimal with integer version of itself to discover decimal places, then round
- dim checkResult as Int32 = Convert.ToInt32(result)
- if (result = checkResult)
- 'For TTS brevity use the one that couldn't end with .000
- result = checkResult
- elseif (checkResult <> result)
- dim roundResult as Double = result
- result = Math.Round(roundResult, decimalPlaces)
- end if
- catch
- 'Result is a whole number already, does not need rounding for TTS brevity
- end try
- 'Correct Pi in equation text string to 2 decimal places for TTS brevity
- if(equationText.Contains(Math.Pi.ToString()))
- equationText = equationText.Replace(Math.Pi.ToString(), "3.14")
- end if
- 'Get Current History Count and/or Increment
- if((VA.GetInt("AVCS_CALC_CountOperations")) isNot nothing)
- countHistory = VA.GetInt("AVCS_CALC_CountOperations")
- countHistory += 1
- if (countHistory > 99)
- countHistory = 1
- end if
- end if
- VA.SetInt("AVCS_CALC_CountOperations", countHistory)
- 'Save to Calc History & Display Last complete equation with result in Event Log
- if (OpsList.Contains(operator1))
- VA.SetText("AVCS_CALC_LastOperation", equationText + "= " + result.ToString())
- VA.SetText("AVCS_CALC_LastOperation_" + countHistory.ToString(), equationText + "= " + result.ToString())
- VA.WriteToLog("Value " + countHistory.ToString() + " = " + equationText + "= " + result.ToString(), "green")
- else
- VA.SetText("AVCS_CALC_LastOperation", equationText + result.ToString() + " " + operatorText2)
- VA.SetText("AVCS_CALC_LastOperation_" + countHistory.ToString(), equationText + result.ToString() + " " + operatorText2)
- VA.WriteToLog("Value " + countHistory.ToString() + " = " + equationText + result.ToString() + " " + operatorText2, "green")
- end if
- 'Save to Memory, Set Last for "that" reference, and Return Result for TTS
- VA.SetDecimal("value" + countHistory.ToString(), result)
- VA.SetDecimal("AVCS_CALC_LastResult", result)
- VA.SetText("avcs_calc_return", result.ToString())
- end if
- end if
- End Sub
- End Class
Add Comment
Please, Sign In to add comment