**Homework 2: Quotients and Conditionals**
**Reed CSCI 121 Fall 2022**
*complete the exercises by 9am on 9/13*
In this second homework we write a few more interactive scripts. Some
of these just rely on what you learned to complete Homework 1. We're
giving you more practice with integer and string calculations, with
`input`, and with `print`. Some also rely on integer division to do
their reasoning about their inputs. And some give you a chance to
practice using the *conditional statement* or "*if-else*" statement
so that their behavior can depend on conditions of the data input.
You can start work on these exercises in lab. They are all due in
a week. We'll talk more about the conditional statement in the coming
lectures.
(##) On Integer Division
Several exercises rely on integer division. This can be computed using
the quotient operator `//` and the remainder operator `%`. Here is an
example of their use:
~~~ python
>>> 37 // 10
3
>>> 37 % 10
7
~~~
These two operations are critical for codes and for digital
representations of numbers. For example, we can use integer division
by 10 to determine a number's digits because decimal representation
uses a base of 10. We can perform integer division by 2 to determine
its *bits*. This is the *binary*, or base 2, representation. Mastering
these operations now is going to be useful for understanding several
computer concepts we introduce later.
Clever people that are new to programming will often invent code like
`dividend - divisor * math.floor(dividend / divisor)`
when they should learn to write
`dividend % divisor`
to compute the remainder due to a division. The former code seems
like the right idea. It says "*Perform the division, throwing out the
fractional part with `floor`, that gives you a whole number. When you
multiply it by the divisor, we can subtract that from the dividend to
see what's missing. That missing amount is the remainder.*" While this
makes sense, there is no reason to rely on floating point operations to
perform integer division. Instead, you can directly use the `%`
operation.
You should not need to use floating point in any of the exercises
below. Instead, stick to using integers.
(##) The Conditional Statement
In lecture we have begun to discuss how Python code can check its data
to see if certain conditions are met. 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.
We will talk more about the *if-else* statement in lecture, and you
will want to use it to finish some of the exercises below.
(##) Submission and Autograding
Submit each Python source file containing your script code to
the Gradescope site. The problems below are labeled the way they will
appear as submission items in Gradescope. As before, we'll run a
series of tests on a problem submission to see if your code is
correct. The autograder will your scripts, trying out different
input strings. It checks to see whether the lines output by `print`
match what we expect. Before submitting, you should run your
scripts several times, and with different inputs, to make sure
that your code is working. Only submit it when you have reasonable
confidence that it is correct.
It's hard to anticipate every possible input, but you should work
to anticipate as much as you can.
Some of the problems allow you to assume that a user won't enter
certain kinds of inputs. When we allow you to make assumptions
like that, you do not need to check inputs that aren't assumed
to happen.
(##) Scoring
Each problem is worth 30 points. 10 of the points are awarded based on
the number of tests you pass. An additional prize of up to 10 points
will be awarded if *all* the tests pass by the due date. You'll earn
fewer of these prize points if you have to submit a problem several
times to get all the tests to pass. Another 10 points will be given
after the deadline as a result of our own assessment of the quality of
your code.
**Summary:**
* **test score:** *(automated)* partial or full credit for passing each test
* **prize score:** *(automated)* additional credit for passing all the tests before the deadline
* **style score:** *(by hand)* partial or full credit for code of reasonable quality
(#) Problems
(##) `[HW2 P1]` menu
A friend in the restaurant business has asked you to develop a Python
script for typesetting menus for his restaurants. Below is one he
produced by hand on a typewriter for his fancy bistro called
"Bobby's":
~~~ none
1234567890123456789012345678901234567890
Bobby's Entrees
---------------
Pasta verde.........................$ 15
Filet mignon w/ lobster and caviar..$107
Hamburger with fries................$ 9
~~~
In the top line, he decided to show that the menus are 40 columns
wide. There is a blank line, followed by the restaurant "Entrees"
lines, followed by the three entree lines.
Write a script `menu.py` that produces these menus as output. It should take
the restaurant name as input, and then it should take three input
strings for the names of three different entrees, along with their
prices in whole dollars. Each menu that your program outputs is 7
lines long and includes the top line with the column numbers.
Here is a sample interaction:
~~~ none
Restaurant name? Bobby's
First entree? Pasta verde
First entree price? 15
Second entree? Filet mignon w/ lobster and caviar
Second entree price? 107
Third entree? Hamburger with fries
Third entree price? 9
1234567890123456789012345678901234567890
Bobby's Entrees
---------------
Pasta verde.........................$ 15
Filet mignon w/ lobster and caviar..$107
Hamburger with fries................$ 9
~~~
You can assume that entree prices are under a 1000 dollars, and so you should
use three columns for formatting their digits. You can also assume
that the entree names they enter will fit, along with their price,
within the 40 columns. That is, for example, the "Filet mignon..."
entry is one character shorter than the longest string for an item
that your script will ever face.
Note that to do this you'll need to use some combination of the string
concatenation, repetition, and length operations, just as in the
`marquee` exercise from the last homework. You'll also want to convert
integers to strings to get the price spacing right.
(##) `[HW2 P2]` tens digit
In a file called `tens_digit.py`, write a script that
takes an input. It should then report the tens digit
of that integer. You can assume that the integer
they enter is 10 or larger. You need not worry about
handling smaller integers.
Here is the interaction in the terminal that we expect with your
script:
~~~ none
jimfix@fix-computer homework2 % python3 tens_digit.py
Enter an integer that is larger than 9: 1234
It has a tens digit of 3.
~~~
Your code should use the integer division operations, namely the
quotient operator `//` and the remainder operator `%` to perform
this calculation.
Note that there are Python library functions that convert integers
to strings of digit characters, and then string operations to extract
these digits. *Please don't use those string operations in your code.*
(##) `[HW2 P3]` reverse
Write a script `reverse.py` that takes a 3-digit integer as its input.
It should then print the number that has the same three digits but in
reverse order. For example, below is the kind of interaction we expect
to have with your code. We are running the script three times in a row,
each time entering a different integer.
~~~ none
jimfix@fix-computer homework2 % python3 reverse.py
Enter a 3-digit integer: 345
543
jimfix@fix-computer homework2 % python3 reverse.py
Enter a 3-digit integer: 719
917
jimfix@fix-computer homework2 % python3 reverse.py
Enter a 3-digit integer: 999
999
~~~
You can assume that the script is given an integer that is not
divisible by 10. You can also assume that the function is given an
integer that is greater than 100 and less than 1000.
Please **do not** use string operations to determine the digits of an
integer. Just as in the "tens digit" problem, you should use
integer division operations `//` and `%` to determine the digits of
the number.
(##) `[HW2 P4]` n-th digit
Write a script named `nth_digit.py` that takes two integer
inputs. You can assume that both inputs are non-negative. The second integer
is used to describe a digit position of the first. The
script should then report that digit in that position
within the digits of the first number.
It should behave exactly as follows:
~~~ none
jimfix@fix-computer homework2 % python3 nth_digit.py
Enter a non-negative integer: 957
Enter a digit position: 1
The 10s digit of that intger is 5.
jimfix@fix-computer homework2 % python3 nth_digit.py
Enter a non-negative integer: 957
Enter a digit position: 2
The 100s digit of that intger is 9.
jimfix@fix-computer homework2 % python3 nth_digit.py
Enter a non-negative integer: 957
Enter a digit position: 0
The 1s digit of that integer is 7.
jimfix@fix-computer homework2 % python3 nth_digit.py
Enter a non-negative integer: 957
Enter a digit position: 3
The 1000s digit of that integer is 0.
~~~
Note that, in the above examples, we are numbering the digits from
right to left, starting at 0, and so we are working from the
least-significant digit to the most-significant digit. This means
that position 0 corresponds to the ones place, position 1 corresponds
to the tens place, position 2 corresponds to the hundreds place, and
so on.
Treat positions that are "off to the left" of the digits of the integer
as being 0 digits. It's as if there is an infinite supply of 0s sitting
to the left of the actual digits of that number.
You can assume neither number entered is negative.
Just as in the earlier two problems where you are asked to determine
the digits of an integer, we ask that you not convert the integer to a
string to perform this function's calculation. Instead, you should
use the integer division operations `//` and `%` to determine the
number's digits.
(##) `[HW2 P5]` toonies
You decide to visit Canada to do some shopping. You've become fond of
their one-dollar coin, called a
["loonie"](https://en.wikipedia.org/wiki/Loonie) because its backside
depicts a common loon. You are even more fond of their two-dollar coin
called a ["toonie"](https://en.wikipedia.org/wiki/Toonie). You like
the toonie so much, you decide to pay for everything using these
two-dollar coins.
Devise a script `toonies.py` that, when given an item's cost in
Canadian dollars, expresses how many toonies you need to pay for
that item. Your script should have this kind of interaction:
~~~ none
C02MX1KLFH04:homework2 jimfix$ python3 toonies.py
Item cost in Canadian dollars? 21
Pay 11 toonies.
C02MX1KLFH04:homework2 jimfix$ python3 toonies.py
Item cost in Canadian dollars? 20
Pay 10 toonies.
~~~
You can assume that the item's price is a whole dollar amount and at least
three dollars. (This means that you'll never calculate payments of fewer
than two toonies.) You should only be using integer calculations for this
script. You shouldn't even need to use the conditional statement.
We are interested here in the evenness and oddness of the payment
amount, so you'd look at the amount's divisibility by two.
(##) `[HW2 P6]` 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 1. 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, and if both things are true they say
"zap buzz".
Devise a script `zap_buzz.py` that plays a turn of the game. It should
take a positive integer input. It should then print that integer if
neither of the "zap"/"buzz" conditions hold. If some condition
holds, print `zap`, or print `buzz`, or print `zap buzz`,
whichever is appropriate. You are allowed to assume
the parameter is less than 1000. As in the earlier exercises, please
don't convert the integer to a string to determine its digits.
Here are several interaction with the code that we might expect:
~~~ none
jimfix@fix-computer homework2 % python3 zap_buzz.py
Integer? 8
8
jimfix@fix-computer homework2 % python3 zap_buzz.py
Integer? 14
zap
jimfix@fix-computer homework2 % python3 zap_buzz.py
Integer? 13
buzz
jimfix@fix-computer homework2 % python3 zap_buzz.py
Integer? 35
zap buzz
~~~
(##) `[HW2 P7]` multiple
Recall that an integer $a$ is a multiple of $b$ when $a$ can be written as a
product of $b$ and some integer. 10 is a multiple of 5 because `10 == 5 * 2`.
100 is a multiple of 5 because `10 == 5 * 20`. -10 is a multiple of 5
because `-10 == 5 * (-2)`. -10 is also a multiple of -5 because `-10 == (-5) * 2`. And finally 10 is also a multiple of -5 because `10 == (-5) * (-2)`.
Write a script named `multiple.py` that takes two integer inputs. It should
then report whether or not the first is an integer multiple of the second.
Below are several interaction with the code that we expect:
~~~ none
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: 10
Enter another integer: 5
10 is a multiple of 5.
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: 100
Enter another integer: 5
100 is a multiple of 5.
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: -10
Enter another integer: 5
-10 is a multiple of 5.
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: 10
Enter another integer: -5
10 is a multiple of -5.
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: 101
Enter another integer: 5
101 is not a multiple of 5.
jimfix@fix-computer homework2 % python3 multiple.py
Enter an integer: 101
Enter another integer: -5
101 is not a multiple of -5.
~~~