from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import random import re #from captcha.fields import ReCaptchaField class Consent(Page): def vars_for_template(self): return {'participation_fee': Constants.participation_fee, 'max_bonus': self.session.config['max_bonus'], 'redemption_code': self.participant.code } class Captcha(Page): _allow_custom_attributes = True form_model = 'player' form_fields = [] # captcha does not get in here #def get_form(self, data=None, files=None, **kwargs): # frm = super().get_form(data, files, **kwargs) # frm.fields['captcha'] = ReCaptchaField() # return frm class Warning(Page): pass class InstructionsRating(Page): def vars_for_template(self): max_bonus = self.session.config['max_bonus'] if self.player.cp_error: return {'message': 'Please, re-read the instructions!', 'participation_fee': self.session.config['participation_fee'], 'max_bonus': self.session.config['max_bonus']} else: return {'participation_fee': self.session.config['participation_fee'], 'max_bonus': self.session.config['max_bonus']} class UQ(Page): form_model = 'player' form_fields = ['uq2', 'uq3', 'uq4'] # Function to redirect to instructions page if the comprehension answers are wrong: def before_next_page(self): p = self.player p.cp_error = False p.flagged = False for k, v in Constants.correct_answers.items(): if getattr(p, k) != v and p.error1 is not True: p.cp_error = True p.error1 = True break elif getattr(p, k) != v and p.error1 is True and p.error2 is not True: p.cp_error = True p.error2 = True break elif getattr(p, k) != v and p.error1 is True and p.error2 is True and p.error3 is not True: p.cp_error = False p.error3 = True break elif getattr(p, k) != v and p.error1 is True and p.error2 is True and p.error3 is True: p.cp_error = False p.flagged = True break if p.cp_error: for f in self.form_fields: setattr(p, f, None) self._is_frozen = False self._index_in_pages -= 2 self.participant._index_in_pages -= 2 class Beliefs(Page): form_model = 'player' random.seed(11235) def get_form_fields(self): all_fields = ['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9'] random.shuffle(all_fields) return all_fields def vars_for_template(self): image = self.participant.vars['images'] return {'img_to_show': image} class Perception(Page): form_model = 'player' random.seed(11235) def get_form_fields(self): all_fields = ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9'] random.shuffle(all_fields) return all_fields def vars_for_template(self): image = self.participant.vars['images'] return {'img_to_show': image} class RatingCredit(Page): """Player chooses whether to signal to show creditworthiness""" form_model = 'player' form_fields = ['rating_c_p1', 'rating_c_p2', 'rating_c_p3', 'rating_c_p4', 'guessed_income1', 'guessed_income2', 'guessed_income3', 'guessed_income4', 'checkslider1', 'checkslider2', 'checkslider3', 'checkslider4'] def checkslider1_error_message(self, value): if not value: return 'Rate Player 1 creditworthiness using the slider!' def checkslider2_error_message(self, value): if not value: return 'Rate Player 2 creditworthiness using the slider!' def checkslider3_error_message(self, value): if not value: return 'Rate Player 3 creditworthiness using the slider!' def checkslider4_error_message(self, value): if not value: return 'Rate Player 4 creditworthiness using the slider!' def vars_for_template(self): n1 = self.player.sender1 - 1 n2 = self.player.sender2 - 1 n3 = self.player.sender3 - 1 n4 = self.player.sender4 - 1 return {"p1_rating": self.player.rating_c_p1, "p2_rating": self.player.rating_c_p2, "p3_rating": self.player.rating_c_p3, "p4_rating": self.player.rating_c_p4, "age1": Constants.age_sender_c[n1], "age2": Constants.age_sender_c[n2], "age3": Constants.age_sender_c[n3], "age4": Constants.age_sender_c[n4], "weight1": Constants.weight_sender_c[n1], "weight2": Constants.weight_sender_c[n2], "weight3": Constants.weight_sender_c[n3], "weight4": Constants.weight_sender_c[n4], "height1": Constants.height_sender_c[n1], "height2": Constants.height_sender_c[n2], "height3": Constants.height_sender_c[n3], "height4": Constants.height_sender_c[n4], "income1": Constants.income_sender[n1], "income2": Constants.income_sender[n2], "income3": Constants.income_sender[n3], "income4": Constants.income_sender[n4], "gender1": Constants.gender_sender[n1], "gender2": Constants.gender_sender[n2], "gender3": Constants.gender_sender[n3], "gender4": Constants.gender_sender[n4], "information1": Constants.info_sender[n1], "information2": Constants.info_sender[n2], "information3": Constants.info_sender[n3], "information4": Constants.info_sender[n4] } def before_next_page(self): n1 = self.player.sender1 - 1 n2 = self.player.sender2 - 1 n3 = self.player.sender3 - 1 n4 = self.player.sender4 - 1 if Constants.info_sender[n1] == 'asymmetric': self.player.guessed_income1 = 0 if Constants.info_sender[n2] == 'asymmetric': self.player.guessed_income2 = 0 if Constants.info_sender[n3] == 'asymmetric': self.player.guessed_income3 = 0 if Constants.info_sender[n4] == 'asymmetric': self.player.guessed_income4 = 0 class RatingDating(Page): """Player chooses whether to signal to show creditworthiness""" form_model = 'player' form_fields = ['rating_d_p1', 'rating_d_p2', 'rating_d_p3', 'rating_d_p4', 'guessed_income5', 'guessed_income6', 'guessed_income7', 'guessed_income8', 'checkslider5', 'checkslider6', 'checkslider7', 'checkslider8'] def vars_for_template(self): n1 = self.player.sender1 - 1 n2 = self.player.sender2 - 1 n3 = self.player.sender3 - 1 n4 = self.player.sender4 - 1 return {"p1_rating": self.player.rating_d_p1, "p2_rating": self.player.rating_d_p2, "p3_rating": self.player.rating_d_p3, "p4_rating": self.player.rating_d_p4, "age1": round(Constants.age_sender_d[n1]), "age2": round(Constants.age_sender_d[n2]), "age3": round(Constants.age_sender_d[n3]), "age4": round(Constants.age_sender_d[n4]), "weight1": round(Constants.weight_sender_d[n1]), "weight2": round(Constants.weight_sender_d[n2]), "weight3": round(Constants.weight_sender_d[n3]), "weight4": round(Constants.weight_sender_d[n4]), "height1": round(Constants.height_sender_d[n1]), "height2": round(Constants.height_sender_d[n2]), "height3": round(Constants.height_sender_d[n3]), "height4": round(Constants.height_sender_d[n4]), "income1": round(Constants.income_sender[n1]), "income2": round(Constants.income_sender[n2]), "income3": round(Constants.income_sender[n3]), "income4": round(Constants.income_sender[n4]), "gender1": Constants.gender_sender[n1], "gender2": Constants.gender_sender[n2], "gender3": Constants.gender_sender[n3], "gender4": Constants.gender_sender[n4], "information1": Constants.info_sender[n1], "information2": Constants.info_sender[n2], "information3": Constants.info_sender[n3], "information4": Constants.info_sender[n4] } def before_next_page(self): n1 = self.player.sender1 - 1 n2 = self.player.sender2 - 1 n3 = self.player.sender3 - 1 n4 = self.player.sender4 - 1 if Constants.info_sender[n1] == 'asymmetric': self.player.guessed_income1 = 0 if Constants.info_sender[n2] == 'asymmetric': self.player.guessed_income2 = 0 if Constants.info_sender[n3] == 'asymmetric': self.player.guessed_income3 = 0 if Constants.info_sender[n4] == 'asymmetric': self.player.guessed_income4 = 0 class Demographics(Page): form_model = 'player' form_fields = ['year_of_birth', 'gender', 'income', 'hhincome', 'marital_status', 'children', 'education', 'height', 'weight', 'health', 'race', 'westernized', 'country', 'zip', 'loan', 'loan_hypothetical', 'loan_hypothetical_why'] class Issues(Page): form_model = 'player' form_fields = ['issues', 'comments'] def before_next_page(self): self.group.set_payoffs() class ResultsUganda(Page): form_model = 'player' form_fields = ['phone_number', 'payment_method'] def vars_for_template(self): if self.player.phone_error: return {"msg": "Invalid mobile phone number!", "participation_fee": Constants.participation_fee, "max_bonus": Constants.maxbonus, "payoff_round1": self.participant.vars["payoff_round1"], "payoff_round2": self.participant.vars["payoff_round2"], "total_payoff": self.participant.payoff_plus_participation_fee() } else: return {"participation_fee": Constants.participation_fee, "max_bonus": Constants.maxbonus, "total_payoff": self.participant.payoff_plus_participation_fee() } def before_next_page(self): """ Raise a ValidationError if the value looks like a mobile telephone number. """ rule = re.compile(r'^(?:\+?256)?[07]\d{9,13}$') if not rule.search(self.player.phone_number): self.player.phone_error = True else: self.player.phone_error = False if self.player.phone_error: self._is_frozen = False self._index_in_pages -= 1 self.participant._index_in_pages -= 1 page_sequence = [ Consent, #Captcha, Warning, InstructionsRating, UQ, Beliefs, Perception, RatingCredit, RatingDating, Demographics, Issues, ResultsUganda ]