from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import csv author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): import csv, io name_in_url = 'bangla_st3_2_BNG_tr1_t0' players_per_group = 10 #Todo: Read this from some config file! #number of questions #Todo: Read this from some config file! num_rounds = int(10 / 2) #num_questions_module = int(2 / 2) #number_questions = 2 # Load question pools #Todo: Read this from some config file! #B = 500 #D = 100 #r = 0.1 # Verbal F1 #Todo: Access same question pool (?) with io.open('bangla_st0/190914_questions.csv', "r", encoding='utf-8-sig') as questions_file: questions = list(csv.DictReader(questions_file)) class Subsession(BaseSubsession): def before_session_starts(self): pass def creating_session(self): if self.round_number == 1: self.session.vars['questions'] = Constants.questions.copy() import random type1_questions = [q for q in Constants.questions if q['type'] == '1'] type2_questions = [q for q in Constants.questions if q['type'] == '2'] random.shuffle(type1_questions) random.shuffle(type2_questions) print("[MAIN]\t\tShuffeling questions") randomized_questions1 = random.sample(type1_questions, Constants.num_rounds ) randomized_questions2 = random.sample(type2_questions, Constants.num_rounds ) #print(randomized_questions1) self.session.vars['questions1_task1'] = randomized_questions1 self.session.vars['questions2_task1'] = randomized_questions2 print(randomized_questions1) print(randomized_questions2) def load_new_questions(self): for p in self.get_players(): question_data1 = p.current_question(1) print("Loading1", question_data1) p.question_id1 = int(question_data1['id']) p.question1 = question_data1['question'] p.solution1 = question_data1['solution'] p.qtype1 = int(question_data1['type']) p.qsubtype1 = int(question_data1['subtype']) question_data2 = p.current_question(2) print("Loading2", question_data2) p.question_id2 = int(question_data2['id']) p.question2 = question_data2['question'] p.solution2 = question_data2['solution'] p.qtype2 = int(question_data2['type']) p.qsubtype2 = int(question_data2['subtype']) def on_app_start(self): print('[MAIN]\t\tInitialising App 3...') self.session.vars['app3_initialised'] = True for p in self.get_players(): print(p.participant.vars['this_uid'],p.participant.vars['matchedTo'],p.participant.vars['myRole'] ) p.matchedPlayer = p.participant.vars['matchedTo'] p.myRole = p.participant.vars['myRole'] p.uid = p.participant.vars['this_uid'] def production_function(self): print('[MAIN]\t\tRunning production function...') #Move this to participant too! productions = {} revenues = {} for p in self.get_players(): #Back-fill player data player_in_all_rounds = p.in_all_rounds() #Because every round/question initialises new player for pp in player_in_all_rounds: pp.matchedPlayer = p.participant.vars['matchedTo'] pp.myRole = pp.participant.vars['myRole'] pp.uid = pp.participant.vars['this_uid'] for p in self.get_players(): if p.matchedPlayer != -1: #is matched print("matched pl", p.matchedPlayer,) other_perf = None for op in self.get_players(): print(op.uid, p.matchedPlayer) if op.uid == p.matchedPlayer: other_perf = op.get_performance() print("other perf", other_perf) self_perf = p.get_performance() p.partner_performance = other_perf print(p.uid, self_perf, other_perf) # DEBT if self.session.vars['treatment'] in [1,3]: # # # # PRODUCTION HERE p.production = self_perf * other_perf * 2 * self.session.vars['B'] productions[p.uid] = p.production # # # # CAPITAL STRUCTURE p.debt_repayment = 2 * (1+self.session.vars['r']) * self.session.vars['D'] p.revenue = p.production - 2 * (1+self.session.vars['r']) * self.session.vars['D'] revenues[p.uid] = p.revenue # EQUITY elif self.session.vars['treatment'] in [2,4]: # # # # PRODUCTION HERE p.production = self_perf * other_perf * 2 * self.session.vars['B'] productions[p.uid] = p.production # # # # CAPITAL STRUCTURE p.debt_repayment = int( round( self.session.vars['s'] * p.production, 0) ) p.revenue = int( round( p.production * (1-self.session.vars['s']) , 0) ) revenues[p.uid] = p.revenue else: # is Unmatched self_perf = p.get_performance() print(p.uid, self_perf) # DEBT if self.session.vars['treatment'] in [1,3]: # # # # PRODUCTION HERE p.production = self_perf * 1 * self.session.vars['B'] productions[p.uid] = p.production # # # # CAPITAL STRUCTURE HERE p.debt_repayment = (1+self.session.vars['r']) * self.session.vars['D'] p.revenue = p.production - (1+self.session.vars['r']) * self.session.vars['D'] revenues[p.uid] = p.revenue # EQUITY elif self.session.vars['treatment'] in [2,4]: # # # # PRODUCTION HERE p.production = self_perf * 1 * self.session.vars['B'] productions[p.uid] = p.production # # # # CAPITAL STRUCTURE HERE p.debt_repayment = int( round( self.session.vars['s'] * p.production, 0) ) p.revenue = int( round( p.production * (1-self.session.vars['s']) , 0) ) revenues[p.uid] = p.revenue print(productions, revenues) def migrate_to_session(self): for p in self.get_players(): p.participant.vars['performance'] = p.performance p.participant.vars['partner_performance'] = p.partner_performance p.participant.vars['production'] = p.production p.participant.vars['revenue'] = p.revenue p.participant.vars['debt_repayment'] = p.debt_repayment def back_up(self): if self.session.vars['do_backups'] == False: return None import smtplib, ssl, time, json this_savepoint_id = 'svpt0301' save_data = [] for p in self.get_players(): this_row = [] # save metadata: date, player uid, player otree id, this_app this_row.append( time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) ) this_row.append( p.uid) this_row.append( p.participant.id_in_session ) this_row.append( p.participant.code ) this_row.append('app3') # save content: this_row.append([ p.participant.vars['performance'], p.participant.vars['partner_performance'] , p.participant.vars['production'], p.participant.vars['revenue'], p.participant.vars['debt_repayment'] , ]) save_data.append(this_row) save_data.append([ self.session.vars['megaRound'], self.session.vars['questions1_task1'], self.session.vars['questions2_task1'] ]) try: this_dat = json.dumps(save_data) message = str(this_savepoint_id) + "\n " + this_dat from_address = "bangladeshi.experimentor@gmail.com" password = "YcDjgzQv44JD9a6R" context = ssl.create_default_context() with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server: server.login(from_address, password) server.sendmail( from_address, "bangladeshi.experimentor@gmail.com", message) except: print("ERR message not sent") #Todo: Record how answered each question? class Group(BaseGroup): pass class Player(BasePlayer): uid = models.IntegerField() matchedPlayer = models.IntegerField() myRole = models.IntegerField() performance = models.FloatField() partner_performance = models.FloatField() production = models.FloatField() revenue = models.FloatField() debt_repayment = models.FloatField() score = models.IntegerField() question_id1 = models.IntegerField() question1 = models.StringField() solution1 = models.StringField() qtype1 = models.IntegerField() qsubtype1 = models.IntegerField() question_id2 = models.IntegerField() question2 = models.StringField() solution2 = models.StringField() qtype2 = models.IntegerField() qsubtype2 = models.IntegerField() is_correct = models.BooleanField() questions = models.StringField() this_question_data = models.StringField() submitted_answer = models.StringField(widget=widgets.RadioSelect) def submitted_answer_choices(self): qd = self.current_question(self.participant.vars['myRole']) print("submitted:" , qd) if int(qd['type']) == 1 and int(qd['subtype']) in [1,] : return [ qd['choice1'], qd['choice2'], qd['choice3'], ] elif int(qd['type']) == 1 and int(qd['subtype']) in [2,] : return [ qd['choice1'], qd['choice2'], qd['choice3'], ] elif int(qd['type']) == 2 and int(qd['subtype']) in [1,] : return [ qd['choice1'], qd['choice2'], ] elif int(qd['type']) == 2 and int(qd['subtype']) in [2,]: return [ qd['choice1'], qd['choice2'], qd['choice3'], qd['choice4'], ] def check_correct(self): if self.participant.vars['myRole'] == 1: self.is_correct = (self.submitted_answer == self.solution1) elif self.participant.vars['myRole'] == 2: self.is_correct = (self.submitted_answer == self.solution2) def current_question(self, role): #print("Role", self.participant.vars['next_role'] ) if role == 1: #print("current", self.session.vars['questions1_task1'][self.round_number - 1]) return self.session.vars['questions1_task1'][self.round_number - 1] elif role == 2: #print("current", self.session.vars['questions2_task1'][self.round_number - 1]) return self.session.vars['questions2_task1'][self.round_number - 1] def get_performance(self): player_in_all_rounds = self.in_all_rounds() if self.participant.vars['myRole'] == 1: self.performance = sum([p.is_correct for p in player_in_all_rounds if int(p.qtype1) == 1]) elif self.participant.vars['myRole'] == 2: self.performance = sum([p.is_correct for p in player_in_all_rounds if int(p.qtype2) == 2]) # Convert to percentage self.performance = round( self.performance / Constants.num_rounds , 2 ) print("PERFO", self.uid, self.performance) return self.performance def update_score(self): # Score can never go negative! self.participant.vars['score'] = max([self.participant.vars['score'] + self.revenue, 0]) self.score = int(self.participant.vars['score']) return self.participant.vars['score']