from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import config_collat import id_gen import random import ast import time debug = True author = "CSN/IFREE REU 2019 oTree Team" doc = """ Full Collateral Game """ class Constants(BaseConstants): """ Description: Inherits oTree Class BaseConstants. Defines constants for the experiment these will remain unchanged Input: uuid - (ID generating package) config_collat - (Dictionary of treatment parameters) Output: None """ name_in_url = 'Instructions&Quiz' # name in webbrowser list_of_treatments = config_collat.parameters.keys() randomized_treatment = list(list_of_treatments)[0] treatment = randomized_treatment # randomized_treatment dic_of_treatment_parameters = config_collat.parameters[treatment] timer = int(dic_of_treatment_parameters['quiz_timeout']) contract_enforcement = eval(dic_of_treatment_parameters['contract_enforcement']) players_per_group = int(dic_of_treatment_parameters["players_per_group"]) num_rounds = int(dic_of_treatment_parameters["num_rounds"]) initial_points = c(dic_of_treatment_parameters["initial_points "]) recovery_fee = c(dic_of_treatment_parameters["recovery_fee"]) productivity = int(dic_of_treatment_parameters["productivity"]) contract_enforcement = eval(dic_of_treatment_parameters["contract_enforcement"]) rate_of_return = float(dic_of_treatment_parameters["rate_of_return"]) instructions_payoff = c(int(dic_of_treatment_parameters["instructions_payoff"])) practice_information_score_sheet = 'Instructions_Quiz/Information_Score_Sheet_Practice.html' '''Quiz Answers''' quiz_fields = dict( question_1_response=True, question_2_response=1, question_3_response=1, question_4_response=4, question_6_response=3, ) quiz_answers = [True, 'The borrower offers collateral, the lender offers a loan, the borrower accepts the loan agreement', '0-10', '3'] if contract_enforcement == False: quiz_fields['question_5_response'] = 2 quiz_answers.append('The lender') quiz_answers.append( 'The lender can recover additional points up to the full collateral amount minus the recovery fee') else: quiz_fields['question_5_response'] = 1 quiz_answers.append('The computer') quiz_answers.append('The computer can recover additional points up to the full collateral amount minus the recovery fee') q2_choices = [ [1, 'The borrower offers collateral, the lender offers a loan, the borrower accepts the loan agreement'], [2, 'The borrower offers collateral, the lender accepts the loan agreement'], [3, 'The lender requests collateral from the borrower, the lender offers a loan, the borrower accepts the loan agreement'], [4, 'The borrower offers collateral, the lender offers a loan, the lender accepts the loan agreement'], ] q3_choices = [ [1, '0-10'], [2, '1-10'], [3, '1-5'], [4, '5-10'], ] q4_choices = [ [1, '1.5'], [2, '2'], [3, '2.5'], [4, '3'], ] q5_choices = [ [1, 'The computer'], [2, 'The lender'], [3, 'The borrower'], ] if contract_enforcement == False and recovery_fee > 0: q6_choices = [ [1, 'The lender recovers the full collateral amount.'], [2, 'The lender can recover additional points from the borrower’s project return'], [3, 'The lender can recover additional points up to the full collateral amount minus the recovery fee'], [4, 'The lender cannot recover any additional points'] ] elif contract_enforcement == False and recovery_fee == 0: q6_choices = [ [1, 'The lender recovers the full collateral amount.'], [2, 'The lender can recover additional points from the borrower’s project return'], [3, 'The lender can recover additional points up to the full collateral amount'], [4, 'The lender cannot recover any additional points.'] ] elif contract_enforcement == True and recovery_fee > 0: q6_choices = [ [1, 'The computer recovers the full collateral amount.'], [2, 'The computer can recover additional points from the borrower’s project return'], [3, 'The computer can recover additional points up to the full collateral amount minus the recovery fee'], [4, 'The computer cannot recover any additional points.'] ] elif contract_enforcement == True and recovery_fee == 0: q6_choices = [ [1, 'The computer recovers the full collateral amount.'], [2, 'The computer can recover additional points from the borrower’s project return'], [3, 'The computer can recover additional points up to the full collateral amount'], [4, 'The computer cannot recover any additional points.'] ] random.SystemRandom().shuffle(q2_choices) random.SystemRandom().shuffle(q3_choices) random.SystemRandom().shuffle(q4_choices) random.SystemRandom().shuffle(q5_choices) random.SystemRandom().shuffle(q6_choices) class Subsession(BaseSubsession): """ Description: Inherits oTree Class BaseSubsession. Defines subsession for the experiment. Input: None Output: None """ class Group(BaseGroup): """ Description: Inherits BaseGroup oTree class. Assigns group characteristics. Input: None Output: None """ # this is here so we can grab its field name treatment = models.CharField(initial=Constants.treatment) treatment_recovery_fee = models.CurrencyField(initial=Constants.recovery_fee) treatment_contract_enforcement = models.BooleanField(initial=Constants.contract_enforcement) accept_loan = models.BooleanField() group_id = models.CharField(initial=id_gen.id_gen()) class Player(BasePlayer): """ Description: Inherits oTree class BasePlayer. Defines player characteristics. Input: None Output: None """ time_spent_on_instructions = models.FloatField(initial=-time.time()) def current_field(self): return 'question_{}_response'.format(self.quiz_page_counter+1) def role(self): """ Description: Inherits oTree class BasePlayer. Defines player characteristics. Input: Player - (Player Location) Output: Player Role """ if self.id_in_group == 1: self.participant.vars['role'] = 'lender' return 'lender' if self.id_in_group == 2: self.participant.vars['role'] = 'borrower' return 'borrower' print('this is your participant variable', self.participant.vars['role']) '''Empty variables for the instruction examples that will be defined in the creating_session method above.''' prac_collateral = models.IntegerField(initial=None) prac_collateral_input = models.IntegerField( verbose_name='Enter a collateral offer:', initial=None) quiz_incorrect_answer = models.StringField(initial=None) prac_loan_offer = models.IntegerField(initial=None) prac_loan_offer_input = models.IntegerField(verbose_name='Enter a loan offer:', initial=None) prac_borrower_money = models.CurrencyField(initial=Constants.initial_points ) prac_lender_money = models.CurrencyField(initial=Constants.initial_points ) prac_lender_dollar_value = models.CharField() prac_borrower_dollar_value = models.CharField() prac_requested_repayment = models.CurrencyField() prac_project_return = models.CurrencyField() prac_returned_collateral = models.CurrencyField() prac_loan_package_decision = models.CharField(verbose_name='Do you accept the loan agreement?', choices=['Yes', 'No'], widget=widgets.RadioSelect ) prac_repayment = models.IntegerField(initial=None) prac_repayment_input = models.IntegerField( verbose_name='Enter the amount you would like to repay:', initial=None) prac_project_return = models.IntegerField(initial=None) prac_collateral_decision = models.CharField(verbose_name='Are you satisfied with the repayment?', choices=['Yes', 'No'], widget=widgets.RadioSelect ) prac_collateral_after_cost = models.IntegerField(initial=None) prac_recovered_collateral = models.IntegerField(initial=None) prac_recovered_collateral_input = models.IntegerField( verbose_name='Enter the amount of collateral you would like to recover:', initial=None) current_practice_page = models.IntegerField(initial=0) '''Quiz''' # Counter of the questions answered correctly on the first try num_correct = models.IntegerField(initial=0) quiz_page_counter = models.IntegerField(initial=0) q_incorrect_attempts = models.IntegerField(initial=0) q_timeout = models.IntegerField(initial=0) q_validation = models.IntegerField(initial=0) q_attempts = models.IntegerField(initial=0) error_sequence = models.CharField(initial='') timeout_sequence = models.CharField(initial='') question_1_response = models.BooleanField(verbose_name='', widget=widgets.RadioSelect, choices=[ [True, 'True'], [False, 'False'], ]) question_2_response = models.IntegerField(verbose_name='', widget=widgets.RadioSelect, choices=Constants.q2_choices) question_3_response = models.IntegerField(verbose_name='', widget=widgets.RadioSelect, choices=Constants.q3_choices) question_4_response = models.IntegerField(verbose_name='', widget=widgets.RadioSelect, choices=Constants.q4_choices) question_5_response = models.IntegerField(verbose_name='', widget=widgets.RadioSelect, choices=Constants.q5_choices) question_6_response = models.IntegerField(verbose_name='', widget=widgets.RadioSelect, choices=Constants.q6_choices) quiz_earnings = models.CurrencyField(initial=0) '''