Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Minimalist calculator - and enhancements


  • Please log in to reply
24 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
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).
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

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
This is again a very excellent script. And it sooooo cool.

In this line
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
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

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

Thanks!

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.

Hey, you changed the code while I wrote this reply. :))

You could alter your reply, too. Maybe, I should change my nick to Speedy Gonzales? ;-)

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
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
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
pi:=4*atan(1); sin(2*pi/3)+cos(pi/3)
which gives 1.366025, or
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.
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.

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
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...
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

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.
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.

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Too bad this won't work for compiled scripts :?
Can Microsoft Calculator or command prompt execute mathmatical expressions?

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

Too bad this won't work for compiled scripts

We have to wait, until Chris implements dynamic expressions -or use my expression parser script.

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.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Updated the enhanced version in previous post, with minor simplifications.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
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.

Veovis
  • Members
  • 389 posts
  • Last active: Mar 17 2009 12:24 AM
  • Joined: 13 Feb 2006
Nice work Laszlo!!!
It is now in my startup script!

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?
Posted Image
"Power can be given overnight, but responsibility must be taught. Long years go into its making."

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

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.

Veovis
  • Members
  • 389 posts
  • Last active: Mar 17 2009 12:24 AM
  • Joined: 13 Feb 2006
*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?
Posted Image
"Power can be given overnight, but responsibility must be taught. Long years go into its making."

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

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.

... 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.

Veovis
  • Members
  • 389 posts
  • Last active: Mar 17 2009 12:24 AM
  • Joined: 13 Feb 2006

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.

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?
Posted Image
"Power can be given overnight, but responsibility must be taught. Long years go into its making."