The Critter Zoo Program
This program extends the previous critter caretaker program to allow us to manage lots of critters, we create a critter zoo!
We can then feed or play with our critters to improve their hunger and boredom to improve their mood.
Our new CritterZoo
class has an attribute called critters
which is a dictionary that stores each of the Critter
instances.
We can then interact with individual Critter
instances through this dictionary.
In the next unit, we will see a different way of doing this by extending Python's built-in dictionary type dict
.
Create a file called critter.py and copy in the following:
# critter.py
# A virtual pet to care for
class Critter:
"""A virtual pet"""
total = 0
def __init__(self, name, hunger=0, boredom=0):
self.name = name
self.hunger = hunger
self.boredom = boredom
Critter.total += 1
def __str__(self):
desc = ""
desc += f"Name: {self.name}\n"
desc += f"Hunger: {self.hunger}\n"
desc += f"Boredom: {self.boredom}\n"
return desc
def pass_time(self):
self.hunger += 1
self.boredom += 1
if self.hunger > 16:
self.hunger = 16
if self.boredom > 16:
self.boredom = 16
# indicate that the method is internal (non-public)
def _mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m
def talk(self):
print(f"I'm {self.name} and I feel {self._mood()} now.\n")
def eat(self, food=5):
print("Brruppp. Thank you.")
self.hunger -= food
if self.hunger < 0:
self.hunger = 0
def play(self, fun=5):
print("Wheee!")
self.boredom -= fun
if self.boredom < 0:
self.boredom = 0
class CritterZoo:
""" A critter zoo"""
def __init__(self, no_critters):
self.critters = {}
for i in range(no_critters):
crit = Critter(f"Critter {i+1}")
self.critters[f"Critter {i+1}"] = crit
def __str__(self):
returnstring = ""
for critter in self.critters.values():
returnstring += critter.__str__()
return returnstring
def feed_critter(self, name):
self.critters[name].eat()
self._pass_time()
def play_with_critter(self, name):
self.critters[name].play()
self._pass_time()
def list_critter_names(self):
for name in self.critters.keys():
print(name)
def list_critter_moods(self):
for critter in self.critters.values():
critter.talk()
self._pass_time()
# indicate that the method is internal (non-public)
def _pass_time(self):
for critter in self.critters.values():
critter.pass_time()
Take some time to look at the CritterZoo
class and some of the amendments made to the Critter
class. For, example pass_time()
is now public and is called from within the CritterZoo
class so that we can pass the time for all of the critters in one go.
Our main.py file contains the following:
# main.py
# Critter Zoo
from critter import CritterZoo
def main():
no_critters = input("How many critters would you like?: ")
zoo = CritterZoo(int(no_critters))
choice = None
while choice != "0":
print \
("""
Critter Caretaker
0 - Quit
1 - Listen to your critters
2 - Feed a critter
3 - Play with a critter
4 - List critters (does not pass time)
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
# listen to your critter
elif choice == "1":
zoo.list_critter_moods()
# feed your critter
elif choice == "2":
print("Which critter do you want to feed?")
zoo.list_critter_names()
crit_num = input("Please enter the number you wish to feed.\n")
zoo.feed_critter(f"Critter {crit_num}")
# play with your critter
elif choice == "3":
print("Which critter do you want to play with?")
zoo.list_critter_names()
crit_num = input("Please enter the number you wish to play with.\n")
zoo.play_with_critter(f"Critter {crit_num}")
# list critters
elif choice == "4":
print(zoo)
else:
print(f"\nSorry, but {choice} isn't a valid choice.")
if __name__ == "__main__":
main()