Finding out Age in Months and Years given DOB in a CSV using python
Question: I making several adjustments to an automatically gennerated CSV report. I am
currently stuck on a part where I need to take a patient's DOB and convert
that into an Age in Months and Years. There is already a Column for age in the
original CSV, and I've figured out how to convert the data in the DOB Column
to find the Age in Days, however, I need to be able to convert that to
Months/years and then also take that calculated value and replace the value in
the current field. The current field is a hand-typed string which has no real
consistent formattin. The actual CSV has about 1700 rows and 18 column, and
uses the standard comma to separate them, so I'm just makign up a shorter form
for an example, and using indents to make it easier to see:

    
    
    Last_Name   First_Name   MI   age                 DOB          SSN         visit_date
    Stalone     Frank        P    62yrs 10 months     07-30-1950   123456789   05-02-2013
    Astley      Richard      P    47years3mo          02-06-1966   987654321   05-03-2013
    

What I want should look like this:

    
    
    Last_Name   First_Name   MI   Age       DOB          SSN
    Stalone     Frank        P    62y10mo   07-30-1950   123456789
    Astley      Richard      P    47y3mo    02-06-1966   987654321
    

EDIT: I realized I could jsut use the date.year and date.month to jsut
subtract year and month, making those values much easier to find. I'm editing
my code now and will update it when I got it working, btu I'm still having
trouble wiht the second part of my question.

My code so far:

    
    
    import re
    import csv
    import datetime
    
    with open(inputfile.csv','r') as fin, open(outputfile.csv','w') as fout:
       reader = csv.DictReader(fin)
       fieldnames = reader.fieldnames
       writer_clinics = csv.DictWriter(fout, fieldnames, dialect="excel")
       writer_clinics.writeheader()
    
       for row in reader:
        data = next(reader)
        today = datetime.date.today()
        DOB = datetime.datetime.strptime(data["DOB"], "%m/%d/%Y").date()
    age_y = (today.year - DOB.year)
    age_m = (today.month - DOB.month)
    
    if age_m < 0:
        age_y = age_y - 1
        age_m = age_m + 12
    
    age = str(age_y) + " y " + str(age_m) + " mo "
    print (age)
    

So, I'm tryign to figure out how to write the age into the correct field in
the outputfile.csv?

Update 2: Managed to get most of it to write, however, it is having errors
with certain fields being left empty in the input file. My boss also wanted me
to make the age, dependant ont he actual date of the appointment. my current
chunk of code:

    
    
    import re
    import csv
    import datetime
    
    def getage(visit, dob):
        years = visit.year - dob.year
        months = visit.month - dob.month
        if visit.day < dob.day:
            months -= 1
        if months < 0:
            months += 12
            years -= 1
        return '%sy%smo'% (years, months)
    
    with open('inputfile.csv','r') as fin, open('outputfile.csv','w') as fout:
        reader = csv.DictReader(fin)
        writer_clinics = csv.DictWriter(fout, reader.fieldnames, dialect="excel")
        writer_clinics.writeheader()
    
        for data in reader:
            visit_date = datetime.strptime(data["visit_date"], "%m-%d-%Y").date()
            DOB = datetime.datetime.strptime(data["DOB"], "%m-%d-%Y").date()
            data["Age"] = getage(visit_date, DOB)
            writer_clinics.writerow(data)
    


Answer: You can't convert days into years and months, since years and months have
different numbers of days in them. You need to take the differences of the
years and months themselves.

    
    
    dob = datetime.datetime.strptime('07-30-1950', '%m-%d-%Y')
    now = datetime.datetime.now()
    years = now.year - dob.year
    months = now.month - dob.month
    if now.day < dob.day:
        months -= 1
    while months < 0:
        months += 12
        years -= 1
    age = '{}y{}mo'.format(years, months)
    
    >>> print age
    62y9mo
    

