def after_all_players_arrive(self): # 1) transfer executed orders to Contracts in the selfre model for region in self.subsession.session.vars['selfremarket'].regions: for k,x in self.subsession.session.vars['AllOrders'].items(): if (x.status=='exec' and x.region==region.name): x.status='postpro' y=self.subsession.session.vars['AllOrders'][x.filled_against] y.status='postpro' if x.typus=='Bid': buyer=next((z for z in self.subsession.session.vars['selfremarket'].selfremarket.players if z == x.player),None) # match by name seller=next((z for z in self.subsession.session.vars['selfremarket'].selfremarket.players if z == y.player),None) # match by name c=selfremarket.Contract(seller,buyer,x.filled_price,region) # eler,buyer,p,region) # print("foo56 CREATE CONTRACT for players %s, %s"%(x.player,y.player)) c.print() self.subsession.session.vars['selfremarket'].selfremarket.add_contract(c) else: seller=next((z for z in self.subsession.session.vars['selfremarket'].selfremarket.players if z == x.player),None) # match by name buyer=next((z for z in self.subsession.session.vars['selfremarket'].selfremarket.players if z == y.player),None) # match by name c=selfremarket.Contract(seller,buyer,x.filled_price,region) print("foo57 CREATE CONTRACT") c.print() self.subsession.session.vars['selfremarket'].selfremarket.add_contract(c) # check if all contracts got inserted... print("SelfreMarket - after deals and before nomination:") self.subsession.session.vars['selfremarket'].selfremarket.show01()
def set_direct_payoff(self): c = self.session.config if self.donation is not None: if self.donation: self.direct_payoff = c.get('yes_ego') self.nko_payoff = c.get('yes_nko') else: self.direct_payoff = c.get('no_ego') self.nko_payoff = c.get('no_nko')
class Constants(BaseConstants): name_in_url = 'BaseExperiment' players_per_group = 2 num_rounds = 1 BasePay = Currency(5) BasePrice = Currency(1) # SellingPrice = Currency(1) EmployeeRatio = 0.5 ManagerRatio = 0.25
class Constants(BaseConstants): players_per_group = 3 num_rounds = 3 name_in_url = 'guess_two_thirds' jackpot = Currency(100) guess_max = 100 instructions_template = 'guess_two_thirds/instructions.html'
class Constants(BaseConstants): players_per_group = None num_rounds = 10 name_in_url = 'beauty_contest' jackpot = Currency(10) guess_max = 100 instructions_template = 'beauty_contest/Instructions.html'
def configure_player(self, player): p = player.id_in_group duration_min = self.session.config[f"P{p}_duration_min"] duration_max = self.session.config[f"P{p}_duration_max"] player.duration = random.randint(duration_min, duration_max) price_min = self.session.config[f"P{p}_price_min"] price_max = self.session.config[f"P{p}_price_max"] player.price = Currency(random.randint(price_min, price_max))
def __init__(self, qdef, question): self._choices = [Choice(c) for c in qdef.iterfind("choice")] if len(self._choices) > 0: self._has_default = max([c.default() for c in self._choices]) else: self._has_default = False logger.info("Question has default: %s" % self._has_default) super(ChoiceQuestion, self).__init__(qdef, question)
def get_bmi_info(self): # we loop through all possible values in our bmi correspondence table from Constants # and look for something that fits into this user's data. # as soon as we find it, we exit with this data. for c in Constants.bmi_info: if c.check_if_in(self.get_bmi()): return c # if corresponding BMI is not found we don't want to generate an error, and we'll still # return something return BMI('Not defined', 0, 0, 'Not defined')
def test_payoff(self): session = otree.session.create_session( session_config_name='two_rounds_1p', num_participants=1, ) # need to activate cache after creating a session # because inside create_session, cache is deactivated with otree.db.idmap.use_cache(): # for some reason id=1 test fails, because the session only has # participant with id=2. ah, that makes sense. even if the DB # is truncated, PKs will still be incremented, i think. participant = session.participant_set.first() round_players = participant.get_players() round_payoff = Currency(13) round_players[0].payoff = round_payoff round_players[1].payoff = round_payoff payoff = participant.payoff self.assertEqual(payoff, 2 * round_payoff) participation_fee = session.config['participation_fee'] self.assertEqual(participation_fee, 1.25) real_world_currency_per_point = session.config[ 'real_world_currency_per_point'] self.assertEqual(real_world_currency_per_point, 0.5) payoff_in_real_world_currency = payoff * real_world_currency_per_point payoff_plus_participation_fee = participant.payoff_plus_participation_fee( ) self.assertEqual(payoff_plus_participation_fee, payoff_in_real_world_currency + participation_fee) payments_url = reverse('SessionPayments', args=[session.code]) client = django.test.Client() resp = client.get(payments_url) html = resp.content.decode('utf-8') for amount in [ '\u20ac1.25', # participation fee '\u20ac13.00', # participant.payoff '\u20ac14.25' # base plus participant.payoff ]: self.assertIn(amount, html)
def vars_for_template(self): c = [] p = [] for cons in self.subsession.session.vars[ 'selfremarket'].selfremarket.consumptions: if (cons.bringer == str(self.player.id_in_group)): c.append(cons.site) for prod in self.subsession.session.vars[ 'selfremarket'].selfremarket.productions: if (prod.receiver == str(self.player.id_in_group)): p.append(prod.prodsite) if len(c) == 0: c2 = 'None' else: c2 = ','.join(str(x) for x in c) if len(p) == 0: p2 = 'None' else: p2 = ','.join(str(x) for x in p) return {'productionfacilities': p2, 'consumptionfacilities': c2}
def helper(self): session = otree.session.create_session( session_config_name='two_rounds_1p', num_participants=1, ) # need to activate cache after creating a session # because inside create_session, cache is deactivated otree.db.idmap.activate_cache() participant = session.participant_set.get(id=1) round_players = participant.get_players() round_payoff = Currency(13) round_players[0].payoff = round_payoff round_players[1].payoff = round_payoff otree.db.idmap.deactivate_cache() payoff = participant.payoff self.assertEqual(payoff, 2 * round_payoff) participation_fee = session.config['participation_fee'] self.assertEqual(participation_fee, 1.25) real_world_currency_per_point = session.config[ 'real_world_currency_per_point'] self.assertEqual(real_world_currency_per_point, 0.5) payoff_in_real_world_currency = payoff * real_world_currency_per_point payoff_plus_participation_fee = participant.payoff_plus_participation_fee( ) self.assertEqual(payoff_plus_participation_fee, payoff_in_real_world_currency + participation_fee) payments_url = reverse('SessionPayments', args=[session.code]) client = django.test.Client() resp = client.get(payments_url) html = resp.content.decode('utf-8') for amount in [ '\u20ac1.25', # participation fee '\u20ac13.00', # participant.payoff '\u20ac14.25' # base plus participant.payoff ]: self.assertIn(amount, html)
def test_participant_payoff(self): '''Should be able to set participant.payoff directly''' session = otree.session.create_session( session_config_name='two_rounds_1p', num_participants=1, ) payoff = Currency(10) participant = session.participant_set.first() participant.payoff = payoff participant.save() participant = session.participant_set.first() self.assertEqual(participant.payoff, payoff)
def test_valid_but_invalid_error_message(self): '''valid individual fields but passes error_message''' values = dict(default_submission) values['f_char'] = Constants.invalid_f_char self.timeout_submit_form(values) auto_submit_defaults = { 'f_bool': False, 'f_char': '', 'f_currency': Currency(0), 'f_float': 0, 'f_posint': 0, } self.assert_player_fields(auto_submit_defaults)
class Constants(BaseConstants): # oTree Constants name_in_url = 'bret' players_per_group = None # ---------------------------------------------------------------------------------------------------------------- # # --- Overall Settings and Appearance --- # # ---------------------------------------------------------------------------------------------------------------- # # value of single collected box # if the bomb is not collected, player's payoff per round is determined by <box_value> times <boxes_collected> # note that the currency of any earnings is determined by the oTree settings in settings.py # if you set this to a decimal number, you must set POINTS_DECIMAL_PLACES in settings.py box_value = Currency(5) # number of rows and columns # i.e. the total number of boxes is determined by <num_rows> times <num_cols> num_rows = 5 num_cols = 5 # box height and box width in pixels # make sure that the size of the boxes fits the screen of the device # note that the layout is responsive, i.e. boxes will break into new rows if they don't fit box_height = '50px' box_width = '50px' # number of rounds to be played num_rounds = 2 # determines whether all rounds played are payed-off or whether one round is randomly chosen for payment # if <random_payoff = True>, one round is randomly determined for payment # if <random_payoff = False>, the final payoff of the task is the sum of all rounds played # note that this is only of interest for the case of <num_rounds> larger than 1 random_payoff = True # if <instructions = True>, a separate template "Instructions.html" is rendered prior to the task in round 1 # if <instructions = False>, the task starts immediately (e.g. in case of printed instructions) instructions = True # show feedback by resolving boxes, i.e. toggle boxes and show whether bomb was collected or not # if <feedback = True>, the button "Solve" will be rendered and active after game play ends ("Stop") # if <feedback = False>, the button "Solve" won't be rendered such that no feedback about game outcome is provided feedback = True # show results page summarizing the game outcome # if <results = True>, a separate page containing all relevant information is displayed after finishing the task # if <num_rounds> larger than 1, results are summarized in a table and only shown after all rounds have been played results = True # ---------------------------------------------------------------------------------------------------------------- # # --- Settings Determining Game Play --- # # ---------------------------------------------------------------------------------------------------------------- # # "dynamic" or "static" game play # if <dynamic = True>, one box per time interval is collected automatically # in case of <dynamic = True>, game play is affected by the variables <time_interval> and <random> below # if <dynamic = False>, subjects collect as many boxes as they want by clicking or entering the respective number # in case of <dynamic = False>, game play is affected by the variables <random>, <devils_game> and <undoable> dynamic = False # time interval between single boxes being collected (in seconds) # note that this only affects game play if <dynamic = True> time_interval = 1.00 # collect boxes randomly or systematically # if <random = False>, boxes are collected row-wise one-by-one, starting in the top-left corner # if <random = True>, boxes are collected randomly (Fisher-Yates Algorithm) # note that this affects game play in both cases, <dynamic = True> and <dynamic = False> random = True # determines whether static game play allows for selecting boxes by clicking or by entering a number # if <devils_game = True>, game play is similar to Slovic (1965), i.e. boxes are collected by subjects # if <devils_game = False>, subjects enter the number of boxes they want to collect # note that this only affects game play if <dynamic = False> devils_game = True # determine whether boxes can be toggled only once or as often as clicked # if <undoable = True> boxes can be selected and de-selected indefinitely often # if <undoable = False> boxes can be selected only once (i.e. decisions can not be undone) # note that this only affects game play if <dynamic = False> and <devils_game = True> undoable = True
from tests.timeout_submission.models import Player, Constants from tests.timeout_submission import views import django.test from otree.api import Submission, Currency, Page import itertools import time import otree.timeout.tasks #.submit_expired_url.schedule( from unittest.mock import patch, MagicMock test_client = django.test.Client() # tuple instead of dict so we don't mutate it by mistake default_submission = ( ('f_bool', True), ('f_char', 'hello'), ('f_currency', Currency(2)), ('f_float', 0.1), ('f_posint', 3), ) class PageWithTimeout(Page): timeout_seconds = 50 class PageWithNoTimeout(Page): pass class TestTimeout(TestCase):
def savings_choices(self): return [[c,c.to_real_world_currency(self.session)] for c in [c(0),c(.5),c(1)]]
def savings_choices(self): return [[c, c.to_real_world_currency(self.session)] for c in currency_range(0, 4, 2)]
class Player(BasePlayer): player_field = models.CurrencyField(initial=Currency(3.14)) align_group = models.CharField() align_participant = models.CharField()