from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from math import factorial import random def round_nearest(x, a=0.05): return round(x / a) * a def hypergeo(N, K, n, k): prob_upd=0 for j in range(k, n+1): prob_upd=prob_upd+(factorial(K)*factorial(N-K)*factorial(n)*factorial(N-n))/(factorial(j)*factorial(K-j)*factorial(n-j)*factorial(N-K-n+j)*factorial(N)) return prob_upd author = 'Robizon' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'gambling' players_per_group = None first_part=2 second_part=2 scenarios_num=5 start_scenario_1=first_part+1 start_second_part=first_part+scenarios_num+2 start_scenario_2=first_part+scenarios_num+second_part+2 start_lottery=first_part+scenarios_num+second_part+scenarios_num+3 num_inv_games=first_part+second_part+4 num_lottery_questions=18 start_questionnaire=first_part+scenarios_num+second_part+scenarios_num+num_lottery_questions+3 num_rounds = start_questionnaire+2 var_length = 30 suns_hidden=15 clouds_hidden=var_length-suns_hidden open_first_stage=5 open_second_stage=5 class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): if self.round_number ==1: p.participant.vars['ticket']=[random.sample([1]*Constants.suns_hidden+[0]*Constants.clouds_hidden, Constants.var_length) for x in range(0, Constants.num_inv_games)] if self.round_number >=1 and self.round_number<=Constants.start_second_part-1: p.smile_needed=6 elif self.round_number>=Constants.start_second_part and Constants.start_lottery-1: p.smile_needed=5 p.endowment=self.session.config['endowment'] if self.round_number==1: prob_for_part=random.uniform(0, 1) if prob_for_part<=0.99: p.participant.vars['payoff_part']=4 elif prob_for_part>0.99 and prob_for_part<=0.993: p.participant.vars['payoff_part']=3 elif prob_for_part>0.993 and prob_for_part<=0.996: p.participant.vars['payoff_part']=2 elif prob_for_part>0.996 and prob_for_part<=1: p.participant.vars['payoff_part']=1 p.part_for_payment=p.participant.vars['payoff_part'] if p.participant.vars['payoff_part']==3: p.participant.vars['payoff_round']=random.choice(range(1, Constants.num_lottery_questions +1)) p.round_for_payment=p.participant.vars['payoff_round'] p.participant.vars['correct']=[0]*(Constants.var_length) p.participant.vars['is_chosen']=[0]*(Constants.var_length) p.participant.vars['iniProb_updProb_bet']=[] p.participant.vars['triples']=[] for bet in [1, 5, 10, 15]: p.participant.vars['triples'].append([round(hypergeo(30, 15, 10, 5), 4), round(hypergeo(30, 15, 10, 5), 4), bet, 5]) p.participant.vars['triples'].append([round(hypergeo(30, 15, 10, 6), 4), round(hypergeo(30, 15, 10, 6), 4), bet, 6]) del bet initial_5=round(hypergeo(30, 15, 10, 5), 4) initial_6=round(hypergeo(30, 15, 10, 6), 4) for i in range(0, 5): p.participant.vars['triples'].append([initial_5, round(hypergeo(25, 11+i, 5, i+1), 4), 5, 5]) del i for i in range(0, 5): p.participant.vars['triples'].append([initial_6, round(hypergeo(25, 10+i, 5, i+1), 4), 5, 6]) del i p.participant.vars['cash_outs']=[] for bet in [1, 5, 10, 15]: list_1=[round_nearest(bet*hypergeo(25, 10+i, 5, i)/initial_5) for i in range(0, 6)] list_1.reverse() p.participant.vars['cash_outs'].append([bet, list_1]) for bet in [1, 5, 10, 15]: list_1=[round_nearest(bet*hypergeo(25, 10+i, 5, i+1)/initial_6) for i in range(0, 6)] list_1.reverse() p.participant.vars['cash_outs'].append([bet, list_1]) class Group(BaseGroup): pass class Player(BasePlayer): part_for_payment=models.IntegerField() round_for_payment=models.IntegerField() smile_needed=models.IntegerField() initial_prob=models.FloatField() updated_prob_1=models.FloatField() endowment=models.FloatField() round_return=models.FloatField() scenario=models.IntegerField() bet=models.FloatField(initial=0) possible_win=models.FloatField(initial=0) for i in range(1,Constants.var_length+1): locals()["num_{}".format(i)] =models.IntegerField(initial=0) del i correct_guess_after_1=models.IntegerField(initial=0) correct_guess_after_2=models.IntegerField(initial=0) offer_accapted=models.IntegerField(initial=0) offer=models.FloatField() ticket_string=models.StringField() correct_string_1=models.StringField() correct_string_2=models.StringField() chosen_string_1=models.StringField() chosen_string_2=models.StringField() def check_correct(self): for i in range(1,Constants.var_length+1): exec("self.participant.vars['correct'][%s] = (self.num_%s==self.participant.vars['ticket'][0][%s] and self.num_%s==1)" % (i-1, i, i-1, i)) del i def check_chosen(self): for i in range(1,Constants.var_length+1): exec("self.participant.vars['is_chosen'][%s] = self.num_%s==1" % (i-1, i)) del i #player status is false if he is still playing and true if he stopped playing player_status=models.BooleanField(initial=True) def check_status(self): if ( self.offer_accapted!=1 and self.offer>0 and self.offer