This notebook contains material for CBE 20258 Numerical and Statistical Analysis taught at the University of Notre Dame. (c) Professors Alexander Dowling, Ryan McClarren, and Yamil Colón. This collection of notebooks cbe-xx258 is available on Github.

In [ ]:
# IMPORT DATA FILES USED BY THIS NOTEBOOK
import os,  requests

file_links = [("data/ChemicalSymbols.csv", "https://ndcbe.github.io/cbe-xx258/data/ChemicalSymbols.csv")]

# This cell has been added by nbpages. Run this cell to download data files required for this notebook.

for filepath, fileurl in file_links:
    stem, filename = os.path.split(filepath)
    if stem:
        if not os.path.exists(stem):
            os.mkdir(stem)
    if not os.path.isfile(filepath):
        with open(filepath, 'wb') as f:
            response = requests.get(fileurl)
            f.write(response.content)

1.5 List, Dictionaries, and Enumeration

Reference: Chapters 2 and 5 of Computational Nuclear Engineering and Radiological Science Using Python, R. McClarren (2018)

1.5.1 Learning Objectives

After studying this notebook, completing the activities, and asking questions in class, you should be able to:

1.5.2 Lists

You can also do other fun stuff with for loops. For instance, you can have the control variable take on non-numeric things:

In [1]:
#silly hat code
hats = ["fedora","trilby","porkpie","tam o'shanter",
        "Phrygian cap","Beefeaters' hat","sombrero"]
days = ["Monday","Tuesday","Wednesday","Thursday",
        "Friday","Saturday","Sunday"]
count = 0
for today in hats:
    print("It is",days[count],"and I will wear a",today)
    count += 1
It is Monday and I will wear a fedora
It is Tuesday and I will wear a trilby
It is Wednesday and I will wear a porkpie
It is Thursday and I will wear a tam o'shanter
It is Friday and I will wear a Phrygian cap
It is Saturday and I will wear a Beefeaters' hat
It is Sunday and I will wear a sombrero

Notice what else we did here: we defined a list called days that contained strings for the names of the days of the week. Inside our for loop we had a numeric variable that kept track of what number the day of the week was (0 for Monday in this case). Then when we access days[count] it returns the string in position count.

We can go one step beyond and plan our wardrobe a month in advance using random numbers. The code below generates a random integer between 0 and 6:

In [2]:
import random
my_random_number = round(random.uniform(0,6))
print(my_random_number)
0
Home Activity: Modify the code below to loop over 30 days. For each day, randomly select which hat to wear.
In [3]:
#silly hat code
import random
hats = ["fedora","trilby","porkpie","tam o'shanter",
        "Phrygian cap","Beefeaters' hat","sombrero"]
days = ["Monday","Tuesday","Wednesday","Thursday",
        "Friday","Saturday","Sunday"]

# loop over 30 days
# YOUR SOLUTION HERE
It is Monday and I will wear a tam o'shanter
It is Tuesday and I will wear a Phrygian cap
It is Wednesday and I will wear a Beefeaters' hat
It is Thursday and I will wear a Beefeaters' hat
It is Friday and I will wear a Phrygian cap
It is Saturday and I will wear a porkpie
It is Sunday and I will wear a trilby
It is Monday and I will wear a trilby
It is Tuesday and I will wear a fedora
It is Wednesday and I will wear a sombrero
It is Thursday and I will wear a tam o'shanter
It is Friday and I will wear a sombrero
It is Saturday and I will wear a trilby
It is Sunday and I will wear a porkpie
It is Monday and I will wear a Phrygian cap
It is Tuesday and I will wear a tam o'shanter
It is Wednesday and I will wear a Phrygian cap
It is Thursday and I will wear a Beefeaters' hat
It is Friday and I will wear a Phrygian cap
It is Saturday and I will wear a trilby
It is Sunday and I will wear a Phrygian cap
It is Monday and I will wear a Beefeaters' hat
It is Tuesday and I will wear a trilby
It is Wednesday and I will wear a Beefeaters' hat
It is Thursday and I will wear a Phrygian cap
It is Friday and I will wear a Phrygian cap
It is Saturday and I will wear a Beefeaters' hat
It is Sunday and I will wear a tam o'shanter
It is Monday and I will wear a Beefeaters' hat
It is Tuesday and I will wear a trilby

Lists are like vectors in MATLAB, except, as you can see above, we can store more than just numbers in them. We will talk about using a package numpy to represent vectors and matrices next class session.

Home Activity: Fix the three examples below to count from 1 to 10.
In [4]:
## Attempt 1
N = [1, 2, 3, 4, 5, 6, 7, 11]
for i in range(len(N)):
    print(i+1)
1
2
3
4
5
6
7
8
In [5]:
# YOUR SOLUTION HERE
1
2
3
4
5
6
7
8
9
10
In [6]:
## Attempt 2
N = [1, 2, 3, 4, 5, 6, 7, 11]
for i in range(len(N)):
    print(N[i])
1
2
3
4
5
6
7
11
In [7]:
# YOUR SOLUTION HERE
1
2
3
4
5
6
7
8
9
10
In [8]:
## Attempt 3
for i in range(0,10):
    print(i)
0
1
2
3
4
5
6
7
8
9
In [9]:
# YOUR SOLUTION HERE
1
2
3
4
5
6
7
8
9
10

1.5.3 Dictionaries

So far, we have used lists to store a sequence of numbers or more generally Python objects. Lists (and NumPy arrays - stay tuned) access elements by position and have an inherent ordering.

A dictionary is a set of key : value pairs. You can think of a dictionary as a fancy list that instead of accessing via the position, you access using a key.

In [10]:
#simple dictionary
days_of_week = {"M":"Monday", "T":"Tuesday",
                "W":"Wednesday", "R":"Thursday",
                "F":"Friday", "S":"Saturday",
                "U":"Sunday"}

print("Key M gives", days_of_week["M"])
print("Key R gives", days_of_week["R"])
Key M gives Monday
Key R gives Thursday
Home Activity: Store the value for key F in the variable answer.
In [11]:
# YOUR SOLUTION HERE
In [12]:
 

Calling days_of_week.keys() returns a special list of the keys of the dictionary.

In [13]:
print(days_of_week.keys())
dict_keys(['M', 'T', 'W', 'R', 'F', 'S', 'U'])

We can also check if G is a valid key for the dictionary.

In [14]:
print("G" in days_of_week.keys()) #is G a key in days_of_week?
False

Main idea: With dictionaries, we access elements using the key. In contrast, we access elements of strings, lists, and Numpy arrays using the position.

1.5.3.1 Example: Shopping List

Home Activity: Create a dictionary to store the following shopping list. The keys should be the item names and the elements should be the quantity of the items.
  • 1.5 bannas (pounds)
  • 3 cans of soup
  • 6 apples
  • 2.3 pork tenderloin (pounds)
In [15]:
# YOUR SOLUTION HERE
{'bananas (pounds)': 1.5, 'cans of soup': 3, 'apples': 6, 'pork tenderloin (pounds)': 2.3}
In [16]:
 

1.5.3.2 Another Example: Chemical Symbols and Element Names

Below is code that parses ChemicalSymbols.csv and stores the data in dictionary.

In [18]:
import csv
element_dict = {} #create a blank dictionary

# this block will only execute if the file opens
with open('./data/ChemicalSymbols.csv') as csvfile: 
    chemreader = csv.reader(csvfile)
    for row in chemreader: # have for loop that loops over each line
        element_dict[row[0]] = row[1] # add a key:value pair

# Ask user to enter a chemical symbol        
key = input("Enter a valid chemical symbol: ")
if key in element_dict:
    print(key,"is",element_dict[key])
else:
    print("Not a valid element")
Enter a valid chemical symbol: Ar
Ar is Argon
Home Activity: Run the code above twice. Try first with a valid chemical symbol. Then try with a chemical symbol not on the periodic table of elements.

We can also print out the dictionary.

In [19]:
print(element_dict)
{'Ac': 'Actinium', 'Ag': 'Silver', 'Al': 'Aluminium (Aluminum)', 'Am': 'Americium', 'Ar': 'Argon', 'As': 'Arsenic', 'At': 'Astatine', 'Au': 'Gold', 'B': 'Boron', 'Ba': 'Barium', 'Be': 'Beryllium', 'Bh': 'Bohrium', 'Bi': 'Bismuth', 'Bk': 'Berkelium', 'Br': 'Bromine', 'C': 'Carbon', 'Ca': 'Calcium', 'Cd': 'Cadmium', 'Ce': 'Cerium', 'Cf': 'Californium', 'Cl': 'Chlorine', 'Cm': 'Curium', 'Cn': 'Copernicium', 'Co': 'Cobalt', 'Cr': 'Chromium', 'Cs': 'Caesium (Cesium)', 'Cu': 'Copper', 'Db': 'Dubnium', 'Ds': 'Darmstadtium', 'Dy': 'Dysprosium', 'Er': 'Erbium', 'Es': 'Einsteinium', 'Eu': 'Europium', 'F': 'Fluorine', 'Fe': 'Iron', 'Fl': 'Flerovium', 'Fm': 'Fermium', 'Fr': 'Francium', 'Ga': 'Gallium', 'Gd': 'Gadolinium', 'Ge': 'Germanium', 'H': 'Hydrogen', 'He': 'Helium', 'Hf': 'Hafnium', 'Hg': 'Mercury', 'Ho': 'Holmium', 'Hs': 'Hassium', 'I': 'Iodine', 'In': 'Indium', 'Ir': 'Iridium', 'K': 'Potassium', 'Kr': 'Krypton', 'La': 'Lanthanum', 'Li': 'Lithium', 'Lr': 'Lawrencium', 'Lu': 'Lutetium', 'Lv': 'Livermorium', 'Md': 'Mendelevium', 'Mg': 'Magnesium', 'Mn': 'Manganese', 'Mo': 'Molybdenum', 'Mt': 'Meitnerium', 'N': 'Nitrogen', 'Na': 'Sodium', 'Nb': 'Niobium', 'Nd': 'Neodymium', 'Ne': 'Neon', 'Ni': 'Nickel', 'No': 'Nobelium', 'Np': 'Neptunium', 'O': 'Oxygen', 'Os': 'Osmium', 'P': 'Phosphorus', 'Pa': 'Protactinium', 'Pb': 'Lead', 'Pd': 'Palladium', 'Pm': 'Promethium', 'Po': 'Polonium', 'Pr': 'Praseodymium', 'Pt': 'Platinum', 'Pu': 'Plutonium', 'Ra': 'Radium', 'Rb': 'Rubidium', 'Re': 'Rhenium', 'Rf': 'Rutherfordium', 'Rg': 'Roentgenium', 'Rh': 'Rhodium', 'Rn': 'Radon', 'Ru': 'Ruthenium', 'S': 'Sulfur (Sulphur)', 'Sb': 'Antimony', 'Sc': 'Scandium', 'Se': 'Selenium', 'Sg': 'Seaborgium', 'Si': 'Silicon', 'Sm': 'Samarium', 'Sn': 'Tin', 'Sr': 'Strontium', 'Ta': 'Tantalum', 'Tb': 'Terbium', 'Tc': 'Technetium', 'Te': 'Tellurium', 'Th': 'Thorium', 'Ti': 'Titanium', 'Tl': 'Thallium', 'Tm': 'Thulium', 'U': 'Uranium', 'Uuo': 'Ununoctium', 'Uup': 'Ununpentium', 'Uus': 'Ununseptium', 'Uut': 'Ununtrium', 'V': 'Vanadium', 'W': 'Tungsten', 'Xe': 'Xenon', 'Y': 'Yttrium', 'Yb': 'Ytterbium', 'Zn': 'Zinc', 'Zr': 'Zirconium'}
In [20]:
element_dict
Out[20]:
{'Ac': 'Actinium',
 'Ag': 'Silver',
 'Al': 'Aluminium (Aluminum)',
 'Am': 'Americium',
 'Ar': 'Argon',
 'As': 'Arsenic',
 'At': 'Astatine',
 'Au': 'Gold',
 'B': 'Boron',
 'Ba': 'Barium',
 'Be': 'Beryllium',
 'Bh': 'Bohrium',
 'Bi': 'Bismuth',
 'Bk': 'Berkelium',
 'Br': 'Bromine',
 'C': 'Carbon',
 'Ca': 'Calcium',
 'Cd': 'Cadmium',
 'Ce': 'Cerium',
 'Cf': 'Californium',
 'Cl': 'Chlorine',
 'Cm': 'Curium',
 'Cn': 'Copernicium',
 'Co': 'Cobalt',
 'Cr': 'Chromium',
 'Cs': 'Caesium (Cesium)',
 'Cu': 'Copper',
 'Db': 'Dubnium',
 'Ds': 'Darmstadtium',
 'Dy': 'Dysprosium',
 'Er': 'Erbium',
 'Es': 'Einsteinium',
 'Eu': 'Europium',
 'F': 'Fluorine',
 'Fe': 'Iron',
 'Fl': 'Flerovium',
 'Fm': 'Fermium',
 'Fr': 'Francium',
 'Ga': 'Gallium',
 'Gd': 'Gadolinium',
 'Ge': 'Germanium',
 'H': 'Hydrogen',
 'He': 'Helium',
 'Hf': 'Hafnium',
 'Hg': 'Mercury',
 'Ho': 'Holmium',
 'Hs': 'Hassium',
 'I': 'Iodine',
 'In': 'Indium',
 'Ir': 'Iridium',
 'K': 'Potassium',
 'Kr': 'Krypton',
 'La': 'Lanthanum',
 'Li': 'Lithium',
 'Lr': 'Lawrencium',
 'Lu': 'Lutetium',
 'Lv': 'Livermorium',
 'Md': 'Mendelevium',
 'Mg': 'Magnesium',
 'Mn': 'Manganese',
 'Mo': 'Molybdenum',
 'Mt': 'Meitnerium',
 'N': 'Nitrogen',
 'Na': 'Sodium',
 'Nb': 'Niobium',
 'Nd': 'Neodymium',
 'Ne': 'Neon',
 'Ni': 'Nickel',
 'No': 'Nobelium',
 'Np': 'Neptunium',
 'O': 'Oxygen',
 'Os': 'Osmium',
 'P': 'Phosphorus',
 'Pa': 'Protactinium',
 'Pb': 'Lead',
 'Pd': 'Palladium',
 'Pm': 'Promethium',
 'Po': 'Polonium',
 'Pr': 'Praseodymium',
 'Pt': 'Platinum',
 'Pu': 'Plutonium',
 'Ra': 'Radium',
 'Rb': 'Rubidium',
 'Re': 'Rhenium',
 'Rf': 'Rutherfordium',
 'Rg': 'Roentgenium',
 'Rh': 'Rhodium',
 'Rn': 'Radon',
 'Ru': 'Ruthenium',
 'S': 'Sulfur (Sulphur)',
 'Sb': 'Antimony',
 'Sc': 'Scandium',
 'Se': 'Selenium',
 'Sg': 'Seaborgium',
 'Si': 'Silicon',
 'Sm': 'Samarium',
 'Sn': 'Tin',
 'Sr': 'Strontium',
 'Ta': 'Tantalum',
 'Tb': 'Terbium',
 'Tc': 'Technetium',
 'Te': 'Tellurium',
 'Th': 'Thorium',
 'Ti': 'Titanium',
 'Tl': 'Thallium',
 'Tm': 'Thulium',
 'U': 'Uranium',
 'Uuo': 'Ununoctium',
 'Uup': 'Ununpentium',
 'Uus': 'Ununseptium',
 'Uut': 'Ununtrium',
 'V': 'Vanadium',
 'W': 'Tungsten',
 'Xe': 'Xenon',
 'Y': 'Yttrium',
 'Yb': 'Ytterbium',
 'Zn': 'Zinc',
 'Zr': 'Zirconium'}

1.5.3.3 Dictionary of Dictionaries

We can make dictionaries even more powerful if we make a dictionary of dictionaries.

Top Level. Day of the week.

  • Key: symbol "M", "T", etc.
  • Value: Another dictionary!

Second Level. Data for each day.

  • Keys: "name", "weekday", "weekend"
  • Values: string, boolean (True or False), boolean
In [21]:
#simple dictionary of dictionaries
days_of_week = {"M":{"name":"Monday","weekday":True,"weekend":False},
                "T":{"name":"Tuesday","weekday":True,"weekend":False},
                "W":{"name":"Wednesday","weekday":True,"weekend":False},
                "R":{"name":"Thursday","weekday":True,"weekend":False},
                "F":{"name":"Friday","weekday":True,"weekend":False},
                "S":{"name":"Saturday","weekday":False,"weekend":True},
                "U":{"name":"Sunday","weekday":False,"weekend":True}}

print("The days that are weekdays are")
for day in days_of_week: #for loop over dictionary, loops over keys
    if days_of_week[day]["weekday"] == True:
        print(days_of_week[day]["name"],"is a weekday.")

print("The days that are weekend days are")        
for day in days_of_week: #for loop over dictionary, loops over keys
    if days_of_week[day]["weekend"] == True:
        print(days_of_week[day]["name"],"is a weekend, whoop.")
The days that are weekdays are
Monday is a weekday.
Tuesday is a weekday.
Wednesday is a weekday.
Thursday is a weekday.
Friday is a weekday.
The days that are weekend days are
Saturday is a weekend, whoop.
Sunday is a weekend, whoop.

Notice that when you loop over a dictionary in a for loop, the loop variable will get each of the keys of the dictionary.

The dictionary has been modified to include the day name in Spanish.

In [22]:
#more complicated dictionary of dictionaries
days_of_week2 = {"M":{"name":"Monday","weekday":True,"Spanish":"Lunes"},
                "T":{"name":"Tuesday","weekday":True,"Spanish":"Martes"},
                "W":{"name":"Wednesday","weekday":True,"Spanish":"Miércoles"},
                "R":{"name":"Thursday","weekday":True,"Spanish":"Jueves"},
                "F":{"name":"Friday","weekday":True,"Spanish":"Viernes"},
                "S":{"name":"Saturday","weekday":False,"Spanish":"Sábado"},
                "U":{"name":"Sunday","weekday":False,"Spanish":"Domingo"}}
Class Activity: With a partner, write pseudocode to loop over the days of the week. Print off the day name in Spanish and whether it is a weekend or weekday.
In [ ]:
 
Class Activity: Implement your pseudocode in Python.
In [ ]:
# YOUR SOLUTION HERE

1.5.4 Enumerate

1.5.4.1 Lists

Let's see some syntax for growing lists.

In [ ]:
# create a list with nothing

students = []

# add a student
students.append("Joe Smith")

# add another student
students.append("Jane Doe")
In [ ]:
print(students)

How to loop for the list? Let's review.

In [ ]:
# Approach 1
for s in students:
    print(s)
In [ ]:
# Approach 2
for i in range(len(students)):
    print(i,": ",students[i])

Can simply the syntax? It is really convienent to access the index with i and the student with s.

In [ ]:
for i, s in enumerate(students):
    print(i,": ",s)

1.5.4.2 Dictionaries

In [ ]: