Rapporten Inleiding Om rapporten te maken voor studenten is een klein Python script gemaakt. Zorg ervoor dat Python3 is geïnstalleerd, en dat  via PIP de juiste library's zijn geïnstalleerd. pip install pandas Benodigde bestanden studenten.csv Nr;Klas;Canvas Id;Student nr;Naam 1;3B;20576;2033543;Leonard Cranary 2;3C;26328;2140079;Walid Sallek ... Dit bestand is een export van de Canvasmonitor waarbij niet relevante kolommen zijn weggehaald. Dit bestand is leidend en de Id's worden gebruikt om een koppeling te maken met andere Excel lijsten. De kolomnamen kunnen worden gebruikt om teksten in de template te vervangen. Zo kun je wordt _Klas_ in een template vervangen door de klas in dit overzicht. template.docx Dit is een Word-template ( template.docx ) waarbij de in-te-vullen velden worden gekenmerkt door een pre-fix en post fix, bijvoorbeeld: _studentNaam_ Ander bestanden Ander bestanden, presentie, blokken, kennis-check,..... Afhankelijk van de gegevens die je nodig hebt kan je meerdere bestanden inlezen. Elk bestand dient een ID-kolom te hebben. Dit id moet het studentennummer bevatten dat overeenkomt met het studentnummer in de stundenten.csv . De bestanden worden ingelezen in het codeblok vanaf regel 51. Vanaf regel 90 worden de velden uit de template vervangen.  Voorbeeld: replace_text_in_doc(doc, "_kennis_", str(kennis.get(student_number, '???'))) In een van de ingelezen bestanden staat een kolom kennis.  Deze wordt gematched uit kennis.csv via het student_number veld (uit studenten.csv). Aanpassen in de code Plaats de docenten en de klassen in de dictionary (regel 12 v/d code). Code import os, sys # import chardet import pandas as pd from shutil import copyfile from docx import Document # Load the Excel file basis_csv = './studenten.csv' word_template = './template.docx' presentie_csv = './presentie.csv' kennis_csv = './kennis.csv' canvas_csv = './canvas.csv' base_output_folder = './' docent = { '3A':'Mina Ulas - Bicer', '3B':'Muhammed Çagli / Anton Boutkam', '3C':'Max Bisschop'} # Define the function to replace text in the document def replace_text_in_doc(doc, old_text, new_text): for paragraph in doc.paragraphs: if old_text in paragraph.text: paragraph.text = paragraph.text.replace(old_text, new_text) for table in doc.tables: for row in table.rows: for cell in row.cells: replace_text_in_doc(cell, old_text, new_text) def readExcel(excel_path): # with open(excel_path, 'rb') as file: # result = chardet.detect(file.read()) # print(f'Encoding {excel_path}: '+result['encoding']) try: excel_data = pd.read_csv(excel_path, index_col=None, sep=';', encoding='utf-8-sig') # print("Column names:", [col for col in excel_data.columns]) except FileNotFoundError: sys.exit(f"The file {excel_path} was not found.") except pd.errors.EmptyDataError: sys.exit(f"The file {excel_path} is empty.") except pd.errors.ParserError: sys.exit(f"The file {excel_path} is probably not a CSV file or it is badly formatted.") except Exception as e: sys.exit(f"An unexpected error occurred in readExcel {excel_path}: {e}") return (excel_data) def getDataFromExcel(file_name, column_name): print(f"Reading {column_name} from {file_name}") if not os.path.exists(file_name): sys.exit(f"File {file_name} not found") data = readExcel(file_name) if column_name not in data.columns: sys.exit(f"Error: Column '{column_name}' does not exist in the file.") if 'ID' not in data.columns: sys.exit(f"Error: Column ID does not exist in the file.") dict = {} for index, row in data.iterrows(): dict[row['ID']] = row[column_name] return(dict) presentie = getDataFromExcel(presentie_csv, 'presentie') kennis = getDataFromExcel(kennis_csv, 'kennis') # praktijk = getDataFromExcel('./canvas.csv', 'praktijk') blok1 = getDataFromExcel(canvas_csv, 'blok1') blok2 = getDataFromExcel(canvas_csv, 'blok2') # studieduur = getDataFromExcel(canvas_csv, 'studieduur') cmon = readExcel(basis_csv) for index, row in cmon.iterrows(): print(f"Processing {row['Naam']}") person_name = row['Naam'] # Adjust the column name as necessary group_name = row['Klas'] # Adjust the column name as necessary student_number = row['Student nr'] # Create a new file name with prefix "voortgang" new_file_name = f"voortgang {student_number} {person_name} {group_name}.docx" # Create a path for the new group folder if it doesn't exist group_folder_path = os.path.join(base_output_folder, group_name) if not os.path.exists(group_folder_path): os.makedirs(group_folder_path) # Define the full path for the new file within the group folder new_file_path = os.path.join(group_folder_path, new_file_name) # Copy the template to the new file name in the group folder doc = Document(word_template) replace_text_in_doc(doc, "_studentnaam_", person_name) replace_text_in_doc(doc, "_docentnaam_", str(docent.get(group_name, '???'))) replace_text_in_doc(doc, "_studentnummer_", str(student_number)) replace_text_in_doc(doc, "_presentie_", str(presentie.get(student_number, '???'))) replace_text_in_doc(doc, "_kennis_", str(kennis.get(student_number, '???'))) # replace_text_in_doc(doc, "_praktijk_", str(praktijk.get(student_number, '???'))) replace_text_in_doc(doc, "_blok1_", str(blok1.get(student_number, '???'))) replace_text_in_doc(doc, "_blok2_", str(blok2.get(student_number, '???'))) # replace_text_in_doc(doc, "_studieduur_", str(studieduur.get(student_number, '???'))) doc.save(new_file_path) print(f"File created for: {person_name} in group: {group_name}") # sys.exit("Test") print("All files have been created.") Voorbeeld extra databestanden (bovenstaande code werkt met deze bestanden). template.docx presentie.csv (uit Eduarte) Deelnemer;% Aanwezig;Nr;ID;presentie 2186011 - Yusuf Aksari;96;1;2186011;96 2132925 - Ibrahim Azarfane;13;2;2132925;13 ... canvas.csv (voor voortgang blokken, uit de Canvas monitor) Rank;ID;Klas;Student;Studentnaam;Tot;blok7;blok8;Voortgang;studieduur;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;;praktijk;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;Naam 7350;2184477;3D;Student;Giovanni Deniz;36;Ja;Ja;3653;3-;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;;0;100;100;100;100;100;0;100;100;13;100;100;100;100;100;40;GiovanniD|/public/index|code|935315184868c08dc18c67ff3f4d3645 ..... kennis.csv (voor kennis-check) ID;Naam;kennis 2202160;Alie Abduka;73,0 2197436;André Romburg;76,5 ... Stappen Let op: Bewaar alle CSV-bestanden in het formaat: CSV - UTF-8 studenten.csv Download uit de Canvas-monitor alles studenten. Menu (beheer - studenten en dan export). Verander de naam naar studenten.csv . Dit is het basisbestand. Kolomnamen hoeven niet te worden aangepast. canvas.scv Download de voortgang uit de Canvas-monitor. Noem de kolom met het studentennummer 'ID' en voeg kolommen toe blok1, blok 2, ....Zet in deze kolommen "ja" of "nee" afhankelijk of het blok is gehaald. Pas de code aan afhankelijk welke blokken je wilt afdrukken. Formule:  =IF(SUM()=300;"Ja";"Nee") presentie.csv Voeg de presentie bestanden samen tot één CSV en bereken het percentage aanwezig. Percentage aanwezig is: =round(aanwezig/(aanwezig+ongeoorloofd+ziek)*100;0) kennis.csv Maak een csv-bestand met ID (studentennummer) en zet het (gemiddelde) cijfer voor de kennis-checks onder de kop kennis . Praktijk test In 2024/25 nog niet getest. Test run Om te testen haal het commentaar uit regel 104. De code stopt na één rapport. Controleer het rapport en indien correct draai alle rapporten door regel 104 weer in commentaar te zetten. --