1+ """
2+ Mauricio Leyva
3+
4+
5+ Calculadora interactiva que cumple con el Principio Abierto-Cerrado (OCP)
6+
7+ Descripción:
8+ Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.
9+
10+ Requisitos:
11+ - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.
12+
13+ Instrucciones:
14+ 1. Implementa las operaciones de suma, resta, multiplicación y división.
15+ 2. Comprueba que el sistema funciona.
16+ 3. Agrega una quinta operación para calcular potencias.
17+ 4. Comprueba que se cumple el OCP.
18+
19+ Este código implementa una calculadora interactiva que cumple con todos estos requisitos,
20+ permitiendo fácilmente la adición de nuevas operaciones sin modificar el código existente.
21+ """
22+
23+
24+ from abc import ABC , abstractmethod
25+
26+ class Operation (ABC ):
27+ @abstractmethod
28+ def execute (self , a , b ):
29+ pass
30+
31+ @abstractmethod
32+ def get_symbol (self ):
33+ pass
34+
35+ class Addition (Operation ):
36+ def execute (self , a , b ):
37+ return a + b
38+
39+ def get_symbol (self ):
40+ return "+"
41+
42+ class Subtraction (Operation ):
43+ def execute (self , a , b ):
44+ return a - b
45+
46+ def get_symbol (self ):
47+ return "-"
48+
49+ class Multiplication (Operation ):
50+ def execute (self , a , b ):
51+ return a * b
52+
53+ def get_symbol (self ):
54+ return "*"
55+
56+ class Division (Operation ):
57+ def execute (self , a , b ):
58+ if b == 0 :
59+ raise ValueError ("No se puede dividir por cero" )
60+ return a / b
61+
62+ def get_symbol (self ):
63+ return "/"
64+
65+ class Power (Operation ):
66+ def execute (self , a , b ):
67+ return a ** b
68+
69+ def get_symbol (self ):
70+ return "^"
71+
72+ class Calculator :
73+ def __init__ (self ):
74+ self .operations = {}
75+
76+ def register_operation (self , operation ):
77+ self .operations [operation .get_symbol ()] = operation
78+
79+ def get_available_operations (self ):
80+ return list (self .operations .keys ())
81+
82+ def calculate (self , operation_symbol , a , b ):
83+ if operation_symbol not in self .operations :
84+ raise ValueError (f"Operación '{ operation_symbol } ' no soportada" )
85+ return self .operations [operation_symbol ].execute (a , b )
86+
87+ def get_user_input ():
88+ while True :
89+ try :
90+ a = float (input ("Ingrese el primer número: " ))
91+ b = float (input ("Ingrese el segundo número: " ))
92+ return a , b
93+ except ValueError :
94+ print ("Por favor, ingrese números válidos." )
95+
96+ def main ():
97+ calc = Calculator ()
98+
99+ # Registro de operaciones
100+ calc .register_operation (Addition ())
101+ calc .register_operation (Subtraction ())
102+ calc .register_operation (Multiplication ())
103+ calc .register_operation (Division ())
104+ calc .register_operation (Power ())
105+
106+ while True :
107+ print ("\n Operaciones disponibles:" )
108+ for op in calc .get_available_operations ():
109+ print (f" { op } " )
110+
111+ operation = input ("Elija una operación (o 'q' para salir): " )
112+
113+ if operation .lower () == 'q' :
114+ break
115+
116+ if operation not in calc .get_available_operations ():
117+ print ("Operación no válida. Intente de nuevo." )
118+ continue
119+
120+ a , b = get_user_input ()
121+
122+ try :
123+ result = calc .calculate (operation , a , b )
124+ print (f"Resultado: { a } { operation } { b } = { result } " )
125+ except ValueError as e :
126+ print (f"Error: { e } " )
127+
128+ if __name__ == "__main__" :
129+ main ()
0 commit comments