<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>GWT BASIERTES SYSTEM ZUR AUTOMATISCHEN BEWERTUNG VON PROGRAMMIERAUFGABEN</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Daniel Eggert und Eike Clas Schulze</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Institut für Kartographie und Geoinformatik</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Nutzung bestehender Authentifizierungsmechanismen Vollautomatische Bewertung der Programmieraufgabe o Kompilierung des Quelltextes o Verifizierung des geforderten Modells o Verifizierung der geforderten Programmlogik o Feedback Mechanismus Unterstützung mehrerer Programmiersprachen o mindestens jedoch Java und Python Nutzung vorhandener Programmbibliotheken in den Programmieraufgaben Einfache und Übersichtliche Darstellung der Resultate</institution>
        </aff>
      </contrib-group>
      <abstract>
        <p>Neben der Vermittlung wichtiger mathematischer Grundlagen spielt auch die Programmierausbildung im Bachelorstudiengang Geodäsie und Geoinformatik eine Schlüsselrolle. Im Rahmen der Veranstaltung „GIS I / Geländemodellierung“ erfolgt die Programmierausbildung mittels der Programmiersprache Java. Der Fokus liegt, nach einer allgemeinen Einführung, auf der Modellierung und Umsetzung von Datenstrukturen für Geodaten sowie darauf basierenden Algorithmen. Aufgrund der stetig wachsenden Bedeutung von Programmierfähigkeiten wurde beschlossen die Programmierausbildung zu intensivieren, ohne jedoch den Lehrund Betreuungsaufwand signifikant zu steigern. Eine Lösung stellt ein System zur automatischen Bewertung von Programmieraufgaben dar, da ein solches System einen nahezu konstanten Aufwand unabhängig von der Anzahl der Studierenden aufweist. Dieses Paper gibt einen Überblick über das eigens für diesen Zweck entwickelte System, welches zurzeit in der Programmierausbildung des Institutes eingesetzt wird.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>Die Entscheidung, welche Art von System um- und eingesetzt wird, wurde anhand folgender
Anforderungen getroffen:
•
•
•
•
•
•</p>
      <p>Das einzusetzende System muss frei Verfügbar und Erweiterbar sein
Zugriff über ein Web-Frontend
Leichte Erweiterbarkeit für weitere
o Programmiersprachen
o Lehrmodule</p>
    </sec>
    <sec id="sec-2">
      <title>2. Systembeschreibung</title>
      <p>Das entworfene System besteht aus drei Hauptkomponenten. Das Web-Frontend stellt dabei die
eigentliche Website mit allen Interaktionsmöglichkeiten dar, wohingegen das Backend die Verwaltung
der angebotenen Inhalte, als auch die Überprüfung der Programmieraufgaben übernimmt. Die dritte
und letzte Komponente stellt das Stud.IP als externer Anbieter von Kurs- und
Teilnehmerinformationen dar, welches darüber hinaus als Authentifizierungsanbieter dient. Abbildung
1 zeigt die beschriebenen Systemkomponenten, sowie deren Kommunikationsschnittstellen.</p>
      <p>Client
(Web-Frontend)
• Login
• Übersicht
• Vorlesungen
• Fortschritt
• Quelltext-Editor
• Feedback Anzeige
• Erstellung von Aufgaben</p>
      <p>GWT RPC
• login
• checkProgrammingExercise
• getCoursesForUser
• getSubmissions
• createNewExercise
• …</p>
      <p>Server
(J2EE-Backend)
• Login-Authentifizierung via Stud.IP
• Sitzungsverwaltung
• Codeüberprüfung
• Ergebnisverwaltung</p>
      <p>SOAP/WSDL
• check_credentials
• find_user_by_user_name
• get_participants
• get_lecturers_for_seminar
• get_lecturers_for_institute</p>
      <p>Stud.IP
(Extern)
• Login-Authentifizierung
• Kursinformationen
• Nutzerstatus (Student/Lehrender)</p>
      <sec id="sec-2-1">
        <title>Abbildung 1: Überblick über Systemkomponenten</title>
        <p>
          Als Basis für das gesamte System dient das Google Web Toolkit „GWT“ Framework. GWT
ermöglicht die Entwicklung von Web-basierten Client-Server Anwendungen. Dabei werden der
Server-seitige, als auch der Client-seitige Code komplett in Java erstellt. Der Client-seitige Code wird
dann vom GWT-Compiler von Java nach JavaScript übersetzt. Über selbstdefinierte Remote
Procedure Calls (RPC) können die Client- und Server-Instanzen miteinander kommunizieren.
Weiterführende Informationen finden sich unter [
          <xref ref-type="bibr" rid="ref3">2</xref>
          ].
        </p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Web-Frontend</title>
      <p>Das Web-Frontend stellt wie bereits beschrieben die Interaktion mit dem Nutzer her. Nach der
Authentifizierung des Nutzers (vgl. Abschnitt Authentifizierung) stehen dem Nutzer in Abhängigkeit
seines Status unterschiedliche Optionen zur Verfügung. Nutzer haben grundsätzlich die Möglichkeit
alle öffentlichen Inhalte abzurufen. Handelt es sich beim angemeldeten Nutzer um ein Stud.IP Konto
können ebenfalls Inhalte zur Veranstaltungen abgerufen werden bei denen sich der Nutzer vorher über
das Stud.IP als Teilnehmer eingetragen hat. Ist der Nutzer darüber hinaus noch Dozent des Instituts hat
dieser entsprechende Editiermöglichkeiten, wie das Hinzufügen neuer Programmieraufgaben.
Desweiteren erhalten Dozenten die Möglichkeit die Fortschritte der Kursteilnehmer zu überwachen,
als auch die getätigten Quelltextabgaben ansehen.</p>
      <p>Abbildung 2 zeigt Beispielhaft die Fortschritte der einzelnen Teilnehmer. Die Veranstaltungsansicht
(links) gibt einen Überblick über alle gestellten Aufgaben und welche Aufgabe von welchem
Teilnehmer bereits absolviert wurde. Die Aufgabenansicht gibt detaillierte Informationen über die
getätigte Quelltextabgabe. Angezeigt werden Bearbeitungsbeginn (Spalte ‚Started‘) und –ende (Spalte
‚Submission‘) der Aufgabe, sowie Anzahl der benötigten Quelltextüberprüfungen (Spalte ‚Runs‘).
Über die Schaltfläche „Show“ können die Quelltextabgaben betrachtet werden. Die
durchnummerierten Spalten „0“, „1“, usw. entsprechen den der Programmieraufgabe
zugrundeliegenden Quelltextdateien. Im gezeigten Beispiel gab es demnach zwei zu Implementierende
Klassen. Der jeweilige Eintrag der Spalten ist eine Analyse der jeweiligen Quelltextabgaben zu allen
anderen und spiegelt die „Ähnlichkeit“ von Abgaben wieder. Dabei symbolisiert die erste Zahl eine
Gruppe von ähnlichen Abgaben und die zweite die Größe der jeweiligen Gruppe. Die Abgabe „1“ von
Teilnehmer drei wurde somit von fünf weiteren, also insgesamt sechs Teilnehmern abgegeben. Um die
Ähnlichkeit von Quelltextabgaben zu beurteilen wurde die Editierdistanz bzw. Levenshtein-Distanz
jeder Abgabe mit allen anderen Abgaben ermittelt. Liegt die ermittelte Distanz unter einem
festgelegtem Schwellwert werden die Abgaben einer Gruppe zugeordnet.</p>
      <sec id="sec-3-1">
        <title>Abbildung 2: Abgabenübersicht für eine komplette Veranstaltung (links) und für eine einzelne Programmieraufgabe (rechts)</title>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Backend</title>
      <p>Die Server-Komponente ist wie bereits beschrieben für die Datenhaltung als auch die Überprüfung der
Programmieraufgaben zuständig. Die Datenhaltung ist über eine lokale Datenbank realisiert. Um ein
einfaches Deploying (Verteilung) des Systems zu gewährleisten wurde für die Datenbank auf ein
eingebettetes Datenbanksystem in Form von HSQLBD zurückgegriffen. Die Datenbank ist komplett in
das Systemeingebettet und somit nach außen nicht sichtbar.</p>
      <p>
        Neben der eigenen Datenhaltung kommuniziert die Server-Komponente noch mit dem Stud.IP Service
um Vorlesungs- und Teilnehmerinformationen abzurufen. Die Kommunikation ist über die vom
Stud.IP bereitgestellte SOAP Schnittstelle, welche in [
        <xref ref-type="bibr" rid="ref4">3</xref>
        ] dokumentiert ist, realisiert. SOAP steht dabei
für Simple Object Access Protocol und ermöglicht den netzwerkbasierten Austausch von Daten
zwischen zwei Systemen. Die jeweiligen Schnittstellen sind WSDL (Web Service Description
Language), einer Beschreibungssprache für SOAP-basierte Schnittstellen, definiert. Die Nutzung der
SOAP Schnittstelle setzt jedoch einen API Schlüssel voraus, welcher erst beim Stud.IP Betreiber
beantragt werden muss. Darüber hinaus sind die Zugriffe auf vorher festgelegte IP Adressen
beschränkt. Die vom System genutzten Funktionen sind: check_credentials zur Authentifizierung
der Nutzer, find_user_by_username zur Ermittlung des vollständigen Nutzernamens,
get_participants liefert eine Liste aller eingetragenen Teilnehmer einer Veranstaltung,
get_lecturers_for_seminar stellt eine Liste der Dozenten einer Veranstaltung bereit, wohingegen
get_lecturers_for_institute alle Dozenten eines Instituts liefert. Die genannten Funktionen
werden dafür genutzt die entsprechenden Ansichten und Interaktionsmöglichkeiten der Nutzer über
das Frontends zu unterscheiden.
      </p>
    </sec>
    <sec id="sec-5">
      <title>Authentifizierung</title>
      <p>Für die Nutzerauthentifizierung wurden zwei Varianten implementiert. Die bevorzugte Methode ist die
Stud.IP Authentifizierung. Die SOAP Schnittstelle stellt dafür die Funktion check_credentials
bereit, mit der Nutzername und Passwort auf ihre Gültig überprüft werden.</p>
      <p>Neben dem Stud.IP Webservice ist auch eine Authentifizierung via OpenID umgesetzt. OpenID ist
dabei ein dezentrales Authentifizierungssystem, welches einem Benutzer erlaubt sich mit einem
OpenID-Konto bei beliebigen das System unterstützenden Websites anzumelden. Fast alle großen
Webportale haben den Standard umgesetzt und fungieren somit als OpenID-Anbieter. Um Inhalte für
externe Teilnehmer zu Verfügung zu stellen integriert das System den beschriebenen OpenID
Standard und unterstützt bisher Google als Anbieter. Weitere Anbieter, wie z.B. Microsoft, Facebook
oder Twitter können bei Bedarf mit minimalem Aufwand hinzugefügt werden.</p>
    </sec>
    <sec id="sec-6">
      <title>3. Bewertung der Programmieraufgaben</title>
      <p>Nach der Eingabe des Quelltextes in die zugehörige Frontend Maske wird dieser per RPC an die
Server-Instanz zur Überprüfung geschickt. Dafür muss der Quelltext in Abhängigkeit der verwendeten
Programmiersprache zunächst kompiliert werden. Etwaige Compiler-Fehler werden dabei als
Feedback im Frontend angezeigt. Anschließend wird die Korrektheit mittels bereitgestellter Unit-Tests
überprüft. Zurzeit wird lediglich zwischen Korrekt und nicht Korrekt unterschieden, eine feinere
Bewertung kann daher nicht angebracht werden. Jedoch ist es vorgesehen, das der Student ein
detailliertes Feedback erhält, welcher Testfall nicht erfüllt wurde und warum er nicht erfüllt wurde.
Somit hat der Student Gelegenheit seine Lösung zu korrigieren und erneut zu übermitteln. Die jeweils
aktuellste Fassung des übermittelten Quelltextes wird neben weiteren Statistiken in der lokalen
Datenbank hinterlegt.</p>
    </sec>
    <sec id="sec-7">
      <title>Modell-Analyse mittels Java-Reflections</title>
      <p>Je nach Aufgabentyp hat sich dabei die Aufteilung in Modell Tests und Logik Tests bewährt. Modell
Tests sind dabei über Java Reflections realisiert, wohingegen auf das JUnit Framework im Falle der
Logik Tests zurückgegriffen wird.</p>
      <p>Das Java Reflection-Modell (häufig als Introspektion bezeichnet) ermöglicht die Analyse und auch
Modifikation von Klassen und Objekten, die sich zur Laufzeit im Speicher der Java Virtual Machine
JVM befinden. Das Reflection-Modell erlaubt es Felder, Methoden und Konstruktoren von Klassen
abzufragen, was sich dazu nutzen lässt die korrekte Umsetzung eines geforderten Modells zu
überprüfen. Der häufigste Aufgabentyp im Rahmen der Programmierausbildung ist die
Implementierung eines vorgegebenen Modells, welches i.d.R. als UML Klassendiagramm dargestellt
oder als reiner Text beschrieben ist.</p>
      <p>Die Überprüfung ob der eingereichte Code dem vorgegebenen Modell genügt soll am folgenden
Beispiel gezeigt werden. Angenommen es soll folgendes Datenmodell umgesetzt werden:
•
•
•
•</p>
      <p>Straßen und Schienenbahnen sind Verkehrswege
Jeder Verkehrsweg besitzt einen Namen
Eine Straße hat eine bestimmte Breite</p>
      <p>Schienenbahnen sind „icetauglich“ oder nicht
Um das implementierte Modell auf Korrektheit zu überprüfen, sind folgende Tests notwendig:
1. Es existiert eine Klasse Schienenbahn, Straße als auch Verkehrsweg
2. Die Klassen Schienenbahn und Straße erben von Verkehrsweg
3. Die Klasse Verkehrsweg besitzt ein Feld mit dem Bezeichner name vom Typ String
4. Die Klasse Straße besitzt ein Feld mit dem Bezeichner breite vom Type double oder float
5. Die Klasse Schienenbahn besitzt ein Feld mit dem Bezeichner icetauglich vom Typ boolean
Überprüfung (1) ist hinfällig, da alle Klassen immer als Code-Stub vorgegeben werden müssen. Um
die Vererbungsbedingung (2) zu überprüfen muss zunächst auf die generische Reflections Klasse
Class&lt;?&gt; zugegriffen werden, dies wird über einen statischen Zugriff auf das Feld class der
entsprechende Klasse realisiert. Anschließend kann über die Methode getSuperclass die
Elternklasse und damit die geforderte Vererbung überprüft werden. Listing 1 zeigt die zugehörige
Implementierung.
Neben der Vererbungshierarchie können alle relevanten Modellparameter auf diese Weise überprüft
werden. Beispielsweise lässt sich mit getDeclaredField auf die Felder einer Klasse über dessen
Name zugreifen. Existiert kein Feld mit dem gegebenen Namen wird eine entsprechende Exception
geworfen. Abschließend lässt sich der Typ des gefundenen Feldes ebenfalls mit getType überprüfen.
Listing 2 zeigt dies am Beispiel der Bedingung (3), wobei Bedingungen (4) und (5) analog zu
überprüfen sind.</p>
      <p>boolean ex = false;
Class&lt;Verkehrsweg&gt; cl = Verkehrsweg.class;
try {</p>
      <p>Field f = cl.getDeclaredField("name");
assertTrue("Das Feld Verkehrsweg.name muss vom Typ String sein!",</p>
      <p>f.getType().equals(String.class));
} catch (NoSuchFieldException e) {</p>
      <p>ex = true;
}
assertFalse("Die Klasse Verkehrsweg muss ein Feld \"name\" besitzen!", ex);</p>
      <sec id="sec-7-1">
        <title>Listing 2: Überprüfung der Klassenfelder mittels Java Reflections</title>
      </sec>
    </sec>
    <sec id="sec-8">
      <title>4. Sicherheit</title>
      <p>Da das gezeigte System eine Authentifizierung voraussetzt, gilt es die Übertragung der eingegebenen
Zugangsdaten entsprechend zu sichern. Grundsätzlich sollte hier auf eine SSL Verschlüsselung via
HTTPS zurückgegriffen werden. Ist dies aus technischen Gründen nicht möglich, unterstützt das
System auch eine eigene Verschlüsselung der Nutzerdaten. Diese basiert jedoch lediglich auf dem
symmetrischen Verschlüsselungsverfahren „Triple-DES“. Da symmetrische Verfahren als leicht
Angreifbar gelten sollte diese Variante nur im Ausnahmefall genutzt werden.</p>
      <p>Da die Bewertung der Programmierübung darauf beruht den studentischen Quelltext serverseitig zu
kompilieren, als auch auszuführen ist eine Sicherung des Servers vor böswilligem oder schlicht
falschem Code unerlässlich. Je nach Programmiersprache kommen hier unterschiedliche Konzepte
zum Einsatz. Grundsätzlich gilt zunächst, dass eine Codeüberprüfung nur als gültiger Benutzer
möglich ist.</p>
      <p>
        Allgemein stellt ein Sandbox-Ansatz, wie er auch in vielen existierenden Systemen wie [
        <xref ref-type="bibr" rid="ref5">4</xref>
        ], [
        <xref ref-type="bibr" rid="ref6">5</xref>
        ] und
[
        <xref ref-type="bibr" rid="ref1 ref7">6</xref>
        ] Verwendung findet, wohl eine der sichersten Varianten dar. Der vom vorgestellten System
verwendete Sandbox-Ansatz nutzt die Java SecurityManager Schnittstelle, um die Rechte des zu
prüfenden Codes stark einzuschränken. Um die Ausführung der restlichen Server- und Testklassen
nicht zu beeinträchtigen ist der SecurityManager ausschließlich auf die zu testenden Klassen
limitiert. Der implementierte SecurityManager verhindert jedweden Zugriff auf bspw. externe
Prozesse, das Dateisystem, Internet-Sockets, Classloader, etc.
      </p>
      <p>Als weiteres Merkmal lässt sich die maximale Ausführungsdauer des Testcodes limitieren. So werden
versehentliche oder absichtliche Endlosschleifen verhindert. Darüber hinaus führt jede Exception im
Testablauf zu einem Automatischem Abbruch des Tests und einem entsprechenden Feedback an den
einreichenden Nutzer.</p>
      <p>
        Im Falle der ebenfalls vom System unterstützten Programmiersprache Python kann der beschriebene
Sandbox-Ansatz nur beschränkt verwendet werden. Hierbei wird der übermittelte Quelltext auf
potentiell Gefährliche Fragmente hin überprüft und entsprechend bereinigt. Konkret werden dabei
sämtliche Import Anweisungen verworfen und nur die für die Lösung der Aufgabe relevanten Imports
wieder hinzugefügt. Darüber hinaus werden sämtliche Anweisungen, die einen Dateisystem- oder
Socketzugriff realisieren herausgefiltert. Die Analyse des Python-Quelltextes basiert dabei auf
Regulären Ausdrücken, ähnlich wie in [
        <xref ref-type="bibr" rid="ref8">7</xref>
        ] beschrieben.
      </p>
    </sec>
    <sec id="sec-9">
      <title>5. Zusammenfassung und Ausblick</title>
      <p>Es wurde ein System zur automatischen Überprüfung von Programmieraufgaben vorgestellt. Realisiert
wurde es als Web-basierte Client-Server-Anwendung mit dem Framework Google Web Toolkit. Das
System ist über eine SOAP Schnittstelle an den Stud.IP Service angebunden und nutz dessen
Nutzerverwaltung, sowie die Kurs- und Teilnehmerinformationen. Darüber hinaus wurde auf die
Modellüberprüfung mittels Java Reflections eingegangen. Abschließend wurden genutzte
Sicherheitsmechanismen wie Sandboxing, Quelltextanalyse via Regulären Ausdrücken und
Verschlüsselung beschrieben.</p>
      <p>Das gezeigte System wird bereits im Lehrbetrieb eingesetzt, nichtsdestotrotz unterliegt es einer
konstanten Weiterentwicklung. Geplant sind beispielsweise die Integration weiterer OpenID Anbieter
zur Nutzerauthentifizierung. Darüber hinaus wird zurzeit untersucht inwiefern das System oder Teile
davon auf Cloudservices wie Googles AppEngine oder Amazons AWS migriert werden kann um eine
bessere Skalierbarkeit zu gewährleisten. Die Einführung einer Bewertungsskala über richtig und falsch
hinaus wird ebenfalls geprüft.
[Online].</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>6. Literaturverzeichnis</mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>P.</given-names>
            <surname>Ihantola</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Ahoniemi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>V.</given-names>
            <surname>Karavirta</surname>
          </string-name>
          und
          <string-name>
            <given-names>O.</given-names>
            <surname>Seppälä</surname>
          </string-name>
          , „
          <article-title>Review of Recent Systems for Automatic Assessment of Programming Assignments,“ in s</article-title>
          <source>Proceedings of the 10th Koli Calling International Conference on Computing Education Research</source>
          , Koli, Finland,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Google</given-names>
            <surname>Inc</surname>
          </string-name>
          ., „GWT Project,“ Google Inc., [Online]. Available: http://www.gwtproject.org/.
          <source>[Zugriff am 25 09</source>
          <year>2013</year>
          ].
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>Stud.IP</given-names>
            <surname>Open-Source-Projekt</surname>
          </string-name>
          , „NuSOAP: Stud.IP Webservice,“ https://elearning.uni-hannover.de/soap.php.
          <source>[Zugriff am 27 09</source>
          <year>2013</year>
          ].
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>B.</given-names>
            <surname>Merry</surname>
          </string-name>
          , „
          <article-title>Using a linux security module for contest security,“ in s Olympiads in Informatics 3</article-title>
          ,
          <year>2009</year>
          , pp.
          <fpage>67</fpage>
          -
          <lpage>73</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>M.</given-names>
            <surname>Amelung</surname>
          </string-name>
          , P. Forbrig und
          <string-name>
            <given-names>D.</given-names>
            <surname>Rösner</surname>
          </string-name>
          , „
          <article-title>Towards generic and flexible web services for eassessment,“ SIGCSE Bull</article-title>
          ., pp.
          <fpage>219</fpage>
          -
          <lpage>224</lpage>
          ,
          <year>Juni 2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>E. a. T. M. A. a. R. J. a. C. F. a. R. S.</given-names>
            <surname>Gutiérrez</surname>
          </string-name>
          , „
          <article-title>A new Moodle module supporting automatic verification of VHDL-based assignments</article-title>
          ,“ Comput. Educ., pp.
          <fpage>562</fpage>
          -
          <lpage>577</lpage>
          ,
          <year>Februar 2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [7]
          <string-name>
            <surname>M.-Y. Chen</surname>
          </string-name>
          , et.al.,
          <article-title>„Design and applications of an algorithm benchmark system in a computational problem solving environment,“ in s Proceedings of the 11th annual SIGCSE conference on Innovation and technology in computer science education</article-title>
          , Bologna, Italy,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>