G.L.I.F.R.P. (Good Life Index For Real People)

Computer Science 2XB3

McMaster University, Faculty of Engineering

Group 05: Pasindu Gunasekara, Nick Morrison, Roberto Temelkovski, Juan Carlos Santana, Teodor Voinea

Version Number: 3 (Caterpillar)

April 11, 2016

Table of Contents

Table of Contents

Page 1

Revision Page

Page 2

Contribution Page

Page 3

Executive Summary

Page 4

Module Interface Specification (MIS)

Page 4-11

  • City,Main,OpenStreetMapWrapper,Sorting,Graph,Node, Edge,State,Usa,Query

Module Implementation Details (MID)

Page 12-18

  • City,Main,OpenStreetMapWrapper,Sorting,Graph,Node, Edge,State,Usa,Query

Class Diagram

Page 19

Uses Relationship

Page 20

Traceability Matrix

Page 20

Design Review

Page 21-23

Revision

The Revised Project can be found in Revised-Project.pdf (latest version in 2XB3 group dropbox).

By virtue of submitting this document we electronically sign and date that

the  work  being  submitted  by  all  the  individuals  in  the  group  is  their  ex-

clusive work as a group and we consent to make available the application

developed  through  [CS]  or  [SE]-2XB3  project,  the  reports,  presentations,

and assignments (not including my name and student number) for future

teaching purposes.

Team Members & Roles:

Name

Student Number

Role

Pasindu Gunasekara

001412155

Programmer

Nick Morrison

001426613

Front End Lead, Log Admin

Juan Carlos Santana

001411625

Project Manager

Roberto Temelkovski

001418731

Programmer

Teodor Voinea

001409586

Back End Lead

Contribution Page

Name

Role

Contribution

Pasindu Gunasekara

Programmer

Parse Data Sets, Query Information, programmer, Design Document

Nick Morrison

Front End Lead, Log Admin

Front end, UI, testing, project log,  Requirement Specs Document

Juan Carlos Santana

Project Manager

Project Plan, Scoring Algorithm,Crime Weighting, Revised Requirement Specs Document, Revised Project Document

Roberto Temelkovski

Programmer

Graph,  Graph searching algorithms, programmer,testing, Design Document

Teodor Voinea

Back End Lead

Set up backend Server and host on AWS, Sorting Algorithm, Design Document

Executive Summary

When looking to purchase a home it can be a daunting task. Especially when you are not familiar with States, Cities, and neighborhoods. The Good Life Index For Real People (GLIFRP) web application will let users know key information about the cities that they are interested in living in. GLIFRP attempts to make one of life’s major decision just a little bit easier and will use open data sets from data.gov. GLIFRP enables users to find cities and it will show key information about that city. It will give the searched area a score. There will be sliders that determine how much emphasis is put on the different attributes. Which will allow the users to make better informed decisions when purchasing homes in cities.  The project will also show simple statistical information such as crime rate and housing price index. GLIFRP will not allow you to see individual rental properties, homes, and apartments. This project will be more focused on cities and the surrounding areas as a whole. It will help people make informed decisions on cities based on their general wellness. It will not be involved in real estate and rental properties directly.

Module Interface Specification

City Specification

USES

None

VARIABLES 

None

ACCESS PROGRAMS

getLat() : String

Returns the latitude of the city as String

getLong() : String

Returns the longitude of the city as String

getCrime() : double

Returns the crime rate of the city as double

getZip() : String

Returns the zip code as String

getPrice() : double

Returns the price as a double

getScore() : double

Returns the score as double

getName() : String

Returns the name as String

getState() : String

Returns the abbreviated state as String

getUState() : String

Returns the un-abbreviated state as String

getPopulation() : int

Returns the population as integer

getViolentCrime() : int

Returns the violent crime as integer

getMurder() : int

Returns the murder as integer

getRape() : int

Returns the rape as integer

getRobbery() : int

Returns the robbery as integer

getAssault() : int

Returns the assault as integer

getProperty() : int

Returns the property as integer

getBurglary() : int

Returns the burglary as integer

getMotor() : int

Returns the motor incidents as integer

getArson() : int

Returns the arson as integer

getPlace_name() : String

Returns the place name as String

getPlace_id() : String

Returns the place id as String

getIndex_nsa() : double

Returns the non adjusted as double

getIndex_sa() : double

Returns the seasonally adjusted as double

getYear() : int

Returns the year as integer

getPriceInflation() : double

Returns inflation as double

setInflation() : void

Calculates inflation based on index_sa and index_sa

setCrime(double d) : void

Takes a double and sets the crime value

setZip(String zip) : void

Takes a String and sets the zip code

setPrice(double d) : void

Takes a double and sets the price

setScore() : void

Calls a private method to calculate the score

setLat(String lat) : void

Takes a String and sets the latitude

setLong(String longe) : void

        Sets the longitude for the City.

setState(String state) : void

Takes a String and sets the abbreviated state

setUState(String ustate) : void

Takes a String and sets the unabbreviated state

setName(String name) : void

Takes a String and sets the name

setPopulation(int population) : void

Takes an integer and sets the population

setViolentCrime(int violentCrime) : void

Takes an integer and sets the violent crime

setMurder(int murder) : void

Takes an integer and sets the murder

setRape(int rape) : void

Takes an integer and sets the rape

setRobbery(int robbery) : void

Takes an integer and sets the robbery.

setAssault(int assault) : void

Takes an integer and sets the assault.

setProperty(int property) : void

Takes an integer and sets the property.

setBurglary(int burglary) : void

Takes an integer and sets the burglary.

setLarceny(int larceny) : void

Takes an integer and sets the larceny.

setMotor(int motor) : void

Takes an integer and sets the motor incidents.

setArson(int arson) : void

Takes an integer and sets the arson.

setPlace_name(String place_name) : void

Takes a String and sets the place_name.

setPlace_id(String place_id) : void

Takes a String and sets the place_id.

setPeriod(int period) : void

Takes an integer and sets the period.

setIndexNSA(int index_nsa) : void

Takes an integer and sets the index_nsa.

setIndexSA(int index_sa) : void

Takes an integer and sets the index_sa.

setYear(int year) : void

Takes an integer and sets the year

compareTo(Comparable o, int attribute) : void

Takes a City object and an integer (which is used to represent the different city attributes) and returns -1 if the argument city object is larger, 0 if the objects are equals or 1 if the argument city object is smaller.

equals(City c) : boolean

Takes a City object and compares their names, true if they’re equal, false otherwise.

Main Specification

USES

OpenStreetMapWrapper

Query

USA

VARIABLES

None

ACCESS PROGRAMS

        main() : void

The main entrance for the program. Starts the server and serves GET/POST requests.

OpenStreetMapWrapper Specification

USES

None

VARIABLES

None

ACCESS PROGRAMS

buildByZip(String zip_code) : void

Takes in a String zip_code. Queries openstreetmap with zip_code. Based on the response, sets city name, state, latitude, longitude

buildByLatLong(String[] latlong) : void

Takes in an array of length 2 of Strings [latitude,longitude]. Queries openstreetmap with lat/long. Based on the response, sets city name, state, zip code.

buildByCityState(String city_name, String city_state) : void

Takes in 2 Strings (city name, state name). Queries openstreetmap with city name and state name. Based on the response, sets city name, state, latitude, longitude, zip code.

getZip() : String

Returns zipcode of the previously queried object as String.

getLat() : String

Returns latitude of the previously queried object as String.

getLon() : String

Returns longitude of the previously queried object as String.

getName() : String

Returns name of the previously queried object as String.

getState() : String

Returns state of the previously queried object as String.

Sorting Specification

USES

        None

VARIABLES

        None

ACCESS PROGRAMS

        SortByType(int attribute, Comparable[] CitiesArray) : void

Sorts the Comparable array using the best sorting algorithm based on the attribute passed in.

Graph Specification

USES

Node

Edge

VARIABLES

None

ACCESS PROGRAMS

getNodeCount() : int

        Returns the amount of nodes in the graph

getNode(int id) : Node

Takes in an id and returns the node with that id

addNode(Node n) : void

        Takes in a Node n and adds it to the list of nodes

connectNodes(int weight, Node i, Node j): void

        Creates an edge between Nodes i and j with the specified weight, stores it in the list of edges

contains(Node n): boolean

        Takes in a Node and returns true if that Node is in the graph, false if not

isEmpty(): boolean

        Returns true if there is no nodes in this graph, false if not

Node Specification

USES

None

VARIABLES

None

ACCESS PROGRAMS

getId() : int

        Returns the ID of the node

setMarked(boolean marked) : void

Takes in a boolean to set the marked property of this node (whether it has been visited)

isMarked() : boolean

        Returns true if the node has been visited, false if it has not

getAdjacent(): ArrayList<Node>

        Returns the list of adjacent nodes as an arraylist

getNextAdjacent(): ArrayList<Node>

        Return the next adjacent node from the list of adjacent nodes (whatever node is at adjacentCount’s position)

addAdjacent(Node n): void

        Add a new node to the list of adjacent nodes

toString(): String

        Returns the string representation of the node

equals(Node node): boolean

        Takes in another Node and returns true if they have the same Id

hasNeighbour(Node node): boolean

        Takes in another Node and returns true if it is in the adjacency arraylist of this node

Edge Specification

USES

Node

VARIABLES

        None

ACCESS PROGRAMS

getVerticies(): Node[]

Return the two nodes that are connected by this edge

hasVertex(Node v) : boolean

Takes in a Node object, and returns true if one of the nodes connected by this edge is the passed in node

getWeight() : int

Returns the weight of the edge

State Specification

USES

Query

City

Sort

Node

VARIABLES

None

ACCESS PROGRAMS

insertCity(String c) : void

Takes in a City object or a List of City Objects and adds it/them to the list of Cities

compareState(City c) : void

Takes in a City and returns true if the city’s state is the same as this state

contains(City c) : void

Takes in a City and checks to see whether this

findLowestCrimeRate(int length) : ArrayList<City>

Takes in a number length and returns n cities with the lowest crime rate in this state

equalsName(State node) : void

Takes in either a Node or the name of the State (as a String) and returns true if the current state is equal to the parameter, else returns false.

equalsCode(State node) : void

Takes in a Node State and returns true if the current state is equal to the parameter, else returns false.

equalsCode(State node) : void

Takes in  a code of the State and returns true if the current state is equal to the parameter, else returns false.

equalsName(String node) : void

Takes in  a code of the State (as a String) and returns true if the current state is equal to the parameter, else returns false.

setName(String name) : void

Takes in a name and sets the of the state to this name

getName():String

Returns the name of this state

setCode(String code) : void

Takes in the state code of the state and sets the state code of this state to equal that state code

getCode() : String

Returns the state code

toString() : String

Returns the string representation of the state

Usa Specification

USES

State

City

Node

Graph

Query

VARIABLES

None

ACCESS PROGRAMS

findStateByState(State s) : State

Takes in a State object and returns the corresponding state

findStateByStateName(State s) : State

Takes in the State’s name and returns that matches that name

findStateByCity(City c) : State

Takes in a City and finds the State which contains this City

getNeighbouringStates(State state, int distance) : ArrayList<State>

Takes in a start state and a distance (states away) and returns all the the states within the distance of the start state

getHops(State state, State state2) : int

Get the amount of hops between two states

findLowestCrimeRate(ArrayList<State> states,int length) : ArrayList<City>

Takes in a list of states and an amount of cities n, returns the n lowest crime rate cities in the states passed in. Alternatively, this can take just an amount of cities n and returns the n lowest crime rate cities in the entire united states.

findLowestCrimeRate(int length) : ArrayList<City>

Takes in a list of states and an amount of cities n, returns the n lowest crime rate cities in the states passed in. Alternatively, this can take just an amount of cities n and returns the n lowest crime rate cities in the entire united states.

addCity(String c) : void

Add a City to the state

containsState(State state) : boolean

Takes in a State and returns true if that state is already in the list of states, false otherwise

printUSA() : void

Prints out information about all the states in the USA data structure

Query Specification

USES

City

VARIABLES

None

ACCESS PROGRAMS

getCityData(String city) : City

Populates City object with data for the city c. Returned as a new City object.

getLowestCrime(String state, int n) : ArrayList<City>

Returns a list of cities of size n, that have the lowest crime rates within the state, state, as a list of strings.

getCityByCrime(City c) :

Gets housing data for city c, and returns it as a City object.

getStateNames() : ArrayList<String>

Returns a list of all the states in the United States as Strings.

getCityNames(String state) : ArrayList<String>

Returns a list of all cities within the state, state, as Strings.

Module Implementation Details

Main Implementation

USES

OpenStreetMapWrapper

Query

USA

VARIABLES

usa : Usa

USA object used to get information about all the states, and cities within the United states in order to create the initial Graph.

gson : Gson

A Gson object used to respond to GET requests, with information about a city.

Mapwrap : OpenStreetMapWrapper

OpenStreetMap wrapper object used to fill in missing information about latitude and longitude within city objects.

q : Query

Used to query information about a city or state from the Query class.

ACCESS PROGRAMS

        main() : void

The main entrance for the program. Starts the server and serves GET/POST requests. Creates the following endpoints, /searchLCMByState, /search, /index. Instantiates the USA graph in order for it to be used for searching. The spark library handles the asynchronous calls to the lambda functions built into main. The lambda functions are what allow us to build all of the endpoints. Additionally, the whole function is wrapped in a try-catch so as to not crash the server on a bad input. The server response on error creates a 500 HTTP error code and prints the stacktrace.

City Implementation

USES

None

VARIABLES

lat : String

Holds the latitude of the City.

        lon : String

Holds the longitude of the City.

        zip : String

                Holds the zip code of the City.

        crime : double

                Holds the crime rate of the city.

        price : double

                Holds the price inflation of the City.

        Score : double

                Holds the score that the city will receive once its calculated.

        State : String

                Holde the abbreviated name of the state.

        uState : String

                Holds the full name of the state.

population,violentCrime, murder, rape,robbery, assault, property ,         burglary, larceny, motor, arson : int

        All the data for crimes that get pulled from a query. These are

all the different crime that will be used for scoring and throughout the GLIFRP program.

        place_name : String

                Holde the name of the City

        place_id : int

                Holds a unique City Id

index_nsa, index_sa, inflation : double

Variables that get pulled from a query and are used to calculate the score.

        period : int

                Holds the time period of price indices.

        Year : int

                Holds the year of the price indices

ACCESS PROGRAMS

calculateScore(int crimeWeight, int indexWeight) : void

Calculates the score based on the variables set in the private class. The weight for the different crimes are  wtArson = 8,

wtAssualt = 8, wtBurglary = 5, wtLarceny = 7, wtMotor = 5 , wtMurder = 15, wtProperty = 7, wtRape = 10, wtRobbery = 5,

wtViolentCrime = 15. The maxScore is 500. It calculated all the crimes with the weights then divides by the city population. Then it takes that resualt and multiplies it by the crimeWieght variables. The subtracts that result from the maxScore.

        calculateCrimeRate() : double

Takes the sum of all the crimes divided by the population of the city.

        totalCrime() : double

Calculates the total crime based on all the crime weights. (Sum of all the crimes).

Sorting Implementation

USES

        None

VARIABLES

        sortBy : int

                The attribute by which to sort the given Comparable array

ACCESS PROGRAMS

        mergeSort(Comparable[] a, Comparable[] aux, int lo, int hi) : void

                Sorts the array of Comparables using merge sort

        quickSort(Comparable[] a, int lo, int hi) : void

                Sorts the array of Comparables using quick sort

        quickSort3way(Comparable[] a, int lo, int hi) : void

                Sorts the array of Comparables using 3 way quick sort

        shellSort(Comparable[] a) : void

                Sorts the array of Comparables using shell sort

        heapSort(Comparable[] pq) : void

                Sorts the array of Comparables using heap sort

        sink(Comparable[] pq, int k, int N) : void

                Sinks the item at index k in the Comparable array pq of size N

        exch(Object[] a, int i, int j) : void

                Exchanges the object at index i in the Object array a with the object at index j

        partition(Comparable[] a, int lo, int hi) : int

        less(Comparable v, Comparable w) : boolean

                Compares the Comparable v with Comparable w and returns true if v < w

        less(Comparable[] pq, int i, int j) : boolean

Compares the item at index i in the Comparable array pq with the item at index j and returns true if pq[i] < pq[j]

        merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) : void

                Merges the sub array a[lo to mid] with a[mid to hi] in a sorted manner

Node Implementation

USES

None

VARIABLES

adjacent : ArrayList<Node>

adjacentCount : int

id : int

visited : boolean

        

Edge Implementation

USES

Node

VARIABLES

        v1 : Node

v2 : Node

        weight: int

State Implementation

USES

Query

City

Sort

Node

VARIABLES

name : String

        Name of the state

code : String

        Code for the state (IE Arizona’s code would be “AZ”

        cities : ArrayList<String>

                A list of the names of the cities in the state

        q : Query

                The object used to make all the SQL queries

ACCESS PROGRAMS

insertCity(String c) : void

Takes in a City object or a List of City Objects and adds it/them to the list of Cities

compareState(City c) : void

Takes in a City and returns true if the city’s state is the same as this state

contains(City c) : void

Takes in a City and checks to see whether this

findLowestCrimeRate(int length) : ArrayList<City>

Takes in a number length and returns n cities with the lowest crime rate in this state

equalsName(State node) : void

Takes in either a Node or the name of the State (as a String) and returns true if the current state is equal to the parameter, else returns false.

equalsCode(State node) : void

Takes in a Node State and returns true if the current state is equal to the parameter, else returns false.

equalsCode(State node) : void

Takes in  a code of the State and returns true if the current state is equal to the parameter, else returns false.

equalsName(String node) : void

Takes in  a code of the State (as a String) and returns true if the current state is equal to the parameter, else returns false.

setName(String name) : void

Takes in a name and sets the of the state to this name

getName():String

Returns the name of this state

setCode(String code) : void

Takes in the state code of the state and sets the state code of this state to equal that state code

getCode() : String

Returns the state code

toString() : String

Returns the string representation of the state

Graph Implementation

USES

Node

Edge

VARIABLES

nodes : ArrayList<Node>

        The list of all the nodes in the graph

edges : ArrayList<Edge>

        The list of all edges in the graph

ACCESS PROGRAMS

edgeWith(Node v1, Node v2) : Edge

Takes in two nodes and returns the edge that connects the two nodes if there is one. Returns null if no edge connects these nodes

Usa Implementation

USES

Node

Edge

Query

Graph

VARIABLES

nodes : ArrayList<Node>

        The list of all the nodes in the graph

edges : ArrayList<Edge>

        The list of all edges in the graph

q : Query

        Object used for all the SQL queries

currentId : int

An ID counter that keep tracks of how many states have been made so that not states have the same ids

ACCESS PROGRAMS

limitedBFSSearch(State state, int distance) : ArrayList<State>

Takes in a state object, and a distance (how many layers of BFS to work with).

Then it performs a BFS and returns the list of all the states within the layers searched

findDistance(State state, State end): int

Takes in a start state and an end state, runs a BFS from the start state to find how many layers have to be explored before you reach the end state. When it finds the end states, it returns the number of layers explored (which is the state distance from the start state to the end state)

        lcmHelper(ArrayList<State> states, int length) : void

Helper function that takes in an array to hold all the cities, a number of cities named length and state. Runs a DFS and adds length cities from each state to the cities array.

        addState(State c) : void

                Takes in a State object and adds it to the list of states

        generateState() : void

Reads in a file of state pairs and for each creates the state objects and connects the relevant state objects together. Afterwards you are left witha fully loaded graph that is connected where it should be

        getStateFromStateCode(String s): State[]

Takes in a state codes and gives the corresponding state objects (“AZ” returns “Arizona” object)

        DFS(Object target, Node n, int flag) : void

Takes in an object to work with, a start node and a flag for the operation. The ADD_CITY_FLAG allows you to find the state that a city should be in and inserts it (The first parameter object is your city).

        rDFS(Object target, Node curNode, int flag): Object

Takes in an object to work with, a start node and a flag for the operation. FIND_STATE_BY_STATE_FLAG takes in a state as the first parameter, and runs DFS to find the State that corresponds to the state passed in and returns it. The FIND_STATE_BY_CITY_FLAG takes in a City as the first object,runs DFS and returns the State that the city is found in. The FIND_STATE_BY_STATE_NAME_FLAG takes in a state name, runs DFS and returns the state object which has the name that you passed.

Query Implementation

USES

        None

VARIABLES

         dbc, dbh : String

dbc holds the connection information for the crime database, dbh holds the connection information for the housing and the coordinate database. Sample connection string: “jdbc:sqlite:databaseName.db”

        queryCityData, queryCrimeData, queryCityData, queryNames : String

Holds the SQL query string for each type of query, crime, housing, and coordinate. Sample query string: “SELECT * FROM db WHERE id=’25’;”

city : City

City object to be populated when certain queries are called.

        stateNames, cityNames : ArrayList<String>

When getStateNames() and getCityNames()are called, each of these ArrayLists are populated with names of all the states in the united states, or names of all the cities in a certain state.

        lowestCrime : ArrayList<City>

When getLowestCrime(String state, int n) is called, this ArrayList is populated with an ‘n’ amount of cities with the lowest crime rates within the specified state. The size of the ArrayList will be the integer n.

        state : Map<String, String>

A hashmap used to hold a set of state Abbreviated states, and abbreviated states. Can be used to switch between the two different strings.

ACCESS PROGRAMS

getCityData(String city) : city

Finds all the data in all three databases for information about the city specified in the argument String. All single quotes are filtered out with escaped quotes in order for the SQL statement to be processed correctly. Sets queryCityData for all data from the Cities database. Sets queryHousingData for all data from the Houses database for the maximum year (2014 or 2015), in order to avoid duplicates. Sets queryCrimeData to get all crime data for the city. Returns the global city object that is now populated with data from all three databases.

getStateCode() : void

Populates the states Hashmap with data about the abbreviated and abbreviated states.

getLowestCrime(String state, int n) : ArrayList<City>

Runs a query on the Crime database by changing the queryCrimeData String. It then populates the lowestCrime ArrayList with a list of cities of size n, that have the lowest crime rates within the state, state, as a list of strings. lowestCrime ArrayList is returned.

getCityByCrime(City c) : city

Assigns the city variable within the module to be the City object within the argument. Then queries all Housing, and coordinate data within that city. Returns the city object that was just modified.

getStateNames() : ArrayList<String>

Searches the Cities database for all unique state names and adds them to the stateNames ArrayList as strings. Returns a list of all the states in the United States as an ArrayList of Strings.

getCityNames(String state) : city

Searches the Cities database for all city names within the state specified in the argument and adds them to the cityNames ArrayList as strings. Returns a list of all the states in the United States as an ArrayList of Strings.

Query() : Constructor

Sets up the initial database connection strings, and populates the state code hashmap.

Class Diagram

Where dotted arrows mean dependencies and use.

Uses relationship

Module (Class)                                        Uses

Main                                                        Graph, City

Graph                                                        Edge, Node, Usa

Edge                                                        None

Node                                                        None

Usa                                                        State

City                                                        Crime

State                                                        Query,Sorting

Query                                                        None

Sorting                                                        None

Crime                                                        None

Traceability Matrix

1

2

3

4

5

6

7

8

9

Main

X

X

Graph

X

X

Sorting

X

City

X

X

State

X

Query

X

X

Requirements

1.score

2.crime stats

3.searching for cities

4.Make a Graph of USA

5.Search Through USA Graph

6.Sort Cities based on Attribute

7.Web Application BackEnd

8. Searching endpoints

9. Have all cities in a state

Design Review

Understandability

What the software does and its purpose?

It helps users find a new city to move to based on criteria they provide in the search query.

The intended market and users of the software?

The intended market is the general US public which is currently looking to move to an area they may not be familiar.

Basic functions of the software?

Allows the user to input a state and city (or just state), the software then returns 9 cities that meet the default criteria.

Advanced functions of the software?

Allows the user to weigh the distance and crime rate of a city according to their needs to generate a more tailored response. Also, users can specify the quantity of cities they would like to see (more or less than the default: 9) by appending “, 10” at the end of their query.

Documentation

Quality

Comments are concise and descriptive.

Completeness

Every class is commented using the JavaDocs system.

All functions are commented, major variables and components are commented.

Accuracy

Comments accurately describe the code.

Appropriateness

Appropriate documents, not extensive, on point and expressive.

Clarity

Clear and explanatory comments. Describes the algorithms and data structures used.

README

Includes a README with styling using the github markdown. Includes images and text to describe running and testing the server.

Buildability

How straightforward is it to meet the build requirements on a build platform?

Requires Java 1.8 and Bower.

How straightforward is it to build the software on the build platform?

Instructions are included in the README. After installing Java 1.8 and Bower, it’s only a matter of cloning the project from GitHub and executing the precompiled jar.

Installability

How easy is it to install the software on  a target platform?

Users interact with the software as a website. Therefore any user with a modern web browser that supports javascript and an internet connection can use the software.

Learnability

How easy is it to learn the basic functional tasks?

The UI follows very closely to that of Google Maps and many other mapping websites. Therefore basic functionality should be intuitive to any previous users of those services.

How easy is it to the the advanced functional tasks?

Advanced tasks such as weighing crime rate and distance differently can be learned by experimenting with the search bar sliders. Selecting the quantity of cities to display is a hidden feature that can only be discovered by accident or reading the Git/provided examples.

Architecture

Extensibility

The software is easily extensible in many different ways. For example, adding new information for cities would simply require finding the new information in a database, adding new variables to the city class to store these new attributes, and adding the ability to sort by these new attributes. Updating previous databases with new information is also easy, so long the new information can be made to match the previous format of the database, no additional changes are required. The API is exposed publicly and can be used in other software projects.

Modularity

The classes (Usa, State) inherit from more generic classes (Graph, Node) so any US specific changes within Usa and State would not impact any other country we could add in the future. Cities are the same across the world so the sorting and searching algorithms are completely independent of the country those cities belong to. The server only hosts the API and serves 1 index page from a public (not-compiled) folder, so any changes to the UI would not impact the server and vise-versa

Concision

Clear variable names.

Short functions and methods that perform only one unique task.

Testing and Validation

Testing

We Incorporated physical distance as well as state dependent “hop” distance. Testing search/sort/graph algorithms with JUnit Testing for correctness.

Validation.

The Scoring algorithm takes into account the type of crime and the population of the city. Since the algorithm takes into account population it gives a more accurate representation of the city, and allows the bigger cities to be fairly represented.   Also, every crime was researched and each weighted according to punishments. A detailed analysis can be seen in the Crime_Correctness.pdf (can be found in the 2XB3 group dropbox).