Python, How to use part of function outside function - python

How can I use today and returntime in return_fee function?
import datetime
class Movie(object):
def __init__(self,title):
self.title = title
def time_of_return(self):
self.today = today
self.returntime = returntime
today = datetime.datetime.now()
returntime = today + datetime.timedelta(days=30)
def return_fee(Movie):
fee = -2
delta = today - returntime

I would do it like this:
class Movie(object):
def __init__(self,title):
self.title = title
def get_times(self):
now = datetime.datetime.now()
return now, now + datetime.timedelta(days=30)
def time_of_return(self):
now, returntime = self.get_times()
return returntime
def return_fee(self):
fee = -2
now, returntime = self.get_times()
delta = now - returntime
return <whatever based on fee and delta>

If you want time_of_return and return_fee to be instance attributes, call time_of_return from __init__ to set them and then prefix with self:
class Movie(object):
def __init__(self,title):
self.title = title
self.time_of_return()
def time_of_return(self):
self.today = datetime.datetime.now()
self.returntime = today + datetime.timedelta(days=30)
def return_fee(Movie):
fee = None
delta = self.today - self.returntime
# ... presumably do something else
Alternatively (since, in particular, today may change over time), call the function time_of_return from within return_fee and make sure it returns something:
class Movie(object):
def __init__(self,title):
self.title = title
def time_of_return(self):
today = datetime.datetime.now()
returntime = today + datetime.timedelta(days=30)
return today, returntime
def return_fee(Movie):
fee = None
today, returntime = self.time_of_return()
delta = today - returntime
# ... presumably do something else
It's a good idea to indent your code by 4 spaces, by the way. And None (or 0) would be a better default value for fee.

class Movie(object):
def __init__(self,title,today,returntime):#<----
self.title = title
def time_of_return(self):
self.today = today
self.returntime = returntime
today = datetime.datetime.now()
returntime = today + datetime.timedelta(days=30)
def return_fee(Movie):
fee = -2
delta = today - returntime
That's because __init__() is taking arguments that using for class from outside.But, when you use your Movie class, you have to define that arguments.

Related

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

Python - a Class to get employee age from Date of birth?

import datetime
class Employee:
def __init__ (self,first,last,pay,dob):
self.first = first
self.last = last
self.pay = pay
self.email = first + "." + last + "#company.com"
self.dob = dob
def fullname(self):
return '{} {}'.format(self.first,self.last)
def age(dob):
today = date.today()
return today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))
emp1 = Employee("aa","ss",122,date(1991,2,3))
emp2 = Employee("ww","ii",637,date(1997,8,24))
emp3 = Employee("ee","oo",986,date(1986,10,19))
#driver code
print(Employee.age(emp2))
I am getting the below error:
AttributeError: 'Employee' object has no attribute 'year'
What is incorrect in this?
Your Employee.age() method signature has only one argument - dob. When you call it first argument that is passed is the instance. By convention we use argument self for it. But you use dob. Stick to convention as you do in the other method. then work with self.dob.year
from datetime import date
class Employee:
def __init__ (self,first,last,pay,dob):
self.first = first
self.last = last
self.pay = pay
self.email = first + "." + last + "#company.com"
self.dob = dob
#property
def fullname(self):
return '{} {}'.format(self.first, self.last) # in 3.6 return f'{self.first} {self.last}'
def age(self):
today = date.today()
return today.year - self.dob.year - ((today.month, today.day) < (self.dob.month, self.dob.day))
emp1 = Employee("aa","ss",122,date(1991,2,3))
emp2 = Employee("ww","ii",637,date(1997,8,24))
emp3 = Employee("ee","oo",986,date(1986,10,19))
#driver code
print(emp1.age())
Note, I also added #property decorator, so that fullname is "read-only" property
and also fixed the import
in 3.6+ you can use f-strings. age and e-mail property, like fullname may be read-only property (i.e. you should not specify age that contradict to dob), e.g.
#property
def age(self):
today = date.today()
return today.year - self.dob.year - ((today.month, today.day) < (self.dob.month, self.dob.day))
Then you can use it like this
print(emp1.age) # note the difference when it is method in the original class, and now when its property
Your employee class does not have a year attribute
but
employee.dob has that
import datetime
from datetime import date
class Employee:
def __init__ (self,first,last,pay,dob):
self.first = first
self.last = last
self.pay = pay
self.email = first + "." + last + "#company.com"
self.dob = dob
def fullname(self):
return '{} {}'.format(self.first,self.last)
def age(dob):
today = date.today()
dob = dob.dob # get dob from the object(of employee class) <<<<< Single change
return today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))
emp1 = Employee("aa","ss",122,date(1991,2,3))
emp2 = Employee("ww","ii",637,date(1997,8,24))
emp3 = Employee("ee","oo",986,date(1986,10,19))
#driver code
print(Employee.age(emp2))

Implement datetime module in Python OOP

I am trying to implement datetime module to my Clock OOP, but the data is not being updated with the current hour, minute and second. Please have a look at the code. I can't see what I am doing wrong.
import datetime
import time
# Python class to emulate CLock
class ClockNow2:
def __init__(self):
self.theHour = 0
self.theMinute = 0
self.theSecond = 0
self.theLocale ="Unknow"
self.AM = True
#setters and getters (transformers and accessors)
#one setter and getter for each attribute
def setHour(self):
self.theHour =datetime.timezone
def getHour(self):
return self.theHour
def setMinute(self):
self.theMinute = now.minute
def getMinute(self):
return self.theMinute
def setSecond(self):
self.theSecond = now.second
def getSecond(self):
return self.theSecond
def setLocale(self,newval):
self.theLocale = newval
def getLocale(self):
return self.theLocale
def toString(self):
clockstring = "The time in " +self.theLocale + " is " +str(self.theHour) \
+ ":" +str(self.theMinute) + ":" + str(self.theSecond)
return clockstring

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])

An issue filtering related models inside the model definition

I'm trying to write some custom methods for my models but I'm getting the following error:
Attribute Error: 'ForeignRelatedObjectsDescriptor' object has no attribute all|filter
This happens when I run this code:
chore = Chore(name='Laundry')
chore.schedule_set.create(week_day='monday', time_due='17:30:00')
chore.scheduled()
Does anyone have any advice on how to make this work or what I might be missing? I've checked the Django documents but they seem to only cover the most basic uses of models.
models.py:
from django.db import models
from datetime import date, timedelta
class ChoreManager(models.Manager):
def by_day(self, week_day):
if week_day == 'today':
week_day = date.today().strftime("%A")
chores = self.filter(week_day=week_day)
if chores.count() > 0:
return chores
else:
return False
def today(self):
return self.by_day(week_day='today')
class Chore(models.Model):
chores = ChoreManager()
name = models.CharField(max_length=50)
notes = models.TextField(null=True)
def scheduled(self, week_day=None):
if week_day is None:
schedule_count = Chore.schedule_set.all().count()
else:
if week_day == 'today':
week_day = date.today().strftime("%A")
schedule_count = Chore.schedule_set.filter(week_day=week_day).count()
if schedule_count > 0:
return True
else:
return False
def times_by_day(self, week_day):
if self.scheduled() == True:
if week_day == 'today':
week_day = date.today().strftime("%A")
return Chore.schedule_set.filter(week_day=week_day).values('time_due')
else:
return False
class Schedule(models.Model):
chore = models.ForeignKey('Chore')
week_day = models.CharField(max_length=9)
time_due = models.TimeField()
def mark_complete(self):
completed_event = Schedule.completedevent_set.create()
completed_event.save()
def completed_this_week(self):
today = date.today()
weekstart = today - timedelta(days=today.weekday())
weekend = weekstart + timedelta(days=7, hours=23, minutes=59, seconds=59)
if Schedule.completedevent_set.filter(datetime_completed__gte=weekstart, datetime_completed__lte=weekend).count() > 0:
return True
else:
return False
class CompletedEvent(models.Model):
schedule = models.ForeignKey('Schedule')
datetime_completed = models.DateTimeField(auto_now_add=True)
change:
schedule_count = Chore.schedule_set.all().count()
to:
schedule_count = self.schedule_set.all().count()
in all the occurrences..

Categories

Resources