Part 1: “for-loops” and “while-loops”¶
This week we will be discussing basic iterable objects (lists, arrays, tuples ...) and how you can use them to repeat operations.
For example lets say you want to print something out several times. Last week you learned some numpy basics so lets start with that...
import numpy as np #importing numpy
print(np.arange(5)) # this is an array with 5 elements
[0 1 2 3 4]
# start the for loop
for i in np.arange(5): # pay attention to the syntax (":") here!
print(i)
0
1
2
3
4
This is an example of a “for-loop” which is the most basic looping fucntionality in Python.
It is intiialized by typing for
in front of the the variable i
which is a an element in
the iterable np.arange(5)
.
It works by iterating over each element in the numpy array. Importantly, the variable i
can be anything as long as you are consistent.
It is effectively a dummy variable that represents each element in the iterable.
for wowza in np.arange(5): #now instead of "i" I used the "wowza" variable
print(wowza)
0
1
2
3
4
You could do somethign similar with a “while-loop” which unlike the “for-loop” iterates as long as some condition is met. For example:
# Initialize a counter
counter = 0
# Define the condition for the while loop
while counter < 5:
print(counter)
counter += 1 # Increment the counter
0
1
2
3
4
Intially, you might not see this looping business as incredibly useful but lets take a more complicated example...
# Define the height of the tree
height = 5
# Using a for loop to print a Christmas tree
for i in range(1, height + 1):
spaces = " " * (height - i)
stars = "*" * (2 * i - 1)
print(spaces + stars)
*
***
*****
*******
*********
This would be kind annoying to print out by actually typing out the spaces and the stars, especially if you want to make the tree larger..
# Define the height of the tree
height = 12
# Using a for loop to print a Christmas tree
for i in range(1, height + 1):
spaces = " " * (height - i)
stars = "*" * (2 * i - 1)
print(spaces + stars)
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
***********************
Above we have the range
function which creates a “range” instance. This is another example of an iterable
Part 2: Iterables¶
Okay so now that we have the basic syntax of these two loops, lets talk iterables. Lets start with a list
my_grocery_list = ["apples", "oranges", "dorritos", "mustard", "eggs", "gummy bears"]
# pay attention to the syntax here! ([] square brackets!)
how many things do I have in my list? and what is each element? and can I iterate over these random things that aren’t integers?
print( len(my_grocery_list) )
print( type(my_grocery_list[2]))
6
<class 'str'>
for food in my_grocery_list[3:5]:
print("oh shoot I forgot the", food)
oh shoot I forgot the mustard
oh shoot I forgot the eggs
As we can see there are 6 str
elements in the list and iterating over the 3rd and 4th element is perfectly easy!
In other words the iterable can be an interger, a string, a list itslef, basically any data type! Lets now loop over a dictionary!
# Define a treasure map dictionary
treasure_map = {
'Start': 'You find yourself on a mysterious island.',
'Palm Tree': 'Under the palm tree, you discover a clue written in the sand.',
'Cave Entrance': 'Following the clue, you reach the entrance of a dark cave.',
'Treasure Room': 'After navigating through the cave, you discover the hidden treasure room!',
'X marks the spot': 'You find the treasure chest buried under a giant "X" on the floor.'
}
# Use a for loop to explore the treasure map
for location, description in treasure_map.items():
print(f'You are at {location}: {description}')
user_input = input('Do you want to continue the adventure? (yes/no): ')
if user_input.lower() != 'yes':
print('Thanks for playing! Adventure complete.')
break
You are at Start: You find yourself on a mysterious island.
Thanks for playing! Adventure complete.
Part 3: Double for-loops ... Tread carefully!¶
Pretend you are sampling ages by asking 10 random people in the grocery store.
You do this expirement three times in the same grocery store on Monday, Tuesday and Wednesday.
You now have three lists of numbers that (rather conviently) are the same length.
list_Mon = [5, 12, 3, 5, 67, 1, 2, 34, 2, 89]
list_Tues = [15, 45, 21, 2, 8, 9, 54, 99, 17, 51]
list_Wed = [32, 65, 11, 9, 5, 75, 21, 14, 39, 71]
Now lets say you wanted to know if any of these people could have been around to see the 2001 superbowl. How would you go about doing so?
min_age = 2023 - 2001
list_Mon > min_age
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/jsmonzon/Research/materials-development/Week3/lecture.ipynb Cell 27 line 2
<a href='vscode-notebook-cell:/Users/jsmonzon/Research/materials-development/Week3/lecture.ipynb#X43sZmlsZQ%3D%3D?line=0'>1</a> min_age = 2023 - 2001
----> <a href='vscode-notebook-cell:/Users/jsmonzon/Research/materials-development/Week3/lecture.ipynb#X43sZmlsZQ%3D%3D?line=1'>2</a> list_Mon > min_age
TypeError: '>' not supported between instances of 'list' and 'int'
well that doesn’t seem to work! so maybe we use a handy loop!
bool_Mon = []
for i in list_Mon:
bool_Mon.append(i > min_age)
print(bool_Mon)
print("only " +str(sum(bool_Mon)) + " people are old enough!")
[False, False, False, False, True, False, False, True, False, True]
only 3 people are old enough!
okay but what about the other days? Maybe we iterate over a list of lists?
all_ages = [list_Mon, list_Tues, list_Wed]
all_bool = []
for list in all_ages:
for i in list:
all_bool.append(i > min_age)
print(all_bool)
print("only " +str(sum(all_bool)) + " people are old enough!")
[False, False, False, False, True, False, False, True, False, True, False, True, False, False, False, False, True, True, False, True, True, True, False, False, False, True, False, False, True, True]
only 12 people are old enough!
Great so the double for-loop seems to work fine!, but lets say it wasn’t just 10 people each day, and it wasn’t just for three days.
Instead, lets say you and your friends talked to 100,000 people each day for 10 years (10x365 days)
Now since I can’t generate that many numbers on the spot I will use the numpy.random package. We will discuss this more later...
all_ages_BIG = np.random.randint(0,100, size=(3650,100000)).tolist()
lets try the same scheme as before with the double for-loop!
all_bool_BIG = []
for list in all_ages_BIG:
for i in list:
all_bool_BIG.append(i > min_age)
print("10^" +str(np.log10(sum(all_bool_BIG))) + " people are old enough!")
10^8.448775123083287 people are old enough!
that is A LOT of people! so much so that it took our computer ~43 seconds to compute that number!
worst of all this is for a relatively simple operation! anything slightly more complicated would greatly impact the preformance of this scheme.
We can do a lot better than that (namely by using numpy arrays)
all_ages_BIG = np.random.randint(0,100, size=(3650,100000))
wow = np.sum(all_ages_BIG > min_age)
print("10^" +str(np.log10(wow)) + " people are old enough!")
10^8.448763231936013 people are old enough!
that only took 3 seconds! so be careful when constructing these seemingly harmless tools and remember double-for loops are a LAST RESORT!