**Homework 2: Conditionals and Loops**
**Reed CSCI 121 Spring 2025**
*submit by 2/11 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 // Increments the count variable by 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*
(#) 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 two example interactions with the script in the terminal console that we expect:
~~~ none
homework2 % python3 make_change.py
Enter the change amount: 47
1 quarter 2 dimes 2 pennies
homework2 % python3 make_change.py
Enter the change amount: 56
2 quarters 1 nickel 1 penny
homework2 % python3 make_change.py
Enter the change amount: 24
2 dimes 4 pennies
~~~
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,
**Note** that there should be no spaces at the end of the line where you output the change!
If you are finding it tricky to get your code to work because of this, **try the alternate Exercise 4** listed just after this exercise. In the alternate version, every coin you report has a space after its mention.
**Hint for getting the proper 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.
---
• **alternate [Hw2 Ex4] give change**
As an alternate to the exercise above, write a script that produces this output instead:
~~~ none
homework2 % python3 make_change.py
Enter the change amount: 47
Give 1 quarter 2 dimes 2 pennies as change.
homework2 % python3 make_change.py
Enter the change amount: 56
Give 2 quarters 1 nickel 1 penny as change.
homework2 % python3 make_change.py
Enter the change amount: 24
Give 2 dimes 4 pennies as change.
~~~
This alternate exercise may be a little easier, depending on your approach.
In this version of the problem every coin reported has a space following its mention.
**You need only do one of these two exercises that output change.**
---
• **[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] AM/PM clock**
Working from [our code for a 24-hour clock](homework2/clock24.py),
write a script that gets the reading of a clock in hours and minutes, and whether the time is morning or not (`AM` or `PM`).
It should then read a non-negative number of minutes that pass from that clock time.
It should output what the clock reads after those minutes pass.
Here is a run of it, showing you how it should behave:
~~~none
Hours on the clock? 12
Minutes on the clock? 38
AM or PM? AM
Minutes that pass? 63
1:41AM
~~~
Here is a second run:
~~~none
Hours on the clock? 9
Minutes on the clock? 37
AM or PM? AM
Minutes that pass? 178
12:35PM
~~~
And here is a third:
~~~none
Hours on the clock? 9
Minutes on the clock? 37
AM or PM? PM
Minutes that pass? 150
12:07AM
~~~
Note that hours are both input and reported as a number from 1 to 12,
minutes as a number from 0 to 59, and that the user is expected to enter either `AM` or `PM`.
(These aren't things your code needs to check. Rather, you can assume that the user will behave this way.)
The format of the time output should be either `HH:MM`
if the resulting hour is 10, 11, and 12, or `H:MM` if the resulting hour is from 1 to 9.