-
Notifications
You must be signed in to change notification settings - Fork 2
feat: timetable models #326
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
Changes from all commits
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,103 @@ | ||
| // For all, id is a CampusID with no relation to raw XML ID. | ||
|
|
||
| // An allocation refers to a new set of classes, people and class timings | ||
| // imported with a new timetable. | ||
| // It refers to one of these: | ||
| // https://github.com/nyjc-computing/nyxchange-timetable-v2/blob/data-schema/tt_file/tt_xml_docs.md | ||
| // This year's timetable and last year's timetable are two seperate allocations. | ||
| // The data for an allocation is stored in some .xml file, named `filename` | ||
|
|
||
| /* Sections that stay constant or only have additions. */ | ||
| /* They will be relevant every for every allocation. */ | ||
|
|
||
| // Describes a day in a repeating timetable. | ||
| // Assumption: This will stay constant across all timetables. | ||
| Table WeekDay { | ||
| id varchar [primary key] | ||
| label varchar // (cosmetic purposes: 'Mon A', 'Tue A', ... 'Mon B', 'Tue B', ..., 'Sat', 'Sun') | ||
| index integer [unique] // index 0 is earliest (eg. Mon A), followed by Tues A, etc. | ||
| } | ||
|
|
||
| // Timeslot which repeats across all `WeekDay`s | ||
| // Assumption: This will stay constant across all timetables. | ||
| Table TimeSlot { | ||
| id varchar [primary key] | ||
| label varchar // (primarily cosmetic: '0730', '0800', ...) | ||
| start_time varchar [unique] // ISO8601 | ||
| end_time varchar [unique] // ISO8601 | ||
| index integer [unique] // index 0 is slot (eg. 0730), followed by 0800, etc. | ||
| } | ||
|
|
||
| // Describes a single venue | ||
| // We have a set of venues that remain across years, except additions. | ||
| // Cannot refer to a group (eg. "All science labs") | ||
| Table Venue { | ||
| id varchar [primary key] | ||
| label varchar // (mutable, e.g. '03-39', 'i-Space 1', ..., follow XML when possible) | ||
| } | ||
|
|
||
| // Imagine each venue has its own timetable. | ||
| // This is one timeslot on such a timetable, representing an intersection of | ||
| // Venue and TimeSlot | ||
| // We use it for clean and convenient timetable coordinates, as | ||
| // we usually reason about an intersection of venue and time anyway | ||
| // Must be automatically generated for each Venue for all WeekDay, TimeSlot. | ||
| Table VenueTimeSlot { | ||
| id varchar [primary key] | ||
| weekday_id varchar | ||
| timeslot_id varchar | ||
| venue_id varchar | ||
| indexes { | ||
| (weekday_id, timeslot_id, venue_id) [unique] | ||
| } | ||
| } | ||
| Ref: VenueTimeSlot.weekday_id > WeekDay.id | ||
| Ref: VenueTimeSlot.timeslot_id > TimeSlot.id | ||
| Ref: VenueTimeSlot.venue_id > Venue.id | ||
|
|
||
| /* Sections that are only relevant to a specific allocation. */ | ||
| /* New entries are created for each allocation. */ | ||
| /* Which allocation the entry is relevant to is . */ | ||
|
|
||
| // This represents a specific lesson taught to a class. | ||
| // Eg. Chem, taught to 2510. (eg. stored as '2510-CM') | ||
| // These are stored as an inconsistently formatted string, imported | ||
| // directly from the XML. | ||
| Table LessonGroup { | ||
| id varchar [primary key] | ||
| filename varchar // Allocation xml filename which this group is relevant to | ||
| label varchar | ||
| } | ||
|
|
||
| // Represents a single member of a LessonGroup. | ||
| // For example, 2510-Math will have: | ||
| // - Rosaline Tan | ||
| // - All the students | ||
| // Where each individual is one LessonGroupMember. | ||
| // 2510-Chem will have its own set of entries, even if the participant is duplicated. | ||
| Table LessonGroupMember { | ||
| id varchar [primary key] | ||
| filename varchar | ||
| lessongroup_id varchar | ||
| // XML id (aka TTCode or teacher_id). We have a unique mapping of these IDs | ||
| // to nyjc email etc., for each allocation. | ||
| ade_participant varchar | ||
| indexes { | ||
| (lessongroup_id, ade_participant, filename) [unique] | ||
| } | ||
| } | ||
| Ref: LessonGroup.id < LessonGroupMember.lessongroup_id | ||
|
|
||
| // A timetable represents a lesson for a LessonGroup | ||
| // at some VenueTimeSlot | ||
| Table Timetable { | ||
| id varchar [primary key] | ||
| filename varchar | ||
| lessongroup_id varchar | ||
| venuetimeslot_id varchar | ||
| indexes { | ||
| (venuetimeslot_id, lessongroup_id, filename) [unique] | ||
| } | ||
| } | ||
| Ref: Timetable.lessongroup_id > LessonGroup.id | ||
| Ref: Timetable.venuetimeslot_id > VenueTimeSlot.id |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,129 @@ | ||||||||||||||||||||||||||||
| """campus.model.timetable | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| Timetable model definitions for Campus. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| The timetable schema describes a schema that stores the | ||||||||||||||||||||||||||||
| following information from a timetable: | ||||||||||||||||||||||||||||
| - Timeslots | ||||||||||||||||||||||||||||
| - Lessons | ||||||||||||||||||||||||||||
| - Students and teachers involved in said lessons | ||||||||||||||||||||||||||||
| - Venues | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| !! The schema is documented in DETAIL by the `timetable.dbml` file. | ||||||||||||||||||||||||||||
| !! Commenting both files would mean duplicate documentation. | ||||||||||||||||||||||||||||
| !! Please visualise it [here](https://dbml-editor.alswl.com/)!!!! | ||||||||||||||||||||||||||||
| !! The tool is also able to export the schema as SQL to create the respective tables. | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from typing import ClassVar | ||||||||||||||||||||||||||||
| from dataclasses import dataclass, field | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from campus.common import schema | ||||||||||||||||||||||||||||
| from campus.common.schema.openapi import String, Integer, Boolean, DateTime | ||||||||||||||||||||||||||||
| from campus.common.utils import uid | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from .base import Model | ||||||||||||||||||||||||||||
| from . import constraints | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # NOTE: Assumes reusing the same object is not an issue | ||||||||||||||||||||||||||||
| unique_field = field(metadata={ | ||||||||||||||||||||||||||||
| "constraints": [constraints.UNIQUE], | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class WeekDay(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Describes a day in a repeating timetable. | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
|
Comment on lines
+36
to
+38
Contributor
Author
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. [C#01] See https://peps.python.org/pep-0257/
Suggested change
|
||||||||||||||||||||||||||||
| id: schema.CampusID = unique_field | ||||||||||||||||||||||||||||
|
Contributor
Author
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. [C#02]
WeekDay and TimeSlot are not Campus entities, but technically enum values. This is a common feature in many programming languages, e.g. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum, but we will not force their use because enum types often have their own constraints. Here we define the model for reference, i.e. to help other readers understand what we mean by a WeekDay or TimeSlot when they encounter it in the DB or in code. So we can stick/revert to using
Suggested change
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. Hi Mr Ng, i realise the reason i used
Contributor
Author
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.
@sparsetable I forgot to mention: for "internal representations" (won't be queried directly through Campus API), there is no need to inherit Internal representations will never be returned by the resource/API, just used as intermediate representations between JSON and database rows, and do not need to be polymorphic in the same way. I realise that means we need another way to create the database table; let me investigate this and get back to you
Contributor
Author
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. @sparsetable I just added an This has been merged into |
||||||||||||||||||||||||||||
| label: String | ||||||||||||||||||||||||||||
|
Contributor
Author
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. [C#03]
Suggested change
|
||||||||||||||||||||||||||||
| index: Integer | ||||||||||||||||||||||||||||
|
Contributor
Author
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. See [C#03]. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class TimeSlot(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Timeslot which repeats across all `WeekDay`s | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
|
Comment on lines
+49
to
+51
Contributor
Author
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. See [C#02].
Suggested change
|
||||||||||||||||||||||||||||
| label: String | ||||||||||||||||||||||||||||
| start_time: DateTime = unique_field | ||||||||||||||||||||||||||||
| end_time: DateTime = unique_field | ||||||||||||||||||||||||||||
| index: Integer = unique_field | ||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+55
Contributor
Author
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. See [C#03]. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class Venue(Model): | ||||||||||||||||||||||||||||
|
Contributor
Author
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. [C#04]
Suggested change
|
||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Describes a single venue | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
|
Comment on lines
+63
to
+65
Contributor
Author
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. See [C#02].
Suggested change
|
||||||||||||||||||||||||||||
| label: String | ||||||||||||||||||||||||||||
|
Contributor
Author
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. See [C#03]. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class VenueTimeSlot(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Imagine each venue has its own timetable. | ||||||||||||||||||||||||||||
| This is one timeslot on such a timetable, representing an intersection of | ||||||||||||||||||||||||||||
| Venue and TimeSlot | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
| weekday_id: schema.CampusID # FK -> weekday_id | ||||||||||||||||||||||||||||
| timeslot_id: schema.CampusID | ||||||||||||||||||||||||||||
| venue_id: schema.CampusID | ||||||||||||||||||||||||||||
|
Comment on lines
+76
to
+81
Contributor
Author
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. See [C#02].
Suggested change
|
||||||||||||||||||||||||||||
| __constraints__ = constraints.Unique("weekday_id", "timeslot_id", "venue_id") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class LessonGroup(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| This represents a specific lesson taught to a class. | ||||||||||||||||||||||||||||
| Eg. Chem, taught to 2510. (eg. stored as '2510-CM') | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
|
Comment on lines
+91
to
+93
Contributor
Author
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. [C#05]
Suggested change
|
||||||||||||||||||||||||||||
| filename: String | ||||||||||||||||||||||||||||
| label: String | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class LessonGroupMember(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Represents a single member of a LessonGroup. | ||||||||||||||||||||||||||||
| For example, 2510-Math will have: | ||||||||||||||||||||||||||||
| - Rosaline Tan | ||||||||||||||||||||||||||||
| - All the students | ||||||||||||||||||||||||||||
| Where each individual is one LessonGroupMember. | ||||||||||||||||||||||||||||
| 2510-Chem will have its own set of entries, even if the participant is duplicated. | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
|
Comment on lines
+108
to
+110
Contributor
Author
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. [C#06]
Suggested change
|
||||||||||||||||||||||||||||
| filename: String | ||||||||||||||||||||||||||||
| lessongroup_id: String | ||||||||||||||||||||||||||||
| ade_participant: String | ||||||||||||||||||||||||||||
| __constraints__ = constraints.Unique("lessongroup_id", "ade_participant", "filename") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @dataclass(eq=False, kw_only=True) | ||||||||||||||||||||||||||||
| class Timetable(Model): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| A timetable represents a lesson for a LessonGroup | ||||||||||||||||||||||||||||
| at some VenueTimeSlot | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
|
Comment on lines
+118
to
+122
Contributor
Author
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. [C#07]
Suggested change
|
||||||||||||||||||||||||||||
| id: schema.CampusID = field(default_factory=( | ||||||||||||||||||||||||||||
| lambda: uid.generate_category_uid("timetable", length=8) | ||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||
|
Comment on lines
+123
to
+125
Contributor
Author
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. [C#08] See [C#05], [C#06]
Suggested change
|
||||||||||||||||||||||||||||
| filename: String | ||||||||||||||||||||||||||||
| lessongroup_id: String | ||||||||||||||||||||||||||||
| venuetimeslot_id: String | ||||||||||||||||||||||||||||
| __constraints__ = constraints.Unique("lessongroup_id", "venuetimeslot_id", "filename") | ||||||||||||||||||||||||||||
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.
Prefer referencing
String,Integer,Boolean,DateTimefromschema(they are re-exported under theschemanamespace for ease of use)See
docs/STYLE-GUIDE.mdfor examples