How to check if 2 elements are same in python OOP? - python

class Course:
def __init__(self, name, classroom, instructor, day, start_time, end_time):
self.name = name
self.classroom = classroom
self.instructor = instructor
self.day = day
self.start_time = start_time
self.end_time = end_time
class Schedule:
def __init__(self):
self.courses = []
program = [["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"]]
def add_course(self, course):
self.courses.append(course)
def print_schedule(self):
days = ["Monday","Tuesday","Wednesday","Thursday","Friday"]
program = [["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"],["9","10","11","12","13","14","15","16","17"]]
for course in self.courses:
for j in range(course.start_time-9,course.end_time-8):
program[days.index(course.day)][j] += f" {course.name} class from {course.instructor} at {course.classroom}"
for i in range(len(days)):
print(days[i],":")
for k in program[i]:
print(k)
schedule = Schedule()
schedule.add_course(Course("Physics","MED A11","James","Monday",9,11))
schedule.add_course(Course("Logic Design","EEB 4105","Jack","Wednesday",9,10))
schedule.add_course(Course("Logic Design","EEB 4205","Jack","Wednesday",15,17))
schedule.print_schedule()
Here I wanted to create an weekly schedule, I want it to write something when two classes collide. So their self.day need to be same and the times need to intersect.
For times I can do something like
time = {for i in range(start_time,end_time+1)}
if time1.intersection(time2) != 0:
#...
But I don't know how to reach 2 different Course elements at the same time. Also would be great if you have any suggestions for this code.

You can add a method to the Course class that checks it against another Course to see if they collide. When you add a course, have it loop through the existing courses to see if it collides with the existing courses in your Schedule.
class Course:
def __init__(self, name, classroom, instructor, day, start_time, end_time):
self.name = name
self.classroom = classroom
self.instructor = instructor
self.day = day
self.start_time = start_time
self.end_time = end_time
def check_collision(self, other):
if self.day == other.day:
if other.start_time < self.start_time < other.end_time:
return True
if other.start_time < self.end_time < other.end_time:
return True
if self.start_time < other.start_time < self.end_time:
return True
if self.start_time < other.end_time < self.end_time:
return True
return False
class Schedule:
def __init__(self):
self.courses = []
self.program = [
["9","10","11","12","13","14","15","16","17"],
["9","10","11","12","13","14","15","16","17"],
["9","10","11","12","13","14","15","16","17"],
["9","10","11","12","13","14","15","16","17"],
["9","10","11","12","13","14","15","16","17"],
]
def add_course(self, course):
for c in self.courses:
if course.check_collision(c):
print(f'New course has collision with course: {c.name} on {c.day}: {c.start_time}-{c.end_time}')
break
else:
self.courses.append(course)
def print_schedule(self):
days = ["Monday","Tuesday","Wednesday","Thursday","Friday"]
program = [x.copy() for x in self.program]
for course in self.courses:
for j in range(course.start_time-9,course.end_time-8):
program[days.index(course.day)][j] += f" {course.name} class from {course.instructor} at {course.classroom}"
for i in range(len(days)):
print(days[i],":")
for k in program[i]:
print(k)

So based on your Code, what you can do is define a compare function for the class Schedule, you make a Schedule object to hold many courses. So if you want to access a course within a Schedule you need to do schedule.courses[i]. But I suggest you add the following function to the courses class to solve your problem.
def compare_course(self, other_course):
my_time = {i for i in range(start_time, end_time+1)}
other_time = {i for i in range(other_course.start_time, other_course.end_time+1)}
if my_time.intersection(other_course.time) != set():
return "Course Collides"
else:
return "Course does not collide"

Related

How to add new variables into objects to use in classes

I have the code:
import timedelta
class Tune:
def __init__(self, title, artist, duration):
self.title = title
self.artist = artist
self.duration = duration
class Play:
def __init__(self):
self.tracks = []
def add(self, song):
self.tracks.append(song)
def delete(self, number):
del (self.song(number))
def look(self, song):
for song in self.tracks:
print(f"{song.artist} - {song.title}")
def duration(self):
s=0
for y in range(0,len(self.song)):
s = s + self.song[y]
print(int(datetime.timedelta(seconds=s)))
n = int(input("Enter the number of tracks to add"))
playlist = Play()
for i in range(n):
title, artist, duration = input("Enter the title, artist, and duration of a track").split(',')
song = Tune(title, artist, duration)
playlist.add(song)
playlist.look()
playlist.duration
playlist.delete (2)
for every input, i have to make it an object pertaining to its class and add it to the list, with the option of removing it when it is called. When song.look is called, it is supposed to print out the title and artist in the list. For example, if the input is:
2
Artic Monkeys,R U Mine?,324
Artic Monkeys,Do I wanna know?,253
when the program is executed it should output:
1 - Artic Monkeys - R U Mine?
2 - Artic Monkeys - Do I wanna know?
when duration is executed:
00:09:62
when the delete is executed:
1 - Artic Monkeys - R U Mine?
and if song.duration is called, it should output the total duration in the format of hours:minutes:seconds. I think the add and look is correct, my only problem is how do i make it so that it can have track number and how can i use it to remove said tracks? and is my program for duration correct?
Edit: I can only change the def for the class Play, I cant change the contents of Tune
import time
class Tune:
def __init__(self, title, artist, duration):
self.title = title
self.artist = artist
self.duration = duration
class Play:
def __init__(self):
self.tracks = []
def add(self, song):
self.tracks.append(song)
def delete(self, number):
self.tracks.pop(number-1)
def look(self):
for i in range(len(self.tracks)):
print(f"{i+1} -{self.tracks[i].artist} - {self.tracks[i].title}")
def duration(self):
s = 0
for y in range(len(self.tracks)):
s += int(self.tracks[y].duration)
print(time.strftime('%H:%M:%S', time.gmtime(s)))
n = int(input("Enter the number of tracks to add"))
playlist = Play()
for i in range(n):
title, artist, duration = input("Enter the title, artist, and duration of a track").split(',')
song = Tune(title, artist, duration)
playlist.add(song)
playlist.look()
playlist.duration()
print("After Deleting 2nd....")
playlist.delete (2)
playlist.look()
print("After Deleting 2nd....")
playlist.delete (2)
playlist.look()

Library Member class, can't figure out where I'm going wrong

I am trying to complete a series of class definition tasks and can't seem to get past this one. It is part of a 3 part series; the first part asks you to model a library book, which I could complete easily.
The next part is asking to create a Member class to model a library member and include a borrow_book() and a return_book() method, and to get the member's list of all loan books to print out in alphabetical order.
I cannot understand which part I am going wrong on. Could someone possibly point me in the right direction? I have included my code so far below.
class Book(object):
def __init__(self, title, author, copies=1, loan=0):
self.title = title
self.author = author
self.copies = copies
self.loan = loan
def checkbook(self, title):
for book in self.title:
if book.title in self.title:
return book
else:
print("Sorry, Not Available.")
def borrow_book(self):
abc = self.checkbook(title)
print(abc)
self.loan += 1
self.copies -= 1
def return_book(self):
self.loan -= 1
def __str__(self):
r = []
r.append('Title: {}'.format(self.title))
r.append('Author: {}'.format(self.author))
r.append('Copies: {}'.format(self.copies))
r.append('On loan: {}'.format(self.loan))
return '\n'.join(r)
def sort_books(b):
return b.title
class Member(object):
def __init__(self, mid, name, loans=0):
self.mid = mid
self.name = name
self.loans = loans
self.d = {}
def __str__(self, mid, name, loans=0):
r = []
r.append('ID: {}'.format(self.mid))
r.append('Name: {}'.format(self.name))
r.append('Loans: {}'.format(self.loans))
l = ['{}'.format(b) for b in sorted(self.d.values(), key=sort_books)]
return '\n'.join(r)
return '\n'.join(l)

Calling variable from another class in “python”

Good day Sir,
I have a problem in calling the variable date, group from class JB() and KL() because I want to compare if the group in JB and KL is 1 and the date for JB()==KL(), I want to print the date. I have tried some solution from this forum, but it seems like I have failed.
class JB(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetableJB(self):
print(self.date)
tt1 = JB("8 Sept", (TS3_JB, TS4_JB, TS5_JB, TS6_JB), G1)
tt2 = JB("15 Sept", (TS3_JB, TS4_JB, TS5_JB, TS6_JB), G2)
tt3 = JB("22 Sept", (TS3_JB, TS4_JB, TS5_JB, TS6_JB), G3)
class KL(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetableKL(self):
print(self.date, self.timeslot, self.group)
tt2 = KL("15 Sept", (TS1_KL, TS2_KL, TS3_KL), G1)
tt3_1 = KL("22 Sept", (TS1_KL, TS2_KL, TS3_KL), G2)
tt3_2 = KL("23 Sept", (TS4_KL, TS5_KL, TS6_KL), G3)
class PP(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetablePP(self):
print(self.date, self.timeslot, self.group)
tt3 = PP("22 Sept", (TS1_PP, TS2_PP, TS3_PP), G1)
tt4_1 = PP("29 Sept", (TS1_PP, TS2_PP, TS3_PP), G2)
tt4_2 = PP("30 Sept", (TS4_PP, TS5_PP, TS6_PP), G3)
print("")
print("Clash analysis for timetable KL and JB")
clashJB = JB()<----- I have error in this part
clashKL = KL()<----- I have error in this part
while clashJB.group and clashKL.group == G1:
if clashJB.date == clashKL.date:
print(clashJB.date)
You might be getting error because you are trying to create instances clashJB and clashKL without passing mandatory parameters date, timeslot, group . You need to create it as:
clashJB = JB(<date>, <timeslot>, <group>)
clashKL = KL(<date>, <timeslot>, <group>)
before you perform comparison operations.
You can go through https://docs.python.org/2/tutorial/classes.html if you have any doubts related to class definition and its use.
Following code work as per your expectation .
class JB(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetableJB(self):
print(self.date)
class KL(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetableKL(self):`enter code here`
print(self.date, self.timeslot, self.group)
class PP(object):
def __init__(self, date, timeslot, group):
self.date = date
self.timeslot = timeslot
self.group = group
def timetablePP(self):
print(self.date, self.timeslot, self.group)
clashJB = JB(1,2,'G1')<---- Note the change
clashKL = KL(1,2,'G1')<-----Note the change
while clashJB.group and clashKL.group == 'G1':
if clashJB.date == clashKL.date:
print(clashJB.date)

How do I inherit a class in python?

I am trying to associate a competitor with the race that they have competed in, how would I do the show() function through inheriting the event class? I'm still wrapping my head around inheritance so I apologise if this question is obvious..
import sqlite3
print "hello"
class competitor(object):
def __init__(self, name, dob, number, events):
self.name = name
self.dob = dob
self.number = number ##this needs to check db for existing
self.events = events
def listEvents(self):
for all in self.events:
self.show()
class event(competitor):
def __init__(self, name, distance, date, time):
self.name = name
self.distance = distance #meters
self.date = date # [dd,mm,yyyy]
self.time = time # [d,h,m,s]
def printDate(self):
date = str(self.date[0]) + "/" + str(self.date[1]) + "/" + str(self.date[2])
##print date
return date
def printTime(self):
if (self.time[0] > 0):
time = str(self.time[0]) + "." + str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
return time
else:
time = str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
return time
def getKmPace(self):
time_s = self.time[0]*3600*24 + self.time[1]*3600 + self.time[2]*60 + self.time[3]
time_m = time_s/60.0
pace = time_m/(self.distance/1000.0)
return pace
def show(self):
print "Event: ", self.name, " Date: ", self.printDate()
print "Distance: ",self.distance/1000.0,"KM, Time: ", self.printTime()
print "Pace per 1 KM: ", self.getKmPace(), " minutes."
kdl = event("20KM",20000,[26,4,2014],[0,1,27,36])
kdl_bad = event("20KM",20000,[26,4,2013],[0,2,35,37])
kdl.show()
richard = competitor("Richard", 1993, 1, [kdl,kdl_bad])
richard.listEvents()
Well, think about your class design more closely. Is an "event" a more specific "competitor"? Or does an "event" have "competitors? Inheritance is usually used when you're describing an "is-a" relationship, not a "has-a".
In your case, a competitor has a reference to multiple event objects. Your class design for both are already on the right track. Your use of inheritance, however, is not.
A simple fix:
class competitor(object):
def __init__(self, name, dob, number, events):
self.name = name
self.dob = dob
self.number = number ##this needs to check db for existing
self.events = events
def listEvents(self):
for event in self.events:
event.show()
class event(object):
def __init__(self, name, distance, date, time):
self.name = name
self.distance = distance #meters
self.date = date # [dd,mm,yyyy]
self.time = time # [d,h,m,s]
def printDate(self):
date = str(self.date[0]) + "/" + str(self.date[1]) + "/" + str(self.date[2])
return date
def printTime(self):
if (self.time[0] > 0):
time = str(self.time[0]) + "." + str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
else:
time = str(self.time[1]) + ":" + str(self.time[2]) + "." + str(self.time[3])
return time
def getKmPace(self):
time_s = self.time[0]*3600*24 + self.time[1]*3600 + self.time[2]*60 + self.time[3]
time_m = time_s/60.0
pace = time_m/(self.distance/1000.0)
return pace
def show(self):
print "Event: ", self.name, " Date: ", self.printDate()
print "Distance: ",self.distance/1000.0,"KM, Time: ", self.printTime()
print "Pace per 1 KM: ", self.getKmPace(), " minutes."
kdl = event("20KM",20000,[26,4,2014],[0,1,27,36])
kdl_bad = event("20KM",20000,[26,4,2013],[0,2,35,37])
print 'First event:'
kdl.show()
print 'Richard has two events:'
richard = competitor("Richard", 1993, 1, [kdl,kdl_bad])
richard.listEvents()
I don't think this is a case for inheritance. To apply inheritance in this example would be something like:
class event(object): # not inheriting from competitor
# your code for the event
# ...
class 20KM_event(event):
def __init__(self, date, time):
super(20KM_event,self).__init__("20KM",20000, date, time)
# if any specific methods are required for JUST the
# 20KM event, put them here. Otherwise you're done
kdl = 20KM_event([26,4,2014],[0,1,27,36])
for your competitor, often this is something that should be handled by the event in question. They are members of the event, after all, so maybe something like:
class event(object):
def __init__(self,name,distance,date,time):
self.name = name
self.distance = distance
self.date = date
self.time = time
self.competitors = []
def addCompetitor(self,*args):
"""Add a competitor to this event
USAGE: self.addCompetitor(competitor) OR
self.addCompetitor(name, dob, number, events)"""
if len(args) == 1 and isinstance(args[0],competitor):
target = args[0]
else:
target = competitor(*args)
target.events.append(self)
self.competitors.append(target)

Why does my class raise an AttributeError?

I might be blind, but I really can't see why this class fails with:
AttributeError: NextSunday instance has no attribute 'trigger'
from datetime import datetime
from datetime import time
from datetime import timedelta
class NextSunday():
def __init__(self, trigger=None):
"""
Get date of, and number of days until, next Sunday.
Arguments:
- `trigger`: Add an extra week if less than trigger number of days.
"""
self.str = u'%s (%s days)' % (self.date().date(), self.no_days())
self.trigger = trigger
def __unicode__(self):
return self.str
def __str__(self):
return unicode(self).encode('utf-8')
def __repr__(self):
return '<Next Sunday: ' + self.str + '>'
def no_days(self):
"""Get date of next sunday. """
days = None
for i in range(7):
dt = datetime.now() + timedelta(days=i)
if dt.weekday() == 6:
days = i
# Add another week if there are less days left then trigger
if self.trigger:
if days < self.trigger:
days += 7
return days
def date(self):
# The datetime obj contains the next sunday, but also the current time
dt_of_next_sun = datetime.now() + timedelta(days=self.no_days())
# Get the whole day
date_of_next_sun = datetime.combine(dt_of_next_sun.date(),
time(23, 59))
return date_of_next_sun
You need to switch these
self.str = u'%s (%s days)' % (self.date().date(), self.no_days())
self.trigger = trigger
like this
self.trigger = trigger
self.str = u'%s (%s days)' % (self.date().date(), self.no_days())
because otherwise the no_days method is called before the self.trigger attribute is created. This is bad because the no_days method tries to read the value of the self.trigger attribute:
if self.trigger:
if days < self.trigger:

Categories