class Player(BasePlayer): # initial shares and payoff shares = models.PositiveIntegerField(initial=5) cash = models.CurrencyField() # default allocated shares for both players; provides a range for buyers; sellers' range is limited by the number of shares they have # order fields bp = models.CurrencyField(initial=0.00, doc="""maximum buying price per share""") bn = models.PositiveIntegerField(initial=0, choices=range(0, Constants.num_shares + 1, 1), doc="""number of shares willing to buy""") sp = models.CurrencyField(initial=0.00, doc="""minimum selling price per share""") sn = models.PositiveIntegerField( initial=0, doc="""number of shares willing to sell.""") order_type = models.CharField(choices=['Sell', 'Buy', 'None'], doc="""player: buy or sell?""", widget=widgets.RadioSelectHorizontal) def other_player(self): """Returns other player in group. Only valid for 2-player groups.""" return self.get_others_in_group()[0] def set_payoff(self): self.payoff = 0 if self.subsession.round_number == Constants.num_rounds: self.payoff = self.cash else: self.payoff = 0
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> contribution = models.PositiveIntegerField( default=None, doc="""The amount contributed by the player""", widget=widgets.TextInput()) points = models.PositiveIntegerField(null=True) question = models.PositiveIntegerField(null=True, verbose_name='', widget=widgets.TextInput()) feedbackq = models.CharField( null=True, verbose_name='How well do you think this sample game was implemented?', widget=widgets.RadioSelectHorizontal()) def feedbackq_choices(self): return ['Very well', 'Well', 'OK', 'Badly', 'Very badly'] def question_correct(self): return self.question == self.subsession.question_correct def contribution_error_message(self, value): if not 0 <= value <= self.subsession.endowment: return 'Your entry is invalid.'
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> training_question_1 = models.PositiveIntegerField(null=True, verbose_name='') def is_training_question_1_correct(self): return self.training_question_1 == self.subsession.training_1_correct points_earned = models.PositiveIntegerField(default=None, ) quantity = models.PositiveIntegerField( default=None, doc="""Quantity of units to produce""") def quantity_error_message(self, value): if not 0 <= value <= self.subsession.max_units_per_player(): return "The value must be an integer between 0 and {}, inclusive.".format( self.subsession.max_units_per_player()) def other_player(self): return self.other_players_in_group()[0] def set_points(self): self.group.price = self.subsession.total_capacity - self.quantity - self.other_player( ).quantity self.points_earned = self.group.price * self.quantity def set_payoff(self): self.payoff = 0
class CompletedSubsessionWaitPage(models.Model): class Meta: app_label = "otree" index_together = ['page_index', 'session_pk'] page_index = models.PositiveIntegerField() session_pk = models.PositiveIntegerField()
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> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> def set_payoff(self): """Calculate payoff, which is zero for the survey""" self.payoff = 0 q_country = CountryField( verbose_name='What is your country of citizenship?') q_age = models.PositiveIntegerField(verbose_name='What is your age?', choices=range(13, 125), initial=None) q_gender = models.CharField(initial=None, choices=['Male', 'Female'], verbose_name='What is your gender?', widget=widgets.RadioSelect()) crt_bat = models.PositiveIntegerField() crt_widget = models.PositiveIntegerField() crt_lake = models.PositiveIntegerField()
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 Group(otree.models.BaseGroup): BONUS = 10 # <built-in> subsession = models.ForeignKey(Subsession) # </built-in> players_per_group = 2 sent_amount = models.PositiveIntegerField(doc="""Amount sent by P1""", ) sent_back_amount = models.PositiveIntegerField( doc="""Amount sent back by P2""", ) def set_payoffs(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p1.payoff = p2.payoff = 0 p1.points = self.BONUS + Constants.amount_allocated\ - self.sent_amount + self.sent_back_amount p2.points = self.BONUS + self.sent_amount * 3 - self.sent_back_amount def sent_amount_error_message(self, value): if not 0 <= value <= Constants.amount_allocated: return 'Your entry is invalid.' def sent_back_amount_error_message(self, value): if not 0 <= value <= self.sent_amount * 3: return 'Your entry is invalid.'
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 Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> def set_payoff(self): """Calculate payoff, which is zero for the survey""" self.payoff = 0 def q_gender_choices(self): return ['Male', 'Female'] def q_age_choices(self): return range(13, 125) q_country = CountryField(verbose_name='What is your country of citizenship?') q_age = models.PositiveIntegerField(verbose_name='What is your age?', default=None) q_gender = models.CharField(default=None, verbose_name='What is your gender?', widget=widgets.RadioSelect()) crt_bat_float = models.DecimalField(max_digits=6, decimal_places=2) crt_bat = models.PositiveIntegerField() crt_widget = models.PositiveIntegerField() crt_lake = models.PositiveIntegerField()
class PageTimeout(models.Model): class Meta: app_label = "otree" participant_pk = models.PositiveIntegerField() page_index = models.PositiveIntegerField() expiration_time = models.PositiveIntegerField()
class Subsession(otree.models.BaseSubsession): name_in_url = 'prisoner' defect_cooperate_amount = models.PositiveIntegerField( doc="""Points made if player defects and the other cooperates""", default=300, ) cooperate_amount = models.PositiveIntegerField( doc="""Points made if both players cooperate""", default=200, ) cooperate_defect_amount = models.PositiveIntegerField( doc="""Points made if player cooperates and the other defects""", default=0, ) defect_amount = models.PositiveIntegerField( doc="""Points made if both players defect""", default=100, ) training_1_correct = "Alice gets 300 points, Bob gets 0 points"
class CompletedGroupWaitPage(models.Model): class Meta: app_label = "otree" page_index = models.PositiveIntegerField() session_pk = models.PositiveIntegerField() group_pk = models.PositiveIntegerField()
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> request_amount = models.PositiveIntegerField( doc=""" Amount requested by this player. """, verbose_name='Please enter a number from 0 to 100') training_amount_mine = models.PositiveIntegerField( verbose_name='You would get') training_amount_other = models.PositiveIntegerField( verbose_name='The other participant would get') points = models.PositiveIntegerField() feedback = models.PositiveIntegerField( choices=((5, 'Very well'), (4, 'Well'), (3, 'OK'), (2, 'Badly'), (1, 'Very badly')), widget=widgets.RadioSelectHorizontal(), verbose_name='') def request_amount_error_message(self, value): if not 0 <= value <= Constants.amount_shared: return 'Your entry is invalid.' def other_player(self): """Returns the opponent of the current player""" return self.get_others_in_group()[0]
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> training_question_1 = models.PositiveIntegerField(null=True, verbose_name='') def is_training_question_1_correct(self): return self.training_question_1 == Constants.training_1_correct points_earned = models.PositiveIntegerField(doc=""".""") units = models.PositiveIntegerField(default=None, doc="""Quantity of units to produce""") def units_error_message(self, value): if not 0 <= value <= Constants.max_units_per_player: return "The value must be a whole number between {} and {}, inclusive.".format( 0, Constants.max_units_per_player) def other_player(self): return self.get_others_in_group()[0] def set_payoff(self): self.payoff = 0
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.)"))
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> subsession = models.ForeignKey(Subsession) group = models.ForeignKey(Group, null = True) # </built-in> # initial shares and payoff shares = models.PositiveIntegerField(initial=5) cash = models.CurrencyField() # default allocated shares for both players; provides a range for buyers; sellers' range is limited by the number of shares they have # order fields bp = models.CurrencyField(initial=0.00, doc="""maximum buying price per share""") bn = models.PositiveIntegerField(initial=0, choices=range(0, Constants.num_shares+1, 1), doc="""number of shares willing to buy""") sp = models.CurrencyField(initial=0.00, doc="""minimum selling price per share""") sn = models.PositiveIntegerField(initial=0, doc="""number of shares willing to sell.""") order_type = models.CharField(choices=['Sell', 'Buy', 'None'], doc="""player: buy or sell?""", widget=widgets.RadioSelectHorizontal) def sn_choices(self): return range(0, self.shares+1, 1) def bp_choices(self): return currency_range(0, self.cash, 0.5) def sp_choices(self): return currency_range(0, self.cash, 0.5) def other_player(self): """Returns other player in group. Only valid for 2-player groups.""" return self.get_others_in_group()[0] QUESTION_1_CHOICES = ['P=3, N=2','P=2, N=3','P=2.5, N=3','P=2.5, N=2','No transaction will take place',] QUESTION_2_CHOICES = ['$8, $12', '$12, $8', '$8, $8', '$12, $12', '$10, $10'] understanding_question_1 = models.CharField(choices=QUESTION_1_CHOICES, widget=widgets.RadioSelect()) understanding_question_2 = models.CharField(choices=QUESTION_2_CHOICES, widget=widgets.RadioSelect()) # check correct answers def is_understanding_question_1_correct(self): return self.understanding_question_1 == Constants.understanding_1_correct def is_understanding_question_2_correct(self): return self.understanding_question_2 == Constants.understanding_2_correct def set_payoff(self): self.payoff = 0 if self.subsession.round_number == Constants.num_rounds: self.payoff = self.cash else: self.payoff = 0
class GroupSize(models.Model): class Meta: app_label = "otree" app_label = models.CharField(max_length=300) subsession_pk = models.PositiveIntegerField() group_index = models.PositiveIntegerField() group_size = models.PositiveIntegerField()
class SessionuserToUserLookup(models.Model): class Meta: app_label = "otree" session_user_pk = models.PositiveIntegerField() page_index = models.PositiveIntegerField() app_name = models.CharField(max_length=300) user_pk = models.PositiveIntegerField()
class ParticipantToPlayerLookup(models.Model): class Meta: app_label = "otree" index_together = ['participant_pk', 'page_index'] participant_pk = models.PositiveIntegerField() page_index = models.PositiveIntegerField() app_name = models.CharField(max_length=300) player_pk = models.PositiveIntegerField()
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 Player(BasePlayer): transcription_1 = models.TextField( validators=[MaxLengthValidator(Constants.transcription_max_length)]) transcription_2 = models.TextField( validators=[MaxLengthValidator(Constants.transcription_max_length)]) distance_1 = models.PositiveIntegerField() distance_2 = models.PositiveIntegerField() def set_payoff(self): self.payoff = 0
class BasePlayer(SaveTheChange, models.Model): """ Base class for all players. """ class Meta: abstract = True index_together = ['participant', 'round_number'] ordering = ['pk'] _index_in_game_pages = models.PositiveIntegerField( default=0, doc='Index in the list of pages views_module.page_sequence') session = models.ForeignKey(Session, related_name='%(app_label)s_%(class)s') round_number = models.PositiveIntegerField(db_index=True) # it's _name instead of name because people might define # their own name field def _name(self): return self.participant.__unicode__() def role(self): # you can make this depend of self.id_in_group return '' def in_round(self, round_number): return type(self).objects.get(participant=self.participant, round_number=round_number) def in_rounds(self, first, last): qs = type(self).objects.filter( participant=self.participant, round_number__gte=first, round_number__lte=last, ).order_by('round_number') return list(qs) def in_previous_rounds(self): return self.in_rounds(1, self.round_number - 1) def in_all_rounds(self): return self.in_previous_rounds() + [self] def __unicode__(self): return self._name() def _GroupClass(self): return self._meta.get_field('group').rel.to @property def _Constants(self): return get_models_module(self._meta.app_config.name).Constants
class WaitPageVisit(models.Model): '''difference between this and PageVisit model is that this is run when the player first loads the page, rather than when they leave ''' class Meta: app_label = "otree" session_pk = models.PositiveIntegerField() page_index = models.PositiveIntegerField() id_in_session = models.PositiveIntegerField()
class User(SaveTheChange, models.Model): _index_in_game_pages = models.PositiveIntegerField( default=0, doc='Index in the list of pages views_module.page_sequence') session = models.ForeignKey(Session, related_name='%(app_label)s_%(class)s') round_number = models.PositiveIntegerField() class Meta: abstract = True
class Player(BasePlayer): time_Instructions = models.TextField(widget=widgets.HiddenInput( attrs={'id': 'arrive_time'})) time_Transcription = models.TextField(widget=widgets.HiddenInput( attrs={'id': 'arrive_time'})) transcribed_text = models.TextField() distance_1 = models.PositiveIntegerField() levenshtein_distance = models.PositiveIntegerField() time_Instructions = models.LongStringField() def set_payoff(self): self.payoff = 0
class Player(BasePlayer): def set_payoff(self): """Calculate payoff, which is zero for the survey""" self.payoff = 0 q_age = models.PositiveIntegerField(verbose_name='What is your age?', choices=range(13, 125), initial=None) q_gender = models.CharField(initial=None, choices=['Male', 'Female'], verbose_name='What is your gender?', widget=widgets.RadioSelect()) q_occupation = models.CharField( widget=widgets.RadioSelect(), choices=["wage-employed", "self-employed", "unemployed"]) q_income = models.CharField(widget=widgets.RadioSelect(), choices=[ "Less than Ksh.10,000", "Ksh.10,000 - Ksh. 30,000", "Ksh. 30,000 - Ksh. 60,000", "Ksh. 60,000 - Ksh.100,000", "More than Ksh.100,000", "Don’t know", ]) q_education_father = models.CharField( widget=widgets.RadioSelect(), choices=[ "Completed High School", "Completed Vocational College", "Completed University (Bachelor)", "Completed University (Advanced)", "Other", ]) q_education_mother = models.CharField( widget=widgets.RadioSelect(), choices=[ "Completed High School", "Completed Vocational College", "Completed University (Bachelor)", "Completed University (Advanced)", "Other", ]) crt_bat = models.PositiveIntegerField() crt_widget = models.PositiveIntegerField() crt_lake = models.PositiveIntegerField()
class Player(otree.models.BasePlayer): # <built-in> group = models.ForeignKey(Group, null=True) subsession = models.ForeignKey(Subsession) # </built-in> transcription_1 = models.TextField(validators=[MaxLengthValidator(Constants.transcription_max_length)]) transcription_2 = models.TextField(validators=[MaxLengthValidator(Constants.transcription_max_length)]) distance_1 = models.PositiveIntegerField() distance_2 = models.PositiveIntegerField() def set_payoff(self): self.payoff = 0
class Player(BasePlayer): id_profile = models.PositiveIntegerField() id_session = models.CharField() paid_individual_task = models.PositiveIntegerField(min=0, max=11) paid_pgg = models.PositiveIntegerField(min=0, max=10) payoff_individual_task = models.CurrencyField() payoff_pgg = models.CurrencyField() def init_var(self): self.id_profile = self.participant.vars['id_profile'] self.id_session = self.participant.vars['id_session']