mirror of https://github.com/stijndcl/didier
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
import dacite
|
|
import json
|
|
from os import path
|
|
|
|
|
|
@dataclass
|
|
class Course:
|
|
abbreviations: list[str]
|
|
code: str
|
|
name: str
|
|
year: int
|
|
alt: Optional[str] = None
|
|
|
|
|
|
def load_courses() -> dict[str, Course]:
|
|
"""Create a list of all courses"""
|
|
# Allows testing
|
|
filepath = path.join(path.dirname(__file__), "..", "files", "courses.json")
|
|
with open(filepath, "r") as file:
|
|
data = json.load(file)
|
|
|
|
courses = {}
|
|
|
|
for course_name in data:
|
|
# Add name into the dict to allow flexibility
|
|
course_data = data[course_name]
|
|
course_data["name"] = course_name
|
|
|
|
courses[course_name] = dacite.from_dict(data_class=Course, data=course_data)
|
|
|
|
return courses
|
|
|
|
|
|
def find_course_from_name(name: str, courses: Optional[dict[str, Course]] = None, case_insensitive: bool = True) -> Optional[Course]:
|
|
# Allow passing a course dict in to avoid having to create it all the time
|
|
if courses is None:
|
|
courses = load_courses()
|
|
|
|
if case_insensitive:
|
|
name = name.lower()
|
|
|
|
def _perhaps_lower(inp: str) -> str:
|
|
"""Cast a string to lowercase if necessary"""
|
|
if case_insensitive:
|
|
return inp.lower()
|
|
|
|
return inp
|
|
|
|
# Iterate over all courses to look for a match
|
|
for course_name, course in courses.items():
|
|
# Check name first
|
|
if _perhaps_lower(course_name) == name:
|
|
return course
|
|
|
|
# Then abbreviations
|
|
for abbreviation in course.abbreviations:
|
|
if _perhaps_lower(abbreviation) == name:
|
|
return course
|
|
|
|
# Finally alternative names
|
|
if course.alt is not None and _perhaps_lower(course.alt) == name:
|
|
return course
|
|
|
|
return None
|