From 14e16ef0e72c43fc2bfa5f18478327feb70aed64 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:09:42 -0700 Subject: [PATCH 01/27] New tuples concept exercise design file. --- .../exercises/concept/tuples/.meta/design.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.meta/design.md diff --git a/languages/python/exercises/concept/tuples/.meta/design.md b/languages/python/exercises/concept/tuples/.meta/design.md new file mode 100644 index 0000000000..82eff955de --- /dev/null +++ b/languages/python/exercises/concept/tuples/.meta/design.md @@ -0,0 +1,46 @@ +## Learning Objectives + +- Access values in a tuple via index using [] (bracket notation). +- Create a tuple via constructor (tuple(_iterable_)) and/or literal (a,b,c or (a, b, c)) +- Understand that tuples are an **immutable data type** (like Strings). Changing a tuple means creating a new copy. +- Understand that tuples can contain other tuples. (e.g. tuples can be nested). +- Create a new tuple from two or more previous tuples via concatenation using the **+** operator. +- Create a new tuple by multiplying a previous tuple using the **`*`** operator. +- Iterate through a tuple using **`for item in`**. +- Check for membership of an item in a given tuple using the **`in`** keyword. +- Understand that it is the comma in a sequence that makes a tuple, and that the () are optional, except for denoting an empty tuple or when omitting them creates ambiguity. + +## Out of Scope + +- Common Sequence type methods such as `min()`, `max()`, `x.index()`, `x.count()`, `len()` +- Slicing or slice notation ([start:stop:step]) +- Additional builtin functions as they relate to this data structure (e.g. `sorted()`, `enumerate()`, `reversed()`, or `hash()`. +- Knowing that tuples can be used as objects in other data structures, -- e.g. " a "List of tuples", "tuples as keys in Dictionaries", ,or "A Set of tuples". +- Hash-ability and when a tuple is not hash-able. +- Related [collections](https://docs.python.org/3/library/collections.html#collections.namedtuple)) module with `namedtuple()` +- Related [dataclass](https://docs.python.org/3.7/library/dataclasses.html) and `@dataclass` decorator +- Memory storage and performance characteristics. + +## Concepts + +- tuples +- immutability +- indexing +- concatenation and multiplication of type +- iteration + +## Prerequisites + +- bool (True/False) +- for loops +- functions +- if keyword +- in keyword +- int +- print +- return keyword +- str + + + + From b6561f02eba26de37293d52e7ad8b580535c78eb Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:10:10 -0700 Subject: [PATCH 02/27] New tuples concept exercise example implementation file. --- .../exercises/concept/tuples/.meta/example.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.meta/example.py diff --git a/languages/python/exercises/concept/tuples/.meta/example.py b/languages/python/exercises/concept/tuples/.meta/example.py new file mode 100644 index 0000000000..2a47ba3e62 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.meta/example.py @@ -0,0 +1,27 @@ + +def get_coordinate(record): + return record[1] + +def convert_coordinate(coordinate): + # alt return tuple(coordinate) + return coordinate[0], coordinate[1] + + +def compare_records(azara_record, rui_record): + return tuple(azara_record[1]) in rui_record + +def create_record(azara_record, rui_record): + if compare_records(azara_record, rui_record): + return azara_record + rui_record + else: + return "not a match" + +def clean_up(combined_record_group): + for item in combined_record_group: + print((item[0], item[2], item[3], item[4])) + +def multiply_records(combined_record_group): + group_for_three = combined_record_group * 3 + + for item in group_for_three: + print(item) From 4fe62d69a7f240d8e6c07bab37fb2f365ea85615 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:10:41 -0700 Subject: [PATCH 03/27] New tuples concept exercise config file. --- .../python/exercises/concept/tuples/.meta/config.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.meta/config.json diff --git a/languages/python/exercises/concept/tuples/.meta/config.json b/languages/python/exercises/concept/tuples/.meta/config.json new file mode 100644 index 0000000000..b18ff2f7d0 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.meta/config.json @@ -0,0 +1,8 @@ +{ + "authors": [ + { + "github_username": "bethanyg", + "exercism_username": "BethanyG" + } + ], +} From a96dd0b997becafa5b7f69ab7583c83e804b215a Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:11:38 -0700 Subject: [PATCH 04/27] New tuples concept exercist after file w TODO. --- languages/python/exercises/concept/tuples/.docs/after.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 languages/python/exercises/concept/tuples/.docs/after.md diff --git a/languages/python/exercises/concept/tuples/.docs/after.md b/languages/python/exercises/concept/tuples/.docs/after.md new file mode 100644 index 0000000000..f9bf1abc13 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.docs/after.md @@ -0,0 +1 @@ +#TODO From 54b711b0ced7f593a773a4f5cba78a176f342e8f Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:12:11 -0700 Subject: [PATCH 05/27] New tuples concept exercist hints file. --- .../exercises/concept/tuples/.docs/hints.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.docs/hints.md diff --git a/languages/python/exercises/concept/tuples/.docs/hints.md b/languages/python/exercises/concept/tuples/.docs/hints.md new file mode 100644 index 0000000000..4eda4da704 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.docs/hints.md @@ -0,0 +1,50 @@ +## General + +* [Tuples](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) are immutable. +[Sequence Types](https://docs.python.org/3/library/stdtypes.html#typesseq) that can contain any data type. +* Tuples are [iterable](https://docs.python.org/3/glossary.html#term-iterable). +* Elements within tuples can be accessed via [bracket notation](https://stackoverflow.com/questions/30250282/whats-the-difference-between-the-square-bracket-and-dot-notations-in-python), using a zero-based index. +* Other [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) can also be used when working with tuples. + +___ + + + +### 1. Retrieve and return the map coordinates from and item on Azaras list. + +* Remember: tuples allow access via _index_, using _brackets_. Indexes start at zero. + + + +### 2. Format coordinates from Azaras list to match coordinates from Ruis list. + +* The `tuple` constructor will take _any iterable_ as an argument, unpack it, and return a tuple. +* Strings are iterable in python. + + + +### 3. Check to see if a record from Azaras list "matches" a record from Ruis list. + +* [in keyword](https://docs.python.org/3/reference/expressions.html#membership-test-operations) for testing membership. +* The `tuple()` constructor will make a tuple from _any iterable_. + + + + +### 4. Combine a record from Azaras list with a record from Ruis IF they are at the same coordinates. + +* [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) +* Could you use the `compare_records()` function here? + + +### 5. "Clean up" & print out the records from Azara and Rui so that there's only one set of coordinates per record, and they have a list of everything they need to put on the map. + + +* Remember: tuples are _immutable_, but the contents can be accessed via _index_ using _bracket notation_. +* Tuples don't have to use parentheses unless there is _ambiguity_. + + +### 6. There's been a last minute addition to the team! Since there are now three team members sharing the combined info, there needs to be three "complete" record groups to refer to. + +* [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) + From ba790778221c93af30b8f042793e9c6a6acc687d Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:30:51 -0700 Subject: [PATCH 06/27] New tuples concept exercise introduction file. --- .../concept/tuples/.docs/introducton.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.docs/introducton.md diff --git a/languages/python/exercises/concept/tuples/.docs/introducton.md b/languages/python/exercises/concept/tuples/.docs/introducton.md new file mode 100644 index 0000000000..3c17e1cc6d --- /dev/null +++ b/languages/python/exercises/concept/tuples/.docs/introducton.md @@ -0,0 +1,148 @@ +In Python, a tuple is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). + +Tuples take up very little memory space compared to other collection types and have constant (_O(1)_) access time. However, they cannot be resized, sorted, or altered once created, so are less flexible when frequent changes or updates to data are needed. + + +## Tuple Construction + +Tuples can be formed in multiple ways, using either the `tuple` class constructor or the `tuple` literal declaration. + +### Using the `tuple()` constructor empty or with an _iterable_: + +```python +no_elements = tuple() +>>> () + +#the string elements (characters) are iterated through and added to the tuple +multiple_elements_string = tuple("Timbuktu") +>>> ('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') + +multiple_elements_list = tuple(["Parrot", "Bird", 334782]) +>>> ("Parrot", "Bird", 334782) + +multiple_elements_set = tuple({2, 3, 5, 7, 11}) +>>> (2,3,5,7,11) + + +""" +The iteration default for dictionaries is over the keys. +To include both keys and values in a tuple made from a dictionary, use dict.items(), +which returns a list of (key, value) tuples. +""" +source_data = {"fish": "gold", "monkey": "brown"} +multiple_elements_dict_1 = tuple(source_data) +>>> ('fish', 'monkey') + +multiple_elements_dict_2 = tuple(source_data.items()) +>>> (('fish', 'gold'), ('monkey', 'brown')) + + +""" +because the tuple constructor only takes iterables (or nothing), it is much easier to create + a one-tuple via the literal method. +""" +one_element = tuple([16]) +>>> (16,) + +``` + +#### Declaring a tuple as a _literal_ : + +```python +no_elements = () +>>> () + +one_element = ("Guava",) +>>> ("Guava",) + +elements_separated_with_commas = "Parrot", "Bird", 334782 +>>> ("Parrot", "Bird", 334782) + +elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60) +>>> ("Triangle", 60, 60, 60) + +nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) +>>> ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) + +#using the plus + operator unpacks each tuple and creates a new tuple. +new_via_concatenate = ("George", 5) + ("cat", "Tabby") +>>> ("George", 5, "cat", "Tabby") + +#likewise, using the multiplication operator * is the equvilent of using + n times +first_group = ("cat", "dog", "elephant") + +multiplied_group = first_group * 3 +>>> ('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant') + +``` + +Note that generally parentheses are not _required_ to create a `tuple` literal - only commas. Parentheses are required in cases of ambiguity, such as an empty or one-item tuple or where a function takes a tuple as an argument. + + + +## Tuples as related information + +Tuples are often used as _records_ containing heterogeneous data that is _organizationally_ or _conceptually_ related and treated as a single unit of information. + +```python + +student_info = ("Alyssa", "grade 3", "female", 8 ) + +``` + +Tuples are also used when homogeneous immutable sequences of data are needed for hashability, storage in a set, or creation of keys in a dictionary. + +```python + +cmyk_color_map = { + (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292), + (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01), + (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E), + (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C) + } + +unique_rgb_colors = { + (59, 178, 146), + (247, 127, 1), + (89, 16, 142), + (140, 0, 76), + (76, 0, 140) + } + +teal_700 = hash((59, 178, 146)) + +``` + +## Accessing data inside a tuple + +Items inside tuples (_like the sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. Items inside tuples can also be _iterated over_ in a loop using `for item in` syntax. + +```python + +student_info = ("Alyssa", "grade 3", "female", 8 ) + +#name is at index 0 +student_name = student_info[0] + +#grade is at index 1 +student_grade = student_info[1] +>>> 'grade 3' + +#age is at index 3 or index -1 +student_age_1 = student_info[3] +>>> 8 + +student_age_2 = student_info[-1] +>>> 8 + + +for item in student_info: + print(item) + +>>> +Alyssa +grade 3 +female +8 +>>> +``` From 2dd31c12a6339abfe26c9cc587bf4bfe43190c38 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:31:35 -0700 Subject: [PATCH 07/27] New tuples concept exercise instructions file. --- .../concept/tuples/.docs/instructions.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/.docs/instructions.md diff --git a/languages/python/exercises/concept/tuples/.docs/instructions.md b/languages/python/exercises/concept/tuples/.docs/instructions.md new file mode 100644 index 0000000000..9297bb9547 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.docs/instructions.md @@ -0,0 +1,148 @@ +Aazra and Rui are teammates competing in a pirate-themed treasure hunt. One has a list of treasures with map coordinates, the other a list of location names with map coordinates. They've also been given blank maps with a starting place marked YOU ARE HERE. + + +
+ + + +
Azara's ListRui's List
+ +| Treasure | Coordinates | +|----------------------------- |------------- | +| 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 | +| Scrimshaw Whale's Tooth | 2A | +| Silver Seahorse | 4E | +| Vintage Pirate Hat | 7E | + + + +| Location Name | Coordinates | Quandrant | +|--------------------------------------- |------------- |----------- | +| 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 | +
+ +
+ +But things are a bit disorganized: Azaras coordinates appear to be formatted and sorted differently from Ruis, and they have to keep looking from one list to the other to figure out which treasures go with which locations. Being budding pythonistas, they've come to you for help in writing a small program (a set of functions, really) to better organize their hunt information. + + +## 1. Retrieve and return the map coordinates from an item on Azaras list. + +Given a `(treasure, coordinate)` pair from Azaras list, extract and return the part that represents the coordinate on the map by implementing the `get_cooordinate()` function. + + +​ +```python + +>>> get_coordinate(("Scrimshaw Whale's Tooth", "2A")) +>>> "2A" + +``` + + +​ +​ +## 2. Format coordinates from Azaras list to match coordinates from Ruis list. + + + +Given a coordinate in the format "2A", return a tuple in the format `("2", "A")` by implementing the `convert_coordinate()` function. + + +​ +```python +convert_coordinate("2A") +>>> ("2", "A") + +``` + + + +## 3. Check to see if a record from Azaras list "matches" a record from Ruis list. + +Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, compare the coordinates from each, and return **`True`** if they "match", **`False`** if they do not. Re-format the coordinate as needed for an accurate comparison. Implement this as the `compare_records()` function. + + + +```python +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. Combine a record from Azaras list with a record from Ruis IF they are at the same coordinates. + +Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, **if the coordinates match**, return `(treasure, coordinate, location, coordinate, quadrant)`. Otherwise return "not a match". Re-format the coordinate as needed for comparison. Implement this as the `create_record()` function. + + + +```python +create_record(('Brass Spyglass', '4B'),('Abandoned Lighthouse', ("4", "B"), 'Blue')) +>>> ('Brass Spyglass', '4B', 'Abandoned Lighthouse', ("4", "B"), 'Blue') + +create_record(('Brass Spyglass', '4B'),(("1", "C"), 'Seaside Cottages', 'blue')) +>>> "not a match" + +``` + + + +## 5. "Clean up" & print out the records from Azara and Rui so that there's only one set of coordinates per record, and they have a list of everything they need to put on the map. + +Given a tuple of tuples, loop through the _outer_ tuple, dropping the unwanted coordinates from each _inner_ tuple and printing each out. Implement ths as the `clean_up()` function. + +```python + +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') +>>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') +>>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') + +``` + + + +## 6. There's been a last minute addition to the team! Since there are now three team members sharing the combined info, there needs to be three "complete" record groups to refer to. + +Given a tuple of tuples, _multiply_ it by three, then iterate through the result, printing out the items. Implement this as the `multiply_records()` function. + + ```python +multiply_records((('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') +>>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') +>>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') +>>> ('Brass Spyglass', 'Abandoned Lighthouse', '("4", "B")', 'Blue') +>>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') +>>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') +>>> ('Brass Spyglass', 'Abandoned Lighthouse', '("4", "B")', 'Blue') +>>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') +>>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') + + ``` From 3ce1f8553621b6cb72c73a792726582962e8d136 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:32:29 -0700 Subject: [PATCH 08/27] New tuples concept exercise boilerplate file. --- .../python/exercises/concept/tuples/tuples.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/tuples.py diff --git a/languages/python/exercises/concept/tuples/tuples.py b/languages/python/exercises/concept/tuples/tuples.py new file mode 100644 index 0000000000..02790d6954 --- /dev/null +++ b/languages/python/exercises/concept/tuples/tuples.py @@ -0,0 +1,28 @@ + +def get_coordinate(record): + return record[1] + +def convert_coordinate(coordinate): + # alt return tuple(coordinate) + return coordinate[0], coordinate[1] + + +def compare_records(azara_record, rui_record): + return tuple(azara_record[1]) in rui_record + +def create_record(azara_record, rui_record): + if compare_records(azara_record, rui_record): + return azara_record + rui_record + else: + return "not a match" + +def clean_up(combined_record_group): + for item in combined_record_group: + new_item = item[0], item[2], item[3], item[4] + print(new_item) + +def multiply_records(combined_record_group): + group_for_three = combined_record_group * 3 + + for item in group_for_three: + print(item) From 92265e45bd00344762d751b0876e56c5126633e4 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:33:52 -0700 Subject: [PATCH 09/27] New tuples concept exercise cleaned boilerplate file. --- .../python/exercises/concept/tuples/tuples.py | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples.py b/languages/python/exercises/concept/tuples/tuples.py index 02790d6954..56572e3cc2 100644 --- a/languages/python/exercises/concept/tuples/tuples.py +++ b/languages/python/exercises/concept/tuples/tuples.py @@ -1,28 +1,19 @@ def get_coordinate(record): - return record[1] + pass def convert_coordinate(coordinate): - # alt return tuple(coordinate) - return coordinate[0], coordinate[1] + pass def compare_records(azara_record, rui_record): - return tuple(azara_record[1]) in rui_record + pass def create_record(azara_record, rui_record): - if compare_records(azara_record, rui_record): - return azara_record + rui_record - else: - return "not a match" + pass def clean_up(combined_record_group): - for item in combined_record_group: - new_item = item[0], item[2], item[3], item[4] - print(new_item) + pass def multiply_records(combined_record_group): - group_for_three = combined_record_group * 3 - - for item in group_for_three: - print(item) + pass From 2323534f744732f0110cfbb8a42171abbec0804b Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 16:34:26 -0700 Subject: [PATCH 10/27] New tuples concept exercise tests. --- .../exercises/concept/tuples/tuples_test.py | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 languages/python/exercises/concept/tuples/tuples_test.py diff --git a/languages/python/exercises/concept/tuples/tuples_test.py b/languages/python/exercises/concept/tuples/tuples_test.py new file mode 100644 index 0000000000..565461a190 --- /dev/null +++ b/languages/python/exercises/concept/tuples/tuples_test.py @@ -0,0 +1,207 @@ +import unittest +import sys +from contextlib import contextmanager +from io import StringIO + +from tuples import get_coordinate, convert_coordinate, compare_records, create_record, clean_up, multiply_records + + +@contextmanager +def captured_output(): + new_out, new_err = StringIO(), StringIO() + old_out, old_err = sys.stdout, sys.stderr + try: + sys.stdout, sys.stderr = new_out, new_err + yield sys.stdout, sys.stderr + finally: + sys.stdout, sys.stderr = old_out, old_err + +class TuplesTest(unittest.TestCase): + def test_get_coordinate(self): + input_data = [('Scrimshaw Whale\'s Tooth', '2A'), + ('Brass Spyglass', '4B'), + ('Robot Parrot', '1C'), + ('Glass Starfish', '6D'), + ('Vintage Pirate Hat', '7E'), + ('Pirate Flag', '7F'), + ('Crystal Crab', '6A'), + ('Model Ship in Large Bottle', '8A'), + ('Angry Monkey Figurine', '5B'), + ('Carved Wooden Elephant', '8C'), + ('Amethyst Octopus', '1F'), + ('Antique Glass Fishnet Float', '3D'), + ('Silver Seahorse', '4E')] + + result_data = ['2A', '4B', '1C', '6D', '7E', '7F', '6A', '8A', '5B', '8C', '1F', '3D', '4E'] + + for item, result in zip(input_data, result_data): + with self.subTest("tuple/coordinate variants", item=item, result=result): + self.assertEqual(get_coordinate(item), result) + + def test_convert_coordinate(self): + input_data = ['2A', '4B', '1C', '6D', '7E', '7F', '6A', '8A', '5B', '8C', '1F', '3D', '4E'] + result_data = [('2', 'A'), + ('4', 'B'), + ('1', 'C'), + ('6', 'D'), + ('7', 'E'), + ('7', 'F'), + ('6', 'A'), + ('8', 'A'), + ('5', 'B'), + ('8', 'C'), + ('1', 'F'), + ('3', 'D'), + ('4', 'E')] + + for item, result in zip(input_data, result_data): + with self.subTest("coordinate variants for conversion", item=item, result=result): + self.assertEqual(convert_coordinate(item), result) + + def test_compare_records(self): + input_data = [ + (('Scrimshaw Whale\'s Tooth', '2A'), ('Deserted Docks', ('2', 'A') ,'Blue')), + (('Brass Spyglass', '4B'), ('Abandoned Lighthouse', ('4', 'B') ,'Blue')), + (('Robot Parrot', '1C'), ('Seaside Cottages', ('1', 'C') ,'Blue')), + (('Glass Starfish', '6D'), ('Tangled Seaweed Patch', ('6', 'D'),'Orange')), + (('Vintage Pirate Hat', '7E'), ('Quiet Inlet (Island of Mystery)', ('7', 'E') ,'Orange')), + (('Amethyst Octopus', '1F'), ('Seaside Cottages', ('1', 'C') ,'Blue')), + (('Angry Monkey Figurine', '5B'), ('Aqua Lagoon (Island of Mystery)', ('1', 'F') ,'Yellow')), + (('Antique Glass Fishnet Float', '3D'), ('Deserted Docks', ('2', 'A') ,'Blue')), + (('Brass Spyglass', '4B'), ('Spiky Rocks', ('3', 'D') ,'Yellow')), + (('Carved Wooden Elephant', '8C'), ('Abandoned Lighthouse', ('4', 'B') ,'Blue')) + ] + result_data = [True, True, True, True, True, False, False, False, False, False] + + for item, result in zip(input_data, result_data): + with self.subTest("do the coordinates match once reformatted?", item=item, result=result): + self.assertEqual(compare_records(item[0], item[1]), result) + + def test_create_record(self): + input_data=[ + (('Angry Monkey Figurine', '5B'), ('Stormy Breakwater', ('5', 'B') ,'Purple')), + (('Carved Wooden Elephant', '8C'), ('Foggy Seacave', ('8', 'C'), 'Purple')), + (('Amethyst Octopus', '1F'), ('Aqua Lagoon (Island of Mystery)', ('1', 'F') ,'Yellow')), + (('Antique Glass Fishnet Float', '3D'), ('Spiky Rocks', ('3', 'D'),'Yellow')), + (('Silver Seahorse', '4E'), ('Hidden Spring (Island of Mystery)', ('4', 'E') ,'Yellow')), + (('Amethyst Octopus', '1F'), ('Seaside Cottages', ('1', 'C') ,'Blue')), + (('Angry Monkey Figurine', '5B'), ('Aqua Lagoon (Island of Mystery)', ('1', 'F') ,'Yellow')), + (('Antique Glass Fishnet Float', '3D'), ('Deserted Docks', ('2', 'A') ,'Blue')), + (('Brass Spyglass', '4B'), ('Spiky Rocks', ('3', 'D'),'Yellow')), + (('Carved Wooden Elephant', '8C'), ('Abandoned Lighthouse', ('4', 'B') ,'Blue')) + ] + result_data = [ + ('Angry Monkey Figurine', '5B', 'Stormy Breakwater', ('5', 'B'), 'Purple'), + ('Carved Wooden Elephant', '8C', 'Foggy Seacave', ('8', 'C'), 'Purple'), + ('Amethyst Octopus', '1F', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow'), + ('Antique Glass Fishnet Float', '3D', 'Spiky Rocks', ('3', 'D'), 'Yellow'), + ('Silver Seahorse', '4E', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow'), + 'not a match', + 'not a match', + 'not a match', + 'not a match', + 'not a match' + ] + + for item, result in zip(input_data, result_data): + with self.subTest("make record if coordinates match", item=item, result=result): + self.assertEqual(create_record(item[0], item[1]), result) + + def test_clean_up(self): + + input_data = ( + ("Scrimshaw Whale's Tooth", '2A', 'Deserted Docks', ('2', 'A'), 'Blue'), + ('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), + ('Robot Parrot', '1C', 'Seaside Cottages', ('1', 'C'), 'Blue'), + ('Glass Starfish', '6D', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange'), + ('Vintage Pirate Hat', '7E', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), + ('Pirate Flag', '7F', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange'), + ('Crystal Crab', '6A', 'Old Schooner', ('6', 'A'), 'Purple'), + ('Model Ship in Large Bottle', '8A', 'Harbor Managers Office', ('8', 'A'), 'Purple'), + ('Angry Monkey Figurine', '5B', 'Stormy Breakwater', ('5', 'B'), 'Purple'), + ('Carved Wooden Elephant', '8C', 'Foggy Seacave', ('8', 'C'), 'Purple'), + ('Amethyst Octopus', '1F', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow'), + ('Antique Glass Fishnet Float', '3D', 'Spiky Rocks', ('3', 'D'), 'Yellow'), + ('Silver Seahorse', '4E', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow') + ) + + result_data = "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ + "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ + "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ + "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ + "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ + "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ + "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ + "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ + "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ + "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ + "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ + "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ + "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')" + + with captured_output() as (out, err): + clean_up(input_data) + output = out.getvalue().strip() + self.assertEqual(output, result_data) + + def test_multiply_records(self): + input_data = ( + ("Scrimshaw Whale's Tooth", 'Deserted Docks', ('2', 'A'), 'Blue'), + ('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), + ('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue'), + ('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange'), + ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), + ('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange'), + ('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple'), + ('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple'), + ('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple'), + ('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple'), + ('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow'), + ('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow'), + ('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow') + ) + + result_data = "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ + "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ + "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ + "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ + "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ + "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ + "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ + "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ + "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ + "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ + "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ + "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ + "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')\n" \ + "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ + "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ + "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ + "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ + "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ + "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ + "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ + "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ + "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ + "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ + "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ + "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ + "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')\n" \ + "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ + "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ + "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ + "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ + "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ + "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ + "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ + "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ + "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ + "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ + "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ + "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ + "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')" + + with captured_output() as (out, err): + multiply_records(input_data) + output = out.getvalue().strip() + self.assertEqual(output, result_data) From 5a432dfea8f5eb617cea1f68e0c693944d67177d Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:12:58 -0700 Subject: [PATCH 11/27] Ran prettier to clean up file markdown formatting. Edited language and cleaned up bloat. --- .../exercises/concept/tuples/.docs/after.md | 146 ++++++++++++++++- .../exercises/concept/tuples/.docs/hints.md | 58 +++---- .../concept/tuples/.docs/instructions.md | 125 ++++++--------- .../concept/tuples/.docs/introducton.md | 147 +++++++----------- 4 files changed, 268 insertions(+), 208 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.docs/after.md b/languages/python/exercises/concept/tuples/.docs/after.md index f9bf1abc13..e11e4fe72e 100644 --- a/languages/python/exercises/concept/tuples/.docs/after.md +++ b/languages/python/exercises/concept/tuples/.docs/after.md @@ -1 +1,145 @@ -#TODO +In Python, a tuple is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). + +Tuples take up very little memory space compared to other collection types and have constant (_O(1)_) access time. However, they cannot be resized, sorted, or altered once created, so are less flexible when frequent changes or updates to data are needed. + +## Tuple Construction + +Tuples can be formed in multiple ways, using either the `tuple` class constructor or the `tuple` literal declaration. + +### Using the `tuple()` constructor empty or with an _iterable_: + +```python +no_elements = tuple() +>>> () + +#the string elements (characters) are iterated through and added to the tuple +multiple_elements_string = tuple("Timbuktu") +>>> ('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') + +multiple_elements_list = tuple(["Parrot", "Bird", 334782]) +>>> ("Parrot", "Bird", 334782) + +multiple_elements_set = tuple({2, 3, 5, 7, 11}) +>>> (2,3,5,7,11) + + +""" +The iteration default for dictionaries is over the keys. +To include both keys and values in a tuple made from a dictionary, use dict.items(), +which returns a list of (key, value) tuples. +""" +source_data = {"fish": "gold", "monkey": "brown"} +multiple_elements_dict_1 = tuple(source_data) +>>> ('fish', 'monkey') + +multiple_elements_dict_2 = tuple(source_data.items()) +>>> (('fish', 'gold'), ('monkey', 'brown')) + + +""" +because the tuple constructor only takes iterables (or nothing), it is much easier to create + a one-tuple via the literal method. +""" +one_element = tuple([16]) +>>> (16,) + +``` + +#### Declaring a tuple as a _literal_ : + +```python +no_elements = () +>>> () + +one_element = ("Guava",) +>>> ("Guava",) + +elements_separated_with_commas = "Parrot", "Bird", 334782 +>>> ("Parrot", "Bird", 334782) + +elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60) +>>> ("Triangle", 60, 60, 60) + +nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) +>>> ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) + +#using the plus + operator unpacks each tuple and creates a new tuple. +new_via_concatenate = ("George", 5) + ("cat", "Tabby") +>>> ("George", 5, "cat", "Tabby") + +#likewise, using the multiplication operator * is the equvilent of using + n times +first_group = ("cat", "dog", "elephant") + +multiplied_group = first_group * 3 +>>> ('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant') + +``` + +Note that generally parentheses are not _required_ to create a `tuple` literal - only commas. Parentheses are required in cases of ambiguity, such as an empty or one-item tuple or where a function takes a tuple as an argument. + +## Tuples as related information + +Tuples are often used as _records_ containing heterogeneous data that is _organizationally_ or _conceptually_ related and treated as a single unit of information. + +```python + +student_info = ("Alyssa", "grade 3", "female", 8 ) + +``` + +Tuples are also used when homogeneous immutable sequences of data are needed for hashability, storage in a set, or creation of keys in a dictionary. + +```python + +cmyk_color_map = { + (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292), + (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01), + (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E), + (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C) + } + +unique_rgb_colors = { + (59, 178, 146), + (247, 127, 1), + (89, 16, 142), + (140, 0, 76), + (76, 0, 140) + } + +teal_700 = hash((59, 178, 146)) + +``` + +## Accessing data inside a tuple + +Items inside tuples (_like the sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. Items inside tuples can also be _iterated over_ in a loop using `for item in` syntax. + +```python + +student_info = ("Alyssa", "grade 3", "female", 8 ) + +#name is at index 0 +student_name = student_info[0] + +#grade is at index 1 +student_grade = student_info[1] +>>> 'grade 3' + +#age is at index 3 or index -1 +student_age_1 = student_info[3] +>>> 8 + +student_age_2 = student_info[-1] +>>> 8 + + +for item in student_info: + print(item) + +>>> +Alyssa +grade 3 +female +8 +>>> +``` diff --git a/languages/python/exercises/concept/tuples/.docs/hints.md b/languages/python/exercises/concept/tuples/.docs/hints.md index 4eda4da704..dea55ef931 100644 --- a/languages/python/exercises/concept/tuples/.docs/hints.md +++ b/languages/python/exercises/concept/tuples/.docs/hints.md @@ -1,50 +1,34 @@ ## General -* [Tuples](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) are immutable. -[Sequence Types](https://docs.python.org/3/library/stdtypes.html#typesseq) that can contain any data type. -* Tuples are [iterable](https://docs.python.org/3/glossary.html#term-iterable). -* Elements within tuples can be accessed via [bracket notation](https://stackoverflow.com/questions/30250282/whats-the-difference-between-the-square-bracket-and-dot-notations-in-python), using a zero-based index. -* Other [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) can also be used when working with tuples. +- [Tuples](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) are immutable. + [Sequence Types](https://docs.python.org/3/library/stdtypes.html#typesseq) that can contain any data type. +- Tuples are [iterable](https://docs.python.org/3/glossary.html#term-iterable). +- Elements within tuples can be accessed via [bracket notation](https://stackoverflow.com/questions/30250282/whats-the-difference-between-the-square-bracket-and-dot-notations-in-python), using a zero-based index. +- Other [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) can also be used when working with tuples. -___ +--- +### 1. Extract coordinates. +- Remember: tuples allow access via _index_, using _brackets_. Indexes start at zero. -### 1. Retrieve and return the map coordinates from and item on Azaras list. +### 2. Format coordinates. -* Remember: tuples allow access via _index_, using _brackets_. Indexes start at zero. +- The `tuple` constructor will take _any iterable_ as an argument, unpack it, and return a tuple. +- Strings are iterable in python. - +### 3. Match coordinates. -### 2. Format coordinates from Azaras list to match coordinates from Ruis list. +- [in keyword](https://docs.python.org/3/reference/expressions.html#membership-test-operations) for testing membership. +- The `tuple()` constructor will make a tuple from _any iterable_. +- Could you re-use your convert_coordinate() function? -* The `tuple` constructor will take _any iterable_ as an argument, unpack it, and return a tuple. -* Strings are iterable in python. +### 4. Combine matched records. - +- [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) +- Could you use the `compare_records()` function here? -### 3. Check to see if a record from Azaras list "matches" a record from Ruis list. - -* [in keyword](https://docs.python.org/3/reference/expressions.html#membership-test-operations) for testing membership. -* The `tuple()` constructor will make a tuple from _any iterable_. - - - - -### 4. Combine a record from Azaras list with a record from Ruis IF they are at the same coordinates. - -* [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) -* Could you use the `compare_records()` function here? - - -### 5. "Clean up" & print out the records from Azara and Rui so that there's only one set of coordinates per record, and they have a list of everything they need to put on the map. - - -* Remember: tuples are _immutable_, but the contents can be accessed via _index_ using _bracket notation_. -* Tuples don't have to use parentheses unless there is _ambiguity_. - - -### 6. There's been a last minute addition to the team! Since there are now three team members sharing the combined info, there needs to be three "complete" record groups to refer to. - -* [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) +### 5. "Clean up" & print out all records. +- Remember: tuples are _immutable_, but the contents can be accessed via _index_ using _bracket notation_. +- Tuples don't have to use parentheses unless there is _ambiguity_. diff --git a/languages/python/exercises/concept/tuples/.docs/instructions.md b/languages/python/exercises/concept/tuples/.docs/instructions.md index 9297bb9547..b3e8a37f55 100644 --- a/languages/python/exercises/concept/tuples/.docs/instructions.md +++ b/languages/python/exercises/concept/tuples/.docs/instructions.md @@ -1,58 +1,57 @@ -Aazra and Rui are teammates competing in a pirate-themed treasure hunt. One has a list of treasures with map coordinates, the other a list of location names with map coordinates. They've also been given blank maps with a starting place marked YOU ARE HERE. - +Aazra and Rui are teammates competing in a pirate-themed treasure hunt. One has a list of treasures with map coordinates, the other a list of location names with map coordinates. They've also been given blank maps with a starting place marked YOU ARE HERE.
Azara's ListRui's List
-| Treasure | Coordinates | -|----------------------------- |------------- | -| 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 | -| Scrimshaw Whale's Tooth | 2A | -| Silver Seahorse | 4E | -| Vintage Pirate Hat | 7E | +| Treasure | Coordinates | +| --------------------------- | ----------- | +| 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 | +| Scrimshaw Whale's Tooth | 2A | +| Silver Seahorse | 4E | +| Vintage Pirate Hat | 7E | -| Location Name | Coordinates | Quandrant | -|--------------------------------------- |------------- |----------- | -| 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 | +| Location Name | Coordinates | Quandrant | +| ------------------------------------- | ----------- | --------- | +| 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 | +

-But things are a bit disorganized: Azaras coordinates appear to be formatted and sorted differently from Ruis, and they have to keep looking from one list to the other to figure out which treasures go with which locations. Being budding pythonistas, they've come to you for help in writing a small program (a set of functions, really) to better organize their hunt information. +But things are a bit disorganized: Azara's coordinates appear to be formatted and sorted differently from Rui's, and they have to keep looking from one list to the other to figure out which treasures go with which locations. Being budding pythonistas, they've come to you for help in writing a small program (a set of functions, really) to better organize their hunt information. - -## 1. Retrieve and return the map coordinates from an item on Azaras list. +## 1. Extract coordinates. Given a `(treasure, coordinate)` pair from Azaras list, extract and return the part that represents the coordinate on the map by implementing the `get_cooordinate()` function. +​ -​ ```python >>> get_coordinate(("Scrimshaw Whale's Tooth", "2A")) @@ -60,30 +59,24 @@ Given a `(treasure, coordinate)` pair from Azaras list, extract and return the p ``` +​ +​ -​ -​ -## 2. Format coordinates from Azaras list to match coordinates from Ruis list. - - +## 2. Format coordinates. Given a coordinate in the format "2A", return a tuple in the format `("2", "A")` by implementing the `convert_coordinate()` function. +​ -​ ```python convert_coordinate("2A") >>> ("2", "A") ``` +## 3. Match coordinates. - -## 3. Check to see if a record from Azaras list "matches" a record from Ruis list. - -Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, compare the coordinates from each, and return **`True`** if they "match", **`False`** if they do not. Re-format the coordinate as needed for an accurate comparison. Implement this as the `compare_records()` function. - - +Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, compare the coordinates from each, and return **`True`** if they "match", **`False`** if they do not. Re-format the coordinate as needed for an accurate comparison. Implement this as the `compare_records()` function. ```python compare_records(('Brass Spyglass', '4B'),('Seaside Cottages', ("1", "C"), 'blue')) @@ -93,13 +86,9 @@ compare_records(('Model Ship in Large Bottle', '8A'), ('Harbor Managers Office', >>> True ``` +## 4. Combine matched records. - -## 4. Combine a record from Azaras list with a record from Ruis IF they are at the same coordinates. - -Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, **if the coordinates match**, return `(treasure, coordinate, location, coordinate, quadrant)`. Otherwise return "not a match". Re-format the coordinate as needed for comparison. Implement this as the `create_record()` function. - - +Given a `(treasure, coordinate)` pair from Azaras list and a `(location, coordinate, quadrant)` record from Ruis list, **if the coordinates match**, return `(treasure, coordinate, location, coordinate, quadrant)`. Otherwise return "not a match". Re-format the coordinate as needed for accurate comparison. Implement this as the `create_record()` function. ```python create_record(('Brass Spyglass', '4B'),('Abandoned Lighthouse', ("4", "B"), 'Blue')) @@ -110,11 +99,10 @@ create_record(('Brass Spyglass', '4B'),(("1", "C"), 'Seaside Cottages', 'blue')) ``` +## 5. "Clean up" & print out all records. - -## 5. "Clean up" & print out the records from Azara and Rui so that there's only one set of coordinates per record, and they have a list of everything they need to put on the map. - -Given a tuple of tuples, loop through the _outer_ tuple, dropping the unwanted coordinates from each _inner_ tuple and printing each out. Implement ths as the `clean_up()` function. +Clean up the combined records from Azara and Rui so that there's only one set of coordinates per record, and there's one list of everything they need to put on their maps. +Given a tuple of tuples, loop through the _outer_ tuple, dropping the unwanted coordinates from each _inner_ tuple and printing each out. Implement ths as the `clean_up()` function. ```python @@ -125,24 +113,3 @@ clean_up((('Brass Spyglass', '4B', 'Abandoned Lighthouse', '("4", "B")', 'Blue') >>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') ``` - - - -## 6. There's been a last minute addition to the team! Since there are now three team members sharing the combined info, there needs to be three "complete" record groups to refer to. - -Given a tuple of tuples, _multiply_ it by three, then iterate through the result, printing out the items. Implement this as the `multiply_records()` function. - - ```python -multiply_records((('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') ->>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') ->>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') ->>> ('Brass Spyglass', 'Abandoned Lighthouse', '("4", "B")', 'Blue') ->>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') ->>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') ->>> ('Brass Spyglass', 'Abandoned Lighthouse', '("4", "B")', 'Blue') ->>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') ->>> ('Crystal Crab', 'Old Schooner', '("6", "A")','Purple') - - ``` diff --git a/languages/python/exercises/concept/tuples/.docs/introducton.md b/languages/python/exercises/concept/tuples/.docs/introducton.md index 3c17e1cc6d..4d0505d685 100644 --- a/languages/python/exercises/concept/tuples/.docs/introducton.md +++ b/languages/python/exercises/concept/tuples/.docs/introducton.md @@ -1,148 +1,113 @@ -In Python, a tuple is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). - -Tuples take up very little memory space compared to other collection types and have constant (_O(1)_) access time. However, they cannot be resized, sorted, or altered once created, so are less flexible when frequent changes or updates to data are needed. - +In Python, a [tuple](https://docs.python.org/3/library/stdtypes.html#tuple) is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). ## Tuple Construction Tuples can be formed in multiple ways, using either the `tuple` class constructor or the `tuple` literal declaration. -### Using the `tuple()` constructor empty or with an _iterable_: +#### Using the `tuple()` constructor: ```python no_elements = tuple() +no_elements >>> () -#the string elements (characters) are iterated through and added to the tuple +#elements are iterated through and added to the tuple in order multiple_elements_string = tuple("Timbuktu") +multiple_elements_string >>> ('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') multiple_elements_list = tuple(["Parrot", "Bird", 334782]) +multiple_elements_list >>> ("Parrot", "Bird", 334782) -multiple_elements_set = tuple({2, 3, 5, 7, 11}) ->>> (2,3,5,7,11) - - -""" -The iteration default for dictionaries is over the keys. -To include both keys and values in a tuple made from a dictionary, use dict.items(), -which returns a list of (key, value) tuples. -""" -source_data = {"fish": "gold", "monkey": "brown"} -multiple_elements_dict_1 = tuple(source_data) ->>> ('fish', 'monkey') - -multiple_elements_dict_2 = tuple(source_data.items()) ->>> (('fish', 'gold'), ('monkey', 'brown')) - - -""" -because the tuple constructor only takes iterables (or nothing), it is much easier to create - a one-tuple via the literal method. -""" -one_element = tuple([16]) ->>> (16,) - ``` -#### Declaring a tuple as a _literal_ : +#### Declaring a tuple _literal_ : + +Note: generally parentheses are not _required_ to create a `tuple` literal - only commas. Parentheses are only required in cases of ambiguity. ```python no_elements = () +no_elements >>> () -one_element = ("Guava",) ->>> ("Guava",) elements_separated_with_commas = "Parrot", "Bird", 334782 +elements_separated_with_commas >>> ("Parrot", "Bird", 334782) -elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60) ->>> ("Triangle", 60, 60, 60) +elements_with_commas_and_parentheses = ("Triangle", (60, 60, 60)) +elements_with_commas_and_parentheses +>>> ("Triangle", (60, 60, 60)) -nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) ->>> ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) +``` -#using the plus + operator unpacks each tuple and creates a new tuple. +## Concatenation + +Tuples can be _concatenated_. Using the plus **`+`** operator unpacks each tuple and creates a new tuple from the combined elements. + +```python new_via_concatenate = ("George", 5) + ("cat", "Tabby") +new_via_concatenate >>> ("George", 5, "cat", "Tabby") -#likewise, using the multiplication operator * is the equvilent of using + n times -first_group = ("cat", "dog", "elephant") - -multiplied_group = first_group * 3 ->>> ('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant') +new_nested_concatenate = ("Triangle", (60, 60, 60)) + ('orange', 'dashed-outline') +new_nested_concatenate +>>> ('Triangle', (60, 60, 60), 'orange', 'dashed-outline') ``` -Note that generally parentheses are not _required_ to create a `tuple` literal - only commas. Parentheses are required in cases of ambiguity, such as an empty or one-item tuple or where a function takes a tuple as an argument. - +## Accessing data - -## Tuples as related information - -Tuples are often used as _records_ containing heterogeneous data that is _organizationally_ or _conceptually_ related and treated as a single unit of information. +Items inside tuples (_like the items inside sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. ```python student_info = ("Alyssa", "grade 3", "female", 8 ) -``` - -Tuples are also used when homogeneous immutable sequences of data are needed for hashability, storage in a set, or creation of keys in a dictionary. +#name is at index 0 +student_name = student_info[0] +student_name +>>> "Alyssa" -```python +#grade is at index 1 +student_grade = student_info[1] +student_grade +>>> 'grade 3' -cmyk_color_map = { - (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292), - (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01), - (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E), - (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C) - } - -unique_rgb_colors = { - (59, 178, 146), - (247, 127, 1), - (89, 16, 142), - (140, 0, 76), - (76, 0, 140) - } - -teal_700 = hash((59, 178, 146)) +#age is at index 3 +student_age = student_info[3] +student_age +>>> 8 ``` -## Accessing data inside a tuple +## Iterating through a tuple -Items inside tuples (_like the sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. Items inside tuples can also be _iterated over_ in a loop using `for item in` syntax. +Items inside tuples can be _iterated over_ in a loop using **`for item in`** syntax. ```python +for item in student_info: +print(item) -student_info = ("Alyssa", "grade 3", "female", 8 ) +> > > Alyssa +> > > grade 3 +> > > female +> > > 8 +``` -#name is at index 0 -student_name = student_info[0] +## Checking membership -#grade is at index 1 -student_grade = student_info[1] ->>> 'grade 3' +The **`in`** operator can be used to check membership in a tuple. -#age is at index 3 or index -1 -student_age_1 = student_info[3] ->>> 8 +```python -student_age_2 = student_info[-1] ->>> 8 +fruits = ('Apple', 'Pear', 'Guava', 'Lychee', 'Agbalumo') +'Tomato' in fruits +>>> False + +'Agbalumo' in fruits +>>> True -for item in student_info: - print(item) - ->>> -Alyssa -grade 3 -female -8 ->>> ``` From 5377eba3134f0b405b75c2f3345598ed41843928 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:14:03 -0700 Subject: [PATCH 12/27] Ran prettier to correct markdown formatting and dleted star operator as learning objective. --- .../exercises/concept/tuples/.meta/design.md | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.meta/design.md b/languages/python/exercises/concept/tuples/.meta/design.md index 82eff955de..ce828d605a 100644 --- a/languages/python/exercises/concept/tuples/.meta/design.md +++ b/languages/python/exercises/concept/tuples/.meta/design.md @@ -2,19 +2,18 @@ - Access values in a tuple via index using [] (bracket notation). - Create a tuple via constructor (tuple(_iterable_)) and/or literal (a,b,c or (a, b, c)) -- Understand that tuples are an **immutable data type** (like Strings). Changing a tuple means creating a new copy. +- Understand that tuples are an **immutable data type** (like strings). Changing a tuple means creating a new copy. - Understand that tuples can contain other tuples. (e.g. tuples can be nested). - Create a new tuple from two or more previous tuples via concatenation using the **+** operator. -- Create a new tuple by multiplying a previous tuple using the **`*`** operator. - Iterate through a tuple using **`for item in`**. - Check for membership of an item in a given tuple using the **`in`** keyword. - Understand that it is the comma in a sequence that makes a tuple, and that the () are optional, except for denoting an empty tuple or when omitting them creates ambiguity. ## Out of Scope -- Common Sequence type methods such as `min()`, `max()`, `x.index()`, `x.count()`, `len()` -- Slicing or slice notation ([start:stop:step]) -- Additional builtin functions as they relate to this data structure (e.g. `sorted()`, `enumerate()`, `reversed()`, or `hash()`. +- Common Sequence type methods such as `min()`, `max()`, `x.index()`, `x.count()`, `len()` +- Slicing or slice notation ([start:stop:step]) +- Additional builtin functions as they relate to this data structure (e.g. `sorted()`, `enumerate()`, `reversed()`, or `hash()`. - Knowing that tuples can be used as objects in other data structures, -- e.g. " a "List of tuples", "tuples as keys in Dictionaries", ,or "A Set of tuples". - Hash-ability and when a tuple is not hash-able. - Related [collections](https://docs.python.org/3/library/collections.html#collections.namedtuple)) module with `namedtuple()` @@ -23,24 +22,20 @@ ## Concepts -- tuples -- immutability -- indexing -- concatenation and multiplication of type -- iteration +- tuples +- immutability +- indexing +- concatenation of type +- iteration ## Prerequisites -- bool (True/False) -- for loops -- functions -- if keyword -- in keyword -- int -- print -- return keyword -- str - - - - +- bool (True/False) +- for loops +- functions +- if keyword +- in keyword +- int +- print +- return keyword +- str From c1acea5968b6972cf4aad165936bbafa398e0781 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:15:07 -0700 Subject: [PATCH 13/27] Removed tuple multiplication with star operator. --- .../exercises/concept/tuples/.meta/example.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.meta/example.py b/languages/python/exercises/concept/tuples/.meta/example.py index 2a47ba3e62..a8cfc74c94 100644 --- a/languages/python/exercises/concept/tuples/.meta/example.py +++ b/languages/python/exercises/concept/tuples/.meta/example.py @@ -3,12 +3,11 @@ def get_coordinate(record): return record[1] def convert_coordinate(coordinate): - # alt return tuple(coordinate) - return coordinate[0], coordinate[1] - + # alt return coordinate[0], coordinate[1] + return tuple(coordinate) def compare_records(azara_record, rui_record): - return tuple(azara_record[1]) in rui_record + return convert_coordinate(azara_record[1]) in rui_record def create_record(azara_record, rui_record): if compare_records(azara_record, rui_record): @@ -18,10 +17,5 @@ def create_record(azara_record, rui_record): def clean_up(combined_record_group): for item in combined_record_group: - print((item[0], item[2], item[3], item[4])) - -def multiply_records(combined_record_group): - group_for_three = combined_record_group * 3 - - for item in group_for_three: - print(item) + clean_record = item[0], item[2], item[3], item[4] + print(clean_record) From b3bee05f2132d9312b0545ee75efda7009834799 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:17:58 -0700 Subject: [PATCH 14/27] Edited to remove multiply function. --- languages/python/exercises/concept/tuples/tuples.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples.py b/languages/python/exercises/concept/tuples/tuples.py index 56572e3cc2..d913aa5290 100644 --- a/languages/python/exercises/concept/tuples/tuples.py +++ b/languages/python/exercises/concept/tuples/tuples.py @@ -14,6 +14,3 @@ def create_record(azara_record, rui_record): def clean_up(combined_record_group): pass - -def multiply_records(combined_record_group): - pass From b9815cc82b5000d9028311efdfc26ab81b6c8801 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:18:35 -0700 Subject: [PATCH 15/27] Edited to remove multiply function test case. --- .../exercises/concept/tuples/tuples_test.py | 64 +------------------ 1 file changed, 1 insertion(+), 63 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples_test.py b/languages/python/exercises/concept/tuples/tuples_test.py index 565461a190..333e1f9435 100644 --- a/languages/python/exercises/concept/tuples/tuples_test.py +++ b/languages/python/exercises/concept/tuples/tuples_test.py @@ -3,7 +3,7 @@ from contextlib import contextmanager from io import StringIO -from tuples import get_coordinate, convert_coordinate, compare_records, create_record, clean_up, multiply_records +from tuples import get_coordinate, convert_coordinate, compare_records, create_record, clean_up @contextmanager @@ -143,65 +143,3 @@ def test_clean_up(self): clean_up(input_data) output = out.getvalue().strip() self.assertEqual(output, result_data) - - def test_multiply_records(self): - input_data = ( - ("Scrimshaw Whale's Tooth", 'Deserted Docks', ('2', 'A'), 'Blue'), - ('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), - ('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue'), - ('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange'), - ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), - ('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange'), - ('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple'), - ('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple'), - ('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple'), - ('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple'), - ('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow'), - ('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow'), - ('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow') - ) - - result_data = "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ - "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ - "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ - "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ - "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ - "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ - "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ - "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ - "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ - "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ - "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ - "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ - "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')\n" \ - "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ - "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ - "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ - "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ - "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ - "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ - "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ - "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ - "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ - "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ - "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ - "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ - "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')\n" \ - "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ - "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ - "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ - "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ - "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ - "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ - "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ - "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ - "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ - "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ - "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ - "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ - "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')" - - with captured_output() as (out, err): - multiply_records(input_data) - output = out.getvalue().strip() - self.assertEqual(output, result_data) From debacea8d3e33ff29dbb74bda20acc3097e3688c Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:24:38 -0700 Subject: [PATCH 16/27] Fixed quoting on Scrimshaw Whale's tooth to match quoting style. --- languages/python/exercises/concept/tuples/tuples_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples_test.py b/languages/python/exercises/concept/tuples/tuples_test.py index 333e1f9435..6460d80356 100644 --- a/languages/python/exercises/concept/tuples/tuples_test.py +++ b/languages/python/exercises/concept/tuples/tuples_test.py @@ -18,7 +18,7 @@ def captured_output(): class TuplesTest(unittest.TestCase): def test_get_coordinate(self): - input_data = [('Scrimshaw Whale\'s Tooth', '2A'), + input_data = [("Scrimshaw Whale's Tooth", '2A'), ('Brass Spyglass', '4B'), ('Robot Parrot', '1C'), ('Glass Starfish', '6D'), @@ -60,7 +60,7 @@ def test_convert_coordinate(self): def test_compare_records(self): input_data = [ - (('Scrimshaw Whale\'s Tooth', '2A'), ('Deserted Docks', ('2', 'A') ,'Blue')), + (("Scrimshaw Whale's Tooth", '2A'), ('Deserted Docks', ('2', 'A') ,'Blue')), (('Brass Spyglass', '4B'), ('Abandoned Lighthouse', ('4', 'B') ,'Blue')), (('Robot Parrot', '1C'), ('Seaside Cottages', ('1', 'C') ,'Blue')), (('Glass Starfish', '6D'), ('Tangled Seaweed Patch', ('6', 'D'),'Orange')), From 172ba40efe93b00da4b48e4f827f5eecb97ec32a Mon Sep 17 00:00:00 2001 From: BethanyG Date: Fri, 3 Jul 2020 22:30:32 -0700 Subject: [PATCH 17/27] Ran prettier for config.json --- languages/python/exercises/concept/tuples/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/exercises/concept/tuples/.meta/config.json b/languages/python/exercises/concept/tuples/.meta/config.json index b18ff2f7d0..371b347a12 100644 --- a/languages/python/exercises/concept/tuples/.meta/config.json +++ b/languages/python/exercises/concept/tuples/.meta/config.json @@ -4,5 +4,5 @@ "github_username": "bethanyg", "exercism_username": "BethanyG" } - ], + ] } From d7445f073578892d4435c1ae14b64b9b8f8dfa92 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:11:40 -0700 Subject: [PATCH 18/27] Edits and adjustments per PR feedback and style guides. Also corrected introduction.md file name spelling. --- .../exercises/concept/tuples/.docs/after.md | 144 ++++++++++-------- .../exercises/concept/tuples/.docs/hints.md | 30 ++-- .../concept/tuples/.docs/instructions.md | 58 +++---- .../concept/tuples/.docs/introduction.md | 55 +++++++ .../concept/tuples/.docs/introducton.md | 113 -------------- 5 files changed, 177 insertions(+), 223 deletions(-) create mode 100644 languages/python/exercises/concept/tuples/.docs/introduction.md delete mode 100644 languages/python/exercises/concept/tuples/.docs/introducton.md diff --git a/languages/python/exercises/concept/tuples/.docs/after.md b/languages/python/exercises/concept/tuples/.docs/after.md index e11e4fe72e..8d10f22456 100644 --- a/languages/python/exercises/concept/tuples/.docs/after.md +++ b/languages/python/exercises/concept/tuples/.docs/after.md @@ -1,4 +1,4 @@ -In Python, a tuple is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). +In Python, a [tuple](../../../../reference/concepts/builtin_types/tuple.md) is an immutable collection of items in _sequence_. Like most collections (_see the built-ins [`list`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/list.md), [`dict`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/dict.md) and [`set`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/set.md)_), tuples can hold any (or multiple) data type(s) -- including other tuples. Like any [sequence](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range), items are referenced by 0-based index number, and can be copied in whole or in part via _slice notation_. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). Tuples take up very little memory space compared to other collection types and have constant (_O(1)_) access time. However, they cannot be resized, sorted, or altered once created, so are less flexible when frequent changes or updates to data are needed. @@ -9,18 +9,18 @@ Tuples can be formed in multiple ways, using either the `tuple` class constructo ### Using the `tuple()` constructor empty or with an _iterable_: ```python -no_elements = tuple() ->>> () +>>> no_elements = tuple() +() #the string elements (characters) are iterated through and added to the tuple -multiple_elements_string = tuple("Timbuktu") ->>> ('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') +>>> multiple_elements_string = tuple("Timbuktu") +('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') -multiple_elements_list = tuple(["Parrot", "Bird", 334782]) ->>> ("Parrot", "Bird", 334782) +>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782]) +("Parrot", "Bird", 334782) -multiple_elements_set = tuple({2, 3, 5, 7, 11}) ->>> (2,3,5,7,11) +>>> multiple_elements_set = tuple({2, 3, 5, 7, 11}) +(2,3,5,7,11) """ @@ -29,49 +29,49 @@ To include both keys and values in a tuple made from a dictionary, use dict.item which returns a list of (key, value) tuples. """ source_data = {"fish": "gold", "monkey": "brown"} -multiple_elements_dict_1 = tuple(source_data) ->>> ('fish', 'monkey') +>>> multiple_elements_dict_1 = tuple(source_data) +('fish', 'monkey') -multiple_elements_dict_2 = tuple(source_data.items()) ->>> (('fish', 'gold'), ('monkey', 'brown')) +>>> multiple_elements_dict_2 = tuple(source_data.items()) +(('fish', 'gold'), ('monkey', 'brown')) """ -because the tuple constructor only takes iterables (or nothing), it is much easier to create +because the tuple constructor only takes _iterables_ (or nothing), it is much easier to create a one-tuple via the literal method. """ -one_element = tuple([16]) ->>> (16,) +>>> one_element = tuple([16]) +(16,) ``` #### Declaring a tuple as a _literal_ : ```python -no_elements = () ->>> () +>>> no_elements = () +() -one_element = ("Guava",) ->>> ("Guava",) +>>> one_element = ("Guava",) +("Guava",) -elements_separated_with_commas = "Parrot", "Bird", 334782 ->>> ("Parrot", "Bird", 334782) +>>> elements_separated_with_commas = "Parrot", "Bird", 334782 +("Parrot", "Bird", 334782) -elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60) ->>> ("Triangle", 60, 60, 60) +>>> elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60) +("Triangle", 60, 60, 60) -nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) ->>> ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) +>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) +({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird")) #using the plus + operator unpacks each tuple and creates a new tuple. -new_via_concatenate = ("George", 5) + ("cat", "Tabby") ->>> ("George", 5, "cat", "Tabby") +>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby") +("George", 5, "cat", "Tabby") #likewise, using the multiplication operator * is the equvilent of using + n times -first_group = ("cat", "dog", "elephant") +>>> first_group = ("cat", "dog", "elephant") -multiplied_group = first_group * 3 ->>> ('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant') +>>> multiplied_group = first_group * 3 +('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant') ``` @@ -83,63 +83,83 @@ Tuples are often used as _records_ containing heterogeneous data that is _organi ```python -student_info = ("Alyssa", "grade 3", "female", 8 ) +>>> student_info = ("Alyssa", "grade 3", "female", 8 ) ``` -Tuples are also used when homogeneous immutable sequences of data are needed for hashability, storage in a set, or creation of keys in a dictionary. +Tuples are also used when homogeneous immutable sequences of data are needed for [`hashability`](https://docs.python.org/3/glossary.html#hashable), storage in a set, or creation of keys in a dictionary. + +Note that while tuples are in most cases _immutable_, because they can contain _any_ data structure or object they can become mutable if any of their elements is a _mutable type_. Using a mutable data type within a tuple will make the enclosing tuple un-hashable. ```python -cmyk_color_map = { - (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292), - (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01), - (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E), - (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C) - } - -unique_rgb_colors = { - (59, 178, 146), - (247, 127, 1), - (89, 16, 142), - (140, 0, 76), - (76, 0, 140) +>>> cmyk_color_map = { + (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292), + (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01), + (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E), + (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C) } -teal_700 = hash((59, 178, 146)) +>>>> unique_rgb_colors = { + (59, 178, 146), + (247, 127, 1), + (89, 16, 142), + (140, 0, 76), + (76, 0, 140) + } + +>>> teal_700 = hash((59, 178, 146)) + +>>> teal_700 = hash(("Pantone 228", [(140, 0, 76), 0x8C004C])) +Traceback (most recent call last): + File "", line 1, in +TypeError: unhashable type: 'list' ``` ## Accessing data inside a tuple -Items inside tuples (_like the sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. Items inside tuples can also be _iterated over_ in a loop using `for item in` syntax. +Items inside tuples (_like the sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. Indexes can be from **`left`** --> **`right`** (_starting at zero_) or **`right`** --> **`left`** (_starting at -1_). + +Items inside tuples can also be _iterated over_ in a loop using `for item in` syntax. ```python -student_info = ("Alyssa", "grade 3", "female", 8 ) +>>> student_info = ("Alyssa", "grade 3", "female", 8 ) -#name is at index 0 -student_name = student_info[0] +#name is at index 0 or index -4 +>>> student_name = student_info[0] +Alyssa + +>>> student_name = student_info[-4] +Alyssa -#grade is at index 1 -student_grade = student_info[1] ->>> 'grade 3' +#grade is at index 1 or index -3 +>>> student_grade = student_info[1] +'grade 3' + +>>> student_grade = student_info[-3] +'grade 3' #age is at index 3 or index -1 -student_age_1 = student_info[3] ->>> 8 +>>> student_age_1 = student_info[3] +8 -student_age_2 = student_info[-1] ->>> 8 +>>> student_age_2 = student_info[-1] +8 -for item in student_info: - print(item) +>>> for item in student_info: +>>> print(item) ->>> +.... Alyssa grade 3 female 8 ->>> + ``` + +## Extended tuples and related data types + +Tuples are often used as _records_, but the data inside them can only be accessed via _position_/_index_. The [`namedtuple()`](https://docs.python.org/3/library/collections.html#collections.namedtuple) class in the [`collections`](https://docs.python.org/3/library/collections.html#module-collections) module extends basic tuple functionality to allow access of elements by _name_. Additionally, users can adapt a [`dataclass`](https://docs.python.org/3/library/dataclasses.html) to provide similar named attribute functionality, with a some [pros and cons](https://stackoverflow.com/questions/51671699/data-classes-vs-typing-namedtuple-primary-use-cases). diff --git a/languages/python/exercises/concept/tuples/.docs/hints.md b/languages/python/exercises/concept/tuples/.docs/hints.md index dea55ef931..9aeebf7139 100644 --- a/languages/python/exercises/concept/tuples/.docs/hints.md +++ b/languages/python/exercises/concept/tuples/.docs/hints.md @@ -6,29 +6,29 @@ - Elements within tuples can be accessed via [bracket notation](https://stackoverflow.com/questions/30250282/whats-the-difference-between-the-square-bracket-and-dot-notations-in-python), using a zero-based index. - Other [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) can also be used when working with tuples. ---- +## 1. Extract coordinates -### 1. Extract coordinates. +- Remember: tuples allow access via _index_, using _brackets_. Indexes start from the left at zero. -- Remember: tuples allow access via _index_, using _brackets_. Indexes start at zero. +## 2. Format coordinates -### 2. Format coordinates. +- Check [`class tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) for more details on tuples. +- Check [`class str`](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str) for more details on strings. -- The `tuple` constructor will take _any iterable_ as an argument, unpack it, and return a tuple. -- Strings are iterable in python. +## 3. Match coordinates -### 3. Match coordinates. +- What methods could be used here for for [testing membership](https://docs.python.org/3/reference/expressions.html#membership-test-operations)?. +- Check [`class tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) for more details on tuples. +- Could you re-use your `convert_coordinate()` function? -- [in keyword](https://docs.python.org/3/reference/expressions.html#membership-test-operations) for testing membership. -- The `tuple()` constructor will make a tuple from _any iterable_. -- Could you re-use your convert_coordinate() function? +## 4. Combine matched records -### 4. Combine matched records. +- Remember that tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). +- Could you re-use your `compare_records()` function here? -- [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations) -- Could you use the `compare_records()` function here? - -### 5. "Clean up" & print out all records. +## 5. "Clean up" & format a report of all records - Remember: tuples are _immutable_, but the contents can be accessed via _index_ using _bracket notation_. - Tuples don't have to use parentheses unless there is _ambiguity_. +- Python has multiple methods of string formatting. [`str.format()`](https://docs.python.org/3/library/stdtypes.html#str.format) and [`f-strings`](https://docs.python.org/3/tutorial/inputoutput.html#formatted-string-literals) are two very common ones. +- There are multiple textual formatting options available via Pythons [`format specification mini-language`](https://docs.python.org/3/library/string.html#format-specification-mini-language). diff --git a/languages/python/exercises/concept/tuples/.docs/instructions.md b/languages/python/exercises/concept/tuples/.docs/instructions.md index b3e8a37f55..b2a7def0b0 100644 --- a/languages/python/exercises/concept/tuples/.docs/instructions.md +++ b/languages/python/exercises/concept/tuples/.docs/instructions.md @@ -46,70 +46,62 @@ Aazra and Rui are teammates competing in a pirate-themed treasure hunt. One has But things are a bit disorganized: Azara's coordinates appear to be formatted and sorted differently from Rui's, and they have to keep looking from one list to the other to figure out which treasures go with which locations. Being budding pythonistas, they've come to you for help in writing a small program (a set of functions, really) to better organize their hunt information. -## 1. Extract coordinates. - -Given a `(treasure, coordinate)` pair from Azaras list, extract and return the part that represents the coordinate on the map by implementing the `get_cooordinate()` function. +## 1. Extract coordinates +Implement the `get_cooordinate()` function that takes a `(treasure, coordinate)` pair from Azaras list and returns only the extracted map coordinate. ​ ```python - >>> get_coordinate(("Scrimshaw Whale's Tooth", "2A")) ->>> "2A" - +"2A" ``` -​ -​ - -## 2. Format coordinates. +## 2. Format coordinates -Given a coordinate in the format "2A", return a tuple in the format `("2", "A")` by implementing the `convert_coordinate()` function. +Implement the `convert_coordinate()` function that takes a coordinate in the format "2A" and returns a tuple in the format `("2", "A")`. ​ ```python -convert_coordinate("2A") ->>> ("2", "A") - +>>> convert_coordinate("2A") +("2", "A") ``` -## 3. Match coordinates. +## 3. Match coordinates -Given a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record, compare the coordinates from each, and return **`True`** if they "match", **`False`** if they do not. Re-format the coordinate as needed for an accurate comparison. Implement this as the `compare_records()` function. +Implement the `compare_records()` function that takes a `(treasure, coordinate)` pair and a `(location, coordinate, quadrant)` record and compares coordinates from each. Return **`True`** if the coordinates "match", and return **`False`** if they do not. Re-format coordinates as needed for accurate comparison. ```python -compare_records(('Brass Spyglass', '4B'),('Seaside Cottages', ("1", "C"), 'blue')) ->>> False +>>> 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 +>>> compare_records(('Model Ship in Large Bottle', '8A'), ('Harbor Managers Office', ("8", "A"), 'purple')) +True ``` -## 4. Combine matched records. +## 4. Combine matched records -Given a `(treasure, coordinate)` pair from Azaras list and a `(location, coordinate, quadrant)` record from Ruis list, **if the coordinates match**, return `(treasure, coordinate, location, coordinate, quadrant)`. Otherwise return "not a match". Re-format the coordinate as needed for accurate comparison. Implement this as the `create_record()` function. +Implement the `create_record()` function that takes a `(treasure, coordinate)` pair from Azaras list and a `(location, coordinate, quadrant)` record from Ruis list and returns `(treasure, coordinate, location, coordinate, quadrant)` **if the coordinates match**. If the coordinats _do not_ match, return the string "not a match.". Re-format the coordinate as needed for accurate comparison. ```python create_record(('Brass Spyglass', '4B'),('Abandoned Lighthouse', ("4", "B"), 'Blue')) >>> ('Brass Spyglass', '4B', 'Abandoned Lighthouse', ("4", "B"), 'Blue') create_record(('Brass Spyglass', '4B'),(("1", "C"), 'Seaside Cottages', 'blue')) ->>> "not a match" - +>>> "not a match." ``` -## 5. "Clean up" & print out all records. +## 5. "Clean up" & make a report of all records -Clean up the combined records from Azara and Rui so that there's only one set of coordinates per record, and there's one list of everything they need to put on their maps. -Given a tuple of tuples, loop through the _outer_ tuple, dropping the unwanted coordinates from each _inner_ tuple and printing each out. Implement ths as the `clean_up()` function. +Clean up the combined records from Azara and Rui so that there's only one set of coordinates per record. Make a report so they can see one list of everything they need to put on their maps. +Implement the `clean_up()` function that takes a tuple of tuples (_everything from both lists_), looping through the _outer_ tuple, dropping the unwanted coordinates from each _inner_ tuple and adding each to a 'report'. Format and return the 'report' so that there is one cleaned record on each line. ```python +>>> 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'))) -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') ->>> ('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', '("7", "E")', 'Orange') ->>> ('Crystal Crab', '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 +""" ``` diff --git a/languages/python/exercises/concept/tuples/.docs/introduction.md b/languages/python/exercises/concept/tuples/.docs/introduction.md new file mode 100644 index 0000000000..f5a067d434 --- /dev/null +++ b/languages/python/exercises/concept/tuples/.docs/introduction.md @@ -0,0 +1,55 @@ +In Python, a [tuple](https://docs.python.org/3/library/stdtypes.html#tuple) is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). + +## Tuple Construction + +Tuples can be formed in multiple ways, using either the `tuple` class constructor or the `tuple` literal declaration. + +#### Using the `tuple()` constructor: + +```python +#elements are iterated through and added to the tuple in order +>>> multiple_elements_string = tuple("Timbuktu") +('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') + +>>> multiple_elements = tuple(("Parrot", "Bird", 334782)) +("Parrot", "Bird", 334782) +``` + +#### Declaring a tuple _literal_ : + +```python +>>> elements_separated_with_commas = "Parrot", "Bird", 334782 +("Parrot", "Bird", 334782) + +>>> elements_with_commas_and_parentheses = ("Triangle", (60, 60, 60)) +("Triangle", (60, 60, 60)) +``` + +## Concatenation + +Tuples can be _concatenated_ via the plus `+` operator, which returns a new tuple. + +```python +>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby") +("George", 5, "cat", "Tabby") +``` + +## Accessing data + +Items inside tuples can be accessed via 0-based index and _bracket notation_. + +```python +student_info = ("Alyssa", "grade 3", "female", 8 ) + +#gender is at index 2 +>>> student_gender = student_info[2] +female +``` + +## Iterating through a tuple + +Items inside tuples can be _iterated over_ in a loop using `for item in` syntax. + +## Checking membership + +The `in` operator can be used to check membership in a tuple. diff --git a/languages/python/exercises/concept/tuples/.docs/introducton.md b/languages/python/exercises/concept/tuples/.docs/introducton.md deleted file mode 100644 index 4d0505d685..0000000000 --- a/languages/python/exercises/concept/tuples/.docs/introducton.md +++ /dev/null @@ -1,113 +0,0 @@ -In Python, a [tuple](https://docs.python.org/3/library/stdtypes.html#tuple) is an immutable collection of items in _sequence_. Like most collections, tuples can hold any (or multiple) data type(s) -- including other tuples. Like any sequence, items are referenced by 0-based index number. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). - -## Tuple Construction - -Tuples can be formed in multiple ways, using either the `tuple` class constructor or the `tuple` literal declaration. - -#### Using the `tuple()` constructor: - -```python -no_elements = tuple() -no_elements ->>> () - -#elements are iterated through and added to the tuple in order -multiple_elements_string = tuple("Timbuktu") -multiple_elements_string ->>> ('T', 'i', 'm', 'b', 'u', 'k', 't', 'u') - -multiple_elements_list = tuple(["Parrot", "Bird", 334782]) -multiple_elements_list ->>> ("Parrot", "Bird", 334782) - -``` - -#### Declaring a tuple _literal_ : - -Note: generally parentheses are not _required_ to create a `tuple` literal - only commas. Parentheses are only required in cases of ambiguity. - -```python -no_elements = () -no_elements ->>> () - - -elements_separated_with_commas = "Parrot", "Bird", 334782 -elements_separated_with_commas ->>> ("Parrot", "Bird", 334782) - -elements_with_commas_and_parentheses = ("Triangle", (60, 60, 60)) -elements_with_commas_and_parentheses ->>> ("Triangle", (60, 60, 60)) - -``` - -## Concatenation - -Tuples can be _concatenated_. Using the plus **`+`** operator unpacks each tuple and creates a new tuple from the combined elements. - -```python -new_via_concatenate = ("George", 5) + ("cat", "Tabby") -new_via_concatenate ->>> ("George", 5, "cat", "Tabby") - -new_nested_concatenate = ("Triangle", (60, 60, 60)) + ('orange', 'dashed-outline') -new_nested_concatenate ->>> ('Triangle', (60, 60, 60), 'orange', 'dashed-outline') - -``` - -## Accessing data - -Items inside tuples (_like the items inside sequence types `string` and `list`_), can be accessed via 0-based index and _bracket notation_. - -```python - -student_info = ("Alyssa", "grade 3", "female", 8 ) - -#name is at index 0 -student_name = student_info[0] -student_name ->>> "Alyssa" - -#grade is at index 1 -student_grade = student_info[1] -student_grade ->>> 'grade 3' - -#age is at index 3 -student_age = student_info[3] -student_age ->>> 8 - -``` - -## Iterating through a tuple - -Items inside tuples can be _iterated over_ in a loop using **`for item in`** syntax. - -```python -for item in student_info: -print(item) - -> > > Alyssa -> > > grade 3 -> > > female -> > > 8 -``` - -## Checking membership - -The **`in`** operator can be used to check membership in a tuple. - -```python - -fruits = ('Apple', 'Pear', 'Guava', 'Lychee', 'Agbalumo') - -'Tomato' in fruits ->>> False - -'Agbalumo' in fruits ->>> True - -``` From 72eb2763f5bbf54f365171b5db6bff0a8f8bab19 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:12:50 -0700 Subject: [PATCH 19/27] Edited for clarity and brevity per PR feedback. Removed excess concepts and code examples. --- .../exercises/concept/tuples/.meta/design.md | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.meta/design.md b/languages/python/exercises/concept/tuples/.meta/design.md index ce828d605a..7ee46dedc8 100644 --- a/languages/python/exercises/concept/tuples/.meta/design.md +++ b/languages/python/exercises/concept/tuples/.meta/design.md @@ -4,9 +4,9 @@ - Create a tuple via constructor (tuple(_iterable_)) and/or literal (a,b,c or (a, b, c)) - Understand that tuples are an **immutable data type** (like strings). Changing a tuple means creating a new copy. - Understand that tuples can contain other tuples. (e.g. tuples can be nested). -- Create a new tuple from two or more previous tuples via concatenation using the **+** operator. -- Iterate through a tuple using **`for item in`**. -- Check for membership of an item in a given tuple using the **`in`** keyword. +- Create a new tuple from two or more previous tuples via concatenation using the `+` operator. +- Iterate through a tuple using `for item in`. +- Check for membership of an item in a given tuple using the `in` keyword. - Understand that it is the comma in a sequence that makes a tuple, and that the () are optional, except for denoting an empty tuple or when omitting them creates ambiguity. ## Out of Scope @@ -22,20 +22,16 @@ ## Concepts -- tuples -- immutability -- indexing -- concatenation of type -- iteration +- `tuples` ## Prerequisites -- bool (True/False) -- for loops -- functions -- if keyword -- in keyword -- int -- print -- return keyword -- str +- `booleans` +- `for-loops` +- `functions` +- `if-keyword` +- `in-keyword` +- `integers` +- `print` +- `return-keyword` +- `strings` From 734793b717993ccea80187bca8a802c84c5e4ab4 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:15:20 -0700 Subject: [PATCH 20/27] Re-worked final task to be a returned report string rather than print()-ing of content. Adjusted instructions accordingly. --- .../python/exercises/concept/tuples/.meta/example.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.meta/example.py b/languages/python/exercises/concept/tuples/.meta/example.py index a8cfc74c94..729e72a412 100644 --- a/languages/python/exercises/concept/tuples/.meta/example.py +++ b/languages/python/exercises/concept/tuples/.meta/example.py @@ -1,9 +1,7 @@ - def get_coordinate(record): return record[1] def convert_coordinate(coordinate): - # alt return coordinate[0], coordinate[1] return tuple(coordinate) def compare_records(azara_record, rui_record): @@ -16,6 +14,8 @@ def create_record(azara_record, rui_record): return "not a match" def clean_up(combined_record_group): + + report = "" for item in combined_record_group: - clean_record = item[0], item[2], item[3], item[4] - print(clean_record) + report += f"{(item[0], item[2], item[3], item[4])}\n" + return report From 14a46de03a55a87ffebcdba3cf7d35d6824d6d3b Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:15:58 -0700 Subject: [PATCH 21/27] Cleaned up per PR feedback. Removed excess lines. --- languages/python/exercises/concept/tuples/tuples.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples.py b/languages/python/exercises/concept/tuples/tuples.py index d913aa5290..9212aa0614 100644 --- a/languages/python/exercises/concept/tuples/tuples.py +++ b/languages/python/exercises/concept/tuples/tuples.py @@ -1,11 +1,9 @@ - def get_coordinate(record): pass def convert_coordinate(coordinate): pass - def compare_records(azara_record, rui_record): pass From 55f231fd82a9daf5554790a0cc2b12ef1fa65c77 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:17:03 -0700 Subject: [PATCH 22/27] Changed final test to support altered task for report string. Removed context handler decorator for re-routing stdout and extra imports. --- .../exercises/concept/tuples/tuples_test.py | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples_test.py b/languages/python/exercises/concept/tuples/tuples_test.py index 6460d80356..5d89131d59 100644 --- a/languages/python/exercises/concept/tuples/tuples_test.py +++ b/languages/python/exercises/concept/tuples/tuples_test.py @@ -1,22 +1,11 @@ import unittest -import sys -from contextlib import contextmanager -from io import StringIO - from tuples import get_coordinate, convert_coordinate, compare_records, create_record, clean_up -@contextmanager -def captured_output(): - new_out, new_err = StringIO(), StringIO() - old_out, old_err = sys.stdout, sys.stderr - try: - sys.stdout, sys.stderr = new_out, new_err - yield sys.stdout, sys.stderr - finally: - sys.stdout, sys.stderr = old_out, old_err - class TuplesTest(unittest.TestCase): + + maxDiff = None + def test_get_coordinate(self): input_data = [("Scrimshaw Whale's Tooth", '2A'), ('Brass Spyglass', '4B'), @@ -105,10 +94,10 @@ def test_create_record(self): for item, result in zip(input_data, result_data): with self.subTest("make record if coordinates match", item=item, result=result): + #self.assertEqual.__self__.maxDiff = None self.assertEqual(create_record(item[0], item[1]), result) def test_clean_up(self): - input_data = ( ("Scrimshaw Whale's Tooth", '2A', 'Deserted Docks', ('2', 'A'), 'Blue'), ('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), @@ -116,7 +105,7 @@ def test_clean_up(self): ('Glass Starfish', '6D', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange'), ('Vintage Pirate Hat', '7E', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), ('Pirate Flag', '7F', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange'), - ('Crystal Crab', '6A', 'Old Schooner', ('6', 'A'), 'Purple'), + ('Crystal Crab', '6A', 'Old Schooner', ('6', 'A'), 'Purple'), ('Model Ship in Large Bottle', '8A', 'Harbor Managers Office', ('8', 'A'), 'Purple'), ('Angry Monkey Figurine', '5B', 'Stormy Breakwater', ('5', 'B'), 'Purple'), ('Carved Wooden Elephant', '8C', 'Foggy Seacave', ('8', 'C'), 'Purple'), @@ -125,21 +114,18 @@ def test_clean_up(self): ('Silver Seahorse', '4E', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow') ) - result_data = "(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n" \ - "('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n" \ - "('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n" \ - "('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n" \ - "('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n" \ - "('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n" \ - "('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n" \ - "('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n" \ - "('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n" \ - "('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n" \ - "('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n" \ - "('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n" \ - "('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')" - - with captured_output() as (out, err): - clean_up(input_data) - output = out.getvalue().strip() - self.assertEqual(output, result_data) + result_data = """(\"Scrimshaw Whale's Tooth\", 'Deserted Docks', ('2', 'A'), 'Blue')\n\ +('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n\ +('Robot Parrot', 'Seaside Cottages', ('1', 'C'), 'Blue')\n\ +('Glass Starfish', 'Tangled Seaweed Patch', ('6', 'D'), 'Orange')\n\ +('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n\ +('Pirate Flag', 'Windswept Hilltop (Island of Mystery)', ('7', 'F'), 'Orange')\n\ +('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n\ +('Model Ship in Large Bottle', 'Harbor Managers Office', ('8', 'A'), 'Purple')\n\ +('Angry Monkey Figurine', 'Stormy Breakwater', ('5', 'B'), 'Purple')\n\ +('Carved Wooden Elephant', 'Foggy Seacave', ('8', 'C'), 'Purple')\n\ +('Amethyst Octopus', 'Aqua Lagoon (Island of Mystery)', ('1', 'F'), 'Yellow')\n\ +('Antique Glass Fishnet Float', 'Spiky Rocks', ('3', 'D'), 'Yellow')\n\ +('Silver Seahorse', 'Hidden Spring (Island of Mystery)', ('4', 'E'), 'Yellow')\n""" + + self.assertEqual(clean_up(input_data), result_data) From a2a864d96773a041d1a696287f38f08693bcc83a Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 00:42:22 -0700 Subject: [PATCH 23/27] Corrected terminal output code exxample for task 4. --- .../python/exercises/concept/tuples/.docs/instructions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.docs/instructions.md b/languages/python/exercises/concept/tuples/.docs/instructions.md index b2a7def0b0..d19758fe8f 100644 --- a/languages/python/exercises/concept/tuples/.docs/instructions.md +++ b/languages/python/exercises/concept/tuples/.docs/instructions.md @@ -84,11 +84,11 @@ True Implement the `create_record()` function that takes a `(treasure, coordinate)` pair from Azaras list and a `(location, coordinate, quadrant)` record from Ruis list and returns `(treasure, coordinate, location, coordinate, quadrant)` **if the coordinates match**. If the coordinats _do not_ match, return the string "not a match.". Re-format the coordinate as needed for accurate comparison. ```python -create_record(('Brass Spyglass', '4B'),('Abandoned Lighthouse', ("4", "B"), 'Blue')) ->>> ('Brass Spyglass', '4B', 'Abandoned Lighthouse', ("4", "B"), 'Blue') +>>> create_record(('Brass Spyglass', '4B'),('Abandoned Lighthouse', ("4", "B"), 'Blue')) +('Brass Spyglass', '4B', 'Abandoned Lighthouse', ("4", "B"), 'Blue') -create_record(('Brass Spyglass', '4B'),(("1", "C"), 'Seaside Cottages', 'blue')) ->>> "not a match." +>>> create_record(('Brass Spyglass', '4B'),(("1", "C"), 'Seaside Cottages', 'blue')) +"not a match." ``` ## 5. "Clean up" & make a report of all records From f70a2abe8e3317349546c1dff1950994e8f43a7f Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 11:35:21 -0700 Subject: [PATCH 24/27] Removed print as a prerequisite of the exercise. Added absolute link for tuples.md refrence doc. --- languages/python/exercises/concept/tuples/.docs/after.md | 2 +- languages/python/exercises/concept/tuples/.meta/design.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/languages/python/exercises/concept/tuples/.docs/after.md b/languages/python/exercises/concept/tuples/.docs/after.md index 8d10f22456..385e791e64 100644 --- a/languages/python/exercises/concept/tuples/.docs/after.md +++ b/languages/python/exercises/concept/tuples/.docs/after.md @@ -1,4 +1,4 @@ -In Python, a [tuple](../../../../reference/concepts/builtin_types/tuple.md) is an immutable collection of items in _sequence_. Like most collections (_see the built-ins [`list`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/list.md), [`dict`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/dict.md) and [`set`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/set.md)_), tuples can hold any (or multiple) data type(s) -- including other tuples. Like any [sequence](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range), items are referenced by 0-based index number, and can be copied in whole or in part via _slice notation_. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). +In Python, a [tuple](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/tuple.md) is an immutable collection of items in _sequence_. Like most collections (_see the built-ins [`list`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/list.md), [`dict`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/dict.md) and [`set`](https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/builtin_types/set.md)_), tuples can hold any (or multiple) data type(s) -- including other tuples. Like any [sequence](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range), items are referenced by 0-based index number, and can be copied in whole or in part via _slice notation_. Tuples support all [common sequence operations](https://docs.python.org/3/library/stdtypes.html#common-sequence-operations). Tuples take up very little memory space compared to other collection types and have constant (_O(1)_) access time. However, they cannot be resized, sorted, or altered once created, so are less flexible when frequent changes or updates to data are needed. diff --git a/languages/python/exercises/concept/tuples/.meta/design.md b/languages/python/exercises/concept/tuples/.meta/design.md index 7ee46dedc8..adea0299bf 100644 --- a/languages/python/exercises/concept/tuples/.meta/design.md +++ b/languages/python/exercises/concept/tuples/.meta/design.md @@ -32,6 +32,5 @@ - `if-keyword` - `in-keyword` - `integers` -- `print` - `return-keyword` - `strings` From 2e00a38ec3591b9a72a651a751306d3175d75746 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 16:58:12 -0700 Subject: [PATCH 25/27] Removed excess PyTest config from test class. --- languages/python/exercises/concept/tuples/tuples_test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/languages/python/exercises/concept/tuples/tuples_test.py b/languages/python/exercises/concept/tuples/tuples_test.py index 5d89131d59..b4127cda58 100644 --- a/languages/python/exercises/concept/tuples/tuples_test.py +++ b/languages/python/exercises/concept/tuples/tuples_test.py @@ -4,8 +4,6 @@ class TuplesTest(unittest.TestCase): - maxDiff = None - def test_get_coordinate(self): input_data = [("Scrimshaw Whale's Tooth", '2A'), ('Brass Spyglass', '4B'), @@ -94,7 +92,6 @@ def test_create_record(self): for item, result in zip(input_data, result_data): with self.subTest("make record if coordinates match", item=item, result=result): - #self.assertEqual.__self__.maxDiff = None self.assertEqual(create_record(item[0], item[1]), result) def test_clean_up(self): From af5736f3636695bb23306353598f830b29d9d32c Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 16:58:42 -0700 Subject: [PATCH 26/27] Added tuples concept exercise information and uuid. --- languages/python/config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/languages/python/config.json b/languages/python/config.json index a33bc2f1dd..bec93ecc65 100644 --- a/languages/python/config.json +++ b/languages/python/config.json @@ -14,6 +14,12 @@ "uuid": "5a9b42fb-ddf4-424b-995d-f9952ea63c37", "concepts": ["strings"], "prerequisites": ["functions"] + }, + { + "slug": "tuples", + "uuid": "7ecd42c1-2ed5-487a-bc89-71c9cbad9b05", + "concepts": ["tuples"], + "prerequisites": ["boleans","for-loops","functions","if-keyword","in-keyword","integers","return-keyword"] } ], "practice": [] From 8416783d3e44178add83e7fd766ea5f0c882e96c Mon Sep 17 00:00:00 2001 From: BethanyG Date: Thu, 9 Jul 2020 17:00:50 -0700 Subject: [PATCH 27/27] Ran prettier on config file, since I forgot to. --- languages/python/config.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/languages/python/config.json b/languages/python/config.json index bec93ecc65..e65598ad44 100644 --- a/languages/python/config.json +++ b/languages/python/config.json @@ -15,11 +15,19 @@ "concepts": ["strings"], "prerequisites": ["functions"] }, - { + { "slug": "tuples", "uuid": "7ecd42c1-2ed5-487a-bc89-71c9cbad9b05", "concepts": ["tuples"], - "prerequisites": ["boleans","for-loops","functions","if-keyword","in-keyword","integers","return-keyword"] + "prerequisites": [ + "boleans", + "for-loops", + "functions", + "if-keyword", + "in-keyword", + "integers", + "return-keyword" + ] } ], "practice": []