Você foi contratado para desenvolver o Noble Knots, o mais badalado aplicativo de relacionamentos para a nobreza! Com séculos de casamentos entre a realeza, as coisas ficaram… complicadas. Para evitar qualquer situação do tipo opa, somos gêmeos, sua tarefa é construir um sistema que verifica o quão próximo é o parentesco entre duas pessoas.
O Noble Knots foi inspirado no "Islendinga-App" da Islândia, que tem por trás um banco de dados que traça todas as conexões familiares conhecidas entre islandeses desde o povoamento da Islândia. Seu algoritmo vai determinar o grau de separação entre duas pessoas na árvore genealógica da realeza.
Será que seu aplicativo vai ajudar a coroar o par perfeito?
Sua tarefa é determinar o grau de separação entre duas pessoas em uma árvore genealógica. Isso é parecido com a ideia da cultura pop de que todo ator de Hollywood está a seis graus de Kevin Bacon.
Dada a seguinte árvore genealógica:
┌──────────┐ ┌──────────┐ ┌───────────┐
│ Helena │ │ Erdős ├─────┤ Shusaku │
└───┬───┬──┘ └─────┬────┘ └────┬──────┘
┌───┘ └───────┐ └───────┬───────┘
┌─────┴────┐ ┌────┴───┐ ┌─────┴────┐
│ Isla ├─────┤ Tariq │ │ Kevin │
└────┬─────┘ └────┬───┘ └──────────┘
│ │
┌────┴────┐ ┌────┴───┐
│ Uma │ │ Morphy │
└─────────┘ └────────┘
O grau de separação entre Tariq e Uma é 2 (Tariq → Isla → Uma). Não há relação conhecida entre Isla e Kevin, já que não existe conexão nos dados fornecidos. O grau de separação entre Uma e Isla é 1.
Isla e Tariq são irmãos e têm uma separação de 1. Da mesma forma, esta implementação reportaria uma separação de 2 entre você e o irmão do seu pai.
Os testes deste exercício esperam que sua solução seja implementada como uma class RelativeDistance em Python.
Se você ainda não conhece classes em Python, classes e classes na documentação oficial do Python são bons pontos de partida.
RelativeDistance deve ser inicializado (veja __init__() para mais informações) usando family_tree, um dicionário em que as keys são indivíduos e os values são lists dos filhos desse indivíduo.
Você também vai precisar implementar um método degree_of_separation, que retorna o grau de separação entre person_a e person_b, que são indivíduos na árvore genealógica passada.
Você recebe uma implementação esboçada do método especial __init__ usado para criar uma instância da classe RelativeDistance, bem como um esboço do método degree_of_separation.
Primeiro, você vai precisar personalizar o __init__ com um atributo apropriado em self (a instância) para representar os dados de family_tree.
Depois, você pode adicionar sua lógica ao método degree_of_separation para calcular o grau de separação entre person_a e person_b.
Às vezes, é necessário lançar uma exceção. Quando fizer isso, sempre inclua uma mensagem de erro significativa para indicar qual é a origem do erro. Isso deixa seu código mais legível e ajuda bastante na depuração. Para situações em que você sabe que a origem do erro será de um determinado tipo, você pode optar por lançar um dos tipos de erro integrados, mas ainda assim deve incluir uma mensagem significativa.
Este exercício em particular exige que você use a instrução raise para "lançar" vários ValueErrors.
No primeiro cenário, você vai precisar lançar um ValueError quando uma ou ambas as pessoas passadas ao método RelativeDistance.degree_of_separation não estiverem presentes na árvore genealógica.
# Example when Person A is not in the tree.
raise ValueError("Person A not in family tree.")
Se as duas pessoas estiverem presentes na árvore genealógica, você vai precisar lançar um ValueError quando não houver nenhuma conexão válida entre elas, conforme definido pelas regras.
# Example when there are no valid connections.
raise ValueError("No connection between person A and person B.")
Os testes só vão passar se você raise o tipo de exception esperado e incluir também a mensagem esperada.
Confira os testes e os resultados esperados com atenção, porque estas instruções não são exaustivas.
Crie sua conta no Exercism para aprender e dominar Python com 17 conceitos146 exercícios e mentoria humana de verdade, tudo de graça.