# -*- coding: utf-8 -*- from __future__ import division from . import models from ._builtin import Page, WaitPage from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from .models import Constants from .models import Player from otree.common import safe_json import random import statistics def vars_for_all_templates(self): return {'total_capacity': self.session.config['total_capacity'], 'marginal_cost': self.session.config['marginal_cost'], 'max_units_per_player': self.group.max_capacity(), 'total_q': 1, 'units': self.player.units, 'number_players':len(self.group.get_players()) } class Introduction(Page): timeout_seconds = 45 def is_displayed(self): # will only display if round number equals 1 if (self.subsession.round_number == 1): template_name = 'cournot_class/Introduction.html' return True else: return False class Question1(Page): timeout_seconds = 20 def is_displayed(self): return self.subsession.round_number == 1 template_name = 'cournot_class/Question.html' form_model = Player form_fields = ['training_question_1'] def vars_for_template(self): return {'num_q': 1} def before_next_page(self): if self.timeout_happened: self.player.training_question_1 = random.randint(0, 301) class Feedback1(Page): timeout_seconds = 30 def is_displayed(self): return self.subsession.round_number == 1 template_name = 'cournot_class/Feedback.html' def vars_for_template(self): capacity_minus_cost = self.session.config['total_capacity'] - self.session.config['marginal_cost'] return { 'num_q': 1, 'training_answer':self.player.training_question_answer(), 'capacity_minus_cost': capacity_minus_cost, } class Decide(Page): timeout_seconds = 30 form_model = Player form_fields = ['units'] def units_max(self): max_unit = (self.group.max_capacity()) return max_unit def before_next_page(self): if self.timeout_happened: # if players don't respond we'll set their answers here: # production from 0 - (total_capcaity / 2) # or set answer based on Best response function: # Best response = ((total capacity - marginal cost) / 2) - ( 1 / number of other players * sum_of_other_player_units) if self.round_number != 1: print("before Best Response, I am: {}".format(self.player.id_in_group)) previous_round_units = self.player.in_round(self.round_number -1) self.player.units = self.group.best_response( previous_round_units.units) #TODO: Transform all print statements to logging, better for django; less chance of crash: See here for more info: https://simonwillison.net/2008/May/22/debugging/ (dated but still applies) print("TIMEOUT:{} Player {} played:{}".format(self.round_number, self.player.id_in_group, self.player.units)) else: self.player.units = random.randint(1,self.group.max_capacity()) print("TIMEOUT: round: {} Player:{} Played Random Number: {}".format(self.round_number, self.player.id_in_group, self.player.units)) self.participant.vars[self.round_number] = self.player.units self.session.vars["Player {}".format(self.player.id_in_group)] = self.player.units print("Player {} Played: {}".format(self.player.id_in_group, self.player.units)) return self.player.units class ResultsWaitPage(WaitPage): def after_all_players_arrive(self): #self.session.vars["Player {}".format(self.player.id_in_group)] = self.player.units self.group.set_payoffs() self.group.average_output() body_text = "Waiting for the other participant to decide." class ShuffleWaitPage(WaitPage): # wait_for_all_groups = True body_text = 'Waiting for other participants.' class Results(Page): timeout_seconds = 15 def vars_for_template(self): return {'total_plus_base': self.player.payoff + self.session.config['base_points']} class FinalResults(Page): def is_displayed(self): return self.subsession.round_number == Constants.num_rounds def vars_for_template(self): group = self.group player_data = [] player_average = [g.average_units for g in group.in_all_rounds()] player_data.append({ 'name':'Average Units Produced', 'data':player_average }) return { 'units':player_data, 'catagories': list(range(1, Constants.num_rounds, 1)) } # def vars_for_template(self): # units = [] # price = [] # total_units =[] # for round in self.player.in_all_rounds(): # units.append(round.units) # data = {} # data['series'] = list() # data['series2'] = list() # data['series'].append({'name': 'Units produced', # 'data': units}) # for round in self.group.in_all_rounds(): # price.append(round.price) # total_units.append(round.total_units) # data['series'].append({'name': 'Price', # 'data': price}) # data['series'].append({'name': 'Total units', # 'data': total_units}) # payoffs for both buyer and sellers in each round # To get data from all groups # for player in self.subsession.get_players(): # for player in self.group.get_players(): # payoffs = [] # for round in player.in_all_rounds(): # payoffs.append(round.payoff) # data['series'].append( # {'name': 'Earnings for %s' % player.role().capitalize(), # 'data': payoffs}) # data['series'] = safe_json(data['series']) # data['series2'] = safe_json(data['series2']) # return data page_sequence = [Introduction, #Question1, #Feedback1, Decide, ResultsWaitPage, ShuffleWaitPage, Results, FinalResults ]