from otree.api import (
models,
widgets,
BaseConstants,
BaseSubsession,
BaseGroup,
BasePlayer,
Currency as c,
currency_range,
)
import random
from random import randint, shuffle
from itertools import cycle
author = 'José Miguel Bustamante Limón'
doc = """
El experimento se divide en dos partes: el primer periodo de recolección de datos personales así como
presentar las preguntas controversiales del proyecto. Se recaba la información de tal manera de definir sólo una
pregunta controversial. El segundo periodo es una interacción grupal secuencial para medir en qué casos
encontramos ignorancia pluralista
"""
class Constants(BaseConstants):
name_in_url = 'temas_controversiales'
players_per_group = None
num_rounds= 4
question_choices = {
'tabaco': ['De acuerdo', 'En desacuerdo'],
'arte': ['Sí tiene el mismo virtuosismo', 'No tiene el mismo virtuosismo'],
'violencia': ['De acuerdo', 'En desacuerdo'],
'pobreza': ['Crisis climática', 'La pobreza extrema']
}
question_labels = {
'tabaco': '¿Estás de acuerdo con la nueva ley antitabaco en México?',
'arte': '¿El arte que se exhibe en los museos de arte contemporáneo ya no tiene el mismo virtuosismo que el arte en los museos clásicos?',
'violencia': '¿Estás de acuerdo con la frase: no hay paz sin la violencia?',
'pobreza': '¿Qué es más importante, afrontar la crisis climática o terminar la pobreza extrema en México?',
}
questions_order = ['tabaco', 'arte', 'violencia', 'pobreza']
class Subsession(BaseSubsession):
def get_players_by_option(self, question):
players_option1 = [p for p in self.get_players() if getattr(p.in_round(1), question) == Constants.question_choices[question][0]]
players_option2 = [p for p in self.get_players() if getattr(p.in_round(1), question) == Constants.question_choices[question][1]]
return players_option1, players_option2
def regroup_players(self):
question = Constants.questions_order[self.round_number - 1]
players_option1, players_option2 = self.get_players_by_option(question)
question_text = Constants.question_labels[question]
question_options = Constants.question_choices[question]
players_option1_copy = players_option1.copy() # Crear copia de players_option1
players_option2_copy = players_option2.copy() # Crear copia de players_option2
groups = []
methods = cycle(['method1', 'method2'])
while len(players_option1_copy) >= 7 and len(players_option2_copy) >= 7:
method = next(methods)
if method == 'method1':
chosen_population = players_option1_copy[:7] + players_option2_copy[:3]
group_players = random.sample(chosen_population, 3)
groups.append(group_players)
for p in group_players:
p.population_text = f"""Bienvenido a la segunda parte del experimento. Gracias por la espera, reunimos la información de todas las respuestas de los participantes. Para esta sección te hemos colocado en un grupo con otras dos personas (Tu grupo es {p.group.id_in_subsession}). Van a tomar turnos para responder la siguiente pregunta en frente de los demás: ({question_text}). A cada uno le asignamos un número que representa el orden en el que responderán a la pregunta, el tuyo es el {p.id_in_group}.
Creamos el grupo a partir de una población de 10 personas. De estas 10, 7 eligeron "{question_options[0]}" y 3 eligeron "{question_options[1]}" a la pregunta: {question_text}. Escogimos a cada uno de los integrantes aleatoriamente."""
p.question = question_text
p.save()
elif method == 'method2':
if random.random() < 0.5: # escoge el subgrupo aleatoriamente
chosen_population = players_option1_copy[:7] + players_option2_copy[:3]
else:
chosen_population = players_option1_copy[:3] + players_option2_copy[:7]
group_players = random.sample(chosen_population[:10], 3)
groups.append(group_players)
for p in group_players:
p.population_text = f"""Bienvenido a la segunda parte del experimento. Gracias por la espera, reunimos la información de todas las respuestas de los participantes. Para esta sección te hemos colocado en un grupo con otras dos personas (Tu grupo es {p.group.id_in_subsession}). Van a tomar turnos para responder la siguiente pregunta en frente de los demás: ({question_text}). A cada uno le asignamos un número que representa el orden en el que responderán a la pregunta, el tuyo es el {p.id_in_group}.
Creamos el grupo tras seleccionar aleatoriamente a una de las dos poblaciones disponibles, cada una con 10 personas, para el presente experimento. La primera población, con una probabilidad del 50%, donde 7 de las personas eligeron "{question_options[0]}" y 3 eligeron "{question_options[1]}" a la pregunta: {question_text}. La segunda población, con una probabilidad del 50%, donde 3 de las personas eligeron "{question_options[0]}" y 7 eligeron "{question_options[1]}" a la pregunta: {question_text}. Escogimos a cada uno de los integrantes aleatoriamente."""
p.question = question_text
p.save()
for p in group_players:
if p in players_option1_copy:
players_option1.remove(p)
if p in players_option2_copy:
players_option2.remove(p)
# Create groups for remaining players
remaining_players = players_option1_copy + players_option2_copy
shuffle(remaining_players)
remaining_groups = [remaining_players[i:i + 3] for i in range(0, len(remaining_players), 3)]
remaining_groups = [group for group in remaining_groups if len(group) == 3]
groups.extend(remaining_groups)
for group in remaining_groups:
for p in group:
p.population_text = f"""Bienvenido a la segunda parte del experimento. Gracias por la espera, reunimos la información de todas las respuestas de los participantes. Para esta sección te hemos colocado en un grupo con otras dos personas (Tu grupo es {p.group.id_in_subsession}). Van a tomar turnos para responder la siguiente pregunta en frente de los demás: ({question_text}). A cada uno le asignamos un número que representa el orden en el que responderán a la pregunta, el tuyo es el {p.id_in_group}."""
p.question = question_text
p.save()
# Pass the ids to set_group_matrix instead of the player objects
groups_ids = [[p.id_in_subsession for p in group if p.id_in_subsession <= self.player_set.count()] for group in groups]
# Antes de llamar a set_group_matrix
players_in_subsession = [p.id_in_subsession for p in self.get_players()]
# Filtrar groups_ids para incluir solo los jugadores que todavía están en la subsesión
filtered_groups_ids = [[id for id in group if id in players_in_subsession] for group in groups_ids]
# Luego llama a set_group_matrix con los IDs filtrados, si no está vacío
if filtered_groups_ids:
super().set_group_matrix(filtered_groups_ids)
def get_population(self, question, option1_count, option2_count):
players_option1, players_option2 = self.get_players_by_option(question)
return players_option1[:option1_count] + players_option2[:option2_count]
class Group(BaseGroup):
current_question_key = models.StringField()
current_question_index = models.IntegerField()
current_question = models.StringField()
group_text = models.StringField()
def set_current_question(self):
self.current_question_key = Constants.questions_order[self.round_number - 1]
self.current_question = Constants.question_labels[self.current_question_key]
self.save()
class Player(BasePlayer):
age = models.IntegerField(label="Edad:")
gender = models.StringField(
choices=[('Femenino', 'Femenino'), ('Masculino', 'Masculino'), ('Otros', 'Otros')],
label="Sexo:",
widget=widgets.RadioSelect,
)
other_gender = models.StringField(blank=True, label="Por favor, especifica:")
career = models.StringField(
choices=['Licenciatura en Economía', 'Licenciatura en Ciencia Política y Relaciones Internacionales', 'Licenciatura en Derecho'],
label="¿En qué licenciatura estás?",
widget=widgets.RadioSelect,
)
level = models.StringField(
choices=['Segundo', 'Cuarto', 'Sexto', 'Octavo'],
label="¿Qué semestre cursas?",
widget=widgets.RadioSelect,
)
race = models.StringField(
choices=[('Mestiza/o', 'Mestiza/o'), ('Indígena', 'Indígena'), ('Caucásico', 'Caucásico'), ('Afrodescendiente', 'Afrodescendiente'), ('Asiática/o', 'Asiática/o'), ('Árabe', 'Árabe'), ('Otros', 'Otros')],
label="¿Cómo te identificas racialmente?",
widget=widgets.RadioSelect,
)
other_race = models.StringField(blank=True, label="Por favor, especifica:")
income = models.StringField(
choices=['Menos de $4,999', '$4,500 - $7,499', '$7,500 - $11,499', '$11,500 - $14,499', '$15,000 - $18,499', '$18,500 o más'],
label="¿Cuál es tu ingreso mensual aproximado?",
widget=widgets.RadioSelect,
)
tabaco = models.StringField(
choices=['De acuerdo', 'En desacuerdo'],
label="¿Estás de acuerdo con la nueva ley antitabaco en México?",
widget=widgets.RadioSelect,
)
arte = models.StringField(
choices=['Sí tiene el mismo virtuosismo', 'No tiene el mismo virtuosismo'],
label="¿El arte que se exhibe en los museos de arte contemporáneo ya no tiene el mismo virtuosismo que el arte en los museos clásicos?",
widget=widgets.RadioSelect,
)
violencia = models.StringField(
choices=['De acuerdo', 'En desacuerdo'],
label="¿Estás de acuerdo con la frase: no hay paz sin la violencia?",
widget=widgets.RadioSelect,
)
pobreza = models.StringField(
choices=['Crisis climática', 'La pobreza extrema'],
label="¿Qué es más importante, afrontar la crisis climática o terminar la pobreza extrema en México?",
widget=widgets.RadioSelect,
)
belief_p1 = models.LongStringField(
label="Con base en la interacción que tuviste con tu grupo, ¿Cuál crees que es la opinión verdadera de la persona 1?",
)
belief_p2 = models.LongStringField(
label="Con base en la interacción que tuviste con tu grupo, ¿Cuál crees que es la opinión verdadera de la persona 2?",
)
belief_p3 = models.LongStringField(
label="Con base en la interacción que tuviste con tu grupo, ¿Cuál crees que es la opinión verdadera de la persona 3?",
)
question = models.StringField()
role_id = models.IntegerField()
population_text = models.StringField()