diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5231862
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea
+*.iml
+target
diff --git a/feedback.txt b/feedback.txt
index b931d50..cc2db2e 100644
--- a/feedback.txt
+++ b/feedback.txt
@@ -1,9 +1,12 @@
-Your team (name of each individual participating):
-How many JUnits were you able to get to pass?
+Your team (name of each individual participating): Alex Kim, Ethan Xie
+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:
-
-
+ Step 1: We developed GUI in JavaFX to visualize the data that we processed in CodingCompCsvUtil.java. (see DataViz.java)
+ Step 2: In order to run it, download the necessary JavaFX libraries for compilation, and run the DataViz file.
+
+
Feedback for the coding competition? Things you would like to see in future events?
+Some coding questions were worded weirdly and hard to understand.
+For example in getVendorsWithGivenRatingThatAreInScope it was not made clear that these vendors should be filtered to have a higher or equal than
+rating. The problem statement made it seem like the vendors should be filtered to as strict equal for the rating filter.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 21d55bf..73686c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,8 @@
Coding Competition
+ 1.8
+ 1.8
diff --git a/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java b/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
index 58267da..40e0c2b 100644
--- a/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
+++ b/src/main/java/sf/codingcompetition2020/CodingCompCsvUtil.java
@@ -1,51 +1,123 @@
package sf.codingcompetition2020;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.FileReader;
+import java.io.IOException;
import java.io.Reader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
+import java.util.Collections;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MappingIterator;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvParser;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import sf.codingcompetition2020.structures.Agent;
import sf.codingcompetition2020.structures.Claim;
import sf.codingcompetition2020.structures.Customer;
+import sf.codingcompetition2020.structures.Dependent;
import sf.codingcompetition2020.structures.Vendor;
+import static java.util.stream.Collectors.toList;
+
public class CodingCompCsvUtil {
-
- /* #1
+ private final String agentListKey = "agentList";
+ private final String claimListKey = "claimList";
+ private final String customerListKey = "customerList";
+
+ /* #1
* readCsvFile() -- Read in a CSV File and return a list of entries in that file.
* @param filePath -- Path to file being read in.
* @param classType -- Class of entries being read in.
* @return -- List of entries being returned.
*/
- public List readCsvFile(String filePath, Class classType) {
+ public List readCsvFile(String filePath, Class classType) {
+ try {
+ //URL url = this.getClass().getResource(filePath);
+ //URI uri = new URI(url.toString());
+ //File file = new File(uri.getPath());
+ File file = new File(filePath);
+
+ CsvMapper mapper = new CsvMapper();
+ mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
+ //CsvSchema schema = mapper.schemaFor(classType); // schema from 'Pojo' definition
+ CsvSchema schema = CsvSchema.emptySchema().withHeader();
+ TypeFactory typeFactory = mapper.getTypeFactory();
+
+ MappingIterator it = mapper.readerFor(classType)
+ .with(schema)
+ .readValues(file);
+ List ans = it.readAll();
+ System.out.println(ans);
+ System.out.println(ans.size());
+ System.out.println(ans.get(0));
+ return ans;
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new IllegalStateException("Yeeto");
+ }
+
+
+// URL url = this.getClass().getResource(filePath);
+// URI uri = new URI(url.toString());
+// File file = new File(uri.getPath());
+// FileInputStream fis = new FileInputStream(file);
+// byte[] data = new byte[(int) file.length()];
+// try {
+// fis.read(data);
+// } catch (IOException e) {
+// e.printStackTrace();
+// } finally {
+// if (fis != null) {
+// fis.close();
+// }
+// }
+// String[] contents = new String(data, "UTF-8").split("\\r?\\n");
+//
+// List entries = new ArrayList<>();
+// for(String entry : contents) {
+// entries.add(new T(entry.split(",")));
+// }
+// return entries;
}
-
+
/* #2
* getAgentCountInArea() -- Return the number of agents in a given area.
* @param filePath -- Path to file being read in.
* @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)
+ .stream()
+ .filter(a -> a.getArea().equals(area))
+ .collect(toList()).size();
}
-
- /* #3
+
+ /** #3
* getAgentsInAreaThatSpeakLanguage() -- Return a list of agents from a given area, that speak a certain language.
* @param filePath -- Path to file being read in.
* @param area -- The area from which the agents should be counted.
@@ -53,34 +125,64 @@ 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)
+ .stream()
+ .filter(a -> a.getArea().equals(area))
+ .filter(a -> a.getLanguage().equals(language))
+ .collect(toList());
}
-
-
- /* #4
+
+
+ /** #4
* countCustomersFromAreaThatUseAgent() -- Return the number of individuals from an area that use a certain agent.
- * @param filePath -- Path to file being read in.
+ * @param csvFilePaths -- Path to file being read in.
* @param customerArea -- The area from which the customers should be counted.
* @param agentFirstName -- First name of agent.
* @param agentLastName -- Last name of agent.
* @return -- The number of customers that use a certain agent in a given area.
+ * @throws NoSuchElementException if the specified agent is not found in the given agent csv file.
*/
public short countCustomersFromAreaThatUseAgent(Map csvFilePaths, String customerArea, String agentFirstName, String agentLastName) {
-
+ List agents = readCsvFile(csvFilePaths.get(agentListKey), Agent.class);
+
+ // find the agent in question
+ Agent agent = null;
+ for (Agent a : agents) {
+ if (a.getFirstName().equals(agentFirstName) && a.getLastName().equals(agentLastName)) {
+ agent = a;
+ break;
+ }
+ }
+ if (agent == null) { // this agent does not exist in the agents file
+ throw new NoSuchElementException("The specified agent: " + agentFirstName + " " + agentLastName + " was not found in the given agent csv file.");
+ }
+
+ final int agentId = agent.getAgentId();
+ List customers = readCsvFile(csvFilePaths.get(customerListKey), Customer.class)
+ .stream()
+ .filter(customer -> customer.getArea().equals(customerArea) && customer.getAgentId() == (agentId))
+ .collect(toList());
+
+ return (short) customers.size();
}
-
+
/* #5
* getCustomersRetainedForYearsByPlcyCostAsc() -- Return a list of customers retained for a given number of years, in ascending order of their policy cost.
* @param filePath -- Path to file being read in.
- * @param yearsOfServeice -- Number of years the person has been a customer.
+ * @param yearsOfService -- Number of years the person has been a customer.
* @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 filteredCustomers = readCsvFile(customerFilePath, Customer.class)
+ .stream()
+ .filter(c -> c.getYearsOfService() == yearsOfService)
+ .collect(toList());
+ Collections.sort(filteredCustomers);
+ return filteredCustomers;
}
-
+
/* #6
* getLeadsForInsurance() -- Return a list of individuals who’ve made an inquiry for a policy but have not signed up.
* *HINT* -- Look for customers that currently have no policies with the insurance company.
@@ -88,12 +190,20 @@ 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) {
+ List customers = readCsvFile(filePath, Customer.class);
+ List customerList = new ArrayList<>();
+ for (Customer customer: customers) {
+ if(!customer.isHomePolicy() && !customer.isAutoPolicy() && !customer.isRentersPolicy()) {
+ customerList.add(customer);
+ }
+ }
+ return customerList;
}
/* #7
- * getVendorsWithGivenRatingThatAreInScope() -- Return a list of vendors within an area and include options to narrow it down by:
+ * getVendorsWithGivenRatingThatAreInScope() -- Return a list of vendors within an area and include options to narrow it down by:
a. Vendor rating
b. Whether that vendor is in scope of the insurance (if inScope == false, return all vendors in OR out of scope, if inScope == true, return ONLY vendors in scope)
* @param filePath -- Path to file being read in.
@@ -103,7 +213,12 @@ 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)
+ .stream()
+ .filter(v -> v.getArea().equals(area))
+ .filter(v -> v.getVendorRating() >= vendorRating)
+ .filter(v -> (!inScope) || (v.isInScope()))
+ .collect(toList());
}
@@ -117,31 +232,85 @@ 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)
+ .stream()
+ .filter(c -> c.getVehiclesInsured() > vehiclesInsured)
+ .filter(c -> c.getDependents().size() <= dependents)
+ .filter(c -> (c.getAge() >= 40 && c.getAge() <= 50))
+ .collect(toList());
+ }
/* #9
- * getAgentIdGivenRank() -- Return the agent with the given rank based on average customer satisfaction rating.
- * *HINT* -- Rating is calculated by taking all the agent rating by customers (1-5 scale) and dividing by the total number
+ * getAgentIdGivenRank() -- Return the agent with the given rank based on average customer satisfaction rating.
+ * *HINT* -- Rating is calculated by taking all the agent rating by customers (1-5 scale) and dividing by the total number
* of reviews for the agent.
* @param filePath -- Path to file being read in.
* @param agentRank -- The rank of the agent being requested.
* @return -- Agent ID of agent with the given rank.
*/
public int getAgentIdGivenRank(String filePath, int agentRank) {
-
- }
+ List customers = readCsvFile(filePath, Customer.class);
+ Map agentCount = new HashMap<>();
+ Map ratingSum = new HashMap<>();
+ for (Customer customer : customers) {
+ int agentId = customer.getAgentId();
+ agentCount.put(agentId, agentCount.getOrDefault(agentId, 0) + 1);
+ ratingSum.put(agentId, ratingSum.getOrDefault(agentId, 0) + customer.getAgentRating());
+ }
+
+ Map agentRatings = new HashMap<>();
+
+ for (int agentId : ratingSum.keySet()) {
+ double agentRating = ratingSum.get(agentId) * 1.0 / agentCount.get(agentId);
+ agentRatings.put(agentId, agentRating);
+ }
+
+ LinkedHashMap sortedAgentRating = new LinkedHashMap<>();
+
+ agentRatings.entrySet()
+ .stream()
+ .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
+ .forEachOrdered(x -> sortedAgentRating.put(x.getKey(), x.getValue()));
+
+ Iterator> iterator = sortedAgentRating.entrySet().iterator();
+ System.out.println(sortedAgentRating);
+ for(int i = 1; i < agentRank; i++) {
+ iterator.next();
+ }
+ return iterator.next().getKey();
+ }
+
-
/* #10
- * getCustomersWithClaims() -- Return a list of customers who’ve filed a claim within the last (inclusive).
+ * getCustomersWithClaims() -- Return a list of customers who’ve filed a claim within the last (inclusive).
* @param filePath -- Path to file being read in.
* @param monthsOpen -- Number of months a policy has been open.
* @return -- List of customers who’ve filed a claim within the last .
*/
public List getCustomersWithClaims(Map csvFilePaths, short monthsOpen) {
+ List claims = readCsvFile(csvFilePaths.get(claimListKey), Claim.class)
+ .stream()
+ .filter(c -> c.getMonthsOpen() <= monthsOpen)
+ .collect(toList());
+
+ Map idToCustomer = new HashMap<>();
+
+ List customers = readCsvFile(csvFilePaths.get(customerListKey), Customer.class);
+ for (Customer customer: customers) {
+ idToCustomer.put(customer.getCustomerId(), customer);
+ }
+
+ Set customerSet = new HashSet<>();
+
+ for (Claim claim: claims) {
- }
+ customerSet.add(idToCustomer.get(claim.getCustomerId()));
+ }
+
+
+
+ return new ArrayList<>(customerSet);
+ }
}
diff --git a/src/main/java/sf/codingcompetition2020/DataViz.java b/src/main/java/sf/codingcompetition2020/DataViz.java
new file mode 100644
index 0000000..b7278dc
--- /dev/null
+++ b/src/main/java/sf/codingcompetition2020/DataViz.java
@@ -0,0 +1,214 @@
+package sf.codingcompetition2020;
+
+import javafx.application.Application;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Scene;
+import javafx.scene.chart.*;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.FlowPane;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DataViz extends Application {
+
+ /**
+ * @param primaryStage the primary stage used for the javaFx scene
+ */
+ //private static CodingCompCsvUtil csvUtil;
+ private int current;
+ private static int[] pos1 = {150, 550};
+ private static int[] pos2 = {150, 600};
+ private static List