This site is from a past semester! The current version will be here when the new semester starts.
CS2103/T 2020 Jan-Apr
  • Full Timeline
  • Week 1 [Jan 13]
  • Week 2 [Jan 20]
  • Week 3 [Jan 27]
  • Week 4 [Feb 3]
  • Week 5 [Feb 10]
  • Week 6 [Feb 17]
  • Week 7 [Mar 2]
  • Week 8 [Mar 9]
  • Week 9 [Mar 16]
  • Week 10 [Mar 23]
  • Week 11 [Mar 30]
  • Week 12 [Apr 6]
  • Week 13 [Apr 13]
  • Textbook
  • Admin Info
  • Report Bugs
  • Forum
  • Instructors
  • Announcements
  • File Submissions
  • Tutorial Schedule
  • Java Coding Standard
  • Participation Marks List

  •  Individual Project (iP):
  • Individual Project Info
  • Duke Upstream Repo
  • iP Code Dashboard
  • iP Showcase

  •  Team Project (tP):
  • Team Project Info
  • Team IDs
  • Addressbook-level3
  • Addressbook-level 1,2,4
  • tP Code Dashboard
  • tP Showcase
  • Week 3 [Jan 27] - Project

    iP:

    1. Do any leftover iP tasks from the previous week
    2. Create a PR to the upstream repo
    3. Add Increments as parallel branches: Level-7, Level-8
    4. Add Increments: A-MoreOOP, A-Packages, A-JUnit, A-Jar
    5. Add Increments as parallel branches: A-JavaDoc, A-CodingStandard, Level-9

    tP:

    1. Get familiar with AB3 features
    2. Set up a project meeting time by the end of the tutorial

    iP

    1 Do any leftover iP tasks from the previous week

    • Remember to do any leftover increments from the past weeks before starting on the current week's increments. This guideline applies to future weeks too.

    2 Create a PR to the upstream repo

    • Create a pull request (PR) from the master branch of your fork to the upstream repo.
      • PR name: [{Your name}] Duke Increments e.g., [John Doe] Duke Increments If you are reluctant to give full name, you may give the first half of your name only

    3 Add Increments as parallel branches: Level-7, Level-8

    • Do Level 7 in a branch named branch-Level-7. Without merging that branch, go back to the master branch and implement Level 8 in a separate branch named branch-Level-8. Now, go back to the master branch and merge the two branches one after the other. As before, tag the commit (in the master branch, after merging) that achieves the respective deliverable, and push to your fork.
      Remember to push the branches to your fork so that the bot can detect them.
      Advanced git users: do not delete the branch after merging.
      Merge without a fast-forward so that git creates a separate commit for the merge.
    Level-7: Save

    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.
    Level-8: Dates and Times

    Level 8. Dates and Times

    Teach Duke to understand dates and times. For example, if the command is deadline return book /by 2/12/2019 1800, Duke understands 2/12/2019 1800 as 2nd of December 2019, 6pm, instead of storing it simply as 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 d 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.

    A code snippet using the LocalDate class:

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.time.temporal.ChronoUnit;

    public class Main {
    public static void main(String[] args) {
    //create dates from strings
    LocalDate d1 = LocalDate.parse("2019-12-01");
    LocalDate d2 = LocalDate.parse("2019-12-02");
    LocalDate d3 = LocalDate.parse("2019-12-02");

    //compare dates
    System.out.println(d1.isBefore(d2)); // -> true
    System.out.println(d1.isAfter(d2)); // -> false
    System.out.println(d2.equals(d3)); // -> true

    //work with dates
    System.out.println(d1.getDayOfWeek()); // -> SUNDAY
    System.out.println(d1.getMonth()); // -> DECEMBER
    System.out.println(d1.plus(1, ChronoUnit.YEARS)); // -> 2020-12-01

    // get today's date and print it in a specific format
    LocalDate d4 = LocalDate.now();
    System.out.println(d4); // -> 2019-10-15
    System.out.println(d4.format(DateTimeFormatter.ofPattern("MMM d yyyy"))); // -> Oct 15 2019
    }
    }

    4 Add Increments: A-MoreOOP, A-Packages, A-JUnit, A-Jar

    • As in the previous week, commit, tag, and push, as you do the following increments in the master branch (no need to use separate branches).
    A-MoreOOP: Use More OOP

    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-Packages: Organize into Packages optional

    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-JUnit: Add JUnit Tess

    A-JUnit

         Add JUnit tests

    Add JUnit tests to test the behavior of the code.

    Conventions to follow:

    • Add test code in a folder named [project root]\src\test\java\ folder (reason: to follow the convention followed by the project structure so far).
    • Name the test class to match the class being tested (Todo.java can be tested by TodoTest.java), and put it in a package to match. For example,
      • Class being tested seedu.duke.Todo: src\main\java\seedu\duke\Todo.java
      • Test class seedu.duke.TodoTest: src\test\java\seedu\duke\TodoTest.java

    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

    Adding JUnit support to your project: As JUnit is a third-party library, you need to add support to it specifically in your project.

    1. Add a folder named [project root]\src\test\java\ (you may have to do this outside of Intellij)
    2. Go to Intellij and add a new module to the project as follows.
      1. FileNewModule From Existing Sources ...
      2. Choose the [project root]\src\test\ (not the java) folder.
      3. In the next screen, select Create module from existing sources
      4. Keep clicking Next until the process is complete
    3. In the Project panel of Intellij, expand the newly-created test module, right-click on the java folder inside it, and choose Mark Directory asTest Source Root (that will make the folder turn to green color).
    4. Now, create a class inside the java folder and type @Test inside it. A code example given below.
      Note: If you are using packages, create this class in a matching package (to test duke.Duke class, create a duke.DukeTest i.e., in src\test\java\duke\DukeTest.java).
      public class DukeTest {
      @Test
      }
    5. Note how the @Test turn to red because Intellij (not having JUnit support yet) does not understand it. But it will pop up a hint, asking if you want to add support for JUnit. Select Add JUnit 5.* to classpath.
    6. In the dialog that pops up, you can optionally tick the Sources, JavaDocs and Annotations boxes. After that, click OK to add the JUnit 5 to the project dependencies.
    7. To check if JUnit integration is working as expected,
      1. Add a dummy test method to the class e.g.,
        import org.junit.jupiter.api.Test;

        import static org.junit.jupiter.api.Assertions.assertEquals;

        public class DukeTest {
        @Test
        public void dummyTest(){
        assertEquals(2, 2);
        }
        }
      2. Run the test (right-click on the class and choose Run DukeTest.
    8. To be able to refer to Duke from DukeTest class, you need to add main module as a dependency of the test module you just created.
      • Option 1: When you add a reference to the Duke inside the DukeTest, Intellij will flag it as an error and will give you an option (i.e., in the bulb icon that pops up) to add the main module as a dependency.
      • Option 2: Follow the info here to add the dependency yourself.

    Refer to the Gradle tutorial at the Duke repo (i.e., the repo you forked from) to find how to use JUnit via Gradle.

    A-Gradle

         Automate project builds using Gradle

    Use Gradle to automate some of the build tasks of the project. Refer to the Gradle tutorial at the Duke repo (i.e., the repo you forked from) to find how to set up Gradle for your project.

    • 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-Jar: Create a JAR File

    A-Jar

         Package the App as a JAR file

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

    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 th release,
      • give an appropriate version number e.g., v0.1
      • attach the JAR file where it says Attach binaries by dropping them ....

    If you are using Gradle for your project, refer to the Gradle tutorial at the Duke repo (i.e., the repo you forked from) to find how to create a jar file using Gradle.

    A-Gradle

         Automate project builds using Gradle

    Use Gradle to automate some of the build tasks of the project. Refer to the Gradle tutorial at the Duke repo (i.e., the repo you forked from) to find how to set up Gradle for your project.

    • 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.

    5 Add Increments as parallel branches: A-JavaDoc, A-CodingStandard, Level-9

    • As in the step 1 above, implement these three increments as three parallel branches first (branch names: branch-A-JavaDoc, branch-A-CodingStandard, branch-Level-9), and then merge them one-by-one. Hopefully, you will encounter some merge conflicts so that you get to practice de-conflicting branches.
    A-JavaDoc: JavaDoc

    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: Follow the Coding Standard

    A-CodingStandard

         Tweak the code to comply with a coding standard

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

    Level-9: Find

    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)
    ____________________________________________________________

    tP: Kickoff

    1 Get familiar with AB3 features

    • Familiarize yourself with AB3: Download the latest released version (i.e., the jar file) of AB3 from its upstream repo and play around with it to familiarize with its current features.

    2 Set up a project meeting time by the end of the tutorial

    • After forming teams, set up a weekly project meeting time/venue (and communication channels) with your team members: