--- title: Two step share tags: 2024, twostep --- [TOC] # [google drive code(download whole folder)](https://drive.google.com/drive/folders/17ZKNhbAojbdIJfu0mC15sQokHXq3Dn15?usp=sharing) --- # SOP 1. check the necessary file tree below, make sure `twostep.py` and `twostep_constants.py` exist, also make sure all file under `payoff folder` and `image_new folder` exist. Note that you can adjust the content of the files freely, but make sure these files exit, and the name stays the way it is. 2. change variables 1. for MacOS user, make sure `twostep_constants.py` line 42: `folder_path = "/Users/XXXXX/Desktop/twostep/"` is where your twostep folder is. 2. for Windows user, make sure `twostep_constants.py` line 76: `folder_path = "C:\\Users\\User\\Downloads\\twostep\\"` is where your twostep folder is. ## necessary file tree ``` twostep necessary files ├── payoff │ ├── payoff_1.csv │ ├── payoff_2.csv │ ├── payoff_3.csv │ ├── payoff_4.csv │ ├── payoff_5.csv │ ├── payoff_practice.csv │ └── payoff_test1.csv ├── image_new │ ├── alien1_a1.jpg │ ├── alien1_deact.jpg │ ├── alien1_norm.jpg │ ├── alien1_sp.jpg │ ├── alien2_a1.jpg │ ├── alien2_deact.jpg │ ├── alien2_norm.jpg │ ├── alien2_sp.jpg │ ├── alien3_a1.jpg │ ├── alien3_deact.jpg │ ├── alien3_norm.jpg │ ├── alien3_sp.jpg │ ├── alien4_a1.jpg │ ├── alien4_deact.jpg │ ├── alien4_norm.jpg │ ├── alien4_sp.jpg │ ├── rocket1_a1.jpg │ ├── rocket1_deact.jpg │ ├── rocket1_norm.jpg │ ├── rocket1_sp.jpg │ ├── rocket2_a1.jpg │ ├── rocket2_deact.jpg │ ├── rocket2_norm.jpg │ ├── rocket2_sp.jpg │ └── t.jpg // coin image ├── twostep.py └── twostep_constants.py ``` --- ## twestep experiment abstract 1. login page: enter user id, session id --- # save data format ``` | Trial | p1 | p2 | p3 | p4 | transition | key1 | key2 | rocket_select_time | alien_select_time | rt1 | rt2 | winorlose | totalgold | start_time | |-------|----|----|----|----|------------|------|------|--------------------|-------------------|-----|-----|-----------|-----------|------------| | 0 | | | | | | | | | | | | | | | | 1 | | | | | | | | | | | | | | | | 2 | | | | | | | | | | | | | | | ``` --- # flow chart note ## [1.wire flow chart(👈click me)](https://docs.google.com/drawings/d/1dplH1J3o5s5o3lr77AxnCSBGnmtj1jRNkjGJi6kozQ8/edit?usp=sharing) ## 2.state diagram ```mermaid stateDiagram-v2 [*] --> Login Login --> Instructions Login --> [*]: press "Esc" to quit Instructions --> Experiment Experiment --> Probephase Probephase --> [*]: Experiment Completed state Login { state if_state <<choice>> [*] --> ID: Enter participant ID [*] --> session: Enter session [*] --> space: Select space space --> confirm session --> confirm ID --> confirm confirm --> if_state: check empty if_state --> confirm: if empty if_state --> [*]: Click "Next" button to next } state Instructions { [*] --> Instruction1 Instruction1 --> Instruction2: press "Space" next Instruction2 --> Instruction3: press "Space" next Instruction3 --> Instruction4: press "Space" next Instruction4 --> Instruction<br>for<br>practice: press "Space" next Instruction<br>for<br>practice --> practice: press "space" next [*] } state Experiment { state select_rocket <<choice>> state select_alien12 <<choice>> state select_alien34 <<choice>> state win_lose <<choice>> state end_main <<choice>> [*] --> display<br>2<br>rocket display<br>2<br>rocket --> select_rocket: select rocket select_rocket --> if<br>press<br>key"2" select_rocket --> if<br>press<br>key"6" if<br>press<br>key"2" --> show<br>alien1<br>and<br>2: 70%(commmon) if<br>press<br>key"2" --> show<br>alien3<br>and<br>4: 30%(rare) if<br>press<br>key"6" --> show<br>alien1<br>and<br>2: 30%(rare) if<br>press<br>key"6" --> show<br>alien3<br>and<br>4: 70%(commmon) show<br>alien1<br>and<br>2 --> select_alien12: select alien1 or 2 show<br>alien3<br>and<br>4 --> select_alien34: select alien3 or 4 select_alien12 --> select<br>alien1: if key "2" press select_alien12 --> select<br>alien2: if key "6" press select_alien34 --> select<br>alien3: if key "2" press select_alien34 --> select<br>alien4: if key "6" press select<br>alien1 --> win_lose select<br>alien2 --> win_lose select<br>alien3 --> win_lose select<br>alien4 --> win_lose win_lose --> win: according to given probability win_lose --> lose: according to given probability win --> update<br>score lose --> update<br>score update<br>score --> end_main end_main --> display<br>2<br>rocket: if trial<200 end_main --> show<br>final<br>coin: if trial=200 show<br>final<br>coin --> [*] } state Probephase { state end_loop <<choice>> [*] --> instruction: press "1" to continue instruction --> show<br>alien1and2 show<br>alien1and2 --> show<br>alien1and3 show<br>alien1and3 --> show<br>alien1and4 show<br>alien1and4 --> show<br>alien2and3 show<br>alien2and3 --> show<br>alien2and4 show<br>alien2and4 --> show<br>alien3and4 show<br>alien3and4 --> end_loop end_loop --> show<br>alien1and2: if trial<5 end_loop --> end<br>instruction: if trial=5 end<br>instruction --> [*] } ``` --- ## 3.main experiment function flowchart ```mermaid stateDiagram-v2 direction TB displayRocketImages() --> rocketKeyPress(event): wait for key press rocketKeyPress(event) --> selectRocketImage(selected_rocket) selectRocketImage(selected_rocket) --> displayAlienImages(selected_rocket) displayAlienImages(selected_rocket) --> alienKeyPress(event) displayAlienImages(selected_rocket) --> dontDetect() alienKeyPress(event) --> selectAlienImage(chosen_alien) selectAlienImage(chosen_alien) --> updateScore(probability) selectAlienImage(chosen_alien) --> showCoin(win_lose_state,chosen_alien) updateScore(probability) --> showCoin(win_lose_state,chosen_alien) showCoin(win_lose_state,chosen_alien) --> incrementCounter() incrementCounter() --> displayRocketImages(): if trial < max incrementCounter() --> displayFinalScore(): if trial = max dontDetect() displayRocketX() displayAlienX() ``` --- ## 4. class diagram ``` mermaid classDiagram note "TWO STEP EXPERIMENT" loginPage <|-- saveId note for loginPage "some note" saveId <|-- instructionPage instructionPage <|-- switchPage instructionPage <|-- keySpacePress switchPage <|-- showCurrentPage switchPage <|-- mainExperiment instructionPage <|-- showCurrentPage instructionPage <|-- clearScreen keySpacePress <|-- switchPage class loginPage{ +String participantID +String session +String var_space +button Next(to saveID) +int score = 0 +int current_counter = 0 +int max_iterations = 5 +int selected_image_display_time = 2500 +int cross_image_display_time = 2000 +int coin_display_time = 1000 +int rt1 = None +int rt2 = None +int start_rocket_time = None +int start_alien_time = None +bool key1 = None +bool key2 = None +list save_data = [] +dict login_data } class saveId{ +String login_ID = entry_id.get() +String login_session = entry_session.get() +String login_space = var_space.get() +String save_file_name(contain above) +DataFrame payoff_df(read payoff dataframe with login_space) +float probability_alien1 = payoff_df.values[0][0] +float probability_alien2 = payoff_df.values[0][1] +float probability_alien3 = payoff_df.values[0][2] +float probability_alien4 = payoff_df.values[0][3] instructionPage() } class instructionPage{ -int current_page_var = tk.IntVar() -list page_frames = [instruction1_frame, instruction2_frame,...,instruction5_frame] -list pages = ["instruction1", "instruction2",...,"instruction5"] root root.bind('<KeyPress>', keySpacePress) showCurrentPage() } class switchPage{ -int current_page = current_page_var.get() mainExperiment(max_iterations) showCurrentPage() } class keySpacePress{ -event event.keysym == 'space' switchPage() } class showCurrentPage{ -page_frame.pack } mainExperiment <|-- displayRocketImages mainExperiment <|-- clearScreen displayRocketImages <|-- rocketKeyPress displayRocketImages <|-- displayRocketX displayRocketImages <|-- clearScreen rocketKeyPress <|-- selectRocketImage displayRocketX <|-- displayRocketImages displayRocketX <|-- selectRocketImage displayRocketX <|-- dontDetect displayRocketX <|-- clearScreen selectRocketImage <|-- displayAlienImages selectRocketImage <|-- clearScreen displayAlienImages <|-- alienKeyPress displayAlienImages <|-- displayAlienX displayAlienImages <|-- clearScreen displayAlienX <|-- displayRocketImages displayAlienX <|-- dontDetect displayAlienX <|-- clearScreen alienKeyPress <|-- selectAlienImage selectAlienImage <|-- updateScore selectAlienImage <|-- showCoin selectAlienImage <|-- clearScreen showCoin <|-- incrementCounter showCoin <|-- clearScreen incrementCounter <|-- displayRocketImages incrementCounter <|-- displayFinalScore displayFinalScore <|-- clearScreen mainExperiment : +int age mainExperiment : +String gender mainExperiment: +isMammal() mainExperiment: +mate() class displayRocketImages{ +bool key_pressed = False +int start_rocket_time = time.time() -threading timer_rocket timer_rocket = threading.Timer(3, displayRocketX) rootbind root.bind("<Key>", rocketKeyPress) } class rocketKeyPress{ +int rt1 = time.time() - start_rocket_time +String key1 = event.char selectRocketImage("rocket1" if event.char == "2" else "rocket2")() } class displayRocketX{ +key_pressed root root.bind("<Key>", dontDetect) root root.after(cross_image_display_time, displayRocketImages) } class selectRocketImage{ root root.after(selected_image_display_time, lambda: displayAlienImages("alien1", "alien2", "rocket1")) root root.after(selected_image_display_time, lambda: displayAlienImages("alien3", "alien4", "rocket2")) } class displayAlienImages{ +bool key_pressed = False +bool display_alien_X = False +list current_alien_images = [toshow_alien_left, toshow_alien_right](alien1,2 | alien3,4) +int start_alien_time = time.time() -threading timer_alien = threading.Timer(3, displayAlienX) root.bind("<Key>", alienKeyPress) } class alienKeyPress{ +bool key_pressed = True +String key2 = event.char +int rt2 = time.time() - start_alien_time } class displayAlienX{ -root root.bind("<Key>", dontDetect) -root root.after(cross_image_display_time, displayRocketImages) } class selectAlienImage{ +bool is_wild +run() } class clearScreen{ +String beakColor +swim() +quack() } class incrementCounter{ -int sizeInFeet -canEat() } class displayFinalScore{ +bool is_wild +run() } class dontDetect{ pass } class showCoin{ +XXX +asdfasdf } class updateScore{ +bool is_wild +run() } ```