This site is from a past semester! The current version will be here when the new semester starts.

Project Duke

Duke, the Java Mascot
[credit: Wikipedia]

Project Duke is a educational software project designed to take you through the steps of building a small software incrementally, while applying as many Java and SE techniques as possible along the way.

The project aims to build a product named Duke, a Personal Assistant Chatbot that helps a person to keep track of various things. The name Duke was chosen as a placeholder name, in honor of Duke, the Java Mascot. You may give it any other name and personality you wish.

Here is a sample interaction with Duke:

    ____________________________________________________________
____ _
| _ \ _ _| | _____
| | | | | | | |/ / _ \
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|

Hello! I'm Duke
What can I do for you?
____________________________________________________________

list
____________________________________________________________
Here are the tasks in your list:
1.[T][✓] read book
2.[D][✗] return book (by: June 6th)
3.[E][✗] project meeting (at: Aug 6th 2-4pm)
4.[T][✓] join sports club
____________________________________________________________

todo borrow book
____________________________________________________________
Got it. I've added this task:
[T][✗] borrow book
Now you have 5 tasks in the list.
____________________________________________________________


deadline return book /by Sunday
____________________________________________________________
Got it. I've added this task:
[D][✗] return book (by: Sunday)
Now you have 6 tasks in the list.
____________________________________________________________

done 2
____________________________________________________________
Nice! I've marked this task as done:
[D][✓] return book (by: June 6th)
____________________________________________________________

blah
____________________________________________________________
☹ OOPS!!! I'm sorry, but I don't know what that means :-(
____________________________________________________________

bye
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________

The project consists of the following increments:

  • Levels: A series of features, meant to be added to Duke in the given order, although some can be skipped. These have been named Level 1 to Level 10 to indicate how each makes the product progressively "level up".
  • Extensions:
    • Category A These are internal/feature enhancements meant to help you practice a specific Java or an SE technique.
    • Category B These are enhancements related to task tracking.
    • Category C These are enhancements, not specifically related to task tracking.
    • Category D Each of these adds the ability to track another type of entities.

Levels

Level 0. Greet

Implement an initial skeletal version of the Duke that simply greets the user and exits.
Example:

____________________________________________________________
Hello! I'm Duke
What can I do for you?
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________
  • The indentation and horizontal lines are optional.

Level 1. Greet, Echo, Exit

Implement a skeletal version of Duke that starts by greeting the user, simply echos commands entered by the user, and exits when the user types bye.
Example:

    ____________________________________________________________
Hello! I'm Duke
What can I do for you?
____________________________________________________________

list
____________________________________________________________
list
____________________________________________________________

blah
____________________________________________________________
blah
____________________________________________________________

bye
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________

  • The indentation and horizontal lines are optional.

You are strongly encouraged to customize the chatbot name, command/display formats, and even the personality of the chatbot to make your chatbot unique.


Level 2. Add, List

Add the ability to store whatever text entered by the user and display them back to the user when requested.

Example:

    ____________________________________________________________
Hello! I'm Duke
What can I do for you?
____________________________________________________________

read book
____________________________________________________________
added: read book
____________________________________________________________

return book
____________________________________________________________
added: return book
____________________________________________________________

list
____________________________________________________________
1. read book
2. return book
____________________________________________________________
bye
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________

  • There is no need to save the data to the hard disk.
  • Assume there will be no more than 100 tasks. If you wish, you may use a fixed size array (e.g., String[100]) to store the items.

Level 3. Mark as Done

Add the ability to mark tasks as done.

list
____________________________________________________________
Here are the tasks in your list:
1.[✓] read book
2.[✗] return book
3.[✗] buy bread
____________________________________________________________

done 2
____________________________________________________________
Nice! I've marked this task as done:
[✓] return book
____________________________________________________________

When implementing this feature, you are also recommended to implement the following extension:

Extension: A-Classes


Level 4. ToDos, Events, Deadlines

Add support for tracking three types of tasks:

  1. ToDos: tasks without any date/time attached to it e.g., visit new theme park
  2. Deadlines: tasks that need to be done before a specific date/time e.g., submit report by 11/10/2019 5pm
  3. Events: tasks that start at a specific time and ends at a specific time e.g., team project meeting on 2/10/2019 2-4pm

Example:

todo borrow book
____________________________________________________________
Got it. I've added this task:
[T][✗] borrow book
Now you have 5 tasks in the list.
____________________________________________________________

list
____________________________________________________________
Here are the tasks in your list:
1.[T][✓] read book
2.[D][✗] return book (by: June 6th)
3.[E][✗] project meeting (at: Aug 6th 2-4pm)
4.[T][✓] join sports club
5.[T][✗] borrow book
____________________________________________________________

deadline return book /by Sunday
____________________________________________________________
Got it. I've added this task:
[D][✗] return book (by: Sunday)
Now you have 6 tasks in the list.
____________________________________________________________

event project meeting /at Mon 2-4pm
____________________________________________________________
Got it. I've added this task:
[E][✗] project meeting (at: Mon 2-4pm)
Now you have 7 tasks in the list.
____________________________________________________________

At this point, dates/times can be treated as strings; there is no need to convert them to actual dates/times.

Example:


deadline do homework /by no idea :-p
____________________________________________________________
Got it. I've added this task:
[D][✗] do homework (by: no idea :-p)
Now you have 6 tasks in the list.
____________________________________________________________

When implementing this feature, you are also recommended to implement the following extension:

Extension: A-Inheritance


Level 5. Handle Errors

Teach Duke to deal with errors such as incorrect inputs entered by the user.

Example:

todo
____________________________________________________________
☹ OOPS!!! The description of a todo cannot be empty.
____________________________________________________________

blah
____________________________________________________________
☹ OOPS!!! I'm sorry, but I don't know what that means :-(
____________________________________________________________

When implementing this feature, you are also recommended to implement the following extension:

Extension: A-Exceptions

  • Minimal: handle at least the two types of errors shown in the example above.
  • Stretch goal: handle all possible errors in the current version. As you evolve Duke, continue to handle errors related to the new features added.

Level 6. Delete

Add support for deleting tasks from the list.

Example:

list
____________________________________________________________
Here are the tasks in your list:
1.[T][✓] read book
2.[D][✓] return book (by: June 6th)
3.[E][✗] project meeting (at: Aug 6th 2-4pm)
4.[T][✓] join sports club
5.[T][✗] borrow book
____________________________________________________________

delete 3
____________________________________________________________
Noted. I've removed this task:
[E][✗] project meeting (at: Aug 6th 2-4pm)
Now you have 4 tasks in the list.
____________________________________________________________

When implementing this feature, you are also recommended to implement the following extension:

Extension: A-Collections


Level 7. Save

Save the tasks in the hard disk automatically whenever the task list changes. Load the data from the hard disk when Duke starts up. You may hard-code the file name and location e.g., [project_root]/data/duke.txt

The format of the file is up to you. Example:

T | 1 | read book
D | 0 | return book | June 6th
E | 0 | project meeting | Aug 6th 2-4pm
T | 1 | join sports club

If you use file paths in your code,

  • remember to use relative paths rather than absolute paths such as C:\data. If not, your app can cause unpredictable results when used in another computer.
  • remember to specify file paths in an OS-independent way. If not, your app might not work when used on a different OS.

Your code must i.e., if the file is missing, your code must creat ithandle the case where the data file doesn't exist at the start. Reason: when someone else takes your Duke and runs it for the first time, the required file might not exist in their computer. Similarly, if you expect the data file to be in as specific folder (e.g., ./data/), you must also handle the folder-does-not-exist-yet case.


Level 8. Dates and Times

Teach Duke how to understand dates and times. For example, if the command is deadline return book /by 2/12/2019 1800, Duke should understand 2/12/2019 1800 as 2nd of December 2019, 6pm, instead of treating it as just a String.

  • Minimal: Store deadline dates as a java.time.LocalDate in your task objects. Accept dates in a format such as yyyy-mm-dd format (e.g., 2019-10-15) and print in a different format such as MMM dd yyyy e.g., (Oct 15 2019).
  • Stretch goal: Use dates and times in more meaningful ways. e.g., add a command to print deadlines/events occurring on a specific date.

Level 9. Find

Give users a way to find a task by searching for a keyword.

Example:

find book
____________________________________________________________
Here are the matching tasks in your list:
1.[T][✓] read book
2.[D][✓] return book (by: June 6th)
____________________________________________________________

Level 10. GUI

Add a GUI to Duke. Use the JavaFX technology to implement the GUI.



Refer to the JavaFX tutorial @SE-EDU/guides to learn how to get started with JavaFX.

Extensions: Category A

A-Classes

     Use a class to represent tasks

While it is possible to represent a task list as a multi-dimensional array containing String, int, boolean etc.primitive values, the more natural approach is to use a Task class to represent tasks.


A-Inheritance

     Use Inheritance to support multiple task types

As there are multiple types of tasks that have some similarity between them, you can implement classes Todo, Deadline and Event classes to inherit from a Task class.

Furthermore, use polymorphism to store all tasks in a data structure containing Task objects e.g., Task[100].


A-AbstractClasses

     Use abstract classes

Make the Task class an abstract class. If applicable, use abstract methods as well.


A-Exceptions

     Use Exceptions to handle errors

Use exceptions to handle errors. For example, define a class DukeException to represent exceptions specific to Duke.


A-TextUiTesting

     Test using the I/O redirection technique

Use the input/output redirection technique to semi-automate the testing of Duke.

Notes:

  • A tutorial of this technique is here.
  • The required scripts are provided in the Duke repo (see the text-ui-test folder).

A-Collections

     Use Java Collections classes

Use Java Collections classes for storing data. For example, you can use an ArrayList<Task> to store the tasks.


A-MoreOOP

     Make the code more OOP

Refactor the code to extract out closely related code as classes.

  • Minimal: Extract the following classes:
    • Ui: deals with interactions with the user
    • Storage: deals with loading tasks from the file and saving tasks in the file
    • Parser: deals with making sense of the user command
    • TaskList: contains the task list e.g., it has operations to add/delete tasks in the list

For example, the code of the main class could look like this:

public class Duke {

private Storage storage;
private TaskList tasks;
private Ui ui;

public Duke(String filePath) {
ui = new Ui();
storage = new Storage(filePath);
try {
tasks = new TaskList(storage.load());
} catch (DukeException e) {
ui.showLoadingError();
tasks = new TaskList();
}
}

public void run() {
//...
}

public static void main(String[] args) {
new Duke("data/tasks.txt").run();
}
}
  • Stretch Goal: Consider extracting more classes. e.g., *Command classes (i.e., AddCommand, DeleteCommand, ExitCommand etc.) that inherits from an abstract Command class, so that you can write the main logic of the App as follows:
    public void run() {
    ui.showWelcome();
    boolean isExit = false;
    while (!isExit) {
    try {
    String fullCommand = ui.readCommand();
    ui.showLine(); // show the divider line ("_______")
    Command c = Parser.parse(fullCommand);
    c.execute(tasks, ui, storage);
    isExit = c.isExit();
    } catch (DukeException e) {
    ui.showError(e.getMessage());
    } finally {
    ui.showLine();
    }
    }
    }
    You can get some inspiration from how the code of the addressbook-level2 is organized.

A-JUnit

     Add JUnit tests

Add JUnit tests to test the behavior of the code.

Requirements:

  • Minimum: More than two test methods, preferably targeting more than one class (if you have multiple classes)
  • Stretch goal: test methods to target all public methods of all classes

Refer to the JUnit tutorial @se-edu/guides to find how to use JUnit.


A-Packages

     Divide classes into packages

Organize the classes into suitable java packages.

  • Minimal: put all classes in one package e.g., duke
  • Stretch goal: divide into multiple packages as the number of classes increase e.g., duke.task, duke.command

A-JavaDoc

     Add JavaDoc comments

Add JavaDoc comments to the code.

  • Minimal: Add header comments to at least half of the non-private classes/methods.
  • Stretch goal: Add header comments to all non-private classes/methods, and non-trivial private methods.

A-CodingStandard

     Tweak the code to comply with a coding standard

Tweak the code to comply with a given coding standard. From this point onward, ensure any new code added are compliant with the given coding standard.


A-CheckStyle

     Use CheckStyle

Use checkStyle to detect coding style violations.

Refer the tutorial Using Checkstyle @SE-EDU/guides to learn how to use Checkstyle.


A-CodeQuality

     Improve code quality

Critically examines the code and refactor to improve the code quality where necessary.

When adding this increment, follow closely the 'Code Quality' topics you have learned so far, rather than merely follow your own intuition about code quality.


A-Assertions

     Use Assertions

Use assert feature (not JUnit assertions) to document important assumptions that should hold at various points in the code.


A-Jar

     Package the App as a JAR file

Package the app as an executable JAR file so that it can be distributed easily.

You can assume the user will run the jar file in the following way only:

  • Copy the jar file into an empty folder
  • Open a command window in that folder
  • Run the command java -jar {filename}.jar e.g., java -jar Duke.jar (i.e., run the command in the same folder as the jar file)

Refer to the tutorial Working with JAR files @SE-EDU/guides to find how to create JAR files.

Do not commit the JAR file created. Instead, you can make the JAR file available in the following manner.

  • Go to your fork on GitHub and create a new release.
  • In the page where you fill the details of the release,
    • give an appropriate version number e.g., v0.1
    • attach the JAR file where it says Attach binaries by dropping them ....

A-Gradle

     Automate project builds using Gradle

Use Gradle to automate some of the build tasks of the project.

Refer to the Gradle tutorial @SE-EDU to learn how to use Gradle.

Gradle support is provided as a separate branch (named add-gradle-support) in the Duke repo. Therefore, you can follow the scenario 2 in the above guide.

  • Minimal: Set up gradle so that you can build and run Duke using gradle.
  • Recommended: Set up gradle to run unit tests.
  • Stretch Goal: Use gradle to automate more things in your project.

A-CI

     Set up CI

Use GitHub Actions to set up Continuous Integration (CI).

The workflow specified by this .yml file is a good candidate for this project. The last three segments are related to I/O redirection tests; can be deleted if not applicable to your project.

Refer to the Using GitHub Actions @SE-EDU/guides to learn how to use that .yml file to set up GitHub actions.


A-Enums

     Use Enumerations

Use Java enums, if applicable.


A-Varargs

     Use var-args

Use Java varargs feature, if applicable.


A-Lambdas

     Use Lambdas

Use the Lambdas feature of Java in your code, if applicable.


A-Streams

     Use Streams

Use the Streams feature of Java in your code, if applicable.


A-Libraries

     Use external libraries

Use third-party libraries in your project. For example, you can use the Natty library to parse strings into meaningful dates.


A-UserGuide

     Add a User Guide

Add a User Guide to the project. Here is one simple way to do it.

  • Update the given docs\README.md. See this guide to GitHub flavored Markdown (GFMD).
  • Go to the settings page of your Duke fork and enable GitHub pages to publish from the docs folder (you can select a theme too).
  • Go to http://{your username}.github.io/{repo name}/ to view the user guide of your product. Note: it could take 5-10 minutes for GitHub to update the page.

A-DevGuide

     Add a Developer Guide

Add a Developer Guide to the project, explaining the design and implementation to future developers.


A-Release

     Release the product

Release the product to be used by potential users. e.g., you can make it available on GitHub


A-BetterGui

     Improve the GUI

Improve the GUI to make it more polished. Some examples:

  • Tweak the GUI to match the asymmetric nature of the conversation: As the conversation is between the user and the app (not between two humans), it is asymmetric in nature. Accordingly, it makes sense not to display both sides of the conversion in the same visual format.
  • Highlight errors e.g., when the user types a wrong command, the error should be shown in a different format to catch ther user's attention.
  • Tweak padding, fonts, colors, alignments to make the GUI more pleasing to look at.
    Given the app is likely to take only a small portion of the screen, and the bot replies can contain lot of text, try to optimize for space (e.g., avoid wasting display space that simply shows the background graphics)
  • Profile pictures: If your GUI shows profile pictures, you can tweak the way the picture is shown (e.g., crop as a circle or a square with rounded corners). In fact, an easy tweak is to use a picture with a transparent background so that it blends nicely with the background.
    Given that the participants of the conversion are fixed (i.e., you and the chatbot), do you even need big profile pictures?

You can take inspiration from these past projects. If you adopt any ideas from them, don't forget to give credit to the original author.

Extensions: Category B

B-TentativeScheduling

     Tentative scheduling

Provide a way for an event to be tentatively scheduled in multiple slots, and later to be confirmed to one the slots.


B-Snooze

     Snoozing/postponing tasks

Provide a way to easily snooze/postpone/reschedule tasks.


B-RecurringTasks

     Recurring tasks

Provide support for managing recurring tasks e.g., a weekly project meeting.


B-DoAfterTasks

     'Do after' tasks

Support the managing of tasks that need to be done after a specific time/task e.g., return book after the exam is over.


B-DoWithinPeriodTasks

     'Do within a period' task

Provide support for managing tasks that need to be done within a certain period e.g., collect certificate between Jan 15 and 25th.


B-FixedDurationTasks

     Unscheduled tasks with a fixed duration

Provide support for managing tasks that takes a fixed amount of time but does not have a fixed start/end time e.g., reading the sales report (needs 2 hours).


B-Reminders

     Reminders for tasks

Provide a way to get reminders about tasks e.g., remind the user about upcoming deadlines.


B-FindFreeTimes

     Find free times

Provide a way for the user to find free times e.g., when is the nearest day in which I have a 4 hour free slot?.


B-ViewSchedules

     View schedules

Provide a way to view tasks in the form of a schedule e.g., view the schedule for a specific date.


B-DetectAnomalies

     Detect scheduling anomalies

Deal with schedule anomalies e.g., detect if a task being added clashes with another task in the list.

Extensions: Category C

C-DetectDuplicates

     Deal duplicate items

Add the ability to recognize and deal with duplicate items. e.g., the same task added multiple times.


C-FlexibleDataSource

     Flexible data source

Provide more flexibility with the data source e.g., the ability for the user to specify which file to use as the data source.


C-Sort

     Sorting items managed by the App

The ability to sort items e.g., sort deadlines chronologically.

C-NaturalDates

     More natural date formats

Support more natural date formats e.g., Mon in a user command can be interpreted as the date of the next Monday in the calendar.

C-BetterSearch

     More flexibility in searching for items

All more flexibility in search e.g., find items even if the keyword matches the item only partially.

C-Update

     Easily edit items

Support a way to easily edit details of items e.g., change the end time of an event without changing anything else.

Minimal: the ability to update an existing item without having to delete it first

Other ideas:

  • the ability to clone items (to easily create new items based on existing items)

C-Tagging

     Tagging items

Provide a way to tag items e.g., tag a task as #fun.

C-Priority

     Prioritizing items

Provide a way to attach priorities to items e.g., mark an item as a high priority (or priority level 1).

C-Archive

     Archiving items

Provide a way to archive items so that the user can remove items from the app but still keep a record of them somewhere e.g., archive all tasks in the list into a file so that the user can start over with a clean slate.

C-MassOps

     Mass operations

Provide a way to perform tasks on multiple items e.g., delete some specific items in one go.

C-Statistics

     Statistics and insights

Provide a way to leverage statistics about the items managed by the App e.g., show the number of tasks that have been completed in the past week.

C-Undo

     Undo

Provide a way to undo a command.

Minimal: the ability to undo the most recent command.

C-Help

     Give help to users

Provide in-App guidance to users.

Minimal: add a command to access a help page.

Other ideas:

  • Load the App with some sample data at the first run.

C-FriendlierSyntax

     Friendlier syntax for commands

Make the command syntax more flexible.

Minimal: provide shorter aliases for keywords e.g., t can be shorter alias for todo.

Other ideas:

  • Allow users to define their own aliases
  • Remove the need for the parts of a command to be in a specific order

Extensions: Category D

D-Contacts

     Support managing contacts

Support managing info about contacts e.g., details of friends

D-Notes

     Support managing notes

Support managing info about small snippets of textual information the user wants to record e.g., one's own waist size, a name of a movie that the user wants to remember

D-Expenses

     Support managing expenses

Support managing info about expenses e.g., the amounts spent on food, books, transport, etc.

D-Loans

     Support managing loan records

Support keeping records of loans given/taken e.g., money lent/owed to colleagues/friends

D-Places

     Support managing info about places

Support recording info about places e.g., info about restaurants visited, for future reference

D-Trivia

     Support managing trivia

Provide the ability to learn/memorize thingse.g., learn vocabulary, answers to questions

D-Clients

     Support managing client info

Support managing info about clients e.g., for an insurance agent to keep track of clients

D-Merchandise

     Support managing merchandise info

Support managing info about merchandise e.g., a property agent to keep track of properties, a collector of stamps keep track of items in the collection