Printing entries in a dictionary in descending order - python

Printing entries in a dictionary in descending order so that I can view them according to the example
08:02 - registration
08:45 - doctor checkup
09:00 - procedure
09:15 - doctor checkup
09:25 - radiography
10:30 - blood test
11:00 - doctor checkup
11:30 - hospital discharge
class Time():
def __init__(self, hour, minutes):
self.hour = hour
self.minutes = minutes
def __str__(self):
return "%02d:%02d" % (self.hour, self.minutes)
def __repr__(self):
if self.minutes == 0:
return 'Time({0},{1}0)'.format(self.hour, self.minutes)
return 'Time({0},{1})'.format(self.hour, self.minutes)
class Event():
def __init__(self, time, nameStattion):
self.time = time
self.nameStattion = nameStattion
def __str__(self):
return "{0}-{1}".format(self.time, self.nameStattion)
def __repr__(self):
return 'Event(Time(%d,%d),"%s")' % (self.time.hour, self.time.minutes, self.nameStattion)
class MedicalRecord():
data = {}
def __init__(self, name, id):
self.name = name
self.id = id
def __repr__(self):
return 'Event(Time(%d,%d),"%s")' % (self.time.hour, self.time.minutes, self.nameStattion)
def add(self, time, station):
self.data[time] = Event(Time(int(time[0:2]), int(time[3:5])), station)
def view(self):
#for i in range(len(self.data)):
print(eval(repr(self.data)))
time1 = Time(8, 2)
time1
print(time1)
time2 = eval(repr(time1))
print(time2)
event1 = Event(time1, 'registration')
event1
event2 = eval(repr(event1))
print(event2)
record1 = MedicalRecord('David', 1)
record1.add('08:02', 'registration')
print(record1.data)
record1.add('09:15','doctor checkup')
record1.add('08:45','doctor checkup')
record1.add('09:00','procedure')
record1.add('11:00','doctor checkup')
record1.add('09:25','radiography')
record1.add('11:30','hospital discharge')
record1.add('10:30','blood test')
record1.view()
In my example it prints as one side list

You would want to use the python sorted() function. It will have a key argument which you can pass a function that returns the time and python will sort the list according to that. From there you will probably get an ascending list which you can just do list.reverse() to make it descending.
Edit: actully sorted lets you choose if its acending or decending using the "reverse" argument. See the sorted link for more info.
def keyFunc(EventObj): return f'{EventObj.time}'
sortedList = sorted(SomeEventList, key=keyFunc, reversed = True)

def view(self):
for key in sorted(self.data):
print(key, '-', self.data[key])

Related

question about counting time calculated by property

I have created a date and time delta property. this property calculates the total time between two date and times for a job. Now I want to create a property that sums all the time of the jobs and represents it on a card. I have tried many ,but no success. Hopefully someone has a solution
#property
def Get_time_diference(self):
start_time = self.date
end_time = self.dateTo
total = end_time - start_time
return total
Try making "total" an attribute of the class
class TimeClass:
def __init__(self):
self.total =0
#property
def Get_time_diference(self):
start_time = self.date
end_time = self.dateTo
diff = end_time - start_time
self.total+=diff
return diff
def get_total(self):
return self.total
Another solution could be using global
global total
total=0
#property
def Get_time_diference(self):
start_time = self.date
end_time = self.dateTo
diff = end_time - start_time
total+=diff
return diff

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

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

How to return the value of given key in method - dictionary

Im trying to write a simple vending machine.
I have Container class that contains items and class Items contains information like the prize and the amount.
The ID indentifies the item. Every calling add item will increment ID by one, so that every item is unique.
I would like to get the prize of given ID.
So for example: I add item, it has ID=30, I give ID and it returns the prize of it.
I tried something like this, but it does not work:
from Item import Item
class Container:
id = 30
def __init__(self, objects=None):
if objects is None:
objects = {}
self.objects = objects
def add_object(self, obj: Item):
self.objects.update({id: obj})
Container.id = container.id + 1
def get_length(self):
return len(self.objects)
def find_price_of_given_id(self, id):
# return self.objects.get(id).get_price()
pass
Cola = Item(20)
print(Cola.get_amount())
container = Container()
container.add_object(Cola)
print(container.objects.items())
Item class:
class Item:
def __init__(self, price,amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
I dont know why also print(container.objects.items()) returns dict_items([(<built-in function id>, <Item.Item object at 0x00000000022C8358>)]), why not ID = 30 + Item object
id is the name of a builtin method. Don't use it as a variable name - leads to name confusion.
You're assigning the id inside the container class but never giving it back, so that people can look up the item using the id.
In python3, dict.items returns a dict_items iterator, so you need to iterate over it to get to the items within.
class Item:
def __init__(self, price, amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
def __str__(self):
return f"{self.amount} # {self.price}"
class Container:
item_id = 30
def __init__(self, objects=None):
if objects is None:
objects = {}
self.objects = objects
def add_object(self, obj: Item):
id_to_assign = Container.item_id
self.objects.update({id_to_assign: obj})
Container.item_id = Container.item_id + 1
return id_to_assign
def get_length(self):
return len(self.objects)
def find_price_of_given_id(self, item_id):
return self.objects.get(item_id).get_price()
Cola = Item(20)
print(Cola.get_amount())
container = Container()
cola_id = container.add_object(Cola)
print(container.objects.items())
print(container.find_price_of_given_id(cola_id))
Output:
5
dict_items([(30, <__main__.Item object at 0x104444b00>)])
20

How to get rid of eval in subclass appending to superclass instance list?

I am using eval to run a generated string to append the newly created EggOrder instance to the list of the correct instance of the DailyOrders class. The day provided by EggOrder is used to used to append to the correct instance. This relies on eval and the variable name of the DailyOrders instance and so it would be great to get this removed. I know there must be a better way.
class DailyOrders:
PRICE_PER_DOZEN = 6.5
def __init__(self, day):
self.orders = []
self.day = day
def total_eggs(self):
total_eggs = 0
for order in self.orders:
total_eggs += order.eggs
return total_eggs
def show_report(self):
if self.total_eggs() < 0:
print("No Orders")
else:
print(f"Summary:\nTotal Eggs Ordered: {self.total_eggs()}")
print(f"Average Eggs Per Customer: {self.total_eggs() / len(self.orders):.0f}\n*********")
class EggOrder():
def __init__(self, eggs=0, name="", day=""):
if not name:
self.new_order()
else:
self.name = name
self.eggs = eggs
self.day = day
eval(f"{self.day.lower()}.orders.append(self)")
def new_order(self):
self.name = string_checker("Name: ")
self.eggs = num_checker("Number of Eggs: ")
self.day = string_checker("Date: ")
def get_dozens(self):
if self.eggs % 12 != 0:
dozens = int(math.ceil(self.eggs / 12))
else:
dozens = self.eggs / 12
return dozens
def show_order(self):
print(f"{self.name} ordered {self.eggs} eggs. The price is ${self.get_dozens() * DailyOrders.PRICE_PER_DOZEN}.")
if __name__ == "__main__":
friday = DailyOrders("Friday")
friday_order = EggOrder(12, "Someone", "Friday")
friday_order.show_order()
friday.show_report()
saturday = DailyOrders("Saturday")
saturday_order = EggOrder(19, "Something", "Saturday")
saturday_order = EggOrder(27, "Alex Stiles", "Saturday")
saturday.show_report()
DailyOrders isn't actually a superclass (it was in a earlier version), it acts like one and I suspect the answer might have some inheritance.

Capture the output of __repr__ function in a variable

I have the below code base:
from datetime import datetime
class Person:
def __init__(self,day,month,year):
self.day = day
self.mon = month
self.year = year
def __repr__(self):
if self.day < 10:
day = "0" + str(self.day)
else:
day = str(self.day)
if self.mon < 10:
mon = "0" + str(self.mon)
else:
mon = str(self.mon)
display = day + "-" + mon + "-" + str(self.year)
return display
def sortdates(l1):
for dates in l1:
date.finalbirthdate = datetime.strptime(str(print(dates)),"%d-%m-%Y")
print (date.finalbirthdate)
if __name__ == '__main__':
p1 = Person(18,9,1984)
print (p1)
p2 = Person(13,1,1988)
print (p2)
sortdates([p1,p2])
Now the main function of sortdates function is to sort the Person objects as per the dates. For that i somehow need to convert the string representation of the Person object into datetime object.
Also since i have to do that i have to somehow capture the string representation into a variable and pass that to datetime.strptime function.
Can someone please guide me out on how to do this?
Thanks in advance.
The correct way to do this is to define __lt__, __gt__, __eq__ methods for your Person object; this way your Person object becomes "sortable" on its own.
class Person:
def __init__(self,day,month,year):
self.day = day
self.mon = month
self.year = year
def _as_date(self):
return datetime.date(self.year, self.mon, self.day)
def __lt__(self, other):
return self._as_date() < other._as_date()
def __gt__(self, other):
return self._as_date() > other._as_date()
def __eq__(self, other):
return self._as_date() == other._as_date()
def __ne__(self, other):
return ! self.__eq__(other)
def __repr__(self):
return '{}-{}-{}'.format(str(self.day).zfill(2),
str(self.mon).zfill(2),
self.year)
Now, you can just sort your objects directly:
if __name__ == '__main__':
p1 = Person(18,9,1984)
print (p1)
p2 = Person(13,1,1988)
print (p2)
sorted_dates = sorted([p1,p2])

Categories

Resources