Add new scripts for processing exam groups and updating schedules; refactor existing code

This commit is contained in:
bdaneels 2025-07-25 11:14:58 +02:00
parent b912de4c44
commit c547a74bba
9 changed files with 678 additions and 38 deletions

View File

@ -0,0 +1,32 @@
import pandas as pd
promotor_assessor = {
"De Munck": ["De Groot"],
"Gelderblom": ["Van Laer"],
"Blondé": ["Schepers", "Kole"],
"Puttevils": ["Heijmans"],
"Greefs": ["Tanis"],
"Wynants": ["Samoy", "Welslau"]
}
df = pd.read_excel('sisa.xlsx', sheet_name='sheet1')
for idx, row in df.iterrows():
promotor_cell = str(row.get('Promotor', '')).strip()
assessors_cell = [a.strip() for a in str(row.get('Assessor(en)', '')).split(',')]
matched_promotor = None
for key in promotor_assessor:
if key in promotor_cell or promotor_cell in key:
matched_promotor = key
break
if matched_promotor:
expected = promotor_assessor[matched_promotor]
missing = []
for e in expected:
if not any(e in a or a in e for a in assessors_cell):
missing.append(e)
if missing:
print(f"Row {idx+1}: ERROR: Expected assessors {expected}, found {assessors_cell}")
print("Check completed successfully.")

View File

@ -0,0 +1,32 @@
import pandas as pd
import openpyxl
sisa_file = pd.read_excel("sisa file.xlsx", sheet_name="Sheet1")
reinoud_file = pd.read_excel("reinoud file.xlsx", sheet_name="Sheet1")
sisa_file["Promotor"] = sisa_file["Promotor"].str.rsplit(" ", n=1).str[0]
sisa_file["Full Name"] = sisa_file["Achternaam"] + " " + sisa_file["Voornaam"]
# Step 3: Check if the Full Name exists in the Naam column of the reinoud file
merged = sisa_file.merge(reinoud_file, left_on="Full Name", right_on="Naam", how="inner")
# Step 4: Find divergent Promotor values
divergent_promotors = merged[merged["Promotor_x"] != merged["Promotor_y"]]
# Step 5: Check if Assessor(en) contains Lector 1 and Lector 2
def check_assessors(row):
assessors = row["Assessor(en)"]
return all(lector in assessors for lector in [row["Lector 1"], row["Lector 2"]])
merged["Assessors Match"] = merged.apply(check_assessors, axis=1)
# Save results
divergent_promotors.to_excel("divergent_promotors.xlsx", index=False)
merged.to_excel("merged_results.xlsx", index=False)
print("Processing complete. Results saved.")

View File

@ -2,7 +2,7 @@ import pandas as pd
# Constants
FILE_PATH = 'file.xlsx'
SHEET_NAME = 'ps (32)'
SHEET_NAME = 'ps (53)'
OUTPUT_FILE_PATH = 'filtered_grote_lokalen.xlsx'
EXAM_FORM_COLUMN = 'Examenvorm'
REGISTRATION_COLUMN = 'Aant. inschr.'
@ -10,6 +10,7 @@ BEGIN_TIME_COLUMN = 'Beginuur S+'
END_TIME_COLUMN = 'Einduur S+'
TEACHERS_COLUMN = 'Docenten'
LOCATION_COLUMNS = ['Datum S+', BEGIN_TIME_COLUMN, END_TIME_COLUMN, 'Studiegidsnr.', 'Omschrijving', TEACHERS_COLUMN, REGISTRATION_COLUMN]
AANTAL_STUDENTEN = 65
# Read the Excel file
def read_excel(file_path, sheet_name):
@ -18,7 +19,7 @@ def read_excel(file_path, sheet_name):
# Filter DataFrame
def filter_dataframe(df):
df = df[df[EXAM_FORM_COLUMN] == 'Schriftelijk']
df = df[df[REGISTRATION_COLUMN] > 65]
df = df[df[REGISTRATION_COLUMN] > AANTAL_STUDENTEN]
return df[LOCATION_COLUMNS]
# Format time strings

@ -0,0 +1 @@
Subproject commit 846d0f6fb41ee880bef7acae427f744c2fffc8df

View File

@ -0,0 +1,231 @@
<!DOCTYPE html>
<html class='pc chrome win psc_dir-ltr psc_form-xlarge' dir='ltr' lang='nl'>
<!-- Copyright (c) 2000, 2022, Oracle and/or its affiliates. -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><body><table border='1' cellpadding='3' cellspacing='0'>
<tr>
<th>Studiegidsnr.</th><th>Omschrijving</th><th>Docenten</th><th>SP</th><th>Aant. inschr.</th><th>Examenvorm</th><th>Tijdslots aanvr.SSS</th><th>Examen groep</th><th>Aant. stdnt. gr.</th><th>Datum S+</th><th>Beginuur S+</th><th>Einduur S+</th><th>Facilitieit S+</th><th>Code examenrooster</th><th>Extra info voor studenten</th></tr>
<tr>
<td >2002FLWGES</td>
<td >Historisch atelier</td>
<td >Titularis Beyen,Marnix</td>
<td >6,00</td>
<td >2</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >2</td>
<td >22/08/2025</td>
<td >09:00</td>
<td >13:00</td>
<td ></td>
<td >2002FLWGES7852_224003_M1_1</td>
<td ></td>
<tr>
<td >2004FLWGES</td>
<td >Theorie van de hist. kennis</td>
<td >Titularis De Munck,Bert</td>
<td >6,00</td>
<td >8</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >8</td>
<td >25/08/2025</td>
<td >08:30</td>
<td >12:30</td>
<td ></td>
<td >2004FLWGES8023_224003_M1_1</td>
<td ></td>
<tr>
<td >2013FLWGES</td>
<td >Landschapsgeschiedenis</td>
<td >Titularis Soens,Tim - Titularis Jongepier,Iason</td>
<td >6,00</td>
<td >2</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >2</td>
<td >21/08/2025</td>
<td >14:00</td>
<td >17:00</td>
<td ></td>
<td >2013FLWGES1238_224003_M1_1</td>
<td ></td>
<tr>
<td >2064FLWGES</td>
<td >Politieke Geschiedenis: thema</td>
<td >Titularis de Smaele,Henk</td>
<td >6,00</td>
<td >3</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >3</td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td >2064FLWGES16077_224003_M1_1</td>
<td >niet roosteren, studenten vragen docenten te contacteren</td>
<tr>
<td >2041FLWGES</td>
<td >Theorie en gesch stedenbouw</td>
<td >Titularis De Block,Greet</td>
<td >6,00</td>
<td >2</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >2</td>
<td >01/09/2025</td>
<td >09:30</td>
<td >12:00</td>
<td ></td>
<td >2041FLWGES15506_224003_M1_1</td>
<td ></td>
<tr>
<td >2066FLWGES</td>
<td >War and Occupation Middle East</td>
<td >Co-Titularis Sayim,Burak<br /> Titularis Shaery-Yazdi,Roschanack<br /> Titularis Beyen,Marnix</td>
<td >6,00</td>
<td ></td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td >2066FLWGES16110_224003_M1_2</td>
<td ></td>
<tr>
<td >2046FLWGES</td>
<td >Stage Cultureel Erfgoed</td>
<td >Titularis Delsaerdt,Pierre</td>
<td >6,00</td>
<td ></td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td >2046FLWGES15618_224003_M1_1</td>
<td ></td>
<tr>
<td >2053FLWGES</td>
<td >Urban History and Theory</td>
<td >Titularis Van Damme,Ilja</td>
<td >6,00</td>
<td >1</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >1</td>
<td >02/09/2025</td>
<td >09:00</td>
<td >12:30</td>
<td ></td>
<td >2053FLWGES15754_224003_M1_1</td>
<td ></td>
<tr>
<td >2063FLWGES</td>
<td >Cultureel erfgoed</td>
<td >Titularis Shaery-Yazdi,Roschanack - Titularis De Roo,Bas</td>
<td >6,00</td>
<td >1</td>
<td >Mondeling</td>
<td >N</td>
<td >1</td>
<td >1</td>
<td >04/09/2025</td>
<td >10:00</td>
<td >12:30</td>
<td ></td>
<td >2063FLWGES16071_224003_M1_1</td>
<td ></td>
<tr>
<td >2066FLWGES</td>
<td >War and Occupation Middle East</td>
<td >Co-Titularis Sayim,Burak<br /> Titularis Shaery-Yazdi,Roschanack<br /> Titularis Beyen,Marnix</td>
<td >6,00</td>
<td ></td>
<td >PC examen</td>
<td >N</td>
<td >1</td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td >2066FLWGES16110_224003_D1_1</td>
<td ></td>
<tr>
<td >2065FLWGES</td>
<td >Cultureel erfgoed</td>
<td >Titularis Delsaerdt,Pierre</td>
<td >6,00</td>
<td ></td>
<td >Schriftelijk</td>
<td >N</td>
<td >1</td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td >2065FLWGES16091_224003_S1_1</td>
<td ></td>
<tr>
<td >2045FLWGES</td>
<td >Masterproef</td>
<td >Co-Titularis Vermoesen,Reinoud - Titularis NNB,- - Medewerker NNB,</td>
<td >18,00</td>
<td >18</td>
<td >Schriftelijk</td>
<td >N</td>
<td >1</td>
<td >18</td>
<td >18/08/2025</td>
<td >09:00</td>
<td >16:00</td>
<td ></td>
<td >2045FLWGES15597_224003_S1_1</td>
<td ></td>
<tr>
<td >2023FLWGES</td>
<td >Hist Body, Gender, Sexuality</td>
<td >Titularis de Smaele,Henk</td>
<td >6,00</td>
<td >3</td>
<td >Schriftelijk</td>
<td >N</td>
<td >1</td>
<td >3</td>
<td >28/08/2025</td>
<td >13:30</td>
<td >16:30</td>
<td ></td>
<td >2023FLWGES15226_224003_S1_1</td>
<td ></td>
<tr>
<td >2073FLWGES</td>
<td >Joodse Geschiedenis NT</td>
<td >Titularis Dunkelgrün,Theodor</td>
<td >6,00</td>
<td >1</td>
<td >Schriftelijk</td>
<td >N</td>
<td >1</td>
<td >1</td>
<td >26/08/2025</td>
<td >08:00</td>
<td >12:00</td>
<td ></td>
<td >2073FLWGES16177_224003_S1_1</td>
<td ></td>
</table></body></html>

View File

@ -0,0 +1,324 @@
<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta name="Excel Workbook Frameset">
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<meta name=ProgId content=Excel.Sheet>
<meta name=Generator content="Microsoft Excel 15">
<link rel=File-List href="examenrooster%20pre-syllabus_files/filelist.xml">
<![if !supportTabStrip]>
<link id="shLink" href="examenrooster%20pre-syllabus_files/sheet001.htm">
<link id="shLink">
<script language="JavaScript">
<!--
var c_lTabs=1;
var c_rgszSh=new Array(c_lTabs);
c_rgszSh[0] = "examenrooster pre-syllabus";
var c_rgszClr=new Array(8);
c_rgszClr[0]="window";
c_rgszClr[1]="buttonface";
c_rgszClr[2]="windowframe";
c_rgszClr[3]="windowtext";
c_rgszClr[4]="threedlightshadow";
c_rgszClr[5]="threedhighlight";
c_rgszClr[6]="threeddarkshadow";
c_rgszClr[7]="threedshadow";
var g_iShCur;
var g_rglTabX=new Array(c_lTabs);
function fnGetIEVer()
{
var ua=window.navigator.userAgent
var msie=ua.indexOf("MSIE")
if (msie>0 && window.navigator.platform=="Win32")
return parseInt(ua.substring(msie+5,ua.indexOf(".", msie)));
else
return 0;
}
function fnBuildFrameset()
{
var szHTML="<frameset rows=\"*,18\" border=0 width=0 frameborder=no framespacing=0>"+
"<frame src=\""+document.all.item("shLink")[0].href+"\" name=\"frSheet\" noresize>"+
"<frameset cols=\"54,*\" border=0 width=0 frameborder=no framespacing=0>"+
"<frame src=\"\" name=\"frScroll\" marginwidth=0 marginheight=0 scrolling=no>"+
"<frame src=\"\" name=\"frTabs\" marginwidth=0 marginheight=0 scrolling=no>"+
"</frameset></frameset><plaintext>";
with (document) {
open("text/html","replace");
write(szHTML);
close();
}
fnBuildTabStrip();
}
function fnBuildTabStrip()
{
var szHTML=
"<html><head><style>.clScroll {font:8pt Courier New;color:"+c_rgszClr[6]+";cursor:default;line-height:10pt;}"+
".clScroll2 {font:10pt Arial;color:"+c_rgszClr[6]+";cursor:default;line-height:11pt;}</style></head>"+
"<body onclick=\"event.returnValue=false;\" ondragstart=\"event.returnValue=false;\" onselectstart=\"event.returnValue=false;\" bgcolor="+c_rgszClr[4]+" topmargin=0 leftmargin=0><table cellpadding=0 cellspacing=0 width=100%>"+
"<tr><td colspan=6 height=1 bgcolor="+c_rgszClr[2]+"></td></tr>"+
"<tr><td style=\"font:1pt\">&nbsp;<td>"+
"<td valign=top id=tdScroll class=\"clScroll\" onclick=\"parent.fnFastScrollTabs(0);\" onmouseover=\"parent.fnMouseOverScroll(0);\" onmouseout=\"parent.fnMouseOutScroll(0);\"><a>&#171;</a></td>"+
"<td valign=top id=tdScroll class=\"clScroll2\" onclick=\"parent.fnScrollTabs(0);\" ondblclick=\"parent.fnScrollTabs(0);\" onmouseover=\"parent.fnMouseOverScroll(1);\" onmouseout=\"parent.fnMouseOutScroll(1);\"><a>&lt</a></td>"+
"<td valign=top id=tdScroll class=\"clScroll2\" onclick=\"parent.fnScrollTabs(1);\" ondblclick=\"parent.fnScrollTabs(1);\" onmouseover=\"parent.fnMouseOverScroll(2);\" onmouseout=\"parent.fnMouseOutScroll(2);\"><a>&gt</a></td>"+
"<td valign=top id=tdScroll class=\"clScroll\" onclick=\"parent.fnFastScrollTabs(1);\" onmouseover=\"parent.fnMouseOverScroll(3);\" onmouseout=\"parent.fnMouseOutScroll(3);\"><a>&#187;</a></td>"+
"<td style=\"font:1pt\">&nbsp;<td></tr></table></body></html>";
with (frames['frScroll'].document) {
open("text/html","replace");
write(szHTML);
close();
}
szHTML =
"<html><head>"+
"<style>A:link,A:visited,A:active {text-decoration:none;"+"color:"+c_rgszClr[3]+";}"+
".clTab {cursor:hand;background:"+c_rgszClr[1]+";font:9pt Arial;padding-left:3px;padding-right:3px;text-align:center;}"+
".clBorder {background:"+c_rgszClr[2]+";font:1pt;}"+
"</style></head><body onload=\"parent.fnInit();\" onselectstart=\"event.returnValue=false;\" ondragstart=\"event.returnValue=false;\" bgcolor="+c_rgszClr[4]+
" topmargin=0 leftmargin=0><table id=tbTabs cellpadding=0 cellspacing=0>";
var iCellCount=(c_lTabs+1)*2;
var i;
for (i=0;i<iCellCount;i+=2)
szHTML+="<col width=1><col>";
var iRow;
for (iRow=0;iRow<6;iRow++) {
szHTML+="<tr>";
if (iRow==5)
szHTML+="<td colspan="+iCellCount+"></td>";
else {
if (iRow==0) {
for(i=0;i<iCellCount;i++)
szHTML+="<td height=1 class=\"clBorder\"></td>";
} else if (iRow==1) {
for(i=0;i<c_lTabs;i++) {
szHTML+="<td height=1 nowrap class=\"clBorder\">&nbsp;</td>";
szHTML+=
"<td id=tdTab height=1 nowrap class=\"clTab\" onmouseover=\"parent.fnMouseOverTab("+i+");\" onmouseout=\"parent.fnMouseOutTab("+i+");\">"+
"<a href=\""+document.all.item("shLink")[i].href+"\" target=\"frSheet\" id=aTab>&nbsp;"+c_rgszSh[i]+"&nbsp;</a></td>";
}
szHTML+="<td id=tdTab height=1 nowrap class=\"clBorder\"><a id=aTab>&nbsp;</a></td><td width=100%></td>";
} else if (iRow==2) {
for (i=0;i<c_lTabs;i++)
szHTML+="<td height=1></td><td height=1 class=\"clBorder\"></td>";
szHTML+="<td height=1></td><td height=1></td>";
} else if (iRow==3) {
for (i=0;i<iCellCount;i++)
szHTML+="<td height=1></td>";
} else if (iRow==4) {
for (i=0;i<c_lTabs;i++)
szHTML+="<td height=1 width=1></td><td height=1></td>";
szHTML+="<td height=1 width=1></td><td></td>";
}
}
szHTML+="</tr>";
}
szHTML+="</table></body></html>";
with (frames['frTabs'].document) {
open("text/html","replace");
charset=document.charset;
write(szHTML);
close();
}
}
function fnInit()
{
g_rglTabX[0]=0;
var i;
for (i=1;i<=c_lTabs;i++)
with (frames['frTabs'].document.all.tbTabs.rows[1].cells[fnTabToCol(i-1)])
g_rglTabX[i]=offsetLeft+offsetWidth-6;
}
function fnTabToCol(iTab)
{
return 2*iTab+1;
}
function fnNextTab(fDir)
{
var iNextTab=-1;
var i;
with (frames['frTabs'].document.body) {
if (fDir==0) {
if (scrollLeft>0) {
for (i=0;i<c_lTabs&&g_rglTabX[i]<scrollLeft;i++);
if (i<c_lTabs)
iNextTab=i-1;
}
} else {
if (g_rglTabX[c_lTabs]+6>offsetWidth+scrollLeft) {
for (i=0;i<c_lTabs&&g_rglTabX[i]<=scrollLeft;i++);
if (i<c_lTabs)
iNextTab=i;
}
}
}
return iNextTab;
}
function fnScrollTabs(fDir)
{
var iNextTab=fnNextTab(fDir);
if (iNextTab>=0) {
frames['frTabs'].scroll(g_rglTabX[iNextTab],0);
return true;
} else
return false;
}
function fnFastScrollTabs(fDir)
{
if (c_lTabs>16)
frames['frTabs'].scroll(g_rglTabX[fDir?c_lTabs-1:0],0);
else
if (fnScrollTabs(fDir)>0) window.setTimeout("fnFastScrollTabs("+fDir+");",5);
}
function fnSetTabProps(iTab,fActive)
{
var iCol=fnTabToCol(iTab);
var i;
if (iTab>=0) {
with (frames['frTabs'].document.all) {
with (tbTabs) {
for (i=0;i<=4;i++) {
with (rows[i]) {
if (i==0)
cells[iCol].style.background=c_rgszClr[fActive?0:2];
else if (i>0 && i<4) {
if (fActive) {
cells[iCol-1].style.background=c_rgszClr[2];
cells[iCol].style.background=c_rgszClr[0];
cells[iCol+1].style.background=c_rgszClr[2];
} else {
if (i==1) {
cells[iCol-1].style.background=c_rgszClr[2];
cells[iCol].style.background=c_rgszClr[1];
cells[iCol+1].style.background=c_rgszClr[2];
} else {
cells[iCol-1].style.background=c_rgszClr[4];
cells[iCol].style.background=c_rgszClr[(i==2)?2:4];
cells[iCol+1].style.background=c_rgszClr[4];
}
}
} else
cells[iCol].style.background=c_rgszClr[fActive?2:4];
}
}
}
with (aTab[iTab].style) {
cursor=(fActive?"default":"hand");
color=c_rgszClr[3];
}
}
}
}
function fnMouseOverScroll(iCtl)
{
frames['frScroll'].document.all.tdScroll[iCtl].style.color=c_rgszClr[7];
}
function fnMouseOutScroll(iCtl)
{
frames['frScroll'].document.all.tdScroll[iCtl].style.color=c_rgszClr[6];
}
function fnMouseOverTab(iTab)
{
if (iTab!=g_iShCur) {
var iCol=fnTabToCol(iTab);
with (frames['frTabs'].document.all) {
tdTab[iTab].style.background=c_rgszClr[5];
}
}
}
function fnMouseOutTab(iTab)
{
if (iTab>=0) {
var elFrom=frames['frTabs'].event.srcElement;
var elTo=frames['frTabs'].event.toElement;
if ((!elTo) ||
(elFrom.tagName==elTo.tagName) ||
(elTo.tagName=="A" && elTo.parentElement!=elFrom) ||
(elFrom.tagName=="A" && elFrom.parentElement!=elTo)) {
if (iTab!=g_iShCur) {
with (frames['frTabs'].document.all) {
tdTab[iTab].style.background=c_rgszClr[1];
}
}
}
}
}
function fnSetActiveSheet(iSh)
{
if (iSh!=g_iShCur) {
fnSetTabProps(g_iShCur,false);
fnSetTabProps(iSh,true);
g_iShCur=iSh;
}
}
window.g_iIEVer=fnGetIEVer();
if (window.g_iIEVer>=4)
fnBuildFrameset();
//-->
</script>
<![endif]><!--[if gte mso 9]><xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>examenrooster pre-syllabus</x:Name>
<x:WorksheetSource HRef="examenrooster%20pre-syllabus_files/sheet001.htm"/>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
<x:Stylesheet HRef="examenrooster%20pre-syllabus_files/stylesheet.css"/>
<x:WindowHeight>8676</x:WindowHeight>
<x:WindowWidth>23040</x:WindowWidth>
<x:WindowTopX>32767</x:WindowTopX>
<x:WindowTopY>32767</x:WindowTopY>
<x:ProtectStructure>False</x:ProtectStructure>
<x:ProtectWindows>False</x:ProtectWindows>
</x:ExcelWorkbook>
</xml><![endif]-->
</head>
<frameset rows="*,39" border=0 width=0 frameborder=no framespacing=0>
<frame src="examenrooster%20pre-syllabus_files/sheet001.htm" name="frSheet">
<frame src="examenrooster%20pre-syllabus_files/tabstrip.htm" name="frTabs" marginwidth=0 marginheight=0>
<noframes>
<body>
<p>This page uses frames, but your browser doesn't support them.</p>
</body>
</noframes>
</frameset>
</html>

View File

@ -0,0 +1,31 @@
import pandas as pd
def assign_exam_group(value):
mapping = {
"Hoofd versus hand: de waardering van ambacht en ambachtelijkheid herbekeken, 1500-2024": 6,
"De wereld van een koopman in de briefwisseling van Henri-François Schilders, tweede helft zeventiende eeuw": 1,
"Hoe overleef ik een revolutie? Huishoudens en hun overlevingsstrategieën in een tijd van polarisatie en verandering (1750-1850)": 5,
"Komt dat zien! Het theatrale uitgaansleven in België in de negentiende en vroege twintigste eeuw (1830-1930)": 4 ,
"Erfenisaangiften als venster op de Antwerpse samenleving, 1835 1912": 3,
"Sporen van gulden en franken. De geldzaken van huishoudens in de twintigste eeuw": 2,
# Add more mappings as needed
}
return mapping.get(value, 0) # Default to 0 if no match
def process_excel(file_path):
df = pd.read_excel(file_path, sheet_name="Sheet1")
if 'Groep' not in df.columns:
raise ValueError("Column 'Groep' not found in the Excel file.")
df['Examengroep'] = df['Groep'].apply(assign_exam_group)
output_file = "processed_" + file_path
df.to_excel(output_file, index=False)
print(f"Processed file saved as {output_file}")
if __name__ == "__main__":
process_excel("bascriptie groepen.xlsx")

View File

@ -128,4 +128,4 @@ def compare_roosters(base_file, comparison_file, output_file):
# Example usage:
compare_roosters('afgewerkte.xlsx', 'bages rooster voor s.xlsx', 'differences_output.xlsx')
compare_roosters('examenrooster post-syllabus.xlsx', 'examenrooster pre-syllabus.xlsx', 'differences_output.xlsx')

View File

@ -2,65 +2,53 @@ import pandas as pd
from datetime import datetime
import locale
file_path = 'bages rooster voor s.xlsx'
file_path = 'examenrooster pre-syllabus.xlsx'
sheet_name = 'rooster'
df = pd.read_excel(file_path, sheet_name=sheet_name)
date_ranges = {
(pd.Timestamp('2025-01-06'), pd.Timestamp('2025-01-12')): 16,
(pd.Timestamp('2025-01-13'), pd.Timestamp('2025-01-19')): 17,
(pd.Timestamp('2025-01-20'), pd.Timestamp('2025-01-26')): 18,
(pd.Timestamp('2025-01-27'), pd.Timestamp('2025-02-02')): 19,
# add more ranges as needed
(pd.Timestamp('2025-05-26'), pd.Timestamp('2025-06-01')): 36,
(pd.Timestamp('2025-06-02'), pd.Timestamp('2025-06-08')): 37,
(pd.Timestamp('2025-06-09'), pd.Timestamp('2025-06-15')): 38,
(pd.Timestamp('2025-06-16'), pd.Timestamp('2025-06-22')): 39,
(pd.Timestamp('2025-08-18'), pd.Timestamp('2025-08-24')): 48,
(pd.Timestamp('2025-08-25'), pd.Timestamp('2025-08-31')): 49,
(pd.Timestamp('2025-09-01'), pd.Timestamp('2025-09-06')): 50,
}
# Custom date parser function
def parse_custom_date(date_str):
if pd.isna(date_str):
return pd.NaT # Return pandas NaT for missing dates
return pd.NaT
if isinstance(date_str, pd.Timestamp):
return date_str
if isinstance(date_str, str):
try:
# Set locale to Dutch
locale.setlocale(locale.LC_TIME, 'nl_NL.UTF-8')
return datetime.strptime(date_str, '%A %d %B %Y')
except ValueError as e:
raise ValueError(f"Date conversion error: {e} for date string: {date_str}")
finally:
# Reset locale to the default setting
locale.setlocale(locale.LC_TIME, 'C')
else:
raise TypeError(f"Expected string, got {type(date_str).__name__}: {date_str}")
raise TypeError(f"Expected string or Timestamp, got {type(date_str).__name__}: {date_str}")
def update_lesweek(date):
if pd.isna(date):
return 0
for date_range, lesweek_value in date_ranges.items():
if date_range[0] <= date <= date_range[1]:
return lesweek_value
return 0
# Ensure the column 'Datum S+' exists and is processed correctly
if 'Datum S+' in df.columns:
if 'Datum' in df.columns:
try:
# Convert 'Datum S+' column to datetime using the custom parser
df['Datum S+'] = df['Datum S+'].apply(parse_custom_date)
df['Datum'] = df['Datum'].apply(parse_custom_date)
print(df['Datum'].apply(type).value_counts()) # Debug: print types after parsing
except (ValueError, TypeError) as e:
print(f"Error: {e}")
# Optionally, re-raise the exception if you want to stop execution
raise
df['Lesweek'] = df['Datum'].apply(update_lesweek)
# Function to update Lesweek based on date ranges
def update_lesweek(date):
if pd.isna(date): # Handle NaT values
return 0
for date_range, lesweek_value in date_ranges.items():
if date_range[0] <= date <= date_range[1]:
return lesweek_value
return 0 # Default value if date doesn't fall in any range
# Apply the function to 'Datum S+' column
df['Lesweek'] = df['Datum S+'].apply(update_lesweek)
# Check the results
print("\nFirst few rows of the DataFrame to verify date formatting:\n", df.head())
# If needed, you can save the DataFrame to a new Excel file to verify changes
df.to_excel('updated_rooster.xlsx', index=False)