CS21 Lab 4: functions and while loops
Written Assignment: Due Friday, October 1, at the start of class
Programming Assignment: Due Saturday, Oct 2, before midnight
Programming Tips
As you write your first programs, start using good programming practices now:
-
Use a comment at the top of the file to describe the purpose of the program (see example).
-
All programs should have a
main()
function (see example). -
Use variable names that describe the contents of the variables.
-
Write your programs incrementally and test them as you go. This is really crucial to success: don’t write lots of code and then test it all at once! Write a little code, make sure it works, then add some more and test it again.
-
Don’t assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.
-
Avoid writing any lines of code that exceed 80 columns.
-
Atom shows the column number in the lower left and draws a vertical line down the editing window at 80 characters.
-
In
emacs
, at the bottom, center of the window, there is an indication of both the line and the column of the cursor.
-
Function Comments
All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.
Are your files in the correct place?
Make sure all programs are saved to your cs21/labs/04
directory! Files
outside that directory will not be graded.
$ update21 $ cd ~/cs21/labs/04 $ pwd /home/username/cs21/labs/04 $ ls Questions-04.txt (should see your program files here)
Goals
-
Write programs with multiple functions.
-
Solve problems using indefinite
while
loops. -
Use the
random
library to make pseudo-random choices.
1. Written Assignment: Stack Diagram
The first part of the lab involves you tracing a program with functions and showing the resulting stack that the function calls generate. This is excellent practice for what will almost certainly be a future quiz question! Download the PDF, print it out, and turn it in at the start of class on Friday.
2. Programming Assignment: Odds and Evens
For this week’s lab we’re going to incrementally develop a variant of the game odds and evens.
Ultimately, we want the game to keep score of how well the human player is doing against the computer in multiple rounds of odds and evens.
We’ll build this game incrementally. As such, we’ll be modifying the main
function as we move from step to step. There’s no need to save your main
function from a previous step as you work on each next step. The entire lab
will be written in the file odd_even.py
.
2.1. Predicting odd or even
The first function you write and test should be named predict_it
. It should
prompt the human player to predict the result by typing either even
or odd
,
and it should return the string they typed in (either "even"
or "odd"
). If
the user doesn’t enter one of these two string values, your function should
print an error message and prompt the user to try again. The function should
only return when the user enters a valid string value.
The predict_it
function should not take any input parameters, and
it should return a string value. Its function definition will look like:
def predict_it():
To help test your program in small pieces as you go, add a call to the
predict_it
function in main
. For now, just print the value that predict_it
returns. Be sure to test it with both good and invalid input to verify that
it’s behaving as expected.
Here are some examples of how your program may behave while testing predict_it
:
$ python3 odd_even.py Predict either odd or even: odd predict_it returned: odd $ python3 odd_even.py Predict either odd or even: 1 Whoops, you must predict either odd or even. Try again. Predict either odd or even: eeeeven Whoops, you must predict either odd or even. Try again. Predict either odd or even: even predict_it returned: even
Recall that python strings can be compared with relational operators like ==
or <
just like integers and floats.
"morning" != "evening" # evaluates to True
2.2. Getting user number choice
Next, write a function named get_choice
that prompts the human player to
enter an integer between 0 and 5 (the value they are contributing to the sum).
Like predict_it
, the get_choice
function should only accept integers between
0 and 5. It should report an error and ask the user to try again if they enter
invalid input. Ultimately, it should return the integer value that the user
typed.
Like the predict_it
function, get_choice
should not take any input
parameters. Its function definition will look like:
def get_choice():
Your implementation of get_choice
will first need to verify that the string
the user types in can be converted to an integer before you call int()
on
it (otherwise the program might crash). Given a string, you can use
.isdigit()
on a string to tell you whether or not conversion is safe. Here
are some examples working with .isdigit()
:
>>> "3".isdigit() True >>> user_value = "37" >>> user_value.isdigit() True >>> "blah".isdigit() False >>> user_value = "swarthmore" >>> user_value.isdigit() False
After you’ve confirmed that the player’s input can be converted to an integer, you also need to ensure that it falls within the range [0,5].
As we did with predict_it
, let’s add a test call of get_choice
to main
so
that we can verify that it’s working as expected before we proceed:
$ python3 odd_even.py Predict either odd or even: odd predict_it returned: odd Enter a number between 0 and 5: 0 get_choice returned: 0 $ python3 odd_even.py Predict either odd or even: even predict_it returned: even Enter a number between 0 and 5: 10 Sorry, you must enter an integer between 0 and 5. Try again. Enter a number between 0 and 5: 5 get_choice returned: 5 $ python3 odd_even.py Predict either odd or even: odd predict_it returned: odd Enter a number between 0 and 5: blue Sorry, you must enter an integer between 0 and 5. Try again. Enter a number between 0 and 5: -2 Sorry, you must enter an integer between 0 and 5. Try again. Enter a number between 0 and 5: 3 get_choice returned: 3
2.3. Determining a winner
Now that we have inputs, let’s write a function to determine a winner. The
determine_winner
function will take three parameters:
-
an even/odd prediction made by the human player (string)
-
the human player’s number choice (integer)
-
the computer player’s number choice (integer)
The function definition should look like:
def determine_winner(prediction, user_choice, comp_choice):
The determine_winner
function should return a Boolean:
-
True
if the human player who predicted odd/even was correct (and won the game) -
False
if the human player who predicted odd/even was incorrect (and lost the game)
Refer to the rules at the top of the page for a description of how to determine "correct".
Remember, we are writing this program incrementally so there’s no need to
preserve your main
function as you develop the solution to this next step.
After completing determine_winner
, you can update main
to use predict_it
and
two calls to get_choice
to gather the inputs you need to test
determine_winner
. For example:
$ python3 odd_even.py Predict either odd or even: odd Enter a number between 0 and 5: 1 Enter a number between 0 and 5: 1 For a prediction of odd and choices 1 and 1, determine_winner returned: False $ python3 odd_even.py Predict either odd or even: odd Enter a number between 0 and 5: 1 Enter a number between 0 and 5: 4 For a prediction of odd and choices 1 and 4, determine_winner returned: True $ python3 odd_even.py Predict either odd or even: even Enter a number between 0 and 5: 2 Enter a number between 0 and 5: 4 For a prediction of even and choices 2 and 4, determine_winner returned: True
2.4. Keeping score
Finally, let’s write a print_scores
function to nicely display the score
between the human player and the computer.
The print_scores
function should take the following parameters as input:
-
the user’s name (string)
-
the number of games won by the user (integer)
-
the number of games won by the computer (integer)
Note that this function does not return a value. The program will call it for the side effect of printing some information. The function definition will look like:
def print_scores(name, user_wins, comp_wins):
The function should print out the current scores of the two players between lines of dashes. For example, with the argument values "Beth", 3, and 1, it should use string formatting and print out something like:
------------------------------ Beth: 3 Computer: 1 ------------------------------
To test print_scores
, you can add a few calls to it in main
with any name
and numbers you want (e.g, Beth, 3, and 1 as shown above). The formatting
doesn’t have to match exactly what’s shown above, but please make it look
similar so that it’s easier to grade!
2.5. Putting it all together
Now that you have all the functions you need, let’s combine them to play multiple rounds of odds and evens against a computer opponent. Be sure that all of the functions you write for this lab are well commented — if you haven’t done so already, now would be a good time to write those comments, as they may help you to put all the pieces together.
2.6. The main function
The main function of your program should do the following:
-
Ask the player for their name and the number of rounds to play. You may assume the player enters a valid positive integer for the number of rounds.
-
Continue playing the game for the number of requested rounds, keeping track of the number of wins for the human player and the computer. Use string formatting when printing results.
-
In each round, make use of the
predict_it
andget_choice
functions to get the human player’s odd/even prediction and number choice. -
Use the
randint function
from python’s random library to randomly choose a value between 0 and 5 for the computer player in each round. For example:from random import randint # Randomly select an integer between 0 and 5 (inclusive) random_value = randint(0, 5) print(random_value) # This will print something different every time from the set {0, 1, 2, 3, 4, 5}
-
Use
determine_winner
to award a win to either the human player or computer. -
Display the results after each round, using
print_scores
to show the current scoreboard. -
After all rounds are over, print the overall winner of the match (which player won the most games). Note: the final score could end in a tie.
2.6.1. Sample output
Your program’s output does not need to be identical to the following output, but you should make sure to have all the required functionality and that your program displays the information in a readable way. The more similar it looks to this output, the easier it will be to grade!
Sample output:
$ python3 odd_even.py What is your name? Kevin How many rounds should we play? 3 Predict either odd or even: odd Enter a number between 0 and 5: 1 Kevin predicts odd and chooses 1. Computer chooses 2. Kevin wins! ------------------------------ Kevin: 1 Computer: 0 ------------------------------ Predict either odd or even: even Enter a number between 0 and 5: 4 Kevin predicts even and chooses 4. Computer chooses 0. Kevin wins! ------------------------------ Kevin: 2 Computer: 0 ------------------------------ Predict either odd or even: odd Enter a number between 0 and 5: 2 Kevin predicts odd and chooses 2. Computer chooses 4. Computer wins! ------------------------------ Kevin: 2 Computer: 1 ------------------------------ The champion is: Kevin!
$ python3 odd_even.py What is your name? Lauri How many rounds should we play? 2 Predict either odd or even: even Enter a number between 0 and 5: 5 Lauri predicts even and chooses 5. Computer chooses 1. Lauri wins! ------------------------------ Lauri: 1 Computer: 0 ------------------------------ Predict either odd or even: odd Enter a number between 0 and 5: 0 Lauri predicts odd and chooses 0. Computer chooses 4. Computer wins! ------------------------------ Lauri: 1 Computer: 1 ------------------------------ The final score is a tie!
3. Answer the Questionnaire
Each lab will have a short questionnaire at the end. Please edit
the Questions-04.txt
file in your cs21/labs/04
directory
and answer the questions in that file.
Once you’re done with that, run handin21
again.
Turning in your labs…
Remember to run handin21
to turn in your lab files! You may run handin21
as many times as you want. Each time it will turn in any new work. We
recommend running handin21
after you complete each program or after you
complete significant work on any one program.
Logging out
When you’re done working in the lab, you should log out of the computer you’re using. First quit any applications you are running, like the browser and the terminal. Then click on the logout icon ( or ) and choose "log out".
If you plan to leave the lab for just a few minutes, you do not need to log out. It is, however, a good idea to lock your machine while you are gone. You can lock your screen by clicking on the lock icon. PLEASE do not leave a session locked for a long period of time. Power may go out, someone might reboot the machine, etc. You don’t want to lose any work!