This notebook goes with a blog post at Agile*.
We're going to get some info from Wikipedia, and some financial prices from Yahoo Finance. We'll make good use of the requests
library, a really nicely designed Python library for making web requests in Python.
We'll start with the Jurassic, then generalize.
In [1]:
url = "http://en.wikipedia.org/wiki/Jurassic" # Line 1
I used View Source
in my browser to figure out where the age range is on the page, and what it looks like. The most predictable spot, that will work on every period's page, is in the infobox. It's given as a range, in italic text, with "million years ago" right after it.
Try to find the same string here.
In [2]:
import requests # I don't count these lines.
r = requests.get(url) # Line 2
Now we have the entire text of the webpage, along with some metadata. The text is stored in r.text
, and I happen to know roughly where the relevant bit of text is: around the 7500th character, give or take:
In [3]:
r.text[7400:7600] # I don't count these lines either.
Out[3]:
We can get at that bit of text using a regular expression:
In [4]:
import re
s = re.search(r'<i>(.+?million years ago)</i>', r.text)
text = s.group(1)
text
Out[4]:
And if we're really cunning, we can get the start and end ages:
In [5]:
start, end = re.search(r'<i>([\.0-9]+)–([\.0-9]+) million years ago</i>', r.text).groups() # Line 3
duration = float(start) - float(end) # Line 4
print("According to Wikipedia, the Jurassic lasted {:.2f} Ma.".format(duration)) # Line 5
An exercise for you, dear reader: Make a function to get the start and end ages of any geologic period, taking the name of the period as an argument. I have left some hints.
In [6]:
def get_age(period):
url = "http://en.wikipedia.org/wiki/" + period
r = requests.get(url)
start, end = re.search(r'<i>([\.0-9]+)–([\.0-9]+) million years ago</i>', r.text).groups()
return float(start), float(end)
You should be able to call your function like this:
In [7]:
period = "Jurassic"
get_age(period)
Out[7]:
Now we can make a function that makes the sentence we made before, calling the function you just wrote:
In [8]:
def duration(period):
t0, t1 = get_age(period)
duration = t0 - t1
response = "According to Wikipedia, the {0} lasted {1:.2f} Ma.".format(period, duration)
return response
In [9]:
duration('Cretaceous')
Out[9]:
Here is an explanation of how to form Yahoo Finance queries.
In [10]:
import requests
url = "http://download.finance.yahoo.com/d/quotes.csv"
params = {'s': 'HHG17.NYM', 'f': 'l1'}
r = requests.get(url, params=params)
In [11]:
price = float(r.text) # Line 9
print("Henry Hub price for Feb 2017: ${:.2f}".format(price))
The symbol s
we're passing is HHF17.NYM
. This means:
The ticker symbols we're passing look like XXMYY.NYM, with components as follows:
XX
— commodity 'benchmark' symbol, as explained below.M
— a month code, symbolizing January to December: [F,G,H,J,K,M,N,Q,U,V,X,Z]
YY
— a two-digit year, like 17..NYM
— the Nymex symbol.Benchmarks that seem to work with this service:
CL
— West Texas Intermediate or WTI, light sweet crudeBB
— Brent crude penultimate financial futuresBZ
— Brent look-alike crude oil futuresMB
— Gulf Coast Sour CrudeRE
— Russian Export Blend Crude Oil (REBCO) futuresGas spot prices that work:
NG
— Henry Hub physical futuresHH
— Henry Hub last day financial futuresSymbols that don't work:
DC
— Dubai crude calendar futuresWCC
— Canadian Heavy (differential, cf CL)WCE
— Western Canadian select crude oil futures (differential, cf CL) — but this seems to be the same price as WCC, which can't be rightLN
— European optionsAs an exercise, write a function to get the futures price for a given benchmark, based on the contract price 90 days from 'now', whenever now is.
In [12]:
import time
def get_symbol(benchmark):
future = time.gmtime(time.time() + 90*24*60*60)
mo = future.tm_mon
yr = future.tm_year
month_codes = 'FGHJKMNQUVXZ'
month = month_codes[mo]
year = str(yr)[-2:]
return benchmark + month + year + ".NYM"
This should work:
In [13]:
get_symbol('CL')
Out[13]:
© Agile Geoscience 2016