**Homework 1: Scripting**
**Reed CSCI 121 Spring 2025**
*submit by 2/4 at 9am*
In lecture we covered some key elements of the Python language. We
looked briefly at some kinds of calculations you can perform on data.
We showed how you can keep track of computed values with variables by
assigning a variable a value that you ask Python to compute. We can
interact with Python's interpreter (the `python3` command) to perform
these computations. Or else we can have the Python interpreter run a
script we've written to have it perform a sequence of calculations
we've programmed.
We also started thinking a little about the different kinds, or
*types*, of data values manipulated in Python programs. For numeric
calculations we played with both floating point data and integer
data. These data values have the type `float` and the type `int`,
respectively. You also learned how to manage text information using
*string* data. Strings are text character sequences and have the
Python type `str`. You can check this type info in the Python
interpreter as shown below:
~~~python
>>> type(3)
>>> type(3.14)
>>> type("Is it confusing that three is 3 and also 3.0?")
>>> type('Or did I mean "three" there?')
~~~
As we continue the semester, and as you read and learn more about
Python, you'll recognize that Python can often be flexible about
programs' use of different types of data. Nevertheless, to be a good
programmer, you'll often want to be deliberate about what types of data
you are working with in a program, and take care in not mixing these
different types up.
In this lab homework we're going to practice programming using the
kinds of calculations you've learned so far. Below are eight Python
exercises. Each asks you to write a simple *interactive* script that
can be run in the terminal. Python allows you to read what's entered
into the terminal (using `input`) and to report computed values (using
`print`).
Below, for example, is a short three-line script that performs
temperature unit conversion, getting a temperature in degrees Celsius,
then reporting the equivalent in degrees Fahrenheit:
~~~python
c = float(input("Temperature in degrees Celsius? "))
f = (c * 9.0 / 5.0) + 32.0
print(f)
~~~
Running the code, we see that `input` produces a prompt, then waits
for the user to enter a value. Python reads their entry as a string of
characters, and so we use `float` to convert those characters to a
floating-point numeric value. The second line, a variable assignment
to `f` using the value `c`, computes the floating point value
according to that calculation. The value of variable `f` gets printed
because of the last line of the script.
Here's what happens in Terminal when we run that code using the `python3`
command and, say, enter `100.0`:
~~~none
C02MX1KLFH04:hw01 jimfix$ python3 temperature.py
Temperature in degrees Celsius? 100.0
212.0
~~~
It's possible to make the output of `print` more readable by including
other text in that line of output. To do this, we can explictly
convert the temperature to a string of characters using the `str`
conversion function and then append strings around that formatted
information. We append strings using the `+` operator. For example, if
we change the last line of the code above to
~~~python
c = float(input("Temperature in degrees Celsius? "))
f = (c * 9.0 / 5.0) + 32.0
print("That is "+str(f)+" in degrees Fahrenheit.")
~~~
it leads to this interaction
~~~none
C02MX1KLFH04:hw01 jimfix$ python3 temperature.py
Temperature in degrees Celsius? 100.0
That is 212.0 in degrees Fahrenheit.
~~~
Note the spaces that we used to separate the number from the other text
of the sentence.
Each of the exercises below asks you to write a Python script similar
to the one above. Each program you write takes an input, or a series of
inputs. It then performs calculations on that input data and produces
a formatted output of those calculations' results. We first ask you to
work with strings alone. You then work with integer and floating point
values. For these you'll want to convert input strings into numbers
using the `int` and `float` functions.
# Submission and Autograding
You should run your scripts several times, and with different inputs,
to make sure that your code is working. Once you have reasonable
confidence that it is working, submit it at the appropriate assignment
link on
[the Gradescope site for this course](https://www.gradescope.com/courses/432033).
When you upload the file for that problem on Gradescope we'll
immediately run a series of tests on that code to see if it is
correct. Within a minute or so, you'll get feedback from our `aga`
Gradescope autograder" as a series of messages. If all these tests
pass, then these messages will be green. Any failed tests will give a
red message, and usually with some extra information underneath that
can help you figure out what we found wrong with the code.
Our ability to give feedback in this way is limited, so you should
seek help from your instructor or a tutor to help you explain what
went wrong, and to help you think about fixing the problem. On some
rare occasions some of you may face something that's wrong with our
set-up so it's helpful to reach out to us if you are confused by the
autograder's report. There will be those moments when there's
something we didn't anticipate in your submission, hopefully rarely.
Do not use Gradescope to test your code. Instead run the code
yourself using Python's interpreter and only submit once you're
convinced that the code is correct. If you fail some of our tests that
should give you some pause. Take a moment to carefully look through
your code and fix it, and then run some of your own tests before
submitting it again. Don't just make a quick change, cross your
fingers, and submit it again.
**Scoring**
Each problem is worth 20 points. 10 of those points are assigned by
the auto-grader, and the remaining 10 will be assigned later by
one of us and is our way of giving you (human) feedback on the
quality of your code.
The auto-graded score is determined by some thoughtful test inputs
that we've devised to check different scenarios. Our use of automated
testing is meant to mimic real-world software coding, where a
programmer's code has to work in practice, sometimes facing
unanticipated but perfectly reasonable scenarios.
The hand-graded score reflects our sense of your coding. Was it clear
and succinct? Or did it do something unusual just to get the tests to
pass? When we get to more complicated coding, these points will help
us give feedback on code "style." Making complicated code
human-readable and human-understandable is often as important as
whether the code works, especially for larger coding projects.
We split the auto-graded score into two components. We give points for
passing some of the tests. This helps us to at least see the progress
you've made in tackling the problem. This will be especially valuable
for later assignments when you've figured out most of the problem but
maybe haven't considered some tricky “edge cases” yet.
Both the test score and the hand-graded score allow us to reward you
for figuring out most, if not all, of the problem's puzzle. And the
hand-grading allows us to give feedback on the quality of your
code.
# Exercises
• **[Hw1 Ex1] temperature**
I've written a simple interactive script, downloadable
[**as this linked file**](homework1/temperature.py) called `temperature.py`
that requests an input, a numeric value that will be treated
as a temperature in degrees Celsius. The program, after that
amount is entered, reports the equivalent temperature in
degrees Fahrenheit.
Here is the Python code for that program:
~~~ python
c = float(input("Temperature in degrees Celsius? "))
f = (c * 9.0 / 5.0) + 32.0
print("That is "+str(f)+" in degrees Fahrenheit.")
~~~
And here is an example of its execution in terminal:
~~~ none
C02MX1KLFH04:homework1 jimfix$ python3 temperature.py
Temperature in degrees Celsius? 40.5
That is 104.9 in degrees Fahrenheit.
~~~
The program takes a string as input and, assuming that its user
types in a valid number, converts that string to a floating point
value (with the `float(•)` conversion we described in lecture). It
uses the variable `c` to store that value. It then assigns the
variable `f` to the appropriate number of degrees, according to the
Celsius-to-Fahrenheit formula. It then outputs that amount, but
has to do so by converting the floating point value held in `f`
to a string (with the `str(•)` conversion we also described in
lecture).
Modify the code so that it instead asks for a temperature in
degrees Fahrenheit and reports the equivalent in degrees Celsius.
Your program should lead to interactions like this one:
~~~ none
C02MX1KLFH04:homework1 jimfix$ python3 temperature.py
Temperature in degrees Fahrenheit? 104.9
That is 40.5 in degrees Celsius.
~~~
Note that you will first need to figure out what the relevant formula
is that does the conversion in the opposite direction. Also, these are
floating point operations. That means that there can be very slight
rounding errors. For example, there is code that will give an output
of 40.50000001 for the interaction above. In code that was interacting
with a real user, you would probably want to round answers to prevent
that sort of thing, but for this problem just give the answer your
formula computes. We'll check that your output is similar enough in
value to the number we expect.
While the number you report only needs to be close enough,
you need to get the spacing exactly right for the code to be
considered correct
---
• **[Hw1 Ex2] distance**
We're writing a new app that allows people in Portland to find where they
are relative to Reed's campus, one that presents a map to the app's user.
The center of Eliot Circle is the origin of the map. When a person is
walking around, the app gives a two-dimensional coordinate of their location,
$(x,y)$, giving them a position within a grid laid over the map. The $x$
coordinate indicates how many miles east of Eliot Circle they are. The
$y$ cordinate indicates how many miles north of Eliot Circle they are.
At any moment, the app tells them their distance from Eliot Circle, and that
is computed (using the Pythagorean Theorem) to be
$$\sqrt{x^2 + y^2}$$
that is, the square root of the sum of the square of the distance east
with the square of the distance north.
We want to enhance the app so that it allows a student to figure out their
distance from a classroom. If they are located at $(x_1,y_1)$ and the
classroom is located at $(x_2,y_2)$, then their distance from that
classroom is
$$\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}$$
Write a Python script `distance.py` that allows you to experiment with
this distance calculation. It should take the $x$ and $y$ coordinates
of one location, and then the $x$ and $y$ coordinates of a second
location. It should then report the distance using the above
calculation.
~~~ none
Location x-coordinate? 3.2
Location y-coordinate? 1.5
Classroom x-coordinate? 6.2
Classroom y-coordinate? -2.5
Distance: 5.0
~~~
Note that you can compute the square root by using the exponentiation
operator `**` and with an exponent of `0.5`. It's also possible to
`import` Python's `math` package which defines a function `sqrt`.
Either is fine, one requires that you practice using `import`.
To import, put this line at the very top of the code, before the
script that does the work:
~~~ python
from math import sqrt
~~~
and then any code below that line will know about the function `sqrt`.
----
• **[Hw1 Ex3] hal**
In the science fiction movie *2001: A Space Odyssey*, the artificial
intelligence of the `HAL 9000` computer, when commanded to do something,
tells the main astronaut character:
~~~ none
I'm sorry, Dave. I'm afraid I can't do that.
~~~
Write a Python script `hal.py` that replicates this interaction. It
should prompt for a name to be entered, and then take a string as
input. It should then prompt for an action it should take, and then
take a second string as input.
Having obtained those two input strings, your program should then output
a contrarian's reply using that name, and then report that the action was
not taken. Here, for example, is a transcript from a terminal
execution of the command `python3 hal.py`:
~~~ none
What is your name? Dave
Ok. Now enter an action: Open the pod bay doors.
I'm sorry, Dave. I'm afraid I can't do that.
(The action "Open the pod bay doors." was not performed.)
~~~
In that example, the first two lines are each a combination of a printed
prompt (each ending with a space character) followed by the characters
entered by the person running the program. Here, they entered `Dave`
and hit the `[return]` key and then `Open the pod bay doors.` followed
by the `[return]` key.
After these two entries, a blank line and then the next two lines are
printed by the script.
Here is another example of an expected interaction with your program
when run:
~~~ none
What is your name? stanley kubrick
Ok. Now enter an action: cut!!!
I'm sorry, stanley kubrick. I'm afraid I can't do that.
(The action "cut!!!" was not performed.)
~~~
Your program's interactions must exactly mimic the examples above.
There should be a space between each prompt and the program user's
input. There should be one space before the name and a period
immediately following it. There should be a double quote character
just before and just after the action. Note that, even though the
document you are reading (this one here) might make it appear so,
there should be no spaces at the start of each line. The lines
are each left justified.
Note that you can output a blank line with the python statement
~~~
print()
~~~
that is, by giving `print` no argument within the parentheses.
Do your best to test your code and check the output, comparing it with
our expected output. Be wary of your spacing before you submit. The
interaction's transcript is in a fixed-width (i.e. monospaced or
"typewriter") font, so each character, including spaces, appears in
its own column. This means that the output characters can be seen to
line up within a grid as depicted below:
![*Figure.* Gridding of terminal output.](images/hal-grid.gif)
Now, with all that being said, get that AI working! (Or, I suppose,
get it *not working*--- HAL is *stubborn* and unwilling to do
anything.)
**Tips**
A big issue here is that there are two ways to describe a string of characters
in Python. For example printing a `Hello.` line can be expressed in a program
as
~~~python
print("Hello.")
~~~
using double quotes around the string of characters and
also instead using single quotes with
~~~python
print('Hello.')
~~~
But this means that the single quote character `'` and the double quote
character `"` have special meaning in this code. So, for example, you
have to do extra work if you literally want a quote within a string.
For example, `Don't.` could be expressed in two ways:
~~~python
print("Don't.")
print('Don\'t.')
~~~
The second form uses the "escape" backslash character `\ ` to alert
Python that a special character is coming next. So we read `\'` as
"escape to quote" There is also `\\ ` for "escape to backslash", `\t`
for "escape to tab", and `\n` for embedding an escaped request to
start a new line within the middle string.
---
• **[Hw1 Ex4] marquee**
Write a Python program `marquee.py` that attempts to mimic movie
theater marquee signs, putting a word "*in lights*". To get an
idea of what we want, below is an execution of the program:
~~~ none
Title? hello
*********
* hello *
*********
~~~
The first line is the input prompt, along with an entry of the word
`hello`. The second output line is just a blank line. The next three
lines show the word decorated with surrounding asterisks.
Here are two other interactions:
~~~ none
Title? Groundhog Day
*****************
* Groundhog Day *
*****************
~~~
~~~ none
Title? Hello World: A Text-Based Adventure
***************************************
* Hello World: A Text-Based Adventure *
***************************************
~~~
To do this you need to use some string operations. We've been using
string concatenation, designated with the `+` plus sign above. Recall
also that the `*` asterisk can be used for string repetition. For
example, the expression `'hi'*5` means `'hihihihihi'`. Here are some
other examples of string repetition in Python:
~~~ python
>>> 'hi'*2
'hihi'
>>> 'hi'*0
''
>>> 'hello ' + ('hey ' * 3) + 'bye'
'hello hey hey hey bye'
~~~
The other string operation you need is a function that computes the
length of a string, `len`. It gives the number of characters in
the string's sequence. Here are some example uses of `len`:
~~~
>>> len('hello')
5
>>> len('Hello, I must be going.')
23
~~~
Note that it counts each space, each letter, and each punctuation mark laid
out between the quotes.
String concatenation, repetition, and length should be enough tools
needed to make `marquee.py`.
---
• **[Hw1 Ex5] toonies**
You decide to visit Canada to do some shopping. You've become fond of
their one-dollar coin, called a *loonie* because its backside depicts a
common loon. You are even more fond of their two-dollar coin called a
*toonie*. You like the toonie so much, you decide to pay for everything
using these two-dollar coins. Devise a Python script 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
terminal:homework reeduser$ python3 toonies.py
Item cost in Canadian dollars? 21
Pay 11 toonies.
terminal:homework reeduser$ 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.)
**Note (and hint):** You should only be using integer calculations for
this script. (No need for floating point!) And you shouldn't use any
kind of Python conditional statement or conditional expression to
write this code. (We'll be learning about those later in the course.)
Instead, since we are interested in the evenness and oddness of the
payment amount, you want to consider the amount's divisibility by two.
---
• **[Hw1 Ex6] tipping**
You've just eaten a tasty meal at a restaurant and you've decided to
reward them for their service. Devise a tool that computes a tip
amount. Your `tip.py` script should take three inputs:
the meal's price in dollars and cents, along with a tip percentage
from 0 to 100. Have it compute the tip as a floating point
value and output that value, like so
~~~none
terminal:hw1 jfix$ python3 tip.py
Price dollars? 20
Price cents? 0
Tip percentage [0-100]? 15
3.0
terminal:hw1 jfix$ python3 tip.py
Price dollars? 3
Price cents? 60
Tip percentage [0-100]? 50
1.8
terminal:hw1 jfix$ python3 tip.py
Price dollars? 3
Price cents? 60
Tip percentage [0-100]? 20
0.72
~~~
You can assume that the dollars, cents, and tip percentage are all
integers. The dollar amount you output should be a floating point value.
**Note:** In the last tip percentage example, suppose we only tipped 1
percent. Then the tip amount would only be 0.036, and that includes a
fraction of a cent (3/5-th of a cent). Your code will be accepted as
correct if the tip amount you output is within one cent of the exact
amount, including fractions of a cent. This means that you are welcome
to output an amount that *does not* have more than two digits after the
decimal point. To do this, you could use Python's built in `round`
function. This function can take two parameters and is documented
[**here**](https://docs.python.org/3/library/functions.html#round).
---
• **[Hw1 Ex7] 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
Bobby's Entrees
---------------
Pasta verde.........................$ 15
Filet mignon w/ lobster and caviar..$107
Hamburger with fries................$ 9
~~~
The menu has a top line with the restaurant name and `"Entrees"`
underlined by dashes, and these lines are followed by
the three entree lines with their prices.
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 5
lines long.
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
Bobby's Entrees
---------------
Pasta verde.........................$ 15
Filet mignon w/ lobster and caviar..$107
Hamburger with fries................$ 9
~~~~
Your program should match this formatting precisely.
Note, for example, that there is a blank line between the last input and the beginning of the menu.
Note that the line of dashes under "Bobby's Entrees" matches it in length.
Also, three columns ares used to list each price.
(I.e., if prices are all under $100, still leave space like the $15 and $9 prices above.)
You can assume that all prices are whole dollar amounts under $1000.
The longest entree item should have two periods between it and its price.
The other prices should be aligned to that.
There is a built-in function `max` that you can use to help you with this calculation.
For the formatting, you'll need to use some combination of the string
concatenation, repetition, and length operations, just as in the
`marquee.py` exercise.
You'll also want to convert integers to strings to get the price spacing right.