Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a447b61
rename Duke to Pixy
thezerohour Jan 22, 2025
38d83cd
implement command echo
thezerohour Jan 31, 2025
b5331c0
implement add, list commands
thezerohour Jan 31, 2025
054d37f
create Task class, mark and unmark commands
thezerohour Jan 31, 2025
c43b0db
implement task, deadline and event classes, debugged and SLAMed as fa…
thezerohour Feb 12, 2025
a245e22
improved compliance with coding standard
thezerohour Feb 13, 2025
3688b61
implement exception handling, clean up code
thezerohour Feb 20, 2025
799cbc5
Merge branch 'branch-Level-5'
thezerohour Feb 20, 2025
a71aa3d
move files into packages
thezerohour Feb 21, 2025
b019b15
minor readme edit
thezerohour Feb 21, 2025
3f8150e
Merge branch 'branch-A-Packages'
thezerohour Feb 21, 2025
d6c763c
Implement task deletion. Collections class already in use.
thezerohour Mar 3, 2025
f844cd3
implement data saving to text file
thezerohour Mar 4, 2025
c4d8a27
Merge branch 'branch-Level-6'
thezerohour Mar 4, 2025
f9dd053
Merge branch 'branch-Level-7'
thezerohour Mar 4, 2025
26e2a96
code cleanup
thezerohour Mar 4, 2025
ae3792e
update gitignore
thezerohour Mar 4, 2025
a03dff7
refactored code for "more OOP"
thezerohour Mar 13, 2025
c85090d
implemented search feature
thezerohour Mar 14, 2025
9c4e0d5
added javadoc to codebase
thezerohour Mar 14, 2025
af13245
Merge branch 'Level-9'
thezerohour Mar 14, 2025
092dc85
Merge branch 'master' of https://github.com/thezerohour/ip into A-Jav…
thezerohour Mar 14, 2025
3d62e35
added javadoc for search feature
thezerohour Mar 14, 2025
474c1dd
Merge branch 'A-JavaDoc'
thezerohour Mar 14, 2025
4647575
update README
thezerohour Mar 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ bin/

/text-ui-test/ACTUAL.TXT
text-ui-test/EXPECTED-UNIX.TXT

#testing data
/data/
87 changes: 73 additions & 14 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,89 @@
# Duke User Guide
# Pixy User Guide

// Update the title above to match the actual product name
```
Hello! I'm Pixy
What can I do for you?
```

Pixy allows you to manage your tasks with ease, while having an anti-border tendency.

## Adding ToDos

`todo {taskName}`

Adds a todo task with the specified task name.

```
todo added: [T][ ] add new task
```

## Adding Deadlines

`deadline {taskName} /by {deadline}`

Adds a deadline task with the specified task name and deadline.

```
deadline added: [D][ ] add new deadline (by: yesterday)
```

## Adding Events

// Product screenshot goes here
`event {eventName} /from {eventStart} /to {eventEnd}`

// Product intro goes here
Adds an event task with the specified event name, start time and end time.

## Adding deadlines
```
event added: [E][ ] erase all borders (from: 25 Dec 1995, to: 31 Dec 1995)
```

## Listing Tasks

`list`

// Describe the action and its outcome.
Lists all tasks in the task list.

// Give examples of usage
```
Here are the tasks in your list:
[T][ ] add new task
[D][ ] add new deadline (by: yesterday)
[E][ ] erase all borders (from: 25 Dec 1995, to: 31 Dec 1995)
```

Example: `keyword (optional arguments)`
## Marking Task as done

// A description of the expected outcome goes here
`mark {taskNumber}`

Marks the task with the specified task number as done.
```
expected output
Nice! I've marked this task as done:
[T][X] add new task
```

## Feature ABC
## Marking Task as undone

`unmark {taskNumber}`

Marks the task with the specified task number as undone.

// Feature details
## Deleting Tasks

`delete {taskNumber}`

## Feature XYZ
Deletes the task with the specified task number.

// Feature details
```
OK, I've marked this task as not done yet:
[T][ ] add new task
```

## Searching Tasks

`find {keyword}`

Searches for tasks with the specified keyword.

```
Here are the matching tasks in your list:
[E][ ] erase all borders (from: 25 Dec 1995, to: 31 Dec 1995)
```
10 changes: 0 additions & 10 deletions src/main/java/Duke.java

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/java/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: pixy.ui.Pixy

136 changes: 136 additions & 0 deletions src/main/java/pixy/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package pixy.parser;

import pixy.ui.PixyException;
import pixy.task.Deadline;
import pixy.task.Event;
import pixy.task.TaskList;
import pixy.task.Todo;

/**
* The Parser class is responsible for parsing user commands and executing corresponding actions on the TaskList.
*/
public class Parser {
private static final String MESSAGE_INVALID_TIME = "invalid time >:(";
private static final String MESSAGE_EMPTY_DESCRIPTION = "empty description >:(";

/**
* Parses the user input and executes the corresponding command.
*
* @param input the user input to be parsed
* @param taskList the task list to be modified
* @throws PixyException if an error occurs during parsing or execution of the command
*/
public static void parseCommand(String input, TaskList taskList) throws PixyException {
String command = input.trim().split(" ")[0];
switch (command) {
case "list" -> taskList.printTasks();
case "unmark" -> unmarkTask(input, taskList);
case "mark" -> markTask(input, taskList);
case "delete" -> deleteTask(input, taskList);
case "todo" -> addTodo(input, taskList);
case "deadline" -> addDeadline(input, taskList);
case "event" -> addEvent(input, taskList);
case "find" -> findTasks(input, taskList);
default -> invalidCommand();
}
}

/**
* Deletes a task from the task list based on the given input.
*
* @param input the input string containing the task index to be deleted
* @param taskList the task list from which the task will be deleted
*/
private static void deleteTask(String input, TaskList taskList) {
int taskIndex = Integer.parseInt(input.substring(7)) - 1;
System.out.println("Noted. I've removed this task:");
System.out.println(taskList.deleteTask(taskIndex));
}

private static void invalidCommand() {
System.out.println("not a command!");
}

/**
* Adds an event task to the task list.
*
* @param input the input string containing the event task details
* @param taskList the task list to add the event task to
* @throws PixyException if the input string does not contain "/from" or "/to"
*/
private static void addEvent(String input, TaskList taskList) throws PixyException {
if (!input.contains(" /from ") || !input.contains(" /to ")) {
throw new PixyException(MESSAGE_INVALID_TIME);
}
String[] eventTask = input.substring(6).split(" /from ", 2);
String[] eventTime = eventTask[1].split(" /to ", 2);
taskList.addTask(new Event(eventTask[0], eventTime[0], eventTime[1]));
}

/**
* Adds a deadline task to the task list.
*
* @param input the input string containing the task details and deadline
* @param taskList the task list to add the deadline task to
* @throws PixyException if the input string does not contain the "/by" delimiter
*/
private static void addDeadline(String input, TaskList taskList) throws PixyException {
if (!input.contains(" /by ")) {
throw new PixyException(MESSAGE_INVALID_TIME);
}
String[] deadlineTask = input.substring(9).split(" /by ", 2);
taskList.addTask(new Deadline(deadlineTask[0], deadlineTask[1]));
}

/**
* Adds a new Todo task to the task list.
*
* @param input the input string containing the description of the task
* @param taskList the task list to add the task to
* @throws PixyException if the description is empty
*/
private static void addTodo(String input, TaskList taskList) throws PixyException {
String description = input.substring(input.indexOf(" ") + 1);
if (description.isBlank()) {
throw new PixyException(MESSAGE_EMPTY_DESCRIPTION);
}
taskList.addTask(new Todo(description));
}

/**
* Marks a task as done in the task list.
*
* @param input the input string containing the task index
* @param taskList the task list to mark the task in
*/
private static void markTask(String input, TaskList taskList) {
int taskIndex = Integer.parseInt(input.substring(5)) - 1;
taskList.markTask(taskIndex, true);
System.out.println("Nice! I've marked this task as done:");
System.out.println(taskList.getTask(taskIndex));
}

/**
* Unmarks a task as not done yet.
*
* @param input the input string containing the task index
* @param taskList the task list to modify
*/
private static void unmarkTask(String input, TaskList taskList) {
int taskIndex = Integer.parseInt(input.substring(7)) - 1;
taskList.markTask(taskIndex, false);
System.out.println("OK, I've marked this task as not done yet:");
System.out.println(taskList.getTask(taskIndex));
}

/**
* Finds tasks in the given input and searches for them in the task list.
*
* @param input The input string containing the keyword to search for tasks.
* @param taskList The task list to search for tasks in.
*/
private static void findTasks(String input, TaskList taskList) {
String keyword = input.substring(5).trim();
taskList.searchTasks(keyword);
}
}
82 changes: 82 additions & 0 deletions src/main/java/pixy/storage/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package pixy.storage;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import pixy.task.Task;
import pixy.task.Todo;
import pixy.task.Deadline;
import pixy.task.Event;

/**
* The `Storage` class is responsible for saving and loading tasks to/from a file.
* It provides methods to save a list of tasks to a specified file path and load tasks from an existing file.
*/
public class Storage {
private final String filePath;

public Storage(String filePath) {
this.filePath = filePath;
}

/**
* Saves the given list of tasks to a file.
*
* @param tasks The list of tasks to be saved.
*/
public void saveTasksToFile(List<Task> tasks) {
try {
File file = new File(filePath);
file.getParentFile().mkdirs(); // Create directories if they do not exist
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
for (Task task : tasks) {
writer.write(task.toFileFormat());
writer.newLine();
}
}
} catch (IOException e) {
System.out.println("An error occurred while saving tasks: " + e.getMessage());
}
}

/**
* Loads tasks from a file and adds them to the provided list of tasks.
*
* @param tasks The list of tasks to add the loaded tasks to.
*/
public void loadTasksFromFile(List<Task> tasks) {
try {
File file = new File(filePath);
if (!file.exists()) {
return; // If the file does not exist, there's nothing to load
}
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" \\| ");
String type = parts[0];
boolean isDone = parts[1].equals("1");
String description = parts[2];
switch (type) {
case "T" -> tasks.add(new Todo(description, isDone));
case "D" -> {
String by = parts[3];
tasks.add(new Deadline(description, by, isDone));
}
case "E" -> {
String from = parts[3];
String to = parts[4];
tasks.add(new Event(description, from, to, isDone));
}
}
}
}
} catch (IOException e) {
System.out.println("An error occurred while loading tasks: " + e.getMessage());
}
}
}
48 changes: 48 additions & 0 deletions src/main/java/pixy/task/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package pixy.task;

/**
* Represents a task with a deadline.
* Inherits from the Task class.
*/
public class Deadline extends Task {
protected String by;

/**
* Creates a new Deadline task with the given description and deadline.
*
* @param description The description of the Deadline task.
* @param by The deadline of the task.
*/
public Deadline(String description, String by) {
super(description);
this.by = by;
System.out.println("deadline added: " + this);
}

/**
* Constructs a new Deadline object with the given description, due date, and completion status.
*
* @param description the description of the deadline
* @param by the due date of the deadline
* @param isDone the completion status of the deadline
*/
public Deadline(String description, String by, boolean isDone) {
super(description, isDone);
this.by = by;
}

@Override
protected String getTaskType() {
return "D";
}

@Override
public String toFileFormat() {
return String.format("%s | %d | %s | %s", getTaskType(), isDone ? 1 : 0, description, by);
}

@Override
public String toString() {
return "[D]" + super.toString() + " (by: " + by + ")";
}
}
Loading