diff --git a/src/adivinar_numero_v2.py b/src/adivinar_numero_v2.py index 5fcca15..e0ee50b 100644 --- a/src/adivinar_numero_v2.py +++ b/src/adivinar_numero_v2.py @@ -17,21 +17,6 @@ def pausa(): limpiar_pantalla() -def mostrar_pista(numero: int, numero_oculto: int, intentos: int, frio: int, caliente: int): - """Muestra la pista basada en la diferencia entre el número y el número oculto.""" - pista = generar_pista(numero, numero_oculto, intentos) - estado_calor = evaluar_distancia(numero, numero_oculto, frio, caliente) - print(f"\n{estado_calor} {pista}") - - -def generar_pista(numero: int, numero_oculto: int, intentos: int) -> str: - """Genera un mensaje de pista indicando si el número oculto es mayor o menor.""" - if numero_oculto > numero: - return f"el número oculto es MAYOR... ¡te quedan {intentos} intentos!\n" - else: - return f"el número oculto es MENOR... ¡te quedan {intentos} intentos!\n" - - def evaluar_distancia(numero: int, numero_oculto: int, frio: int, caliente: int) -> str: """Evalúa la distancia entre el número oculto y el ingresado y devuelve el estado.""" diferencia = abs(numero_oculto - numero) @@ -44,6 +29,21 @@ def evaluar_distancia(numero: int, numero_oculto: int, frio: int, caliente: int) return "* TE QUEMAS," +def generar_pista(numero: int, numero_oculto: int, intentos: int) -> str: + """Genera un mensaje de pista indicando si el número oculto es mayor o menor.""" + if numero_oculto > numero: + return f"el número oculto es MAYOR... ¡te quedan {intentos} intentos!\n" + else: + return f"el número oculto es MENOR... ¡te quedan {intentos} intentos!\n" + + +def mostrar_pista(numero: int, numero_oculto: int, intentos: int, frio: int, caliente: int): + """Muestra la pista basada en la diferencia entre el número y el número oculto.""" + pista = generar_pista(numero, numero_oculto, intentos) + estado_calor = evaluar_distancia(numero, numero_oculto, frio, caliente) + print(f"\n{estado_calor} {pista}") + + def adivina_el_numero(numero_oculto: int, total_intentos: int, frio: int, caliente: int): """Gestiona el proceso de adivinación del número oculto.""" intentos_realizados = 0 @@ -73,50 +73,61 @@ def comprobar_numero_entero(valor: str) -> bool: def pedir_numero_usuario(mensaje: str) -> int: """Pide al usuario que introduzca un número entero, validándolo.""" - valor = input(mensaje).strip() + salir = False - while not comprobar_numero_entero(valor): - print("\n*ERROR* Ha introducido un número entero no válido!") + while not salir: valor = input(mensaje).strip() + salir = comprobar_numero_entero(valor) + + if not salir: + print("\n*ERROR* Ha introducido un número entero no válido!") return int(valor) -def genera_numero_oculto(minimo: int, maximo: int) -> int: - """Genera un número oculto aleatorio dentro de un rango.""" - return random.randint(minimo, maximo) - - def configurar_rangos_numeros() -> tuple: """Configura el rango de números válidos para el juego.""" - minimo = pedir_numero_usuario("Introduce el mínimo número posible: ") - maximo = pedir_numero_usuario("Introduce el máximo número posible: ") + salir = False - while not (minimo < maximo and (maximo - minimo) >= 100): - print("\n*ERROR* Debe haber por lo menos 100 números de diferencia entre ellos...") + while not salir: minimo = pedir_numero_usuario("Introduce el mínimo número posible: ") maximo = pedir_numero_usuario("Introduce el máximo número posible: ") + + salir = (minimo < maximo) and ((maximo - minimo) >= 100) + + if not salir: + print("\n*ERROR* Debe haber por lo menos 100 números de diferencia entre ellos...") return minimo, maximo def configurar_pistas(minimo: int, maximo: int) -> tuple: """Configura los valores de frío y caliente para las pistas.""" - frio = pedir_numero_usuario("Introduce la diferencia para mostrar la pista FRÍO, FRÍO: ") - caliente = pedir_numero_usuario("Introduce la diferencia para mostrar la pista CALIENTE, CALIENTE: ") + salir = False - while not (frio > caliente and minimo <= frio <= maximo and minimo <= caliente <= maximo): - print(f"\n*ERROR* Deben estar dentro del rango ({minimo}.{maximo}) y no ser iguales...") + while not salir: frio = pedir_numero_usuario("Introduce la diferencia para mostrar la pista FRÍO, FRÍO: ") caliente = pedir_numero_usuario("Introduce la diferencia para mostrar la pista CALIENTE, CALIENTE: ") + + salir = (frio > caliente) and (minimo <= frio <= maximo) and (minimo <= caliente <= maximo) + + if not salir: + print(f"\n*ERROR* Deben estar dentro del rango ({minimo}.{maximo}) y no ser iguales...") return frio, caliente def configurar_intentos() -> int: """Configura el número de intentos para adivinar el número oculto.""" - return pedir_numero_usuario("Introduce el número de intentos: ") + salir = False + + while not salir: + intentos = pedir_numero_usuario("Introduce el número de intentos: ") + salir = intentos > 0 + if not salir: + print("\n*ERROR* El número de intentos debe ser un entero positivo...") + return intentos def configurar_juego() -> tuple: """Configura todos los parámetros del juego: rango, pistas e intentos.""" @@ -152,6 +163,11 @@ def mostrar_menu(): print("4. Salir.\n") +def comprobar_opcion(opcion: int) -> bool: + """Comprueba si la opción elegida está en el rango permitido.""" + return 1 <= opcion <= 4 + + def elegir_opcion_menu() -> int: """Permite al usuario elegir una opción del menú.""" mostrar_menu() @@ -164,11 +180,6 @@ def elegir_opcion_menu() -> int: return opcion -def comprobar_opcion(opcion: int) -> bool: - """Comprueba si la opción elegida está en el rango permitido.""" - return 1 <= opcion <= 4 - - def jugar(numero_oculto, intentos, frio, caliente): """Gestiona el proceso de juego y muestra los resultados.""" limpiar_pantalla() @@ -183,6 +194,11 @@ def jugar(numero_oculto, intentos, frio, caliente): pausa() +def genera_numero_oculto(minimo: int, maximo: int) -> int: + """Genera un número oculto aleatorio dentro de un rango.""" + return random.randint(minimo, maximo) + + def main(): """Función principal del juego.""" limpiar_pantalla() diff --git a/src/adivinar_numero_v3.py b/src/adivinar_numero_v3.py new file mode 100644 index 0000000..88fe04d --- /dev/null +++ b/src/adivinar_numero_v3.py @@ -0,0 +1,375 @@ +import os +import random +import time + + +def limpiar_pantalla(): + """ + Limpia la consola según el sistema operativo. + + En sistemas Windows utiliza el comando 'cls', en Linux o macOS utiliza 'clear'. + """ + if os.name == 'nt': + os.system('cls') + else: + os.system('clear') + + +def pausa(): + """ + Realiza una pausa hasta que el usuario presione ENTER. + + También limpia la pantalla después de que el usuario presiona ENTER. + """ + input("\nPresione ENTER para continuar...") + input("\nPresione ENTER para continuar...") + limpiar_pantalla() + + +def evaluar_distancia(numero: int, numero_oculto: int, frio: int, caliente: int) -> str: + """ + Evalúa la distancia entre el número oculto y el ingresado, y devuelve una pista basada en la cercanía. + + Args: + numero (int): Número ingresado por el usuario. + numero_oculto (int): Número que debe ser adivinado. + frio (int): Diferencia máxima para considerar la pista como "Frío". + caliente (int): Diferencia máxima para considerar la pista como "Caliente". + + Returns: + str: Mensaje indicando si el número está "Frío", "Caliente" o "Te Quemas". + """ + diferencia = abs(numero_oculto - numero) + + if diferencia > frio: + return "* FRÍO, FRÍO," + elif diferencia > caliente: + return "* CALIENTE, CALIENTE," + else: + return "* TE QUEMAS," + + +def generar_pista(numero: int, numero_oculto: int, intentos: int) -> str: + """ + Genera una pista indicando si el número oculto es mayor o menor que el número ingresado. + + Args: + numero (int): Número ingresado por el usuario. + numero_oculto (int): Número que debe ser adivinado. + intentos (int): Cantidad de intentos restantes. + + Returns: + str: Mensaje indicando si el número oculto es mayor o menor, y cuántos intentos quedan. + """ + if numero_oculto > numero: + return f"el número oculto es MAYOR... ¡te quedan {intentos} intentos!\n" + else: + return f"el número oculto es MENOR... ¡te quedan {intentos} intentos!\n" + + +def mostrar_pista(numero: int, numero_oculto: int, intentos: int, frio: int, caliente: int): + """ + Muestra una pista combinando la distancia y si el número oculto es mayor o menor. + + Args: + numero (int): Número ingresado por el usuario. + numero_oculto (int): Número que debe ser adivinado. + intentos (int): Cantidad de intentos restantes. + frio (int): Diferencia máxima para considerar la pista como "Frío". + caliente (int): Diferencia máxima para considerar la pista como "Caliente". + """ + pista = generar_pista(numero, numero_oculto, intentos) + estado_calor = evaluar_distancia(numero, numero_oculto, frio, caliente) + print(f"\n{estado_calor} {pista}") + + +def adivina_el_numero(numero_oculto: int, total_intentos: int, frio: int, caliente: int): + """ + Gestiona el proceso de adivinación del número oculto, permitiendo que el usuario ingrese números. + + Args: + numero_oculto (int): Número que debe ser adivinado. + total_intentos (int): Cantidad total de intentos permitidos. + frio (int): Diferencia máxima para considerar la pista como "Frío". + caliente (int): Diferencia máxima para considerar la pista como "Caliente". + + Returns: + tuple: Un booleano que indica si el número fue adivinado y el número de intentos realizados. + """ + intentos_realizados = 0 + numero_adivinado = False + salir = False + + while not salir and total_intentos > 0: + numero = pedir_numero_usuario("¿Qué número es? ") + intentos_realizados += 1 + total_intentos -= 1 + + if numero != numero_oculto: + mostrar_pista(numero, numero_oculto, total_intentos, frio, caliente) + else: + numero_adivinado = True + salir = True + + return numero_adivinado, intentos_realizados + + +def comprobar_numero_entero(valor: str) -> bool: + """ + Verifica si el valor ingresado es un número entero válido. + + Args: + valor (str): Valor ingresado por el usuario. + + Returns: + bool: True si el valor es un número entero válido, False en caso contrario. + """ + if valor.startswith("-"): + valor = valor[1:] + return valor.isdigit() + + +def pedir_numero_usuario(mensaje: str) -> int: + """ + Solicita al usuario que introduzca un número entero válido. + + Args: + mensaje (str): Mensaje que se muestra al usuario para pedir el número. + + Returns: + int: Número entero ingresado por el usuario. + """ + salir = False + + while not salir: + valor = input(mensaje).strip() + salir = comprobar_numero_entero(valor) + + if not salir: + print("\n*ERROR* Ha introducido un número entero no válido!") + + return int(valor) + + +def configurar_rangos_numeros() -> tuple: + """ + Configura el rango de números válidos para el juego. + + Returns: + tuple: El mínimo y el máximo número posibles. + """ + salir = False + + while not salir: + minimo = pedir_numero_usuario("Introduce el mínimo número posible: ") + maximo = pedir_numero_usuario("Introduce el máximo número posible: ") + + salir = (minimo < maximo) and ((maximo - minimo) >= 100) + + if not salir: + print("\n*ERROR* Debe haber por lo menos 100 números de diferencia entre ellos...") + + return minimo, maximo + + +def configurar_pistas(minimo: int, maximo: int) -> tuple: + """ + Configura los valores de frío y caliente para las pistas. + + Args: + minimo (int): Mínimo número del rango. + maximo (int): Máximo número del rango. + + Returns: + tuple: Valores para las pistas de "Frío" y "Caliente". + """ + salir = False + + while not salir: + frio = pedir_numero_usuario("Introduce la diferencia para mostrar la pista FRÍO, FRÍO: ") + caliente = pedir_numero_usuario("Introduce la diferencia para mostrar la pista CALIENTE, CALIENTE: ") + + salir = (frio > caliente) and (minimo <= frio <= maximo) and (minimo <= caliente <= maximo) + + if not salir: + print(f"\n*ERROR* Deben estar dentro del rango ({minimo}.{maximo}) y no ser iguales...") + + return frio, caliente + + +def configurar_intentos() -> int: + """ + Configura el número de intentos para adivinar el número oculto. + + Returns: + int: Número de intentos configurado por el usuario. + """ + salir = False + + while not salir: + intentos = pedir_numero_usuario("Introduce el número de intentos: ") + + salir = intentos > 0 + + if not salir: + print("\n*ERROR* El número de intentos debe ser un entero positivo...") + + return intentos + + +def configurar_juego() -> tuple: + """ + Configura todos los parámetros del juego: rango de números, pistas e intentos. + + Returns: + tuple: Mínimo, máximo, número de intentos, valor para "Frío" y valor para "Caliente". + """ + limpiar_pantalla() + print("--- CONFIGURA EL JUEGO DE ADIVINA EL NÚMERO OCULTO ---\n\n") + + minimo, maximo = configurar_rangos_numeros() + frio, caliente = configurar_pistas(minimo, maximo) + intentos = configurar_intentos() + + return minimo, maximo, intentos, frio, caliente + + +def mostrar_configuracion(minimo, maximo, intentos, frio, caliente): + """ + Muestra la configuración actual del juego. + + Args: + minimo (int): Mínimo número del rango. + maximo (int): Máximo número del rango. + intentos (int): Número de intentos posibles. + frio (int): Diferencia mayor para la pista "Frío". + caliente (int): Diferencia mayor para la pista "Caliente". + """ + limpiar_pantalla() + print(f"--- CONFIGURACIÓN ACTUAL DE ADIVINA EL NÚMERO OCULTO ---\n\n") + print(f"* El número oculto será un número entre {minimo} y {maximo}.") + print(f"* El número de intentos es {intentos}.") + print(f"* Pista FRÍO si la diferencia es mayor a {frio}.") + print(f"* Pista CALIENTE si la diferencia es mayor a {caliente}.") + print(f"* Pista TE QUEMAS si la diferencia es menor.") + pausa() + + +def mostrar_menu(): + """ + Muestra el menú principal del juego. + """ + limpiar_pantalla() + print(f"--- MENÚ DE ADIVINA EL NÚMERO OCULTO ---\n\n") + print("1. Jugar.") + print("2. Configurar.") + print("3. Mostrar configuración.") + print("4. Salir.\n") + + +def comprobar_opcion(opcion: int) -> bool: + """ + Comprueba si la opción elegida está dentro del rango permitido (1-4). + + Args: + opcion (int): Opción ingresada por el usuario. + + Returns: + bool: True si la opción es válida, False en caso contrario. + """ + return 1 <= opcion <= 4 + + +def elegir_opcion_menu() -> int: + """ + Permite al usuario elegir una opción del menú. + + Returns: + int: La opción elegida por el usuario. + """ + mostrar_menu() + salir = False + + while not salir: + opcion = pedir_numero_usuario("Elije => ") + salir = comprobar_opcion(opcion) + + if not salir: + print(f"\n*ERROR* Opción {opcion} incorrecta! (1-4)") + + return opcion + + +def jugar(numero_oculto, intentos, frio, caliente): + """ + Gestiona el proceso del juego de adivinar el número oculto y muestra los resultados. + + Args: + numero_oculto (int): Número que debe ser adivinado. + intentos (int): Número de intentos disponibles. + frio (int): Diferencia máxima para la pista "Frío". + caliente (int): Diferencia máxima para la pista "Caliente". + """ + limpiar_pantalla() + print(f"--- ADIVINA EL NÚMERO OCULTO EN {intentos} INTENTOS ---\n\n") + numero_adivinado, intentos_realizados = adivina_el_numero(numero_oculto, intentos, frio, caliente) + + if numero_adivinado: + print(f"\n¡Bravo! ¡Lo conseguiste en {intentos_realizados} intentos!") + else: + print(f"\nGAME OVER - ¡Otra vez será! (#{numero_oculto}#)") + + pausa() + + +def genera_numero_oculto(minimo: int, maximo: int) -> int: + """ + Genera un número oculto aleatorio dentro de un rango determinado. + + Args: + minimo (int): El valor mínimo posible. + maximo (int): El valor máximo posible. + + Returns: + int: Número generado aleatoriamente entre mínimo y máximo. + """ + return random.randint(minimo, maximo) + + +def main(): + """ + Función principal que ejecuta el flujo completo del juego de adivinar el número oculto. + Configura los parámetros iniciales y gestiona el bucle principal del menú. + """ + limpiar_pantalla() + print("--- BIENVENIDOS AL JUEGO DE ADIVINAR EL NÚMERO OCULTO ---\n\n") + time.sleep(2) + + # Configuración inicial por defecto + minimo = 0 + maximo = 100 + frio = 15 + caliente = 5 + intentos = 5 + + salir = False + + while not salir: + opcion = elegir_opcion_menu() + + if opcion == 1: + numero_oculto = genera_numero_oculto(minimo, maximo) + jugar(numero_oculto, intentos, frio, caliente) + elif opcion == 2: + minimo, maximo, intentos, frio, caliente = configurar_juego() + elif opcion == 3: + mostrar_configuracion(minimo, maximo, intentos, frio, caliente) + else: + salir = True + + limpiar_pantalla() + print("Bye, bye...\n\n") + + +if __name__ == "__main__": + main() diff --git a/tests/test_adivinar_numero_v3.py b/tests/test_adivinar_numero_v3.py new file mode 100644 index 0000000..ecb19de --- /dev/null +++ b/tests/test_adivinar_numero_v3.py @@ -0,0 +1,194 @@ +import pytest + +from src.adivinar_numero_v3 import ( + evaluar_distancia, generar_pista, mostrar_pista, + adivina_el_numero, comprobar_numero_entero, pedir_numero_usuario, + configurar_rangos_numeros, configurar_pistas, configurar_intentos, + genera_numero_oculto +) + +################################################################################################### + +@pytest.mark.parametrize( + "numero, numero_oculto, frio, caliente, expected", + [ + (50, 100, 30, 10, "* FRÍO, FRÍO,"), + (85, 100, 30, 10, "* CALIENTE, CALIENTE,"), + (99, 100, 30, 10, "* TE QUEMAS,"), + ] +) +def test_evaluar_distancia(numero, numero_oculto, frio, caliente, expected): + assert evaluar_distancia(numero, numero_oculto, frio, caliente) == expected + +################################################################################################### + +@pytest.mark.parametrize( + "numero, numero_oculto, intentos, expected", + [ + (50, 100, 5, "el número oculto es MAYOR... ¡te quedan 5 intentos!\n"), + (90, 100, 3, "el número oculto es MAYOR... ¡te quedan 3 intentos!\n"), + (98, 100, 2, "el número oculto es MAYOR... ¡te quedan 2 intentos!\n"), + (150, 100, 1, "el número oculto es MENOR... ¡te quedan 1 intentos!\n") + ] +) +def test_generar_pista(numero, numero_oculto, intentos, expected): + assert generar_pista(numero, numero_oculto, intentos) == expected + +################################################################################################### + +@pytest.mark.parametrize( + "numero, numero_oculto, intentos, frio, caliente, expected_output", + [ + (50, 100, 5, 20, 10, "\n* FRÍO, FRÍO, el número oculto es MAYOR... ¡te quedan 5 intentos!\n\n"), + (85, 100, 3, 20, 10, "\n* CALIENTE, CALIENTE, el número oculto es MAYOR... ¡te quedan 3 intentos!\n\n"), + (98, 100, 2, 20, 10, "\n* TE QUEMAS, el número oculto es MAYOR... ¡te quedan 2 intentos!\n\n"), + (150, 100, 1, 20, 10, "\n* FRÍO, FRÍO, el número oculto es MENOR... ¡te quedan 1 intentos!\n\n"), + ] +) +def test_mostrar_pista(capsys, numero, numero_oculto, intentos, frio, caliente, expected_output): + mostrar_pista(numero, numero_oculto, intentos, frio, caliente) + captured = capsys.readouterr() + assert captured.out == expected_output + +################################################################################################### + +@pytest.mark.parametrize( + "numero_oculto, total_intentos, frio, caliente, mock_inputs, expected_result, expected_intentos", + [ + (100, 5, 20, 10, ['50', '75', '90', '100'], True, 4), # Adivina en el 4º intento + (100, 3, 20, 10, ['50', '75', '90'], False, 3), # No adivina en los 3 intentos + (100, 2, 20, 10, ['98', '100'], True, 2), # Adivina en el último intento + (100, 4, 20, 10, ['150', '140', '120', '100'], True, 4), # Adivina en el 4º intento + ] +) +def test_adivina_el_numero(monkeypatch, numero_oculto, total_intentos, frio, caliente, mock_inputs, expected_result, expected_intentos): + # Simular las entradas del usuario + inputs_iter = iter(mock_inputs) + monkeypatch.setattr('builtins.input', lambda _: next(inputs_iter)) + + # Ejecutar la función y capturar el resultado + result, intentos_realizados = adivina_el_numero(numero_oculto, total_intentos, frio, caliente) + + # Probar si el número fue adivinado correctamente + assert result == expected_result + # Probar si el número de intentos realizados es el esperado + assert intentos_realizados == expected_intentos + +################################################################################################### + +@pytest.mark.parametrize( + "valor, expected", + [ + ("100", True), + ("-50", True), + ("abc", False), + ("12.5", False), + ("", False), + ] +) +def test_comprobar_numero_entero(valor, expected): + assert comprobar_numero_entero(valor) == expected + +################################################################################################### + +@pytest.mark.parametrize( + "minimo, maximo", + [ + (0, 100), + (-100, 0), + (50, 150), + ] +) +def test_genera_numero_oculto(minimo, maximo): + numero_oculto = genera_numero_oculto(minimo, maximo) + assert minimo <= numero_oculto <= maximo + +################################################################################################### + +@pytest.mark.parametrize( + "frio, caliente, expected", + [ + (30, 10, True), + (50, 25, True), + ] +) +def test_configurar_pistas(frio, caliente, expected): + result = frio > caliente + assert result == expected + +################################################################################################### + +@pytest.mark.parametrize( + "mock_inputs, expected", + [ + ([' 10'], 10), # Entrada válida con espacios + (['-5'], -5), # Número negativo válido + (['0'], 0), # Número cero + (['abc', '10'], 10), # Entrada no válida seguida de entrada válida + (['', '100'], 100), # Entrada vacía seguida de número válido + ] +) +def test_pedir_numero_usuario(mock_inputs, expected, monkeypatch): + # Simular múltiples entradas del usuario usando monkeypatch + inputs_iter = iter(mock_inputs) + monkeypatch.setattr('builtins.input', lambda _: next(inputs_iter)) + + # Llamar a la función y comparar el resultado con lo esperado + assert pedir_numero_usuario("Introduce un número: ") == expected + +################################################################################################### + +@pytest.mark.parametrize( + "mock_inputs, expected", + [ + (['0', '200'], (0, 200)), # Rango válido con diferencia de 100 + (['100', '500'], (100, 500)), # Otro rango válido + (['50', '50', '50', '200'], (50, 200)), # Caso inválido (misma entrada dos veces) seguido de entrada válida + (['0', '50', '0', '150'], (0, 150)), # Caso inválido (diferencia menor a 100) seguido de entrada válida + ] +) +def test_configurar_rangos_numeros(mock_inputs, expected, monkeypatch): + # Simular entradas para mínimo y máximo + inputs_iter = iter(mock_inputs) + monkeypatch.setattr('builtins.input', lambda _: next(inputs_iter)) + + # Probar si el rango es configurado correctamente + assert configurar_rangos_numeros() == expected + +################################################################################################### + +@pytest.mark.parametrize( + "mock_inputs, minimo, maximo, expected", + [ + (['20', '10'], 0, 100, (20, 10)), # Pistas válidas: frío > caliente y dentro del rango + (['30', '15'], 1, 200, (30, 15)), # Otro set válido dentro del rango + (['10', '10', '25', '5'], 0, 100, (25, 5)), # Caso inválido (frío y caliente iguales) seguido de entrada válida + (['60', '70', '50', '10'], 0, 100, (50, 10)), # Caso inválido (frío < caliente) seguido de entrada válida + ] +) +def test_configurar_pistas(mock_inputs, minimo, maximo, expected, monkeypatch): + # Simular entradas para frío y caliente + inputs_iter = iter(mock_inputs) + monkeypatch.setattr('builtins.input', lambda _: next(inputs_iter)) + + # Probar si las pistas son configuradas correctamente + assert configurar_pistas(minimo, maximo) == expected + +################################################################################################### + +@pytest.mark.parametrize( + "mock_input, expected", + [ + (['5'], 5), # Intentos válidos + (['10'], 10), # Otro valor válido + (['-1', '7'], 7), # Caso inválido (número negativo) seguido de entrada válida + (['0', '20'], 20), # Caso inválido (entrada no numérica) seguido de entrada válida + ] +) +def test_configurar_intentos(mock_input, expected, monkeypatch): + # Simular la entrada para el número de intentos + inputs_iter = iter(mock_input) + monkeypatch.setattr('builtins.input', lambda _: next(inputs_iter)) + + # Probar si los intentos son configurados correctamente + assert configurar_intentos() == expected