The problem we have is that our informants are always asking for odd or unusual currencies. This isn't really all that surprising; we're dealing with spies and criminals on the run. They always seem to need obscure foreign currencies for their own nefarious projects.
We can get a big pile of international exchange rates using a piece of code like the following:
query_exchange_rates= "http://www.coinbase.com/api/v1/currencies/exchange_rates/"
with urllib.request.urlopen( query_exchange_rates ) as document:
pprint.pprint( document.info().items() )
exchange_rates= json.loads( document.read().decode("utf-8") )The query string is a simple URL. When we make the request, we get back a long string of bytes. We decode this to make a proper string and use json.loads() to build a Python object.
The problem is that we get a giant dictionary object that's not really all that useful. It looks like this:
{'aed_to_btc': '0.000552',
'aed_to_usd': '0.272246',
'afn_to_btc': '3.6e-05',
'afn_to_usd': '0.01763',Also, it goes on and on for 632 different combinations of currencies.
The keys to this mapping involve two currencies separated by _to_ and written in lowercase letters. The currency code pieces that we got in the earlier example (see the Using a REST API in Python section) are in uppercase. We got a bit of work on our hands to match this data up properly.
We need to break this long list of currencies down into sublists. The neat way to handle this is with a dictionary of lists. We can use the defaultdict class to build these lists. Here's a typical approach:
from collections import defaultdict
rates = defaultdict(list)
for conversion, rate in exchange_rates.items():
source, _, target = conversion.upper().partition("_TO_")
rates[source].append( (target, float(rate)) )We set the rates variable to be a defaultdict(list) object. When a key is not found in this dictionary, an empty list will be built as the value for that missing key.
We can iterate through each conversion and rate in the items() method of the raw data. We'll convert the conversion string to uppercase and then partition the conversion on the _TO_ string. This will separate the two currency codes, assigning them to source and target. As they're uppercase, we can also match them against our list of currency-to-country codes.
We also converted the rate from a string to a more useful float number. The string isn't useful for further calculations.
We can then accumulate a list for each currency within the rates dictionary. If the source currency exists, we'll append it to the list that's already present in the dictionary. If the source currency doesn't exist, we'll create an empty list and append it to that empty list.
We'll append a target currency and the conversion rate as a simple two-tuple.
When we're done, we'll have tidy, short lists. Here's how we can pick a few currencies and display the conversions:
for c in 'USD', 'GBP', 'EUR':
print( c, rates[c] )For a select few currencies, we printed the currency and the list of conversion rates available right now.
This shows us results like the following:
GBP [('BTC', 0.003396), ('USD', 1.682624)]
EUR [('BTC', 0.002768), ('USD', 1.371864)]The USD list is rather large, as it includes 159 other countries and currencies.
As we got the currency details from our earlier query, we can do this to make our output a little more useful:
currency_details = dict( (code,name) for name,code in currencies )
for c in 'USD', 'GBP', 'EUR':
print( currency_details[c], rates[c] ) We built a dictionary that maps a currency code to the full name for the currency. When we look up the details for a currency, our output looks a little nicer, as shown in the following snippet:
British Pound (GBP) [('USD', 1.682624), ('BTC', 0.003407)]
Euro (EUR) [('USD', 1.371864), ('BTC', 0.002778)]This is the kind of thing that can help us convert the bribe amounts into budget numbers that the accountants at HQ will find useful. We can also use this information to send national assessments based on the value of the local currency.
Also, we can use this for our own purposes to buy and sell bitcoins. This might help keep us one step ahead of international chaos. Alternatively, it may help us leverage the advantages of crypto currency.
We can save our currency details to a file using json.dump(currency_details, some_open_file). See the example in the Saving our data via JSON section for a refresher on how this is done.