Python Forum
Calculate AGE in years
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Calculate AGE in years
#1
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
Gribouillis write Apr-24-2023, 08:03 AM:
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.
Reply
#2
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).
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
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
Reply
#4
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)))
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
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.
Reply
#6
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.
Reply
#7
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'
Reply
#8
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.
Reply
#9
Thanks I see it, type error VerhoogSalaris
Reply
#10
(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.
Gribouillis and DeaD_EyE like this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Tracking leap.py years for gregorian calendar (Exercism org) Drone4four 11 3,658 Oct-14-2022, 03:20 PM
Last Post: betinajessen
  Problem with code to calculate weekday for leap years! Event 2 2,797 Dec-15-2018, 05:13 PM
Last Post: Event
  python age calculator need to find the number of years before they turn 100 not using orangevalley 4 9,846 Mar-26-2018, 04:44 AM
Last Post: PyMan
  human years to dog years jhall710 7 11,356 May-08-2017, 05:57 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020