¡Te han contratado para desarrollar Noble Knots, la nueva aplicación de citas para la nobleza que está causando furor! Tras siglos de matrimonios entre familias reales, las cosas se han vuelto… complicadas. Para evitar cualquier situación del tipo vaya, resulta que somos gemelos, tu trabajo consiste en construir un sistema que compruebe el grado de parentesco entre dos personas.
Noble Knots se inspira en la «Islendinga-App» islandesa, que se apoya en una base de datos que rastrea todos los vínculos familiares conocidos entre islandeses desde la época de la colonización de Islandia. Tu algoritmo determinará el grado de separación entre dos personas del árbol genealógico de la realeza.
¿Ayudará tu aplicación a coronar a la pareja perfecta?
Tu tarea consiste en determinar el grado de separación entre dos personas de un árbol genealógico. Es parecido a la idea popular de que cualquier actor de Hollywood está a menos de seis grados de Kevin Bacon.
Dado el siguiente árbol genealógico:
┌──────────┐ ┌──────────┐ ┌───────────┐
│ Helena │ │ Erdős ├─────┤ Shusaku │
└───┬───┬──┘ └─────┬────┘ └────┬──────┘
┌───┘ └───────┐ └───────┬───────┘
┌─────┴────┐ ┌────┴───┐ ┌─────┴────┐
│ Isla ├─────┤ Tariq │ │ Kevin │
└────┬─────┘ └────┬───┘ └──────────┘
│ │
┌────┴────┐ ┌────┴───┐
│ Uma │ │ Morphy │
└─────────┘ └────────┘
El grado de separación entre Tariq y Uma es 2 (Tariq → Isla → Uma). No hay ninguna relación conocida entre Isla y Kevin, ya que no existe conexión en los datos proporcionados. El grado de separación entre Uma e Isla es 1.
Isla y Tariq son hermanos y tienen una separación de 1. Del mismo modo, esta implementación indicaría una separación de 2 entre tú y el hermano de tu padre.
Las pruebas de este ejercicio esperan que tu solución se implemente como una class RelativeDistance en Python.
Si no estás familiarizado con las classes en Python, classes y classes en la documentación oficial de Python son buenos puntos de partida.
RelativeDistance debe inicializarse (consulta __init__() para más información) usando family_tree, un diccionario en el que las keys son individuos y los values son lists de los hijos de ese individuo.
También tendrás que implementar un método degree_of_separation que devuelva el grado de separación entre person_a y person_b, que son individuos del árbol genealógico que se pasa.
Se te da una implementación esbozada para el método especial __init__ que se usa para crear una instancia de la clase RelativeDistance, así como un esbozo del método degree_of_separation.
En primer lugar, tendrás que personalizar el __init__ con un atributo adecuado en self (la instancia) que represente los datos de family_tree.
Después podrás añadir tu lógica al método degree_of_separation para calcular el grado de separación entre person_a y person_b.
A veces es necesario lanzar una excepción. Cuando lo hagas, siempre debes incluir un mensaje de error significativo que indique cuál es el origen del error. Esto hace que tu código sea más legible y ayuda mucho a la hora de depurar. En los casos en los que sepas que el origen del error será de un tipo concreto, puedes optar por lanzar uno de los tipos de error integrados, pero aun así deberías incluir un mensaje significativo.
Este ejercicio en concreto requiere que uses la instrucción raise para «lanzar» varios ValueErrors.
En el primer caso, tendrás que lanzar un ValueError cuando una de las dos personas, o ambas, que se pasan al método RelativeDistance.degree_of_separation no estén presentes en el árbol genealógico.
# Example when Person A is not in the tree.
raise ValueError("Person A not in family tree.")
Si ambas personas están presentes en el árbol genealógico, tendrás que lanzar un ValueError cuando no exista una conexión válida entre ellas según lo definido por las reglas.
# Example when there are no valid connections.
raise ValueError("No connection between person A and person B.")
Las pruebas solo pasarán si lanzas el tipo de exception esperado y además incluyes junto a él el mensaje esperado.
Revisa con atención las pruebas y sus resultados esperados, ya que estas instrucciones no son exhaustivas.
Regístrate en Exercism para aprender y dominar Python con 17 conceptos146 ejercicios y mentoría humana real, todo gratis.