primeiro commit com exercicios de Exercism realizados até esta data
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"authors": [
|
||||
"j08k"
|
||||
],
|
||||
"contributors": [
|
||||
"valentin-p",
|
||||
"bethanyG",
|
||||
"mukeshgurpude",
|
||||
"kotp"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"dicts.py"
|
||||
],
|
||||
"test": [
|
||||
"dicts_test.py"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.py"
|
||||
]
|
||||
},
|
||||
"icon": "high-scores",
|
||||
"blurb": "Learn about dicts by managing warehouse inventory."
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"track":"python","exercise":"inventory-management","id":"cd6171c10c1d4c5c8ff039bc0d4af80f","url":"https://exercism.org/tracks/python/exercises/inventory-management","handle":"sanctushck","is_requester":true,"auto_approve":false}
|
||||
@@ -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 dicts.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,49 @@
|
||||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- [The Python Dictionary Tutorial][dict-tutorial] can be a great place to start.
|
||||
- The Python docs on [Mapping Types - dicts][dict docs] is also pretty helpful.
|
||||
|
||||
## 1. Create an inventory based on a list
|
||||
|
||||
- You need a [for loop][for-loop] to iterate the list of items, then insert each item in the dictionary if missing and increment the item count using the dictionary accessor.
|
||||
- You can use [`dict.setdefault`][dict setdefault] to make sure the value is set before incrementing the count of the item.
|
||||
- This function should [return][return-keyword] a dict].
|
||||
|
||||
## 2. Add items from a list to an existing dictionary
|
||||
|
||||
- You need a [for loop][for-loop] to iterate the list of items, then insert each item if not already in the dictionary and [increment][increment] the item count using the dictionary accessor.
|
||||
- You can use [`dict.setdefault`][dict setdefault] to make sure the value is set before incrementing the count of the item.
|
||||
- The function `add_items` can be used by the `create_inventory` function with an empty dictionary in parameter.
|
||||
- This function should [return][return-keyword] a dict.
|
||||
|
||||
## 3. Decrement items from the inventory
|
||||
|
||||
- You need [for loop][for-loop] to iterate the list of items, if the number of items is not `0` then [decrement][decrement] the current number of items.
|
||||
- You can use the check `key in dict` that returns `True` if the key exists to make sure the value is in the dictionary before decrementing the number of items.
|
||||
- This function should [return][return-keyword] a dict.
|
||||
|
||||
## 4. Remove an item entirely from the inventory
|
||||
|
||||
- If item is in the dictionary, [remove it][dict-pop].
|
||||
- If item is not in the dictionary, do nothing.
|
||||
- This function should [return][return-keyword] a dict.
|
||||
|
||||
## 5. Return the inventory content
|
||||
|
||||
- You need to use a [for loop][for-loop] on the inventory and if the number of item is greater of `0` then append the `tuple` to a `list`.
|
||||
- You can use [`dict.items()`][dict items] to iterate on both the item and the value at the same time, `items()` returns a `tuple` that you can use or deconstruct, if needed.
|
||||
- This function should [return][return-keyword] a [list][list] of [tuples][tuples].
|
||||
|
||||
[decrement]: https://www.w3schools.com/python/gloss_python_assignment_operators.asp
|
||||
[dict docs]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
|
||||
[dict items]: https://docs.python.org/3/library/stdtypes.html#dict.items
|
||||
[dict setdefault]: https://www.w3schools.com/python/ref_dictionary_setdefault.asp
|
||||
[dict-pop]: https://www.w3schools.com/python/ref_dictionary_pop.asp
|
||||
[dict-tutorial]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
|
||||
[for-loop]: https://docs.python.org/3/tutorial/controlflow.html#for-statements
|
||||
[increment]: https://www.w3schools.com/python/gloss_python_assignment_operators.asp
|
||||
[list]: https://docs.python.org/3/tutorial/introduction.html#lists
|
||||
[return-keyword]: https://www.w3schools.com/python/ref_keyword_return.asp
|
||||
[tuples]: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences
|
||||
@@ -0,0 +1,247 @@
|
||||
# Inventory Management
|
||||
|
||||
Welcome to Inventory Management 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 dictionary (`dict`) in Python is a data structure that associates [hashable][term-hashable] _keys_ to _values_ and is known in other programming languages as a resizable [hash table][hashtable-wikipedia], hashmap, or [associative array][associative-array].
|
||||
Dictionaries are Python's only built-in [mapping type][mapping-types-dict].
|
||||
|
||||
|
||||
`Keys` must be hashable and unique across the dictionary.
|
||||
Key types can include `numbers`, `str`, or `tuples` (of _immutable_ values).
|
||||
They cannot contain _mutable_ data structures such as `lists`, `dict`s, or `set`s.
|
||||
As of Python 3.7, `dict` key order is guaranteed to be the order in which entries are inserted.
|
||||
|
||||
`values` can be of any data type or structure.
|
||||
Values can also nest _arbitrarily_, so they can include lists-of-lists, sub-dictionaries, and other custom or compound data structures.
|
||||
|
||||
Given a `key`, dictionaries can retrieve a `value` in (on average) constant time (_independent of the number of entries_).
|
||||
Compared to searching for a value within a `list` or `array` (_without knowing the `index` position_), a `dict` uses significantly more memory, but has very rapid retrieval.
|
||||
Dictionaries are especially useful in scenarios where the collection of items is large and must be accessed and updated frequently.
|
||||
|
||||
|
||||
## Dictionary Construction
|
||||
|
||||
Dictionaries can be created in many ways.
|
||||
The two most straightforward are using the `dict()`constructor or declaring a `dict` _literal_.
|
||||
|
||||
### The `dict()` Class Constructor
|
||||
|
||||
`dict()` (_the constructor for the dictionary class_) can be used with any iterable of `key`, `value` pairs or with a series of `<name>=<value>` _arguments_:
|
||||
|
||||
```python
|
||||
#Passing a list of key,value tuples.
|
||||
>>> wombat = dict([('name', 'Wombat'),('speed', 23),('land_animal', True)])
|
||||
{'name': 'Wombat', 'speed': 23, 'land_animal': True}
|
||||
|
||||
|
||||
#Using key=value arguments.
|
||||
>>> bear = dict(name="Black Bear", speed=40, land_animal=True)
|
||||
{'name': 'Black Bear', 'speed': 40, 'land_animal': True}
|
||||
```
|
||||
|
||||
### Dictionary Literals
|
||||
|
||||
A `dict` can also be directly entered as a _dictionary literal_, using curly brackets (`{}`) enclosing `key : value` pairs:
|
||||
|
||||
```python
|
||||
>>> whale = {"name": "Blue Whale", "speed": 35, "land_animal": False}
|
||||
{'name': 'Blue Whale', 'speed': 35, 'land_animal': False}
|
||||
```
|
||||
|
||||
## Accessing Values in a Dictionary
|
||||
|
||||
You can access an entry in a dictionary using a _key_ in square (`[]`) brackets.
|
||||
If a `key` does not exist n the `dict`, a `KeyError` is thrown:
|
||||
|
||||
```python
|
||||
>>> bear["speed"]
|
||||
40
|
||||
|
||||
>>> bear["color"]
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
KeyError: 'color'
|
||||
```
|
||||
|
||||
Accessing an entry via the `.get(<key>, <default value>)` method can avoid the `KeyError`:
|
||||
|
||||
```python
|
||||
>>> bear.get("color", 'not found')
|
||||
'not found'
|
||||
```
|
||||
|
||||
## Changing or Adding Dictionary Values
|
||||
|
||||
You can change an entry `value` by assigning to its _key_:
|
||||
|
||||
```python
|
||||
#Assigning the value "Grizzly Bear" to the name key.
|
||||
>>> bear["name"] = "Grizzly Bear"
|
||||
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True}
|
||||
|
||||
>>> whale["speed"] = 25
|
||||
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False}
|
||||
```
|
||||
|
||||
New `key`:`value` pairs can be _added_ in the same fashion:
|
||||
|
||||
```python
|
||||
# Adding an new "color" key with a new "tawney" value.
|
||||
>>> bear["color"] = 'tawney'
|
||||
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True, 'color': 'tawney'}
|
||||
|
||||
>>> whale["blowholes"] = 1
|
||||
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False, 'blowholes': 1}
|
||||
```
|
||||
|
||||
## Removing (Pop-ing) Dictionary Entries
|
||||
|
||||
You can use the `.pop(<key>)` method to delete a dictionary entry.
|
||||
`.pop()` removes the (`key`, `value`) pair and returns the `value` for use.
|
||||
Like `.get()`, `.pop(<key>)` accepts second argument (_`dict.pop(<key>, <default value>)`_) that will be returned if the `key` is not found.
|
||||
This prevents a `KeyError` being raised:
|
||||
|
||||
```python
|
||||
#Using .pop() removes both the key and value, returning the value.
|
||||
>>> bear.pop("name")
|
||||
'Grizzly Bear'
|
||||
|
||||
|
||||
#The "name" key is now removed from the dictionary.
|
||||
#Attempting .pop() a second time will throw a KeyError.
|
||||
>>> bear.pop("name")
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
KeyError: 'name'
|
||||
|
||||
|
||||
#Using a default argument with .pop() will prevent a KeyError from a missing key.
|
||||
>>> bear.pop("name", "Unknown")
|
||||
'Unknown'
|
||||
```
|
||||
|
||||
## Looping through/Iterating over a Dictionary
|
||||
|
||||
Looping through a dictionary using `for item in dict` or `while item` will iterate over only the _keys_ by default.
|
||||
You can access the _values_ within the same loop by using _square brackets_:
|
||||
|
||||
```python
|
||||
>>> for key in bear:
|
||||
>>> print((key, bear[key])) #this forms a tuple of (key, value) and prints it.
|
||||
('name', 'Black Bear')
|
||||
('speed', 40)
|
||||
('land_animal', True)
|
||||
```
|
||||
|
||||
You can also use the `.items()` method, which returns (`key`, `value`) tuples automatically:
|
||||
|
||||
```python
|
||||
#dict.items() forms (key, value tuples) that can be unpacked and iterated over.
|
||||
>>> for key, value in whale.items():
|
||||
>>> print(key, ":", value)
|
||||
name : Blue Whale
|
||||
speed : 25
|
||||
land_animal : False
|
||||
blowholes : 1
|
||||
```
|
||||
|
||||
Likewise, the `.keys()` method will return `keys` and the `.values()` method will return the `values`.
|
||||
|
||||
[associative-array]: https://en.wikipedia.org/wiki/Associative_array#:~:text=In%20computer%20science%2C%20an%20associative,a%20function%20with%20finite%20domain.
|
||||
[hashtable-wikipedia]: https://en.wikipedia.org/wiki/Hash_table
|
||||
[mapping-types-dict]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
|
||||
[term-hashable]: https://docs.python.org/3/glossary.html#term-hashable
|
||||
|
||||
## Instructions
|
||||
|
||||
In this exercise, you will be managing an inventory system.
|
||||
|
||||
The inventory should be organized by the item name and it should keep track of the number of items available.
|
||||
|
||||
You will have to handle adding items to an inventory.
|
||||
Each time an item appears in a given list, the item's quantity should be increased by `1` in the inventory.
|
||||
You will also have to handle deleting items from an inventory by decreasing quantities by `1` when requested.
|
||||
|
||||
Finally, you will need to implement a function that will return all the key-value pairs in a given inventory as a `list` of `tuples`.
|
||||
|
||||
|
||||
## 1. Create an inventory based on a list
|
||||
|
||||
Implement the `create_inventory(<input list>)` function that creates an "inventory" from an input list of items.
|
||||
It should return a `dict` containing each item name paired with their respective quantity.
|
||||
|
||||
```python
|
||||
>>> create_inventory(["coal", "wood", "wood", "diamond", "diamond", "diamond"])
|
||||
{"coal":1, "wood":2, "diamond":3}
|
||||
```
|
||||
|
||||
## 2. Add items from a list to an existing dictionary
|
||||
|
||||
Implement the `add_items(<inventory dict>, <item list>)` function that adds a list of items to the passed-in inventory:
|
||||
|
||||
```python
|
||||
>>> add_items({"coal":1}, ["wood", "iron", "coal", "wood"])
|
||||
{"coal":2, "wood":2, "iron":1}
|
||||
```
|
||||
|
||||
## 3. Decrement items from the inventory
|
||||
|
||||
Implement the `decrement_items(<inventory dict>, <items list>)` function that takes a `list` of items.
|
||||
Your function should remove `1` from an item count for each time that item appears on the `list`:
|
||||
|
||||
```python
|
||||
>>> decrement_items({"coal":3, "diamond":1, "iron":5}, ["diamond", "coal", "iron", "iron"])
|
||||
{"coal":2, "diamond":0, "iron":3}
|
||||
```
|
||||
|
||||
Item counts in the inventory should not be allowed to fall below 0.
|
||||
If the number of times an item appears on the input `list` exceeds the count available, the quantity listed for that item should remain at 0.
|
||||
Additional requests for removing counts should be ignored once the count falls to zero.
|
||||
|
||||
```python
|
||||
>>> decrement_items({"coal":2, "wood":1, "diamond":2}, ["coal", "coal", "wood", "wood", "diamond"])
|
||||
{"coal":0, "wood":0, "diamond":1}
|
||||
```
|
||||
|
||||
## 4. Remove an entry entirely from the inventory
|
||||
|
||||
Implement the `remove_item(<inventory dict>, <item>)` function that removes an item and its count entirely from an inventory:
|
||||
|
||||
```python
|
||||
>>> remove_item({"coal":2, "wood":1, "diamond":2}, "coal")
|
||||
{"wood":1, "diamond":2}
|
||||
```
|
||||
|
||||
If the item is not found in the inventory, the function should return the original inventory unchanged.
|
||||
|
||||
```python
|
||||
>>> remove_item({"coal":2, "wood":1, "diamond":2}, "gold")
|
||||
{"coal":2, "wood":1, "diamond":2}
|
||||
```
|
||||
|
||||
## 5. Return the entire content of the inventory
|
||||
|
||||
Implement the `list_inventory(<inventory dict>)` function that takes an inventory and returns a list of `(item, quantity)` tuples.
|
||||
The list should only include the _available_ items (_with a quantity greater than zero_):
|
||||
|
||||
```python
|
||||
>>> list_inventory({"coal":7, "wood":11, "diamond":2, "iron":7, "silver":0})
|
||||
[('coal', 7), ('diamond', 2), ('iron', 7), ('wood', 11)]
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @j08k
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @valentin-p
|
||||
- @bethanyG
|
||||
- @mukeshgurpude
|
||||
- @kotp
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,80 @@
|
||||
"""Functions to keep track and alter inventory."""
|
||||
|
||||
|
||||
def create_inventory(items):
|
||||
"""Create a dict that tracks the amount (count) of each element on the `items` list.
|
||||
|
||||
:param items: list - list of items to create an inventory from.
|
||||
:return: dict - the inventory dictionary.
|
||||
"""
|
||||
inventory: dict = {}
|
||||
for item in items:
|
||||
inventory[item] = items.count(item)
|
||||
return inventory
|
||||
|
||||
|
||||
def add_items(inventory, items):
|
||||
"""Add or increment items in inventory using elements from the items `list`.
|
||||
|
||||
:param inventory: dict - dictionary of existing inventory.
|
||||
:param items: list - list of items to update the inventory with.
|
||||
:return: dict - the inventory updated with the new items.
|
||||
"""
|
||||
# inventory is empty, create new one and return inventory
|
||||
if inventory == {}:
|
||||
return create_inventory(items)
|
||||
# increment items that already exists in inventory
|
||||
for item in inventory:
|
||||
inventory[item] += items.count(item)
|
||||
# add new items that doesnt exist in inventory
|
||||
# the new items can only be added after incrementing items that already
|
||||
# exists in inventory to avoid adding the new items again
|
||||
for item in items:
|
||||
if item not in inventory:
|
||||
inventory[item] = items.count(item)
|
||||
return inventory
|
||||
|
||||
|
||||
def decrement_items(inventory, items):
|
||||
"""Decrement items in inventory using elements from the `items` list.
|
||||
|
||||
:param inventory: dict - inventory dictionary.
|
||||
:param items: list - list of items to decrement from the inventory.
|
||||
:return: dict - updated inventory with items decremented.
|
||||
"""
|
||||
for item in inventory:
|
||||
if item in items:
|
||||
inventory[item] -= items.count(item)
|
||||
if inventory[item] < 0:
|
||||
inventory[item] = 0
|
||||
return inventory
|
||||
|
||||
|
||||
def remove_item(inventory, item):
|
||||
"""Remove item from inventory if it matches `item` string.
|
||||
|
||||
:param inventory: dict - inventory dictionary.
|
||||
:param item: str - item to remove from the inventory.
|
||||
:return: dict - updated inventory with item removed. Current inventory if item does not match.
|
||||
"""
|
||||
if item in inventory:
|
||||
inventory.pop(item)
|
||||
return inventory
|
||||
|
||||
|
||||
def list_inventory(inventory):
|
||||
"""Create a list containing only available (item_name, item_count > 0) pairs in inventory.
|
||||
|
||||
:param inventory: dict - an inventory dictionary.
|
||||
:return: list of tuples - list of key, value pairs from the inventory dictionary.
|
||||
"""
|
||||
inventory_list: list[tuple] = []
|
||||
# conventional
|
||||
# for item in inventory:
|
||||
# if inventory[item] > 0:
|
||||
# inventory_list.append((item, inventory[item]))
|
||||
# using list comprehension
|
||||
inventory_list = [
|
||||
(item, inventory[item]) for item in inventory if inventory[item] > 0
|
||||
]
|
||||
return inventory_list
|
||||
@@ -0,0 +1,120 @@
|
||||
import unittest
|
||||
import pytest
|
||||
from dicts import (create_inventory,
|
||||
add_items,
|
||||
decrement_items,
|
||||
remove_item,
|
||||
list_inventory)
|
||||
|
||||
|
||||
class InventoryTest(unittest.TestCase):
|
||||
|
||||
@pytest.mark.task(taskno=1)
|
||||
def test_create_inventory(self):
|
||||
|
||||
actual_result = create_inventory(["wood", "iron", "iron", "diamond", "diamond"])
|
||||
expected = {"wood": 1, "iron": 2, "diamond": 2}
|
||||
error_message = ('Called create_inventory(["wood", "iron", "iron", "diamond", "diamond"]). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_add_one_item(self):
|
||||
actual_result = add_items({"wood": 4, "iron": 2}, ["iron", "iron"])
|
||||
expected = {"wood": 4, "iron": 4}
|
||||
error_message = ('Called add_items({"wood": 4, "iron": 2}, ["iron", "iron"]). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_add_multiple_items(self):
|
||||
actual_result = add_items({"wood": 2, "gold": 1, "diamond": 3}, ["wood", "gold", "gold"])
|
||||
expected = {"wood": 3, "gold": 3, "diamond": 3}
|
||||
error_message = ('Called add_items({"wood": 2, "gold": 1, "diamond": 3}, ["wood", "gold", "gold"]). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_add_new_item(self):
|
||||
actual_result = add_items({"iron": 1, "diamond": 2}, ["iron", "wood", "wood"])
|
||||
expected = {"iron": 2, "diamond": 2, "wood": 2}
|
||||
error_message = ('Called add_items({"iron": 1, "diamond": 2}, ["iron", "wood", "wood"]). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_add_from_empty_dict(self):
|
||||
actual_result = add_items({}, ["iron", "iron", "diamond"])
|
||||
expected = {"iron": 2, "diamond": 1}
|
||||
error_message = ('Called add_items({}, ["iron", "iron", "diamond"]). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=3)
|
||||
def test_decrement_items(self):
|
||||
actual_result = decrement_items({"iron": 3, "diamond": 4, "gold": 2},
|
||||
["iron", "iron", "diamond", "gold", "gold"])
|
||||
expected = {"iron": 1, "diamond": 3, "gold": 0}
|
||||
error_message = ('Called decrement_items({"iron": 3, "diamond": 4, "gold": 2},'
|
||||
'["iron", "iron", "diamond", "gold", "gold"]). The function '
|
||||
f'returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=3)
|
||||
def test_not_below_zero(self):
|
||||
actual_result = decrement_items({"wood": 2, "iron": 3, "diamond": 1},
|
||||
["wood", "wood", "wood", "iron", "diamond", "diamond"])
|
||||
expected = {"wood": 0, "iron": 2, "diamond": 0}
|
||||
error_message = ('Called decrement_items({"wood": 2, "iron": 3, "diamond": 1}, '
|
||||
'["wood", "wood", "wood", "iron", "diamond", "diamond"]). The '
|
||||
f'function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=3)
|
||||
def test_decrement_items_not_in_inventory(self):
|
||||
actual_result = decrement_items({"iron": 3, "gold": 2},
|
||||
["iron", "wood", "iron", "diamond"])
|
||||
|
||||
expected = {"iron": 1, "gold": 2}
|
||||
error_message = ('Called decrement_items({"iron": 3, "gold": 2}, '
|
||||
'["iron", "wood", "iron", "diamond"]). The function '
|
||||
f'returned {actual_result}, but the tests '
|
||||
f'expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=4)
|
||||
def test_remove_item(self):
|
||||
actual_result = remove_item({"iron": 1, "diamond": 2, "gold": 1}, "diamond")
|
||||
expected = {"iron": 1, "gold": 1}
|
||||
error_message = ('Called remove_item({"iron": 1, "diamond": 2, "gold": 1}, "diamond"). '
|
||||
f'The function returned {actual_result}, but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=4)
|
||||
def test_remove_item_not_in_inventory(self):
|
||||
actual_result = remove_item({"iron": 1, "diamond": 2, "gold": 1}, "wood")
|
||||
expected = {"iron": 1, "gold": 1, "diamond": 2}
|
||||
error_message = ('Called remove_item({"iron": 1, "diamond": 2, "gold": 1}, "wood"). '
|
||||
f'The function returned {actual_result}, '
|
||||
f'but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
|
||||
@pytest.mark.task(taskno=5)
|
||||
def test_list_inventory(self):
|
||||
actual_result = list_inventory({"coal": 15, "diamond": 3, "wood": 67, "silver": 0})
|
||||
expected = [("coal", 15), ("diamond", 3), ("wood", 67)]
|
||||
error_message = ('Called list_inventory({"coal": 15, "diamond": 3, "wood": 67, "silver": 0}). '
|
||||
f'The function returned {actual_result}, '
|
||||
f'but the tests expected {expected}.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_message)
|
||||
Reference in New Issue
Block a user