import csv import random from collections import defaultdict from otree.api import * DEBUG = False ### todo: Set to False for real experiment & controlstages working / True doc = """ AutoML """ ''' reads speed, temp & voltage csv ''' def read_csv(filename): with open(f"automl/data/{filename}.csv", encoding='utf-8-sig') as file: return [ dict( x=float(row['x'].replace(',', '.')), y=float(row['y'].replace(',', '.')), value=int(row['error']) ) for row in csv.DictReader(file, delimiter=";") ] ''' reads situation & secondphase csv ''' def read_situation(filename, second_phase = False): if second_phase: with open(f"automl/data/{filename}.csv", encoding='utf-8-sig') as file: return [ dict( temp=float(row['temp'].replace(',', '.')), speed=float(row['speed'].replace(',', '.')), volt=float(row['volt'].replace(',', '.')), outcome_low=int(row['outcome_low']), outcome_high=int(row['outcome_high']), error=int(row['error']) ) for row in csv.DictReader(file, delimiter=';') ] else: with open(f"automl/data/{filename}.csv", encoding='utf-8-sig') as file: return [ dict( temp=float(row['temp'].replace(',', '.')), speed=float(row['speed'].replace(',', '.')), volt=float(row['volt'].replace(',', '.')), outcome=int(row['outcome']), error=int(row['error']) ) for row in csv.DictReader(file, delimiter=';') ] ''' build rows for highchart chart out of read_csv ''' def group_rows(filename): d = defaultdict(list) for row in read_csv(filename): value = row['value'] d[value].append([row['x'], row['y']]) return d ''' build a series out of given rows (group_rows) has to be voltage, temp or speed as filename ''' def build_series(filename='voltage'): dicts = group_rows(filename) error_0 = {} error_1 = {} error_2 = {} output = [error_0, error_1] error_0['data'] = dicts[0] error_0['name'] = 'keine Störung' error_0['color'] = 'rgba(0, 230, 64, 1)' error_1['data'] = dicts[1] error_1['name'] = 'Störung' error_1['color'] = 'rgba(255, 0, 0, 1)' ## íf there is more than correct and incorrect if 2 in dicts.keys(): error_2['data'] = dicts[2] error_2['name'] = 'Undefined' error_2['color'] = 'rgba(52,45,113,1)' output.append(error_2) return output # return [error_0, error_1] ############# STARTING OTREE HERE ''' Here is the experiment controls ''' class C(BaseConstants): NAME_IN_URL = 'automl' PLAYERS_PER_GROUP = None TREATMENT = 0 ### Treatment 0 or 1 or 2 EARNINGS = 10 ## Taler Earnings INTERVALL_ROUNDS = 0 # Choosing and showing intervals LEARNING_SCENARIOS = 4 # Show different types of point recognition SCENARIOS = 10 # ask for real answers from the participants SITUATIONS_ROUNDS = 0 ## 1 page, no additional anything, just for programm to run as intended EXPERIMENT_ROUNDS = 10 SECONDPHASE_ROUNDS = 25# 30 #swap back , but dont wanna klick so much NUM_ROUNDS = SITUATIONS_ROUNDS * 2 + EXPERIMENT_ROUNDS + SECONDPHASE_ROUNDS ## Pathes to the underlying html pages INSTRUCTION_TEMPLATE = "automl/instructions1.html" LEARNING_INSTRUCTIONS = "automl/learning_instructions.html" CHART_TEMPLATE = 'automl/chart.html' X_RANGE_CHART_TEMPLATE = 'automl/x-range-chart.html' X_RANGE_CHART_OVERVIEW_TEMPLATE = 'automl/x-range-chart-overview.html' X_RANGE_CHART_OVERVIEW_FORMFIELDS_TEMPLATE = 'automl/x-range-chart-overview-with-formfields.html' INTRODUCTION_1 = 'automl/introduction_1.html' INTRODUCTION_2 = 'automl/introduction_2.html' CHART_OVERVIEW_TEMPLATE = 'automl/chart_overview.html' TREATMENT0_TEXT = "automl/treatment_0.html" TREATMENT0_RESULT_TEXT = "automl/result_treatment_0.html" TREATMENT1_TEXT = "automl/treatment_1.html" TREATMENT1_RESULT_TEXT = "automl/result_treatment_1.html" INSTRUCTION_2= 'automl/instruction2.html' \ '' ### series for point/scatter charts ROWS_VOLT = build_series("voltage") ROWS_SPEED = build_series("speed") ROWS_TEMP = build_series("temp") ROWS_EXAMPLE = build_series('example') ## series for x-range ROWS_SITUATIONS = read_situation('situations') ROWS_SECOND_PHASE = read_situation('second_phase', True) ## Names for Graphs (swap as you like) ## TITLES = ['Temperatur', 'Geschwindigkeit', 'Auslastung'] X_TITLES = ['', '', ''] Y_TITLES = ['', '', ''] ## chart titles CHART_TITLES = ['', #für temperatur '', #für zweites ''] #für drittes DISTURBANCE_DISTRIBUTION = [0.05, 0.35, 0.65, 0.95] Y_RANGE = [0, 1] X_RANGE = [0, 5] DESCRIPTION = ['sehr unwahrscheinlich', 'unwahrscheinlich', 'wahrscheinlich', 'sehr wahrscheinlich'] ## Text FAUSTREGEL_1 = [ "Faustregel 1: Temperatur des Motors. Ihnen liegen Vergangenheitsdaten über Störungen bei unterschiedlichen Temperaturen vor. Die Farbe der Messpunkte über einer Temperatur zeigt, ob in Vergangenheit bei dieser Temperatur eine Störung auftrat. ", "Grüne Punkte bedeuten, dass bei dieser Temperatur keine Störung vorlag. Rote Punkte bedeuten, dass es bei " "dieser Temperatur eine Störung gab. Da zwei andere Parameter ebenfalls einen Einfluss darauf haben, " "ob eine Störung vorliegt, kann es bei zwei verschiedenen Messpunkten mit gleicher Temperatur zu " "unterschiedlichen Ereignissen (Störung bzw. keine Störung) kommen", "Welchen Temperaturintervall halten Sie für akzeptabel? Dieser Intervall wird Ihnen in späteren Entscheidungssituationen angezeigt und kann Ihnen als Entscheidungshilfe (Faustregel) dienen."] FAUSTREGEL_2 = [ "Faustregel 2: Geschwindigkeit des Förderbandes. Ihnen liegen Vergangenheitsdaten über Störungen bei unterschiedlichen Geschwindigkeiten vor. Die Farbe der Messpunkte über einer Geschwindigkeit zeigt, ob in Vergangenheit bei dieser Geschwindigkeit eine Störung auftrat. ", "Grüne Punkte bedeuten, dass bei dieser Geschwindigkeit keine Störung vorlag. Rote Punkte bedeuten, " "dass es bei dieser Geschwindigkeit eine Störung gab. Da zwei andere Parameter ebenfalls einen Einfluss " "darauf haben, ob eine Störung vorliegt, kann es bei zwei verschiedenen Messpunkten mit gleicher " "Geschwindigkeit zu unterschiedlichen Ereignissen (Störung bzw. keine Störung) kommen", "Ihre Faustregel für die Geschwindigkeit: Welchen Geschwindigkeitsintervall halten Sie für akzeptabel? Dieser Intervall wird Ihnen in späteren Entscheidungssituationen angezeigt und kann Ihnen als Entscheidungshilfe (Faustregel) dienen."] FAUSTREGEL_3 = [ "Faustregel 3: Auslastung der Funktionselemente. Ihnen liegen Vergangenheitsdaten über Störungen bei unterschiedlichen Auslastungen vor. Die Farbe der Messpunkte über einer Auslastung zeigt, ob in Vergangenheit bei dieser Auslastung eine Störung auftrat.", "Grüne Punkte bedeuten, dass bei dieser Auslastung keine Störung vorlag. Rote Punkte bedeuten, dass es bei dieser Auslastung eine Störung gab. Da zwei andere Parameter ebenfalls einen Einfluss darauf haben, ob eine Störung vorliegt, kann es bei zwei verschiedenen Messpunkten mit gleicher Auslastung zu unterschiedlichen Ereignissen (Störung bzw. keine Störung) kommen.", "Ihre Faustregel für die Auslastung: Welchen Auslastungsintervall halten Sie für akzeptabel? Dieser Intervall wird Ihnen in späteren Entscheidungssituationen angezeigt und kann Ihnen als Entscheidungshilfe (Faustregel) dienen."] EINHEIT = ["°C", "m/s", "%"] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): ki_accuracy = models.IntegerField(initial=0) volt_min = models.FloatField(initial=0) volt_max = models.FloatField(initial=0) speed_min = models.FloatField(initial=0) speed_max = models.FloatField(initial=0) temp_min = models.FloatField(initial=0) temp_max = models.FloatField(initial=0) swapped = models.BooleanField(initial=False) experiment_correct_counter = models.IntegerField(initial=0) experiment_correct_interval_counter = models.IntegerField(initial=0) learning_input = models.IntegerField( choices=[ [-2, 'sehr unwahrscheinlich'], [-1, 'unwahrscheinlich'], [1, 'wahrscheinlich'], [2, 'sehr wahrscheinlich']], widget=widgets.RadioSelectHorizontal ) bonus = models.CurrencyField( initial=0, min=0, max=250, ) introduction_control1 = models.IntegerField( label="Was ist Ihre Aufgabe im Experiment?", choices=[ [1, "Die Wahrscheinlichkeit einer Störung bei der Produktionsanlage zu bewerten und darauf basiert zu entscheiden, ob die Anlage gewartet werden soll."], [2, "Zu erraten, wann eine Störung als nächstes auftritt."], [3, "Die KI zu trainieren, damit sie eigenständig Entscheidungen über die Wartungsnotwendigkeit treffen kann."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control2 = models.IntegerField( label="Was passiert, wenn Sie sich entscheiden, die Produktionsanlage zu warten?", choices=[ [1, "Sie können zu 50% produzieren und bekommen die Hälfte der Auszahlung für die Runde."], [2, "Eine Störung kann trotzdem auftreten und Sie können Ihre Auszahlung für die Runde verlieren."], [3, "Sie können zu 100% produzieren und die maximale Auszahlung für die Runde bekommen."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control3 = models.IntegerField( label="Was passiert, wenn Sie sich entscheiden, die Produktionsanlage nicht zu warten?", choices=[ [1, "Eine Störung ist ausgeschlossen."], [2, "Sie können zu 50% produzieren und bekommen die Hälfte der Auszahlung für die Runde."], [3, "Sie können zu 100% produzieren und die maximale Auszahlung für die Runde bekommen, es kann aber auch eine Störung auftreten und Sie würden Ihre Auszahlung für die Runde verlieren."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control4 = models.IntegerField( label="Welche Aussage über den Optimalbereich eines Indikators ist richtig?", choices=[ [1, "Optimalbereiche aller Indikatoren sind bekannt."], [2, "Wenn ein Indikator mit seinem Wert im Optimalbereich liegt, ist es für die Anlage besonders gut."], [3, "Der Optimalbereich und der Akzeptanzbereich sind identisch."] ], widget=widgets.RadioSelect, #initial=3 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control5 = models.IntegerField( label="Welche Aussage über den Akzeptanzbereich eines Indikators ist richtig?", choices=[ [1, "Der Akzeptanzbereich ist immer gleich dem Optimalbereich."], [2, "Je näher Ihr Akzeptanzbereich am tatsächlichen Optimalbereich liegt, desto genauer können Sie Störungswahrscheinlichkeiten bewerten."], [3, "Sie können die Akzeptanzbereiche nicht beeinflussen."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control6 = models.IntegerField( label="Welche Aussage über die Künstliche Intelligenz (KI) ist richtig?", choices=[ [1, "Die KI trifft die Entscheidung über die Wartungsnotwendigkeit komplett eigenständig."], [2, "Die KI gibt Ihnen eine verbindliche Anweisung."], [3, "Die KI gibt Ihnen eine unverbindliche Empfehlung als Entscheidungshilfe."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control7 = models.IntegerField( label="Wie wird die KI angelernt?", choices=[ [1, "Die KI wird mithilfe von Big Data angelernt."], [2, "Die KI wird ausschließlich mit den Daten über vergangene Störungen angelernt."], [3, "Die KI wird mit den Daten über vergangene Störungen und mit Informationen über Ihre Akzeptanzbereiche angelernt."] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) introduction_control8 = models.IntegerField( label="Welche Aussage über die Genauigkeit der KI ist richtig?", choices=[ [1, "Die KI ist immer besser als ein Mensch."], [2, "Die KI ist immer schlechter als ein Mensch."], [3, "Die Genauigkeit der KI hängt vom Erfolg der Anlernphase ab und kann bei (gerundet)) 50% oder bei 90% liegen."] ], widget=widgets.RadioSelect, #initial=3 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) ki_control1 = models.IntegerField( label="Welche Aussage über die KI ist richtig?", choices=[ [1, "Die KI gibt eine unverbindliche Empfehlung dazu, ob eine Wartung in einer Zeitperiode sinnvoll ist"], [2, "Die KI ersetzt Sie vollständig in Ihrer Aufgabe, Wartungsentscheidungen zu treffen"], [3, "Die Empfehlung der KI ist für Sie verbindlich"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) ki_control2 = models.IntegerField( label="Welche Aussage über die Funktionsweise der KI ist richtig?", choices=[ [1,"Die KI kann mit 100%-er Genauigkeit potenzielle Störungen erkennen, deshalb ist ihre Empfehlung immer richtig"], [2, "Die KI ist ein einfaches regelbasiertes Rechenmodell"], [3, "Das hochkomplexe Modell der KI entsteht durch einen Lernprozess und basiert auf umfangreichen Vergangenheitsdaten"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) ki_control3 = models.IntegerField( label="Welche Aussage über die KI und die Faustregeln ist richtig?", choices=[ [1, "Eine Faustregel bildet die Realität sehr genau ab"], [2, "Das datenbasierte mehrdimensionale Model der KI kann die Komplexität der realen Welt besser abbilden"], [3, "Die Faustregeln sind erwartungsgemäß genauer als die KI"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) # situation_control_1 = models.IntegerField( # label="Wie bewerten Sie diese Beispielsituation basierend auf Ihren Akzeptanzbereiche?", # choices=[ # [-2, "sehr unwahrscheinlich"], # [-1, "unwahrscheinlich"], # [1, "wahrscheinlich"], # [2, "sehr wahrscheinlich"], # ], # widget=widgets.RadioSelect, # initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann # ) situation_control_1 = models.IntegerField( label="Wie bewerten Sie diese Beispielsituation basierend auf Ihren Akzeptanzbereichen?", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) situation_control_2 = models.IntegerField( label="Wie bewerten Sie diese Beispielsituation basierend auf Ihren Faustregeln?", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) situation_control_3 = models.IntegerField( label="Wie bewerten Sie diese Beispielsituation basierend auf Ihren Faustregeln?", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) situation_control_4 = models.IntegerField( label="Wie bewerten Sie diese Beispielsituation basierend auf Ihren Faustregeln?", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) experiment_answer = models.IntegerField( label="Wie bewerten Sie die Störungswahrscheinlichkeit in dieser Anlernsituation?", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelect, #initial=0, ) maintenance_self = models.BooleanField( label="Möchten Sie in dieser Zeitperiode eine Wartung vornehmen?", choices=[ [False, 'Nein'], [True, 'Ja'], ]) disturbance_self = models.IntegerField( label="Eine Störung in dieser Zeitperiode ist: ", choices=[ [-2, "sehr UNwahrscheinlich"], [-1, "UNwahrscheinlich"], [1, "wahrscheinlich"], [2, "sehr wahrscheinlich"], ], widget=widgets.RadioSelectHorizontal ) maintenance_ki = models.BooleanField( label="Möchten Sie in dieser Zeitperiode eine Wartung vornehmen?", choices=[ [False, 'Nein'], [True, 'Ja'], ]) age = models.IntegerField( label="Wie alt sind Sie?", ) gender = models.IntegerField( label="Welchem Geschlecht fühlen Sie sich zugehörig?", choices=[ [1, "weiblich"], [2, "männlich"], [3, "nicht-binär"] ], widget=widgets.RadioSelect, #initial=1 ## TODO: herausnehmen wenn keine vorauswahl gewünscht ist, nur damit schneller geklickt werden kann ) educ = models.IntegerField( label="Bitte geben Sie Ihren höchsten (bereits erlangten) Bildungsabschluss an.", choices=[ [1, "Haupt-/Volksschulabschluss"], [2, "Realschulabschluss"], [3, "Abitur/Fachabitur"], [4, "Bachelor"], [5, "Master"], [6, "Sonstiges"] ], widget=widgets.RadioSelect, ) major = models.StringField( label="Bitte geben Sie Ihren aktuellen Studiengang an.", ) expert1 = models.IntegerField( label="Ich glaube, dass meine Schätzungen der Störungswahrscheinlichkeiten richtig waren.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], [6, "6"], [7, "7"], ], widget=widgets.RadioSelectHorizontal, ) expert2 = models.IntegerField( label="Ich glaube, dass meine Schätzungen der Störungswahrscheinlichkeiten nahe am wahren Wert liegen.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], [6, "6"], [7, "7"], ], widget=widgets.RadioSelectHorizontal, ) expert3 = models.IntegerField( label="Ich war mir sehr sicher, was die Genauigkeit meiner Schätzungen der Störungswahrscheinlichkeiten betrifft.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], [6, "6"], [7, "7"], ], widget=widgets.RadioSelectHorizontal, ) expert4 = models.IntegerField( label="Ich war sicher, dass ich bei der Aufgabe gut abschneiden werde.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], [6, "6"], [7, "7"], ], widget=widgets.RadioSelectHorizontal, ) expert5 = models.IntegerField( label=" Ich habe keine Zweifel, dass meine Schätzungen der Störungswahrscheinlichkeiten nahe an den wahren Werten liegen.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], [6, "6"], [7, "7"], ], widget=widgets.RadioSelectHorizontal, ) asku1 = models.IntegerField( label="In schwierigen Situationen kann ich mich auf meine Fähigkeiten verlassen.", choices=[ [1, "Trifft gar nicht zu"], [2, "Trifft wenig zu"], [3, "Trifft etwas zu"], [4, "Trifft ziemlich zu"], [5, "Trifft voll und ganz zu"], ], widget=widgets.RadioSelect, ) asku2 = models.IntegerField( label="Die meisten Probleme kann ich aus eigener Kraft gut meistern.", choices=[ [1, "Trifft gar nicht zu"], [2, "Trifft wenig zu"], [3, "Trifft etwas zu"], [4, "Trifft ziemlich zu"], [5, "Trifft voll und ganz zu"], ], widget=widgets.RadioSelect, ) asku3 = models.IntegerField( label="Auch anstrengende und komplizierte Aufgaben kann ich in der Regel gut lösen.", choices=[ [1, "Trifft gar nicht zu"], [2, "Trifft wenig zu"], [3, "Trifft etwas zu"], [4, "Trifft ziemlich zu"], [5, "Trifft voll und ganz zu"], ], widget=widgets.RadioSelect, ) percex1 = models.IntegerField( label="Ich konnte das im Experiment dargestellte Wartungsszenario gut nachvollziehen.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], ], widget=widgets.RadioSelect, ) percex2 = models.IntegerField( label="Ich konnte mich in die Rolle eines Produktionsanlageverantwortlichen versetzen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex3 = models.IntegerField( label="Die mir zur Verfügung gestellten Informationen und Beispiele haben mich gut auf die Entscheidungen im Experiment vorbereitet.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex4 = models.IntegerField( label="Die meisten Erläuterungen im Experiment konnte ich nachvollziehen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex5 = models.IntegerField( label="Ich habe die im Experiment dargestellten Zusammenhänge verstanden.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex6 = models.IntegerField( label="Ich wusste genau, was im Experiment von mir verlangt wurde.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex7 = models.IntegerField( label="Ich wusste, was ich tun muss, um im Experiment möglichst erfolgreich zu sein.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex8 = models.IntegerField( label="Die Aufgaben im Experiment waren anspruchsvoll.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex9 = models.IntegerField( label="Ich bin mit meiner Leistung im Experiment zufrieden.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) percex10 = models.IntegerField( label="Ich denke, die meisten Experimentteilnehmer haben die Aufgaben gut gelöst.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat1 = models.IntegerField( label="Die Anlernphase der KI war gut investierte Zeit.", choices=[ [1, "1"], [2, "2"], [3, "3"], [4, "4"], [5, "5"], ], widget=widgets.RadioSelect, ) perctreat2 = models.IntegerField( label="Ich hätte gerne noch mehr Zeit investiert, um die KI anzulernen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat3 = models.IntegerField( label="Ich habe maßgeblich dazu beigetragen, wie gut die Qualität der KI-Empfehlungen war.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat4 = models.IntegerField( label="Ich hatte das Gefühl, dass es ein Glückspiel ist, ob man am Ende der Anlernphase eine gute oder eine schlechte KI erhält.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat5 = models.IntegerField( label="Das Anlernen der KI hat mir geholfen, besser zu verstehen, wie die Empfehlungen der KI zustande kommen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat6 = models.IntegerField( label="Das Anlernen der KI hat mir geholfen, die Funktionsweise der KI besser zu verstehen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat7 = models.IntegerField( label="Ich fand es gut, dass mein Expertenwissen, in Form meiner Akzeptanzintervalle, mit der KI geteilt wurde.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat8 = models.IntegerField( label="Ich fand es unangenehm, dass die KI Zugriff auf mein Expertenwissen, in Form meiner Akzeptanzintervalle, hatte.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat9 = models.IntegerField( label="Wenn ich eine Möglichkeit gehabt hätte, hätte ich gerne noch mehr Wissen mit der KI geteilt.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat10 = models.IntegerField( label="Wenn ich die Möglichkeit gehabt hätte, hätte ich lieber gar kein Wissen mit der KI geteilt.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat11 = models.IntegerField( label="Mein Einfluss auf das Anlernen der KI war groß.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat12 = models.IntegerField( label="Das Anlernen der KI hat mir Spaß gemacht.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat13 = models.IntegerField( label="Die Empfehlungen der KI habe ich als qualitativ hochwertig eingeschätzt.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat14 = models.IntegerField( label="Bei den Entscheidungen, ob eine Wartung vorgenommen werden soll, habe ich logisch abgewägt.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) perctreat15 = models.IntegerField( label="Die Entscheidungen, ob eine Wartung vorgenommen werden soll, habe ich eher intuitiv als strategisch getroffen.", choices=[ [1, ""], [2, ""], [3, ""], [4, ""], [5, ""], ], widget=widgets.RadioSelect, ) ati_1 = models.IntegerField( label="Ich beschäftige mich gern genauer mit technischen Systemen.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_2 = models.IntegerField( label="Ich probiere gern die Funktionen neuer technischer Systeme aus.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_3 = models.IntegerField( label="In erster Linie beschäftige ich mich mit technischen Systemen, weil ich muss.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_4 = models.IntegerField( label="Wenn ich ein neues technisches System vor mir habe, probiere ich es intensiv aus.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_5 = models.IntegerField( label="Ich verbringe sehr gern Zeit mit dem Kennenlernen eines neuen technischen Systems.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_6 = models.IntegerField( label="Es genügt mir, dass ein technisches System funktioniert, mir ist es egal, wie oder warum.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_7 = models.IntegerField( label="Ich versuche zu verstehen, wie ein technisches System genau funktioniert.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_8 = models.IntegerField( label="Es genügt mir, die Grundfunktionen eines technischen Systems zu kennen.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) ati_9 = models.IntegerField( label="Ich versuche, die Möglichkeiten eines technischen Systems vollständig auszunutzen.", choices=[ [1, "stimmt gar nicht"], [2, "stimmt weitgehend nicht"], [3, "stimmt eher nicht"], [4, "stimmt eher"], [5, "stimmt weitgehend"], [6, "stimmt völlig"], ], widget=widgets.RadioSelect, ) comment = models.LongStringField( blank=True, label="Möchten Sie uns noch etwas mitteilen? (optional)", ) counter = models.IntegerField(initial=-1) ## 0 = Y , 1 = W , 2 = Z # PAGES class ResultsWaitPage(WaitPage): pass class Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS ###show only in last ### Reihenfolge hier nochmal neu class CabinNumber(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first @staticmethod def vars_for_template(player: Player): return dict( title="Einführung ", ) class IntroductionControl(Page): form_model = 'player' form_fields = ['introduction_control1', 'introduction_control2', 'introduction_control3', 'introduction_control4'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first @staticmethod def error_message(player, values): if not DEBUG: if values['introduction_control1'] != 1 or values['introduction_control2'] != 1 or values[ 'introduction_control3'] != 3 or values['introduction_control4'] != 2: return 'Sie haben falsch geantwortet, bitte überprüfen Sie noch einmal Ihre Antworten.' class IntroductionControl2(Page): form_model = 'player' form_fields = ['introduction_control5', 'introduction_control6', 'introduction_control7', 'introduction_control8'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first @staticmethod def error_message(player, values): if not DEBUG: if values['introduction_control5'] != 2 or values['introduction_control6'] != 3 or values[ 'introduction_control7'] != 3 or values['introduction_control8'] != 3: return 'Sie haben falsch geantwortet, bitte überprüfen Sie noch einmal Ihre Antworten.' class Introduction2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first class Instructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 ## just in the first @staticmethod def js_vars(player: Player): data_1 = get_example_data_for_situation_descrition(0) return dict( min_temp_1=data_1[0], max_temp_1=data_1[1], min_volt_1=data_1[2], max_volt_1=data_1[3], min_speed_1=data_1[4], max_speed_1=data_1[5], speed_1=-1, # 0.5, ##todo: daten irgendwo herholen volt_1=-1, # 2.5, temp_1=-1, # 3, title_1 = "Ueberschrift zu entscheiden" ) class SituationDescription(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 # and player.round_number < C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS @staticmethod def js_vars(player: Player): data_1 = get_example_data_for_situation_descrition(0) data_2 = get_example_data_for_situation_descrition(1) data_3 = get_example_data_for_situation_descrition(2) data_4 = get_example_data_for_situation_descrition(3) return dict( min_temp_1=data_1[0], max_temp_1=data_1[1], min_volt_1=data_1[2], max_volt_1=data_1[3], min_speed_1=data_1[4], max_speed_1=data_1[5], speed_1=data_1[8], # 0.5, ##todo: daten irgendwo herholen volt_1=data_1[7], # 2.5, temp_1=data_1[6], # 3, title_1=data_1[9], min_temp_2=data_2[0], max_temp_2=data_2[1], min_volt_2=data_2[2], max_volt_2=data_2[3], min_speed_2=data_2[4], max_speed_2=data_2[5], speed_2=data_2[8], # 0.5, ##todo: daten irgendwo herholen volt_2=data_2[7], # 2.5, temp_2=data_2[6], # 3, title_2=data_2[9], min_temp_3=data_3[0], max_temp_3=data_3[1], min_volt_3=data_3[2], max_volt_3=data_3[3], min_speed_3=data_3[4], max_speed_3=data_3[5], speed_3=data_3[8], # 0.5, ##todo: daten irgendwo herholen volt_3=data_3[7], # 2.5, temp_3=data_3[6], # 3, title_3=data_3[9], min_temp_4=data_4[0], max_temp_4=data_4[1], min_volt_4=data_4[2], max_volt_4=data_4[3], min_speed_4=data_4[4], max_speed_4=data_4[5], speed_4=data_4[8], # 0.5, ##todo: daten irgendwo herholen volt_4=data_4[7], # 2.5, temp_4=data_4[6], # 3, title_4=data_4[9], ) class SituationDescriptionControl(Page): form_model = 'player' form_fields = ['situation_control_2', 'situation_control_3', 'situation_control_1', 'situation_control_4'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 # player.round_number == C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2 - 1 @staticmethod def error_message(player: Player, values): if not DEBUG: #TODO: Hier noch die richtigen antworten in die situationcontrollen abfragen! #if values['situation_control_1'] != get_example_data_for_situation_descrition(0)['answer']:#vermutlich gehts nicht über answer sondern über den Schlüssel 10 if values['situation_control_1'] != -2 or values['situation_control_2'] != -1 or values['situation_control_3'] != 1 or values['situation_control_4'] != 2: return 'Sie haben falsch geantwortet, bitte überprüfen Sie noch einmal Ihre Antworten' #wahr, sehr unw, sehr w, unw. @staticmethod def js_vars(player: Player): data_1 = get_example_data_for_situation_descrition(0 ) data_2 = get_example_data_for_situation_descrition(1) data_3 = get_example_data_for_situation_descrition(2) data_4 = get_example_data_for_situation_descrition( 3) ##todo : change data, swap titles, get answers return dict( ## umsoriteren nach 2,0,3,1) min_temp_1=data_1[0], max_temp_1=data_1[1], min_volt_1=data_1[2], max_volt_1=data_1[3], min_speed_1=data_1[4], max_speed_1=data_1[5], speed_1=data_1[8], # 0.5, ##todo: daten irgendwo herholen volt_1=data_1[7], # 2.5, temp_1=data_1[6], # 3, title_1=data_1[9], min_temp_2=data_2[0], max_temp_2=data_2[1], min_volt_2=data_2[2], max_volt_2=data_2[3], min_speed_2=data_2[4], max_speed_2=data_2[5], speed_2=data_2[8], # 0.5, ##todo: daten irgendwo herholen volt_2=data_2[7], # 2.5, temp_2=data_2[6], # 3, title_2=data_2[9], min_temp_3=data_3[0], max_temp_3=data_3[1], min_volt_3=data_3[2], max_volt_3=data_3[3], min_speed_3=data_3[4], max_speed_3=data_3[5], speed_3=data_3[8], # 0.5, ##todo: daten irgendwo herholen volt_3=data_3[7], # 2.5, temp_3=data_3[6], # 3, title_3=data_3[9], min_temp_4=data_4[0], max_temp_4=data_4[1], min_volt_4=data_4[2], max_volt_4=data_4[3], min_speed_4=data_4[4], max_speed_4=data_4[5], speed_4=data_4[8], # 0.5, ##todo: daten irgendwo herholen volt_4=data_4[7], # 2.5, temp_4=data_4[6], # 3, title_4=data_4[9], ) class ExperimentStart(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 # player.round_number == C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2 - 1 class DescriptionInterval(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def js_vars(player: Player): return dict( series_example=C.ROWS_EXAMPLE, # todo series anpassen title="Beispieldiagramm", xTitle="", yTitle="", ) @staticmethod def live_method(player, data): if DEBUG: print('min and max from player', player.id_in_group, ':', data) #fill_player_min_max(player, data[0], data[1]) class IntervallEingabe(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def live_method(player: Player, data): if DEBUG: print("input player (", player.id_in_group, ") : ", data) fill_data(player,data) @staticmethod def js_vars(player: Player): return dict( series_temp=get_series(1), series_speed=get_series(2), series_volt = get_series(3), min_temp=-1, min_speed=-1, min_volt=-1, max_temp=-1, max_speed=-1, max_volt=-1, x_title_temp=C.X_TITLES[0], y_title_temp=C.Y_TITLES[0], chart_title_temp=C.CHART_TITLES[0], volt=-1, speed=-1, temp=-1, ) class KIInfo(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class KIControl(Page): form_model = 'player' form_fields = ['ki_control1', 'ki_control2', 'ki_control3'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def error_message(player, values): if not DEBUG: if values['ki_control1'] != 3 or values['ki_control2'] != 1 or values[ 'ki_control3'] != 2: return 'Sie haben falsch geantwortet, bitte überprüfen Sie noch einmal Ihre Antworten' ## Treatment 1 und 0 , unterschiede nur in der Anzeige class Experiment(Page): form_model = 'player' form_fields = ['experiment_answer'] @staticmethod def is_displayed(player: Player): return player.round_number <= C.EXPERIMENT_ROUNDS @staticmethod def vars_for_template(player: Player): ## geändert sodass er nur die Daten aus der ersten Runde holt, wo der Spieler es auch eingegeben hat copy_old_player_to_this_player(player, player.in_round(1)) print(player.temp_min,player.temp_max) ##my_dict['treatment'] = C.TREATMENT my_dict = C.ROWS_SITUATIONS[player.round_number-1] if C.TREATMENT == 0: inside_temp = player.temp_min <= my_dict['temp'] <= player.temp_max #inside_temp = my_dict['temp'] in [player.temp_min, player.temp_max] inside_speed = player.speed_min <= my_dict['speed'] <= player.speed_max inside_volt = player.volt_min <= my_dict['volt'] <= player.volt_max if DEBUG: print(f'inside temp: {inside_temp} ; inside_speed : {inside_speed}; inside_volt : {inside_volt}') inside_points = int(inside_volt + inside_temp + inside_speed) real_answer = [2, 1, -1, -2] # [-2, -1, 1, 2] my_dict['outcome_generated'] = real_answer[inside_points] player.experiment_answer = my_dict['outcome_generated'] tendenz = my_dict['outcome']* my_dict['outcome_generated'] > 0 else: my_dict['outcome_generated'] = 0 # änderung von " " return dict( treatment=C.TREATMENT, ROUND = player.round_number, MAX_ROUNDS = C.EXPERIMENT_ROUNDS, outcome=get_description(my_dict['outcome_generated']), outcome_hidden = my_dict['outcome_generated'], ) @staticmethod def js_vars(player: Player): ## geändert sodass er nur die Daten aus der ersten Runde holt, wo der Spieler es auch eingegeben hat copy_old_player_to_this_player(player, player.in_round(1)) if DEBUG: print(f'{player.round_number} - {C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2}') my_dict = C.ROWS_SITUATIONS[player.round_number -1 ] my_dict['min_temp'] = player.temp_min my_dict['max_temp'] = player.temp_max my_dict['min_speed'] = player.speed_min my_dict['max_speed'] = player.speed_max my_dict['min_volt'] = player.volt_min my_dict['max_volt'] = player.volt_max if DEBUG: print(my_dict) return my_dict @staticmethod def before_next_page(player, timeout_happened): # check if right answer in regard of outcome my_dict = C.ROWS_SITUATIONS[player.round_number - 1] if C.TREATMENT==1: # if player.experiment_answer == my_dict['outcome']: if player.experiment_answer * my_dict['outcome'] > 0 : ## Same sign player.experiment_correct_counter = 1 # check if right answer in regard of intervals #inside_temp = my_dict['temp'] in [player.temp_min, player.temp_max] #inside_speed = my_dict['speed'] in [player.speed_min, player.speed_max] #inside_volt = my_dict['volt'] in [player.volt_min, player.volt_max] inside_temp = player.temp_min <= my_dict['temp'] <= player.temp_max inside_speed = player.speed_min <= my_dict['speed'] <= player.speed_max inside_volt = player.volt_min <= my_dict['volt'] <= player.volt_max if DEBUG: print(f'inside temp: {inside_temp} ; inside_speed : {inside_speed}; inside_volt : {inside_volt}') inside_points = int(inside_volt + inside_temp + inside_speed) real_answer = [2, 1, -1, -2]#[-2, -1, 1, 2] # if player.experiment_answer == real_answer[inside_points]: ##todo: same sign instead of equal answer ! if player.experiment_answer * real_answer[inside_points] > 0 : ## Same sign player.experiment_correct_interval_counter = 1 if C.TREATMENT==0: inside_temp = player.temp_min <= my_dict['temp'] <= player.temp_max inside_speed = player.speed_min <= my_dict['speed'] <= player.speed_max inside_volt = player.volt_min <= my_dict['volt'] <= player.volt_max inside_points = int(inside_volt + inside_temp + inside_speed) real_answer = [2, 1, -1, -2] # [-2, -1, 1, 2] my_dict['outcome_generated'] = real_answer[inside_points] if my_dict['outcome'] * real_answer[inside_points] > 0 : ## richtige tendenz player.experiment_correct_counter = 1 player.experiment_correct_interval_counter = 1 ## macht hier halt kein sinn, nur für die auswertung return dict( reality=my_dict['outcome'], subjectivity=my_dict['outcome_generated'], tendency=player.experiment_correct_counter ) class ResultKI(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS @staticmethod def vars_for_template(player: Player): correct_answers = sum(p.experiment_correct_counter for p in player.in_rounds(1 , C.EXPERIMENT_ROUNDS )) player.ki_accuracy = 50 player.participant.vars['low'] = True if correct_answers >= 7: player.ki_accuracy = 90 player.participant.vars['low'] = False if DEBUG: print(f'Correct Answers = {correct_answers}') return dict( treatment=C.TREATMENT, correct_answers=correct_answers, bad_ki = player.participant.vars['low'] ) class SecondPhaseSelf(Page): form_fields = ['disturbance_self', 'maintenance_self'] form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number >= C.EXPERIMENT_ROUNDS and player.round_number <=(C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS-1) @staticmethod def vars_for_template(player: Player): return dict( ROUND=player.round_number - (C.EXPERIMENT_ROUNDS)+1, MAX_ROUNDS=C.SECONDPHASE_ROUNDS ) @staticmethod def js_vars(player: Player): copy_old_player_to_this_player(player, player.in_round(1)) my_dict = C.ROWS_SECOND_PHASE[ player.round_number - (C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2 + C.EXPERIMENT_ROUNDS)] my_dict['min_temp'] = player.temp_min my_dict['max_temp'] = player.temp_max my_dict['min_speed'] = player.speed_min my_dict['max_speed'] = player.speed_max my_dict['min_volt'] = player.volt_min my_dict['max_volt'] = player.volt_max return my_dict class SecondPhaseKI(Page): form_model = 'player' form_fields = ['maintenance_ki'] def is_displayed(player: Player): return player.round_number >= C.EXPERIMENT_ROUNDS and player.round_number <= (C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS-1) @staticmethod def js_vars(player: Player): copy_old_player_to_this_player(player, player.in_round(1)) my_dict = C.ROWS_SECOND_PHASE[ player.round_number - (C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2 + C.EXPERIMENT_ROUNDS)] my_dict['min_temp'] = player.temp_min my_dict['max_temp'] = player.temp_max my_dict['min_speed'] = player.speed_min my_dict['max_speed'] = player.speed_max my_dict['min_volt'] = player.volt_min my_dict['max_volt'] = player.volt_max my_dict['outcome'] = my_dict['outcome_high'] if player.participant.vars['low']: my_dict['outcome'] = my_dict['outcome_low'] ## hier wird die "strafe" gesetzt für die entscheidung der schlehct definierten ki return my_dict @staticmethod def vars_for_template(player: Player): answer = "keine" if player.maintenance_self: answer = "eine" my_dict = C.ROWS_SECOND_PHASE[ player.round_number - (C.INTERVALL_ROUNDS + C.SITUATIONS_ROUNDS * 2 + C.EXPERIMENT_ROUNDS)] my_dict['outcome'] = my_dict['outcome_high'] if player.participant.vars['low']: my_dict['outcome'] = my_dict[ 'outcome_low'] ## hier wird die "strafe" gesetzt für die entscheidung der schlehct definierten ki return dict( answer_self=get_description(player.disturbance_self), answer_maintance=answer, outcome=get_description(my_dict['outcome']), ROUND=player.round_number - (C.EXPERIMENT_ROUNDS)+1, MAX_ROUNDS=C.SECONDPHASE_ROUNDS ) @staticmethod def before_next_page(player, timeout_happened): # check if right answer in regard of outcome my_dict = C.ROWS_SECOND_PHASE[ player.round_number - (C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS)] ''' check what they said check if they swapped check if they maintain calculate payoff for this ''' # error: my_dict['error'] ## Getauscht die Meinung? if player.maintenance_ki != player.maintenance_self: player.swapped = True ## Wartung vorgenommen if player.maintenance_ki: player.counter = 2 else: ## keine wartung vorgenommen if my_dict['error']: player.counter = 1 else: player.counter = 0 class SecondPhaseResult(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS @staticmethod def vars_for_template(player: Player): interval = [C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 1, C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 2 + C.SECONDPHASE_ROUNDS] ## Y = 0 #Anzahl keine Wartung / keine Störung W = 0 # Anzahl keine Wartung / Störung Z = 0 # Anzahl Wartung for p in player.in_rounds((interval[0]),interval[1]): if p.counter == 2: Z+=1 if p.counter == 1: W+= 1 if p.counter == 0: Y+= 1 if DEBUG: print(interval, W,Y,Z) return dict( Y=Y, W=W, Z=Z, earnings_y=C.EARNINGS*Y, earnings_w=0, earnings_z=C.EARNINGS*Z/2, earning_sum=C.EARNINGS*Y + 0 + (C.EARNINGS*Z/2), earning_sum_euro=(C.EARNINGS*Y + 0 + (C.EARNINGS*Z/2))/10 ) @staticmethod def before_next_page(player, timeout_happened): interval = [C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 1, C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 2 + C.SECONDPHASE_ROUNDS] Y = 0 # Anzahl keine Wartung / keine Störung W = 0 # Anzahl keine Wartung / Störung Z = 0 # Anzahl Wartung for p in player.in_rounds((interval[0]), interval[1]): if p.counter == 2: Z += 1 if p.counter == 1: W += 1 if p.counter == 0: Y += 1 player.payoff = (C.EARNINGS * Y + 0 + (C.EARNINGS * Z / 2)) class WaitingPage(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireDemographics(Page): form_model = 'player' form_fields = ['age', 'gender', 'educ', 'major'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireExpert(Page): form_model = 'player' form_fields = ['expert1', 'expert2', 'expert3', 'expert4', 'expert5', 'asku1', 'asku2', 'asku3'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireExperimentPerception(Page): form_model = 'player' form_fields = ['percex1', 'percex2', 'percex3', 'percex4', 'percex5', 'percex6', 'percex7', 'percex8', 'percex9', 'percex10'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireTreatmentPerception(Page): form_model = 'player' form_fields = ['perctreat1', 'perctreat2', 'perctreat3', 'perctreat4', 'perctreat5', 'perctreat6', 'perctreat7', 'perctreat8', 'perctreat9', 'perctreat10', 'perctreat11', 'perctreat12', 'perctreat13', 'perctreat14', 'perctreat15'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireTechnicalExpertise(Page): form_model = 'player' form_fields = ['ati_1', 'ati_2', 'ati_3', 'ati_4', 'ati_5', 'ati_6', 'ati_7', 'ati_8', 'ati_9'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class QuestionnaireOpen(Page): form_model = 'player' form_fields = ['comment'] @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS class FinalPage(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.EXPERIMENT_ROUNDS + C.SECONDPHASE_ROUNDS @staticmethod #kopiert aus SecondPhaseResult, damit Payoff nochmal angezeigt werden kann def vars_for_template(player: Player): interval = [C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 1, C.INTERVALL_ROUNDS + C.EXPERIMENT_ROUNDS - 2 + C.SECONDPHASE_ROUNDS] ## Y = 0 # Anzahl keine Wartung / keine Störung W = 0 # Anzahl keine Wartung / Störung Z = 0 # Anzahl Wartung for p in player.in_rounds((interval[0]), interval[1]): if p.counter == 2: Z += 1 if p.counter == 1: W += 1 if p.counter == 0: Y += 1 if DEBUG: print(interval, W, Y, Z) return dict( Y=Y, W=W, Z=Z, earnings_y=C.EARNINGS * Y, earnings_w=0, earnings_z=C.EARNINGS * Z / 2, earning_sum_euro=(C.EARNINGS * Y + 0 + (C.EARNINGS * Z / 2)) / 10 ) # page_sequence = [ChooseIntervall, ShowIntervall, LearningIntroduction,Learning, Results] page_sequence = [CabinNumber, Introduction, Instructions, IntroductionControl, IntroductionControl2, SituationDescriptionControl, ExperimentStart, #Introduction2, Kontrolle wegen Berechnungen #SituationDescription, Kontrolle wegen Berechnungen DescriptionInterval, IntervallEingabe, #ChooseInterval, #ShowInterval, #IntervallCatched, KIInfo, #KIControl, Kontrolle.. Experiment, ResultKI, SecondPhaseSelf, SecondPhaseKI, SecondPhaseResult, WaitingPage, QuestionnaireDemographics, QuestionnaireExpert, QuestionnaireExperimentPerception, QuestionnaireTreatmentPerception, QuestionnaireTechnicalExpertise, QuestionnaireOpen, FinalPage, ] # [ChooseIntervallVolt, ShowIntervallVolt, ChooseIntervallTemp, ShowIntervallTemp, ChooseIntervallSpeed, ChooseIntervallSpeed, Results] #####HELPER def get_description(outcome): # between -2 and 2 w/o 0 if DEBUG: print(outcome) if outcome < 0: outcome += 2 ### auf 0 und 1 elif outcome > 0: ## auf 2 und 3 outcome += 1 if DEBUG: print(C.DESCRIPTION[outcome]) return C.DESCRIPTION[outcome] ''' todo : change the example data here the intnervals are the first 6 return [temp_min, temp_max, volt_min, volt_max, speed_min, speed_max , tempPoint, voltPoint, SpeedPoint, Title] ''' def get_example_data_for_situation_descrition(index): temp_points = [50, 95, 10, 90] speed_points = [20, 20, 45, 5] volt_points = [60, 65, 70, 15] title = [ " ", " ", " ", " " ] return [40, 60, 55, 75, 10, 30, temp_points[index], volt_points[index], speed_points[index], title[index]] ''' temp_points = [3, 4.6, 1.5, 4.5] speed_points = [2, 2, 4.5, 0.5] volt_points = [3.5, 3.5, 3.5, 2] return [2, 4, 3, 4, 1, 3, temp_points[index], volt_points[index], speed_points[index], title[index]] ''' ''' not used atm ''' def generate_point(player: Player, series: list, runde: int, inside: bool): min_max = get_min_max(player, runde) y = random.uniform(C.Y_RANGE[0], C.Y_RANGE[1]) x = 0 if inside: x = random.uniform(min_max[0], min_max[1]) else: # outside #### todo: fallunterscheidung bin ich ganz links oder ganz rechts, dann das andere nehmen x_1 = random.uniform(C.X_RANGE[0], min_max[0]) x_2 = random.uniform(min_max[1], C.X_RANGE[1]) x = x_1 if random.random() >= 0.5: x = x_2 new_point = {} new_point['data'] = [[x, y]] new_point['name'] = 'Undefined' new_point['name'] = 'Undefined' new_point['color'] = 'rgba(255,255,255,1)' a = series.copy() a.append(new_point) return a ''' not used ''' def add_point_to_series(player: Player, points_outside: int): points_inside = 3 - points_outside series = [C.ROWS_TEMP, C.ROWS_VOLT, C.ROWS_SPEED] order = list(range(3)) random.shuffle(order) for i in range(points_inside): series[order[i]] = generate_point(player, series[order[i]], order[i], True) for i in range(points_outside): series[order[points_inside + i + 1]] = generate_point(player, series[order[points_inside + i + 1]], order[points_inside + i + 1], False) return series ''' fill the player data ''' def fill_player_min_max(player: Player, minimum, maximum): runde = player.round_number if runde == 1: player.temp_min = minimum player.temp_max = maximum elif runde == 3: player.volt_min = minimum player.volt_max = maximum elif runde == 2: player.speed_min = minimum player.speed_max = maximum else: print("This shouldn't happen, your rounds doesnt match the amount of datasets") ''' get the right series for the scatterplot ''' def get_series(runde, with_unknown=False): if not with_unknown: if runde == 1: return C.ROWS_TEMP if runde == 3: return C.ROWS_VOLT if runde == 2: return C.ROWS_SPEED else: ##todo: Hier das ganze mit anderen Inputs (ohne die undefineds, und diese dann erweitern je nach runde) return C.ROWS_EXAMPLE return None ### error no graph ''' text for the Faustregeln from Constants ''' def get_faustregel(round_number): if round_number == 1: return C.FAUSTREGEL_1 if round_number == 2: return C.FAUSTREGEL_2 if round_number == 3: return C.FAUSTREGEL_3 return None ### error ''' not necessary, but if you wanna swap smth you can do it here ''' def get_einheit(round_number): return C.EINHEIT[round_number - 1] ''' get Intervalls ''' def get_min_max(player: Player): runde = player.round_number if runde == 1: return [player.temp_min, player.temp_max] if runde == 3: return [player.volt_min, player.volt_max] if runde == 2: return [player.speed_min, player.speed_max] return None ## error no graph or intervals ''' get data from earlier rounds ''' def copy_old_player_to_this_player(player: Player, player_old: Player): if DEBUG: print('\n', "player now:" , player, "player old:" , player_old, '\n') if player_old.field_maybe_none('temp_min') is not None: player.temp_min = player_old.field_maybe_none('temp_min') if player_old.field_maybe_none('temp_max') is not None: player.temp_max = player_old.field_maybe_none('temp_max') if player_old.field_maybe_none('speed_min') is not None: player.speed_min = player_old.field_maybe_none('speed_min') if player_old.field_maybe_none('speed_max') is not None: player.speed_max = player_old.field_maybe_none('speed_max') if player_old.field_maybe_none('volt_min') is not None: player.volt_min = player_old.field_maybe_none('volt_min') if player_old.field_maybe_none('volt_max') is not None: player.volt_max = player_old.field_maybe_none('volt_max') def fill_data(player: Player, data): ## fall unterscheidung # data[0] typ : 1 - 3 # data[1] min # data[2] max minimum = data[1] maximum = data[2] if data[0] == 1: player.temp_min = minimum player.temp_max = maximum elif data[0] == 3: player.volt_min = minimum player.volt_max = maximum elif data[0] == 2: player.speed_min = minimum player.speed_max = maximum else: print("This shouldn't happen, data[0] is out of range (1-3)") '''' # Choose Intervall ## Hier die 3 ineinander schachteln mit : # https://www.otreehub.com/projects/back-button/ # ShowIntervall auch zusammenbauen . class ChooseInterval(Page): @staticmethod def is_displayed(player: Player): return player.round_number <= C.INTERVALL_ROUNDS ## just on the third ## ODER zusätzlich , back button = steuerungsvariable gesetzt und dann zuusätzlich noch bis IntervalRounds*2 @staticmethod def js_vars(player: Player): return dict( series=get_series(player.round_number), min=-1, max=-1, xTitle=C.X_TITLES[player.round_number - 1], yTitle=C.Y_TITLES[player.round_number - 1], title=C.CHART_TITLES[player.round_number - 1], ) @staticmethod def vars_for_template(player): return dict( title=C.TITLES[player.round_number - 1], faustregel1=get_faustregel(player.round_number)[0], faustregel2=get_faustregel(player.round_number)[1], faustregel3=get_faustregel(player.round_number)[2], einheit=get_einheit(player.round_number), ) @staticmethod def live_method(player, data): if DEBUG: print('min and max from player', player.id_in_group, ':', data) fill_player_min_max(player, data[0], data[1]) ## Change Show Intervall to just one side class ShowInterval(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.INTERVALL_ROUNDS ##just on the last @staticmethod def js_vars(player: Player): copy_old_player_to_this_player(player, player.in_round(1), 0) copy_old_player_to_this_player(player, player.in_round(2), 1) copy_old_player_to_this_player(player, player.in_round(3), 2) if DEBUG: print(player) return dict( series_temp=get_series(1), min_temp=player.temp_min, max_temp=player.temp_max, xTitle_temp=C.X_TITLES[0], yTitle_temp=C.Y_TITLES[0], title_temp=C.CHART_TITLES[0], series_volt=get_series(2), min_volt=player.volt_min, max_volt=player.volt_max, xTitle_volt=C.X_TITLES[1], yTitle_volt=C.Y_TITLES[1], title_volt=C.CHART_TITLES[1], series_speed=get_series(3), min_speed=player.speed_min, max_speed=player.speed_max, xTitle_speed=C.X_TITLES[2], yTitle_speed=C.Y_TITLES[2], title_speed=C.CHART_TITLES[2], speed=-1, # 0.5, ##todo: daten irgendwo herholen volt=-1, # 2.5, temp=-1, # 3, ) @staticmethod def vars_for_template(player): copy_old_player_to_this_player(player, player.in_round(1), 0) copy_old_player_to_this_player(player, player.in_round(2), 1) copy_old_player_to_this_player(player, player.in_round(3), 2) if DEBUG: print(player) return dict( title="Überblick", min_speed=player.speed_min, max_speed=player.speed_max, min_temp=player.temp_min, max_temp=player.temp_max, min_volt=player.volt_min, max_volt=player.volt_max, ) '''