This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Simple calculator.

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Simple calculator.

Post by Gewan »

Hi!

I'm looking for a simple calculator. Project GConvert seems to be faded, and even if it hadn't been, I'd still like a version that is not depending on Google for its math.

The closest thing I've come is "calc.tcl" (http://briped.net/2007/06/20/calctcl/), which seemed to be exactly what I wanted. I'm pleased with everything with it, except how it parses decimals in division sums.

For instance:
19:59:24 <@Gewan> !c 123/2
19:59:25 <@Eggdrop> 123/2 = 61


Where 123/2 is really 61.5. So, is there any simple way to make the script include decimals? I understand that it would be complicated with division math where the result is infinite, eg. 16/9=1.7777777.... But in this case, perhaps a round off to like say two or there decimals would suffice. Any chance for this? Without tons of coding? Perhaps Tcl even comes with simple math functions? If so, this wouldn't be too complicated?


Ty in advance~
Regards~
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Tcl is integer math unless it is otherwise implied in the function eg. by using one or more decimal number values.

[20:45] <@arfer> % return [expr {123/7}]
[20:45] <@Baal> 17

[20:45] <@arfer> % return [expr {123/7.0}]
[20:45] <@Baal> 17.5714285714

[20:51] <@arfer> % return [format %.2f [expr {123/7.0}]]
[20:51] <@Baal> 17.57
I must have had nothing to do
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Post by Gewan »

01:33:07 <@Gewan> !c 123/2
01:33:07 <@Eggdrop> 123/2 = 61
01:33:10 <@Gewan> !c 123/2.0
01:33:11 <@Eggdrop> error calculating '123/2.0' (syntax error in expression "123/2.0": extra tokens at end of expression)
01:33:17 <@Gewan> !c 123/2,0
01:33:20 <@Eggdrop> error calculating '123/2,0' (syntax error in expression "123/2,0": extra tokens at end of expression)
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

The errors you are getting are as a consequence of how the script you are using treats the command arguments. I was merely illustrating how core Tcl handles math.
I must have had nothing to do
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Post by Gewan »

@arfer,

I see, pardon me. Then I change approach to officially request for a script/modification of calc.tcl that will be able to handle decimals.
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I copied the script calc.tcl directly from the site you pasted above and loaded it into one of my bots. It seems to work fine for me.

[12:44] <@arfer> .calc 123/2
[12:44] <Colossus> 123/2 = 61
[12:44] <@arfer> .calc 123/2.0
[12:44] <Colossus> 123/2.0 = 61.5

The script is on an Eggdrop version 1.6.20 using Tcl 8.5

There is some discussion on google regarding the script but this is more to do with the difference in default decimal precision between Tcl 8.4 and Tcl 8.5, rather than the generation of errors.

Hopefully somebody following this thread will recognise the exact error and point you in the right direction. I would download the file again and ensure that you use a competent text editor to read/modify it. I suggest you do not modify it in any way until you have established whether or not it works for you as is.
I must have had nothing to do
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Post by Gewan »

@arfer,
Thank you very much for you taking the time to check the script. Very kind.
I tried copying the script again, pasting it into vim. Same error again though :/
It works fine without use of decimals, but the 123/2.0 won't fly.

Also, for your information:

I am Eggdrop, running eggdrop v1.6.19+ctcpfix: 6 users (mem: 267k).
Tcl version: 8.4.19 (header version 8.4.19)



--EDIT--
Guys! Never mind this.
I did a simple .restart and guess what?
Yeah, it now works like a charm.
Thanks for all your help!
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Erhm.

Post by Gewan »

Hi (again).
Guys. Regarding calc.tcl now.

<@NejthanX> !c 123/5
<@Eggdrop> 123/5 = 24

<@Gewan> !c 123/5.
<@Eggdrop> 123/5. = 24.6

<@Gewan> !c 123./5
<@Eggdrop> 123/5. = 24.6


It won't even round off per default, but just omit the decimals, see. Adding a simple dot will make it return correct answer. Any chance that anyone here could modify calc.tcl so that it add the dot auto matically? When I'm tired I forget to add the dot, and I'm too slow/dumb to always "see" when decimals are to be expected in a result (please don't judge me).

So, anyone feeling bored? Please make me a "calc_mod.tcl" that will add the "." (in either numerator or denominator) per default. I would be _very_ happy! :)
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Gewan wrote:So, anyone feeling bored? Please make me a "calc_mod.tcl" that will add the "." (in either numerator or denominator) per default. I would be _very_ happy! :)
Using the original script make these simple modifications:

Code: Select all

change this:

            } elseif {[catch {expr [calc_fixexpr $remainder]} output]} {

to this:

            } elseif {[catch {set output [format "%.${::calc_precision}f" [expr [calc_fixexpr [calc_force_floats $remainder]]]]} output]} {

change this:

            calc_msg $output2 "$remainder = $output"

to this:

            calc_msg $output2 "$remainder = [calc_precision_format $output]"

then add these procedures to the end:

proc calc_precision_format {value} {
		set v [split $value .]
		set v1 [lindex $v 0]
		set v2 [string trim [lindex $v 1] " 0"]
		if {[string length $v2]} { set v "${v1}.${v2}" } { set v $v1 }
}

proc calc_force_floats {equation} {
	regsub -all -- {[0-9.]+} $equation "double(\\0)" equation
	return $equation
}

then add this to the very top of the script:

# set the digits of precision you want in your display
set calc_precision 7
This will remove the ending 0's, as well as the decimal point when not needed. Using the variable calc_precision you control how many digits will be the maximum after the decimal point. If this looks familiar, yes, this is the exact same technique used within Incith:Weather. ;)

You will never see things like ( 7.0200000 or 7.0000000 ) .. These will instead be displayed as ( 7.02 or 7 ) respectively. This is because even though you've set calc_precision to 7, it will smartly clean the number up before displaying to remove needless precision.

Try this out and see if it works ;)


edit: corrected issue mentioned below....
Last edited by speechles on Wed Mar 09, 2011 11:20 am, edited 2 times in total.
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Post by Gewan »

Thanks alot for your effort speechles. I'm so thankful.
Some minor flaw though, from what it seems.

<Gewan> !c 1+2
<Eggdrop> error calculating '1+2' (can't read "::": no such variable)


Getting the same respons with 1-2, 1/2, or even 1*2.

Ideas?
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Gewan wrote:Thanks alot for your effort speechles. I'm so thankful.
Some minor flaw though, from what it seems.

<Gewan> !c 1+2
<Eggdrop> error calculating '1+2' (can't read "::": no such variable)


Getting the same respons with 1-2, 1/2, or even 1*2.

Ideas?
That was a flaw in my code. I've corrected that, you can now safely use the above code changes and they will function correctly. :)

Enjoys, and have a fun :P
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Post by Gewan »

It works like a charm! :D
Thanks a lot!

Cheers~
G
Gewan
Voice
Posts: 27
Joined: Sat Dec 25, 2010 7:50 pm

Something messed up

Post by Gewan »

Script has worked flawlessly over the years.
However, now something's messed up.
I'm not sure if auto-updates ('Buntu) over apt-get has caused it.
Anyhow, with my latest revision, all !c requests yields answers in /MSG.
I was dazed and angry and worked my way for a solution -- empty handed.
Niow, I found this simple script that may be a better scratch than the one we used.
It works nice (decimals and all) by default, but it's adding ".0" for integers.
Is there any easy way to modify this script so that it returns integers without .0 and I would fly of happyness! :>
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Code: Select all

# this is the maximum amount of digits
# that will be shown after the decimal point
set calc_precision 7

bind pub - !calc safe_calc
bind pub - .calc safe_calc
setudef flag calc

proc is_op {str} {
	return [expr [lsearch {{ } . + - * ^ / ( ) %} $str] != -1]
}

proc safe_calc {nick uhost hand chan str} {
	if {![channel get $chan calc]} { return }
	foreach char [split $str {}] {
		if {![is_op $char] && ![string is integer $char]} {
			putserv "PRIVMSG $chan :$nick: Invalid expression. Cannot calculate '$char'."
			return
		}
	}
	if {[catch {format "%.${::calc_precision}f" [expr [calc_force_floats $str]]} out]} {
		putserv "PRIVMSG $chan :$nick: Invalid equation. Cannot calculate."
		return
	} else {
		putserv "PRIVMSG $chan :$str = [calc_precision_format $out]"
	}
}

proc calc_precision_format {value} {
      set v [split $value .]
      set v1 [lindex $v 0]
      set v2 [string trim [lindex $v 1] " 0"]
      if {[string length $v2]} { set v "${v1}.${v2}" } { set v $v1 }
}

proc calc_force_floats {equation} {
   regsub -all -- {[0-9.]+} $equation "double(\\0)" equation
   return $equation
} 

putlog "calculate loaded."
# eof
<speechles> !calc [die]
<sp33chy> speechles: Invalid expression. Cannot calculate '['.
<speechles> !calc -2.02 + 3.112312 * 0.2
<sp33chy> -2.02 + 3.112312 * 0.2 = -1.3975376
<speechles> !calc 5 + 3 + 2.1
<sp33chy> 5 + 3 + 2.1 = 10.1
<speechles> !calc 5 + 3 + 2
<sp33chy> 5 + 3 + 2 = 10
<speechles> !calc 5 + 3 + 2 + M
<sp33chy> speechles: Invalid expression. Cannot calculate 'M'.

-- These last two demonstrate how precision affects results ---
<speechles> !calc 2.000005+9.38712317823781287817237812789378912318923*5
<sp33chy> 2.000005+9.38712317823781287817237812789378912318923*5 = 48.9356209
<speechles> !calc 48.9356209 - 5*9.38712317823781287817237812789378912318923
<sp33chy> 48.9356209 - 5*9.38712317823781287817237812789378912318923 = 2.5

That should be "2.000005" but because we restrict precision to 7, we wind up off by .5 or so .. This is normal because we create the condition by stripping excess digits. You need to take this into account when you set your precision. 7 seems a good number. Maybe 8 is better. Who knows?
Enjoys ;^)

Uses same procedures used to modify other script to same behavior.
Last edited by speechles on Fri Jul 13, 2012 7:20 pm, edited 1 time in total.
User avatar
spithash
Master
Posts: 248
Joined: Thu Jul 12, 2007 9:21 am
Location: Libera
Contact:

Post by spithash »

this script is awesome. I'm so copying it. thank you guys :)
Libera ##rtlsdr & ##re - Nick: spithash
Click here for troll.tcl
Post Reply