oTree Forum >

How does ExtraModel interact with rounds?

#1 by mitnec

Hi,
The documentation on ExtraModel doesn't mention much of this. I have an app that uses rounds to present new questions, and I want to store the wrong answers to those questions in an ExtraModel (you get 10 tries per question). I do this with somefield_error_message.

This seems to work fine, until I try to export this data with custom_export. I don't like dealing with wide data that has a lot of rounds, it's messy and repetitive. So I would like to export long and just what I need.

I do this: 

def custom_export(players):
    # header row
    yield ['session', 'participant_code', 'round_number', 'prompt', 'prompt_num', 'counter', 'guess']
    print("len players: ", len(players))
    print(IncorrectResponses.filter())
    for p in players:
        players_all_rounds = p.in_all_rounds()
        for player in players_all_rounds:
            print(IncorrectResponses.filter())
            # need to figure out which prompt_number s this player got, let's do it by num_rounds
            round = player.round_number
            # print("round: ", round)
            current_prompt = player.participant.vars['exp_subset_word'][(round-1)]
            incorrect_responses = IncorrectResponses.filter( player=player, prompt_number=current_prompt['Prompt_number'] )
            for guess in incorrect_responses:
                yield [player.session.code, player.participant.code, player.round_number, current_prompt['Prompt_with_blank'], current_prompt['Prompt_number'], guess.counter, guess.guess]
                
                
...which, for some reason, just gives me repetitions of the same round's data for all players.

Here is how I store it in an ExtraModel:

def guess_error_message(player, value):
    prompt = player.participant.vars['exp_subset_word'][(player.round_number-1)]
    # strip value of spaces and make it lower case
    cleaned_value = ''.join(e for e in value if e.isalnum())
    cleaned_value = cleaned_value.lower()
    if (cleaned_value != prompt['Answer']) and (player.participant.vars['answer_counter'] < C.NUM_GUESSES):
        IncorrectResponses.create(player=player, prompt_number=prompt['Prompt_number'], counter=player.participant.vars['answer_counter'], guess=str(cleaned_value))
        player.participant.vars['answer_counter'] += 1
        return "Not the right answer. Try again!"
        
        
What am I missing?
I could store all this in participant.vars and then export, I guess, but it seems like I should be using ExtraModel.

#2 by Chris_oTree

You don't need this:

        players_all_rounds = p.in_all_rounds()
        for player in players_all_rounds:

Because 'players' already includes all players from all rounds of the app.

Write a reply

Set forum username