Von 3-Star nach 5-Star#

5-Star:

Dieses Notebook: Wir haben CSV-Dateien (3 star), wollen nach 5 star gehen.

Testdaten erzeugen#

Anfrage an Google.AI

Ich benötige einige CSV-Dateien. Domäne: Prüfungsplanung Hochschule, Fakultät Informatik.

Studiengänge: Wirtschaftsinformatik WIF, Digitales Verwaltungsmanagement DVM, Automobilinformatik AIF, Kerninformagtik IF, Künstliche Intelligenz KI.

Dozenten: BUJ, NAZ, OSC, WUJ

Insgesamt 10 Fächer.

In jedem Studiengang gibt es ein eigenes Modul mit dem gleichen Titel "Prog 1"; sonst überschneiden sich die Fächer nicht.

BUJ und WUJ unterrichten beide in den Studiengängen WIF und DVM.
Studierende aus WIF und DVM melden sich nur für Prüfungen aus WIF oder DVM an (gemischt).

NAZ unterrichtet in den Studiengängen IF und AIF.
Studierende aus AIF und IF melden sich nur für Prüfungen aus diesen Studiengängen an. 

OSC unterrichtet in KI.
KI-Studierende melden sich nur  KI-Module an.


Tabelle "Dozent"
Dozent-ID;Name

Tabelle "Modul"
Modul_ID;Modultitel;Studiengang;Prüfungssemester

Tabelle "unterrichtet"
Dozent-ID;Modul_ID

Tabelle "Student"
MatNr;Studiengang_ID;Fachsemester

Tabelle "Pruefungsanmeldung"
MatNr;Pruefungs_ID

Kontext herstellen#

Wir werden mehrere CSV-Dateien benötigen. Wir halten den Code in einem Dict fest, die Schlüssel sind dann die Dateinamen.

csv = {}

Antwort Google.AI, 2026-05-04 T 12:26#

Hier sind die gewünschten CSV-Daten, strukturiert nach deinen Vorgaben. Ich habe die 10 Fächer so verteilt, dass die Logik der Dozenten und Studiengänge gewahrt bleibt.

1. Dozent.csv#

csv["Dozent"] = """Dozent-ID;Name
BUJ;Prof. BUJ
NAZ;Prof. NAZ
OSC;Prof. OSC
WUJ;Prof. WUJ
""" 
#with open("Dozent.csv","w") as f:
#    f.write(csv["Dozent"])

with open(“abc.html”, “w”) as f: f.write( “”” Hallo Welt! ””” )

2. Modul.csv#

Hinweis: “Prog 1” existiert für jeden Studiengang als eigenes Modul.

csv["Modul"] = """Modul_ID;Modultitel;Studiengang;Prüfungssemester
MOD01;Prog 1;WIF;1
MOD02;Prog 1;DVM;1
MOD03;Prog 1;AIF;1
MOD04;Prog 1;IF;1
MOD05;Prog 1;KI;1
MOD06;Datenbanken;WIF;2
MOD07;E-Government;DVM;2
MOD08;Bussysteme;AIF;2
MOD09;Theoretische Informatik;IF;2
MOD10;Machine Learning;KI;2
"""

3. unterrichtet.csv#

csv["unterrichtet"] = """Dozent-ID;Modul_ID
BUJ;MOD01
BUJ;MOD06
WUJ;MOD02
WUJ;MOD07
NAZ;MOD03
NAZ;MOD04
NAZ;MOD08
NAZ;MOD09
OSC;MOD05
OSC;MOD10
"""

4. Student.csv#

Beispielhafte Matrikelnummern für die Gruppen.

csv["Student"] = """MatNr;Studiengang_ID;Fachsemester
1001;WIF;1
1002;DVM;1
1003;AIF;1
1004;IF;1
1005;KI;1
"""

5. Pruefungsanmeldung.csv#

Berücksichtigt die gemischten Anmeldungen für WIF/DVM und AIF/IF sowie die Exklusivität von KI.

csv["Pruefungsanmeldung"] = """MatNr;Pruefungs_ID
1001;MOD01
1001;MOD02
1002;MOD02
1002;MOD06
1003;MOD03
1003;MOD09
1004;MOD04
1004;MOD08
1005;MOD05
1005;MOD10
"""
csv
{'Dozent': 'Dozent-ID;Name\nBUJ;Prof. BUJ\nNAZ;Prof. NAZ\nOSC;Prof. OSC\nWUJ;Prof. WUJ\n',
 'Modul': 'Modul_ID;Modultitel;Studiengang;Prüfungssemester\nMOD01;Prog 1;WIF;1\nMOD02;Prog 1;DVM;1\nMOD03;Prog 1;AIF;1\nMOD04;Prog 1;IF;1\nMOD05;Prog 1;KI;1\nMOD06;Datenbanken;WIF;2\nMOD07;E-Government;DVM;2\nMOD08;Bussysteme;AIF;2\nMOD09;Theoretische Informatik;IF;2\nMOD10;Machine Learning;KI;2\n',
 'unterrichtet': 'Dozent-ID;Modul_ID\nBUJ;MOD01\nBUJ;MOD06\nWUJ;MOD02\nWUJ;MOD07\nNAZ;MOD03\nNAZ;MOD04\nNAZ;MOD08\nNAZ;MOD09\nOSC;MOD05\nOSC;MOD10\n',
 'Student': 'MatNr;Studiengang_ID;Fachsemester\n1001;WIF;1\n1002;DVM;1\n1003;AIF;1\n1004;IF;1\n1005;KI;1\n',
 'Pruefungsanmeldung': 'MatNr;Pruefungs_ID\n1001;MOD01\n1001;MOD02\n1002;MOD02\n1002;MOD06\n1003;MOD03\n1003;MOD09\n1004;MOD04\n1004;MOD08\n1005;MOD05\n1005;MOD10\n'}

CSV schreiben#

for datname in csv.keys():
    print(datname)

    with open( datname+".csv", "w") as f:
        f.write( csv[ datname ] )
Dozent
Modul
unterrichtet
Student
Pruefungsanmeldung

CSV lesen#

Aus Python 101: siehe https://www.jbusse.de/python-101/woche_07.html#csv-datei-mit-pandas-einlesen

import pandas as pd
module_df =  pd.read_csv( "Modul.csv", delimiter=";"  )
module_df
Modul_ID Modultitel Studiengang Prüfungssemester
0 MOD01 Prog 1 WIF 1
1 MOD02 Prog 1 DVM 1
2 MOD03 Prog 1 AIF 1
3 MOD04 Prog 1 IF 1
4 MOD05 Prog 1 KI 1
5 MOD06 Datenbanken WIF 2
6 MOD07 E-Government DVM 2
7 MOD08 Bussysteme AIF 2
8 MOD09 Theoretische Informatik IF 2
9 MOD10 Machine Learning KI 2
# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html
module_df.to_dict(orient="index")
{0: {'Modul_ID': 'MOD01',
  'Modultitel': 'Prog 1',
  'Studiengang': 'WIF',
  'Prüfungssemester': 1},
 1: {'Modul_ID': 'MOD02',
  'Modultitel': 'Prog 1',
  'Studiengang': 'DVM',
  'Prüfungssemester': 1},
 2: {'Modul_ID': 'MOD03',
  'Modultitel': 'Prog 1',
  'Studiengang': 'AIF',
  'Prüfungssemester': 1},
 3: {'Modul_ID': 'MOD04',
  'Modultitel': 'Prog 1',
  'Studiengang': 'IF',
  'Prüfungssemester': 1},
 4: {'Modul_ID': 'MOD05',
  'Modultitel': 'Prog 1',
  'Studiengang': 'KI',
  'Prüfungssemester': 1},
 5: {'Modul_ID': 'MOD06',
  'Modultitel': 'Datenbanken',
  'Studiengang': 'WIF',
  'Prüfungssemester': 2},
 6: {'Modul_ID': 'MOD07',
  'Modultitel': 'E-Government',
  'Studiengang': 'DVM',
  'Prüfungssemester': 2},
 7: {'Modul_ID': 'MOD08',
  'Modultitel': 'Bussysteme',
  'Studiengang': 'AIF',
  'Prüfungssemester': 2},
 8: {'Modul_ID': 'MOD09',
  'Modultitel': 'Theoretische Informatik',
  'Studiengang': 'IF',
  'Prüfungssemester': 2},
 9: {'Modul_ID': 'MOD10',
  'Modultitel': 'Machine Learning',
  'Studiengang': 'KI',
  'Prüfungssemester': 2}}
# andere Darstellung z.B.
# module_df.to_dict(orient="list")

Turtle erzeugen#

# so sieht ein einzelner Record aus "Module" aus:
zeile = {'Modul_ID': 'MOD01',
  'Modultitel': 'Prog 1',
  'Studiengang': 'WIF',
  'Prüfungssemester': 1}
# Welchen Typ haben die einzelnen Zeilen?
Entity = [ "Studiengang" ]
Number = [ "Prüfungssemester" ]

ergebnis = []

# wegen Übersichtlichkeit nur die ersten 3 Zeilen
for zeilennummer, zeile in module_df[0:3].to_dict(orient="index").items():

    #print(f"\n# {zeilennummer=}, {zeile=}")

    # darüber wollen wir eine Aussage machen
    subjekt = zeile["Modul_ID"]
    #print(f"# Zeile {zeilennummer}: {subjekt=}")
    
    for k, v in zeile.items():
        #print(k, ":" , v)

        # haben wir eine ressource?
        if k in Entity:
            ttl = f"ex:{subjekt} ex:hat_{k} ex:{v} ."

        # oder haben wir ein Liteal vom Typ Number?
        elif k in Number:
            ttl = f"ex:{subjekt} ex:hat_{k} {v} ."

        # Wenn wir nicht wissen, was wir haben,
        # bauen ein Literal vom Typ String
        else:
            ttl = f"""ex:{subjekt} ex:hat_{k} "{v}" ."""
        #print(ttl)
        ergebnis.append( ttl )        
    
    #print()
    
# das haben wir gebaut
turtlestring = "\n".join(ergebnis)

# Präfix definieren
turtlestring = "\n@prefix ex: <https://www.example.com#> . \n" + turtlestring 
print(turtlestring)
@prefix ex: <https://www.example.com#> . 
ex:MOD01 ex:hat_Modul_ID "MOD01" .
ex:MOD01 ex:hat_Modultitel "Prog 1" .
ex:MOD01 ex:hat_Studiengang ex:WIF .
ex:MOD01 ex:hat_Prüfungssemester 1 .
ex:MOD02 ex:hat_Modul_ID "MOD02" .
ex:MOD02 ex:hat_Modultitel "Prog 1" .
ex:MOD02 ex:hat_Studiengang ex:DVM .
ex:MOD02 ex:hat_Prüfungssemester 1 .
ex:MOD03 ex:hat_Modul_ID "MOD03" .
ex:MOD03 ex:hat_Modultitel "Prog 1" .
ex:MOD03 ex:hat_Studiengang ex:AIF .
ex:MOD03 ex:hat_Prüfungssemester 1 .
# ! pip install rdflib 
import rdflib
# turtlestring als RDF Graph parsen
g = rdflib.Graph().parse( data=turtlestring )
# und die intererne Repräsentation wieder ausgeben
print( g.serialize(format="ttl") )
@prefix ex: <https://www.example.com#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:MOD01 ex:hat_Modul_ID "MOD01" ;
    ex:hat_Modultitel "Prog 1" ;
    ex:hat_Prüfungssemester 1 ;
    ex:hat_Studiengang ex:WIF .

ex:MOD02 ex:hat_Modul_ID "MOD02" ;
    ex:hat_Modultitel "Prog 1" ;
    ex:hat_Prüfungssemester 1 ;
    ex:hat_Studiengang ex:DVM .

ex:MOD03 ex:hat_Modul_ID "MOD03" ;
    ex:hat_Modultitel "Prog 1" ;
    ex:hat_Prüfungssemester 1 ;
    ex:hat_Studiengang ex:AIF .

https://rdflib.readthedocs.io/en/7.1.1/intro_to_sparql.html

# Eine CONSTRUCT-Abfrage definiert das Muster des Ergebnis-Graphen
query = """
CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    ?s ?p ?o .
    FILTER(isLITERAL(?o)) # auch: isIRI(?o)
}
"""

# Das Ergebnis von g.query() ist bei CONSTRUCT direkt ein rdflib.Graph
neuer_graph = g.query(query).graph
print( neuer_graph.serialize(format="ttl") )
@prefix ns1: <https://www.example.com#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ns1:MOD01 ns1:hat_Modul_ID "MOD01" ;
    ns1:hat_Modultitel "Prog 1" ;
    ns1:hat_Prüfungssemester 1 .

ns1:MOD02 ns1:hat_Modul_ID "MOD02" ;
    ns1:hat_Modultitel "Prog 1" ;
    ns1:hat_Prüfungssemester 1 .

ns1:MOD03 ns1:hat_Modul_ID "MOD03" ;
    ns1:hat_Modultitel "Prog 1" ;
    ns1:hat_Prüfungssemester 1 .