diff --git a/feedback.txt b/feedback.txt
index b931d50..0c3b98d 100644
--- a/feedback.txt
+++ b/feedback.txt
@@ -1,9 +1,7 @@
-Your team (name of each individual participating):
-How many JUnits were you able to get to pass?
+Your team (name of each individual participating): Stuart Irwin
+How many JUnits were you able to get to pass? 10
Document and describe any enhancements included to help the judges properly grade your submission.
- Step 1:
- Step 2:
Feedback for the coding competition? Things you would like to see in future events?
diff --git a/pom.xml b/pom.xml
index 21d55bf..c35e2ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,19 @@
4.0.0
coding-competition
1.0.0-SNAPSHOT
- jar
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+ jar
sf.codingcompetition2020
coding-competition
diff --git a/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java b/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
index 58267da..c936ea2 100644
--- a/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
+++ b/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
@@ -1,20 +1,9 @@
package sf.codingcompetition2020;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.MappingIterator;
-import com.fasterxml.jackson.databind.ObjectReader;
-import com.fasterxml.jackson.dataformat.csv.CsvMapper;
-import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.*;
+import java.util.function.Predicate;
import sf.codingcompetition2020.structures.Agent;
import sf.codingcompetition2020.structures.Claim;
@@ -30,7 +19,42 @@ public class CodingCompCsvUtil {
* @return -- List of entries being returned.
*/
public List readCsvFile(String filePath, Class classType) {
-
+ return readCsvFile(filePath, classType, null);
+ }
+
+ private List readCsvFile(String filePath, Class classType, Predicate filter) {
+ //Open file
+ File file = new File(filePath);
+ ArrayList list = new ArrayList<>();
+ try {
+ //Skip first line
+ Scanner scan = new Scanner(file);
+ scan.nextLine();
+
+ while(scan.hasNextLine()) {
+
+ //Build object
+ String[] values = scan.nextLine().split(",");
+ T ob = readLine(values, classType);
+ if(filter == null || filter.test(ob))
+ list.add(ob);
+ }
+ } catch(FileNotFoundException e) {
+ System.out.println("File " + filePath + " not found");
+ }
+ return list;
+ }
+
+ private T readLine(String[] input, Class classType) {
+ if(classType == Agent.class)
+ return (T) new Agent(input);
+ if(classType == Claim.class)
+ return (T) new Claim(input);
+ if(classType == Customer.class)
+ return (T) new Customer(input);
+ if(classType == Vendor.class)
+ return (T) new Vendor(input);
+ throw new IllegalArgumentException("Invalid class type");
}
@@ -40,8 +64,8 @@ public List readCsvFile(String filePath, Class classType) {
* @param area -- The area from which the agents should be counted.
* @return -- The number of agents in a given area
*/
- public int getAgentCountInArea(String filePath,String area) {
-
+ public int getAgentCountInArea(String filePath, String area) {
+ return readCsvFile(filePath, Agent.class, agent -> agent.getArea().equals(area)).size();
}
@@ -53,7 +77,7 @@ public int getAgentCountInArea(String filePath,String area) {
* @return -- The number of agents in a given area
*/
public List getAgentsInAreaThatSpeakLanguage(String filePath, String area, String language) {
-
+ return readCsvFile(filePath, Agent.class, agent -> agent.getArea().equals(area) && agent.getLanguage().equals(language));
}
@@ -66,7 +90,13 @@ public List getAgentsInAreaThatSpeakLanguage(String filePath, String area
* @return -- The number of customers that use a certain agent in a given area.
*/
public short countCustomersFromAreaThatUseAgent(Map csvFilePaths, String customerArea, String agentFirstName, String agentLastName) {
-
+ List agents = readCsvFile(csvFilePaths.get("agentList"), Agent.class,
+ agent -> agent.getFirstName().equals(agentFirstName) && agent.getLastName().equals(agentLastName));
+ if(agents.size() != 1)
+ return 0;
+
+ return (short)readCsvFile(csvFilePaths.get("customerList"), Customer.class,
+ customer -> customer.getArea().equals(customerArea) && customer.getAgentId() == agents.get(0).getAgentId()).size();
}
@@ -77,7 +107,9 @@ public short countCustomersFromAreaThatUseAgent(Map csvFilePaths,
* @return -- List of customers retained for a given number of years, in ascending order of policy cost.
*/
public List getCustomersRetainedForYearsByPlcyCostAsc(String customerFilePath, short yearsOfService) {
-
+ List customers = readCsvFile(customerFilePath, Customer.class, customer -> customer.getYearsOfService() == yearsOfService);
+ customers.sort(Comparator.comparingInt(customer -> Integer.parseInt(customer.getTotalMonthlyPremium().substring(1))));
+ return customers;
}
@@ -88,7 +120,8 @@ public List getCustomersRetainedForYearsByPlcyCostAsc(String customerF
* @return -- List of customers who’ve made an inquiry for a policy but have not signed up.
*/
public List getLeadsForInsurance(String filePath) {
-
+ return readCsvFile(filePath, Customer.class, customer ->
+ !(customer.hasAutoPolicy() || customer.hasHomePolicy() || customer.hasRentersPolicy()));
}
@@ -103,7 +136,8 @@ b. Whether that vendor is in scope of the insurance (if inScope == false, return
* @return -- List of vendors within a given area, filtered by scope and vendor rating.
*/
public List getVendorsWithGivenRatingThatAreInScope(String filePath, String area, boolean inScope, int vendorRating) {
-
+ return readCsvFile(filePath, Vendor.class,
+ vendor -> vendor.getArea().equals(area) && vendor.getVendorRating() >= vendorRating && (!inScope || vendor.isInScope()));
}
@@ -117,7 +151,9 @@ public List getVendorsWithGivenRatingThatAreInScope(String filePath, Str
* @return -- List of customers filtered by age, number of vehicles insured and the number of dependents.
*/
public List getUndisclosedDrivers(String filePath, int vehiclesInsured, int dependents) {
-
+ return readCsvFile(filePath, Customer.class,
+ customer -> customer.getVehiclesInsured() > vehiclesInsured && customer.getDependents().size() <= dependents &&
+ customer.getAge() >= 40 && customer.getAge() <= 50);
}
@@ -130,8 +166,30 @@ public List getUndisclosedDrivers(String filePath, int vehiclesInsured
* @return -- Agent ID of agent with the given rank.
*/
public int getAgentIdGivenRank(String filePath, int agentRank) {
-
- }
+ List list = readCsvFile(filePath, Customer.class);
+ HashMap agents = new HashMap<>();
+
+ //Create map of agent ratings
+ for(Customer c : list) {
+ int agentId = c.getAgentId();
+ if(agents.containsKey(agentId))
+ agents.replace(agentId, agents.get(agentId).add(new Pair(c.getAgentRating(), 1)));
+ else
+ agents.put(agentId, new Pair(c.getAgentRating(), 1));
+ }
+
+ //Create new list
+ List agentsList = new ArrayList<>();
+ for(int agentId : agents.keySet()) {
+ //Calculate avg rating
+ Pair p = agents.get(agentId);
+ agentsList.add(new Pair(agentId, 100 * p.first / p.second));
+ }
+
+ //Sort agents
+ agentsList.sort(Comparator.comparingInt(pair -> pair.second));
+ return agentsList.get(agentsList.size() - agentRank).first;
+ }
/* #10
@@ -141,7 +199,14 @@ public int getAgentIdGivenRank(String filePath, int agentRank) {
* @return -- List of customers who’ve filed a claim within the last .
*/
public List getCustomersWithClaims(Map csvFilePaths, short monthsOpen) {
-
+ List claims = readCsvFile(csvFilePaths.get("claimList"), Claim.class, claim -> claim.getMonthsOpen() <= monthsOpen);
+ List customers = readCsvFile(csvFilePaths.get("customerList"), Customer.class);
+ Set filteredCustomers = new HashSet<>();
+
+ for(Claim c : claims)
+ filteredCustomers.add(customers.get(c.getCustomerId() - 1));
+
+ return new ArrayList<>(filteredCustomers);
}
}
diff --git a/src/main/java/sf/codingcompetition2020/Pair.java b/src/main/java/sf/codingcompetition2020/Pair.java
new file mode 100644
index 0000000..838ada3
--- /dev/null
+++ b/src/main/java/sf/codingcompetition2020/Pair.java
@@ -0,0 +1,15 @@
+package sf.codingcompetition2020;
+
+public class Pair {
+ public final int first;
+ public final int second;
+
+ public Pair(int first, int second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public Pair add(Pair other) {
+ return new Pair(first + other.first, second + other.second);
+ }
+}
diff --git a/src/main/java/sf/codingcompetition2020/structures/Agent.java b/src/main/java/sf/codingcompetition2020/structures/Agent.java
index e2e6f93..df272c8 100644
--- a/src/main/java/sf/codingcompetition2020/structures/Agent.java
+++ b/src/main/java/sf/codingcompetition2020/structures/Agent.java
@@ -8,4 +8,35 @@ public class Agent {
private String firstName;
private String lastName;
+ public Agent(String[] s) {
+ if(s.length != 5)
+ return;
+
+ //Set values
+ agentId = Integer.parseInt(s[0]);
+ area = s[1];
+ language = s[2];
+ firstName = s[3];
+ lastName = s[4];
+ }
+
+ public int getAgentId() {
+ return agentId;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
}
diff --git a/src/main/java/sf/codingcompetition2020/structures/Claim.java b/src/main/java/sf/codingcompetition2020/structures/Claim.java
index 581140a..af61687 100644
--- a/src/main/java/sf/codingcompetition2020/structures/Claim.java
+++ b/src/main/java/sf/codingcompetition2020/structures/Claim.java
@@ -6,4 +6,30 @@ public class Claim {
private boolean closed;
private int monthsOpen;
+ public Claim(String[] s) {
+ if(s.length != 4)
+ return;
+
+ //Set values
+ claimId = Integer.parseInt(s[0]);
+ customerId = Integer.parseInt(s[1]);
+ closed = s[2].equals("true");
+ monthsOpen = Integer.parseInt(s[3]);
+ }
+
+ public int getClaimId() {
+ return claimId;
+ }
+
+ public int getCustomerId() {
+ return customerId;
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ public int getMonthsOpen() {
+ return monthsOpen;
+ }
}
diff --git a/src/main/java/sf/codingcompetition2020/structures/Customer.java b/src/main/java/sf/codingcompetition2020/structures/Customer.java
index f151906..0675d10 100644
--- a/src/main/java/sf/codingcompetition2020/structures/Customer.java
+++ b/src/main/java/sf/codingcompetition2020/structures/Customer.java
@@ -3,10 +3,6 @@
import java.util.ArrayList;
import java.util.List;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
public class Customer {
private int customerId;
private String firstName;
@@ -23,5 +19,94 @@ public class Customer {
private String totalMonthlyPremium;
private short yearsOfService;
private Integer vehiclesInsured;
+
+ public Customer(String[] s) {
+ if(s.length < 15)
+ return;
+
+ //First set of values
+ customerId = Integer.parseInt(s[0]);
+ firstName = s[1];
+ lastName = s[2];
+ age = Integer.parseInt(s[3]);
+ area = s[4];
+ agentId = Integer.parseInt(s[5]);
+ agentRating = Short.parseShort(s[6]);
+ primaryLanguage = s[7];
+
+ //Variable number of dependents
+ int i = 0;
+ dependents = new ArrayList<>();
+ if(s[8].length() > 0) {
+ do {
+ dependents.add(new Dependent(s[8 + i], s[9 + i]));
+ i += 2;
+ } while(s[8 + i].charAt(0) == '{');
+ i--;
+ }
+
+ //Other variables offset accordingly
+ homePolicy = s[9 + i].equals("true");
+ autoPolicy = s[10 + i].equals("true");
+ rentersPolicy = s[11 + i].equals("true");
+ totalMonthlyPremium = s[12 + i];
+ yearsOfService = Short.parseShort(s[13 + i]);
+ vehiclesInsured = Integer.parseInt(s[14 + i]);
+ }
+
+ public int getCustomerId() {
+ return customerId;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public int getAgentId() {
+ return agentId;
+ }
+
+ public short getAgentRating() {
+ return agentRating;
+ }
+
+ public List getDependents() {
+ return dependents;
+ }
+
+ public boolean hasHomePolicy() {
+ return homePolicy;
+ }
+
+ public boolean hasAutoPolicy() {
+ return autoPolicy;
+ }
+
+ public boolean hasRentersPolicy() {
+ return rentersPolicy;
+ }
+
+ public String getTotalMonthlyPremium() {
+ return totalMonthlyPremium;
+ }
+
+ public int getYearsOfService() {
+ return yearsOfService;
+ }
+ public Integer getVehiclesInsured() {
+ return vehiclesInsured;
+ }
}
diff --git a/src/main/java/sf/codingcompetition2020/structures/Dependent.java b/src/main/java/sf/codingcompetition2020/structures/Dependent.java
index d4deb1a..ce42ebb 100644
--- a/src/main/java/sf/codingcompetition2020/structures/Dependent.java
+++ b/src/main/java/sf/codingcompetition2020/structures/Dependent.java
@@ -4,4 +4,9 @@ public class Dependent {
private String firstName;
private String lastName;
+ public Dependent(String first, String last) {
+ //Clean json data
+ firstName = first.split(":")[1].replaceAll("[\"}]","");
+ lastName = last.split(":")[1].replaceAll("[\"}]","");
+ }
}
diff --git a/src/main/java/sf/codingcompetition2020/structures/Vendor.java b/src/main/java/sf/codingcompetition2020/structures/Vendor.java
index 6b6fb76..d6824e2 100644
--- a/src/main/java/sf/codingcompetition2020/structures/Vendor.java
+++ b/src/main/java/sf/codingcompetition2020/structures/Vendor.java
@@ -5,5 +5,31 @@ public class Vendor {
private String area;
private int vendorRating;
private boolean inScope;
-
+
+ public Vendor(String[] s) {
+ if(s.length != 4)
+ return;
+
+ //Set values
+ vendorId = Integer.parseInt(s[0]);
+ area = s[1];
+ vendorRating = Integer.parseInt(s[2]);
+ inScope = s[3].equals("true");
+ }
+
+ public int getVendorId() {
+ return vendorId;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public int getVendorRating() {
+ return vendorRating;
+ }
+
+ public boolean isInScope() {
+ return inScope;
+ }
}
diff --git a/src/main/resources/schema.graphqls b/src/main/resources/schema.graphqls
new file mode 100644
index 0000000..05eb4b2
--- /dev/null
+++ b/src/main/resources/schema.graphqls
@@ -0,0 +1,51 @@
+type Agent {
+ agentId: ID!
+ area: String
+ language: String
+ firstName: String
+ lastName: String
+}
+
+type Dependent {
+ firstName: String
+ lastName: String
+}
+
+type Customer {
+ customerId: ID!
+ firstName: String
+ lastName: String
+ age: Int
+ area: String
+ agentId: Int
+ agentRating: Int
+ primaryLanguage: String
+ dependents: [Dependent]
+ homePolicy: Boolean
+ autoPolicy: Boolean
+ rentersPolicy: Boolean
+ totalMonthlyPremium: String
+ yearsOfService: Int
+ vehiclesInsured: Int
+}
+
+type Claim {
+ claimId: ID!
+ customer: Customer
+ closed: Boolean
+ monthsOpen: Int
+}
+
+type Vendor {
+ vendorId: ID!
+ area: String
+ vendorRating: Int
+ inScope: Boolean
+}
+
+type Query {
+ agents: [Agent]
+ claims: [Claim]
+ customers: [Customer]
+ vendors: [Vendor]
+}
\ No newline at end of file
diff --git a/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class b/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class
index 00daba9..09b9782 100644
Binary files a/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class and b/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class differ
diff --git a/target/classes/sf/codingcompetition2020/structures/Agent.class b/target/classes/sf/codingcompetition2020/structures/Agent.class
index 26bf31f..021e4f8 100644
Binary files a/target/classes/sf/codingcompetition2020/structures/Agent.class and b/target/classes/sf/codingcompetition2020/structures/Agent.class differ
diff --git a/target/classes/sf/codingcompetition2020/structures/Claim.class b/target/classes/sf/codingcompetition2020/structures/Claim.class
index 1ce796d..0e79a6a 100644
Binary files a/target/classes/sf/codingcompetition2020/structures/Claim.class and b/target/classes/sf/codingcompetition2020/structures/Claim.class differ
diff --git a/target/classes/sf/codingcompetition2020/structures/Customer.class b/target/classes/sf/codingcompetition2020/structures/Customer.class
index 844ea29..10fa7f9 100644
Binary files a/target/classes/sf/codingcompetition2020/structures/Customer.class and b/target/classes/sf/codingcompetition2020/structures/Customer.class differ
diff --git a/target/classes/sf/codingcompetition2020/structures/Dependent.class b/target/classes/sf/codingcompetition2020/structures/Dependent.class
index 3ee505f..41b1be7 100644
Binary files a/target/classes/sf/codingcompetition2020/structures/Dependent.class and b/target/classes/sf/codingcompetition2020/structures/Dependent.class differ
diff --git a/target/classes/sf/codingcompetition2020/structures/Vendor.class b/target/classes/sf/codingcompetition2020/structures/Vendor.class
index fdbca9b..c537673 100644
Binary files a/target/classes/sf/codingcompetition2020/structures/Vendor.class and b/target/classes/sf/codingcompetition2020/structures/Vendor.class differ
diff --git a/target/test-classes/sf/codingcompetition2020/CodingCompCsvUtilTest.class b/target/test-classes/sf/codingcompetition2020/CodingCompCsvUtilTest.class
index 765ac60..7efe870 100644
Binary files a/target/test-classes/sf/codingcompetition2020/CodingCompCsvUtilTest.class and b/target/test-classes/sf/codingcompetition2020/CodingCompCsvUtilTest.class differ