<jupyter_start><jupyter_text>Resolviendo las situacionesBien, ahora que ya sabemos como calcular [probabilidades](https://es.wikipedia.org/wiki/Probabilidad), llegó finalmente el momento de ponerse a resolver las situaciones planteadas en el comienzo, para eso vamos a utilizar nuevamente un poco de [Python](https://www.python.org/).  La coincidencia de cumpleañosLa [paradoja del cumpleaños](https://es.wikipedia.org/wiki/Paradoja_del_cumplea%C3%B1os) es un problema muy conocido en el campo de la [teoría de probabilidad](https://es.wikipedia.org/wiki/Teor%C3%ADa_de_la_probabilidad).Plantea las siguientes interesantes preguntas: ¿Cuál es la [probabilidad](https://es.wikipedia.org/wiki/Probabilidad) de que, en un grupo de personas elegidas al azar, al menos dos de ellas habrán nacido el mismo día del año? ¿Cuántas personas son necesarias para asegurar una probabilidad mayor al 50%?. Excluyendo el 29 de febrero de nuestros cálculos y asumiendo que los restantes 365 días de posibles cumpleaños son igualmente probables, nos sorprendería darnos cuenta de que, en un grupo de sólo 23 personas, la [probabilidad](https://es.wikipedia.org/wiki/Probabilidad) de que dos personas compartan la misma fecha de cumpleaños es mayor al 50%!.El truco para resolver el problema no es enfrentarse a el en primera persona si no plantear que ¿cuál es la probabilidad de que en un grupo de n personas al menos 2 cumplan años el mismo día? e infinitamente más sencillo es calcular la probabilidad opuesta ¿qué probabilidad hay de no acertar?. Especialmente si simplificamos el problema a un grupo muy pequeño. Supongamos que  el grupo sólo tiene una persona, en ese caso, hay una probabilidad del 100% que esta persona no comparte un cumpleaños puesto que no hay nadie más quien compartir. Pero ahora podemos añadir una segunda persona al grupo. ¿Cuáles son las posibilidades de que tenga un cumpleaños diferente de esa persona? De hecho esto es bastante fácil, hay 364 otros días en el año, así que las posibilidades son 364/365. ¿Qué tal si agregamos una tercera persona al grupo? Ahora hay 363/365 días. Para obtener la [probabilidad](https://es.wikipedia.org/wiki/Probabilidad) general de que no hay cumpleaños compartidos simplemente multiplicamos las probabilidades individuales. Si utilizamos este procedimiento, con la ayuda de [Python](https://www.python.org/) podemos calcular fácilmente las [probabilidades](https://es.wikipedia.org/wiki/Probabilidad) de un cumpleaños compartido en un grupo de 50 personas.<jupyter_code># Ejemplo situación 2 La coincidencia de cumpleaños
prob = 1.0
asistentes = 50

for i in range(asistentes):
    prob = prob * (365-i)/365

print(f"Probabilidad de que compartan una misma fecha de cumpleaños es {round(1-prob, 3)}")<jupyter_output>Probabilidad de que compartan una misma fecha de cumpleaños es 0.97<jupyter_text>Resolviendo la situación 2 - ¿Que puerta elegir?Este problema, más conocido con el nombre de [Monty Hall](https://es.wikipedia.org/wiki/Problema_de_Monty_Hall), también es un problema muy popular dentro de la [teoría de probabilidad](https://es.wikipedia.org/wiki/Teor%C3%ADa_de_la_probabilidad); y se destaca por su solución que a simple vista parece totalmente anti-intuitiva.Intuitivamente, es bastante sencillo que nuestra elección original (cuando hay tres puertas para elegir) tiene una [probabilidad](https://es.wikipedia.org/wiki/Probabilidad) de 1/3 de ganar el concurso. Las cosas sin embargo se complican, cuando se descarta una puerta. Muchos dirían que ahora tenemos una [probabilidad](https://es.wikipedia.org/wiki/Probabilidad) de 1/2 de ganar, seleccionando cualquiera de las dos puertas; pero este no es el caso. Un aspecto crítico del problema es darse cuenta de que la elección de la puerta a descartar por el presentador, no es una decisión al azar. El presentador puede descartar una puerta porque él sabe (a) qué puerta hemos seleccionado y (b) qué puerta tiene la ferrari. De hecho, en muchos casos, el presentador debe quitar una puerta específica. Por ejemplo, si seleccionamos la puerta 1 y el premio está detrás de la puerta 3, el presentador no tiene otra opción que retirar la puerta 2. Es decir, que la elección de la puerta a descartar está condicionada tanto por la puerta con el premio como por la puerta que seleccionamos inicialmente. Este hecho, cambia totalmente la naturaleza del juego, y hace que las [probabilidades](https://es.wikipedia.org/wiki/Probabilidad) de ganar sean 2/3 si cambiamos de puerta!.Si aun no están convencidos, simulemos los resultados del concurso con la ayuda de [Python](https://www.python.org/).<jupyter_code>import numpy as np
def elegir_puerta():
    """
    Función para elegir una puerta. Devuelve 1, 2, o 3 en forma aleatoria.
    """
    return np.random.randint(1,4)


class MontyHall:
    """
    Clase para modelar el problema de Monty Hall.
    """
    def __init__(self):
        """
        Crea la instancia del problema. 
        """
        # Elige una puerta en forma aleatoria.
        self.puerta_ganadora = elegir_puerta()
        # variables para la puerta elegida y la puerta descartada
        self.puerta_elegida = None
        self.puerta_descartada = None
 
    def selecciona_puerta(self):
        """
        Selecciona la puerta del concursante en forma aleatoria.
        """
        self.puerta_elegida = elegir_puerta()
 
    def descarta_puerta(self):
        """
        Con este método el presentador descarta una de la puertas.
        """
        # elegir puerta en forma aleatoria .
        d = elegir_puerta()
        # Si es al puerta ganadora o la del concursante, volver a elegir.
        while d == self.puerta_ganadora or d == self.puerta_elegida:
            d = elegir_puerta()
        # Asignar el valor a puerta_descartada.
        self.puerta_descartada = d
 
    def cambiar_puerta(self):
        """
        Cambia la puerta del concursante una vez que se elimino una puerta.
        """
        # 1+2+3=6. Solo existe una puerta para elegir.
        self.puerta_elegida = 6 - self.puerta_elegida - self.puerta_descartada
 
    def gana_concursante(self):
        """
        Determina si el concursante gana. 
        Devuelve True si gana, False si pierde.
        """
        return self.puerta_elegida == self.puerta_ganadora
            
 
    def jugar(self, cambiar=True):
        """
        Una vez que la clase se inicio, jugar el concurso.
 
        'cambiar' determina si el concursante cambia su elección.
        """
        # El concursante elige una puerta.
        self.selecciona_puerta()
        # El presentador elimina una puerta.
        self.descarta_puerta()
        # El concursante cambia su elección.
        if cambiar:
            self.cambiar_puerta()
        # Determinar si el concursante ha ganado.
        return self.gana_concursante()
# Ahora, jugamos el concurso. primero nos vamos a quedar con nuestra elección
# inicial. Vamos a ejecutar el experimiento 10.000 veces.
gana, pierde = 0, 0
for i in range(10000):
    # Crear la instancia del problema.
    s2 = MontyHall()
    # ejecutar el concurso sin cambiar de puerta..
    if s2.jugar(cambiar=False):
        # si devuelve True significa que gana.
        gana += 1
    else:
        # si devuelve False significa que pierde.
        pierde += 1

# veamos la fecuencia de victorias del concursante.
porc_gana = 100.0 * gana / (gana + pierde)
 
print("\n10.000 concursos sin cambiar de puerta:")
print("  gana: {0:} concursos".format(gana))
print("  pierde: {0:} concursos".format(pierde))
print("  probabilidad: {0:.2f} procentaje de victorias".format(porc_gana))
# Ahora, jugamos el concurso siempre cambiando la elección inicial
# Vamos a ejecutar el experimiento 10.000 veces.
gana, pierde = 0, 0
for i in range(10000):
    # Crear la instancia del problema.
    s2 = MontyHall()
    # ejecutar el concurso con cambiar de puerta..
    if s2.jugar(cambiar=True):
        # si devuelve True significa que gana.
        gana += 1
    else:
        # si devuelve False significa que pierde.
        pierde += 1

# veamos la fecuencia de victorias del concursante.
porc_gana = 100.0 * gana / (gana + pierde)
 
print("\n10.000 concursos cambiando de puerta:")
print("\t gana: {0:} concursos".format(gana))
print("  pierde: {0:} concursos".format(pierde))
print("  probabilidad: {0:.2f} procentaje de victorias".format(porc_gana))<jupyter_output>10.000 concursos cambiando de puerta:
	 gana: 6678 concursos
  pierde: 3322 concursos
  probabilidad: 66.78 procentaje de victorias
{'fraction_non_alphanumeric': 0.07432590855803048, 'fraction_numerical': 0.01723329425556858, 'mean_word_length': 3.554725040042712, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 15, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '344450', 'license': 'MIT', 'n_tokens_mistral': 2901, 'n_tokens_neox': 2747, 'n_words': 1018, 'path': 'Precurso/03_Matematicas_estadistica_Git/Ejercicios-explicativos-estadistica.ipynb', 'repo_name': 'Lawlesscodelen/Bootcamp-Data-', 'size': '8530'}