This is Wang Shiyao’s Project Portfolio Page - highlighting his contributions to his CS2103T Software Engineering Project.

LiBerry

Overview

In the spirit of spreading education, literacy and a sense of community to the world (and completing our software engineering project), my team has developed Liberry - a desktop software for managing community and private libraries. The target users are mainly librarians in under-developed communities who cannot afford commercial versions of such software.

LiBerry can execute the basic functions of library management:

  • Addition and deletion of books in the catalog

  • Registering Borrowers and editing their particulars

  • Loan, return, renew and pay fine functions

  • Searching through books in the catalog by filters

As part of the requirements of the project, we were given the source code for a common AddressBook application and were tasked to morph it to something else that is useful. We were also limited to designing software that takes in the majority of user input through a Command Line Interface (CLI), though displays information through a Graphical User Interface (GUI).

This is what the GUI looks like:

Ui
Figure 1. Graphical User Interface (GUI) for LiBerry

My role was to:

  1. configure the basic AddressBook software to accommodate Json-type storage for a catalog, a record of borrowers, and a record of loans

  2. design the Find Command to execute given a set of parameters - such as searching by title, genre, loan status etc

  3. Add a Clear Command to clear user searches

  4. design the GUI in terms of color schemes

  5. create the Toggle UI Command to allow users to switch the GUI between 'light mode' and 'dark mode' themes

  6. Create sample data for testing

Summary of Contributions

Major enhancement - Finding by various parameters

Allows the user to filter the catalog by various parameters

What it does

  1. Searches books in catalog and displays them on the screen through filtering by:

    1. title

    2. author

    3. serial number

    4. genres

    5. loan status (available / loaned / overdue)

  2. sets the number of books to display on the screen

Justification

As a librarian who is keeping charge of book and loan records, the ability to find books and their loan statuses fast is necessary.

Highlights

This enhancement was decently demanding as it required a way to test every book on whether it met the query requirements. It showcases my ability to play with functional programming and Streams in Java. As the predicate used has multiple possible combinations, extensive tests were written to ensure that it worked the way it should.

Minor enhancement - Switching GUI themes

Allows the user to toggle the GUI between 'light mode' and 'dark mode'.

Justification

As a librarian who may work after the sun has set, this command helps to switch the GUI into a more eye-friendly mode when using the software.

Highlights

This feature was rather challenging as it required a decent amount of CSS knowledge and the ability to manipulate JavaFx elements.

Other contributions

Project management

  • Managed the release of v1.4-alpha on GitHub. This is the final version of our software at Alpha release for final pre-release testing. The improvements made to v1.3 are:

    • Feature: Undo and Redo

    • Feature: Toggle UI theme

    • GUI theme update

    • Additional sample data on startup

    • Bug fixes

Enhancements to existing features

Done through the following pull requests:

  • #292: Updated sample data for users to test on

  • #255: Updated the GUI color scheme

  • #84: Created the relevant Storage classes for others to build on

Documentation

Done through the following pull requests:

  • #277: Styled the aesthetics of the LiBerry Netlify main page and sub-pages (including User Guide (UG) and Developer Guide (DG))

  • #94: Create the broad User Guide structure for others to build on

Community

  • Left a DG review on another group’s PR as a group

  • Posted a tip in the module forum (as a group) on making a code coverage check shortcut

  • Left a User Stories review on another group’s PR as a group

  • Tested another team’s PR and submitted bugs during Practical Exam Dry Run.

Contributions to the User Guide

Given below are sections I have contributed to in the User Guide. They showcase my ability to write documentation targeting end-users. The official User Guide is linked here.

User Guide: Find Command

The following segment shows my description of the find command which I have implemented in LiBerry.


Locating books by title: find

Shows all relevant books found.

Format: find [NUMBER] { [t/TITLE] [a/AUTHOR] [g/GENRE]…​ [sn/BOOK_SN] [-overdue] [-loaned] [-available] }
Format: find [NUMBER] { [t/TITLE] [a/AUTHOR] [g/GENRE]…​ [sn/BOOK_SN] [-overdue] [-loaned] [-available] [-rated] [-popular] [-new] } - Coming in v2.0

  • The search is case insensitive. e.g harry will match Harry

  • When searching by book titles and authors, partial words will also be matched e.g. Har will match Harry, J will match J K Rowling and Jin Yong

  • Books matching at least one keyword will be returned (i.e. OR search). e.g. harry will return both Harry Potter and Harry Botter

  • [NUMBER] will limit the search to NUMBER books

  • [t/TITLE] will be used to search through book titles

  • [a/AUTHOR] will be used to search through or filter by authors

  • [g/GENRE] will be used to search through or filter by genre

  • [sn/BOOK_SN] will be used to search through book serial numbers

  • Only 1 of the following 3 flags can be used

    • [-overdue] will only show overdue books

    • [-loaned] will only show loaned books

    • [-available] will only show available books

  • Adding one of the following will sort the books such that:

    • [-rated] will list the top 10 highly rated books - Coming in v2.0

    • [-popular] will list the top 10 most borrowed books - Coming in v2.0

    • [-new] will list the 10 newest books - Coming in v2.0

Inputs for g/GENRE is automatically capitalized.
t/TITLE and a/AUTHOR are matched by partial spellings. Search t/phil if you forgot how to spell 'Philosopher'!

Examples:

  • find t/Animal Farm a/George Orwell
    Searches for the book titled “Animal Farm” by the author “George Orwell”.

  • find 3 g/mystery g/children -available
    Searches for children mystery books that are not on loan and show the first 3 entries.

User Guide: Command Summary

The following segment shows my summary of all the commands in LiBerry. I made this so that users can have an overview of all the commands and be able to find the relevant one quickly without having to go through the entire User Guide.


This section contains the summary of LiBerry’s commands.
Commands applicable to both Normal and Serve mode:

  • Help : help

  • Find a book : find [NUMBER] { [t/TITLE] [a/AUTHOR] [g/GENRE]…​ [sn/BOOK_SN]] [-overdue] [-loaned] [-available] }
    e.g. find t/Animal Farm a/George Orwell, find 3 g/mystery g/children -available
    [-rated] [-popular] [-new] - Coming in v2.0

  • View book info : info INDEX

  • Clear results : clear

  • Add a book : add t/TITLE a/AUTHOR sn/BOOK_SN [g/GENRE]…​ `
    e.g. `add t/Harry Botter and the Baby’s Potty a/Reali Jolking sn/B02010 g/children

  • Delete a book : delete INDEX or delete sn/BOOK_SN

  • Register a borrower : register n/NAME p/PHONE_NUMBER e/EMAIL
    e.g. register n/matt p/83938249 e/matt@damon.com

  • Unregister a borrower : unregister id/BORROWER_ID

  • Undo : undo

  • Redo : redo

  • Set user settings: set [lp/LOAN_PERIOD] [rp/RENEW_PERIOD] [fi/FINE_INCREMENT] [mr/MAX_RENEWS]

  • Toggle UI theme: toggleui

  • Rate a book : rate INDEX r/RATING - Coming in v2.0

  • Exit : exit

  • Enter Serve mode : serve id/BORROWER_ID
    e.g. serve id/K0001

Commands applicable to Serve mode only:

  • Exit serve mode : done

  • Edit a borrower’s particulars : edit { [n/NAME] [p/PHONE_NUMBER] [e/email] }
    e.g. edit p/91234567 e/jane@austen.com

  • Loan book : loan sn/BOOK_SN
    e.g. loan sn/B00201

  • Return book(s) : return INDEX or return -all

  • Renew book(s) : renew INDEX or renew -all

  • Pay fines : pay $AMOUNT

  • Reserve book : reserve INDEX or reserve sn/BOOK_SN - Coming in v2.0

Contributions to the Developer Guide

Given below are sections I have contributed to in the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. The official Developer Guide is linked here

Book Finding is the main feature that I have implemented in LiBerry. The following is an extract from the Developer Guide that describes and explains the feature.


Book finding feature

The command for finding a book in the catalog is as follows:
find [NUMBER] { [t/TITLE] [a/AUTHOR] [g/GENRE]…​ [sn/BOOK_SN]] [-overdue] [-loaned] [-available] }

Details of Implementation

ModelManager contains a FilteredList of Books (filteredBooks), which is used to display books on the LiBerry GUI. Book finding works by starting converting the command string in to a BookPredicate object, then updating filteredBooks with that predicate.

The parsing of the command string to create the required BookPredicate object is done with the help of the ArgumentTokenizer object. ArgumentTokenizer tokenizes the command string to generate an ArgumentMultimap, which is internally a HashMap of predicate values paired to prefix keys. The FindCommandParser then extracts all the values from the ArgumentMultimap prefix by prefix and building the predicate through functions such as setTitle(), setGenres() setLoanStatus etc.

The diagram below shows a simplified command generation sequence of a 'find t/Animal Farm a/George' command, starting from the CatalogParser

FindSequenceDiagram
Figure 2. Sequence Diagram showing the execution of a Find Command input

The BookPredicate class stores in its fields the specific values to match. Default values are mostly null, which will indicate that there is no need to filter for that field. Below is an example.

BookPredicateObjectDiagram
Figure 3. Object Diagram showing the fields present in an empty (left) and partially filled (right) BookPredicate object

The figure above shows what happens when we are trying to filter for books with title 'harry' and 'Potter' that are loaned out, showing up to 5 books only. Notice that the rest of the fields in the object are null.

Design Considerations

Aspect: Ensuring only 1 Loan Status Flag

In order for LiBerry to display only books that are loaned, available or overdue, flags are used. All flags have the prefix -, and the ArgumentTokenizer is able to detect this. However, a user can technically enter more than 1 of such loan status flags eg. -loaned -available. This is not meaningful, as there can be multiple interpretations of this statement. The user could be looking for both types of books (which will show every book), or books that are both loaned and available (which will show none). To prevent such meaningless confusion, there is a need for only 1 such flag to be accepted in the BookPredicate.

  • Alternative 1: Hard code a priority for loan status flags and accept the highest one when generating BookPredicate*

    • Pros: Easy to implement, since Flags are implemented as Enums.

    • Cons: Can be confusing to the reader as it is not clear why an unintended display is shown / why a certain priority exists.

  • Alternative 2 (Currently Used): Raise an exception whenever there are more than 1 loan status flags

    • Pros: Helps user clarify misconception of using more than 1 loan status flag

    • Cons: Slightly more complicated code where the flags obtained from ArgumentMultimap has to be counted, checked and selected.

Alternative 2 was chosen in the end as it conformed with the norms of directly informing the user of his mistake through the use of exceptions and error messages.

Aspect: Limiting the Number of Books to Display

As users generally do not want to be flooded with information when using the find command, a display limit [NUMBER] is used. Users can ask for a limited number of books to display. However, the FilteredList JavaFx class that is used to implement the list of filtered books does not have an API that sets a hard limit on the number of books to show. A work-around has to be made.

  • Alternative 1: Create an new class that extends the JavaFx FilteredList class that has a function that caps the number of items in the inner ObservableList.

    • Pros: Does not require a change in other parts of the code. Interface is simple and elegant.

    • Cons: Hard to implement. Need to know the ins and outs of FilteredList and ObservableList.

  • Alternative 2 (Currently Used): Create a counter variable in BookPredicate that decrements after every passed test

    • Pros: Easy to implement.

    • Cons: Not the cleanest and most developer friendly way of implementation.

Alternative 2 was chosen instead as the extension of FilteredList would take too much time for the implementation of such a simple feature. The cons of this choice will be compensated for in source code documentation to explain to developers how it works.


End of PPP

Thank you for reading this Portfolio Page. If you have any suggestions for LiBerry, for this page, or for me in general, contact me at wangshiyao@u.nus.edu!

Special thanks to my team for making this project a success!