Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help Fix My Function
#1
Hi All,

I am new to python and have a number of csv files and am trying to get the count of people who have died and suffered a fall or died and not suffered a fall. I also am trying to work out the average age people lived with each of the above conditions but am having issues tweaking a function. The function in the code below is def is65, I have underlined the relevant aspects below. The function currently subtracts DOB from current date to work out the age, what I am trying to do is to subtract the DOB from the DOD instead. The DOD is from a csv file named DEATHREG (I have also bolded and underlined), problem is no matter how I try to reference the DOD in def is65 it does not work. Any help will be welcome
import csv
from datetime import datetime

def get_years(delta_in):
    """Get years from timedelta"""
    return delta_in.days / 365.25

class PersonData(object):
    def __init__(self, dem_data):
        """Initialize person data with dictionary of demographic data from GP_DEM.csv
        :param dem_data: dict
        """
        self.data = dict()
        # clinical events
        self.clin = []
        # hospital events
        self.hosp = []
        self.list_names = {'GP_CLIN': self.clin, 'HOSPDAT': self.hosp}
        # initialize data with dictionary provided
        self.add_data(dem_data)
        # first fall event will be written here
        self.first_fall_event = None
    def is65(self):
        """Return True if the person is older than 65 years"""
        return get_years(cur_datetime - all_persons[patid].data['DOB']) > 65
    def get_first_fall_event_date(self):
        """Get datetime of the first fall event if exists"""
        if self.first_fall_event:
            return self.first_fall_event
        fall_events = []
        # iterate through all events
        for hosp_event in self.hosp:
            # check for event code
            event_code = hosp_event['EVENT_CODE']
            if event_code[:3] in fall_event_codes:
                # if fall event, append to the temporary list of fall events
                fall_events.append(hosp_event['EVENT_DATE'])
        if fall_events:  # if found:
            # first date of fall events
            first_event = sorted(fall_events)[0]
            self.first_fall_event = first_event
            return first_event
        # if not found:
        return False
    def add_data(self, data_dict, keys_to_add=None, list_name=''):
        """Add data to this object's dataset"""
        # check for necessary keys to add
        if keys_to_add:
            new_data = {key: value for key, value in data_dict.items() if key in keys_to_add}
        else:
            new_data = data_dict
        # converting date to datetime format
        for date_code in ['EVENT_DATE', 'DOB', 'DOD']:
            if date_code in new_data:
                new_data[date_code] = datetime.strptime(new_data[date_code], '%Y-%m-%d %H:%M:%S')
        # if data should go to the list:
        if list_name:
            if list_name in self.list_names:
                self.list_names[list_name].append(new_data)
        # if data goings to the dictionary
        else:
            self.data.update(new_data)

def add_data_from_csv(file_name, keys_to_add=None, list_name=''):
    """Add data from certain csv file to all_persons dictionary
    :param file_name: str
    :param keys_to_add: list
    :param list_name: str
    """
    global all_persons
    with open(file_name) as input_file:
        input_csv = csv.DictReader(input_file, delimiter=',')
        # iterating through all lines in csv file
        for line in input_csv:
            patid = get_patid(line['PATID'])
            if patid in all_persons:
                all_persons[patid].add_data(line, keys_to_add=keys_to_add, list_name=list_name)
            else:
                # if PATID not found, do nothing
                pass

with open('GP_DEM.csv') as input_file:
    input_csv = csv.DictReader(input_file, delimiter=',')
    # all persons data dictionary {PATID1: PersonData1, ...}
    all_persons = {line['PATID']: PersonData(line) for line in input_csv}

add_data_from_csv('DEATHREG.csv', ['DOD', 'CAUSE'])
add_data_from_csv('GP_CLIN.csv', ['GPID', 'EVENT_DATE', 'EVENT_CODE', 'EVENT_DATA'], list_name='GP_CLIN')
add_data_from_csv('HOSPDAT.csv', ['HOSPID', 'EVENT_DATE', 'EVENT_CODE'], list_name='HOSPDAT')

# {PATID: [years before first fall event, years after the first}
patid_years = dict()
for patid in all_persons:
    person = all_persons[patid]
    # use only persons with ages > 65 years
    if not person.is65():
        continue
    # get first fall event date-time
    first_event = person.get_first_fall_event_date()
    # if no fall events, use other persons
    if not first_event:
        continue
    # if person died
    if 'DOD' in person.data:
        years_after = get_years(person.data['DOD'] - first_event)
    else:  # if not died, use current date
        years_after = get_years(cur_datetime - first_event)
    # get years before the first fall event
    years_before = get_years(first_event - person.data['DOB'])
    # {PATID: [years before first fall event, years after the first}
    patid_years[patid] = [years_before, years_after]
print('2)a) Counting how many persons:')
no_falls = 0
with_falls = 0
# iterate through all persons
for patid in all_persons:
    person = all_persons[patid]
    # check if person is 65 years old, if died, and without fall events
    if person.is65() and ('DOD' in person.data):
        if not person.get_first_fall_event_date():
            no_falls += 1
        else:
            with_falls += 1
print('i. The person is over the age of 65 years old, has died and DID NOT suffer a fall event:')
print(no_falls)
print('ii. The person is over the age of 65 years old, has died and HAS suffer at least one fall event in their life:')
print(with_falls)
Reply
#2
(Nov-23-2016, 07:25 PM)PietonNewbie Wrote: problem is no matter how I try to reference the DOD in def is65 it does not work
Can you reproduce your problem with <20 lines of code, an example (short) CSV file, zero globals, and more detail on what the expected vs. actual results are beyond "it does not work"?
Reply
#3
Why are you referencing all_persons[patid].data['DOB']? Why not reference self.data['DOB']?
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

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