OOP - Creation of Class, iterating through an album of songs? - python

I'm learning about OOP and I need some help with defining one of the methods under Album, specifically total_runtime.
Here's some code (verified, all correct) on the context of the question.
class Duration(object):
def __init__(self, minutes, seconds):
self.total_seconds = minutes * 60 + seconds
self.minutes = int(self.total_seconds / 60)
self.seconds = self.total_seconds % 60
def get_minutes(self):
return self.minutes
def get_seconds(self):
return self.seconds
def __str__(self):
# returns the string representation of the Duration in "mm:ss" form.
if len(str(self.minutes)) < 2:
self.minutes = "0" + str(self.minutes)
if len(str(self.seconds)) < 2:
self.seconds = "0" + str(self.seconds)
return str(self.minutes) + ":" + str(self.seconds)
def __add__(self, duration):
#Adds 2 durations together
return Duration(self.minutes + duration.minutes, self.seconds + duration.seconds)
class Song(object):
def __init__(self, artist, title, duration):
self.artist = artist
self.title = title
self.duration = duration
def get_artist(self):
return self.artist
def get_title(self):
return self.title
def get_duration(self):
return self.duration
class Album(object):
def __init__(self, artist, title):
self.artist = artist
self.title = title
self.songs = list()
def add_song(self, song):
# Adds song (of class Song) to the album.
self.songs.append(song)
I need some help with defining the property total_runtime(self) under class Album which is supposed to return the total runtime (of class Duration) of the album.
Here's what I have now. I tried iterating through the album to get the durations of all the songs. Somehow I'm getting an error which says that add is not defined.
def total_runtime(self):
duration = (0,0)
for song in self.songs:
__add__(self, duration)
return duration
Would really appreciate any help debugging! Thank you!

You need to call __add__ as an attribute of the class, the self argument is the object you're calling from. It's implicitly moved into the arguments.
def total_runtime(self):
duration = Duration(0,0)
for song in self.songs:
duration.__add__(song.get_duration())
return duration
But really, __add__ is more cleanly used with the plus operator:
def total_runtime(self):
duration = Duration(0,0)
for song in self.songs:
duration += song.get_duration()
return duration

Related

java.lang.IllegalStateException: 2 members with a #ValueRangeProvider annotation must not have the same id (timeslotRangeLS)

Trying to generate school timetable with lab hours.
Kindly help me to solve this error! Thanks in advance.
Here is my code!
#planning_solution
class TimeTable:
timeslot_list: list[Timeslot]
timeslot_list1: list[Timeslot]
room_list: list[Room]
lesson_list: list[Lesson]
lab_list: list[Lab]
score: HardSoftScore
def __init__(self, timeslot_list, timeslot_list1, room_list, lesson_list,lab_list,
score=None):
self.timeslot_list = timeslot_list
self.timeslot_list1 = timeslot_list1
self.room_list = room_list
self.lesson_list = lesson_list
self.lab_list = lab_list
self.score = score
#problem_fact_collection_property(Timeslot)
#value_range_provider("timeslotRangeLS")
def get_timeslot_list(self):
return self.timeslot_list
#problem_fact_collection_property(Timeslot)
#value_range_provider("timeslotRangeLB")
def get_timeslot_list1(self):
return self.timeslot_list1
#problem_fact_collection_property(Room)
#value_range_provider("roomRange")
def get_room_list(self):
return self.room_list
#planning_entity_collection_property(Lesson)
def get_lesson_list(self):
return self.lesson_list
#planning_entity_collection_property(Lab)
def get_lab_list(self):
return self.Lab_list
#planning_score(HardSoftScore)
def get_score(self):
return self.score
def set_score(self, score):
self.score = score
def __str__(self):
return (
f"TimeTable("
f"timeslot_list={format_list(self.timeslot_list)},\n"
f"timeslot_list1={format_list(self.timeslot_list1)},\n"
f"room_list={format_list(self.room_list)},\n"
f"lesson_list={format_list(self.lesson_list)},\n"
f"lab_list={format_list(self.lab_list)},\n"
f"score={str(self.score.toString()) if self.score is not None else 'None'}"
f")"
)
Trying to get the 2 timeslots one for lesson(1 hour) and one for lab(2 hour).Here is my #planning_solution.
I defined 2 #planning_entity for both lab & lesson with #value_range_provider.
#planning_entity
class Lab(Base):
id: int
subject: str
teacher: str
student_group: str
timeslot1: Timeslot
room: Room
def __init__(self, id, subject, teacher, student_group, timeslot1 = None, room=None):
self.id = id
self.subject = subject
self.teacher = teacher
self.student_group = student_group
self.timeslot1 = timeslot1
self.room = room
#planning_variable(Base, value_range_provider_refs=['roomRange', 'timeslotRangeLB'],
graph_type=PlanningVariableGraphType.CHAINED)
#planning_id
def get_id(self):
return self.id
#planning_variable(Timeslot, ["timeslotRangeLB"])
def get_timeslot1(self):
return self.timeslot1
#value_range_provider(range_id = "timeslotRangeLB", value_range_type = Timeslot)
def get_possible_timeslot_list1(self):
return self.subject.teacher.student_group.room_list
def set_timeslot1(self, new_timeslot):
self.timeslot1 = new_timeslot
#planning_variable(Room, ["roomRange"])
def get_room(self):
return self.room
def set_room(self, new_room):
self.room = new_room
def __str__(self):
return (
f"Lab("
f"id={self.id}, "
f"timeslot1={self.timeslot1}, "
f"room={self.room}, "
f"teacher={self.teacher}, "
f"subject={self.subject}, "
f"student_group={self.student_group}"
f")"
)
#planning_entity
class Lesson(Base):
id: int
subject: str
teacher: str
student_group: str
timeslot: Timeslot
room: Room
def __init__(self, id, subject, teacher, student_group, timeslot=None, room=None):
self.id = id
self.subject = subject
self.teacher = teacher
self.student_group = student_group
self.timeslot = timeslot
self.room = room
#planning_variable(Base, value_range_provider_refs=['timeslotRangeLS', 'roomRange'],
graph_type=PlanningVariableGraphType.CHAINED)
#planning_id
def get_id(self):
return self.id
#planning_variable(Timeslot, ["timeslotRangeLS"])
def get_timeslot(self):
return self.timeslot
#value_range_provider(range_id = "timeslotRangeLS", value_range_type = Timeslot)
def get_possible_timeslot_list(self):
return self.subject.teacher.student_group.room_list
# return self.course.teacher.department.room_list
def set_timeslot(self, new_timeslot):
self.timeslot = new_timeslot
#planning_variable(Room, ["roomRange"])
def get_room(self):
return self.room
def set_room(self, new_room):
self.room = new_room
def __str__(self):
return (
f"Lesson("
f"id={self.id}, "
f"timeslot={self.timeslot}, "
f"room={self.room}, "
f"teacher={self.teacher}, "
f"subject={self.subject}, "
f"student_group={self.student_group}"
f")"
)
The issue is you defined #value_range_provider(range_id = "timeslotRangeLS") on both your #planning_solution and your #planning_entity. You can only have one; if you want the value range to apply to every entity, do it on the #planning_solution. If you want each planning entity to have it own value range that only applies to it, do it on the #planning_entity. If you want to combine a value range that contains common values for all entities, and a value range that is per entity, use a #value_range_provider on the #planning_solution, and a #value_range_provider on the entity, but give them different ids (ex: #value_range_provider(range_id = "timeslotRangeLSSolution") and #value_range_provider(range_id = "timeslotRangeLSEntity"), and in the #planning_variable, use both range ids in the list (ex: #planning_variable(Room, ["timeslotRangeLSSolution", "timeslotRangeLSEntity"])

RecursionError: maximum recursion depth exceeded while calling a Python object(Algorithmic Change Required)

I am learning about Class Inheritance and overriding methods in python. To implement my learning, I wrote this code to let me better understand how Inheritance and Overriding works. But as I ran the code, I faced this error
"RecursionError: maximum recursion depth exceeded while calling a Python object"
I have tried to increase the recursion limit to 10000, but doing so, Python interpreter stopped working in my local machine. Can anyone help me with how I can overcome the error to have my expected output?
As I am new to the community, I may lack the appropriate presentation of the problem. Feel free to ask for more detailed information about the problem.
# Increasing Recursion Limit
import sys
sys.setrecursionlimit(10000)
import random
# Parent Class
class Unique_id_creator():
def __init__(self, birthdate, birthmonth, birthyear):
self.date = birthdate
self.month = birthmonth
self.year = birthyear
def random_digits(self):
last_two_digits = random.randrange(10, 99)
return self.random_digits()
def unique_id(self):
id = int(self.date + self.month + self.year + self.random_digits())
return self.unique_id()
# Child Class
class Unique_id_distributer(Unique_id_creator):
def __init__(self, name, birthdate, birthmonth, birthyear):
Unique_id_creator.__init__(self, birthdate, birthmonth, birthyear)
self.name = name
def unique_id(self):
Unique_id_creator.unique_id(self)
return "Dear "+ str(self.name) + ", Your Unique Id is: "+ str(self.unique_id())
citizen1 = Unique_id_distributer("hasan", "01", "11", "2000")
print(citizen1.unique_id())
# Output Window
RecursionError: maximum recursion depth exceeded while calling a Python object
This line return self.random_digits() and this line return self.unique_id() are infinite recursive loops.
I assume what you intended to return was last_two_digits and id.
When you return a function call, that function has to execute to return the result of its call. Since you are calling the function you are executing it continues calling itself forever.
Corrected code
# Increasing Recursion Limit
import sys
sys.setrecursionlimit(10000)
import random
# Parent Class
class Unique_id_creator:
def __init__(self, birthdate, birthmonth, birthyear):
self.date = birthdate
self.month = birthmonth
self.year = birthyear
def random_digits(self):
last_two_digits = random.randrange(10, 99)
# convert to a string since you are concatenating the result
return str(last_two_digits)
def unique_id(self):
id = int(self.date + self.month + self.year + self.random_digits())
return id
# Child Class
class Unique_id_distributer(Unique_id_creator):
def __init__(self, name, birthdate, birthmonth, birthyear):
Unique_id_creator.__init__(self, birthdate, birthmonth, birthyear)
self.name = name
def unique_id(self):
id = Unique_id_creator.unique_id(self)
return "Dear "+ str(self.name) + ", Your Unique Id is: "+ str(id)
citizen1 = Unique_id_distributer("hasan", "01", "11", "2000")
print(citizen1.unique_id())
Additionally, you can eliminate the full call of your parent class by using super().
Child class example
# Child Class
class Unique_id_distributer(Unique_id_creator):
def __init__(self, name, birthdate, birthmonth, birthyear):
super().__init__(birthdate, birthmonth, birthyear)
self.name = name
def unique_id(self):
id = super().unique_id()
return "Dear "+ str(self.name) + ", Your Unique Id is: "+ str(id)

TypeError: __str__ returned non-string (type NoneType)

So for my last assingment in my python course at uni, I have to write a program consisting of three objects, two of which inherit. I keep running into a snag especially with regards to the last two objects. Here is my code:
class Course:
def __init__(self,title="",ID=0):
self._ID = ID
self._title = title
def getID(self):
return self._ID
def getTitle(self):
return self._title
def setTitle(self,title):
self._title = title
def setID(self,ID):
self._ID = ID
def __repr__(self):
return "Title: " + self._title + "ID: " + str(self._ID)
class OfferedCourse(Course):
def __init__(self,title="",ID=0,enrollment=[]):
super().__init__(title,ID)
self._enrollment = len(enrollment)
def getEnrollment(self):
return self._enrollment
def addStudent(self,stu):
if stu in enrollment:
print("Student is already enrolled.")
else:
enrollment.append(stu)
def dropStudent(self,stu):
if stu in enrollment:
def __repr__(self):
super().__repr__() + "Enrollment: " + str(self._enrollment)
class StudentCourse(Course):
def __init__(self,grade,ID=0,title=""):
super().__init__(title,ID)
self._grade = grade
def getGrade(self):
return self._grade
def setGrade(self,grade):
self._grade = grade
def __repr__(self):
super().__repr__() + "Grade: " + str(self._grade)
def main():
#Set primary course
lego=Course("Lego Design",32013)
#display course
print(lego)
#Set OfferedCourse
bonk=OfferedCourse("Matoran History",82932,["Josh","Rick","Greg","Chris"])
#Display OfferedCourse
print(bonk)
#Set StudentCourse
lp=StudentCourse("History of Nu-Metal",57859,82)
#display Student Course
print(lp)
At around line 60 I recieve the error:
TypeError: str returned non-string (type NoneType)
I'm pretty lost as to what is going on.
Your __repr__s don't explicitly return anything. You build up a string, then throw it away, causing None to be implicitly returned instead.
Just add a return:
def __repr__(self):
return super().__repr__() + "Grade: " + str(self._grade)
Adjustments to the source code of the original question:
add missing statement at def dropStudent(self,stu):
add missing return expression for def __repr__(self):
adjust signature of StudentCourse(Course) init to def __init__(self,title,ID,grade): to be in line with parent classes and process given statement StudentCourse("History of Nu-Metal",57859,82) as expected
add missing indentions for def main():
class Course:
def __init__(self,title="",ID=0):
self._ID = ID
self._title = title
def getID(self):
return self._ID
def getTitle(self):
return self._title
def setTitle(self,title):
self._title = title
def setID(self,ID):
self._ID = ID
def __repr__(self):
return "Title: " + self._title + "ID: " + str(self._ID)
class OfferedCourse(Course):
def __init__(self,title="",ID=0,enrollment=[]):
super().__init__(title,ID)
self._enrollment = len(enrollment)
def getEnrollment(self):
return self._enrollment
def addStudent(self,stu):
if stu in enrollment:
print("Student is already enrolled.")
else:
enrollment.append(stu)
def dropStudent(self,stu):
if stu in enrollment:
print("#todo Something is missing here...")
def __repr__(self):
return super().__repr__() + "Enrollment: " + str(self._enrollment)
class StudentCourse(Course):
def __init__(self,title,ID,grade):
super().__init__(title,ID)
self._grade = grade
def getGrade(self):
return self._grade
def setGrade(self,grade):
self._grade = grade
def __repr__(self):
return super().__repr__() + "Grade: " + str(self._grade)
def main():
#Set primary course
lego=Course("Lego Design",32013)
#display course
print(lego)
#Set OfferedCourse
bonk=OfferedCourse("Matoran History",82932,["Josh","Rick","Greg","Chris"])
#Display OfferedCourse
print(bonk)
#Set StudentCourse
lp=StudentCourse("History of Nu-Metal",57859,82)
#display Student Course
print(lp)
main()

Why the following code results in error?

It works for Employee and calculate_wage, but returns an error when I try to create an instance of PartTimeEmployee and call to the calculate_wage method of PartTimeEmployee's parent class.
class Employee(object):
"""Models real-life employees!"""
def __init__(self, employee_name):
self.employee_name = employee_name
def calculate_wage(self, hours):
self.hours = hours
return hours * 20.00
class PartTimeEmployee(Employee):
def __init__(self, employee_name):
self.employee_name = employee_name
def calculate_wage(self, hours):
self.hours = hours
return hours * 12.00
def full_time_wage(self, hours):
return super(PartTimeEmployee, self).calculate_wage(self, hours)
milton = PartTimeEmployee("Milton")
print (milton.full_time_wage(10))
return super(PartTimeEmployee, self).calculate_wage(self, hours)
is incorrect, it should be
return super(PartTimeEmployee, self).calculate_wage(hours)
And next time: Also post the error message you're seeing.

Class in python instances

class fase1():
def __init__ (self, num, date, desc)
self.num = num
self.date = date
self.desc = desc
class fase2(fase1):
def __init__(self, ele):
self.ele = [ele,[]]
def __str__(self):
return self.ele
def addfase2(self, num, date, desc):
newfase = fase1()
self.ele[1].append(newfase)
namefase2 = "FASE"
cload = fase2
cload.ele = namefase2
cload.addfase2(10,"date","Desc")
when print ...
['FASE',[<__main__.fase1 instance at 0x01C2BEB8>]]
can anyone help me please?
you have an array containing your fase1 object, which isn't initialized in your addfase2 method (as you'd probably want)
def addfase2(self, num, date, desc):
newfase = fase1(num, date, desc)
also if you add a __str__ method to fase1, you won't see anymore the object repr
def __str__(self):
return self.desc + ' ' + self.num + ' ' + self.date
or something like that

Categories

Resources