PROJECT: TutorPal


Overview

TutorPal is a desktop application used by private home tutors for managing student information. The useage is primarily through CLI. It is written in Java.

Summary of contributions

  • Major enhancement: enhanced FindCommand to make it support fuzzy matching

    • What it does: allows the user to find Person by name and supports fuzzy matching, which means even if the user has a small typo, it can still find Persons with similar names.

    • Justification: This feature enhancement makes this command more practical because sometimes users may type wrongly during searching. However, fuzzy matching allows small mistakes in typing and makes searching much easier.

    • Highlights: This search allows fuzzy matching (with Levenshtein Distance < 3) only when the length of the keyword is greater than 3. If the length of the keyword you type in is smaller or equal to 3, the keyword must be exactly the same to expected

  • Major enhancement: extended FindCommand to FindAddressCommand, FindEmailCommand, and FindPhoneCommand

    • What it does: allows the user to find Persons by address, email, and phone number and support fuzzy matching, which means even if the user has a small typo, it can still find Persons with similar address, email, or phone number.

    • Justification: These features largely improve the convenience for finding a specific Person or a list of Persons. For instance, a Person now can be found by his or her address, email or phone number, and multiple step of find command can be used to find a person by more than one kind of conditions.

    • Highlights: All these commands are case insensitive and support fuzzy matching (however, with some restrictions, which are specified in User Guide).

  • Minor enhancement:

    • Built tests case for Find related commands and UI.

  • Code contributed: [Functional code] [Test code] {give links to collated code files}

  • Other contributions:

    • Project management:

      • Set milestones for v1.2 - v1.4 on GitHub

      • Opened issues for v1.2 - v1.4 on GitHub

      • Set up milestone deadlines, close issues accordingly on GitHub

    • Enhancements to existing features:

      • Modified the UI and added related test case (Pull requests #169, #178)

      • Wrote additional tests for existing features to increase coverage (Pull requests #101)

    • Documentation:

      • Modified the format and changed some inaccurate expressions for the whole User Guide: #167

    • Community:

      • PRs reviewed (with non-trivial review comments): #166, #175, #182, #183

      • Reported bugs and suggestions for other teams in the class (examples: #257)

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.

Locating persons by name: find

Finds persons whose names contain any of the given keywords.
Format: find KEYWORD [MORE_KEYWORDS]…​

  • The search is case insensitive.
    e.g. hans will match Hans

  • The search allows fuzzy matching when the length of the keyword is greater than 3 (with Levenshtein Distance < 3).
    e.g. challotto will match Charlotte

  • If the length of the keyword you type in is smaller or equal to 3, the keyword must be exactly the same to expected (but still case insensitive).
    e.g. Lo will not match Li

  • The order of the keywords does not matter.
    e.g. Hans Bo will match Bo Hans

  • Only the name is searched.

  • Persons matching at least one keyword will be returned (i.e. OR search).
    e.g. Hans Bo will return Hans Gruber, Bo Yang

Examples:

  • find John
    Returns john and John Doe

  • find challotto
    Returns Charlotte Oliveiro

  • find David Roy John
    Returns any person having names David, Roy, or John

Locating persons by address: find/a

Finds persons whose addresses contain all the given keywords.
Format: find/a KEYWORD [MORE_KEYWORDS]…​

  • The search will search for persons whose addresses contain all the keywords.
    e.g. Clementi will find person John Doe whose address is 311, Clementi Ave 2, #02-25

  • If the keywords match more than one person, all of these person will be returned.
    e.g. Serangoon will return the persons whose addresses contain Serangoon, who are Bernice Yu and David Li

  • The search is case insensitive.
    e.g cLeMenTi is same as Clementi, and cLeMenTi can also be used to find person John Doe whose address is 311, Clementi Ave 2, #02-25

  • The search allows fuzzy matching on long keywords (long keyword means the keyword whose length is greater than 3).
    e.g. clenti will be fuzzy matched with Clementi, and will find the person John Doe whose address is 311, Clementi Ave 2, #02-25

  • The search will not support fuzzy matching when the keywords are too short (≤ 3) or contain numbers.
    e.g. Clementi Avo does not match Clementi Ave because keyword Avo is short and will not be allowed to use fuzzy matching, therefore, no person will be found

  • The order of the keywords does not matter.
    e.g. Ave Clementi 2, 311, #02-25 will match 311, Clementi Ave 2, #02-25, and will find the person John Doe whose address is 311, Clementi Ave 2, #02-25

  • Only the address is searched.

Examples:

  • find/a B311, Clementi Ave 2, #02-25
    Returns John Doe

  • find/a B311, CLEMENTI Ave 2, #02-25
    Returns John Doe (case insensitive)

  • find/a #02-25, Ave 2 Clementi, B311
    Returns John Doe (the order of the keywords does not matter)

  • find/a serangoon
    Returns person whose addresses containing the keyword Serangoon, i.e. Bernice Yu and David Li

  • find/a srangon
    Returns persons whose addresses containing the keyword Serangoon, i.e. Bernice Yu and David Li (fuzzy matching)

Locating persons by email address: find/e

Finds a person through his/her email address.
Format: find/e EMAIL [MORE_EMAILS]…​

  • The search is case insensitive.
    e.g LIDaVid@example.com will match lidavid@example.com, and will find person David Li whose email is lidavid@example.com

  • The search allows fuzzy matching (with Levenshtein Distance < 4).
    e.g.lidavd@exmple.com will match lidavid@example.com, and will find person David Li whose email is lidavid@example.com

  • Only the email is searched.

  • Person matching the email will be returned.

Examples:

  • find/e John@example.com
    Returns John Doe whose email address is John@example.com

  • find/e LIDavd@example.com
    Returns David Li whose email address is lidavid@example.com (case insensitive)

  • find/e lidavd@exmple.com
    Returns David Li whose email address is lidavid@example.com (fuzzy matching)

Locating persons by phone number: find/p

Finds a person through his/her phone number.
Format: find/p PHONE_NUMBER [MORE_PHONE_NUMBER]…​

  • Only the phone number is searched.

  • The search allows fuzzy matching (with Levenshtein Distance < 3).
    e.g. 123456 will match 12345678, 12435678 will match 12345678

  • Person matching the phone number will be returned.

Examples:

  • find/p 98765432
    Returns John Doe whose phone number is 98765432

  • find/p 9876543
    Returns John Doe whose phone number is 98765432 (fuzzy matching)

  • find/p 98765433
    Returns John Doe whose phone number is 98765432 (fuzzy matching)

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.

The find related features include four commands, which are FindCommand, FindAddressCommand, FindEmailCommand, and FindPhoneCommand. They support finding by name, address, email, and phone numbers.

Current Implementation

Find command (find KEYWORD [MORE_KEYWORDS]…​)

The find command has been implemented to find students by their names.

  • The find command accepts one or more arguments, each argument represent a keyword.

  • The find command finds persons whose names contain any of the given keywords.

  • The number of students found will be displayed on the PersonCard GUI.

  • All the keywords are put into a List<String> and converted to a stream. Perform .anyMatch(…​) on the keywords stream to find all the students whose names match any of the keywords.

  • The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. The condition for using fuzzy matching in this command is the length of the keyword is greater than 3 and if the condition is satisfied, we set the Levenshtein Distance to be less than 3, which means at most two differences.

FindCommandLogicDiagram
Find by address command (find/a KEYWORD [MORE_KEYWORDS]…​)

The find/a command has been implemented to find students by their address.

  • The find/a command accepts one or more arguments, each argument represent a keyword.

  • The find/a command finds persons whose addresses contain all the given keywords.

  • The number of students found will be displayed on the PersonCard GUI.

  • All the keywords are put into a List<String> and converted to a stream. Perform .allMatch(…​) on the keywords stream to find all the students whose addresses match all the keywords.

  • The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. The condition for using fuzzy matching in this command is the length of the keyword is greater than 3 and if the condition is satisfied and the length of keyword is 4 to 7, we set the Levenshtein Distance to be less than 3; if the length of keyword is more than 8, we set the Levenshtein Distance to be less than 4.

FindAddressCommandLogicDiagram
Find by email command (find/e EMAIL [MORE_EMAILS]…​)

The find/e command has been implemented to find students by their email.

  • The find/e command accepts one or more arguments, each argument represent an email address keyword.

  • The find/e command finds persons whose emails are the same as any of the keywords.

  • The number of students found will be displayed on the PersonCard GUI.

  • All the keywords are put into a List<String> and converted to a stream. Perform .anyMatch(…​) on the keywords stream to find all the students whose emails match any of the keywords.

  • The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. We set the Levenshtein Distance to be less than 4, which means at most three differences.

FindEmailCommandLogicDiagram
Find by phone number command (find/p PHONE_NUMBER [MORE_PHONE_NUMBERS]…​)

The find/p command has been implemented to find students by their phone number.

  • The find/p command accepts one or more arguments, each argument represent a phone number keyword.

  • The find/p command finds persons whose phone numbers are the same as any of the keywords.

  • The number of students found will be displayed on the PersonCard GUI.

  • All the keywords are put into a List<String> and converted to a stream. Perform .anyMatch(…​) on the keywords stream to find all the students whose phone numbers match any of the keywords.

  • The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. We set the Levenshtein Distance to be less than 3, which means at most two differences.

FindPhoneCommandLogicDiagram 1

Design considerations

Aspect: Fuzzy matching
  • Alternative 1 (current choice): Allow fuzzy matching in searching.

    • Pros:

      1. Small typos will not affect the searching output.

      2. Make the application much more practical and easier to use.

    • Cons:

      1. Some minor mistakes in spelling might lead to totally different meanings. We have tried to prevent this from happening by limiting the minimum length of keywords for fuzzy matching, however, there might still be a few cases that exist problems.