If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

Sunday, January 16, 2011

gcalc - Command line interface to Google calculator

#!/usr/bin/env python
'''Command line interface to Google calculator
    gcalc 100f c -> 37.7777778 degrees Celsius
'''

# Idea taken from http://bit.ly/dVL4H3

import json
from urllib import urlopen
import re

def main(argv=None):
    import sys
    from optparse import OptionParser

    argv = argv or sys.argv

    parser = OptionParser("%prog FROM TO\n\t%prog 100f c")
    opts, args = parser.parse_args(argv[1:])
    if len(args) != 2:
        parser.error("wrong number of arguments") # Will exit

    url = "http://www.google.com/ig/calculator?q=%s=?%s" % tuple(args)
    try:
        # We decode to UTF-8 since Google sometimes return funny stuff
        result = urlopen(url).read().decode("utf-8", "ignore")
        # Convert to valid JSON: {foo: "1"} -> {"foo" : "1"}
        result = re.sub("([a-z]+):", '"\\1" :', result)
        result = json.loads(result)
    except (ValueError, IOError), e:
        raise SystemExit("error: %s" % e)

    if result["error"]:
        raise SystemExit("error: %s" % result["error"])

    print result["rhs"]

if __name__ == "__main__":
    main()

4 comments:

Anonymous said...

Actually it's only for unit conversions and not a complete cmd line interface to the google calculator. The latter would support such things as "12 * 1000 usd in bulgarian money"

coca cola guy

Miki Tebeka said...

[06:53] ~ $gcalc '12*10usd' 'bulgarian money'
175.36809 Bulgarian levs
[06:54] ~ $

Close enough :)

Anonymous said...

suprisingly your suggestion works, but add a digit and I get this:

gcalc '12*110usd' 'bulgarian money'

error: 'utf8' codec can't decode byte 0xa0 in position 1: invalid start byte


This is so funny!

Miki Tebeka said...

Yeah, for some definition of "fun" :)

Fixed now.

Blog Archive