Live Pages

464 views
Skip to first unread message

Alexander Marchal

unread,
Sep 22, 2021, 5:13:10 PM9/22/21
to oTree help & discussion
This is my first time making an experiment in oTree and I am having problems with live pages, i.e. it is not entering my live_method. I have posted the code below (not sure why it won't let me indent). As background, I want people to make sequential decisions (I'm experimenting in an information cascade) so I'm trying to make it so that only one person can make a decision at a time and to pre-set that order (all that is going fine). I'm sure that it is something very novice that I am missing but I appreciate the help.



def live_method(player, data):
print('in live_method', data)
group = player.group
my_id = player.player_id

broadcast = {}

if not (player.is_in_queue or player.is_live): # Once both are off they are finished with turn
return {my_id: dict(finished=True)}

if player.is_live and 'state_of_world_guess' in data: # Finishing turn (turn of is_live after guess)
player.state_of_world_guess = data['state_of_world_guess']
if player.state_of_world_guess == group.world_state: # Set earnings
player.earnings_from_guess = 1 # Guessed Correctly
else:
player.earnings_from_guess = 0 # Guessed Incorrectly
player.is_in_queue = False # No longer waiting
player.is_live = False # No longer live
player.past_player = True # Finished
group.num_decided += 1 # Another player decided
group.live_player_id = None # Nobody is live

return {0: dict(reload=True)} # Reload the live page

if player.is_in_queue and get_or_none(group, 'live_player_id') is None: # Setting next live player
waiting_players = [p for p in group.get_players() if p.is_in_queue] # Find who's left
next_player = min(waiting_players, key=lambda p: p.player_id) # Lowest player
next_player.is_live = True # Set them live
group.live_player_id = next_player.id_in_group
next_player.is_in_queue = False # No longer waiting
broadcast[next_player.id_in_group] = dict(reload=True) # Broadcast they're live

if player.is_live: # Need to give them the ball signal
broadcast[my_id] = dict(
color_of_ball_signal=player.color_of_ball_signal
)
else:
broadcast[my_id] = dict(wait=True)
return broadcast


class Prediction(Page):

# Move participants on after they make a prediction since no next button
@staticmethod
def is_displayed(player: Player):
return player.is_in_queue or player.is_live

live_method = live_method

@staticmethod
def error_message(player: Player, values):
if player.is_in_queue or player.is_live:
return "Not ready to move on" # Wait for everyone to make turn

Chris @ oTree

unread,
Sep 22, 2021, 5:22:53 PM9/22/21
to oTree help & discussion
if it's not entering the live page at all, then the issue is probably in your HTML/JS code. can you post that?
by the way, for the indentation, try pasting your code into another text editor like Notepad first, then copy/paste here.

anyway, you should also check out the 'sequential' game in otree-snippets: https://www.otreehub.com/projects/otree-snippets/
it's much simpler, since it doesn't involve live pages. You can easily change it so that each player is making the same decision, by changing the group fields to player fields.

Chris @ oTree

unread,
Sep 22, 2021, 5:24:21 PM9/22/21
to oTree help & discussion
by the way, if you continue with the live page approach, the first thing you should do is check your browser's javascript console for errors, and use console.log() in your javascript code, just as you would use print() in python to debug the values of your variables.

Alexander Marchal

unread,
Sep 22, 2021, 5:48:53 PM9/22/21
to oTree help & discussion

Thanks for the feedback and tips on that. I may go back and try the sequential game approach because it does seem that it's much easier to implement. Nonetheless in the meantime this is a good learning opportunity for me about live methods (for the future) so if you could explain what's going on I appreciate it. My html/javascript code is below (note I know it's quite simple at the moment- my intention was to get it running then add the signals, options,etc. afterwards). It looks like there is a problem on the addEventListener.   


{{ block content }}
    <p>Your randomly set player number for this round is. Please wait for your turn to
        make a guess about the state of the round (Up or Down).</p>

    <div id="is-live" style="...">
        <p>
            Before you guess if the state is Up or Down, you can now also view the color of the ball that was randomly
            drawn.
        </p>

        <p>
            Now that you can see what color of ball the computer drew it is time for you to guess the state of the world.
            You can use this draw to help you make your guess. You will be informed of whether your guess is correct
            and if your random partner guessed correctly at the end of the experiment when your payout is determined.
        </p>

        <button type="button" onclick="sendOffer()">Submit</button>

    </div>

    <div id="is-waiting">
        <progress></progress>
        <p> You are in the queue. Please wait for your turn while those before you make their guess.</p>
    </div>


<script>
    let state_of_world_guess = document.getElementById('state_of_world_guess')

    state_of_world_guess.addEventListener("keydown", function (event) {
        if (event.key === "Enter") {
            sendOffer();
        }
    });

    function sendOffer() {
        if (state_of_world_guess.reportValidity()) {
            liveSend({'state_of_world_guess': parseInt(state_of_world_guess.value)});
        }
    }

    function liveRecv(data) {
        console.log('liveRecv',data);
        if ('color_of_ball_signal' in data) {
            document.getElementById('is-waiting').style.display = 'none';
            document.getElementById('is-live').style.display = 'block';
            //let color_of_ball_signal = data.color_of_ball_signal;
        }
        if ('finished' in data) {
            document.getElementById('form').submit();
        }
        if ('reload' in data) {
            liveSend({});
        }
        if ('error' in data) {
            alert(data.error);
        }
        else {
            document.getElementById('is-waiting').style.display = 'block';
            document.getElementById('is-live').style.display = 'none';
        }
    }


</script>


{{ endblock }}

Chris @ oTree

unread,
Sep 22, 2021, 6:33:22 PM9/22/21
to oTree help & discussion
your code has this: document.getElementById('state_of_world_guess')
but i don't see any element with that ID in your HTML.
anyway, try using console.log() to see what lines of your code are being executed.

Reply all
Reply to author
Forward
0 new messages