My error is:
NameError: name 'breed' is not defined
but I thought it was defined in the __init__ function? Any suggestions? This is code from a study guide for an exam, and I'm trying to input it into python 2.7 myself to see the output.
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)
You should have had #property for breed as well:
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#property
def breed(self):
return self.breed
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)
Related
i have a list of until 3 items each item have a list of until 5 items. i need to replace 2 items from another lists.
i get only the strings to change.
without return anything
for example:
i have a class School that have a list of Class [size<=3]. and each class have a list of Student [size<=5]
i get two "name"s of Students, i need to search them in School by running on all Classes and all Students and swap them.
The Student class have a "name" field.
especially if their are not in same ClassRoom
class Student:
def __init__(self, id, name):
self.name = name
self.id = id
class ClassRoom:
def __init__(self):
self.Students[]
class School:
def __init__(self):
self.classes = []
def swap(self, name1, name2):
#???
scl.classes = [c1,c3]
s2 = Student(2,"John")
s6 = Student(6, "Ben")
c1.students = [s1,s2,s3]
c3.students = [s1,s4,s6]
scl.search_replace("John", "Ben")
thanks
You need three classes - School, Class and Student. A School has multiple classes. A Class has multiple students.
In order to be able to easily see what's going on it's a good idea to implement __str__ for each class.
Something like this:
class School:
def __init__(self, name):
self._name = name # name of the school
self._classes = [] # list of classes in the school
#property
def classes(self):
return self._classes
#property
def name(self):
return self._name
def add(self, clazz):
assert isinstance(clazz, Class)
self.classes.append(clazz)
def search(self, name):
for c, clazz in enumerate(self.classes):
if name in clazz.students:
return c, clazz.students.index(name)
return -1, -1
def replace(self, st1, st2):
c1, s1 = self.search(st1)
c2, s2 = self.search(st2)
if s1 >= 0 and s2 >= 0:
self.classes[c1].students[s1], self.classes[c2].students[s2] = self.classes[c2].students[s2], self.classes[c1].students[s1]
def __str__(self):
return f'{self.name}:\n' + '\n'.join(map(str, self.classes))
class Class:
def __init__(self, name):
self._name = name # name of the class
self._students = [] # list of students in the class
#property
def students(self):
return self._students
#property
def name(self):
return self._name
def add(self, student):
assert isinstance(student, Student)
self.students.append(student)
def __str__(self):
return f'{self.name}: ' + ', '.join(map(str, self.students))
class Student:
def __init__(self, name, ident):
self._name = name # student's name
self._ident = ident # student ID
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
#property
def ident(self):
return self._ident
def __str__(self):
return f'{self.name} ({self.ident})'
def __eq__(self, other):
if isinstance(other, str):
return other == self.name
if isinstance(other, Student):
return other.name == self.name
return False
school = School('Tel Aviv High School')
clazz = Class('Psychology')
school.add(clazz) # add the Psychology class to the school
student1 = Student('John', 1)
student2 = Student('Ben', 2)
clazz.add(student1) # add student to the class
clazz.add(student2)
clazz = Class('Chemistry') # add Chemistry class to the school
school.add(clazz)
clazz.add(Student('Haim', 3)) # add student to the class
print(school) # print the school, all of it classes and students within those classes
school.replace('Haim', 'John')
print(school) # print the school again and note that Haim and John have changed places
Output:
Tel Aviv High School:
Psychology: John (1), Ben (2)
Chemistry: Haim (3)
Tel Aviv High School:
Psychology: Haim (3), Ben (2)
Chemistry: John (1)
I'm trying to solve a problem in my class, and I'm not sure what I'm doing wrong.
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
self.name = name
if name == None:
name = "Generic"
super().__init__(name)
def __str__(self, name=None):
self.name = name
return "Company name:{}".format(name)
def __repr__(self):
return "Travel('{self.name}')"
def set_name(self, new_name):
self.new_name = new_name
return new_name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)
I want it to return
Company name: bever
Company name: beverly hills
but it just returns
Company name: None
Company name: None
any help is appreciated
You need to change a few things:
Check if name is None before you assign it to self.name
f"Travel('{self.name}')", you forgot to add an f while returning the string in __repr__
Assign new_name to self.name when you use .set_name()
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
if name == None:
name = "Generic"
self.name = name
super().__init__(name)
def __str__(self, name=None):
#self.name = name
return "Company name:{}".format(self.name)
def __repr__(self):
return f"Travel('{self.name}')"
def set_name(self, new_name):
self.name = new_name
return self.name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)
This should do the trick
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
if name == None:
name = "Generic" # First set the local parameter
self.name = name # Then the attribute
super().__init__(name)
def __str__(self): # str() does not expect parameters
return f"Company name:{self.name}" # use the instance's attribute instead
def __repr__(self):
return f"Travel('{self.name}')"
def set_name(self, new_name):
self.name = new_name # Update the instance's attribute
return new_name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)
I have 2 classes
class Robot1:
def __init__(self, name):
self.name = name
def sayHi(self):
return "Hi, I am " + self.name
class Robot2:
def __init__(self, name):
self.name = name
def sayHello(self):
return "Hello, I am " + self.name
robot_directory = {1: Robot1(), 2: Robot2()}
def object_creator(robo_id, name):
robot_object = robot_directory[robo_id]
return robot_object
But I don't know how to pass the variable name while instantiating the class on the line robot_object = robot_directory[robo_id]. How can I pass the variable?
You are storing already-created instances in the dictionary. Store the class itself instead:
# ...
robot_directory = {1: Robot1, 2: Robot2}
def object_creator(robo_id, name):
robot_class = robot_directory[robo_id]
# Here, the object is created using the class
return robot_class(name)
Obviously, this requires that all your robot classes have the same __init__ parameters.
Going further, you might want to look into inheritance and use a common base class for your robots.
maybe you can try
class Robot1:
def __init__(self):
pass
def set_name(self, name):
return "Hi, I am " + name
class Robot2:
def __init__(self):
pass
def set_name(self, name):
return "Hello, I am " + name
robot_directory = {1: Robot1(), 2: Robot2()}
def object_creator(robo_id, name):
robot_object = robot_directory[robo_id]
return robot_object.set_name(name)
I have a list of instances of my Business class. I'm used to defining the variables for a class at the top of the class. On of the variables in the Business class is a list of tags. When I loop through the list of businesses some have tags, some don't. Out of the 20 businesses the 4th element in the list has 4 tags. After these tags are added to this business all following instances of Business also share these tags. Here is my Business class-
from tag import *
class Business:
name = ""
website = ""
phone = ""
address = ""
city = ""
state = ""
postalCode = ""
tags = []
data = {}
def __init__(self, name):
self.setName(name)
# Modifiers
def setName(self, name):
self.name = name
def setWebsite(self, website):
self.website = website
def setPhone(self, phone):
self.phone = phone
def addTag(self, Tag):
self.tags.append(Tag)
def setAddress(self, address):
self.address = address
def setCity(self, city):
self.city = city
def setState(self, state):
self.state = state
def setPostalCode(self, postalCode):
self.postalCode = postalCode
def set(self, key, value):
self.data[key] = value
def unset(self, key):
del self.data[key]
# Accessors
def getWebsite(self):
return self.website
def getName(self):
return self.name
def getPhone(self):
return self.phone
def getTags(self):
return self.tags
def getAddress(self):
return self.address
def getCity(self):
return self.city
def getState(self):
return self.state
def getPostalCode(self):
return self.postalCode
def get(self, key):
return self.data[key]
def getKeys(self):
return self.data.keys()
# Helpers
And a tag is added to a business like this-
if len(categories) > 1:
for cat in categories:
B.addTag(Tag(cat))
Are the variables defined at the top of my business class global to all instances of Business? How do I fix this problem?
Yes, mutables assigned that way are "global" to the class. To make them "local," define them as instance variables. To do this for tags, for example, remove the global definition that you have and add instead a line to __init__ like:
def __init__(self, name):
self.setName(name)
self.tags = []
This assigns that value of tags to self rather than to the class generally.
You should be doing it this way instead:
from tag import *
class Business:
def __init__(self, name, website='', phone='', address='', city='', state='', postal_code='', tags=None, data=None):
self.name = name
self.website = website
self.phone = phone
self.address = address
self.city = city
self.state = state
self.postal_code = postal_code
self.tags = []
if tags is not None:
for tag in tags:
self.add_tag(tag)
self.data = {} if data is None else data
def add_tag(self, tag):
if not isinstance(tag, Tag):
tag = Tag(tag)
self.tags.append(tag)
def add_data(self, key, value):
self.data[key] = value
def remove_data(self, key):
del self.data[key]
def get_data(self, key):
return self.data[key]
def get_data_keys(self):
return self.data.keys()
Python generally avoids getters and setters unless some extra processing or error-checking is required
Why does user.params() not return all the params up the inheritance
chain? -- It's not including the params defined in Person() -- notice
Vertex() does not have a params() method.
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
self.s = super(Person,self)
self.s.__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(self.s.params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
self.s = super(User,self)
self.s.__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print self.s.params()
params.update(self.s.params())
return params
In User you do:
self.s = super(User,self)
self.s.__init__(name,uri,email)
so self.s is what? As you do the same in Person, self.s is super(Person) and that anywhere, in Person and User as you reassign self.s, so the self.s.params that gets picked is the one of Element.
edit : also the following code works, Sebastians has the correct interpretation: self.s is reassigned each time in the __init__ of the classes. So self.s is reassigned as super(Person,self).
import uuid
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
print 'here Element'
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
super(Person,self).__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
print 'here Person'
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(super(Person,self).params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
super(User,self).__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print 'here User'
params.update(super(User, self).params())
return params
if __name__ == '__main__':
u = User()
print '\n'.join(sorted(u.params().keys()))