AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Minimalist calculator - and enhancements
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon May 01, 2006 7:48 pm    Post subject: Minimalist calculator - and enhancements Reply with quote

This calculator gives the result faster than the Windows calculator loads and does not cover much screen area. Choose you favorite hotkey to activate it. Below Win-Alt-Z is used, because it can be pressed with one hand. Esc hides the window, but keeps the previous entries.

The calculator is just a simple (Combo) box, where you type (or paste via the context menu of the right mouse button or with Ctrl-V) what you want to compute. Like 1+2, or sqrt(atan(1)). Pressing Enter activates an invisible button (OK), which launches a second copy of AHK to compute the expression. It will appear as the last entry in the box, highlighted. With the up/down arrow keys you can go back to previous inputs and results, edit them and re-compute with Enter. The highlighted text can be copied to the ClipBoard with Ctrl-C or via the context menu (right-click).
Code:
file = C:\$temp$.ahk             ; any unused filename
Gui Add, ComboBox, X0 Y0 H1 W300 vExpr
Gui Add, Button, Default, OK     ; button activated by Enter, Gui Show cuts it off
Gui -Caption +Border             ; small window w/o title bar

!#z::
   Gui Show, H24 W277            ; cut off unnecessary parts
Return

GuiEscape:
   Gui Show, Hide                ; keep data for next run
Return

ButtonOK:
   GuiControlGet Expr,,Expr      ; get Expr from ComboBox
   GuiControl,,Expr,%Expr%       ; write Expr to internal ComboBox list
   FileDelete %file%             ; delete old temporary file -> write new
   FileAppend #NoTrayIcon`nFileDelete %file%`nFileAppend `% %Expr%`, %file%, %file%
   RunWait %A_AhkPath% %file%    ; run AHK to execute temp script, evaluate expression
   FileRead Result, %file%       ; get result
   FileDelete %file%
   GuiControl,,Expr,%Result%     ; write Result to internal ComboBox list
   N += 2                        ; count lines
   GuiControl Choose,Expr,%N%    ; show Result
Return

Edit 20060501: Minor simplifications (thanks to toralf)
Edit 20060503: RunWait with explicit program name (useful if AHK is not installed properly). Thanks Titan


Last edited by Laszlo on Wed May 03, 2006 9:25 pm; edited 3 times in total
Back to top
View user's profile Send private message
toralf



Joined: 31 Jan 2005
Posts: 3841
Location: Bremen, Germany

PostPosted: Mon May 01, 2006 9:20 pm    Post subject: Reply with quote

This is again a very excellent script. And it sooooo cool.

In this line
Code:
FileDelete C:\$temp$.ahk
you should have use the %file% though. :)

Why have you set the buttons width to 0? You could have used Hidden?


EDIT: Hey, you changed the code while I wrote this reply. :))
_________________
Ciao
toralf
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon May 01, 2006 9:31 pm    Post subject: Reply with quote

toralf wrote:
This is again a very excellent script. And it sooooo cool.
Thanks!
toralf wrote:
Why have you set the buttons width to 0? You could have used Hidden?
True, but that is 4 characters longer!!! Actually, none of them is necessary (save 3 characters), because the Gui Show command cuts off the unused part, anyway.
toralf wrote:
Hey, you changed the code while I wrote this reply. Smile)
You could alter your reply, too. Maybe, I should change my nick to Speedy Gonzales? Wink
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon May 01, 2006 11:16 pm    Post subject: Reply with quote

Here is a version, which can handle short AHK programs, too. All the instructions have to be written in one line, separated by semicolons ";". The expression after the last semicolon is evaluated and returned. For example, entering
Code:
loop 9; S+=A_Index**2; S
computes the sum of the first 9 squares: 1+4+9+16+25+36+49+64+81, and returns 285. Another example is
Code:
pi:=4*atan(1); sin(2*pi/3)+cos(pi/3)
which gives 1.366025, or
Code:
SetFormat Integer,Hex; 999
which converts 999 to hexadecimal: 0x3e7. Of course, if there is only a single expression, it is evaluated as before: 3**7 --> 2187.
Code:
file = C:\$temp$.ahk             ; any unused filename
Gui Add, ComboBox, X0 Y0 W300 vExpr
Gui Add, Button, Default, OK     ; button activated by Enter, Gui Show cuts it off
Gui -Caption +Border             ; small window w/o title bar

!#z::
   Gui Show, H24 W277            ; cut off unnecessary parts
Return

GuiEscape:
   Gui Show, Hide                ; keep data for next run
Return

ButtonOK:
   GuiControlGet Expr,,Expr      ; get Expr from ComboBox
   GuiControl,,Expr,%Expr%       ; append Expr to internal ComboBox list
   StringReplace Expr, Expr, `;, `n, All
   StringGetPos Last, Expr, `n, R1
   StringLeft Pre, Expr, Last
   StringTrimLeft Expr, Expr, Last+1
   FileDelete %file%             ; delete old temporary file -> write new
   FileAppend #NoTrayIcon`nFileDelete %file%`n%pre%`nFileAppend `% (%Expr%)+0`, %file%, %file%
   RunWait %A_AhkPath% %file%    ; run AHK to execute temp script, evaluate expression
   FileRead Result, %file%       ; get result
   FileDelete %file%
   GuiControl,,Expr,%Result%     ; append Result to internal ComboBox list
   N += 2                        ; count lines
   GuiControl Choose,Expr,%N%    ; show Result
Return
In this version, the Alt-Up or Alt-Down arrows open the list of entries (history), for easier navigation. Esc closes it.

Edit 20060503: RunWait with explicit program name (useful if AHK is not installed properly). Thanks Titan.


Last edited by Laszlo on Wed May 03, 2006 9:29 pm; edited 1 time in total
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Tue May 02, 2006 9:26 am    Post subject: Reply with quote

That's nice, leaving room for improvements (like choosing the display base).
Too bad AutoHotkey doesn't support scientific notation, like 1.0e5. Of course, there is ambiguity of 1e5 with a variable name... Again legacy weight...
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue May 02, 2006 7:17 pm    Post subject: Reply with quote

PhiLho wrote:
room for improvements (like choosing the display base).
OK, here you are. Alt-D (the default) selects decimal output mode for integers, Alt-H does hex, Alt-B does binary. After changing the output mode, a TrayTip shows the new settings for several seconds, then disappears.

Alt-0,..,Alt-9 sets the floating point precision to 0,..,9 digits. Alt-E toggles between engineering and normal output formats for floating point results. These settings are also shown in the TrayTip, for a short time.

The script is no longer short, but maybe, more useful. There are still many possible enhancements, like tray menu or context menu for the settings or the possibility for binary- or engineering form input, predefined constants (pi, e). These are left for the reader.
Code:
file = C:\$temp$.ahk             ; any unused filename
Menu Tray, Icon, Shell32.dll, 97
IntMode = Decimal                ; default output mode
Prec = 0.6                       ; default floating point precision
Gui Add, ComboBox, X0 Y0 W300 vExpr
Gui Add, Button, Default, OK     ; button activated by Enter, Gui Show cuts it off
Gui Add, Button, gIntM, &Binary  ; Alt-B: binary integer output
Gui Add, Button, gIntM, &Decimal ; Alt-D: decimal integer output
Gui Add, Button, gIntM, &Hex     ; Alt-H: hex integer output
Gui Add, Button,      , &Eng     ; Alt-E: On/Off engineering mode float output
Gui Add, Button, gPrec, &0
Loop 9                           ; Alt-number buttons for setting precision
   Gui Add, Button, gPrec, &%A_Index%
Gui -Caption +Border             ; small window w/o title bar

!#z::
   Gui Show, H24 W277            ; calculator window: cut off unnecessary parts
Return

GuiEscape:
   Gui Show, Hide                ; hide, keep data for next run
Return

IntM:                            ; setting decimal/hex/binary Integer output Mode
   StringTrimLeft IntMode, A_GuiControl, 1
   TrayTip,,%IntMode%
Return

ButtonEng:                       ; toggle engineering mode
   EngMode := !EngMode
   TrayTip,,Eng-Mode = %EngMode%
Return

Prec:                            ; set floating point precision
   StringTrimLeft p, A_GuiControl, 1
   If (A_TickCount > Tick0+999)  ; long delay = set precision to entered digit
        pp = %p%
   Else pp = %pp%%p%             ; short delay = append digit to precision
   TrayTip,,Precision = %pp%     ; TrayTip w/o "0."
   Prec = 0.%pp%
   Tick0 = %A_TickCount%
Return

ButtonOK:                        ; calculate
   GuiControlGet Expr,,Expr      ; get Expr from ComboBox
   GuiControl,,Expr,%Expr%       ; append Expr to internal ComboBox list
   StringReplace Expr,Expr,`;,`n,All
   StringGetPos Last, Expr, `n, R1
   StringLeft Pre, Expr, Last    ; separate Pre-amble code and Expr to evaluate
   StringTrimLeft Expr,Expr,Last+1
   FileDelete %file%             ; delete old temporary file -> write new
   FileAppend #NoTrayIcon`nSetFormat Float`,%Prec%`nFileDelete %file%`n%pre%`nFileAppend `% %Expr%`,%file%,%file%
   RunWait %A_AhkPath% %file%    ; run AHK to execute temp script, evaluate expression
   FileRead Result, %file%       ; get result
   FileDelete %file%
   GuiControl,,Expr,% OM(Result) ; append Result to internal ComboBox list
   N += 2                        ; count lines
   GuiControl Choose,Expr,%N%    ; show Result
Return

OM(x) {                          ; format x according to the Output Mode
   Global IntMode, EngMode, Prec
   If x is not Integer
   {
      SetFormat Float, %Prec%    ; used precision
      If (!EngMode OR x+0 = "" or x = 0)
          Return x+0
      Loop                       ; engineering mode
         If (Abs(x) < 1) {
            e--
            x *= 10              ; move the decimal point
         } Else If (Abs(x) >= 10) {
            e++
            x *= .1
         } Else Break            ; normalized if 1 <= x < 10
      Return x chr(101+e-e) e    ; 1.23e4, no "e" if e = ""
   }
   IfEqual IntMode,Binary, {     ; binary integer output
      Loop {
         b := x&1 b
         x := x>>1
         If (x = x>>1)           ; negative x: leading 11..1 omitted
            Break
      }
      Return b
   }
   SetFormat Integer,%IntMode%   ; Decimal, Hex
   Return x+0
}

Edit 20060502: Minor simplifications
Edit 20060502: Alt-digits entered with less than a second delay, define multi digit precisions.
Edit 20060503: RunWait with explicit program name (useful if AHK is not installed properly). Thanks Titan.


Last edited by Laszlo on Wed May 03, 2006 9:36 pm; edited 3 times in total
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5382
Location: /b/

PostPosted: Tue May 02, 2006 7:33 pm    Post subject: Reply with quote

Too bad this won't work for compiled scripts Confused
Can Microsoft Calculator or command prompt execute mathmatical expressions?
_________________

Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue May 02, 2006 7:43 pm    Post subject: Reply with quote

Titan wrote:
Too bad this won't work for compiled scripts
We have to wait, until Chris implements dynamic expressions -or use my expression parser script.
Titan wrote:
Can Microsoft Calculator or command prompt execute mathematical expressions?
Calculator can. You have to paste or ControlSend complicated expressions. In the command prompt you would need to call yet another calculator program. There are many short ones out there.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue May 02, 2006 10:33 pm    Post subject: Reply with quote

Updated the enhanced version in previous post, with minor simplifications.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue May 02, 2006 11:03 pm    Post subject: Reply with quote

Updated the enhanced version in previous post, again. Alt-digits entered with less than a second delay, define multi digit precisions. For example, ALT-2 -short time- Alt-5 sets the floating point precision to 25 digits. If there is more than a second time between the keystrokes, the last one takes precedence, that is, the precision will be 5 digits after the decimal point.
Back to top
View user's profile Send private message
Veovis



Joined: 13 Feb 2006
Posts: 390
Location: Utah

PostPosted: Tue May 02, 2006 11:54 pm    Post subject: Reply with quote

Nice work Laszlo!!!
It is now in my startup script!

Titan wrote:
Too bad this won't work for compiled scripts


Why won't it work? Can't a compiled script still write the file, and then read it back?
_________________

"Power can be given overnight, but responsibility must be taught. Long years go into its making."
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Wed May 03, 2006 12:07 am    Post subject: Reply with quote

Veovis wrote:
Titan wrote:
Too bad this won't work for compiled scripts
Why won't it work? Can't a compiled script still write the file, and then read it back?
If your customer does not have AHK installed, he can still run compiled scripts, but for the spun-off second script an installed AHK is needed. This is the limitation of the script generated scripts (and the slight delay, and the extra memory). We just have to wait for dynamic expressions. Don't you want to join the development team? It might speed up things.
Back to top
View user's profile Send private message
Veovis



Joined: 13 Feb 2006
Posts: 390
Location: Utah

PostPosted: Wed May 03, 2006 12:27 am    Post subject: Reply with quote

*slaps self in forehead*

Yeah, i get that now. That is some really cool code though. Having a script write a script that overwrites itself... pretty crazy.

I remember that either you or PhiLho made an eval(exp) function. Couldnt that be converted to C++ (or whatver AHK was written in) and made into a real function? I've only looked at the source code a little and i dont know C ( i know AHK, flash, and im barely starting java) but would this be possible?
_________________

"Power can be given overnight, but responsibility must be taught. Long years go into its making."
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Wed May 03, 2006 3:14 am    Post subject: Reply with quote

Veovis wrote:
That is some really cool code
Thanks! There are a number of other tricks in the code, too. Has everyone got the idea behind "Return x chr(101+e-e) e"? How about the test x+0 = "", and why do we return x+0? The invisible buttons are activated by their default shortcut letters, which work like hotkeys, but only when the GUI has focus.
Veovis wrote:
... an eval(exp) function. Couldnt that be converted to C++ (or whatver AHK was written in) and made into a real function?
I have not looked at the AHK code, at all, being lazy and not being a programmer (despite the huge amount of code I had to write). My first idea was to call again the parser/executive part of AHK, with the dynamic code, stored in a variable. This is already there, we would not need another expression parser. There are difficulties, though, like with labels, since the dynamic code disappears, and so the labels have to be removed, too. How about hotkeys? Probably the dynamic code should behave like a function. We would happily accept limitations, because the primary application of dynamic code was calculators, maybe with syntax translation.
Back to top
View user's profile Send private message
Veovis



Joined: 13 Feb 2006
Posts: 390
Location: Utah

PostPosted: Wed May 03, 2006 4:14 am    Post subject: Reply with quote

Laszlo wrote:
Has everyone got the idea behind "Return x chr(101+e-e) e"? How about the test x+0 = "", and why do we return x+0?

Hmmmm, i admit that several parts of the code baffle me. When i first looked at it I was totally lost. "How is this a calulator?" I now understand the code in the first post, but the base changing stuff confuses me. I'll look closer tomorow.

Laszlo wrote:
The invisible buttons are activated by their default shortcut letters, which work like hotkeys, but only when the GUI has focus.

Yeah, that was soooo smart! So much easier that window specific hotkeys and stuff. I'll use that in all my new programs. But can you make it respond to things like F5?
_________________

"Power can be given overnight, but responsibility must be taught. Long years go into its making."
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group