from otree.api import Currency as c, currency_range, safe_json from ._builtin import WaitPage, Page as oTreePage from .models import Constants import numpy as np import random import string import re #numbers for math quiz numbers = np.array([3, 1, 6, 7, 4, 1, 2, 5, 6, 1, 6, 1, 1, 5, 1, 1, 2, 2, 4, 1, 3, 8, 4, 4, 4, 2, 4, 2, 3, 7, 4, 1, 6, 5, 4, 1, 3, 3, 6, 1, 5, 2, 3, 5, 6, 2, 1, 1, 6, 5, 6, 8, 1, 6, 8, 2, 2, 3, 7, 2, 7, 4, 2, 7, 3, 2, 3, 5, 8, 2, 5, 7, 3, 1, 6, 4, 8, 1, 3, 5, 3, 8, 5, 3,2,5,4,1,4,7,3,5,1,4,4,4,2,2,1,2,3,7,4,8,1,8,2,5,6,5,5 ,1,2,1,8,8,7,1,4,3,3,6,8,7,1,7,1,1,6,4,7,2,5,6,8,8,8,4,1,6,3,4,2,2,8,5,8,7 ,5,3,8,5,8,8,7,3,6,7,6,5,3,8,5,3,7,7,2,4,4,5,6,3,2,1,6,3,7,4,7,6,8,6,8,7,4 ,3,6,8,8,7,5,1,4,1,5,3,5,4,2,4,3,4,6,3,1,3,3,6,4,3,5,6,2,4,4,6,2,5,5,5,6,4 ,1,1,5,6,7,6,6,3,2,3,3,4,6,8,7,4,7,3,1,8,8,5,7,6,8,8,6,7,6,6,4,8,3,4,3,4,5 ,4,8,8,6,3,8,5,7,3,6,4,7,6,6,8,2,3,6,5,3,8,5,6,4,1,3,6,8,4,5,8,3,2,3,7,1,6 ,4,6,7,4,7,6,2,5,5,8,7,2,6,1,8,6,4,6,4,8,2,4,4,6,4,6,1,4,7,3,2,6,8,5,5,2,1 ,2,2,8,1,6,4,5,7,6,3,6,6,2,2,2,1,4,4,1,3,8,8,6,3,6,3,8,8,2,5,1,4,7,7,7,8,5 ,6,6,8,8,1,3,8,8,6,8,3,3,4,8,1,8,5,2,4,3,1,4,1,1,1,4,6,1,5,2,7,2,5,4,6,1,8 ,5,3,7,7,1,6,8,8,6,2,5,6,2,6,8,6,2,5,1,1,6,3,3,6,4,4,7,7,8,4,4,3,8,7,2,3,4 ,8,4,3,2,5,8,4,7,5,1,6,6,6,2,1,4,5,7,1,5,3,2,4,2,1,2,3,6,7,5,6,6,4,4,5,3,5 ,7,8,4,4,1,2,7,8,1,5,3,4,3,4,2,2,5,3,6]) #Different scenarios in a list ## 0: Relative Default: Equal factors on initial wealth ## 1: Absolute Default: Equal income added to initial wealth ## 2: Advantage Rich: Higher factors and income for rich. ## 3: Advantage Poor: Higher income and factors for poor. ## 4: Intermediate: Higher factors for poor, higher income for rich. decision_type_arr = ["RelativeDefault", "AbsoluteDefault", "AdvantageRich", "AdvantagePoor", "Intermediate", "EqualWealth"] #decision_type_arr = ["RelativeDefault", "AbsoluteDefault", "AdvantageRich", "AdvantagePoor", "Intermediate", "EqualWealth", "RelativeDefaultHigh", "AbsoluteDefaultHigh"] #p1_initial_wealth_arr = np.array(6*[3.5]) #p1_initial_wealth_arr = np.array(8*[3.5]) #p1_income_arr = np.array([3.5,2.5,4.5,0.5,3.0,1.5]) #p1_income_arr = np.array([3.5,2.5,4.5,0.5,3.0,1.5, 7.0, 5.0]) #p1_income_arr = np.array(5*[7.0]) #p1_final_wealth_arr = p1_initial_wealth_arr + p1_income_arr #p1_factor_arr = np.array([round(p1_final_wealth_arr[i]/p1_initial_wealth_arr[i], 2) for i in [0,1,2,3,4,5]]) #p2_initial_wealth_arr = np.array(6*[1.5]) #p2_initial_wealth_arr = np.array(8*[1.5]) #p2_income_arr = np.array([1.5,2.5,0.5,4.5,2.0, 3.5]) #p2_income_arr = np.array([1.5,2.5,0.5,4.5,2.0, 3.5, 3.0, 5.0]) #p2_income_arr = np.array(5*[5.0]) #p2_final_wealth_arr = p2_initial_wealth_arr + p2_income_arr #p2_factor_arr = np.array([round(p2_final_wealth_arr[i]/p2_initial_wealth_arr[i], 2) for i in [0,1,2,3,4,5]]) additional_sum_arr = np.array([3., 3., 5., 5., 5., 4., 3., 5., 3., 5., 3., 4., 4., 4., 5., 4., 4., 4., 3., 4., 4., 3., 4., 3., 4., 3., 4., 3., 3., 4., 3., 3., 3., 4., 3., 3., 3., 4., 3., 4., 5., 4., 5., 3., 3., 4., 3., 4., 3., 4., 5., 3., 3., 3., 3., 4., 5., 4., 5., 3., 5., 3., 4., 4., 3., 4., 3., 4., 5., 3., 5., 5., 4., 4., 3., 4., 4., 3., 5., 3., 3., 5., 3., 4., 3., 3., 5., 3., 5., 3., 5., 3., 5., 4., 5., 5., 3., 5., 3., 3., 5., 4., 4., 3., 3., 5., 3., 3., 3., 3., 4., 5., 3., 4., 4., 4., 5., 5., 3., 5., 5., 5., 4., 4., 5., 5., 5., 3., 4., 5., 3., 3., 4., 4., 5., 3., 5., 5., 3., 3., 5., 3., 4., 5., 5., 5., 3., 5., 4., 4., 4., 4., 4., 3., 4., 5., 3., 4., 5., 3., 4., 5., 3., 5., 4., 4., 4., 5., 4., 4., 5., 4., 5., 4., 3., 5., 4., 4., 4., 5., 4., 5., 4., 3., 3., 4., 4., 3., 4., 3., 5., 3., 5., 3., 4., 5., 4., 5., 3., 5., 3., 5., 4., 5., 5., 5., 3., 4., 4., 5., 4., 4., 3., 4., 5., 3., 5., 5., 4., 5., 3., 3., 5., 5., 3., 4., 5., 3., 3., 5., 5., 5., 3., 5., 4., 3., 3., 3., 3., 4., 5., 5., 4., 4., 4., 4., 4., 5., 3., 5., 4., 5., 3., 5., 4., 3., 3., 5., 4., 3., 3., 5., 5., 4., 5., 3., 4., 3., 5., 4., 3., 4., 3., 3., 5., 5., 3., 3., 3., 3., 4., 5., 4., 4., 3., 4., 5., 5., 5., 4., 4., 4., 5., 4., 5., 4., 3., 3., 5., 5., 4., 4., 3., 4., 5., 4., 4., 3., 4., 3., 3., 4., 3., 5., 3., 5., 5., 5., 5., 5., 5., 4., 5., 3., 3., 5., 5., 3., 5., 3., 5., 4., 5., 4., 4., 5., 4., 5., 5., 5., 3., 5., 3., 4., 5., 5., 4., 3., 3., 3., 5., 4., 4., 3., 4., 5., 4., 3., 3., 5., 4., 4., 3., 5., 3., 4., 5., 3., 3., 5., 5., 5., 5., 4., 4., 5., 5., 4., 4., 4., 3., 4., 3., 4., 3., 5., 4., 4., 5., 4., 4., 3., 4., 4., 3., 3., 5., 4., 3., 3., 5., 4., 5., 3., 4., 3., 4., 5., 3., 3., 5., 3., 3., 4., 4., 3., 4., 4., 3., 4., 4., 4., 4., 4., 5., 5., 5., 4., 4., 3., 5., 5., 5., 5., 5., 4., 3., 3., 4., 4., 3., 4., 3., 5., 3., 4., 5., 3., 3., 3., 4., 5., 3., 4., 4., 3., 5., 5., 4., 3., 5., 5., 4., 5., 4., 4., 3., 5., 5., 5., 3., 4., 5., 4., 4., 3., 3., 5., 3., 3., 5., 4., 3., 3., 4., 4., 3., 5., 5., 3., 5., 4., 4., 3., 3., 3., 3., 5., 3., 5., 5., 4., 3., 5., 5., 5., 4., 4., 4., 4., 5., 5., 3., 4., 4., 4., 5., 5., 4., 3., 4., 3., 5., 5., 4., 4., 5., 4., 3., 3., 3., 3., 3., 5., 5., 4., 3., 3., 3., 5., 5., 3., 5., 3., 4., 4., 3., 4., 5., 5., 3., 4., 5., 3., 3., 5., 4., 4., 5., 4., 5., 3., 5., 4., 3., 5., 5., 5., 5., 3., 4., 5., 4., 4., 5., 4., 5., 3., 3., 3., 4., 5., 3., 3., 3., 3., 5., 5., 4., 5., 5., 5., 5., 3., 4., 4., 3., 5., 4., 3.]) p1_prize_arr = np.array([3. , 3. , 4. , 3. , 3.5, 3.5, 4. , 4. , 4. , 4. , 3. , 4. , 4. , 3.5, 4. , 4. , 4. , 3.5, 3. , 3. , 4. , 4. , 3.5, 3. , 3. , 4. , 4. , 3. , 3.5, 4. , 4. , 3.5, 4. , 4. , 4. , 3. , 3.5, 3.5, 4. , 4. , 4. , 4. , 4. , 4. , 4. , 3. , 4. , 3. , 3.5, 3. , 3.5, 3.5, 4. , 3.5, 3.5, 3. , 4. , 4. , 3.5, 3. , 3. , 4. , 3.5, 3. , 3.5, 3. , 3.5, 3.5, 3. , 3. , 3.5, 4. , 4. , 3. , 3.5, 3.5, 3. , 4. , 3.5, 4. , 3.5, 4. , 4. , 3.5, 3. , 3. , 3.5, 4. , 3.5, 4. , 3.5, 3.5, 3. , 3. , 3.5, 3. , 3.5, 3.5, 3. , 3.5, 3. , 3.5, 3.5, 3.5, 4. , 3. , 4. , 4. , 3.5, 3.5, 3. , 3.5, 3.5, 4. , 4. , 3.5, 4. , 3. , 4. , 3.5, 3.5, 3.5, 3.5, 4. , 3. , 3. , 4. , 4. , 3. , 3. , 3. , 3.5, 3. , 3.5, 4. , 3.5, 3. , 3. , 3. , 3. , 4. , 3.5, 3. , 3.5, 3. , 4. , 3.5, 3.5, 3. , 4. , 4. , 4. , 4. , 3. , 3.5, 4. , 4. , 3.5, 4. , 3.5, 3.5, 4. , 3.5, 3. , 4. , 3. , 3. , 3.5, 3. , 3. , 3.5, 4. , 3. , 4. , 4. , 3. , 3.5, 3. , 3. , 3.5, 3. , 3.5, 4. , 3. , 3.5, 3. , 3.5, 3. , 3.5, 3.5, 3.5, 3.5, 3.5, 3. , 3. , 3. , 3.5, 3.5, 3.5, 3. , 3.5, 3.5, 4. , 4. , 4. , 3. , 3. , 4. , 3.5, 3.5, 4. , 3.5, 3.5, 4. , 3.5, 3.5, 3. , 3. , 3.5, 4. , 3.5, 3.5, 3.5, 3. , 3. , 3. , 3.5, 3.5, 4. , 3.5, 3. , 4. , 3. , 3. , 4. , 3. , 3.5, 3.5, 3. , 4. , 3. , 3.5, 3. , 3. , 3.5, 3.5, 3.5, 4. , 3. , 4. , 3.5, 3.5, 3. , 4. , 3. , 3. , 3.5, 3.5, 3.5, 4. , 3.5, 4. , 4. , 3. , 3.5, 3. , 4. , 4. , 3. , 3.5, 4. , 3. , 3. , 4. , 3. , 3.5, 3. , 3.5, 3.5, 4. , 3.5, 3.5, 3.5, 3.5, 4. , 3. , 3.5, 4. , 4. , 3.5, 3.5, 4. , 3. , 4. , 3. , 3. , 4. , 3.5, 4. , 3.5, 3. , 3. , 3. , 3. , 4. , 3. , 4. , 3. , 3. , 4. , 4. , 4. , 3.5, 3.5, 3. , 4. , 3.5, 3.5, 3. , 4. , 4. , 3.5, 4. , 3. , 4. , 3. , 3. , 4. , 4. , 3. , 3.5, 4. , 4. , 3. , 3. , 4. , 4. , 4. , 3.5, 4. , 3.5, 4. , 4. , 3.5, 3. , 4. , 4. , 3. , 3. , 4. , 3. , 3. , 3. , 4. , 4. , 3. , 4. , 4. , 3. , 4. , 4. , 3. , 3. , 4. , 4. , 3. , 3.5, 3. , 3.5, 3. , 3. , 3. , 3.5, 3.5, 3.5, 4. , 4. , 3.5, 4. , 4. , 4. , 3.5, 3. , 4. , 3.5, 3.5, 4. , 3.5, 4. , 3.5, 3.5, 4. , 3.5, 4. , 3.5, 3.5, 3. , 3. , 3. , 3.5, 4. , 4. , 3. , 4. , 4. , 3.5, 3.5, 3. , 3. , 3. , 3. , 4. , 3.5, 4. , 3. , 4. , 3.5, 4. , 4. , 3. , 3.5, 3. , 4. , 4. , 4. , 3. , 3.5, 4. , 3.5, 3. , 4. , 3.5, 3.5, 3. , 4. , 3. , 3. , 4. , 3.5, 3.5, 3. , 3. , 3.5, 3.5, 3.5, 3. , 3. , 4. , 3.5, 3. , 3. , 3.5, 3.5, 4. , 4. , 4. , 3. , 3. , 3. , 3. , 4. , 3.5, 4. , 3. , 4. , 3. , 3.5, 3.5, 3. , 4. , 4. , 4. , 4. , 3. , 3.5, 3.5, 3. , 4. , 3. , 3.5, 3. , 3.5, 3.5, 3. , 3.5, 3. , 3.5, 4. , 4. , 4. , 3. , 3. , 4. , 4. , 3. , 4. , 4. , 3.5, 3. , 4. , 3. , 4. , 3.5, 3.5, 3. , 4. , 3. , 4. , 3.5, 3. , 3.5, 3.5, 4. , 4. , 3. , 3.5, 3.5, 3.5, 3. , 4. , 3.5, 3.5, 3. , 3. , 4. , 3. , 3. , 3. , 3.5, 3.5, 4. , 3.5, 4. , 4. , 3.5, 3. , 4. , 3. , 3. , 3. , 3.5, 3.5, 3.5, 3. , 3. , 3. , 4. , 4. , 4. , 4. , 3.5, 4. , 3. , 4. , 3. , 3. , 4. , 3. , 3. , 3.5, 3.5, 3.5, 3. , 3. , 3. , 3. , 3. , 4. , 3.5, 3.5, 4. , 3. , 4. , 3.5, 3.5, 4. , 4. , 3. , 4. , 3.5, 3.5, 3. , 3.5, 3. , 3.5, 3. , 4. , 4. , 3.5, 3.5, 3. , 4. , 3.5, 3.5, 3.5, 3. , 3. , 3. , 4. , 4. ]) four_decision_type_arr = ["RelativeDefault, AbsoluteDefault, EqualWealth, AdvantageRich", "RelativeDefault, AbsoluteDefault, EqualWealth, AdvantagePoor", "RelativeDefault, AbsoluteDefault, EqualWealth, Intermediate", "RelativeDefault, AbsoluteDefault, AdvantagePoor, AdvantageRich", "RelativeDefault, AbsoluteDefault, Intermediate, AdvantageRich", "RelativeDefault, AbsoluteDefault, Intermediate, AdvantagePoor"] def absolute_default_proposition(prize_1, prize_2, additional_sum): proposed_income_1 = additional_sum / 2 proposed_income_2 = additional_sum / 2 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def relative_default_proposition(prize_1, prize_2, additional_sum): proposed_income_1 = ((prize_1)/(prize_1 + prize_2))*additional_sum proposed_income_2 = additional_sum - proposed_income_1 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def advantage_rich_proposition(prize_1, prize_2, additional_sum): proposed_income_1 = ((1/3)*(prize_1)/(prize_1 + prize_2)+(2/3)*1)*additional_sum proposed_income_2 = additional_sum - proposed_income_1 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def advantage_poor_proposition(prize_1, prize_2, additional_sum): proposed_income_1 = ((1/7)*(prize_1)/(prize_1 + prize_2)+(6/7)*0)*additional_sum proposed_income_2 = additional_sum - proposed_income_1 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def intermediate_proposition(prize_1, prize_2, additional_sum): if prize_1 != 3: proposed_income_1 = (3/5)*additional_sum proposed_income_2 = additional_sum - proposed_income_1 else: proposed_income_1 = (3/5-0.05)*additional_sum proposed_income_2 = additional_sum - proposed_income_1 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def equal_wealth_proposition(prize_1, prize_2, additional_sum): proposed_income_1 = 0.5*(additional_sum + prize_2 - prize_1) proposed_income_2 = additional_sum - proposed_income_1 return np.round(proposed_income_1, 2), np.round(proposed_income_2, 2) def proposition(prize_1, prize_2, additional_sum, decision_type): if decision_type == "AbsoluteDefault": return absolute_default_proposition(prize_1, prize_2, additional_sum) if decision_type == "RelativeDefault": return relative_default_proposition(prize_1, prize_2, additional_sum) if decision_type == "AdvantageRich": return advantage_rich_proposition(prize_1, prize_2, additional_sum) if decision_type == "AdvantagePoor": return advantage_poor_proposition(prize_1, prize_2, additional_sum) if decision_type == "Intermediate": return intermediate_proposition(prize_1, prize_2, additional_sum) if decision_type == "EqualWealth": return equal_wealth_proposition(prize_1, prize_2, additional_sum) class Page(oTreePage): def get_progress(self): totpages = self.participant._max_page_index curpage = self.participant._index_in_pages return f"{curpage / totpages * 100:.0f}" class Welcome(Page): form_model = 'player' form_fields = ['name', 'email', 'iban', 'bic'] def is_displayed(self): return (self.player.round_number == 1) def error_message(self, values): ###IBAN VALIDIERUNG BEGINNT HIER valid_codes = ["AL", "AT", "BE", "BG", "CH", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR", "GB", "GR", "HR", "HU", "IE", "IS", "IT", "LI", "LT", "LU", "LV", "MC", "MT", "NL", "NO", "PL", "PT", "RO", "SE", "SI", "SK", "SM"] len_dict = {"AT": 20, "EE": 20, "LT": 20, "LU": 20, "BE": 16, "BG": 22, "DE": 22, "GB": 22, "IE": 22, "CH": 21, "HR": 21, "LI": 21, "LV": 21, "CY": 28, "HU": 28, "PL": 28, "CZ": 24, "ES": 24, "RO": 24, "SE": 24, "SK": 24, "DK": 18, "FI": 18, "NL": 18, "FR": 27, "GR": 27, "IT": 27, "MC": 27, "SM": 27, "IS": 26, "MT": 31, "NO": 15, "PT": 25, "SI": 19, "AL": 28} LETTERS = {ord(d): str(i) for i, d in enumerate(string.digits + string.ascii_uppercase)} iban = values["iban"] IBAN = iban.upper() IBAN = IBAN.replace(" ", "") c1 = False c2 = False c3 = False c4 = False country = IBAN[0:2] c1 = country in valid_codes if c1: c2 = len_dict[country] == len(IBAN) if c1 and c2: temp = IBAN[:2] + '00' + IBAN[4:] number_iban = (temp[4:] + temp[:4]).translate(LETTERS) check_digits = '{:0>2}'.format(98 - (int(number_iban) % 97)) c3 = check_digits == IBAN[2:4] if c1 and c2 and c3: _number_iban = (IBAN[4:] + IBAN[:4]).translate(LETTERS) c4 = int(_number_iban) % 97 == 1 if not (c1 and c2 and c3 and c4): return "Die von Ihnen angegebene IBAN ist nicht gültig. Bitte überprüfen Sie Ihre Eingabe." #check no small letters in iban for c in values["iban"]: if c.islower(): return "Die von Ihnen angegebene IBAN enthält Kleinbuchstaben." ###IBAN VALIDIERUNG ENDET HIER #check basic @ structure in email if(re.match("[^@]+@[^@]+\.[^@]+", values["email"]) == None): return "Die von Ihnen eingegebene E-Mail-Adresse ist ungültig." #check no spaces in email address if (' ' in values["email"]) == True: return "Die von Ihnen eingegebene E-Mail-Adresse enthält Leerzeichen." #valide BIC code if(re.match('([a-zA-Z]{4}[a-zA-Z]{2}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)', values["bic"]) == None): return "Der von Ihnen eingegebene BIC-Code ist ungültig." def before_next_page(self): #EDIT THIS SO WELCOME PAGE IN LATER ROUNDS BECOMES OBSOLETE #SET ALL VARIABLES FOR ALL ROUNDS IN THE FIRST ROUND p = self.player for r in [1,2,3,4,5,6,7,8,9]: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['iban'] = p.iban indices = [0,1,2,3,4,5,6,7,8] decision_indices = [0,1,2,3,4,5] random.shuffle(indices) random.shuffle(decision_indices) realized_bool = bool(np.random.binomial(n=1, p=0.2)) if realized_bool is True: realized_stage = random.randint(1, len(decision_type_arr)) else: realized_stage = -1 self.participant.vars['realized_bool'] = realized_bool self.participant.vars['realized_stage'] = realized_stage prize_1_array = np.array([3.0, 3.0, 3.0, 3.5, 3.5, 3.5, 4.0, 4.0, 4.0,]) add_sum_array = np.array([4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0]) decision_array = ["RelativeDefault, AbsoluteDefault, EqualWealth, AdvantageRich", "RelativeDefault, AbsoluteDefault, EqualWealth, AdvantagePoor", "RelativeDefault, AbsoluteDefault, EqualWealth, Intermediate", "RelativeDefault, AbsoluteDefault, AdvantagePoor, AdvantageRich", "RelativeDefault, AbsoluteDefault, Intermediate, AdvantageRich", "RelativeDefault, AbsoluteDefault, Intermediate, AdvantagePoor"] random.shuffle(decision_array) random.shuffle(prize_1_array) random.shuffle(add_sum_array) for r in [1,2,3,4,5,6,7,8,9]: #assign treatments if p.id_in_group % 2 == 0: p.in_round(r).treatment = "Relative" if p.id_in_group % 2 == 1: p.in_round(r).treatment = "Absolute" index = indices[r-1] if 2