Could someone explain to me how to correctly use classmethod with inheritance in Python?
I need to create two classmethod methods:
to makefull-timeime employee.
to make a part-time employee in Employee class which is inhering from BaseEmployee.
Seem that I fully don't understand a concept:(
Ok, so the question is how to properly create a classmethod and then
how to create a fulltime employee?
Thanks
from datetime import datetime
class Error(Exception):
"""Base class for exception"""
pass
class InvalidDateOfEmployment(Error):
"""Except bigger date then today and seniority more than 50 years"""
pass
class Application:
#staticmethod
def main(self):
name = input('Name: ')
last_name = input('Last name: ')
date_of_employement = datetime.strptime(input('Date of Employement (2022-03-02): '), '%Y.%m.%d')
if Application.date_of_employment_validation(datetime.today(), date_of_employement):
raise InvalidDateOfEmployment
employee = BaseEmployee(name, last_name, date_of_employement)
#staticmethod
def date_of_employment_validation(today: datetime, date: datetime):
diff = today - date
diff_in_years = round(diff.days / 365.25)
return 50 > diff_in_years > 0 #diff_in_years < 50 and diff_in_years > 0
class BaseEmployee:
def __init__(self, name, last_name, date_of_employement):
self.name = name
self.last_name = last_name
self.date_of_employement = date_of_employement
self.now = datetime.now()
#property
def employment_time(self):
return (self.now - self.date_of_employement).days
def __lt__(self, other):
return self.employment_time < other.employment_time
def __repr__(self):
return self.name, self.last_name, self.date_of_employement
class Employee(BaseEmployee):
def __init__(self, bonus, type_of_employment, hour_pay_rate, name, last_name, date_of_employement):
super().__init__(name, last_name, date_of_employement)
self.bonus = bonus
self.type_of_employment = type_of_employment
self.hour_pay_rate = hour_pay_rate
#classmethod
def create_fulltime(cls, bonus, type_of_employment, hour_pay_rate):
return cls(bonus, 160, hour_pay_rate)
# #classmethod
# def create_partime(cls, name, last_name, date_of_employement, bonus, hour_pay_rate):
# return cls(name, last_name, date_of_employement, bonus, hour_pay_rate, 80)
def calculate_sallary(self):
return self.hour_pay_rate * self.type_of_employment + self.bonus
if __name__ == '__main__':
Application.main()
def test_sort_employees():
#given
a = BaseEmployee('A', 'A', datetime(2020, 12, 10))
b = BaseEmployee('B', 'B', datetime(2020, 10, 10))
employees = [a, b]
#when
sorted_employees = sorted(employees)
#then
assert sorted_employees[0] == a
For example:
from datetime import datetime
class Employee:
bonus = 1
base_hpr = 300
#classmethod
#property
def salary_bonus_multiplier(cls):
return cls.bonus
def __init__(self, name, last_name, date_of_employement, hour_pay_rate = base_hpr):
self.name = name
self.last_name = last_name
self.date_of_employement = date_of_employement
self.hour_pay_rate = hour_pay_rate
self.now = datetime.now()
#property
def employment_time(self):
return (self.now - self.date_of_employement).days
def calculate_sallary(self):
return self.employment_time * self.hour_pay_rate * self.salary_bonus_multiplier
def __lt__(self, other):
return self.employment_time < other.employment_time
def __repr__(self):
return self.name, self.last_name, self.date_of_employement
class HalfTimeEmployee(Employee):
bonus = 0.5
class FullTimeEmployee(Employee):
pass
if __name__ == '__main__':
a = HalfTimeEmployee('A', 'A', datetime(2020, 10, 10))
b = FullTimeEmployee('B', 'B', datetime(2020, 10, 10))
print(a.calculate_sallary(), b.calculate_sallary())
classmethod mean to use only class avaluable variables.
Inheritance helps to change them in a particular case.
Related
My error is:
NameError: name 'breed' is not defined
but I thought it was defined in the __init__ function? Any suggestions? This is code from a study guide for an exam, and I'm trying to input it into python 2.7 myself to see the output.
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)
You should have had #property for breed as well:
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#property
def breed(self):
return self.breed
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)
I am writing my own class and methods and I have it all complete except the part of using localtime() to determine a user's age. I have never used localtime(). so I don't know how to implement it in the code. Currently, in the manner it's written, it returns a bound error.
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 15 22:10:07 2015
#author: Daddy
"""
class Person ():
def __init__(self, name, birthyear):
self.name = name
self.birthyear = birthyear
def age(self, birthyear):
age = 2015 - self.birthyear
return age
def name(self):
return self.name
class Instructor(Person):
def __init__(self, name, birthyear, degree):
self.name = name
self.birthyear = birthyear
self.degree = degree
def degree(self, degree):
return (self.degree)
class Student(Person):
def __init__(self, name, birthyear, major):
self.name = name
self.birthyear = birthyear
self.major = major
def major(self, major):
return (self.major)
import datetime
def age(self):
return datetime.datetime.now().year - self.birthyear
Note you don't need to pass birthyear because it's in self, and return is the value of the called function.
Can anyone describe how to return objects from a method on which further methods and attributes can be accessed?
Example:
pizza = PizzaHut()
order = pizza.order()
print order.order_number
order.cancel()
Create an Order class with appropriate methods and properties. After that, you'll be able to return an instance of this class from PizzaHut.order() method.
class Order(object):
def __init__(self, number, amount):
self.number = number
self.amount = amount
print self
def __str__(self):
return "Order #%s: amount = %s" % (self.number, self.amount)
#property
def order_number(self):
return self.number
def cancel(self):
self.amount = 0
print "Order is cancelled."
print self
class PizzaHut(object):
def __init__(self, price):
self.price = price
def order(self):
return Order(42, self.price)
pizza = PizzaHut(4.99)
order = pizza.order()
print order.order_number
order.cancel()
http://repl.it/WWB
Python 3 version
class Order:
def __init__(self, number, amount):
self.number = number
self.amount = amount
print(self)
def __str__(self):
return f'Order #{self.number}: amount = {self.amount}'
#property
def order_number(self):
return self.number
def cancel(self):
self.amount = 0
print('Order is cancelled.')
print(self)
class PizzaHut:
def __init__(self, price):
self.price = price
def order(self):
return Order(42, self.price)
pizza = PizzaHut(4.99)
order = pizza.order()
print(order.order_number)
order.cancel()
Py3 repl: https://replit.com/#f0t0n/so-25158930#main.py
you can use Namedtuplesin in python.
# Using namedtuple is way shorter than
# defining a class manually:
>>> from collections import namedtuple
>>> Car = namedtuple('Car', 'color mileage')
# Our new "Car" class works as expected:
>>> my_car = Car('red', 3812.4)
>>> my_car.color
'red'
>>> my_car.mileage
3812.4
# We get a nice string repr for free:
>>> my_car
Car(color='red' , mileage=3812.4)
# Like tuples, namedtuples are immutable:
>>> my_car.color = 'blue'
AttributeError: "can't set attribute"
class Foo():
def f(self):
print "Foo.f called"
class Bar():
def b(self):
return Foo()
bar = Bar()
bar.b().f() # prints "Foo.f called"
class Order:
def __init__(self, number):
self.order_number = number
class PizzaHut:
def __init__(self):
self.order = Order(1234)
def order(self):
return self.order
This is how to return back the object from a method
class Order(object):
def __init__(self, number, amount):
self.number = number
self.amount = amount
def cancel(self):
self.amount = 0
return self #here you return back the object
class Artist:
def __init__(self, name, dob):
self.name = name
self.dob = dob
def get_name(self):
return self.name
def get_dob(self):
return self.dob
def age(self):
if get_date_today() < (2013, 12, 27):
return self.age
else:
return self.age + 1
def get_date_today():
return (2013, 10, 30) #'today'
hw = Artist("Hayley Williams", (1988, 12, 27))
print(hw.age()) # 24 if 'today' is < (2013, 12, 27), 25 if 'today' is >= (2013, 12, 27)
How do I do an addition in the else loop. It can't work here because I can't add 1 to the method. So what is wrong ?
from datetime import datetime
class Artist:
def __init__(self, name, dob):
self.name = name
self.dob = dob
def get_name(self):
return self.name
def get_dob(self):
return self.dob
def age(self):
return ((datetime.today() - datetime(*self.dob)).days)/365
datetime is module in python which use to perform date realted operation. datetime.today will return you current date.
You do not have a self.age variable in your __init__ loop. Try this instead:
class Artist:
def __init__(self, name, dob, age):
self.name = name
self.dob = dob
self.age = age
def get_name(self):
return self.name
def get_dob(self):
return self.dob
def get_age(self):
if get_date_today() < (2013, 12, 27):
return self.age
else:
return self.age + 1
You are trying to return an age in your method age() which you have no data about. Decide where to get that data from and store it, then you can return it in the method.
One way to achieve this is to get the data upon object construction:
def __init__(self, birthday):
self.birthday = birthday
# store also your other data like name and dob
then you can use it to compute the age:
def age(self):
if get_date_today() < (2013, 12, 27):
return get_date_today() - self.birthday
else:
return get_date_today() - self.birthday + 1
# this assumes of course that you are using a date type which understands subtraction
But there are other ways like getting the age from a data base or just returning the age given on construction (see sshashank124's answer for that).
Why does user.params() not return all the params up the inheritance
chain? -- It's not including the params defined in Person() -- notice
Vertex() does not have a params() method.
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
self.s = super(Person,self)
self.s.__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(self.s.params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
self.s = super(User,self)
self.s.__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print self.s.params()
params.update(self.s.params())
return params
In User you do:
self.s = super(User,self)
self.s.__init__(name,uri,email)
so self.s is what? As you do the same in Person, self.s is super(Person) and that anywhere, in Person and User as you reassign self.s, so the self.s.params that gets picked is the one of Element.
edit : also the following code works, Sebastians has the correct interpretation: self.s is reassigned each time in the __init__ of the classes. So self.s is reassigned as super(Person,self).
import uuid
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
print 'here Element'
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
super(Person,self).__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
print 'here Person'
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(super(Person,self).params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
super(User,self).__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print 'here User'
params.update(super(User, self).params())
return params
if __name__ == '__main__':
u = User()
print '\n'.join(sorted(u.params().keys()))