diff options
author | Niclas Dobbertin <niclas.dobbertin@mailbox.org> | 2023-10-23 14:28:27 +0200 |
---|---|---|
committer | Niclas Dobbertin <niclas.dobbertin@mailbox.org> | 2023-10-23 14:28:27 +0200 |
commit | 9ad2fb0e18373f84e2a8a52a5ae93311744ed23e (patch) | |
tree | b34a3a919d9e6803086436622d2d55e0095a89c5 | |
parent | 9ad4ebeccfb7ac7f86ac74faf646f4ec95910b7e (diff) |
rename experiment dir
-rw-r--r-- | experiment/EK_Muster-Einverstaendniserklaerung_2022.odt | bin | 0 -> 120847 bytes | |||
-rw-r--r-- | experiment/EK_Muster-Einverstaendniserklaerung_2022.pdf | bin | 0 -> 95322 bytes | |||
-rw-r--r-- | experiment/data/vp01/samples.txt (renamed from master_thesis/data/vp01/samples.txt) | 0 | ||||
-rw-r--r-- | experiment/data/vp01/vp.pkl (renamed from master_thesis/data/vp01/vp.pkl) | bin | 20383 -> 20383 bytes | |||
-rw-r--r-- | experiment/data/vp01/vp_results.csv (renamed from master_thesis/data/vp01/vp_results.csv) | 0 | ||||
-rw-r--r-- | experiment/frensch_procedures.py (renamed from master_thesis/frensch_procedures.py) | 0 | ||||
-rw-r--r-- | experiment/frensch_task.py | 409 | ||||
-rw-r--r-- | master_thesis/__init__.py | 1 | ||||
-rw-r--r-- | master_thesis/pyactr_tut.py | 512 |
9 files changed, 409 insertions, 513 deletions
diff --git a/experiment/EK_Muster-Einverstaendniserklaerung_2022.odt b/experiment/EK_Muster-Einverstaendniserklaerung_2022.odt Binary files differnew file mode 100644 index 0000000..8634478 --- /dev/null +++ b/experiment/EK_Muster-Einverstaendniserklaerung_2022.odt diff --git a/experiment/EK_Muster-Einverstaendniserklaerung_2022.pdf b/experiment/EK_Muster-Einverstaendniserklaerung_2022.pdf Binary files differnew file mode 100644 index 0000000..c21c686 --- /dev/null +++ b/experiment/EK_Muster-Einverstaendniserklaerung_2022.pdf diff --git a/master_thesis/data/vp01/samples.txt b/experiment/data/vp01/samples.txt index 264a570..264a570 100644 --- a/master_thesis/data/vp01/samples.txt +++ b/experiment/data/vp01/samples.txt diff --git a/master_thesis/data/vp01/vp.pkl b/experiment/data/vp01/vp.pkl Binary files differindex fee9fb2..fee9fb2 100644 --- a/master_thesis/data/vp01/vp.pkl +++ b/experiment/data/vp01/vp.pkl diff --git a/master_thesis/data/vp01/vp_results.csv b/experiment/data/vp01/vp_results.csv index e32bc73..e32bc73 100644 --- a/master_thesis/data/vp01/vp_results.csv +++ b/experiment/data/vp01/vp_results.csv diff --git a/master_thesis/frensch_procedures.py b/experiment/frensch_procedures.py index 3c64471..3c64471 100644 --- a/master_thesis/frensch_procedures.py +++ b/experiment/frensch_procedures.py diff --git a/experiment/frensch_task.py b/experiment/frensch_task.py new file mode 100644 index 0000000..fb68093 --- /dev/null +++ b/experiment/frensch_task.py @@ -0,0 +1,409 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import pickle +import random +from collections import namedtuple +from pprint import pprint + +import pandas as pd +from psychopy import core, event, gui, visual + +import frensch_procedures + +DisplayVariable = namedtuple("DisplayVariable", ["name", "values"]) +DisplayProcedure = namedtuple("DisplayProcedure", ["procedure", "solution"]) + +intro_text = """Vielen Dank dass Sie bei unserem Experiment zum menschlichen Lernen teilnehmen! + +In diesem Experiment arbeiten Sie in einem Labor, welches die Wasserqualität analysiert. +Dafür bekommen Sie einige Wasserproben und müssen für jede Probe verschiedene Kennwerte ermitteln. + +Jede Wasserprobe besitzt bereits verschiedene gemessene Werte, wie der Algengehalt, welche für die Berechnungen benutzt werden. + + +(Leertaste zum Fortfahren) +""" + +intro2_text = """Im folgenden müssen sie verschiedene Rechenaufgaben lösen um die Kennwerte zu berechnen. +Verwenden Sie die gewohnten Rechenregeln und geben sie Ihre Lösung bitte immer als zweistellige Zahl ein, und bestätigen mit Enter. +Die Werte der Variablen (z.B. Algen) werden oben am Bildschirm angezeigt. + +Manche Variablen haben mehrere mögliche Werte; "Gifte_2" besagt z.B., dass der zweite Wert der Giftwerte zu verwenden ist. +"_max/_min" besagt, dass der maximale/minimale Wert dieser Variable zu verwenden ist. + +Als letzte Berechnung müssen Sie den Gesamtwert der Wasserqualität aus ihren Ergebnissen berechnen. + +Nach jeder Aufgabe können Sie kurz pausieren. + +Drücken Sie die Leertaste um zu beginnen""" + + +def experiment_shutdown(): + WIN.close() + core.quit() + + +WIN = visual.Window((1920, 1080), fullscr=True, units="pix") +MONITOR_FPS = 60 +TRAIN_TRIALS = 75 +TEST_TRIALS = 50 +# TRAIN_TRIALS = 3 +# TEST_TRIALS = 3 +ORDER_CONDITIONS = ["fixed", "random", "blocked"] +PROCEDURE_KEYS = ["1", "2", "3", "4", "5", "6", "overall"] + +# Cancel experiment anytime with Esc +event.globalKeys.add(key="escape", func=experiment_shutdown, name="shutdown") + + +def generate_variable_display(varx: list[DisplayVariable], x_positions: list[int]): + assert len(varx) == len(x_positions) + + stims = [] + + def gen_value_stims(values, x, y, offset): + for value in values: + y -= offset + value_stim = visual.TextBox2( + WIN, + pos=(x, y), + text=value, + # size=200, + letterHeight=75, + alignment="center", + ) + stims.append(value_stim) + + y = 550 + offset = 100 + + for var, x_pos in zip(varx, x_positions): + stim_var = visual.TextBox2( + WIN, + pos=[x_pos, y], + text=var.name, + # size=[1000, 1000], + letterHeight=40, + alignment="center", + ) + stims.append(stim_var) + + gen_value_stims(var.values, x_pos, y, offset) + + return stims + + +def generate_procedure_display(procedure: DisplayProcedure, position): + stim_procedure = visual.TextBox2( + WIN, + pos=position, + text=procedure.procedure, + size=[1000000, 1000], + letterHeight=40, + alignment="center", + ) + return stim_procedure + + +def generate_all_watersamples(n): + samples = [] + for _ in range(n): + samples.append(frensch_procedures.constrained_WaterSample()) + return samples + + +def run_blocked_trials(water_samples, procedure_keys): + results = {} + for proc_idx, proc in enumerate(procedure_keys): + for sample_idx, sample in enumerate(water_samples): + cur_key = f"train_{sample_idx}" + if not cur_key in results.keys(): + results[cur_key] = {} + results[cur_key]["procedure_order"] = tuple(procedure_keys) + results[cur_key]["water_sample"] = sample.water_sample_dict() + + solid = DisplayVariable("Mineralien", [sample.solid]) + algae = DisplayVariable("Algen", [sample.algae]) + lime = DisplayVariable("Sandstein", sample.lime) + toxin = DisplayVariable("Gifte", sample.toxin) + x_positions = [-800, -400, 400, 800] + + stims = generate_variable_display([solid, algae, lime, toxin], x_positions) + + procedures = sample.procedure_dict() + + proc_x = -600 + proc_y = -100 + answ_x = 200 + answ_y = -100 + y_offset = 80 + + print(procedure_keys[:proc_idx]) + for prev in procedure_keys[:proc_idx]: + print(prev) + if not prev: + continue + p = DisplayProcedure(procedures[prev][1], procedures[prev][0]) + p = generate_procedure_display(p, (proc_x, proc_y)) + stims.append(p) + proc_y -= y_offset + + stim_answer_equals = visual.TextBox2( + WIN, + "=", + letterHeight=50, + pos=(answ_x - 100, answ_y), + size=[150, 70], + alignment="center", + ) + stims.append(stim_answer_equals) + + print(sample_idx) + stim_answer_box = visual.TextBox2( + WIN, + results[f"train_{sample_idx}"][prev]["answer"], + letterHeight=50, + pos=(answ_x, answ_y), + size=[150, 70], + editable=True, + fillColor="white", + color="black", + alignment="center", + ) + stims.append(stim_answer_box) + answ_y -= y_offset + + p = DisplayProcedure(procedures[proc][1], procedures[proc][0]) + p = generate_procedure_display(p, (proc_x, proc_y)) + stims.append(p) + proc_y -= y_offset + + stim_answer_equals = visual.TextBox2( + WIN, + "=", + letterHeight=50, + pos=(answ_x - 100, answ_y), + size=[150, 70], + alignment="center", + ) + stims.append(stim_answer_equals) + + print(sample_idx) + stim_answer_box = visual.TextBox2( + WIN, + "", + letterHeight=50, + pos=(answ_x, answ_y), + size=[150, 70], + editable=True, + fillColor="white", + color="black", + alignment="center", + ) + stims.append(stim_answer_box) + answ_y -= y_offset + + not_finished = True + answer = "not answered" + start_time = core.monotonicClock.getTime() + while not_finished: + stim_answer_box.hasFocus = True + for stim in stims: + stim.draw() + WIN.flip() + answer = stim_answer_box.text + if "\n" in answer: + if answer[0].isdigit() and answer[1].isdigit(): + not_finished = False + else: + stim_answer_box.text = answer[:-1] + if len(answer) > 2: + stim_answer_box.text = stim_answer_box.text[:2] + answer_time = core.monotonicClock.getTime() - start_time + answer = (answer.replace("\n", ""), answer_time) + results[cur_key][proc] = {"answer": answer[0], "time": answer[1]} + + return results + + +def run_trial(water_sample, procedure_keys: list, condition): + water_sample.print_all() + + if condition == "random": + overall = procedure_keys.pop() + random.shuffle(procedure_keys) + procedure_keys.append(overall) + + solid = DisplayVariable("Mineralien", [water_sample.solid]) + algae = DisplayVariable("Algen", [water_sample.algae]) + lime = DisplayVariable("Sandstein", water_sample.lime) + toxin = DisplayVariable("Gifte", water_sample.toxin) + x_positions = [-800, -400, 400, 800] + + stims = generate_variable_display([solid, algae, lime, toxin], x_positions) + + procedures = water_sample.procedure_dict() + + answers = [] + proc_x = -600 + proc_y = -100 + answ_x = 200 + answ_y = -100 + y_offset = 80 + for proc in procedure_keys: + p = DisplayProcedure(procedures[proc][1], procedures[proc][0]) + p = generate_procedure_display(p, (proc_x, proc_y)) + stims.append(p) + proc_y -= y_offset + + stim_answer_equals = visual.TextBox2( + WIN, + "=", + letterHeight=50, + pos=(answ_x - 100, answ_y), + size=[150, 70], + alignment="center", + ) + stims.append(stim_answer_equals) + + stim_answer_box = visual.TextBox2( + WIN, + "", + letterHeight=50, + pos=(answ_x, answ_y), + size=[150, 70], + editable=True, + fillColor="white", + color="black", + alignment="center", + ) + stims.append(stim_answer_box) + answ_y -= y_offset + + not_finished = True + answer = "not answered" + start_time = core.monotonicClock.getTime() + while not_finished: + stim_answer_box.hasFocus = True + for stim in stims: + stim.draw() + WIN.flip() + answer = stim_answer_box.text + if "\n" in answer: + if answer[0].isdigit() and answer[1].isdigit(): + not_finished = False + else: + stim_answer_box.text = answer[:-1] + if len(answer) > 2: + stim_answer_box.text = stim_answer_box.text[:2] + answer_time = core.monotonicClock.getTime() - start_time + answers.append((answer.replace("\n", ""), answer_time)) + + # event.waitKeys(keyList=["space"]) + + return tuple(answers), tuple(procedure_keys) + + +condition_dlg = gui.Dlg(title="Experiment Condition") +condition_dlg.addText("Condition") +condition_dlg.addField("condition") +CONDITION = condition_dlg.show()[0] + +assert CONDITION in ORDER_CONDITIONS + +pause = visual.TextBox2( + WIN, + """Drücken Sie die Leertaste um mit der nächsten Wasserprobe fortzufahren""", + letterHeight=50, + alignment="center", +) + +intro = visual.TextBox2( + WIN, intro_text, letterHeight=40, alignment="center", size=(100000, 100000) +) +intro.draw() +WIN.flip() +event.waitKeys(keyList=["space"]) + +intro2 = visual.TextBox2( + WIN, intro2_text, letterHeight=40, alignment="center", size=(100000, 100000) +) +intro2.draw() +WIN.flip() +event.waitKeys(keyList=["space"]) + +train_procedures = PROCEDURE_KEYS[:-1] +random.shuffle(train_procedures) +transfer_procedure = train_procedures[-1] +train_procedures = train_procedures[:-1] +train_procedures.append(PROCEDURE_KEYS[-1]) + +all_samples = generate_all_watersamples(TRAIN_TRIALS + TEST_TRIALS) + +if CONDITION != "blocked": + results = {} + for i in range(TRAIN_TRIALS): + print(train_procedures) + answer, procedure_keys = run_trial(all_samples[i], train_procedures, CONDITION) + answer_dict = {} + answer_dict["procedure_order"] = procedure_keys + answer_dict["water_sample"] = all_samples[i].water_sample_dict() + for proc, key in zip(answer, procedure_keys): + answer_dict[key] = {"answer": proc[0], "time": proc[1]} + + results[f"train_{i}"] = answer_dict + + pause.draw() + WIN.flip() + event.waitKeys(keyList=["space"]) +else: + results = run_blocked_trials(all_samples[:TRAIN_TRIALS], train_procedures) + + +phase = visual.TextBox2( + WIN, + """Sie haben den ersten Teil geschafft! Der zweite Teil ist etwas kürzer als der erste + +Drücken Sie die Leertaste um anzufangen.""", + letterHeight=40, + alignment="center", +) +phase.draw() +WIN.flip() +event.waitKeys(keyList=["space"]) + +train_procedures[2] = transfer_procedure +for i in range(TEST_TRIALS): + print(train_procedures) + answer, procedure_keys = run_trial( + all_samples[TRAIN_TRIALS + i], train_procedures, "fixed" + ) + print(procedure_keys) + answer_dict = {} + answer_dict["procedure_order"] = procedure_keys + answer_dict["water_sample"] = all_samples[TRAIN_TRIALS + i].water_sample_dict() + for proc, key in zip(answer, procedure_keys): + answer_dict[key] = {"answer": proc[0], "time": proc[1]} + + results[f"test_{i}"] = answer_dict + + pause.draw() + WIN.flip() + event.waitKeys(keyList=["space"]) + +pprint(results) + +df = pd.DataFrame.from_dict(results, orient="index") +df.to_csv("vp_results.csv") + +with open("vp.pkl", "wb") as file: + pickle.dump(results, file) + +outro_text = "Das Experiment ist nun vorüber.\n\nVielen Dank für Ihre Teilnahme!" +outro = visual.TextBox2( + WIN, outro_text, letterHeight=40, alignment="center", size=(100000, 100000) +) +outro.draw() +WIN.flip() +event.waitKeys(keyList=["space"]) diff --git a/master_thesis/__init__.py b/master_thesis/__init__.py deleted file mode 100644 index 548fbdf..0000000 --- a/master_thesis/__init__.py +++ /dev/null @@ -1 +0,0 @@ -print("hello world!!") diff --git a/master_thesis/pyactr_tut.py b/master_thesis/pyactr_tut.py deleted file mode 100644 index a44209e..0000000 --- a/master_thesis/pyactr_tut.py +++ /dev/null @@ -1,512 +0,0 @@ -#!/usr/bin/env python3 - -import pyactr as actr - - -def memory_motor(): - playing_memory = actr.ACTRModel() - - actr.chunktype("playgame", "game, activity") - - initial_chunk = actr.makechunk(typename="playgame", game="memory") - - goal = playing_memory.set_goal("goal") - - playing_memory.productionstring( - name="startplaying", - string=""" - =goal> - isa playgame - game memory - activity None - ?manual> - state free - ==> - =goal> - isa playgame - activity presskey - """, - ) - - playing_memory.productionstring( - name="presskey", - string=""" - =goal> - isa playgame - game memory - activity presskey - ==> - +manual> - isa _manual - cmd press_key - key 1 - =goal> - isa playgame - activity None - """, - ) - - simulation_game = playing_memory.simulation() - simulation_game.run() - - -def memory_vision(): - environment = actr.Environment() - playing_memory = actr.ACTRModel(environment=environment) - - memory = [{}, {"A": {"text": "A", "position": (100, 100)}}] - - goal = playing_memory.set_goal("goal") - actr.chunktype("playgame", "game, activity, key, object") - initial_chunk = actr.makechunk(typename="playgame", game="memory", key="1") - goal.add(initial_chunk) - - playing_memory.productionstring( - name="startplaying", - string=""" - =goal> - isa playgame - game memory - activity None - ==> - =goal> - isa playgame - activity presskey""", - ) - - playing_memory.productionstring( - name="presskey", - string=""" - =goal> - isa playgame - game memory - activity presskey - key =k - ==> - +manual> - isa _manual - cmd press_key - key =k - =goal> - isa playgame - activity attend""", - ) - - playing_memory.productionstring( - name="attendobject", - string=""" - =goal> - isa playgame - game memory - activity attend - =visual_location> - isa _visuallocation - ?manual> - state free - ==> - =goal> - isa playgame - activity storeobject - +visual> - isa _visual - cmd move_attention - screen_pos =visual_location""", - ) - - playing_memory.productionstring( - name="storeobject", - string=""" - =goal> - isa playgame - game memory - activity storeobject - =visual> - isa _visual - value =v - ==> - =goal> - isa playgame - activity None - object =v""", - ) - - simulation = playing_memory.simulation( - gui=False, - environment_process=environment.environment_process, - stimuli=memory, - triggers="1", - ) - simulation.run() - - print(goal) - - -def memory_memory(): - environment = actr.Environment() - playing_memory = actr.ACTRModel(environment=environment) - - memory = [ - {}, - {"A": {"text": "A", "position": (100, 100)}}, - {"A": {"text": "A", "position": (100, 100)}}, - ] - - goal = playing_memory.set_goal("goal") - actr.chunktype("playgame", "game, activity, key, object") - initial_chunk = actr.makechunk(typename="playgame", game="memory", key="1") - goal.add(initial_chunk) - - playing_memory.productionstring( - name="startplaying", - string=""" - =goal> - isa playgame - game memory - activity None - object None - ==> - =goal> - isa playgame - activity presskey""", - ) - - playing_memory.productionstring( - name="continueplaying", - string=""" - =goal> - isa playgame - game memory - activity None - object ~None - ==> - =goal> - isa playgame - game memory - activity recall""", - ) - - playing_memory.productionstring( - name="recallvalue", - string=""" - =goal> - isa playgame - game memory - activity recall - object =val - ==> - =goal> - isa playgame - game memory - activity checkrecalled - +retrieval> - isa playgame - object =val""", - ) - - playing_memory.productionstring( - name="recallsuccessful", - string=""" - =goal> - isa playgame - game memory - activity checkrecalled - object =val - ?retrieval> - buffer full - =retrieval> - isa playgame - key =k - ==> - =goal> - isa playgame - key =k - activity done""", - ) - - playing_memory.productionstring( - name="recallfailed", - string=""" - =goal> - isa playgame - game memory - activity checkrecalled - key 1 - object =val - ?retrieval> - state error - ==> - ~goal> - +goal> - isa playgame - game memory - activity presskey - key 2""", - ) - - playing_memory.productionstring( - name="presskey", - string=""" - =goal> - isa playgame - game memory - activity presskey - key =k - ==> - +manual> - isa _manual - cmd press_key - key =k - =goal> - isa playgame - activity attend""", - ) - - playing_memory.productionstring( - name="attendobject", - string=""" - =goal> - isa playgame - game memory - activity attend - =visual_location> - isa _visuallocation - ?manual> - state free - ==> - =goal> - isa playgame - activity storeobject - +visual> - isa _visual - cmd move_attention - screen_pos =visual_location""", - ) - - playing_memory.productionstring( - name="storeobject", - string=""" - =goal> - isa playgame - game memory - activity storeobject - =visual> - isa _visual - value =v - ==> - =goal> - isa playgame - activity None - object =v""", - ) - - simulation = playing_memory.simulation( - gui=False, - environment_process=environment.environment_process, - stimuli=memory, - triggers="1", - ) - simulation.run(max_time=2) - - print(goal) - print(playing_memory.decmem) - - -def memory_memory_loop(): - environment = actr.Environment() - playing_memory = actr.ACTRModel(environment=environment) - - goal = playing_memory.set_goal("goal") - actr.chunktype("playgame", "game, activity, key, object") - initial_chunk = actr.makechunk(typename="playgame", game="memory", key="1") - - memory = [{}] + [{i: {"text": i, "position": (100, 100)}} for i in "BCDEFGHDIJ"] - goal.add(initial_chunk) - - playing_memory.productionstring( - name="startplaying", - string=""" - =goal> - isa playgame - game memory - activity None - object None - ==> - =goal> - isa playgame - activity presskey""", - ) - - playing_memory.productionstring( - name="continueplaying", - string=""" - =goal> - isa playgame - game memory - activity None - object ~None - ==> - =goal> - isa playgame - game memory - activity recall""", - ) - - playing_memory.productionstring( - name="recallvalue", - string=""" - =goal> - isa playgame - game memory - activity recall - object =val - ==> - =goal> - isa playgame - game memory - activity checkrecalled - +retrieval> - isa playgame - object =val""", - ) - - playing_memory.productionstring( - name="recallsuccessful", - string=""" - =goal> - isa playgame - game memory - activity checkrecalled - object =val - ?retrieval> - buffer full - =retrieval> - isa playgame - key =k - ==> - =goal> - isa playgame - key =k - activity done""", - ) - - for i in range(1, 9): - playing_memory.productionstring( - name="recallfailed" + str(i), - string=""" - =goal> - isa playgame - game memory - activity checkrecalled - key """ - + str(i) - + """ - object =val - ?retrieval> - state error - ==> - ~goal> - +goal> - isa playgame - game memory - activity presskey - key """ - + str((i + 1) % 10), - ) - - playing_memory.productionstring( - name="recallfailed9", - string=""" - =goal> - isa playgame - game memory - activity checkrecalled - key 0 - object =val - ?retrieval> - state error - ==> - ~goal>""", - ) - - playing_memory.productionstring( - name="presskey", - string=""" - =goal> - isa playgame - game memory - activity presskey - key =k - ==> - +manual> - isa _manual - cmd press_key - key =k - =goal> - isa playgame - activity attend""", - ) - - playing_memory.productionstring( - name="attendobject", - string=""" - =goal> - isa playgame - game memory - activity attend - =visual_location> - isa _visuallocation - ?manual> - state free - ==> - =goal> - isa playgame - activity storeobject - +visual> - isa _visual - cmd move_attention - screen_pos =visual_location""", - ) - - playing_memory.productionstring( - name="storeobject", - string=""" - =goal> - isa playgame - game memory - activity storeobject - =visual> - isa _visual - value =v - ==> - =goal> - isa playgame - activity None - object =v""", - ) - playing_memory.model_parameters["subsymbolic"] = True - - goal.add(initial_chunk) - # playing_memory.retrieval.pop() - # for i in playing_memory.decmem.copy(): - # playing_memory.decmem.pop(i) - simulation = playing_memory.simulation( - gui=False, - environment_process=environment.environment_process, - stimuli=memory, - triggers=[str(i % 10) for i in range(1, 11)] + ["0"], - ) - - while True: - simulation.step() - if simulation.current_event.action == "RULE FIRED: recallsuccessful": - break - if simulation.show_time() > 10: - print("Nothing found, breaking") - break - - print(goal) - print(simulation.show_time()) - print(playing_memory.decmem) - - -memory_memory_loop() |