from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import logging import time import math logger = logging.getLogger(__name__) author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'memory_matching' players_per_group = None # About 45 seconds per game, so 40 rounds should take about 30min. We expect to run for 20min num_rounds = 15 # Running time of experiment, in minutes total_time = 3 * 60 # * 60 total_time_minutes = 3 payoff_per_star = 0.05 class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): p.participant.vars['last_stars'] = 0.0 p.participant.vars['num_correct'] = 0.0 class Group(BaseGroup): pass class Player(BasePlayer): star_rating = models.FloatField() timeout = models.IntegerField( choices=[0, 1] ) payoff_memory_rounded = models.CurrencyField() def calc_payoff(self): self.payoff = self.star_rating logger.debug(f"Payoff: {self.payoff}") self.participant.vars['last_stars'] = self.star_rating self.participant.vars['num_correct'] += self.star_rating logger.info( f"Total {self.participant.vars['num_correct']}, last attempt: {self.participant.vars['last_stars']}, round: {self.round_number}") # If this is the last round, store the final payout in participant.vars if (self.round_number == Constants.num_rounds): set_participant_payoff_info(self.participant, "memory_matching") def calc_final_payoff(self): # Payoffs are integers, so just round up the score self.participant.payoff = c(math.ceil(self.participant.vars['num_correct'])) logger.info(f"Setting final payment to: {self.participant.payoff}, from: {self.participant.vars['num_correct']}") def set_participant_payoff_info(participant, task_name): vars = participant.vars if not vars or 'payouts' not in vars: vars['payouts'] = {} payouts = vars['payouts'] # This will either create a new entry or update the current one new_entry = {task_name: vars['num_correct']} logger.info(f"Setting {task_name} payoff to: {vars['num_correct']}") payouts.update(new_entry)