Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion src/main/java/com/unitime/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@
import com.unitime.feature.InputHandler;

public class App {
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String PURPLE = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String BLACK = "\u001B[30m";
public static final String BOLD = "\u001B[1m";
public static void main(String[] args) {

// Only one scanner!!!!!
Scanner sc = new Scanner(System.in);

IntroScreen.start();
System.out.println("Press [ENTER] to start...");
System.out.println("Press"+PURPLE+" [ENTER]"+RESET+" to start...");
sc.nextLine();

// get input
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/unitime/UI/ResultView.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static String printBatchAndGetInput(List<List<Course>> allSchedules, int

// 2. Print Header (Print in each new page)
System.out.println(CYAN + "\n========================= Timetable =========================" + RESET);
System.out.println(YELLOW + BOLD + " (*'▽ '*) Found " + totalSize + " timetables! Showing " + (currentIndex + 1) + "~" + endIndex + " (*'▽ '*)" + RESET);
System.out.println(YELLOW + BOLD + " (*'▽ '*) Found " + totalSize + " timetables! Showing " + (currentIndex + 1) + "~" + endIndex + " (*'▽ '*)" + RESET);
System.out.println(CYAN + "=============================================================" + RESET);

// 3. Print 5 timetables
Expand Down
57 changes: 33 additions & 24 deletions src/main/java/com/unitime/feature/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
import com.unitime.algorthm.Scheduler;

public class Editor {
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String PURPLE = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String BLACK = "\u001B[30m";
public static final String BOLD = "\u001B[1m";

private List<List<Course>> schedules;
private List<Course> mandatoryList;
Expand Down Expand Up @@ -38,7 +47,7 @@ public void route(String input, List<List<Course>> currentSchedules) {
else if (input.equals("edit")) editList();
else if (input.equals("next")) viewLoop(5);
else {
System.out.println("[Error] Invalid input. Going back to View Mode.");
System.out.println(RED+"[Error] Invalid input. Going back to View Mode."+RESET);
viewLoop(0);
}
}
Expand All @@ -60,7 +69,7 @@ private void viewLoop(int startIndex) {
int nextIndex = startIndex;
if(nextInput.equals("next")) {
if (startIndex + 5 < schedules.size()) nextIndex += 5;
else System.out.println("[Info] Last page.");
else System.out.println(YELLOW+"[Info]"+RESET + " Last page.");
}

route(nextInput, this.schedules);
Expand All @@ -69,7 +78,7 @@ private void viewLoop(int startIndex) {

// 'edit': edit lists and send it back to InputHandler
private void editList() {
System.out.println("[Edit Mode]");
System.out.println(GREEN+"[Edit Mode]"+RESET);
modifyCourse(this.mandatoryList, this.optionList);

System.out.println("Re-calculating schedules...");
Expand All @@ -87,96 +96,96 @@ private void modifyCourse(List<Course> mandatory, List<Course> optional) {
InputHandler ih = new InputHandler();

while (true) {
System.out.println("\n------------------------------------------");
System.out.println(" Current Goal Credit: " + this.goalCredit);
System.out.println(" Mandatory: " + mandatory.size() + " courses");
System.out.println(" Optional : " + optional.size() + " courses");
System.out.println("------------------------------------------");
System.out.println(CYAN+"\n------------------------------------------"+RESET);
System.out.println(" Current Goal Credit: " + this.goalCredit);
System.out.println(" Mandatory: " + mandatory.size() + " courses");
System.out.println(" Optional : " + optional.size() + " courses");
System.out.println(CYAN+"------------------------------------------"+RESET);
System.out.println("1. Add/Edit MANDATORY Courses");
System.out.println("2. Add/Edit OPTIONAL Courses");
System.out.println("3. Remove a Course");
System.out.println("4. Change Goal Credit");
System.out.println("0. Finish Editing (Run Scheduler)");
System.out.print("> Select: ");
System.out.print(YELLOW+"> (,,>∇<,,) Select: "+RESET);

String choice = sc.nextLine().trim();

// Add
if (choice.equals("1")) {
System.out.println("\n[Add to Mandatory] Type 'done' to finish.");
System.out.println(BLUE+"\n[Add to Mandatory]"+RESET+" Type 'done' to finish.");
ih.inputLoop(sc, mandatory);
}
else if (choice.equals("2")) {
System.out.println("\n[Add to Optional] Type 'done' to finish.");
System.out.println(BLUE+"\n[Add to Optional]"+RESET+" Type 'done' to finish.");
ih.inputLoop(sc, optional);
}
else if (choice.equals("3")) {
removeCourseHelper(mandatory, optional);
}
else if (choice.equals("4")) {
System.out.print("Enter new max credit: ");
System.out.print("(*'▽ '*) Enter"+YELLOW+" new"+RESET+" max credit: ");
try {
int newCredit = Integer.parseInt(sc.nextLine().trim());
if (newCredit > 0) {
this.goalCredit = newCredit;
System.out.println("Goal credit updated.");
System.out.println("Goal credit"+YELLOW+" updated."+RESET);
} else {
System.out.println("Credit must be positive.");
System.out.println("Credit must be"+RED+" positive."+RESET);
}
} catch (Exception e) {
System.out.println("Invalid number.");
System.out.println(RED+"Invalid number."+RESET);
}
}
else if (choice.equals("0")) {
break;
}
else {
System.out.println("Invalid choice.");
System.out.println(RED+"Invalid choice."+RESET);
}
}
}

// helper of 'edit': remove
private void removeCourseHelper(List<Course> mandatory, List<Course> optional) {
System.out.println("\n[Remove Course]");
System.out.println(PURPLE+"\n(*'▽ '*) [Remove Course]"+RESET);
System.out.println("1. From Mandatory");
System.out.println("2. From Optional");
System.out.print("> Select list: ");
System.out.print(YELLOW+"> (,,>∇<,,) Select list: "+RESET);
String listType = sc.nextLine().trim();

List<Course> target = null;
if (listType.equals("1")) target = mandatory;
else if (listType.equals("2")) target = optional;
else {
System.out.println("Canceled.");
System.out.println(RED+"Canceled."+RESET);
return;
}

if (target.isEmpty()) {
System.out.println("This list is empty.");
System.out.println(RED+"This list is empty."+RESET);
return;
}

for (int i = 0; i < target.size(); i++) {
System.out.println("[" + i + "] " + target.get(i).getName());
}

System.out.print("Enter index to remove (or -1 to cancel): ");
System.out.print(RED+"(*'▽ '*) Enter index to remove "+RESET+" (or -1 to cancel): ");
try {
int idx = Integer.parseInt(sc.nextLine().trim());
if (idx >= 0 && idx < target.size()) {
Course removed = target.remove(idx);
System.out.println("Removed: " + removed.getName());
} else if (idx != -1) {
System.out.println("Invalid index.");
System.out.println(RED+"Invalid index."+RESET);
}
} catch (Exception e) {
System.out.println("Invalid input.");
System.out.println(RED+"Invalid input."+RESET);
}
}

public void quit(){
System.out.println("[Bye] Closing system...");
System.out.println(BLUE+"[Bye] Closing system..."+RESET);
System.exit(0);
}
}
79 changes: 44 additions & 35 deletions src/main/java/com/unitime/feature/InputHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,46 @@
import java.util.Scanner;

public class InputHandler {
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String PURPLE = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String BLACK = "\u001B[30m";
public static final String BOLD = "\u001B[1m";

private List<Course> mandatoryList = new ArrayList<>();
private List<Course> optionalList = new ArrayList<>();
private int maxCredit = 0;

public void handle(Scanner sc) {
System.out.println("===== UniTime-Solver: Input Courses =====");
System.out.println(CYAN +"===== UniTime-Solver: Input Courses ====="+ RESET);

// Maximum credit
System.out.print("What is your MAXIMUM total credit? (positive number): ");
System.out.print(YELLOW+"(*'▽ '*) What is your MAXIMUM total credit?"+RESET+" ('"+RED+"positive"+RESET+"' number): ");
while (true) {
try {
maxCredit = Integer.parseInt(sc.nextLine().trim());
if (maxCredit > 0) {
System.out.println("Maximum credit checked.");
break;
}
System.out.println("Please enter a positive number.");
System.out.println("Please enter a '"+RED+"positive"+RESET+"' number.");
} catch (NumberFormatException e) {
System.out.println("Invalid number. Please try again.");
System.out.println(RED+"Invalid number. Please try again."+RESET);
}
}

// Put into list

// MandatoryList
System.out.println("\n[1] Enter MANDATORY Courses");
System.out.println(BLUE+"\n[1] Enter MANDATORY Courses"+RESET);
inputLoop(sc, mandatoryList);

// OptionalList
System.out.println("\n[2] Enter OPTIONAL Courses");
System.out.println(BLUE+"\n[2] Enter OPTIONAL Courses"+RESET);
inputLoop(sc, optionalList);

printSummary();
Expand All @@ -44,39 +53,39 @@ public void handle(Scanner sc) {

// Show result
public void printSummary() {
System.out.println("\n==========================================");
System.out.println(" Check Input Summary ");
System.out.println("==========================================");
System.out.println("Maximum Credit: " + maxCredit);
System.out.println(CYAN +"\n=========================================="+ RESET);
System.out.println(PURPLE+" (*>3<*) Check Input Summary "+RESET);
System.out.println(CYAN +"=========================================="+ RESET);
System.out.println(RED+"Maximum Credit: "+RESET + maxCredit);

// Mandatory
System.out.println("\n[Fixed Courses] (" + mandatoryList.size() + " courses)");
System.out.println(GREEN+"\n[Fixed Courses]"+RESET+" (" + mandatoryList.size() + " courses)");
if (mandatoryList.isEmpty()) System.out.println(" (None)");
for (Course c : mandatoryList) {
System.out.println(" - " + c);
}

// Optional
System.out.println("\n[Optional Courses] (" + optionalList.size() + " courses)");
System.out.println(GREEN+"\n[Optional Courses]"+RESET+" (" + optionalList.size() + " courses)");
if (optionalList.isEmpty()) System.out.println(" (None)");
for (Course c : optionalList) {
System.out.println(" - " + c);
}

System.out.println("==========================================");
System.out.println("Finding timetables...");
System.out.println("==========================================");
System.out.println(CYAN +"=========================================="+ RESET);
System.out.println(" Finding timetables...");
System.out.println(CYAN +"=========================================="+ RESET);
}

// Get user input
public void inputLoop(Scanner sc, List<Course> targetList) {
System.out.println("------------------------------------------------------------------");
System.out.println("Format: Name / Credit / Time");
System.out.println("Example: Data Structure / 3 / Mon 12:30 14:00");
System.out.println("------------------------------------------------------------------");
System.out.println(PURPLE +"------------------------------------------------------------------"+ RESET);
System.out.println(" Format: Name / Credit / Time");
System.out.println(" Example: Data Structure / 3 / Mon 12:30 14:00");
System.out.println(PURPLE +"------------------------------------------------------------------"+ RESET);

while (true) {
System.out.print("\nInput (or 'done'): ");
System.out.print(BLUE+"\nInput (or 'done'): "+RESET);
String input = sc.nextLine().trim();

if (input.equalsIgnoreCase("done")) break;
Expand All @@ -85,7 +94,7 @@ public void inputLoop(Scanner sc, List<Course> targetList) {
// Split by '/'
String[] parts = input.split("/");
if (parts.length != 3) {
throw new Exception("All 3 fields must be separated by '/'");
throw new Exception(RED +"All 3 fields must be separated by '/'"+RESET);
}

// Trim and parse
Expand All @@ -95,13 +104,13 @@ public void inputLoop(Scanner sc, List<Course> targetList) {

// Validate credit
if (credit <= 0) {
throw new Exception("Credit must be a positive number");
throw new Exception(RED +"Credit must be a positive number"+RESET);
}

// Split time input
String[] timeParts = timeString.split(" ");
if (timeParts.length != 3) {
throw new Exception("Time format should be 'Day Start End'");
throw new Exception(RED +"Time format should be 'Day Start End'"+RESET);
}

// Handle 'day'
Expand All @@ -112,14 +121,14 @@ public void inputLoop(Scanner sc, List<Course> targetList) {
else if (d.startsWith("w")) day = 2;
else if (d.startsWith("th")) day = 3;
else if (d.startsWith("f")) day = 4;
else throw new Exception("Invalid day (use Mon, Tue, Wed, Thu, or Fri)");
else throw new Exception(RED +"Invalid day (use Mon, Tue, Wed, Thu, or Fri)"+RESET);

// Parse time
int startMin = parseMin(timeParts[1]);
int endMin = parseMin(timeParts[2]);

if (startMin >= endMin) {
throw new Exception("End time must be after start time");
throw new Exception(RED +"End time must be after start time" +RESET);
}

// String for returning toString
Expand All @@ -128,17 +137,17 @@ public void inputLoop(Scanner sc, List<Course> targetList) {
// Add to list
Course c = new Course(name, credit, day, startMin, endMin, timeRaw);
targetList.add(c);
System.out.println(" -> [Added] " + name);
System.out.println(GREEN+" -> [Added] " +RESET+ name);

} catch (NumberFormatException e) {
System.out.println("Error: Credit must be a valid number");
System.out.println("Try again: Name / Credit / Day Start End");
System.out.println(RED +"Error: Credit must be a valid number"+ RESET);
System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Invalid time format");
System.out.println("Try again: Name / Credit / Day Start End");
System.out.println(RED +"Error: Invalid time format"+ RESET);
System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
System.out.println("Try again: Name / Credit / Day Start End");
System.out.println(RED +"Error: "+ RESET + e.getMessage());
System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET);
}
}
}
Expand All @@ -148,18 +157,18 @@ public int parseMin(String t) throws Exception {
try {
String[] hhmm = t.split(":");
if (hhmm.length != 2) {
throw new Exception("Time must be in HH:MM format");
throw new Exception(RED +"Time must be in HH:MM format"+ RESET);
}
int hours = Integer.parseInt(hhmm[0]);
int minutes = Integer.parseInt(hhmm[1]);

if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
throw new Exception("Invalid time range (hours: 0-23, minutes: 0-59)");
throw new Exception(RED +"Invalid time range (hours: 0-23, minutes: 0-59)"+ RESET);
}

return hours * 60 + minutes;
} catch (NumberFormatException e) {
throw new Exception("Time must contain valid numbers");
throw new Exception(RED +"Time must contain valid numbers"+ RESET);
}
}

Expand Down