Skip to content

Commit

Permalink
Exámenes de DAW1B
Browse files Browse the repository at this point in the history
  • Loading branch information
dcsibon committed Nov 10, 2024
1 parent 6e43051 commit 61209b0
Show file tree
Hide file tree
Showing 30 changed files with 9,812 additions and 17 deletions.
364 changes: 364 additions & 0 deletions daw1b_calculadora/abel_calculadora_alumnos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,364 @@
# TODO: ATENCIÓN!!!
# 1. Importar los paquetes necesarios
# 2. Usar la función mostrar_error para imprimir los errores por consola.
# 3. Los comentarios TODO os ayudan a resolver cada apartado de esta prueba.
# 4. CADA función SOLO puede tener una instrucción return.
# 5. En test_calculadora_alumnos.py crear el test unitario para la función es_resultado_negativo y hacer que todos los test unitarios se cumplan.

import time
import os

# Mensajes de error predefinidos
MENSAJES_ERROR = (
"Problemas al intentar limpiar la pantalla {error}",
"Error al configurar los decimales. Formato: decimales <n>.",
"Entrada no válida. Ingrese número, operador, 'resultado', 'cancelar' o <ENTER> para finalizar el cálculo.",
"Error: Introduzca un operador antes de otro número.",
"Comando no reconocido. Escriba 'lista' para ver las operaciones disponibles.",
"Error: no es posible la división por 0! Introduzca otro valor diferente a 0...",
"Se produjo un error: {error}"
)

# Operadores soportados por la calculadora
OPERADORES =
# TODO: Ayuda: incluye en esta constante los símbolos que reconocerá la aplicación para el cálculo de las operaciones:
# '+' para la suma.
# '-' para la resta.
# 'x' o '*' para la multiplicación.
# '/' o ':' para la división.
# '**' o 'exp' para la potencia.



def limpiar_pantalla():
"""
Limpia la consola según el sistema operativo.
"""
# TODO: El desarrollo de esta función está incompleto y con errores.
try:
if os.name == "poxis":
os.system("clear")
else:
os.system("cls")
except Exception as e:
mostrar_error(f"Problemas al intentar limpiar la pantalla: {e}")

# Otra forma de expresar la misma instrucción sería la siguiente:
# if os.name = posix:
# os.system(clear)
# else:
# os.system(cls)


def pausa(tiempo :int, tecla_enter :False):
"""
Pausa la ejecución del programa hasta que se pulse ENTER... "\nPresione ENTER para continuar..."
"""
# TODO: Desarrollar esta función según su documentación.
if tiempo != 0:
time.sleep(tiempo)
elif tecla_enter == False:
input("\nPresione ENTER para continuar...")

def mostrar_error(indice_error: int, msj_error = None):
"""
Muestra un mensaje de error en la consola.
Args:
indice_error (int): Índice del mensaje de error en MENSAJES_ERROR.
msj_error (str, opcional): Texto adicional para personalizar el mensaje de error.
"""
# TODO:
# 1. Corrige el error que existe a la hora de acceder a los mensajes de error que están en la constante
# MENSAJES_ERROR. A los elementos de una tupla se accede igual que a los caracteres de una
# cadena de caracteres.
# 2. Completa el código de esta función para que controle específicamente las excepciones IndexError y
# muestre el mensaje: "\n*ERROR* Mensaje de error no definido.\n"
# 3. También se pide que se controle cualquier otra excepción que se pueda producir y muestre el mensaje:
# "\n*ERROR* Problemas al mostrar error!\n{e}\n"
# 4. En esta función los mensajes de error deben mostrarse con print.
if msj_error != None:
print(f"\n*ERROR* {MENSAJES_ERROR.format(error = msj_error)}\n")
else:
print(f"\n*ERROR* {MENSAJES_ERROR}\n")


def sumar():
# TODO: Realizar el desarrollo completo, incluida la documentación... recibe 2 números float y retorna la suma de ambos.



def restar():
# TODO: Realizar el desarrollo completo, incluida la documentación... recibe 2 números float y retorna la resta de ambos.



def es_resultado_negativo(num1: float, num2: float) -> bool:
"""Determina si el resultado de una operación entre num1 y num2 debe ser negativo."""
# TODO: Realizar el desarrollo completo de esta función teniendo en cuenta la documentación y completándola también.
# Debe pasar las pruebas unitarias.
# Se trata de una función que os puede venir bien para utilizarla tanto en la función multiplicar, como en dividir.
# Ya que va a determinar si la multiplicación o división entre dos números debería ser de signo negativo o no.



def multiplicar():
"""
Realiza la multiplicación ENTERA de dos números usando solo sumas y restas.
Args:
num1 (float): Primer número.
num2 (float): Segundo número.
Returns:
int: Resultado de la multiplicación.
Note:
Debe redondear los números recibidos a enteros para trabajar.
"""
# TODO:
# 1. Realizar el desarrollo completo de esta función teniendo en cuenta la documentación.
# 2. Esta función debe pasar las pruebas unitarias.
# 3. No podéis usar el operador de multiplicación de Python para realizar el desarrollo de la misma,
# es decir, que debéis realizar la multiplicación con SUMAS y/o RESTAS...
# 4. Aunque se reciben números de tipo float, debéis redondearlos como números enteros para
# simplificar esta función, es decir, la operación 4.98 * 3.33, deberá convertirse en 5 * 3.
# 5. Tened en cuenta que podéis recibir números negativos, es decir, la operación -5 * -5 = 25
# 6. OBLIGATORIO usar un bucle for.
# 7. Incluir algún comentario para mejorar la claridad y permitir que otros comprendan el propósito y funcionamiento del código.



def dividir():
"""
Realiza la división ENTERA de dos números usando solo sumas y restas.
Args:
num1 (float): Dividendo.
num2 (float): Divisor.
Returns:
int: Resultado de la división.
Raises:
ZeroDivisionError: Si el divisor es cero.
Note:
Debe redondear los números recibidos a enteros para trabajar.
"""
# TODO:
# 1. Realizar el desarrollo completo de esta función teniendo en cuenta la documentación.
# 2. Esta función debe pasar las pruebas unitarias.
# 3. No podéis usar el operador de división de Python para realizar el desarrollo de la misma,
# es decir, que debéis realizar la división con SUMAS y/o RESTAS...
# 4. Aunque se reciben números de tipo float, debéis redondearlos como números enteros para
# simplificar esta función, es decir, la operación 4.98 / 3.33, deberá convertirse en 5 / 3.
# 5. Tened en cuenta que podéis recibir números negativos, es decir, la operación -5 / -5 = 1
# 6. Incluir algún comentario para mejorar la claridad y permitir que otros comprendan el propósito y funcionamiento del código.


def potencia():
# TODO:
# 1. Realizar el desarrollo completo de esta función y su documentación.
# 2. Esta función debe pasar las pruebas unitarias.
# 3. PREMISAS a tener en cuenta:
# - Cualquier número elevado a 0 da como resultado 1.
# - Para simplificar esta función, vamos a suponer que un número elevado a un
# exponente negativo siempre dará 0 (aunque en realidad no es así matemáticamente)
# 4. Utiliza la función de multiplicar para realizar los cálculos que te
# harán falta en esta función (RECUERDA que no puedes usar directamente los operadores
# de Python para la multiplicación y división).
# 5. Incluir algún comentario para mejorar la claridad y permitir que otros comprendan el propósito y funcionamiento del código.


def pedir_entrada(msj: str) -> str:
"""
Pide al usuario una entrada, elimina espacios por delante y por detrás y la convierte a minúsculas.
Args:
msj (str): Mensaje para solicitar la entrada.
Returns:
str: Entrada del usuario.
"""
# TODO: El desarrollo de esta función está incompleto, debéis terminarla teniendo en cuenta la documentación
return input(msj)


def calcular_operacion(num1: float, num2: float, operador: str) -> float:
"""
Realiza la operación especificada entre num1 y num2 dependiendo del valor del operador.
Args:
num1 (float): Primer número.
num2 (float): Segundo número.
operador (str): Operador de la operación.
Returns:
float: Resultado de la operación.
Raises:
ZeroDivisionError: Si el divisor es cero.
"""
# TODO: El desarrollo de esta función está incompleto... completadla teniendo en cuenta la documentación
# y que debe realizar las llamadas adecuadas a las funciones ya creadas para realizar los distintos
# cálculos... sumar, restar, multiplicar, dividir y potencia.
# IMPORTANTE: Si hacemos caso a la documentación de esta función, NO debéis capturar la excepción
# ZeroDivisionError aquí, sino que hay que dejadla que se propague a la función llamante, realizar_calculo(),
# dónde se os indica cómo realizar la gestión de estos errores.

return resultado



def obtener_operaciones() -> str:
"""
Devuelve una cadena con la lista de operaciones disponibles en la calculadora.
Returns:
(str): cadena de caracteres con la información de las operaciones disponibles.
"""
# TODO: El desarrollo de esta función está incompleto... ver documentación para solucionarla correctamente.
"""
Operaciones disponibles:
ce => Reiniciar resultado a 0
decimales <n> => Establecer decimales en resultado
cadena vacía + <ENTER> => Pregunta si desea salir
calculo => Iniciar cálculo secuencial
+ => Suma
- => Resta
x o * => Multiplicación
/ o : => División
** o exp => Potencia
cancelar => vovler sin actualizar resultado de la calculadora
cadena vacía + <ENTER> => volver actualizando resultado de la calculadora
"""


def realizar_calculo():
"""
Realiza una secuencia de cálculos solicitando números y operadores al usuario.
Args:
decimales (int): Número de decimales para el resultado.
resultado_almacenado (float): Valor almacenado en la calculadora.
Returns:
float: Resultado final del cálculo o None si se cancela.
Note:
* Dentro de esta función el usuario puede realizar cálculos secuenciales, es decir,
comenzará introduciendo un número, después un operador, y otro número... a partir
de aquí sobre el resultado acumulado, introducirá operador y número para seguir
realizando cálculos (ver ejemplos en README.md de la tarea en el repositorio de GitHub).
* El usuario es guiado para introducir números y operadores secuencialmente
para realizar operaciones básicas.
* El usuario puede utilizar "resultado" en la secuencia de cálculo para reutilizar el
resultado almacenado en la calculadora.
* El cálculo finaliza al pulsar <ENTER>, volviendo y actualizando el resultado almacenado
de la calculadora con el cálculo realizado.
* También podemos escribir "cancelar", volviendo sin realizar ningún cambio en el
resultado almacenado de la calculadora.
"""
# TODO: El desarrollo de esta función está incompleto... ver documentación para solucionarla correctamente.

operador = None
resultado = None
realizando_calculos = True

print("\n## Ingrese número, operador, 'resultado', 'cancelar' o <ENTER> para finalizar el cálculo ##\n")

while realizando_calculos:
entrada = pedir_entrada(f"\t (Cálculo = resultado) >> ")

if entrada == "cancelar":


elif entrada == "":


elif entrada in OPERADORES:
operador =

else:
# TODO: este código funciona cuando solucionéis que reconozca las variables resultado_almacenado y decimales.
# Pero no gestiona los posibles tipos de Excepciones que se pueden producir:
# - ValueError que debe mostrar el error que está en la posición 2 de MENSAJES_ERROR.
# - ZeroDivisionError que debe mostrar el error que está en la posición 5 de MENSAJES_ERROR.
# - Exception que debe mostrar el error que está en la posición 6 de MENSAJES_ERROR.
if entrada == "resultado":
entrada = resultado_almacenado

try:
numero = float(entrada)

if operador is not None:
if resultado is None:
resultado = 0
resultado = round(calcular_operacion(resultado, numero, operador), decimales)
operador = None

elif resultado is None:
resultado = numero

else:
mostrar_error(3)
except


def main():
"""
Función principal de la calculadora. Gestiona la entrada del usuario y coordina las operaciones.
Note:
El flujo del programa es el siguiente:
1. Inicia la calculadora mostrando el resultado almacenado por defecto (0.00).
2. El usuario ingresa un comando, que puede ser:
- "lista" para ver todas las operaciones disponibles.
- "ce" para reiniciar el resultado almacenado a 0.
- "decimales <n>" para establecer el número de decimales mostrados en el resultado.
- "calculo" para iniciar una secuencia de cálculo paso a paso.
- Una entrada vacía y pulsa la tecla <ENTER> para salir de la calculadora.
3. Según el comando ingresado:
- El programa realiza la operación o ejecuta la acción indicada.
- Al ingresar "calculo":
* El usuario es guiado para introducir números y operadores secuencialmente para realizar operaciones básicas.
* El usuario puede utilizar "resultado" en la secuencia de cálculo para reutilizar el resultado almacenado en la calculadora.
* El cálculo finaliza al pulsar <ENTER>, volviendo y actualizando el resultado almacenado de la calculadora con el cálculo realizado.
* También podemos escribir "cancelar", volviendo sin realizar ningún cambio en el resultado almacenado de la calculadora.
4. La calculadora sigue ejecutándose hasta que el usuario confirma la salida al ingresar una entrada vacía y pulsar <ENTER>.
5. Finalmente, se limpia la pantalla, el programa se despide con el mensaje "\n\nBye, bye...\n\n" y termina.
"""
# TODO: Corrige los errores y haz que el main funcione correctamente...

decimales = 2
resultado = 0.0

while not desea_salir:

pedir_entrada(f"Operación (RES => ({resultado}) >> ")

if entrada == "":
pedir_entrada("¿Desea salir de la calculadora? (s/n) ")

elif entrada == "lista":
obtener_operaciones

elif entrada == "ce":


elif entrada.startswith("decimales"):
# Extraemos las posiciones decimales y las convertimos a un valor entero
decimales = str(entrada.split()[1])
print(f"Decimales configurados a {decimales}.")

elif entrada == "calculo":
realizar_calculo(decimales, resultado)

else:
mostrar_error
Loading

0 comments on commit 61209b0

Please sign in to comment.