From dc512850f3c74a44bc4d9aa07e659f64a7b7b1e3 Mon Sep 17 00:00:00 2001 From: Coding with Peter Date: Thu, 15 Jun 2023 07:55:57 -0700 Subject: [PATCH] degree checking 50% degrees running --- courses.py | 22 +++++++++++++++ degrees.py | 78 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/courses.py b/courses.py index 18ad470..df9ca9c 100644 --- a/courses.py +++ b/courses.py @@ -1596,8 +1596,29 @@ def create_calendar_event(): if "id" in result: print("ok, id#", result["id"]) +def utc_to_local(utc_str): + if not utc_str: return "" + utc_dt = datetime.strptime(utc_str, '%Y-%m-%dT%H:%M:%SZ') + # Set the UTC timezone + utc_tz = pytz.timezone('UTC') + # Convert the UTC datetime to the Pacific Time Zone + pacific_tz = pytz.timezone('US/Pacific') + pacific_dt = utc_dt.astimezone(pacific_tz) + + return pacific_dt.strftime('%a %b %d, %Y %#I:%M%p') + +def list_all_assignments(): + course = input("the course id> ") + u = url + f"/api/v1/courses/{course}/assignments" + c = fetch(u) + #print(json.dumps(c,indent=2)) + for a in c: + p = 'not published' + if a['published'] == True: p = 'published' + date = utc_to_local(a['due_at']) + print(f"{a['name']}\t{p}\t{date}") @@ -1637,6 +1658,7 @@ if __name__ == "__main__": 30: ['Quick course list', quick_sem_course_list ], 31: ['Cross list CWE courses', xlist_cwe], 34: ['Create calendar event', create_calendar_event], + 35: ['list all assignments', list_all_assignments], 40: ['Enroll GOTT Workshops', enroll_gott_workshops_su23], # 24: ['Add course evals to whole semester',instructor_list_to_activate_evals], diff --git a/degrees.py b/degrees.py index f468a20..0b609ad 100644 --- a/degrees.py +++ b/degrees.py @@ -323,28 +323,44 @@ def is_noncourse_new_section(noncourse_line): rule_lookup = { 'take_all_prereq': ['RN PROGRAM PREREQUISITES', 'PREREQUISITES', ], - 'take at least n courses': ['(\d+) courses total', 'SELECT (ONE|TWO) OF THE FOLLOWING', 'Select (one|two|three)', 'Select (\d+) courses', - 'Choose (one) or more', 'Choose (one|two|three) of the classes listed', - 'Choose (\w+) of the following','Choose (one|two|three)', 'Choose ([\d\w]+) courses from', - 'ANY (COURSE) NOT USED IN', 'Select (1)', 'Select (one) of the following REQUIRED CORE', - '(One) of the following:', 'LIST [AB]: Select (\d)', 'Choose (One) Course:', ], - 'take at least n units': ['LIST A \((\d+) units\)', 'LIST B \((\d+) units\)', 'LIST C \- Any course .*\((\d+) units\)', '(\d+) units total', - 'Select (\d+) units', 'Any combination totaling (\d+) units', - 'Choose (\w+) units from classes listed', 'Choose a minimum of ([\w\d]+) units from', - 'Choose any combination of courses for a minimum of ([\w\d]+) units\:?', - 'Choose ([\w\d]+) units', 'Choose courses for at least ([\w\d]+) units', - 'Choose a minimum of (\d+) units', 'Select any (\d+)\-\d+ units from the following'], + 'take at least n courses': ['(One) of the following:', + '(\d+) courses total', + 'ANY (COURSE) NOT USED IN', + 'Choose (One) Course:', + 'Choose (one) or more', + 'Choose (one|two|three) of the classes listed', + 'Choose (one|two|three)', + 'Choose ([\d\w]+) courses from', + 'Choose (\w+) of the following', + 'LIST [AB]: Select (\d)', + 'Select (1)', + 'Select (one) of the following REQUIRED CORE', + 'SELECT (ONE|TWO) OF THE FOLLOWING', 'Select (one|two|three)', + 'Select (\d+) courses', ], + 'take at least n units': [ '(\d+) units total', + 'Any combination totaling (\d+) units', + 'Choose (eight|\d+) units', + 'Choose (\w+) units from classes listed', + 'Choose a minimum of ([\w\d]+) units from', + 'Choose a minimum of (\d+) units', + 'Choose any combination of courses for a minimum of ([\w\d]+) units\:?', + 'Choose courses for at least ([\w\d]+) units', + 'LIST A \((\d+) units\)', + 'LIST B \((\d+) units\)', + 'LIST C \- Any course .*\((\d+) units\)', + 'Select (\d+) units', + 'Select any (\d+)\-\d+ units from the following',], 'electives': ['Electives', 'Recommended electives?:', ], - 'take_all': ['RN PROGRAM', 'REQUIRED CORE', 'CORE COURSES', 'ADDITIONAL REQUIREMENTS','REQUIREMENTS:', 'Requirements', 'Core Requirements', + 'take_all': ['RN PROGRAM', 'REQUIRED CORE', 'CORE COURSES', 'ADDITIONAL REQUIREMENTS','REQUIREMENTS:', + 'Requirements', 'Core Requirements', 'Required Core', 'REQUIRED', 'LVN PROGRAM', 'Student Teaching Practicum', '^LIST A:?$', '^LIST B:$', - 'Program Requirements', 'Required Courses:', 'PROGRAM REQUIREMENTS (5 Units)', 'PROGRAM REQUIREMENTS (162 Hours)', + 'Program Requirements', 'Required Courses:', 'PROGRAM REQUIREMENTS (5 Units)', + 'PROGRAM REQUIREMENTS (162 Hours)', ], } def lookup_rule(line): verbose = 0 - if re.search(rule_lookup['take at least n units'][8], line): - print(f"line: {line} matched: {rule_lookup['take at least n units'][8]}") for key in rule_lookup.keys(): for each in rule_lookup[key]: m = re.search(each, line) @@ -600,16 +616,8 @@ def create_degree_mzn(): %% %% or what courses they'd still need for it +include "base_courses.mzn"; -%% -%% Set up all courses -int: numcourses = [[numcourses]]; -array[1..numcourses] of string: - all_courses = [ [[allcourses]] ]; - -array[1..numcourses] of float: - all_units = [ [[allunits]] ]; - %% Courses student took array[1..numcourses] of bool: student_taken; """.split("\n") @@ -623,6 +631,14 @@ array[1..numcourses] of bool: student_taken; output = substitute_template_var(output, 'degreename', this_course[0]) out_file.write("\n".join(output)) + for r in this_course[1:]: + if re.search(r'^electives', r): + this_course.remove(r) + + # + # + # EACH RULE + # for n,rule in enumerate(this_course[1:]): @@ -704,9 +720,9 @@ constraint sum(j in 1..numcourses)(bool2float(rule_[[n]]_selected[j]) * all_unit ################### - m1 = re.search(r'take_all from (.*)$', rule) + m1 = re.search(r'(take_all|take_all_prereq) from (.*)$', rule) if m1: - crs = m1.group(1).strip(',').split(",") + crs = m1.group(2).strip(',').split(",") crs = [ re.sub(r'\s+','',x) for x in crs ] print(f"\ttake all from {crs}") # take n courses @@ -802,6 +818,7 @@ def check_student_degrees(): records = grades_to_vectors(boolean=1) i = 0 needed = defaultdict(dict) + completion = defaultdict(dict) # took no classes? empty_student = {} @@ -823,7 +840,7 @@ def check_student_degrees(): print(f"student: {r[0]}, taken {crs}") for degree in os.listdir('cache/program_check'): m1 = re.match(r'(.*)\.mzn', degree) - if m1: + if m1 and degree != 'base_courses.mzn': try: d = m1.group(1) @@ -837,6 +854,10 @@ def check_student_degrees(): # Create an Instance of the n-Queens model for Gecode instance = Instance(gecode, deg_model) + + # Add the base courses data file + #instance = instance.add_file("base_courses.dzn") + # Assign student courses taken s = f"student_taken = [" + ','.join( [ str(x) for x in r[1]] ) + "];" instance.add_string(s) @@ -852,6 +873,7 @@ def check_student_degrees(): if str(r[0]) == "0": empty_student[d] = r1['total units'] needed[r[0]][d] = r1['total units'] + completion[r[0]][d] = r1['total units'] / empty_student[d] if r1['total units']>0 and r1['total units'] < lowest: lowest = r1['total units'] lowest_deg = d @@ -872,6 +894,8 @@ def check_student_degrees(): df = pd.DataFrame.from_dict(needed, orient='index') df.to_csv('cache/program_check/needed.csv') + df2 = pd.DataFrame.from_dict(completion, orient='index') + df2.to_csv('cache/program_check/needed_percentage.csv') if __name__ == "__main__": options = { 1: ['parsing example',parser] ,