primeiro commit com exercicios de Exercism realizados até esta data

This commit is contained in:
2026-10-17 22:10:27 +01:00
commit 58fccbe27a
708 changed files with 35038 additions and 0 deletions
@@ -0,0 +1,24 @@
{
"authors": [
"mohanrajanr",
"BethanyG"
],
"contributors": [
"BethanyG",
"valentin-p",
"pranasziaukas"
],
"files": {
"solution": [
"list_methods.py"
],
"test": [
"list_methods_test.py"
],
"exemplar": [
".meta/exemplar.py"
]
},
"icon": "spiral-matrix",
"blurb": "Learn useful list methods helping Chaitana manage the lines for her colossal roller coaster."
}
@@ -0,0 +1 @@
{"track":"python","exercise":"chaitanas-colossal-coaster","id":"74ca4126d16e47bc872cd9fcc30f6d12","url":"https://exercism.org/tracks/python/exercises/chaitanas-colossal-coaster","handle":"sanctushck","is_requester":true,"auto_approve":false}
+130
View File
@@ -0,0 +1,130 @@
# Help
## Running the tests
We use [pytest][pytest: Getting Started Guide] as our website test runner.
You will need to install `pytest` on your development machine if you want to run tests for the Python track locally.
You should also install the following `pytest` plugins:
- [pytest-cache][pytest-cache]
- [pytest-subtests][pytest-subtests]
Extended information can be found in our website [Python testing guide][Python track tests page].
### Running Tests
To run the included tests, navigate to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with your path_).
Test files usually end in `_test.py`, and are the same tests that run on the website when a solution is uploaded.
Linux/MacOS
```bash
$ cd {path/to/exercise-folder-location}
```
Windows
```powershell
PS C:\Users\foobar> cd {path\to\exercise-folder-location}
```
<br>
Next, run the `pytest` command in your terminal, replacing `{exercise_test.py}` with the name of the test file:
Linux/MacOS
```bash
$ python3 -m pytest -o markers=task {exercise_test.py}
==================== 7 passed in 0.08s ====================
```
Windows
```powershell
PS C:\Users\foobar> py -m pytest -o markers=task {exercise_test.py}
==================== 7 passed in 0.08s ====================
```
### Common options
- `-o` : override default `pytest.ini` (_you can use this to avoid marker warnings_)
- `-v` : enable verbose output.
- `-x` : stop running tests on first failure.
- `--ff` : run failures from previous test before running other test cases.
For additional options, use `python3 -m pytest -h` or `py -m pytest -h`.
### Fixing warnings
If you do not use `pytest -o markers=task` when invoking `pytest`, you might receive a `PytestUnknownMarkWarning` for tests that use our new syntax:
```bash
PytestUnknownMarkWarning: Unknown pytest.mark.task - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
```
To avoid typing `pytest -o markers=task` for every test you run, you can use a `pytest.ini` configuration file.
We have made one that can be downloaded from the top level of the Python track directory: [pytest.ini][pytest.ini].
You can also create your own `pytest.ini` file with the following content:
```ini
[pytest]
markers =
task: A concept exercise task.
```
Placing the `pytest.ini` file in the _root_ or _working_ directory for your Python track exercises will register the marks and stop the warnings.
More information on pytest marks can be found in the `pytest` documentation on [marking test functions][pytest: marking test functions with attributes] and the `pytest` documentation on [working with custom markers][pytest: working with custom markers].
Information on customizing pytest configurations can be found in the `pytest` documentation on [configuration file formats][pytest: configuration file formats].
### Extending your IDE or Code Editor
Many IDEs and code editors have built-in support for using `pytest` and other code quality tools.
Some community-sourced options can be found on our [Python track tools page][Python track tools page].
[Pytest: Getting Started Guide]: https://docs.pytest.org/en/latest/getting-started.html
[Python track tools page]: https://exercism.org/docs/tracks/python/tools
[Python track tests page]: https://exercism.org/docs/tracks/python/tests
[pytest-cache]:http://pythonhosted.org/pytest-cache/
[pytest-subtests]:https://github.com/pytest-dev/pytest-subtests
[pytest.ini]: https://github.com/exercism/python/blob/main/pytest.ini
[pytest: configuration file formats]: https://docs.pytest.org/en/6.2.x/customize.html#configuration-file-formats
[pytest: marking test functions with attributes]: https://docs.pytest.org/en/6.2.x/mark.html#raising-errors-on-unknown-marks
[pytest: working with custom markers]: https://docs.pytest.org/en/6.2.x/example/markers.html#working-with-custom-markers
## Submitting your solution
You can submit your solution using the `exercism submit list_methods.py` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Python track's documentation](https://exercism.org/docs/tracks/python)
- The [Python track's programming category on the forum](https://forum.exercism.org/c/programming/python)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
Below are some resources for getting help if you run into trouble:
- [The PSF](https://www.python.org) hosts Python downloads, documentation, and community resources.
- [The Exercism Community on Discord](https://exercism.org/r/discord)
- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community.
- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners.
- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done.
- [Python Community Forums](https://discuss.python.org/)
- [Free Code Camp Community Forums](https://forum.freecodecamp.org/)
- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help)
- [Pythontutor](http://pythontutor.com/) for stepping through small code snippets visually.
Additionally, [StackOverflow](http://stackoverflow.com/questions/tagged/python) is a good spot to search for your problem/question to see if it has been answered already.
If not - you can always [ask](https://stackoverflow.com/help/how-to-ask) or [answer](https://stackoverflow.com/help/how-to-answer) someone else's question.
@@ -0,0 +1,39 @@
# Hints
- Make sure you have a good understanding of how to create and update lists.
- The Python [documentation on `lists`][python lists] can be really helpful.
- The Python [tutorial section on `lists`][more on lists] is also a good resource.
## 1. Add Me to the queue
- An `if-else` statement can help you find which ticket type you are dealing with.
- You can then `append()` the person to the queue based on the ticket type.
## 2. Where are my friends
- You need to find the `index()` of the friend name from the queue.
## 3. Can I please join them?
- Since you know the `index()`, you can `insert()` the friend into the queue at that point.
## 4. Mean person in the queue
- You know the mean persons name, so you can `remove()` them from the queue.
## 5. Namefellows
- `count()`-ing the occurrences of the `name` in the queue could be a good strategy here.
## 6. Remove the last person
- Although you could `remove()` the person by name, `pop()`-ing them out might be quicker.
## 7. Sort the Queue List
- Don't forget that You need to avoid mutating the queue and losing its original order.
- Once you have a `copy()`, `sort()`-ing should be straightforward.
- We're looking for an _ascending_ sort, or _alphabetical from a-z_.
[python lists]: https://docs.python.org/3.11/library/stdtypes.html#list
[more on lists]: https://docs.python.org/3.11/tutorial/datastructures.html#more-on-lists
+419
View File
@@ -0,0 +1,419 @@
# Chaitana's Colossal Coaster
Welcome to Chaitana's Colossal Coaster on Exercism's Python Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
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.
Lists can be copied in whole or in part via [slice notation][slice notation] or through the use of `<list>.copy()`.
Like any [sequence][sequence type], elements within `lists` are referenced by `0-based index` number from the left, or `-1-based index` number from the right.
Lists support both [common][common sequence operations] and [mutable][mutable sequence operations] sequence operations such as `min(<list>)`/`max(<list>)`, `<list>.index()`, `<list>.append()` and `<list>.reverse()`.
Elements inside a `list` can be iterated over using the `for item in <list>` construct.
`for index, item in enumerate(<list>)` can be used when both the element index and element value are needed.
Python also provides many useful [list-methods][list-methods] for working with lists.
A selection of these `list methods` is covered below.
Note that when you manipulate a `list` with a `list-method`, **you alter the list** object that has been passed.
If you do not wish to mutate the original `list`, you will need to at least make a `shallow copy` of it via slice or `<list>.copy()`.
## Adding Items
To add an item to the end or "right-hand side" of an existing list, use `<list>.append(<item>)`:
```python
>>> numbers = [1, 2, 3]
>>> numbers.append(9)
>>> numbers
[1, 2, 3, 9]
```
Rather than _appending_, `<list>.insert()` gives you the ability to add the item to a _specific index_ in the list.
It takes 2 parameters:
1. the `<index>` at which you want the item to be inserted.
2. the `<item>` to be inserted.
**Note**: If the given `index` is 0, the item will be added to the start ("left-hand side") of the `list`.
If the supplied `index` is greater than the final `index` on the `list`, the item will be added in the final position -- the equivalent of using `<list>.append(<item>)`.
```python
>>> numbers = [1, 2, 3]
>>> numbers.insert(0, -2)
>>> numbers
[-2, 1, 2, 3]
>>> numbers.insert(1, 0)
>>> numbers
[-2, 0, 1, 2, 3]
```
`<list>.extend(<item>)` can be used to combine an existing list with the elements from another iterable (for example, a `set`, `tuple`, `str`, or `list`).
The iterable is _unpacked_ and elements are appended in order (_Using `<list>.append(<item>)` in this circumstance would add the entire iterable as a **single item**._).
```python
>>> numbers = [1, 2, 3]
>>> other_numbers = [5, 6, 7]
>>> numbers.extend(other_numbers)
>>> numbers
[1, 2, 3, 5, 6, 7]
>>> numbers.extend([8, 9])
>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9]
>>> numbers.append([8,9])
>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9, [8, 9]]
```
## Removing Items
To delete an item from a list use `<list>.remove(<item>)`, passing the item to be removed as an argument.
`<list>.remove(<item>)` will throw a `ValueError` if the item is not present in the `list`.
```python
>>> numbers = [1, 2, 3]
>>> numbers.remove(2)
>>> numbers
[1, 3]
# Trying to remove a value that is not in the list throws a ValueError
>>> numbers.remove(0)
ValueError: list.remove(x): x not in list
```
Alternatively, using the `<list>.pop(<index>)` method will both remove **and** `return` an element for use.
`<list>.pop(<index>)` takes one optional parameter: the `index` of the item to be removed and returned.
If the (optional) `index` argument is not specified, the final element of the `list` will be removed and returned.
If the `index` specified is higher than the final item `index`, an `IndexError` is raised.
```python
>>> numbers = [1, 2, 3]
>>> numbers.pop(0)
1
>>> numbers
[2, 3]
>>> numbers.pop()
3
>>> numbers
[2]
>>> numbers.pop(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
```
All elements can be removed from a `list` with `list.clear()`. It doesn't take any parameters.
```python
>>> numbers = [1, 2, 3]
>>> numbers.clear()
>>> numbers
[]
```
## Reversing and reordering
The `<list>.reverse()` method will reverse the order of elements **in-place**.
```python
>>> numbers = [1, 2, 3]
>>> numbers.reverse()
>>> numbers
[3, 2, 1]
```
A list can be re-ordered _**in place**_ with the help of [`<list>.sort()`][sort].
Default sort order is _ascending_ from the left.
The Python docs offer [additional tips and techniques for sorting][sorting how to].
~~~~exercism/note
From 2002 to 2022, Python used an algorithm called [`Timsort`][timsort] internally to arrange lists, but switched to [`Powersort`][powersort] from `Python 3.11` onward.
[powersort]: https://www.wild-inter.net/publications/munro-wild-2018
[timsort]: https://en.wikipedia.org/wiki/Timsort
~~~~
```python
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
# The default sort order is *ascending*.
>>> names.sort()
>>> names
["Bruce", "Natasha", "Thor", "Tony"]
```
If a _descending_ order is desired, pass the `reverse=True` argument:
```python
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> names.sort(reverse=True)
>>> names
["Tony", "Thor", "Natasha", "Bruce"]
```
For cases where mutating the original list is undesirable, the built-in [`sorted(<iterable>)`][sorted] function can be used to return a sorted **copy**.
```python
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> sorted(names)
['Bruce', 'Natasha', 'Thor', 'Tony']
```
## Occurrences of an item in a list
The number of occurrences of an element in a list can be calculated with the help of `list.count(<item>)`.
It takes the `item` to be counted as its argument and returns the total number of times that element appears in the `list`.
```python
>>> items = [1, 4, 7, 8, 2, 9, 2, 1, 1, 0, 4, 3]
>>> items.count(1)
3
```
## Finding the index of items
`<list>.index(<item>)` will return the `index` number of the _first occurrence_ of an item passed in.
If there are no occurrences, a `ValueError` is raised.
If the exact position of an item isn't needed, the built-in `in` operator is more efficient for checking if a list contains a given value.
Indexing is zero-based from the left, so the position of the "first" item is `0`.
Indexing will also work from the right, beginning with `-1`.
```python
>>> items = [7, 4, 1, 0, 2, 5]
>>> items.index(4)
1
>>> items.index(10)
ValueError: 10 is not in list
```
`start` and `end` indices can also be provided to narrow the search to a specific section of the `list`:
```python
>>> names = ["Tina", "Leo", "Thomas", "Tina", "Emily", "Justin"]
>>> names.index("Tina")
0
>>> names.index("Tina", 2, 5)
3
```
[common sequence operations]: https://docs.python.org/3/library/stdtypes.html#common-sequence-operations
[dict]: https://docs.python.org/3/library/stdtypes.html#dict
[list-methods]: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
[list]: https://docs.python.org/3/library/stdtypes.html#list
[mutable sequence operations]: https://docs.python.org/3/library/stdtypes.html#typesseq-mutable
[sequence type]: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
[set]: https://docs.python.org/3/library/stdtypes.html#set
[slice notation]: https://docs.python.org/3/reference/expressions.html#slicings
[sort]: https://docs.python.org/3/library/stdtypes.html#list.sort
[sorted]: https://docs.python.org/3/library/functions.html#sorted
[sorting how to]: https://docs.python.org/3/howto/sorting.html
[tuple]: https://docs.python.org/3/library/stdtypes.html#tuple
## Instructions
Chaitana owns a very popular theme park.
She only has one ride in the very center of beautifully landscaped grounds: The Biggest Roller Coaster in the World(TM).
Although there is only this one attraction, people travel from all over the world and stand in line for hours for the opportunity to ride Chaitana's hypercoaster.
There are two queues for this ride, each represented as a `list`:
1. Normal Queue
2. Express Queue (_also known as the Fast-track_) - where people pay extra for priority access.
You have been asked to write some code to better manage the guests at the park.
You need to implement the following functions as soon as possible before the guests (and your boss, Chaitana!) get cranky.
Make sure you read carefully.
Some tasks ask that you change or update the existing queue, while others ask you to make a copy of it.
## 1. Add me to the queue
Define the `add_me_to_the_queue()` function that takes 4 parameters `<express_queue>, <normal_queue>, <ticket_type>, <person_name>` and returns the appropriate queue updated with the person's name.
1. `<ticket_type>` is an `int` with 1 == express_queue and 0 == normal_queue.
2. `<person_name>` is the name (as a `str`) of the person to be added to the respective queue.
```python
>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=1, person_name="RichieRich")
...
["Tony", "Bruce", "RichieRich"]
>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=0, person_name="HawkEye")
....
["RobotGuy", "WW", "HawkEye"]
```
## 2. Where are my friends?
One person arrived late at the park but wants to join the queue where their friends are waiting.
But they have no idea where their friends are standing and there isn't any phone reception to call them.
Define the `find_my_friend()` function that takes 2 parameters `queue` and `friend_name` and returns the position in the queue of the person's name.
1. `<queue>` is the `list` of people standing in the queue.
2. `<friend_name>` is the name of the friend whose index (place in the queue) you need to find.
Remember: Indexing starts at 0 from the left, and -1 from the right.
```python
>>> find_my_friend(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], friend_name="Steve")
...
1
```
## 3. Can I please join them?
Now that their friends have been found (in task #2 above), the late arriver would like to join them at their place in the queue.
Define the `add_me_with_my_friends()` function that takes 3 parameters `queue`, `index`, and `person_name`.
1. `<queue>` is the `list` of people standing in the queue.
2. `<index>` is the position at which the new person should be added.
3. `<person_name>` is the name of the person to add at the index position.
Return the queue updated with the late arrivals name.
```python
>>> add_me_with_my_friends(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], index=1, person_name="Bucky")
...
["Natasha", "Bucky", "Steve", "T'challa", "Wanda", "Rocket"]
```
## 4. Mean person in the queue
You just heard from the queue that there is a really mean person shoving, shouting, and making trouble.
You need to throw that miscreant out for bad behavior!
Define the `remove_the_mean_person()` function that takes 2 parameters `queue` and `person_name`.
1. `<queue>` is the `list` of people standing in the queue.
2. `<person_name>` is the name of the person that needs to be kicked out.
Return the queue updated without the mean person's name.
```python
>>> remove_the_mean_person(queue=["Natasha", "Steve", "Eltran", "Wanda", "Rocket"], person_name="Eltran")
...
["Natasha", "Steve", "Wanda", "Rocket"]
```
## 5. Namefellows
You may not have seen two unrelated people who look exactly the same, but you have _definitely_ seen unrelated people with the exact same name (_namefellows_)!
Today, it looks like there are a lot of them in attendance.
You want to know how many times a particular name occurs in the queue.
Define the `how_many_namefellows()` function that takes 2 parameters `queue` and `person_name`.
1. `<queue>` is the `list` of people standing in the queue.
2. `<person_name>` is the name you think might occur more than once in the queue.
Return the number of occurrences of `person_name`, as an `int`.
```python
>>> how_many_namefellows(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"], person_name="Natasha")
...
2
```
## 6. Remove the last person
Sadly, it's overcrowded at the park today and you need to remove the last person in the normal line (_you will give them a voucher to come back in the fast-track on another day_).
You will have to define the function `remove_the_last_person()` that takes 1 parameter `queue`, which is the list of people standing in the queue.
You should update the `list` and also `return` the name of the person who was removed, so you can write them a voucher.
```python
>>> remove_the_last_person(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
'Rocket'
```
## 7. Sort the Queue List
For administrative purposes, you need to get all the names in a given queue in alphabetical order.
Define the `sorted_names()` function that takes 1 argument, `queue`, (the `list` of people standing in the queue), and returns a `sorted` copy of the `list`.
```python
>>> sorted_names(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
['Eltran', 'Natasha', 'Natasha', 'Rocket', 'Steve']
```
## Source
### Created by
- @mohanrajanr
- @BethanyG
### Contributed to by
- @BethanyG
- @valentin-p
- @pranasziaukas
@@ -0,0 +1,87 @@
"""Functions to manage and organize queues at Chaitana's roller coaster."""
def add_me_to_the_queue(express_queue, normal_queue, ticket_type, person_name):
"""Add a person to the 'express' or 'normal' queue depending on the ticket number.
:param express_queue: list - names in the Fast-track queue.
:param normal_queue: list - names in the normal queue.
:param ticket_type: int - type of ticket. 1 = express, 0 = normal.
:param person_name: str - name of person to add to a queue.
:return: list - the (updated) queue the name was added to.
"""
match ticket_type:
case 1:
express_queue.append(person_name)
return express_queue
case 0:
normal_queue.append(person_name)
return normal_queue
def find_my_friend(queue, friend_name):
"""Search the queue for a name and return their queue position (index).
:param queue: list - names in the queue.
:param friend_name: str - name of friend to find.
:return: int - index at which the friends name was found.
"""
for index, name in enumerate(queue):
if name == friend_name:
return index
return None
def add_me_with_my_friends(queue, index, person_name):
"""Insert the late arrival's name at a specific index of the queue.
:param queue: list - names in the queue.
:param index: int - the index at which to add the new name.
:param person_name: str - the name to add.
:return: list - queue updated with new name.
"""
queue.insert(index, person_name)
return queue
def remove_the_mean_person(queue, person_name):
"""Remove the mean person from the queue by the provided name.
:param queue: list - names in the queue.
:param person_name: str - name of mean person.
:return: list - queue update with the mean persons name removed.
"""
for index, name in enumerate(queue):
if name == person_name:
queue.pop(index)
return queue
def how_many_namefellows(queue, person_name):
"""Count how many times the provided name appears in the queue.
:param queue: list - names in the queue.
:param person_name: str - name you wish to count or track.
:return: int - the number of times the name appears in the queue.
"""
return queue.count(person_name)
def remove_the_last_person(queue):
"""Remove the person in the last index from the queue and return their name.
:param queue: list - names in the queue.
:return: str - name that has been removed from the end of the queue.
"""
return queue.pop()
def sorted_names(queue):
"""Sort the names in the queue in alphabetical order and return the result.
:param queue: list - names in the queue.
:return: list - copy of the queue in alphabetical order.
"""
queue.sort()
sorted_queue: list = queue.copy()
return sorted_queue
@@ -0,0 +1,316 @@
import unittest
from copy import deepcopy
import pytest
from list_methods import (
add_me_to_the_queue,
find_my_friend,
add_me_with_my_friends,
remove_the_mean_person,
how_many_namefellows,
remove_the_last_person,
sorted_names,
)
class ListMethodsTest(unittest.TestCase):
@pytest.mark.task(taskno=1)
def test_add_me_to_the_queue(self):
test_data = [
((['Tony', 'Bruce'], ['RobotGuy', 'WW'], 0, 'HawkEye'), ['RobotGuy', 'WW', 'HawkEye']),
((['Tony', 'Bruce'], ['RobotGuy', 'WW'], 1, 'RichieRich'), ['Tony', 'Bruce', 'RichieRich']),
((['Agatha', 'Pepper', 'Valkyrie'], ['Drax', 'Nebula'], 1, 'Okoye'), ['Agatha', 'Pepper', 'Valkyrie', 'Okoye']),
((['Agatha', 'Pepper', 'Valkyrie'], ['Drax', 'Nebula'], 0, 'Gamora'), ['Drax', 'Nebula', 'Gamora']),
]
for variant, (params, expected) in enumerate(test_data, start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
express_queue, normal_queue, ticket_type, person_name = deepcopy(params)
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = add_me_to_the_queue(*params)
error_message = (
f'\nCalled add_me_to_the_queue{express_queue, normal_queue, ticket_type, person_name}.\n'
f'The function returned {actual_result},\n'
f' but the tests expected {expected} after {person_name} was added.')
self.assertEqual(actual_result, expected, msg=error_message)
@pytest.mark.task(taskno=1)
def test_add_me_to_the_queue_validate_queue(self):
test_data = [
((['Tony', 'Bruce'], ['RobotGuy', 'WW'], 0, 'HawkEye'), ['RobotGuy', 'WW', 'HawkEye']),
((['Tony', 'Bruce'], ['RobotGuy', 'WW'], 1, 'RichieRich'), ['Tony', 'Bruce', 'RichieRich']),
((['Agatha', 'Pepper', 'Valkyrie'], ['Drax', 'Nebula'], 1, 'Okoye'), ['Agatha', 'Pepper', 'Valkyrie', 'Okoye']),
((['Agatha', 'Pepper', 'Valkyrie'], ['Drax', 'Nebula'], 0, 'Gamora'), ['Drax', 'Nebula', 'Gamora']),
]
for variant, (params, expected) in enumerate(test_data, start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
express_queue, normal_queue, ticket_type, person_name = deepcopy(params)
express, normal, ticket, name = params
with self.subTest(f'variation #{variant}',
express=express, normal=normal,
ticket=ticket, name=name, expected=expected):
actual_result = add_me_to_the_queue(express, normal, ticket, name)
if type == 1:
error_message = (
f'\nCalled add_me_to_the_queue{express_queue, normal_queue, ticket_type, person_name}.\n'
f'The queue == {express}, but the tests expected\n'
f'queue == {expected} after {person_name} was added.'
)
self.assertIs(actual_result, express, msg=error_message)
if type == 0:
error_message = (
f'\nCalled add_me_to_the_queue{express_queue, normal_queue, ticket_type, person_name}.\n'
f'The queue == {normal}, but the tests expected \n'
f'queue == {expected} after {person_name} was added.'
)
self.assertIs(actual_result, normal, msg=error_message)
@pytest.mark.task(taskno=2)
def test_find_my_friend(self):
test_data = [
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 'Natasha'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 'Steve'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 'Rocket'),
]
result_data = (0,1,4)
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = find_my_friend(*params)
error_message = (
f'\nCalled find_my_friend{params}.\n'
f'The function returned {actual_result}, but\n'
f'the tests expected {expected} when looking for\n'
f'{params[-1]} in the queue.'
)
self.assertIs(actual_result, expected, msg=error_message)
@pytest.mark.task(taskno=3)
def test_add_me_with_my_friends(self):
test_data = [
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 0, 'Bucky'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 1, 'Bucky'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 5, 'Bucky'),
]
result_data = [
['Bucky', 'Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'],
['Natasha', 'Bucky', 'Steve', 'Tchalla', 'Wanda', 'Rocket'],
['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket', 'Bucky'],
]
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
queue, index, person_name = deepcopy(params)
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = add_me_with_my_friends(*params)
error_message = (
f'\nCalled add_me_with_my_friends{queue, index, person_name}.\n'
f'The function returned {actual_result}, but\n'
f'the tests expected {expected} when adding\n'
f'{person_name} to position {index} in the queue.'
)
self.assertEqual(actual_result, expected, msg=error_message)
@pytest.mark.task(taskno=3)
def test_add_me_with_my_friends_validate_queue(self):
test_data = [
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 0, 'Bucky'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 1, 'Bucky'),
(['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'], 5, 'Bucky'),
]
result_data = [
['Bucky', 'Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket'],
['Natasha', 'Bucky', 'Steve', 'Tchalla', 'Wanda', 'Rocket'],
['Natasha', 'Steve', 'Tchalla', 'Wanda', 'Rocket', 'Bucky'],
]
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
start_queue, add_index, person_name = deepcopy(params)
queue, _, _ = params
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = add_me_with_my_friends(*params)
error_message = (
f'\nCalled add_me_with_my_friends{start_queue, add_index, person_name}.\n'
f'The function returned {actual_result},\n'
'but the original queue was unmodified. The tests expected the \n'
f'*original* queue to be modified by adding "{person_name}".'
)
self.assertIs(actual_result, queue, msg=error_message)
@pytest.mark.task(taskno=4)
def test_remove_the_mean_person(self):
test_data = [
(['Natasha', 'Steve', 'Ultron', 'Wanda', 'Rocket'], 'Ultron'),
(['Natasha', 'Steve', 'Wanda', 'Rocket', 'Ultron'], 'Rocket'),
(['Ultron', 'Natasha', 'Steve', 'Wanda', 'Rocket'], 'Steve'),
]
result_data = [
['Natasha', 'Steve', 'Wanda', 'Rocket'],
['Natasha', 'Steve', 'Wanda', 'Ultron'],
['Ultron', 'Natasha', 'Wanda', 'Rocket'],
]
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
start_queue, person_name = deepcopy(params)
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = remove_the_mean_person(*params)
error_message = (
f'\nCalled remove_the_mean_person{start_queue, person_name}.\n'
f'The function returned {actual_result}, but\n'
f'the tests expected {expected} when removing\n'
f'{person_name} from the queue.'
)
self.assertEqual(actual_result, expected, msg=error_message)
@pytest.mark.task(taskno=4)
def test_remove_the_mean_person_validate_queue(self):
test_data = [
(['Natasha', 'Steve', 'Ultron', 'Wanda', 'Rocket'], 'Ultron'),
(['Natasha', 'Steve', 'Wanda', 'Rocket', 'Ultron'], 'Rocket'),
(['Ultron', 'Natasha', 'Steve', 'Wanda', 'Rocket'], 'Steve'),
]
result_data = [
['Natasha', 'Steve', 'Wanda', 'Rocket'],
['Natasha', 'Steve', 'Wanda', 'Ultron'],
['Ultron', 'Natasha', 'Wanda', 'Rocket'],
]
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
start_queue, person_name = deepcopy(params)
queue, _ = params
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = remove_the_mean_person(*params)
error_message = (
f'\nCalled remove_the_mean_person{start_queue, person_name}.\n'
f'The function returned {actual_result}, queue == {queue}.\n'
f'But the tests expected queue == {expected} when removing\n'
f'{person_name}.'
)
self.assertIs(actual_result, queue, msg=error_message)
@pytest.mark.task(taskno=5)
def test_how_many_namefellows(self):
test_data = [(['Natasha', 'Steve', 'Ultron', 'Natasha', 'Rocket'], 'Bucky'),
(['Natasha', 'Steve', 'Ultron', 'Rocket'], 'Natasha'),
(['Natasha', 'Steve', 'Ultron', 'Natasha', 'Rocket'], 'Natasha')]
result_data = (0,1,2)
for variant, (params, expected) in enumerate(zip(test_data, result_data), start=1):
with self.subTest(f'variation #{variant}', params=params, expected=expected):
actual_result = how_many_namefellows(*params)
error_message = (f'Called how_many_namefellows{params}. '
f'The function returned {actual_result}, but '
f'The tests expected {expected} when counting '
f'namefellows in the queue for {params[-1]}.')
self.assertIs(actual_result, expected, msg=error_message)
@pytest.mark.task(taskno=6)
def test_remove_the_last_person(self):
test_data = [
(['Natasha', 'Steve', 'Ultron', 'Natasha', 'Rocket'], ['Natasha', 'Steve', 'Ultron', 'Natasha'], 'Rocket'),
(['Wanda', 'Natasha', 'Steve', 'Rocket', 'Ultron'], ['Wanda', 'Natasha', 'Steve', 'Rocket'], 'Ultron'),
(['Steve', 'Wanda', 'Rocket', 'Ultron', 'Natasha'], ['Steve', 'Wanda', 'Rocket', 'Ultron'], 'Natasha')
]
for variant, (queue, modified, expected) in enumerate(test_data, start=1):
with self.subTest(f'variation #{variant}', queue=queue, modified=modified, expected=expected):
# Deepcopy() is needed here because the task expects the input lists to be mutated.
# That mutation wrecks havoc with the verification and error messaging.
unmodified_queue = deepcopy(queue)
expected_result = expected
actual_result = remove_the_last_person(queue)
expected_queue = modified
error_message = (f'\nCalled remove_the_last_person({unmodified_queue}).\n'
f'The function was expected to remove and return the name "{expected_result}" '
f'and change the queue to {expected_queue},\n'
f'but the name "{actual_result}" was returned and the queue == {queue}.')
self.assertEqual((actual_result, queue), (expected_result, expected_queue), msg=error_message)
@pytest.mark.task(taskno=7)
def test_sorted_names(self):
test_data =(
(['Steve', 'Ultron', 'Natasha', 'Rocket'], ['Natasha', 'Rocket', 'Steve', 'Ultron']),
(['Agatha', 'Pepper', 'Valkyrie', 'Drax', 'Nebula'], ['Agatha', 'Drax', 'Nebula', 'Pepper', 'Valkyrie']),
(['Gamora', 'Loki', 'Tony', 'Peggy', 'Okoye'], ['Gamora', 'Loki', 'Okoye', 'Peggy', 'Tony']),
)
for variant, (queue, expected) in enumerate(test_data, start=1):
with self.subTest(f'variation #{variant}', queue=queue, expected=expected):
actual_result = sorted_names(queue)
expected_result = expected
error_message = (f'\nCalled sorted_names({queue}).\n'
f'The function returned {actual_result}, but \n'
f'the tests expect {expected_result}.')
self.assertEqual(actual_result, expected_result, msg=error_message)
@pytest.mark.task(taskno=7)
def test_sorted_names_validate_queue(self):
test_data = (
(['Steve', 'Ultron', 'Natasha', 'Rocket'], ['Natasha', 'Rocket', 'Steve', 'Ultron']),
(['Agatha', 'Pepper', 'Valkyrie', 'Drax', 'Nebula'], ['Agatha', 'Drax', 'Nebula', 'Pepper', 'Valkyrie']),
(['Gamora', 'Loki', 'Tony', 'Peggy', 'Okoye'], ['Gamora', 'Loki', 'Okoye', 'Peggy', 'Tony']),
)
for variant, (queue, expected) in enumerate(test_data, start=1):
with self.subTest(f'variation #{variant}', queue=queue, expected=expected):
# Deepcopy() is needed here because the input lists might be mutated.
# That mutation wrecks havoc with the verification and error messaging.
original_queue = deepcopy(queue)
actual_result = sorted_names(queue)
expected_result = expected
error_message = (f'\nCalled sorted_names({original_queue}).\n'
f'The function returned {actual_result}, \n'
f'with a queue == {queue}.\n'
f'The tests expect {expected_result}, \n'
f'with a queue == {original_queue}.')
self.assertIsNot(actual_result, queue, msg=error_message)