[Deskbar] Calculator Handler for Deskbar



Hi,

I have written a handler for deskbar to do maths.

Idea: Type maths expressions into deskbar, python evaluates it (with
decimal floating point arithmetic!) and allows you to copy the result to
the clipboard. Can paste result back into deskbar if you want to keep
calculating!

Right now it supports addition (+), subtraction (-), multiplication (*),
division (/), exponentials (**) and scientific notation (eg: 5e-3). Any
expression that does not evaluate is silently ignored (uncomment the two
trackback lines to debug).

Future:
* configuration option to set precision (just saw that this is planned)
* include constants (pi, e etc), operators (sin, log etc)
  look here: http://python.org/doc/current/lib/decimal-recipes.html
* better restriction (pretty dirty at the moment)

Note: this takes advantage of the decimal module which is new in Python
2.4. There is version for 2.3 (one file) here:
http://www.taniquetil.com.ar/facundo/bdvfiles/get_decimal.html

Have fun!

Drew.
"""
Calculator handler for Deskbar
by Andrew Kerr <drewkerr at gmail.com>

Version 0.1 (November 16 2005)

Idea: Type maths expressions into deskbar, python evaluates it (with decimal 
floating point arithmetic!) and allows you to copy the result to the clipboard. 
Can paste result back into deskbar if you want to keep calculating!

Installation:
1) copy to ~/.gnome2/deskbar-applet/handlers and you're done!

Right now it supports addition (+), subtraction (-), multiplication (*), 
division (/), exponentials (**) and scientific notation (eg: 5e-3). Any 
expression that does not evaluate is silently ignored (uncomment the two 
traceback lines to debug).

Future:
* configuration option to set precision
* include constants (pi, e etc), operators (sin, log etc)
  look here: http://python.org/doc/current/lib/decimal-recipes.html
* better restriction

Note to [other] aspiring developers: the traceback module is very handy!

Licensed under the GNU GPL
"""

from gettext import gettext as _

import gtk
import gnomevfs
import deskbar.handler
import re
from decimal import Decimal, getcontext
#import traceback

HANDLERS = {
	"CalculatorHandler" : {
		"name": _("Calculator"),
		"description": _("Copies the result of a valid expression to the clipboard"),
	}
}

DECIEXPR = re.compile(r"((\A|(?<=\W))(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)")
VALID = re.compile(r"^[0123456789/*-=+.eE()]+$")
PRECISION = 10

class CalculatorMatch(deskbar.handler.Match):
	def __init__(self, backend, result):
		deskbar.handler.Match.__init__(self, backend, result)
		self._result = result
		
	def action(self, text=None):
		for clipboard in ['CLIPBOARD', 'PRIMARY']:
			gtk.clipboard_get(clipboard).set_text(self._result)

	def get_verb(self):
		return _("Copy <b>%(name)s</b> to clipboard")
	
	def get_hash(self, text=None):
		return self._result

class CalculatorHandler(deskbar.handler.Handler):
	def __init__(self):
		deskbar.handler.Handler.__init__(self, "gnome-calculator")
		
	def deciexpr(self, expr):
		"""Substitute Decimals for floats in an expression string.

		>>> from decimal import Decimal
		>>> s = '+21.3e-5*85-.1234/81.6'
		>>> deciexpr(s)
		"+Decimal('21.3e-5')*Decimal('85')-Decimal('.1234')/Decimal('81.6')"

		>>> eval(s)
		0.016592745098039215
		>>> eval(deciexpr(s))
		Decimal("0.01659274509803921568627450980")

		"""
		return DECIEXPR.sub(r"Decimal('\1')", expr)

	def query(self, query, max=5):
		if VALID.match(query) != None:
			try:
				getcontext().prec = PRECISION
				query = self.deciexpr(query)
				query = eval(query)
				query = query.to_eng_string()
				return [CalculatorMatch(self, query)]
			except:
				#print traceback.format_exc()
				return []
		else:
			return []


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]