# -*- coding: utf-8 -*- from __future__ import division from . import models from ._builtin import Page, WaitPage #from otree.common import Currency as c, currency_range from .models import Constants from otree.common import safe_json import math from random import randint from django.utils.translation import ugettext as _ def vars_for_all_templates(self): if self.subsession.round_number == 1: t_min = -Constants.num_rounds+1 t_max = 3 t_min_small = -1 t_max_small = 16 # t_max = min(Constants.num_rounds, self.subsession.round_number+3) # t_min = max(-2, self.subsession.round_number-10-2) data = { 't_min': t_min, 't_max': t_max, 't_min_small': t_min_small, 't_max_small': t_max_small, 'now': self.subsession.round_number, 'tomorrow': self.subsession.round_number + 1, 'now_ind': self.subsession.round_number+Constants.num_rounds-1, 'tomorrow_ind': self.subsession.round_number +Constants.num_rounds, 'yesterday': self.subsession.round_number - 1, 'in2days': self.subsession.round_number + 2, 'end_hor': self.subsession.round_number + 1, 'horizon': self.subsession.horizon, } return data if self.subsession.round_number >= 2: player_in_all_rounds = self.player.in_all_rounds() # temp = range(0, self.subsession.round_number) # temp = reversed(temp) # temp2 = range(Constants.num_rounds+1,self.subsession.round_number) # temp2 = reversed(temp2) # temp3 = range(0,Constants.num_rounds+1) # temp3 = reversed(temp3) # t_max = min(Constants.num_rounds, self.subsession.round_number+3) # t_min = max(-2, self.subsession.round_number-10-2) t_max = self.subsession.round_number + 2 t_min = self.subsession.round_number-Constants.num_rounds t_min_small = max(-1, self.subsession.round_number - 8) t_max_small = max(self.subsession.round_number + 8, 16) data = { 'player_in_all_rounds': player_in_all_rounds, 'number_rounds': Constants.num_rounds, 'init_1': Constants.num_rounds + 1, 'init': Constants.num_rounds, 't_max': t_max, 't_min': t_min, 't_min_small': t_min_small, 't_max_small': t_max_small, 'now': self.subsession.round_number , 'yesterday': self.subsession.round_number - 1, 'in2days': self.subsession.round_number + 2, 'tomorrow': self.subsession.round_number + 1, 'now_ind': self.subsession.round_number + Constants.num_rounds-1, 'tomorrow_ind': self.subsession.round_number + Constants.num_rounds, # 'scrollswitch':Constants.scroll_switch_period } return data ############# class ForecastDecision(Page): form_model = 'player' def get_form_fields(self): return ['nowcast', 'forecast'] def before_next_page(self): if self.timeout_happened: self.player.forecast = 0 if self.subsession.round_number == 1: self.player.nowcast = 0 else: self.player.nowcast = self.player.in_previous_rounds()[-1].forecast self.player.set_payoffs() # when to show it: when round <= nb of total rounds def is_displayed(self): return self.subsession.round_number <= Constants.num_rounds # var specifically for this page def vars_for_template(self): self.group.model() # return a dictionary called data to be displayed in html, to create vectors based on time series # I think we should display in the table and the graphs the quarterly data, not the yearly ones # the horizon should come somewhere at some point player_in_all_rounds = self.player.in_all_rounds() temps = range(1, self.subsession.round_number) # list from 0 to t-1 #temps = reversed(temps) # list from t-1 to 0 # adjust the axis of the two plots y_x_default_min = -145 y_x_default_max = 145 y_TS = [] x1_TS = [] x2_TS = [] expected_y_TS = [None] * (self.subsession.round_number+Constants.num_rounds-1) past_exp_y_TS = [None] * (Constants.num_rounds ) for j in range(0,Constants.num_rounds ): y_TS.append(self.session.vars['y_init'][j]) x1_TS.append(self.session.vars['x1_init'][j] ) x2_TS.append(self.session.vars['x2_init'][j] ) if self.subsession.round_number > 1: # self because player are a parent of page, collect each data series for r in self.player.in_previous_rounds(): # paid_forcasts_TS.append(r.paid_forc) y_TS.append(r.group.y) x1_TS.append(r.group.x1) x2_TS.append(r.group.x2) if r.FE_selected ==1: if r.forecast_lag == 1000: past_exp_y_TS.append(None) else: past_exp_y_TS.append(r.forecast_lag ) else: if r.nowcast == 1000: past_exp_y_TS.append(None) else: past_exp_y_TS.append(r.nowcast) if self.player.in_previous_rounds()[-1].forecast== 1000: past_exp_y_TS.append(None) else: past_exp_y_TS.append(self.player.in_previous_rounds()[-1].forecast) x1_TS.append(self.group.x1) x2_TS.append(self.group.x2) # cumpayoff_lag1=round(self.player.in_previous_rounds()[-1].cum_score_y) # if self.subsession.round_number > 2: # score=round(self.player.in_previous_rounds()[-1].score) # FE=round(self.player.in_previous_rounds()[-1].abs_FE,2) # vint = round(self.player.in_previous_rounds()[-1].group.random_vintage) # else: # vint = None # score=None # FE=None # rescale the plot (above are the defaults value), it only rescales for realizations past_exp_no_none=[x for x in past_exp_y_TS if x is not None] if len(past_exp_no_none)<1: y_x_min = min(min(x for x in x1_TS if x is not None), min(x for x in x2_TS if x is not None), min(x for x in y_TS if x is not None), y_x_default_min) y_x_max = max(max(x for x in x1_TS if x is not None), max(x for x in x2_TS if x is not None), max(x for x in y_TS if x is not None), y_x_default_max) else: if len(past_exp_no_none) < 2: minpast=past_exp_no_none[0] maxpast = past_exp_no_none[0] else: minpast = min(past_exp_no_none) maxpast = max(past_exp_no_none) y_x_min = min(min(x for x in x1_TS if x is not None), min(x for x in x2_TS if x is not None), min(x for x in y_TS if x is not None), minpast, y_x_default_min) y_x_max = max(max(x for x in x1_TS if x is not None), max(x for x in x2_TS if x is not None), max(x for x in y_TS if x is not None), maxpast, y_x_default_max) # we first take the min of all three variables plotted on the output plot y_y_min = y_x_min y_y_max = y_x_max data = { 'player_in_all_rounds': player_in_all_rounds, 'temp_A': temps, # 'realized_y': int(self.player.in_previous_rounds()[-1].group.y), # 'y_payoff': payoff_TS, # 'vintage': vint, # 'score': score, # 'FE': FE, # 'cumulated_payoff_lag1': cumpayoff_lag1, 'y_y_min': y_y_min, 'y_y_max': y_y_max, 'y_x_min': y_x_min, 'y_x_max': y_x_max, 'tot_rounds': Constants.num_rounds, # 'prde1': round(self.session.vars['debt'][self.subsession.round_number] * 100, 2), # 'prde2': round(self.session.vars['debt'][self.subsession.round_number + 1] * 100, 2), #'prde3': round(self.session.vars['debt'][self.subsession.round_number + 2] * 100, 2), } initt=None initt_show= (y_y_max//50+1)*50-15 if self.subsession.round_number > 1: data['prev_nowc'] = self.player.in_previous_rounds()[-1].nowcast data['prev_forc'] = self.player.in_previous_rounds()[-1].forecast data['prev_forc_round'] = round(self.player.in_previous_rounds()[-1].forecast) data['init_forc_round'] = initt data['cum_score']= self.player.in_previous_rounds()[-1].cum_score_y else: data['prev_nowc'] = initt data['prev_forc'] = initt data['prev_forc_round'] = initt data['init_forc_round'] = initt data['cum_score'] =0 # if self.subsession.round_number > 1: # expected_y_TS += [self.player.in_previous_rounds()[-1].forecast,initt] # else: expected_y_TS += [initt, initt] data['y_TS'] = safe_json(y_TS) data['exp_y_TS'] = safe_json(expected_y_TS) data['past_exp_y_TS'] = safe_json(past_exp_y_TS) data['x1_TS'] = safe_json(x1_TS) data['x2_TS'] = safe_json(x2_TS) return data # class pre(Page): # def before_next_page(self): # self.group.model() # # class NormalWaitPage(WaitPage): # title_text = "Custom title text" # body_text = "Custom body text" # after_all_players_arrive = 'model' # # class NormalWaitPage2(WaitPage): # title_text = "Custom title text" # body_text = "Custom body text" # after_all_players_arrive = 'set_payoffs' # define here the welcome page (first page) class Welcome(Page): template_name = 'LtF/Welcome.html' # says when it is displayed: here only if period 1 (it takes time if there is a lot of pages to skip) def is_displayed(self): return self.subsession.round_number == 1 # here you define your password def psw1_error_message(self, value): if value != 'go': return 'The password is wrong' # define here the instructions/questions page (third page) # class InstructionsQuestions(Page): # # template_name = 'LtF/InstructionsQuestions.html' # form_model = 'player' # form_fields = ['answer1', 'answer2', 'answer3', 'answer4', 'answer5'] # # # says when it is displayed: here only if period 1 (it takes time if there is a lot of pages to skip) # def is_displayed(self): # return self.subsession.round_number == 1 # # #def vars_for_template(self): # # answer1 = '2' # # answer2 = '9' # # answer3 = 'Yes' # # answer4 = 'Output decreases.' # # answer5 = 'No, thank you.' # # # return{ # # 'answer1': answer1, # # 'answer2': answer2, # # 'answer3': answer3, # # 'answer4': answer4, # # 'answer5': answer5, # # } # # # here check your answers # def answer1_error_message(self,value): # if value != 2: # float, integer, char, char, char # #if value != ['2','9','Yes','Output decreases','No, thank you.']: # float, integer, char, char, char # return 'Stupid subject! Your answer is wrong!' # # def answer2_error_message(self,value): # if value != 9: # float, integer, char, char, char # #if value != ['2','9','Yes','Output decreases','No, thank you.']: # float, integer, char, char, char # return 'Stupid subject! Your answer is wrong!' # # def answer3_error_message(self, value): # if value != 'Yes': # float, integer, char, char, char # # if value != ['2','9','Yes','Output decreases','No, thank you.']: # float, integer, char, char, char # return 'Stupid subject! Your answer is wrong!' # # def answer4_error_message(self, value): # if value != 'Output decreases': # float, integer, char, char, char # # if value != ['2','9','Yes','Output decreases','No, thank you.']: # float, integer, char, char, char # return 'Stupid subject! Your answer is wrong!' # # def answer5_error_message(self, value): # if value != 'No, thank you.': # float, integer, char, char, char # # if value != ['2','9','Yes','Output decreases','No, thank you.']: # float, integer, char, char, char # return 'Stupid subject! Your answer is wrong!' class Questionnaire(Page): # all the questions and possible answers are defined in the models.py file form_model = 'player' form_fields = ['q_age', 'q_gender', 'q_study', 'q_experience', 'question1', 'comment'] def is_displayed(self): return self.subsession.round_number == Constants.num_rounds # def before_next_page(self): # # self.player.set_payoff() # for p in self.group.get_players(): # p.set_payoffs() class consent(Page): def is_displayed(self): return self.subsession.round_number == 1 class Instructions(Page): def is_displayed(self): return self.subsession.round_number == 1 class End(Page): def vars_for_template(self): self.player.set_fin_payoff() cum_score_ne = self.player.score_NE cum_score_fe = self.player.score_FE for r in self.player.in_previous_rounds(): cum_score_ne += r.score_NE cum_score_fe += r.score_FE if self.participant.payoff>0: failnow=0 failfor=0 failboth=0 else: failnow=1 failfor=1 failboth=1 if cum_score_ne > 450: failboth=0 failnow=0 if cum_score_fe > 450 / 60 * 59: failboth=0 failfor=0 bon=float(self.participant.payoff) bon=bon/100 data = {'points': round(self.player.cum_score_y, 2), 'bonus': round(bon, 2), 'failnow': failnow, 'failfor': failfor, 'failboth': failboth, } # 'payment': c(round(self.participant.payoff, 1)), # 'payment2': c(round(self.player.real_cum_score_y, 1)), return data def is_displayed(self): return self.subsession.round_number == Constants.num_rounds # we make several pages and we define here in the sequence each player goes through page_sequence = [ consent, Instructions, # Welcome, # password thing # Instructions, # InstructionQuestion, # StartExperiment, # NormalWaitPage, #pre, ForecastDecision, # NormalWaitPage2, # ResultsWaitPage, # waiting for the others to play, once all players arrive there, the payoff function of # models.py page computes all the variables from the model # PaymentPage, # Questionnaire, # ask for specific questions, strategies, etc. about the experiment Questionnaire, End ]