From bc9ee20ba8b6d667871bee27aad1c2419be1a9ba Mon Sep 17 00:00:00 2001 From: serenalucca <49030938+serenalucca@users.noreply.github.com> Date: Tue, 8 Dec 2020 23:50:27 +0100 Subject: [PATCH] Improve Concept Exercise: lists #2880 (#2898) * Improve Concept Exercise: lists #2880 Hi! This is my very first contribution to an open-source project, I need feedback, especially for the hints file. Thanks in advance. * Improve Concept Exercise: lists #2880 applied prettier * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.meta/design.md Co-authored-by: BethanyG * Update languages/exercises/concept/elyses-enchantments/.docs/introduction.md Co-authored-by: BethanyG * slice notation in introduction and about file * modification of hint and introduction file + format of comments * prettier format * Update hints.md * Update languages/concepts/lists/about.md Co-authored-by: BethanyG * Update languages/concepts/lists/about.md Co-authored-by: BethanyG * Update languages/concepts/lists/about.md Co-authored-by: BethanyG * Update languages/concepts/lists/about.md Co-authored-by: BethanyG * Update about.md * Update introduction.md * prettier Co-authored-by: BethanyG --- concepts/lists/about.md | 44 +++-- concepts/lists/links.json | 18 ++ .../elyses-enchantments/.docs/hints.md | 53 ++++++ .../elyses-enchantments/.docs/introduction.md | 175 ++++++++++++++++++ .../elyses-enchantments/.meta/design.md | 37 ++++ 5 files changed, 314 insertions(+), 13 deletions(-) create mode 100644 concepts/lists/links.json create mode 100644 exercises/concept/elyses-enchantments/.docs/hints.md create mode 100644 exercises/concept/elyses-enchantments/.docs/introduction.md create mode 100644 exercises/concept/elyses-enchantments/.meta/design.md diff --git a/concepts/lists/about.md b/concepts/lists/about.md index 987a97fd484..bf5e4dbd5c1 100644 --- a/concepts/lists/about.md +++ b/concepts/lists/about.md @@ -57,11 +57,11 @@ The `list()` constructor can be used empty or with an _iterable_ as an argument. >>> no_elements = list() [] -#the tuple is unpacked and each element is added +# The tuple is unpacked and each element is added. >>> multiple_elements_tuple = list(("Parrot", "Bird", 334782)) ["Parrot", "Bird", 334782] -#the set is unpacked and each element is added +# The set is unpacked and each element is added. >>> multiple_elements_set = list({2, 3, 5, 7, 11}) [2,3,5,7,11] ``` @@ -70,7 +70,7 @@ Results when using a list constructor with a string or a dict may be surprising: ````python -#string elements (Unicode code points) are iterated through and added *individually* +# String elements (Unicode code points) are iterated through and added *individually*. >>> multiple_elements_string = list("Timbuktu") ['T', 'i', 'm', 'b', 'u', 'k', 't', 'u'] @@ -112,7 +112,7 @@ Items inside lists (_like the sequence types `string` and `tuple`_), can be acce >>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"] -#Oatmeal is at index 0 or index -4 +# Oatmeal is at index 0 or index -4. >>> first_breakfast_food = breakfast_foods[0] 'Oatmeal' @@ -120,13 +120,31 @@ Items inside lists (_like the sequence types `string` and `tuple`_), can be acce 'Oatmeal' ``` +You can access a portion of a list with _slice notation_ (`[start:stop]`). A _slice_ is defined as the sequence of items in a list at position `index` such that `start <= index < stop`. + +Slicing does not modify the original `list`. Instead, you get a new list with copies of all the elements you asked for. +You can also slice a list using a `step` parameter with the notation `[start:stop:step]`. Using a `step` will "skip over" or filter the list elements (_for example, a `step` of 2 will be every other element in the range_). + +```python + +>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"] + +# If there is no step parameter, the step is assumed to be 1. +>>> middle_colors = colors[2:6] +["Green", "Yellow", "Orange", "Pink"] + +# If the stop parameter is omitted, the slice will stop at the end of the list. +>>> primary_colors = colors[0::3] +["Red", "Yellow", "Blue"] +``` + The method `.pop()` can be used to both remove and return a value at a given index: ```python >>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"] -#Fruit Salad is at index 1 or index -3 +# Fruit Salad is at index 1 or index -3. >>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"] >>> fruit_on_the_side = breakfast_foods.pop(-3) 'Fruit Salad' @@ -142,13 +160,13 @@ The method `.insert()` can be used to add an element at a specific position. The breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"] -#adding bacon to the mix before index 3 or index -1 +# Adding bacon to the mix before index 3 or index -1. >>> breakfast_foods.insert(3,"Bacon") >>> print(breakfast_foods) ['Oatmeal', 'Fruit Salad', 'Eggs', 'Bacon', 'Toast'] -#adding coffee in the first position +# Adding coffee in the first position. >>> breakfast_foods.insert(0, "Coffee") >>> print(breakfast_foods) ['Coffee', 'Oatmeal', 'Fruit Salad', 'Eggs', 'Bacon', 'Toast'] @@ -196,29 +214,29 @@ One common way to compose a list of values is to use `list.append()` with a loop Lists can be combined via various techniques: ```python -# using the plus + operator unpacks each list and creates a new list, but it is not efficent. +# Using the plus + operator unpacks each list and creates a new list, but it is not efficent. >>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"] ["George", 5, "cat", "Tabby"] -#likewise, using the multiplication operator * is the equivalent of using + n times +# Likewise, using the multiplication operator * is the equivalent of using + n times. >>> first_group = ["cat", "dog", "elephant"] >>> multiplied_group = first_group * 3 ['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant'] -# a more efficent method of combining 2 lists is to use slice asignment or appending in a loop -# by mutating one of the original lists +# A more efficent method of combining 2 lists is to use slice asignment or appending in a loop +# by mutating one of the original lists. first_one = ["cat", "Tabby"] second_one = ["George", 5] -# this assigns the second list to index 0 in the first list +# This assigns the second list to index 0 in the first list. >>> first_one[0:0] = second_one >>> first_one ["George", 5, "cat", "Tabby"] -# this loops through the first list and appends it's items to the end of the second list +# This loops through the first list and appends it's items to the end of the second list. >>> for item in first_one: >>> second_one.append(item) ... diff --git a/concepts/lists/links.json b/concepts/lists/links.json new file mode 100644 index 00000000000..c9ade573ba8 --- /dev/null +++ b/concepts/lists/links.json @@ -0,0 +1,18 @@ +[ + { + "url": "https://docs.python.org/3/tutorial/datastructures.html", + "description": "Python Tutorial: Lists" + }, + { + "url": "https://docs.python.org/3/library/stdtypes.html#list", + "description": "Lists Type in Python Docs" + }, + { + "url": "https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range", + "description": "Sequence Types in Python Docs" + }, + { + "url": "https://realpython.com/python-lists-tuples/", + "description": "Real Python: Lists and Tuples" + } +] diff --git a/exercises/concept/elyses-enchantments/.docs/hints.md b/exercises/concept/elyses-enchantments/.docs/hints.md new file mode 100644 index 00000000000..380d77c588b --- /dev/null +++ b/exercises/concept/elyses-enchantments/.docs/hints.md @@ -0,0 +1,53 @@ +## General + +## 1. Creating a List + +- `Lists` in python may be [constructed](https://docs.python.org/3/library/stdtypes.html#list) in several ways. +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list`. + +## 2. Creating a copy of a List + +- `Lists` can be [nested](https://realpython.com/python-lists-tuples/#lists-can-be-nested), this means that a `list` can be an element of another `list`. +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list` containing two `lists`. + +## 3. Concatenating Lists + +- Sequence types such as `list` already support a few [common operations](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range) +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list`. + +## 4. Testing List Membership + +- Sequence types such as `list` already support a few [common operations](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range) +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `boolean`. + +## 5. Accessing List Elements by Index + +- Sequence types such as `list` already support a few [common operations](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range) +- To access an element use the square brackets notation. +- Remember that the first element of the `list` is at index 0 +- In python, negative indexing starts the count from the end. This mean that you can find the last element of the `list` at index -1. +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list` containig two elements. + +## 6. Accessing Sublists by Slicing + +- Sequence types such as `list` already support a few [common operations](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range) +- For the last part of the exercise, think about reusing the code from the functions that you just implemented. +- These functions should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list`. + +## 7. Iterating Over List Items + +- There are a few techniques to [iterate over a `list` in python](https://www.geeksforgeeks.org/iterate-over-a-list-in-python/). +- You should use the function `print` on each element of the `list` to print each of them on a separate line. +- This function should not [return](https://www.w3schools.com/python/ref_keyword_return.asp) anything so you should end it with just the statement `return`. + +## 8. Creating Lists with Mixed Data Types + +- There are many [built-in types](https://docs.python.org/3/library/stdtypes.html) in python. +- [`Lists` Can Contain Arbitrary Objects](https://realpython.com/python-lists-tuples/#lists-can-contain-arbitrary-objects). +- This function should [return](https://www.w3schools.com/python/ref_keyword_return.asp) a `list`. + +## 9. Modifying Values in Lists + +- `Lists` in python are mutable, this means that once a `list` is created, you can modify, delete or add any element as you wish. +- Python provides a wide range of [ways to modify `lists`](https://realpython.com/python-lists-tuples/#lists-are-mutable). +- This function should not [return](https://www.w3schools.com/python/ref_keyword_return.asp) anything so you should end it with the statement `return` alone. diff --git a/exercises/concept/elyses-enchantments/.docs/introduction.md b/exercises/concept/elyses-enchantments/.docs/introduction.md new file mode 100644 index 00000000000..b7f20304aff --- /dev/null +++ b/exercises/concept/elyses-enchantments/.docs/introduction.md @@ -0,0 +1,175 @@ +In Python, a [list][list] is a mutable collection of items in _sequence_. Like most collections (_see the built-ins [`tuple`][tuple], [`dict`][dict] and [`set`][set]_), lists can hold reference to any (or multiple) data type(s) - including other lists. Like any [sequence][sequence type], items are referenced by 0-based index number, and can be copied in whole or in part via _slice notation_. Lists support all [common sequence operations][common sequence operations], as well as [mutable sequence operations][mutable sequence operations] like `.append()` and `.reverse()`. They can be iterated over in a loop by using the `for item in ` construct. + +Under the hood, `lists` are implemented as [dynamic arrays][dynamic array] -- similar to Java's [`Arraylist`][arraylist] type. Lists are most often used to store groups of similar data (_strings, numbers, sets etc._) of unknown length. Accessing items, checking for membership via `in`, or appending items to the "right-hand" side of a list are all very efficient. Appending to the "left-hand" side or inserting into the middle of a list is much _less_ efficient because it requires shifting items to keep them in sequence. + +Because lists are mutable and can contain references to arbitrary objects, they take up more memory space than a fixed-size `array.array` type of the same apparent length. Despite this, lists are an extremely flexible and useful data structure and many built-in methods and operations in Python produce lists as their output. + +## Construction + +A list can be declared as a _literal_ with square `[]` brackets and commas between elements: + +```python +>>> no_elements = [] +[] + +>>> one_element = ["Guava"] +["Guava"] + +>>> elements_separated_with_commas = ["Parrot", "Bird", 334782] +["Parrot", "Bird", 334782] +``` + +For readability, line breaks can be used when there are many elements or nested data structures within a list: + +```python +>>> lots_of_entries =[ + "Rose", + "Sunflower", + "Poppy", + "Pansy", + "Tulip", + "Fuchsia", + "Cyclamen", + "Lavender" + ] +['Rose', 'Sunflower', 'Poppy', 'Pansy', 'Tulip', 'Fuchsia', 'Cyclamen', 'Lavender'] +>>> nested_data_structures = [ + {"fish": "gold", "monkey": "brown", "parrot" : "grey"}, + ("fish", "mammal", "bird"), + ['water', 'jungle', 'sky'] + ] +[{"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"), ['water', 'jungle', 'sky']] +``` + +The `list()` constructor can be used empty or with an _iterable_ as an argument. Elements in the iterable are cycled through by the constructor and added to the list in order: + +```python +>>> no_elements = list() +[] + +# The tuple is unpacked and each element is added. +>>> multiple_elements_tuple = list(("Parrot", "Bird", 334782)) +["Parrot", "Bird", 334782] + +# The set is unpacked and each element is added. +>>> multiple_elements_set = list({2, 3, 5, 7, 11}) +[2,3,5,7,11] +``` + +Results when using a list constructor with a string or a dict may be surprising: + +````python + +# String elements (Unicode code points) are iterated through and added *individually*. +>>> multiple_elements_string = list("Timbuktu") +['T', 'i', 'm', 'b', 'u', 'k', 't', 'u'] + + +>>> multiple_code_points_string = list('अभ्यास') +['अ', 'भ', '्', 'य', 'ा', 'स'] + +""" +Because the `list` constructor will only take _iterables_ (or nothing) as arguments, objects that are _not_ iterable will throw a type error. Consequently, it is much easier to create a one-item list via the literal method. + +```python + +>>> one_element = list(16) +Traceback (most recent call last): + File "", line 1, in + TypeError: 'int' object is not iterable + +>>> one_element_from_iterable = list((16,)) +[16] +```` + +## Accessing elements + +Items inside lists (_like the sequence types `string` and `tuple`_), 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_). + +| **0** | **1** | **2** | **3** | **4** | **5** |\ + -------------------------\ + | P | y | t | h | o | n |\ + -------------------------\ + |_**-6**_ |_**-5**_ |_**-4**_ |_**-3**_ |_**-2**_ |_**-1**_ | <---- + +```python + +>>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"] + +# Oatmeal is at index 0 or index -4. +>>> first_breakfast_food = breakfast_foods[0] +'Oatmeal' + +>>> first_breakfast_food = breakfast_foods[-4] +'Oatmeal' +``` + +You can access a portion of a list with _slice notation_ (`[start:stop]`). A _slice_ is defined as the sequence of items in a list at position `index` such that `start <= index < stop`. + +Slicing does not modify the original `list`. Instead, you get a new list with copies of all the elements you asked for. +You can also slice a list using a `step` parameter with the notation `[start:stop:step]`. Using a `step` will "skip over" or filter the list elements (_for example, a `step` of 2 will be every other element in the range_). + +```python +>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"] +# If there is no step parameter, the step is assumed to be 1. +>>> middle_colors = colors[2:6] +["Green", "Yellow", "Orange", "Pink"] +# If the stop parameter is omitted, the slice will stop at the end of the list. +>>> primary_colors = colors[0::3] +["Red", "Yellow", "Blue"] +``` + +## Working with lists + +Lists supply an _iterator_, and can be looped through/over in the same manner as other _sequence types_: + +```python + +>>> colors = ["Orange", "Green", "Grey", "Blue"] +>>> for item in colors: +... print(item) +... +Orange +Green +Grey +Blue + +>>> numbers_to_cube = [5, 13, 12, 16] +>>> for number in numbers_to_cube: +... print(number*3) +... +15 +39 +36 +48 + +``` + +Lists can be combined via various techniques: + +```python +# Using the plus + operator unpacks each list and creates a new list, but it is not efficent. +>>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"] +["George", 5, "cat", "Tabby"] + + +# Likewise, using the multiplication operator * is the equivalent of using + n times. +>>> first_group = ["cat", "dog", "elephant"] + +>>> multiplied_group = first_group * 3 +['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant'] + + + + +[list]: https://docs.python.org/3/library/stdtypes.html#list +[tuple]: https://docs.python.org/3/library/stdtypes.html#tuple +[dict]: https://docs.python.org/3/library/stdtypes.html#dict +[set]: https://docs.python.org/3/library/stdtypes.html#set +[sequence type]: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range +[common sequence operations]: https://docs.python.org/3/library/stdtypes.html#common-sequence-operations +[mutable sequence operations]: https://docs.python.org/3/library/stdtypes.html#typesseq-mutable +[dynamic array]: https://en.wikipedia.org/wiki/Dynamic_array +[arraylist]: https://beginnersbook.com/2013/12/java-arraylist/ +[doubly linked list]: https://en.wikipedia.org/wiki/Doubly_linked_list +``` diff --git a/exercises/concept/elyses-enchantments/.meta/design.md b/exercises/concept/elyses-enchantments/.meta/design.md new file mode 100644 index 00000000000..027c8e79159 --- /dev/null +++ b/exercises/concept/elyses-enchantments/.meta/design.md @@ -0,0 +1,37 @@ +## Goal + +The goal of this exercise is to teach the basics of the `list` data type in Python. The exercise will walk the student through how to create lists via various methods, iterate through lists via looping, and access items in various lists through indexing and forming/accessing list slices. + +## Learning objectives + +- Create a `list` via constructor (`list()`) & literal (`[]`) +- Combine two or more lists by concatenation via `+` +- Check for an items membership/absence in a list using `in` and/or `not in` +- Access items in a list via index (`bracket notation`) +- Access a range of items in a list via list slicing (`[start:stop:step]`) +- Iterate through a list using `for item in` +- Understand that `lists` can store mixed/any data types +- Understand that `lists` are mutable. Assigning a new value to a list index will change the value at that index. + +## Out of scope + +- List Comprehensions (these will be covered in their own concept exercise) +- List methods (`copy()`, `append()`, `sort()` etc) +- How builtin functions relate to lists (`len()`, `max()`, `min()`, `count()`, `sorted()`) +- Construction of complex or nested `lists` (i.e a `list` of `dicts`, a `list` of `lists`, a `list` of `tuples`) +- Consequences and considerations of mutability + +## Concepts + +- `lists` +- indexing +- slicing +- concatenation +- iteration + +## Prerequisites + +- `basics` +- `str` +- `comparisons` +- `conditionals`