Diving into Python
In this section we present two short pieces of code that will serve as an informal introduction to Python, its syntax and a glimpse of its capabilities. All of the topics commented here are further discussed in the following chapters where we go through more particularities.
A first Python program
Let’s get started and take a look at our first Python code! Here it is:
def common_letter(word1, word2):
for x in word1:
if x in word2:
return True
return False
def main():
a = 'python'
b = input('Insert word: ')
if common_letter(a, b):
print('At least one letter in common with', a, '!')
else:
print('No letter in common...')
main()
That’s what happens when we execute it and input the following word:
Insert word: cookbook
At least one letter in common with python !
Analysing the code in greater detail, the first line that has been executed is the call to the function main()
. Next, in a = 'python'
we assign a name (a
) on the left with a value (the string 'python'
) on the right. Notice that there is no need to declare the type of variables.
The third line in order of execution is b = input('Insert word: ')
. It is analogous to the previous one but in this case, the value is given by the input()
function that reads a line, converts it to a string and returns it.
Once we have a
and b
defined, we would like to know if they share at least one letter. To do so, we encounter our first if
statement which is evaluated according to the call to the function common_letter(word1, word2)
.
In Python, functions are defined with the def
keyword and we don’t have to specify which type of object is returned. The body of the function is pretty self-explanatory. For each character in the first word we check if it is present in the second word. In case we find a coincidence we return True
or False
otherwise. Notice that Python doesn’t use curly brackets to group different code blocks. Instead, it relies on identation.
Finally, we use the print()
function in the body of the if
-else
clause.
So far so good.
A second Python program
Why don’t we take Python some steps further?
Rather than manually entering our data we can download it. The json
format is commonly used to exchange data between a server and a web application. For instance, http://wservice.viabicing.cat/v2/stations provides real-time information of the Barcelona city council bicycle service, Bicing. This address contains a json
file with the location of each station together with the number of bikes and slots available among others.
Find below a fragment of the file:
{
"stations": [
{
"id": "1",
"type": "BIKE",
"latitude": "41.397952",
"longitude": "2.180042",
"streetName": "Gran Via Corts Catalanes",
"streetNumber": "760",
"altitude": "21",
"slots": "29",
"bikes": "0",
"nearbyStations": "24, 369, 426",
"status": "CLS"
},
{
"id": "2",
"type": "BIKE",
"latitude": "41.39553",
"longitude": "2.17706",
"streetName": "Roger de Flor/ Gran Vía",
"streetNumber": "126",
"altitude": "21",
"slots": "8",
"bikes": "17",
"nearbyStations": "2",
"status": "OPN"
},
/* ... */
],
"updateTime": 1550096472
}
In order to download and read this file with Python we need to use two Python built-in modules: urllib.request
for opening the url
and json
to decode the file obtained:
import urllib.request
import json
response = urllib.request.urlopen('http://wservice.viabicing.cat/v2/stations')
bicing = json.load(response)
Essentially, the structure of the file is a dictionary with two keys: 'stations'
and 'updateTime'
. Inside of 'stations'
, we have a list of all the Bicing stations and, for each one, we have another dictionary with all its relevant information.
For instance, if you want to print the location of all the open stations, you can loop over bicing['stations']
in this natural way:
for station in bicing['stations']:
if station['status'] == 'OPN':
print(station['streetName'], station['streetNumber'])
To visualize this information on a map you can rely on a useful third-party module called Folium. It allows you to manipulate data in Python with minimal instructions and it gets the job done in the background. To install it you just need to open the Terminal (or the Anaconda Prompt on Windows) and enter the command
conda install folium
Once it is installed, you can import the module and start working:
import folium
BCN_COORDINATES = [41.390205, 2.154007]
# Create the base map
m = folium.Map(location=BCN_COORDINATES, tiles='Stamen Terrain', zoom_start=12)
At this point, if you display the map by just typing
>>> m
you will see the map of Barcelona magically appear.
Let’s now focus on bringing the open stations to the map m
. To do so, you can repeat the same loop as before and for each station define a marker from the folium
module and add it to the map:
for station in bicing['stations']:
if station['status'] == 'OPN':
lat, lon = float(station['latitude']), float(station['longitude'])
# Create new marker...
new_marker = folium.CircleMarker(location=[lat, lon])
# ... and add it to the map
new_marker.add_to(m)
Note that you need to parse the latitude and longitude into floats since in the loaded data they come as strings. Again, you can display m
to make sure that you are on the right path and all the open stations are marked:
Finally, you can enhance the visualization by means of changing the color of the stations according to how many bikes are available and adding pop-ups:
# Function that determines the color of the stations
def set_color(bikes, slots):
if bikes > slots:
return 'green'
elif 3*bikes > slots:
return 'orange'
return 'red'
# Iterate the list of stations
for station in bicing['stations']:
# Only interested in open stations
if station['status'] == 'OPN':
# Get the required information from the station
slots, bikes = int(station['slots']), int(station['bikes'])
lat, lon = float(station['latitude']), float(station['longitude'])
# Text that will appear in the marker
text = str(bikes) + '/' + str(bikes+slots) + ' available'
# Create new marker...
new_marker = folium.CircleMarker(location=[lat, lon], radius=7,
popup=text, fill_color=set_color(bikes, slots),
color='gray', fill_opacity=0.7)
# ... and add it to the map
new_marker.add_to(m)
# Save map
m.save('bicing-map.html')
You can download the full program here to obtain a map like this one!
Lliçons.jutge.org
Víctor Adell
Universitat Politècnica de Catalunya, 2023
Prohibit copiar. Tots els drets reservats.
No copy allowed. All rights reserved.