I have been struggling with an example code that I use to practice and learn Python. Understanding the below's code is not hard, however, if I go line by line I am not sure what the following one does.
course_running.add_student(self)
How is it possible that we run add_student method of CourseRunning class to a parameter course_running (Student class, enrol method)?
I would be very grateful if you can provide an explanation how that line of code works?
The full code is provided below.
class Student:
def __init__(self, name, student_number):
self.name = name
self.student_number = student_number
self.classes = []
def enrol(self, course_running):
self.classes.append(course_running)
course_running.add_student(self)
class Department:
def __init__(self, name, department_code):
self.name = name
self.department_code = department_code
self.courses = {}
def add_course(self, description, course_code, credits):
self.courses[course_code] = Course(description, course_code, credits, self)
return self.courses[course_code]
class Course:
def __init__(self, description, course_code, credits, department):
self.description = description
self.course_code = course_code
self.credits = credits
self.department = department
self.department.add_course(self)
self.runnings = []
def add_running(self, year):
self.runnings.append(CourseRunning(self, year))
return self.runnings[-1]
class CourseRunning:
def __init__(self, course, year):
self.course = course
self.year = year
self.students = []
def add_student(self, student):
self.students.append(student)
Thanks in advance!
Igor
A CourseRunning object has its list of attending students, and a Student object has a list of courses the student is currently taking.
Say there are student1 and running_course1. We wish to enroll student1 to running_course1. We than run:
student1.enroll(running_course1)
The enroll method does two things:
self.classes.append(course_running) - which translated to `student1.classes.append(running_course1). So now the course is registered in the student's list.
course_running.add_student(self) - which translates to running_course1.add_student(student1). This invokes running_course1.add_student(self, student1) which adds the student to the course's list.
I believe this is not a full code because no any object is present no method call..
i am providing you a code please run this in your pc.
class Student:
def __init__(self, name, student_number):
self.name = name
self.student_number = student_number
self.classes = []
def enrol(self, course_running):
print "In enroll method"
self.classes.append(course_running)
course_running.add_student(self)
class Department:
def __init__(self, name, department_code):
self.name = name
self.department_code = department_code
self.courses = {}
def add_course(self, description, course_code, credits):
self.courses[course_code] = Course(description, course_code, credits, self)
return self.courses[course_code]
class Course:
def __init__(self, description, course_code, credits, department):
self.description = description
self.course_code = course_code
self.credits = credits
self.department = department
self.department.add_course(self)
self.runnings = []
def add_running(self, year):
self.runnings.append(CourseRunning(self, year))
return self.runnings[-1]
class CourseRunning:
def __init__(self, course, year):
self.course = course
self.year = year
self.students = []
def add_student(self, student):
print "student-->", student
print "In Add Student"
self.students.append(student)
course_running = CourseRunning('b.tech', '2011')
obj = Student('student_xyz', "1234")
obj.enrol(course_running)
what happening here is we are creating an object of "CourseRunning" class.
and when we call "enroll" method of "Student" class we are passing the object of "CourseRunning" class so we are able to access the method of "CourseRunning" class because "course_running" is a object of "CourseRunning" class so it will access all methods of "CourseRunning" class
Related
I have this class and method:
class Person(object):
def __init__(self, name):
self.name = personname
self.surname = personsurname
def changenameorsurname(self, x, y):
self.x = y
return
AdamSmith = Person ("Adam", "Smith")
I want to use method changenameorsurname to change AdamSmith's name or surname, but if I use this code I'm getting a NameError"
AdamSmith.changenameorsurname(personname, Dave)
Result:
NameError: name personname is not defined.
Is there elegant way to reference personname in code like this? Or do I have to make two separate methods like this?
def changename(self, y):
self.name = y
return
AdamSmith.changename(Dave)
There are a couple of problems. Your init method needs to be fixed so you can properly construct a Person object. You can have your changenameorsurname() method take one argument that is a name and a second argument that determines whether that name is the first name or the surname. Here, I have set the default to first name.
class Person:
def __init__(self, first_name, surname):
self.first_name = first_name
self.surname = surname
def changenameorsurname(self, name, first = True):
if first:
self.first_name = name
else:
self.surname = name
def __str__(self):
return f'{self.first_name} {self.surname}'
some_guy = Person ("Adam", "Smith")
print(some_guy) #Adam Smith
some_guy.changenameorsurname("Michael")
print(some_guy) #Michael Smith
some_guy.changenameorsurname("Jones", first=False)
print(some_guy) #Michael Jones
def greeting_decorator(original_function):
def return_function(*args):
name = 'John'
return f'Hi, I\'m {name}, fullname: {original_function(*args)}'
return return_function
#greeting_decorator
def greeting(name, surname):
return f'{name} {surname}'
print(greeting('John', 'Doe'))
Above, I have a simple decorator function that works as intended.
I'd like to do something similar, but with an inherited class.
How might I go about inheriting a decorator function like this:
class Guy:
def __init__(self, name):
self.name = 'John'
def greeting_decorator(self, original_function):
def return_function(*args):
return f'Hi, I\'m {self.name}, fullname: {original_function(*args)}'
return return_function
class GuyWithSurname(Guy):
def __init__(self, name, surname):
super().__init__(name)
self.surname = surname
#greeting_decorator # <----- here
def __str__(self):
return f'{self.name} {self.surname}'
JohnDoe = GuyWithSurname('John', 'Doe')
print(JohnDoe)
If you are certain that the parent class will always be Guy, you can simply annotate via #Guy.greeting_decorator:
class Guy:
def __init__(self, name):
self.name = 'John'
def greeting_decorator(original_function):
def return_function(self, *args):
return f'Hi, I\'m {self.name}, fullname: {original_function(self, *args)}'
return return_function
class GuyWithSurname(Guy):
def __init__(self, name, surname):
super().__init__(name)
self.surname = surname
#Guy.greeting_decorator # <----- here
def __str__(self):
return f'{self.name} {self.surname}'
JohnDoe = GuyWithSurname('John', 'Doe')
That way, when you call print(JohnDoe) it will output Hi, I'm John, fullname: John Doe.
Note that I had to change the greeting_decorator and the return_function parameters to properly handle self.
I have defined a simple class.
class Person:
age = 0
name = ''
def __init__(self,personAge,personName):
self.age = personAge
self.name= personName
def __str__(self):
return self.name
d = Person(24,'ram')
print(d)
so o/p is coming like this <__main__.Person object at 0x0000020256652CF8> .But i want o/p like this ram. How can i get this?
please be correcting me.Thnaks in adavance
your indentation is wrong. Your overrided str inside init (constructor). Also you don't have to specify class variables if you are getting/initialising the variables through constrcutor.
try below,
`
class Person:
def __init__(self,personAge,personName):
self.age = personAge
self.name= personName
def __str__(self):
return self.name
d = Person(24,'ram')
print(d)
`
You are printing the class object, not return value of the method (see last line here). Possible indentation issue for __str__() method fixed, too.
class Person:
age = 0
name = ''
def __init__(self,personAge,personName):
self.age = personAge
self.name= personName
def __str__(self):
return self.name
d = Person(24,'ram')
print(d.__str__())
See also PEP 8 for naming conventions.
class Person:
age = 0
name = ''
def __init__(self, personAge, personName):
self.age = personAge
self.name= personName
def __str__(self):
return self.name
d = Person(24,'ram')
print(d)
__str__ should be out of __init__ scope
I need help , I have the following classes in Python with inheritance and I have an error:
class Human:
def __init__(self,name,surname,age):
self.name = name
self.surname = surname
self.age = age
def getName(self):
return self.name
def getSurname(self):
return self.surname
def setName(self, name):
self.name = name
def setSurname(self, surname):
self.surname = surname
def setAge(self, age):
self.age = age
def getAge(self):
return self.age
pass
and:
from Human import Human
class Student(Human):
def __init__(self,name,surname,age,file):
Human().__init__(self,name, surname, file)
self.file = file
def getFile(self):
return self.file
def setFile(self, file):
self.file = file
pass
When I instantiate me the following error
from Student import Student
student1 = Student("Jhon", "Santana", "20", "111000")
Error:
Human().__init__(self, name, surname, age)
TypeError: __init__() takes exactly 4 arguments (1 given)
which is the cause of this error? Thanks...
Human().__init__(self,name, surname, age)
thats not how you create an instance of your class
you should do:
Human.__init__(self,name, surname, age)
without the () .otherwise you try to create an instance of it in Human()
dont instanciate your parent class
def __init__(self,name,surname,age,file):
Human.__init__(self,name, surname, file)
or even better
super(Human,self).__init__(name,surname,age)
Try this:
class Human:
def __init__(self,name,surname,age):
self.name = name
self.surname = surname
self.age = age
def getName(self):
return self.name
def getSurname(self):
return self.surname
def setName(self, name):
self.name = name
def setSurname(self, surname):
self.surname = surname
def setAge(self, age):
self.age = age
def getAge(self):
return self.age
class Student(Human):
def __init__(self, name,surname,age,file):
super().__init__(name, surname, age)
self.file = file
def getFile(self):
return self.file
def setFile(self, file):
self.file = file
student1 = Student("Jhon", "Santana", "20", "111000")
input()
When you inherit another class but want to overwrite some of the attributes, you need to add the parent class's attributes that you want to overwrite in the super constructor so that the attributes passed into the student class can be passed straight into the parent class.
Feel free to watch my video on inheritance at the following address:
https://www.youtube.com/watch?v=cqRtcmPGcic
As detailed here, the use of super is prefered:
def __init__(self, name, surname, age, file):
super(Human, self).__init__(name, surname, age)
self.file = file
Let's say I have a class named Books that has the variables: author, title, and book_id. And then I have another class name Patrons that has the variables: name, patron_id, and borroweds.Borroweds is supposed to be a list of Books currently "checked out" so I would have to encorporate the class Books into the class Patron. But how would I go about doing that?
This is what I have so far:
class Book:
author= ""
title = ""
book_id= ""
# the class constructor
def __init__(self, author, title, book_id):
self.title = title
self.author = author
self.book_id = book_id
def __str__(self):
s = str("Books("+str(self.author)+", "+str(self.title)+", "+str(self.book_id+")"))
return s
def __repr__(self):
return str(self)
class Patron:
name= ""
patron_id= ""
borroweds= list()
# the class constructor
def __init__(self, name, patron_id, borroweds):
self.name= name
self.patron_id= patron_id
self.borroweds= borroweds
def __str__(self):
s= str("Patron("+str(self.name)+","+str(self.patron_id)+","+list(self.borroweds)+")")
return s
def __repr__(self):
return str(self)
borroweds = [Book('Author Authorsson', 'The book of books', 'ISBN76576575757')]
patron = Patron('thename', 'theid', borroweds)
>>> patron
Patron(thename,theid,[Books(Author Authorsson, The book of books, ISBN76576575757)])
>>> patron.borroweds[0]
Books(Author Authorsson, The book of books, ISBN76576575757)
Also, skip the class attributes, you don't need them.
class Book:
# the class constructor
def __init__(self, author, title, book_id):
self.title = title
self.author = author
self.book_id = book_id
def __str__(self):
s = str("Books("+str(self.author)+", "+str(self.title)+", "+str(self.book_id+")"))
return s
def __repr__(self):
return str(self)
class Patron:
# the class constructor
def __init__(self, name, patron_id, borroweds):
self.name= name
self.patron_id= patron_id
self.borroweds= borroweds
def __str__(self):
s= str("Patron("+str(self.name)+","+str(self.patron_id)+","+str(self.borroweds)+")")
return s
def __repr__(self):
return str(self)
Did you notice the typo in the __str__ method of Books? Your parenthesis at the end needs moved left, after self.book_id.
You don't need the class attributes because they are for "global" purposes for every 'Patron'. So if you wanted to keep track of how many patrons you make, you could update that "global" variable each time you make one, like this:
class Patron:
patron_id= 0
# the class constructor
def __init__(self, name, borroweds):
self.name= name
self.patron_id=self.patron_id
self.borroweds= borroweds
Every time you create a Patron object you could add one to the class attribute:
p1 = Patron('Dave',[Book('Me','Something', '8675309')])
print p1.patron_id
Patron.patron_id+=1
p2 = Patron('Dave',[Book('You','Others', 'Number9')])
print p2.patron_id
You'll notice the class attribute was changed and set the objects attribute. You could even create a class attribute in Patron that was a list of every Patron object and add each one during the __init__ method if you wanted. Its going to keep track of it for the class.
Also, I think you need ","+list(self.borroweds)+")" to be ","+str(self.borroweds)+")"