import os import json from json import JSONDecodeError from otree.api import * import random from otree import settings ## Helper def make_boolean(blank = True, initial=False): return models.BooleanField( blank=blank, initial=initial ) def make_int(label, choices, widget=widgets.RadioSelect): return models.IntegerField( widget=widget, label=label, choices=choices ) ### EXTRA MODEL ### class NumberSequence(ExtraModel): question = models.StringField() solution = models.StringField() type = models.BooleanField() class Analogy(ExtraModel): question = models.StringField() optionA = models.StringField() optionB = models.StringField() optionC = models.StringField() optionD = models.StringField() optionE = models.StringField() solution = models.StringField() class Similarities(ExtraModel): id_p1 = models.IntegerField() id_p2 = models.IntegerField() def get_similarities(p1,p2): id_1 = p1.id id_2 = p2.id if id_1 > id_2: id_1,id_2 = id_2,id_1 sim = Similarities.filter(id_p1 = id_1 , id_p2 = id_2) if sim is None: Similarities.create( id_p1 = id_1, id_p2 = id_2, ) sim = Similarities.filter(id_p1 = id_1 , id_p2 = id_2) return sim def get_form_fields(cat): return [x['name'] for x in cat] def error_message(cat, values, min=1, max=3 ): num_selected = 0 min_answers = "eine Antwort" if min == 1 else f"{min} Antworten" max_answers = "eine Antwort" if max == 1 else f"{max} Antworten" for x in cat: if values[x['name']]: num_selected += 1 if num_selected < min: return f"Bitte wählen Sie mindestens {min_answers} aus" if num_selected >3: return f"Bitte wählen Sie höchstens {max_answers} aus" def role_assignment(subsession, SELLER, CUSTOMER): player_list = subsession.get_players() player_points = [(player.id, player.participant.total_points_test) for player in player_list] # Sort the list based on total_points_test sorted_player_points = sorted(player_points, key=lambda x: x[1]) middle = len(sorted_player_points)//2 customer_list = [] seller_list = [] for id, player in enumerate(sorted_player_points): player.role = SELLER player.customer = False if 4 <= id <= 8: player.type = 1 elif middle - 2 <= id <= middle + 2: player.type = 2 elif len(player_list)-7 <= id <= len(player_list)-3: player.type = 3 else: player.type = 0 player.role = CUSTOMER player.customer = True if player.type==0: customer_list.append(player) else: seller_list.append(player) return customer_list, seller_list def role_assignment_small(subsession,SELLER, CUSTOMER): player_list = subsession.get_players() player_points = [(player.id, player.participant.total_points_test) for player in player_list] customer_list, seller_list = [],[] # Sort the list based on total_points_test sorted_player_points = sorted(player_points, key=lambda x: x[1]) for id, player in sorted_player_points: if id <= len(player_list)//2: player.role = CUSTOMER player.type = 0 player.customer = True customer_list.append(player) else: player.role = SELLER player.type = 1 player.customer = False seller_list.append(player) return customer_list, seller_list pass def matching(customer, seller, seller_order): sorted_sellers = sorted(seller, seller_order) random.shuffle(customer) match_count = 4 matching_array = [] # Create the matching arrays for i in range(match_count): match = customer[i * 3: (i + 1) * 3] + sorted_sellers[i * 3: (i + 1) * 3] matching_array.append(match) # Todo: Falls leute nichtauftauchen (weniger Customer) hier die logikanpassen return matching_array def seller_order_swap(): mix_bottom = [0,1,2,3] mix_top = [8,9,10,11] order_mid = [7,6,5,4] random.shuffle(mix_bottom) random.shuffle(mix_top) matching_array=[] for i in range(len(mix_bottom)//2): match = [ mix_bottom[i*2], mix_bottom[i*2+1], order_mid[i] ] match_top = [ mix_top[i*2], mix_top[i*2+1], order_mid[2+i] ] matching_array.extend(match) matching_array.extend(match_top) return matching_array def generate_order_for_tasks(player, analogy_length, num_sequence_length): maximum_length = min(analogy_length, num_sequence_length) indices_seller = list(range(0, maximum_length)) ## only 37 in the num_sequence file indices_customer = list(range(0, maximum_length)) random.shuffle(indices_customer) random.shuffle(indices_seller) player.participant.social_proximity_order_customer = indices_customer player.participant.social_proximity_order_seller = indices_seller def get_cities(): with open(os.path.join(os.path.dirname(__file__), 'files/', 'staedte.txt'), 'r', encoding='utf-8') as file: cities = [line.strip() for line in file] return [(city, city) for city in cities] def get_countries(): with open(os.path.join(os.path.dirname(__file__), 'files/', 'laender.txt'), 'r', encoding='utf-8') as file: countries = [line.strip() for line in file] return [(country, country) for country in countries] def count_similarities(player,opposite): pass def avg_similarities(player, opp_group): pass ### OLD UNPERFORMANT 7ER def seven_old_generator(): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 # if Player.count_7 == solution: # return { # Player.count_7_points == 2, # print("Points",Player.count_7_points) # } return numbers, solution def load_logic_tasks(type="analogy"): path = __name__[:-7] + "/files/" + type + ".csv" typemodel = Analogy ## todo: type ändern oder analogy boolsch machen if type=='nums': typemodel = NumberSequence rows = read_csv(path, typemodel) for i, row in enumerate(rows): row['number'] = i+1 return rows def get_number_for_player(player,stage): number = player.round_number*2 - 3 + stage ## stage sollte 1 oder 2 sein if player.type: return player.participant.social_proximity_order_customer[number] return player.participant.social_proximity_order_seller[number] def check_for_correct_answer(player, game_object, response_games): try: resp = json.loads(str(response_games)) print(resp , game_object) if resp == 0: return False return resp['answer'] == game_object['solution'] except JSONDecodeError: return False def one_to_one_matching(customer, seller): random.shuffle(customer) random.shuffle(seller) matching_array = [ [s,c] for s,c in zip(seller,customer) ] return matching_array def calc_points_round(player): count7_nums = player.count7_num + player.count7_num2 + player.count7_num3 + player.count7_num4 analogy = player.analogy_answer_1 + player.analogy_answer_2 sequence = player.sequence_answer_1 + player.sequence_answer_2 ## evtl einzeln zurück geben wenn behnud das braucht TODO return count7_nums+analogy+sequence ''' Runden Stages 1 intro, personality, test aufgabe1 2 test aufgabe 2, seller customer decision 3 instruktionen, 1:1 aufgabe 4 1:1 aufgabe 5-12 Markt Interaktion 12 Fragebogen '''