I am writing my own class and methods and I have it all complete except the part of using localtime() to determine a user's age. I have never used localtime(). so I don't know how to implement it in the code. Currently, in the manner it's written, it returns a bound error.
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 15 22:10:07 2015
#author: Daddy
"""
class Person ():
def __init__(self, name, birthyear):
self.name = name
self.birthyear = birthyear
def age(self, birthyear):
age = 2015 - self.birthyear
return age
def name(self):
return self.name
class Instructor(Person):
def __init__(self, name, birthyear, degree):
self.name = name
self.birthyear = birthyear
self.degree = degree
def degree(self, degree):
return (self.degree)
class Student(Person):
def __init__(self, name, birthyear, major):
self.name = name
self.birthyear = birthyear
self.major = major
def major(self, major):
return (self.major)
import datetime
def age(self):
return datetime.datetime.now().year - self.birthyear
Note you don't need to pass birthyear because it's in self, and return is the value of the called function.
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)
This question already has answers here:
How does the #property decorator work in Python?
(15 answers)
Closed 2 years ago.
I tried adding property decorators to my class but something went wrong.
I got 6 errors!!!
my code:
class person:
def __init__ (self, name, age):
self.name = name
self.age = age
#property
def age(self):
return self.age
#age.setter
def age(self, new_age):
if isinstance(new_age, int):
self.age = new_age
def __str__ (self):
return f"{self.name} is {self.age}"
p1 = person('moe',34)
print(person)
You are using same names and the property then shadows the member. This makes these recursion issue as self.age calls itself again and again in setter.
You need to use different attribute name, like this:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
#property
def age(self):
return self._age
#age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
return f"{self.name} is {self.age}"
p1 = person('moe',34)
print(p1)
You defined age both as a class method and a class variable. When you refer to self.age, the interpreter has no way of knowing what you meant.
Change the code to this to fix it:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
#property
def age(self):
return self._age
#age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
# Here you can either use the property or the real variable
return f"{self.name} is {self.age}"
p1 = person('moe',34)
print(person)
There may be two mistakes in your code.
First, methods and attributes shouldn't have the same name age.
You should print the instance p1, if I understand your intention correctly.
Something like this:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
#property
def age(self):
return self._age
#age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
return f"{self.name} is {self._age}"
p1 = person('moe',34)
print(p1)
You get:
moe is 34
I want to call a method when an attribute of an object is written. For example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def isAdult(self):
print(True if self.age>=21 else False)
If i want to call .isAdult() when an object's age is written a value, how can I achieve this?
I heard of people suggesting to use decorators, but they didn't give more details.
What you want to have is called a setter. You must use new-style classes and extend object to use them:
class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age
def isAdult(self):
print(self.age >= 21)
#property
def age(self):
return self._age
#age.setter
def age(self, value):
self._age = value
self.isAdult()
Then, for example:
p = Person("John Doe", 12)
p.age = 16
p.age = 25
will print
False
True
you can use decorator in class like below.
In below code, isAdultDeco will be call when you create Person object.
class Person:
def isAdultDeco(func):
def foo(self, name, age):
func(self, name, age)
print(True if self.age>=21 else False)
return foo
#isAdultDeco
def __init__(self, name, age):
self.name = name
self.age = age
Person('a',22) # True
Person('a',20) # False
I have the following code:
class Person:
def __init__(self,name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = vale
def setName(self, name):
self.name = name
class Main:
def __init__(self):
self.people = []
def addPerson(self,name):
self.people.append(Person(name))
def updateBalance(self,balance,index):
self.people[index].setBalance(50)
print self.people[0]
main = Main()
main.addPerson("Jack")
main.updateBalance(30,0)
I made the following code just to see how objects works with array. But, when I try to run it I get NameError: name 'self' is not defined. I'm not sure what I'm doing wrong ?
If something is not clear or needs editing then please let me know in the comments before down voting.
Many thanks
There a several issues with your code:
Class methods, need to refer to the class def ...(self, ...)
print(...) is a function in Python3 and has to be called from within a method.
The following adjustments make your code work:
class Person:
def __init__(self, name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = value
def setName(self, name):
self.name = name
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance, index):
self.people[index].setBalance(50)
print("Updating people at index %d" % index)
main = Main()
main.addPerson("Jack")
main.updateBalance(30, 0)
print (main.people[0])
Prints:
Updating people at index 0
<__main__.Person instance at 0x100d065f0>
You should pass self as a parameter as well:
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance,index):
self.people[index].setBalance(50)
print people[0] #no need for self if you are calling local variable of class but this will print an empty array
Also you have type error
class Person:
def __init__(self,name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = vale --> not vale but value
def setName(self, name):
self.name = name
Whereas languages like Java or C++ make the "self"/"this" argument implicit in their method definitions, Python makes it explicit. So, the method definitions in your Main class should look like this:
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance, index):
self.people[index].setBalance(50)
In effect, what you had before was an addPerson() method that accepted zero arguments from the caller... and it had renamed self to name, quite unintuitively. Calling the first parameter to a method "self" in Python is only by convention... you could just as easily define addPerson() like this:
class Main:
def addPerson(something_other_t_self, name):
something_other_than_self.people.append(Person(name))
...and it would work exactly the same.