Skip to content

Commit

Permalink
Add Sort functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
koh-jx committed Sep 16, 2021
1 parent 007c788 commit a966916
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 44 deletions.
38 changes: 26 additions & 12 deletions src/main/java/duke/command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,6 @@ public abstract class Command {
*/
public abstract String execute();

/**
* Takes in a String date and returns its corresponding LocalDate object.
*
* @param date String date in format DD/MM/YYYY, with 1-2 digits from Day and Month.
* @return LocalDate object with the corresponding day, month and year.
* @throws DateTimeParseException Thrown if date passed is an invalid one.
*/
protected static LocalDate getDate(String date) throws DateTimeParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy");
return LocalDate.parse(date, formatter);
}

/**
* Represents Command as a string.
*
Expand All @@ -51,4 +39,30 @@ public String toString() {
return commandName + " - " + description + '\n'
+ argString + '\n';
}

protected static String getCommand(String str)
throws IllegalArgumentException{
int index = getCommandArgumentSplitIndex(str);
return str.substring(0, index);
}

protected static String getArgument(String str)
throws IllegalArgumentException {

// Ensure validity; has a command and an argument
int index = getCommandArgumentSplitIndex(str);
return str.substring(index).trim();
}

private static int getCommandArgumentSplitIndex(String str)
throws IllegalArgumentException {
// Ensure validity; has a command and an argument
int index = str.indexOf(' ');

if (index == -1) {
throw new IllegalArgumentException(Ui.MESSAGE_INVALID_ARG);
}

return index;
}
}
5 changes: 3 additions & 2 deletions src/main/java/duke/command/CommandAddDeadline.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.format.DateTimeParseException;

import duke.ui.Ui;
import duke.util.DukeParser;
import task.TaskDeadline;
import task.TaskList;

Expand All @@ -20,7 +21,7 @@ public class CommandAddDeadline extends Command {
* @param input Array with info needed to create the class.
*/
public CommandAddDeadline(TaskList taskList, String[] input) {
this.commandName = "deadline <string> /by DD/MM/YYYY xxxxH";
this.commandName = "deadline <string> /by DD/MM/YYYY xxxx";
this.description = "Creates a deadline task";
this.arguments = new String[]{
"<string> Description of Deadline",
Expand All @@ -40,7 +41,7 @@ public String execute() {
try {
return taskList.add(new TaskDeadline(
input[0],
Command.getDate(input[1]),
DukeParser.getDate(input[1]),
input[2],
false));
} catch (DateTimeParseException e) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/duke/command/CommandAddEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.format.DateTimeParseException;

import duke.ui.Ui;
import duke.util.DukeParser;
import task.TaskEvent;
import task.TaskList;

Expand All @@ -20,7 +21,7 @@ public class CommandAddEvent extends Command {
* @param input Array with info needed to create the class.
*/
public CommandAddEvent(TaskList taskList, String[] input) {
this.commandName = "event <string> /at DD/MM/YYYY xxxxH";
this.commandName = "event <string> /at DD/MM/YYYY xxxx";
this.description = "Creates a deadline task (Optional time argument)";
this.arguments = new String[]{
"<string> Description of Event",
Expand All @@ -40,7 +41,7 @@ public String execute() {
try {
return taskList.add(new TaskEvent(
input[0],
Command.getDate(input[1]),
DukeParser.getDate(input[1]),
input[2],
false));
} catch (DateTimeParseException e) {
Expand Down
25 changes: 10 additions & 15 deletions src/main/java/duke/command/CommandList.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.function.Predicate;

import duke.ui.Ui;
import duke.util.DukeParser;
import task.Task;
import task.TaskList;

Expand All @@ -15,15 +16,15 @@
public class CommandList extends Command {

private final TaskList taskList;
private final String args;
private final String unparsedFilters;

/**
* Constructor for this command.
*
* @param taskList Task list to list.
* @param args Un-parsed list of filters.
* @param unparsedFilters Un-parsed list of filters.
*/
public CommandList(TaskList taskList, String args) {
public CommandList(TaskList taskList, String unparsedFilters) {
this.commandName = "list /name <name> /date DD/MM/YYYY";
this.description = "Toggles completion of task. Order of arguments does not matter";
this.arguments = new String[]{
Expand All @@ -33,15 +34,15 @@ public CommandList(TaskList taskList, String args) {
};

this.taskList = taskList;
this.args = args;
this.unparsedFilters = unparsedFilters;
}

/**
* Lists out tasks based on given filters.
*/
@Override
public String execute() {
if (args == null) {
if (unparsedFilters == null) {
// Display all if no filters
ArrayList<Predicate<Task>> filter = new ArrayList<>();
filter.add(task -> true);
Expand All @@ -50,7 +51,7 @@ public String execute() {

// Extract modifiers and filter
try {
ArrayList<Predicate<Task>> filters = listStringToFilter(args);
ArrayList<Predicate<Task>> filters = listStringToFilter(unparsedFilters);
return taskList.displayList(filters);
} catch (DateTimeParseException e) {
return Ui.MESSAGE_INVALID_DATE;
Expand Down Expand Up @@ -82,22 +83,16 @@ private ArrayList<Predicate<Task>> listStringToFilter(String stringToParse)
continue;
}

// Ensure validity; has a command and an argument
int index = str.indexOf(' ');
if (index == -1) {
throw new IllegalArgumentException(Ui.MESSAGE_INVALID_ARG);
}

// Get command and argument information
String command = str.substring(0, index);
String arg = str.substring(index).trim();
String command = getCommand(str);
String arg = getArgument(str);

switch (command) {
case ("name"):
results.add(task -> task.getDescription().contains(arg));
break;
case ("date"):
LocalDate date = Command.getDate(arg);
LocalDate date = DukeParser.getDate(arg);
results.add(task -> task.isDate(date));
break;
default:
Expand Down
110 changes: 110 additions & 0 deletions src/main/java/duke/command/CommandSort.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package duke.command;

import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;

import duke.ui.Ui;
import task.Task;
import task.TaskList;

/**
* Command to sort the tasklist
*/
public class CommandSort extends Command {

private final TaskList taskList;
private final String sortFilters;

/**
* Constructor for this command.
*
* @param taskList Task list to list.
* @param sortFilters Un-parsed list of filters.
*/
public CommandSort(TaskList taskList, String sortFilters) {
this.commandName = "list /name <name> /date DD/MM/YYYY";
this.description = "Toggles completion of task. Order of arguments does not matter";
this.arguments = new String[]{
"/name Optional argument to search for particular name",
"/date Optional date argument in DAY/MONTH/YEAR, "
+ "to search for tasks on a particular date"
};

this.taskList = taskList;
this.sortFilters = sortFilters;
}

/**
* Lists out tasks based on given filters.
* TODO
*/
@Override
public String execute() {
try {
taskList.sort(sortStringToFilter(sortFilters));
return new CommandList(taskList, null).execute();
} catch (IllegalArgumentException e) {
return e.getMessage();
}
}

/**
* Gets arguments from a multi-argument string.
*
* @param stringToParse String to parse.
* @return Arraylist with all filters to use to display list.
* @throws DateTimeParseException Thrown if error in parsing dates.
* @throws IllegalArgumentException Thrown if an argument is in a wrong format.
*/
private ArrayList<Comparator<Task>> sortStringToFilter(String stringToParse)
throws DateTimeParseException, IllegalArgumentException {

if (stringToParse == null) {
ArrayList<Comparator<Task>> results = new ArrayList<>();
results.add(createNameComparator());
return results;
}

// Separate individual commands
String[] args = stringToParse.split(" /");

ArrayList<Comparator<Task>> results = new ArrayList<>();

for (String str : args) {

// Ignore any empty strings
if (str.equals("")) {
continue;
}

switch (str) {
case ("name"):
results.add(createNameComparator());
break;
case ("date"):
results.add(createDateTimeComparator());
break;
default:
throw new IllegalArgumentException(Ui.MESSAGE_INVALID_ARG);
}
}

return results;
}

private Comparator<Task> createNameComparator() {
return Comparator.comparing(Task::getDescription);
}

private Comparator<Task> createDateTimeComparator() {
return (o1, o2) -> {
int compareDate = o1.getDate().compareTo(o2.getDate());
return compareDate == 0
? o1.getTime().compareTo(o2.getTime())
: o1.getDate().compareTo(o2.getDate());
};
}
}
34 changes: 22 additions & 12 deletions src/main/java/duke/util/DukeParser.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package duke.util;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import duke.command.Command;
import duke.command.CommandAddDeadline;
import duke.command.CommandAddEvent;
import duke.command.CommandAddTodo;
import duke.command.CommandDelete;
import duke.command.CommandDone;
import duke.command.CommandExit;
import duke.command.CommandHelp;
import duke.command.CommandInvalid;
import duke.command.CommandList;
import duke.command.*;
import task.TaskList;

/**
Expand All @@ -28,11 +22,12 @@ public class DukeParser {
private static final Pattern DELETE_PATTERN = Pattern.compile("delete (\\d+)", Pattern.CASE_INSENSITIVE);
private static final Pattern TODO_PATTERN = Pattern.compile("todo (.+)", Pattern.CASE_INSENSITIVE);
private static final Pattern DEADLINE_PATTERN = Pattern.compile(
"deadline (.+) /by (\\d{1,2}/\\d{1,2}/\\d{4}+)( \\d{4}+H)?",
"deadline (.+) /by (\\d{1,2}/\\d{1,2}/\\d{4}+)( \\d{4}+)?",
Pattern.CASE_INSENSITIVE);
private static final Pattern EVENT_PATTERN = Pattern.compile(
"event (.+) /at (\\d{1,2}/\\d{1,2}/\\d{4}+)( \\d{4}+H)?",
"event (.+) /at (\\d{1,2}/\\d{1,2}/\\d{4}+)( \\d{4}+)?",
Pattern.CASE_INSENSITIVE);
private static final Pattern SORT_PATTERN = Pattern.compile("sort( .+)?", Pattern.CASE_INSENSITIVE);

private final TaskList taskList;

Expand Down Expand Up @@ -65,6 +60,7 @@ public Command parseInput(String input) {
final Matcher checkTodo = TODO_PATTERN.matcher(input);
final Matcher checkDeadline = DEADLINE_PATTERN.matcher(input);
final Matcher checkEvent = EVENT_PATTERN.matcher(input);
final Matcher checkSort = SORT_PATTERN.matcher(input);

// Check if matcher found any matches and returns relevant command
if (checkList.matches()) {
Expand All @@ -85,10 +81,24 @@ public Command parseInput(String input) {
checkEvent.group(2),
checkEvent.group(3)
});
} else if (checkSort.matches()) {
return new CommandSort(taskList, checkSort.group(1));
} else {
return new CommandInvalid(input);
}
}

/**
* Takes in a String date and returns its corresponding LocalDate object.
*
* @param date String date in format DD/MM/YYYY, with 1-2 digits from Day and Month.
* @return LocalDate object with the corresponding day, month and year.
* @throws DateTimeParseException Thrown if date passed is an invalid one.
*/
public static LocalDate getDate(String date) throws DateTimeParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy");
return LocalDate.parse(date, formatter);
}


}
13 changes: 13 additions & 0 deletions src/main/java/task/Task.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package task;

import java.time.LocalDate;
import java.time.format.DateTimeParseException;

import duke.ui.Ui;

Expand Down Expand Up @@ -41,6 +42,18 @@ public String getDescription() {
return description;
}

public abstract LocalDate getDate();

public abstract String getTime();

//TODO
protected static boolean checkInvalidTime(String time) {
if (time.equals("")) return false;

int timeInt = Integer.parseInt(time);
return ( timeInt >= 2400 || timeInt < 0);
}

/**
* Represents string of Task.
*
Expand Down
Loading

0 comments on commit a966916

Please sign in to comment.