Skip to content

Commit

Permalink
Merge pull request #5708 from neslarra/patch-47
Browse files Browse the repository at this point in the history
Reto# 34 - python
  • Loading branch information
Roswell468 committed Aug 22, 2024
2 parents ae2eef3 + 629bdd1 commit 2527181
Showing 1 changed file with 329 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
"""
EJERCICIO:
¡La Casa del Dragón ha finalizado y no volverá hasta 2026!
¿Alguien se entera de todas las relaciones de parentesco
entre personajes que aparecen en la saga?
Desarrolla un árbol genealógico para relacionarlos (o invéntalo).
Requisitos:
1. Estará formado por personas con las siguientes propiedades:
- Identificador único (obligatorio)
- Nombre (obligatorio)
- Pareja (opcional)
- Hijos (opcional)
2. Una persona sólo puede tener una pareja (para simplificarlo).
3. Las relaciones deben validarse dentro de lo posible.
Ejemplo: Un hijo no puede tener tres padres.
Acciones:
1. Crea un programa que permita crear y modificar el árbol.
- Añadir y eliminar personas
- Modificar pareja e hijos
2. Podrás imprimir el árbol (de la manera que consideres).
NOTA: Ten en cuenta que la complejidad puede ser alta si
se implementan todas las posibles relaciones. Intenta marcar
tus propias reglas y límites para que te resulte asumible.
"""
from typing import Literal


class Relationship:

def __init__(self, relation: Literal["single", "spouse", "parent", "child"]):
self.relation = []
self.add_relation(relation)

def add_relation(self, relation: Literal["single", "spouse", "parent", "child"]):
self.relation.append(relation)

def drop_relation(self, relation: Literal["single", "spouse", "parent", "child"]):
self.relation.remove(relation)


class Person(Relationship):

id = 0
people = []

def __init__(self, name: str, gender: Literal["F", "M"]):
super().__init__("single")
self.name = name.title()
self.gender = gender
self.spouse = None
self.parents = []
self.children = []
self.id = self.set_id()
Person.people.append(self)

@classmethod
def set_id(cls):
cls.id += 1
return cls.id

@classmethod
def get_people(cls):
def sort_people(p):
return p.get_name()

cls.people.sort(key=sort_people)
return cls.people

def get_id(self):
return self.id

def get_name(self):
return self.name

def get_parent(self):
return self.parents

def get_children(self):
return self.children

def is_maried(self):
return self.spouse

def get_relations(self):
return self.relation

def set_spouse(self, spouse):
if "spouse" in self.get_relations():
return False
self.spouse = spouse
self.drop_relation("single")
self.add_relation("spouse")
return True

def set_parents(self, parents):

def restrictions():
if self in parents:
print(f"No se puede ser padre de uno mismo")
return True
if self.parents:
print(f"Ya tiene padres")
return True
if parents.__len__() > 1:
if parents[0] == parents[1]:
print(f"Ambos padres NO pueden ser la misma persona.")
return True
if parents[0] != parents[1].is_maried():
print(f"Los padres NO estan casados.")
return True
return False

if restrictions():
return False

self.parents.append(parents[0])
if self not in parents[0].get_children():
parents[0].set_children([self])
if parents.__len__() > 1:
self.parents.append(parents[1])
if self not in parents[1].get_children():
parents[1].set_children([self])
if "child" not in self.get_relations():
self.add_relation("child")
return True

def set_children(self, children):
for child in children:
if child not in self.get_children():
self.children.append(child)
if "child" not in child.get_relations():
child.add_relation("child")
if "parent" not in self.get_relations():
self.add_relation("parent")


def are_siblings(person1: Person, person2: Person):

for parent in person1.get_parent():
if person2 in parent.get_children():
return True

for parent in person2.get_parent():
if person1 in parent.get_children():
return True

return False


def get_married(person1: Person, person2: Person):

if person1 == person2:
print(f"No se puede casar consigo mismo")
else:
p1_married = person1.is_maried()
p2_married = person2.is_maried()
siblings = are_siblings(person1, person2)
p1_son = person1 in person2.get_children()
p2_son = person1 in person1.get_children()
p1_parent = person1 in person2.get_parent()
p2_parent = person1 in person1.get_parent()
if any([p1_married, p2_married]):
print(f"No se pueden casar: bigamia")
elif any([siblings, p1_son, p2_son, p1_parent, p2_parent]):
print(f"No se pueden casar: consanguinidad")
else:
person1.set_spouse(person2)
person2.set_spouse(person1)


def menu():
option = -1

print("\n\tElegir una persona para mostrar el árbol genealógico\n")
for index, person in enumerate(Person.get_people()):
print(f"\t{index + 1} - {person.get_name()}")
print(f"\t0 - Salir")
while option < 0 or option > Person.get_people().__len__():
option = input(f"\n\tIngrese una opción [1 - {Person.get_people().__len__()} | 0 para salir]: ")
if not option.isnumeric():
option = -1
else:
option = int(option)
return Person.get_people()[option - 1] if option > 0 else None


def load_generations():
# Primera generación
tito = Person("Tito", "M")
livia = Person("Livia", "F")
chacho = Person("Chacho", "M")
tina = Person("Tina", "F")
romula = Person("Romula", "F")

get_married(tito, livia)
get_married(chacho, tina)

# Segunda generación
turula = Person("Turula", "F")
pepe = Person("Pepe", "M")
papo = Person("Papo", "M")
pipa = Person("Pipa", "F")
soto = Person("Soto", "M")
rema = Person("Rema", "F")
roma = Person("Roma", "F")

for child in [turula, pepe, papo]:
child.set_parents([tito, livia])

for child in [pipa, soto]:
child.set_parents([chacho, tina])

for child in [rema, roma]:
child.set_parents([romula])

get_married(turula, soto)
get_married(pepe, pipa)
get_married(papo, roma)

# Tercera generación
tita = Person("Tita", "F")
sita = Person("Sita", "F")
pipo = Person("Pipo", "M")
pepa = Person("Pepa", "F")
chino = Person("Chino", "M")
ramo = Person("Ramo", "M")
rima = Person("Rima", "F")

for child in [tita, sita]:
child.set_parents([turula, soto])

for child in [pipo, pepa, chino]:
child.set_parents([pepe, pipa])

for child in [ramo, rima]:
child.set_parents([rema])

get_married(tita, ramo)
get_married(pipo, rima)

# Cuarta generación
paco = Person("Paco", "M")
chicho = Person("Chicho", "M")
chona = Person("Chona", "F")
chano = Person("Chano", "M")
rama = Person("Rama", "F")

paco.set_parents([tita, ramo])

for child in [chicho, chona, chano]:
child.set_parents([pipo, rima])

rama.set_parents([sita])

# Quinta generación
pico = Person("Pico", "M")

pico.set_parents([paco])


def show_tree(person: Person, level: int = 0, iteration: int = 0, tree=None):
if tree is None:
tree = {0: [], 1: [], 2: []}
message = ""
for relationship in person.get_relations():
match relationship, level:
case "child", 0:
parents = []
siblings = []
for parent in person.get_parent():
parents.append(parent.get_name())
show_tree(parent, 1, iteration + 1, tree)
for sibling in person.get_parent()[0].get_children():
if person != sibling:
siblings.append(sibling.get_name())
message = f"\t{person.get_name()} es {'hijo' if person.gender == 'M' else 'hija'} de " + f"{', '.join(parents)}"
if siblings:
message += f"\n\t{person.get_name()} es {'hermano' if person.gender == 'M' else 'hermana'} de " + f"{', '.join(siblings)}"
if message not in tree[level]:
tree[level].append(message)
case "spouse", 0:
message = f"\t{person.get_name()} está {'casado' if person.gender == 'M' else 'casada'} con {person.spouse.get_name()}"
if message not in tree[level]:
tree[level].append(message)
case "parent", 0:
children = []
for child in person.get_children():
children.append(child.get_name())
show_tree(child, 2, iteration + 1, tree)
message = f"\t{person.get_name()} es {'padre' if person.gender == 'M' else 'madre'} de " + f"{', '.join(children)}"
if message not in tree[level]:
tree[level].append(message)
case "single", 0:
message = f"\t{person.get_name()} es {'soltero' if person.gender == 'M' else 'soltera'}"
if message not in tree[level]:
tree[level].append(message)
case "child", 1:
parents = []
for parent in person.get_parent():
parents.append(parent.get_name())
show_tree(parent, 1, iteration + 1, tree)
message = f"\t{'-' * 5 * iteration + '> '}{person.get_name()} es {'hijo' if person.gender == 'M' else 'hija'} de " + f"{', '.join(parents)}"
if message not in tree[level]:
tree[level].append(message)
case "parent", 2:
children = []
for child in person.get_children():
children.append(child.get_name())
show_tree(child, 2, iteration + 1, tree)
message = f"\t{'-' * 5 * iteration + '> '}{person.get_name()} es {'padre' if person.gender == 'M' else 'madre'} de " + f"{', '.join(children)}"
if message not in tree[level]:
tree[level].append(message)
# tree[level].append(message)
return tree


load_generations()
while True:
person = menu()
if not person:
break
tree = show_tree(person)
tree[2].sort(reverse=True)
print(f"\n\t## Árbol {'#' * 30}\n")
for level in (1, 0, 2):
for msg in tree[level]:
print(msg)
print(f"\n\t{'#' * 40}")

0 comments on commit 2527181

Please sign in to comment.