I’ve read a few books recently where references were made to dollar amounts from many years ago. However, I often find it difficult to understand the context of, say, $10,000 in 1829.

But Wolfram Alpha can give you a rough approximation by applying inflation data. This isn’t perfect but is useful to get a general idea of what a similar amount might be today. (There isn’t all the context needed for a more accurate determination, and the underlying basket for inflation measures can be misleading.)

Handily, there’s a Wolfram Alpha API we can use to get this information programmatically. I originally wrote this script as a command-line tool, but how often do you read at your computer with a terminal window open? So the one in this post uses Pythonista and its ui module to make things more practical.

The code to get the new amount is pretty trivial:

 1 from __future__ import division
 3 from datetime import date
 4 from xml.etree import ElementTree
 5 import requests
 6 import ui
 9 def calculate_amount(sender):
10   """Convert given dollar amount for given year to current dollars"""
11   amount = view['amount'].text
12   year = view['year'].text
14   if not (amount and year):
15     return
17   api_key = 'YOUR API KEY IN HERE'
18   api_url = 'http://api.wolframalpha.com/v2/query'
19   query_template = '${amount} ({past_year} US dollars) in {current_year}'
20   query = query_template.format(amount=amount,
21                                 past_year=year,
22                                 current_year=date.today().year)
23   parameters = {'appid': api_key,
24                 'input': query,
25                 'format': 'plaintext',
26                 'podtitle': 'Result'}
27   response = requests.get(api_url, params=parameters)
28   xml_soup = ElementTree.fromstring(response.content)
29   new_amount = xml_soup.find('pod/subpod/plaintext').text.splitlines()[0]
30   view['result'].text = new_amount

The calculate_amount function above is called on a button press (hence the sender argument) and fetches the text from a couple of UI elements (all that view subscripting), bailing out if either the amount or year is missing.

The query template (line 19) is how Wolfram Alpha parses historical dollar calculations (shown as “Input interpretation” on the website) so we can skip as much parsing time as possible.

Requests makes sending the query a doddle, and we use an exact XPath expression to get at the result in the response. There’s an API explorer so you can get a handle on the structure. (Normally I’d use Beautiful Soup, but Pythonista doesn’t include lxml, so BS parses it as HTML and there’s really no point in risking — however slightly — that causing some problem. ElementTree isn’t bad if you’re doing something simple, anyway.)

Lastly we update another UI element to show the result. Pretty simple.

With the UI, you’ve got two choices: make it in code or use Pythonista’s UI editor. I chose to do it in code, because the UI editor saves a .pyui JSON file that takes a little work to share.

But now I would recommend people use the editor, as actually getting the code to work was a bit of a headache too. For the record: Ole Zorn has done an incredible job with Pythonista and the UI tools are incredible. However: the ui module seems to expose the Cocoa way of making GUIs, so unless you’ve got an understanding of that you may be in for some bumps. Helpfully, you can view the ui module documentation online Here’s the rest of the code:

33 def setup_view():
34     view = ui.View()
35     view.name = 'Historical Dollars'
36     view.background_color = 'white'
37     view.width, view.height = ui.get_screen_size()
39     amount_field = ui.TextField()
40     amount_field.name = 'amount'
41     amount_field.keyboard_type = ui.KEYBOARD_DECIMAL_PAD
42     amount_field.placeholder = 'Dollar amount'
43     amount_field.width *= 2
44     amount_field.height /= 2
46     year_field = ui.TextField()
47     year_field.name = 'year'
48     year_field.keyboard_type = ui.KEYBOARD_NUMBER_PAD
49     year_field.placeholder = 'Year'
50     year_field.width *= 2
51     year_field.height /= 2
53     button = ui.Button(title='Calculate')
54     button.action = calculate_amount
56     result_label = ui.Label()
57     result_label.name = 'result'
58     result_label.width = view.width
59     result_label.alignment = ui.ALIGN_CENTER
61     horizontal_centre = view.width * 0.5
62     field_spacing = amount_field.height * 1.5
63     amount_field.center = (horizontal_centre, amount_field.height)
64     year_field.center = (horizontal_centre,
65                          amount_field.center[1] + field_spacing)
66     button.center = (horizontal_centre,
67                      year_field.center[1] + field_spacing * 0.75)
68     result_label.center = (horizontal_centre,
69                            button.centre[1] + field_spacing * 0.75)
71     view.add_subview(amount_field)
72     view.add_subview(year_field)
73     view.add_subview(button)
74     view.add_subview(result_label)
76     return view
79 view = setup_view()
80 view.present('sheet')

And here’s what it looks like in action:

A screenshot of the historical dollars script run in Pythonista on an iPhone.

The thing that really tripped me up was .flex on views, for resizing the element based on its containing view. In the code above this isn’t used. I initially followed the example code from the documentation and had all sorts of fun trying to work out why the view spacing was screwed up.

Another problem was expecting the 'master', containing view (instantiated on line 34) to have the same size as the screen, when it seems to act kind of like HTML elements do when they’re full of floated elements (they collapse). That’s why I set the containing view’s size on line 37. (get_screen_size also seems to always return the portrait size.) All sorts of headaches resulted from this (centring elements based on the view’s centre particularly).

Otherwise, it’s so straightforward and repetitive that I’m not going to explain most of the lines. It works well enough on an iPhone 5-sized screen in portrait mode (elements are off-centre in landscape) but for smaller screens you may want to shift things about a bit vertically.

There are a couple of things to note. The names you give to elements are how you pick them out later (check out lines 11 and 40). Setting the button’s action (line 54) is obviously key, and you just give it a function object. And specifying the keyboard type for the two text fields relieves the need to do input validation (though the decimal keyboard lets you type multiple points), but frankly anyone who might use this should understand that it’ll break if you type in something funky.

I’ve put the whole file online if that’s easier for anyone. You just need to paste it into an empty script in Pythonista and run it.