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 currentItems; + + private static final String agentListKey = "agentList.csv"; + private static final String claimListKey = "claimList.csv"; + private static final String customerListKey = "customerList.csv"; + + private static CodingCompCsvUtil csvUtil; + + public void start(Stage primaryStage) { + csvUtil = new CodingCompCsvUtil(); + Pane pane = new Pane(); + FlowPane root = new FlowPane(); + + currentItems = new ArrayList<>(); + + VBox vBox = new VBox(); + + ObservableList options = FXCollections.observableArrayList( + "getAgentCountInArea", + "getAgentsInAreaThatSpeakLanguage", + "countCustomersFromAreaThatUseAgent", + "getCustomersRetainedForYearsByPlcyCostAsc", + "getLeadsForInsurance", + "getVendorsWithGivenRatingThatAreInScope", + "getUndisclosedDrivers", + "getAgentIdGivenRank", + "getCustomersWithClaims" + ); + + final ComboBox comboBox = new ComboBox(options); + + onComboBoxChange(comboBox, vBox); + + comboBox.setTranslateX(150); + comboBox.setTranslateY(500); + + vBox.getChildren().add(comboBox); + root.getChildren().add(vBox); + + + Scene scene = new Scene(root, 600, 800); + + primaryStage.setTitle("Data Viz"); + primaryStage.setScene(scene); + primaryStage.show(); + } + + private static void onComboBoxChange(ComboBox comboBox, VBox vBox) { + EventHandler event = new EventHandler() { + public void handle(ActionEvent e) { + ComboBox chooseConstant2; + if (currentItems.size() != 0) { + while (currentItems.size() != 0) { + vBox.getChildren().remove(currentItems.get(0)); + currentItems.remove(0); + } + } + if (comboBox.getValue().equals("getAgentCountInArea")) { + String[] areaNames = {"area-1", "area-2", "area-3", "area-4", "area-5"}; + ObservableList pieChartData = FXCollections.observableArrayList(); + for (int i = 0; i < areaNames.length; i++) { + pieChartData.addAll(new PieChart.Data(areaNames[i], csvUtil.getAgentCountInArea(agentListKey, areaNames[i]))); + } + final PieChart chart = new PieChart(pieChartData); + chart.setTitle("Agents per Area"); + (vBox).getChildren().add(chart); + currentItems.add(chart); + } else if (comboBox.getValue().equals("getAgentsInAreaThatSpeakLanguage")) { + ObservableList options = FXCollections.observableArrayList( + "Language", + "Area" + ); + ObservableList options2 = FXCollections.observableArrayList( + + ); + + final ComboBox chooseConstant1 = new ComboBox(options); + chooseConstant1.setTranslateX(pos1[0]); + chooseConstant1.setTranslateY(pos1[1]); + + EventHandler event = new EventHandler() { + public void handle(ActionEvent e) { + ComboBox chooseConstant2; + String[] arr1 = {"Arabic", "Hindi", "Mandarin", "French", "Russian", "English", "Spanish"}; + String[] arr2 = {"area-1", "area-2", "area-3", "area-4", "area-5"}; + if (chooseConstant1.getValue().equals("Language")) { + for (int i = 0; i < arr1.length; i++) { + options2.add(arr1[i]); + } + } else { + for (int i = 0; i < arr2.length; i++) { + options2.add(arr2[i]); + } + } + chooseConstant2 = new ComboBox(options2); + chooseConstant2.setTranslateX(pos2[0]); + chooseConstant2.setTranslateY(pos2[1]); + + EventHandler event = new EventHandler() { + public void handle(ActionEvent e) { + ObservableList pieChartData = FXCollections.observableArrayList(); + if (chooseConstant1.getValue().equals("Language")) { + String current = (String) chooseConstant2.getValue(); + for (int i = 0; i < arr1.length; i++) { + pieChartData.addAll(new PieChart.Data(arr1[i], csvUtil.getAgentsInAreaThatSpeakLanguage(agentListKey, arr1[i], current).size())); + } + } else { + String current = (String) chooseConstant2.getValue(); + for (int i = 0; i < arr1.length; i++) { + pieChartData.addAll(new PieChart.Data(arr2[i], csvUtil.getAgentsInAreaThatSpeakLanguage(agentListKey, arr2[i], current).size())); + } + } + final PieChart chart = new PieChart(pieChartData); + chart.setTitle("Agents per Area"); + (vBox).getChildren().add(chart); + currentItems.add(chart); + } + }; + chooseConstant2.setOnAction(event); + Label label2 = new Label("Enter a valid langage/area"); + label2.setTranslateX(pos2[0]); + label2.setTranslateY(pos2[1]); + + vBox.getChildren().addAll(label2, chooseConstant2); + currentItems.add(chooseConstant2); + currentItems.add(label2); + } + }; + + chooseConstant1.setOnAction(event); + + Label label1 = new Label("Enter Value to Hold Constant"); + + label1.setTranslateX(pos1[0]); + label1.setTranslateY(pos1[1]); + + + vBox.getChildren().addAll(label1, chooseConstant1); + + currentItems.add(chooseConstant1); + currentItems.add(label1); + + + // ObservableList pieChartData = FXCollections.observableArrayList(); + // pieChartData.addAll(new PieChart.Data("test", 13)); + // final PieChart chart = new PieChart(pieChartData); + // chart.setTitle("Agents per Area"); + // vBox.getChildren().add(chart); + } else if (comboBox.getValue().equals("countCustomersFromAreaThatUseAgent")) { + final TextField chooseConstant1 = new TextField(); + chooseConstant1.setTranslateX(pos1[0]); + chooseConstant1.setTranslateY(pos1[1]); + + Label label1 = new Label("Enter First and Last name of an Agent (Press Enter to submit)"); + label1.setTranslateX(pos1[0]); + label1.setTranslateY(pos1[1]); + + EventHandler event = new EventHandler() { + public void handle(ActionEvent e) { + int split = chooseConstant1.getText().indexOf(" "); + String firstName = chooseConstant1.getText().substring(0, split); + String lastName = chooseConstant2.getValue().substring(split + 1); + String[] areaNames = {"area-1", "area-2", "area-3", "area-4", "area-5"}; + ObservableList pieChartData = FXCollections.observableArrayList(); + for (int i = 0; i < areaNames.length; i++) { + pieChartData.addAll(new PieChart.Data(areaNames[i], csvUtil.countCustomersFromAreaThatUseAgent(agentListKey, areaNames[i], firstName, lastName))); + } + final PieChart chart = new PieChart(pieChartData); + chart.setTitle("Area distribution for Agent: " + firstName + " " + lastName); + (vBox).getChildren().add(chart); + currentItems.add(chart); + + } + }; + chooseConstant1.setOnAction(event); + + vBox.getChildren().addAll(label1, chooseConstant1); + currentItems.add(chooseConstant1); + currentItems.add(label1); + } + } + }; + comboBox.setOnAction(event); + } +} diff --git a/src/main/java/sf/codingcompetition2020/structures/Agent.java b/src/main/java/sf/codingcompetition2020/structures/Agent.java index e2e6f93..cc3a18a 100644 --- a/src/main/java/sf/codingcompetition2020/structures/Agent.java +++ b/src/main/java/sf/codingcompetition2020/structures/Agent.java @@ -1,11 +1,61 @@ package sf.codingcompetition2020.structures; +import java.util.Objects; + public class Agent { - + private int agentId; private String area; private String language; private String firstName; private String lastName; - + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Agent)) return false; + Agent agent = (Agent) o; + return agentId == agent.agentId && + Objects.equals(area, agent.area) && + Objects.equals(language, agent.language) && + Objects.equals(firstName, agent.firstName) && + Objects.equals(lastName, agent.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(agentId); + } + + 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; + } + + @Override + public String toString() { + return "Agent{" + + "agentId=" + agentId + + ", area='" + area + '\'' + + ", language='" + language + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + '}'; + } } diff --git a/src/main/java/sf/codingcompetition2020/structures/Claim.java b/src/main/java/sf/codingcompetition2020/structures/Claim.java index 581140a..a40fc54 100644 --- a/src/main/java/sf/codingcompetition2020/structures/Claim.java +++ b/src/main/java/sf/codingcompetition2020/structures/Claim.java @@ -5,5 +5,30 @@ public class Claim { private int customerId; private boolean closed; private int monthsOpen; - + + public int getClaimId() { + return claimId; + } + + public int getCustomerId() { + return customerId; + } + + public boolean isClosed() { + return closed; + } + + public int getMonthsOpen() { + return monthsOpen; + } + + @Override + public String toString() { + return "Claim{" + + "claimId=" + claimId + + ", customerId=" + customerId + + ", closed=" + closed + + ", monthsOpen=" + monthsOpen + + '}'; + } } diff --git a/src/main/java/sf/codingcompetition2020/structures/Customer.java b/src/main/java/sf/codingcompetition2020/structures/Customer.java index f151906..8b2d52f 100644 --- a/src/main/java/sf/codingcompetition2020/structures/Customer.java +++ b/src/main/java/sf/codingcompetition2020/structures/Customer.java @@ -2,12 +2,16 @@ import java.util.ArrayList; import java.util.List; +import java.lang.Comparable; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; -public class Customer { +public class Customer implements Comparable { private int customerId; private String firstName; private String lastName; @@ -20,8 +24,139 @@ public class Customer { private boolean homePolicy; private boolean autoPolicy; private boolean rentersPolicy; + + @JsonCreator + public static Customer fromJson(String value) { + String[] vals = value.split(","); + System.out.println(value); + return null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Customer)) return false; + Customer customer = (Customer) o; + return customerId == customer.customerId && + age == customer.age && + agentId == customer.agentId && + agentRating == customer.agentRating && + homePolicy == customer.homePolicy && + autoPolicy == customer.autoPolicy && + rentersPolicy == customer.rentersPolicy && + yearsOfService == customer.yearsOfService && + Objects.equals(firstName, customer.firstName) && + Objects.equals(lastName, customer.lastName) && + Objects.equals(area, customer.area) && + Objects.equals(primaryLanguage, customer.primaryLanguage) && + Objects.equals(dependents, customer.dependents) && + Objects.equals(totalMonthlyPremium, customer.totalMonthlyPremium) && + Objects.equals(vehiclesInsured, customer.vehiclesInsured); + } + + @Override + public int hashCode() { + return Objects.hash(customerId); + } + private String totalMonthlyPremium; private short yearsOfService; private Integer vehiclesInsured; + @Override + public String toString() { + return "Customer{" + + "customerId=" + customerId + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", age=" + age + + ", area='" + area + '\'' + + ", agentId=" + agentId + + ", agentRating=" + agentRating + + ", primaryLanguage='" + primaryLanguage + '\'' + + ", dependents=" + dependents + + ", homePolicy=" + homePolicy + + ", autoPolicy=" + autoPolicy + + ", rentersPolicy=" + rentersPolicy + + ", totalMonthlyPremium='" + totalMonthlyPremium + '\'' + + ", yearsOfService=" + yearsOfService + + ", vehiclesInsured=" + vehiclesInsured + + '}'; + } + + 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 String getPrimaryLanguage() { + return primaryLanguage; + } + + public List getDependents() { + return dependents; + } + + public boolean isHomePolicy() { + return homePolicy; + } + + public boolean isAutoPolicy() { + return autoPolicy; + } + + public boolean isRentersPolicy() { + return rentersPolicy; + } + + public String getTotalMonthlyPremium() { + return totalMonthlyPremium; + } + + public short getYearsOfService() { + return yearsOfService; + } + + public Integer getVehiclesInsured() { + return vehiclesInsured; + } + + @Override + public int compareTo(Customer customer) { + return totalMonthlyPremium.compareTo(customer.getTotalMonthlyPremium()); + } + + + public void setDependents(String dependents) { + String split = "}"; + String[] splitted = dependents.split(split); + List temp = new ArrayList<>(); + for (int i = 1; i < splitted.length; i++) { + temp.add(new Dependent()); + } + this.dependents = temp; + } } diff --git a/src/main/java/sf/codingcompetition2020/structures/Dependent.java b/src/main/java/sf/codingcompetition2020/structures/Dependent.java index d4deb1a..18e1e39 100644 --- a/src/main/java/sf/codingcompetition2020/structures/Dependent.java +++ b/src/main/java/sf/codingcompetition2020/structures/Dependent.java @@ -1,7 +1,38 @@ package sf.codingcompetition2020.structures; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; + +import java.io.IOException; + public class Dependent { private String firstName; private String lastName; + public Dependent () { + + } + public Dependent(String str) { + this.firstName = str; + this.lastName = str; + System.out.println(str); + } +// CsvMapper mapper = new CsvMapper(); +// CsvSchema schema = mapper.schemaFor(Dependent.class); +// MappingIterator it = mapper.readerFor(Dependent.class) +// .with(schema) +// .readValues(csv); +// Dependent d = it.next(); +// this.firstName = d.firstName; +// this.lastName = d.lastName; + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + } diff --git a/src/main/java/sf/codingcompetition2020/structures/Vendor.java b/src/main/java/sf/codingcompetition2020/structures/Vendor.java index 6b6fb76..5162c2a 100644 --- a/src/main/java/sf/codingcompetition2020/structures/Vendor.java +++ b/src/main/java/sf/codingcompetition2020/structures/Vendor.java @@ -5,5 +5,30 @@ public class Vendor { private String area; private int vendorRating; private boolean inScope; - + + public int getVendorId() { + return vendorId; + } + + public String getArea() { + return area; + } + + public int getVendorRating() { + return vendorRating; + } + + public boolean isInScope() { + return inScope; + } + + @Override + public String toString() { + return "Vendor{" + + "vendorId=" + vendorId + + ", area='" + area + '\'' + + ", vendorRating=" + vendorRating + + ", inScope=" + inScope + + '}'; + } } diff --git a/src/test/java/sf/codingcompetition2020/CodingCompCsvUtilTest.java b/src/test/java/sf/codingcompetition2020/CodingCompCsvUtilTest.java index c29959f..49716c8 100644 --- a/src/test/java/sf/codingcompetition2020/CodingCompCsvUtilTest.java +++ b/src/test/java/sf/codingcompetition2020/CodingCompCsvUtilTest.java @@ -13,7 +13,7 @@ import sf.codingcompetition2020.structures.Customer; public class CodingCompCsvUtilTest{ - + private final String agentFilePath = "src/main/resources/DataFiles/agents.csv"; private final String claimFilePath = "src/main/resources/DataFiles/claims.csv"; private final String customerFilePath = "src/main/resources/DataFiles/customers.csv"; @@ -21,10 +21,10 @@ public class CodingCompCsvUtilTest{ private final String agentList = "agentList"; private final String claimList = "claimList"; private final String customerList = "customerList"; - - + + CodingCompCsvUtil codingCompCsVUtil = new CodingCompCsvUtil(); - + //#1 @Test public void test1() { @@ -32,14 +32,14 @@ public void test1() { assertEquals(424, ((Claim)codingCompCsVUtil.readCsvFile(claimFilePath, Claim.class).get(423)).getClaimId()); assertEquals("Lorin", ((Customer)codingCompCsVUtil.readCsvFile(customerFilePath, Customer.class).get(499)).getFirstName()); } - + //#2 @Test public void getAgentCountInArea() { assertEquals(247,codingCompCsVUtil.getAgentCountInArea(agentFilePath, "area-4")); assertEquals(55,codingCompCsVUtil.getAgentCountInArea(agentFilePath, "area-2")); } - + //#3 @Test public void getAgentsInAreaThatSpeakLanguage() { @@ -47,29 +47,29 @@ public void getAgentsInAreaThatSpeakLanguage() { assertEquals(2, agentList.size()); assertEquals(49, agentList.get(0).getAgentId()); assertEquals(424, agentList.get(1).getAgentId()); - + agentList = codingCompCsVUtil.getAgentsInAreaThatSpeakLanguage(agentFilePath, "area-2", "Spanish"); assertEquals(1, agentList.size()); assertEquals(242, agentList.get(0).getAgentId()); } - + //#4 @Test public void countCustomersFromCitythatUseAgent() { Map csvFilePaths = new HashMap<>(); - + csvFilePaths.put(agentList, agentFilePath); csvFilePaths.put(customerList, customerFilePath); assertEquals(4,codingCompCsVUtil.countCustomersFromAreaThatUseAgent(csvFilePaths, "area-3", "Piggy","Ferrai")); assertEquals(6,codingCompCsVUtil.countCustomersFromAreaThatUseAgent(csvFilePaths, "area-4", "Rabi","Figg")); } - + //#5 @Test public void getCustomersRetainedForYearsByPlcyCostAsc() { List customerList = codingCompCsVUtil.getCustomersRetainedForYearsByPlcyCostAsc(customerFilePath, Short.valueOf("5")); - + assertEquals(15,customerList.size()); assertEquals(215,customerList.get(0).getCustomerId()); assertEquals(5,customerList.get(2).getYearsOfService()); @@ -78,13 +78,13 @@ public void getCustomersRetainedForYearsByPlcyCostAsc() { assertEquals("Tesoe",customerList.get(5).getLastName()); assertEquals("$888",customerList.get(14).getTotalMonthlyPremium()); } - + //#6 @Test public void getLeadsForInsurance() { assertEquals(82, codingCompCsVUtil.getLeadsForInsurance(customerFilePath).size()); } - + //#7 @Test public void getVendorsWithGivenRatingThatAreInScope() { @@ -92,33 +92,32 @@ public void getVendorsWithGivenRatingThatAreInScope() { assertEquals(2, codingCompCsVUtil.getVendorsWithGivenRatingThatAreInScope(vendorFilePath, "area-2", true, 2).size()); assertEquals(12, codingCompCsVUtil.getVendorsWithGivenRatingThatAreInScope(vendorFilePath, "area-3", false, 3).size()); } - + //#8 @Test - public void getCustomersRetainedForYearsByPlcyCostAsc2() { + public void getCustomersRetainedForYearsByPlcyCostAsc2() { assertEquals(15,codingCompCsVUtil.getUndisclosedDrivers(customerFilePath,2,2).size()); assertEquals(14,codingCompCsVUtil.getUndisclosedDrivers(customerFilePath,3,3).size()); } - + //#9 @Test - public void getAgentIdGivenRank() { + public void getAgentIdGivenRank() { assertEquals(3,codingCompCsVUtil.getAgentIdGivenRank(customerFilePath, 1)); assertEquals(12,codingCompCsVUtil.getAgentIdGivenRank(customerFilePath, 4)); assertEquals(14,codingCompCsVUtil.getAgentIdGivenRank(customerFilePath, 20)); } - + //#10 @Test public void getCountCustomersWithClaims() { Map csvFilePaths = new HashMap<>(); - + csvFilePaths.put(customerList, customerFilePath); csvFilePaths.put(claimList, claimFilePath); - + assertEquals(81,codingCompCsVUtil.getCustomersWithClaims(csvFilePaths, Short.valueOf("1")).size()); assertEquals(312,codingCompCsVUtil.getCustomersWithClaims(csvFilePaths, Short.valueOf("6")).size()); } } - diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF deleted file mode 100644 index e2a1a34..0000000 --- a/target/classes/META-INF/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Manifest-Version: 1.0 -Built-By: yc1d -Build-Jdk: 1.8.0_201 -Created-By: Maven Integration for Eclipse - diff --git a/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.properties b/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.properties deleted file mode 100644 index fe569e3..0000000 --- a/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.properties +++ /dev/null @@ -1,7 +0,0 @@ -#Generated by Maven Integration for Eclipse -#Thu Oct 08 09:27:33 MST 2020 -version=1.0.0-SNAPSHOT -groupId=sf.codingcompetition2020 -m2e.projectName=coding-competition -m2e.projectLocation=/Users/yc1d/Development/coding-competition/problem/online-competition -artifactId=coding-competition diff --git a/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.xml b/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.xml deleted file mode 100644 index 21d55bf..0000000 --- a/target/classes/META-INF/maven/sf.codingcompetition2020/coding-competition/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - coding-competition - 1.0.0-SNAPSHOT - jar - sf.codingcompetition2020 - - coding-competition - Coding Competition - - - - - - - junit - junit - 4.12 - test - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-csv - 2.11.2 - - - - diff --git a/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class b/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class deleted file mode 100644 index 00daba9..0000000 Binary files a/target/classes/sf/codingcompetition2020/CodingCompCsvUtil.class and /dev/null differ diff --git a/target/classes/sf/codingcompetition2020/structures/Agent.class b/target/classes/sf/codingcompetition2020/structures/Agent.class deleted file mode 100644 index 26bf31f..0000000 Binary files a/target/classes/sf/codingcompetition2020/structures/Agent.class and /dev/null differ diff --git a/target/classes/sf/codingcompetition2020/structures/Claim.class b/target/classes/sf/codingcompetition2020/structures/Claim.class index 1ce796d..c63eaa1 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..da96fab 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..91281ed 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..aac84e7 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 deleted file mode 100644 index 765ac60..0000000 Binary files a/target/test-classes/sf/codingcompetition2020/CodingCompCsvUtilTest.class and /dev/null differ