From 0199f12b0d55f5ab847dce6f18903585662895b2 Mon Sep 17 00:00:00 2001 From: dcsibon Date: Sat, 9 Nov 2024 10:34:39 +0100 Subject: [PATCH] =?UTF-8?q?Refactorizaci=C3=B3n=20y=20mejoras=20en=20la=20?= =?UTF-8?q?soluci=C3=B3n=20de=20la=20calculadora?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- otros/calculadora.py | 100 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 20 deletions(-) diff --git a/otros/calculadora.py b/otros/calculadora.py index fddab3a..c5753e4 100644 --- a/otros/calculadora.py +++ b/otros/calculadora.py @@ -123,25 +123,35 @@ def multiplicar(num1: float, num2: float) -> int: Note: Debe redondear los números recibidos a enteros para trabajar. """ - - if num2 == 0: - resultado = 0 - else: - resultado_negativo = es_resultado_negativo(num1, num2) + resultado_negativo = es_resultado_negativo(num1, num2) - num1 = round(abs(num1)) - num2 = round(abs(num2)) + # Redondeo a enteros + num1 = round(abs(num1)) + num2 = round(abs(num2)) + + # Inicializa el resultado a 0, por si alguno de los números es 0 + resultado = 0 - # Para optimizar el menor número de iteraciones del bucle for, seleccionamos el rango del número menor + if num1 != 0 and num2 != 0: + # Para optimizar, usamos el menor número en el rango de iteraciones num_a_sumar = max(num1, num2) num_rango = min(num1, num2) - resultado = 0 + # Calcula el resultado usando solo sumas for _ in range(num_rango): resultado += num_a_sumar + # También podríamos haber utilizado la función sumar: + # for _ in range(num_rango): + # resultado += sumar(resultado, num_a_sumar) + + # Ajuste de signo si el resultado es negativo if resultado_negativo: - resultado = resultado - (resultado + resultado) + resultado = 0 - resultado + + # También podríamos haber utilizado la función restar: + # if resultado_negativo: + # resultado = restar(0, resultado) return resultado @@ -166,19 +176,32 @@ def dividir(num1: float, num2: float) -> int: if num2 == 0: raise ZeroDivisionError("No es posible dividir por cero!") - else: - resultado_negativo = es_resultado_negativo(num1, num2) + resultado_negativo = es_resultado_negativo(num1, num2) + resultado = 0 + + if num1 != 0: + # Redondeo a enteros num1 = round(abs(num1)) num2 = round(abs(num2)) - resultado = 0 + # Realiza la división entera restando repetidamente el divisor while num1 >= num2: num1 -= num2 resultado += 1 + # También podríamos haber utilizado la función restar + # while num1 >= num2: + # num1 += restar(num1, num2) + # resultado = sumar(resultado, 1) + + # Ajuste de signo si el resultado es negativo if resultado_negativo: - resultado = resultado - (resultado + resultado) + resultado = 0 - resultado + + # También podríamos haber utilizado la función restar: + # if resultado_negativo: + # resultado = restar(0, resultado) return resultado @@ -221,7 +244,7 @@ def potencia(base: float, exponente: float) -> int: resultado = multiplicar(resultado, base) if resultado_negativo: - resultado = resultado - (resultado + resultado) + resultado = 0 - resultado return resultado @@ -319,19 +342,37 @@ def realizar_calculo(decimales: int, resultado_almacenado: float) -> float: realizando_calculos = False elif entrada in OPERADORES: + # Cogemos el último operador ingresado (si antes había otro, lo reemplaza) + # De esta manera, si ingresamos varios operadores seguidos, se realizará + # la operación que indique el último operador introducido. operador = entrada else: + # Si se ingresó el comando resultado, reemplazamos el valor de entrada por + # el valor del resultado de la calculadora. if entrada == "resultado": entrada = resultado_almacenado try: + # Si estamos aquí es porque esperamos un número, pero siempre con el + # control de excepciones, para capturar errores de conversión. numero = float(entrada) + # Si existe un operador, debemos realizar un cálculo. if operador is not None: + # Si el resultado aún no se ha asignado, tomamos 0 cómo el valor + # inicial del cálculo. Esto se produce cuando solo ingresamos un + # operador y después un número. if resultado is None: resultado = 0 + + # Realizamos el cálculo y ajustamos el resultado a las posiciones + # decimales adecuadas. resultado = round(calcular_operacion(resultado, numero, operador), decimales) + + # Importante! Debemos reiniciar el operador después de realizar un + # cálculo, para que lo siguiente válido sea un operador y no un + # número. operador = None elif resultado is None: @@ -350,6 +391,28 @@ def realizar_calculo(decimales: int, resultado_almacenado: float) -> float: return resultado +def ajustar_decimales(decimales: int, entrada: str) -> int: + """ + Ajusta el número de posiciones decimales según la entrada proporcionada. + + Args: + decimales (int): El número de posiciones decimales actual. + entrada (str): Una cadena de texto que se espera contenga, en la segunda palabra, + el número deseado de posiciones decimales. La primera palabra se ignora. + + Returns: + (int): El número de posiciones decimales ajustado. Si ocurre un error en la conversión, devuelve el valor original de `decimales`. + """ + posiciones_decimales = decimales + + try: + posiciones_decimales = int(entrada.split()[1]) + except (IndexError, ValueError): + mostrar_error(1) + + return posiciones_decimales + + def main(): """ Función principal de la calculadora. Gestiona la entrada del usuario y coordina las operaciones. @@ -399,11 +462,8 @@ def main(): resultado = 0 elif entrada.startswith("decimales"): - try: - decimales = int(entrada.split()[1]) - print(f"Decimales configurados a {decimales}.") - except (IndexError, ValueError): - mostrar_error(1) + decimales = ajustar_decimales(decimales, entrada) + print(f"Decimales configurados a {decimales}.") elif entrada == "calculo": resultado_ultimo_calculo = realizar_calculo(decimales, resultado)