from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import math doc = """ Cудья и истец """ class Constants(BaseConstants): name_in_url = 'pi' players_per_group = 2 num_rounds = 2 instructions_template = 'pi/instructions.html' TotalResult_template = 'pi/AdminReport.html' # Initial amount allocated to each player class Subsession(BaseSubsession): def creating_session(self): self.group_randomly(fixed_id_in_group=True) if self.round_number % 2 == 1: pl_matrix = self.get_group_matrix() for row in pl_matrix: row.reverse() self.set_group_matrix(pl_matrix) def get_active_players(self): return [p for p in self.get_players() if p.is_alive()] def do_my_shuffle(self): newlist = [p for p in self.get_players() if p.is_alive()] leftlist = [p for p in self.get_players() if not p.is_alive()] pcount = len(newlist) num_to_add = Constants.players_per_group - pcount % Constants.players_per_group if num_to_add < Constants.players_per_group: newlist += leftlist[:num_to_add] leftlist = leftlist[num_to_add:] pcount = len(newlist) nums = random.SystemRandom().sample(range(pcount), pcount) shufflelist = [newlist[i] for i in nums]+leftlist gr_matrix = [shufflelist[i:i+Constants.players_per_group] for i in range(0, len(shufflelist), Constants.players_per_group)] self.set_group_matrix(gr_matrix) def vars_for_admin_report(self): subs_avg1 = [] subs_avg2 = [] for subs in self.in_all_rounds(): humans = subs.get_active_players() humans_1 = [p for p in humans if (p.id_in_group == 1)] humans_2 = [p for p in humans if (p.id_in_group == 2)] sum_1 = sum(p.payoff for p in humans_1) sum_2 = sum(p.payoff for p in humans_2) avg_1 = round(sum_1 / len(humans_1), 1) if humans_1 else 0.0 avg_2 = round(sum_2 / len(humans_2), 1) if humans_2 else 0.0 subs_avg1.append(avg_1) subs_avg2.append(avg_2) series = [] for player in self.get_active_players(): pl_id = player.participant.id_in_session name = player.participant.label pl_totalpay = sum(p.payoff for p in player.in_all_rounds()) p1 = [p for p in player.in_all_rounds() if (p.id_in_group == 1)] p2 = [p for p in player.in_all_rounds() if (p.id_in_group == 2)] sum_applicant = sum(p.payoff if (p.id_in_group == 1) else 0 for p in player.in_all_rounds()) sum_judge = sum(p.payoff if (p.id_in_group == 2) else 0 for p in player.in_all_rounds()) avg_applicant = round(sum_applicant / len(p1), 1) if p1 else 0.0 avg_judge = round(sum_judge / len(p2), 1) if p2 else 0.0 sum_for_p1 = sum(p.group.fnature() for p in p1) avg = round(sum_for_p1 / len(p1), 1) if p1 else 0.0 count_id_1 = sum((p.id_in_group == 1) for p in player.in_all_rounds()) count_id_2 = sum((p.id_in_group == 2) for p in player.in_all_rounds()) series.append(dict(ID=pl_id, Name=name, TotalPay=pl_totalpay,Total_Applicant=sum_applicant,Total_Judge=sum_judge,Avg_Applicant=avg_applicant,Avg_Judge=avg_judge, Avg_Applicant_damage=avg)) cnt = len(series) if cnt>0: av = dict(ID=0, Name='AVG', TotalPay=round(sum(s['TotalPay'] for s in series)/cnt, 0), Total_Applicant=round(sum(s['Total_Applicant'] for s in series)/cnt, 2), Total_Judge=round(sum(s['Total_Judge'] for s in series)/cnt, 2), Avg_Applicant=round(sum(s['Avg_Applicant'] for s in series)/cnt,2), Avg_Judge=round(sum(s['Avg_Judge'] for s in series) / cnt, 2), Avg_Applicant_damage=round(sum(s['Avg_Judge'] for s in series) / cnt, 2)) series.insert(0, av) print(series) return dict(game_data=series, period_data1=subs_avg1, period_data2=subs_avg2,round_numbers=list(range(1, len(subs_avg1) + 1))) class Group(BaseGroup): decision1 = models.StringField(widget=widgets.RadioSelect, choices=['Предъявлять', 'Не предъявлять']) #decision2 compensation = models.IntegerField(label="Назначаемая компенсация", min=0, max=99) nature = models.IntegerField(initial = None) def fnature(self): rand = random.randint(0, 99) if self.nature == None: self.nature = rand return self.nature def set_payoffs(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p2.payoff = 100 - math.fabs(self.nature - self.compensation) p1.payoff = 100 - self.nature + self.compensation class Player(BasePlayer): def is_alive(self): return not ((self.participant.label is None) or (self.participant.label == "")) def role(self): return {1: 'A', 2: 'B'}[self.id_in_group] def other_player(self): return self.get_others_in_group()[0]