**Homework 2: Conditionals and Loops**
**Reed CSCI 121 Spring 2026**
*submit by 2/10 at 9am*
In this series of lab exercises you will be writing code that uses
conditional statements (the `if` and `if-else` statements) and that
performs loops (using the `while` statement).
We say a little bit about each of these below, and then we give the
exercises.
(##) The Conditional Statement
In lecture we learned how, in Python, our code can perform actions
conditionally. For example, we might have an integer variable `number`
and we might check to see if it is a ranking from 1 to 100. Here is a
script that does that:
~~~ python
number = int(input("Enter a ranking from 1 to 100: "))
if (number < 1) or (number > 100):
print("The integer "+str(number)+" is not a rank.")
print("That was a bad entry.")
else:
print("Thanks!")
print("The number "+str(number)+" is indeed a rank.")
~~~
In the code above, the expression `(number < 1)` is true whenever the
integer they entered is 0 or smaller. And the expression
`(number > 100)` is true if the integer they entered is 101 or greater.
If either condition holds, then the script tells them that the number is not a
ranking. Otherwise, it thanks them for their entry of a rank from 1 to 100.
The four lines of code starting with `if` is a conditional
statement. It has the general syntax
`if` *condition-to-check* `:`
*lines-to-execute-if-the-condition-holds*
`else:`
*lines-to-execute-otherwise*
The statements in the lines immediately following the `if` line
must be indented, and with four spaces. They are executed whenever the condition checked
is true. The statements immediately following the `else:` line
should also each be indented with four spaces. They are executed whenever the condition checked
is false.
(##) Control Flow
The `if-else` statement is just one example of a family of statements
called *control flow* statements. These can be used to direct the
"flow of control" that your program takes through its code.
An `if-else` is a "branch" because, depending on whether its
condition is `True` or is `False`, the program either executes the
first set of statements or it executes the second set of statements.
Some executions of the code take one of the two paths, the other
executions of the code take the other of the two paths.
(##) While Loops
A `while` statement provides a different pattern that program
execution might follow called a *loop*. Using it, a program might
repeatedly perform a series of actions until some condition is
met. For example, the code below counts from 1 to 10. It keeps
printing then adding one to the variable `count` until that variable
gets larger than 10:
~~~ python
print("I will now count from 1 to 10...")
count = 1
while count <= 10:
print("The count is now " + str(count) + ".")
count = count + 1
print("There. I am done counting.")
~~~
Here is what that code does: After executing the first two lines, the
program will execute the `print` and the increment statements inside
the `while` statement's *body*. This is because the `count` variable
is only at `1`, and that value is less than or equal to 10. After
executing those two lines once, the interpreter "jumps" back to the
condition line to see whether `count <= 10`.
Since the condition is
still true (`count == 2` and `2 <= 10`), it runs those two lines again
and re-checks the condition. It keeps looping through those three code
lines-- checking the condition, printing, incrementing-- until the
assignment statement changes the value of `count` from `10` to
`11`.
When the loop condition is checked an 11-th time, the condition
will then be `False`, and the program skips to the line below the loop
body. It prints the message "`There. I am done counting.`"
WIth a `while` statement, we perform *iteration*, that is,
repeated execution of the same lines of code. Here is the general syntax:
*statements-that-execute-before-the-loop*
`while` *condition-to-check* `:`
*statements-to-repeatedly-execute-on-the-condition*
*statements-that-execute-after-the-loop*
(##) Working in pairs
We will be pairing most of you up for the first four exercises. Pairs only
need to turn in a single group submission to Gradescope. When you do submit an exercise solution on Gradescope, please make sure to select your programming partner in Gradescope.
In pair programming, you work together on the same exercise.
One person (the *driver*) does the actual coding in the editor and testing the code in the terminal.
The other person (the *navigator*) makes suggestions and points out typos and other mistakes. They "have the driver's back," so to speak.
The navigator also looks things up in notes and references other course resources.
**Complete one exercise as the two roles and then switch for the next exercise.**
Only work this way for exercises 1 through 4, then submit the remainder on your own. Even so, feel free to chat with your partner and with others on those other exercises.
If you miss lab, please complete the lab assignment on your own.
(#) Exercises
• **[Hw2 Ex1] rank**
Write a script `rank.py` that requests input of a positive integer.
It should then report it as a ranking.
Your script should exactly mimic the terminal interactions seen below:
~~~none
homework2 % python3 rank.py
What is your rank? 1
You are in 1st place.
homework2 % python3 rank.py
What is your rank? 2
You are in 2nd place.
homework2 % python3 rank.py
What is your rank? 3
You are in 3rd place.
homework2 % python3 rank.py
What is your rank? 4
You are in 4th place.
homework2 % python3 rank.py
What is your rank? 10
You are in 10th place.
homework2 % python3 rank.py
What is your rank? 102
You are in 102nd place.
homework2 % python3 rank.py
What is your rank? 112
You are in 112th place.
~~~
With some exceptions, the suffix that gets printed depends on the last digit of the rank number. It should be
`"st"` for `1`,
`"nd"` for `2`,
`"rd"` for `3`,
and
`"th"` for everything else.
The exception to this "last digit" rule is for numbers whose last two digits are in the teens, like 12, or 111, or 313. These all also have a suffix of `"th"`.
---
• **[Hw2 Ex2] down up**
Write a script `down_up.py` that takes a positive integer as input.
It should then count down from that number, and then count back up again.
Here is the kind of interaction we expect:
~~~ none
Enter a positive integer: 4
Okay, here goes...
4
3
2
1
2
3
4
Done.
~~~
---
• **[Hw2 Ex3] zap buzz**
*Zap-Buzz* is a variant of a common children's game. The way the game
works is that each person takes a turn saying a number, counting
upwards from a starting number. However, if the number is a multiple
of 7 they say "zap" instead of the number. If the number has a digit
of 3 in it they say "buzz" instead of the number. If both things
are true they say "zap buzz".
Write a script `zap_buzz.py` that plays several successive turns of the game.
It should get a positive integer input for the starting number,
then get a positive integer input for the ending number.
It should then play the game, reporting what a player would
say for each number from start to end.
~~~none
How should the game start? First number: 25
And when should it end? Last number: 35
Starting play...
25
26
27
zap
29
buzz
buzz
buzz
buzz
buzz
zap buzz
Game over.
~~~
In the above, we start at 25, list the first three numbers, but then
instead output `zap` because 28 is divisible by 7. And then when the
numbers hit the 30s, we output `buzz` because each number has a `3` in
its digits. We end at `zap buzz` because 35 is divisible by 7.
You can assume that the first number input is less than or equal to the
second, and you can assume that the numbers are less than 1000.
To compute its output, your code should use integer division to determine
divisibility and also to determine a number's digits. *You should not* use
string operations to extract digits from an integer.
---
• **[Hw2 Ex4] make change**
Write a python script that, when given a **positive number** of cents
(1/100ths of a US dollar) outputs the amount of change to be given in
quarters, dimes, nickels, and pennies. It should choose these amounts
so that the fewest coins are used. In its reporting, it should only
report the coins needed (if there are no dimes needed, then it shouldn't
mention them). It should report them in plural or in singular, appropriately.
Here are several example interactions with the script in the terminal console
that we expect:
~~~ none
homework2 % python3 give_change.py
Enter the change amount: 47
Give 1 quarter 2 dimes 2 pennies as change.
homework2 % python3 give_change.py
Enter the change amount: 56
Give 2 quarters 1 nickel 1 penny as change.
homework2 % python3 give_change.py
Enter the change amount: 24
Give 2 dimes 4 pennies as change.
~~~
You can compute these amounts by first checking quarters, then checking for dimes on the cents remaining, then nickels, and then pennies. Use the integer division operations to determine the amounts,
**Hint for producing output**
A tricky thing to handle is that certain coins might not be included. For example, 26 cents has a quarter, a penny, but no dimes and no nickels. And yet what you output has to appear on one line.
I have mentioned to some of you that code like
~~~python3
print("here is the start", end="")
print("and here is the end", end="")
print()
print("Done.")
~~~
leads to the output
~~~none
here is the startand here is the end
Done.
~~~
The directive `end=""` is a way to have several `print` statements
put their text on a single line.
Another way to do the same is to build a string and then output the string.
For example, the code
~~~python
s = ""
s = s + "here is the start"
s = s + "and here is the end"
print(s)
print("Done.")
~~~
leads to the same output as the code just above.
It builds a string `s` first, and then it prints its text out onto a single line.
**Hint hint hint.** Also note that each of the coin denominations, when output, has a space after it.
---
• **[Hw2 Ex5] star pyramid**
Write code for a script `star_pyramid.py` that outputs a pyramid of asterisks of a requested height.
Below shows the execution of the script when the user requests a pyramid of height five:
~~~none
THE PYRAMID MAKER
Enter the height: 5
*
* *
* * *
* * * *
* * * * *
---------
~~~
The first two lines of input introduce the program.
The next line gets an input value with the string `"Enter the height: "` as its prompt.
Having received an input, it then prints a blank line, several lines of asterisks, and then a line of dashes.
Here is another execution, this time with height 6:
~~~ none
THE PYRAMID MAKER
Enter the height: 6
*
* *
* * *
* * * *
* * * * *
* * * * * *
-----------
~~~
You can assume that the user enters a value greater than 0 and that the pyramid fits within the width of the terminal. (It does not need to *check* these conditions. It can just assume that the user types in a reasonable value.)
**Please note:** The end of each printed line of the pyramid should end with an asterisk.
It should not end with a space. This means that you'll have to be more careful when you
describe its line with a string using the repetion operator (the `*` operator for strings).
---
• **[Hw2 Ex6] guess six**
I've written the script `guess.py` for a guessing game.
[You may download it at this link](homework2/guess.py).
It runs by first picking a random integer from 1 to 100 using this line of code:
~~~python
number = randint(1,100)
~~~
To do this, it relies on an earlier line
~~~python
from random import randint`
~~~
It then asks the user make guesses and gives them feedback on each guess.
Here is a run:
~~~none
*****************
* GUESSING GAME *
*****************
I've chosen a number from 1 to 100.
Try to guess it!
What's your guess? 59
Too high! Guess again.
What's your next guess? 32
Too low! Guess again.
What's your next guess? 48
You got it!
~~~
Modify the game so that it counts the number of guesses they've made
and limits the number of guesses to six.
The feedback it gives should be enhanced.
Among other things, it should keep the player aware of how many guesses they have left.
Here is a run where the player succeeds:
~~~
*****************
* GUESSING GAME *
*****************
I've chosen a number from 1 to 100.
Try to guess it in 6 or fewer guesses!
What's your guess? 59
59 is too high! Guess again.
You have 5 guesses left.
What's your next guess? 32
32 is too low! Guess again.
You have 4 guesses left.
What's your next guess? 48
48 is too high! Guess again.
You have 3 guesses left.
What's your next guess? 39
39 is correct.
You got it!
~~~
Here is an example where the player runs out of guesses:
~~~
*****************
* GUESSING GAME *
*****************
I've chosen a number from 1 to 100.
Try to guess it in 6 or fewer guesses!
What's your guess? 10
10 is too low! Guess again.
You have 5 guesses left.
What's your next guess? 90
90 is too high! Guess again.
You have 4 guesses left.
What's your next guess? 20
20 is too low! Guess again.
You have 3 guesses left.
What's your next guess? 85
85 is too high! Guess again.
You have 2 guesses left.
What's your next guess? 23
23 is too low! Guess again.
You have 1 guesses left.
What's your next guess? 30
Oh, sorry! Your guess of 30 was not correct.
And you are out of guesses.
My number was 55.
~~~
**[Hw2 Ex7] table**
Working from [our code for reporting a multiplication table](homework2/table.py),
write a script that reports the multiplication table with a bit more formatting.
It should output lines separating the rows and the columns in terminal text.
Here is a run of it, showing you how it should behave:
~~~none
Enter the number of rows: 8
Enter the number of columns 14
1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2| 4| 6| 8| 10| 12| 14| 16| 18| 20| 22| 24| 26| 28|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
3| 6| 9| 12| 15| 18| 21| 24| 27| 30| 33| 36| 39| 42|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4| 8| 12| 16| 20| 24| 28| 32| 36| 40| 44| 48| 52| 56|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
5| 10| 15| 20| 25| 30| 35| 40| 45| 50| 55| 60| 65| 70|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
6| 12| 18| 24| 30| 36| 42| 48| 54| 60| 66| 72| 78| 84|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
7| 14| 21| 28| 35| 42| 49| 56| 63| 70| 77| 84| 91| 98|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
8| 16| 24| 32| 40| 48| 56| 64| 72| 80| 88| 96|104|112|
---+---+---+---+---+---+---+---+---+---+---+---+---+---+
~~~
The rows and columns should be divided up using the minus, plus,
and bar characters `'-'`, `'+'`, and `'|'`.
It should also include the end-of-line character `'\n'` at each row's end.
The numbers reported should have leading spaces to
make the width of each column the same.
You can assume that the person enters a positive number of rows and a positive number of columns. (Your script need not check this or give errors--- it can just assume that the person enters these reasonable inputs.)
Here is a second run of the script:
~~~none
Enter the number of rows: 3
Enter the number of columns 2
1|2|
-+-+
2|4|
-+-+
3|6|
-+-+
~~~
Here is a third run:
~~~none
Enter the number of rows: 2
Enter the number of columns: 5
1| 2| 3| 4| 5|
--+--+--+--+--+
2| 4| 6| 8|10|
--+--+--+--+--+
~~~