AutoHotkey Community

It is currently May 26th, 2012, 8:11 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 81 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject:
PostPosted: July 4th, 2008, 6:42 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
If you want to evaluate a string, representing an arithmetic expression, you can use the Eval() function. Its parameter can be a literal string or a variable, containing a string, or even an AHK expression, resulting in a string of an arithmetic expression:
Code:
b := "a"
a := "1+2"
MsgBox % Eval(%b%)
The parameter of the Eval() function can contain other Eval() calls, so the recursion you are asking for is there. It just does not seem to be a good idea to generally change the meaning of %var% to Eval(%var%). It is an interesting idea you could gain some convenience with, but we loose consistency and possibilities.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2009, 9:41 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
I have to read an arithmetic expression from Steam's skin definition file, replace some variables (which my function already does), and then evaluate the expression.

I was trying to start the daunting task of creating something like an Eval function for my SteamWin needs, when I found this.

Edit:

I initially posted to ask if I could use your functions from Monster in my script, but when looking further into them, I realized they are more generalized than I need. So as a result, I'm just going to use them as a reference in creating a lightweight eval function for simple math.

Thanks so much for this amazing script. I've learned a lot just from looking at it.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2009, 10:05 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Here you find a much simpler version, which might be sufficient for your task. The following script is further simplified:
Code:
MsgBox % Eval("-2+(-1+2)*3")

Eval(x) {   ; Evaluate arithmetic expression with numbers, + - / * ( )
   Return Eval#(RegExReplace(x,"-","#")) ; # = subtraction, to distinguish from sign
}

Eval#(x) {  ; Evaluate expression with numbers, + #(subtract) / * ( ). Recurse into (..)
   Return RegExMatch(x,"(.*)\(([^\(\)]+)\)(.*)",y) ? Eval#(y1 . Eval@(y2) . y3) : Eval@(x)
}

Eval@(x) {  ; Evaluate expression with numbers, + #(subtract) / *
   RegExMatch(x,"(.*)(\+|#)(.*)",y)    ; last + or -
   IfEqual y2,+, Return Eval@(y1) + Eval@(y3)
   IfEqual y2,#, Return Eval@(y1) - Eval@(y3)

   RegExMatch(x,"(.*)(\*|/)(.*)",y)    ; last * or /
   IfEqual y2,*, Return Eval@(y1) * Eval@(y3)
   IfEqual y2,/, Return Eval@(y1) / Eval@(y3)

   Return x ? x : 0                    ; empty expression: 0, number: unchanged
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2009, 10:57 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Wow! I just finished writing a 51-line script to evaluate simple math expressions with parenthesis, and I feel completely and utterly humbled by the version you just posted. For some reason I didn't find the other script you linked to in my previous search, but I'm very glad for the new version you just posted above :)

It looks streamlined and lightweight, and it's perfect for my needs.

Thanks a million Laszlo!

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2009, 9:05 pm 
Offline

Joined: May 17th, 2008, 5:00 am
Posts: 39
Location: Dallas, TX
I chopped out the existing hotkeys, and am using the Eval() etc functions as a library. I then set up a hotkey for Cntl-C in my auto-start script, so that if hit twice quickly will Eval() the ClipBoard.

Code:
#include MathMONSTER (Core) by Laszlo.ahk

$^c::
    if gvCtrlCTicks
    {
        if (( A_TickCount - gvCtrlCTicks ) < 501 )
        {
            MonsterClip := ClipBoard
            if ( SubStr( MonsterClip, 0, 1) = "=" )
            {
                MonsterEval := Eval( SubStr(MonsterClip, 1, -1) )
                a := MonsterClip . MonsterEval
            }
            else
            {
                MonsterEval := Eval( MonsterClip )
                a := MonsterEval
            }
            ClipBoard := a
            caretx := A_CaretX
            carety := A_CaretY
            if ( carety > 150 )
                carety -= 25
            else
                carety += 20
            ToolTip, %a%,caretx,carety,2
            SetTimer, RemoveToolTipMonster, 1100
        }
        else
        {
            gvCtrlCTicks := A_TickCount
            Send ^c
        }
    }
    else
    {
        gvCtrlCTicks := A_TickCount
        Send ^c
    }
Return

RemoveToolTipMonster:
SetTimer, RemoveToolTipMonster, Off
ToolTip,,,,2
return


Thanks Laszlo for this great script!

Edit: I made a tweak in the Monster core, so instead of using "x" as a var prefix internally, it now uses "mmx":
Code:
   If RegExMatch(x, "(\S*?)\s*:=\s*(.*)", y) {
      y := "x" . y1                    ; user vars internally start with x to avoid name conflicts
      Return %y% := Eval1(y2)
   }

   x := RegExReplace(x,"([a-z_A-Z]\w*)([^\w'»’]|$)","%x$1%$2") ; VAR -> %xVAR%

is now
Code:
   If RegExMatch(x, "(\S*?)\s*:=\s*(.*)", y) {
      y := "mmx" . y1                    ; user vars internally start with x to avoid name conflicts
      Return %y% := Eval1(y2)
   }

   x := RegExReplace(x,"([a-z_A-Z]\w*)([^\w'»’]|$)","%mmx$1%$2") ; VAR -> %xVAR%

Enjoy,
Shawn


Last edited by greynite on June 24th, 2009, 9:28 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2009, 9:27 pm 
Offline

Joined: August 20th, 2008, 4:25 pm
Posts: 256
Seriously, Laszlo, you should try getting into Assembly, this stuff you do with AHK only already is amazing.

_________________
-Chavez.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 16th, 2009, 3:34 am 
Offline

Joined: May 17th, 2008, 5:00 am
Posts: 39
Location: Dallas, TX
Chavez wrote:
Seriously, Laszlo, you should try getting into Assembly, this stuff you do with AHK only already is amazing.


He already has :) He's got more than a few posts of binary ASM code to use in-line in AHK scripts to speed up various operations.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 13th, 2009, 7:36 pm 
Offline

Joined: March 7th, 2009, 6:44 pm
Posts: 49
Location: Europe, Lithuania
Need help! I noticed that Sin(), Tan() and other trigonometry functions, is used with radians. How can I make it usable with degrees? This what i found in ahk help file:
Code:
Note: To convert a radians value to degrees, multiply it by 180/pi (approximately 57.29578). To convert a degrees value to radians, multiply it by pi/180 (approximately 0.01745329252). The value of pi (approximately 3.141592653589793) is 4 times the arctangent of 1.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 13th, 2009, 8:35 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Code:
deg := 57.295779513082321
MsgBox % sin(30/deg)   ; sine of 30 degrees
MsgBox % deg*asin(0.5) ; arc sine of 0.5 in degrees
In Monster you can use 180/pi in place of deg, that is:
Code:
sin(30/180*pi)
180/pi*asin(0.5)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 14th, 2009, 9:29 pm 
Offline

Joined: March 7th, 2009, 6:44 pm
Posts: 49
Location: Europe, Lithuania
Thanks


Report this post
Top
 Profile  
Reply with quote  
PostPosted: April 23rd, 2010, 6:52 am 
Offline

Joined: April 23rd, 2010, 6:47 am
Posts: 1
Location: Bristol UK
Laszlo wrote:
Monster: evaluate math expressions in strings w/o external programs


Would you allow Rosetta code to show your code, under its license instead of its link here?

http://rosettacode.org/wiki/Arithmetic_ ... AutoHotkey

Thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 23rd, 2010, 4:45 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
I have no objection, but Monster does not qualify:
RosettaCode wrote:
an abstract-syntax tree (AST) for the expression must be created from parsing the input
.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 11th, 2010, 8:32 pm 
Offline

Joined: February 27th, 2009, 9:11 am
Posts: 693
Location: Burbank, California
Thanks Laszlo, very handy.
I was using the built-in constants and realized that you're using 1 gallon = 4.54609 liter (Imperial) rather than 3.785411784 liter (US)... :wink:

_________________
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom" but let's start to get the data...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 11th, 2010, 9:50 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
flyingDman wrote:
you're using 1 gallon = 4.54609 liter (Imperial) rather than 3.785411784 liter (US)
Thanks. I changed the first post to US gallon.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 12th, 2010, 6:53 pm 
Offline

Joined: February 27th, 2009, 9:11 am
Posts: 693
Location: Burbank, California
Why would this not give the correct result?:
Code:
MsgBox % Eval("$16 5.85")


It gives me 5.8499999999999996. Other examples show similar error.

:?:

_________________
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom" but let's start to get the data...


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 81 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Exabot [Bot], Uberi and 24 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group