Week 2 [Mon, Aug 17th] - Project

iP:

  1. Learn about the project
  2. Set up prerequisites
  3. Set up the project on your computer
  4. Add Increments while committing frequently: Level-0, Level-1, Level-2, Level-3, Level-4, Level-5, Level-6, A-Enums Fri, Aug 21st 1600

iP

If you encounter any problem while doing the project, please post in the forum so that we can take the necessary action. We did significant changes to the individual project (iP) and the team project (tP) this semester. Hence, teething issues are a possibility.

We discourage you from doing project tasks allocated to future weeks, although it is fine to stay ahead of the schedule a bit (but no more than a week ahead).
Reasons: To help you gain and better simulate real projects, we want the project work to be over a longer period, rather than done as a short burst.

Reminder: As stated in the iP grading criteria, some increments need to be done each week. Clumping all the iP work into a short burst will not earn you full marks.

Please follow instructions closely. Any deviations can cause our grading scripts to miss your work (and result in you not getting credit for it).

Deadline:

Note the typical deadline for weekly project tasks:

As stated above, you have until the weekly briefing at the end of this week (i.e., Fri, Aug 21st 1600) to finish this week's iP tasks, but if you fail to do so, we won't penalize you if you can catch up within one more week after that deadline.

1 Learn about the project

  • Read the following two sections, if you haven't done so already:

Admin iP - Overview


Admin iP - Grading


2 Set up prerequisites

  • Ensure you have followed the Preparation sections of the following course tools:

Admin Programming Language


3 Set up the project on your computer

Read through this week's topics before starting the project.
If you encounter technical problems while doing the iP, follow the guidelines given below:

Admin Appendix D: Getting Help


Your GitHub username :  GitHub Avatar
Note: Type your GitHub username in the blank above so that we can customize sample commands to fit you.

  1. Fork https://github.com/NUS-CS2103-AY2627-S1/ip, while noting the points below:
    Keep the fork name as ip or else our grading scripts will not be able to detect it. You can change the fork name to something else after the semester (and the grading) is over e.g., after receiving your grade for the course.
    Keep the default branch name as master. While Git-Mastery uses main as the default branch name, iP and tP use master. As both these are used widely in the industry, it is good for you to be comfortable using both.
    Keep the source location as [project root]/src. Our grading scripts look for code in this folder.
    Uncheck the [ ] Copy the master branch only option so that you get a copy of the full repo.
  2. Enable the issue tracker of your fork (Go to Settings, scroll to the Features section, and select the Issues checkbox). Reason: At times we post feedback on your issue tracker.
    If the issue tracker is enabled, you should be able to visit the following URL: https://github.com/{your_user_name}/ip/issues/new
    e.g., https://github.com/[[username: JohnDoe]]/ip/issues/new
  3. Clone the fork onto your computer.
    Avoid putting Git-controlled files inside cloud-synced (e.g., OneDrive, Dropbox) folders. Reason: Multiple tools trying to detect/sync changes in the same folder can cause conflicts and unexpected behavior.
    If you want to access project files from multiple computers, use Git to do that (rather than cloud-syncing tools).
  4. Set up the project in your IDE as explained in the README file, if you plan to use an IDE for the project.
    Not willing to lose Vim power? If you are worried about losing access to powerful Vim features when using an IDE for the project, note that most IDEs have a Vim plugin (e.g., IdeaVim plugin) for using Vim features within the IDE. In other words, it is possible to access both IDE features and Vim features at the same time!
  5. Run Duke.java to verify that your project setup works.

4 Add Increments while committing frequently: Level-0, Level-1, Level-2, Level-3, Level-4, Level-5, Level-6, A-Enums Fri, Aug 21st 1600

Implement the below in the given order.

Keep in mind ...
  • From this point onward, commit code at important points. Minimally, commit after completing each increment.
    Remember not to commit .class files and any other file that should not be revision-controlled.
  • From this point onward, after completing each increment,
    • git tag the commit that completed the increment with the exact increment ID e.g., Level-2, A-Classes
      Git tags are not the same as Git commit messages.
      %%{init: { 'theme': 'default', 'gitGraph': {'mainBranchName': 'master'}} }%%
      gitGraph
        commit id: "..."
        commit id: "Rename main class"
        commit id: "Add greeting" tag: "Level-0"
        commit id: "Add support for echo"
        commit id: "Fix bug in echo" tag: "Level-1"
        commit id: "Add support for list"
        commit id: "Add support for bye"
      
    • git push the code to your fork
      Git doesn't push tags unless you specifically ask it to. After pushing a tag to your fork, you should be able to see that tag by visiting https://github.com/YOUR_USER_NAME/REPO_NAME/tags e.g., https://github.com/[[username: JohnDoe]]/ip/tags
      If you encounter issues connecting Sourcetree with your GitHub account, refer to this Sourcetree Tutorial.
  • The relevant textbook topics are:
  • Be familiar with how this course expects to use AI tools:

FAQ Wait. So, do we hand-code the iP or use the prompts given?
A: It's your decision, as given in the panel above. If you are not sure, you can start with level AI-2 of AI use) and move to higher levels only when you feel it is justified.

  • Remember to take note of our plagiarism policies, if you haven't done so already:

Duke Level-0: Rename, Greet, Exit

Level 0. Rename, Greet, Exit

(a) Give your chatbot a new name, to differentiate it from the placeholder name Duke.

  • Avoid these common choices as well: Chatty, Jarvis, ChatBot, Chad
  • Rename Duke.java to match the chatbot name you selected, and remove all traces of Duke from the code.
AI Guidance » Renaming the chatbot
  1. Tweak the AGENTS.md file in the project root, and commit it.

    AI agents read the information in AGENTS.md, which is included in their context.
    In this case, you can tweak the following:

    • Fill in the parts marked as [to be filled]
    • If using a Mac, ensure the instructions about switching to the correct Java version match your Java setup.
  2. Start a new chat/project in Codex (i.e., ChatGPT app in Codex mode). Set your iP folder as the folder of that chat.
    Refer to the tutorial Using the Codex Desktop App at SE-EDU Guides for more info.

  3. Try the following prompt.

I wish to change the chatbot name from duke to [NEW NAME]. Which files need to be changed in what way?

  1. If you are happy with the reply, you can follow up with a Go ahead and make those changes.

    To save tokens, start with a cheaper model (e.g., Luna at High or Extra High setting). Use more expensive models only when cheaper ones fail to meet expectations or you think the task is worth a higher cost of tokens.

    Set the permission level to Approve for me: Codex will still ask for permission before 'risky' actions but will proceed with lower-risk ones without asking every time.

  2. If Codex doesn't update the banner, you can ask it to do so.

Generate an ASCII-art banner for the word [NEW NAME] (case-sensitive). Give me a few variations.

  1. Examine and test the updated code. If you are happy with it, commit the changes. You can ask Codex to create the commit, but if you are new to Git, do the commits yourself -- it can even be faster, and it saves tokens.

(b) Update the initial code to simply greet the user and exit.

Example:

____________________________________________________________
[CHATBOT BANNER]
Hello! I'm [CHATBOT NAME].
What can I do for you?
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________
  • Horizontal lines are optional. So is the banner.
  • Change the wording to match the personality you wish to give your chatbot. The above is an example only.
AI Guidance » Updating the initial code

This change is simple enough to do by hand. Using AI lets you take 'baby steps' without giving up much hand-coding practice. Here are two sample prompts:

The requirement given to me:

[=====

Update the initial code to simply greet the user and exit.

=====]

Here is an example output:

____________________________________________________________
[CHATBOT BANNER]
Hello! I'm [CHATBOT NAME].
What can I do for you?
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________

Your task: I have updated the code to match the requirements. Review my changes and suggest possible issues and areas to improve.


Your task: Update the code to meet the above requirements.

[=====

Update the initial code to simply greet the user and exit.

=====]

Example output:

____________________________________________________________
[CHATBOT BANNER]
Hello! I'm [CHATBOT NAME].
What can I do for you?
____________________________________________________________
Bye. Hope to see you again soon!
____________________________________________________________



Duke Level-1: Echo

Level 1. Echo

Update the code to echo commands entered by the user, and exit when the user types the command bye.


Example:
     ...

     What can I do for you?
    ____________________________________________________________

list
    ____________________________________________________________
     list
    ____________________________________________________________

blah
    ____________________________________________________________
     blah
    ____________________________________________________________

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

  • The indentations are optional.

You are strongly encouraged to customize the chatbot: In addition to the command/display formats, you can even customize its personality to make your chatbot unique.

AI Guidance » Level 1. Echo

Start a new chat thread in the Codex project you created in Level-0.

Use one chat thread per iP increment, and rename the thread to match the increment. Renaming makes past chat threads easier to find, and, more importantly, one thread per increment reduces the risk of context rot .

First part of a possible prompt:

The requirement given to me:

[=====

Update the code to echo commands entered by the user, and exit when the user types the command bye.

=====]

An example output:

     ...

     What can I do for you?
    ____________________________________________________________

list
    ____________________________________________________________
     list
    ____________________________________________________________

blah
    ____________________________________________________________
     blah
    ____________________________________________________________

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

Second part of a possible prompt:

Your task: I have updated the code to match the requirements. Review my changes and suggest possible issues and areas to improve.


Your task: Update the code to meet the above requirements.




Duke Level-2: Add, List

Level 2. Add, List

Add the ability to store whatever text the user enters and display it back when requested.

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

Example:
    ...
     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!
    ____________________________________________________________

AI Guidance » Level 2. Add, List

First part of a possible prompt:

The requirement given to me:

[=====

Add the ability to store whatever text the user enters and display it back when requested.

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

=====]

An example output:

    ...
     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!
    ____________________________________________________________

Second part of a possible prompt:

Your task: I have updated the code to match the requirements. Review my changes and suggest possible issues and areas to improve.


Your task: Update the code to meet the above requirements.




Duke Level-3: Mark as Done

Level 3. Mark as Done

Add the ability to mark tasks as done. Optionally, add the ability to change the status back to not done.

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

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

unmark 2
    ____________________________________________________________
     OK, I've marked this task as not done yet:
       [ ] return book
    ____________________________________________________________

When implementing this feature, also follow the extension given below:

Extension: A-Classes


AI Guidance » General: Proceed in small steps. Examine each step.

Using AI for coding can cost us our understanding of the code, and the coding and problem-solving skills we would have gained by doing the work ourselves. We should proceed in small steps, examining each one before moving on, so we understand what is happening and learn from it.

Example In this iP increment, we can break the task into smaller steps, such as:

  1. Implement the mark command to update task status, without using additional classes.
  2. Implement the unmark command to update task status, without using additional classes.
  3. Implement the A-Classes extension by introducing a Task class.

AI Guidance » General: Use AI to explore more.

Under time pressure, we normally implement the option we think is best without considering alternatives. With AI, we can generate and compare multiple options quickly, make more informed decisions, and learn from the alternatives.

Example In this iP increment, most would have used a Task class right away. However, we can ask the AI to generate code for the mark and unmark commands without using a Task class. We can then compare the two approaches.


AI Guidance » General: Using 'skills' to create reusable workflows.

Most AI tools support 'skills', which are reusable workflows. We can create our own skills to automate repetitive tasks, and share them with others.

Example When doing a project like the iP, we can create a skill to generate a webpage that shows a visual diff between two versions of the code. This skill can be used to quickly examine the code generated by the AI before moving to the next increment.

Create the present-changes-visually skill

  1. We have already created a present-changes-visually skill and shared it at https://github.com/se-edu/skill-present-changes-visually.
    Instead of creating one from scratch, give the following prompt to Codex.

Create a project-specific skill named present-changes-visually. Use the repo https://github.com/se-edu/skill-present-changes-visually as the basis. Ask for my permission if you run into any permission issues. If required packages are missing, go ahead and install them.

If Codex runs into problems when performing tasks (e.g., permission issues, network restrictions, missing tools), push back and ask it to troubleshoot, e.g., Why couldn't you download the file? How to fix?.

  1. After the skill is created, restart Codex so that it recognizes the new skill.
  2. To test the skill, you can use the following prompt.

Use the /present-changes-visually skill

This will create _temp/visual-diff.html, a webpage comparing the current uncommitted changes with the last committed version of the code.
The format of the page should look similar to the screenshot below:

Example result of running the present-changes-visually skill


  1. You can be more specific when invoking this skill. Here is an example:

Use the /present-changes-visually skill to compare the most recent commit with the one before it. Save the file as _temp/with-and-without-tasks-class.html.

  1. Commit the new skill (it will be inside a folder .codex/skills/present-changes-visually) to the repo so that it is available for future use. Alternatively, you can add it to the .gitignore file so that the skill stays in your local repo but is not pushed to the remote repo.

AI Guidance » Level 3. Mark as Done

Step 1: Implement the mark command to update task status, without using additional classes

Implement the following requirement.

[=====

Add the ability to mark tasks as done. Do not add any new classes.

=====]

Example output:

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

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

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

Examine the new code using your code editor. Commit the changes.

Step 2: Implement the unmark command to update task status, without using additional classes

Implement the following requirement. [=====

Add the ability to reverse the done status of tasks. Do not add any new classes.

=====]

Example output:

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

unmark 2
    ____________________________________________________________
     OK, I've marked this task as not done yet:
       [ ] return book
    ____________________________________________________________

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

As before, examine the code, and commit.

Step 3: Implement the A-Classes extension

Implement the following requirement.

[=====

Add a Task class to represent tasks. Put that class in a separate file.

=====]

Partial solution:

public class Task {
    protected String description;
    protected boolean isDone;

    public Task(String description) {
        this.description = description;
        this.isDone = false;
    }

    public String getStatusIcon() {
        return (isDone ? "X" : " "); // mark done task with X
    }

    //...
}

Elsewhere in the code:

Task t = new Task("read book");
t.markAsDone();

Now that we have multiple files being updated, it is a good time to put the present-changes-visually skill to use. Invoke the skill and use the generated file to examine how introducing a separate Task class changes the code structure.

If you are not sure of the pros and cons of adding this new class, simply prompt Codex to explain it to you. Feel free to probe further using follow-up questions and push back using counterarguments.



Duke Level-4: ToDos, Events, Deadlines

Level 4. ToDos, Events, Deadlines

Add support for tracking three types of tasks:

  1. ToDos: tasks without any date/time attached to them, 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 date/time and end at a specific date/time,
    e.g., (a) team project meeting 2/10/2019 2-4pm (b) orientation week 4/10/2019 to 11/10/2019

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][X] read book
     2.[D][ ] return book (by: June 6th)
     3.[E][ ] project meeting (from: Aug 6th 2pm to: 4pm)
     4.[T][X] 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 /from Mon 2pm /to 4pm
    ____________________________________________________________
     Got it. I've added this task:
       [E][ ] project meeting (from: Mon 2pm to: 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, also follow the extension given below:

Extension: A-Inheritance


AI Guidance » Level 4. ToDos, Events, Deadlines

As before, you can proceed in small steps, for example, first adding the feature without using inheritance and then adding the extension A-Inheritance. Commit after each step, and tag after completing each increment.


AI Guidance » General: Get AI to check its work

Recent AI coding harnesses already check their own work to some extent. Even so, it is worth strengthening those guard rails yourself. In addition, do some manual testing of your own.

Create a test-ui skill that you (and Codex) can use to test the code. Here's a sample prompt:

Create a project-specific skill named test-ui, as follows.

  • The skill should accept lists of commands and expected outputs. For each command, it should run the program and check the output against the expected output.
  • The list of test cases (and other relevant information) should be recorded in the test/ui-test-plan.md file.
  • Each test case should specify the aim of the test case, inputs, and the expected output.
  • After testing, show a record of the console input and output so we can see the test session.
  • If a test case failed, terminate the test session immediately, and report the actual and expected outputs.

After the skill is created, invoke it. If the behavior is not to your satisfaction, you can ask the AI to improve the skill.

To ensure the skill is used after each code update, you can issue a prompt such as the following:

Update relevant agent files to ensure that after each code update,

  1. the test/ui-test-plan.md is updated (if needed), and,
  2. the test-ui skill is invoked.

It is likely this will result in an update to the AGENTS.md file.

Commit the changes to the Codex files.



Duke Level-5: Handle Errors

Level 5. Handle Errors

Teach the chatbot 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 :-(
    ____________________________________________________________

You are strongly encouraged to use your own wording for the error messages, rather than the ones given in the example above.

When implementing this feature, also follow the extension given below:

Extension: A-Exceptions


  • Minimal: Handle at least the two types of errors shown in the example above.
  • Typical:
    • Handle all possible errors in the current version.
    • As you evolve the chatbot, continue to handle errors related to the new features added.
  • Stretch goal:
    • Make the error handling more error-specific, e.g., give the user a clear/specific explanation of the error and how to correct it.
AI Guidance » Level 5. Handle Errors

As before, you can proceed in small steps. Ensure AI runs the test-ui skill after each code update.


AI Guidance » General: Keep updating AI files

As the project progresses, observe where AI falters or overlooks things, and update the AI files accordingly.

For example, you can force AI to improve the quality of testing with a prompt like this:

Add more test cases to cover edge cases and incorrect inputs. Interleave positive and negative test cases to detect incorrect inputs affecting the correctness of the internal states.

Then, you can introduce temporary bugs into the code and see if the test-ui skill can detect them. If it cannot, you can ask AI to improve the skill to cover such cases.



Duke Level-6: Delete

Level 6. Delete

Add support for deleting tasks from the list.

Example:

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

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

When implementing this feature, also follow the extension given below:

Extension: A-Collections


AI Guidance » General: Get AI to review tests
  • You can also ask different Codex models to review the ui-test-plan.md and suggest ways to improve it. Something overlooked by one model can be detected by another.
  • This is also a good place to use more powerful models. Crafting good test cases has long-term benefits and is worth the extra token cost.
  • You can go one step further and get other AI tools (Claude, Gemini, etc.) to review the test cases file too.


Duke A-Enums: Use Enums if-applicable

A-Enums

     ↳ Use enumerations

Use Java enums, if applicable (i.e., if enums a natural fit for somewhere your current code).

AI Guidance » A-Enums

Here's a useful experiment: First, look through the code and see if you can identify any variables that can be represented as an enum. Then, ask AI to suggest a list of enums that can be used in the code.



FAQ about iP increments

FAQ How are the iP git tags used in grading?


FAQ What if I discovered a bug after I finished an increment?


FAQ I did multiple increments in the same commit. How to fix?


FAQ The requirements of an increment scheduled for this week are already satisfied by the work I did in an earlier week. What now?


FAQ My iP increments are not detected by the dashboard because I forgot to push my tags earlier. What now?


FAQ Can the iP dashboard be updated more frequently?


FAQ If I do optional increments, do I get more marks?


FAQ Oh no! I used the wrong tag/branch name.


FAQ I forked the iP repo from a previous semester. How to fix?