This repository was archived by the owner on Oct 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathCodingCompCSVUtil.java
More file actions
254 lines (231 loc) · 8.96 KB
/
CodingCompCSVUtil.java
File metadata and controls
254 lines (231 loc) · 8.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
package codingcompetition2019;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CodingCompCSVUtil {
private final String ALL_CATEGORIES = "ALL";
private final String COMMA_DELIMITER = ",";
private final String SKIP_HEADER = "SKIP_HEADER";
private final String ALL_DISASTERS = "All natural disasters";
private final int ENTITY_COLMN = 0;
private final int YEAR_COLMN = 2;
private final int INCIDENTS_COLMN = 3;
/**
* Returns a list of all the records parsed by country
* @param fileName the csv filename
* @param countryName the country
* @return the list of all records
* @throws IOException if file is not found
*/
public List<List<String>> readCSVFileByCountry(String fileName, String countryName) throws IOException {
return helperReadCSVFile(fileName, countryName);
}
/**
* Returns a list of all the records with the first header line
* @param fileName the csv filename
* @return the list of all the records
* @throws IOException if file is not found
*/
public List<List<String>> readCSVFileWithHeaders(String fileName) throws IOException {
return helperReadCSVFile(fileName, ALL_CATEGORIES);
}
/**
* Returns a list of all the records without the first header line
* @param fileName the csv filename
* @return the list of all the records
* @throws IOException if file is not found
*/
public List<List<String>> readCSVFileWithoutHeaders(String fileName) throws IOException {
return helperReadCSVFile(fileName, SKIP_HEADER);
}
/**
* Returns a disaster description containing the most impactful year
* @param records the records from the csv file
* @return the disaster description with the most impactful year
*/
public DisasterDescription getMostImpactfulYear(List<List<String>> records) {
return helperGetMostImpactfulYear(ALL_CATEGORIES, records);
}
/**
* Returns a disaster description containing the most impactful year by category
* @param category the category of the record
* @param records the records from the csv file
* @return the disaster description with the most impactful year by category
*/
public DisasterDescription getMostImpactfulYearByCategory(String category, List<List<String>> records) {
return helperGetMostImpactfulYear(category, records);
}
/**
* Returns the most impactful disaster for the specified year.
* @param year the specified year
* @param records the records from the csv file
* @return the disaster description with the most impactful year
*/
public DisasterDescription getMostImpactfulDisasterByYear(String year, List<List<String>> records) {
String maxCategory = null;
int maxDisaster = 0;
for (List<String> record : records) {
if (!getLineEntity(record).equals(ALL_DISASTERS)) {
if (getLineYear(record).equals(year)) {
String category = getLineEntity(record);
int numDisasters = Integer.parseInt(getNumIncidents(record));
if (numDisasters > maxDisaster) {
maxDisaster = numDisasters;
maxCategory = category;
}
}
}
}
return new DisasterDescription(year, maxCategory, maxDisaster);
}
/**
* Returns the total number of incidents based on the records that match the category.
* @param category the category of records
* @param records the records from the csv file
* @return the total number of reported incidents
*/
public DisasterDescription getTotalReportedIncidentsByCategory(String category, List<List<String>> records) {
return helperGetTotalReportedIncidents(category, records);
}
/**
* This method will return the count if the number of incident falls within the provided range.
* To simplify the problem, we assume:
* + A value of -1 is provided if the max range is NOT applicable.
* + A min value can be provided, without providing a max value (which then has to be -1 like indicated above).
* + If a max value is provided, then a max value is also needed.
*/
public int countImpactfulYearsWithReportedIncidentsWithinRange(List<List<String>> records, int min, int max) {
if (max == -1) {
max = Integer.MAX_VALUE;
}
int numYearsInRange = 0;
for (List<String> record : records) {
if (Integer.parseInt(getNumIncidents(record)) >= min && Integer.parseInt(getNumIncidents(record)) <= max) {
numYearsInRange++;
}
}
return numYearsInRange;
}
/**
* Determines whether the first record has more total incidents than the second record.
* @param records1 the first csv file records
* @param records2 the second csv file records
* @return true if the first csv file has more incidents or false otherwise
*/
public boolean firstRecordsHaveMoreReportedIndicents(List<List<String>> records1, List<List<String>> records2) {
return helperGetTotalReportedIncidents(ALL_CATEGORIES, records1).getReportedIncidentsNum() > helperGetTotalReportedIncidents(ALL_CATEGORIES, records2).getReportedIncidentsNum();
}
/**
* Helper method to get the total number of incidents that match the category.
* @param category the category of incidents or all categories
* @param records the records from the csv file
* @return a disaster description object containing the total reported incidents
*/
public DisasterDescription helperGetTotalReportedIncidents (String category, List<List<String>> records) {
boolean allCategories = false;
if (category.equals(ALL_CATEGORIES)) {
allCategories = true;
}
DisasterDescription disaster = new DisasterDescription("N/A", category, 0);
for (List<String> record : records) {
if (!allCategories && !getLineEntity(record).equals(category)) {
continue;
}
disaster.addReportedIncidents(Integer.parseInt(getNumIncidents(record)));
}
return disaster;
}
/**
* Helper method to get the most impactful year (most number of incidents) by category.
* @param category the category of the entity in the record or all categories
* @param records the records from the csv file
* @return the disaster description containing the most impactful year
*/
public DisasterDescription helperGetMostImpactfulYear (String category, List<List<String>> records) {
boolean allCategories = false;
if (category.equals(ALL_CATEGORIES)) {
allCategories = true;
}
String mostImpactfulYear = null;
int maxYearImpact = 0;
for (List<String> record : records) {
if (!allCategories && !getLineEntity(record).equals(category)) {
continue;
}
int currImpact = Integer.parseInt(getNumIncidents(record));
if (currImpact > maxYearImpact) {
maxYearImpact = currImpact;
mostImpactfulYear = getLineYear(record);
}
}
return new DisasterDescription(mostImpactfulYear);
}
/**
* Helper method to parse csv file based on the specified parameters. Extra parameter is ALL_CATEGORIES
* if entire csv file needs to be parsed, SKIP_HEADER if entire csv needs to be parsed without header,
* or the country name if a specific country needs to be parsed.
*
* @param fileName the csv file
* @param extraParam the extra parameter (all categories/skip header/country name)
* @return a list of all the entries in csv file matching the query
* @throws IOException if file is not found
*/
private List<List<String>> helperReadCSVFile(String fileName, String extraParam) throws IOException{
boolean allCategories = false;
boolean header = true;
if (extraParam.equals(SKIP_HEADER)) {
header = false;
allCategories = true;
} else if (extraParam.equals(ALL_CATEGORIES)) {
allCategories = true;
}
List<List<String>> csvFile = new ArrayList<List<String>>();
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = "";
while ((line = br.readLine()) != null) {
if (!header) {
header = true;
continue;
}
String[] lineData = line.split(COMMA_DELIMITER, -1);
List<String> lineDataList = Arrays.asList(lineData);
if (!allCategories && !getLineEntity(lineDataList).equals(extraParam)) {
continue;
}
csvFile.add(lineDataList);
}
} catch(FileNotFoundException e) {
e.printStackTrace();
}
return csvFile;
}
/**
* Helper method returns the year from the current line in csv file.
* @param lineData current line in csv file
* @return year of current line
*/
private String getLineYear(List<String> lineData) {
return lineData.get(YEAR_COLMN);
}
/**
* Helper method returns the entity from the current line in csv file.
* @param lineData current line in csv file
* @return entity of current line
*/
private String getLineEntity(List<String> lineData) {
return lineData.get(ENTITY_COLMN);
}
/**
* Helper method returns the number of incidents from the current line in csv file.
* @param lineData current line in csv file
* @return year of current line
*/
private String getNumIncidents(List<String> lineData) {
return lineData.get(INCIDENTS_COLMN);
}
}