Posts: 24
Threads: 5
Joined: Apr 2023
Apr-24-2023, 07:31 AM
(This post was last modified: Apr-24-2023, 08:03 AM by Gribouillis.)
Hello
I want to try to calculate the age in years but in de output i get 1 day instead of 1 year
from datetime import datetime, date
class persoon:
def __init__(self, naam, sekse, geboortedatum):
self.naam = naam
self.sekse = sekse
self.geboortedatum = datetime.strptime(geboortedatum, '%d-%m-%Y').date()
def getNaam(self):
return self.naam
def getGebDatum(self):
return self.geboortedatum
def isVrouw(self):
if self.sekse == "V":
return True
else:
return False
def isMan(self):
if self.sekse == "M":
return True
else:
return False
def leeftijd(self):
today = date.today()
age = (today - self.geboortedatum) // 365
return age
p1 = persoon("John", "M", "24-04-2022")
print(p1.getNaam(), p1.leeftijd()) Output
John 1 day, 0:00:00
What I want is
John 1 Year
Posts: 2,128
Threads: 11
Joined: May 2017
You can't do this. A normal year has 364 days and a leap year has 365 days.
Calculate instead the years and not the timedelta.
import datetime
import calendar
# today = datetime.date.today()
today = datetime.date(2000, 2, 29)
bday = datetime.date(1984, 2, 29)
years = today.year - bday.year
# correct the bday, if it's the 29th february and today is not a leap yaar
if bday.month == 2 and bday.day == 29 and not calendar.isleap(today.year):
bday = datetime.date(bday.year, 3, 1)
# check if today earlier than birthday
if (today.month, today.day) < (bday.month, bday.day):
years -= 1
# today it's not the birthday, so one year lesser
print(years) Improvement of your class:
class Persoon:
def __init__(self, naam, sekse, geboortedatum):
self._naam = naam
self._sekse = sekse
self._geboortedatum = datetime.strptime(geboortedatum, "%d-%m-%Y").date()
@property
def naam(self):
return self._naam
@property
def geb_datum(self):
return self._geboortedatum
@property
def vrouw(self):
return self._sekse == "V"
@property
def man(self):
return self._sekse == "M"
def leeftijd(self, today=None):
today = today or date.today()
years = today.year - self.geb_datum.year
geboortedatum = self.geb_datum
# leap fix 29 feb.
if (
geboortedatum.month == 2
and geboortedatum.day == 29
and not isleap(today.year)
):
geboortedatum = date(geboortedatum.year, 3, 1)
if (today.month, today.day) < (self.geb_datum.month, self.geb_datum.day):
years -= 1
return years
p1 = Persoon("John", "M", "29-2-1980")
# 2023 is not a leap year
print(p1.naam, p1.leeftijd(date(2023, 3, 1))) The properties are read-only.
leeftijd() is still a method, but now you can also set today (better for testing).
Posts: 24
Threads: 5
Joined: Apr 2023
When i try the Improvement of your class then I get the following erors
3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)]
Python Type "help", "copyright", "credits" or "license" for more information.
[evaluate Objectgeoriënteerd programmeren_FeedackVraag4a.py]
Traceback (most recent call last):
File "C:\Python\Objectgeoriënteerd programmeren_FeedackVraag4a.py", line 42, in <module>
p1 = Persoon("John", "M", "29-2-1980")
File "C:\Python\Objectgeoriënteerd programmeren_FeedackVraag4a.py", line 5, in <module>
self._geboortedatum = datetime.strptime(geboortedatum, "%d-%m-%Y").date()
builtins.NameError: name 'datetime' is not defined
Posts: 2,128
Threads: 11
Joined: May 2017
You still need to import the classes datetime and date .
Also calendar.isleap .
from calendar import isleap
from datetime import datetime, date
class Persoon:
def __init__(self, naam, sekse, geboortedatum):
self._naam = naam
self._sekse = sekse
self._geboortedatum = datetime.strptime(geboortedatum, "%d-%m-%Y").date()
@property
def naam(self):
return self._naam
@property
def geb_datum(self):
return self._geboortedatum
@property
def vrouw(self):
return self._sekse == "V"
@property
def man(self):
return self._sekse == "M"
def leeftijd(self, today=None):
today = today or date.today()
years = today.year - self.geb_datum.year
geboortedatum = self.geb_datum
# leap fix 29 feb.
if (
geboortedatum.month == 2
and geboortedatum.day == 29
and not isleap(today.year)
):
geboortedatum = date(geboortedatum.year, 3, 1)
if (today.month, today.day) < (self.geb_datum.month, self.geb_datum.day):
years -= 1
return years
p1 = Persoon("John", "M", "29-2-1980")
# 2023 is not a leap year
print(p1.naam, p1.leeftijd(date(2023, 3, 1)))
Posts: 24
Threads: 5
Joined: Apr 2023
Apr-24-2023, 06:05 PM
(This post was last modified: Apr-24-2023, 06:06 PM by deanhystad.)
Other question, I try to make a sub classes and when there is no argument then value 0
But get the following error
from datetime import datetime, date
class persoon:
def __init__(self, naam, sekse, geboortedatum):
self.naam = naam
self.sekse = sekse
self.geboortedatum = datetime.strptime(geboortedatum, '%d-%m-%Y').date()
def getNaam(self):
return self.naam
def getGebDatum(self):
return self.geboortedatum
def isVrouw(self):
if self.sekse == "V":
return True
else:
return False
def isMan(self):
if self.sekse == "M":
return True
else:
return False
def leeftijd(self):
today = date.today()
age = (today.year - self.geboortedatum.year)
return age
class Docent(persoon):
def __init__(self, naam, sekse, geboortedatum,*Salaris):
if(Salaris==None):
self.Salaris = "0"
else:
self.Salaris = Salaris
d1 = Docent("John", "M", "24-04-2000")
print(d1.naam) Error: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)]
Python Type "help", "copyright", "credits" or "license" for more information.
[evaluate Objectgeoriënteerd programmeren_FeedackVraag4.py]
Traceback (most recent call last):
File "C:\Python\Objectgeoriënteerd programmeren_FeedackVraag4.py", line 43, in <module>
print(d1.naam)
builtins.AttributeError: 'Docent' object has no attribute 'naam'
deanhystad write Apr-24-2023, 06:06 PM:Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Posts: 6,819
Threads: 20
Joined: Feb 2020
When you subclass and the superclass has an __init__ method, the subclass needs to call the __init__ method for the superclass. The best way to do that is use super().
class Docent(persoon):
def __init__(self, naam, sekse, geboortedatum,*Salaris):
super().__init__(naam, seksa, geboortedatum)
if(Salaris==None):
self.Salaris = "0"
else:
self.Salaris = Salaris You are not handling the optional Salaris argument correctly.
class Docent(persoon):
def __init__(self, naam, sekse, geboortedatum, Salaris=0):
super().__init__(naam, seksa, geboortedatum)
self.Salaris = Salaris Your __init__() method made Python think Solaris was a list of positional arguments following geboortedatum when what you really want is an argument where the user has to option of providing an argument value, or using the default value.
Posts: 24
Threads: 5
Joined: Apr 2023
Great Thanks for your help !!!
Now I get the following error , can you please help me !!
from datetime import datetime, date
class persoon:
def __init__(self, naam, sekse, geboortedatum):
self.naam = naam
self.sekse = sekse
self.geboortedatum = datetime.strptime(geboortedatum, '%d-%m-%Y').date()
def getNaam(self):
return self.naam
def getGebDatum(self):
return self.geboortedatum
def isVrouw(self):
if self.sekse == "V":
return True
else:
return False
def isMan(self):
if self.sekse == "M":
return True
else:
return False
def leeftijd(self):
today = date.today()
age = (today.year - self.geboortedatum.year)
return age
class Docent(persoon):
def __init__(self, naam, sekse, geboortedatum, Salaris=0):
super().__init__(naam, sekse, geboortedatum)
self.Salaris = Salaris
def setSalaris(self, SalarisInput):
self.Salaris = SalarisInput
def getSalaris(self):
return self.Salaris
def VerhoogSalaris(self, percentage):
return self.Salaris * percentage
d1 = Docent("Marcella", "V", "24-04-2000")
print(d1.getNaam(), d1.leeftijd(), d1.isVrouw(),d1.getSalaris())
d1.setSalaris(2500)
print(d1.getSalaris)
d1.verhoogSalaris(5)
print(d1.getSalaris()) Error: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)]
Python Type "help", "copyright", "credits" or "license" for more information.
[evaluate Objectgeoriënteerd programmeren_FeedackVraag5.py]
Marcella 23 True 0
<bound method Docent.getSalaris of <__main__.Docent object at 0x00000000036CA390>>
Traceback (most recent call last):
File "C:\Python\Objectgeoriënteerd programmeren_FeedackVraag5.py", line 52, in <module>
d1.verhoogSalaris(5)
builtins.AttributeError: 'Docent' object has no attribute 'verhoogSalaris'
Posts: 6,819
Threads: 20
Joined: Feb 2020
Apr-24-2023, 07:20 PM
(This post was last modified: Apr-24-2023, 11:34 PM by deanhystad.)
Read the error message carefully. There is no Docent.verhoogSalaris() method.
Don't do this:
def isMan(self):
if self.sekse == "M":
return True
else:
return False Do this:
def isMan(self):
return self.sekse == "M" Think about how to solve the problem. Think about how to translate the solution to code. When the code is written, review and think about your code. In this case, you have a comparison that returns True or False. Does it make sense to check if the comparison is True and then return True? The if-else is extra code. Don't write extra code.
I don't like this either:
def setSalaris(self, SalarisInput):
self.Salaris = SalarisInput Why did you write this? The user can access the attribute directly. What is added by writing this extra code?
Your age calculation is wrong. If I was born July 6, 2000, am I 23 years old today (April 24, 2023)? Your code says I am. I don't agree. Look at DeaD_EyE's year calculation that takes month and day into account.
Posts: 24
Threads: 5
Joined: Apr 2023
Thanks I see it, type error VerhoogSalaris
Posts: 8,168
Threads: 160
Joined: Sep 2016
(Apr-24-2023, 09:46 AM)DeaD_EyE Wrote: A normal year has 364 days and a leap year has 365 days. Obvious mistake, but nevertheless 365 days in "normal" year and 366 days in leap year.
DeaD_EyE and Gribouillis like this post
|