\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
]
}
],
"source": [
"a = 3/5\n",
"b = 10\n",
"print b/a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"What did just happen here? Can you find what caused this *bug* and fix it?\n",
"
\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Control structures: loops and conditionals\n",
"\n",
"So far, we have seen how to store data, and how to do things with it. However, we do not have the ability to control what happens. To do this, we would need to be able to repeat some actions varying some parameters, and we would need to be able to control the flow of things by checking some conditions. The former kind of structures usually go by the name of *loops*, whereas the second are usually called *conditionals*.\n",
"\n",
"### `for` loops\n",
"\n",
"The most common loop is the `for` loop. The `for` loop iterates over a sequence (e.g. a list), giving the value of each element in turn. Once it reaches the end of the sequence, the program flow continues in the next line. In Python, the contents of the loop (i.e. the things that get executed for each iteration of the loop) are indented by a tab stop. Let's see how this works. Let's print the average monthly temperatures for our previous stations in March:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:16:04.706203Z",
"start_time": "2017-10-10T15:16:04.695944Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
">>> At the start of the loop\n",
"10.5 \t9.8 \t10.5 \t\n",
">>> At the end of the loop\n"
]
}
],
"source": [
"print \">>> At the start of the loop\"\n",
"for station in [\"Hull\", \"Sheffield\", \"Hampstead\"]:\n",
" print climatology[station][2], \"\\t\",\n",
"print\n",
"print \">>> At the end of the loop\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We see that the loop variable (`station`) sequentially takes the values in the list. The other interestig bit is that the print statement within the loop has a `,` at the end to prevent a new line character every time it is executed. Note the indentation of the print statement as well.\n",
"\n",
"We can also *nest* loops within loops. For example, we might want print a table with the climatology for each month in every row, and the different stations in different columns. Further, we might want to add a first column with the name of the month. To this end, we'll store the month names in a list in order. We will use the `enumerate` method applied to the loop iterator to get the right position for the month:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:16:06.535608Z",
"start_time": "2017-10-10T15:16:06.520963Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jan \t7.3 \t6.8 \t7.1\n",
"Feb \t7.9 \t7.1 \t7.4\n",
"Mar \t10.5 \t9.8 \t10.5\n",
"Apr \t12.9 \t12.5 \t13.3\n",
"May \t16.1 \t16.1 \t16.8\n",
"Jun \t19.1 \t18.8 \t19.9\n",
"Jul \t21.6 \t21.1 \t22.4\n",
"Aug \t21.5 \t20.6 \t22.0\n",
"Sep \t18.6 \t17.7 \t18.8\n",
"Oct \t14.5 \t13.5 \t14.6\n",
"Nov \t10.3 \t9.5 \t10.3\n",
"Dec \t7.6 \t6.9 \t7.4\n"
]
}
],
"source": [
"month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n",
"\n",
"for imonth, month in enumerate(month_name):\n",
" print month,\n",
" for station in [\"Hull\", \"Sheffield\", \"Hampstead\"]:\n",
" print \"\\t\", climatology[station][imonth], \n",
" print\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following snippet has the climatology for the different stations above as multi-line strings (data comes from the [Met Office](https://www.metoffice.gov.uk/public/weather/climate)). The different columns are:\n",
"\n",
"1. Month\n",
"2. Max. temp(°C)\n",
"3. Min. temp (°C)\n",
"4. Days of air frost (days)\n",
"5. Sunshine (hours)\n",
"6. Rainfall (mm)\n",
"7. Days of rainfall >= 1 mm (days)\n",
"8. Monthly mean wind speed at 10m (knots)\n",
"\n",
"Try the following things:\n",
"\n",
"\n",
"For one station, store the monthly temperatures (or other variable as a list)\n",
"
\n",
" **HINT** You can loop over the lines by splitting each string by `\\n`, and can then further split each line by `\\t` tab stops. Remember that you want to have temperatures as numbers, so you'll have to convert the string of interest!\n",
"
\n",
"
\n",
"\n",
"\n",
"For one station, calculate the total number of sunshine hours in a year\n",
"
\n",
"\n",
"\n",
"For one station, calculate the average annual maximum and minimum temperatures\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:14:54.504339Z",
"start_time": "2017-10-10T15:14:54.493515Z"
}
},
"outputs": [],
"source": [
"hull_txt = \"\"\"Jan\t7.3\t1.9\t7.8\t54.8\t55.2\t11.8\tn/a\n",
"Feb\t7.9\t1.8\t8.0\t76.3\t44.1\t9.3\tn/a\n",
"Mar\t10.5\t3.3\t3.8\t110.6\t49.0\t11.1\tn/a\n",
"Apr\t12.9\t4.8\t1.6\t151.2\t50.9\t10.0\tn/a\n",
"May\t16.1\t7.5\t0.1\t195.4\t49.8\t9.3\tn/a\n",
"Jun\t19.1\t10.4\t0.0\t177.1\t66.5\t9.5\tn/a\n",
"Jul\t21.6\t12.7\t0.0\t193.8\t56.1\t9.0\tn/a\n",
"Aug\t21.5\t12.5\t0.0\t181.1\t60.7\t9.1\tn/a\n",
"Sep\t18.6\t10.5\t0.0\t145.1\t61.0\t9.1\tn/a\n",
"Oct\t14.5\t7.7\t0.5\t111.7\t61.2\t10.8\tn/a\n",
"Nov\t10.3\t4.5\t3.0\t65.4\t62.9\t12.3\tn/a\n",
"Dec\t7.6\t2.2\t7.7\t50.5\t62.5\t11.7\tn/a\"\"\"\n",
"\n",
"sheffield_txt = \"\"\"Jan\t6.8\t1.9\t8.0\t45.2\t83.4\t13.4\tn/a\n",
"Feb\t7.1\t1.7\t9.0\t68.3\t60.4\t10.5\tn/a\n",
"Mar\t9.8\t3.3\t3.9\t111.9\t63.4\t12.3\tn/a\n",
"Apr\t12.5\t4.8\t1.4\t144.0\t65.5\t10.3\tn/a\n",
"May\t16.1\t7.5\t0.0\t190.9\t53.8\t9.6\tn/a\n",
"Jun\t18.8\t10.5\t0.0\t179.5\t75.6\t9.1\tn/a\n",
"Jul\t21.1\t12.7\t0.0\t199.5\t56.0\t9.2\tn/a\n",
"Aug\t20.6\t12.4\t0.0\t185.0\t65.3\t9.9\tn/a\n",
"Sep\t17.7\t10.3\t0.0\t136.2\t63.8\t8.9\tn/a\n",
"Oct\t13.5\t7.5\t0.5\t90.7\t81.2\t12.7\tn/a\n",
"Nov\t9.5\t4.5\t3.1\t53.7\t79.4\t12.6\tn/a\n",
"Dec\t6.9\t2.3\t7.9\t40.0\t86.7\t13.0\tn/a\"\"\"\n",
"hampstead_txt = \"\"\"Jan\t7.1\t2.0\t8.6\t57.5\t64.7\t12.0\tn/a\n",
"Feb\t7.4\t1.7\t9.5\t76.4\t46.6\t9.7\tn/a\n",
"Mar\t10.5\t3.5\t4.0\t107.1\t48.9\t10.2\tn/a\n",
"Apr\t13.3\t5.0\t1.5\t151.6\t51.5\t9.9\tn/a\n",
"May\t16.8\t8.0\t0.1\t192.2\t58.0\t9.5\tn/a\n",
"Jun\t19.9\t10.9\t0.0\t191.0\t54.2\t9.0\tn/a\n",
"Jul\t22.4\t13.2\t0.0\t199.9\t50.4\t8.5\tn/a\n",
"Aug\t22.0\t13.1\t0.0\t193.0\t64.4\t8.9\tn/a\n",
"Sep\t18.8\t11.0\t0.0\t140.8\t56.9\t8.8\tn/a\n",
"Oct\t14.6\t8.1\t0.3\t109.9\t77.7\t11.0\tn/a\n",
"Nov\t10.3\t4.8\t2.9\t69.4\t68.3\t11.4\tn/a\n",
"Dec\t7.4\t2.5\t7.7\t51.6\t62.9\t11.4\tn/a\"\"\"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### `if/elif/else` conditionals\n",
"\n",
"A conditional `if` loop allows for different actions to be taken when a situation is true. For example, you may want to check that a number is positive before you do something with it. An `if` statement allows you to have a block of instructions that are executed when the experssion in the `if` statement evaluates to `True`. For example, if we just want to report months where the temperature in Hampstead is greater than 15 degrees..."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:17:33.169791Z",
"start_time": "2017-10-10T15:17:33.161734Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"May \t16.8\n",
"Jun \t19.9\n",
"Jul \t22.4\n",
"Aug \t22.0\n",
"Sep \t18.8\n"
]
}
],
"source": [
"for imonth, month in enumerate(month_name):\n",
" if climatology[\"Hampstead\"][imonth] >= 15:\n",
" print month, \"\\t\", climatology[station][imonth]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`if` statements can evaluate multiple conditions, each with a different set of actions. We can add additional tests with the `elif` statement, and you should always also have an `else` statement, which is triggered if neither the `if` or any other `elif` statements have been true. "
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:21:19.669375Z",
"start_time": "2017-10-10T15:21:19.658343Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jan \t7.1 -> Brrrr..\n",
"Feb \t7.4 -> Brrrr..\n",
"Mar \t10.5 -> Brrrr..\n",
"Apr \t13.3 -> Jumper\n",
"May \t16.8 -> Jumper\n",
"Jun \t19.9 -> Jumper\n",
"Jul \t22.4 -> Shorts\n",
"Aug \t22.0 -> Shorts\n",
"Sep \t18.8 -> Jumper\n",
"Oct \t14.6 -> Jumper\n",
"Nov \t10.3 -> Brrrr..\n",
"Dec \t7.4 -> Brrrr..\n"
]
}
],
"source": [
"for imonth, month in enumerate(month_name):\n",
" if climatology[\"Hampstead\"][imonth] >= 20:\n",
" print month, \"\\t\", climatology[station][imonth], \"->\", \"Shorts\"\n",
" elif climatology[\"Hampstead\"][imonth] >= 12:\n",
" print month, \"\\t\", climatology[station][imonth], \"->\", \"Jumper\"\n",
" else:\n",
" print month, \"\\t\", climatology[station][imonth], \"->\", \"Brrrr..\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also note the order of how the different tests are done: first, we check the first `if` statement. If this evaluates to true (in this case, temperature is more than 20 degrees), this code block is executed (prints `Shorts`). If this isn't true, then we test the first `elif` statement, and if true, it will take action (print `Jumper`). If it isn't true, then it goes to the `else` statement, and once the code is here, it will get executed (print `Brrrr`)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Files and remote streams\n",
"\n",
"### Writing a text file\n",
"\n",
"In Python, working with files is quite straightforward: you open a file (either for reading or writing), you read from it (or write to it), and then close it. Let's just write our climatology to a file as a [CSV file](https://en.wikipedia.org/wiki/Comma-separated_values):"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:35:35.973398Z",
"start_time": "2017-10-10T15:35:35.960792Z"
}
},
"outputs": [],
"source": [
"fp = open (\"climatology.txt\", 'w') # Open the file for WRITING!\n",
"\n",
"fp.write(\"#Month,Hull,Sheffield,Hampstead\\n\") # Write file header\n",
"for imonth, month in enumerate(month_name):\n",
" fp.write (month) # Write month name to file\n",
" for station in [\"Hull\", \"Sheffield\", \"Hampstead\"]:\n",
" fp.write(\",{}\".format(climatology[station][imonth]))\n",
" # Write \",\" and temperature for current month and station\n",
" fp.write(\"\\n\")\n",
" # Add new line\n",
"fp.close() # close file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So we do the following:\n",
"\n",
"1. Open the file for writing (`w` option)\n",
"2. Write a string (terminated with a new line `\\n` character) with the header of the file\n",
"3. For each month, write the month name, as well as the temperature of every station\n",
"4. Once all months have gone, close the file\n",
"\n",
"We can check the file contents by using the `cat` command in the UNIX shell (you can get it through the notebook by prepending it with the `!` symbol):\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:35:38.041778Z",
"start_time": "2017-10-10T15:35:37.930727Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jan,7.3,6.8,7.1\r\n",
"Feb,7.9,7.1,7.4\r\n",
"Mar,10.5,9.8,10.5\r\n",
"Apr,12.9,12.5,13.3\r\n",
"May,16.1,16.1,16.8\r\n",
"Jun,19.1,18.8,19.9\r\n",
"Jul,21.6,21.1,22.4\r\n",
"Aug,21.5,20.6,22.0\r\n",
"Sep,18.6,17.7,18.8\r\n",
"Oct,14.5,13.5,14.6\r\n",
"Nov,10.3,9.5,10.3\r\n",
"Dec,7.6,6.9,7.4\r\n"
]
}
],
"source": [
"!cat climatology.txt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here, we have used [string format templates](https://pyformat.info/) (you can also use older-fashioned [C style templates](https://www.learnpython.org/en/String_Formatting)) to substitute parts of a string. Basically, `\",{}\".format(14.9)` will substitute the floating point 14.9 in the space occupied by the curly braces. You can also specify what format you want the number in. For example, if we want to have zero padding and 5 decimal places, we could have written `\",{:08.5f}\".format(14.9)`"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:44:50.657536Z",
"start_time": "2017-10-10T15:44:50.653412Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
",14.90000\n"
]
}
],
"source": [
"print \",{:08.5f}\".format(14.9)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Reading a text file\n",
"\n",
"Once a file is opened for reading, you can usually read it line by line. Each line will be string, and string methods will be of great use here. So, to open the file we saved previously, and print the months and temperature in Sheffield **only** when it's over 18 degrees, we would:\n"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T15:51:45.256376Z",
"start_time": "2017-10-10T15:51:45.247203Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jun 18.8\n",
"Jul 21.1\n",
"Aug 20.6\n"
]
}
],
"source": [
"with open(\"climatology.txt\", 'r') as fp:\n",
" for line in fp:\n",
" x = line.split(\",\")\n",
" month = x[0]\n",
" temp = float(x[2])\n",
" if temp > 18:\n",
" print month, temp"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `with` statement is a context manager. Basically, it will open the file, and if succesful, it will do whatever is within the `with` indented block. At the end, it will automatically close the file. As it is, it's a much safer way of dealing with files than presented above, as the contents of the file are not guaranteed to be in present in the file unless the file has been properly closed.\n",
"\n",
"### Accessing online resources\n",
"\n",
"We will briefly see how to access a text file on the internet (remember that the vast majority of content on the web can be accessed as a text file!). To do this, we will need to **import** a Python module. Python modules provide extra capacities, and allow you to do more stuff. A Python module has been written by someone and is usually read to use. You could (and should) use these modules in your code. Python comes with a [ton of modules by default](https://docs.python.org/2/library/index.html).\n",
"\n",
"Here, we'll use a module that isn't part of the default Python library, but that it's installed on the system here at UCL: the [`requests`](http://docs.python-requests.org/en/master/) module. We will demonstrate how to get a text file with El Niño/Southern Oscillation (ENSO) anomalies from NOAA (you can find [more information here](https://www.esrl.noaa.gov/psd/enso/mei)). The data are available under the following URL: [https://www.esrl.noaa.gov/psd/enso/mei/table.html](https://www.esrl.noaa.gov/psd/enso/mei/table.html). We will just \n",
"1. Get the remote data\n",
"2. Check that it worked\n",
"3. Print a few lines of data (the values between years 2005 and 2015, for example)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T16:07:08.824598Z",
"start_time": "2017-10-10T16:07:08.290790Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2005\t.32\t.81\t1.067\t.637\t.893\t.612\t.519\t.362\t.329\t-.167\t-.392\t-.57\n",
"2006\t-.438\t-.424\t-.527\t-.575\t.043\t.546\t.718\t.77\t.84\t.955\t1.286\t.951\n",
"2007\t.985\t.528\t.12\t.02\t.354\t-.136\t-.247\t-.427\t-1.175\t-1.217\t-1.165\t-1.193\n",
"2008\t-1.02\t-1.388\t-1.579\t-.879\t-.349\t.164\t.089\t-.252\t-.545\t-.692\t-.597\t-.663\n",
"2009\t-.726\t-.707\t-.723\t-.105\t.328\t.779\t1.06\t1.073\t.745\t.909\t1.121\t1.045\n",
"2010\t1.067\t1.52\t1.469\t.99\t.668\t-.211\t-1.099\t-1.662\t-1.86\t-1.899\t-1.49\t-1.577\n",
"2011\t-1.739\t-1.563\t-1.575\t-1.399\t-.202\t.016\t-.191\t-.502\t-.751\t-.933\t-.949\t-.957\n",
"2012\t-.993\t-.695\t-.398\t.112\t.769\t.866\t1.128\t.628\t.351\t.081\t.125\t.094\n",
"2013\t.096\t-.08\t-.037\t.095\t.203\t-.078\t-.311\t-.466\t-.125\t.13\t-.053\t-.248\n",
"2014\t-.275\t-.266\t.027\t.312\t1.01\t1.057\t.921\t.961\t.593\t.438\t.763\t.558\n",
"2015\t.42\t.459\t.631\t.943\t1.592\t2.101\t1.987\t2.365\t2.532\t2.241\t2.297\t2.112\n"
]
}
],
"source": [
"url = \"https://www.esrl.noaa.gov/psd/enso/mei/table.html\"\n",
"import requests\n",
"r = requests.get(url)\n",
"if r.ok:\n",
" for i, line in enumerate(r.text.split(\"\\n\")):\n",
" if 68 < i < 80:\n",
" print line"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Some fun exercises\n",
"\n",
"[Transport for London (TfL)](http://www.tfl.gov.uk/) publishes most of its data using an [API](https://blog.tfl.gov.uk/2015/10/01/tfl-unified-api-part-1-introduction/). Basically, you can query a URL (maybe even passing some parameters), and the TfL server will send you some information. For example, to get the forecast on air quality, the URL is [https://api.tfl.gov.uk/AirQuality](https://api.tfl.gov.uk/AirQuality). If you click on that link, you will see that it returns a text file with some interesting format: a [JSON file](http://www.json.org/). However, we can treat it as a text file, and we can try to get the forecast for tomorrow, by noting how the file structure works.\n",
"\n",
"* There are two lines: current conditions and forecast\n",
"* The forecast appears after the tag `forecastText`\n",
"* We note that the carriage returns are encoded as `\"<br/>`\n",
"\n",
"A simple snippet that will work is this one"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T16:14:17.523384Z",
"start_time": "2017-10-10T16:14:17.426824Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\"Wednesday is expected to be mainly dry, but showers are forecast during the afternoon and evening. \n",
"\n",
"Similarly breezy conditions to Tuesday should give good dispersal of locally-emitted pollutants while the continued Atlantic air feed will carry very little by way of imported pollution. \n",
"\n",
"Air pollution is expected to remain 'Low' for the following pollutants throughout the forecast period:\n",
"\n",
"Nitrogen Dioxide\n",
"Ozone\n",
"PM10 Particulates\n",
"PM2.5 Particulates\n",
"Sulphur Dioxide\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\"\n",
"\n",
"\n"
]
}
],
"source": [
"import requests\n",
"\n",
"r = requests.get (\"https://api.tfl.gov.uk/AirQuality\")\n",
"for i,line in enumerate(r.text.split(\"}\")):\n",
" if i > 0:\n",
" iloc = line.find ('\"forecastText\":')\n",
" the_text = line[(iloc+len('\"forecastText\":')):]\n",
" the_text = the_text.replace(\"<br/>\", \"\\n\")\n",
" print the_text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, if we import the [`json`](https://pymotw.com/2/json/) module from the Python standard library, we can access all the information as a simple Python dictionary. The structure looks like this:\n",
"\n",
"```json\n",
"{\n",
" \"$id\": \"1\",\n",
" \"$type\": \"Tfl.Api.Presentation.Entities.LondonAirForecast, Tfl.Api.Presentation.Entities\",\n",
" \"currentForecast\": [\n",
" {\n",
" \"$id\": \"2\",\n",
" \"$type\": \"Tfl.Api.Presentation.Entities.CurrentForecast, Tfl.Api.Presentation.Entities\",\n",
" \"forecastBand\": \"Low\",\n",
" \"forecastID\": \"12771\",\n",
" \"forecastSummary\": \"Low air pollution forecast valid from Tuesday 10 October to end of Tuesday 10 October GMT\",\n",
" \"forecastText\": \"A largely cloudy and relatively mild day for Tuesday as a weak Atlantic weather front moves across south-east England. Increasingly breezy conditions should give good dispersal of locally-emitted pollutants while the Atlantic air feed will carry very little by way of imported pollution.<br/><br/>Air pollution is expected to remain 'Low' for the following pollutants throughout the forecast period:<br/><br/>Nitrogen Dioxide<br/>Ozone<br/>PM10 Particulates<br/>PM2.5 Particulates<br/>Sulphur Dioxide<br/><br/><br/><br/>\",\n",
" \"forecastType\": \"Current\",\n",
" \"fromDate\": \"2017-10-10T00:00:00Z\",\n",
" \"nO2Band\": \"Low\",\n",
" \"o3Band\": \"Low\",\n",
" \"pM10Band\": \"Low\",\n",
" \"pM25Band\": \"Low\",\n",
" \"publishedDate\": \"2017-09-10T11:58:00Z\",\n",
" \"sO2Band\": \"Low\",\n",
" \"toDate\": \"2017-10-10T23:59:00Z\"\n",
" },\n",
" {\n",
" \"$id\": \"3\",\n",
" \"$type\": \"Tfl.Api.Presentation.Entities.CurrentForecast, Tfl.Api.Presentation.Entities\",\n",
" \"forecastBand\": \"Low\",\n",
" \"forecastID\": \"12772\",\n",
" \"forecastSummary\": \"Low air pollution forecast valid from Wednesday 11 October to end of Wednesday 11 October GMT\",\n",
" \"forecastText\": \"Wednesday is expected to be mainly dry, but showers are forecast during the afternoon and evening. <br/><br/>Similarly breezy conditions to Tuesday should give good dispersal of locally-emitted pollutants while the continued Atlantic air feed will carry very little by way of imported pollution. <br/><br/>Air pollution is expected to remain 'Low' for the following pollutants throughout the forecast period:<br/><br/>Nitrogen Dioxide<br/>Ozone<br/>PM10 Particulates<br/>PM2.5 Particulates<br/>Sulphur Dioxide<br/><br/><br/><br/><br/><br/>\",\n",
" \"forecastType\": \"Future\",\n",
" \"fromDate\": \"2017-11-10T00:00:00Z\",\n",
" \"nO2Band\": \"Low\",\n",
" \"o3Band\": \"Low\",\n",
" \"pM10Band\": \"Low\",\n",
" \"pM25Band\": \"Low\",\n",
" \"publishedDate\": \"2017-10-10T09:25:00Z\",\n",
" \"sO2Band\": \"Low\",\n",
" \"toDate\": \"2017-11-10T23:59:00Z\"\n",
" }\n",
" ],\n",
" \"disclaimerText\": \"This forecast is intended to provide information on expected pollution levels in areas of significant public exposure. It may not apply in very specific locations close to unusually strong or short-lived local sources of pollution.\",\n",
" \"forecastURL\": \"http://londonair.org.uk/forecast\",\n",
" \"updateFrequency\": \"1\",\n",
" \"updatePeriod\": \"hourly\"\n",
"}```\n",
"\n",
"We see that we have both a current and a future forecast, and that these appear to be under the key `currentForecast` stored as a list. We can replicate our previous work as:"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"ExecuteTime": {
"end_time": "2017-10-10T16:28:40.976733Z",
"start_time": "2017-10-10T16:28:40.883049Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"[u'updateFrequency', u'updatePeriod', u'disclaimerText', u'$id', u'$type', u'currentForecast', u'forecastURL']\n",
"Wednesday is expected to be mainly dry, but showers are forecast during the afternoon and evening. \n",
"\n",
"Similarly breezy conditions to Tuesday should give good dispersal of locally-emitted pollutants while the continued Atlantic air feed will carry very little by way of imported pollution. \n",
"\n",
"Air pollution is expected to remain 'Low' for the following pollutants throughout the forecast period:\n",
"\n",
"Nitrogen Dioxide\n",
"Ozone\n",
"PM10 Particulates\n",
"PM2.5 Particulates\n",
"Sulphur Dioxide\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n"
]
}
],
"source": [
"import json\n",
"r = requests.get (\"https://api.tfl.gov.uk/AirQuality\")\n",
"if r.ok:\n",
" air_quality = json.loads(r.text)\n",
" print type(air_quality)\n",
" print air_quality.keys()\n",
" \n",
"print air_quality[\"currentForecast\"][1][\"forecastText\"].replace(\"<br/>\", \"\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exploring public transport outside Gower Street\n",
"\n",
"* You should be able to find out what (and when) buses will arrive at the bus stop outside UCL in Gower Street (the bus stop code is `490013914N`). Some context [here](https://blog.tfl.gov.uk/2015/12/07/unified-api-part-5-aot-arrivals-of-things/), but the URL is broadly `https://api.tfl.gov.uk/StopPoint/490013914N/arrivals`.\n",
"* TfL has information on all bike docking stations. You can get the entire status from this URL: [`https://api.tfl.gov.uk/bikepoint`](https://api.tfl.gov.uk/bikepoint). You should be able to find the one near to Gower Place, and find out how many free bikes are present"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": true,
"toc_cell": true,
"toc_position": {},
"toc_section_display": "block",
"toc_window_display": true
}
},
"nbformat": 4,
"nbformat_minor": 2
}