diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 40b4e92..030a70b 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -34,4 +34,3 @@ jobs: #cache: maven - name: Build with Maven run: mvn -B package --file pom.xml - diff --git a/pom.xml b/pom.xml index 4c0a0c6..6e621d2 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.7 - 1.7 + 17 + 17 diff --git a/src/main/java/com/unitime/feature/Course.java b/src/main/java/com/unitime/feature/Course.java index e69de29..f38153e 100644 --- a/src/main/java/com/unitime/feature/Course.java +++ b/src/main/java/com/unitime/feature/Course.java @@ -0,0 +1,37 @@ +package com.unitime.feature; + +public class Course { + private String name; // course name + private int credit; // credit + + // time + private int day; // 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri + private int startTime; + private int endTime; + + // for toString + private String timeRaw; + + public Course(String name, int credit, + int day, int startTime, int endTime, String timeRaw) { + this.name = name; + this.credit = credit; + this.day = day; + this.startTime = startTime; + this.endTime = endTime; + this.timeRaw = timeRaw; + } + + // Getters + public String getName() { return name; } + public int getCredit() { return credit; } + public int getDay() { return day; } + public int getStartTime() { return startTime; } + public int getEndTime() { return endTime; } + + @Override + public String toString() { + return String.format("%s | %d (credits) | %s ", + name, credit, timeRaw); + } +} diff --git a/src/main/java/com/unitime/feature/InputHandler.java b/src/main/java/com/unitime/feature/InputHandler.java new file mode 100644 index 0000000..83bf541 --- /dev/null +++ b/src/main/java/com/unitime/feature/InputHandler.java @@ -0,0 +1,177 @@ +package com.unitime.feature; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class InputHandler { + + private static List mandatoryList = new ArrayList<>(); + private static List optionalList = new ArrayList<>(); + private static int maxCredit = 0; + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + + System.out.println("===== UniTime-Solver: Input Courses ====="); + + // 목표 학점 + System.out.print("What is your MAXIMUM total credit? (positive 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."); + } catch (NumberFormatException e) { + System.out.println("Invalid number. Please try again."); + } + } + + // Put into list + + // MandatoryList + System.out.println("\n[1] Enter MANDATORY Courses"); + inputLoop(sc, mandatoryList); + + // OptionalList에 담기 + System.out.println("\n[2] Enter OPTIONAL Courses"); + inputLoop(sc, optionalList); + + // Show result + System.out.println("\n=========================================="); + System.out.println(" Check Input Summary "); + System.out.println("=========================================="); + System.out.println("Maximum Credit: " + maxCredit); + + // Mandatory + System.out.println("\n[Fixed Courses] (" + 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)"); + 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("=========================================="); + + sc.close(); + } + + // Get user input + private static void inputLoop(Scanner sc, List 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("------------------------------------------------------------------"); + + while (true) { + System.out.print("\nInput (or 'done'): "); + String input = sc.nextLine().trim(); + + if (input.equalsIgnoreCase("done")) break; + + try { + // Split by '/' + String[] parts = input.split("/"); + if (parts.length != 3) { + throw new Exception("All 3 fields must be separated by '/'"); + } + + // Trim and parse + String name = parts[0].trim(); + int credit = Integer.parseInt(parts[1].trim()); + String timeString = parts[2].trim(); // "Mon 12:30 14:00" + + // Validate credit + if (credit <= 0) { + throw new Exception("Credit must be a positive number"); + } + + // Split time input + String[] timeParts = timeString.split(" "); + if (timeParts.length != 3) { + throw new Exception("Time format should be 'Day Start End'"); + } + + // Handle 'day' + int day = -1; + String d = timeParts[0].toLowerCase(); + if (d.startsWith("m")) day = 0; + else if (d.startsWith("tu")) day = 1; + 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)"); + + // 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"); + } + + // String for returning toString + String timeRaw = timeParts[0] + " " + timeParts[1] + "-" + timeParts[2]; + + // Add to list + Course c = new Course(name, credit, day, startMin, endMin, timeRaw); + targetList.add(c); + System.out.println(" -> [Added] " + name); + + } catch (NumberFormatException e) { + System.out.println("Error: Credit must be a valid number"); + System.out.println("Try again: Name / Credit / Day Start End"); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("Error: Invalid time format"); + System.out.println("Try again: Name / Credit / Day Start End"); + } catch (Exception e) { + System.out.println("Error: " + e.getMessage()); + System.out.println("Try again: Name / Credit / Day Start End"); + } + } + } + + // Change time into minutes + private static 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"); + } + 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)"); + } + + return hours * 60 + minutes; + } catch (NumberFormatException e) { + throw new Exception("Time must contain valid numbers"); + } + } + + //Getters + public static List getMandatoryList() { + return mandatoryList; + } + + public static List getOptionalList() { + return optionalList; + } + + public static int getMaxCredit() { + return maxCredit; + } +} \ No newline at end of file diff --git a/src/test/java/com/unitime/feature/CourseTest.java b/src/test/java/com/unitime/feature/CourseTest.java new file mode 100644 index 0000000..9cc0a3f --- /dev/null +++ b/src/test/java/com/unitime/feature/CourseTest.java @@ -0,0 +1,116 @@ +package com.unitime.feature; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class CourseTest { + + @Test + public void testGetCredit() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + int credit = course.getCredit(); + assertEquals(3, credit); + } + + @Test + public void testGetDay() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + int day = course.getDay(); + assertEquals(0, day); + } + + @Test + public void testGetEndTime() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + int endTime = course.getEndTime(); + assertEquals(840, endTime); + } + + @Test + public void testGetName() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + String name = course.getName(); + assertEquals("Data Structure", name); + } + + @Test + public void testGetStartTime() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + int startTime = course.getStartTime(); + assertEquals(750, startTime); + } + + @Test + public void testToString() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + String result = course.toString(); + + assertTrue(result.contains("Data Structure")); + assertTrue(result.contains("3")); + assertTrue(result.contains("Mon 12:30-14:00")); + } + + @Test + public void testToStringFormat() { + Course course = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + String result = course.toString(); + + assertTrue(result.contains("Data Structure")); + assertTrue(result.contains("3")); + assertTrue(result.contains("credits")); + assertTrue(result.contains("Mon 12:30-14:00")); + } + + @Test + public void testCourseWithDifferentDays() { + // Monday (0) + Course mon = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + assertEquals(0, mon.getDay()); + + // Tuesday (1) + Course tue = new Course("Data Structure", 3, 1, 750, 840, "Tue 12:30-14:00"); + assertEquals(1, tue.getDay()); + + // Wednesday (2) + Course wed = new Course("Data Structure", 3, 2, 750, 840, "Wed 12:30-14:00"); + assertEquals(2, wed.getDay()); + + // Thursday (3) + Course thu = new Course("Data Structure", 3, 3, 750, 840, "Thu 12:30-14:00"); + assertEquals(3, thu.getDay()); + + // Friday (4) + Course fri = new Course("Data Structure", 3, 4, 750, 840, "Fri 12:30-14:00"); + assertEquals(4, fri.getDay()); + } + + @Test + public void testCourseWithDifferentCredits() { + Course c1 = new Course("Data Structure", 1, 0, 750, 840, "Mon 12:30-14:00"); + assertEquals(1, c1.getCredit()); + + Course c2 = new Course("Data Structure", 2, 0, 750, 840, "Mon 12:30-14:00"); + assertEquals(2, c2.getCredit()); + + Course c3 = new Course("Data Structure", 3, 0, 750, 840, "Mon 12:30-14:00"); + assertEquals(3, c3.getCredit()); + + Course c4 = new Course("Data Structure", 4, 0, 750, 840, "Mon 12:30-14:00"); + assertEquals(4, c4.getCredit()); + } + + @Test + public void testTimeConversion() { + Course c1 = new Course("Data Structure", 3, 0, 540, 660, "Mon 09:00-11:00"); + assertEquals(540, c1.getStartTime()); + assertEquals(660, c1.getEndTime()); + + Course c2 = new Course("Data Structure", 3, 0, 750, 870, "Mon 12:30-14:30"); + assertEquals(750, c2.getStartTime()); + assertEquals(870, c2.getEndTime()); + + Course c3 = new Course("Data Structure", 3, 0, 1080, 1200, "Mon 18:00-20:00"); + assertEquals(1080, c3.getStartTime()); + assertEquals(1200, c3.getEndTime()); + } +} \ No newline at end of file