from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import csv import json import uuid from random import shuffle, randint, choice from itertools import cycle from django.db.models import EmailField author = 'Tommaso Batistoni - t.batistoni@ucl.ac.uk' doc = """ Welcome, Consent, Login and Introduction pages to survey experience. Students and teachers data are retrieved from legacy database. The page sequence of the app for the students starts from website-domain/bienvenue """ years = {'Seconde': 1, 'Première': 2, 'Terminale': 3} # APP RANDOMIZATION NOT IMPLEMENTED #from otree.models_concrete import ParticipantToPlayerLookup #from otree.common_internal import ( # get_models_module) #from otree import common_internal #def get_new_sequence_of_apps(app_sequence): # rnd_apps = app_sequence[4:9] # shuffle(rnd_apps) # app_sequence = app_sequence[:4] + rnd_apps + app_sequence[9:] # return app_sequence #def build_participant_to_player_lookups(participant, subsession_app_names, session): # participant_to_player_lookups = [] # page_index = 0 # for app_name in subsession_app_names: # # views_module = common_internal.get_pages_module(app_name) # models_module = get_models_module(app_name) # Constants = models_module.Constants # Player = models_module.Player # players_flat = Player.objects.filter(session=session, participant=participant).values( # 'id', 'participant__code', 'participant__id', 'subsession__id', # 'round_number' # ) # # players_by_round = [[] for _ in range(Constants.num_rounds)] # for p in players_flat: # players_by_round[p['round_number'] - 1].append(p) # for round_number, round_players in enumerate(players_by_round, start=1): # for View in views_module.page_sequence: # page_index += 1 # for p in round_players: # participant_code = p['participant__code'] # url = View.get_url( # participant_code=participant_code, # name_in_url=Constants.name_in_url, # page_index=page_index # ) # participant_to_player_lookups.append( # ParticipantToPlayerLookup( # participant_id=p['participant__id'], # participant_code=participant_code, # page_index=page_index, # app_name=app_name, # player_pk=p['id'], # subsession_pk=p['subsession__id'], # session_pk=session.pk, # url=url)) # ParticipantToPlayerLookup.objects.bulk_create( # participant_to_player_lookups # ) class Constants(BaseConstants): name_in_url = 'intro' players_per_group = None num_rounds = 1 # APP RANDOMIZATION NOT IMPLEMENTED # interactive_tasks = ['compete', 'cooperation', 'trust', 'guessing_game', 'coordination', 'redistribute_team'] # Retrieve STUDENT data from the ministry database # Synthetic data are used for testing with open('data/FINAL_STUDENTS_DATASET_IN_SAMPLE_LF.csv', encoding="utf-8") as file: reader = csv.DictReader(file) students_db = [ {"uuid": row["stud_ID"], "first_name": row["stud_first_name"].title(), "last_name": row["stud_last_name"].title(), "dob": row["stud_birth_date"].rsplit('/', 1)[0], "classroom": row["stud_division"], "school": row["stud_school_name"], "school_ID": row["stud_school_ID"], "year": years[row["stud_level"]], "region": row["stud_academie"], "not_in_db": False} for row in reader] stud_first_names = list(set([r["first_name"] for r in students_db])) stud_first_names.sort() stud_last_names = list(set([r["last_name"] for r in students_db])) stud_last_names.sort() schools = list(set([r["school"] for r in students_db])) schools.sort() classrooms = list(set([r["classroom"] for r in students_db])) classrooms.sort() schools_ID = list(set([r["stud_school_ID"] for r in reader])) schools_ID.sort() # Teachers' mode is commented out for testing #with open('_static/data/classrooms.json', 'w', encoding='utf-8') as f: # json.dump(classrooms, f, ensure_ascii=False, indent=4) # retrieve TEACHERS data from the ministry database # with open('_static/data/FINAL_TEACHERS_DATASET_LF.csv', encoding="ISO-8859-1") as file: # reader = csv.DictReader(file) # teachers_db = [ # {"uuid": row["teach_ID"], "first_name": row["teach_first_name"].title(), # "last_name": row["teach_last_name"].title(), # "dob": row["teach_birth_date"].rsplit('/', 1)[0], # "school": row["teach_school_name"], # "school_ID": row["teach_school_ID"], # "region": row["teach_academie"], # "not_in_db": False} # for row in reader] # teach_first_names = list(set([r["first_name"] for r in teachers_db])) # teach_last_names = list(set([r["last_name"] for r in teachers_db])) # teach_first_names.sort() # teach_last_names.sort() class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): p.participant.vars['solo_tasks_assigned'] = [] # APP RANDOMIZATION NOT IMPLEMENTED #if not p.sequence_of_apps: # ParticipantToPlayerLookup.objects.filter(participant=p.participant).delete() # p.sequence_of_apps = json.dumps(get_new_sequence_of_apps(self.session.config['app_sequence'])) # build_participant_to_player_lookups(p.participant, json.loads(p.sequence_of_apps), # self.session) class Group(BaseGroup): pass class Player(BasePlayer): not_in_db = models.BooleanField() uuid = models.StringField() is_creteil = models.BooleanField() region = models.StringField() school = models.StringField() school_ID = models.StringField() classroom = models.StringField() subject = models.StringField() year = models.IntegerField() is_mobile = models.BooleanField() is_tablet = models.BooleanField() browser = models.StringField() # APP RANDOMIZATION NOT IMPLEMENTED # sequence_of_apps = models.LongStringField() email = EmailField(max_length=70, blank=True)