Spaces:
Runtime error
Runtime error
| import numpy as np | |
| import pandas as pd | |
| import re | |
| from pathlib import Path | |
| def read_and_preprocess_spreadsheet(file_name): | |
| """ Creates a pandas dataframe from the curriculum overview spreadsheet """ | |
| DATA_DIR = Path(__file__).parent.parent / "mathtext_fastapi" / "data" / file_name | |
| script_df = pd.read_excel(DATA_DIR, engine='openpyxl') | |
| # Ensures the grade level columns are integers instead of floats | |
| script_df.columns = script_df.columns[:2].tolist() + script_df.columns[2:11].astype(int).astype(str).tolist() + script_df.columns[11:].tolist() | |
| script_df.fillna('', inplace=True) | |
| return script_df | |
| def extract_skill_code(skill): | |
| """ Looks within a curricular skill description for its descriptive code | |
| Input | |
| - skill: str - a brief description of a curricular skill | |
| >>> extract_skill_code('A3.3.4 - Solve inequalities') | |
| 'A3.3.4' | |
| >>> extract_skill_code('A3.3.2 - Graph linear equations, and identify the x- and y-intercepts or the slope of a line') | |
| 'A3.3.2' | |
| """ | |
| pattern = r'[A-Z][0-9]\.\d+\.\d+' | |
| result = re.search(pattern, skill) | |
| return result.group() | |
| def build_horizontal_transitions(script_df): | |
| """ Build a list of transitional relationships within a curricular skill | |
| Inputs | |
| - script_df: pandas dataframe - an overview of the curriculum skills by grade level | |
| Output | |
| - horizontal_transitions: array of arrays - transition data with label, from state, and to state | |
| >>> script_df = read_and_preprocess_spreadsheet('curriculum_framework_for_tests.xlsx') | |
| >>> build_horizontal_transitions(script_df) | |
| [['right', 'N1.1.1_G1', 'N1.1.1_G2'], ['right', 'N1.1.1_G2', 'N1.1.1_G3'], ['right', 'N1.1.1_G3', 'N1.1.1_G4'], ['right', 'N1.1.1_G4', 'N1.1.1_G5'], ['right', 'N1.1.1_G5', 'N1.1.1_G6'], ['left', 'N1.1.1_G6', 'N1.1.1_G5'], ['left', 'N1.1.1_G5', 'N1.1.1_G4'], ['left', 'N1.1.1_G4', 'N1.1.1_G3'], ['left', 'N1.1.1_G3', 'N1.1.1_G2'], ['left', 'N1.1.1_G2', 'N1.1.1_G1'], ['right', 'N1.1.2_G1', 'N1.1.2_G2'], ['right', 'N1.1.2_G2', 'N1.1.2_G3'], ['right', 'N1.1.2_G3', 'N1.1.2_G4'], ['right', 'N1.1.2_G4', 'N1.1.2_G5'], ['right', 'N1.1.2_G5', 'N1.1.2_G6'], ['left', 'N1.1.2_G6', 'N1.1.2_G5'], ['left', 'N1.1.2_G5', 'N1.1.2_G4'], ['left', 'N1.1.2_G4', 'N1.1.2_G3'], ['left', 'N1.1.2_G3', 'N1.1.2_G2'], ['left', 'N1.1.2_G2', 'N1.1.2_G1']] | |
| """ | |
| horizontal_transitions = [] | |
| for index, row in script_df.iterrows(): | |
| skill_code = extract_skill_code(row['Knowledge or Skill']) | |
| rightward_matches = [] | |
| for i in range(9): | |
| # Grade column | |
| current_grade = i+1 | |
| if row[current_grade].lower().strip() == 'x': | |
| rightward_matches.append(i) | |
| for match in rightward_matches: | |
| if rightward_matches[-1] != match: | |
| horizontal_transitions.append([ | |
| "right", | |
| f"{skill_code}_G{match}", | |
| f"{skill_code}_G{match+1}" | |
| ]) | |
| leftward_matches = [] | |
| for i in reversed(range(9)): | |
| current_grade = i | |
| if row[current_grade].lower().strip() == 'x': | |
| leftward_matches.append(i) | |
| for match in leftward_matches: | |
| if leftward_matches[0] != match: | |
| horizontal_transitions.append([ | |
| "left", | |
| f"{skill_code}_G{match}", | |
| f"{skill_code}_G{match-1}" | |
| ]) | |
| return horizontal_transitions | |
| def gather_all_vertical_matches(script_df): | |
| """ Build a list of transitional relationships within a grade level across skills | |
| Inputs | |
| - script_df: pandas dataframe - an overview of the curriculum skills by grade level | |
| Output | |
| - all_matches: array of arrays - represents skills at each grade level | |
| >>> script_df = read_and_preprocess_spreadsheet('curriculum_framework_for_tests.xlsx') | |
| >>> gather_all_vertical_matches(script_df) | |
| [['N1.1.1', '1'], ['N1.1.2', '1'], ['N1.1.1', '2'], ['N1.1.2', '2'], ['N1.1.1', '3'], ['N1.1.2', '3'], ['N1.1.1', '4'], ['N1.1.2', '4'], ['N1.1.1', '5'], ['N1.1.2', '5'], ['N1.1.1', '6'], ['N1.1.2', '6']] | |
| """ | |
| all_matches = [] | |
| columns = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] | |
| for column in columns: | |
| for index, value in script_df[column].iteritems(): | |
| row_num = index + 1 | |
| if value == 'x': | |
| # Extract skill code | |
| skill_code = extract_skill_code( | |
| script_df['Knowledge or Skill'][row_num-1] | |
| ) | |
| all_matches.append([skill_code, column]) | |
| return all_matches | |
| def build_vertical_transitions(script_df): | |
| """ Build a list of transitional relationships within a grade level across skills | |
| Inputs | |
| - script_df: pandas dataframe - an overview of the curriculum skills by grade level | |
| Output | |
| - vertical_transitions: array of arrays - transition data with label, from state, and to state | |
| >>> script_df = read_and_preprocess_spreadsheet('curriculum_framework_for_tests.xlsx') | |
| >>> build_vertical_transitions(script_df) | |
| [['down', 'N1.1.1_G1', 'N1.1.2_G1'], ['down', 'N1.1.2_G1', 'N1.1.1_G1'], ['down', 'N1.1.1_G2', 'N1.1.2_G2'], ['down', 'N1.1.2_G2', 'N1.1.1_G2'], ['down', 'N1.1.1_G3', 'N1.1.2_G3'], ['down', 'N1.1.2_G3', 'N1.1.1_G3'], ['down', 'N1.1.1_G4', 'N1.1.2_G4'], ['down', 'N1.1.2_G4', 'N1.1.1_G4'], ['down', 'N1.1.1_G5', 'N1.1.2_G5'], ['down', 'N1.1.2_G5', 'N1.1.1_G5'], ['down', 'N1.1.1_G6', 'N1.1.2_G6'], ['up', 'N1.1.2_G6', 'N1.1.1_G6'], ['up', 'N1.1.1_G6', 'N1.1.2_G6'], ['up', 'N1.1.2_G5', 'N1.1.1_G5'], ['up', 'N1.1.1_G5', 'N1.1.2_G5'], ['up', 'N1.1.2_G4', 'N1.1.1_G4'], ['up', 'N1.1.1_G4', 'N1.1.2_G4'], ['up', 'N1.1.2_G3', 'N1.1.1_G3'], ['up', 'N1.1.1_G3', 'N1.1.2_G3'], ['up', 'N1.1.2_G2', 'N1.1.1_G2'], ['up', 'N1.1.1_G2', 'N1.1.2_G2'], ['up', 'N1.1.2_G1', 'N1.1.1_G1']] | |
| """ | |
| vertical_transitions = [] | |
| all_matches = gather_all_vertical_matches(script_df) | |
| # Downward | |
| for index, match in enumerate(all_matches): | |
| skill = match[0] | |
| row_num = match[1] | |
| if all_matches[-1] != match: | |
| vertical_transitions.append([ | |
| "down", | |
| f"{skill}_G{row_num}", | |
| f"{all_matches[index+1][0]}_G{row_num}" | |
| ]) | |
| # Upward | |
| for index, match in reversed(list(enumerate(all_matches))): | |
| skill = match[0] | |
| row_num = match[1] | |
| if all_matches[0] != match: | |
| vertical_transitions.append([ | |
| "up", | |
| f"{skill}_G{row_num}", | |
| f"{all_matches[index-1][0]}_G{row_num}" | |
| ]) | |
| return vertical_transitions | |
| def build_all_states(all_transitions): | |
| """ Creates an array with all state labels for the curriculum | |
| Input | |
| - all_transitions: list of lists - all possible up, down, left, or right transitions in curriculum | |
| Output | |
| - all_states: list - a collection of state labels (skill code and grade number) | |
| >>> all_transitions = [['right', 'N1.1.1_G1', 'N1.1.1_G2'], ['right', 'N1.1.1_G2', 'N1.1.1_G3'], ['right', 'N1.1.1_G3', 'N1.1.1_G4'], ['right', 'N1.1.1_G4', 'N1.1.1_G5'], ['right', 'N1.1.1_G5', 'N1.1.1_G6'], ['left', 'N1.1.1_G6', 'N1.1.1_G5'], ['left', 'N1.1.1_G5', 'N1.1.1_G4'], ['left', 'N1.1.1_G4', 'N1.1.1_G3'], ['left', 'N1.1.1_G3', 'N1.1.1_G2'], ['left', 'N1.1.1_G2', 'N1.1.1_G1'], ['right', 'N1.1.2_G1', 'N1.1.2_G2'], ['right', 'N1.1.2_G2', 'N1.1.2_G3'], ['right', 'N1.1.2_G3', 'N1.1.2_G4'], ['right', 'N1.1.2_G4', 'N1.1.2_G5'], ['right', 'N1.1.2_G5', 'N1.1.2_G6'], ['left', 'N1.1.2_G6', 'N1.1.2_G5'], ['left', 'N1.1.2_G5', 'N1.1.2_G4'], ['left', 'N1.1.2_G4', 'N1.1.2_G3'], ['left', 'N1.1.2_G3', 'N1.1.2_G2'], ['left', 'N1.1.2_G2', 'N1.1.2_G1'], ['down', 'N1.1.1_G1', 'N1.1.2_G1'], ['down', 'N1.1.2_G1', 'N1.1.1_G1'], ['down', 'N1.1.1_G2', 'N1.1.2_G2'], ['down', 'N1.1.2_G2', 'N1.1.1_G2'], ['down', 'N1.1.1_G3', 'N1.1.2_G3'], ['down', 'N1.1.2_G3', 'N1.1.1_G3'], ['down', 'N1.1.1_G4', 'N1.1.2_G4'], ['down', 'N1.1.2_G4', 'N1.1.1_G4'], ['down', 'N1.1.1_G5', 'N1.1.2_G5'], ['down', 'N1.1.2_G5', 'N1.1.1_G5'], ['down', 'N1.1.1_G6', 'N1.1.2_G6'], ['up', 'N1.1.2_G6', 'N1.1.1_G6'], ['up', 'N1.1.1_G6', 'N1.1.2_G6'], ['up', 'N1.1.2_G5', 'N1.1.1_G5'], ['up', 'N1.1.1_G5', 'N1.1.2_G5'], ['up', 'N1.1.2_G4', 'N1.1.1_G4'], ['up', 'N1.1.1_G4', 'N1.1.2_G4'], ['up', 'N1.1.2_G3', 'N1.1.1_G3'], ['up', 'N1.1.1_G3', 'N1.1.2_G3'], ['up', 'N1.1.2_G2', 'N1.1.1_G2'], ['up', 'N1.1.1_G2', 'N1.1.2_G2'], ['up', 'N1.1.2_G1', 'N1.1.1_G1']] | |
| >>> build_all_states(all_transitions) | |
| ['N1.1.1_G1', 'N1.1.1_G2', 'N1.1.1_G3', 'N1.1.1_G4', 'N1.1.1_G5', 'N1.1.1_G6', 'N1.1.2_G1', 'N1.1.2_G2', 'N1.1.2_G3', 'N1.1.2_G4', 'N1.1.2_G5', 'N1.1.2_G6'] | |
| """ | |
| all_states = [] | |
| for transition in all_transitions: | |
| for index, state in enumerate(transition): | |
| if index == 0: | |
| continue | |
| if state not in all_states: | |
| all_states.append(state) | |
| return all_states | |
| def build_curriculum_logic(): | |
| script_df = read_and_preprocess_spreadsheet('Rori_Framework_v1.xlsx') | |
| horizontal_transitions = build_horizontal_transitions(script_df) | |
| vertical_transitions = build_vertical_transitions(script_df) | |
| all_transitions = horizontal_transitions + vertical_transitions | |
| all_states = build_all_states(all_transitions) | |
| return all_states, all_transitions | |