From c1481f7275482f7ace6c207523923d2b7a93ab6f Mon Sep 17 00:00:00 2001 From: Artem Baranovskyi <artem.baranovsky1980@gmail.com> Date: Tue, 18 Jun 2024 21:30:25 +0300 Subject: [PATCH] Fixed whole Docker infrastructure with dummy moodle plugin. All necessary input data are provided. Python ASYST script (run_LR_SBERT.py) is set with absolute paths. ----------------------------------------------------------- Result: On script execution we obtain just once the result at /var/www/html/moodle/asyst/Source/Skript/outputs/test.tsv ----------------------------------------------------------- TODO: Create an API to use script run_LR_SBERT.py on http://127.0.0.1:5000/api/data or like that. Configure relative paths at ASYST script (run_LR_SBERT.py). --- .env | 10 +- .gitignore | 6 +- Dockerfile | 124 +++++++-- api.py | 21 ++ asyst/DE_Demo_Daten.xlsx | Bin 0 -> 11381 bytes asyst/README.md | 7 + asyst/README_DE.md | 249 ++++++++++++++++++ asyst/README_EN.md | 236 +++++++++++++++++ asyst/Source/LICENSE | 21 ++ .../Skript/german/models/clf_BERT.pickle | Bin 0 -> 3924 bytes asyst/Source/Skript/german/run_LR_SBERT.py | 146 ++++++++++ docker-compose.yml | 22 +- install_moodle.sh | 38 +++ readme.md | 14 +- requirements.txt | 7 + yourplugin/lang/en/yourplugin.php | 33 ++- yourplugin/version.php | 2 +- 17 files changed, 891 insertions(+), 45 deletions(-) create mode 100755 api.py create mode 100755 asyst/DE_Demo_Daten.xlsx create mode 100755 asyst/README.md create mode 100755 asyst/README_DE.md create mode 100755 asyst/README_EN.md create mode 100755 asyst/Source/LICENSE create mode 100644 asyst/Source/Skript/german/models/clf_BERT.pickle create mode 100755 asyst/Source/Skript/german/run_LR_SBERT.py create mode 100755 install_moodle.sh create mode 100755 requirements.txt diff --git a/.env b/.env index 964e458..98be37a 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 aae1073..858d25f 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ -/.idea -/.git +/.idea/* +/.git/* +.idea/* +/.idea/ diff --git a/Dockerfile b/Dockerfile index 350cdec..1c797eb 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 0000000..65c8f17 --- /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 GIT binary patch literal 11381 zcmeHt1y@|j)^-!zU4jG;?hu^D-CcvbOCY#IfMAWg2X}W3(81k35Zoa+A2W0BJ2RR4 z{epX|*Q#2l*V+4=Q}yh6YKx)_Bor0^1^@>D07wBw#~BvyApn3FC;$Kx0QX8q#NN)u z)Xqg;)!o6=S	ftqn;o)GO+2z^j-0|JVMDXP_*8NWPaDP3))SgUELV>E#+hIF6%$ z0SsCtfv&!|{t{!IOiRn>%&>bj;T&u$&T5RYWlz?#5sMl-+lGKo{jJJK5&nZ+YVQd+ znZ6DjQg-6L203YKon&JX2(rA^*N-$y10*{(_A0ZBZU{-2;agzi2>5MfEDornuk|-0 zm1q}n4=#1D%d4-VbA2nGLfe|aoVK#0@qB-=#UKS0LFT!P<NCfpkyKNK#z?u@=`Km8 z!<o8?ZN|X()hcsHOgqZT=o(CG2j?3(cKn*+@XHeI{upbzPA^?Ak51~Sh)c!0mUq|| z`V2amg8rldlk)&Y>xep>a#p)B?>-=Qp6t+R56Q|s<pw5U-x`5QOJ;P8i98;eE&Y1I zK&GeyHz#d?PvIcAiK|QD$e7T}?#l%1cPO!&XRK@Vy_SnEVKi_TDTR0F(fZ&Xujk?T zwoc&jS>m2A>k|wB@cax3Q2d)&)~hj-U%p^X_QmQDU(8b9$<)S~iSf7of9CjKY=eLK z^fHi~LN7B?$cf}b=-|(pl^8T(88;!xR#H_TKdEKZ`p7&Af|X7xLNrzUKu8JScAtlD zODlYl`-7y{o9tx~7+AdI4Q}NjNq3GPU}@hvC5k(iZS<kL&Ror0r$|V<Q@gfD)0Q?B z<;Z~7$i=75M61!p7&Y+WF$)MoaQIXFwfp6?R*h~dAZCPBj><!-8acD~<Hpi_=Mul{ zAp<{g%N|aqU=KPQnJ-j$4cd@i-QugMSa4fb8D%>0kh$xd*mPZprgdUIdNIhS4=R(f zW8AQgNeobCU-@d+v7ZfPxc70w_m&Qxf&(Imi&kG4>Yqm9FA$$}@iHSVFGhk7fP?sG z!}N!pxY;{d8`;}i|HfYbwi$>Q3VYG=-`&cT<z)Jp(b^H8LYdvtT(Qv?T$soX)ecbM zz;!fBZ%NsFF4qWXTl6$%WtbrCL)=eB23&t~plm{7UUkzIg=0W@VA`DULfemAj6lK} z9hJWckbuU-INU!dJwilDb;fKK01eV-VsY)<P*c7R&HF+odf7Y~!frLn{DIZVd7S9m z3ucDuzWdz;sT`IE)HODeq|%seKR1gkUBhGrxD!uYyoQ(JLv{yD>`s%?-E@mx!=1N1 zn8~@1T6gE&A#D?u%DgGz;P(n~AqgFnAoisJIdA8tw5pwKxCq~Wqv>2arysgJG5Zc4 zm|1&S>3>2dZ@bB#0}=q>garUlU+#E;%wNHhuO?@|#D&(*H2$1T>7+)@(_jN1i?~!% z4Y4Q|lYdm5UEnC1jG+b!C&Ict;f<%Ks$g1Bue!~NeX};)_FB((Icd`Km2FT7Mh_$8 zrcgq$u4**=?RnKXRUccT26s|PKoDObDRCk3Q_Ct%yB=Nr6<RhcJWW}-v9z4JAb6yp zBu98id=I3vyf0y8h0MnZ?Z-e#1SKRX!$><x+IPo~XH|>-I-k~By2u7LSI8;iQjXMW zDlcKdb6vWkQSQjRqzv7NA-`&jf%@zleTREl{El^)-O0k>lJ!IIjX4BL;1dOV29a90 zEM4BaYm6LAiMwH69L0Wl;VNKs_kB!=YHyqaH($-<hJ6h}wB`mK9^w;TWKNxSc^_We znkWHLGxFf22RVh;QU1YM%TrPkqYCIFh@f>iIGB&rc)5fqeR*7t-#$o`4zZt}%*7-A zqWs!v{#1Ms7Rw1W8a2d_9j}>636ITENMpH2SPkdH$I}A^jyWSHgkXf9$LkX0>;{H8 z9pf5=?l>3q&D#y9_zalBop>&p@024L#<7NHOHw;xDS?&#&!n=M-1amrOG^8*oh?zr zF3S-ovsS2coO@KVUHra1E(VhqBK4~VZB%Q%QAu$#RszzGU;~zOE%wh3)X4=;PUzxW zhIlX+hL-{FcbP}A>}?z+t9xY!(JtK0?uLK12SYoOpU++R!h{aFT`-B*dpc&em|d%N zjkbk%+qOS)Ds5ZMwVW?kN<i>5SR=2A+96WKl!DJzfh2DbO?bN*CHRKs+$uyU^SzO` zPq^NG57Jq5)Y;f>-3TJ^7OAk!maNHWFTs9<)DMjBs?un^-Y1K+CTdl=lp9@?y=Kbo z5QA=}!wqt;<@M8|Pdxc~vAq&Vm+^V%{tX++)Kh*ZlNm03ha{7xgWQ@ywzT}&*&|ZK zH@PUB5Xb{%<D+~M28m1=-`(BrRUg)d4AgB3>{VWCEafr|7oz&d5;S@k|7ya}KnE6h z*e8Sj3a|b|a$g?~!rRhqD-Od6GCk2!T>5+*4)O0|62qF2Yc0I<%Rr6UJ&Wcs!O@nO z4dY!!g~;o*wmskfXko{8JPY4mHsrgPa}Dwz7Ut~YZe!~F+h$y*remMRjOCM6_iS*R zfp0Mgf-6e=BALKrsmx<piIUt`!Zhg0Q)Bt;Js^lt;@W8E{wX@zyW=7w0(DP~4%)+{ z->ICHP%j9NMQuO4)HVdTg4>Nmeo$0WG#+kx(?#F$ZLLG9oENTPm1PG_kUDK6!+9hC zP3Jf{|5}(+wp*$^G9RVEOvc6-ue^*C6wqhLMG0~W_6!Q9e})oOzNoSfP#y~5>DUNp z6$uTFrN?d5DL`I<%U%@6)XsgEnu=GyvztF9a6#^FSvOPP3ee3xNKHEAUg1u`)Xt0r z+<uT$67IQ?IxKgmoD9Od9`wF-$eh*Yj*xEGVC-c<yQ0zLqka^_euAUrTmGhUkIk<P zk%||`$51~GlXCR7R}9@1SgEdB^R&o;?Pc7gF{|q2xI5E+7KM)(IlgsE*T=SZ`=Fr! zY1gRP^+Wjc<`K3#LgYrW5_Ed5PzR8G90S3lsSsA8v%Q_;674H^(9Z?s!X-}*+I}b5 zGHd#MLSeuR3WmXr>ko}Wf}1sqAK8`Xb(=1w*w_MM5)ndv4$^P?7CTGFt}qW9#I2YR z_v}iMdJ(U{{NZSWB-bAw`?sPeJPy%qkm8@;;M8BiKby~@pL(WDgYhT6pu?`kc92Hv z`maz!D_}SvK;MQ8pSGk)ehEM!hRYerL>!nw+<>&2$;8C>2px_7#5h9*jF}6caba41 z++*%FzlAKldEb+VZ|D6zdhr9=Yk?uRj^l~xdxP@U+EX|KG0$GMha<CFyN(u`O#>W8 z^X~5;%5FZbiU1R*cHQ!Dcf8QKHHpA|;(k?5jhwy-6GLbuHZ~~U82zjdF(VgW3fB^# zETWsowk&T1!g{iskn#*z3u+DCwaW&Og>BBb)U-*3oAmL!Z*w6^VO<4I#3|rJ$-Hgi zncdgSsm2M1TGEFSib^2)5v~68LLUF56-`*qJ^2?(=_2{fi~gNfTr5m&O__f0S$>25 zq1H$Q0Vh@`?i~=x+3kU2E1Gh3eat3qg~B8wp0K{*P)VJQ71Tz6`HGVJN|`#pAW7Js zKYmgW61n{{8lIwVk9dM=WS+cyn<C9dTH6&lLgJ~tu<&Q5kH>|}*<^dNheR@B4=7Q; zL-CwH{quY>#Z;oNH5WCzmx5&cXLM6|yIVy12brZTA18EMFx<dA<gKVpP9m`s_Yy76 zSGbVarY<us|FyTD2PAvQvv39oi2_%Xap($^%kjuTH}3<C6g|CJNy!iGnP#qOcIERG zA<4h}Oi*r%A|g)27N!?Xayo&VNJM4(yl{rL7S|yW8*?f$#Iy(OZ1S%D)WAwg%Q=Ye z1o@Z*Hhs0#8=e`bfT|t`BZN1-NcV^@xXn|ce=>JhpCEuNn1^1*UjKDgtI{P9$=YwS z5@n^`qf)!!G~{VNb>v9Vo4yUE;4YBk!C)MkN&6$R^w|c!z#%&?zfLDi!ObFm$9t=v z0WAgkfn?I4UJe(UGPTyBnF<n2akunSGd!gI1X=f}02@uyq*S9GjAoiSBbTHz2mn?L znG}WsquIv*@t96MQ7{D6Dr1Ux%ty9(W{BPbX-mbD9^WhYOHLxCy5LyS^21j$eTy+Q z1DNFUW;NUT5ak^Z?q`P!7oiGSz=xyTJc%*lC(uZ_nwAqUbxNvJrO(6N$w}ww)7@35 zMs%lCp+Fe!+o$a@{f>vn=(*xh>>m{$&yM1f6tdcGj!S{Q9*5(rJG)&$s8XMU-H?er zIkk`wUFM@vZ}uoc(8&^^!UY>eKIn_%oG!jn!mS9j#a-R$Vr5+4zSSF=ef%^=={W4g z5zesw#<;GxX$nGPMmHoh^ulC6Gkr{MSuQ9_*V#?U2)YTF1<{U?^vy1afz4hqUXuMQ zd}8KZB$3gf<_eK8edlp3x_N+HzFX)=BGGil*C0r`Sf?B!3=v%%Mo7}>MEh$yPa<)> z(&G(s0{Ep@N}*>WvJ9N>#ht^9lD?6K7w?_wQIIFa-XjXII(n0mPO8YJ%n=)t>axyp zm(9W5sTtt8&HvmbYlzhai6o8c^(BWLR`=QkZKh0_fkfY4vpK@igtrmMwyb*&uafS+ z-t+@SZgj|1VIOm1b~BJ@Oy%<lO*1(kf7&)3K74G-#thP<pW3PZT45`nzA%xZP(Ho- zH96Oqy??&-Dy267B~43UEV2UwqV&)}!$?oawW8z)6yo7ti&+MlTUeE{E3v`?jOR5D z)hBa*5Z;+wYNgP0`E;<#s8qq+-tIWmdve7ap$@JLCp|wD^5*-ry46oHA6$#gH%8~6 z8#jNx^F+GdUYR<UiRms(gfQ~8UPD5!e>;e2_9?r|VS?e4=Ej)VbaTnq9r@<4cFPN9 zK|_-nUKXiU&4+Yq&mP~xLq}X@bH&pp>`sN^+Aw8Tc`U9phv)8^FQGeNWF#suk9md$ z#}Bp0=gvy2cSqY7+B<ED+?A%f_WH#6iQpmJBAau@=;PZy0v!QN;k^!B#Wp&ZIf*WU zk&l4D7NP=AP$|wjeL$sFAh<`4dy@5y`MEP$-Xq*dHizo$$Y}APszNZQ@hcv24^2*` zGx(L36ZYtz^IS(Ri9;o&DJ_a5DbYziGh8mkCgBw`7so5o?Z=_=ACf*;`hoZ((fdsr z(A7fGueM1<H$I5(CS-(R%Y|Yi7x=s`F~!oT08FVX`D@srzMt0d!OJHyvFI0a7f^SU zP6H3^maL~+=5un#rM?DGUb8};OL8WZ6C@R?Cw*De5nW{Mk>p&0BS$9xh(1~~Wz(Ex zT9)Q6$#4-*m)J_mnYVg_R;^Cq6hL5M#0o9fww0(~8sd<}DqNcg^p9fkiZqYm6>k4P z$`g#36#IQI#242r#gWugQna|2V=vzZ4Ku7+LTdSZ=3HYz5OaidvB3!%ZX=JQ0>19N z`ZcUjW8h~hOg@m=d?fnz-X%Joz&65<O6`Z0ZfVd6>GJ)=%{*_mvk#_Fc<@z?(|R&o z6Bl*iDj{YQybiinrY{xBm(Q*vrPLWBdtAA-aHdq@Qad!dal79LAM4Kj&*IBp6Sf@p z1Qzoctldw0UnrIHna7y<m}!^g%FA)4_%w;ER?z}Q8A_G+XHTZdezfd>4oH+T3i}A; zR~os{kfzST^i%O)57^7NcnRv|czXl7PDO14*VN5}rZ7)D&I6ahWooc}H5Jogl}tk; zI<~G3xPy7HKSP~qgHb4#wVa{E^gSR`CSh!1Jy}c9H_|wN<ZrJr1s`SWz_$h~lON&+ zSSix7_qf)Nqx4!e6DP{F%Wp#v(zAvS8G0xI{pgTd1}hG(ZWa@~+u916nT;G{_vmhO z-|6ZvB+*6DdD<7*?RZB6_LeKvU`DKJRp{7DkAz5fKi~(OHO|spTCI54j~|3Y?yUQt z5Lr5mSGWdhcPbSnw5|v%($QQHj0p1=sV)k&uk6Ae!D_vRq*K@<zkqJiSgL>g&1d^3 z{VGq=S<b!?^9dpVfcFRe{^r#=TbP=<I5Yh|{LaDYDnn5($IlgweW2zlETq&pRPbkU z%t)TJlKsnS*I`P{YL@y8jnXI2N>YkgGPMbks>q{@rW<BoJ_|8dgA8^#p*ZR<Q22(@ z3uTCRk4r<l{un>pRh&%msdv!{y>-1FnAZqe9Xb4{2FIHMW>*`zjpe7an<Hcqkt<aD zt&Y!TDpIT&PHP}7zfN+EChyeb@Qc`;Y%r@)LeodiTUmH17zsH>Kj|^(a8_A5qGs&4 z*4j$+?BdX<D@*wvO43Y_`RZ}@pC|ORpn`)CovJ<--h75lv3nAik}-^AONfq1xyrO3 z%Bp_7wK?pf^Q^}X4$_(jJNV(2TzV&h_EPBDV<Ok25;MR(KWc8(6QLh5vntT9r7SjO z*vcLYBHU@tf<)B%gw@6iDfHj6m`1qcW)ovvA6v=t>9_m8+JF$lkoF<STZ7U#<)%>F z(EYrCQmps77XDOY880v9z(D8|B9q%G5<(-;6z@U5-37;FLF=an-^Y)8PETJ!*lwpb z(+XO5JfD=6g}*j_(^nAJdKXsf;_?2$>N-oX!a5oa>sUD<X@HW;pG6`|37-!xPZ3Qg z*Yrk@rQl)w>i)ew4*%z=kLgfW)gM-Oy9eP{A<rCmNiv7vZ_xDl9$~q-A*z88g-Wc` zP7%f#8-I8wzr!Uy;m9iJC2*}Tb`F>+x|dR)r(hye->tM=7__^;=9QK*V?<_uo_3xv z-T@__vW!I#Cpj|z95esWNnKuY%CY)NFT+#K`@koC^aSXGGUcViSmJIyWAKH;qkx_t z-sKq&Uj+!GqR=_)^o7zny&mK~+A?TW6A^CfPiC5Dgc_cHBp6%EPwnJ-qf<?%m~W%X z7eHoCrTAU8_uLbOEsA}`S0S}#!SuWARuOccmUD9KGPb1hJL&!DjPg=-L5l!Pw32o1 zVa;PidYUx)9BuWk%jzTCbiZ+|F~k0IMFXh?6Znx@!iI4^Dw64L=j3WW98KkS+7083 zbT8NNa34+y&FB@N6XWF)|Mu4hm7285jU#|$Llbd1lPs1Sg%IyD2uf^&CqtC!_lf(x zbBPi{33!>k%E@7fd}u65YP!Y>E}<C+{8-BnB}{pH78b)C->ZxF=NAX-9(>%#kL;!B zyw%xm(A3wDr$@pYB12@A?`VWFq=Jrpzxy4Bw|#48DPZ9lL9r~kXj(-F+b6JJ-4%(s zLt*O*+C2u~&?@%5p>o``tU>z}oPnz-@*Po(<xOB?j3x4Z82wWXspC6$^tBxbrBu$} zU+>q*`7Vu4J32f7(2NZLV7=V&65(;SFmy6CQE_pyv@`$R4L#HxvLgUvufPrhv6{{S z7~4_-LI%4K?j}?r#KwZD)DAIXvEJYcLpP4X679MhwuKvlw#g{qyC2K@Z)qC%7EH16 zV!%cpX1voqkDI+c&YCNRGlF*Uec#>rJb0P(DWvt>-Y)F^NShn*B}z#yW3rj~$W5>! zL#UVje1=-c@;1=in~xxYhCx3)z0Z=SK61;9=1u2ts^U^mrJ)Z-l8_C$OsuK~m9NLs zLulM050G{0%hjIEC9dw0$4_fI;7%~m7svyQJbqx$FlKqH>E;0%RZwV3oC_SL=u&UK zbfnxk{gJ#V?B#JcV1_}tEM>UUjpKB)TaIjN`?kAbiZx}?gKdcq>SFBYNtFE|Un*(? z4sq{}jLy*4jb4q}2eM$O3uUjg*&AlWO;=Q0R_E0Tr`oDj;yr!x33}VlEj}g)UeiEj zxxRJzt+wI<q`P^w+ODqx8$qpa=~G+e;okdOYiyQS^tpEn3o92E#N|3kA`R2z%av!P zO@28eCzchBa?m#1Gxu$e<KpW-8SRE_3JYy%uD0#N?GklRwxq)k%_o60tG?ZD?^3d> zklUEfv+%LC-8QpB&QfXo*+t*ww84ow^jdzRYmTwlty}jl;pWw98`o!`u>qOxY#O^7 zoQfM@_&bDku>rcXQH2dg=vZ24SpQJO5}St?Wp&x%_t<Js-~d!gm^gOTu@lUX^8_n@ zTXU<*u?PT`0p)2^U!?47$K3lXs!&jk<hrSJx16@u*^U}zsx?~@d?p%Dz~!b_f%rXt z<hsWNHlSZ^j@kMZ+IdUX+s;8Uh$oZ{s&zPcnCp{@)UXg*=!3He1+$v>k#ei|v4rT3 z+8#&ww40qz<q$qgH(0497*He@X#SP(Q|+MeCeO%`CfAc5fu+F7W^4tt{!wwr8@o4( z!rE(6!vtB}&?W$o^!AQSaP9h%$AgoNK(2*)S|vmiko9VZR9skFY5Csgao#%Hkg+M> z%Ei8)ZUglJF1&}0SP;pu)gCxHqQpKlE*nEa*cExuAUyJs?<k_0CFy7fNbkQmyaLq~ zsYmYs8THf8ViD+Sgigt4nOV#`H{wD{lNvJ7Dzp~}>?BB|`%r{vm1Iyr4Z@Dh2Fg2J zpwZy3z0u8;S}SO2Fs#-HM}n-Gm|@;JizM0U(ZUdKI$ts%T`10R@mV?cjFJ|gb`8m~ znN4Fdr3_6U3%MX;Ji>~EBNF5Ga(VLYe_Ug&c+EWi9+;m<VmTIHTz~Wd>&r)D`$c2> z_1F5(4emwbqBxt%P>6_N&tt`<Mc1&%q!n8CaOf-a5w{(IQU}r$qoG7<aH$SG@;pej zX<JOQ7ek&^PMNT_C_bT8UPerriS4<DwXZEnHTTVgo1p?=DDs{$i(8%d<f`tHky4RT zOKC`B?ua6H5r=EX7P<t4n8#z>6%cygMG+mf?5eu8WYE<aZ%zxtlNU9-fzBJqi-4au z=10{ocYOTy#P-<?4uz#Fy*&F30{Cug9BMrD8>ubQ?zjm=)3z6Jv3*Oykx9%zj`+dt z9!401EL=j=yOFE*ti+r%#-5FSRN<#Lkqs~(SS#xh{N$mO@Jd5o^)(cZ(2==B%BbE9 ztBTyD?=9m>IykT6^#psP9S1xh>eN9fX_H%LIoJtT8l4nyHB+|LPyjf1ItA68YrpOn z;&^saODG>IDf`QWq8t9y-D<FrLftGt#t|%&h1RB=vU|+_rs}`I!N%?#L+f#!Ngd2V z>>MpJv%OR=MApZ(r$lj$->6NXNED+$ms2;qFlKbej}e<n0w<Rz1&M_a@kuHyhRg1x z_tTw8q^rW|MU`Rn2puESA;#+EVh{bR$=<L&UHMaDI^_`3-Vr)ngd<yTN8`o}hxzUm z2x?)X!uKO2my!BVhBbD_Nju`Tw^7Iu$s*c>(_FNzz~nm-g)xqkEFLewK+@m_=4?>` zX9n3>lTFk(Syk0GIY_s+#BUp{3mAuzx-0YZsGp%QCQxwg6;dQ^@_xHwY_LTQvEsKb zVq!uHL)_rW(=2>EBz5v?+?pSTMPINP6pG5cLby3|3%4|Uj}wd36j6)BsVB_MjY5Gg zB3(s|tjm>z%?pIVf-%Ia6VR!54@MyCr4>dqVLHO$qJAg;`lrk?vXgGB{EnT-JHc1> zc}kCvv=M5yS35m8)9*>d94>cBPveIt&#DPL>%?qnzRNX8^hPFbvkX8N<R{1ZjrS$U zOr3wU$|Iy}4#nYzG}L%{AUaCd3bE<Atv#lsO$)ltI<~{klTd7QH{#|U@=lr3^t#U2 zxXcSS?gA<}$V#k;OvNG>&6x6bH@TZIZ!Jov(O|?Zvs-U=C+F5+Otsf&0}I9%wG%{u zd&hK8{Fe<hrOgibl9YljhO5eY=R$Bh7`k$-la}$Ak)wmG`Hz7riiK7Ps@$zw>Q5Gj zKLr-XxS;C^mOnSocc9EiZDv@U44|;uz0u0TXRdo4lyYr9xnxVg9J@(O#gF1)vQBSb zdwkOu66krqweW>`-k9>hIsPy+gtcr-v{OoFMe=JB?vlf?I7hw|Z2I^?;e$tjUJark zvj(RIVdFR<R}J-wz-W~8{R|`J_%+HK3$h)pCDX5CYDl3%TFz@m@*VUGy`LZQx(z-v zCd{sfRW~nVGPI7nu^|vVS-6B2H+0DY@w=ZEd?8T++WV$?WI_i;Wx$oNEp7}c!tl(f z!Xy)$kO^PBjyqhGzMTlLIveb1t}&r$0iqp{R5#)@r)_r!xM$utBRvp(;qb$^SZL25 zWC~|5YNH#A)^W(A`=Ls{_Ic-nn^>bg6K`OyPaGXp@&Pvf-dVzQB$%kJ6pDQhU-$3} zVx(nMkIX5zVD1!6Kz3)0>p71HoP<T&UbX@1-MRDul@NP1l}aSuH{gRLNvG}EyMSJ{ zbAGSF5V_X-4<v()hzNzyvsz+FD!JD)MA_j@xlccFoRX+G&79l|HxUYZ5c<-+A;$A_ z_N{;D#Bg6jXM}@8+;33K?%6+P_YKj-V~+Z>rE=b!lB)uVz!H<I1R+I;`y>$SkVn?7 zb2_d+5Jf-THHqxPzi-cc{*T26!}eUPaWA=2*cX=y{UxtzVsEVIWbfe2WNhzb`mc(h z|D{u3&Xz%-mvrH8DR}5>Vx$!!u;bj9fUQ>t1I674>_VX{>|yftiy#sfxr-C3p|CUq zB3DeXM)Y7(NyS?0J5NaBIu2)LSv+u;WNDq&7}&}^YfKVH5sy;a+CbhFZSce6b{Qy2 z=3rw&2lfp|5IsnCeR2ehn7b7ZbNea-F0P2VdR}u4{&SAL3f1>gO~?#ZS0P@(94LfE zNM}wA@SEcApIivm-ui*Cw0FA<vcKkM6Kg}Q1uHP+e~Yb|YI1h`;@vu6Lm9eR<b&#g zW!Ja_ZjiO@dqTW3K0A#UAF1DK2MO*=OGV-96w%!|elD!Ky&|AM*<<+xy(g4?btNog zA85;bzsjyH+<>r-`8|7g0U_XW(NK5Ek4LI+yN+y~?6`U&yW{9d>``Z)X|^}*7$~YI zOXop2kQ5gtQkz|4fk-UNr<ysGwzSP(Txg@cbI59rEAwvaD>hT-(_tZ3^V$+SMT>Xo zGv(;{rWd&4qa#?xRg@0^x+rHpkbBUt4|up{OyT@8DO#xC_@CqQyDJG(LoY}kenB$Y zUy*F+;P5{nzaaQuEnj8GZiyMK4R;qv-8K+EMFNKuE|i`>m?IRa4X)Qzp^JbML-;OU zb<h78_oPWf6Kk5ko6~+Ilb5nk(6l)7)^Y;&$fkd%HlETVfv#@F?2zTz%L5D&G(cn? zHR`{{n@@PS5h`o59*^sf5rrdQRY&JQ91Sd~3So}0CEzW%;82u(Ol+;0MzGKDD4xIo z%1j|f@e1o0I4*wnvk}y-yR6I(Rw3#<jXz0~)C?y)=m+FrJ)rGGb$xFUcYi%(OjeQB zZvl<P5R0nqj;kvLhNQLy2h%n$(Xa<742WXYi(hSW9GTMIuwz?8!`PD%YX!hl-{g=S zqw`d1WP8Wt7KlZJrz-?Jp|1#-gJE8|(z4D5%o)&>?DdD_N6TRj4q0~!$r&2^JW>cV zeN4ya@#cCoz&~*2K7lnlo$H3M4#O#<lug`K8c=(F_T|Y9+?QORkJgRrKCRdFF9gmz zzpF3&!I{jaIAR#szn*<O6E+doxC3vPeR8n9()f@8^1)pBN?3c7d*uAl#>s7oX!<}p zI>JcLe}L?Lchh+_$??{^_B}y6+A1CTRkKyj78Ni2H-+i?!;=b@ZRJvOr@d_Poi8x| zBQgf@is8lc{m%uS|6cHakN=_EQ&Hyc3jSV-_HV)8#-tak`b%NjuY!Ls&-trh+Y9ad z|BH2g)$?o3#-Ex_UTRo>so?lk_}6swpTbH=e*_2qFFF0I=&wn=KSjk~!jLb|{WZn+ ztAby{l7A}rit~Rj{*NH#uUdW$X#A;V0{@RM_%*!otA@Yx`JeJH0TK!T;2-S%tN7nH i(Z7nXzWs~%zqV9G8R(bQ1pp9Uets`?0BbbAUHw0Pw@?EB literal 0 HcmV?d00001 diff --git a/asyst/README.md b/asyst/README.md new file mode 100755 index 0000000..56f29b7 --- /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 0000000..1849a98 --- /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 0000000..6752a7f --- /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 0000000..2394171 --- /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 GIT binary patch literal 3924 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 LjEGG^?gsw`r8#(? literal 0 HcmV?d00001 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 0000000..e4f169e --- /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 e5f4f3a..0932d69 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 0000000..c261025 --- /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 d9104c4..f3c8a29 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 0000000..4bcbfa4 --- /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 b2af31b..28c38a6 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 66d7627..452923b 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; -- GitLab