I'm currently working on an OOP project in my CSI class in which I have to create various sports team and athlete objects as well as a method addPlayer() for adding the athletes to a roster. This is what I have so far.
class Athlete:
def __init__(self, name, number):
self.name = name
self.number = number
def __str__(self):
return "Athlete(" + self.name + ", " + self.number + ")"
def name(self):
return self.name
def number(self):
return self.number
from Athlete import *
class SportsTeam:
roster = []
def __init__(self, city, name, colors):
self.city = city
self.name = name
self.colors = colors
SportsTeam.roster = roster
def __str__(self):
return "SportsTeam(" + self.city + ", " + self.name + \
", " + str(self.colors) + ", " + ")"
def getcity(self):
return self.city
def getname(self):
return self.name
def getcolors(self):
return self.colors
def getRoster(self):
return SportsTeam.roster
def printRoster(self):
for player in roster:
print("Current Team Roster: " + str(SportsTeam.roster))
def addPlayer(self, player):
SportsTeam.roster.append(player)
return SportsTeam.roster
The thing is when I try to use the addPlayer() method I created, I get an error message telling me that list has no attribute. Not sure what needs to be added to fix this.
P.S I have only been programming for a couple of months, so I apologize if the solution is obvious
When you are dealing with classes, you have your instance variables (like self.city = city) and your class variables (like roster = []).
Instance variables are tied to an instance of the class. So if you create 2 SportsTeam objects, they each have their own city.
Class variables are a little different. They are not tied to an instance of the class; meaning, no matter how many SportsTeam objects you create, there will only be one roster variable.
To me, roster being a class variable seems a bit odd because each SportsTeam should have its own roster. However, if you are required to use class variables for you CSI class, maybe you could keep a list of all_teams and/or all_players.
Taking this into consideration:
class SportsTeam:
all_teams = []
all_players = []
def __init__(self, city, name, colors):
self.city = city
self.name = name
self.colors = colors
self.roster = []
SportsTeam.all_teams.append(self)
def __str__(self):
return "SportsTeam(" + self.city + ", " + self.name + ", " + str(self.colors) + ")"
def getCity(self):
return self.city
def getName(self):
return self.name
def getColors(self):
return self.colors
def getRoster(self):
return self.roster
def printRoster(self):
# the for loop was unnecessary
print("Current Team Roster:", str(self.roster))
def addPlayer(self, player):
SportsTeam.all_players.append(player)
self.roster.append(player)
return self.roster
If you would like to keep roster as a class variable, leave a comment and I can help you adjust the code to accommodate for this.
Related
If I call a list from a class, the output is not the content of the list.
I would like to call self.pets from the class Owner, but the output is not the content of the list, but that:
David Friend's pets are: [<__main__.Pet object at 0x7f547c620128>, <__main__.Pet object at 0x7f547c620198>]
Audrey Hepburn's pets are: [<__main__.Pet object at 0x7f547c620208>]
I expected my code to print this:
David Friend's pets are: Boggle Joyner, Artemis Joyner
Audrey Hepburn's pets are: Pippin Hepburn
Here is the code:
class Name:
def __init__(self, first, last):
self.first = first
self.last = last
class Pet:
def __init__(self, name, owner):
self.name = name
self.owner = owner
class Owner:
def __init__(self, name):
self.name = name
self.pets = []
def get_pets_string(an_owner):
return str(an_owner.name.first) + " " + str(an_owner.name.last) + "'s pets are: " + str(an_owner.pets)
owner_1 = Owner(Name("David", "Friend"))
owner_2 = Owner(Name("Audrey", "Hepburn"))
pet_1 = Pet(Name("Boggle", "Joyner"), owner_1)
pet_2 = Pet(Name("Artemis", "Joyner"), owner_1)
pet_3 = Pet(Name("Pippin", "Hepburn"), owner_2)
owner_1.pets.append(pet_1)
owner_1.pets.append(pet_2)
owner_2.pets.append(pet_3)
print(owner_2.name.first)
print(get_pets_string(owner_1))
print(get_pets_string(owner_2))
This is because you are storing the pet objects in a list so it is printing out the object. You should overwrite the string function to fix this issue like so:
class Pet:
def __init__(self, name, owner):
self.name = name
self.owner = owner
def __str__(self):
return self.name
The name class should be like so:
class Name:
def __init__(self, first, last):
self.first = first
self.last = last
def __str__(self):
return self.first + " " + self.last
And the get pets function should be like so:
def get_pets_string(an_owner):
res = str(an_owner.name.first) + " " + str(an_owner.name.last) + "'s pets are: "
for pet in an_owner.pets:
res += str(pet) + ", "
return res
This is if you would like to keep it like you have created it, however there are much easier ways of writing this code such as:
class Owner:
def __init__(self, name: str):
self.name = name
self.pets = []
def add_pet(self, pet: str):
self.pets.append(pet)
def get_pets(self):
res = self.name + "'s pets are: "
for pet in self.pets:
res += pet + ", "
return res
o = Owner("David Friend")
o.add_pet("Boggle Joyner")
o.add_pet("Artemis Joyner")
print(o.get_pets())
class Employee:
num_of_emps = 0
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = first + last + '#gmail.com'
Employee.num_of_emps += 1
def fullname(self):
return f'I am {self.first} {self.last}'
def apply_raise(self):
self.pay = int(self.pay * Employee.raise_amount)
#classmethod
def set_raise_amt(cls, amount):
cls.raise_amount = amount
#classmethod
def from_string(cls, emp_str):
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
#staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6:
return False
return True
class Developer(Employee):
raise_amount = 1.50
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
self.prog_lang = prog_lang
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self,emp):
if emp not in self.employees:
self.employees.append(emp)
def remove_emp(self,emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('--->', emp.full_name())
dev_1 = Developer('John','Doe',30000, 'Python')
dev_2 = Developer('Emily','Smith',23000, 'Java')
# print(help(Developer))
print(dev_1.email)
print(dev_2.email)
print(dev_1.pay)
dev_1.apply_raise()
print(dev_1.pay)
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
print(type(mgr_1.employees))
print(mgr_1.employees)
print(type(dev_1))
print(type([dev_1]))
print([dev_1])
mgr_1.print_emps()
I recently studied this code on youtube. So basically this code started with a class named 'Employee' at the beginning, and then a subclass called 'Developer' was created. I still able to catch up with the logic behind the code at the moment, but after another subclass called 'Manager' was created, I lost.
I don't know why the parameter,'employees' in the class 'Manager' would suddenly become a list in the end
And I also don't know why the for loop could be able to run
Please help, thank you so much
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
first='Sarah', last='Smith', pay=34000, employees=[dev_1]
Your parameter is an list
I am working on a personal project and I am having trouble implementing this following part.
Implementing a Menu Class.
This class will make use of MenuItem objects.
This class represents the restaurant menu which contains 4 different categories of menu item diners can order from.
This class will have a single class(or static) variable:
Menu_Item_types: a list containing 4 strings representing the 4 possible types of menu items.: Drink, appetizer, entree, dessert.
This class will use the following instance attribute:
List item
self.menuItemDrinkList: list of all drink list
self.menuItemAppetizerList: list of all appetizer list
self.menuItemEntreeList: a list of all entree list
self.menuItemDessertList: a list of all the dessert list
Below is the menuItem object
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self.name = name
self.types = types
self.price = price
self.description = description
def setName(self, name):
self.name = name
def getName(self):
return self.name
def setTypes(self, types):
self.types = types
def getTypes(self):
return self.types
def setPrice(self, price):
self.price = price
def getPrice(self):
return self.price
def setDescription(self, description):
self.description = description
def getDescription(self):
return self.description
def __str__(self):
return "{} ({}): ${}, {}".format(self.name, self.types, self.price, self.description)
If I understand you correctly you are looking for setters and getters properties. Here is the way how you do it in Python.
You can learn more about properties here:
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self._name = name
self._types = types
self._price = price
self._description = description
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
#property
def types(self):
return self._types
#types.setter
def types(self, types):
self._types = types
#property
def price(self):
return self._price
#price.setter
def price(self, price):
self._price = price
#property
def description(self):
return self._description
#description.setter
def description(self, description):
self._description = description
def __str__(self):
return "{} ({}): ${}, {}".format(
self._name, self._types, self._price, self._description
)
menu_item = MenuItem("pizza", "entry", 10)
print(menu_item)
menu_item.price = 20
menu_item.description = "Delicious"
print(menu_item)
output:
pizza (entry): $10, None
pizza (entry): $20, Delicious
Please notice:
In python you don't call properties with getXxx or setXxx, you just use regular names and decoreate methods with #property and #xxx.setter
You should have #property before #setter.
Setter must start with the property name
In order to escape recursion, name your internal
attributes with _ (_name). If you will not do it you will have a
"RecursionError: maximum recursion depth exceeded in comparison"
because setter will call itself in the loop.
I'm writing a text adventure game in Python and I'm curious on how I can go about listing all the items inside of the Room class
I'm very new to Python and have very limited practice.
# Declaring items and assigning them rooms
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.items = []
self.items_in_room = ''
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.items.append(item)
def list_items_in_room(self):
for item in self.items:
self.items_in_room += item
', '.split(self.items)
return self.items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __str__(self):
return f'{self.name} - {self.description}' + '\n' + "-" * 40
I'm expecting Room.list_items_in_room to list all the items in the room in a comma separated string.
I have re-arranged your code and also changed the function list_items_in_room. Also, have changed the __str__ function to __repr__ and removed the '-' * 40 (I couldn't understand why that's there).
class Room:
def __init__(self, title, description):
self.title = title
self.description = description
self.__items = []
# __ so that it's not modifiable without getter and setter functions
def __repr__(self):
print(f"-" * 40)
return (f"You are at the {self.title}.")
def add_item(self, item):
return self.__items.append(item)
def list_items_in_room(self):
return self.__items
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
def __repr__(self):
return f'{self.name} - {self.description}'
# Declare all the rooms
room = {
'garden': Room("Garden",
"""The flowers are blooming wonderfully. To the south lies a dark path.""")
}
dingus = Item("Dingus", "This really dings.")
room["garden"].add_item(dingus)
flippers = Item("Flippers", "Webbed in nature.")
room["garden"].add_item(flippers)
print(room['garden'].list_items_in_room())
Output:
[Dingus - This really dings., Flippers - Webbed in nature.]
I need to pass the class instantiation to a function.
This is what i wrote so far:
def func(dog):
print(dog.get_name)
def main():
new_dog = dog(name, age, weight)
func(new_dog)
but when i try to execute it i get the following error message:
<bound method animal.get_name of <classes.dog object at 0x7f9611002b70>
Basically i have a class file with the following classes:
animal - Mother class(it include the name getter)
dog - Child class of animal
cat - Child class of animal
What i'm doing wrong?
--EDIT--
Structure of the classes:
class animal:
# public vars
name = ""
age = 0
weight = 0.00
animal_type = ""
# public constructor
def __chars(self):
print("His name is: " + self.name)
print("He is: " + str(self.age) + " y.o.")
print("His weight: " + str(self.weight) + " Kg")
def __init__(self, name, age, weight, animal_type):
self.name = name
self.age = age
self.weight = weight
self.animal_type = animal_type
print("A new animal has been created!")
self.__chars()
# public methods
def eat(self):
print("The animal eat!")
def drink(self):
print("The animal drink!")
def play(self):
print("The animal plays!")
def get_name(self):
return self.name
# public destructor
def __del__(self):
print('\n' + self.name + "has died :(")
# Child classes
class dog(animal):
__dlevel = None # dangerous level, it can be 0, 1 or more, it's private
# private methods
def set_dlevel(self, dlevel):
self.__dlevel = dlevel
print("Dangerous level set!")
def get_dlevel(self):
# CHeck if the level is define
if not self.__dlevel:
print("Dog dangerous level not found")
sys.exit(1)
# if is equal or more than 1 is dangerous
if int(self.__dlevel) >= 1:
print("The dog is dangerous, be careful while playing with him!")
# otherwise it's a quiet dog
elif int(self.__dlevel) <= 0:
print("The dog isn't dangerous")
I figured out the real problem: i was printing the function, not calling it.
So instead i've used
def func(animal):
print(animal.get_name())
def main():
new_dog = dog("max", 14, 11, "dog")
func(new_dog)