import pandas as pd import numpy as np from io import StringIO pandas_json_format = 'table' def read_csv(table_str: StringIO) -> pd.DataFrame: try: df = pd.read_csv(table_str, engine='python', skipfooter=2) except: return pd.DataFrame() df = df.set_index(['Nachname', 'Vorname']) # Rename columns to replace commas. # Replace with _ as AggGrid does not seem to support columns with decimals in name df = df.rename(columns=lambda x: x.replace(',','_')) exercises = [col for col in list(df.columns) if 'F' in col] df.update(df[exercises].map(lambda v: v.replace(',','.'))) # German floats -> international floats df.update(df[exercises].map(lambda v: v.replace('-','0.0'))) # '-' -> 0 df = df.astype({k: 'float64' for k in exercises}) return df def parse_header(df: pd.DataFrame) -> tuple[int, list[str]]: max_points = [col for col in list(df.columns) if 'Bewertung' in col] if len(max_points) != 1: raise ValueError("Could not find column 'Bewertung' in table!") max_points = float(max_points[0].split('/', 1)[1].replace('_','.')) exercises = [col for col in list(df.columns) if 'F' in col] if len(exercises) < 1: raise ValueError("Table does not seem to contain exercise points!") return max_points, exercises def merge_points(points_df_hisio: pd.DataFrame, points_df_moodle: pd.DataFrame) -> tuple[pd.DataFrame, int]: points_df_hisio = points_df_hisio.reset_index().set_index(['Nachname', 'Vorname']) common_keys = points_df_hisio.index.intersection(points_df_moodle.index) update_count = len(common_keys) points_df_hisio.update(points_df_moodle) points_df_hisio = points_df_hisio.reset_index().set_index('Matrikelnummer') return points_df_hisio, update_count