diff --git a/.env b/.env index 964e458481f0ca65d9450905857aedaacde65a38..98be37a38edd253b4a6d505faf21397a4182b4aa 100755 --- a/.env +++ b/.env @@ -3,10 +3,14 @@ MARIADB_DATABASE=moodle MARIADB_USER=moodleuser MARIADB_PASSWORD=moodlepassword MOODLE_DATABASE_ROOT_PASSWORD=rootpassword -MOODLE_DATABASE_HOST=localhost -#MOODLE_DATABASE_HOST=mariadb +#MOODLE_DATABASE_HOST=localhost +MOODLE_DATABASE_HOST=mariadb MOODLE_DATABASE_NAME=moodle MOODLE_DATABASE_USER=moodleuser MOODLE_DATABASE_PASSWORD=moodlepassword MOODLE_BASE_DIR=/var/www/html/moodle -MOODLE_BASE_DIR_DATA=/var/www/html/moodledata \ No newline at end of file +MOODLE_BASE_DIR_DATA=/var/www/html/moodledata + +MOODLE_WWWROOT=https://www.moodle.loc +MOODLE_FULLNAME="Moodle LMS Site" +MOODLE_SHORTNAME="Moodle" \ No newline at end of file diff --git a/.gitignore b/.gitignore index aae107327e2d483717b7fe609d733f26af3bb86d..858d25fb39dd2505a10d349d7ed2885285c4919b 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ -/.idea -/.git +/.idea/* +/.git/* +.idea/* +/.idea/ diff --git a/Dockerfile b/Dockerfile index 350cdec500ef966da242c6b2c9949c336c2dcb37..1c797ebc640767a3bd347cfcf74d4c4965fe731b 100755 --- a/Dockerfile +++ b/Dockerfile @@ -17,42 +17,82 @@ ENV MOODLE_BASE_DIR_DATA ${MOODLE_BASE_DIR_DATA} # Installing necessary packages RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y apache2 php libapache2-mod-php php-mysqli php-mysql php-xml php-pdo php-pdo-mysql mariadb-client mariadb-server wget unzip python3 python3-pip iputils-ping curl php-mbstring graphviz aspell ghostscript clamav php8.2-pspell php8.2-curl php8.2-gd php8.2-intl php8.2-mysql php8.2-xml php8.2-xmlrpc php8.2-ldap php8.2-zip php8.2-soap php8.2-mbstring && \ + apt-get install -y apache2 php libapache2-mod-php php-mysqli php-mysql php-xml php-pdo php-pdo-mysql mariadb-client mariadb-server wget unzip p7zip-full python3 python3-pip iputils-ping php-mbstring graphviz aspell ghostscript clamav php8.2-pspell php8.2-curl php8.2-gd php8.2-intl php8.2-mysql php8.2-xml php8.2-xmlrpc php8.2-ldap php8.2-zip php8.2-soap php8.2-mbstring openssl git && \ apt-get clean && rm -rf /var/lib/apt/lists/* # Setting necessary php params -RUN echo "mysql.default_socket=/run/mysqld/mysqld.sock" >> /etc/php/8.2/cli/php.ini +#RUN echo "mysql.default_socket=/run/mysqld/mysqld.sock" >> /etc/php/8.2/cli/php.ini +RUN echo "mysql.default_socket=/run/mysqld/mysqld.sock" >> /etc/php/8.2/apache2/php.ini +RUN echo "max_input_vars = 5000" >> /etc/php/8.2/apache2/php.ini RUN echo "max_input_vars = 5000" >> /etc/php/8.2/cli/php.ini # Starting Apache server -RUN systemctl start apache2 +RUN chmod 1777 /tmp -# Installing Moodle +# Add necessary packages for adding Python 3 repository and installing curl +RUN apt-get update && apt-get install -y curl software-properties-common gnupg2 dirmngr --no-install-recommends + +# Add the repository +RUN add-apt-repository 'deb https://deb.debian.org/debian/dists/trixie/ trixie main' + +# Update package lists after adding the repository +RUN apt-get update + +# Installing necessary Python dependencies & Flask +RUN apt-get install -y python3-venv python3-pip python3-matplotlib +RUN python3 -m venv /opt/myenv +RUN /opt/myenv/bin/python3 -m pip install --upgrade pip +#RUN /opt/myenv/bin/python3 -m pip install matplotlib Flask torch sklearn-learn +COPY requirements.txt /opt/myenv/ +RUN /opt/myenv/bin/python3 -m pip install -r /opt/myenv/requirements.txt +RUN /opt/myenv/bin/python3 -m pip install --upgrade setuptools wheel + +# Copy the api.py script into the container +COPY api.py /var/www/html/moodle/api.py +COPY install_moodle.sh /var/www/html/moodle/install_moodle.sh +RUN chmod +x /var/www/html/moodle/install_moodle.sh + +RUN mkdir -p /asyst +# Download and extract the ASYST archive +#RUN curl -o asyst.zip -L https://transfer.hft-stuttgart.de/gitlab/ulrike.pado/ASYST/-/archive/main/ASYST-main.zip && \ +# 7z x asyst.zip -o/asyst && \ +# mv /asyst/ASYST-main/* /asyst && \ +# rm -rf /asyst/ASYST-main asyst.zip + +# Set permissions (if necessary) +RUN chown -R www-data:www-data /asyst +RUN chmod -R 755 /asyst + +COPY ./asyst /var/www/html/moodle/asyst +RUN ln -s /var/www/html/moodle/asyst/Source/Skript /var/www/html/moodle/Skript + +# Installing Moodle Setting correct acces rules RUN mkdir -p ${MOODLE_BASE_DIR} && \ - wget -qO- https://packaging.moodle.org/stable403/moodle-4.3.4.tgz | tar xz -C ${MOODLE_BASE_DIR} --strip-components=1 \ + wget -qO- https://packaging.moodle.org/stable403/moodle-4.3.4.tgz | tar xz -C ${MOODLE_BASE_DIR} --strip-components=1 -# Setting correct acces rules RUN chown -R www-data:www-data ${MOODLE_BASE_DIR} && \ - chmod -R 755 ${MOODLE_BASE_DIR} && \ + find ${MOODLE_BASE_DIR} -type d -exec chmod 755 {} \; && \ + find ${MOODLE_BASE_DIR} -type f -exec chmod 644 {} \; && \ mkdir -p ${MOODLE_BASE_DIR_DATA} && \ chown -R www-data:www-data ${MOODLE_BASE_DIR_DATA} && \ chmod -R 755 ${MOODLE_BASE_DIR_DATA} # Copying of beeing developed Plugin -COPY yourplugin ${MOODLE_BASE_DIR}/local/yourplugin +COPY yourplugin ${MOODLE_BASE_DIR}/mod/yourplugin # Setting correct acces rules for Plugin -RUN chown -R www-data:www-data ${MOODLE_BASE_DIR}/local/yourplugin && \ - chmod -R 755 ${MOODLE_BASE_DIR}/local/yourplugin +#RUN chown -R www-data:www-data ${MOODLE_BASE_DIR}/mod/yourplugin && \ +RUN chmod -R 755 ${MOODLE_BASE_DIR}/mod/yourplugin # Making Symlink for MariaDB Socket RUN ln -s /run/mysqld/mysqld.sock /tmp/mysql.sock -#RUN php ${MOODLE_BASE_DIR}/admin/cli/install_database.php --adminpass=${MOODLE_DATABASE_ROOT_PASSWORD} --agree-license +RUN echo "ServerName modhost" >> /etc/apache2/apache2.conf -# Apache Settings -RUN echo "<VirtualHost *:80>\n" \ - "ServerName localhost\n" \ +# Apache Settings for HTTP +RUN echo \ + "<VirtualHost *:80>\n" \ + "ServerName www.moodle.loc\n" \ "ServerAlias www.moodle.loc\n" \ "DocumentRoot /var/www/html/moodle\n" \ "<Directory /var/www/html/moodle>\n" \ @@ -60,22 +100,56 @@ RUN echo "<VirtualHost *:80>\n" \ " AllowOverride All\n" \ " Require all granted\n" \ "</Directory>\n" \ - "ErrorLog \${APACHE_LOG_DIR}/error.log\n" \ - "CustomLog \${APACHE_LOG_DIR}/access.log combined\n" \ - "</VirtualHost>\n" \ + "</VirtualHost>\n" \ + "ErrorLog /var/log/apache2/error.log\n" \ + "CustomLog /var/log/apache2/access.log combined\n" \ +# "RewriteEngine On\n" \ +# "RewriteCond %{HTTPS} !=on\n" \ +# "RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]\n" \ > /etc/apache2/sites-enabled/000-default.conf # Setting Apache RUN a2enmod rewrite -RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf -# Installing Moodle non interactive -#RUN sleep 4 && php ${MOODLE_BASE_DIR}/admin/cli/install.php --wwwroot=http://0.0.0.0 --dataroot=${MOODLE_BASE_DIR_DATA} --dbtype=mariadb --dbname=${MOODLE_DATABASE_NAME} --dbuser=${MOODLE_DATABASE_USER} --dbpass=${MOODLE_DATABASE_PASSWORD} --dbhost=${MOODLE_DATABASE_HOST} --adminpass=${MOODLE_DATABASE_ROOT_PASSWORD} --fullname="Moodle Site" --shortname="Moodle" --agree-license --non-interactive -RUN chmod -R 755 /var/www/html/moodle -RUN chown -R www-data:www-data /var/www/html/moodle +# Generate a self-signed SSL certificate (replace example.com with your domain) +RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /etc/ssl/private/apache-selfsigned.key \ + -out /etc/ssl/certs/apache-selfsigned.crt \ + -subj "/C=EU/ST=Berlin/L=Berlin/O=HFT/CN=www.moodle.loc" + +# Configure SSL virtual host +RUN echo \ + "<VirtualHost *:443>\n" \ + "ServerName www.moodle.loc\n" \ + "ServerAlias www.moodle.loc\n" \ + "DocumentRoot /var/www/html/moodle\n" \ + "<Directory /var/www/html/moodle>\n" \ + " Options +FollowSymlinks\n" \ + " AllowOverride All\n" \ + " Require all granted\n" \ + "</Directory>\n" \ + "SSLEngine on\n" \ + "SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt\n" \ + "SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key\n" \ + "ErrorLog /var/log/apache2/error.log\n" \ + "CustomLog /var/log/apache2/access.log combined\n" \ + "</VirtualHost>\n" \ + > /etc/apache2/sites-enabled/default-ssl.conf + +# Opening 000-default.conf for edit +RUN sed -i '/<\/VirtualHost>/i \ +RewriteEngine On \n\ +RewriteCond %{SERVER_PORT} 80 \n\ +RewriteRule ^(.*)$ https://www.moodle.loc/$1 [R,L] \n\ +' /etc/apache2/sites-enabled/000-default.conf + +# Enable SSL module in Apache +RUN a2enmod ssl #Opening ports -EXPOSE 80 443 +EXPOSE 80 443 5000 -# Команда запуÑка Apache -CMD ["apachectl", "-D", "FOREGROUND"] +#RUN /var/www/html/moodle/install_moodle.sh +# Run the Flask app (modify entrypoint or use a custom script if needed) +#CMD ["bash", "-c", "service apache2 start && source /opt/myenv/bin/activate && python3 /var/www/html/moodle/install_moodle.sh /var/www/html/moodle/api.py "] +#CMD ["bash", "-c", "service apache2 start && source /opt/myenv/bin/activate && python3 /var/www/html/moodle/api.py && /var/www/html/moodle/install_moodle.sh"] diff --git a/api.py b/api.py new file mode 100755 index 0000000000000000000000000000000000000000..65c8f170d8c566aaed0cc03234314ba8997ac1d2 --- /dev/null +++ b/api.py @@ -0,0 +1,21 @@ +# api.py + +from flask import Flask, jsonify + +app = Flask(__name__) + +# Example of an endpoint returning JSON data +@app.route('/api/data', methods=['GET']) +def get_data(): +# TODO: use run_LR_SBERT.py ASYST script instead + data = { + 'message': 'Hello from Python API!', + 'data': { + 'key1': 'value1', + 'key2': 'value2' + } + } + return jsonify(data) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/asyst/DE_Demo_Daten.xlsx b/asyst/DE_Demo_Daten.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..a387752d3800aac3b3ecf4ff22783962f73b583c Binary files /dev/null and b/asyst/DE_Demo_Daten.xlsx differ diff --git a/asyst/README.md b/asyst/README.md new file mode 100755 index 0000000000000000000000000000000000000000..56f29b7604e79d37229463a42ed93b762245dc94 --- /dev/null +++ b/asyst/README.md @@ -0,0 +1,7 @@ +ASYST ist ein Werkzeug zur Unterstützung beim Bewerten von Freitextantworten. <a href="README_DE.md">Mehr +Information</a> + +ASYST is a tool to support grading of free text answers. <a href="README_EN.md">More information</a> + +<a href="https://www.hft-stuttgart.com/research/projects/current/knight-project"><img src="images/csm_Knight_Logo_eac7003904.webp" alt="KNIGHT-Logo" width="200"/></a> <img src="images/csm_BMBF_gefoerdert_vom_deutsch_48a18b1887.webp" alt="BMBF-Logo" width="200"/> + diff --git a/asyst/README_DE.md b/asyst/README_DE.md new file mode 100755 index 0000000000000000000000000000000000000000..1849a98206731abd4f6210588ce143abc9d6ee2b --- /dev/null +++ b/asyst/README_DE.md @@ -0,0 +1,249 @@ +<h2>Inhalt:</h2> +<ul> + <li><a href="#1"> Was ist ASYST? </a> </li> + <li><a href="#2"> Welche Sprachen unterstützt ASYST? </a></li> + <li><a href="#3"> Wie verwendet man ASYST? </a></li> + <ol> + <li><a href="#4"> Wie müssen auszuwertende Daten formatiert sein?</a> </li> + <li><a href="#5"> Wie führe ich das Programm unter Windows 11 aus? </a> </li> + + </ol> + <li><a href="#6"> Wie arbeit man mit der Ausgabe von ASYST weiter? </a></li> + <li><a href="#7"> Wie kann ich ASYST ausführen, wenn ich kein Windows 11 nutze? </a> + <ul><li><a href="#8"> Ausführen von ASYST in der Entwicklungsumgebung Pycharm</a> </li></ul></li> +</ul> + + +<h2 id=1>Was ist ASYST?</h2> + +ASYST ist ein Programm, das Lehrenden die Auswertung von Freitextantworten in Tests erleichtern soll: Mit Hilfe +künstlicher Intelligenz +macht ASYST Bewertungsvorschläge, die von den Lehrenden gezielt überprüft und ggf. verändert werden können. + +ASYST ist für die Bewertung von Freitext-Kurzantworten gedacht - diese Kurzantworten sollten etwa ein bis drei Sätze +umfassen. Für längere Antworten ist die Anwendung nicht vorgesehen. + +ASYST hilft der Lehrperson, indem es eine Bewertung vorschlägt. Diese Bewertung kann im Einzelfall durchaus auch falsch +sein; die Lehrperson kann sie prüfen und korrigieren. +Dabei spart man gegenüber der völlig manuellen Bewertung an zwei Stellen Zeit: Zum Einen ist das Überprüfen von +Bewertungen im Allgemeinen schneller als das Bewerten von Grund auf; +und zum anderen empfehlen wir, bei der Überprüfung gezielt die ASYST-Bewertungen auszuwählen, die eher fehleranfällig +sind (s. Abschnitt <a href="#6"> Wie arbeit man mit der Ausgabe von ASYST weiter? </a>). + +Das Programm ist in Python geschrieben; der Quellcode ist öffentlich zugänglich. Um ASYST einfacher nutzbar zu machen, +wurden die Python-Skripte +in eine ausführbare Programmdatei umgewandelt, die in Windows 11 nutzbar ist. + +Die technischen Hintergründe zu ASYST und eine Beispielrechnung zum Einsatz für das Deutsche finden sich +in <a href="https://rdcu.be/dxPLg">Pado, Eryilmaz und Kirschner, IJAIED 2023</a>. + +<h2 id=2>Welche Sprachen unterstützt ASYST?</h2> + +ASYST wurde für <a href="https://rdcu.be/dxPLg">Deutsch</a> und <a href="https://nlpado.de/~ulrike/papers/Pado22.pdf"> +Englisch</a> getestet. + +Das Sprachmodell, das Deutsch abdeckt, kann im Prinzip noch weitere Sprachen verarbeiten. Sie können also +grundsätzlich "Deutsch" als Spracheinstellung auswählen und Daten in einer der anderen unterstützten Sprachen hochladen. +Bitte prüfen Sie die Ergebnisse aber sorgfältig, es liegen keine Erfahrungen vor! (Die Sprachen +sind <a href="https://www.sbert.net/docs/pretrained_models.html#multi-lingual-models">lt. den Modellerstellern</a>: ar, +bg, ca, cs, da, de, el, en, es, et, fa, fi, fr, fr-ca, gl, gu, he, hi, hr, hu, hy, id, it, ja, ka, ko, ku, lt, lv, mk, +mn, mr, ms, my, nb, nl, pl, pt, pt-br, ro, ru, sk, sl, sq, sr, sv, th, tr, uk, ur, vi, zh-cn, zh-tw.) + +<h2 id=3>Wie verwendet man ASYST?</h2> +Wir haben bei der Entwicklung von ASYST versucht, die Verwendung möglichst einfach zu machen sein. + +<h3 id=4>Wie müssen auszuwertende Daten formatiert sein?</h3> +Das Programm arbeitet auf Basis Ihrer Daten im Excel-Format .xlsx (das auch von Libre Office Calc und anderen Programmen +erzeugt werden kann). Eine Beispieltabelle: + + + +Dabei müssen die folgende Informationen in der **richtigen Reihenfolge** und mitem **richtigen Titel** der Spalten +enthalten sein: + +1) **Question**: Die gestellte Frage +2) **referenceAnswer**: Eine korrekte Antwort / Musterlösung / Referenzantwort +3) **studentAnswer**: Die vom Prüfling gegebene Antwort, die bewertet werden soll. +5) (optional) **observed grade**: Hier kann die tatsächliche Bewertung durch die Lehrkraft eingetragen werden, um + Kennzahlen über die Richtigkeit der Vorhersagen zu bekommen. + +Die Beispieltabelle finden Sie +unter <a href="https://transfer.hft-stuttgart.de/gitlab/ulrike.pado/ASYST/-/blob/main/DE_Demo_Daten.xlsx"> +DE_Demo_Daten.xlsx</a>. Sie enthält einige Fragen und Antworten aus dem CSSAG-Korpus (Computer Science Short Answers in +German) der HFT Stuttgart. Das Korpus is CC-BY-NC lizenziert. + +<h3 id=5>Wie führe ich das Programm unter Windows 11 aus? </h3> + +Zunächst muss die Datei +_ASYST.exe_ <a href="https://transfer.hft-stuttgart.de/gitlab/ulrike.pado/ASYST/-/blob/main/ASYST.exe"> heruntergeladen +werden</a>. +Sobald dies geschehen ist, kann das Programm mittels Doppelklick gestartet werden. + +Der Start des Programmes wird eine Weile dauern (ca 1 Minute). In dieser Zeit wird das System initialisiert. + +**Hinweis**: Es kann passieren, dass Windows Defender davor warnt, die Anwendung auszuführen, da das Programm kein +Sicherheitszertifikat besitzt. +Durch Auswählen von _weitere Informationen_ und anschließend _Trotzdem ausführen_ verschwindet die Fehlermeldung und +ASYST kann ausgeführt werden. Der Quelltext von ASYST ist offen zugänglich, so dass Sie sich vergewissern können, dass +ASYST keine Schadsoftware ist. + + +<img src="images/win_def_de_1.JPG" width="450"> +<img src="images/win_def_de_2.JPG" width="450"> + +Nachdem das Programm gestartet wurde, erscheint eine Oberfläche, auf der die Sprache der auszuwertenden Antworten +ausgewählt werden kann. +Anschließend kann über einen Klick auf das Feld "Input File" die zu verarbeitende Tabelle ausgewählt werden. +Hierbei sollten die Daten wie oben beschrieben angeordnet sein. +Nach einem Klick auf das "Start"-Feld beginnt ASYST mit der Verarbeitung der Daten. Dies kann wiederum eine Weile +dauern (1-2 Minuten, relativ unabhängig von der Menge der zu verarbeitenden Daten). + +Sobald das Programm alle Einträge verarbeitet und Vorhersagen getroffen hat, öffnet sich eine Tabellenansicht mit der +Überschrift "Results" (Ergebnisse). + +Die Ergebnistabelle enthält alle Spalten der eingelesenen Tabelle, sowie zusätzlich in der Spalte "predicted grade" die +von ASYST vorgeschlagene Bewertung der Antworten. Die "incorrect"-Einträge der als falsch eingestuften Antworten sind +rot hinterlegt. Sie können in dieser Tabelle allerdings noch keine Bewertungen verändern. Speichern Sie hierzu über +einen Klick auf "Save as" die erzeugte Tabelle und öffnen Sie sie dann mit einem Tabellenkalkulationsprogramm. + + + +Sobald die Ergebnistabelle angezeigt wird, kann ASYST die nächste Tabelle einlesen und verarbeiten. + +**ACHTUNG: Die Ergebnistabelle wird nicht automatisch gespeichert.** Werden die Ergebnisse nicht gespeichert, +wird die Erbgebnistabelle im nächsten Durchlauf überschrieben. +Daher sollte, um die Ergebnisse zu sichern, auf den **"Save as"**- Button geklickt und die Ausgabetabelle am gewünschten +Ort gespeichert werden. + +<h2 id=6>Wie arbeitet man mit der Ausgabe von ASYST weiter?</h2> + +Wir empfehlen die folgende **Vorgehensweise** beim Einsatz von ASYST: + +(Weitere Informationen und eine konkretes Beispiel für das Vorgehen liefert der +Artikel <a href="https://nlpado.de/~ulrike/papers/Pado22.pdf">_Assessing the Practical Benefit of Automated Short-Answer +Graders_</a>.) + +1) **Definition der Anforderungen**: Wie genau muss die Bewertung in meinem aktuellen Anwendungsfall sein? + <ul> + <li>Bei der Bewertung von Freitextfragen in eher informellen Testsituationen (keine Abschlussklausur o.ä.) unterscheiden sich auch <b>menschliche Bewertungen</b> in ca. 15% der Fälle - 0% Abweichung sind also auch für Menschen kaum erreichbar! </li> + <li>Wir empfehlen daher in solchen Situationen, eine Bewertungsgenauigkeit von mindestens 85% auch nach dem Einsatz von ASYST plus der menschlichen Korrektur anzustreben. </li> + <li>Zu Beachten ist zudem die Verteilung der Bewertungsfehler (Übermäßige Strenge/Milde)</li> + <li>Letztlich sollte die Verwendung des Tools den Anwender:innen eine Zeitersparnis bringen: Setzen Sie das verfügbare Budget oder eine angestrebte Mindestersparnis fest. </li> + </ul> + +2) **Sammeln von** manuell bewerteten **Testdaten:** + + Um einen Eindruck von der Genauigkeit und Zuverlässigkeit des automatischen Bewerters zu bekommen, werden annotierte + Testdaten benötigt, + d.h. Eingabe-Daten, für die eine korrekte Klassifizierung bereits festgelegt ist. Es werden also Daten im einlesbaren + Format benötigt, die bereits manuell bewertet wurden. Dies können z.B. Antworten aus früheren Tests sein. + Um den Datensatz möglichst robust gegenüber zufälligen Schwankungen zu machen, sollte er idealerweise einige hundert + Antworten umfassen -- aber kleinere Datensätze können natürlich ebenfalls verwendet werden. + +4) **Analyse** der Leistung der automatischen Bewertung + + Anhand der manuell bewerteten Testdaten kann nun gemessen werden, wie zuverlässig und treffsicher der Klassifizierer + für die spezifischen Fragen arbeitet. Damit bekommen Sie einen Eindruck davon, wie gut die Vorhersage für Ihren + eigenen Datensatz funktioniert. + + Hierzu werden die Fragen und Antworten aus dem Testdatensatz von ASYST verarbeitet und anschließend die erhaltene + Klassifikation mit der manuellen Bewertung abgeglichen (z.B. in einer Tabellenkalkulation wie Excel oder Libre Office + Calc). + + Dabei kann der Anteil der korrekt klassifizierten Antworten im gesamten Datensatz ermittelt werden - dieser sollte + 85% oder höher betragen (das entspricht einer Fehlerquote von 15% oder weniger). + + Sie können auch für die einzelnen Bewertungen (richtig/falsch) berechnen, wie groß die Präzision für die + verschiedenen Bewertungen jeweils ist. Die Präzision misst, wie viele Vorhersagen einer bestimmten Bewertung + tatsächlich richtig waren, d.h. wie vertrauenswürdig die Vorhersagen des Bewerters für ein bestimmtes Label sind. So + bedeutet eine Präzision von 75% für die Bewertung "korrekt", dass drei Viertel aller Vorhersagen von "korrekt" + gestimmt haben, aber in einem Viertel der Fälle die Antwort laut der manuellen Bewertung falsch war. + + _(Die Funktion, diese Kenngrößen der Zuverlässigkeit automatisch in einem Testmodus zu generieren soll in Zukunft dem + Programm noch hinzugefügt werden.)_ + +5) **Entscheidung** wie der Ansatz genutzt werden soll. + + Anhand der erhobenen Kenngrößen zur Zuverlässigkeit für die oben genannten Kriterien kann nun eine Entscheidung + getroffen werden. + <ul> + <li> Wie groß ist der Anteil der korrekt vorhergesagten Bewertungen? Beträgt er >85%, können Sie die ASYST-Vorhersagen sogar unverändert übernehmen, falls Sie dies wünschen. </li> + <li> Wie ist die Präzision der einzelnen Bewertungsklassen (richtig/falsch)? Wenn eine der Klassen deutlich zuverlässiger vorhergesagt wird, können Sie entscheiden, diese Vorhersagen ungeprüft zu übernehmen und <b>nur</b> die Vorhersagen für die weniger verlässlich erkannte Klasse zu überprüfen. Dies führt in der Praxis zu einer deutlichen Zeitersparnis. </li> + <li>Wie ist der Bewertungsfehler verteilt? Werden übermäßig viele korrekte Antworten als falsch bewertet, oder umgekehrt? Ist dies für Ihre Situation akzeptabel? </li> + <li> Wie viel Bewertungsaufwand hätten Sie für den Beispieldatensatz eingespart, z.B. indem Sie die verlässlichere Bewertungsklasse ungeprüft akzeptieren? + </ul> + +<h3 id=7>Wie kann ich ASYST ausführen, wenn ich kein Windows 11 nutze?</h3> +Die klickbare Anwendung "ASYST.exe" eignet sich nur für die Ausführung unter Windows 11. + +In anderen Betriebssystemen kann ASYST aus einer Entwicklungsumgebung heraus ausgeführt werden. +Der ASYST-Quellcode ist ursprünglich in Python geschrieben und kann daher robust in verschiedenen Umgebungen ausgeführt +werden. +Für Anwender, die mit dem Ausführen von Python-Programmen nicht vertraut sind, wird im folgenden eine Möglichkeit näher +beschrieben. +<h4 id=8>Ausführen von ASYST in der Entwicklungsumgebung Pycharm </h4> +<ol> +<li>Falls noch nicht geschehen, die Entwicklungsumgebung Pycharm aus dem Internet + <a href="https://www.jetbrains.com/pycharm/download/?section=mac"> herunterladen </a> und installieren. + Für mehr Informationen und Problemlösung siehe + <a href="https://www.jetbrains.com/help/pycharm/installation-guide.html"> Pycharm-Installationsguide</a>.</li> +<li>Python installieren + +Die Entwicklung von ASYST erfolgte in Python 3.10 - daher wird diese Version für die Ausführung empfohlen. +Die zum Betriebssystem passende Version kann unter https://www.python.org/downloads ausgewählt und installiert werden. +</li> + +<li> Den Quellcode aus Gitlab in die Entwicklungsumgebung herunterladen: + +Get from VCS + + +<img src="images/get_from_vcs.png" width="450"> + + +im Feld _url_ folgenden Pfad eintragen: git@transfer.hft-stuttgart.de:ulrike.pado/ASYST.git + + +<img src="images/svn_url.png" width="450"> + + +Anschließend auf _clone_ klicken und warten +</li> + +<li>Entwicklungsumgebung konfigurieren +**Python-Interpreter konfigurieren:** + +Navigiere zu _Settings >> Project ASYST >> Python Interpreter >> Add Interpreter >> Add local Interpreter_ + + + + + +_Location_: [Projektpfad]/[Projektname]/Source, + +_Base interpreter_: Pfad zur installierten Pythonversion + +*Benötigte Pakte installieren:* +Falls Pycharm nicht von sich aus vorschlägt, die in der requirements.txt aufgeführten Pakete zu installieren, +führe manuell über das Terminal von PyCharm folgende Befehle aus: + +''' +> cd Source +> +> +> pip install -r requirements.txt + +''' + +</li> +<li>ASYST ausführen + + + +Nachdem über das Projektverzeichnis links die Datei _main.py_ ausgewählt wurde, wird der ausgegraute _Startknopf_ oben +rechts +im Fenster grün. Ein einfacher Klick genügt, und ASYST wird ausgeführt. + +</li> +</ol> + diff --git a/asyst/README_EN.md b/asyst/README_EN.md new file mode 100755 index 0000000000000000000000000000000000000000..6752a7f8bc28e78424ff957f8f7f245abb7b1bd8 --- /dev/null +++ b/asyst/README_EN.md @@ -0,0 +1,236 @@ +<h2>Content:</h2> +<ul> + <li><a href="#1"> What is ASYST? </a> </li> + <li><a href="#2"> Which languages are supported by ASYST? </a></li> + <li><a href="#3"> How do I use ASYST? </a></li> + <ol> + <li><a href="#4"> What does the input look like?</a> </li> + <li><a href="#5"> How do I run ASYST on Windows 11? </a></li> + + </ol> + <li><a href="#6"> How do I continue with the output from ASYST? </a></li> + <li><a href="#7"> How do I run ASYST if I don't use Windows 11? </a> + <ul><li><a href="#8"> Running ASYST in the Pycharm development environment</a> </li></ul></li> +</ol></ul> + + +<h2 id=1>What is ASYST?</h2> + +ASYST is a program designed to support teachers as they grade free-text answers in tests: With the help of Artificial +Intelligence, +ASYST makes grade suggestions that can be reviewed and, if necessary, modified by the teachers. + +ASYST is intended for the evaluation of short answers that are one to three sentences in long. It is not intended to be +used for longer responses. + +ASYST helps the teacher by suggesting a grade. This assessment may well be incorrect in individual cases; the teacher +can check and correct it. +This saves time in two ways compared to completely manual grading: First, reviewing grades is generally faster than +grading from scratch; +and second, we recommend reviewing mostly those ASYST grades that are most prone to errors (see Section <a href="#6"> +How do I continue with the output from ASYST? </a>). + +The program is written in Python; the source code is publicly available. To make ASYST easier to use, the Python scripts +have been +converted into an executable that is usable in Windows 11. + +The technical background and development history of ASYST are described in <a href="https://rdcu.be/dxPLg"> Pado, +Eryilmaz and Kirschner, IJAIED 2023</a> along with a worked example for German data. For English data, a similar example +is available in <a href="https://nlpado.de/~ulrike/papers/Pado22.pdf">Pado, AIED 2022</a> + +<h2 id=2>Which languages are supported by ASYST?</h2> + +ASYST has been tested for <a href="https://rdcu.be/dxPLg">German</a> +and <a href="https://nlpado.de/~ulrike/papers/Pado22.pdf">English</a>. + +The language model that covers German can in principle handle other languages, as well. So, in principle, you could +select "German" as language setting and upload data in one of the other languages covered by the model. If you try this, +please check the results carefully, as this is +untested! (<a href="https://www.sbert.net/docs/pretrained_models.html#multi-lingual-models">According to the model +developers,</a> the covered languages are: ar, bg, ca, cs, da, de, el, en, es, et, fa, fi, fr, fr-ca, gl, gu, he, hi, +hr, hu, hy, id, it, ja, ka, ko, ku, lt, lv, mk, mn, mr, ms, my, nb, nl, pl, pt, pt-br, ro, ru, sk, sl, sq, sr, sv, th, +tr, uk, ur, vi, zh-cn, zh-tw.) + +<h2 id=3>How do I use ASYST?</h2> +We developed ASYST to be as user-friendly as possible. + +<h3 id=4>What does the input look like?</h3> + +The program works based on your data in Excel's .xlsx format (which can also be generated by Libre Office Calc and other +programs). This is an example table: + + + +The following information needs to be included in the **correct order** and with the **correct column headings**: + +1) **question**: The question that was asked +2) **referenceAnswer**: A correct answer / reference answer +3) **studentAnswer**: The student answer that is to be evaluated +5) (optional) **observed grade**: The grade given by the teacher can be entered here in order to evaluate the accuracy + of the ASYST predictions. + +The example table can be found +at <a href="https://transfer.hft-stuttgart.de/gitlab/ulrike.pado/ASYST/-/blob/main/DE_Demo_Daten.xlsx"> +DE_Demo_Daten.xlsx</a>. It contains some questions and answers from the CSSAG corpus (Computer Science Short Answers in +German) of HFT Stuttgart. The corpus is licensed as CC-BY-NC. + +<h3 id=5>How do I run ASYST on Windows 11? </h3> + +First, download <a href="https://transfer.hft-stuttgart.de/gitlab/ulrike.pado/ASYST/-/blob/main/ASYST.exe"> +_ASYST.exe_ </a>. +The program can be started by double-clicking its icon. + +The program will take a while to start (approx. 1 minute). During this time the system is initialized. + +**Note**: Windows Defender may warn against running the application because the program does not have a security +certificate. +By selecting _more information_ and then _Run anyway_ the error message disappears and ASYST can be executed. ASYST's +source code is open source so you can verify the code is not malicious. + + +<img src="images/win_def_de_1.JPG" width="450"> +<img src="images/win_def_de_2.JPG" width="450"> + +After the program has been started, a window appears. First, select the language of the answers to be evaluated. +The table to be processed can then be selected by clicking on the “Input File†field. The data should be arranged as +described above. +After clicking on the “Start†field, ASYST begins processing the data. Again, this can take a while (1-2 minutes, +relatively independent of the amount of data being processed). + +Once the program has processed all answers and made predictions, a table view headed "Results" opens. + +The results table contains all columns of the input table, as well as the grades suggested by ASYST -- see the the " +predicted grade" column. The grades for answers classified as incorrect are highlighted in red. You cannot make change +in this table. Instead, save the data by clicking on “Save as†and then open the resulting .xlsx file with a spreadsheet +program. + + + +As soon as the result table is displayed, ASYST can read and process the next input table. + +**ATTENTION: The results table is not saved automatically.** +Therefore, to save the results, the **"Save as"** button should be clicked and the output table should be saved at the +desired location. + +<h2 id=6>How do I continue with the output from ASYST?</h2> + +We recommend the following **process** when using ASYST: + +(Further information and a concrete example of the procedure can be found +in <a href="https://nlpado.de/~ulrike/papers/Pado22.pdf">_Assessing the Practical Benefit of Automated Short-Answer +Graders_</a>.) + +1) **Define requirements**: How accurate does the grading need to be in my current use case? + <ul> + <li>When evaluating free text questions in low-stakes test situations (not in a final exam or similar), <b>human grades</b> differ in around 15% of cases! </li> + <li>In such situations, we therefore recommend aiming for a grading accuracy of at least 85% after using ASYST plus human review. </li> + <li>The distribution of grading errors (excessive strictness/leniency) should also be taken into account</li> + <li>Ultimately, using the tool should save users time: set the available time budget or a minimum requirement for time saved. </li> + </ul> + +2) **Collect** manually evaluated **test data:** + + To get an idea of the accuracy and reliability of the automated grader, annotated test data is needed. + This is input data for which a grade has already been determined. This can be answers from previous tests, for + example. + To make the data set as robust as possible against random fluctuations, it should ideally contain a few hundred + responses -- but smaller data sets can of course also be used. + +4) **Analyze** the performance of the automated grading + + The manually graded test data can be used to measure how reliable and accurate the automated grader is for the test + data. This will give you an idea of how well the grade prediction works for your own data set. + + For this purpose, process the questions and answers from the test data set using ASYST and compare the grade + predictions with the manual assessment (e.g. in a spreadsheet such as Excel or Libre Office Calc). + + The proportion of correctly classified answers in the entire data set gives you the system accuracy (which should be + at around 85% or higher, which means disagreement between the manual and machine grades of 15% or less). + + You can also calculate the precision for each grade ("correct"/"incorrect"). Precision measures how many predictions + of a given grade were actually correct, i.e. how trustworthy the ASYST's predictions are for a given label. A + precision of 75% for the rating "correct" means that three quarters of all predictions of "correct" were in fact + right, but for a quarter of the cases the answer was actually wrong according to the manual grades. + + _(We plan to add functionality to automatically generate these reliability parameters in the future.)_ + +5) **Decide** how to use ASYST's predictions. + + A usage decision can now be made based on the reliability parameters collected for the criteria mentioned above. + <ul> + <li> How large is the proportion of correctly predicted reviews? If it is >85%, you can even adopt the ASYST predictions unchanged if you wish. </li> + <li> What is the precision of the grade labels ("correct"/"incorrect")? If one of the grade labels is likely to be significantly more reliable, you can decide to accept these predictions without review and <b>only</b> check the predictions for the less reliable grade predictions. In practice, this leads to significant time savings. </li> + <li>How is the grading error distributed? Are correct answers frequently predicted to be incorrect, or vice versa? Is this acceptable for your situation? </li> + <li> How much evaluation effort would you have saved for the example data set, e.g. by accepting the more reliable grade label without review? + </ul> + +<h3 id=7>How can I run ASYST if I don't use Windows 11?</h3> +The clickable application “ASYST.exe†is only suitable for running on Windows 11. + +On other operating systems, ASYST can be run from a development environment. +The ASYST source code is written in Python and can therefore be robustly executed in various development environments. +For users who are not familiar with running Python programs, one option is described in more detail below. +<h4 id=8>Running ASYST in the Pycharm development environment </h4> +<ol> +<li>If you haven't already done so, the Pycharm development environment from the Internet + Download <a href="https://www.jetbrains.com/pycharm/download/?section=mac"> </a> and install. + For more information and troubleshooting see + <a href="https://www.jetbrains.com/help/pycharm/installation-guide.html">Pycharm installation guide</a>.</li> +<li>Install Python + +ASYST was developed in Python 3.10 - therefore this version is recommended for execution. +The version that matches the operating system can be selected and installed at https://www.python.org/downloads. +</li> + +<li> Download the source code from Gitlab to the development environment: + +Get from VCS + + +<img src="images/get_from_vcs.png" width="450"> + + +Enter the following path in the _url_ field: git@transfer.hft-stuttgart.de:ulrike.pado/ASYST.git + + +<img src="images/svn_url.png" width="450"> + + +Then click on _clone_ and wait +</li> + +<li>Configure development environment +**Configure Python interpreter:** + +Navigate to _Settings >> Project ASYST >> Python Interpreter >> Add Interpreter >> Add local Interpreter_ + + + + + +_Location_: [Project Path]/[Project Name]/Source, + +_Base interpreter_: Path to the installed Python version + +*Install required packages:* +If Pycharm does not itself suggest installing the packages listed in the requirements.txt, +manually run the following commands in the PyCharm terminal: + +''' +> cd Source +> +> +> pip install -r requirements.txt + +''' + +</li> +<li>Run ASYST + + + +After the file _main.py_ has been selected via the project directory on the left, the greyed out _Start button_ at the +top right of the window will appear green. A single click is enough to execute the ASYST code. + +</li> +</ol> diff --git a/asyst/Source/LICENSE b/asyst/Source/LICENSE new file mode 100755 index 0000000000000000000000000000000000000000..23941714ca965eccdd4ec3ec4879cd16936ca5a1 --- /dev/null +++ b/asyst/Source/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Larissa Kirschner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/asyst/Source/Skript/german/models/clf_BERT.pickle b/asyst/Source/Skript/german/models/clf_BERT.pickle new file mode 100644 index 0000000000000000000000000000000000000000..9504f92999e1fd1395acabf956c6a81ef4352ac8 Binary files /dev/null and b/asyst/Source/Skript/german/models/clf_BERT.pickle differ diff --git a/asyst/Source/Skript/german/run_LR_SBERT.py b/asyst/Source/Skript/german/run_LR_SBERT.py new file mode 100755 index 0000000000000000000000000000000000000000..e4f169ef1e2fabdd60c40a6e11be5ade14eba3f9 --- /dev/null +++ b/asyst/Source/Skript/german/run_LR_SBERT.py @@ -0,0 +1,146 @@ +import os +import sys +import time +import numpy as np +import pandas as pd + +# UP +import pickle +import argparse + +from sklearn import metrics +from sentence_transformers import models, SentenceTransformer +from sklearn.linear_model import LogisticRegression, Perceptron +from sklearn.metrics import confusion_matrix +from sklearn.model_selection import cross_validate, cross_val_predict + +__author__ = "Yunus Eryilmaz" +__version__ = "1.0" +__date__ = "21.07.2021" +__source__ = "https://pypi.org/project/sentence-transformers/0.3.0/" + + + +def main(): + parser = argparse.ArgumentParser() + + # Where are we? + location = "."; + if getattr(sys, 'frozen', False): + # running in a bundle + location = sys._MEIPASS + + # Required parameters + parser.add_argument( + "--data", + #default=None, + default="/var/www/html/moodle/asyst/Source/Skript/outputs/test.tsv", + type=str, + # required=True, + required=False, + help="The input data file for the task.", + ) + parser.add_argument( + "--output_dir", + # default=None, + default="/var/www/html/moodle/asyst/Source/Skript/outputs", + type=str, + # required=True, + required=False, + help="The output directory where predictions will be written.", + ) + parser.add_argument( + "--model_dir", + # default=None, + default=location+"/Skript/german/models", + type=str, + # required=True, + required=False, + help="The directory where the ML models are stored.", + ) + args = parser.parse_args() + + # open a log file next to the executable with line buffering + # out = open("log.txt", "a",buffering=1); + + # print("Started German processing in",location,file=out); + + # import SentenceTransformer-model + start_time = time.time() + + # print("Reading from",args.data, file=out); + + with open(os.path.join(location,args.data)) as ft: + dft = pd.read_csv(ft, delimiter='\t') + + # Sentences we want sentence embeddings for + sentences1_test = dft['referenceAnswer'].values.tolist() + sentences2_test = dft['studentAnswer'].values.tolist() + # print("Input read:",sentences2_test, file=out); + + # Use BERT for mapping tokens to embeddings + word_embedding_model = models.Transformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2') + # pooling operation can choose by setting true (Apply mean pooling to get one fixed sized sentence vector) + pooling_model = models.Pooling(word_embedding_model.get_word_embedding_dimension(), + pooling_mode_mean_tokens=True, + pooling_mode_cls_token=False, + pooling_mode_max_tokens=False) + + # compute the sentence embeddings for both sentences + model = SentenceTransformer(modules=[word_embedding_model, pooling_model]) + # print("Model loaded", file=out); + + sentence_embeddings1_test = model.encode(sentences1_test, convert_to_tensor=True, show_progress_bar=False) + # print("Embeddings RefA:",sentence_embeddings1_test,file=out); + + sentence_embeddings2_test = model.encode(sentences2_test, convert_to_tensor=True, show_progress_bar=False) + # print("Embeddings found", file=out); + + # Possible concatenations from the embedded sentences can be selected + def similarity(sentence_embeddings1, sentence_embeddings2): + # I2=(|u − v| + u ∗ v) + simi = abs(np.subtract(sentence_embeddings1, sentence_embeddings2)) + np.multiply(sentence_embeddings1, + sentence_embeddings2) + + return simi + + # calls the similarity function and get the concatenated values between the sentence embeddings + computed_simis_test = similarity(sentence_embeddings1_test, sentence_embeddings2_test) + + # get the sentence embeddings and the labels fpr train and test + + X_test = computed_simis_test + # Y_test = np.array(dft['label']) + + # UP: read pre-trained LR model + clf_log = pickle.load(open("/var/www/html/moodle/asyst/Source/Skript/german/models/clf_BERT.pickle", "rb")) + + + # print('--------Evaluate on Testset------- ', file=out) + predictions = clf_log.predict(X_test) + + # UP print results + with open(args.output_dir + "/predictions.txt", "w") as writer: + writer.write("question\treferenceAnswer\tstudentAnswer\tsuggested grade\tobserved grade\n") + for i in range(len(dft)): + hrpred = "incorrect" + if predictions[i] == 1: + hrpred = "correct" + writer.write( + str(dft.iloc[i][0]) + + "\t" + + str(dft.iloc[i][1]) + + "\t" + + str(dft.iloc[i][2]) + + "\t" + + str(hrpred) + + "\t" + + str(dft.iloc[i][3]) + + "\n" + ) + + # print('\nExecution time:', time.strftime("%H:%M:%S", time.gmtime(time.time() - start_time)),file=out) + + +if __name__ == "__main__": + main() diff --git a/docker-compose.yml b/docker-compose.yml index e5f4f3adb1e247693c8ec451140d9bcb5e93d9ef..0932d6924e080be03aac910f01965be5536db03b 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,10 +3,11 @@ version: '3.8' services: mariadb: image: mariadb:11.3 + restart: always env_file: - ./.env volumes: - - moodledata:${MOODLE_BASE_DIR_DATA} + # - moodledata:${MOODLE_BASE_DIR_DATA} - mariadb_data:/var/lib/mysql ports: - 3306:3306 @@ -25,6 +26,7 @@ services: moodle: env_file: - ./.env + restart: always build: # Собираем Ñвой образ Moodle из Dockerfile+. context: . # КонтекÑÑ‚ Ñборки (где находитÑÑ Dockerfile+.) dockerfile: Dockerfile @@ -37,14 +39,14 @@ services: - MOODLE_DATABASE_USER=${MOODLE_DATABASE_USER} # Пользователь базы данных - MOODLE_DATABASE_PASSWORD=${MOODLE_DATABASE_PASSWORD} # Пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±Ð°Ð·Ñ‹ данных ports: - - 80:80 # Порт на хоÑте:порт в контейнере - - 443:443 # Порт на хоÑте:порт в контейнере -# - 80:8080 # Порт на хоÑте:порт в контейнере -# - 443:8443 # Порт на хоÑте:порт в контейнере - depends_on: # ЗавиÑимоÑть от ÑервиÑа MariaDB + - 80:80 + - 443:443 + - 5000:5000 + depends_on: # Dependency from MariaDB service - mariadb volumes: - - ./yourplugin:${MOODLE_BASE_DIR}/local/yourplugin # Синхронизируем папку плагина Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð¾Ð¼ + # - ./yourplugin:${MOODLE_BASE_DIR}/mod/yourplugin # Синхронизируем папку плагина Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð¾Ð¼ + - moodle_plugin:${MOODLE_BASE_DIR}/mod/yourplugin # Синхронизируем папку плагина Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð¾Ð¼ - moodle_data:${MOODLE_BASE_DIR} # Том Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… Moodle - moodledata:${MOODLE_BASE_DIR_DATA} # Том Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… Moodle networks: @@ -54,6 +56,7 @@ services: interval: 10s timeout: 5s retries: 5 + command: [ "bash", "-c", "apache2ctl -D FOREGROUND" ] volumes: moodledata: driver: local # Локальный драйвер томов @@ -61,7 +64,8 @@ volumes: driver: local moodle_data: driver: local + moodle_plugin: + driver: local networks: - network: # Создание пользовательÑкой Ñети - driver: bridge \ No newline at end of file + network: # Создание пользовате \ No newline at end of file diff --git a/install_moodle.sh b/install_moodle.sh new file mode 100755 index 0000000000000000000000000000000000000000..c26102584d511142c22f1849f1e23a702d9f5c21 --- /dev/null +++ b/install_moodle.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Import environment variables from .env +set -a +. .env +set +a + +# Install Moodle +docker-compose exec moodle php ${MOODLE_BASE_DIR}/admin/cli/install.php \ + --wwwroot="${MOODLE_WWWROOT}" \ + --dataroot="${MOODLE_BASE_DIR_DATA}" \ + --dbtype="mariadb" \ + --dbname="${MOODLE_DATABASE_NAME}" \ + --dbuser="${MOODLE_DATABASE_USER}" \ + --dbpass="${MOODLE_DATABASE_PASSWORD}" \ + --dbhost="${MOODLE_DATABASE_HOST}" \ + --adminpass="${MOODLE_DATABASE_ROOT_PASSWORD}" \ + --fullname="${MOODLE_FULLNAME}" \ + --shortname="${MOODLE_SHORTNAME}" \ + --agree-license \ + --non-interactive + +#docker-compose exec moodle chown -R www-data:www-data /var/www/html/moodle +docker-compose exec moodle chmod -R 755 /var/www/html/moodle + +# Set correct access rules for the plugin +#docker-compose exec moodle chown -R www-data:www-data /var/www/html/moodle/mod/yourplugin +#docker-compose exec moodle chmod -R 775 /var/www/html/moodle/mod/yourplugin + +# Create the run_sag script file +docker-compose exec moodle bash -c 'echo "#!/bin/bash" > /usr/local/bin/run_sag' +docker-compose exec moodle bash -c 'echo ". /opt/myenv/bin/activate" >> /usr/local/bin/run_sag' +docker-compose exec moodle bash -c 'echo "cd /var/www/html/moodle/asyst/Source/Skript/german" >> /usr/local/bin/run_sag' +docker-compose exec moodle bash -c 'echo "/opt/myenv/bin/python3 /var/www/html/moodle/asyst/Source/Skript/german/run_LR_SBERT.py" >> /usr/local/bin/run_sag' + +# Make the script executable & run it +docker-compose exec moodle chmod +x /usr/local/bin/run_sag +docker-compose exec moodle /usr/local/bin/run_sag diff --git a/readme.md b/readme.md index d9104c44a46b932539c5f53155e52b374a8d8f31..f3c8a29677dcd66de5f5681a6f43ea20dc18abaf 100755 --- a/readme.md +++ b/readme.md @@ -1,9 +1,15 @@ +### How to wrap up and run Moodle Server: -How to run Moodle Server: +Run these commands at CLI to use ASYST with universal BERT model based on German language. ~~~bash docker-compose up -d --build -docker-compose exec moodle php /var/www/html/moodle/admin/cli/install.php --wwwroot=http://0.0.0.0 --dataroot=/var/www/html/moodledata --dbtype=mariadb --dbname=moodle --dbuser=moodleuser --dbpass=moodlepassword --dbhost=mariadb --adminpass=rootpassword --fullname="Moodle Site" --shortname="Moodle" --agree-license --non-interactive -docker-compose exec moodle chown -R www-data:www-data /var/www/html/moodle -docker-compose exec moodle chmod -R 755 /var/www/html/moodle +install_moodle ~~~ + +It is suggested to use our moodle plugin to communicate with ASYST script using such a +route http://127.0.0.1:5000/api/data + +Now the preinstalled MOODLE LMS is available at https://www.moodle.loc + +**Note**: Bind https://www.moodle.loc to your localhost at **hosts** file depending on your OS. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000000000000000000000000000000000000..4bcbfa47423a8d4e119e535a4e3fc2909a292179 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +torch +Flask +matplotlib +scikit-learn +transformers +pandas +sentence_transformers \ No newline at end of file diff --git a/yourplugin/lang/en/yourplugin.php b/yourplugin/lang/en/yourplugin.php index b2af31bf17297103fd273b2c2af1bd42c37c9eeb..28c38a631ffd93aed3443b05bf2a688e610edf1f 100755 --- a/yourplugin/lang/en/yourplugin.php +++ b/yourplugin/lang/en/yourplugin.php @@ -7,4 +7,35 @@ * @license http://www.gnu.org/copyleft/gpl.html gnu gpl v3 or later */ -$string['pluginname'] = 'New local plugin'; \ No newline at end of file +$string['pluginname'] = 'New local plugin'; + +// Path to the Python 3 executable +$python_executable = '/usr/bin/python3'; + +// Path to the moodlemlbackend script to be executed. First we use test API api.py, then run_LR_SBERT.py +$python_script = '/var/www/html/moodle/api.py'; +//$python_script = '/var/www/html/moodle/asyst/Source/Skript/german/run_LR_SBERT.py'; + +// Python command you want to execute +$python_command = 'print("Hello, world!!!")'; + +// Formation of a command to execute +//$full_command = $python_executable . ' -c \'' . $python_command . '\''; +$full_command = $python_executable . ' ' . $python_script; + +// Execution the command and getting the result +$result = shell_exec($full_command); + +// Output the result +echo $result; +// Output the result (assuming moodlemlbackend returns JSON) +$data = json_decode($result, true); +if ($data !== null) { +// Data processing +// Example: output results + echo "<pre>"; + print_r($data); + echo "</pre>"; +} else { + echo "Error on data processing from moodlemlbackend!"; +} diff --git a/yourplugin/version.php b/yourplugin/version.php index 66d76276973df72a801112f1f1aeaaf32c23969e..452923b847f66bcf28f5037b26fdd6754c49eae6 100755 --- a/yourplugin/version.php +++ b/yourplugin/version.php @@ -11,5 +11,5 @@ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2022051101; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2014050800; // Requires this Moodle version. -$plugin->component = 'local_yourplugin';// Full name of the plugin (used for diagnostics). +$plugin->component = 'yourplugin';// Full name of the plugin (used for diagnostics). $plugin->cron = 0;