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:

  1. Anonymous18/1/11 12:04

    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

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

    Close enough :)

    ReplyDelete
  3. Anonymous18/1/11 18:22

    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!

    ReplyDelete
  4. Yeah, for some definition of "fun" :)

    Fixed now.

    ReplyDelete