Jump to content
Sign in to follow this  
TheAutomator

My rpn calculator can't compute negative numbers...

Recommended Posts

TheAutomator

hi everyone!

I need some help with my rpn calculator.

I first translated it from vbscript to autoitscript and that's when i stumbled on problem one:

(46) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

$Stack[ubound($Stack)] = $Item

^ ERROR

After that (and i know this from testing it as a vbscript) it can't work with negative numbers:

"1 - - 2" to Reverse Polish notation = "1 - 2 -" gives me the build in error...

 

Can you guy's help me with my code pleas?

Func Print($what,$er = 0)
        $t = ''
        if $err <> 0 then $t = 'ERROR!'
    MsgBox($er,$st,$what)
EndFunc

Func RPN($Tokenarray)
    Local $Stack = []
    Local $Result
    Local $Operator_B
    Local $Operator_A

    For $Token = 0 To Ubound($Tokenarray)
        If Isoperator($Tokenarray[$Token]) Then
            $Operator_B = Pop($Stack)
            $Operator_A = Pop($Stack)
            If $Operator_A = "" Then
                Print("The user has not input sufficient values in the expression.",16)
                exit
            EndIf
            Switch $Tokenarray[$Token]
                Case "+"
                    $Result = Number($Operator_A,3) + Number($Operator_B,3)
                Case "-"
                    $Result = Number($Operator_A,3) - Number($Operator_B,3)
                Case "*"
                    $Result = Number($Operator_A,3) * Number($Operator_B,3)
                Case "/"
                    $Result = Number($Operator_A,3) / Number($Operator_B,3)
                Case "^"
                    $Result = Number($Operator_A,3) ^ Number($Operator_B,3)
            EndSwitch
            Push($Result,$Stack)
        Else
            Push($Tokenarray[$Token],$Stack)
        EndIf
    Next
    If Ubound($Stack) > 1 Then
        Print("The user input has too many values.",16)
        Exit
    EndIf
    Return pop($Stack)
EndFunc

Func Push($Item, Byref $Stack)
    If Ubound($Stack) > -1 Then
        Redim $Stack[Ubound($Stack) + 1]
        $Stack[Ubound($Stack)] = $Item
    Else
        Local $Stack = [$Item]
    EndIf
EndFunc

Func Pop($Stack)
    $pop = ""
    If Ubound($Stack) > -1 Then
        $Pop = $Stack[Ubound($Stack)]
        Redim $Stack[Ubound($Stack) - 1]
    EndIf
    Return $pop
EndFunc

Func Peek($Stack)
    $peek = ""
    If Ubound($Stack) > -1 Then
        $Peek = $Stack(Ubound($Stack))
    EndIf
    Return $peek
EndFunc

Func Isoperator($Operator)
    Return StringInstr("+-*/^&<=>", $Operator) <> 0 And StringLen($Operator) = 1
EndFunc

Func Precedence($Operator)
    If Isoperator($Operator) Then
        Switch $Operator
            case "^"
                Return 4
            case "*","/"
                Return 3
            case "+","-"
                Return 2
            case "&"
                Return 1
            case "<","=",">"
                Return 0
        EndSwitch
    EndIf
EndFunc

;##################################################################################################

; (4 - -5) = (4|-|-|5) = (4|-|5|-)
;  input      tokens        rpn
Global $calculate_this = ["4","-","5","-"]

Print(rpn($calculate_this))

thanks in advance :) ,

TheAutomator

Edited by TheAutomator

Share this post


Link to post
Share on other sites
JohnOne

Without reading the code I'd say 

$Stack[ubound($Stack)] = $Item

should be

$Stack[ubound($Stack) -1 ] = $Item

Which is the highest index of the array.

EDIT:

Also, I can tell you that

If Ubound($Stack) > -1 Then will always be true, assuming it is actually an array.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
TheAutomator

Without reading the code I'd say 

$Stack[ubound($Stack)] = $Item

should be

$Stack[ubound($Stack) -1 ] = $Item

Which is the highest index of the array.

EDIT:

Also, I can tell you that

If Ubound($Stack) > -1 Then will always be true, assuming it is actually an array.

 

but aren't array's 0 based if you declare them that way?  :huh:

Share this post


Link to post
Share on other sites
TheAutomator

Local $Stack[10]

UBound($Stack) equals 10, but the highest element is [9] including [0]

 

got it, thanks JohnOne!

problem one: Solved ;)

Func Print($what,$er = 0)
    MsgBox($er,'',$what)
EndFunc

Func RPN($Tokenarray)
    Local $Stack = []
    Local $Result
    Local $Operator_B
    Local $Operator_A

    For $Token = 0 To Ubound($Tokenarray) - 1
        If Isoperator($Tokenarray[$Token]) Then
            $Operator_B = Pop($Stack)
            $Operator_A = Pop($Stack)
            If $Operator_A = "" Then
                Print("The user has not input sufficient values in the expression.",16)
                exit
            EndIf
            Switch $Tokenarray[$Token]
                Case "+"
                    $Result = Number($Operator_A,3) + Number($Operator_B,3)
                Case "-"
                    $Result = Number($Operator_A,3) - Number($Operator_B,3)
                Case "*"
                    $Result = Number($Operator_A,3) * Number($Operator_B,3)
                Case "/"
                    $Result = Number($Operator_A,3) / Number($Operator_B,3)
                Case "^"
                    $Result = Number($Operator_A,3) ^ Number($Operator_B,3)
            EndSwitch
            Push($Result,$Stack)
        Else
            Push($Tokenarray[$Token],$Stack)
        EndIf
    Next
    If Ubound($Stack) - 1 > 1 Then
        Print("The user input has too many values.",16)
        Exit
    EndIf
    Return pop($Stack)
EndFunc

Func Push($Item, Byref $Stack)
    If Ubound($Stack) > -1 Then
        Redim $Stack[Ubound($Stack) + 1]
        $Stack[Ubound($Stack) - 1] = $Item
    Else
        Local $Stack = [$Item]
    EndIf
EndFunc

Func Pop($Stack)
    $pop = ""
    If Ubound($Stack) > -1 Then
        $Pop = $Stack[Ubound($Stack) - 1]
        Redim $Stack[Ubound($Stack) - 2]
    EndIf
    Return $pop
EndFunc

Func Peek($Stack)
    $peek = ""
    If Ubound($Stack) > -1 Then
        $Peek = $Stack[Ubound($Stack) - 1]
    EndIf
    Return $peek
EndFunc

Func Isoperator($Operator)
    Return StringInstr("+-*/^&<=>", $Operator) <> 0 And StringLen($Operator) = 1
EndFunc

Func Precedence($Operator)
    If Isoperator($Operator) Then
        Switch $Operator
            case "^"
                Return 4
            case "*","/"
                Return 3
            case "+","-"
                Return 2
            case "&"
                Return 1
            case "<","=",">"
                Return 0
        EndSwitch
    EndIf
EndFunc

;##################################################################################################

; (4 - -5) = (4|-|-|5) = (4|-|5|-)
;  input      tokens        rpn
Global $calculate_this = ["4","-","5","-"]

Print(rpn($calculate_this))

the negative number evaluation problem is still a big problem..

Share this post


Link to post
Share on other sites
TheAutomator

Explain it.

the second problem?

well, in reverse polish notation 1|-|-|1 becomes 1|-|1|-

but my version of the rpn calculator can only deal with the '-' operator and does not know what to do with the second '-' (unary operator)..

hope I made my question more clear now :)

Edited by TheAutomator

Share this post


Link to post
Share on other sites
jchd

Aren't you confusing two distinct operations? Substraction (dyadic) and sign_change (monadic).


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
TheAutomator

Aren't you confusing two distinct operations? Substraction (dyadic) and sign_change (monadic).

 

Yes, that's the problem.

I'm searching for a simple way to make the calculator function know which one is the subtraction operator and how to deal with

the rest of the negation signs..  :think:

Share this post


Link to post
Share on other sites
jchd

Differentiate between the regular sub - and some symbol evocating sign change, for instance ±


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
czardas

I assume the unary (sign change) operator will either be the first instruction or else it will always be directly preceeded by another operator. If this is true, then you can test the type of operator using this rule. I don't know if I am correct - it's just a thought.

Edited by czardas

Share this post


Link to post
Share on other sites
UEZ

This example seems to work also for negative numbers:

 

Global $__iStackElement = 0
Global $oErrorHandler = ObjEvent("AutoIt.Error", "__Catch_COM_Errors")

ConsoleWrite(ReversePolishNotation("- * / 15 - 7 + 1 1 3 + 2 + 1 1") & @CRLF)
ConsoleWrite(ReversePolishNotation("/ 12 3") & @CRLF)
ConsoleWrite(ReversePolishNotation("/ 12 3-") & @CRLF)
ConsoleWrite(ReversePolishNotation("+ 1.25 2.25") & @CRLF)


Func ReversePolishNotation($sPolishNotation) ;coded by UEZ build 2014-09-07
    If StringRegExp($sPolishNotation, "[^\d+|^\-|^\+|^\*|^\^|^\/|^\s|\.]", 0) Then Return SetError(1, 0, "") ;simple error handling only
    Local $oStack = Stack_Init()
    Local $aTokens = StringSplit($sPolishNotation, " ", 2)
    If @error Then Return SetError(2, 0, "")
    Local $sToken, $sOperand1, $sOperand2
    For $sToken = UBound($aTokens) - 1 To 0 Step -1
        Switch $aTokens[$sToken]
            Case "+", "-", "/", "*", "^"
                $sOperand1 = Stack_Pop($oStack)
                If StringRight($sOperand1, 1) = "-" Then $sOperand1 = StringRegExpReplace($sOperand1, "(.+)-", "-$1")
                $sOperand2 = Stack_Pop($oStack)
                If StringRight($sOperand2, 1) = "-" Then $sOperand2 = StringRegExpReplace($sOperand2, "(.+)-", "-$1")
                Stack_Push(Execute($sOperand1 & $aTokens[$sToken] & $sOperand2), $oStack)
            Case Else
                Stack_Push($aTokens[$sToken], $oStack)
        EndSwitch
    Next
    Return Stack_Peek($oStack)
EndFunc   ;==>ReversePolishNotation

#Region Stack UDF
;stack (LIFO) implementation using ActiveXObject "Scripting.Dictionary" -> http://msdn.microsoft.com/en-us/library/x4k5wbx4(v=vs.84).aspx
;coded by UEZ (proof of concept version)
;~ #include-once

;function list:
;Stack_Clear
;Stack_Count
;Stack_Init
;Stack_IsEmpty
;Stack_Peek
;Stack_Pop
;Stack_PrintToConsole
;Stack_Push
;Stack_ToArray

;~ Global $__iStackElement = 0
;~ Global $oErrorHandler = ObjEvent("AutoIt.Error", "__Catch_COM_Errors")

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Push
; Description ...: adds an element onto the stack
; Syntax ........: Stack_Push($element, $obj)
; Parameters ....: $element             - any kind of an element
;                  $obj                 - must be the an object returned by Stack_Init()
; Return values .: True
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......:
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Push($element, $obj)
    $obj.Add($__iStackElement, $element)
    $__iStackElement += 1
    Return True
EndFunc   ;==>Stack_Push

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Pop
; Description ...: returns the topmost element and removes it from the stack
; Syntax ........: Stack_Pop($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: topmost element from the stack
;                  on error false and sets error to 1
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......: if stack is empty then error will be set to 1 and 0 returned
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Pop($obj)
    If Not $__iStackElement Then Return SetError(1, 0, False)
    Local $return = $obj.Item($__iStackElement - 1)
    $obj.Remove($__iStackElement - 1)
    $__iStackElement -= 1
    Return $return
EndFunc   ;==>Stack_Pop

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Peek
; Description ...: returns the topmost element without removing it from the stack
; Syntax ........: Stack_Peek($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: topmost element from the stack
;                  on error false and sets error to 1
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......: if stack is empty then error will be set to 1 and 0 returned
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Peek($obj)
    If Not $__iStackElement Then Return SetError(1, 0, False)
    Return $obj.Item($__iStackElement - 1)
EndFunc   ;==>Stack_Peek

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_PrintToConsole
; Description ...: prints all stack elements to the console
; Syntax ........: Stack_PrintToConsole($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: True
;                  on error false and sets error to 1
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......: if stack is empty then error will be set to 1 and 0 returned
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_PrintToConsole($obj)
    If Not $__iStackElement Then Return SetError(1, 0, False)
    Local $i
    For $i = $__iStackElement - 1 To 0 Step -1
        ConsoleWrite($obj.Item($i) & @CRLF)
    Next
    Return True
EndFunc   ;==>Stack_PrintToConsole

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_ToArray
; Description ...: returns an array with all stack elements
; Syntax ........: Stack_ToArray($obj[, $bReverse = True])
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
;                  $bReverse            - [optional] a binary value. Default is True. If true topmost stack element is the 1st
;                                         entry in the array, if false then last element
; Return values .: array with all stack elements
;                  on error false and sets error to 1
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......: if stack is empty then error will be set to 1 and 0 returned
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_ToArray($obj, $bReverse = True)
    If Not $__iStackElement Then Return SetError(1, 0, False)
    Local $a = $obj.Items(), $j = UBound($a) - 1
    If Not $j Then Return $a
    If Not $bReverse Then Return $a
    Local $i, $aRevers[$j + 1]
    For $i = 0 To $j
        $aRevers[$i] = $a[$j - $i]
    Next
    Return $aRevers
EndFunc   ;==>Stack_ToArray

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Count
; Description ...: return the amount of stack elements
; Syntax ........: Stack_Count($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: the amount of stack elements (an integer value)
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......:
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Count($obj)
    Return $obj.Count()
EndFunc   ;==>Stack_Count

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_IsEmpty
; Description ...: checks whether stack is empty
; Syntax ........: Stack_IsEmpty($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: True, if stack is empty, otherwise false
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......:
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_IsEmpty($obj)
    Return $obj.Count() = 0
EndFunc   ;==>Stack_IsEmpty

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Clear
; Description ...: clears all stack elements
; Syntax ........: Stack_Clear($obj)
; Parameters ....: $obj                 - must be the an object returned by Stack_Init()
; Return values .: None
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......:
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Clear($obj)
    $obj.RemoveAll()
    $__iStackElement = 0
EndFunc   ;==>Stack_Clear

; #FUNCTION# ====================================================================================================================
; Name ..........: Stack_Init
; Description ...: initialize a stack object
; Syntax ........: Stack_Init()
; Parameters ....: None
; Return values .: an dictionary object
;                  on error false and sets error to 1
; Author ........: UEZ
; Version .......: 0.90 build 2014-04-14
; Remarks .......:
; Related .......: data types
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func Stack_Init()
    Local $oDictionary = ObjCreate('Scripting.Dictionary')
    If @error Then Return SetError(1, 0, False)
    Return $oDictionary
EndFunc   ;==>Stack_Init

;internal functions
Func __Catch_COM_Errors()
    ConsoleWrite( _
            "A COM error has occured!" & @CRLF & @CRLF & _
            "err.description is: " & @TAB & $oErrorHandler.description & @CRLF & _
            "err.windescription:" & @TAB & $oErrorHandler & @CRLF & _
            "err.number (hex) is: " & @TAB & Hex($oErrorHandler.number, 8) & @CRLF & _
            "err.lastdllerror is: " & @TAB & $oErrorHandler.lastdllerror & @CRLF & _
            "err.scriptline is: " & @TAB & $oErrorHandler.scriptline & @CRLF & _
            "err.source is: " & @TAB & $oErrorHandler.source & @CRLF & _
            "err.helpfile is: " & @TAB & $oErrorHandler.helpfile & @CRLF & _
            "err.helpcontext is: " & @TAB & $oErrorHandler.helpcontext & @CRLF _
            )
EndFunc   ;==>__Catch_COM_Errors
#EndRegion Stack UDF
Edit: added ^ operator.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
jchd

My take:

#include <Array.au3>

Func Print($what, $err = 0)
        $t = ''
        if $err <> 0 then $t = 'ERROR!'
    MsgBox($err, $t, $what)
EndFunc

Func Bye($iCause)
    Local Const $aReason = [ _
        "Invalid input.", _
        "The user has not input enough values in the expression.", _
        "The user has input too many values in the expression." _
    ]
    Print($aReason[$iCause], 16)
    Exit
EndFunc

Func RPN($aTokens)
    If UBound($aTokens) < 1 Then Bye(0)
    Local $iToken = 0
    While Ubound($aTokens) > 1 And $iToken < UBound($aTokens)
        If $aTokens[$iToken] = "±" Then        ; only one monadic operator
            $aTokens[$iToken - 1] = -$aTokens[$iToken - 1]
            _ArrayDelete($aTokens, $iToken)
            $iToken -= 1
        ElseIf StringInstr("+-*/^&<=>", $aTokens[$iToken]) Then
            If $iToken < 2 Then Bye(1)
            Switch $aTokens[$iToken]        ; process dyadic operators
                Case "+", "-", "*", "/", "^"
                    $aTokens[$iToken - 2] = Execute(Number($aTokens[$iToken - 2]) & $aTokens[$iToken] & Number($aTokens[$iToken - 1]))
                Case Else
                    Bye(2)
            EndSwitch
            _ArrayDelete($aTokens, $iToken)
            _ArrayDelete($aTokens, $iToken - 1)
            $iToken -= 2
        Else                                ; must be a value
            $iToken += 1
        EndIf
    WEnd
    Return $aTokens[0]
EndFunc


;~ Func Precedence($Operator)
;~     If Isoperator($Operator) Then
;~         Switch $Operator
;~             case "±"
;~                 Return 5
;~             case "^"
;~                 Return 4
;~             case "*","/"
;~                 Return 3
;~             case "+","-"
;~                 Return 2
;~             case "&"
;~                 Return 1
;~             case "<","=",">"
;~                 Return 0
;~         EndSwitch
;~     EndIf
;~ EndFunc

;##################################################################################################

; (4 - ±5) / 3.14 = 4|5|±|-|3.1415926|/
;      input              rpn
Global $calculate_this = [4, 5, "±", "-", 3.1415926, "/"]

Print(rpn($calculate_this))

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
TheAutomator
czardas,
no problem, thanks for the help :)
 
UEZ,
trying to figure out what you just did there,
 
  1. first you check what the token is,
  2. if it is a number:
  3.     you push it to the stack,
  4. if it is an operator:
  5.     Operand1 = first value
  6.         if the last char of Operand1 is a '-' then Operand1 = '-' & the value of Operand1 without the '-'
  7.     Operand2 = second value
  8.         if the last char of Operand2 is a '-' then Operand2 = '-' & the value of Operand2 without the '-'
  9.         (tell me if i'm wrong here, i'm a noob if it comes to regex..)
  10.     then let autoit evaluate(Operand1 & operator token & Operand2)
is this correct?
well, the shunting yard algorithm i made returns the tokens token by token, '3-' could never be a single token, to would rather be '3', '-'
 
jchd,
I never heard about this '±' operator before, i don't even know how to type it...
what i'm trying to find out is how to let my script know how to do '1 - -2'
so i don't want to use '±', want it to calculations based on a simple basic syntax with only '+','-','*','/' and '^'.
made a tokenization function that converts "1+2--3*5&"abc" to array["1","+","2","-","-","3","*","5","&",'"abc"'] and if
the current rpn calculator (after conversion to reverse polish notation) sees the extra minus it does not know what to do with it..
thanks for the help and your example, i didn't know you actually wanted to put that symbol into the algorithm.
Edited by TheAutomator

Share this post


Link to post
Share on other sites
jchd

That isn't going to work anyday, period.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • imitto
      By imitto
      Hello all!
      I use Autoit for a while, already made some automation for a TV station's master control room with it. I made a UDF to easily work with PAL timecode and time with milliseconds, convert, add or subtract them. Feel free to use it if you want something like this
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Description=PAL Timecode Calculator UDF #AutoIt3Wrapper_Res_LegalCopyright=horvath.imre@gmail.com #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ; #FUNCTION# ; Name...........: _tcAdd ; Description....: Returns addition of two timecodes ; Syntax.........: _tcAdd($fTc1, fTc2 [, $fFormat = "P"]) ; ; Parameters.....: $fTc1 - First timecode in hh:mm:ss.ff format ; $fTc2 - Second timecode in hh:mm:ss.ff format ; $fFormat - Time base - "P" (default): PAL (25 fps) ; "M" : millisecond ; ; Return value...: Sum of the two timecode in the selected format Func _tcAdd($fTc1, $fTc2, $fFormat = "P", $fHourFormat = 1) Local $fMs1 = _tcToMs($fTc1) Local $fMs2 = _tcToMs($fTc2) Local $fSumMs = $fMs1 + $fMs2 Return _msToTc($fSumMs, $fFormat, $fHourFormat) EndFunc ; #FUNCTION# ; Name...........: _tcsSub ; Description....: Returns addition of two timecodes ; Syntax.........: _tcSub($fTc1, fTc2 [, $fFormat = "P"]) ; ; Parameters.....: $fTc1 - First timecode in hh:mm:ss.ff format ; $fTc2 - Second timecode in hh:mm:ss.ff format ; $fFormat - Time base - "P" (default): PAL (25 fps) ; "M" : millisecond ; ; Return value...: Subtract $fTc2 from $fTc1 in the source format Func _tcSub($fTc1, $fTc2, $fFormat = "P") Local $fMs1 = _tcToMs($fTc1) Local $fMs2 = _tcToMs($fTc2) Local $fSumMs = $fMs1 - $fMs2 If $fSumMs < 0 Then $fSumMs = _tcToMs("24:00:00.00") - ($fSumMs * -1) EndIf Return _msToTc($fSumMs, $fFormat) EndFunc ; #FUNCTION# ; Name...........: _tcToMs ; Description....: Returns timecode converted to total milliseconds ; Syntax.........: _tcToMs($fTc) ; ; Parameters.....: $fTc - Timecode in hh:mm:ss.ff or hh:mm:ss:xxx format, where xxx are milliseconds ; ; Return value...: Milliseconds as an integer value Func _tcToMs($fTc) Local $fTemp = StringSplit($fTc, ":.") Local $fChr = StringLen($fTemp[4]) Switch $fChr Case 2 Return ($fTemp[4] * 40) + ($fTemp[3] * 1000) + ($fTemp[2] * 60000) + ($fTemp[1] * 3600000) Case 3 Return ($fTemp[4]) + ($fTemp[3] * 1000) + ($fTemp[2] * 60000) + ($fTemp[1] * 3600000) EndSwitch EndFunc ; #FUNCTION# ; Name...........: _msToTc ; Description....: Converts total milliseconds to timecode ; Syntax.........: _msToTc($fIn, $fFormat = "P", $fHourFormat = 1) ; ; Parameters.....: $fIn - Time in milliseconds ; $fFormat - Output format "P": PAL TC (default) ; "M": hh:mm:ss.xxx where xxx are milliseconds ; $fHourFormat - Hour format "1": max. value is 23, then starts from 0 (default) ; "0": hours can be more then 23 ; ; Return value...: Timecode as string in the selected format Func _msToTc($fIn, $fFormat = "P", $fHourFormat = 1) Switch $fFormat Case "P" Local $fFr = StringFormat("%02i", (StringRight($fIn, 3) - Mod(StringRight($fIn, 3), 40)) / 40) Case "M" Local $fFr = StringFormat("%03i", StringRight($fIn, 3)) EndSwitch $fIn = StringTrimRight($fIn, 3) Local $fSec = StringFormat("%02i", Mod($fIn, 60)) $fIn -= $fSec Local $fMinTot = $fIn / 60 Local $fMin = StringFormat("%02i", Mod($fMinTot, 60)) $fIn -= $fMin*60 Local $fHourTot = $fIn / 60 / 60 Switch $fHourFormat Case 1 $fHour = StringFormat("%02i", Mod($fHourTot, 24)) Case 0 $fHour = StringFormat("%02i", $fHourTot) EndSwitch Return($fHour & ":" & $fMin & ":" & $fSec & "." & $fFr) EndFunc ; #FUNCTION# ; Name...........: _tcFormatChange ; Description....: Toggle TC format ; Syntax.........: _tcFormatChange($fTc) ; ; Parameters.....: $fTc - Timecode in hh:mm:ss.ff or hh:mm:ss:xxx format, where xxx are milliseconds ; ; Return value...: PAL timecode or time with milliseconds as string, depends on input Func _tcFormatChange($fTc) Local $fTemp = StringSplit($fTc, ":.") Local $fChr = StringLen($fTemp[4]) Switch $fChr Case 2 Return $fTemp[1]&":"&$fTemp[2]&":"&$fTemp[3]&"."&StringFormat("%03i", $fTemp[4]*40) Case 3 Return $fTemp[1]&":"&$fTemp[2]&":"&$fTemp[3]&"."&StringFormat("%02i", ($fTemp[4]-Mod($fTemp[4], 40))/40) EndSwitch EndFunc And the example script:
      #include<_PAL_TC_Calc.au3> $palTC1 = "00:01:12.20" $palTC2 = "23:59:50.02" $msTC1 = "00:01:12.800" $msTC2 = "23:59:50.120" MsgBox(0, "1", _tcAdd($palTC1, $palTC2)); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns PAL TC format MsgBox(0, "2", _tcAdd($palTC1, $palTC2, "M")); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns time with milliseconds format MsgBox(0, "3", _tcAdd($palTC1, $palTC2, "M", 0)); Adds $palTC1 to $palTC2, hours can be infinite, returns time with milliseconds format MsgBox(0, "4", _tcAdd($msTC1, $msTC2)); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns PAL TC format MsgBox(0, "5", _tcAdd($msTC1, $msTC2, "M")); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns time with milliseconds format MsgBox(0, "6", _tcAdd($msTC1, $msTC2, "M", 0)); Adds $palTC1 to $palTC2, hours can be infinite, returns time with milliseconds format MsgBox(0, "7", _tcSub($palTC2, $palTC1)); Subtract $palTC1 from $palTC2, returns PAL TC format MsgBox(0, "8", _tcSub($palTC2, $palTC1, "M")); Subtract $palTC1 from $palTC2, time with milliseconds format MsgBox(0, "9", _tcSub($msTC1, $msTC2)); Subtract $palTC1 from $palTC2, returns PAL TC format - when hits zero, counts back from 24:00:00.00 MsgBox(0, "10", _tcSub($msTC1, $msTC2, "M")); Subtract $palTC1 from $palTC2, time with milliseconds format - when hits zero, counts back from 24:00:00.000 MsgBox(0, "11", _tcFormatChange($palTC2)); Convert PAL TC to time with milliseconds and back MsgBox(0, "12", _tcFormatChange($msTC2)); Convert PAL TC to time with milliseconds and back  
      TC_CALC_example.au3
      _PAL_TC_Calc.au3
    • nacerbaaziz
      By nacerbaaziz
      Hi dears
      How are you?
      I have a question, to you please.
      How do I create an edit box for numbers only and does not accept letters? using autoit
      greetings to all
      I hope you help ME
      Thanks to all in advance
    • Simpel
      By Simpel
      Hi,
      I wondered why negative integers I wrote into registry (e.g. negative x-coordinates of a gui if using two monitors and the right one is the main one) wouldn't return right when reading. Now I know: it is saved as an unsigned integer (without algebraic sign). So here is a snippet that is changing unsigned to signed integer:
      Global Const $g_sRegKey = "HKEY_CURRENT_USER\Software\" & @ScriptName ; path to registry RegWrite($g_sRegKey, "Value", "REG_DWORD", -2147483647) ; write some negative integer into registry; -2147483647 highest possible negative integer , 2147483648 highest possible positive integer if talking of 32bit Local $sValue = RegRead($g_sRegKey, "Value") ; read out registry ConsoleWrite("Value: " & $sValue & @CRLF) ; show real value in console Local $sResult = _SignedInteger($sValue) ; change to signed value ConsoleWrite("Result: " & $sResult & @CRLF) ; and show it in console Func _SignedInteger($iUnsignedInteger) Local $iSignedInteger If $iUnsignedInteger > (2^31) Then ; then it means a negative integer $iSignedInteger = $iUnsignedInteger - (2^32) Else $iSignedInteger = $iUnsignedInteger EndIf Return $iSignedInteger EndFunc It took me some time to find out the problem and so I hope I can help somebody with this.
      Regards, Conrad
    • UritOR
      By UritOR
      Hi all,
      How do I allow an input control (GUICtrlCreateInput) to get only digits and dots?
      $ES_NUMBER - allows only digits, but I need to be able to type something like this only:   2.15.1598.1
      Can you help me please? 
    • coffeeturtle
      By coffeeturtle
      Hello. I need to perform a specific string replace, but not sure how to go about it.
      The scenario is this: I have a large block of text. Within the text colons appear ":",  Sometimes the colons are used in a sentence appearing after a word. Other times they appear in between numbers like a ratio or a sport score (e.g. "6:8").
      I want to replace the colons appearing between numeric values like 6:8 with the word "to", but not the ones appearing at the end of a sentence.
      Is there a way that I can have StringReplace (or any other method) differentiate when to replace the colon based on it appearing between numbers?
      I did try searching for a similar scenario.
      Thank you for any help. 
×