Skip to content

Commit d200b79

Browse files
authored
Merge pull request #7174 from mrodara/mrodara/main
#26-Python
2 parents b8db3f6 + babb0c4 commit d200b79

File tree

3 files changed

+477
-0
lines changed

3 files changed

+477
-0
lines changed
+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
### SOLID PRINCPIO DE RESPONSABILIDAD ÚNICA (SRP)
2+
3+
'''
4+
El Principio de Responsabilidad Única (SRP) es uno de los cinco principios SOLID en la programación orientada a objetos.
5+
Este principio establece que una clase debe tener una única razón para cambiar, es decir, una sola responsabilidad o
6+
propósito.
7+
En términos simples, cada clase debe encargarse de una sola tarea y hacerlo bien.
8+
'''
9+
10+
'''
11+
VENTAJAS:
12+
- Facilita la comprensión y el mantenimiento del código.
13+
- Reduce la complejidad del código.
14+
- Mejora la reutilización del código.
15+
'''
16+
17+
# Ejemplo que viola este principio
18+
#class User():
19+
#
20+
# def __init__(self, name, email):
21+
# self.name = name
22+
# self.email = email
23+
#
24+
# def save_to_file(self):
25+
# with open('users.txt', 'w') as file:
26+
# file.write(f"Name: {self.name}, Email: {self.email}")
27+
28+
# El ejemplo anterior viola el SRP, ya que gestiona tanto los datos del usuario como su almacenamiento en un registro.
29+
30+
# Vamos a reestructuar el diseño para cumplir con SRP con dos clases separadas
31+
#class User():
32+
#
33+
# def __init__(self, name, email):
34+
# self.name = name
35+
# self.email = email
36+
#
37+
#class UserFileHandler():
38+
# @staticmethod
39+
# def save_to_file(user, filename):
40+
# with open(filename, 'w') as file:
41+
# file.write(f"Name: {user.name}, Email: {user.email}")
42+
43+
44+
# Prueba de funcionamiento
45+
#user = User("Manuel", "[email protected]")
46+
#UserFileHandler.save_to_file(user, "user_data.txt")
47+
48+
49+
## EJERCICIO EXTRA
50+
51+
# Clase que incumple el principio SRP
52+
#class Library():
53+
#
54+
# users = []
55+
# loans = []
56+
#
57+
# def __init__(self, title, author, copies):
58+
#
59+
# self.books.append({'title': title, 'author':author, 'copies': copies})
60+
#
61+
# def register_book(self, title, author, copies):
62+
# self.books.append({'title': title, 'author': author, 'copies': copies})
63+
# print(f"Registro de libro realizado con éxito")
64+
#
65+
# def register_user(self, name, id, email):
66+
# self.users.append({'name': name, 'id': id, 'email': email})
67+
# print(f"Registro de usuario realizado con éxito")
68+
#
69+
# def loan_book(self, user, book):
70+
# if book['copies'] > 0:
71+
# self.loans.append({'user': user, 'book': book})
72+
# book['copies'] -= 1
73+
# print(f"Préstamo de libro realizado con éxito")
74+
# else:
75+
# print(f"No hay copias disponibles del libro {book['title']}")
76+
#
77+
# def return_book(self, user, book):
78+
# if user in [loan['user'] for loan in self.loans] and book in [book['name'] for book in self.books]:
79+
# self.loans.remove({'user': user, 'book': book})
80+
# book['copies'] += 1
81+
# print(f"Devolución de libro realizada con éxito")
82+
# else:
83+
# print(f"No hay préstamos activos del libro {book['title']}")
84+
85+
# Aplicando SRP
86+
class User():
87+
88+
def __init__(self, name, id, email):
89+
self.name = name
90+
self.id = id
91+
self.email = email
92+
93+
class Book():
94+
95+
def __init__(self, name, author, copies):
96+
self.name = name
97+
self.author = author
98+
self.copies = copies
99+
100+
class Library():
101+
102+
def __init__(self, users = [], books = [], loans=[]):
103+
self.users = users
104+
self.books = books
105+
self.loans = loans
106+
107+
def register_user(self, user: User):
108+
self.users.append(user)
109+
print(f"Registro de usuario realizado con éxito")
110+
111+
def register_book(self, book: Book):
112+
self.books.append(book)
113+
print(f"Registro de libro realizado con éxito")
114+
115+
def register_loan(self, user: User, book: Book):
116+
if book.copies > 0:
117+
self.loans.append({"user": user, "book" : book})
118+
book.copies -= 1
119+
print(f"Préstamo de libro realizado con éxito")
120+
else:
121+
print(f"No hay copias disponibles del libro {book.name}")
122+
123+
def return_loan(self, user: User, book: Book):
124+
if user in [loan['user'] for loan in self.loans] and book in [loan['book'] for loan in self.loans]:
125+
self.loans.remove({'user': user, 'book': book})
126+
book.copies += 1
127+
print(f"Devolución de libro realizada con éxito")
128+
129+
# Pruebas del programa
130+
user1 = User(name="Manuel", id=1, email="[email protected]")
131+
user2 = User(name="Pedro", id=2, email="[email protected]")
132+
book1 = Book(name="Libro 1", author="Autor 1", copies=2)
133+
book2 = Book(name="Libro 2", author="Autor 2", copies=1)
134+
library = Library()
135+
library.register_user(user1)
136+
library.register_user(user2)
137+
library.register_book(book1)
138+
library.register_book(book2)
139+
library.register_loan(user1, book1)
140+
library.register_loan(user2, book2)
141+
library.register_loan(user1, book2)
142+
library.return_loan(user2, book2)
143+
library.register_loan(user1, book2)
144+
145+
# Fin Aplicando SRP
146+
147+
## FIN EJERCICIO EXTRA
148+
149+
### FIN SOLID PRINCPIO DE RESPONSABILIDAD ÚNICA (SRP)
+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#### SOLID PRINCIPIO ABIERTO-CERRADO (OCP)
2+
3+
'''
4+
Este principio establece que las clases deben estar abiertas para la extensión, pero cerradas para la modificación.
5+
6+
En otras palabras, puedes agregar nuevas funcionalidades a una clase sin modificar su código existente.
7+
Esto ayuda a evitar errores inesperados en el código ya probado y a facilitar la escalabilidad.
8+
'''
9+
10+
'''
11+
Ventajas:
12+
13+
Protege el código existente
14+
Facilita la extensión
15+
Favorece el diseño modular
16+
'''
17+
18+
# Ejemplo que inclumple OCP
19+
20+
#class CalculadoraArea():
21+
# def calcular_area(self, forma):
22+
# if forma.lower() == "circulo":
23+
# radio = float(input("Introduce el radio de la circunferencia: "))
24+
# return 3.14 * (radio ** 2)
25+
# elif forma.lower() == "cuadrado":
26+
# lado = float(input("Introduce longitud de lado: "))
27+
# return lado ** 2
28+
#
29+
#print(CalculadoraArea().calcular_area("Circulo"))
30+
#print(CalculadoraArea().calcular_area("cuadrado"))
31+
32+
# Fin Ejemplo que inclumple OCP
33+
34+
# Podemos usar polimorfismo para cumplir con el OCP, creando una clase base o interfaz que permita
35+
# a las formas geométricas implementar su propio método de cálculo de área.
36+
37+
from abc import ABC, abstractmethod
38+
39+
# Clase abstracta para formas geométricas
40+
#class Forma(ABC):
41+
# @abstractmethod
42+
# def calcular_area(self):
43+
# pass
44+
#
45+
## Implementaciones específicas de formas
46+
#class Circulo(Forma):
47+
# def __init__(self, radius):
48+
# self.radius = radius
49+
#
50+
# def calcular_area(self):
51+
# return 3.14 * (self.radius ** 2)
52+
#
53+
#class Cuadrado(Forma):
54+
# def __init__(self, side):
55+
# self.side = side
56+
#
57+
# def calcular_area(self):
58+
# return self.side ** 2
59+
#
60+
## Prueba
61+
#formas = [
62+
# Circulo(5),
63+
# Cuadrado(4)
64+
#]
65+
#
66+
#for forma in formas:
67+
# print(forma.calcular_area()) # Output: 78.5, 16
68+
69+
class Calculadora(ABC):
70+
71+
@abstractmethod
72+
def calcular(self):
73+
pass
74+
75+
class Suma(Calculadora):
76+
77+
def calcular(self, a, b):
78+
return a + b
79+
80+
class Resta(Calculadora):
81+
def calcular(self, a, b):
82+
return a - b
83+
84+
class Multiplicacion(Calculadora):
85+
def calcular(self, a, b):
86+
return a * b
87+
88+
class Division(Calculadora):
89+
def calcular(self, a, b):
90+
if b == 0:
91+
raise ValueError("No se puede dividir por cero")
92+
return a / b
93+
94+
# Para añadir una quinta operación es sencillo creando un nuevo método abstracto y su correspondiente clase
95+
class Potencia2(Calculadora):
96+
def calcular(self, a):
97+
return a ** 2
98+
99+
# Pruebas de calculadora
100+
a = 560
101+
b = 12
102+
103+
operaciones = [
104+
Suma(),
105+
Resta(),
106+
Multiplicacion(),
107+
Division(),
108+
Potencia2()
109+
]
110+
111+
for operacion in operaciones:
112+
if isinstance(operacion, Suma):
113+
print(f"La suma de {a} y {b} es: {operacion.calcular(a, b)}")
114+
elif isinstance(operacion, Resta):
115+
print(f"La resta de {a} y {b} es: {operacion.calcular(a,b)}")
116+
elif isinstance(operacion, Multiplicacion):
117+
print(f"La multiplicación de {a} y {b} es: {operacion.calcular(a,b)}")
118+
elif isinstance(operacion, Division):
119+
print(f"La división de {a} y {b} es: {operacion.calcular(a,b)}")
120+
else:
121+
print(f"El cuadrado de {a} es: {operacion.calcular(a)}")
122+
#
123+
#suma = Suma()
124+
#print(suma.calcular(a, b))
125+
#
126+
#resta = Resta()
127+
#print(resta.calcular(a, b))
128+
#
129+
#multiplicacion = Multiplicacion()
130+
#print(multiplicacion.calcular(a, b))
131+
#
132+
#division = Division()
133+
#print(division.calcular(a, b))
134+
#
135+
#potencia2 = Potencia2()
136+
#print(potencia2.calcular(a))
137+
138+
#### FIN SOLID PRINCIPIO ABIERTO-CERRADO (OCP)

0 commit comments

Comments
 (0)