Warning: include_once(/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php): failed to open stream: No such file or directory in /var/www/html/fields/dbp09/local/config.php on line 4

Warning: include_once(): Failed opening '/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php' for inclusion (include_path='.:/opt/php/lib/php') in /var/www/html/fields/dbp09/local/config.php on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fields/dbp09/local/config.php:4) in /var/www/html/pmwiki-2.2.86/pmwiki.php on line 1250
Datenbankpraktikum SS 2009 - Gruppe 3 - Pruefungsverwaltung

Klausur- und Übungsblattverwaltung

von Katharina Röhr und Dominik Abraham

Inhalt:

Prüfungsmodel

Klausuren und Übungsblätter werden gemeinsam in einem Model namens 'Prüfung' verwaltet. Die Unterscheidung zwischen Übungsblättern und Klausuren findet durch ein Attribut 'Typ' statt, das entweder auf 'U' oder 'K' steht. Datenbankseitig ist dieses Attribut ein Enumerator mit diesen beiden Werten. Das Model enthält

  • Typ, Veranstaltungsschlüssel und Nummer
  • Datum
  • eine Aufgabenliste

der Prüfung.

Das Aufgabenmodel ist vom Prinzip her eine Wrapperklasse für eine Zahl, da sie ausser ihrem Primärschlüssel nur die Punktzahl für diese Aufgabe verwaltet. Es enthält die Standardmethoden zum Konstruieren und Verändern. Von der Benutzung ist die meiste Funktionalität über das Prüfungsmodel erreichbar, Zugriffe auf die Datenbank über insert, update und delete werden an alle Aufgaben zu der Prüfung weitergeleitet. Da Teile des Aufgabenschlüssels den Prüfungsschlüssel darstellen, und in der Datenbank ON DELETE CASCADE gesetzt wurde, wirken sich die Löschoperationen sogar automatisch auf die Aufgaben aus.

Das Prüfungsmodel ist wie auch die für Aufgaben und Notenschlüssel als kurzlebig und unabhängig von der Datenbank konzipiert, die Models werden aus den Datenbankwerten oder manuell konstruiert und können geändert werden, ohne dass es Auswirkungen auf die Datenbank hat. Die Änderungen an der Datenbank werden erst mit bestimmten Methoden angestoßen. Nach Benutzung werden die Models wieder gelöscht. Will man dann etwas ändern, muss man ein neues Model erstellen, um es wie schon zuvor beschrieben, zu benutzen.

Nach oben

Methoden des Models:
  • Erstellen einer Prüfung aus den Daten
  • Sich für eine Prüfung die maximale Aufgabenzahl, für die schon Punkte eingetragen sind, holen lassen
  • Eine Prüfung mit dem angegebenen Schlüssel aus der Datenbank holen
  • Sich alle Prüfungen in einer bestimmten Veranstaltung holen
    • Oder nur eine spezielle Prüfungsart holen
  • Nachfragen, ob eine Prüfung zu einem bestimmten Schlüssel existiert
  • Eine Auflistung aller Prüfungen aus der Datenbank holen (wird wohl nicht gebraucht, wenn die Datenbank zu viele Prüfungen enthält)
  • Eine neue Aufgabe zu der Prüfung hinzufügen
    • Oder ein Array von Aufgaben
  • Datenbankfunktionen:
    • Prüfung in die Datenbank schreiben
    • Daten in der Datenbank aktualisieren
    • Prüfung aus der Datenbank löschen
  • Getter und Setter der Klasse sind so überladen,
    • dass man die Aufgabenliste durch das Attribut 'Aufgaben' verändern kann ('Aufgaben' steht für die Anzahl der Aufgaben)
      • Verkleinern des Attributs 'Aufgaben' schneidet die Liste zurecht
      • Vergrößern fügt Dummy-Aufgaben mit 0 Punkten ein
    • dass man sich auch ein Attribute holen kann wie
      • 'fix' gibt die maximale Aufgabennummer zurück, für die schon Punkte eingetragen sind
      • 'Aufgaben', Gebrauch siehe oben
      • 'Punkte' die maximale Punktzahl dieser Prüfung

Nach oben

Implementation der Getter- und Setter-Methode

Die folgenden Quelltexte sind gekürzt und der Übersichtlichkeit halber in einem lesbareren Code verfasst. Die Funktion des echten Programms ist allerdings die gleiche.

Überladener Setter

Auch der Setter prüft, ob das angegebene Attribut existiert. Wenn es existiert und kein Schlüssel ist, wird es auf den übergebenen Wert gesetzt. Wenn der Name unbekannt war, wird geprüft, ob der Name 'Aufgaben' heißt. Wenn es so ist, wird die Aufgabenliste entsprechend verändert. Ist der übergebene Wert kleiner als die alte Listenlänge, werden entsprechend viele Elemente am Ende der Liste gelöscht, ist er größer, werden Aufgaben mit 0 Punkten angehängt.

function __set($property, $value) {
  if (array_key_exists($property, $this->properties)){
    if (gehört_zum_Schlüssel($property)) fehler("Schlüssel dürfen nicht editiert werden.");
 
    $this->properties["$property"] = $value;			
  }
  elseif ($property = 'Aufgaben') {
    if ($this->fix > $value)
      fehler("Sie löschen Aufgaben, für die bereits Punkte eingetragen wurden. ");
 
    // loesche alle Aufgaben mit hoeherer Nummer
    $Aufgabenzahl = count($this->Aufgabenliste);
    for($i = $value; $i < $Aufgabenzahl; $i++){
      loesche($this->Aufgabenliste[$i]);	  
    }
 
    // Fuege Dummy-Aufgaben ein
    for($i = $Aufgabenzahl + 1; $i <= $value; $i++){
      $this->addAufgabe(new Aufgabe(array('AufgNr' => $i, 'Punkte' => 0) ,$this->env));
    } 
  } else {
    fehler('Pruefung->__set: Attribut '.$property.' existiert nicht!');
  }
}

Nach oben


Überladener Getter

Der Getter prüft zunächst ab, ob sich der übergebene Name als Index im property-Array befindet. Ist dies der Fall, wird es zurückgegeben. Ansonsten wird auf andere Attributnamen getestet, und zwar auf 'Aufgaben', 'Punkte', 'fix'. 'Aufgaben' gibt die Aufgabenzahl zurück, 'Punkte' die kumulierte Punktzahl, 'fix' gibt eine Zahl zurück, an Hand derer man prüfen kann, ob an der Prüfung etwas verändert werden darf. Sie beträgt entweder die maximale Aufgabennummer, für die Punkte eingetragen sind, oder ist gleich -1, falls diese Prüfung nicht die letzte ihres Typs ist. Die Aufgaben dürfen nur oberhalb dieser Grenze verändert werden, und die Prüfung darf nur gelöscht werden, wenn fix genau 0 beträgt.

function __get($property) {
  if(array_key_exists($property, $this->properties)) {
    return $this->properties[$property];
 
  } elseif ($property == 'Aufgaben') {            // Pseudoattribut 'Aufgaben'
    return count($this->Aufgabenliste);
 
  } elseif ($property == 'Punkte') {              // Pseudoattribut 'Punkte'
    $sum = 0;
    foreach($this->Aufgabenliste as $aufg)
      $sum += $aufg->Punkte;
    return $sum;
 
  } elseif ($property == 'fix') {                 // Pseudoattribut 'fix' um zu wissen,
    return $this->eintraege;                      //  ob editiert werden darf
 
  } else {
    throw new TuksException('Key '.$property.' not found!');
  }
}

Nach oben

Prüfungsverwaltung:

Pruefung_Controller.php:

Die Klasse Pruefung_Controller erweitert die Klasse Controller und verwaltet Prüfungen. Da die Aufgaben nur die Punktzahlen zu speichern haben, ist kein Aufgaben_Controller vorhanden, alle Operationen an Aufgaben sind komplett im Pruefung_Controller eingebettet. Ausser den action_-Methoden hat diese Klasse auch noch einige Methoden, um Wiederholungen von häufigen Quelltextausschnitten zu vermeiden:

  • Die Methode req liest aus dem $_REQUEST-Array eine Variable aus, wenn sie gesetzt ist (siehe Notenschlüsselcontroller).
  • Die Methode getPruefung liest aus dem $_REQUEST-Array den Primärschlüssel einer Prüfung aus und holt diese dann aus der Datenbank.
  • Die Methode VerName gibt den Namen einer übergebenen Veranstaltung zurück.
  • Die Methoden canedit, istutor geben für die jeweiligen Rechte Editierrecht oder Tutorrecht zurück, ob der eingeloggte User diese Rechte hat.
  • Die Methode get_ergebnisse holt die Ergebnisse des eingeloggten Users zu einer bestimmten Prüfung aus der Datenbank.
  • Die Methode getTypName gibt zu den übergebenen Werten 'K' oder 'U' den vollständig ausgeschriebenen Namen 'Klausur' oder 'Übungsblatt' zurück.
  • Die Methode info zeigt ein Info- oder Fehlerfenster mit einer übergebenen Nachricht an.

Die restlichen Methoden sind 'actions', die durch Formulare oder Menüpunkte aufgerufen werden und entweder nur Formulare befüllen oder Daten empfangen und Änderungen verwalten und die Ergebnisse als html-Formular zurückgeben.

Views:

Die Templates sind so angelegt, dass sie oft über boolsche Variablen steuerbar sind, z.B. um die Möglichkeiten zum Löschen oder Ändern je nach Rechten des Users an- oder auszuschalten. Ausserdem werden meist ganze Objekte an die Variablen zugewiesen, sodass man mehrere Informationen über Klassenattribute erzeugen kann. Dabei werden auch die durch die überladenen __get()- und __set()Methoden realisierten Pseudoattribute benutzt, um häufig benutzte Berechnungen an die Models auszulagern.

Beispiel aus 'pruefung_show.tpl': Wenn jemand die Berechtigung zum Löschen hat, wird ein Löschbutton ('delete.png') angezeigt. Wenn die Prüfung nicht gelöscht werden darf (überprüft durch das Pseudoattribut fix), ist der Button grau eingefärbt ('delete_disabled.png'). Die Linkadresse für den Löschbutton wird mit Informationen aus dem Prüfungsobjekt vervollständigt.

{if ($darf_löschen)}
  {if ($pruefung->fix == 0)}
    <a href="index.php?controller=pruefung&action=loeschen&typ={$pruefung->Typ}&verid={$pruefung->VerID}&nr={$pruefung->Nr}">
      <img src="images/delete.png" alt="Löschen" style="border:0;">
    </a>
  {else}
      <img src="images/delete_disabled.png" alt="Löschen" style="border:0;">
  {/if}
{/if}

Für das Anlegen und Editieren der Daten stehen dabei jeweils 2 actions bereit, die erste gibt ein Formular zum Eingeben der Daten zurück, die zweite wird von dem Formular aufgerufen und setzt die Änderungen oder neuen Prüfungen in der Datenbank fest. Anschließend wird ein html-konformes Informationsfenster erzeugt und daran eine Ansicht der Daten angehängt. Beides wird zurückgegeben, sodass das Infofenster über der aktuellen Ansicht erscheint.

Ist beim Ändern der Daten ein Fehler aufgetreten, etwa fehlerhafte Werte, wird anstatt des Informationsfensters ein Fehlerfenster erzeugt und statt der Ansicht erneut das Änderungsformular angezeigt.

Man kann einerseits die Daten der Prüfung, wie etwa das Datum oder die Aufgabenzahl, oder auch die Punktzahlen der Aufgabenliste ändern. Beides sind getrennte Formulare, da es möglich ist, für eine Prüfung, für die schon Punkte eingetragen wurden, die Daten im Nachhinein zu ändern, die Aufgabenliste kann jedoch nur an den Aufgaben verändert werden, für die noch keine Punkte eingetragen wurden.

Es ist nur möglich, Prüfungen zu löschen, wenn keine nachfolgende Prüfung existiert, oder wenn bereits Punkte für diese Prüfung eingetragen wurden.

Nach oben


Verwaltungsoberfläche

Die Prüfungsverwaltung besteht aus mehreren Oberflächen, von denen aus man die Eigenschaften der Prüfungen kontrollieren und bearbeiten kann. Ausgangspunkt für die Verwaltung ist die Liste aller Prüfungen zu einer Veranstaltung.

Prüfungsliste:

Dazu muss man die Veranstaltung im Seitenmenü ausgewählt haben. Die Liste zeigt die Klausuren und Übungsblätter einer Vorlesung getrennt an und informiert über die Nummer der Prüfung, das Datum, Aufgabenzahl und die maximale Punktzahl der Prüfung an.

Unter den Optionen kann man sich eine Detailansicht der Prüfung zeigen lassen. Für Dozenten und Übungsleiter stehen zusätzlich noch Möglichkeiten zur Verfügung, Prüfungen zu bearbeiten oder zu löschen. Ein Link unter der Auflistung führt zu dem Erstellen von neuen Klausuren/Übungsblättern.

Nach oben

Dateneingaben:

Für das Erstellen von Prüfungen, das Bearbeiten und das Setzen der Aufgabenlisten gibt es mehrere Formulare, in denen man die Daten zum Setzen und Bearbeiten eingeben kann. Über Buttons am unteren Ende kann man die Daten absenden bzw. das Formular auf Standardwerte zurücksetzen. Kleine grafische Buttons führen aus den Formularen heraus. Ein kleiner grüner Pfeil nach links bedeutet dabei, dass man zurück zur Prüfungsliste gelangt. Ein kleines blaues 'i' führt zur Detailansicht. In beiden Fällen werden eingegebene Daten nicht übernommen.

Natürlich ist es nicht möglich, wesentliche Informationen zu einer Prüfung zu ändern, wie etwa den Typ, die zugehörige Veranstaltung oder die Prüfungsnummer. Änderungen an diesen Daten würden zu Inkonsistenzen in der Datenbank (zum Beispiel doppelte Prüfungsnummern) und zu unvorhersagbarem Verhalten von TuKS führen. Bei der Eingabe eines Datums kommen als EyeSugar Textfelder zum Einsatz, die beim Versuch, sie zu beschreiben, einen Kalender oder ein Feld mit Uhrzeiten aufklappen, über die Datum und Uhrzeit ausgeählt werden müssen. Zu beachten ist hierbei, dass die Uhrzeit mit am bw. pm versehen ist, und "12:00 am" Mitternacht und "12:00 pm" Mittag bedeutet.

Fehlerhafte Eingaben werden in einem Fehlerfenster gemeldet und sorgen dafür, dass man das Formular erneut ausfüllen muss.

Nach oben

Die Detailansicht:

In der Detailansicht werden alle Daten einer Klausur oder eines Übungsblattes übersichtlich dargestellt. Die Aufgabenliste ist komplett mit Aufgabennummern und maximal erreichbaren Punktzahlen angezeigt. Ein kleiner grüner Pfeil am unteren Ende der Ansicht führt zurück zu einer Liste aller Übungsblätter und Klausuren dieser Veranstaltung.

Wer Berechtigung zum Ändern einer Prüfung hat, also ein Übungsleiter oder Dozent ist, findet in der Detailansicht zusätzlich noch grafische Buttons zum Bearbeiten oder Löschen einer Prüfung. Insgesamt kommen an drei Stellen neue Buttons hinzu (siehe rote Rahmen): Rechts neben der Aufgabenliste ein Editiersymbol, um die Aufgabenliste zu bearbeiten, unter der Ansicht statt des "Zurück zur Liste"-Buttons ein kleines Menü und darunter ein Link, um Punkte einzutragen, falls man die Berechtigung dafür hat.

Abb. 1:Detailansicht einer Klausur, für die der der eingeloggte User Berechtigung zum Ändern hat.

Im Menü hat man vier Menüpunkte zur Auswahl:
Ein grüner Pfeil:Zurück zur Aufgabenliste
Ein Stift auf einem Blatt Papier:Die gesamte Prüfung bearbeiten
Ein Notenschlüssel:Notenschlüssel ansehen
 (dieser Punkt ist nur bei Klausuren vorhanden)
Ein Kreuz auf rotem Grund:Die Prüfung löschen

Abb. 2:Menü zum Bearbeiten einer Prüfung

Wer bereits an einer Klausur teilgenommen hat, findet nach dem Eintragen der Punkte eine Detailansicht vor, die ihm zusätzlich zu den üblichen Informationen seine Ergebnisse an Hand einzelner Punktzahlen und die Note darstellt. Diese Zusatzansicht wird durch die Methode action_anhang im Notenschluessel_Controller erstellt.

Abb. 3:Detailansicht einer Klausur, in der der eingeloggte User Punkte hat.

Nach oben

Notenschlüssel

Der Notenschlüssel einer Klausur trägt die Note (von 1.0 bis 5.0) gegen die maximale Punktzahl auf, für die man noch diese Note erhalten würde. Durch ihn lässt sich aus den eingetragenen Ergebnissen automatisch eine Note berechnen.

Das Model zum Notenschlüssel kann aus einer Prüfung einen Standardnotenschlüssel berechnen. Die zugehörige Prüfung wird dem Konstruktor übergeben.

// Array mit Standardprozentzahlen
// da php keine floats als Arrayindices erlaubt,
// werden die Noten * 10 als Key genommen 
 
private $std_steps = array(10 => 100,
                           13 => 91,
                           17 => 84,
                           20 => 80,
                           23 => 76,
                           27 => 72,
                           30 => 68,
                           33 => 64, 
                           37 => 60,
                           40 => 56,
                           50 => 49);
protected $steps = array();
 
function __construct(Pruefung $pruefung, $env) {
  parent::__construct($env);
 
  $Punktzahl = $pruefung->Punkte;
  foreach($this->std_steps as $note => $punkte){
    $this->steps[$note] = round(($punkte * $Punktzahl) / 100);
  }
  sortieren_nach_Schlüssel($this->steps);
}

Daneben stellt das Model noch andere Methoden zur Verfügung, u.a.:

  • function exists($VerID, $Nr, $env): Prüft, ob es zu dem angebenen Primärschlüssel einen Notenschlüssel in der Datenbank gibt.
  • function insert(): Schreibt den Notenschlüssel in die Datenbank
  • function update(): Aktualisiert den Notenschlüssel in der Datenbank
  • function check(): Prüft den Notenschlüssel auf Konsistenz und gibt einen entsprechenden Wahrheitswert zurück. Es wird geprüft, ob alle Punktzahlen zwischen 0 und der maximalen Punktzahl der Prüfung sind, und ob wirklich die Punktzahlen für bessere Noten monton ansteigen.
  • function __get($property) ist wieder so überladen, dass man auf zusätzliche Pseudoattribute zugreifen kann.
    • $notenschluessel->Note23 gibt beispielsweise die Punktzahl für die Note 2,3 zurück.
    • $notenschluessel->Array gibt ein Array der Bauart {"1.0" => xy, "1.3" => xyz} zurück, wobei jeweils die Note als String auf die maximale Punktzahl für diese Note abgebildet wird.

Nach oben

Notenschlüsselcontroller

Ein paar Methoden zur Übersicht

  • Die function __construct($env) ist der Konstruktor der Klasse Notenschluessel_Controller
  • Die function req($attr, $default = false) gibt eine Variable aus dem Request-Array zurück, sonst ein Defaultwert
  • Die function getNotenschluessel() gibt aus dem Schlüssel, der per $_REQUEST übergeben wurde, den passenden Notenschlüssel zurück
  • Die function action_speichern() legt eine neue Prüfung an und schreibt sie in die Datenbank
  • Die function action_zuruecksetzen() ersetzt den Notenschlüssel der Klausur durch einen automatisch erzeugten Standard-Notenschlüssel. Dies ist mit einem Funktionsaufruf der Prüfungsklasse getan.
$pr->stdNotenschluessel(true); // der übergebene Wert 'wahr' bedeutet, alte Notenschlüssel werden überschrieben
  • Die function action_anhang($ergebnisse) generiert einen Anhang, um unter einer Prüfung den Notenschlüssel samt Ergebnissen anzuzeigen. Die Ergebnisse werden aufsummiert und als Gesamtpunktzahl und Endnote dargestellt.
if ($ergebnisse) {
     $punkte = array_sum($ergebnisse);		
     $this->env->templateEngine()->assign('allePunkte', $punkte);
     $this->env->templateEngine()->assign('endnote', $Notenschluessel->getNote($punkte));
   }
   return $this->env->templateEngine()->fetch('notenschluessel_anzeigen.tpl');
  • Die function canedit gibt an, ob der Benutzer berechtigt ist, Notenschlüssel anzulegen oder zu ändern
function canedit(){
     return anzahl_elemente(
       schnittmenge(
       $this->meine_rollen(), 
       	$this->editors)
	) != 0;
	           }

Der Notenschlüsselcontroller implementiert die Funktionalitäten zum Ansehen und Ändern von Notenschlüsseln, analog zu den Prüfungen. Die Formulare haben dabei das gleiche Aussehen, die Erfahrungen mit der Prüfungsverwaltung können also direkt auf die Notenschlüsselverwaltung übertragen werden.

Nach oben


Page last modified on September 05, 2009, at 05:58 PM