- como das chaves chegamos aos valores
- como dos valores encontramos as chaves
- as consequências de os dicionários não serem ordenados
Do mesmo modo somos confrontados com a possibilidade de reutilizar código, o que nos leva ao conceito de programação por abstracções. Podemos chegar a estes resultados sejam por um processo da base para o topo (como quem brinca com um Lego), seja do topo para a base. Esta última observação é importante, porque nos dá um princípio fundamental da programação: construir soluções por etapas sucessivas, decompondo o problema inicial em sub-problemas mais simples, cuja solução vai sendo obtida por refinamento da solução corrente. Dizemos que usamos camadas de abstracção.
Mas comecemos as nossas soluções definindo os dois tijolos básicos: (1) a partir de um nome obtemos os seus descendentes e (2) a partir de um descendente obtemos o seu progenitor.
01.
def
filhos(dicio,progenitor):
02.
""" Lista dos filhos/descendentes."""
03.
return
dicio.get(progenitor,[])
04.
05.
def
progenitor(dic, nome):
06.
""" Devolve o progenitor do nome."""
07.
for
chave, valor
in
dic.items():
08.
if
nome
in
valor:
09.
return
chave
10.
return
[]
Note-se como decidimos que na ausência de resposta (um pai sem filhos, alguém que não consta na árvore genealógica) o resultado a devolver é a lista vazia. Esta decisão tem consequências. Veja-se também que é mais natural resolver problemas em que a procura vai no sentido chave --> valor. Finalmente, atente-se no modo como percorremos o dicionário através dos seus elementos. Não havendo ordem não podemos aspirar a procura por aquilo que não existe: índices.
A partir destes elementos os outros problemas têm soluções fáceis.
Irmãos = filhos do mesmo progenitor
1.
def
irmaos(dic,nome1,nome2):
2.
""" Têm o mesmo progenitor?"""
3.
prog1
=
progenitor(dic, nome1)
4.
prog2
=
progenitor (dic,nome2)
5.
return
prog1
=
=
prog2
O que acontece se ambos os nomes não constarem no dicionário? Bem, vamos ter listas vazias a serem devolvidas... e o resultado será True, ou seja, são irmãos. Isto resulta do modo como implementámos a função progenitor. Pode ser corrigido:
1.
def
irmaos(dic,nome1,nome2):
2.
""" Têm o mesmo progenitor?"""
3.
prog1
=
progenitor(dic, nome1)
4.
prog2
=
progenitor (dic,nome2)
5.
if
prog1
and
prog2:
6.
return
prog1
=
=
prog2
7.
else
:
8.
return
False
Netos = filhos dos filhos
1.
def
netos(dicio,progenitor):
2.
""" Lista netos."""
3.
net
=
[]
4.
for
elem
in
filhos(dicio,progenitor):
5.
net.extend(filhos(dicio,elem))
6.
return
net
Veja-se a necessidade de usar o método extend. É comum o erro de usar antes append.
Avo = progenitor do progenitor
1.
def
avo(dic,nome):
2.
""" Quem é o/a avô/avó do nome."""
3.
return
progenitor(dic,progenitor(dic,nome))
Mais palavras para quê? Talvez para dizer de novo que perante um problema, a primeira coisa a fazer é ... pensar no problema, e definir uma estratégia para o resolver. Sem ter problemas em pensar assim: se eu tivesse esta funcionalidade então era fácil. Implementar uma solução provisória que depende da existência dessa funcionalidade. Pesquisar para ver se a linguagem a oferece. Em caso de resposta negativa, criar as funções auxiliares que a permitam implementar.
Sem comentários:
Enviar um comentário