ubc_mds_helper Tutorial

Tools to help navigate MDS

ubc_mds_helper is a project that helps students in the UBC Masters of Data Science (MDS) program better understand and plan their academic timeline.

With the large number of deadlines and the variability in workload across the 5 weeks within each block, it is difficult for students to get a sense of where they are in the program at a given time. This helper package provides date-based tools to describe a student’s academic position, program phase, and progress, and support planning for personal commitments, absences, late submissions, and meeting course-level requirements.

Status

We set up our date configuration to the 2025/2026 cycle, as shown in config.py.

If other years are needed, the config.py file would need to be updated.

from ubc_mds_helper.status import status
from ubc_mds_helper.config import PROGRAM_CONFIG_2025_2026

status(PROGRAM_CONFIG_2025_2026, "January 15, 2026")
{'date': datetime.date(2026, 1, 15),
 'day_of_week': 'Thursday',
 'block': 4,
 'week_in_block': 2,
 'during_break': False,
 'break_name': None,
 'days_until_next_break': 31,
 'next_break_name': 'Winter break',
 'between_blocks': False}

Assessment

The late_assignment() function applies the UBC MDS late-submission policy.

It prints the late penalty applied to an assignment based on the number of days it is late, and returns the adjusted grade.

Inputs - raw_grade (float or int): original grade (0–100) - late_count (int): number of previous late submissions - is_lower_stakes (bool): if True, late submissions are not accepted for lower-stakes assignments (e.g., quizzes, labs)

Outputs - float: grade after the late-submission scaling is applied

from ubc_mds_helper.assessments import late_assignment

# Example 1: on-time submission
print("\nExample 1: on-time submission")
adjusted_grade = late_assignment(
    raw_grade=85,
    late_count=0,
    is_lower_stakes=False
)
print("Adjusted grade:", adjusted_grade)  # Expected: 85

# Example 2: late submission with no prior late submissions
print("\nExample 2: late submission with no prior late submissions")
adjusted_grade = late_assignment(
    raw_grade=90,
    late_count=0,
    is_lower_stakes=False
)
print("Adjusted grade:", adjusted_grade)  # Expected: 80.0

Example 1: on-time submission
Status: Late (1st occurrence)
Late count: 1
Scaling factor: 0.75
Adjusted grade: 63.75

Example 2: late submission with no prior late submissions
Status: Late (1st occurrence)
Late count: 1
Scaling factor: 0.75
Adjusted grade: 67.5

Grades

The needed_to_pass() function helps you answer a very practical question:

“Given the grades I already have, what minimum grade do I need on each remaining component to finish the course with at least 60%?”

It assumes you will earn the same grade on every remaining component, and returns that required grade for each remaining item.

What grading schemes are supported?

needed_to_pass() supports two course grading layouts, selected by course_type: 1. course_type=“quiz”

lab1, lab2, lab3, lab4 are 12.5% each quiz1, quiz2 are 25% each

  1. course_type=“project”

Milestone1 - Milestone4 are 20% each IndividualAssignment1 - IndividualAssignment4 are 5% each

Inputs 1. course_type: string Must be exactly: “quiz” or “project”

grades: dictionary A dictionary of completed components → grade earned (0–100). Example: {“lab1”: 80, “quiz1”: 70}

Dictionary rules: - keys must be strings (component names) - values must be numbers (int/float) - grades must be between 0 and 100

Output The function returns a dict of remaining components mapped to the minimum grade needed on each (same value for all remaining components).

Example output: {“lab3”: 52.5, “lab4”: 52.5, “quiz2”: 52.5}

Usage examples:

  1. Quiz based course

Input:

from ubc_mds_helper.grade import needed_to_pass

needed_to_pass("quiz", {"lab1": 80, "lab2": 70, "quiz1": 60})
{'lab3': 52.5, 'lab4': 52.5, 'quiz2': 52.5}
  1. Project based course
from ubc_mds_helper.grade import needed_to_pass

needed_to_pass("project", {"Milestone1": 80})
{'IndividualAssignment1': 55.0,
 'IndividualAssignment2': 55.0,
 'Milestone2': 55.0,
 'IndividualAssignment3': 55.0,
 'Milestone3': 55.0,
 'IndividualAssignment4': 55.0,
 'Milestone4': 55.0}

Have fun using it!

Progress Visualization

The visualize_program_progress() function calculates how far along you are in the MDS program and saves a bar chart containing your progress to the img/ folder. Also returns: - capstone_progress_percentage: progress from program start to the capstone start (0 to 1) - completion_percentage: progress from program start to the total program end (0 to 1)

from ubc_mds_helper.progress import visualize_program_progress
from ubc_mds_helper.config import PROGRAM_CONFIG_2025_2026

# pull the key dates from the config file 
program_start = PROGRAM_CONFIG_2025_2026["program_start"]
capstone_start = PROGRAM_CONFIG_2025_2026["capstone"]["start"]
program_end = PROGRAM_CONFIG_2025_2026["program_end"]

# Example 1: If the current date = program start date: Progress equals 0.
print("\nExample 1: current_date = program_start")

capstone_completion_pct, program_completion_pct = visualize_program_progress(current_date = program_start)

print("Capstone progress:", capstone_completion_pct) # Expected: 0
print("Program progress:", program_completion_pct) # Expected: 0

# Example 2: If the current date = capstone start date: Capstone progress should equal 1 and program end progress should be less than 1.
print("\nExample 2: current_date = capstone_start")

capstone_completion_pct, program_completion_pct = visualize_program_progress(current_date = capstone_start)

print("Capstone progress:", capstone_completion_pct) # Expected: 1
print("Program progress:", program_completion_pct) # Expected: <FLOAT> < 1

# Example 3: Passing in date strings (works the same as datetime.date)
print("\nExample 3: passing date strings")

capstone_completion_pct, program_completion_pct = visualize_program_progress(
  current_date = "January 1, 2026",
  program_start_date = "August 29, 2025",
  program_end_date = "June 30, 2026",
  capstone_start_date = "April 24, 2026"
)

print("Capstone progress:", capstone_completion_pct) # Expected: <FLOAT> < 1
print("Program progress:", program_completion_pct) # Expected: <FLOAT> < 1

Example 1: current_date = program_start
Capstone progress: 0
Program progress: 0

Example 2: current_date = capstone_start
Capstone progress: 1
Program progress: 0.7901639344262295

Example 3: passing date strings
Capstone progress: 0.5252100840336135
Program progress: 0.4098360655737705

Keep in mind, the function also saves the progress bar chart to the img/ folder with the timestamp of the current date appended.