#1
by
DaveO
Hello! I have a simple design where subjects answer questions from a .csv file in a random order. I'm getting a Type Error for a variable (question_id, which indexes the question from the .csv file) in my Subjects table that I reference in my creating_session function, but it only happens when I add more apps to my session config. When I test the quiz app on its own it works fine, but when I add apps for a demographic questionnaire I get the error. It seems to be reading the question_id variable as a string rather than an integer. The problem is obviously in my creating_session function, and I'm guessing it has something to do with the difference between a session and a subsession when I add additional apps. I'm new to OTree and sub-novice at Python, so this may be an obvious question. I'll also have a hard time understanding responses that are heavy in programming logic #MODELS: class Player(BasePlayer): # RANDOM NUMBER WILL BREAK TIES: random_number = models.FloatField(initial=0) # FIELD THAT DETERMINES GROUP RANKING/WINNER: rank_field = models.FloatField(initial=0) # GROUP WINNER DUMMY: winner = models.BooleanField(initial=0) # QUESTION DETAILS FROM THE TEXT OF THE CSV QUIZ FILE: question_id = models.PositiveIntegerField(initial=0) question = models.CharField() solution = models.CharField() # ANSWER CHOSEN BY SUBJECT: submitted_answer = models.CharField(widget=widgets.RadioSelect) is_correct = models.BooleanField() quiz_score = models.IntegerField(initial=0) expiry = models.FloatField() # FUNCTIONS def get_timeout_seconds(player): import time return player.expiry - time.time() def creating_session(subsession): # ONLY IN ROUND 1 if subsession.round_number == 1: for p in subsession.get_players(): p.random_number = random.random() ## to randomize the order of the questions, you could instead do: randomized_questions = random.sample(C.questions, len(C.questions)) subsession.session.vars['questions'] = randomized_questions # ONLY AFTER ROUND 1: if subsession.round_number > 1: for p in subsession.get_players(): p.random_number = p.in_round(1).random_number # ALL ROUNDS: for p in subsession.get_players(): question_data = current_question(p) p.question_id = question_data['id'] p.question = question_data['question'] p.solution = question_data['solution'] THE ERROR MESSAGE: Failed to create session: question_id should be set to int, not str. Traceback (most recent call last): File "C:\Users\dowens\venv\lib\site-packages\otree\session.py", line 447, in create_session_traceback_wrapper return create_session(**kwargs) File "C:\Users\dowens\venv\lib\site-packages\otree\session.py", line 418, in create_session func(subsession) File "G:\My Drive\Work\Research\Projection Bias and Other-Regarding Preferences\Proj-Bias-Other-Regard-Python\testproject\prolific_test_2\__init__.py", line 70, in creating_session p.question_id = question_data['id'] File "C:\Users\dowens\venv\lib\site-packages\otree\database.py", line 551, in __setattr__ raise TypeError(msg) TypeError: question_id should be set to int, not str. Anyway, thanks for any help anyone can provide! Dave O
#2
by
Chris_oTree
When Python reads a CSV file, it interprets all fields as strings, even if those fields contain numeric values. For example if you have number 1, it'll be read as the string '1' instead of the integer 1. Solutions: (a) use oTree's built-in read_csv function, it will make sure all values have the right datatype. (b) use the int() function: p.question_id = int(question_data['id'])
#3
by
DaveO
Thank you, Chris. That did the trick. I'm still curious why I don't run into the same issue when using only one app. I appreciate your help. Dave O