CS21 Lab 5: More Advanced Functions

Due Saturday, Feb 25, before midnight

Programming Tips

As you write programs, use good programming practices:

  • 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.

    • Always work in a terminal window that is 80 characters wide (resize it to be this wide)

    • In vscode, at the bottom right in 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/05 directory! Files outside that directory will not be graded.

$ update21
$ cd ~/cs21/labs/05
$ pwd
/home/username/cs21/labs/05
$ ls
Questions-05.txt
(should see your program files here)

Goals

  • Work with functions and lists

  • Work with mutable and immutable function parameters

  • Work with functions that return values

  • Work with functions used only for their side effect

For this week’s lab we’re going to incrementally develop an implementation of the game guessSports.

Game rules.

The program first ask the player to choose how many (num_turns) turns the game takes, and how long (code_length) the secret code is. Let’s assume num_turns = 3 and code_length = 4.

In this game, the computer generates a secret "code", which is a list of four (code_length) sports e.g. "basketball soccer tennis soccer". There are six possible sports: basketball, golf, lacrosse, soccer, swimming, and tennis.

The object of the game is to guess the secret code. Each turn, the player enters a guess for the code, for example "golf soccer tennis lacrosse". The computer then reports how many exact matches the player had. An exact match is when the player guesses a sport correctly and puts it in the correct position.

The player has three (num_turns) turns to guess the secret code. If they do, they win! Otherwise, the computer wins.

For example, if the secret code is "basketball soccer tennis soccer", then:

  • a guess of "basketball soccer tennis soccer" has 4 exact matches.

  • a guess of "tennis swimming tennis soccer" has 2 exact matches.

  • a guess of "golf golf basketball swimming" has 0 exact matches.

1. Printing lists of sports

Before writing functions to handle the main game mechanics, you should write some initial simple functions that generate and print lists of sports.

The first function you write and test should be named print_sports(sport_list). It should take a single list sport_list of strings representing sports and nicely print the sports to the screen. Put commas between the sports to make the printout look nice. For example,

  • if the input to print_sports was ["golf", "golf", "soccer", "tennis"], then print_sports should print

golf, golf, soccer, tennis

Before moving onto other functions, test just this function by calling it within main(). For now, just make up the sports you want to print out.

2. Prompting a lists of sports from the user

Once you’ve written and tested print_sports, write a function get_guess(sports, code_length). This function should take a list of the six possible sports, and ask the player for code_length legal sports. The function should repeatedly ask for a sport until the player enters a legal one. Store these code_length sports in a list, and return the list once the player has entered code_length many legal sports.

See the example code below (player input in bold).

$ python3 guessSports.py
Please enter four legal sports.  Your choices are:
basketball, golf, lacrosse, soccer, swimming, tennis
Enter sport 1: running
running is not a valid sport.
Please choose from the following sports:
basketball, golf, lacrosse, soccer, swimming, tennis

Enter sport 1: soccer
Enter sport 2: soccer,
soccer, is not a valid sport.
Please choose from the following sports:
basketball, golf, lacrosse, soccer, swimming, tennis
Enter sport 2: soccer
Enter sport 3: golf
Enter sport 4: biking
biking is not a valid sport.
Please choose from the following sports:
basketball, golf, lacrosse, soccer, swimming, tennis
Enter sport 4: basketball

You guessed:
soccer, soccer, golf, basketball

3. Generating a code of sports

Once you’ve written and tested get_guess(sports, code_length), write and test a function generate_code(sports, code_length). This function should take a list of the six possible sports, a code_length variable, and return a list of code_length random sports. Use the choice function from the random library. The choice function takes a list as input and returns a random element from the list.

from random import choice
...
L=[2,3,5,7,11]
print(choice(L))  # prints out random item from list L

Test your implementation of generate_code(sports, code_length) by calling it once or twice in main(). Use print_sports(sport_list) to print out the sports.

By the end of this part of the lab, you should have implemented and tested the following functions:

  • print_sports(sport_list)

  • get_guess(sports, code_length)

  • generate_code(sports, code_length)

Now you have functions to handle the game setup and prompting the user for input, so it’s time to move on to the rest of the game!

4. Checking the player’s guess

Write and test a function exact_matches(secret_code, guess) which checks how many exact matches the player got. The exact_matches(secret_code, guess) function takes two input parameters. secret_code and guess are the target code and the player’s guess. Each is a list of code_length sports. The function should return an integer representing the number of exact correct matches that the user got in the secret code.

  • For each guessed sport

    • Check whether it was an exact match in secret_code sequentially

Be sure to test this function in your main() program before moving on. Does exact_matches return the correct number of matches? If so, you are ready to complete the full guessSports program!

5. Write some helper functions

Before moving on to the final part of the implementation, it will be helpful to write and test some simple helper functions.

  • print_introduction() should take no parameters and print out the rules to guessSports.

  • is_game_over(num_exact_matches, turn, num_turns, code_length) takes four integer input parameters. This function should return True if the game is over; that is, if the player guessed all code_length exact matches, or if the player ran out of their num_turns turns.

  • player_won(num_exact_matches, code_length) takes two integer input parameter. This function should return True if the player won the game.

It might seem a little strange to test the is_game_over() or player_won() functions before writing the main part of the game. Just call these functions with dummy variables to see if they return what you expect them to return. It will be helpful to know these functions work before it comes time to complete your program.

6. Putting it all together

We’re almost all done now. The fully finished guessSports program might have the primary steps in main() as shown below. Think about how to use all the helper functions you’ve just implemented to accomplish each step.

  1. Print out instructions to the player

  2. Ask the player to choose how many (num_turns) turns the game takes, and how long (code_length) the secret code is. (You can assume the player enters integers for (num_turns) and (code_length).)

  3. Pick a secret code for the player to guess.

  4. Until the player guesses the secret code or runs out of turns:

    • Show the current turn number

    • Ask the player for a guess

    • Compute the number of exact matches

    • Print out the number of exact matches

  5. Check to see if the player won. If so, print out how many turns it took. If not, print out a sympathetic message.

Hint: Even though we ask how many turns the game should last, the game can end early if the player guesses the code correctly. So what kind of loop will be useful to implement this game?

7. Sample output

As with the previous lab, your program’s output does not need to be identical to the following output, but you should have all the required functionality, and your program should display the information in a readable way.

$ python3 guessSports.py
Welcome to guessSports!

Your goal is to guess a sequence of (code_length) sports.
Each sport can be basketball, golf, lacrosse, soccer, swimming, or tennis.
Each turn, enter (code_length) sports separated by spaces.
Then I'll tell you how many times you guessed the correct sport
  in the correct position.
You have (num_turns) turns to guess the correct sequence.
Good luck!

Please enter an integer for how many (num_turns) turns the game lasts: 2
Please enter an integer for how how long (code_length) the secret code is: 1

Turn 1:
Please enter 1 legal sports.  Your choices are:
basketball, soccer, tennis, golf, lacrosse, swimming
Enter sport 1: golf

You guessed:
golf
There are 1 exact matches.

The answer was:
golf
You won!
It took you 1 turn to get the correct answer.

Here’s another example:

$ python3 guessSports.py

Welcome to guessSports!

Your goal is to guess a sequence of (code_length) sports.
Each sport can be basketball, golf, lacrosse, soccer, swimming, or tennis.
Each turn, enter (code_length) sports separated by spaces.
Then I'll tell you how many times you guessed the correct sport
  in the correct position.
You have (num_turns) turns to guess the correct sequence.
good luck!

Please enter an integer for how many (num_turns) turns the game takes: 3
Please enter an integer for how how long (code_length) the secret code is: 2

Turn 1:
Please enter 2 legal sports.  Your choices are:
basketball, soccer, tennis, golf, lacrosse, swimming
Enter sport 1: golf
Enter sport 2: soccer

You guessed:
golf, soccer
There are 0 exact matches.

Turn 2:
Please enter 2 legal sports.  Your choices are:
basketball, soccer, tennis, golf, lacrosse, swimming
Enter sport 1: lacrosse
Enter sport 2: swimming

You guessed:
lacrosse, swimming
There are 1 exact matches.

Turn 3:
Please enter 2 legal sports.  Your choices are:
basketball, soccer, tennis, golf, lacrosse, swimming
Enter sport 1: basketball
Enter sport 2: swimming

You guessed:
basketball, swimming
There are 0 exact matches.


The answer was:
lacrosse, tennis
Oh no, you lost!

8. Optional Extra Challenges

This is an optional extra challenge. There are lots of fun extensions you could add to guessSports.py.

  • Check for valid player input, so that if the player enters "-4" number of turns, the program detects that and forces them to fix it.

  • Allow the player to change how many sports you can guess from.

  • Allow the player to change which sports you can guess from.

  • Implement a computer player who will make guesses instead of the human player.

  • Anything else you can think of? Let us know if you come up with something interesting!

Answer the Questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-05.txt file in your cs21/labs/05 directory and answer the questions in that file.

Once you’re done with that, you should run handin21 again.

Submitting lab assignments

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 (logout icon or other logout icon) 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 xlock 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!