from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants, Belief from django.forms import modelformset_factory from django.http import HttpResponse import vanilla import datetime import csv BeliefFormSet = modelformset_factory(Belief, fields=('value',), extra=0) class BeliefsBeforeFirstRound(Page): def is_displayed(self) -> bool: return self.round_number == 1 def vars_for_template(self) -> dict: num_other_players = len(self.group.get_players()) - 1 belief_queryset = Belief.objects.filter(player__exact=self.player) belief_formset = BeliefFormSet(queryset=belief_queryset) return { "num_other_players": num_other_players, 'belief_formset': belief_formset, 'belief_values_and_forms': zip([belief.about_player_in_group for belief in belief_queryset], belief_formset.forms), } def before_next_page(self): num_other_players = len(self.group.get_players()) - 1 submitted_data = self.form.data belief_objs_by_id = {belief.pk: belief for belief in self.player.belief_set.all()} for i in range(num_other_players): input_prefix = 'form-%d-' % i # get the inputs belief_id = int(submitted_data[input_prefix + 'id']) belief_value = int(submitted_data[input_prefix + 'value']) # lookup by ID and save submitted data bel = belief_objs_by_id[belief_id] bel.value = belief_value # important: save to DB! bel.save() class Interruption1(Page): def is_displayed(self) -> bool: return self.round_number == 11 def vars_for_template(self): prev_player = self.player.in_round(self.round_number - 1) payoff = prev_player.pgg_payoff contribution = prev_player.blue_token_contribution grp_history = [] contrib_history = [] for group in self.group.in_previous_rounds(): grp_history.append(group.pot_size) contrib_history.append(group.total_contributions / len(group.get_players())) return { 'prev_contribution': contribution, 'prev_payoff': payoff, 'group_account_history': grp_history, 'contribution_history': contrib_history, 'end_of_round_blue': grp_history[-1] } class BeliefsAfterAnnouncement(Page): def is_displayed(self) -> bool: return self.round_number == 11 def vars_for_template(self) -> dict: num_other_players = len(self.group.get_players()) - 1 belief_queryset = Belief.objects.filter(player__exact=self.player) belief_formset = BeliefFormSet(queryset=belief_queryset) return { "num_other_players": num_other_players, 'belief_formset': belief_formset, 'belief_values_and_forms': zip([belief.about_player_in_group for belief in belief_queryset], belief_formset.forms), } def before_next_page(self): num_other_players = len(self.group.get_players()) - 1 submitted_data = self.form.data belief_objs_by_id = {belief.pk: belief for belief in self.player.belief_set.all()} for i in range(num_other_players): input_prefix = 'form-%d-' % i # get the inputs belief_id = int(submitted_data[input_prefix + 'id']) belief_value = int(submitted_data[input_prefix + 'value']) # lookup by ID and save submitted data bel = belief_objs_by_id[belief_id] bel.value = belief_value # important: save to DB! bel.save() class Interruption2(Page): def is_displayed(self) -> bool: return self.round_number == 21 def vars_for_template(self) -> dict: prev_player = self.player.in_round(self.round_number - 1) payoff = prev_player.pgg_payoff contribution = prev_player.blue_token_contribution grp_history = [] contrib_history = [] for group in self.group.in_previous_rounds(): grp_history.append(group.pot_size) contrib_history.append(group.total_contributions / len(group.get_players())) return { 'prev_contribution': contribution, 'prev_payoff': payoff, 'group_account_history': grp_history, 'contribution_history': contrib_history, 'end_of_round_blue': grp_history[-1] } class BeliefsAfterChange(Page): def is_displayed(self) -> bool: return self.round_number == 21 def vars_for_template(self) -> dict: num_other_players = len(self.group.get_players()) - 1 belief_queryset = Belief.objects.filter(player__exact=self.player) belief_formset = BeliefFormSet(queryset=belief_queryset) return { "num_other_players": num_other_players, 'belief_formset': belief_formset, 'belief_values_and_forms': zip([belief.about_player_in_group for belief in belief_queryset], belief_formset.forms), } def before_next_page(self): num_other_players = len(self.group.get_players()) - 1 submitted_data = self.form.data belief_objs_by_id = {belief.pk: belief for belief in self.player.belief_set.all()} for i in range(num_other_players): input_prefix = 'form-%d-' % i # get the inputs belief_id = int(submitted_data[input_prefix + 'id']) belief_value = int(submitted_data[input_prefix + 'value']) # lookup by ID and save submitted data bel = belief_objs_by_id[belief_id] bel.value = belief_value # important: save to DB! bel.save() class Interruption3(Page): def is_displayed(self) -> bool: return self.round_number == Constants.SURE_ROUNDS def vars_for_template(self) -> dict: grp_history = [] contrib_history = [] for group in self.group.in_all_rounds(): grp_history.append(group.pot_size) contrib_history.append(group.total_contributions / len(group.get_players())) return { 'prev_contribution': self.player.blue_token_contribution, 'prev_payoff': self.player.pgg_payoff, 'group_account_history': grp_history, 'contribution_history': contrib_history, 'end_of_round_blue': grp_history[-1] } class BeliefsAfterMinRounds(Page): def is_displayed(self) -> bool: return self.round_number == Constants.SURE_ROUNDS def vars_for_template(self) -> dict: num_other_players = len(self.group.get_players()) - 1 belief_queryset = Belief.objects.filter(player__exact=self.player) belief_formset = BeliefFormSet(queryset=belief_queryset) return { "num_other_players": num_other_players, 'belief_formset': belief_formset, 'belief_values_and_forms': zip([belief.about_player_in_group for belief in belief_queryset], belief_formset.forms), } def before_next_page(self): num_other_players = len(self.group.get_players()) - 1 submitted_data = self.form.data belief_objs_by_id = {belief.pk: belief for belief in self.player.belief_set.all()} for i in range(num_other_players): input_prefix = 'form-%d-' % i # get the inputs belief_id = int(submitted_data[input_prefix + 'id']) belief_value = int(submitted_data[input_prefix + 'value']) # lookup by ID and save submitted data bel = belief_objs_by_id[belief_id] bel.value = belief_value # important: save to DB! bel.save() class WaitBeforeGameRound(WaitPage): def is_displayed(self) -> bool: return self.round_number <= self.group.num_rounds after_all_players_arrive = 'prepare_round' class GameRound(Page): form_model = 'player' form_fields = ['blue_token_contribution'] def is_displayed(self) -> bool: return self.round_number <= self.group.num_rounds def vars_for_template(self) -> dict: grp_history = [] contrib_history = [] for group in self.group.in_previous_rounds(): grp_history.append(group.pot_size) contrib_history.append(group.total_contributions / len(group.get_players())) if self.round_number > 1: prev_player = self.player.in_round(self.round_number - 1) payoff = prev_player.pgg_payoff contribution = prev_player.blue_token_contribution end_of_round_blue = grp_history[-1] else: payoff = 0 contribution = 0 end_of_round_blue = 0 return dict( prev_contribution=contribution, prev_payoff=payoff, group_account_history=grp_history, contribution_history=contrib_history, end_of_round_blue=end_of_round_blue ) class WaitAfterRound(WaitPage): def is_displayed(self) -> bool: return self.round_number <= self.group.num_rounds after_all_players_arrive = 'handle_contributions' page_sequence = [ WaitBeforeGameRound, BeliefsBeforeFirstRound, Interruption1, BeliefsAfterAnnouncement, Interruption2, BeliefsAfterChange, GameRound, WaitAfterRound, Interruption3, BeliefsAfterMinRounds ] class ExportBeliefs(vanilla.View): url_name = 'belief_export' url_pattern = '^belief_export/$' display_name = 'PGG Belief Data Export' def get(request, *args, **kwargs):# response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="{}"'.format( 'PGG Belief Data (accessed {}).csv'.format( datetime.date.today().isoformat() ) ) column_names = [ 'session_code', 'participant_code', 'player_id', 'round', 'player_in_group', 'about_player_in_group', 'value', ] rows = Belief.objects.values_list(*column_names) writer = csv.writer(response) writer.writerows([column_names]) writer.writerows(rows) return response