from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants, Player, Group import random import config_collat as cc from practice_game import Practice_Game debug = True """docstring format Method Description: Input: Output: Class Description: Input: Output: """ """Instructions Pages""" lender_pg = Practice_Game() lender_pg.environment({'productivity':Constants.productivity, 'endowment': Constants.initial_points , 'recovery_fee': Constants.recovery_fee, 'contract_enforcement': Constants.contract_enforcement, 'rate_of_return':Constants.rate_of_return}) borrower_pg = Practice_Game() borrower_pg.environment({'productivity':Constants.productivity, 'endowment': Constants.initial_points , 'recovery_fee': Constants.recovery_fee, 'contract_enforcement': Constants.contract_enforcement, 'rate_of_return':Constants.rate_of_return}) pg_vars = [lender_pg, borrower_pg] for p in pg_vars: productivity = p.fetch('productivity') endowment = p.fetch('endowment') recovery_fee = p.fetch('recovery_fee') contract_enforcement = p.fetch('contract_enforcement') p.add('collateral', random.SystemRandom().randrange(1, 11, 2)) p.add('loan', random.SystemRandom().randrange(1, 11, 2)) p.add('project_return', p.fetch('loan') * productivity) p.add('requested_repayment', int(p.fetch('rate_of_return') * p.fetch('loan'))) if contract_enforcement == False: p.add('repay', random.SystemRandom().randrange(1, p.fetch('project_return') + 1, 2)) p.add('collateral_after_cost', max(0, p.fetch('collateral') - recovery_fee)) if p.fetch('collateral_after_cost') > 0: p.add('collateral_recovered', (random.SystemRandom().randrange(1, p.fetch('collateral_after_cost')+ 1, 2))) else: p.add('collateral_recovered', 0) if contract_enforcement == True: p.add('repay', random.SystemRandom().randrange(1, p.fetch('requested_repayment') + 1, 2)) p.add('collateral_after_cost', max(0, p.fetch('collateral') - recovery_fee)) if p.fetch('repay') + p.fetch('collateral_after_cost') <= p.fetch('requested_repayment'): p.add('collateral_recovered', p.fetch('collateral_after_cost')) else: p.add('collateral_recovered', p.fetch('requested_repayment') - p.fetch('repay')) p.add('collateral_returned', max(0, p.fetch('collateral') - p.fetch('collateral_recovered') - recovery_fee)) p.add('total_lender', endowment - p.fetch('loan') + p.fetch('repay') + p.fetch('collateral_recovered')) p.add('total_borrower', endowment - p.fetch('collateral') + p.fetch('project_return') - p.fetch('repay') + p.fetch('collateral_returned')) class NotMobilePlayers(WaitPage): group_by_arrival_time = True class WelcomePage(Page): def before_next_page(self): self.player.role() if self.player.role() == 'lender': self.player_borrower_money -= lender_pg.fetch('collateral') self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) def is_displayed(self): if self.participant.vars['is_mobile'] is False: return True else: return False class PracCollateralOffer(Page): form_model = 'player' form_fields = ['practice_input'] def practice_input_error_message(self, value): '''returns an error message if the player inputs the wrong value''' if value != borrower_pg.fetch('collateral'): return 'Enter a collateral offer of ' + str(pg.fetch('collateral')) + ' to continue.' def before_next_page(self): self.player.current_practice_page += 1 self.player.prac_borrower_money -= borrower_pg.fetch('collateral') self.player.prac_lender_money -= borrower_pg.fetch('loan') self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) def is_displayed(self): if self.player.role() == 'borrower' and self.participant.vars['is_mobile'] is False: return True else: return False class PracLoanPackageDecision(Page): form_model = 'player' form_fields = ['practice_input'] def before_next_page(self): self.player.current_practice_page += 1 self.player.prac_borrower_money += borrower_pg.fetch('project_return') self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) def practice_input_error_message(self, value): '''returns an error message if the player inputs the wrong value''' if value != 'Yes': return 'Accept the loan package to continue' def is_displayed(self): if self.player.role() == 'borrower' and self.participant.vars['is_mobile'] is False: return True else: return False class PracReturnRealization(Page): form_model = 'player' form_fields = ['practice_input'] def before_next_page(self): self.player.current_practice_page += 1 self.player.prac_borrower_money -= borrower_pg.fetch('repay') self.player.prac_borrower_money += borrower_pg.fetch('collateral_returned') self.player.prac_lender_money += borrower_pg.fetch('repay') self.player.prac_lender_money += borrower_pg.fetch('collateral_recovered') self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) def practice_input_error_message(self, value): if value != borrower_pg.fetch('repay'): return 'Enter a return of ' + str(borrower_pg.fetch('repay')) + ' to continue.' def is_displayed(self): if self.player.role() == 'borrower' and self.participant.vars['is_mobile'] is False: return True else: return False class PracLoanOffer(Page): form_model = 'player' form_fields = ['practice_input'] def before_next_page(self): self.player.current_practice_page += 1 self.player.prac_borrower_money += lender_pg.fetch('project_return') self.player.prac_borrower_money -= lender_pg.fetch('repay') self.player.prac_lender_money += lender_pg.fetch('repay') self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) def practice_input_error_message(self, value): '''returns an error message if the player inputs the wrong value''' if value != lender_pg.fetch('loan'): return 'Enter a loan offer of ' + str(lender_pg.fetch('loan')) + ' to continue.' def is_displayed(self): if self.player.role() == 'lender' and self.participant.vars['is_mobile'] is False: return True else: return False class PracCollateralDecision(Page): if Constants.contract_enforcement == False: form_model = 'player' form_fields = ['practice_input'] def before_next_page(self): self.player.current_practice_page += 1 def practice_input_error_message(self, value): if value != 'No': return 'Select yes to continue.' def is_displayed(self): if self.player.role() == 'lender' and self.participant.vars['is_mobile'] is False: return True else: return False class PracCollateralSeizure(Page): if Constants.contract_enforcement is False: form_model = 'player' form_fields = ['practice_input'] def practice_input_error_message(self, value): if value != lender_pg.fetch('collateral_returned'): return 'Select ' + str(self.player.prac_collateral_seizure_amount) + ' to continue.' def before_next_page(self): self.player.current_practice_page += 1 self.player.prac_borrower_money += lender_pg.fetch('collateral_returned') self.player.prac_lender_money += lender_pg.fetch('collateral_recovered') self.player.prac_lender_dollar_value = str(self.player.prac_lender_money.to_real_world_currency(self.session)) self.player.prac_borrower_dollar_value = str(self.player.prac_borrower_money.to_real_world_currency(self.session)) def is_displayed(self): if self.player.role() == 'lender' and self.participant.vars['is_mobile'] is False: return True else: return False class PracResults(Page): def is_displayed(self): if self.participant.vars['is_mobile'] is False: return True else: return False # DYNAMIC QUIZ WITH TIMEOUTS page_sequence = [ NotMobilePlayers, WelcomePage, PracCollateralOffer, PracLoanOffer, PracLoanPackageDecision, PracReturnRealization, PracCollateralDecision, PracCollateralSeizure, PracResults, ]