""" author: Florian Krach """ import numpy as np import panel as pn import pandas as pd import openpyxl from io import BytesIO import os import shutil from make_anonym_list import make_anonym_list from generate_version import generate_versions from pyscript import display as dispplay_default import warnings warnings.filterwarnings("ignore") def display(*args, target=None, append=None): if append is None: append = False dispplay_default(*args, target=target, append=append) display("Choose the Excel file:", target="desc fileinput") display("Choose all the relevant TeX files:", target="desc fileinput-tex") display("", target="output") fileInput = pn.widgets.FileInput(accept='.xlsx') fileInputTex = pn.widgets.FileInput(accept='.tex', multiple=True) uploadButton = pn.widgets.Button(name='Upload and Process', button_type = 'primary') textInput = pn.widgets.TextInput( name='Number of random groups:', placeholder='Leave blank for no randomization') textInputGlobSeed = pn.widgets.TextInput( name='Global Seed:', placeholder='Leave blank for a random global_seed') def makedirs(dirname): if not os.path.exists(dirname): os.makedirs(dirname) def process_file(event): display("Processing ...", target="output") display("", target="output2") display("", target="download") display("", target="download2") display("", target="attention") n = textInput.value try: n = int(n) except Exception: n = 1 amount_rand_groups = n attention = 0 if fileInput.value is not None: f = fileInput.filename if "pruefungsanmeldung" in f.lower() or "belegung" in f.lower(): lang = 1 if "belegung" in f.lower(): attention = 1 elif "examinationregistration" in f.lower() or "registration" in f.lower(): lang = 0 if f.lower().startswith("registration"): attention = 1 else: lang = 0 display("error: could not determine language of registrations file", target="output") return 0 try: df = pd.read_excel(BytesIO(fileInput.value)) df_out, rand_group_dict, df_sol = make_anonym_list( df, amount_rand_groups, lang, return_list_for_solution=True) display("preview:", target="output") display(df_out.head(n=10), target="output2") df_out.to_csv("registration.csv", index=False, sep=";") downloadButton.servable(target='download') if attention: display( "WARNING: The student file is NOT an Exam-Registration " "file! You can ignore this warning if this was " "intended (e.g. for an inofficial midterm exam).", target="attention") input_dir = "QuestionsAndSolutions/" makedirs(input_dir) df_sol.to_csv( input_dir+"registration_for_solution.csv", index=False, sep=";") # if tex files are provided, randomize them if fileInputTex.value is not None: file_names = fileInputTex.filename # save the uploaded files for name, filebytes in zip( fileInputTex.filename, fileInputTex.value): with open(input_dir+name, "wb+") as f: f.write(filebytes) number_questions = len(file_names)-1 # get random seeds try: global_seed = int(textInputGlobSeed.value) except Exception: global_seed = np.random.randint(1, 1000000) np.random.seed(global_seed) rand_seeds = np.random.choice( 1000000, amount_rand_groups, replace=False) # generate the randomized versions if amount_rand_groups > 1: for i in range(amount_rand_groups): generate_versions( path=input_dir, existing_version="v0", number_questions=number_questions, new_version=rand_group_dict["{}".format(i)], seed=rand_seeds[i], global_seed=global_seed, debug=False) # zip the directory for download shutil.make_archive(input_dir[:-1], "zip", base_dir=input_dir) downloadButton2.servable(target='download2') display("Files successfully processed -> ready for download", target="output") display("preview:", target="output", append=True) except Exception as e: display("error:\n{}".format(e), target="output") display("", target="output2") else: display("please select a file first ...", target="output") display("", target="output2") uploadButton.on_click(process_file) downloadButton = pn.widgets.FileDownload(file="registration.csv") downloadButton2 = pn.widgets.FileDownload(file="QuestionsAndSolutions.zip") uploadButton.servable(target='upload') fileInput.servable(target='fileinput') fileInputTex.servable(target='fileinput-tex') textInput.servable(target='textinput') textInputGlobSeed.servable(target='textinput-seed')