primeiro commit com exercicios de Exercism realizados até esta data
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"authors": [
|
||||
"meatball133",
|
||||
"BethanyG"
|
||||
],
|
||||
"contributors": [
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"dict_methods.py"
|
||||
],
|
||||
"test": [
|
||||
"dict_methods_test.py"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.py"
|
||||
],
|
||||
"editor": [
|
||||
"dict_methods_test_data.py"
|
||||
]
|
||||
},
|
||||
"icon": "gross-store",
|
||||
"blurb": "Learn about dictionary methods by building a shopping cart MVP for the Mecha Munch grocery app."
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"track":"python","exercise":"mecha-munch-management","id":"06c21c3131224c7d9bcc64e988c58106","url":"https://exercism.org/tracks/python/exercises/mecha-munch-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 dict_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,57 @@
|
||||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
Remember, this is an [MVP][mvp].
|
||||
That means you don't need to get too fancy with error handling or different "edge case" scenarios.
|
||||
It's OK to be simple and direct with the functions you are writing.
|
||||
|
||||
The dictionary section of the [official tutorial][dicts-docs] and the mapping type [official library reference][mapping-types-dict] are excellent places to look for more help with all these methods.
|
||||
|
||||
|
||||
## 1. Add Item(s) to the Users Shopping Cart
|
||||
|
||||
- You will need to iterate through each item in `items_to_add`.
|
||||
- You can avoid a `KeyError` when a key is missing by using a `dict` [method][set-default] that takes a _default value_ as one of its arguments.
|
||||
- It is also possible to accomplish the same thing manually in the `loop` by using some checking and error handling, but the `dict` method is easier.
|
||||
|
||||
## 2. Read in Items Listed in the Users Notes App
|
||||
|
||||
- Remember, Python's got a method for _everything_. This one is a _classmethod_ that's an easy way to [populate a `dict`][fromkeys] with keys.
|
||||
- This `dict` method returns a _new dictionary_, populated with default values. If no value is given, the default value will become `None`
|
||||
|
||||
## 3. Update Recipe "Ideas" Section
|
||||
|
||||
- Don't overthink this one! This can be solved in **one** `dict` method call.
|
||||
- The key word here is .... [_update_][update].
|
||||
|
||||
## 4. Sort the Items in the User Cart
|
||||
|
||||
- What method would you call to get an [iterable view of items][items] in the dictionary?
|
||||
- If you had a `list` or a `tuple`, what [`built-in`][builtins] function might you use to sort them?
|
||||
- The built-in function you want is the one that returns a _copy_, and doesn't mutate the original.
|
||||
|
||||
## 5. Send User Shopping Cart to Store for Fulfillment
|
||||
|
||||
- Having a fresh, empty dictionary here as the `fulfillment_cart` might be handy for adding in items.
|
||||
- `Looping` through the members of the cart might be the most direct way of accessing things here.
|
||||
- What method would you call to get an [iterable view of just the keys][keys] of the dictionary?
|
||||
- Remember that you can get the `value` of a given key by using `<dict name>[<key_name>]` syntax.
|
||||
- If you had a `list` or a `tuple`, what [`built-in`][builtins] function might you use to sort them?
|
||||
- Remember that the `built-in` function can take an optional `reverse=True` argument.
|
||||
|
||||
## 6. Update the Store Inventory to Reflect what a User Has Ordered.
|
||||
|
||||
- There is a method that will give you an iterable view of (`key`, `value`) pairs from the dictionary.
|
||||
- You can access an item in a _nested tuple_ using _bracket notation_: `<tuple>[<nested_tuple>][<index_of_value>]`
|
||||
- Don't forget to check if an inventory count falls to zero, you'll need to add in the "Out of Stock" message.
|
||||
|
||||
[builtins]: https://docs.python.org/3/library/functions.html
|
||||
[dicts-docs]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
|
||||
[fromkeys]: https://docs.python.org/3/library/stdtypes.html#dict.fromkeys
|
||||
[items]: https://docs.python.org/3/library/stdtypes.html#dict.items
|
||||
[keys]: https://docs.python.org/3/library/stdtypes.html#dict.keys
|
||||
[mapping-types-dict]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
|
||||
[mvp]: https://en.wikipedia.org/wiki/Minimum_viable_product
|
||||
[set-default]: https://docs.python.org/3/library/stdtypes.html#dict.setdefault
|
||||
[update]: https://docs.python.org/3/library/stdtypes.html#dict.update
|
||||
@@ -0,0 +1,364 @@
|
||||
# Mecha Munch Management
|
||||
|
||||
Welcome to Mecha Munch 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
|
||||
|
||||
The `dict` class in Python provides many useful [methods][dict-methods] for working with dictionaries.
|
||||
Some were introduced in the concept for `dicts`.
|
||||
Here we cover a few more - along with some techniques for iterating through and manipulating dictionaries.
|
||||
|
||||
### Use `setdefault()` for Error-Free Insertion
|
||||
|
||||
The dictionary concept previously covered that `.get(key, <default value>)` returns an existing `value` or the `default value` if a `key` is not found in a dictionary, thereby avoiding a `KeyError`.
|
||||
This works well in situations where you would rather not have extra error handling but cannot trust that a looked-for `key` will be present.
|
||||
|
||||
For a similarly "safe" (_without KeyError_) insertion operation, there is the `.setdefault(key, <default value>)` method.
|
||||
`setdefault(key, <default value>)` will return the `value` if the `key` is found in the dictionary.
|
||||
If the key is **not** found, it will _insert_ the (`key`, `default value`) pair and return the `default value` for use.
|
||||
|
||||
```python
|
||||
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
|
||||
|
||||
# Looking for the value associated with key "Rock Brown".
|
||||
# The key does not exist, so it is added with the default value, and the value is returned.
|
||||
>>> palette_I.setdefault('Rock Brown', '#694605')
|
||||
'#694605'
|
||||
|
||||
# The (key, default value) pair has now been added to the dictionary.
|
||||
>>> palette_I
|
||||
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}
|
||||
```
|
||||
|
||||
## Use `fromkeys()` to Populate a Dictionary from an Iterable
|
||||
|
||||
To quickly populate a dictionary with various `keys` and default values, the _class method_ [`fromkeys(iterable, <default value>)`][fromkeys] will iterate through an iterable of `keys` and create a new `dict`.
|
||||
All `values` will be set to the `default value` provided:
|
||||
|
||||
```python
|
||||
>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')
|
||||
|
||||
{'Grassy Green': 'fill in hex color here',
|
||||
'Purple Mountains Majesty': 'fill in hex color here',
|
||||
'Misty Mountain Pink': 'fill in hex color here'}
|
||||
```
|
||||
|
||||
## Iterating Over Entries in a Dictionary Via Views
|
||||
|
||||
The `.keys()`, `.values()`, and `.items()` methods return [_iterable views_][dict-views] of a dictionary.
|
||||
|
||||
These views can be used to easily loop over entries without altering them.
|
||||
Views are also _dynamic_ -- when underlying dictionary data changes, the associated `view object` will reflect the change:
|
||||
|
||||
```python
|
||||
>>> palette_I = {'Grassy Green': '#9bc400',
|
||||
'Purple Mountains Majesty': '#8076a3',
|
||||
'Misty Mountain Pink': '#f9c5bd'}
|
||||
|
||||
# Using .keys() returns a list of keys.
|
||||
>>> palette_I.keys()
|
||||
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])
|
||||
|
||||
# Using .values() returns a list of values.
|
||||
>>> palette_I.values()
|
||||
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])
|
||||
|
||||
# Using .items() returns a list of (key, value) tuples.
|
||||
>>> palette_I.items()
|
||||
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])
|
||||
|
||||
# Views are dynamic. Changing values in the dict changes all of the associated views.
|
||||
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
|
||||
>>> palette_I['Deep Red'] = '#932432'
|
||||
|
||||
>>> palette_I.values()
|
||||
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])
|
||||
|
||||
>>> palette_I.keys()
|
||||
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])
|
||||
|
||||
>>> palette_I.items()
|
||||
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])
|
||||
```
|
||||
|
||||
## More on `.keys()`, `.values()`, and `.items()`
|
||||
|
||||
In Python 3.7+, `dicts` preserve the order in which entries are inserted allowing First-in, First-out (_`FIFO`_), iteration when using `.keys()`, `.values()`, or `.items()`.
|
||||
|
||||
In Python 3.8+, views are also _reversible_.
|
||||
This allows keys, values, or (`key`, `value`) pairs to be iterated over in Last-in, First-out (`LIFO`) order by using `reversed(<dict>.keys())`, `reversed(<dict>.values())`, or `reversed(<dict>.items())`:
|
||||
|
||||
```python
|
||||
>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
|
||||
|
||||
# Iterating in insertion order
|
||||
>>> for item in palette_II.items():
|
||||
... print(item)
|
||||
...
|
||||
('Factory Stone Purple', '#7c677f')
|
||||
('Green Treeline', '#478559')
|
||||
('Purple baseline', '#161748')
|
||||
|
||||
|
||||
# Iterating in the reverse direction.
|
||||
>>> for item in reversed(palette_II.items()):
|
||||
... print (item)
|
||||
...
|
||||
('Purple baseline', '#161748')
|
||||
('Green Treeline', '#478559')
|
||||
('Factory Stone Purple', '#7c677f')
|
||||
```
|
||||
|
||||
## Sorting a Dictionary
|
||||
|
||||
Dictionaries do not have a built-in sorting method.
|
||||
However, it is possible to sort a `dict` _view_ using the built-in function `sorted()` with `.items()`.
|
||||
The sorted view can then be used to create a new dictionary.
|
||||
Like iteration, the default sort is over dictionary `keys`.
|
||||
|
||||
```python
|
||||
# Default ordering for a dictionary is last in, first out (LIFO).
|
||||
>>> color_palette = {'Grassy Green': '#9bc400',
|
||||
'Purple Mountains Majesty': '#8076a3',
|
||||
'Misty Mountain Pink': '#f9c5bd',
|
||||
'Factory Stone Purple': '#7c677f',
|
||||
'Green Treeline': '#478559',
|
||||
'Purple baseline': '#161748'}
|
||||
|
||||
|
||||
# The default sort order for a dictionary uses the keys.
|
||||
>>> sorted_palette = dict(sorted(color_palette.items()))
|
||||
>>> sorted_palette
|
||||
{'Factory Stone Purple': '#7c677f',
|
||||
'Grassy Green': '#9bc400',
|
||||
'Green Treeline': '#478559',
|
||||
'Misty Mountain Pink': '#f9c5bd',
|
||||
'Purple Mountains Majesty': '#8076a3',
|
||||
'Purple baseline': '#161748'}
|
||||
```
|
||||
|
||||
## Combining Dictionaries with `.update()`
|
||||
|
||||
`<dict_one>.update(<dict_two>)` can be used to _combine_ two dictionaries.
|
||||
This method will take the (`key`,`value`) pairs of `<dict_two>` and write them into `<dict_one>`:
|
||||
|
||||
```python
|
||||
>>> palette_I = {'Grassy Green': '#9bc400',
|
||||
'Purple Mountains Majesty': '#8076a3',
|
||||
'Misty Mountain Pink': '#f9c5bd'}
|
||||
>>> palette_II = {'Factory Stone Purple': '#7c677f',
|
||||
'Green Treeline': '#478559',
|
||||
'Purple Baseline': '#161748'}
|
||||
|
||||
>>> palette_I.update(palette_II)
|
||||
|
||||
# Note that new items from palette_II are added.
|
||||
>>> palette_I
|
||||
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}
|
||||
```
|
||||
|
||||
Where keys in the two dictionaries _overlap_, the `value` in `dict_one` will be _overwritten_ by the corresponding `value` from `dict_two`:
|
||||
|
||||
```python
|
||||
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd',
|
||||
'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
|
||||
>>> palette_III = {'Grassy Green': (155, 196, 0), 'Purple Mountains Majesty': (128, 118, 163),
|
||||
'Misty Mountain Pink': (249, 197, 189)}
|
||||
>>> palette_I.update(palette_III)
|
||||
|
||||
# Overlapping values in palette_I are replaced with values from palette_III
|
||||
>>> palette_I
|
||||
{'Grassy Green': (155, 196, 0),
|
||||
'Purple Mountains Majesty': (128, 118, 163),
|
||||
'Misty Mountain Pink': (249, 197, 189),
|
||||
'Factory Stone Purple': '#7c677f',
|
||||
'Green Treeline': '#478559', 'Purple baseline': '#161748'}
|
||||
```
|
||||
|
||||
## Merge or Update Dictionaries Via the Union (`|`) Operators
|
||||
|
||||
Python 3.9 introduces a different means of merging `dicts`: the `union` operators.
|
||||
`dict_one | dict_two` will create a **new dictionary**, made up of the (`key`, `value`) pairs of `dict_one` and `dict_two`.
|
||||
When both dictionaries share keys, `dict_two` values take precedence.
|
||||
|
||||
```python
|
||||
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
|
||||
>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
|
||||
>>> new_dict = palette_I | palette_II
|
||||
>>> new_dict
|
||||
...
|
||||
{'Grassy Green': '#9bc400',
|
||||
'Purple Mountains Majesty': '#8076a3',
|
||||
'Misty Mountain Pink': '#f9c5bd',
|
||||
'Factory Stone Purple': '#7c677f',
|
||||
'Green Treeline': '#478559',
|
||||
'Purple baseline': '#161748'}
|
||||
```
|
||||
|
||||
`dict_one |= other` behaves similar to `<dict_one>.update(<other>)`, but in this case, `other` can be either a `dict` or an iterable of (`key`, `value`) pairs:
|
||||
|
||||
```python
|
||||
>>> palette_III = {'Grassy Green': (155, 196, 0),
|
||||
'Purple Mountains Majesty': (128, 118, 163),
|
||||
'Misty Mountain Pink': (249, 197, 189)}
|
||||
>>> new_dict |= palette_III
|
||||
>>> new_dict
|
||||
...
|
||||
{'Grassy Green': (155, 196, 0),
|
||||
'Purple Mountains Majesty': (128, 118, 163),
|
||||
'Misty Mountain Pink': (249, 197, 189),
|
||||
'Factory Stone Purple': '#7c677f',
|
||||
'Green Treeline': '#478559',
|
||||
'Purple baseline': '#161748'}
|
||||
```
|
||||
|
||||
For a detailed explanation of dictionaries and methods for working with them, the [official tutorial][dicts-docs] and the [official library reference][mapping-types-dict] are excellent starting places.
|
||||
|
||||
[Real Python][how-to-dicts] and [Finxter][fi-dict-guide] also have very thorough articles on Python dictionaries.
|
||||
|
||||
[dict-methods]: https://docs.python.org/3/library/stdtypes.html#dict
|
||||
[dict-views]: https://docs.python.org/3/library/stdtypes.html#dict-views
|
||||
[dicts-docs]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
|
||||
[fi-dict-guide]: https://blog.finxter.com/python-dictionary
|
||||
[fromkeys]: https://docs.python.org/3/library/stdtypes.html#dict.fromkeys
|
||||
[how-to-dicts]: https://realpython.com/python-dicts/
|
||||
[mapping-types-dict]: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
|
||||
|
||||
## Instructions
|
||||
|
||||
Mecha Munch™, a grocery shopping automation company has just hired you to work on their ordering app.
|
||||
Your team is tasked with building an MVP (_[minimum viable product][mvp]_) that manages all the basic shopping cart activities, allowing users to add, remove, and sort their grocery orders.
|
||||
Thankfully, a different team is handling all the money and check-out functions!
|
||||
|
||||
## 1. Add Item(s) to the Users Shopping Cart
|
||||
|
||||
The MVP should allow the user to add items to their shopping cart.
|
||||
This could be a single item or multiple items at once.
|
||||
Since this is an MVP, item quantity is indicated by _repeats_.
|
||||
If a user wants to add 2 Oranges, 'Oranges' will appear twice in the input iterable.
|
||||
If the user already has the item in their cart, the cart quantity should be increased by 1.
|
||||
If the item is _new_ to the cart, it should be added with a quantity of 1.
|
||||
|
||||
Create the function `add_item(<current_cart>, <items_to_add>)` that takes a cart dictionary and any list-like iterable of items to add as arguments.
|
||||
It should return a new/updated shopping cart dictionary for the user.
|
||||
|
||||
```python
|
||||
>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
|
||||
('Apple', 'Apple', 'Orange', 'Apple', 'Banana'))
|
||||
{'Banana': 4, 'Apple': 5, 'Orange': 2}
|
||||
|
||||
>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
|
||||
['Banana', 'Orange', 'Blueberries', 'Banana'])
|
||||
{'Banana': 5, 'Apple': 2, 'Orange': 2, 'Blueberries': 1}
|
||||
```
|
||||
|
||||
## 2. Read in Items Listed in the Users Notes App
|
||||
|
||||
Uh-oh.
|
||||
Looks like the product team is engaging in [feature creep][feature creep].
|
||||
They want to add extra functionality to the MVP.
|
||||
The application now has to create a shopping cart by reading items off a users notes app.
|
||||
Convenient for the users, but slightly more work for the team.
|
||||
|
||||
Create the function `read_notes(<notes>)` that can take any list-like iterable as an argument.
|
||||
The function should parse the items and create a user shopping cart/dictionary.
|
||||
Each item should be added with a quantity of 1.
|
||||
The new user cart should then be returned.
|
||||
|
||||
```python
|
||||
>>> read_notes(('Banana','Apple', 'Orange'))
|
||||
{'Banana': 1, 'Apple': 1, 'Orange': 1}
|
||||
|
||||
>>> read_notes(['Blueberries', 'Pear', 'Orange', 'Banana', 'Apple'])
|
||||
{'Blueberries' : 1, 'Pear' : 1, 'Orange' : 1, 'Banana' : 1, 'Apple' : 1}
|
||||
```
|
||||
|
||||
## 3. Update Recipe "Ideas" Section
|
||||
|
||||
The app has an "ideas" section that's filled with finished recipes from various cuisines.
|
||||
The user can select any one of these recipes and have all its ingredients added to their shopping cart automatically.
|
||||
The project manager has asked you create a way to edit these "ideas" recipes, since the content team keeps changing around ingredients and quantities.
|
||||
|
||||
Create the function `update_recipes(<ideas>, <recipe_updates>)` that takes an "ideas" dictionary and an iterable of recipe updates as arguments.
|
||||
The function should return the new/updated "ideas" dictionary.
|
||||
|
||||
```python
|
||||
>>> update_recipes({'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
|
||||
'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}},
|
||||
(('Banana Bread', {'Banana': 4, 'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3}),))
|
||||
...
|
||||
|
||||
{'Banana Bread' : {'Banana': 4, 'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3},
|
||||
'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}}
|
||||
|
||||
>>> update_recipes({'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
|
||||
'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1},
|
||||
'Pasta Primavera': {'Eggs': 1, 'Carrots': 1, 'Spinach': 2, 'Tomatoes': 3, 'Parmesan': 2, 'Milk': 1, 'Onion': 1}},
|
||||
[('Raspberry Pie', {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2}),
|
||||
('Pasta Primavera', {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1}),
|
||||
('Blueberry Crumble', {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3})])
|
||||
...
|
||||
|
||||
{'Banana Bread': {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
|
||||
'Raspberry Pie': {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2},
|
||||
'Pasta Primavera': {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1},
|
||||
'Blueberry Crumble': {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3}}
|
||||
```
|
||||
|
||||
## 4. Sort the Items in the User Cart
|
||||
|
||||
Once a user has started a cart, the app allows them to sort their items alphabetically.
|
||||
This makes things easier to find, and helps when there are data-entry errors like having 'potatoes' and 'Potato' in the database.
|
||||
|
||||
Create the function `sort_entries(<cart>)` that takes a shopping cart/dictionary as an argument and returns a new, alphabetically sorted one.
|
||||
|
||||
```python
|
||||
>>> sort_entries({'Banana': 3, 'Apple': 2, 'Orange': 1})
|
||||
{'Apple': 2, 'Banana':3, 'Orange': 1}
|
||||
```
|
||||
|
||||
## 5. Send User Shopping Cart to Store for Fulfillment
|
||||
|
||||
The app needs to send a given users cart to the store for fulfillment.
|
||||
However, the shoppers in the store need to know which store aisle the item can be found in and if the item needs refrigeration.
|
||||
So (_rather arbitrarily_) the "fulfillment cart" needs to be sorted in reverse alphabetical order with item quantities combined with location and refrigeration information.
|
||||
|
||||
Create the function `send_to_store(<cart>, <aisle_mapping>)` that takes a user shopping cart and a dictionary that has store aisle number and a `True`/`False` for refrigeration needed for each item.
|
||||
The function should `return` a combined "fulfillment cart" that has (quantity, aisle, and refrigeration) for each item the customer is ordering.
|
||||
Items should appear in _reverse_ alphabetical order.
|
||||
|
||||
```python
|
||||
>>> send_to_store({'Banana': 3, 'Apple': 2, 'Orange': 1, 'Milk': 2},
|
||||
{'Banana': ['Aisle 5', False], 'Apple': ['Aisle 4', False], 'Orange': ['Aisle 4', False], 'Milk': ['Aisle 2', True]})
|
||||
{'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]}
|
||||
```
|
||||
|
||||
## 6. Update the Store Inventory to Reflect what a User Has Ordered.
|
||||
|
||||
The app can't just place customer orders endlessly.
|
||||
Eventually, the store is going to run out of various products.
|
||||
So your app MVP needs to update the store inventory every time a user sends their order to the store.
|
||||
Otherwise, customers will order products that aren't actually available.
|
||||
|
||||
Create the function `update_store_inventory(<fulfillment_cart>, <store_inventory>)` that takes a "fulfillment cart" and a store inventory.
|
||||
The function should reduce the store inventory amounts by the number "ordered" in the "fulfillment cart" and then return the updated store inventory.
|
||||
Where a store item count falls to 0, the count should be replaced by the message 'Out of Stock'.
|
||||
|
||||
```python
|
||||
>>> update_store_inventory({'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]},
|
||||
{'Banana': [15, 'Aisle 5', False], 'Apple': [12, 'Aisle 4', False], 'Orange': [1, 'Aisle 4', False], 'Milk': [4, 'Aisle 2', True]})
|
||||
|
||||
{'Banana': [12, 'Aisle 5', False], 'Apple': [10, 'Aisle 4', False], 'Orange': ['Out of Stock', 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True]}
|
||||
```
|
||||
|
||||
[feature creep]: https://en.wikipedia.org/wiki/Feature_creep
|
||||
[mvp]: https://en.wikipedia.org/wiki/Minimum_viable_product
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @meatball133
|
||||
- @BethanyG
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
"""Functions to manage a users shopping cart items."""
|
||||
|
||||
from re import fullmatch
|
||||
|
||||
|
||||
def add_item(current_cart, items_to_add):
|
||||
"""Add items to shopping cart.
|
||||
|
||||
:param current_cart: dict - the current shopping cart.
|
||||
:param items_to_add: iterable - items to add to the cart.
|
||||
:return: dict - the updated user cart dictionary.
|
||||
"""
|
||||
# create a new cart with items_to_add if current_cart is empty
|
||||
# if current_cart == {}:
|
||||
# current_cart = dict.fromkeys(items_to_add, 0)
|
||||
# for item in items_to_add:
|
||||
# current_cart[item] += 1
|
||||
# return current_cart
|
||||
|
||||
# (after doing this i realized that the bellow code also addresses the
|
||||
# concern of the current_cart being empty, so i commented out the code
|
||||
# above)
|
||||
|
||||
# increment item by one if item already exists in current_cart,
|
||||
# otherwise add new item to current_cart with value of 1
|
||||
for item in items_to_add:
|
||||
current_cart[item] = current_cart.get(item, 0) + 1
|
||||
return current_cart
|
||||
|
||||
|
||||
def read_notes(notes):
|
||||
"""Create user cart from an iterable notes entry.
|
||||
|
||||
:param notes: iterable of items to add to cart.
|
||||
:return: dict - a user shopping cart dictionary.
|
||||
"""
|
||||
shopping_cart: dict = dict.fromkeys(notes, 0)
|
||||
for item in notes:
|
||||
shopping_cart[item] += 1
|
||||
return shopping_cart
|
||||
|
||||
|
||||
def update_recipes(ideas, recipe_updates):
|
||||
"""Update the recipe ideas dictionary.
|
||||
|
||||
:param ideas: dict - The "recipe ideas" dict.
|
||||
:param recipe_updates: dict - dictionary with updates for the ideas section.
|
||||
:return: dict - updated "recipe ideas" dict.
|
||||
"""
|
||||
ideas |= recipe_updates
|
||||
return ideas
|
||||
|
||||
|
||||
def sort_entries(cart):
|
||||
"""Sort a users shopping cart in alphabetically order.
|
||||
|
||||
:param cart: dict - a users shopping cart dictionary.
|
||||
:return: dict - users shopping cart sorted in alphabetical order.
|
||||
"""
|
||||
sorted_cart: dict = dict(sorted(cart.items()))
|
||||
return sorted_cart
|
||||
|
||||
|
||||
def send_to_store(cart, aisle_mapping):
|
||||
"""Combine users order to aisle and refrigeration information.
|
||||
|
||||
:param cart: dict - users shopping cart dictionary.
|
||||
:param aisle_mapping: dict - aisle and refrigeration information dictionary.
|
||||
:return: dict - fulfillment dictionary ready to send to store.
|
||||
"""
|
||||
fulfillment: dict[str, list] = {}
|
||||
for item in cart:
|
||||
fulfillment[item] = [cart[item],
|
||||
aisle_mapping[item][0], aisle_mapping[item][1]]
|
||||
fulfillment = dict(sorted(fulfillment.items(), reverse=True))
|
||||
return fulfillment
|
||||
|
||||
|
||||
def update_store_inventory(fulfillment_cart, store_inventory):
|
||||
"""Update store inventory levels with user order.
|
||||
|
||||
:param fulfillment cart: dict - fulfillment cart to send to store.
|
||||
:param store_inventory: dict - store available inventory
|
||||
:return: dict - store_inventory updated.
|
||||
"""
|
||||
for item in fulfillment_cart:
|
||||
new_stock = store_inventory[item][0] - fulfillment_cart[item][0]
|
||||
store_inventory[item] = [
|
||||
"Out of Stock" if new_stock <= 0 else new_stock,
|
||||
store_inventory[item][1],
|
||||
store_inventory[item][2],
|
||||
]
|
||||
return store_inventory
|
||||
@@ -0,0 +1,94 @@
|
||||
import unittest
|
||||
import pytest
|
||||
from collections import OrderedDict
|
||||
from dict_methods import (
|
||||
add_item,
|
||||
read_notes,
|
||||
update_recipes,
|
||||
sort_entries,
|
||||
send_to_store,
|
||||
update_store_inventory,
|
||||
)
|
||||
|
||||
from dict_methods_test_data import (
|
||||
add_item_data,
|
||||
read_notes_data,
|
||||
update_recipes_data,
|
||||
sort_entries_data,
|
||||
send_to_store_data,
|
||||
update_store_inventory_data,
|
||||
)
|
||||
|
||||
class MechaMunchManagementTest(unittest.TestCase):
|
||||
|
||||
@pytest.mark.task(taskno=1)
|
||||
def test_add_item(self):
|
||||
for variant, (input_data, expected) in enumerate(add_item_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expected=expected):
|
||||
actual_result = add_item(input_data[0], input_data[1])
|
||||
error_msg= (f'Called add_item({input_data[0]}, {input_data[1]}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} once the item was added.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_msg)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_read_notes(self):
|
||||
for variant, (input_data, expected) in enumerate(read_notes_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expected=expected):
|
||||
actual_result = read_notes(input_data)
|
||||
error_msg = (f'Called read_notes({input_data}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} once the notes were read.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_msg)
|
||||
|
||||
@pytest.mark.task(taskno=3)
|
||||
def test_update_recipes(self):
|
||||
for variant, (input_data, expected) in enumerate(update_recipes_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expected=expected):
|
||||
actual_result = update_recipes(input_data[0], input_data[1])
|
||||
error_msg = (f'Called update_recipes({input_data[0]}, {input_data[1]}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} once the recipes were updated.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_msg)
|
||||
|
||||
@pytest.mark.task(taskno=4)
|
||||
def test_sort_entries(self):
|
||||
for variant, (input_data, expected) in enumerate(sort_entries_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expecred=expected):
|
||||
actual_result = sort_entries(input_data)
|
||||
error_msg = (f'Called sort_entries({input_data}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} for the sorted entries.')
|
||||
|
||||
# Because we are asserting equal, we need to convert to an OrderedDict.
|
||||
# Regular dictionaries will compare equal even when they are ordered
|
||||
# differently from one another. See https://stackoverflow.com/a/58961124
|
||||
self.assertEqual(OrderedDict(actual_result), OrderedDict(expected), msg=error_msg)
|
||||
|
||||
@pytest.mark.task(taskno=5)
|
||||
def test_send_to_store(self):
|
||||
for variant, (input_data, expected) in enumerate(send_to_store_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expected=expected):
|
||||
actual_result = send_to_store(input_data[0], input_data[1])
|
||||
error_msg = (f'Called send_to_store({input_data[0]}, {input_data[1]}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} as the fulfillment cart.')
|
||||
|
||||
# Because we are asserting equal, we need to convert to an OrderedDict.
|
||||
# Regular dictionaries will compare equal even when they are ordered
|
||||
# differently from one another. See https://stackoverflow.com/a/58961124
|
||||
self.assertEqual(OrderedDict(actual_result), OrderedDict(expected), msg=error_msg)
|
||||
|
||||
@pytest.mark.task(taskno=6)
|
||||
def test_update_store_inventory(self):
|
||||
for variant, (input_data, expected) in enumerate(update_store_inventory_data, start=1):
|
||||
with self.subTest(f'variation #{variant}', input_data=input_data, expected=expected):
|
||||
actual_result = update_store_inventory(input_data[0], input_data[1])
|
||||
error_msg = (f'Called update_store_inventory({input_data[0]}, {input_data[1]}). '
|
||||
f'The function returned {actual_result}, but the tests '
|
||||
f'expected: {expected} as the store inventory.')
|
||||
|
||||
self.assertEqual(actual_result, expected, msg=error_msg)
|
||||
@@ -0,0 +1,394 @@
|
||||
## add_item test cases##
|
||||
add_item_inputs = [
|
||||
({"Apple": 1, "Banana": 4}, ("Apple", "Banana", "Orange")),
|
||||
(
|
||||
{"Orange": 1, "Raspberry": 1, "Blueberries": 10},
|
||||
["Raspberry", "Blueberries", "Raspberry"],
|
||||
),
|
||||
(
|
||||
{"Broccoli": 1, "Banana": 1},
|
||||
("Broccoli", "Kiwi", "Kiwi", "Kiwi", "Melon", "Apple", "Banana", "Banana"),
|
||||
),
|
||||
]
|
||||
|
||||
add_item_outputs = [
|
||||
{"Apple": 2, "Banana": 5, "Orange": 1},
|
||||
{"Orange": 1, "Raspberry": 3, "Blueberries": 11},
|
||||
{"Broccoli": 2, "Banana": 3, "Kiwi": 3, "Melon": 1, "Apple": 1},
|
||||
]
|
||||
|
||||
add_item_data = zip(add_item_inputs, add_item_outputs)
|
||||
|
||||
|
||||
## read_notes test cases##
|
||||
read_notes_inputs = [
|
||||
("Apple", "Banana"),
|
||||
("Orange", "Raspberry", "Blueberries"),
|
||||
["Broccoli", "Kiwi", "Melon", "Apple", "Banana"],
|
||||
]
|
||||
|
||||
read_notes_outputs = [
|
||||
{"Apple": 1, "Banana": 1},
|
||||
{"Orange": 1, "Raspberry": 1, "Blueberries": 1},
|
||||
{"Broccoli": 1, "Kiwi": 1, "Melon": 1, "Apple": 1, "Banana": 1},
|
||||
]
|
||||
|
||||
read_notes_data = zip(read_notes_inputs, read_notes_outputs)
|
||||
|
||||
|
||||
## update_recipes test cases##
|
||||
update_recipes_inputs = [
|
||||
(
|
||||
{
|
||||
"Banana Bread": {
|
||||
"Banana": 1,
|
||||
"Apple": 1,
|
||||
"Walnuts": 1,
|
||||
"Flour": 1,
|
||||
"Eggs": 2,
|
||||
"Butter": 1,
|
||||
},
|
||||
"Raspberry Pie": {
|
||||
"Raspberry": 1,
|
||||
"Orange": 1,
|
||||
"Pie Crust": 1,
|
||||
"Cream Custard": 1,
|
||||
},
|
||||
},
|
||||
(
|
||||
(
|
||||
"Banana Bread",
|
||||
{
|
||||
"Banana": 4,
|
||||
"Walnuts": 2,
|
||||
"Flour": 1,
|
||||
"Butter": 1,
|
||||
"Milk": 2,
|
||||
"Eggs": 3,
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
{
|
||||
"Apple Pie": {"Apple": 1, "Pie Crust": 1, "Cream Custard": 1},
|
||||
"Blueberry Pie": {"Blueberries": 1, "Pie Crust": 1, "Cream Custard": 1},
|
||||
},
|
||||
(
|
||||
("Blueberry Pie", {"Blueberries": 2,
|
||||
"Pie Crust": 1, "Cream Custard": 1}),
|
||||
("Apple Pie", {"Apple": 1, "Pie Crust": 1, "Cream Custard": 1}),
|
||||
),
|
||||
),
|
||||
(
|
||||
{
|
||||
"Banana Bread": {
|
||||
"Banana": 1,
|
||||
"Apple": 1,
|
||||
"Walnuts": 1,
|
||||
"Flour": 1,
|
||||
"Eggs": 2,
|
||||
"Butter": 1,
|
||||
},
|
||||
"Raspberry Pie": {
|
||||
"Raspberry": 1,
|
||||
"Orange": 1,
|
||||
"Pie Crust": 1,
|
||||
"Cream Custard": 1,
|
||||
},
|
||||
"Pasta Primavera": {
|
||||
"Eggs": 1,
|
||||
"Carrots": 1,
|
||||
"Spinach": 2,
|
||||
"Tomatoes": 3,
|
||||
"Parmesan": 2,
|
||||
"Milk": 1,
|
||||
"Onion": 1,
|
||||
},
|
||||
},
|
||||
(
|
||||
(
|
||||
"Raspberry Pie",
|
||||
{
|
||||
"Raspberry": 3,
|
||||
"Orange": 1,
|
||||
"Pie Crust": 1,
|
||||
"Cream Custard": 1,
|
||||
"Whipped Cream": 2,
|
||||
},
|
||||
),
|
||||
(
|
||||
"Pasta Primavera",
|
||||
{
|
||||
"Eggs": 1,
|
||||
"Mixed Veggies": 2,
|
||||
"Parmesan": 2,
|
||||
"Milk": 1,
|
||||
"Spinach": 1,
|
||||
"Bread Crumbs": 1,
|
||||
},
|
||||
),
|
||||
(
|
||||
"Blueberry Crumble",
|
||||
{
|
||||
"Blueberries": 2,
|
||||
"Whipped Creme": 2,
|
||||
"Granola Topping": 2,
|
||||
"Yogurt": 3,
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
update_recipes_outputs = [
|
||||
{
|
||||
"Banana Bread": {
|
||||
"Banana": 4,
|
||||
"Walnuts": 2,
|
||||
"Flour": 1,
|
||||
"Butter": 1,
|
||||
"Milk": 2,
|
||||
"Eggs": 3,
|
||||
},
|
||||
"Raspberry Pie": {
|
||||
"Raspberry": 1,
|
||||
"Orange": 1,
|
||||
"Pie Crust": 1,
|
||||
"Cream Custard": 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
"Apple Pie": {"Apple": 1, "Pie Crust": 1, "Cream Custard": 1},
|
||||
"Blueberry Pie": {"Blueberries": 2, "Pie Crust": 1, "Cream Custard": 1},
|
||||
},
|
||||
{
|
||||
"Banana Bread": {
|
||||
"Banana": 1,
|
||||
"Apple": 1,
|
||||
"Walnuts": 1,
|
||||
"Flour": 1,
|
||||
"Eggs": 2,
|
||||
"Butter": 1,
|
||||
},
|
||||
"Raspberry Pie": {
|
||||
"Raspberry": 3,
|
||||
"Orange": 1,
|
||||
"Pie Crust": 1,
|
||||
"Cream Custard": 1,
|
||||
"Whipped Cream": 2,
|
||||
},
|
||||
"Pasta Primavera": {
|
||||
"Eggs": 1,
|
||||
"Mixed Veggies": 2,
|
||||
"Parmesan": 2,
|
||||
"Milk": 1,
|
||||
"Spinach": 1,
|
||||
"Bread Crumbs": 1,
|
||||
},
|
||||
"Blueberry Crumble": {
|
||||
"Blueberries": 2,
|
||||
"Whipped Creme": 2,
|
||||
"Granola Topping": 2,
|
||||
"Yogurt": 3,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
update_recipes_data = zip(update_recipes_inputs, update_recipes_outputs)
|
||||
|
||||
|
||||
## sort_entries test cases##
|
||||
sort_entries_inputs = [
|
||||
{"Banana": 4, "Apple": 2, "Orange": 1, "Pear": 12},
|
||||
{"Apple": 3, "Orange": 5, "Banana": 1, "Avocado": 2},
|
||||
{"Orange": 3, "Banana": 2, "Apple": 1},
|
||||
{
|
||||
"Apple": 2,
|
||||
"Raspberry": 2,
|
||||
"Blueberries": 5,
|
||||
"Broccoli": 2,
|
||||
"Kiwi": 1,
|
||||
"Melon": 4,
|
||||
},
|
||||
]
|
||||
|
||||
sort_entries_outputs = [
|
||||
{"Apple": 2, "Banana": 4, "Orange": 1, "Pear": 12},
|
||||
{"Apple": 3, "Avocado": 2, "Banana": 1, "Orange": 5},
|
||||
{"Apple": 1, "Banana": 2, "Orange": 3},
|
||||
{
|
||||
"Apple": 2,
|
||||
"Blueberries": 5,
|
||||
"Broccoli": 2,
|
||||
"Kiwi": 1,
|
||||
"Melon": 4,
|
||||
"Raspberry": 2,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
sort_entries_data = zip(sort_entries_inputs, sort_entries_outputs)
|
||||
|
||||
|
||||
## send_to_store test cases##
|
||||
send_to_store_inputs = [
|
||||
(
|
||||
{"Banana": 3, "Apple": 2, "Orange": 1, "Milk": 2},
|
||||
{
|
||||
"Banana": ["Aisle 5", False],
|
||||
"Apple": ["Aisle 4", False],
|
||||
"Orange": ["Aisle 4", False],
|
||||
"Milk": ["Aisle 2", True],
|
||||
},
|
||||
),
|
||||
(
|
||||
{"Kiwi": 3, "Juice": 5, "Yoghurt": 2, "Milk": 5},
|
||||
{
|
||||
"Kiwi": ["Aisle 6", False],
|
||||
"Juice": ["Aisle 5", False],
|
||||
"Yoghurt": ["Aisle 2", True],
|
||||
"Milk": ["Aisle 2", True],
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"Apple": 2,
|
||||
"Raspberry": 2,
|
||||
"Blueberries": 5,
|
||||
"Broccoli": 2,
|
||||
"Kiwi": 1,
|
||||
"Melon": 4,
|
||||
},
|
||||
{
|
||||
"Apple": ["Aisle 1", False],
|
||||
"Raspberry": ["Aisle 6", False],
|
||||
"Blueberries": ["Aisle 6", False],
|
||||
"Broccoli": ["Aisle 3", False],
|
||||
"Kiwi": ["Aisle 6", False],
|
||||
"Melon": ["Aisle 6", False],
|
||||
},
|
||||
),
|
||||
(
|
||||
{"Orange": 1},
|
||||
{
|
||||
"Banana": ["Aisle 5", False],
|
||||
"Apple": ["Aisle 4", False],
|
||||
"Orange": ["Aisle 4", False],
|
||||
"Milk": ["Aisle 2", True],
|
||||
},
|
||||
),
|
||||
(
|
||||
{"Banana": 3, "Apple": 2, "Orange": 1},
|
||||
{
|
||||
"Banana": ["Aisle 5", False],
|
||||
"Apple": ["Aisle 4", False],
|
||||
"Orange": ["Aisle 4", False],
|
||||
"Milk": ["Aisle 2", True],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
send_to_store_outputs = [
|
||||
{
|
||||
"Orange": [1, "Aisle 4", False],
|
||||
"Milk": [2, "Aisle 2", True],
|
||||
"Banana": [3, "Aisle 5", False],
|
||||
"Apple": [2, "Aisle 4", False],
|
||||
},
|
||||
{
|
||||
"Yoghurt": [2, "Aisle 2", True],
|
||||
"Milk": [5, "Aisle 2", True],
|
||||
"Kiwi": [3, "Aisle 6", False],
|
||||
"Juice": [5, "Aisle 5", False],
|
||||
},
|
||||
{
|
||||
"Raspberry": [2, "Aisle 6", False],
|
||||
"Melon": [4, "Aisle 6", False],
|
||||
"Kiwi": [1, "Aisle 6", False],
|
||||
"Broccoli": [2, "Aisle 3", False],
|
||||
"Blueberries": [5, "Aisle 6", False],
|
||||
"Apple": [2, "Aisle 1", False],
|
||||
},
|
||||
{"Orange": [1, "Aisle 4", False]},
|
||||
{
|
||||
"Orange": [1, "Aisle 4", False],
|
||||
"Banana": [3, "Aisle 5", False],
|
||||
"Apple": [2, "Aisle 4", False],
|
||||
},
|
||||
]
|
||||
|
||||
send_to_store_data = zip(send_to_store_inputs, send_to_store_outputs)
|
||||
|
||||
|
||||
## update_store_inventory test cases##
|
||||
update_store_inventory_inputs = [
|
||||
(
|
||||
{
|
||||
"Orange": [1, "Aisle 4", False],
|
||||
"Milk": [2, "Aisle 2", True],
|
||||
"Banana": [3, "Aisle 5", False],
|
||||
"Apple": [2, "Aisle 4", False],
|
||||
},
|
||||
{
|
||||
"Banana": [15, "Aisle 5", False],
|
||||
"Apple": [12, "Aisle 4", False],
|
||||
"Orange": [1, "Aisle 4", False],
|
||||
"Milk": [4, "Aisle 2", True],
|
||||
},
|
||||
),
|
||||
(
|
||||
{"Kiwi": [3, "Aisle 6", False]},
|
||||
{
|
||||
"Kiwi": [3, "Aisle 6", False],
|
||||
"Juice": [5, "Aisle 5", False],
|
||||
"Yoghurt": [2, "Aisle 2", True],
|
||||
"Milk": [5, "Aisle 2", True],
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"Kiwi": [1, "Aisle 6", False],
|
||||
"Melon": [4, "Aisle 6", False],
|
||||
"Apple": [2, "Aisle 1", False],
|
||||
"Raspberry": [2, "Aisle 6", False],
|
||||
"Blueberries": [5, "Aisle 6", False],
|
||||
"Broccoli": [1, "Aisle 3", False],
|
||||
},
|
||||
{
|
||||
"Apple": [2, "Aisle 1", False],
|
||||
"Raspberry": [5, "Aisle 6", False],
|
||||
"Blueberries": [10, "Aisle 6", False],
|
||||
"Broccoli": [4, "Aisle 3", False],
|
||||
"Kiwi": [1, "Aisle 6", False],
|
||||
"Melon": [8, "Aisle 6", False],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
update_store_inventory_outputs = [
|
||||
{
|
||||
"Banana": [12, "Aisle 5", False],
|
||||
"Apple": [10, "Aisle 4", False],
|
||||
"Orange": ["Out of Stock", "Aisle 4", False],
|
||||
"Milk": [2, "Aisle 2", True],
|
||||
},
|
||||
{
|
||||
"Juice": [5, "Aisle 5", False],
|
||||
"Yoghurt": [2, "Aisle 2", True],
|
||||
"Milk": [5, "Aisle 2", True],
|
||||
"Kiwi": ["Out of Stock", "Aisle 6", False],
|
||||
},
|
||||
{
|
||||
"Kiwi": ["Out of Stock", "Aisle 6", False],
|
||||
"Melon": [4, "Aisle 6", False],
|
||||
"Apple": ["Out of Stock", "Aisle 1", False],
|
||||
"Raspberry": [3, "Aisle 6", False],
|
||||
"Blueberries": [5, "Aisle 6", False],
|
||||
"Broccoli": [3, "Aisle 3", False],
|
||||
},
|
||||
]
|
||||
|
||||
update_store_inventory_data = zip(
|
||||
update_store_inventory_inputs, update_store_inventory_outputs
|
||||
)
|
||||
Reference in New Issue
Block a user