Notebook 4 - Controlling Program Flow and Using Modules¶
You can make your own copy of this notebook by selecting File->Save a copy in Drive from the menu bar above.
Things you'll learn in this lesson:
- how to control program flow based based on conditional values
- how to represent blocks of code
- how to express complex conditional logic
- how to import and use modules in your programs
Controlling Program Flow¶
Trivia Question: Will the year 2100 be a leap year?
- Up to now, we've looked at very simple programs, involving a sequence of statements (A, then B, then C…)
- But real world algorithms are rarely so simple
Example: If a year is divisible by 4, then it's a leap year, otherwise it's not a leap year.
This is called conditional logic because the program’s logic or execution path is determined by the testing of a true or false condition.
Everyday example: if it's not raining then I'll ride my bike to work, otherwise I'll take public transit.
if
Statements¶
- The
if
statement is how we express conditional logic in Python. - Virtually every programming language has this concept.
- If statements define a condition and a sequence of statements to execute if the condition is
True
.
Prototype...
if some_expression:
do_this()
do_that()
If the condition is true, the indented statements are executed.
Otherwise, the indented statements are skipped and program execution continues after the if
statement.
month = "jan"
summer_months = ["may", "jun", "jul", "aug"]
if month in summer_months:
print(“yay - it’s still summer!")
else:
print(“boo - have to go to school today!")
print(“program done”)
Challenge¶
In Python, we use indentation to associate a block of statements with a condition, for example...
print("1")
if some_condition:
print("2")
print("3")
print("4") # this line is NOT part of the if block
What does the output look like...
- when
some_condition
is True? - when
some_condition
is False?
Try testing your guess by running the following cell with some_condition
set to True, then False.
some_condition = True
print(“1”)
if some_condition:
print(“2”)
print(“3”)
print(“4”) # this line is NOT part of the if block
Here’s a slightly different example...
print("1")
if some_condition:
print("2")
print("3") # this line is NOT part of if block
print("4") # this line is NOT part of if block
What’s different? What does the output look like...
- when the
some_condition
is True? - when the
some_condition
is False?
if
Block Structure¶
- In Python,
if
statements blocks are defined by indentation. - This idea of using indentation to delineate program structure is pervasive in Python and unique across programming languages.
- For now, we're focusing on if statements but later we'll see how indentation is used to define other blocks of statements.
Block Stucture in Other Languages¶
In other languages, explicit delineators are used. For example, in Java, C, and C++ we would write:
if ((cur_year % 4) == 0) {
leap_year = true;
}
whereas, in Python we write:
if (cur_year % 4) == 0:
leap_year = True
Indentation in Java/C/C++ is a helpful practice for program readability but it does not affect program functionality. In Python, indentation is not just a good idea - it's affects program logic!
Python's use of whitespace¶
- Many people have strong opinions about this aspect of Python.
- Personally, I find that it leads to compact, readable code.
- My advice: don’t get hung up on this feature. Try it and see what you think after you've written a few Python programs.
- Pitfalls:
- watch out for mismatched indentation within a block
- avoid mixing tabs and spaces in your code
- I prefer spaces over tabs because it's more explicit.
Marc's law of whitespace: Pick spaces or tabs and be consistent.
Encoding our leap year rule¶
Remember our leap year rule?
- if the current year is divisible by 4, we have a leap year
Here's a short Python program, which prompts the user to enter a year and uses the strategy above to decide if the year entered was (or will be, if in the future) a leap year:
leap_year = False # initialization
year = input("Enter desired year: ")
year = int(year)
if (year % 4) == 0:
leap_year = True
print(f"leap year status for {year}: {str(leap_year)}")
Question: Why is the first statement needed?
leap_year = False # initialization
year = input("Enter desired year: ")
year = int(year)
if (year % 4) == 0:
leap_year = True
print(f"leap year status for {year}: {str(leap_year)}")
else
Statements¶
Sometimes we want to specify an alternative to the if
condition, which we do with an else
statement, for example...
if <condition>:
<block1>
else:
<block2>
- If the condition is true, block1 is executed.
- if the condition is false, block2 is executed.
The else cause is Python's way of saying "otherwise..."
Just as if
blocks are defined by indentation, else
blocks are also defined by indentation.
For example, this:
if <condition>:
<statement1>
else:
<statement2>
<statement3>
is different from this:
if <condition>:
<statement1>
else:
<statement2>
<statement3>
Challenge¶
Consider the following if/else statement...
print("1")
if some_condition:
print("2")
else:
print("3")
print("4")
Question: what does the output look like…
- when the
some_condition
is True? - when the
some_condition
is False?
Try testing your guess by running the following cell with some_condition
set to True, then False.
some_condition = False
print(“1”)
if some_condition:
print(“2”)
else:
print(“3”)
print(“4”)
Let's use if
and else
to express our leap year rule¶
Can we use if/else to rewrite our leap year program to avoid needing this initialization step:
leap_year = False # initialization
year = input("Enter current year: ")
year = int(year)
if (year % 4) == 0:
leap_year = True
else:
leap_year = False
print(f"leap year status for {year}: {leap_year}")
elif
Statements¶
Sometimes we need one or more intermediate conditions between the if and else parts, for example...
if A then do X, else if B then do Y, otherwise do Z
We use the elif
statement to express this in Python...
if condition1:
do_thing_1()
elif condition2:
do_thing_2()
else:
do_thing_3()
- If
condition1
is true,do_thing_1()
is executed. - Else, if
condition2
is true,do_thing_2()
is executed. - Otherwise,
do_thing_3()
is executed.
elif
blocks are defined the same way asif
andelse
blocks - using indentation.It's good to have an if/elif for every condition of interest and not lump errors together with cases of interest.
For example, if you care about values 1 and 2 and everything else is considered an error, this code:
if month == "jan": # deal with jan here
apply_jan_discount()
elif month == "feb": # deal with feb here
apply_feb_discount()
else: # deal with errors here
apply_no_discount()
is better than this:
if month == "jan":
apply_jan_discount()
else: # x must be 2 then, right? not necessarily!
apply_feb_discount()
The latter code hides errors by combining a valid case with error cases.
Challenge¶
Consider the following if/elif/else statement...
print("1")
if condition1:
print("2")
elif condition2:
print("3")
else:
print("4")
print("5")
What does the output look like...
- when both conditions are False?
- when both conditions are True?
- when
condition1
isTrue
andcondition2
isFalse
? - when
condition1
isFalse
andcondition2
isTrue
?
Try testing your guess by running the following cell with condition1
and condition2
set to the four possible combinations of True and False.
condition1 = False
condition2 = True
print(“1”)
if condition1:
print(“2”)
elif condition2:
print(“3”)
else:
print(“4”)
print(“5”)
Nested if
Statements¶
- Sometimes we need to embed one if statement inside another.
- We call these nested if statements.
- We can embed if statements inside any part of an
if
statement, i.e. in theif
block or theelif
block or theelse
block. - We can embed
if
statements arbitrarily deeply, i.e. we could have, for example...
if condition1:
if condition2:
if condition3:
...
Challenge¶
print("1")
if condition1:
print("2")
if condition2:
print("3")
else:
print("4")
else:
print("5")
print("6")
What does the output look like...
- when both conditions are False?
- when both conditions are True?
- when
condition1
isTrue
andcondition2
isFalse
? - when
condition1
isFalse
andcondition2
isTrue
?
Try testing your guess by running the following cell with condition1
and condition2
set to the four possible combinations of True and False.
condition1 = False
condition2 = True
print(“1”)
if condition1:
print(“2”)
if condition2:
print(“3”)
else:
print(“4”)
else:
print(“5”)
print(“6”)
Improving Our Rule¶
A more accurate rule for determining leap years:
If the current year is divisible by 4 but not divisible by 100 then we have a leap year. How would you encode that refinement in Python? Try it yourself and then have a look at the next cell.
leap_year = False
year = input("Enter current year: ")
year = int(year)
if (year % 4) == 0:
if (year % 100) != 0:
leap_year = True
print(f"leap year status for {year}: {leap_year}")
Variation - using boolean logic instead of nested if
¶
This example could also be coded using boolean logic in place of the nested if statement.
leap_year = False
year = input("Enter current year: ")
year = int(year)
if (year % 4) == 0 and (year % 100) != 0:
leap_year = True
print(f"leap year status for {year}: {leap_year}")
What does the above code print for these years...
- 2020?
- 2100? -- that answers our trivia questions from the beginning of this notebook
- 2000? -- surprise, that one's wrong!
The Whole Story About Leap Years¶
A year is a leap year if its divisible by 4, but not divisible by 100, unless also divisible by 400.
So...
- 2008 was a leap year because it's divisible by 4 and not divisible by 100.
- 2100 will NOT be a leap year because although it's divisible by 4, it is also divisible by 100.
- 2000 was a leap year because although it's divisible by 4 and 100, it's also divisible by 400!
Importing Modules¶
import
is how you use someone else's code.
Let's say we want to generate a random number between 1 and 100. We can use the Python random
module, like this...
import random
good_dogs = [“Benji”, “Maple”, “Kirby”, “Rosie”]
for i in range(3):
random.shuffle(good_dogs)
print(good_dogs)
Challenges¶
Question 1¶
Write a program that prompts the user for their birth year and prints their age in years, days, hours, minutes, and seconds. Don’t worry about the user’s birthday (just subtract the birth year from the current year to get the approximate current age in years) and you can ignore leap years. Here's a sample run:
Enter your birth year: 1970
You are...
50 years old
18250 days old
438000 hours old
26280000 minutes old
1576800000 seconds old
# Add your code here
Extra challenge: write the program so that it works any year it is run, not just this year (hint: google the Python datetime
module, which you can use to find out the current year).
# Add your code here
#@title Double click here to reveal solution
Coming soon.
Question 2¶
A person is eligible to be a US Senator if they are at least 30 years old and have been a US citizen for at least 9 years.
A person is eligible to be a US Representative if they are at least 25 years old and have been a US citizen for at least 7 years.
Write a program to prompt a user to enter their age and length of citizenship in years, then print out one of the following three statements:
- You are eligible to run for both the House and Senate.
- You eligible to run only for the House.
- You are ineligible to run for either branch of Congress.
Something to think about: why don't we also have the possibility of printing "You are eligible to run only for the Senate"?
# Add your code here
#@title Double click here to reveal solution
Coming soon.
Todo¶
In last class, show how to test this program using functions (turn this snippet into a function), loops, boolean logic, lists, and pytest.
Question 3¶
Write a program that generates two random 1 digit integers and prompts the user to provide the product of those two digits (basically, this is an interactive multiplication test). Check the user's answer and print a response indicating whether it is correct or not. Here are two sample runs:
Welcome to the multiplication tester!
What is 3 * 9? 25
Sorry, that's incorrect, 3 * 9 = 27.
Welcome to the multiplication tester!
What is 4 * 7? 28
Correct!
# Add your code here
#@title Double click here to reveal solution
Coming soon.
Question 4¶
Write a program that prompts the user for a year and, using the complete set of rules described in class, tells the user whether the provided year is a leap year or not.
# Add your code here
#@title Double click here to reveal solution
Coming soon.