diff --git a/FEEDBACK.md b/FEEDBACK.md index 010fecd..f2b4865 100644 --- a/FEEDBACK.md +++ b/FEEDBACK.md @@ -1,13 +1,10 @@ # Feedback -1. Your team: -2. Name of each individual participating: -3. How many unit tests were you able to pass? +1. Your team: Lonewolf +2. Name of each individual participating: Anthony Ham +3. How many unit tests were you able to pass? 12 4. Document and describe any enhancements included to help the judges properly grade your submission. - - Example One - - Example Two - - Example Three - + - Unforunately I was not able to past the last challenge. 5. Any feedback for the coding competition? Things you would like to see in future events? This form can also be emailed to [codingcompetition@statefarm.com](mailto:codingcompetition@statefarm.com). Just make sure that you include a link to your GitHub pull requests. diff --git a/python/simple_data_tool.py b/python/simple_data_tool.py index 5391073..51a351f 100644 --- a/python/simple_data_tool.py +++ b/python/simple_data_tool.py @@ -2,6 +2,8 @@ import math from statistics import mean +from datetime import datetime, timedelta + @@ -59,6 +61,13 @@ def get_num_closed_claims(self): Returns: int: number of closed claims """ + closed_claims = 0 + + for object in self.get_claim_data(): + if object["status"] == "Closed": + closed_claims += 1 + + return closed_claims pass def get_num_claims_for_claim_handler_id(self, claim_handler_id): @@ -70,6 +79,13 @@ def get_num_claims_for_claim_handler_id(self, claim_handler_id): Returns: int: number of claims assigned to claim handler """ + + claims_assigned = 0 + + for object in self.get_claim_data(): + if object["claim_handler_assigned_id"] == claim_handler_id: + claims_assigned += 1 + return claims_assigned pass def get_num_disasters_for_state(self, state): @@ -82,6 +98,13 @@ def get_num_disasters_for_state(self, state): Returns: int: number of disasters for state """ + + state_disasters = 0 + + for object in self.get_disaster_data(): + if object["state"] == state: + state_disasters += 1 + return state_disasters pass # endregion @@ -98,7 +121,15 @@ def get_total_claim_cost_for_disaster(self, disaster_id): float | None: estimate cost of disaster, rounded to the nearest hundredths place returns None if no claims are found """ - + + damage_costs = 0 + + for object in self.get_claim_data(): + if object["disaster_id"] == disaster_id: + damage_costs += object["estimate_cost"] + + if damage_costs == 0: return None + return damage_costs pass def get_average_claim_cost_for_claim_handler(self, claim_handler_id): @@ -111,7 +142,17 @@ def get_average_claim_cost_for_claim_handler(self, claim_handler_id): float | None : average cost of claims, rounded to the nearest hundredths place or None if no claims are found """ - + + total_cost = 0 + num_claims = 0 + + for object in self.get_claim_data(): + if object["claim_handler_assigned_id"] == claim_handler_id: + total_cost += object["estimate_cost"] + num_claims += 1 + + if num_claims == 0: return None + return round(total_cost / num_claims, 2) pass def get_state_with_most_disasters(self): @@ -127,6 +168,36 @@ def get_state_with_most_disasters(self): Returns: string: single name of state """ + d = {} + disaster_count = 0 + state = "" + states = [] + + # count the amount of disasters occured per state + for object in self.get_disaster_data(): + if object["state"] in d: + d[object["state"]] += 1 + else: + d[object["state"]] = 1 + + + + # find the highest amount of disasters recorded + for key, value in d.items(): + if value > disaster_count: + disaster_count = value + state = key + + states.append(state) + print(state) + + # if multiple states contain same amount, we add to list, sort, and return first + for key, value in d.items(): + if value == disaster_count and key != state: + states.append(key) + + if len(states) > 1: states.sort() + return states[0] pass def get_state_with_least_disasters(self): @@ -142,6 +213,36 @@ def get_state_with_least_disasters(self): Returns: string: single name of state """ + d = {} + disaster_count = 100000 + state = "" + states = [] + + # count the amount of disasters occured per state + for object in self.get_disaster_data(): + if object["state"] in d: + d[object["state"]] += 1 + else: + d[object["state"]] = 1 + + + + # find the least amount of disasters recorded + for key, value in d.items(): + if value < disaster_count: + disaster_count = value + state = key + + states.append(state) + print(state) + + # if multiple states contain same amount, we add to list, sort, and return first + for key, value in d.items(): + if value == disaster_count and key != state: + states.append(key) + + if len(states) > 1: states.sort() + return states[0] pass def get_most_spoken_agent_language_by_state(self, state): @@ -154,6 +255,35 @@ def get_most_spoken_agent_language_by_state(self, state): string: name of language or empty string if state doesn't exist """ + + most_spoken_languages = {} + count = 0 + language = "" + + for object in self.get_agent_data(): + if object["state"] == state: + + # primary spoken language that is not english + if object["primary_language"] != "English": + if object["primary_language"] in most_spoken_languages: + most_spoken_languages[object["primary_language"]] += 1 + else: + most_spoken_languages[object["primary_language"]] = 1 + + # secondary spoken language that is not english + if object["secondary_language"] != "English": + if object["secondary_language"] in most_spoken_languages: + most_spoken_languages[object["secondary_language"]] += 1 + else: + most_spoken_languages[object["secondary_language"]] = 1 + + + for key, value in most_spoken_languages.items(): + if value > count: + count = value + language = key + + return language pass def get_num_of_open_claims_for_agent_and_severity(self, agent_id, min_severity_rating): @@ -170,7 +300,26 @@ def get_num_of_open_claims_for_agent_and_severity(self, agent_id, min_severity_r -1 if severity rating out of bounds None if agent does not exist, or agent has no claims (open or not) """ - + + if min_severity_rating < 1 or min_severity_rating > 10: return -1 + agent_exists = False + open_claims = 0 + total_claims = 0 + + for object in self.get_claim_data(): + + # calculate open claims under restriction + if object["agent_assigned_id"] == agent_id and object["severity_rating"] >= min_severity_rating and object["status"] != "Closed": + agent_exists = True + open_claims += 1 + + # calculate total claims no restriction + if object["agent_assigned_id"] == agent_id: + total_claims += 1 + + if agent_exists == False: return None + if total_claims == 0: return None + return open_claims pass # endregion @@ -183,7 +332,20 @@ def get_num_disasters_declared_after_end_date(self): Returns: int: number of disasters where the declared date is after the end date """ - + + total = 0 + + for object in self.get_disaster_data(): + end_date = object["end_date"].split("-") + end_date_ref = datetime(int(end_date[0]), int(end_date[1]), int(end_date[2])) + + declared_date = object["declared_date"].split("-") + declared_date_ref = datetime(int(declared_date[0]), int(declared_date[1]), int(declared_date[2])) + + if declared_date_ref > end_date_ref: total += 1 + + + return total pass def build_map_of_agents_to_total_claim_cost(self): @@ -197,7 +359,25 @@ def build_map_of_agents_to_total_claim_cost(self): Returns: dict: key is agent id, value is total cost of claims associated to the agent """ - + + agents_costs = {} + + # setup map with agents + for object in self.get_agent_data(): + agents_costs[object["id"]] = 0 + + # sum up agent costs. if not found, set to none + for object in self.get_claim_data(): + if object["agent_assigned_id"] in agents_costs: + agents_costs[object["agent_assigned_id"]] += object["estimate_cost"] + else: + agents_costs[object["agent_assigned_id"]] = None + + # round all sums + for key, value in agents_costs.items(): + agents_costs[key] = round(value, 2) + + return agents_costs pass def calculate_disaster_claim_density(self, disaster_id): @@ -214,6 +394,18 @@ def calculate_disaster_claim_density(self, disaster_id): float: density of claims to disaster area, rounded to the nearest thousandths place None if disaster does not exist """ + disaster = next((d for d in self.get_disaster_data() if d['id'] == disaster_id), None) + if not disaster: return None + + radius = disaster['radius_miles'] + + claims = [claim for claim in self.get_claim_data() if claim['disaster_id'] == disaster_id] + + density = len(claims) / (math.pi * radius**2) + + density_rounded = round(density, 5) + + return density_rounded pass # endregion @@ -221,10 +413,7 @@ def calculate_disaster_claim_density(self, disaster_id): # region TestSetFour def get_top_three_months_with_highest_num_of_claims_desc(self): - """Gets the top three months with the highest number of claims - - OPTIONAL! OPTIONAL! OPTIONAL! - AS OF 9:21CDT, TEST IS OPTIONAL. SEE GITHUB ISSUE #8 FOR MORE DETAILS + """Gets the top three months with the highest total claim cost Hint: Month should be full name like 01 is January and 12 is December @@ -234,7 +423,31 @@ def get_top_three_months_with_highest_num_of_claims_desc(self): Returns: list: three strings of month and year, descending order of highest claims """ - + + def custom_sort(item): + month, year = item.split() + return (int(year), month_order[month]) + + month_order = {"January": 1, "February": 2, "March": 3, "April": 4, "May": 5, "June": 6,"July": 7, "August": 8, "September": 9, "October": 10, "November": 11, "December": 12} + + total_claim_by_month = {} + + # Iterate through the claims data + for claim in self.get_claim_data(): + disaster_id = claim.get("disaster_id") + hazard = next((h for h in self.get_disaster_data() if h.get("id") == disaster_id), None) + + if hazard: + start_date = datetime.strptime(hazard["start_date"], "%Y-%m-%d") + month_year_key = start_date.strftime("%m-%Y") + total_claim_by_month[month_year_key] = total_claim_by_month.get(month_year_key, 0) + claim["estimate_cost"] + + sorted_months = sorted(total_claim_by_month.items(), key=lambda x: (x[1], datetime.strptime(x[0], "%m-%Y")), reverse=True) + top_three_months = sorted_months[:3] + result = [datetime.strptime(month_year, "%m-%Y").strftime("%B %Y") for month_year, _ in top_three_months] + print(sorted(result, key=custom_sort, reverse=True)) + + return sorted(result, key=custom_sort, reverse=True) pass - # endregion + # endregion \ No newline at end of file