import random import json from json import JSONDecodeError from otree import settings from otree.api import * import csv doc = """ Your app description """ #### EXTRA MODELS class NumberSequence(ExtraModel): question = models.StringField() solution = models.StringField() type = models.BooleanField() class Analogy(ExtraModel): question = models.StringField() optionA = models.StringField() optionB = models.StringField() optionC = models.StringField() optionD = models.StringField() optionE = models.StringField() solution = models.StringField() ## helper def load_analogy(filepath='analogy.csv'): rows = read_csv(__name__ + '/' + filepath, Analogy) for i, row in enumerate(rows): row['number'] = i+1 return rows def load_number_sequence(filepath='nums.csv'): rows = read_csv(__name__ + '/' + filepath, NumberSequence) for i, row in enumerate(rows): row['number'] = i+1 return rows def generate_order_for_tasks(player): maximum_length = min(len(C.ANALOGY_LIST), len(C.NUM_SEQUENCE_LIST)) indices_seller = list(range(0, maximum_length)) ## only 37 in the num_sequence file indices_customer = list(range(0, maximum_length)) random.shuffle(indices_customer) random.shuffle(indices_seller) player.participant.social_proximity_order_customer = indices_customer player.participant.social_proximity_order_seller = indices_seller def get_number_for_player(player, customer, stage=1): number = player.round_number*2 - 3 + stage ## stage sollte 1 oder 2 sein if customer: return player.participant.social_proximity_order_customer[number] return player.participant.social_proximity_order_seller[number] ### Start Basic Classes class C(BaseConstants): NAME_IN_URL = 'analogientest' PLAYERS_PER_GROUP = None NUM_ROUNDS = 10 ## LOAD Models ANALOGY_LIST = load_analogy() NUM_SEQUENCE_LIST = load_number_sequence() ## Kontrollvariablen AMOUNT_NUMBER_GENERATOR = 18 AMOUNT_NUMBERS_COMPLETE = 2 * AMOUNT_NUMBER_GENERATOR ANALOGY_POINTS = 2 NUMBER_SEQ_POINTS = 2 ## Timeout basierte TIMEOUT_GAME = 60 TIMER_TEXT = "Verbleibende Zeit:" class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): response_games = models.LongStringField() points_analogy = models.IntegerField(initial=0) points_number_seq = models.IntegerField(initial=0) ## Creating Session def creating_session(subsession: Subsession): for player in subsession.get_players(): generate_order_for_tasks(player) # PAGES def check_for_correct_answer(player, game_object, response_games): try: resp = json.loads(response_games) ### Für Behnud zum anschauen print(resp , game_object) return resp['answer'] == game_object['solution'] except JSONDecodeError: return False class Analogy_Stage1(Page): form_model = 'player' form_fields = ['response_games'] #timeout_seconds = C.TIMEOUT_GAME ##todo nach dem testen wieder rein timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): return True # todo: pcds Hier die richtige Anzeige wählen (runden oder was auch immer) @staticmethod def vars_for_template(player: Player): return dict( DEBUG=settings.DEBUG#False#settings.DEBUG ) @staticmethod def js_vars(player: Player): # analogy = Analogy.filter(player=player, round_number=player.round_number, stage=1)[0] ## todo: pcds nach type customer oder seller hier auswählen aus der participant variante ## für die Kunden ist es round_number*2 - 1 für den Index der ersten Analogy stage & roundnumber*2 für die 2te analogy = C.ANALOGY_LIST[get_number_for_player(player=player, customer=True, stage=1)] return dict( analogy=analogy #analogy=vars(analogy) ) @staticmethod def before_next_page(player: Player, timeout_happened): game_object = C.ANALOGY_LIST[get_number_for_player(player=player, customer=True, stage=1)] answer = check_for_correct_answer(player, game_object, player.response_games) ## todo: Behnud : reicht hier die summe als punkte oder willst du beide print('richtige Antwort ? ', answer) player.points_analogy += answer * C.ANALOGY_POINTS player.response_games = '' # leer machen class Zahlenreihe_Stage1(Page): form_model = 'player' form_fields = ['response_games'] # timeout_seconds = C.TIMEOUT_GAME ##todo nach dem testen wieder rein timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): return True ##todo: sag wann und was @staticmethod def vars_for_template(player: Player): return dict( DEBUG=settings.DEBUG#False#settings.DEBUG ) @staticmethod def js_vars(player: Player): # analogy = Analogy.filter(player=player, round_number=player.round_number, stage=1)[0] ## todo: pcds nach type customer oder seller hier auswählen aus der participant variante ## für die Kunden ist es round_number*2 - 1 für den Index der ersten Analogy stage & roundnumber*2 für die 2te num_seq = C.NUM_SEQUENCE_LIST[get_number_for_player(player=player, customer=True, stage=1)] return dict( number_sequence=num_seq #analogy=vars(analogy) ) @staticmethod def before_next_page(player: Player, timeout_happened): game_object = C.NUM_SEQUENCE_LIST[get_number_for_player(player=player, customer=True, stage=1)] answer = check_for_correct_answer(player, game_object, player.response_games) ## todo: Behnud : reicht hier die summe als punkte oder willst du beide print('richtige Antwort ? ', answer) player.points_number_seq += answer * C.NUMBER_SEQ_POINTS player.response_games = '' # leer machen class MyPage(Page): pass class ResultsWaitPage(WaitPage): pass class Results(Page): pass page_sequence = [ Analogy_Stage1, Zahlenreihe_Stage1, ]