CS21 Lab 11: Classes and Objects

Due Thursday, December 8, by 11:59pm


Read through this entire lab writeup BEFORE you begin to write any code. Taking the time to thoroughly understand what you are trying to accomplish will allow you to more effectively implement the code.

Goals

  • Gain experience writing classes

  • Gain experience reading and using classes

Requirements

The following are the main requirements of this lab:

  • You must write and use an Adventurer class (i.e. don’t try to find a workaround using some other language feature)

  • The primary logic controlling the behavior of individual Adventurers should be in the class

  • You will maintain a team of Adventurers outside of the class (i.e. in the main program, which should maintain a list of Adventurer objects)

  • You should have test code for your Adventurer class in the file that defines the class, adventurer.py. Details are below in the section describing adventurer.py

Adventure Team!

For this lab, you’ll make a simple class to represent a team of Adventurers who love to go off on quests! Each Adventurer will described by the class Adventurer. Your program will consist of two files:

  1. adventurer.py will contain the class definition for the Adventurer class, and

  2. team.py will contain a program to let the user take the Adventurers on quests.

adventurer.py

Read through this entire section before writing any code!

Adventurers are characters in a fictional world that like to go on adventures. Each Adventurer has a favorite quest to go on. For example, Barney likes to chase dragons. However, Adventurers can’t go on quests on an empty stomach, so before going on quests, Adventurers need to eat. Barney’s favorite food is purple grapes, so before setting off to chase dragons, Barney will eat purple grapes. And after eating and questing, Barney might want to buy some purple hiking boots before setting off to go chase more dragons. Of course, after a long day of eating purple grapes, chasing dragons, and shopping for new hiking boots, an Barney will want to rest.

The adventurer.py file should contain a class definition for a class called Adventurer. The Adventurer class should have at minimum the following methods:

  • Constructor (__init__)

    • this should take in the Adventurer’s name, their favorite_quest, their favorite_food, and their favorite_equipment. In the example above, the Adventurer’s name was "Barney", their favorite quest was "chasing dragons", their favorite food was "purple grapes", and their favorite equipment was "hiking boots".

    • each of these should be stored in an instance variable

    • the constructor should also initialize instance variables counting the number of times the Adventurer has quested (which starts out as 0), how much food they’ve eaten (which should start out as 0), and how many items of their favorite equipment they currently have (which should start out as 0).

  • get_name()

    • this method should take no parameters (other than self), and should return the Adventurer’s name.

  • __str__()

    • this should take no parameters (other than self), and should return a string that reports back all of the instance variables

    • this method can be used as you test your program so you can be sure you are storing the correct values for each of the instance variables.

    • the format of this output is up to you, but it must include the name of each instance variable and the value of each instance variable.

  • quest()

    • this method should each take no parameters (other than self), should update the Adventurer’s state and print a message about what’s happening.

    • your Adventurer cannot go on a quest if they haven’t eaten. if they try to quest while hungry, print out an appropriate status message (e.g. "Barney needs to eat!")

    • if they are able to go on a quest:

      • you should increase the number of times the Adventurer has quested by 1

      • going on quests makes the Adventurer hungry so you should decrease the amount of they’ve eaten by one.

      • print a status such as "<name> is <descriptor>!" where "<descriptor>" is the favorite_quest they like to go on (e.g. "Barney is chasing dragons!")

  • eat()

    • this method should each take no parameters (other than self), should update the Adventurer’s state and print a message about what’s happening.

    • your Adventurer can only eat twice without getting overly full.

    • if they try to eat too much, your Adventurer can’t eat anymore

      • print an appropriate message (e.g. "Barney has already eaten too much!")

      • don’t increase the amount they’ve eaten

    • otherwise

      • increase the amount they’ve eaten by 1

      • print a status such as "<name> ate some <descriptor>!" where descriptor is their favorite_food (e.g. "Barney ate some purple grapes!")

  • shop()

    • this method should each take no parameters (other than self), should update the Adventurer’s state and print a message about what’s happening.

    • when your Adventurer goes shopping, add 1 to the number of items of equipment they own

    • print out a status message such as "<name> bought <descriptor>" where descriptor is their favorite_equipment (e.g. "Barney bought hiking boots!")

    • there’s no such thing as too much shopping so Adventurers can shop as much as they want!

  • rest()

    • should print an appropriate message saying the Adventurer is going to rest for the night

    • this method should decrease the amount they’ve eaten by 1 (to a minimum of 0) and should decrease the number of times they’ve quested recently by 1 (to a minimum of 0).

    • print out a status message such as "<name> is resting." (e.g. "Barney is resting.")

  • status()

    • this should take no parameters (other than self), and should return a string with a description of the Adventurer and their current state

    • it should start with the Adventurer’s name and then a descriptor, e.g. "<name> is <descriptor>"

    • the descriptor should be a phrase that captures the Adventurer’s state (how many times they’ve quested recently, how much they’ve eaten, and how many items of equipment they have), e.g. "Barney is well-fed, contented, and could use some hiking boots.", or "Barney is hungry, wants to be chasing dragons, and has some hiking boots."

    • this is the longest method to write so save this one for the end!

    • be creative!! you can have put any text you want here as long as it responds using the format above. The description should have multiple interesting phrases for the number of times they’ve quested, the amount of food they’ve eaten, and the amount of equipment they own.

    • don’t worry if your output isn’t always grammatically correct. for example, saying "Barney has eaten 1 pizzas" is fine!

    • You can experiment with using emojis by importing the emoji library and following the linked examples.

Testing

Before going on to the next section, test your class!

At the bottom of your adventurer.py file, you should have code that looks like this:

def main():
   # put your test code here

if __name__ == "__main__":
  # only call main if we run this file directly
  # don't call main when we import this file
  main()

You need to include tests in main to be sure your Adventurer class is working.

In addition, you can try interactively testing your Adventurer class. You still need to put tests in the adventurer.py file, but this will let you test your code one method at a time. See the example interactive tests provided as examples of how you can test your file.

See a demo of interactive testing for your class.

team.py

In this part of the lab, you will need to import your Adventurer class into your team.py program by writing from adventurer import * at the top of your team.py program. As long as adventurer.py is in the same directory, this import statement will be enough for python to find the file and pull in the Adventurer class definition. Note that we import from adventurer, not adventurer.py: Python knows to add the .py automatically when looking for the file.

The program in team.py should implement a menu loop similar to previous labs, with options for taking your Adventurers on a quest. You will store your all of your Adventurers in a list of Adventurer objects, which will initially be empty when the program starts. The menu should allow the user to perform one of several actions on the team of Adventurers.

Main Menu:
1. Report the status of the adventurers
2. Recruit a new adventurer
3. Take an adventurer on a quest
4. Feed an adventurer
5. Shop for an adventurer
6. Rest for the night
0. Quit

As with previous labs, you should handle invalid input so the program doesn’t crash or get stuck; see the Example Output for some examples of what this looks like.

Each of the menu options should let you interact with the list of Adventurers:

  • Report on the status of all of the Adventurers

    • should print the status of all Adventurers: call the status() method for each Adventurer

    • if there aren’t any Adventurers, print an appropriate message

  • Recruit one new Adventurer

    • should prompt the user for information needed to create a new Adventurer, then should construct a new Adventurer object and add it to the list of Adventurers.

  • Quest/Feed/Shop with one Adventurer

    • should prompt the user to select a single Adventurer from the list, and should then call the appropriate method on only that Adventurer

    • be sure to validate input so the program doesn’t crash if the user provides invalid input

  • Rest all Adventurers for the night

    • should let all Adventurers rest: call the rest() method for each Adventurer

    • should not prompt the user asking which Adventurer should rest, since it this menu option should always call rest on all Adventurers.

  • Quit

    • print a goodbye message and end the program

Example Output

Here are some examples of running the program:

Answer the Questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-11.txt file in your cs21/labs/11 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!

Resources

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/11 directory! Files outside that directory will not be graded.

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