Control Structures¶

In this lesson, we will introduce fundamental control structures (if statements, for loops, and while loops) for Python. By the end of this lesson, students will be able to:

  1. Explain the difference between the output of running a cell and printed output.
  2. Evaluate expressions involving arithmetic and boolean operators.
  3. Apply for loops to iterate over a range of numbers increasing/decreasing by a fixed step size.

Jupyter Notebooks¶

Before we learn about control structures, let's learn a bit about the Jupyter Notebook data programming environment that we'll be using throughout this course. Jupyter Notebooks allow you to write formatted text descriptions (Markdown cells) alongside runnable Python code (Code cells). The text you're reading now is an example of a Markdown cell. You can double-click this text to edit it. Feel free to edit the contents of any cells that we give you: your changes only apply to your own copy.

JupyterHub has a built-in debugger that enables you to pause the program on any line of code and inspect its state. But, we are not going to use it because it's an overkill for this course (and even in actual work sometimes).

“The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.” — Brian Kernighan, “Unix for Beginners” (1979)

Python code cells, like the one that appears below, can be run by clicking on the cell and then using the ▶️ play button at the top to run it. The keyboard shortcut Ctrl + Enter allows you to run the current cell, which comes in handy if you make some edits to a cell and your fingers are already on your keyboard.

Try editing the following cell to replace Yuxuan with your own name and then run it using the keyboard shortcut.

In [6]:
"Hello, my name is Yuxuan"
Out[6]:
'Hello, my name is Yuxuan'

When running this code cell, notice how Jupyter Notebook produces an output. Usually, the output is the value of the last expression that was run. (There are some fancy ways to override the output but we won't learn how to do this.)

In [4]:
"Hello, my name is Yuxuan"
"My favorite course is CSE 163"
Out[4]:
'My favorite course is CSE 163'

Print function¶

How can I have Python display both of the lines of text? To do this, we will need to print out lines of text. The print function has the side-effect of outputting the arguments as text.

In [5]:
print("Hello, my name is Yuxuan")
print("My favorite course is CSE 163")
Hello, my name is Yuxuan
My favorite course is CSE 163

This helps us display more than one line of text in a cell, but take a closer look and you'll notice more subtle details happening behind the scenes.

Before we introduced print, the cell produced as the last line of output

'My favorite course is CSE 163'

After we introduced print, the cell produced as the last line of output

My favorite course is CSE 163

What is different between these two outputs? Try to explain the cause for the difference.

Assignment statements¶

Variables store values. Each Python value is composed of a value and its type. Unlike Java, Python doesn't require you to define the type of a variable. Variables are assigned using assignment statements.

In [7]:
x = 2.4
y = 1.2
x = x / y
y = 5

Assignment statements don't produce values, so there's no output displayed. If you want to display an output, ask for the value of a variable. This expression evaluates to the current value stored in the variable y.

In [10]:
y
Out[10]:
5

Comparison operators¶

In addition to the string and numeric values that we see above, Python also has comparison operators that produce boolean (True or False) values.

In [11]:
x = 3
print(x < 4)   # Is x less than 4?
print(x >= 5)  # Is x greater than or equal to 5?
print(x == 2)  # Is x equal to 2?
print(x != 2)  # Is x not equal to 2?
True
False
False
True

Let's try putting together everything you've seen so far. Before running the follow code cell, predict the output that will appear. (x ** 2 computes x raised to the second power.)

In [12]:
x = 2.4
y = 1.2
x = x / y
y = 5

print(x ** 2 <= y)
True

The most effective way to learn all the key programming details is to predict the output of every code cell before running it. Then, you can compare your predicted output to the real output and use that to plan your next steps.

Many of our in-class coding polls will provide an opportunity to pause and predict, but you can actually apply this learning strategy in any class. Even in classes that don't involve coding, comparing what you predict to what actually happens next in a lecture is an effective way to think and stay engaged.

Conditional statements¶

Comparison operators are frequently used together with conditional statements (if statements). Whereas Java uses curly braces { and } to indicate a block of code, Python relies primarily on indentation to indicate blocks of code.

In [13]:
if x ** 2 < y:
    print("x-squared is less than y")
elif x ** 2 == y:
    print("x-squared is equal to y")
else:
    print("x-squared is greater than y")
x-squared is less than y

Loops¶

Think about how you might write the following program so that it counts down from one minute decrementing by 10 seconds, producing the following predicted output.

One minute countdown
60
50
40
30
20
10
0
Done!

We can certainly write this out using a lot of print statements.

In [14]:
print("One minute countdown")
print(60)
print(50)
print(40)
print(30)
print(20)
print(10)
print(0)
print("Done!")
One minute countdown
60
50
40
30
20
10
0
Done!

But perhaps we can write a more general solution using loops instead. Let's practice converting this code into a for loop.

In [15]:
print("One minute countdown")
for n in range(60, 0, -10):
    print(n)
print(0)
print("Done!")
One minute countdown
60
50
40
30
20
10
0
Done!
In [22]:
# Let's write it as a function that takes in n (integer) and counts down to 0 by 10 seconds decrement.
# remember to document every function you write! using triple quotes ''' for docstrings.

def countdown(n):
    """
    Input:
        n - the number of seconds to count down from.
    Counts down from n seconds by 10 seconds decrement.
    """
    print(f"{n} seconds countdown")
    for i in range(n, -1, -10):
        print(i)
    print("Done!")

Let's try some different test cases.

In [18]:
countdown(60)
One minute countdown
60
50
40
30
20
10
0
Done!
In [19]:
countdown(9)
One minute countdown
9
Done!
In [20]:
countdown(0.5)
One minute countdown
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 1
----> 1 countdown(0.5)

Cell In[17], line 11, in countdown(n)
      5 """
      6 Input:
      7     n - the number of seconds to count down from.
      8 Counts down from n seconds by 10 seconds decrement.
      9 """
     10 print("One minute countdown")
---> 11 for i in range(n, -1, -10):
     12     print(i)
     13 print("Done!")

TypeError: 'float' object cannot be interpreted as an integer
In [21]:
countdown(-1)
One minute countdown
Done!

While loops¶

A while loop has a condition and a body. Each iteration executes the indented code only if the condition is True, otherwise the loop ends.

In [23]:
x = 1
while x < 100:
    print(x)
    x = x * 2

print("After loop: x =", x)
1
2
4
8
16
32
64
After loop: x = 128

Practice: Countdown with while loop¶

Use a while loop to write a function countdown that takes a starting whole number of seconds and counts down to 0 (inclusive) decrementing by 10 each time. If the starting number of seconds is less than 0, it should instead print "Start must be non-negative!"

Here are 4 example countdown calls (prefixed >>>) and followed by the corresponding printed output.

>>> countdown(60)
60 second countdown
60
50
40
30
20
10
0
Done!
>>> countdown(15)
15 second countdown
15
5
Done!
>>> countdown(-4)
Start must be non-negative!
>>> countdown(0)
0 second countdown
0
Done!
In [25]:
def countdown(n):
    """
    Input:
        n - the number of seconds to count down from.
    Counts down from n seconds by 10 seconds decrement.
    """
    print(f"{n} seconds countdown")
    while n > -1:
        print(n)
        n -= 10 # n = n-10
    print("Done!")
In [26]:
countdown(60)
60 seconds countdown
60
50
40
30
20
10
0
Done!
In [27]:
countdown(15)
15 seconds countdown
15
5
Done!
In [28]:
countdown(-4)
-4 seconds countdown
Done!
In [29]:
countdown(0)
0 seconds countdown
0
Done!

How to write doctest¶

In [14]:
import doctest
In [25]:
def countdown(n):
    """
    Input:
        n - the number of seconds to count down from.
    Counts down from n seconds by 10 seconds decrement.

    >>> countdown(60)
    60 second countdown
    60
    50
    40
    30
    20
    10
    0
    Done!
    
    >>> countdown(15)
    15 second countdown
    15
    5
    Done!
    
    >>> countdown(0)
    0 second countdown
    0
    Done!

    We cannot countdown from less-than-zero number of seconds, so
    we print out a message in this case.
    
    >>> countdown(-4)
    Start must be non-negative!

    """
    if n < 0:
        print("Start must be non-negative!")
    else:
        print(f"{n} second countdown")
        while n > -1:
            print(n)
            n -= 10 # n = n-10
        print("Done!")
In [26]:
doctest.testmod()
Out[26]:
TestResults(failed=0, attempted=4)