proj6/Collision.java
proj6/Collision.java
package
proj6
;
import
java
.
util
.
ArrayList
;
/**
* Collision objects represent individual collisions occuring on NYC streets.
* Each object contains information regarding the time, location, number
* of injuries and fatalities and types of involved vehicles.
*
@author
Joanna K.
*
*/
public
class
Collision
implements
Comparable
<
Collision
>
{
static
private
SortOrder
sortOrder
=
SortOrder
.
ZIP
;
private
String
date
;
private
String
time
;
private
String
borough
;
private
String
zip
;
private
int
personsInjured
;
private
int
personsKilled
;
private
int
pedestriansInjured
;
private
int
pedestriansKilled
;
private
int
cyclistsInjured
;
private
int
cyclistsKilled
;
private
int
motoristsInjured
;
private
int
motoristsKilled
;
private
String
vehicleCode1
;
private
String
vehicleCode2
;
private
String
uniqueKey
;
/**
* Creates a Collision object given an array of entries.
* There should be 21 string entries in the following order:
* date
* time
* borough
* zip
* lattitude^
* longitude ^
* on street name^
* cross street name ^
* personsInjured
* personsKilled
* pedestriansInjured
* pedestriansKilled
* cyclistsInjured
* cyclistsKilled
* motoristsInjured
* motoristsKilled
* contributing factor vehicle 1^
* contributing factor vehicle 2^
* uniqueKey
* vehicleCode1
* vehicleCode2
* The entries indicated with ^ are not used.
*
*
@param
entries an array of entries containing information about the
* collision
*
@throws
IllegalArgumentException when the Collision object cannot be created
* due to errors or incompleteness of the entries parameter
*/
public
Collision
(
ArrayList
<
String
>
entries
)
throws
IllegalArgumentException
{
date
=
entries
.
get
(
0
);
time
=
entries
.
get
(
1
);
borough
=
entries
.
get
(
2
);
zip
=
entries
.
get
(
3
);
if
(
!
verifyZip
(
zip
))
{
throw
new
IllegalArgumentException
(
"invalid zip"
);
}
try
{
personsInjured
=
Integer
.
parseInt
(
entries
.
get
(
8
));
personsKilled
=
Integer
.
parseInt
(
entries
.
get
(
9
));
pedestriansInjured
=
Integer
.
parseInt
(
entries
.
get
(
10
));
pedestriansKilled
=
Integer
.
parseInt
(
entries
.
get
(
11
));
cyclistsInjured
=
Integer
.
parseInt
(
entries
.
get
(
12
));
cyclistsKilled
=
Integer
.
parseInt
(
entries
.
get
(
13
));
motoristsInjured
=
Integer
.
parseInt
(
entries
.
get
(
14
));
motoristsKilled
=
Integer
.
parseInt
(
entries
.
get
(
15
));
}
catch
(
NumberFormatException
ex
)
{
throw
new
IllegalArgumentException
(
ex
.
getMessage
()
);
}
uniqueKey
=
entries
.
get
(
18
);
vehicleCode1
=
entries
.
get
(
19
);
vehicleCode2
=
entries
.
get
(
20
);
}
/*
* Verifies accuracy of the zip code.
* @param zip the zip code to be verified
* @return true if zip is a valid zip code, false otherwise
*/
private
boolean
verifyZip
(
String
zip
)
{
if
(
zip
.
length
()
!=
5
)
return
false
;
for
(
int
i
=
0
;
i
<
zip
.
length
();
i
++
)
{
if
(
!
Character
.
isDigit
(
zip
.
charAt
(
i
)
)
)
{
return
false
;
}
}
return
true
;
}
/**
* Computes and returns string representation of this Collision object.
*
@see
java.lang.Object#toString()
*/
@
Override
public
String
toString
()
{
return
"Collision [date="
+
date
+
", time="
+
time
+
", borough="
+
borough
+
", zip="
+
zip
+
", personsInjured="
+
personsInjured
+
", personsKilled="
+
personsKilled
+
", pedestriansInjured="
+
pedestriansInjured
+
", pedestriansKilled="
+
pedestriansKilled
+
", cyclistsInjured="
+
cyclistsInjured
+
", cyclistsKilled="
+
cyclistsKilled
+
", motoristsInjured="
+
motoristsInjured
+
", motoristsKilled="
+
motoristsKilled
+
", vehicleCode1="
+
vehicleCode1
+
", vehicleCode2="
+
vehicleCode2
+
", uniqueKey="
+
uniqueKey
+
"]"
;
}
/**
* Set the sort order for Collision objects to be one of the allowed values by the SortOrder enumerator.
*
@param
sortOrder the sortOrder to set
*/
public
static
void
setSortOrder
(
SortOrder
sortOrder
)
{
Collision
.
sortOrder
=
sortOrder
;
}
/**
* Compares two Collision objects based on their zip code, number of cyclist-injuries or
* number of person-injuries. The comparison is determined by the value of a flag set by
* setSortOrder() method.
*
@see
java.lang.Comparable#compareTo(java.lang.Object)
*/
@
Override
public
int
compareTo
(
Collision
other
)
{
if
(
sortOrder
==
SortOrder
.
ZIP
)
{
return
this
.
zip
.
compareTo
(
other
.
zip
);
}
else
if
(
sortOrder
==
SortOrder
.
CYCLISTS
)
{
return
(
(
this
.
cyclistsInjured
+
this
.
cyclistsKilled
)
-
(
other
.
cyclistsInjured
+
this
.
cyclistsKilled
)
);
}
else
if
(
sortOrder
==
SortOrder
.
PERSONS
)
{
return
(
(
this
.
personsInjured
+
this
.
personsKilled
)
-
(
other
.
personsInjured
+
this
.
personsKilled
)
);
}
return
0
;
}
/**
* Return the time of this Collision object.
*
@return
the time
*/
public
String
getTime
()
{
return
time
;
}
/**
* Return the zip code of this Collision object.
*
@return
the zip
*/
public
String
getZip
()
{
return
zip
;
}
/**
* Return the number of injured cyclists of this Collision object.
*
@return
the cyclistsInjured
*/
public
int
getCyclistsInjured
()
{
return
cyclistsInjured
;
}
/**
* Return the number of killed cyclists of this Collision object.
*
@return
the cyclistsKilled
*/
public
int
getCyclistsKilled
()
{
return
cyclistsKilled
;
}
/**
* Return the number of injured persons of this Collision object.
*
@return
the personsInjured
*/
public
int
getPersonsInjured
()
{
return
personsInjured
;
}
/**
* Return the number of killed persons of this Collision object.
*
@return
the personsKilled
*/
public
int
getPersonsKilled
()
{
return
personsKilled
;
}
/**
* Return the number of injured pedestrians of this Collision object.
*
@return
the pedestriansInjured
*/
public
int
getPedestriansInjured
()
{
return
pedestriansInjured
;
}
/**
* Return the number of killed pedestrians of this Collision object.
*
@return
the pedestriansKilled
*/
public
int
getPedestriansKilled
()
{
return
pedestriansKilled
;
}
/**
* Return the number of injured motorists of this Collision object.
*
@return
the motoristsInjured
*/
public
int
getMotoristsInjured
()
{
return
motoristsInjured
;
}
/**
* Return the number of killed motorists of this Collision object.
*
@return
the motoristsKilled
*/
public
int
getMotoristsKilled
()
{
return
motoristsKilled
;
}
/**
* Return the vehicle 1 of this Collision object.
*
@return
the vehicleCode1
*/
public
String
getVehicleCode1
()
{
return
vehicleCode1
;
}
/**
* Return the vehicle 2 of this Collision object.
*
@return
the vehicleCode2
*/
public
String
getVehicleCode2
()
{
return
vehicleCode2
;
}
}
proj6/CollisionInfo.java
proj6/CollisionInfo.java
package
proj6
;
import
java
.
io
.
File
;
import
java
.
io
.
FileNotFoundException
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Scanner
;
/**
* This is a program that computes some information about the data posted by
* OpenNYC regarding the collision records on the streets of NYC.
*
*
@author
Joanna K.
*
*/
public
class
CollisionInfo
{
/**
* The main method that starts the program. It is responsible for opening and reading the
* input file, creating the CollisionList object and using it compute the
* predetermined results.
*
@param
args the array should contain the name of the input file as the first element,
* all other elements are ignored
*
@throws
FileNotFoundException if the input file is corrupted or vanishes during the
* execution of this program
*/
public
static
void
main
(
String
[]
args
)
throws
FileNotFoundException
{
final
int
NUM_OF_ENTRIES
=
21
;
long
startTimer
,
elapsedTime1
,
elapsedTime2
;
startTimer
=
System
.
nanoTime
();
if
(
args
.
length
<
1
)
{
System
.
err
.
println
(
"File name missing"
);
System
.
exit
(
0
);
}
File
fileName
=
new
File
(
args
[
0
]);
if
(
!
fileName
.
canRead
())
{
System
.
err
.
printf
(
"Cannot read from file %s\n."
,
fileName
.
getAbsolutePath
());
System
.
exit
(
0
);
}
Scanner
fin
=
new
Scanner
(
fileName
);
CollisionList
list
=
new
CollisionList
();
while
(
fin
.
hasNextLine
()
)
{
String
textLine
=
fin
.
nextLine
();
ArrayList
<
String
>
words
=
split
(
textLine
)
;
if
(
words
.
size
()
!=
NUM_OF_ENTRIES
)
{
continue
;
//skip lines that are not complete
}
list
.
add
(
words
);
}
elapsedTime1
=
System
.
nanoTime
()
-
startTimer
;
startTimer
=
System
.
nanoTime
();
//task 1
System
.
out
.
println
(
"ZIP codes with the largest number of collisions:"
);
System
.
out
.
println
(
list
.
getZipCodesWithMostCollisions
(
3
)
);
//task2
System
.
out
.
println
(
"ZIP codes with the fewest number of collisions:"
);
System
.
out
.
println
(
list
.
getZipCodesWithLeastCollisions
(
3
)
);
//task 3
System
.
out
.
println
(
"ZIP codes with the most injuries and fatalities (combined):"
);
System
.
out
.
println
(
list
.
getZipCodesWithMostPersonIncidents
(
3
)
);
//task 4
System
.
out
.
println
(
"ZIP codes with the most cyclist injuries and fatalities:"
);
System
.
out
.
println
(
list
.
getZipCodesWithMostCyclistIncidents
(
3
)
);
//task5:
System
.
out
.
println
(
"Percentage of collisions involving certain vehicle type:"
);
System
.
out
.
println
(
list
.
getVehicleTypeStats
());
//task6:
System
.
out
.
println
(
"Fraction of collisions by hour:"
);
System
.
out
.
println
(
list
.
getHourlyStats
());
elapsedTime2
=
System
.
nanoTime
()
-
startTimer
;
System
.
out
.
println
(
"\n\n============================================\n"
);
System
.
out
.
printf
(
"Reading and storing data: %,15d nanoseconds\n"
,
elapsedTime1
);
System
.
out
.
printf
(
"Computation of results : %,15d nanoseconds\n"
,
elapsedTime2
);
fin
.
close
();
}
/**
* Splits a given line according to commas (commas within entries are ignored)
*
@param
textLine line of text to be parsed
*
@return
an ArrayList object containing all individual entries/tokens
* found on the line.
*/
public
static
ArrayList
<
String
>
split
(
String
textLine
)
{
ArrayList
<
String
>
entries
=
new
ArrayList
<
String
>
();
int
lineLength
=
textLine
.
length
();
StringBuffer
nextWord
=
new
StringBuffer
();
char
nextChar
;
boolean
insideQuotes
=
false
;
for
(
int
i
=
0
;
i
<
lineLength
;
i
++
)
{
nextChar
=
textLine
.
charAt
(
i
);
//add character to the current entry
if
(
nextChar
!=
','
&&
nextChar
!=
'"'
)
{
nextWord
.
append
(
nextChar
);
}
//double quote found, decide if it is opening or closing one
else
if
(
nextChar
==
'"'
)
{
if
(
insideQuotes
)
{
insideQuotes
=
false
;
}
else
{
insideQuotes
=
true
;
}
}
//found comma inside double quotes, just add it to the string
else
if
(
nextChar
==
','
&&
insideQuotes
)
{
nextWord
.
append
(
nextChar
);
}
//end of the current entry reached, add it to the list of entries
//and reset the nextWord to empty string
else
if
(
nextChar
==
','
&&
!
insideQuotes
)
{
//trim the white space before adding to the list
entries
.
add
(
nextWord
.
toString
().
trim
()
);
nextWord
=
new
StringBuffer
();
}
else
{
System
.
err
.
println
(
"This should never be printed.\n"
);
}
}
//add the last word
//trim the white space before adding to the list
entries
.
add
(
nextWord
.
toString
().
trim
()
);
return
entries
;
}
}
proj6/CollisionList.java
proj6/CollisionList.java
package
proj6
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Collections
;
import
java
.
util
.
Comparator
;
/**
* CollisionList class stores a list of collisions. The organization of this list is
* based on the zip code associated with a given collision. This organization simplifies
* processing of collisions that occur within a particular zip code.
*
@author
Joanna K.
*/
public
class
CollisionList
{
private
ArrayList
<
ZipCodeList
>
list
;
/**
* Creates an empty CollisionList object.
*/
public
CollisionList
()
{
list
=
new
ArrayList
<
ZipCodeList
>
();
}
/**
* Adds a particular record to this CollisionList object.
* The record should consist of 21 string entries in the following order:
* date
* time
* borough
* zip
* lattitude^
* longitude ^
* on street name^
* cross street name ^
* personsInjured
* personsKilled
* pedestriansInjured
* pedestriansKilled
* cyclistsInjured
* cyclistsKilled
* motoristsInjured
* motoristsKilled
* contributing factor vehicle 1^
* contributing factor vehicle 2^
* uniqueKey
* vehicleCode1
* vehicleCode2
* The entries indicated with ^ are not used.
*
*
@param
record an list of string describing a particular collision (see above
* for order of entries)
*
@return
true if the record was added to this CollisionList object, false if any
* problem occurred and the record was not added
*/
public
boolean
add
(
ArrayList
<
String
>
record
)
{
try
{
Collision
col
=
new
Collision
(
record
);
ZipCodeList
tmp
=
new
ZipCodeList
(
col
);
int
index
=
list
.
indexOf
(
tmp
);
if
(
index
>=
0
)
{
//add the collision object to the existing zip code list
list
.
get
(
index
).
add
(
col
);
}
else
{
//add the new zip code list
list
.
add
(
tmp
);
}
}
catch
(
IllegalArgumentException
ex
)
{
return
false
;
//return false if the Collision constructor failed
}
return
true
;
//return true to indicate that the object was added
}
/**
* Determines k zip codes with most collisions in this CollisionList object.
*
@param
k number of zip codes with the highest number of collisions
*
@return
a string formatted as
* zip numOfCollisions
* one per line, that contains k zip codes with the highest number of collisions
*/
public
String
getZipCodesWithMostCollisions
(
int
k
)
{
@
SuppressWarnings
(
"unchecked"
)
ArrayList
<
ZipCodeList
>
sortedList
=
(
ArrayList
<
ZipCodeList
>
)
list
.
clone
();
//sort the list
Collections
.
sort
(
sortedList
,
new
CompareByNumOfCollisionsDescending
()
);
StringBuffer
result
=
new
StringBuffer
();
int
count
=
0
;
for
(
int
i
=
0
;
i
<
k
&&
i
<
sortedList
.
size
()
&&
count
<
sortedList
.
size
();
i
++
)
{
do
{
result
.
append
(
String
.
format
(
" %5s %5d collisions\n"
,
sortedList
.
get
(
count
).
getZip
(),
sortedList
.
get
(
count
).
getTotalNumOfCollisions
()));
count
++
;
}
while
(
count
+
1
<
sortedList
.
size
()
&&
sortedList
.
get
(
count
).
getTotalNumOfCollisions
()
==
sortedList
.
get
(
count
+
1
).
getTotalNumOfCollisions
()
)
;
}
return
result
.
toString
();
}
/**
* Determines k zip codes with least collisions in this CollisionList object.
*
@param
k number of zip codes with the lowest number of collisions
*
@return
a string formatted as
* zip numOfCollisions
* one per line, that contains k zip codes with the lowest number of collisions
*/
public
String
getZipCodesWithLeastCollisions
(
int
k
)
{
@
SuppressWarnings
(
"unchecked"
)
ArrayList
<
ZipCodeList
>
sortedList
=
(
ArrayList
<
ZipCodeList
>
)
list
.
clone
();
//sort the list
Collections
.
sort
(
sortedList
,
new
CompareByNumOfCollisionsAscending
()
);
StringBuffer
result
=
new
StringBuffer
();
int
count
=
0
;
for
(
int
i
=
0
;
i
<
k
&&
i
<
sortedList
.
size
()
&&
count
<
sortedList
.
size
();
i
++
)
{
do
{
result
.
insert
(
0
,
String
.
format
(
" %5s %5d collisions\n"
,
sortedList
.
get
(
count
).
getZip
(),
sortedList
.
get
(
count
).
getTotalNumOfCollisions
()));
count
++
;
}
while
(
count
+
1
<
sortedList
.
size
()
&&
sortedList
.
get
(
count
).
getTotalNumOfCollisions
()
==
sortedList
.
get
(
count
+
1
).
getTotalNumOfCollisions
()
)
;
}
return
result
.
toString
();
}
/**
* Determines k zip codes with most number of collisions involving
* cyclists in this CollisionList object.
*
@param
k number of zip codes with the highest number of collisions that involved cyclists
*
@return
a string formatted as
* zip numOfCycliststHurt (numOfCyclists killed)
* one per line, that contains k zip codes with the highest number of injured cyclists
*/
public
String
getZipCodesWithMostCyclistIncidents
(
int
k
)
{
@
SuppressWarnings
(
"unchecked"
)
ArrayList
<
ZipCodeList
>
sortedList
=
(
ArrayList
<
ZipCodeList
>
)
list
.
clone
();
//sort the list
CompareByNumOfCyclistsIncidentsDescending
comp
=
new
CompareByNumOfCyclistsIncidentsDescending
()
;
Collections
.
sort
(
sortedList
,
comp
);
StringBuffer
result
=
new
StringBuffer
();
int
inj
=
0
,
killed
=
0
;
int
count
=
0
;
for
(
int
i
=
0
;
i
<
k
&&
i
<
sortedList
.
size
()
&&
count
<
sortedList
.
size
();
i
++
)
{
do
{
inj
=
sortedList
.
get
(
count
).
getTotalNumOfCyclistsInjured
();
killed
=
sortedList
.
get
(
count
).
getTotalNumOfCyclistsKilled
();
result
.
append
(
String
.
format
(
" %5s %5d (%3d killed ) cyclists hurt\n"
,
sortedList
.
get
(
count
).
getZip
(),
inj
+
killed
,
killed
));
count
++
;
}
while
(
count
+
1
<
sortedList
.
size
()
&&
0
==
comp
.
compare
(
sortedList
.
get
(
count
),
sortedList
.
get
(
count
+
1
)
)
)
;
}
return
result
.
toString
();
}
/**
* Determines k zip codes with most number of injured and killed persons.
*
@param
k number of zip codes with the highest number of injured and killed persons
*
@return
a string formatted as
* zip numOfPersonsHurt (numOfPersons killed)
* one per line, that contains k zip codes with the highest number of injured persons
*/
public
String
getZipCodesWithMostPersonIncidents
(
int
k
)
{
@
SuppressWarnings
(
"unchecked"
)
ArrayList
<
ZipCodeList
>
sortedList
=
(
ArrayList
<
ZipCodeList
>
)
list
.
clone
();
//sort the list
CompareByNumOfPersonsIncidentsDescending
comp
=
new
CompareByNumOfPersonsIncidentsDescending
()
;
Collections
.
sort
(
sortedList
,
comp
);
StringBuffer
result
=
new
StringBuffer
();
int
inj
=
0
,
killed
=
0
;
int
count
=
0
;
for
(
int
i
=
0
;
i
<
k
&&
i
<
sortedList
.
size
()
&&
count
<
sortedList
.
size
();
i
++
)
{
do
{
inj
=
sortedList
.
get
(
count
).
getTotalNumOfPersonsInjured
();
killed
=
sortedList
.
get
(
count
).
getTotalNumOfPersonsKilled
();
result
.
append
(
String
.
format
(
" %5s %5d (%3d killed ) persons hurt\n"
,
sortedList
.
get
(
count
).
getZip
(),
inj
+
killed
,
killed
));
count
++
;
}
while
(
count
+
1
<
sortedList
.
size
()
&&
0
==
comp
.
compare
(
sortedList
.
get
(
count
),
sortedList
.
get
(
count
+
1
)
)
)
;
}
return
result
.
toString
();
}
/**
* Computes percentage of total collisions in this CollisionList object that involved one
* of the following vehicle types: taxi, bus, bicycle, truck, fire truck and ambulance.
*
@return
a string containing the results of the computation
*/
public
String
getVehicleTypeStats
(
)
{
String
result
=
new
String
();
int
taxi
=
0
;
int
bus
=
0
;
int
bicycle
=
0
;
int
fireTruck
=
0
;
int
ambulance
=
0
;
int
totalNumOfCollisions
=
0
;
for
(
ZipCodeList
l
:
list
)
{
totalNumOfCollisions
+=
l
.
getTotalNumOfCollisions
();
for
(
Collision
c
:
l
)
{
if
(
c
.
getVehicleCode1
().
equalsIgnoreCase
(
"taxi"
)
||
c
.
getVehicleCode2
().
equalsIgnoreCase
(
"taxi"
))
taxi
++
;
if
(
c
.
getVehicleCode1
().
equalsIgnoreCase
(
"bus"
)
||
c
.
getVehicleCode2
().
equalsIgnoreCase
(
"bus"
))
bus
++
;
if
(
c
.
getVehicleCode1
().
equalsIgnoreCase
(
"bicycle"
)
||
c
.
getVehicleCode2
().
equalsIgnoreCase
(
"bicycle"
))
bicycle
++
;
if
(
c
.
getVehicleCode1
().
equalsIgnoreCase
(
"fire truck"
)
||
c
.
getVehicleCode2
().
equalsIgnoreCase
(
"fire truck"
))
fireTruck
++
;
if
(
c
.
getVehicleCode1
().
equalsIgnoreCase
(
"ambulance"
)
||
c
.
getVehicleCode2
().
equalsIgnoreCase
(
"ambulance"
))
ambulance
++
;
}
}
//create a string object with results
result
+=
String
.
format
(
" %-11s %5.2f%%\n"
,
"taxi"
,
(
float
)(
taxi
)
/
totalNumOfCollisions
*
100
);
result
+=
String
.
format
(
" %-11s %5.2f%%\n"
,
"bus"
,
(
float
)(
bus
)
/
totalNumOfCollisions
*
100
);
result
+=
String
.
format
(
" %-11s %5.2f%%\n"
,
"bicycle"
,
(
float
)(
bicycle
)
/
totalNumOfCollisions
*
100
);
result
+=
String
.
format
(
" %-11s %5.2f%%\n"
,
"fire truck"
,
(
float
)(
fireTruck
)
/
totalNumOfCollisions
*
100
);
result
+=
String
.
format
(
" %-11s %5.2f%%\n"
,
"ambulance"
,
(
float
)(
ambulance
)
/
totalNumOfCollisions
*
100
);
return
result
;
}
/**
* Computes percentage of total collisions in this CollisionList object that occured within
* a particular hour. The collisions are placed into bins of 1 hour intervals.
*
@return
a string containing the results of the computation
*/
public
String
getHourlyStats
(
)
{
StringBuffer
result
=
new
StringBuffer
()
;
//counter for each hour
int
[]
hourlyCount
=
new
int
[
24
];
String
hour
=
""
,
time
=
""
;
StringBuffer
bar
;
int
totalNumOfCollisions
=
0
;
for
(
ZipCodeList
l
:
list
)
{
totalNumOfCollisions
+=
l
.
getTotalNumOfCollisions
();
for
(
Collision
c
:
l
)
{
try
{
//extract the hour from the time entry
time
=
c
.
getTime
();
hour
=
time
.
substring
(
0
,
time
.
indexOf
(
':'
)).
trim
();
//increment counter for that hour
hourlyCount
[
Integer
.
parseInt
(
hour
)]
++
;
}
catch
(
IndexOutOfBoundsException
e
)
{
//ignore incorrectly formed times
}
catch
(
NumberFormatException
e
)
{
//ignore incorrectly formed times
}
}
}
for
(
int
i
=
0
;
i
<
24
;
i
++
)
{
//determine number of "bars" to be printed for visual representation of
//the histogram
int
numOfBars
=
(
int
)(((
double
)
hourlyCount
[
i
]
/
totalNumOfCollisions
)
*
240
);
bar
=
new
StringBuffer
(
numOfBars
);
for
(
int
j
=
0
;
j
<
numOfBars
;
j
++
)
bar
.
append
(
"|"
);
result
.
append
(
String
.
format
(
"%3d h %5.1f%% %s%n"
,
i
,
100.0
*
hourlyCount
[
i
]
/
totalNumOfCollisions
,
bar
.
toString
()
));
}
return
result
.
toString
();
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of collisions occurring in each. The resulting order is ascending.
* @author Joanna K.
*
*/
class
CompareByNumOfCollisionsAscending
implements
Comparator
<
ZipCodeList
>
{
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
return
arg0
.
getTotalNumOfCollisions
()
-
arg1
.
getTotalNumOfCollisions
();
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of collisions occurring in each. The resulting order is descending.
* @author Joanna K.
*
*/
class
CompareByNumOfCollisionsDescending
implements
Comparator
<
ZipCodeList
>
{
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
return
arg1
.
getTotalNumOfCollisions
()
-
arg0
.
getTotalNumOfCollisions
();
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of injured persons. The resulting order is descending. Ties are resolved
* based on the number of killed persons.
* @author Joanna K.
*
*/
class
CompareByNumOfPersonsIncidentsDescending
implements
Comparator
<
ZipCodeList
>
{
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
int
diff
=
(
arg1
.
getTotalNumOfPersonsInjured
()
+
arg1
.
getTotalNumOfPersonsKilled
())
-
(
arg0
.
getTotalNumOfPersonsInjured
()
+
arg0
.
getTotalNumOfPersonsKilled
())
;
if
(
diff
!=
0
)
return
diff
;
else
return
(
arg1
.
getTotalNumOfPersonsKilled
()
-
arg0
.
getTotalNumOfPersonsKilled
()
);
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of injured persons. The resulting order is ascending. Ties are resolved
* based on the number of killed persons.
* @author Joanna K.
*
*/
class
CompareByNumOfPersonsIncidentsAscending
implements
Comparator
<
ZipCodeList
>
{
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
int
diff
=
-
(
arg1
.
getTotalNumOfPersonsInjured
()
+
arg1
.
getTotalNumOfPersonsKilled
())
+
(
arg0
.
getTotalNumOfPersonsInjured
()
+
arg0
.
getTotalNumOfPersonsKilled
())
;
if
(
diff
!=
0
)
return
diff
;
else
return
(
-
arg1
.
getTotalNumOfPersonsKilled
()
+
arg0
.
getTotalNumOfPersonsKilled
()
);
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of injured cyclists. The resulting order is descending. Ties are resolved
* based on the number of killed cyclists.
* @author Joanna K.
*
*/
class
CompareByNumOfCyclistsIncidentsDescending
implements
Comparator
<
ZipCodeList
>
{
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
int
diff
=
(
arg1
.
getTotalNumOfCyclistsInjured
()
+
arg1
.
getTotalNumOfCyclistsKilled
())
-
(
arg0
.
getTotalNumOfCyclistsInjured
()
+
arg0
.
getTotalNumOfCyclistsKilled
())
;
if
(
diff
!=
0
)
return
diff
;
else
return
(
arg1
.
getTotalNumOfCyclistsKilled
()
-
arg0
.
getTotalNumOfCyclistsKilled
()
);
}
}
/*
* Comparator class for comparing two @see ZipCodeList objects based on the
* number of injured cyclists. The resulting order is ascending. Ties are resolved
* based on the number of killed cyclists.
* @author Joanna K.
*
*/
class
CompareByNumOfCyclistsIncidentsAscending
implements
Comparator
<
ZipCodeList
>
{
@
Override
public
int
compare
(
ZipCodeList
arg0
,
ZipCodeList
arg1
)
{
int
diff
=
-
(
arg1
.
getTotalNumOfCyclistsInjured
()
+
arg1
.
getTotalNumOfCyclistsKilled
())
+
(
arg0
.
getTotalNumOfCyclistsInjured
()
+
arg0
.
getTotalNumOfCyclistsKilled
())
;
if
(
diff
!=
0
)
return
diff
;
else
return
(
-
arg1
.
getTotalNumOfCyclistsKilled
()
+
arg0
.
getTotalNumOfCyclistsKilled
()
);
}
}
proj6/SortOrder.java
proj6/SortOrder.java
package
proj6
;
/**
* Enumerator used to decide on sort order of Collision objects.
*
@author
Joanna K.
*
*/
enum
SortOrder
{
ZIP
,
CYCLISTS
,
PERSONS
}
proj6/ZipCodeList.java
proj6/ZipCodeList.java
package
proj6
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Iterator
;
/**
* ZipCodeList contains collision objects that all occured in the same zip
* code. It keeps track of additional information like total number of
* collisions, injuries and fatalities.
*
@author
Joanna K.
*
*/
public
class
ZipCodeList
implements
Iterable
<
Collision
>
,
Comparable
<
ZipCodeList
>
{
private
ArrayList
<
Collision
>
list
;
private
String
zip
;
private
int
totalNumOfCollisions
;
private
int
totalNumOfPersonsInjured
;
private
int
totalNumOfPersonsKilled
;
private
int
totalNumOfCyclistsInjured
;
private
int
totalNumOfCyclistsKilled
;
private
int
totalNumOfPedestriansInjured
;
private
int
totalNumOfPedestriansKilled
;
private
int
totalNumOfMotoristsInjured
;
private
int
totalNumOfMotoristsKilled
;
/**
* Creates a ZipCodeList objects based on the first collision. The
* zip code for this ZipCodeList is set to the zip code
* associated with the collision col.
*
@param
col the initial collisions for this ZipCodeList object
*/
public
ZipCodeList
(
Collision
col
)
{
list
=
new
ArrayList
<
Collision
>
()
;
zip
=
col
.
getZip
();
add
(
col
);
}
/**
* Adds another Collision object to this ZipCodeList object.
*
@param
col a Collision object to be added to this ZipCodeList object
*
@throws
IllegalArgumentException when the zip code of the new Collision
* object col is not the same as the zip code for this ZipCodeList object
*/
public
void
add
(
Collision
col
)
throws
IllegalArgumentException
{
if
(
col
==
null
)
return
;
if
(
!
col
.
getZip
().
equals
(
zip
))
throw
new
IllegalArgumentException
(
"Error: zip codes are not matching. "
)
;
list
.
add
(
col
);
totalNumOfCollisions
++
;
totalNumOfPersonsInjured
+=
col
.
getPersonsInjured
();
totalNumOfPersonsKilled
+=
col
.
getPersonsKilled
();
totalNumOfCyclistsInjured
+=
col
.
getCyclistsInjured
();
totalNumOfCyclistsKilled
+=
col
.
getCyclistsKilled
();
totalNumOfPedestriansInjured
+=
col
.
getPedestriansInjured
();
totalNumOfPedestriansKilled
+=
col
.
getPedestriansKilled
();
totalNumOfMotoristsInjured
+=
col
.
getMotoristsInjured
();
totalNumOfMotoristsKilled
+=
col
.
getMotoristsKilled
();
}
/**
* Returns an iterator for this ZipCodeList object.
*
@see
java.lang.Iterable#iterator()
*/
@
Override
public
Iterator
<
Collision
>
iterator
()
{
return
list
.
iterator
();
}
/**
* Computes the hash code for this ZipCodeList object. The hashcode
* is based on the zip code associated with this object.
*
@see
java.lang.Object#hashCode()
*/
@
Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
((
zip
==
null
)
?
0
:
zip
.
hashCode
());
return
result
;
}
/**
* Returns true if this ZipCodeList object and the parameter have the
* same zip code associated with them. Returns false otherwise.
*
@see
java.lang.Object#equals(java.lang.Object)
*/
@
Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
ZipCodeList
other
=
(
ZipCodeList
)
obj
;
if
(
zip
==
null
)
{
if
(
other
.
zip
!=
null
)
return
false
;
}
else
if
(
!
zip
.
equals
(
other
.
zip
))
return
false
;
return
true
;
}
/**
* Compares two ZioCodeList objects based on the zip code value stored in them.
* The results are based on string comparison of the two zip codes.
*
@see
java.lang.Comparable#compareTo(java.lang.Object)
* Compares two ZipCodeList objects based on the zip codes.
*/
@
Override
public
int
compareTo
(
ZipCodeList
o
)
{
return
zip
.
compareTo
(
o
.
zip
);
}
/**
* Returns the zip code of this ZipCodeList object
*
@return
the zip
*/
public
String
getZip
()
{
return
zip
;
}
/**
* Returns the total number of collisions of this ZipCodeList object
*
@return
the totalNumOfCollisions
*/
public
int
getTotalNumOfCollisions
()
{
return
totalNumOfCollisions
;
}
/**
* Returns the total number of persons injured of this ZipCodeList object
*
@return
the totalNumOfPersonsInjured
*/
public
int
getTotalNumOfPersonsInjured
()
{
return
totalNumOfPersonsInjured
;
}
/**
* Returns the total number of persons killed of this ZipCodeList object
*
@return
the totalNumOfPersonsKilled
*/
public
int
getTotalNumOfPersonsKilled
()
{
return
totalNumOfPersonsKilled
;
}
/**
* Returns the total number of cyclists injured of this ZipCodeList object
*
@return
the totalNumOfCyclistsInjured
*/
public
int
getTotalNumOfCyclistsInjured
()
{
return
totalNumOfCyclistsInjured
;
}
/**
* Returns the total number of cyclists killed of this ZipCodeList object
*
@return
the totalNumOfCyclistsKilled
*/
public
int
getTotalNumOfCyclistsKilled
()
{
return
totalNumOfCyclistsKilled
;
}
/**
* Returns the total number of pedestrians injured of this ZipCodeList object
*
@return
the totalNumOfPedestriansInjured
*/
public
int
getTotalNumOfPedestriansInjured
()
{
return
totalNumOfPedestriansInjured
;
}
/**
* Returns the total number of pedestrians killed of this ZipCodeList object
*
@return
the totalNumOfPedestriansKilled
*/
public
int
getTotalNumOfPedestriansKilled
()
{
return
totalNumOfPedestriansKilled
;
}
/**
* Returns the total number of motorists injured of this ZipCodeList object
*
@return
the totalNumOfMotoristsInjured
*/
public
int
getTotalNumOfMotoristsInjured
()
{
return
totalNumOfMotoristsInjured
;
}
/**
* Returns the total number of motorists killed of this ZipCodeList object
*
@return
the totalNumOfMotoristsKilled
*/
public
int
getTotalNumOfMotoristsKilled
()
{
return
totalNumOfMotoristsKilled
;
}
/**
* Computes and returns a string representation of this ZipCodeList object.
*
@see
java.lang.Object#toString()
*/
@
Override
public
String
toString
()
{
return
"ZipCodeList for "
+
zip
+
": "
+
totalNumOfCollisions
+
", "
+
totalNumOfPersonsInjured
+
", "
+
totalNumOfPersonsKilled
+
", "
+
totalNumOfCyclistsInjured
+
", "
+
totalNumOfCyclistsKilled
+
", "
+
totalNumOfPedestriansInjured
+
", "
+
totalNumOfPedestriansKilled
+
", "
+
totalNumOfMotoristsInjured
+
", "
+
totalNumOfMotoristsKilled
;
}
}
CSCI-UA 102 sec 3,5, Fall 2015 Programming Project 6
Joanna Klukowska [email protected]
Programming Project 6: NYPD Motor Vehicle Collisions Analysis - Revisited
Due date: Dec. 11, 11:55 PM EST.
You may discuss any of the assignments with your classmates and tutors (or anyone else) but all work for all assignments must be entirely your own. Any sharing or copying of assignments will be considered cheating. If you get significant help from anyone, you should acknowledge it in your submission (and your grade will be proportional to the part that you completed on your own). You are responsible for every line in your program: you need to know what it does and why. You should not use any data structures or features of Java that have not been covered in class (or the prerequisite class). If you have doubts whether or not you are allowed to use certain structures, just ask your instructor.
In this project you will revisit your project 1 implementation of a program that used the NYPD motor vehicle collision data. A version of the solution to the original project is provided (it has been slightly modified from the specification of the original project). You should use that implementation as the basis for your project 6 solution.
Please, see project 1 for the details of tasks and implementation requirements.
Objectives
The goal of this programming project is for you to master (or at least get practice on) the following tasks:
• using/modifying existing code
• selecting data structures appropriate for given tasks
• writing Java programs
The Program Input and Output
You should not change this part of the implementation.
There are three data sets posted on the course website that you should be using for this project. The largest of them contains all collision data for the entire NYC from July 1, 2012 till June 30, 2015 (three years total). The medium size data set contains all collision data for the entire NYC from July 1, 2013 till June 30, 2015 (two years total). Finally, the smallest data set contains all collision data for the entire NYC from July 1, 2014 till June 30, 2015 (one year total).
For testing purposes, you may wish to use smaller data sets.
Computational Task
The posted program stores all the Collision objects in an ArrayList of ZipCodeList objects. The ZipCodeList object, in turn, stores all Collision objects from a particular zip code in an ArrayList of collisions.
At this point in the semester, you should realize that this is not an optimal way of organizing the data. Your task for this project is to modify how the Collision objects are stored in memory when the program is running in order to improve the time performance of the program.
1
CSCI-UA 102 sec 3,5, Fall 2015 Programming Project 6
Joanna Klukowska [email protected]
You do not need to provide implementation of any data structures yourself. You should use the implementations provided by Java API. You should only use the data structures that we discussed in class during this semester. Here is the list with links to Java API interfaces and classes:
• linked list https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html
• stack https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html
• queue https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html (any of the implementing classes)
• (self-balancing) binary search tree http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html
• priority queue https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html
• hashtable https://docs.oracle.com/javase/8/docs/api/java/util/Map.html (any of the implementing classes)
You are not supposed to use all of the above data structures. Your task is to decide which of them could improve the time performance of the program and use those.
You may wish to try several different changes. In your final program you should leave only the changes that resulted in a better time performance of the program. All other changes should be described in the written report (see below).
Written Report: Performance Analysis
You should write a 1-2 page report that summarizes the results of this project. Your report should include justification for why particular data structures are appropriate and others are not. You may wish to include time comparison results for different sizes of data sets that you obtain with the provided version of the code and with your modified version of the code. If you tried some of the data structures and they did not turn out to be appropriate, mention that in your report.
If you decide to include graphs and tables, those do not count towards the 2-page limit.
Program Design
You should only change parts of the design of this program that are related to change in data structures. Overall program design should remain the same.
Programming Rules
You should follow the rules outlined in the document Code conventions posted on the course website at http://cs.nyu.edu/ ˜joannakl/cs102_f15/notes/CodeConventions.pdf.
You must document all your code using Javadoc. Your class documentation needs to provide a description of what it is used for and the name of its author. Your methods need to have description, specification of parameters, return values, exceptions thrown and any assumptions that they are making.
A class’s data fields and methods should not be declared static unless they are to be shared by all instances of the class or provide access to such data.
You must use the provided implementation of the program and modify only the parts that change the storage of Collision objects.
Grading
Make sure that you are following all the rules in the Programming Rules section above.
If your program does not compile or crashes (almost) every time it is ran, you will get a zero on the assignment.
2
CSCI-UA 102 sec 3,5, Fall 2015 Programming Project 6
Joanna Klukowska [email protected]
If the program does not adhere to the specification, the grade will be low and will depend on how easy it is to figure out what the program is doing.
30 points choice and use of data structures,
40 points written report with analysis of the observations,
10 points use of existing program structure,
20 points proper documentation and program style (for the parts of the code that you modify; you should add your name as the author for the classes that you modify).
How and What to Submit
Your should submit all your source code files (the ones with .java extensions only) and your report (in PDF format) in a single zip file to NYU Classes. If you are unsure how to create a zip file or how to get to your source code files, you should ask long before the project is due.
If you wish to use your (one and only) freebie for this project (one week extension, no questions asked), then complete the form at http://goo.gl/forms/YFDVBlscEB before the due date for the assignment. All freebies are due seven days after the original due date and should be submitted to NYU Classes.
3

Get help from top-rated tutors in any subject.
Efficiently complete your homework and academic assignments by getting help from the experts at homeworkarchive.com