Solved:Need simple example,real time calculating and output the result

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
vsub
Posts: 541
Joined: 29 Sep 2015, 03:39

Solved:Need simple example,real time calculating and output the result

05 Jun 2019, 12:46

How can I do this.
Lets say I have two controls
Edit1 contains the numbers and symbols I input
Edit2 will contains the answer

While typing in Edit1,to show the answer in Edit2
For example
I type 1 => and Edit2 shows 1
I type 1+1 => and edit2 shows 2 not 1+1
In real time,not by requiring Enter or something to execute the calculation

I am trying to make a simple calculator that support hex and dec values...something better than the windows calculator
Something like this and show the answer in hex and dex
0.2*(1-(30/0x220))
Last edited by vsub on 06 Jun 2019, 11:36, edited 1 time in total.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Need simple example,real time calculating and output the result

05 Jun 2019, 14:26

This does the first thing.
vsub wrote:
05 Jun 2019, 12:46
I type 1 => and Edit2 shows 1
I type 1+1 => and edit2 shows 2 not 1+1
In real time,not by requiring Enter or something to execute the calculation

Code: Select all

#SingleInstance,Force

Gui,+AlwaysOnTop
Gui,Add,Edit,xm ym w100 r1 vIn1 gSum,
Gui,Add,Edit,x+20 w100 r1 vOut,
Gui,Show, h100
return
GuiClose:
GuiContextMenu:
*Esc::
	ExitApp

Sum(){
	GuiControlGet,In1
	Arr:=StrSplit(In1,A_Space)
	if(Arr.Length()>=3)
		(Arr[2]="+")?(Sum1:=Arr[1] + Arr[3]):(Arr[2]="-")?(Sum1:=Arr[1] - Arr[3]):(Arr[2]="**")?(Sum1:=Arr[1] ** Arr[3]):(Arr[2]="/")?(Sum1:=Arr[1] / Arr[3]):(Arr[2]="*")?(Sum1:=Arr[1] * Arr[3]):(Arr[2]="//")?(Sum1:=Arr[1]//Arr[3])
	if(Arr.Length()>=5)
		(Arr[4]="+")?(Sum2:=Sum1+Arr[5]):(Arr[4]="-")?(Sum2:=Sum1-Arr[5]):(Arr[4]="*")?(Sum2:=Sum1*Arr[5]):(Arr[4]="/")?(Sum2:=Sum1/Arr[5]):(Arr[4]="**")?(Sum2:=Sum1**Arr[5]):(Arr[4]="//")?(Sum2:=Sum1//Arr[5])
	GuiControl,1:,Out,% (Sum2)?(Sum2):(Sum1)?(Sum1):(Arr[1])
}

be sure to add spaces

***Edit fixed syntax error and gui size
Last edited by Hellbent on 05 Jun 2019, 14:58, edited 1 time in total.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Need simple example,real time calculating and output the result

05 Jun 2019, 14:56

Try this: Eval()

Code: Select all

#NoEnv
#SingleInstance Force


    Gui, Add, Edit, w200 vInput gInput_onTyping
    Gui, Add, Edit, wp vResult
    Gui, Show

return ; end of auto-execute section

Input_onTyping:
    GuiControlGet, Input
    GuiControl,, Result, % Eval(Input)

return

F1:: GuiControl,, Input, 0.2*(1-(30/0x220))



;-------------------------------------------------------------------------------
Eval(Exp) { ; using Javascript/COM
;-------------------------------------------------------------------------------
    static Constants := "E|LN2|LN10|LOG2E|LOG10E|PI|SQRT1_2|SQRT2"
    static Functions := "abs|acos|asin|atan|atan2|ceil|cos|exp|floor"
                     .  "|log|max|min|pow|random|round|sin|sqrt|tan"

    Transform, Exp, Deref, %Exp% ; support variables

    Exp := Format("{:L}", Exp) ; everything lowercase
    Exp := RegExReplace(Exp, "i)(" Constants ")", "$U1") ; constants uppercase
    Exp := RegExReplace(Exp, "i)(" Constants "|" Functions ")", "Math.$1")
    Exp := StrReplace(Exp, "Math.ceil", "Math.ceil")
    Exp := StrReplace(Exp, "Math.exp", "Math.exp")

    Obj := ComObjCreate("HTMLfile")
    Obj.Write("<body><script>document.body.innerText=eval('" Exp "');</script>")
    return, InStr(Result := Obj.body.innerText, "body") ? "ERROR" : Result
}
I hope that helps.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Need simple example,real time calculating and output the result

05 Jun 2019, 15:04

wolf_II wrote:
05 Jun 2019, 14:56
Try this:
Doesn't seem to do anything.
garry
Posts: 3760
Joined: 22 Dec 2013, 12:50

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 05:58

script from wolf_II works > it calculates e.g. 3*5/2
Rohwedder
Posts: 7616
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 06:40

Hallo,
only added hex integer result line.

Code: Select all

#NoEnv
#SingleInstance Force
Gui, Add, Edit, w200 vInput gInput_onTyping
Gui, Add, Edit, wp vResult
Gui, Add, Edit, wp vHResult
Gui, Show
return ; end of auto-execute section
Input_onTyping:
GuiControlGet, Input
GuiControl,, Result, % Result := Eval(Input)
Minus := Result < 0 ? "-":""
StringSplit, Hex,% Result, ., -
Hex2 := SubStr(Format("{:A}","1." Hex2),4)
Hex2 := SubStr(Hex2,1,(Hex2 ~= "0*P")-1)
GuiControl,, HResult, % Minus Format("0x{:X}", Hex1) Hex2
return
F1:: GuiControl,, Input, 0.2*(1-(30/0x220))
;-------------------------------------------------------------------------------
Eval(Exp)
{ ; using Javascript/COM
	;-------------------------------------------------------------------------------
	static Constants := "E|LN2|LN10|LOG2E|LOG10E|PI|SQRT1_2|SQRT2"
	static Functions := "abs|acos|asin|atan|atan2|ceil|cos|exp|floor"
	.  "|log|max|min|pow|random|round|sin|sqrt|tan"
	Transform, Exp, Deref, %Exp% ; support variables
	Exp := Format("{:L}", Exp) ; everything lowercase
	Exp := RegExReplace(Exp, "i)(" Constants ")", "$U1") ; constants uppercase
	Exp := RegExReplace(Exp, "i)(" Constants "|" Functions ")", "Math.$1")
	Exp := StrReplace(Exp, "Math.ceil", "Math.ceil")
	Exp := StrReplace(Exp, "Math.exp", "Math.exp")
	Obj := ComObjCreate("HTMLfile")
	Obj.Write("<body><script>document.body.innerText=eval('" Exp "');</script>")
	return, InStr(Result := Obj.body.innerText, "body") ? "ERROR" : Result
}
Last edited by Rohwedder on 06 Jun 2019, 10:51, edited 2 times in total.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 07:51

garry wrote:
06 Jun 2019, 05:58
script from wolf_II works > it calculates e.g. 3*5/2
Doesn't do anything for me.
SnapShot_498.png
SnapShot_498.png (4.43 KiB) Viewed 4640 times
vsub
Posts: 541
Joined: 29 Sep 2015, 03:39

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 10:27

Looks little advanced,I don't know from where to even start to understand why this works but all of the code posted here works and I will probably do the rest myself(the other features),thanks(not sure which post to mark as solved because they all do what I want)

I thought it will be something simple because just running a msgbox with this
Msgbox,% 0.2*(1-(30/0x220))
and I get the answer.
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 10:55

To give a basic rundown of the function this is how it works.
static Constants and static Functions are what we have as replacements specifically for the input (basic math like your example don't use it so this is more for using tan and sin functions).
The transform function you can find here https://www.autohotkey.com/docs/commands/Transform.htm but it just "Expands variable references and escape sequences contained inside other variables."
Format forces everything lowercase (javascript specific), then the RegExReplace and StrReplace are using the list of Constants and functions to replace them with Math.constant or Math.function as this is how javascript calls those functions like tan and sin.
ComObjectCreate is creating an html file that we place the eval statement for javascript inside (so each time it is ran a new file is created with the new eval) which returns a value of ERROR (if the value isn't valid) or the answer.
Finally we push the answer back out of the function and return it to the control.

But simply it just takes the input and produces an output from the javascript eval function (and places Math. if functions or constants exist).

Edit: This is based off wolf_II script.
Last edited by MannyKSoSo on 06 Jun 2019, 10:57, edited 1 time in total.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 10:56

There is a different Eval():

Code: Select all

#NoEnv
#SingleInstance Force

    Gui, Add, Edit, w200 vInput gInput_onTyping
    Gui, Add, Edit, wp vResult
    Gui, Show

return ; end of auto-execute section



;-------------------------------------------------------------------------------
Input_onTyping: ;
;-------------------------------------------------------------------------------
    GuiControlGet, Input
    GuiControl,, Result, % Eval(Input)

return



;-------------------------------------------------------------------------------
Eval(x) { ; by Laszlo
;-------------------------------------------------------------------------------
    StringGetPos, i, x, +, R
    StringGetPos, j, x, -, R
    if (i > j)
        return Left(x, i) + Right(x, i)
    if (j > i)
        return Left(x, j) - Right(x, j)

    StringGetPos, i, x, *, R
    StringGetPos, j, x, /, R
    if (i > j)
        return Left(x, i) * Right(x, i)
    if (j > i)
        return Left(x, j) / Right(x, j)

    return x
}



;-------------------------------------------------------------------------------
Left(x, i) {
;-------------------------------------------------------------------------------
    StringLeft, x, x, i
    return, Eval(x)
}



;-------------------------------------------------------------------------------
Right(x,i) {
;-------------------------------------------------------------------------------
    StringTrimLeft, x, x, i + 1
    return, Eval(x)
}
Maybe that suits you more.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 11:02

There is a different Eval():

Code: Select all

#NoEnv
#SingleInstance Force

    Gui, Add, Edit, w200 vInput gInput_onTyping
    Gui, Add, Edit, wp vResult
    Gui, Show

return ; end of auto-execute section



;-------------------------------------------------------------------------------
Input_onTyping: ;
;-------------------------------------------------------------------------------
    GuiControlGet, Input
    GuiControl,, Result, % Eval(Input)

return



;---------------------------------------------------------------------------
Eval(Expr) { ; evaluate expression using separate AHK process
;---------------------------------------------------------------------------
    static File := "24$Temp.ahk"

    ; delete old temporary file, and write new
    FileDelete, %File%
    FileContent := "#NoTrayIcon`r`n"
                .  "FileDelete, " File "`r`n"
                .  "FileAppend, `% " Expr ", " File "`r`n"
    FileAppend, %FileContent%, %File%

    ; run AHK to execute temp script, evaluate expression
    RunWait, %A_AhkPath% %File%

    ; get result
    FileRead, Result, %File%
    FileDelete, %File%
    Return, Result
}
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Need simple example,real time calculating and output the result

06 Jun 2019, 11:06

There is a different Eval():

Code: Select all

#NoEnv
#SingleInstance Force

    Gui, Add, Edit, w200 vInput gInput_onTyping
    Gui, Add, Edit, wp vResult
    Gui, Show

return ; end of auto-execute section



;-------------------------------------------------------------------------------
Input_onTyping: ;
;-------------------------------------------------------------------------------
    GuiControlGet, Input
    GuiControl,, Result, % Eval(Input)

return



; https://autohotkey.com/board/topic/4779-simple-script-for-evaluating-arithmetic-expressions/page-3

;-------------------------------------------------------------------------------
Eval(__) {                               ; expression preprocessing
;-------------------------------------------------------------------------------
    ; Arithmetic expressions evaluator, handling
    ; unary +,- (-2*3; +3)
    ; +,-,*,/,\(or % = mod); **(or @ = power)
    ; (..); constants (pi,e); Global variables (not starting with '_'); abs(),sqrt(),floor()

   Static pi = 3.141592653589793, e = 2.718281828459045

   StringReplace __, __,`%, \, All       ; % -> \ for MOD
   __ := RegExReplace(__,"\s*")          ; remove whitespace
   __ := RegExReplace(__,"([a-zA-Z]\w*)([^\w\(]|$)","%$1%$2") ; var -> %var%
   Transform __, Deref, %__%             ; dereference all %var%

   StringReplace __, __, -, #, All       ; # = subtraction
   StringReplace __, __, (#, (0#, All    ; (-x -> (0-x
   If (Asc(__) = Asc("#"))
      __ = 0%__%                         ; leading -x -> 0-x
   StringReplace __, __, (+, (, All      ; (+x -> (x
   If (Asc(__) = Asc("+"))
      StringTrimLeft __, __, 1           ; leading +x -> x
   StringReplace __, __, **, @, All      ; ** -> @ for easier process

   Loop {                                ; find innermost (..)
      If !RegExMatch(__, "(.*)\(([^\(\)]*)\)(.*)", _)
         Break
      __ := _1 . Eval@(_2) . _3          ; replace "(x)" with value of x
   }
   Return Eval@(__)                      ; no more (..)
}

Eval@(__) {
   RegExMatch(__, "(.*)(\+|\#)(.*)", _)  ; execute rightmost +- operator
   IfEqual _2,+,  Return Eval@(_1) + Eval@(_3)
   IfEqual _2,#,  Return Eval@(_1) - Eval@(_3)
                                        ; execute rightmost */% operator
   RegExMatch(__, "(.*)(\*|\/|\\)(.*)", _)
   IfEqual _2,*,  Return Eval@(_1) * Eval@(_3)
   IfEqual _2,/,  Return Eval@(_1) / Eval@(_3)
   IfEqual _2,\,  Return Mod(Eval@(_1),Eval@(_3))
                                        ; execute rightmost power
   StringGetPos ___, __, @, R
   IfGreaterOrEqual ___,0, Return Eval@(SubStr(__,1,___)) ** Eval@(SubStr(__,2+___))
                                        ; execute rightmost function
   If !RegExMatch(__,".*(abs|floor|sqrt)(.*)", _)
      Return __                         ; no more function
   IfEqual _1,abs,  Return abs(  Eval@(_2))
   IfEqual _1,floor,Return floor(Eval@(_2))
   IfEqual _1,sqrt, Return sqrt( Eval@(_2))
}
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Solved:Need simple example,real time calculating and output the result

06 Jun 2019, 16:14

I realize the topic is solved, but I want to share one more:

This is a hotkey (F12), which will use a (not shown) ActiveX to call an Eval() function.
Output is via MsgBox, Input is via "manual highlight an expression" in a editor or a browser,
The code will use Clipboard to read what is highlighted, evaluate the expression and output via MsgBox.

Code: Select all

Gui, Add, ActiveX, vWB, <!DOCTYPE html>
WB.Silent := True
F12:: MsgBox, % WB.Document.ParentWindow.Eval(get_Highlight())



;-------------------------------------------------------------------------------
get_Highlight() { ; get highlighted text
;-------------------------------------------------------------------------------
    Clipboard := ""                     ; empty clipboard
    SendInput, ^c                       ; copy highlighted text
    ClipWait, .1                        ; wait for change
    return Clipboard
}
Maybe this is also of interest/help to you.
vsub
Posts: 541
Joined: 29 Sep 2015, 03:39

Re: Solved:Need simple example,real time calculating and output the result

10 Jun 2019, 12:28

I endup using the ComObjCreate example but I have a problem
How can I make ahk work with percentage

Percentage is just doing result / 100 * the percentage but adding the percentage symbol in this example

100/20% => it must be 20 not 4

I tried making a copy of the current calculation when one of those appear /*-+ and then if a % appear,from the variable that contains all get the last digit I input and then use the result from the first part then / 100 * the value I inserted after the last /*-+(one of those)but I am getting more and more problems and if feels like I am making it way more complicated
garry
Posts: 3760
Joined: 22 Dec 2013, 12:50

Re: Solved:Need simple example,real time calculating and output the result

10 Jun 2019, 13:50

type
100*20/100 ;- get 20
or

Code: Select all

setformat,float,0.2
a:=100
b:=20   ;- procent
c:=(a*b)/100
msgbox,%c%
vsub
Posts: 541
Joined: 29 Sep 2015, 03:39

Re: Solved:Need simple example,real time calculating and output the result

10 Jun 2019, 14:22

The problem is not the formula but the how to tell the script that when I use % after a number I mean "get the input from before the last "/*-+" and then use that formula

For example
((5+15)*4)/20%
Is there is some regexp(I don't understand them very well)that searches for the last symbol in the input variable
Is there is a way to search in backward

Isn't this making it way too complicated and why am I not getting anything

Var := "((5+15)*4)/20%"
Len := StrLen(Var)
Loop,Parse,Var
{
If A_LoopField in /,*,-,+
Found := A_Index
}
Len := SubStr(Var,1,Found-1)
Type := SubStr(Var,Found,1)
Perc := SubStr(Var,Found+1,-1)
Answer := (Len / 100) * Perc
msgBox,% Answer
exitapp
User avatar
YoucefHam
Posts: 372
Joined: 24 Aug 2015, 12:56
Location: Algeria
Contact:

Re: Solved:Need simple example,real time calculating and output the result

10 Jun 2019, 16:28

try this

Code: Select all

Var := "((5+15)*4)/20%+30%"

MsgBox, % CalcPercente(Var)
ExitApp

CalcPercente(Var)
{
    Loop
    {
        IfNotInString, Var, % "%"
            break
        if RegExMatch(Var, "([0-9]*)%",per%A_Index%)
            Var := StrReplace(Var, per%A_Index%1 "%", per%A_Index%1 / 100)
    }
    return var
}
:wave: There is always more than one way to solve a problem. ;)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Solved:Need simple example,real time calculating and output the result

11 Jun 2019, 02:27

Thanks, YoucefHam for the code. This is a very good example how to handle unary operators. (or whatever it is, but I think that's right)
I trimmed the code a bit:

Code: Select all

MsgBox, % calc_Percent( "123%" )
MsgBox, % calc_Percent( "((5+15)*4)/20%+30%" )



;-------------------------------------------------------------------------------
calc_Percent(Var) { ; replace 123% with 1.23 and similar
;-------------------------------------------------------------------------------
    while RegExMatch(Var, "(\d+)%", M )
        Var := StrReplace(Var, M1 "%", M1 / 100)
    return Var
}
vsub
Posts: 541
Joined: 29 Sep 2015, 03:39

Re: Solved:Need simple example,real time calculating and output the result

11 Jun 2019, 09:49

Thanks,it work...but only with round numbers
100*7.5% displays 750,it should be 7.5
The msgbox is showing 100*7.0.050000

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mcd, NullRefEx and 124 guests