Geo-Python review
Contents
Geo-Python review¶
It has been requested that we review a few topics covered in the Geo-Python part of this course. This notebook presents the main topics and notes/examples generated during our discussion in class.
for loops¶
for loops are used to iterate over a collection of items and perform calculations using that collection. The collection could be something like a Python list, a NumPy array, or some other structure.
The structure of the loop is:
for variable in collection:
code
to
execute
where variable is a normal Python variable that will be assigned a value from collection sequentially as the loop is executed. All of the lines indented beneath the for statement contain code that will be run each time a new value from collection is assigned to variable.
Direct iteration¶
weather_conditions = ["Cloudy", "Snowing", "Rainy", "Windy"]
for weather in weather_conditions:
print(f"Today the weather is {weather}.")
Today the weather is Cloudy.
Today the weather is Snowing.
Today the weather is Rainy.
Today the weather is Windy.
Iteration using the range() function¶
# Example using index values
temperatures = ["Cold", "Unpleasant", "Blustery", "Cool"]
for i in range(len(temperatures)):
print(f"Today the weather is {temperatures[i]}.")
Today the weather is Cold.
Today the weather is Unpleasant.
Today the weather is Blustery.
Today the weather is Cool.
# Using index values to access items from 2 lists
for i in range(len(temperatures)):
print(f"Today the weather is {temperatures[i]} and {weather_conditions[i]}.")
Today the weather is Cold and Cloudy.
Today the weather is Unpleasant and Snowing.
Today the weather is Blustery and Rainy.
Today the weather is Cool and Windy.
Nested loops¶
# Not covered in today's lesson
Other loop notes¶
# None
Functions¶
Functions are designed to be used to perform calculations that are frequently used in a program. One of the key ideas of a function is to avoid having to repeat code within a program, as it is possible that repeating code may introduct typographic errors and it can be cumbersome to update the code if the same thing occurs in multiple places in a program.
The syntax of a function in Python is below:
def function_name(parameter1, parameter2=0.0, ...):
code
to
execute
return return_value
where function_name is the name of the function, and parameter1 and parameter2 are parameters (or the names of variables used within the function), default2 is a default value assigned to a function parameter, the indented code is that executed within the function, and the return statement lists the value(s) that will be returned when the function is used. Note that parameters with default values do not need to be listed when calling the function, and when defining the function the parameters without a default value must be listed first in the parameter list.
Function examples¶
def family_name_printer(first_name, last_name="Whipp"):
print(f"Hello {first_name} {last_name}!")
return 0
# This is OK
# Note: the function prints something and then the return value is displayed
family_name_printer("Dave")
Hello Dave Whipp!
0
# This is also OK
family_name_printer(first_name="Dave")
Hello Dave Whipp!
0
# This too is OK
family_name_printer(first_name="Dave", last_name="Smith")
Hello Dave Smith!
0
# So is this
family_name_printer("Dave", last_name="Smith")
Hello Dave Smith!
0
# This is not OK because "Dave" is ambiguous
# Is that value meant to be the second parameter or assigned to first_name?
# Python cannot tell, so you need to include the parameter name
family_name_printer(last_name="Smith", "Dave")
File "/tmp/ipykernel_280/2272524676.py", line 4
family_name_printer(last_name="Smith", "Dave")
^
SyntaxError: positional argument follows keyword argument
# Like this, all is OK
family_name_printer(last_name="Smith", first_name="Dave")
Hello Dave Smith!
0
# Note that first_name is not a variable available outside of the function
print(first_name)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/tmp/ipykernel_280/1852285805.py in <module>
1 # Note that first_name is not a variable available outside of the function
----> 2 print(first_name)
NameError: name 'first_name' is not defined
# Unless we define it first
first_name = "John"
print(first_name)
John
# Note that this does not affect the function use if first_name is assigned in the call
family_name_printer(first_name="Fred", last_name="Smith")
Hello Fred Smith!
0
# Let's define a middle_name variable
middle_name = "Michael"
# And we can modify our function to return middle_name
# NOTE: We do not pass in middle_name or define it in our function
def family_name_printer(first_name, last_name="Whipp"):
print(f"Hello {first_name} {last_name}!")
return middle_name
# Now look what is returned when the function is used
# Be careful!
family_name_printer(first_name="Fred", last_name="Smith")
Hello Fred Smith!
'Michael'
# Let's make a modified function where the string is returned rather than printed
def family_name_printer2(first_name, last_name="Whipp"):
return f"Hello {first_name} {last_name}!"
# Let's assign the returned value to a variable
name_output = family_name_printer2("Dave")
# And print...nice!
print(name_output)
Hello Dave Whipp!
# New function to add two to a number
def add_two(number):
"""Adds two to a number (duh)"""
return number + 2
# It works!
new_number = add_two(4)
print(new_number)
6
# But we can break it
# Note: This is a good example of a Pythonic way to have your code fail
# We let Python identify the problem, rather than checking that a number was passed
# into the function
new_number = add_two("Dave")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_280/3922626930.py in <module>
3 # We let Python identify the problem, rather than checking that a number was passed
4 # into the function
----> 5 new_number = add_two("Dave")
/tmp/ipykernel_280/1215093505.py in add_two(number)
2 def add_two(number):
3 """Adds two to a number (duh)"""
----> 4 return number + 2
TypeError: can only concatenate str (not "int") to str
# Having fun with formatting output :D
print(3 * '*' + 72 * '-' + 3 * '*')
***------------------------------------------------------------------------***
Namespaces and functions¶
# Covered above
Other function notes¶
# None
When to use which brackets¶
A common point of confusion in Python relates to when to use which kinds of brackets. There are three different types of brackets that are commonly used, and each are used for different purposes. Below you can find examples of each.
Parentheses - ( and )¶
Mathematical order of operations¶
Of course, the most natural example familiar to you would be to use parentheses in a mathematical equation to determine the order in which calculations should be done. Let’s consider an example.
# Parentheses matter
# Add 3 and 2, then divide by 2
(3 + 2) / 2
2.5
# Not equal to above!
# Divide 2 by 2, add 3 to result
3 + 2 / 2
4.0
Here, the parentheses determine the order in which the math operations occur and will have important implications for the resulting calculated value.
Defining and calling functions¶
When functions are defined and called, you also use parentheses to give the list of parameters.
# Functions use parentheses too
def add_divide(number1, number2, number3):
return (number1 + number2) / number3
# Same as the example above
add_divide(3, 2, 2)
2.5
Tuples¶
We have not dealt much with tuples so far, but they are similar to Python lists with one important difference: Tuples are immutable, meaning they cannot be changed after they are defined. Let’s see an example.
# Make an example tuple
my_tuple = (3.0, "Dave", True, 1)
# Check the data type
type(my_tuple)
tuple
# Tuples cannot be modified, this will fail!
my_tuple[1] = "John"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_280/1030788979.py in <module>
1 # Tuples cannot be modified, this will fail!
----> 2 my_tuple[1] = "John"
TypeError: 'tuple' object does not support item assignment
# Cannot append (modify) a tuple!
my_tuple.append('Whipp')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_280/2694787715.py in <module>
1 # Cannot append (modify) a tuple!
----> 2 my_tuple.append('Whipp')
AttributeError: 'tuple' object has no attribute 'append'
Square brackets - [ and ]¶
Python lists¶
As you have seen, the square brackets are used to create Python lists.
# Make a list
my_list = [3.0, "Dave", True, 1]
# Check the data type
type(my_list)
list
# Lists CAN be modified
my_list[1] = "John"
# Confirm list has changed
print(my_list)
[3.0, 'John', True, 1]
Accessing values using index values¶
Another common use of the square brackets in Python is to access values from Python lists, tuples, or other collections using an index value.
# Check a value in our list
my_list[1]
'John'
# Check that values in the list and tuple are the same at the same position...yes!
my_list[3] == my_tuple[3]
True
# Check that values in the list and tuple are the same at the same position...no!
# Names were changed
my_list[1] == my_tuple[1]
False
Curly braces - { and }¶
Dictionaries¶
We have only dealt with dictionaries to a limited extent so far, but they can be used to relate a “key” in the dictionary to a “value”, as shown below.
dictionary_name = {key1: value1, key2: value2, ...}
where dictionary_name is the name of the dictionary, and the keys (key1, key2) are listed and followed by a : character that is followed by a corresponding value (value1, value2). This allows you to find a value using its associated key. This may be easiest to understand through an example.
# Create a dictionary
my_dict = {"Helsinki": "Cloudy", "Hyvinkää": "Snowy"}
# Check the data type
type(my_dict)
dict
# Use a key to access a value
my_dict["Hyvinkää"]
'Snowy'
Sets¶
Sets are yet another type of collection in Python, however they are slightly different from lists and tuples. In a Python set you can create a collection, but one that is not indexed and cannot contain duplicate values. Let’s look at an example again.
# Create a set
my_set = {3.0, "Dave", 1, 2}
# Check the data type
type(my_set)
set
# Sets are unindexed. Cannot use indices to get values!
my_set[1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_280/3507569771.py in <module>
1 # Sets are unindexed. Cannot use indices to get values!
----> 2 my_set[1]
TypeError: 'set' object is not subscriptable
# Check set contents
print(my_set)
{1, 2, 3.0, 'Dave'}
# Create another set
my_set = {3.0, "Dave", 1, True, "Dave"}
# Check set contents. What???
# Sets do not allow duplicate values, so the name "Dave" can only occur once
# We have also guessed that True is converted to 1 and thus does not appear separately!
# Often 0 = False and 1 = True in programming languages
print(my_set)
{1, 3.0, 'Dave'}
F-strings¶
# F-strings also use curly braces to enclose variables
print(f"My name is {first_name}.")
My name is John.
Other notes¶
Looping over dictionary keys and values¶
Dictionaries are quite handy data structures in Python, and often there is a need to use loops to find the values for each key in the dictionary. Below is a silly example.
animal_sound = {"dog": "woof", "cat": "meow", "bird": "chirp"}
for key, value in animal_sound.items():
print(f"The {key} goes {value}.")
The dog goes woof.
The cat goes meow.
The bird goes chirp.
Checking variables defined in memory¶
You can check to see what is defined in the notebook by running %whos.
%whos
Variable Type Data/Info
--------------------------------------------
add_divide function <function add_divide at 0x7f96f0150200>
add_two function <function add_two at 0x7f96f0191b00>
animal_sound dict n=3
family_name_printer function <function family_name_printer at 0x7f96f01915f0>
family_name_printer2 function <function family_name_printer2 at 0x7f96f0191440>
first_name str John
i int 3
key str bird
middle_name str Michael
my_dict dict n=2
my_list list n=4
my_set set {1, 3.0, 'Dave'}
my_tuple tuple n=4
name_output str Hello Dave Whipp!
new_number int 6
temperatures list n=4
value str chirp
weather str Windy
weather_conditions list n=4