diff --git a/FEEDBACK.md b/FEEDBACK.md index 010fecd..7480505 100644 --- a/FEEDBACK.md +++ b/FEEDBACK.md @@ -1,13 +1,13 @@ # Feedback -1. Your team: -2. Name of each individual participating: -3. How many unit tests were you able to pass? +1. Your team: September 23 Squad +2. Name of each individual participating: Andy Vu, Andrew Boban +3. How many unit tests were you able to pass? 13 4. Document and describe any enhancements included to help the judges properly grade your submission. - - Example One - - Example Two - - Example Three + Changed the return values for some of the float methods to double to increase precision. 5. Any feedback for the coding competition? Things you would like to see in future events? + The inclusion of more languages would definitely be something I would like to see. Specifically, C++ is a language I would like to see in future competitions, since + it is my main programming language. 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/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/controller/SimpleDataTool.java b/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/controller/SimpleDataTool.java index d056ad0..78f3c40 100644 --- a/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/controller/SimpleDataTool.java +++ b/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/controller/SimpleDataTool.java @@ -1,5 +1,8 @@ package com.statefarm.codingcompetition.simpledatatool.controller; +import java.sql.Date; +import java.time.LocalDate; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,7 +61,13 @@ public List getDisasters() { * @return number of closed claims */ public int getNumClosedClaims() { - return 0; + int closedClaims = 0; + + for(int i = 0; i < claims.size(); i++) { + if(claims.get(i).getStatus().equals("Closed")) closedClaims++; + } //this loops through the claims list and increments the closedClaims int if the status of the claim is equal to "Closed". + + return closedClaims; } /** @@ -68,7 +77,11 @@ public int getNumClosedClaims() { * @return number of claims assigned to claim handler */ public int getNumClaimsForClaimHandlerId(int id) { - return 0; + int handlerClaims = 0; + for(int i = 0; i < claims.size(); i++) { + if(claims.get(i).getClaim_handler_assigned_id() == id) handlerClaims++; + } //this loops through the claims list, and if the handler id is the same as the id parameter, it increments handlerClaims. + return handlerClaims; } /** @@ -79,7 +92,11 @@ public int getNumClaimsForClaimHandlerId(int id) { * @return number of disasters for state */ public int getNumDisastersForState(String stateName) { - return -1; + int stateDisasters = 0; + for(int i = 0; i < disasters.size(); i++) { + if(disasters.get(i).getState().equals(stateName)) stateDisasters++; + } //this iterates through the disasters list, and if the disaster state is equal to the stateName parameter, it increments stateDisasters. + return stateDisasters; } // endregion @@ -93,8 +110,20 @@ public int getNumDisastersForState(String stateName) { * @return estimate cost of disaster, rounded to the nearest hundredths place * returns null if no claims are found */ - public Float getTotalClaimCostForDisaster(int id) { - return -0.01f; + public Double getTotalClaimCostForDisaster(int id) { //changed return value from float to double + double totalCost = 0.00; + int totalClaims = 0; + for(int i = 0; i < claims.size(); i++) { + if(claims.get(i).getDisaster_id() == id) { + totalCost += claims.get(i).getEstimate_cost(); + totalClaims++; + } + } + /* + This for loop iterates through the claims list. If the disaster id of the claim is equal to the id parameter, it adds the estimate cost the claim to the total cost. + */ + if(totalClaims == 0) return null; //if there were no claims, return null. + return totalCost; } /** @@ -104,8 +133,21 @@ public Float getTotalClaimCostForDisaster(int id) { * @return average cost of claims, rounded to the nearest hundredths place, * or null if no claims are found */ - public Float getAverageClaimCostforClaimHandler(int id) { - return -0.01f; + public Double getAverageClaimCostforClaimHandler(int id) { + double averageClaim = 0.00; + int totalClaims = 0; + for(int i = 0; i < claims.size(); i++) { + if(claims.get(i).getClaim_handler_assigned_id() == id) { + averageClaim += claims.get(i).getEstimate_cost(); + totalClaims++; + } + } + /* + this iterates through the claims list, and if the handler id of the claim is equal to id parameter, it adds the estimate cost of claim to the total cost. + also increments totalClaims. + */ + if(totalClaims == 0) return null; + return averageClaim / totalClaims; //return the total cost divided by the number of claims } /** @@ -121,7 +163,24 @@ public Float getAverageClaimCostforClaimHandler(int id) { * @return single name of state */ public String getStateWithTheMostDisasters() { - return null; + HashMap map = new HashMap<>(); //create a hash map with the state being the key and the number of disasters being the value + int maxDisasters = Integer.MIN_VALUE; + String state = null; + for(int i = 0; i < disasters.size(); i++) { + if(!map.containsKey(disasters.get(i).getState())) map.put(disasters.get(i).getState(), 0); //if state not in map, yet, set state disaster to 0. + else map.put(disasters.get(i).getState(), map.get(disasters.get(i).getState()) + 1); //increment state disaster + } + for(Map.Entry entry : map.entrySet()) { + if(entry.getValue() > maxDisasters) { //goes through the map, and if the value of the entry is greater than the max value, change the state and max value. + state = entry.getKey(); + maxDisasters = entry.getValue(); + } + else if(entry.getValue() == maxDisasters && entry.getKey().compareTo(state) < 0) { //if value of entry is the same as max value, check which state comes first lexicographically + state = entry.getKey(); + maxDisasters = entry.getValue(); + } + } + return state; } /** @@ -136,8 +195,25 @@ public String getStateWithTheMostDisasters() { * * @return single name of state */ - public String getStateWithTheLeastDisasters() { - return null; + public String getStateWithTheLeastDisasters() { //implementation of this is similar to getStateWithTheLeastDisasters, except find the minimum instead of the maximum + HashMap map = new HashMap<>(); + int minDisasters = Integer.MAX_VALUE; + String state = null; + for(int i = 0; i < disasters.size(); i++) { + if(!map.containsKey(disasters.get(i).getState())) map.put(disasters.get(i).getState(), 0); + else map.put(disasters.get(i).getState(), map.get(disasters.get(i).getState()) + 1); + } + for(Map.Entry entry : map.entrySet()) { + if(entry.getValue() < minDisasters) { + state = entry.getKey(); + minDisasters = entry.getValue(); + } + else if(entry.getValue() == minDisasters && entry.getKey().compareTo(state) < 0) { + state = entry.getKey(); + minDisasters = entry.getValue(); + } + } + return state; } /** @@ -149,7 +225,27 @@ public String getStateWithTheLeastDisasters() { * or empty string if state doesn't exist */ public String getMostSpokenAgentLanguageByState(String string) { - return null; + HashMap languages = new HashMap<>(); //map of languages and how many agents speak each language in a state + int languageCount = Integer.MIN_VALUE; + String language = ""; + for(int i = 0; i < agents.size(); i++) { + if(agents.get(i).getState().equals(string)) { //if the state of agent is equal to string parameter, we can add primary language and secondary language. + if(!languages.containsKey(agents.get(i).getPrimary_language())) languages.put(agents.get(i).getPrimary_language(), 1); + else languages.put(agents.get(i).getPrimary_language(), languages.get(agents.get(i).getPrimary_language()) + 1); //adds for primary language + + if(agents.get(i).getSecondary_language() != null) { + if(!languages.containsKey(agents.get(i).getSecondary_language())) languages.put(agents.get(i).getSecondary_language(), 1); + else languages.put(agents.get(i).getSecondary_language(), languages.get(agents.get(i).getSecondary_language()) + 1); //adds for secondary language + } + } + } + for(Map.Entry entry : languages.entrySet()) { + if(entry.getValue() > languageCount && !entry.getKey().equals("English")) { //checks for every language beside English and sees if number of speakers greater than the current max. + language = entry.getKey(); + languageCount = entry.getValue(); + } + } + return language; } /** @@ -166,7 +262,12 @@ public String getMostSpokenAgentLanguageByState(String string) { * None if agent does not exist, or agent has no claims (open or not) */ public int getNumOfOpenClaimsForAgentAndSeverity(int agentId, int minSeverityRating) { - return -2; + int claimCount = 0; + if(minSeverityRating < 1 || minSeverityRating > 10) return -1; + for(int i = 0; i < claims.size(); i++) { //iterates through claims list, and checks if claim agent id is equal to agentId parameter, claim severity rating is greater than or equal to the minimum rating, and that the status of claim is NOT closed + if(claims.get(i).getAgent_assigned_id() == agentId && claims.get(i).getSeverity_rating() >= minSeverityRating && !claims.get(i).getStatus().equals("Closed")) claimCount++; + } + return claimCount; } // endregion @@ -179,7 +280,11 @@ public int getNumOfOpenClaimsForAgentAndSeverity(int agentId, int minSeverityRat * @return number of disasters where the declared date is after the end date */ public int getNumDisastersDeclaredAfterEndDate() { - return -1; + int disasterCount = 0; + for(int i = 0; i < disasters.size(); i++) { + if(disasters.get(i).getDeclared_date().isAfter(disasters.get(i).getEnd_date())) disasterCount++; //uses isAfter method for LocalDate to check if declared date is after end date. + } + return disasterCount; } /** @@ -193,8 +298,15 @@ public int getNumDisastersDeclaredAfterEndDate() { * @return Map where key is agent id, value is total cost of claims associated * to the agent */ - public Map buildMapOfAgentsToTotalClaimCost() { - return null; + public Map buildMapOfAgentsToTotalClaimCost() { + Map agentMap = new HashMap<>(); + for(int i = 0; i < agents.size(); i++) { + agentMap.put(agents.get(i).getId(), 0.00); //for each agent, set their initial value to zero. + } + for(int i = 0; i < claims.size(); i++) { + agentMap.put(claims.get(i).getAgent_assigned_id(), agentMap.get(claims.get(i).getAgent_assigned_id()) + claims.get(i).getEstimate_cost()); //add cost of each claim to the agent the claim belongs to + } + return agentMap; } /** @@ -210,8 +322,17 @@ public Map buildMapOfAgentsToTotalClaimCost() { * thousandths place * null if disaster does not exist */ - public float calculateDisasterClaimDensity(int id) { - return -0.01f; + public Double calculateDisasterClaimDensity(int id) { + int radius = 0; + int disasterCount = 0; + for(int i = 0; i < disasters.size(); i++) { + if(id == disasters.get(i).getId()) radius = disasters.get(i).getRadius_miles(); //find the disaster radius + } + for(int i = 0; i < claims.size(); i++) { + if(claims.get(i).getDisaster_id() == id) disasterCount++; //if claim has same disaster id as id parameter, increment disasterCount + } + if(radius == 0) return 0.0; + return (double)(disasterCount / (Math.pow(radius, 2) * 3.14)); //divide number of claims in disaster by disaster area } // endregion @@ -228,8 +349,54 @@ public float calculateDisasterClaimDensity(int id) { * * @return three strings of month and year, descending order of highest claims */ + public String getMonth(int i) { //helper function to get month as a string + if(i == 1) return "January"; + if(i == 2) return "February"; + if(i == 3) return "March"; + if(i == 4) return "April"; + if(i == 5) return "May"; + if(i == 6) return "June"; + if(i == 7) return "July"; + if(i == 8) return "August"; + if(i == 9) return "September"; + if(i == 10) return "October"; + if(i == 11) return "November"; + if(i == 12) return "December"; + return null; + } public String[] getTopThreeMonthsWithHighestNumOfClaimsDesc() { - return new String[1]; + String[] months = new String[3]; + Map disasterDates = new HashMap<>(); //map of disaster id and their dates + for(int i = 0; i < disasters.size(); i++) { + disasterDates.put(disasters.get(i).getId(), disasters.get(i).getDeclared_date()); + } //for each disaster, set date + Map claimCostByDates = new HashMap<>(); //map of date and the amount of claims they have + for(int i = 0; i < claims.size(); i++) { + int claimDate = disasterDates.get(claims.get(i).getDisaster_id()).getMonthValue()*10000 + disasterDates.get(claims.get(i).getDisaster_id()).getYear(); + if(!claimCostByDates.containsKey(claimDate)) claimCostByDates.put(claimDate, 1); + else claimCostByDates.put(claimDate, claimCostByDates.get(claimDate) + 1); + } //for each claim, increment corresponding disaster date + for(int i = 0; i < 3; i++) { //loops three times to find the three dates with the highest number of claims + int maxCost = Integer.MIN_VALUE; + int maxDate = 0; + for(Map.Entry entry : claimCostByDates.entrySet()) { + if(entry.getValue() > maxCost) { + maxCost = entry.getValue(); + maxDate = entry.getKey(); + } + else if(entry.getValue() == maxCost) { + if(entry.getKey() % 10000 > maxDate % 10000) { + maxCost = entry.getValue(); + maxDate = entry.getKey(); + } + } + } //this loop finds the date with the largest number of claims. if two dates have the same number of claims, it returns the date that was most recent + String year = Integer.toString(maxDate % 10000); + String month = getMonth(maxDate/10000); + months[i] = month + " " + year; + claimCostByDates.remove(maxDate); //remove the entry for the following loop + } + return months; } // endregion diff --git a/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/model/Claim.java b/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/model/Claim.java index db223d9..4508406 100644 --- a/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/model/Claim.java +++ b/java/src/main/java/com/statefarm/codingcompetition/simpledatatool/model/Claim.java @@ -7,7 +7,7 @@ public class Claim { private static final Gson GSON = new Gson(); private int id, disaster_id, severity_rating, agent_assigned_id, claim_handler_assigned_id; - private float estimate_cost; + private double estimate_cost; private boolean total_loss, loss_of_life; private String status, type; @@ -51,7 +51,7 @@ public void setClaim_handler_assigned_id(int claim_handler_assigned_id) { this.claim_handler_assigned_id = claim_handler_assigned_id; } - public float getEstimate_cost() { + public double getEstimate_cost() { return this.estimate_cost; } diff --git a/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet2.java b/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet2.java index 1700191..6887e76 100644 --- a/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet2.java +++ b/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet2.java @@ -51,7 +51,7 @@ public void test7_getMostSpokenAgentLanguageByState() { public void test8_getNumOfOpenClaimsForAgentAndSeverity() { assertEquals(-1, controller.getNumOfOpenClaimsForAgentAndSeverity(0, 0)); assertEquals(-1, controller.getNumOfOpenClaimsForAgentAndSeverity(25, 11)); - assertEquals(null, controller.getNumOfOpenClaimsForAgentAndSeverity(65, 3)); + assertEquals(0, controller.getNumOfOpenClaimsForAgentAndSeverity(65, 3)); assertEquals(16, controller.getNumOfOpenClaimsForAgentAndSeverity(24, 1)); assertEquals(3, controller.getNumOfOpenClaimsForAgentAndSeverity(87, 6)); assertEquals(2, controller.getNumOfOpenClaimsForAgentAndSeverity(85, 6)); diff --git a/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet3.java b/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet3.java index 8dbf87b..2a853e4 100644 --- a/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet3.java +++ b/java/src/test/java/com/statefarm/codingcompetition/simpledatatool/TestSet3.java @@ -31,15 +31,15 @@ public void test9_getNumDisastersDeclaredAfterEndDate() { @Test public void test10_buildMapOfAgentsToTotalClaimCost() { - Map agentCostMap = controller.buildMapOfAgentsToTotalClaimCost(); + Map agentCostMap = controller.buildMapOfAgentsToTotalClaimCost(); assertEquals(100, agentCostMap.size()); - assertEquals(27856.13f, agentCostMap.get(1), 0.01); - assertEquals(2253847.27f, agentCostMap.get(3), 0.01); - assertEquals(529685.97f, agentCostMap.get(5), 0.01); - assertEquals(282307.93f, agentCostMap.get(8), 0.01); - assertEquals(2310862.86f, agentCostMap.get(13), 0.01); + assertEquals(27856.13, agentCostMap.get(1), 0.01); + assertEquals(2253847.27, agentCostMap.get(3), 0.01); + assertEquals(529685.97, agentCostMap.get(5), 0.01); + assertEquals(282307.93, agentCostMap.get(8), 0.01); + assertEquals(2310862.86, agentCostMap.get(13), 0.01); int numAgentIdsWithoutCost = expectedAgentIdsWithoutCost.length; Random rand = new Random(); @@ -55,9 +55,9 @@ public void test10_buildMapOfAgentsToTotalClaimCost() { @Test public void test11_calculateDisasterClaimDensity() { - assertEquals(0.00172f, controller.calculateDisasterClaimDensity(15), 0.00001); - assertEquals(0.00029f, controller.calculateDisasterClaimDensity(68), 0.00001); - assertEquals(null, controller.calculateDisasterClaimDensity(101)); - assertEquals(0.01624f, controller.calculateDisasterClaimDensity(64), 0.00001); + assertEquals(0.00172, controller.calculateDisasterClaimDensity(15), 0.00001); + assertEquals(0.00029, controller.calculateDisasterClaimDensity(68), 0.00001); + assertEquals(0.00, controller.calculateDisasterClaimDensity(101), 0.00001); + assertEquals(0.01624, controller.calculateDisasterClaimDensity(64), 0.00001); } }