From 66e55ea64baef29f67589ad929a5bbf32c8a7bba Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Fri, 31 Oct 2025 23:22:17 +0100 Subject: [PATCH 1/5] added new fragebogen2025 --- src/feedback/admin.py | 4 +- ...mester_fragebogen_ergebnis2025_and_more.py | 120 ++++++++ src/feedback/models/__init__.py | 1 + src/feedback/models/base.py | 2 +- src/feedback/models/fragebogen2025.py | 259 ++++++++++++++++++ src/feedback/parser/ergebnisse/parser2025.py | 64 +++++ 6 files changed, 448 insertions(+), 2 deletions(-) create mode 100644 src/feedback/migrations/0055_alter_semester_fragebogen_ergebnis2025_and_more.py create mode 100644 src/feedback/models/fragebogen2025.py create mode 100644 src/feedback/parser/ergebnisse/parser2025.py diff --git a/src/feedback/admin.py b/src/feedback/admin.py index 51652521..ec160651 100644 --- a/src/feedback/admin.py +++ b/src/feedback/admin.py @@ -8,7 +8,7 @@ from feedback.models import Person, Veranstaltung, Semester, \ Mailvorlage, Kommentar, Tutor, BarcodeScanner, BarcodeScannEvent, BarcodeAllowedState, \ - EmailEndung, Fragebogen2020, FragebogenUE2020, Ergebnis2020, Fragebogen2016, FragebogenUE2016, Ergebnis2016 + EmailEndung, Fragebogen2020, Fragebogen2025, FragebogenUE2020, Ergebnis2020, Ergebnis2025, Fragebogen2016, FragebogenUE2016, Ergebnis2016 from feedback.models.base import Log, Fachgebiet, FachgebietEmail @@ -257,6 +257,8 @@ class FragebogenAdmin(admin.ModelAdmin): admin.site.register(Person, PersonAdmin) admin.site.register(Veranstaltung, VeranstaltungAdmin) admin.site.register(Semester, SemesterAdmin) +admin.site.register(Fragebogen2025, FragebogenAdmin) +admin.site.register(Ergebnis2025, FragebogenAdmin) admin.site.register(Fragebogen2020, FragebogenAdmin) admin.site.register(FragebogenUE2020, FragebogenAdmin) admin.site.register(Ergebnis2020, FragebogenAdmin) diff --git a/src/feedback/migrations/0055_alter_semester_fragebogen_ergebnis2025_and_more.py b/src/feedback/migrations/0055_alter_semester_fragebogen_ergebnis2025_and_more.py new file mode 100644 index 00000000..77923358 --- /dev/null +++ b/src/feedback/migrations/0055_alter_semester_fragebogen_ergebnis2025_and_more.py @@ -0,0 +1,120 @@ +# Generated by Django 5.2.7 on 2025-10-31 23:20 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('feedback', '0054_alter_alternativvorname_vorname_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='semester', + name='fragebogen', + field=models.CharField(choices=[('2008', 'Fragebogen 2008'), ('2009', 'Fragebogen 2009'), ('2012', 'Fragebogen 2012'), ('2016', 'Fragebogen 2016'), ('2020', 'Fragebogen 2020'), ('2025', 'Fragebogen 2025')], help_text='Verwendete Version des Fragebogens.', max_length=5, verbose_name='Fragebogen'), + ), + migrations.CreateModel( + name='Ergebnis2025', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('anzahl', models.PositiveIntegerField()), + ('v_didaktik', models.FloatField(blank=True, null=True)), + ('v_didaktik_count', models.PositiveIntegerField(default=0)), + ('v_organisation', models.FloatField(blank=True, null=True)), + ('v_organisation_count', models.PositiveIntegerField(default=0)), + ('v_praxisbezug_motivation', models.FloatField(blank=True, null=True)), + ('v_praxisbezug_motivation_count', models.PositiveIntegerField(default=0)), + ('v_digitale_lehre', models.FloatField(blank=True, null=True)), + ('v_digitale_lehre_count', models.PositiveIntegerField(default=0)), + ('v_7_5', models.FloatField(blank=True, null=True)), + ('v_7_5_count', models.PositiveIntegerField(default=0)), + ('v_feedbackpreis', models.FloatField(blank=True, null=True)), + ('v_feedbackpreis_count', models.PositiveIntegerField(default=0)), + ('ue_didaktik', models.FloatField(blank=True, null=True)), + ('ue_didaktik_count', models.PositiveIntegerField(default=0)), + ('ue_organisation', models.FloatField(blank=True, null=True)), + ('ue_organisation_count', models.PositiveIntegerField(default=0)), + ('ue_arbeitsbedingungen', models.FloatField(blank=True, null=True)), + ('ue_arbeitsbedingungen_count', models.PositiveIntegerField(default=0)), + ('ue_umgang', models.FloatField(blank=True, null=True)), + ('ue_umgang_count', models.PositiveIntegerField(default=0)), + ('ue_lernerfolg', models.FloatField(blank=True, null=True)), + ('ue_lernerfolg_count', models.PositiveIntegerField(default=0)), + ('ue_digitale_lehre', models.FloatField(blank=True, null=True)), + ('ue_digitale_lehre_count', models.PositiveIntegerField(default=0)), + ('ue_feedbackpreis', models.FloatField(blank=True, null=True)), + ('ue_feedbackpreis_count', models.PositiveIntegerField(default=0)), + ('gesamt', models.FloatField(blank=True, null=True)), + ('gesamt_count', models.PositiveIntegerField(default=0)), + ('veranstaltung', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='feedback.veranstaltung')), + ], + options={ + 'verbose_name': 'Ergebnis 2025', + 'verbose_name_plural': 'Ergebnisse 2025', + 'ordering': ['veranstaltung'], + }, + ), + migrations.CreateModel( + name='Fragebogen2025', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('fach', models.CharField(blank=True, choices=[('inf', 'Informatik'), ('math', 'Mathematik'), ('ce', 'Computational Engineering'), ('ist', 'Informationssystemtechnik'), ('etit', 'Elektrotechnik'), ('psyit', 'Psychologie in IT'), ('winf', 'Wirtschaftsinformatik'), ('sonst', 'etwas anderes')], max_length=5)), + ('abschluss', models.CharField(blank=True, choices=[('bsc', 'Bachelor'), ('msc', 'Master'), ('dipl', 'Diplom'), ('lehr', 'Lehramt'), ('sonst', 'anderer Abschluss')], max_length=5)), + ('semester', models.CharField(blank=True, choices=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '>=10')], max_length=4)), + ('geschlecht', models.CharField(blank=True, choices=[('w', 'weiblich'), ('m', 'männlich'), ('s', 'sonstiges')], max_length=1)), + ('studienberechtigung', models.CharField(blank=True, choices=[('d', 'Deutschland'), ('o', 'anderes Land')], max_length=1)), + ('pflichveranstaltung', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('male_veranstaltung_gehoert', models.CharField(blank=True, choices=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '<=4')], max_length=1)), + ('pruefung_angetreten', models.CharField(blank=True, choices=[('0', '0'), ('1', '1'), ('2', '2')], max_length=1)), + ('v_wie_oft_besucht', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_besuch_ueberschneidung', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_qualitaet', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_verhaeltnisse', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_privat', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_elearning', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_zufrueh', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_besuch_sonstiges', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('v_vorwissen_ausreichend', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_technisch_moeglich', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_3_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_5', models.CharField(blank=True, choices=[('0', '0'), ('1', '0.5'), ('2', '1'), ('3', '2'), ('4', '3'), ('5', '4'), ('6', '5'), ('7', '>=5')], max_length=1)), + ('v_4_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_4_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_5', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_5_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_5', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_6_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_7_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_7_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_8_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('v_8_4', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('veranstaltung', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='feedback.veranstaltung')), + ], + options={ + 'verbose_name': 'Fragebogen 2025', + 'verbose_name_plural': 'Fragebögen 2025', + 'ordering': ['semester', 'veranstaltung'], + }, + ), + ] diff --git a/src/feedback/models/__init__.py b/src/feedback/models/__init__.py index 91f841d8..6df05f10 100644 --- a/src/feedback/models/__init__.py +++ b/src/feedback/models/__init__.py @@ -11,6 +11,7 @@ from feedback.models.fragebogen2016 import Fragebogen2016, Ergebnis2016 from feedback.models.fragebogenUE2016 import FragebogenUE2016 from feedback.models.fragebogen2020 import Fragebogen2020, Ergebnis2020 +from feedback.models.fragebogen2025 import Fragebogen2025, Ergebnis2025 from feedback.models.fragebogenUE2020 import FragebogenUE2020 from django.core.exceptions import ObjectDoesNotExist diff --git a/src/feedback/models/base.py b/src/feedback/models/base.py index 2aad9927..1aa8abe5 100644 --- a/src/feedback/models/base.py +++ b/src/feedback/models/base.py @@ -26,7 +26,7 @@ class Semester(models.Model): ('2012', 'Fragebogen 2012'), ('2016', 'Fragebogen 2016'), ('2020', 'Fragebogen 2020'), - + ('2025', 'Fragebogen 2025'), ) SICHTBARKEIT_CHOICES = ( ('ADM', _('Administratoren')), diff --git a/src/feedback/models/fragebogen2025.py b/src/feedback/models/fragebogen2025.py new file mode 100644 index 00000000..9803112c --- /dev/null +++ b/src/feedback/models/fragebogen2025.py @@ -0,0 +1,259 @@ +# coding=utf-8 + +from django.db import models +from feedback.models import Fragebogen, Ergebnis + + +class Fragebogen2025(Fragebogen): + fach = models.CharField(max_length=5, choices=Fragebogen.FACH_CHOICES, blank=True) + abschluss = models.CharField(max_length=5, choices=Fragebogen.ABSCHLUSS_CHOICES, blank=True) + semester = models.CharField(max_length=4, choices=Fragebogen.SEMESTER_CHOICES16, blank=True) + geschlecht = models.CharField(max_length=1, choices=Fragebogen.GESCHLECHT_CHOICES, blank=True) + studienberechtigung = models.CharField(max_length=1, choices=Fragebogen.STUDIENBERECHTIGUNG_CHOICES, blank=True) + pflichveranstaltung = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + male_veranstaltung_gehoert = models.CharField(max_length=1, choices=Fragebogen.VERANSTALTUNG_GEHOERT, blank=True) + pruefung_angetreten = models.CharField(max_length=1, choices=Fragebogen.KLAUSUR_ANGETRETEN, blank=True) + + v_wie_oft_besucht = models.PositiveSmallIntegerField(blank=True, null=True) + v_besuch_ueberschneidung = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_qualitaet = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_verhaeltnisse = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_privat = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_elearning = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_zufrueh = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_besuch_sonstiges = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + v_vorwissen_ausreichend = models.PositiveSmallIntegerField(blank=True, null=True) + v_technisch_moeglich = models.PositiveSmallIntegerField(blank=True, null=True) + + + v_3_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_3_2 = models.PositiveSmallIntegerField(blank=True, null=True) + v_3_3 = models.PositiveSmallIntegerField(blank=True, null=True) + v_3_4 = models.PositiveSmallIntegerField(blank=True, null=True) + v_3_6 = models.PositiveSmallIntegerField(blank=True, null=True) + v_3_7 = models.PositiveSmallIntegerField(blank=True, null=True) + + v_4_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_4_2 = models.PositiveSmallIntegerField(blank=True, null=True) + v_4_3 = models.PositiveSmallIntegerField(blank=True, null=True) + v_4_4 = models.PositiveSmallIntegerField(blank=True, null=True) + v_4_5 = models.CharField(max_length=1, choices=Fragebogen.STUNDEN_NACHBEARBEITUNG, blank=True) + v_4_6 = models.PositiveSmallIntegerField(blank=True, null=True) + v_4_7 = models.PositiveSmallIntegerField(blank=True, null=True) + + v_5_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_2 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_3 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_4 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_5 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_6 = models.PositiveSmallIntegerField(blank=True, null=True) + v_5_7 = models.PositiveSmallIntegerField(blank=True, null=True) + + v_6_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_6_2 = models.PositiveSmallIntegerField(blank=True, null=True) + v_6_3 = models.PositiveSmallIntegerField(blank=True, null=True) + v_6_4 = models.PositiveSmallIntegerField(blank=True, null=True) + v_6_5 = models.PositiveSmallIntegerField(blank=True, null=True) + v_6_6 = models.PositiveSmallIntegerField(blank=True, null=True) + + v_7_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_7_2 = models.PositiveSmallIntegerField(blank=True, null=True) + + v_8_1 = models.PositiveSmallIntegerField(blank=True, null=True) + v_8_4 = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + + class Meta: + verbose_name = 'Fragebogen 2025' + verbose_name_plural = 'Fragebögen 2025' + ordering = ['semester', 'veranstaltung'] + app_label = 'feedback' + + +class Ergebnis2025(Ergebnis): + parts_vl = [ + [ + 'v_8_1', 'Vorlesung: Gesamtnote', + [ + '8.1 Welche Gesamtnote würdest Du der Vorlesung (ohne Übungen) geben?' + ] + ], + [ + 'v_didaktik', 'Vorlesung: Didaktik', + [ + '2.4 Mein Vorwissen war ausreichend, um der Vorlesung folgen zu können.', + '4.6 Der Stoff wurde anhand von Beispielen verdeutlicht.', + '5.1 Die Lehrkraft hat die Vorlesung didaktisch gut gestaltet.', + '5.2 Die Lehrkraft hat Kompliziertes verständlich dargelegt.', + '5.3 Ich habe durch diese Veranstaltung viel gelernt.', + '5.4 Die Lernziele der Veranstaltung sind mir klar geworden.', + '5.5 Die Vorlesung motivierte dazu, sich außerhalb der Veranstaltung selbstständig mit den behandelten Themen auseinander zu setzen.', + '5.6 Ich kann abschätzen, was in der Prüfung von mir erwartet wird.', + '5.7 Ich habe vor, in diesem Semester die Prüfung anzutreten.', + '6.1 Die Lehrkraft regte gezielt zum Mitdenken und zu eigener Mitarbeit in der Vorlesung an.', + '6.4 Die Lehrkraft hat die Vorlesung rhetorisch gut gestaltet.', + ] + ], + [ + 'v_organisation', 'Vorlesung: Organisation', + [ + '3.1 Die Organisation der Vorlesung war gut.', + '3.2 Die Vorlesungsmaterialien (Folien, Skripte, Tafelanschrieb, Lehrbücher, e-Learning, etc.) haben das Lernen wirkungsvoll unterstützt.', + '3.3 Ich habe ausreichend Informationen zur Nutzung des digitalen Lehr-/Lernangebots von dem/der Lehrenden erhalten.', + '3.4 Die Lehrkraft hat elektronische Plattformen sinnvoll und hilfreich eingesetzt.', + '3.6 Die Veranstalter waren auch außerhalb der Vorlesung ansprechbar.', + '3.7 Der Raum war für die Vorlesung geeignet', + '4.4 Die Vorlesung war inhaltlich gut strukturiert.', + '6.2 Die (Zwischen-)Fragen der Studierenden wurden angemessen beantwortet.', + '6.3 Die Lehrkraft zeigte sich gut vorbereitet.', + '6.5 Die Sprachkenntnisse der Lehrkraft in der Vorlesungssprache waren gut.', + '6.6 Die Qualität der Vorlesung war konsistent (auch bei verschiedenen Dozierenden).' + ] + ], + [ + 'v_praxisbezug_motivation', 'Vorlesung: Praxisbezug und Motivation', + [ + '4.7 Der Bezug zwischen Theorie und praktischem Arbeiten bzw. praktischen Anwendungen wurde hergestellt.', + ] + ], + [ + 'v_digitale_lehre', 'Vorlesung: Digitale Lehre', + [ + '2.5 Mir ist es technisch möglich, in vollem Umfang an der Veranstaltung teilzunehmen.', + ] + ], + ] + + parts_ue = [ + ['ue_didaktik', 'Übung: Didaktik', + ['4.1 Die Übung war inhaltlich gut strukturiert.', + '4.2 Die Lernziele der Übung sind mir klar geworden.', + '5.2 Der*Die Tutor*in hat gut und verständlich erklärt.', + '5.3 Der*Die Tutor*in hat die Gruppe motiviert.', + '5.4 Der*Die Tutor*in war fachlich kompetent.', + '5.5 Der*Die Tutor*in zeigte sich gut vorbereitet.', + '5.6 Der*Die Tutor*in hat die Übungstunde gut strukturiert.', + '5.7 Der*Die Tutor*in war engagiert.', + '5.8 Der*Die Tutor*in stellte wesentliche Punkte zur Bearbeitung der Aufgaben vor.', + '5.9 Der*Die Tutor*in regte mich gezielt zum Mitdenken und zu eigener Mitarbeit an.', + '5.10 Der*Die Tutor*in setzte verfügbare Medien (z. B. Tafel, Projektor, Beamer) sinnvoll ein.', + '5.11 Der*Die Tutor*in hat elektronische Plattformen sinnvoll und hilfreich eingesetzt.', + '5.15 Der*Die Tutor*in hat konstruktives bzw. gutes Feedback gegeben.']], + ['ue_organisation', 'Übung: Organisation', + ['3.3 Die Aufgabenstellungen waren verständlich.', + '3.4 Die Übungsaufgaben hatten inhaltlich eine klare Struktur.', + '3.5 Die Übungsaufgaben waren motivierend.', + '3.6 Es wurden ausreichend Lösungsvorschläge bereitgestellt bzw. präsentiert.', + '3.7 Der Stoff der Vorlesung war gut auf die Übungen abgestimmt.', + '3.8 Mein Vorwissen war ausreichend, um die Übungsaufgaben bearbeiten zu können.', + '4.3 Die Organisation des Übungsbetriebs war gut.', + '4.4 Es wurde genug Übungsmaterial (Aufgaben, etc.) zur Verfügung gestellt.', + '4.5 Es stand genug Zeit für die Bearbeitung der Aufgaben zur Verfügung.', + '4.6 Die Abgaben waren gut vereinbar mit anderen Veranstaltungen laut Regelstudienplan.']], + ['ue_arbeitsbedingungen', 'Übung: Arbeitsbedingungen', + ['4.7 Die Auswahlmöglichkeiten der Termine waren angemessen bzw. der Übungszeitpunkt war passend.', + '4.8 Die Gruppengröße war zufriedenstellend.', + '4.9 Der Raum für die Übungen war zum Arbeiten und Lernen geeignet.']], + ['ue_umgang', 'Übung: Umgang', + ['5.12 Der*Die Tutor*in erschien pünktlich.', + '5.13 Der*Die Tutor*in behandelte alle Studierenden respektvoll.', + '5.14 Der*Die Tutor*in teilte die Zeit zwischen den Studierenden angemessen auf.', + '5.16 Der*Die Tutor*in hat nachvollziehbar bewertet bzw. benotet.']], + ['ue_lernerfolg', 'Übung: Lernerfolg', + ['3.1 Durch die Aufgaben und den Übungsbetrieb habe ich viel gelernt.', + '3.2 Die Übungen haben mir geholfen, den Stoff der Vorlesung besser zu verstehen.']], + ['ue_digitale_lehre', 'Übung: Digitale Lehre', + ['6.1. Ich habe ausreichend Informationen zur Nutzung des digitalen Lehr-/Lernangebots von dem/der Lehrenden erhalten.', + '6.2. Mir ist es technisch möglich, in vollem Umfang an der Veranstaltung teilzunehmen.']], + ] + + parts = parts_vl + parts_ue + hidden_parts = [ + [ + 'v_feedbackpreis', 'Feedbackpreis: Beste Vorlesung', + [ + '3.2 Die Vorlesungsmaterialien (Folien, Skripte, Tafelanschrieb, Lehrbücher,e-Learning, etc.) haben das Lernen wirkungsvoll unterstützt.', + '3.6 Der Lehrende war auch außerhalb der Veranstaltung ansprechbar.', + '3.8 Die Vorlesung motivierte dazu, sich außerhalb der Veranstaltungselbstständig mit den behandelten Themen auseinander zu setzen.', # not in fragebogen? + '4.4 Die Vorlesung war inhaltlich gut strukturiert, ein roter Faden war erkennbar.', + '4.6 Der Stoff wurde anhand von Beispielen verdeutlicht.', + '4.7 Der Bezug zwischen Theorie und praktischem Arbeiten / praktischen Anwendungen wurde hergestellt.', + '5.2 Die Lehrkraft hat Kompliziertes verständlich dargelegt.', + '5.4 Die Lernziele der Veranstaltung sind mir klar geworden.', + '6.1 Der Lehrende regte gezielt zur eigenen Mitarbeit / zum Mitdenken in der Veranstaltung an.', + '6.2 Die (Zwischen-)Fragen der Studierenden wurden angemessen beantwortet.', + '6.3 Die Lehrkraft zeigte sich gut vorbereitet.', + '8.1 Welche Gesamtnote würdest Du der Vorlesung (ohne Übungen) geben?' + ] + ], + ['ue_feedbackpreis', 'Feedbackpreis: Beste Übung', + ['3.1 Durch die Aufgaben und den Übungsbetrieb habe ich viel gelernt.', + '3.2 Die Übungen haben mir geholfen, den Stoff der Vorlesung besser zu verstehen.', + '3.3 Die Aufgabenstellungen waren verständlich.', + '3.4 Die Übungsaufgaben hatten inhaltlich eine klare Struktur.', + '3.5 Die Übungsaufgaben waren motivierend.', + '3.7 Der Stoff der Vorlesung war gut auf die Übungen abgestimmt.', + '4.1 Die Übung war inhaltlich gut strukturiert.', + '4.2 Die Lernziele der Übung sind mir klar geworden.', + '4.3 Die Organisation des Übungsbetriebs war gut.', + '4.4 Es wurde genug Übungsmaterial (Aufgaben, etc.) zur Verfügung gestellt.', + '4.5 Es stand genug Zeit für die Bearbeitung der Aufgaben zur Verfügung.', + '7.3 Welche Gesamtnote gibst du der Übung?']], + ] + weight = { + 'v_feedbackpreis': [1] * 13 + [13], + 'ue_feedbackpreis': [1] * 10 + [10], + } + + + # TODO: decimal statt float benutzen + v_didaktik = models.FloatField(blank=True, null=True) + v_didaktik_count = models.PositiveIntegerField(default=0) + v_didaktik_parts = ['v_2_4', 'v_4_6', 'v_5_1', 'v_5_2', 'v_5_3', 'v_5_4', 'v_5_5', 'v_5_6', 'v_5_7', 'v_6_1', 'v_6_4', 'v_6_6',] + v_organisation = models.FloatField(blank=True, null=True) + v_organisation_count = models.PositiveIntegerField(default=0) + v_organisation_parts = ['v_3_1', 'v_3_2', 'v_3_3', 'v_3_4', 'v_3_6', 'v_3_7', 'v_4_4', 'v_6_2', 'v_6_3', 'v_6_5',] + v_praxisbezug_motivation = models.FloatField(blank=True, null=True) + v_praxisbezug_motivation_count = models.PositiveIntegerField(default=0) + v_praxisbezug_motivation_parts = ['v_4_7'] + v_digitale_lehre = models.FloatField(blank=True, null=True) + v_digitale_lehre_count = models.PositiveIntegerField(default=0) + v_digitale_lehre_parts = ['v_2_5'] + v_7_5 = models.FloatField(blank=True, null=True) + v_7_5_count = models.PositiveIntegerField(default=0) + + v_feedbackpreis = models.FloatField(blank=True, null=True) + v_feedbackpreis_count = models.PositiveIntegerField(default=0) + v_feedbackpreis_parts = [ + 'v_3_2', 'v_3_6', 'v_3_8', 'v_4_4', 'v_4_6', 'v_4_7', 'v_5_2', 'v_5_4', 'v_6_1', 'v_6_2', 'v_6_3', 'v_8_1', + ] + + ue_didaktik = models.FloatField(blank=True, null=True) + ue_didaktik_count = models.PositiveIntegerField(default=0) + ue_didaktik_parts = ['ue_4_1', 'ue_4_2', 'ue_5_2', 'ue_5_3', 'ue_5_4', 'ue_5_5', 'ue_5_6', 'ue_5_7', 'ue_5_8', 'ue_5_9', 'ue_5_10', 'ue_5_11', 'ue_5_15'] + ue_organisation = models.FloatField(blank=True, null=True) + ue_organisation_count = models.PositiveIntegerField(default=0) + ue_organisation_parts = ['ue_3_3', 'ue_3_4', 'ue_3_5', 'ue_3_6', 'ue_3_7', 'ue_3_8', 'ue_4_3', 'ue_4_4', 'ue_4_5', 'ue_4_6'] + ue_arbeitsbedingungen = models.FloatField(blank=True, null=True) + ue_arbeitsbedingungen_count = models.PositiveIntegerField(default=0) + ue_arbeitsbedingungen_parts = ['ue_4_7', 'ue_4_8', 'ue_4_9'] + ue_umgang = models.FloatField(blank=True, null=True) + ue_umgang_count = models.PositiveIntegerField(default=0) + ue_umgang_parts = ['ue_5_12', 'ue_5_13', 'ue_5_14', 'ue_5_16'] + ue_lernerfolg = models.FloatField(blank=True, null=True) + ue_lernerfolg_count = models.PositiveIntegerField(default=0) + ue_lernerfolg_parts = ['ue_3_1', 'ue_3_2'] + ue_digitale_lehre = models.FloatField(blank=True, null=True) + ue_digitale_lehre_count = models.PositiveIntegerField(default=0) + ue_digitale_lehre_parts = ['ue_6_1', 'ue_6_2'] + ue_feedbackpreis = models.FloatField(blank=True, null=True) + ue_feedbackpreis_count = models.PositiveIntegerField(default=0) + ue_feedbackpreis_parts = ['ue_3_1', 'ue_3_2', 'ue_3_3', 'ue_3_4', 'ue_3_5', 'ue_3_7', 'ue_4_1', 'ue_4_2', 'ue_4_3', 'ue_4_4', 'ue_4_5', 'ue_7_3'] + + gesamt = models.FloatField(blank=True, null=True) + gesamt_count = models.PositiveIntegerField(default=0) + + class Meta: + verbose_name = 'Ergebnis 2025' + verbose_name_plural = 'Ergebnisse 2025' + ordering = ['veranstaltung'] + app_label = 'feedback' diff --git a/src/feedback/parser/ergebnisse/parser2025.py b/src/feedback/parser/ergebnisse/parser2025.py new file mode 100644 index 00000000..9b6f66e0 --- /dev/null +++ b/src/feedback/parser/ergebnisse/parser2025.py @@ -0,0 +1,64 @@ +# coding = utf-8 + +from feedback.models import Fragebogen2025 +from feedback.parser.ergebnisse.parser import Parser + + +class Parser2025(Parser): + @classmethod + def create_fragebogen(cls, veranst, frageb): + Fragebogen2025.objects.create( + veranstaltung=veranst, + fach=cls.parse_fach_16(frageb[1]), + abschluss=cls.parse_abschluss_16(frageb[3]), + semester=cls.parse_semester_16(frageb[4]), + geschlecht=cls.parse_geschlecht_16(frageb[5]), + studienberechtigung=cls.parse_studienberechtigung(frageb[6]), + pflichveranstaltung=cls.parse_boolean(frageb[7]), + male_veranstaltung_gehoert=cls.parse_veranstaltung_gehoert(frageb[8]), + pruefung_angetreten=cls.parse_klausur_angetreten(frageb[9]), + + v_wie_oft_besucht=cls.parse_int(frageb[10]), + v_besuch_ueberschneidung=cls.parse_boolean(frageb[11]), + v_besuch_qualitaet=cls.parse_boolean(frageb[12]), + v_besuch_verhaeltnisse=cls.parse_boolean(frageb[13]), + v_besuch_privat=cls.parse_boolean(frageb[14]), + v_besuch_elearning=cls.parse_boolean(frageb[15]), + v_besuch_zufrueh=cls.parse_boolean(frageb[16]), + v_besuch_sonstiges=cls.parse_boolean(frageb[17]), + v_vorwissen_ausreichend=cls.parse_int(frageb[19]), + v_technisch_moeglich=cls.parse_int(frageb[20]), + + v_3_1=cls.parse_int(frageb[21]), + v_3_2=cls.parse_int(frageb[22]), + v_3_3=cls.parse_int(frageb[23]), + v_3_4=cls.parse_int(frageb[24]), + v_3_6=cls.parse_int(frageb[26]), + v_3_7=cls.parse_int(frageb[27]), + + v_4_1=cls.parse_int(frageb[28]), + v_4_2=cls.parse_int(frageb[29]), + v_4_3=cls.parse_int(frageb[30]), + v_4_4=cls.parse_int(frageb[31]), + v_4_5=cls.parse_int(frageb[32]), + v_4_6=cls.parse_int(frageb[33]), + v_4_7=cls.parse_int(frageb[34]), + + v_5_1=cls.parse_int(frageb[35]), + v_5_2=cls.parse_int(frageb[36]), + v_5_3=cls.parse_int(frageb[37]), + v_5_4=cls.parse_int(frageb[38]), + v_5_5=cls.parse_int(frageb[39]), + v_5_6=cls.parse_int(frageb[40]), + v_5_7=cls.parse_int(frageb[41]), + + v_6_1=cls.parse_int(frageb[42]), + v_6_2=cls.parse_int(frageb[43]), + v_6_3=cls.parse_int(frageb[44]), + v_6_4=cls.parse_int(frageb[45]), + v_6_5=cls.parse_int(frageb[46]), + v_6_6=cls.parse_int(frageb[47]), + + v_8_1=cls.parse_extrazeit(frageb[50]), + v_8_4=cls.parse_geschwindigkeit16(frageb[53]), + ) From 4939c8712c8f0bcdaacf77030247ac06175e66eb Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Tue, 11 Nov 2025 23:51:00 +0100 Subject: [PATCH 2/5] add 2025UE, fixes to fragebogen2025 --- src/feedback/admin.py | 4 +- .../migrations/0056_fragebogenue2025.py | 80 +++++++++++++++++++ ...ename_v_7_5_ergebnis2025_v_8_1_and_more.py | 23 ++++++ src/feedback/models/__init__.py | 3 +- src/feedback/models/fragebogen2025.py | 10 +-- src/feedback/models/fragebogenUE2025.py | 72 +++++++++++++++++ src/feedback/parser/ergebnisse/parser2025.py | 8 +- .../parser/ergebnisse/parserUE2025.py | 65 +++++++++++++++ src/feedback/views/intern/__init__.py | 7 +- 9 files changed, 259 insertions(+), 13 deletions(-) create mode 100644 src/feedback/migrations/0056_fragebogenue2025.py create mode 100644 src/feedback/migrations/0057_rename_v_7_5_ergebnis2025_v_8_1_and_more.py create mode 100644 src/feedback/models/fragebogenUE2025.py create mode 100644 src/feedback/parser/ergebnisse/parserUE2025.py diff --git a/src/feedback/admin.py b/src/feedback/admin.py index ec160651..7573f7c3 100644 --- a/src/feedback/admin.py +++ b/src/feedback/admin.py @@ -8,7 +8,8 @@ from feedback.models import Person, Veranstaltung, Semester, \ Mailvorlage, Kommentar, Tutor, BarcodeScanner, BarcodeScannEvent, BarcodeAllowedState, \ - EmailEndung, Fragebogen2020, Fragebogen2025, FragebogenUE2020, Ergebnis2020, Ergebnis2025, Fragebogen2016, FragebogenUE2016, Ergebnis2016 + EmailEndung, Fragebogen2020, FragebogenUE2020, Ergebnis2020, Fragebogen2016, FragebogenUE2016, Ergebnis2016, \ + Fragebogen2025, FragebogenUE2025, Ergebnis2025 from feedback.models.base import Log, Fachgebiet, FachgebietEmail @@ -258,6 +259,7 @@ class FragebogenAdmin(admin.ModelAdmin): admin.site.register(Veranstaltung, VeranstaltungAdmin) admin.site.register(Semester, SemesterAdmin) admin.site.register(Fragebogen2025, FragebogenAdmin) +admin.site.register(FragebogenUE2025, FragebogenAdmin) admin.site.register(Ergebnis2025, FragebogenAdmin) admin.site.register(Fragebogen2020, FragebogenAdmin) admin.site.register(FragebogenUE2020, FragebogenAdmin) diff --git a/src/feedback/migrations/0056_fragebogenue2025.py b/src/feedback/migrations/0056_fragebogenue2025.py new file mode 100644 index 00000000..e56348a7 --- /dev/null +++ b/src/feedback/migrations/0056_fragebogenue2025.py @@ -0,0 +1,80 @@ +# Generated by Django 5.2.7 on 2025-11-09 22:16 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('feedback', '0055_alter_semester_fragebogen_ergebnis2025_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='FragebogenUE2025', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('fach', models.CharField(blank=True, choices=[('inf', 'Informatik'), ('math', 'Mathematik'), ('ce', 'Computational Engineering'), ('ist', 'Informationssystemtechnik'), ('etit', 'Elektrotechnik'), ('psyit', 'Psychologie in IT'), ('winf', 'Wirtschaftsinformatik'), ('sonst', 'etwas anderes')], max_length=5)), + ('abschluss', models.CharField(blank=True, choices=[('bsc', 'Bachelor'), ('msc', 'Master'), ('dipl', 'Diplom'), ('lehr', 'Lehramt'), ('sonst', 'anderer Abschluss')], max_length=5)), + ('semester', models.CharField(blank=True, choices=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '>=10')], max_length=4)), + ('geschlecht', models.CharField(blank=True, choices=[('w', 'weiblich'), ('m', 'männlich'), ('s', 'sonstiges')], max_length=1)), + ('studienberechtigung', models.CharField(blank=True, choices=[('d', 'Deutschland'), ('o', 'anderes Land')], max_length=1)), + ('ue_wie_oft_besucht', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_besuch_ueberschneidung', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_qualitaet', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_verhaeltnisse', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_privat', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_elearning', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_zufrueh', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_besuch_sonstiges', models.CharField(blank=True, choices=[('j', 'ja'), ('n', 'nein')], max_length=1)), + ('ue_3_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_5', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_3_8', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_5', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_8', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_9', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_4_10', models.CharField(blank=True, max_length=1)), + ('ue_4_11', models.CharField(blank=True, max_length=1)), + ('kennziffer', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_4', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_5', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_6', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_7', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_8', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_9', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_10', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_11', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_12', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_13', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_14', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_15', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_5_16', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_6_1', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_6_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_7_1', models.CharField(blank=True, choices=[('0', '0'), ('1', '0.5'), ('2', '1'), ('3', '2'), ('4', '3'), ('5', '4'), ('6', '5'), ('7', '>=5')], max_length=1)), + ('ue_7_2', models.PositiveSmallIntegerField(blank=True, null=True)), + ('ue_7_3', models.PositiveSmallIntegerField(blank=True, null=True)), + ('veranstaltung', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='feedback.veranstaltung')), + ], + options={ + 'verbose_name': 'Übungsfragebogen 2025', + 'verbose_name_plural': 'Übungsfragebögen 2025', + 'ordering': ['semester', 'veranstaltung'], + }, + ), + ] diff --git a/src/feedback/migrations/0057_rename_v_7_5_ergebnis2025_v_8_1_and_more.py b/src/feedback/migrations/0057_rename_v_7_5_ergebnis2025_v_8_1_and_more.py new file mode 100644 index 00000000..619aba4c --- /dev/null +++ b/src/feedback/migrations/0057_rename_v_7_5_ergebnis2025_v_8_1_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2025-11-09 22:18 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('feedback', '0056_fragebogenue2025'), + ] + + operations = [ + migrations.RenameField( + model_name='ergebnis2025', + old_name='v_7_5', + new_name='v_8_1', + ), + migrations.RenameField( + model_name='ergebnis2025', + old_name='v_7_5_count', + new_name='v_8_1_count', + ), + ] diff --git a/src/feedback/models/__init__.py b/src/feedback/models/__init__.py index 6df05f10..a763013c 100644 --- a/src/feedback/models/__init__.py +++ b/src/feedback/models/__init__.py @@ -11,8 +11,9 @@ from feedback.models.fragebogen2016 import Fragebogen2016, Ergebnis2016 from feedback.models.fragebogenUE2016 import FragebogenUE2016 from feedback.models.fragebogen2020 import Fragebogen2020, Ergebnis2020 -from feedback.models.fragebogen2025 import Fragebogen2025, Ergebnis2025 from feedback.models.fragebogenUE2020 import FragebogenUE2020 +from feedback.models.fragebogen2025 import Fragebogen2025, Ergebnis2025 +from feedback.models.fragebogenUE2025 import FragebogenUE2025 from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q diff --git a/src/feedback/models/fragebogen2025.py b/src/feedback/models/fragebogen2025.py index 9803112c..8ea20fc1 100644 --- a/src/feedback/models/fragebogen2025.py +++ b/src/feedback/models/fragebogen2025.py @@ -208,7 +208,7 @@ class Ergebnis2025(Ergebnis): # TODO: decimal statt float benutzen v_didaktik = models.FloatField(blank=True, null=True) v_didaktik_count = models.PositiveIntegerField(default=0) - v_didaktik_parts = ['v_2_4', 'v_4_6', 'v_5_1', 'v_5_2', 'v_5_3', 'v_5_4', 'v_5_5', 'v_5_6', 'v_5_7', 'v_6_1', 'v_6_4', 'v_6_6',] + v_didaktik_parts = ['v_vorwissen_ausreichend', 'v_4_6', 'v_5_1', 'v_5_2', 'v_5_3', 'v_5_4', 'v_5_5', 'v_5_6', 'v_5_7', 'v_6_1', 'v_6_4', 'v_6_6',] v_organisation = models.FloatField(blank=True, null=True) v_organisation_count = models.PositiveIntegerField(default=0) v_organisation_parts = ['v_3_1', 'v_3_2', 'v_3_3', 'v_3_4', 'v_3_6', 'v_3_7', 'v_4_4', 'v_6_2', 'v_6_3', 'v_6_5',] @@ -217,14 +217,14 @@ class Ergebnis2025(Ergebnis): v_praxisbezug_motivation_parts = ['v_4_7'] v_digitale_lehre = models.FloatField(blank=True, null=True) v_digitale_lehre_count = models.PositiveIntegerField(default=0) - v_digitale_lehre_parts = ['v_2_5'] - v_7_5 = models.FloatField(blank=True, null=True) - v_7_5_count = models.PositiveIntegerField(default=0) + v_digitale_lehre_parts = ['v_technisch_moeglich'] + v_8_1 = models.FloatField(blank=True, null=True) + v_8_1_count = models.PositiveIntegerField(default=0) v_feedbackpreis = models.FloatField(blank=True, null=True) v_feedbackpreis_count = models.PositiveIntegerField(default=0) v_feedbackpreis_parts = [ - 'v_3_2', 'v_3_6', 'v_3_8', 'v_4_4', 'v_4_6', 'v_4_7', 'v_5_2', 'v_5_4', 'v_6_1', 'v_6_2', 'v_6_3', 'v_8_1', + 'v_3_2', 'v_3_6', 'v_4_4', 'v_4_6', 'v_4_7', 'v_5_2', 'v_5_4', 'v_5_5', 'v_6_1', 'v_6_2', 'v_6_3', 'v_8_1', ] ue_didaktik = models.FloatField(blank=True, null=True) diff --git a/src/feedback/models/fragebogenUE2025.py b/src/feedback/models/fragebogenUE2025.py new file mode 100644 index 00000000..6c767e29 --- /dev/null +++ b/src/feedback/models/fragebogenUE2025.py @@ -0,0 +1,72 @@ +from django.db import models +from feedback.models import Fragebogen + + +class FragebogenUE2025(Fragebogen): + fach = models.CharField(max_length=5, choices=Fragebogen.FACH_CHOICES, blank=True) + abschluss = models.CharField(max_length=5, choices=Fragebogen.ABSCHLUSS_CHOICES, blank=True) + semester = models.CharField(max_length=4, choices=Fragebogen.SEMESTER_CHOICES16, blank=True) + geschlecht = models.CharField(max_length=1, choices=Fragebogen.GESCHLECHT_CHOICES, blank=True) + studienberechtigung = models.CharField(max_length=1, choices=Fragebogen.STUDIENBERECHTIGUNG_CHOICES, blank=True) + + ue_wie_oft_besucht = models.PositiveSmallIntegerField(blank=True, null=True) + ue_besuch_ueberschneidung = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_qualitaet = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_verhaeltnisse = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_privat = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_elearning = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_zufrueh = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + ue_besuch_sonstiges = models.CharField(max_length=1, choices=Fragebogen.BOOLEAN_CHOICES, blank=True) + + ue_3_1 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_2 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_3 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_4 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_5 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_6 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_7 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_3_8 = models.PositiveSmallIntegerField(blank=True, null=True) + + ue_4_1 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_2 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_3 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_4 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_5 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_6 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_7 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_8 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_9 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_4_10 = models.CharField(max_length=1, blank=True) + ue_4_11 = models.CharField(max_length=1, blank=True) + + kennziffer = models.PositiveSmallIntegerField(blank=True, null=True) + + ue_5_1 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_2 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_3 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_4 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_5 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_6 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_7 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_8 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_9 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_10 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_11 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_12 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_13 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_14 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_15 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_5_16 = models.PositiveSmallIntegerField(blank=True, null=True) + + ue_6_1 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_6_2 = models.PositiveSmallIntegerField(blank=True, null=True) + + ue_7_1 = models.CharField(max_length=1, choices=Fragebogen.STUNDEN_NACHBEARBEITUNG, blank=True) + ue_7_2 = models.PositiveSmallIntegerField(blank=True, null=True) + ue_7_3 = models.PositiveSmallIntegerField(blank=True, null=True) + + class Meta: + verbose_name = 'Übungsfragebogen 2025' + verbose_name_plural = 'Übungsfragebögen 2025' + ordering = ['semester', 'veranstaltung'] + app_label = 'feedback' diff --git a/src/feedback/parser/ergebnisse/parser2025.py b/src/feedback/parser/ergebnisse/parser2025.py index 9b6f66e0..d1c2e64a 100644 --- a/src/feedback/parser/ergebnisse/parser2025.py +++ b/src/feedback/parser/ergebnisse/parser2025.py @@ -37,10 +37,10 @@ def create_fragebogen(cls, veranst, frageb): v_3_7=cls.parse_int(frageb[27]), v_4_1=cls.parse_int(frageb[28]), - v_4_2=cls.parse_int(frageb[29]), + v_4_2=cls.parse_geschwindigkeit16(frageb[29]), v_4_3=cls.parse_int(frageb[30]), v_4_4=cls.parse_int(frageb[31]), - v_4_5=cls.parse_int(frageb[32]), + v_4_5=cls.parse_extrazeit(frageb[32]), v_4_6=cls.parse_int(frageb[33]), v_4_7=cls.parse_int(frageb[34]), @@ -59,6 +59,6 @@ def create_fragebogen(cls, veranst, frageb): v_6_5=cls.parse_int(frageb[46]), v_6_6=cls.parse_int(frageb[47]), - v_8_1=cls.parse_extrazeit(frageb[50]), - v_8_4=cls.parse_geschwindigkeit16(frageb[53]), + v_8_1=cls.parse_int(frageb[50]), + v_8_4=cls.parse_boolean(frageb[53]), ) diff --git a/src/feedback/parser/ergebnisse/parserUE2025.py b/src/feedback/parser/ergebnisse/parserUE2025.py new file mode 100644 index 00000000..0431c7c4 --- /dev/null +++ b/src/feedback/parser/ergebnisse/parserUE2025.py @@ -0,0 +1,65 @@ +# coding = utf-8 + +from feedback.models import FragebogenUE2025 +from feedback.parser.ergebnisse.parser import Parser + + +class ParserUE2025(Parser): + @classmethod + def create_fragebogen(cls, veranst, frageb): + FragebogenUE2025.objects.create( + veranstaltung=veranst, + fach=cls.parse_fach_16(frageb[1]), + abschluss=cls.parse_abschluss_16(frageb[3]), + semester=cls.parse_semester_16(frageb[4]), + geschlecht=cls.parse_geschlecht_16(frageb[5]), + studienberechtigung=cls.parse_studienberechtigung(frageb[6]), + ue_wie_oft_besucht=cls.parse_int(frageb[7]), + ue_besuch_ueberschneidung=cls.parse_boolean(frageb[8]), + ue_besuch_qualitaet=cls.parse_boolean(frageb[9]), + ue_besuch_verhaeltnisse=cls.parse_boolean(frageb[10]), + ue_besuch_privat=cls.parse_boolean(frageb[11]), + ue_besuch_elearning=cls.parse_boolean(frageb[12]), + ue_besuch_zufrueh=cls.parse_boolean(frageb[13]), + ue_besuch_sonstiges=cls.parse_boolean(frageb[14]), + ue_3_1=cls.parse_int(frageb[16]), + ue_3_2=cls.parse_int(frageb[17]), + ue_3_3=cls.parse_int(frageb[18]), + ue_3_4=cls.parse_int(frageb[19]), + ue_3_5=cls.parse_int(frageb[20]), + ue_3_6=cls.parse_int(frageb[21]), + ue_3_7=cls.parse_int(frageb[22]), + ue_3_8=cls.parse_int(frageb[23]), + ue_4_1=cls.parse_int(frageb[24]), + ue_4_2=cls.parse_int(frageb[25]), + ue_4_3=cls.parse_int(frageb[26]), + ue_4_4=cls.parse_int(frageb[27]), + ue_4_5=cls.parse_int(frageb[28]), + ue_4_6=cls.parse_int(frageb[29]), + ue_4_7=cls.parse_int(frageb[30]), + ue_4_8=cls.parse_int(frageb[31]), + ue_4_9=cls.parse_int(frageb[32]), + ue_4_10=cls.parse_geschwindigkeit16(frageb[33]), + ue_4_11=cls.parse_geschwindigkeit16(frageb[34]), + kennziffer=cls.parse_int(frageb[35]), + ue_5_2=cls.parse_int(frageb[36]), + ue_5_3=cls.parse_int(frageb[37]), + ue_5_4=cls.parse_int(frageb[38]), + ue_5_5=cls.parse_int(frageb[39]), + ue_5_6=cls.parse_int(frageb[40]), + ue_5_7=cls.parse_int(frageb[41]), + ue_5_8=cls.parse_int(frageb[42]), + ue_5_9=cls.parse_int(frageb[43]), + ue_5_10=cls.parse_int(frageb[44]), + ue_5_11=cls.parse_int(frageb[45]), + ue_5_12=cls.parse_int(frageb[46]), + ue_5_13=cls.parse_int(frageb[47]), + ue_5_14=cls.parse_int(frageb[48]), + ue_5_15=cls.parse_int(frageb[49]), + ue_5_16=cls.parse_int(frageb[50]), + ue_6_1=cls.parse_int(frageb[51]), + ue_6_2=cls.parse_int(frageb[52]), + ue_7_1=cls.parse_extrazeit(frageb[54]), + ue_7_2=cls.parse_int(frageb[55]), + ue_7_3=cls.parse_int(frageb[56]), + ) diff --git a/src/feedback/views/intern/__init__.py b/src/feedback/views/intern/__init__.py index 239015cb..f5997981 100644 --- a/src/feedback/views/intern/__init__.py +++ b/src/feedback/views/intern/__init__.py @@ -33,6 +33,7 @@ FachgebietEmail, Tutor from feedback.models.fragebogenUE2016 import FragebogenUE2016 from feedback.models.fragebogenUE2020 import FragebogenUE2020 +from feedback.models.fragebogenUE2025 import FragebogenUE2025 import feedback.parser.tan as tanparser @@ -516,13 +517,15 @@ def sync_ergebnisse(request): ergebnis.objects.filter(veranstaltung__semester=semester).delete() found_something = False - if semester.fragebogen == '2016' or semester.fragebogen == '2020': + if semester.fragebogen == '2016' or semester.fragebogen == '2020' or semester.fragebogen == '2025': for v in Veranstaltung.objects.filter(semester=semester): fbs = fragebogen.objects.filter(veranstaltung=v) if semester.fragebogen == '2016': erg = FragebogenUE2016.objects.filter(veranstaltung=v) - else: + elif semester.fragebogen == '2020': erg = FragebogenUE2020.objects.filter(veranstaltung=v) + else: + erg = FragebogenUE2025.objects.filter(veranstaltung=v) if len(fbs): found_something = True data = {'veranstaltung': v, 'anzahl': len(fbs)} From fd19e6d4ea8973c98fb92adce438411bd4afabc3 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:24:06 +0100 Subject: [PATCH 3/5] added test and test_data --- src/feedback/tests/test_parser_ergebnisse.py | 5 ++++- testdata/ergebnis_test_20255.csv | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 testdata/ergebnis_test_20255.csv diff --git a/src/feedback/tests/test_parser_ergebnisse.py b/src/feedback/tests/test_parser_ergebnisse.py index 14dfd68e..4ebcc8a2 100644 --- a/src/feedback/tests/test_parser_ergebnisse.py +++ b/src/feedback/tests/test_parser_ergebnisse.py @@ -3,7 +3,7 @@ from django.conf import settings from django.test import TestCase -from feedback.models import Semester, Veranstaltung, Fragebogen2008, Fragebogen2009, Fragebogen2012, Fragebogen2016 +from feedback.models import Semester, Veranstaltung, Fragebogen2008, Fragebogen2009, Fragebogen2012, Fragebogen2016, Fragebogen2025 from feedback.parser.ergebnisse import parse_ergebnisse from feedback.parser.ergebnisse.parser import Parser @@ -78,3 +78,6 @@ def test_parse_ergebnisse2012(self): def test_parse_ergebnisse2016(self): self._do_parse_ergebnisse_test(20155, '2016', Fragebogen2016) + + def test_parse_ergebnisse2025(self): + self._do_parse_ergebnisse_test(20255, '2025', Fragebogen2025) diff --git a/testdata/ergebnis_test_20255.csv b/testdata/ergebnis_test_20255.csv new file mode 100644 index 00000000..40ee5d70 --- /dev/null +++ b/testdata/ergebnis_test_20255.csv @@ -0,0 +1,7 @@ +"Teilbereich";"Anrede";"Titel";"Vorname";"Nachname";"Lehrveranstaltung";"Kennung";"Studiengang";"Raum";"Lehrveranstaltungsart";"Teilnehmer";"Sekundärdozenten";"Periode";"Sprache";"Studienabschnitt";"Pflicht/Wahlpflicht";Bogen;"Studienfach_FB20V";"V2_B";"Studienabschluss_FB20V";"Semester_FB20V";"Geschlecht_FB20V";"V2_F";"V2_G";"V2_H";"V2_I";"V3_A";"V3_B_1";"V3_B_2";"V3_B_3";"V3_B_4";"V3_B_5";"V3_B_6";"V3_B_7";"V3_C";"V4_J";"Technik_FB20V";"V4_B";"V4_G";"Nutzung_FB20V";"V5_G";"Feedback_FB20V";"V5_E";"V4_M";"V8_C";"V8_B";"V8_D";"Struktur_FB20V";"V8_A";"V4_D";"V4_E";"V5_D";"V5_A";"V4_I";"Lernziele_FB20V";"V4_H";"V4_K";"V4_L";"Mitarbeit_FB20V";"V4_F";"V5_B";"V5_C";"V5_H";"V5_I";"Note_FB20V";"V8_F";"V8_G";"V8_H";"V8_I";Zeitstempel;Datensatz-Ursprung +"FB 20";"Herr";"Dr.";"Je";"Mand";"Test I";"1";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";1;1;"[BILD]";1;2;1;1;2;2;2;8;0;0;3;0;0;0;0;"[BILD]";3;2;3;2;3;2;"test 1234";4;3;4;3;4;2;7;3;4;4;3;3;3;2;3;2;4;3;2;3;4;3;4;"test test";"test test test";1;"1234";09.11.2025 um 13:18:29;"O" +"FB 20";"Herr";"Dr.";"Je";"Mand";"Test I";"1";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";2;3;"[BILD]";2;2;2;2;2;1;1;3;0;2;0;4;0;0;0;"[BILD]";4;2;2;2;2;2;"12341234";3;2;4;4;5;4;3;4;1;1;1;2;4;2;2;3;4;0;0;0;4;3;3;"3456";"2345";2;"[BILD]";09.11.2025 um 13:20:21;"O" +"FB 20";"Herr";"Dr.";"Je";"Mand";"LV-Nr. existiert nicht";"2342";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";1;1;"[BILD]";1;2;1;1;2;2;2;8;0;0;3;0;0;0;0;"[BILD]";3;2;3;2;3;2;"test 1234";4;3;4;3;4;2;7;3;4;4;3;3;3;2;3;2;4;3;2;3;4;3;4;"test test";"test test test";1;"1234";09.11.2025 um 13:18:29;"O" +"FB 20";"Herr";"Dr.";"Je";"Mand";"V.-Name existiert nicht";"1234";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";1;1;"[BILD]";1;2;1;1;2;2;2;8;0;0;3;0;0;0;0;"[BILD]";3;2;3;2;3;2;"test 1234";4;3;4;3;4;2;7;3;4;4;3;3;3;2;3;2;4;3;2;3;4;3;4;"test test";"test test test";1;"1234";09.11.2025 um 13:18:29;"O" +"FB 20";"Herr";"Dr.";"Je";"Mand";"V. existiert nicht";"1337";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";2;3;"[BILD]";2;2;2;2;2;1;1;3;0;2;0;4;0;0;0;"[BILD]";4;2;2;2;2;2;"12341234";3;2;4;4;5;4;3;4;1;1;1;2;4;2;2;3;4;0;0;0;4;3;3;"3456";"2345";2;"[BILD]";09.11.2025 um 13:20:21;"O" +"FB 20";"Herr";"Dr.";"Je";"Mand";"Ergebnis bereits importiert";"9876";"";"";"Vorlesung";"10";"0";"WS25/26";"deutsch";"";"";2;3;"[BILD]";2;2;2;2;2;1;1;3;0;2;0;4;0;0;0;"[BILD]";4;2;2;2;2;2;"12341234";3;2;4;4;5;4;3;4;1;1;1;2;4;2;2;3;4;0;0;0;4;3;3;"3023";"2740";2;"[BILD]";09.11.2025 um 13:20:21;"O" From 6157b65c0efb0c90d1839120a416ecbcda926a52 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 12 Nov 2025 21:38:53 +0100 Subject: [PATCH 4/5] footer fix --- src/templates/d120/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/d120/footer.html b/src/templates/d120/footer.html index 303becc6..ff4fc251 100644 --- a/src/templates/d120/footer.html +++ b/src/templates/d120/footer.html @@ -7,7 +7,7 @@
- +