Percursos
/
Python
Python
/
Exercícios
/
Caça ao Tesouro de Tisbury
Caça ao Tesouro de Tisbury

Caça ao Tesouro de Tisbury

Exercício de aprendizagem

Introdução

Em Python, um tuplo é uma coleção imutável de itens em sequência. Como a maioria das coleções, os tuples podem conter qualquer tipo de dados (ou vários), incluindo outros tuples. Os tuplos suportam todas as operações comuns de sequências, mas não suportam operações de sequências mutáveis.

Podes iterar sobre os elementos de um tuplo com a construção for item in <tuple>. Se precisares tanto do índice como do valor do elemento, podes usar for index, item in enumerate(<tuple>). Como em qualquer sequência, podes aceder aos elementos dentro de tuples através de notação de parênteses retos, usando um 0-based index a contar da esquerda ou um -1-based index a contar da direita. Também podes copiar tuplos, total ou parcialmente, usando a notação de fatias (<tuple>[<start>:<stop>:<step>]).

Construção de tuplos

Podes formar tuplos de várias formas, usando o construtor da classe tuple(<iterable>) ou a declaração literal tuple.

Usar o construtor tuple() vazio ou com um iterável:

>>> no_elements = tuple()
()

# The constructor *requires* an iterable, so single elements must be passed in a list or another tuple.
>>> one_element = tuple([16])
(16,)

As strings são iteráveis, por isso usar um único str como argumento do construtor tuple() pode dar resultados surpreendentes:

# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')

Nos iteráveis únicos, os elementos são adicionados um a um:

>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)

>>> multiple_elements_set = tuple({2, 3, 5, 7, 11})
(2,3,5,7,11)
Declarar um tuplo como literal:

Como o construtor tuple(<iterable>) só aceita iteráveis (ou nada) como argumentos, é muito mais fácil criar um tuplo de um só elemento com o método literal.

>>> no_elements = ()
()

>>> one_element = ("Guava",)
("Guava",)

Podes incluir estruturas de dados aninhadas como elementos de um tuple, incluindo outros tuples:

>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))

>>> nested_data_structures_1 = (["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
(["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))

Concatenação de tuplos

Podes concatenar tuplos com o operador de adição +, que desempacota cada tuple e cria um novo tuple combinado.

>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby")
("George", 5, "cat", "Tabby")

#likewise, using the multiplication operator * is the equivalent of using + n times
>>> first_group = ("cat", "dog", "elephant")

>>> multiplied_group = first_group * 3
('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant')

Aceder aos elementos dentro de um tuplo

Podes aceder aos elementos dentro de um tuple através de notação de parênteses retos, usando um 0-based index a contar da esquerda ou um -1-based index a contar da direita.

student_info = ("Alyssa", "grade 3", "female", 8 )

#gender is at index 2 or index -2
>>> student_gender = student_info[2]
'female'

>>> student_gender = student_info[-2]
'female'

#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa

>>> student_name = student_info[-4]
Alyssa

Iterar sobre os elementos de um tuplo

Podes iterar sobre os elementos dentro de um tuple num ciclo, usando a sintaxe for item in <tuple>. Se precisares tanto dos índices como dos valores, podes usar for index, item in enumerate(<tuple>).

>>> student_info = ("Alyssa", "grade 3", "female", 8 )
>>> for item in student_info:
...   print(item)

...
Alyssa
grade 3
female
8

>>> for index, item in enumerate(student_info):
...  print("Index is: " + str(index) + ", value is: " + str(item) +".")

...
Index is: 0, value is: Alyssa.
Index is: 1, value is: grade 3.
Index is: 2, value is: female.
Index is: 3, value is: 8.

Verificar a pertença num tuplo

Podes usar o operador in para verificar se um elemento pertence a um tuple.

>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)

>>> "Parrot" in multiple_elements_list
True

Instruções

A Azara e o Rui são colegas de equipa numa caça ao tesouro com tema pirata. Um tem uma lista de tesouros com coordenadas do mapa, o outro uma lista de nomes de locais com coordenadas do mapa. Também receberam mapas em branco com o ponto de partida assinalado com as palavras ESTÁS AQUI.


Lista da Azara Lista do Rui
Tesouro Coordenadas
Amethyst Octopus 1F
Angry Monkey Figurine 5B
Antique Glass Fishnet Float 3D
Brass Spyglass 4B
Carved Wooden Elephant 8C
Crystal Crab 6A
Glass Starfish 6D
Model Ship in Large Bottle 8A
Pirate Flag 7F
Robot Parrot 1C
Scrimshawed Whale Tooth 2A
Silver Seahorse 4E
Vintage Pirate Hat 7E
Nome do Local Coordenadas Quadrante
Seaside Cottages ("1", "C") Blue
Aqua Lagoon (Island of Mystery) ("1", "F") Yellow
Deserted Docks ("2", "A") Blue
Spiky Rocks ("3", "D") Yellow
Abandoned Lighthouse ("4", "B") Blue
Hidden Spring (Island of Mystery) ("4", "E") Yellow
Stormy Breakwater ("5", "B") Purple
Old Schooner ("6", "A") Purple
Tangled Seaweed Patch ("6", "D") Orange
Quiet Inlet (Island of Mystery) ("7", "E") Orange
Windswept Hilltop (Island of Mystery) ("7", "F") Orange
Harbor Managers Office ("8", "A") Purple
Foggy Seacave ("8", "C") Purple

Mas as coisas estão um pouco desorganizadas: as coordenadas da Azara parecem estar formatadas e ordenadas de forma diferente das do Rui, e eles têm de andar sempre a olhar de uma lista para a outra para perceber que tesouros correspondem a que locais. Como são aspirantes a pythonistas, vieram pedir-te ajuda para escrever um pequeno programa (na verdade, um conjunto de funções) para organizar melhor a informação da sua caça ao tesouro.

1. Extrair coordenadas

Implementa a função get_coordinate() que recebe um par (treasure, coordinate) da lista da Azara e devolve apenas a coordenada do mapa extraída.

>>> get_coordinate(('Scrimshawed Whale Tooth', '2A'))
2A

2. Formatar coordenadas

Implementa a função convert_coordinate() que recebe uma coordenada no formato "2A" e devolve um tuplo no formato ("2", "A").

>>> convert_coordinate("2A")
("2", "A")

3. Comparar coordenadas

Implementa a função compare_records() que recebe um par (treasure, coordinate) e um registo (location, coordinate, quadrant) e compara as coordenadas de cada um. Devolve True se as coordenadas "corresponderem" e devolve False se não corresponderem. Reformata as coordenadas conforme for necessário para uma comparação correta.

>>> compare_records(('Brass Spyglass', '4B'), ('Seaside Cottages', ('1', 'C'), 'blue'))
False

>>> compare_records(('Model Ship in Large Bottle', '8A'), ('Harbor Managers Office', ('8', 'A'), 'purple'))
True

4. Combinar registos correspondentes

Implementa a função create_record() que recebe um par (treasure, coordinate) da lista da Azara e um registo (location, coordinate, quadrant) da lista do Rui e devolve (treasure, coordinate, location, coordinate, quadrant) se as coordenadas corresponderem. Se as coordenadas não corresponderem, devolve a string "not a match". Reformata a coordenada conforme for necessário para uma comparação correta.

>>> create_record(('Brass Spyglass', '4B'), ('Abandoned Lighthouse', ('4', 'B'), 'Blue'))
('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')

>>> create_record(('Brass Spyglass', '4B'), ('Seaside Cottages', ('1', 'C'), 'blue'))
"not a match"

5. "Limpar" e fazer um relatório de todos os registos

Limpa os registos combinados da Azara e do Rui para que fique apenas um conjunto de coordenadas por registo. Faz um relatório para que eles possam ver uma única lista de tudo o que precisam de colocar nos seus mapas. Implementa a função clean_up() que recebe um tuplo de tuplos (tudo das duas listas), percorrendo o tuplo mais externo, descartando as coordenadas indesejadas de cada tuplo mais interno e adicionando cada um a um 'relatório'. Formata e devolve o 'relatório' de forma a que fique um registo limpo em cada linha.

>>> clean_up((('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), ('Vintage Pirate Hat', '7E', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), ('Crystal Crab', '6A', 'Old Schooner', ('6', 'A'), 'Purple')))

"""
('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n
('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n
('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n
"""
Editar via GitHub A ligação abre numa nova janela ou separador
Python Exercism

Estás pronto para começar Caça ao Tesouro de Tisbury?

Inscreve-te no Exercism para aprenderes e dominares Python com 17 conceitos146 exercícios, e mentoria humana real, tudo grátis.