from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import itertools from random import shuffle # author = 'Dan Way' doc = """ Cost Reporting Task """ class Constants(BaseConstants): name_in_url = 'cost_reporting_ss' players_per_group = 2 num_rounds = 5 class Subsession(BaseSubsession): # Group by time but make sure to get Mgr A and Mgr B separated so roles don't get flip-flopped def group_by_arrival_time_method(self, waiting_players): # Don't need to restrict by condition because I won't be running conditions at the same time mgrs_A = [p for p in waiting_players if p.participant.vars['type'] == 1] mgrs_B = [p for p in waiting_players if p.participant.vars['type'] == 2] num_waiting_A = len(mgrs_A) num_waiting_B = len(mgrs_B) if num_waiting_A > 0 and num_waiting_B > 0: #As long as one Mgr A and one Mgr B waiting, see if we can form a group... i = 0 while i < num_waiting_A: mgr_match_A = mgrs_A[i] # Take the first waiting mgr A mgr_partners_A = [p.partner_id for p in mgr_match_A.in_previous_rounds()] # Get all their previous partners j = 0 # Start with the first waiter who is not the 'source' matcher while j < num_waiting_B: # While there are Mgr Bs left to check mgr_potential_partner = mgrs_B[j].participant_id # The first potential new partner # Compare source matcher's previous partners with first potential partner to see if they can match k = 0 match_count = 0 while k < len(mgr_partners_A): # To loop through previous partners if mgr_partners_A[k] == mgr_potential_partner or mgr_potential_partner == mgr_match_A.participant_id: # See if previous partner id matches first potential match match_count += 1 # If so flag it k += 1 if match_count == 0: # If we got all the way through without finding they had previously matched... return [mgrs_A[i], mgrs_B[j]] # Match them! j += 1 i += 1 # Move on to the next waiter to see if they can find a match else: return [mgrs_A[0], mgrs_B[0]] class Group(BaseGroup): pass class Player(BasePlayer): def role(self): if self.type == 1: return 'Manager A' else: return 'Manager B' firm_id = models.IntegerField() #For data prep for employees/owners condition = models.IntegerField() type = models.IntegerField() partner_id = models.IntegerField() def get_partner(self): return self.get_others_in_group()[0] def chat_channel(self): return '1-' + str(self.group_id) actual_A = models.IntegerField() actual_B = models.IntegerField() report_A = models.IntegerField(initial=None, choices=[(20000, '20,000'), (25000, '25,000'), (30000, '30,000'), (35000, '35,000'), (40000, '40,000'), (45000, '45,000'), (50000, '50,000'), (55000, '55,000'), (60000, '60,000'), (65000, '65,000'), (70000, '70,000'), (75000, '75,000'), (80000, '80,000'), (85000, '85,000'), (90000, '90,000'), (95000, '95,000'), (100000, '100,000')], verbose_name='') report_B = models.IntegerField(initial=None, choices=[(20000, '20,000'), (25000, '25,000'), (30000, '30,000'), (35000, '35,000'), (40000, '40,000'), (45000, '45,000'), (50000, '50,000'), (55000, '55,000'), (60000, '60,000'), (65000, '65,000'), (70000, '70,000'), (75000, '75,000'), (80000, '80,000'), (85000, '85,000'), (90000, '90,000'), (95000, '95,000'), (100000, '100,000')], verbose_name='') report_A_partner = models.IntegerField() report_B_partner = models.IntegerField() slack_A = models.IntegerField() slack_B = models.IntegerField() slack_dol_A = models.DecimalField(max_digits=3, decimal_places=2) slack_dol_B = models.DecimalField(max_digits=3, decimal_places=2) audit_flag_A = models.IntegerField() audit_flag_B = models.IntegerField() bust_A = models.IntegerField() bust_A_partner = models.IntegerField() bust_B = models.IntegerField() bust_B_partner = models.IntegerField() chat_time = models.CharField() lira = models.IntegerField() potential_comp = models.DecimalField(max_digits=4, decimal_places=2) lira_partner = models.IntegerField() potential_comp_partner = models.DecimalField(max_digits=4, decimal_places=2) worker_id = models.CharField(initial='e')