def get_birthdays(import_id): database = get_db() # get list of citizens for particular import try: citizens = database[import_id]['citizens'] except KeyError: return tools.error(f'import {import_id} not found'), 400 # create dictionary for output months = {key: [] for key in range(1, 12 + 1)} for citizen in citizens: for relative in citizen['relatives']: # recipient is person who receives the gift recipient = [ item for item in citizens if item['citizen_id'] == relative ][0] birthday = datetime.strptime(recipient['birth_date'], '%d.%m.%Y') # giver is person who gives a gift try: # if dict for a particular giver already exists giver = [ item for item in months[birthday.month] if item['citizen_id'] == citizen['citizen_id'] ][0] giver['presents'] += 1 except IndexError: # create dict for a particular giver giver = {'citizen_id': citizen['citizen_id'], 'presents': 1} months[birthday.month].append(giver) return {'data': months}, 200
def get_citizens(import_id: int) -> (dict, int): """Gets list of citizens for particular import. :param import_id: the ID of import. :return: list of citizens and status code. """ database = get_db() try: return {'data': database[import_id]['citizens']}, 200 except KeyError: return tools.error(f'import {import_id} not found'), 400
def get_statistics(import_id): database = get_db() # get list of citizens for particular import try: citizens = database[import_id]['citizens'] except KeyError: return tools.error(f'import {import_id} not found'), 400 # create list of all towns from import towns = list(set([citizen['town'] for citizen in citizens])) # create dict for every town data = [{'town': town, 'ages': []} for town in towns] for citizen in citizens: # calculate age try: birth_date = datetime.strptime(citizen['birth_date'], '%d.%m.%Y') age = tools.calculate_age(birth_date) except ValueError: return tools.error('birth_date is not valid'), 400 # get dict for particular town town_statistics = [ item for item in data if item['town'] == citizen['town'] ][0] index = data.index(town_statistics) # add age town_statistics['ages'].append(age) # apply changes data[index] = town_statistics # count percentiles for town_statistics in data: ages = town_statistics.pop('ages') for percent in [50, 75, 99]: town_statistics[f'p{percent}'] = tools.percentile(ages, percent) return {'data': data}, 200
def create_import() -> (dict, int): """Creates a new import. :return: import identifier and status code """ data = request.get_json() if not data: return tools.error('invalid json'), 400 invalid_payload = tools.validate_payload(data['citizens']) if invalid_payload: return invalid_payload database = get_db() try: import_id = int(list(database.keys())[-1]) + 1 except IndexError: import_id = 1 data['import_id'] = import_id database[import_id] = data return {'data': {'import_id': import_id}}, 201
def update_citizen(import_id: int, citizen_id: int) -> (dict, int): """Updates citizen information. :param import_id: the ID of import. :param citizen_id: the ID of citizen. :return: updated information and status code. """ data = request.get_json() if not data: return tools.error('invalid json'), 400 database = get_db() # find import to update try: citizens = database[import_id]['citizens'] except KeyError: return tools.error(f'import {import_id} not found'), 400 # find particular citizen and its index try: citizen = [ citizen for citizen in citizens if citizen['citizen_id'] == citizen_id ][0] index = citizens.index(citizen) except IndexError: return tools.error(f'invalid citizen_id: {citizen_id}'), 400 # forbid citizen_id changing if data.get('citizen_id'): return tools.error('citizen_id cannot be changed'), 400 fields_to_update = [] new_relatives, old_relatives = [], [] for field in data.keys(): # if relatives are changed if data.get('relatives') is not None and \ isinstance(data.get('relatives'), list): old_relatives = citizen['relatives'] new_relatives = data['relatives'] if not len(new_relatives) == len(set(new_relatives)): return tools.error('invalid relatives'), 400 if data.get(field) is not None: fields_to_update.append(field) citizen[field] = data[field] # apply changes to citizen citizens[index] = citizen # modify relatives for relative in list(set(old_relatives + new_relatives)): if relative in new_relatives and relative in old_relatives: pass elif relative in new_relatives and relative not in old_relatives: new_relative = [ item for item in citizens if item['citizen_id'] == relative ][0] index = citizens.index(new_relative) if citizen_id not in new_relative['relatives']: new_relative['relatives'].append(citizen_id) citizens[index] = new_relative elif relative in old_relatives and relative not in new_relatives: old_relative = [ item for item in citizens if item['citizen_id'] == relative ][0] index = citizens.index(old_relative) if citizen_id in old_relative['relatives']: old_relative['relatives'].remove(citizen_id) citizens[index] = old_relative invalid_payload = tools.validate_payload(citizens, fields_to_update) if invalid_payload: return invalid_payload database[import_id] = {'citizens': citizens, 'import_id': import_id} return {'data': citizen}, 200