-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Qin Nanxin] iP #572
base: master
Are you sure you want to change the base?
[Qin Nanxin] iP #572
Changes from 22 commits
28ad2b8
ed6d4d2
abfac81
517a3a2
5130bfd
5823330
59f198a
5f799dd
227c818
c8a51aa
b60464f
fb28447
cb37643
06d749e
ccefdd8
c5e5035
f6fa252
268ecd1
ec71f5a
2832520
8e0a3da
bc254bf
bc20f51
5591645
90fb38b
b0c2294
e1e5352
1b46958
60851c5
9ee8913
13f7891
0915f76
f1b52a4
48e1b39
3e9730d
e3f32d4
4ef7983
cbba5e0
14daed2
454b9ec
83021ff
202d315
3a6c213
f270bbc
87585ce
0264fab
64cd33a
677a0a3
e9c434c
c9b3825
e62e810
9c23bc9
f1ca54a
59dedbd
7c5fc1f
8cc478f
69a2e5d
96b6642
17e9d8b
066511a
34a161e
22fc82a
91503fa
77e2a1d
47711eb
ca6addc
618da5b
f7d2b25
6182e16
ad511a3
a87b8a8
c77c2bb
27af30c
55a69f3
699769d
722c222
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
T | 1 | task1 | ||
E | 1 | task3 | startTime-endTime | ||
T | 0 | task4 | ||
D | 0 | task5 | ddl2 | ||
E | 0 | task6 | startTime1-endTime2 | ||
E | 0 | task1 | a-a | ||
E | 0 | task 2 | a-a | ||
E | 0 | task 1 | a-a | ||
E | 0 | task 1 | a-a | ||
D | 0 | test | a |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
public class Deadline extends Task { | ||
private String deadline; | ||
|
||
public Deadline(String task, String deadline) throws DukeException{ | ||
super(task); | ||
this.deadline = deadline; | ||
} | ||
|
||
@Override | ||
public String getStatus(){ | ||
String time = "(by: " + deadline + ")"; | ||
return "[Deadline]" + super.getStatus() + " " + time; | ||
} | ||
|
||
@Override | ||
public String getTime() { | ||
return deadline; | ||
} | ||
|
||
@Override | ||
public String toFileString() { | ||
return super.isDone ? ("D | 1 | " + super.task + " | " + this.deadline) | ||
: ("D | 0 | " + super.task + " | " + this.deadline); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The indentation for the case blocks inside the switch statement within the try block does not follow the coding standard |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,291 @@ | ||
import java.io.BufferedReader; | ||
import java.io.FileReader; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.io.PrintWriter; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.time.format.DateTimeParseException; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Scanner; | ||
|
||
public class Duke { | ||
public static void main(String[] args) { | ||
String logo = " ____ _ \n" | ||
+ "| _ \\ _ _| | _____ \n" | ||
+ "| | | | | | | |/ / _ \\\n" | ||
+ "| |_| | |_| | < __/\n" | ||
+ "|____/ \\__,_|_|\\_\\___|\n"; | ||
System.out.println("Hello from\n" + logo); | ||
public static final String PARTITION = "------------------------------------------------------------"; | ||
public static final String NAME = "Duke Max"; | ||
public static final Scanner SCANNER = new Scanner(System.in); | ||
public static final String FILEPATH = "./data/tasks.txt"; | ||
|
||
public static ArrayList<Task> taskList = new ArrayList<Task>(); | ||
|
||
public static void main(String[] args) throws DukeException{ | ||
load(FILEPATH); | ||
greet(); | ||
String input = SCANNER.next(); | ||
while(!input.equals("bye")) { | ||
try { | ||
switch(input){ | ||
case "list": | ||
print(); | ||
break; | ||
case "print": | ||
String time = SCANNER.nextLine(); | ||
if (time.isBlank() || time.isEmpty()) { | ||
print(); | ||
break; | ||
} | ||
|
||
time = formatTime(time); | ||
if (time == null) { | ||
String messageSorry = "Sorry, you have entered the wrong format for time."; | ||
String messageFormat = "Please enter in the format of yyyy-MM-dd HH:mm:ss or yyyy-MM-dd"; | ||
throw new DukeException(messageSorry + "\n" + messageFormat); | ||
} | ||
|
||
print(time); | ||
break; | ||
case "mark": | ||
int markItem = SCANNER.nextInt(); | ||
taskList.get(markItem - 1).markItem(true); | ||
save(FILEPATH); | ||
break; | ||
case "unmark": | ||
int unmarkItem = SCANNER.nextInt(); | ||
taskList.get(unmarkItem - 1).markItem(false); | ||
save(FILEPATH); | ||
break; | ||
case "delete": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider making inputs case-insensitive! This way, if I requested to add a todo writing: tOdO it would still add the task into the list. |
||
int deleteItem = SCANNER.nextInt(); | ||
if (deleteItem >= taskList.size()) { | ||
throw new DukeException("Sorry, seleted event is out of range."); | ||
} | ||
delete(deleteItem); | ||
save(FILEPATH); | ||
break; | ||
case "todo": | ||
String toDoEvent = SCANNER.nextLine(); | ||
if (toDoEvent.isBlank() || toDoEvent.isEmpty()) { | ||
throw new DukeException("Sorry, the todo task must have a title."); | ||
} | ||
add(new ToDo(toDoEvent)); | ||
save(FILEPATH); | ||
break; | ||
case "event": | ||
String eventCommand = SCANNER.nextLine(); | ||
//when user didn't provide title and start & end time | ||
if (eventCommand.isBlank() || eventCommand.isEmpty() | ||
|| !eventCommand.contains(" /from ") || !eventCommand.contains(" /to ")) { | ||
throw new DukeException("Sorry, this event must have a title, start time, and end time."); | ||
} | ||
String[] event = new String[3]; | ||
try { | ||
event[0] = eventCommand.substring(1, eventCommand.indexOf(" /")); | ||
event[1] = eventCommand.substring(eventCommand.indexOf("/from") + 6, | ||
eventCommand.indexOf(" /to")); | ||
event[2] = eventCommand.substring(eventCommand.indexOf("/to") + 4); | ||
} | ||
catch (StringIndexOutOfBoundsException e) { | ||
System.out.println("Sorry, this event must have a title, start time, and end time."); | ||
} | ||
//when user provide empty title | ||
if (event[0].isBlank() || event[0].isEmpty()) { | ||
throw new DukeException("Sorry, the event must have a title."); | ||
} | ||
//when user didn't provide the starting time | ||
if (event[1].isBlank() || event[1].isEmpty()) { | ||
throw new DukeException("Sorry, the event must have a starting time"); | ||
} | ||
//when user didn't provide the end time | ||
if (event[2].isBlank() || event[2].isEmpty()) { | ||
throw new DukeException("Sorry, the event must have an end time"); | ||
} | ||
//when user provide wrong time format | ||
String startTime = formatTime(event[1]); | ||
String endTime = formatTime(event[2]); | ||
if (startTime.isBlank() || startTime.isEmpty() || endTime.isBlank() || endTime.isEmpty()) { | ||
throw new DukeException("Please enter the time with this format: yyyy-MM-dd HH:mm:ss"); | ||
} | ||
add(new Event(event[0], startTime, endTime)); | ||
save(FILEPATH); | ||
break; | ||
case "deadline": | ||
String ddlCommand = SCANNER.nextLine(); | ||
//when user didn't provide title & ddl | ||
if (ddlCommand.isBlank() || ddlCommand.isEmpty() || !ddlCommand.contains(" /by ")) { | ||
throw new DukeException("Sorry, the deadline task must have a title and a deadline."); | ||
} | ||
String[] ddl = new String[2]; | ||
try { | ||
ddl = ddlCommand.split(" /by "); | ||
} | ||
catch (ArrayIndexOutOfBoundsException e) { | ||
System.out.println("Sorry, this deadline task must have a title and a deadline."); | ||
} | ||
//when user provide empty title | ||
if (ddl[0].isBlank() || ddl[0].isEmpty()) { | ||
throw new DukeException("Sorry, the deadline event must have a title."); | ||
} | ||
//when user didn't provide ddl | ||
if (ddl[1].isBlank() || ddl[1].isEmpty()) { | ||
throw new DukeException("Sorry, the deadline event must have a dealine"); | ||
} | ||
String ddlTime = formatTime(ddl[1]); | ||
//when user provide wrong time format | ||
if (ddlTime.isBlank() || ddlTime.isEmpty()) { | ||
throw new DukeException("Please enter the time with this format: yyyy-MM-dd HH:mm:ss"); | ||
} | ||
add(new Deadline(ddl[0].substring(1), ddlTime)); | ||
save(FILEPATH); | ||
break; | ||
case "clear": | ||
clear(); | ||
break; | ||
default: | ||
throw new DukeException("Sorry, I don't recognize this input. Please try again."); | ||
} | ||
} | ||
|
||
catch (DukeException e) { | ||
System.out.println(e.getMessage()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think your method is too long here. Maybe try to create some other methods?😎 |
||
//help(); | ||
} | ||
|
||
finally { | ||
System.out.println(PARTITION); | ||
input = SCANNER.next(); | ||
} | ||
} | ||
|
||
exit(); | ||
} | ||
|
||
public static void greet() { | ||
System.out.println(PARTITION); | ||
System.out.println("Hello! I'm " + NAME + "."); | ||
System.out.println("What can I do for you?"); | ||
System.out.println(PARTITION); | ||
} | ||
|
||
public static void add(Task input) { | ||
taskList.add(input); | ||
System.out.println("Got it! This task has been added: "); | ||
System.out.println(input.getStatus()); | ||
System.out.println("Current # of " + plural(taskList.size(), "task") + ": " + taskList.size()); | ||
} | ||
|
||
public static void delete(int num) { | ||
System.out.println("I've removed this task:"); | ||
taskList.get(num-1).getStatus(); | ||
taskList.remove(num - 1); | ||
System.out.println("Current # of " + plural(taskList.size(), "task") + ": " + taskList.size()); | ||
} | ||
|
||
public static void print() { | ||
int index = 1; | ||
for (Task task: taskList) { | ||
System.out.println(index + ". " + task.getStatus()); | ||
index ++; | ||
} | ||
System.out.println("Current # of " + plural(taskList.size(), "task") + ": " + taskList.size()); | ||
} | ||
|
||
public static void print(String time) { | ||
int count = 0; | ||
for(Task task: taskList) { | ||
if(task.getTime().contains(time)) { | ||
System.out.println(task.getStatus()); | ||
count += 1; | ||
} | ||
} | ||
System.out.println("Current # of " + plural(count, "task") + ": " + taskList.size()); | ||
} | ||
|
||
public static void clear() { | ||
taskList.clear(); | ||
System.out.println("Okay, I have cleared all tasks."); | ||
} | ||
|
||
public static void exit() { | ||
System.out.println("Bye. Hope to see you again soon!"); | ||
System.out.println(PARTITION); | ||
} | ||
|
||
private static String plural(int count, String word) { | ||
return (count <= 1) ? word : (word + "s"); | ||
} | ||
|
||
private static void save(String path) { | ||
try (PrintWriter printwriter = new PrintWriter(new FileWriter(path))) { | ||
for (Task task : taskList) { | ||
printwriter.write(task.toFileString() +"\n"); | ||
} | ||
} catch (IOException e) { | ||
System.out.println("There is an error saving this file: " + e.getMessage()); | ||
} | ||
} | ||
|
||
private static ArrayList<Task> load(String path) throws DukeException{ | ||
handleMissing(path); | ||
|
||
try (BufferedReader reader = new BufferedReader(new FileReader(path))) { | ||
String text = reader.readLine(); | ||
while (text != null) { | ||
Task task = Task.convertStringToTask(text); | ||
taskList.add(task); | ||
text = reader.readLine(); | ||
} | ||
} catch (IOException e) { | ||
System.out.println("There is an error loading tasks from file: " + e.getMessage()); | ||
} | ||
return taskList; | ||
} | ||
|
||
private static void handleMissing(String testPath) { | ||
try{ | ||
//if directory or path doesn't exist | ||
Path directoryPath = Paths.get(".", "data"); | ||
if (!Files.exists(directoryPath)) { | ||
Files.createDirectories(directoryPath); | ||
} | ||
|
||
Path path = directoryPath.resolve("tasks.txt"); | ||
if (!Files.exists(path)) { | ||
Files.createFile(path); | ||
} | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
System.out.println("There is an error loading file: " + e.getMessage()); | ||
} | ||
} | ||
|
||
private static String formatTime(String input) { | ||
try { | ||
// when input have a date and a time | ||
// convert string to LocalDateTime then convert to another format | ||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | ||
LocalDateTime dateTime = LocalDateTime.parse(input, formatter); | ||
return dateTime.format(DateTimeFormatter.ofPattern("MMM d yyyy HH:mm")); | ||
} catch (DateTimeParseException notDateTime) { | ||
try { | ||
// input is only a date | ||
LocalDate date = LocalDate.parse(input); | ||
return date.format(DateTimeFormatter.ofPattern("MMM d yyyy")); | ||
} catch (DateTimeParseException notDate) { | ||
try { | ||
// input is only a time | ||
LocalTime time = LocalTime.parse(input); | ||
return time.format(DateTimeFormatter.ofPattern("HH:mm")); | ||
} catch (DateTimeParseException nullError) { | ||
return null; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation & Formatting: The code seems to be properly indented, which makes it easier to read. Names like input, eventCommand, and ddlCommand are meaningful, but some variables like ddl could have a more descriptive name. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
public class DukeException extends Exception { | ||
public DukeException(String message) { | ||
super(message); | ||
} | ||
|
||
@Override | ||
public String getMessage() { | ||
return ":( Oh no! " + super.getMessage(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
public class Event extends Task { | ||
private String from; | ||
private String to; | ||
|
||
public Event(String task, String from, String to) throws DukeException { | ||
super(task); | ||
this.from = from; | ||
this.to = to; | ||
} | ||
|
||
@Override | ||
public String getStatus(){ | ||
String time = "(from: " + from + " to: " + to + ")"; | ||
return "[Event]" + super.getStatus() + " " + time; | ||
} | ||
|
||
@Override | ||
public String getTime() { | ||
return this.from + " " + this.to; | ||
} | ||
|
||
@Override | ||
public String toFileString() { | ||
return super.isDone ? ("E | 1 | " + super.task + " | " + this.from + "-" + this.to) | ||
: ("E | 0 | " + super.task + " | " + this.from + "-" + this.to); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall good job! Good use of abstraction using the Task class! However, it might be a better idea to have even more abstraction through the addition of a UI class that handles all the printing and a TaskList class that handles the list of Tasks.