class FormFieldModel(otree.models.BaseGroup): null_boolean = models.BooleanField() big_integer = models.BigIntegerField() boolean = models.BooleanField(default=False) char = models.CharField() comma_separated_integer = models.CommaSeparatedIntegerField(max_length=100) date = models.DateField() date_time = models.DateTimeField() alt_date_time = models.DateTimeField( widget=otree.forms.SplitDateTimeWidget) decimal = models.DecimalField(max_digits=5, decimal_places=2) email = models.EmailField() file = models.FileField(upload_to='_tmp/uploads') file_path = models.FilePathField() float = models.FloatField() integer = models.IntegerField() generic_ip_address = models.GenericIPAddressField() positive_integer = models.PositiveIntegerField() positive_small_integer = models.PositiveSmallIntegerField() slug = models.SlugField() small_integer = models.SmallIntegerField() text = models.TextField() alt_text = models.TextField(widget=otree.forms.TextInput) time = models.TimeField() url = models.URLField() many_to_many = models.ManyToManyField('SimpleModel', related_name='+') one_to_one = models.OneToOneField('SimpleModel', related_name='+') currency = models.CurrencyField() currency_choice = models.CurrencyField(choices=[('0.01', '0.01'), ('1.20', '1.20')]) sent_amount = models.CurrencyField(choices=currency_range(0, 0.75, 0.05)) slider_widget = models.IntegerField(widget=widgets.SliderInput())
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> name = models.CharField(max_length=255, verbose_name="Your name") age = models.CharField(max_length=255, verbose_name="Your age") email = models.EmailField(verbose_name="Your email address") gender = models.CharField(verbose_name="Are you", max_length=255, widget=widgets.RadioSelect(), choices=["Male", "Female"]) major = models.CharField(max_length=1000, verbose_name="What is your major?") location_of_your_partners_influence_your_decisions = models.TextField( verbose_name=("Did the location of your partners influence your " "decisions of how much to contribute to the individual " "account versus the team account? If yes, how?")) working_in_a_location_of_their_choice_more_less_to_the_team = models.BooleanField( widget=widgets.RadioSelect(), verbose_name=("When you were partnered with two people working in a " "location of their choice, did you want to give more " "to the team or less than when you were partnered " "with two people working in a lab?")) partners_in_location_their_choice_worked_harder_than_the_lab = models.BooleanField( widget=widgets.RadioSelect(), verbose_name=("Do you believe your partners participation in a " "location of their choice gave more to the group than " "your partners working the lab?")) I_work_best_in = models.CharField( verbose_name="Are you", max_length=255, widget=widgets.RadioSelect(), choices=["Structured environments", "flexible environments"]) risks_in_everyday_life = models.PositiveIntegerField( min=1, max=10, widget=widgets.SliderInput(), verbose_name=("In general, do you take more or less risks in everyday " "life? ('1' = take less risk and '10' take more risk.)")) risks_in_financial_decision = models.PositiveIntegerField( min=1, max=10, widget=widgets.SliderInput(), default=5, verbose_name= (" In general, do you take more or less risks in financial decisions? " "life? ('1' = take less risk and '10' take more risk.)"))
def test_normal_widget_is_required_depending_on_blank(self): modelfield = models.BooleanField() formfield = modelfield.formfield() self.assertTrue(formfield.required) modelfield = models.BooleanField(blank=True) formfield = modelfield.formfield() self.assertFalse(formfield.required)
class Player(BasePlayer): training_question_1 = models.CharField( max_length=100, choices=[ 'Player 1 gets 0 points, Player 2 gets 0 points', 'Player 1 gets 100 points, Player 2 gets 100 points', 'Player 1 gets 100 points, Player 2 gets 0 points', 'Player 1 gets 0 points, Player 2 gets 100 points' ], widget=widgets.RadioSelect()) def is_training_question_1_correct(self): return self.training_question_1 == Constants.training_1_correct penny_side = models.CharField(choices=['Heads', 'Tails'], doc="""Heads or tails""", widget=widgets.RadioSelect()) is_winner = models.BooleanField(doc="""Whether player won the round""") def other_player(self): """Returns the opponent of the current player""" return self.get_others_in_group()[0] def role(self): if self.id_in_group == 1: return 'Player 1' if self.id_in_group == 2: return 'Player 2'
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> item_value_estimate = models.CurrencyField( doc="""Estimate of the common value, may be different for each player""" ) bid_amount = models.CurrencyField( doc="""Amount bidded by the player""" ) def bid_amount_bounds(self): return [Constants.min_allowable_bid, Constants.max_allowable_bid] is_winner = models.BooleanField( default=False, doc="""Indicates whether the player is the winner""" ) def set_payoff(self): if self.is_winner: self.payoff = self.group.item_value - self.bid_amount if self.payoff < 0: self.payoff = 0 else: self.payoff = 0
class Player(BasePlayer): def score_round(self): # update player payoffs if self.solution == self.user_total: self.is_correct = True self.payoff_score = 1 else: self.is_correct = False self.payoff_score = c(0) def set_task_score(self): op_scores = [] for op in self.get_others_in_group(): op_scores.append(int(op.participant.vars['task_2_score'])) self.participant.vars['task_2_op_scores'] = op_scores task_timer = models.PositiveIntegerField( doc="""The length of the real effort task timer.""") solution = models.PositiveIntegerField( doc="this round's correct summation") user_total = models.PositiveIntegerField( min=1, max=9999, doc="user's summation", widget=widgets.TextInput(attrs={'autocomplete': 'off'})) is_correct = models.BooleanField(doc="did the user get the task correct?") payoff_score = models.FloatField(doc='''score in this task''')
class Player(otree.models.BasePlayer): # <built-in> subsession = models.ForeignKey(Subsession) group = models.ForeignKey(Group, null=True) # </built-in> def other_player(self): """Returns other player in group. Only valid for 2-player groups.""" return self.get_others_in_group()[0] blank = models.CharField(blank=True) add100_1 = models.PositiveIntegerField() add100_2 = models.PositiveIntegerField() even_int = models.PositiveIntegerField() after_next_button_field = models.BooleanField() dynamic_choices = models.CharField() dynamic_min_max = models.CurrencyField() in_before_session_starts = models.CurrencyField() def role(self): # you can make this depend of self.id_in_group return ''
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> private_value = models.MoneyField( doc="""How much the player values the item, generated randomly""" ) bid_amount = models.MoneyField( default=None, doc="""Amount bidded by the player""" ) def bid_amount_choices(self): return money_range(Constants.min_allowable_bid, Constants.max_allowable_bid, 0.05) is_winner = models.BooleanField( default=False, doc="""Indicates whether the player is the winner""" ) def generate_private_value(self): return round(random.uniform(Constants.min_allowable_bid, Constants.max_allowable_bid), 1) def set_payoff(self): if self.is_winner: self.payoff = self.private_value - self.bid_amount if self.payoff < 0: self.payoff = 0 else: self.payoff = 0
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> item_value_estimate = models.MoneyField( doc="""Estimate of the common value, may be different for each player""" ) bid_amount = models.MoneyField(doc="""Amount bidded by the player""") def bid_amount_error_message(self, value): if not Constants.min_allowable_bid <= value <= Constants.max_allowable_bid: return 'The amount bidded must be between {} and {}, inclusive.'.format( Constants.min_allowable_bid, Constants.max_allowable_bid) is_winner = models.BooleanField( default=False, doc="""Indicates whether the player is the winner""") def set_payoff(self): if self.is_winner: self.payoff = self.subsession.item_value - self.bid_amount if self.payoff < 0: self.payoff = 0 else: self.payoff = 0
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> training_my_profit = models.CurrencyField( verbose_name='My profit would be') price = models.CurrencyField( doc="""Price player chooses to sell product for""" ) is_a_winner = models.BooleanField( default=False, doc="""Whether this player offered lowest price""" ) def price_bounds(self): return [0, Constants.maximum_price] def is_sole_winner(self): return self.is_a_winner and self.group.num_winners == 1 def is_shared_winner(self): return self.is_a_winner and self.group.num_winners > 1
class Group(otree.models.BaseGroup): # <built-in> subsession = models.ForeignKey(Subsession) # </built-in> total_return = models.CurrencyField( doc="""Total return from agent's effort = [Return for single unit of agent's work effort] * [Agent's work effort]""") agent_fixed_pay = models.CurrencyField( doc="""Amount offered as fixed pay to agent""", min=Constants.min_fixed_payment, max=Constants.max_fixed_payment, verbose_name='Fixed Payment (from %i to %i)' % (Constants.min_fixed_payment, Constants.max_fixed_payment)) agent_return_share = models.FloatField( choices=Constants.agent_return_share_choices, doc="""Agent's share of total return""", verbose_name='Return Share', widget=widgets.RadioSelectHorizontal()) agent_work_effort = models.PositiveIntegerField( choices=range(1, 10 + 1), doc="""Agent's work effort, [1, 10]""", widget=widgets.RadioSelectHorizontal(), ) agent_work_cost = models.CurrencyField( doc="""Agent's cost of work effort""") contract_accepted = models.BooleanField( doc="""Whether agent accepts proposal""", widget=widgets.RadioSelect(), choices=( (True, 'Accept'), (False, 'Reject'), )) def set_payoffs(self): principal = self.get_player_by_role('principal') agent = self.get_player_by_role('agent') if not self.contract_accepted: principal.payoff = Constants.reject_principal_pay agent.payoff = Constants.reject_agent_pay else: self.agent_work_cost = cost_from_effort(self.agent_work_effort) self.total_return = return_from_effort(self.agent_work_effort) money_to_agent = self.agent_return_share * \ self.total_return + self.agent_fixed_pay agent.payoff = money_to_agent - self.agent_work_cost principal.payoff = self.total_return - money_to_agent principal.payoff += Constants.bonus agent.payoff += Constants.bonus def return_share_as_percentage(self): return utils.float_as_percentage(self.agent_return_share)
class Group(BaseGroup): two_third_guesses = models.FloatField() best_guess = models.FloatField() tie = models.BooleanField(initial=False) def set_payoffs(self): players = self.get_players() self.two_third_guesses = ((2 / 3) * sum(p.guess_value for p in players) / len(players)) candidates = [] smallest_difference_so_far = Constants.guess_max + 1 # initialize to largest possible difference tie = False for p in self.get_players(): p.payoff = 0 p.is_winner = False # initialize to false difference = abs(p.guess_value - self.two_third_guesses) if difference < smallest_difference_so_far: tie = False candidates = [p] smallest_difference_so_far = difference elif difference == smallest_difference_so_far: tie = True candidates.append(p) self.tie = tie winners = candidates winners_cnt = len(winners) for p in winners: p.is_winner = True p.payoff = (Constants.winner_payoff / winners_cnt if tie else Constants.winner_payoff) self.best_guess = winners[0].guess_value
class Player(BasePlayer): is_winner = models.BooleanField( initial=False, doc=""" True if player had the winning guess """ ) guess_value = models.PositiveIntegerField( initial=None, min=0, max=Constants.guess_max, doc=""" Each player guess: between 0-{} """.format(Constants.guess_max) ) training_question_1_win_pick = models.PositiveIntegerField(min=0, max=Constants.training_1_maximun_pick) training_question_1_my_payoff = models.CurrencyField(min=0, max=Constants.training_1_maximun_offered_points) def is_training_question_1_win_pick_correct(self): return (self.training_question_1_win_pick == Constants.training_question_1_win_pick_correct) def is_training_question_1_my_payoff_correct(self): return (self.training_question_1_my_payoff == Constants.training_question_1_my_payoff_correct)
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> is_winner = models.BooleanField(initial=False, doc=""" True if player had the winning guess """) guess_value = models.PositiveIntegerField(initial=None, min=0, max=Constants.guess_max, doc=""" Each player guess: between 0-{} """.format(Constants.guess_max)) training_question_1_win_pick = models.PositiveIntegerField( min=0, max=Constants.training_1_maximun_pick) training_question_1_my_payoff = models.CurrencyField( min=0, max=Constants.training_1_maximun_offered_points) def is_training_question_1_win_pick_correct(self): return (self.training_question_1_win_pick == Constants.training_question_1_win_pick_correct) def is_training_question_1_my_payoff_correct(self): return (self.training_question_1_my_payoff == Constants.training_question_1_my_payoff_correct)
class GlobalSingleton(models.Model): """object that can hold site-wide settings. There should only be one GlobalSingleton object. Also used for wait page actions. """ class Meta: app_label = "otree" locked = models.BooleanField(default=False)
def test_checkbox_form_field_is_required_if_blank_is_set(self): # blank=True means en empty checkbox is ok. modelfield = models.BooleanField(widget=widgets.CheckboxInput(), blank=True) formfield = modelfield.formfield() self.assertFalse(formfield.required) # blank=False means the checkbox must be checked (is required). modelfield = models.BooleanField(widget=widgets.CheckboxInput(), blank=False) formfield = modelfield.formfield() self.assertTrue(formfield.required)
class Group(otree.models.BaseGroup): # <built-in> subsession = models.ForeignKey(Subsession) # </built-in> n_empresa_trabajador_finalizacion_forzada = models.BooleanField( default=False) n_empresa_trabajador_fin_ciclo = models.BooleanField(default=False) def set_negociacion_simple_payoff(self): proponente = self.get_player_by_role(Constants.proponente) respondente = self.get_player_by_role(Constants.respondente) if respondente.n_simple_respuesta == "Aceptar": proponente.payoff = 200 - proponente.n_simple_propuesta respondente.payoff = proponente.n_simple_propuesta else: proponente.payoff = 0 respondente.payoff = 0 def set_negociacion_simple_virtual_payoff(self, proponente): proponente.payoff = 200 - proponente.n_simple_propuesta def set_negociacion_empresa_trabajador_payoff(self): empresa = self.get_player_by_role(Constants.empresa) trabajador = self.get_player_by_role(Constants.trabajador) if self.n_empresa_trabajador_finalizacion_forzada: empresa.payoff = c(50) trabajador.payoff = 0 else: propuestas = empresa.all_propuestas() contrapropuestas = trabajador.all_contrapropuestas() X = c(contrapropuestas[-1] if len(propuestas) == len(contrapropuestas) else propuestas[-1]) trabajador.payoff = X empresa.payoff = 200 - X def set_negociacion_empresa_trabajador_virtual_payoff(self, empresa): empresa.payoff = 200 - empresa.n_empresa_trabajador_propuesta def forzar_finalizacion_empresa_trabajador(self): finalizar = random.choice(Constants.finalizar_muestra) if finalizar: self.n_empresa_trabajador_finalizacion_forzada = True self.n_empresa_trabajador_fin_ciclo = True
class CompletedSubsessionWaitPage(models.Model): class Meta: app_label = "otree" unique_together = ['page_index', 'session_pk'] index_together = ['page_index', 'session_pk'] page_index = models.PositiveIntegerField() session_pk = models.PositiveIntegerField() after_all_players_arrive_run = models.BooleanField(default=False)
class ParticipantLockModel(models.Model): class Meta: app_label = "otree" participant_code = models.CharField(max_length=16, db_index=True, unique=True) locked = models.BooleanField(default=False)
class Group(otree.models.BaseGroup): # <built-in> subsession = models.ForeignKey(Subsession) # </built-in> # transaction fields transaction_price = models.CurrencyField(doc="""Given by 0.5*(BP+SP)""") shares_traded = models.PositiveIntegerField(initial=0) # dividend fields dividend_per_share = models.CurrencyField() is_dividend = models.BooleanField(initial=False, doc="""Indicates whether dividend is issued""") # method to set cash and shares to balance in previous round def set_assets_to_previous(self): for p in self.get_players(): p.cash = p.in_previous_rounds()[-1].cash p.shares = p.in_previous_rounds()[-1].shares def trade(self): buyers = [p for p in self.get_players() if p.order_type == 'Buy'] sellers = [p for p in self.get_players() if p.order_type == 'Sell'] # both lists must have exactly 1 element if not (buyers and sellers): return buyer = buyers[0] seller = sellers[0] if seller.sp >= buyer.bp or (buyer.bn * buyer.bp == 0) or (seller.sn * seller.sp == 0): return # average of buy & sell price self.transaction_price = 0.5*(buyer.bp+seller.sp) self.shares_traded = min(buyer.bn, seller.sn) # adjust shares and cash amount = self.transaction_price * self.shares_traded if amount > buyer.cash: return buyer.shares += self.shares_traded buyer.cash -= amount seller.shares -= self.shares_traded seller.cash += amount def set_dividend(self): self.dividend_per_share = randint(1,2) self.is_dividend = True # adjust cash for p in self.get_players(): p.cash += ( p.shares * self.dividend_per_share if p.shares != 0 else p.cash )
class Player(BasePlayer): price = models.CurrencyField( min=0, max=Constants.maximum_price, doc="""Price player chooses to sell product for""" ) is_a_winner = models.BooleanField( initial=False, doc="""Whether this player offered lowest price""" )
class Player(BasePlayer): training_my_profit = models.CurrencyField( verbose_name='My profit would be') price = models.CurrencyField( min=0, max=Constants.maximum_price, doc="""Price player chooses to sell product for""") is_a_winner = models.BooleanField( initial=False, doc="""Whether this player offered lowest price""")
class Player(BasePlayer): penny_side = models.CharField(choices=['Heads', 'Tails'], widget=widgets.RadioSelect()) is_winner = models.BooleanField() def role(self): if self.id_in_group == 1: return 'Mismatcher' if self.id_in_group == 2: return 'Matcher'
class Player(BasePlayer): is_winner = models.BooleanField(initial=False, doc=""" True if player had the winning guess """) guess_value = models.PositiveIntegerField(initial=None, min=0, max=Constants.guess_max, doc=""" Each player guess: between 0-{} """.format(Constants.guess_max))
class PageCompletion(models.Model): class Meta: app_label = "otree" app_name = models.CharField(max_length=300) page_index = models.PositiveIntegerField() page_name = models.CharField(max_length=300) time_stamp = models.PositiveIntegerField() seconds_on_page = models.PositiveIntegerField() subsession_pk = models.PositiveIntegerField() participant_pk = models.PositiveIntegerField() session_pk = models.PositiveIntegerField() auto_submitted = models.BooleanField()
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> training_my_payoff = models.CurrencyField( verbose_name='My payoff would be') volunteer = models.BooleanField( doc="""Whether player volunteers""", widget=widgets.RadioSelect(), )
class Player(BasePlayer): comprehension_1 = models.CharField( max_length=10, choices=sorted(Constants.comprehension_1.items()), widget=widgets.RadioSelect()) comprehension_2 = models.CharField( max_length=10, choices=sorted(Constants.comprehension_2.items()), widget=widgets.RadioSelect()) comprehension_3 = models.CharField( max_length=10, choices=sorted(Constants.comprehension_3.items()), widget=widgets.RadioSelect()) last_question = models.BooleanField(widget=widgets.RadioSelect())
class Player(otree.models.BasePlayer): def other_player(self): """Returns other player in group. Only valid for 2-player groups.""" return self.get_others_in_group()[0] from_other_player = models.PositiveIntegerField() is_winner = models.BooleanField(initial=False) in_all_groups_wait_page = models.FloatField(initial=0) group_id_before_p1_switch = models.PositiveIntegerField() def role(self): # you can make this depend of self.id_in_group return ''
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> penny_side = models.CharField(choices=['Heads', 'Tails'], widget=widgets.RadioSelect()) is_winner = models.BooleanField() def role(self): if self.id_in_group == 1: return 'Mismatcher' if self.id_in_group == 2: return 'Matcher'
class Player(BasePlayer): private_value = models.CurrencyField( null=True, doc="How much the player values the item, generated randomly") bid_amount = models.CurrencyField(null=True, min=Constants.min_allowable_bid, max=Constants.max_allowable_bid, doc="Amount bidded by the player") is_winner = models.BooleanField( initial=False, doc="""Indicates whether the player is the winner""") training_question_1_my_payoff = models.CurrencyField() def is_training_question_1_my_payoff_correct(self): return (self.training_question_1_my_payoff == Constants.training_question_1_my_payoff_correct)