Skip to content

Autogen#45

Merged
Abish-27 merged 88 commits into
mainfrom
autogen
Dec 2, 2025
Merged

Autogen#45
Abish-27 merged 88 commits into
mainfrom
autogen

Conversation

@Abish-27

@Abish-27 Abish-27 commented Nov 17, 2025

Copy link
Copy Markdown
Collaborator

Timetable Autogeneration Usecase

This PR introduces a basic auto-generation system that uses a depth-first search (DFS) backtracking algorithm to produce a valid timetable based on course offerings, locked sections, and user-defined constraints.

Entities

  • CourseVariable: One course var each containing the course offering and domain of all it's sections
  • Constraints package: The constraints package contains constraints that need to be met that can be checked during the generation phase. Since the tutorials have not been mapped to the lectures yet I have not yet created a constraint for that but I will do that once I finish testing this, since it's quite easy to implement using this constraint system. Contains TimeConflictConstraint (avoids conflicts between 2 sections) and BlockedTimeConstraint (checks that no section's meetings collide with blocked times provided)
  • PotentialTimetable: This is a class used by the interactor to conduct it's searches. It returns a possible timetable-(a timetable that has been built) and a boolean- true if all constraints are met or else false.

Interface Adapter

  • AutogenController: Converts UI-level selections (courses, locked sections, blocked blocks) into AutogenInputData and contains no business logic.
  • AutogenPresenter: Bridges the gap between pure use-case output and UI state and separates success message and error message so the view can decide how to show each

Use_Case

Autogen Input Data

Bundles all inputs required by the use case:

  • Set<CourseCode> selectedCourses
  • Set<Section> lockedSections
  • WeeklyOccupancy blockedTimes
    Immutable DTO to keep the interactor free of UI concerns.

AutogenOutputData

  • Holds the generated timetable
  • This is what the presenter uses to update the TimetableState.

AutogenInputBoundary / AutogenOutputBoundary

  • Define the primary port interfaces for the use case and presenter
  • Allow controllers and presenters to depend only on abstractions

Autogen Interactor:

  • execute: uses the AutogenInputData provided by the Controller to get necessary variables and constraint for generation algorithm to work using the AutogenDataAccessObject. Calls the buildConstraints and applyLock helpers to set up a proper constraint system.
  • buildConstraints: Creates a list of Constraints or rules that the generated table needs to meet such as BlockedTimeConstraint and TimeConflictConstraint.
  • applyLock: Goes through all the sections from the timetable that have been locked. If a certain section is locked it ensures that its CourseVariable only contains that section rather all the other sections it it's domain. This is can thought of as an automatic locking system, where it filters the locked sections for the timetable rather than introducing a new entity.
  • generateTimetable: returns a PotentialTimetable by calling the recursive function timetableSearch
  • timetableSearch: THE MVP. Uses depth first search a recursive backtracking algorithm. The ideal base case occurs when all variables have been assigned. It acts like a tree- starts with an potential timetable which is initially empty. Picks a variable, and iterates through all it's sections. For each one it tries using that section and moves ahead to the next variable, essentially forming a tree path. Each time it meets a dead end, it backtracks and tries a different section. A dead end is met after each section in a variable doesn't return a successful result. In each loop, a isConsistent( timetable) is called where we check if the potential timetable so far is valid else we backtrack.
  • isConsistent: Takes in a Timetable and ensures that it meets all the necessary rules by looping through the list of constraints. Returns a boolean, true if all constraints are met else false.

UI Integration (View)

  • Hooked the AutogenController into the main view and TimetablePanel
  • Created an Autogenerate Button in TimetablePanel which that relies on an event listener and alerts the AutogenController when activated.
  • The Presenter's fail view (called when no timetable is generated or interactor runs into an error) creates a dialogue popup that alerts the user in the view, that a 'new' timetable could not be generated
  • After successful generation the GlobalView (affected by GlobalPresenter via AutogenPresenter) creates a new tab on the workbook with the brand new timetable loaded in

Data Access

  • AutogenDataAccessObject, has a method getSelectedCourseOfferings which gets all the sections for a course that has been selected on the timetable. This is done by using a JsonCourseDataRepository object that holds the mappings to all courses and their domains.

Tests

  • Added an AutogenInteractorTest which covers multiple scenarios such as courses having conflicts, time blocks, locks, no possible generation solution etc. (
    Update: Full Coverage done in later PR- Autogen update tests

Design/SOLID Notes

Single Responsibility Principle

  • AutogenController only translates user actions → use-case input.
  • AutogenInteractor only does business logic / algorithm.
  • AutogenPresenter only prepares view-specific state.

Open/Closed Principle

New constraints (e.g., professor preference, campus location) can be added by:

  • Implementing the Constraint interface.
  • Plugging the new constraint into the constraint list used by DFS.
  • The DFS engine doesn’t need to be rewritten; it just asks each constraint if a partial assignment is valid.

Dependency Inversion Principle

  • UI depends on AutogenInputBoundary rather than concrete AutogenInteractor.
  • Interactor depends on AutogenOutputBoundary, not on a concrete view.
  • Data sources come through data access interfaces/objects so the interactor is decoupled from any particular data storage

TODO;

  • For now you only get assigned one section per course offering, which might mean only 1 tut/lec. I will fix this once we link tutorials to lectures in the data.

TLDR; Finished Autogen Implementation, and applied clean architecture, need to finish data tut-section mapping

…nt, search result and variable to recursively build a valid timetable.
Got rid of LockedSectionConstraint.java and replaced it with a VariableFactory that builds the required variables in such a way that if something has locked sections only those appear. This saves times and doesn't add wrong sections and go down the wrong path for no reason.
@Abish-27

Copy link
Copy Markdown
Collaborator Author

Need to turn into clean architecture.

…urning autogen use case into Clean architecture by implementing InputBoundary and Interactor.
@SeriousGuy888
SeriousGuy888 marked this pull request as draft November 18, 2025 22:11
@Abish-27

Copy link
Copy Markdown
Collaborator Author

Updated top comment with all new changes have been made. Autogen now abides by clean architecture (hopefully).

@Abish-27
Abish-27 marked this pull request as ready for review November 22, 2025 03:55

@SeriousGuy888 SeriousGuy888 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\huge{\tiny\text{H}\small\text{u}\normalsize\text{z}\large\text{z}\LARGE\text{a}\huge\text{h}\huge!\huge\large!\huge\LARGE!}$ Abish has mostly implemented the timetable autogeneration feature$\small!\normalsize!\large!\LARGE!\huge\large!$

i may have written a lot of comments in the code
but they're mostly style concerns or typo fixes

the main thing that actually matters is
im a bit iffy still on the CourseVariableFactory class
(see comments there)

most things are good though
i don't think there's anything major to change

Comment thread src/main/java/entity/CourseVariableFactory.java Outdated
Comment thread src/main/java/entity/constraints/TimeConflictConstraint.java Outdated
Comment thread src/main/java/entity/CourseVariableFactory.java Outdated
Comment thread src/main/java/entity/CourseVariableFactory.java Outdated
Comment thread src/main/java/interface_adapter/autogen/AutogenPresenter.java Outdated
Comment thread src/test/java/use_case/autogen/AutogenInteractorTest.java Outdated
Comment thread src/test/java/use_case/autogen/AutogenInteractorTest.java
Comment thread src/test/java/use_case/autogen/AutogenInteractorTest.java Outdated
Comment thread src/test/java/use_case/autogen/AutogenInteractorTest.java Outdated
Comment thread src/test/java/use_case/autogen/AutogenInteractorTest.java Outdated

@CarolineLyu CarolineLyu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good work this was heavy lift

@Abish-27
Abish-27 dismissed Victoriaecai’s stale review December 2, 2025 07:00

just to merge dw

@Abish-27
Abish-27 merged commit bf182c4 into main Dec 2, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Timetable Autogeneration

6 participants