Given that I need to operate a machine, I need a
VendingMachine class:
Property is a stock(list) that stores Food items.
Methods:
Constructor takes in no arguments.
get_stock_names(): returns a list of strings that represents the names of
all food items in the stock.
load(food): adds the Food object to stock
and others,
#predefined
class Food(object):
def __init__(self, name, nutrition, good_until):
self.name = name
self.nutrition = nutrition
self.good_until = good_until
self.age = 0
def get_name(self):
return str(self.name)
def get_age(self):
return self.age
def get_nutrition(self):
if self.age <= self.good_until:
return self.nutrition
else:
return 0
def ripen(self, days):
self.age = self.age + days
return self.age
def is_spoiled(self):
return self.good_until < self.age
#my code below
class VendingMachine:
def __init__(self):
Property = Food.get_name #no clue how to make a Property
self.load = Food.load #same here
def get_stock_names(self, Property):
lst = []
for i in Food:
i = str(i)
lst.append(i)
return lst
def has_stock(self, name):
return name in Property
def load(self, food):
Property.append(food)
return Property
def sell(self, name):
if name in Property:
Property.remove(name)
return name
else:
return None
What I get is
AttributeError: 'VendingMachine' object has no attribute 'load' (a variable)
I'm pretty sure you've misunderstood the line of your instructions telling you about the stock property. I suspect it is just telling you to make an instance variable named self.stock which holds a list of Food instances. Since the constructor takes no arguments, it presumably starts empty. Using the term "property" seems like a red herring, since property has a specific meaning in Python (a wrapper around a method to make it look like an attribute), which doesn't make much sense in this situation.
Anyway, here's what I think you want your constructor to look like:
def VendingMachine(object):
def __init__(self):
self.stock = [] # initially empty
Your later methods can inspect or manipulate self.stock as necessary.
Related
This is for an assignment.
So there are two classes. The first is Student, which creates Students with a Name, an Username and the semester theyre in. I got the first class to work pretty effortlessly, but the second one calles UniClass is hard to do. It creates a University class and gives it a name.
Then it can enroll Students into the class. It is supposed to put them into a set. If it is empty the method "str" shall return "set()" and if not then it shall return the set.
class Student:
def __init__(self,name,imt_name,semester):
"""
Constructor
"""
self.name=name
self.imt_name=imt_name
self.semester=semester
def __str__(self):
"""
"""
return ("{} [{}] in Semester {}".
format(self.name,
self.imt_name,
self.semester))
class UniClass:
def __init__(self,name):
"""
Constructor
"""
self.name=name
def enroll_student(self,students):
self.students=Student.str()
global x
x=True
def __str__(self):
if x==True:
return (students)
else:
return("set()")
I messed up at the second class.
I presume UniClass maintains a set of Student objects, which means it's the responsibility of whoever calls UniClass.enroll_student to provide an instance of Student, rather than enroll_student needing to create a new student. Something like
class UniClass:
def __init__(self, name):
self.name = name
self.students = set()
def enroll_student(self, student):
self.students.add(student)
def __str__(self):
return ",".join(str(s) for s in self.students)
c = UniClass("math")
c.enroll_student(Student("john", "doe", "fall"))
c.enroll_student(Student("alice", "smith", "fall"))
I have a list of objects of the Person class. This list includes myself, so I need to remove "myself" from the list.
It means I need to remove the object from the list that calls this method.
class Population:
def __init__(self):
self.people = list()
class Person:
def __init__(self):
self.friends_list = list()
def make_friends(self, population, n):
temp_list = population.copy()
temp_list.remove(self)
self.friends_list.extend(random.sample(temp_list,n))
my test:
per = Person()
per2 = Person()
per3 = Person()
per4 = Person()
per5 = Person()
pop = [per,per2,per3,per4,per5]
for per in pop:
per.make_friends(pop, 2)
print('ME: ',per)
print(per.friends_list)
My tests run well, but there are general tests that check the code and they generate an error on this line:
try:
stud_res = person.make_friends(population, count)
except Exception:
print("\tPerson.make_friends() generated error")
return
Can I use self in this way, and if not, how can I better remove "myself" from the list?
It is a perfectly fine use case. By the way, note that you're overriding the builtin list.
To use self, you have to share a list collection between instances of a Person-class. In that case this collection should be declared as a class attribute or global list variable (not an instance attribute).
These samples of code are working:
with global list variable:
class Person:
def __init__(self, name):
self.name = name
def make_friends(self, list):
list.remove(self)
def __repr__(self):
return self.name
p1 = Person("Joe")
p2 = Person("Barack")
the_list = []
the_list.append(p1)
the_list.append(p2)
p1.make_friends(the_list)
print(the_list)
With class attribute:
class Person2:
class_list = []
def __init__(self, name):
self.name = name
Person2.class_list.append(self)
def make_friends(self):
Person2.class_list.remove(self)
def __repr__(self):
return self.name
p1 = Person2("Joe")
p2 = Person2("Barack")
print(Person2.class_list)
p1.make_friends()
print(Person2.class_list)
EDIT:
Variable 3 when a list of people is inside another class.
For accessing a list inside another class you could use attribute name or public method to get it if implemented:
class ClassWithList:
def __init__(self):
self.list_collection = []
def get_list(self):
return self.list_collection
class_with_list = ClassWithList()
class Person:
def __init__(self, name):
self.name = name
def make_friends(self, list):
list.remove(self)
def __repr__(self):
return self.name
p1 = Person("Joe")
p2 = Person("Barack")
# using implemented get-method of instance list attribute
class_with_list.get_list().append(p1)
class_with_list.get_list().append(p2)
print(class_with_list.get_list())
p1.make_friends(class_with_list.get_list())
print(class_with_list.get_list())
# instance list attribute of class`ClassWithList
print(class_with_list.list_collection)
p2.make_friends(class_with_list.list_collection)
print(class_with_list.list_collection)
This question already has answers here:
Printing a list of objects of user defined class
(3 answers)
Closed 2 years ago.
i have a class for lists that creates list objects and deals with list actions, and i have another class 'Dog' to create Dog objects. However, i canĀ“t manage to print the atributes of class 'Dog'(name and age)after appending an object of type 'Dog' to a list of type 'Dogslist'. Instead by printing the list it prints the addresses of the objects. How can i print name and age of all the dogs i have in the list?
class Dogslist():
def __init__(self):
self.lista = []
def append(self, object):
self.lista.append(object)
def delete(self):
pass
def showlist(self):
pass
class Dog:
def __init__(self, name, age):
self.__name = name
self.__age = age
def description(self):
return self.__name, self.__age
a=Dog("Geralt", 10)
b=Dog("Vesemir", 13)
doglist = Dogslist()
doglist.append(a)
doglist.append(b)
print(doglist.lista)
The output shows the following wich refers to objects' addresses:
[<__main__.Dog object at 0x7f25ed30c0a0>, <__main__.Dog object
at 0x7f25ed2f18b0>]
Implement __str__ or __repr__ for Dog so Python knows how to represent it.
class Dog:
def __init__(self, name, age):
self.__name = name
self.__age = age
def __repr__(self):
return f"Dog({self.__name}, {self.__age})"
def __str__(self):
return f"Woof! I'm {self.__name}, and I'm {self.__age} years old!"
More information about __str__ and __repr__ can be found here
You should be able to access the objects like below( because those attributes were defined as 'private' and you cant access them directly) .
for item in doglist.lista:
print(item.__dict__['_Dog__name'])
print(item.__dict__['_Dog__age'])
Simpler to just not make those attributes private.Then you would be able to access it like item.name
class Dogslist():
def __init__(self):
self.lista = []
def append(self, objectt):
self.lista.append(objectt)
def delete(self):
pass
def showlist(self):
return(self.lista)
Dogslist.lista technically only exists within the class so you can't call it from outside. You need a function in that class that returns Dogslist.lista
class Dog:
def __init__(self, name, age):
self.__name = name
self.__age = age
def description(self):
return self.__name, self.__age
a=Dog("Geralt", 10)
b=Dog("Vesemir", 13)
doglist = Dogslist()
Same with the dogs.
doglist.append(a.description())
doglist.append(b.description())
print(doglist.showlist())
Result:
[('Geralt', 10), ('Vesemir', 13)]
I wrote a class called person and used setter and getter. At first, the code was working fine when I used one variable.However when I added another variable , it said that 2 required positional arguments were missing:"name" and "age".
class person:
def __init__(self, name, age):
self.name = name
self.age = age
def set_name(self,y):
self.name = y
def get_name(self):
return self.name
def set_age(self,x):
self.age = x
def get_age(self):
return self.age
p1 = person()
p1.set_name("Armeen")
p1.set_age("20")
print(p1.get_age())
print(p1.get_name())
Your __init__ method takes two arguments namely name and age. You aren't providing any argument when creating an instance of Person. So you may want to do the following:
p1 = person('Armeen', 20)
As opposed to
p1 = person()
Or if you want to allow user not to specify name and age at the time of instance creation, you can set those parameter as optional by doing the following change in __init__
def __init__(self, name = None, age = None): ##This would work with your code as well
So I keep getting the
error: " AttributeError: 'Dog' object has no attribute '_Dog__name'"
The thing is print(spot.get_name()) works fine. Also when I tried spot.multiple_sounds() that fails similarly. I think the issue is when I try to call object attributes from the super class in functions in object definition. I can't understand why though. I'm doing all this from a tutorial and the code is identical to his. I think it may be because he's using python2.x and I'm using spyder python3.x but I have no idea. Any help is greatly appreciated.
import random
import os
import sys
class Animal:
__name = ""
__height = 0
__weight = 0
__sound = 0
def __init__(self,name,height,weight,sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound
def set_name(self, name):
self.__name = name
def get_name(self):
return(self.__name)
def set_height(self, height):
self.__height = height
def get_height(self):
return(self.__height)
def set_weight(self, weight):
self.__weight = weight
def get_weight(self):
return(self.__weight)
def set_sound(self, sound):
self.__sound = sound
def get_sound(self):
return(self.__sound)
def get_type(self):
print("animal")
def toString(self):
return("{} is {} cm tall and {} kilograms and says {}".format(self.__name,
self.__height,
self.__weight,
self.__sound))
cat = Animal('Whiskers', 33, 10,'Meow')
print(cat.toString())
class Dog(Animal):
__owner = ""
def __init__(self, name, height, weight, sound, owner):
self.__owner = owner
super().__init__(name, height, weight, sound)
def set_owner(self,owner):
self.__owner = owner
def get_owner(self):
return self.__owner
def get_type(self):
print("Dog")
def toString(self):
return "{} is {} cm tall and {} kilograms says {} and his owner is {}".format(self.__name, self.__height, self.__weight, self.__sound, self.__owner)
def multiple_sounds(self, how_many=None):
if how_many is None:
print(self.getsound())
else:
print(self.getsound()*how_many)
spot = Dog("Spot", 53, 27, "Ruff", "Some Guy")
print(spot.get_name())
print(spot.toString())
In python, __fieldName emulates the private field, means two underscores that in field name. So such fields can not be reached from derived classes, but you still can get them using getter.
Any attribute or method that begins with '__' is only accessible by that name from functions in that same class. Not from other classes, not even from subclasses.
class A:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
class B(A):
def get_name_capitalized(self):
return self.__name.upper()
b = B('Bob')
print(b.get_name()) # prints 'Bob'
print(b.get_name_capitalized()) # fails
In the code above, calling A.get_name() accesses the A instance's __name attribute successfully. But B.get_name_capitalized() fails with the error "AttributeError: 'B' object has no attribute '_B__name'
". "__" names get mangled by the compiler so that they are not accessible as-is. If the code in get_name_capitalized is changed to:
return self._A__name.upper()
then it would work, so these attributes are accessible, but you have to use the mangled name to get at them.
That is how Python has been since 1.x, and is nothing new with Python 3.
Names that begin with double-underscores and end with zero or 1 underscore are python's answer to private variables. Python munges them to be __Class_name to make them private to the class and not its inherited subclasses. The idea is to let you have intra-class names without subclasses messing with them. Obviously this is easily subverted by using the well-known munged name, but then, python is a dynamic language.
See Private Variables