Skip to content

Commit f4473d1

Browse files
#9 - python
1 parent 9af7f1e commit f4473d1

File tree

1 file changed

+354
-0
lines changed

1 file changed

+354
-0
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
#9 { Retos para Programadores } HERENCIA Y POLIMORFISMO
2+
"""
3+
* EJERCICIO:
4+
* Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que
5+
* implemente una superclase Animal y un par de subclases Perro y Gato,
6+
* junto con una función que sirva para imprimir el sonido que emite cada Animal.
7+
*
8+
* DIFICULTAD EXTRA (opcional):
9+
* Implementa la jerarquía de una empresa de desarrollo formada por Empleados que
10+
* pueden ser Gerentes, Gerentes de Proyectos o Programadores.
11+
* Cada empleado tiene un identificador y un nombre.
12+
* Dependiendo de su labor, tienen propiedades y funciones exclusivas de su
13+
* actividad, y almacenan los empleados a su cargo.
14+
15+
"""
16+
17+
# Bibliography
18+
# Professional JavaScript for web developers by Matt Frisbie
19+
# GPT
20+
21+
# In Python, inheritance is a mechanism that allows one class to acquire the properties and methods of another class.
22+
# This is typically achieved through class inheritance, enabling code reuse and the creation of hierarchical relationships between classes.
23+
24+
# All classes in Python can inherit from other classes, allowing for a prototype chain where a class can access properties and methods from its parent class.
25+
26+
log = print
27+
28+
# Define the base class Animal
29+
class Animal:
30+
def __init__(self, name=None, sound=None, animal_type=None):
31+
self._name = name if name else 'set no name'
32+
self._sound = sound if sound else 'set no sound'
33+
self._type = animal_type if animal_type else 'set no type'
34+
35+
@property
36+
def name(self):
37+
return self._name
38+
39+
@name.setter
40+
def name(self, name):
41+
self._name = name
42+
43+
def speak(self):
44+
log(f"{self.name} the {self._type} says: {self._sound}!")
45+
46+
# Define the Dog class that inherits from Animal
47+
class Dog(Animal):
48+
def __init__(self, name, sound, animal_type):
49+
super().__init__(name, sound, animal_type)
50+
51+
def eat(self, meal):
52+
log(f"{self._name} the {self._type} eats some: {meal}")
53+
54+
def move(self):
55+
log(f"The {self._type} moves its tail.")
56+
57+
# Create an instance of Dog
58+
cap_dog = Dog('Capitan', 'I guau some pizza', 'Dog')
59+
cap_dog.speak() # Capitan the Dog says: I guau some pizza!
60+
cap_dog.eat('pizza') # Capitan the Dog eats some: pizza
61+
cap_dog.move() # The Dog moves its tail.
62+
63+
# Define the Cat class that inherits from Animal
64+
class Cat(Animal):
65+
def __init__(self, name, sound, animal_type):
66+
super().__init__(name, sound, animal_type)
67+
68+
def eat(self, meal):
69+
log(f"{self._name} the {self._type} eats some: {meal}")
70+
71+
def move(self):
72+
log(f"The {self._type} hunts the rat.")
73+
74+
# Create an instance of Cat
75+
black_jack = Cat('BlackJack', 'Miuauuuu', 'Cat')
76+
black_jack.speak() # BlackJack the Cat says: Miuauuuu!
77+
black_jack.eat('rat snack') # BlackJack the Cat eats some: rat snack
78+
black_jack.move() # The Cat hunts the rat.
79+
80+
# Note: It's interesting to know that we can use variables like key-value pairs assigned to object properties.
81+
# This also works with functions.
82+
83+
def make_person(name, age, email):
84+
return {'name': name, 'age': age, 'email': email}
85+
86+
person = make_person('Angy', 28, '[email protected]')
87+
log(person) # {'name': 'Angy', 'age': 28, 'email': '[email protected]'}
88+
89+
# Using destructuring (unpacking)
90+
person_name = person.get('name')
91+
person_age = person.get('age')
92+
person_email = person.get('email')
93+
person_job = person.get('job', 'Web Developer') # Default value if 'job' is not found
94+
95+
log(person_age) # 28
96+
log(person_job) # Web Developer
97+
98+
import re
99+
100+
import re # Make sure to import the re module
101+
102+
# Define the User class
103+
class User:
104+
def __init__(self, id, name, email, country):
105+
try:
106+
self._id = self.set_id(id)
107+
self._name = self.set_name(name)
108+
self._email = self.set_email(email)
109+
self._country = self.set_country(country)
110+
self.validate_properties() # Validate properties before freezing or sealing
111+
except Exception as error:
112+
log('Error creating User:', error)
113+
114+
@property
115+
def id(self):
116+
return self._id
117+
118+
@property
119+
def name(self):
120+
return self._name
121+
122+
@property
123+
def email(self):
124+
return self._email
125+
126+
@property
127+
def country(self):
128+
return self._country
129+
130+
@id.setter
131+
def id(self, id):
132+
self._id = self.set_id(id)
133+
134+
@name.setter
135+
def name(self, name):
136+
self._name = self.set_name(name)
137+
138+
@email.setter
139+
def email(self, email):
140+
self._email = self.set_email(email)
141+
142+
@country.setter
143+
def country(self, country):
144+
self._country = self.set_country(country)
145+
146+
def set_id(self, id): # Corrected to a regular method
147+
id_string = str(id)
148+
max_length = 15
149+
150+
if len(id_string) > max_length:
151+
raise ValueError(f"ID must be at most {max_length} characters long.")
152+
153+
return id_string
154+
155+
def set_name(self, name):
156+
name_string = str(name)
157+
max_length = 35
158+
159+
if len(name_string) > max_length:
160+
raise ValueError(f"Name must be at most {max_length} characters long.")
161+
162+
return name_string
163+
164+
def set_email(self, email):
165+
email_regex = r'^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?$'
166+
167+
if not re.match(email_regex, email):
168+
raise ValueError('Invalid email address format.')
169+
170+
return email
171+
172+
def set_country(self, country):
173+
country_string = str(country)
174+
max_length = 35
175+
176+
if len(country_string) > max_length:
177+
raise ValueError(f"Country must be at most {max_length} characters long.")
178+
179+
return country_string
180+
181+
def validate_properties(self):
182+
if not self._id or not self._name or not self._email or not self._country:
183+
raise ValueError('All properties must be set before freezing the object.')
184+
185+
def user_data(self):
186+
return {'id': self._id, 'name': self._name, 'email': self._email, 'country': self._country}
187+
188+
# Example usage of User class
189+
try:
190+
sussy = User('0067', 'Sussan', '[email protected]', 'Canada')
191+
log(sussy.user_data()) # {'id': '0067', 'name': 'Sussan', 'email': '[email protected]', 'country': 'Canada'}
192+
except Exception as error:
193+
log('Failed to create user:', error)
194+
195+
# Note: If we use a number to set the value for id, '0067' becomes '67' because it is turned to a decimal value.
196+
197+
# Define the SuperUser class that inherits from User
198+
class SuperUser(User):
199+
def __init__(self, id, name, email, country):
200+
super().__init__(id, name, email, country)
201+
self.permission = True
202+
203+
def has_permission(self):
204+
return self.permission
205+
206+
def display_user_info(self):
207+
user_info = self.user_data()
208+
return f"{user_info['name']} has permission: {self.has_permission()}"
209+
210+
class SuperUser:
211+
def __init__(self, user_id, name, email, country):
212+
self._id = user_id
213+
self.name = name
214+
self.email = email
215+
self.country = country
216+
self.permission = True # Assuming permission is always true for this example
217+
218+
def user_data(self):
219+
# Returns user data as a dictionary
220+
return {
221+
"id": self._id,
222+
"name": self.name,
223+
"email": self.email,
224+
"country": self.country
225+
}
226+
227+
# Creating an instance of SuperUser
228+
niko = SuperUser('001', 'Niko', '[email protected]', 'Venezuela')
229+
niko.country = 'undefined' # Setting country to 'undefined'
230+
231+
# Logging the outputs
232+
log(niko._id) # 001
233+
log(niko.country) # undefined
234+
log(niko.permission) # True
235+
log(niko.user_data()) # {'id': '001', 'name': 'Niko', 'email': '[email protected]', 'country': 'undefined'}
236+
237+
class Employed:
238+
def __init__(self, user_id, name, occupation):
239+
try:
240+
self._id = self.set_id(user_id)
241+
self._name = self.set_name(name)
242+
self._occupation = self.set_occupation(occupation)
243+
self.validate_properties()
244+
except Exception as error:
245+
log('Error creating Employed:', error)
246+
247+
@property
248+
def id(self):
249+
return self._id
250+
251+
@property
252+
def name(self):
253+
return self._name
254+
255+
@property
256+
def occupation(self):
257+
return self._occupation
258+
259+
@id.setter
260+
def id(self, user_id):
261+
self._id = self.set_id(user_id)
262+
263+
@name.setter
264+
def name(self, name):
265+
self._name = self.set_name(name)
266+
267+
@occupation.setter
268+
def occupation(self, occupation):
269+
self._occupation = self.set_occupation(occupation)
270+
271+
def set_id(self, user_id):
272+
id_string = str(user_id)
273+
max_length = 15
274+
275+
if len(id_string) > max_length:
276+
raise ValueError(f'ID must be at most {max_length} characters long.')
277+
278+
return id_string
279+
280+
def set_name(self, name):
281+
name_string = str(name)
282+
max_length = 35
283+
284+
if len(name_string) > max_length:
285+
raise ValueError(f'Name must be at most {max_length} characters long.')
286+
287+
return name_string
288+
289+
def set_occupation(self, occupation):
290+
occupation_str = str(occupation)
291+
max_length = 50
292+
293+
if len(occupation_str) > max_length:
294+
raise ValueError(f'Occupation must be at most {max_length} characters long.')
295+
296+
return occupation_str
297+
298+
def validate_properties(self):
299+
if not self._id or not self._name or not self._occupation:
300+
raise ValueError('All properties must be set before freezing the object.')
301+
302+
def employed_data(self):
303+
return {'id': self._id, 'name': self._name, 'occupation': self._occupation}
304+
305+
306+
class Developer(Employed):
307+
def __init__(self, user_id, name, occupation, languages, area=None):
308+
super().__init__(user_id, name, occupation)
309+
self._languages = languages
310+
self._area = area
311+
312+
def functions(self):
313+
log(f'Developer ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Area: {self._area} | Languages: {", ".join(self._languages)}')
314+
315+
316+
class Secretary(Employed):
317+
def functions(self):
318+
log(f'Secretary ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Responsibilities: Administrative operations and user attention.')
319+
320+
321+
class Manager(Employed):
322+
def __init__(self, user_id, name, occupation, employeds):
323+
super().__init__(user_id, name, occupation)
324+
self._employeds = employeds # Expecting a list of employee names
325+
326+
def functions(self):
327+
log(f'Manager ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Supervising Employees: {", ".join(self._employeds)}')
328+
329+
330+
class GeneralManager(Manager):
331+
def functions(self):
332+
log(f'General Manager ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Supervising Employees: {", ".join(self._employeds)}')
333+
334+
335+
# Creating instances
336+
s1 = Secretary('0023', 'Gabriela Mistral', 'Secretary')
337+
d12 = Developer('0041', 'Niko Zen', 'Web Developer', ['Python', 'JavaScript', 'Rust', 'Ruby', 'Bash'])
338+
m3 = Manager('0098', 'Patty Smith', 'Manager', [s1.name, d12.name])
339+
mg2 = GeneralManager('003', 'Lenny Kravitz', 'General Manager', [m3.name])
340+
341+
342+
# Logging the outputs
343+
log(s1.employed_data())
344+
# Output: {'id': '0023', 'name': 'Gabriela Mistral', 'occupation': 'Secretary'}
345+
346+
d12.functions()
347+
# Output: Developer ID: 0041 | Name: Niko Zen | Occupation: Web Developer | Area: None | Languages: Python, JavaScript, Rust, Ruby, Bash
348+
349+
m3.functions()
350+
# Output: Manager ID: 0098 | Name: Patty Smith | Occupation: Manager | Supervising Employees: Gabriela Mistral, Niko Zen
351+
352+
mg2.functions()
353+
# Output: General Manager ID: 003 | Name: Lenny Kravitz | Occupation: General Manager | Supervising Employees: Patty Smith
354+

0 commit comments

Comments
 (0)