Introduction


Hi! My name is Fong Zhi Zhong but you can call me Keith! I am currently a second year student at National University of Singapore studying Computer Science.
As a passionate programmer, I believe I can solve many problems through coding.

I am the team leader for Car Park Finder, a project for my CS2103T Software Engineering module, where I was in charge of UI (user interface), threading, scheduling and tracking.


Project: Car Park Finder


1. Overview

Car park Finder is a CLI (command line interface) application to find HDB (Housing Development Board) car parks in Singapore. It allows you to display a list of car parks with the convenience of typing. It provides crucial information like real time updates and cost of car parks. If you use the computer frequently and commute by driving, you would find our application useful in your daily lives.
Interested? Head towards our releases page to download and try it out! No installation is required.


2. Summary of contributions

Given below are sections I contributed to the development of the application. They showcase my technical depth and ability.

  • Major enhancement 1: Modified the find feature to search for partial words and ignore certain words.

    • What it does: Allows the user to search for partial instances of words without needed to type everything.

    • Justification: This feature improves the product significantly because a user can type lesser and the app should provide the same data still.

    • Highlights: This enhancement affects the existing commands and commands to be added in the future. I also wrote extra code which allowed us to re-use in the future.

  • Major enhancement 2: Integrated Google maps javascript api.

    • What it does: Every time the user sends a command, the display will be updated accordingly. E.g. Selecting a car park shows that one and only carpark.

    • Justification: This feature greatly improves the look and feel of the application. Plus it allows further more information to be displayed.

    • Highlights: This enhancement allows the user to see where the car park is in the entire map without needing to interact with the GUI itself.

  • Minor enhancements:

    • Pulled postal code information using coordinates data by querying an API to convert it to store in a file for quick loading.

    • Credits: [SVY21 to WGS84].

  • Code contributed: Click here to view my code on the CS2103T Project Code Dashboard.

  • Notable Contributions: [String Util], [Find Command], [Find Command Parser], [Gson test], [HTML, JS].

  • Other contributions:

    • Project management:

      • Morphed the code from address book to car park. [#1], [#5].

      • Morphed the test cases from address book to car park. [#15], [#25].

    • Enhancement of existing features:

      • Wrote additional test for existing features to increase coverage from 72% - 77% [#83].

      • Updated all test cases for existing features to increase coverage from 69% - 73% [#129].

    • Documentation:

      • Did cosmetics tweaks to existing contents of the User Guide: [#36], [#60], [#76], #125].

      • Updated contents of User Guide and Developer Guide: [#34], [#74], [#83], [#120].

    • Community:

      • PRs reviewed (with non-trivial review comments): [#28], [#37].

    • Tools:

      • Integrated Google Maps Javascript API [#89].

      • Integrated One Map API to convert coordinated to postal code [#83].


3. Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

3.1. Finding car parks : find

With a list of car parks, you can narrow down to just the car parks near your destination by either typing in the location or the specific car park number.

Format Abbreviation Example(s)

find KEYWORD

fin

find serangoon
fin HG83

  • Common words like BLK and AVE are ignored.

  • It does not matter whether the keywords are upper or lower case characters.


3.1.1. Example: How to find car parks by location

For this example, we will be looking at how to find all the car parks in Punggol.

find location
Figure 1. Found car parks in Punggol
Message: Found 53 car parks

53 car park(s) found!

Type find punggol into the Command Box. The message above should appear in the Message Box as confirmation that you typed in correctly. Found car parks in Punggol shows how it would look like, with the Google Maps zoomed in.

3.1.2. Example: How to find car park by car park number

find number
Figure 2. Found car parks in Punggol
Message: Found 1 car park

1 car park(s) found!

Type find PP5 into the Command Box. The message above should appear in the Message Box as confirmation that you typed in correctly. Found car parks in Punggol shows how it would look like, with the Google Maps zoomed in.

3.1.3. Example: Unable to find car park

If Car Park Finder is unable to find your location or car park number, it will display nothing.

Message: Found 0 car park

0 car park(s) found!

The message above will be shown, as well as an empty list in the Display Panel and no markers in the Google Maps.

3.2. Undoing commands: undo

Restores the list of car parks to the state before the previous undoable command was executed.

Format Abbreviation

undo

u / un / und

Only available for the following undoable commands:
query | find | filter | notify | clear

  • This does not turn off notification as it only affects the list of car parks.


3.2.1. Example: Successful undo

If you accidentally type an undoable command and wish to undo it, here is how.

Message: Success in undoing

Undo success!

Type undo into the Command Box. The message above should appear in the Message Box as confirmation that you typed in correctly.

3.2.2. Example: Unable to undo

Not all commands are undoable as there is a limit to the number of undo commands.

Message: Success in undoing

No more commands to undo!

If you see the message above in the Command Box it means there are no more undoable commands. You can also check the history to view what commands you have typed in so far.

3.3. Redoing commands : redo

Reverse the most recent undo command.

Format Abbreviation

redo

r / re / red

You can only redo after an undo command.

  • Like undo, this does not turn off notification as it only affects the list of car parks.

  • Redoable commands are the same as undoable commands.


3.3.1. Example: Successful redo

If you decided to redo the undo command, here is how.

Message: Success in redoing

Redo success!

Type redo into the Command Box. The message above should appear in the Message Box as confirmation that you typed in correctly.

3.3.2. Example: Unable to redo

You reach the end of how far you can redo. Take note that not all commands are undoable / redoable.

Message: Success in redoing

No more commands to redo!

If you see the message above in the Command Box it means there are no more redoable commands. You can also check the history to view what commands you have typed in so far.


4. Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

4.1. Find feature

The find feature searches for a car park by keyword or location.

4.1.1. Overview

The find mechanism is facilitated by FindCommand and FindCommandParser. It extends Command and implements the following operations:

  • FindCommand#execute() — Executes the command by running a predicate CarparkContainsKeywordsPredicate to update the car park list.

The find mechanism is supported by FindCommandParser. It implements Parser and contains the following operations:

  • FindCommandParser#parse() — Checks the arguments for empty strings and throws a ParseException if empty string is found. It then splits it by one or more white spaces. It then removes any strings in the list of common words.

The predicate CarparkContainsKeywordsPredicate takes in a list of strings and checks if any of the strings matches the name or address of a car park fully or partially.

FindSdForLogic
Figure 3. How the find operation works

The diagram above describes how the flow of a find command would execute. It rely on FindCommandParser to ensure the variables are correct.

4.1.2. Example

Given below is an example usage scenario of how the find mechanism behaves at each step.

Step 1. The user launches the application for the first time.

Step 2. The user executes find punggol command to get all car parks in punggol. The find command calls FindCommandParser#parse().

If a command execution fails, it will not call FindCommand#execute(), and the car park finder state will not be saved.

Step 3. The entire list of car parks is filtered by the predicate CarparkContainsKeywordsPredicate, which checks for the keyword punggol.

Step 4. The filtered list of car parks is returned to the GUI.

The flow chart below describes the user interaction with the application and how it processes it.

actdiagram findresize
Figure 4. Flow chart of the find operation.

4.1.3. Design Considerations

Aspect: How predicate works
  • Alternative 1 (Current choice): Predicate have additional filter with an ignore list.

    Pros

    Re-usable functions introduced for partial checking.

    Cons

    Reading the car park list while querying might cause unintended side effects if not handled properly.

  • Alternative 2: Filter the data when it is taken in.

    Pros

    Easy to maintain as predicate will have lesser conditions.

    Cons

    Breaks OOP style as the parser will modify the data.

4.2. UI

It is a combination of JavaFX, HTML and CSS. This section describes the challenges faced, how it was overcome and an example of how it works.

4.2.1. Overview

Initially, we wanted to showcase real time updates when the user issues a command. This would mean updating the HTML accordingly. However, we did not want to just update it, we wanted to showcase the selected car park or the filtered list accordingly.

4.2.2. Example

Step 1. The user launches the application and is greeted by this UI.

UiS1
Figure 5. On start of the application

Step 2. The user selects a car park with a select command. E.g. select 10.

UiS2
Figure 6. An example outcome of the select 10 command

SelectCommand#Execute is called. If the input is valid, it creates a JumpToListRequestEvent event for BrowserPanel#handleCarparkPanelSelectionChangedEvent() to catch.

Step 3. The user then list all the car park with a list command. A ListCarparkRequestEvent is created and BrowserPanel catches the event to call BrowserPanel#handleListCarparkRequestEvent()

UiS3
Figure 7. An example outcome of the list command

The HTML is refreshed to show all car parks.

4.2.3. Design Considerations

Aspect: HTML/CSS/JS design choices
  • Alternative 1 (Current choice): Have a callback function in javascript

    Pros

    Easy to implement google maps and stylesheet.

    Cons

    Hard to test. Different rendering between devices.

  • Alternative 2: Have a query in the url parameters to filter data and update iFrame

    Pros

    No rendering issue. Easy to test and debug.

    Cons

    Complex query and hard to understand again once working. Server must allow filtering by url paramters.

4.3. Postal Code

The postal code feature is built to allow easier finding of car park by knowing the postal code they are searching for. As the car park data from data.gov.sg does not have any postal code, we converted coordinates of each respective car park to a postal code whenever possible.

4.3.1. Overview

Currently, postal code data are stored in a separate file. This is due to it being too slow and unreliable to convert coordinate to postal code in real time. However, in order to generate the file, we went through every car park and found their respective postal code.

4.3.2. Example

Step 1. The user launches the application.

Step 2. The system loads the file, postalcodeData.txt into a Hashmap<Long,String> using the GsonUtil#loadCarparkPostalCode() where the key is a hash and the value is a postal code.

Step 3. The system goes through every car park’s coordinates and hashes them together with GsonUtil#fnvHash(x,y) where x is the x-coordinate of the carpark and y is the y-coordinate of the carpark.

Step 4. If the key is found, it will return the value which is the postal code of the car park. If not, it will return the default value 000000.

As certain car park do not have postal code, 000000 is the default value and a flag to show that the car park does not have a postal code.

4.3.3. Design Considerations

Aspect: Source of postal code information
  • Alternative 1 (Current choice): Pull data from file

    Pros

    Fast and efficient. No need to change due to no postal code changes.

    Cons

    Unable to update for new car parks. Requires user to download updated jar file.

  • Alternative 2: Pull data from API

    Pros

    Easy to update and scalable to new car parks.

    Cons

    Too slow to do in real time. Takes roughly 20 minutes to update all car park postal code. Not realistic and efficient to do in real time.

4.4. [Proposed] Data Encryption

The car park data and user data will be encrypted to prevent users from editing and manipulating them.

4.4.1. Overview

The data encryption mechanism works by encrypting the information by a unique key generated by every users individual system. The key will stored in a secured location to prevent people from accessing it.

The two main files it will encrypt are:

  • Car park information

  • User’s favorites

4.4.2. Example

This feature is coming in v2.0.