Skip to content

Commit 65fae2e

Browse files
J08KcmccandlessBethanyGErikSchierboom
committed
Implement new Concept Exercise: dicts (new PR) (exercism#1936)
* Added it again * Updated the following to the requested changes. * Fixed some spelling in after.md * Add stuff to after.md * formatting * Some touches here and there and added example.py * Create test * Update dicts_test.py * formatting * Update after.md * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.docs/after.md Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/dicts_test.py Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.docs/hints.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/after.md Co-authored-by: BethanyG <[email protected]> * Update after.md * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.meta/design.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.meta/design.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.meta/design.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.meta/design.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.meta/design.md Co-authored-by: BethanyG <[email protected]> * Update design.md * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> * Rewriting introduction.md and adding some stuff to after.md * Update example.py * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: Erik Schierboom <[email protected]> * Update introduction.md * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update languages/exercises/concept/dicts/.docs/instructions.md Co-authored-by: BethanyG <[email protected]> * Update instructions.md * Rework * Update introduction.md * Update languages/exercises/concept/dicts/.meta/example.py Co-authored-by: Corey McCandless <[email protected]> Co-authored-by: Corey McCandless <[email protected]> Co-authored-by: BethanyG <[email protected]> Co-authored-by: Erik Schierboom <[email protected]>
1 parent 3b83833 commit 65fae2e

File tree

9 files changed

+288
-0
lines changed

9 files changed

+288
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Python dictionaries are very powerful and you will be using them a lot if you're working with APIs and such. Dictionaries are essentially an array of _keys_ paired with _values_.
2+
3+
## Dictionaries and lists
4+
5+
Just like `lists`, dictionaries are ordered by insertion order, they are mutable (which means you can change their content without changing their identity). They can also (just like `lists`) be nested, which means that a dictionary can contain another dictionary. Dictionaries are generally used in databases for use cases where looking up things by _key_ are used over and over, although they are not generally used for use cases with demand for high-speed insertion. This [blog post][listsvdicts] by _Jessica Yung_ goes into what data type is preferred in what use cases, on a more _scientific_ level.
6+
7+
## Dealing with dictionaries
8+
9+
Dictionaries have different methods to change them, like getting a value from a specific key in the dictionary, setting a default value for a key and many more. Dictionaries are also iterable by their keys. For a full explanation of dictionaries in python refer to the [official documentation][docs] and on how to use them look at [W3-Schools.com'][how-to] tutorial.
10+
11+
Now that you know the basics of _creation_, _membership_ and _retrieval_ here are some useful `dict` methods. You can get values from a dictionary by using the `.get(key, [default])`, which returns the value of the given key in the dictionary, if the key does not exist it returns the `default` value. Dictionaries also have the `.setdefault(key, [default])` method, which is almost the same as `.get()`, but it also places that key with the default value if it does not exist inside the dictionary.
12+
13+
## The collections module
14+
15+
The [`collections`][collections-docs] module adds more functionality to Python's standard collection-based datatypes (`dictionary`, `set`, `list`, `tuple`). A handy member of this module is the [`Counter`][counter-dicts] class, which can count items and return them in a dictionary form. There is also [`OrderedDict`][ordered-dicts-docs] which has methods specialized for re-arranging the order of a dictionary. Finally, there is `defaultdict`- a subclass of the built-in `dict` module that overrides one method and adds one new one. The `collections` module is a handy module to use if you need some _extra_ or extended functionality for your container-based datatypes.
16+
17+
[listsvdicts]: https://www.jessicayung.com/python-lists-vs-dictionaries-the-space-time-tradeoff/
18+
[docs]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
19+
[how-to]: https://www.w3schools.com/python/python_dictionaries.asp
20+
[collections-docs]: https://docs.python.org/3/library/collections.html
21+
[counter-dicts]: https://docs.python.org/3/library/collections.html#collections.Counter
22+
[ordered-dicts-docs]: https://docs.python.org/3/library/collections.html#collections.OrderedDict
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TO DO
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
In this exercise you'll be managing an inventory system.
2+
3+
You will be given a list of items. Each time an item is in the given list, add `1` to the key in the _given_ inventory. Each item should be organized by their name and the amount of that item. You will also have to delete items from the inventory.
4+
5+
You will also have to implement a function which returns a list of `tuples` of all the key-value pairs in the _given_ inventory.
6+
7+
## 1. Create an inventory from a list
8+
9+
Implement the `create_inventory()` function that creates an "inventory" from a list of items. It should return a `dictionary` representing the types and amounts of the items.
10+
11+
```python
12+
>>> create_inventory(["coal", "wood", "wood", "diamond", "diamond", "diamond"])
13+
{"coal":1, "wood":2 "diamond":3}
14+
```
15+
16+
## 2. Add items from a list to an existing dictionary
17+
18+
Implement the `add_items()` function that adds a list of items to a passed in inventory dictionary:
19+
20+
```python
21+
>>> add_items({"coal":1}, ["wood", "iron", "coal", "wood"])
22+
{"coal":2, "wood":2, "iron":1}
23+
```
24+
25+
## 3. Remove items from the inventory
26+
27+
Implement the `delete_items()` function that removes items in the passed-in list from the passed inventory dictionary:
28+
29+
```python
30+
>>> delete_items({"coal":3, "diamond":1, "iron":5}, ["diamond", "coal", "iron", "iron"])
31+
{"coal":2, "diamond":0, "iron":3}
32+
```
33+
34+
Item counts should not fall below `0`, if the amount of an item in the list exceeds the amount of items in the inventory, the value should stop at `0` and not go into negative numbers.
35+
36+
```python
37+
>>> delete_items({"coal":2, "wood":1, "diamond":2}, ["coal", "coal", "wood", "wood", "diamond"])
38+
{"coal":0, "wood":0, "diamond":1}
39+
```
40+
41+
## 4. Return the inventory content
42+
43+
Implement the `list_inventory()` function that takes an inventory and returns a list of `(item, amount)` tuples. Only include items where the amount is greater than zero:
44+
45+
```python
46+
>>> list_inventory({"coal":7, "wood":11, "diamond":2, "iron":7, "silver": 0})
47+
[('coal', 7), ('diamond', 2), ('iron', 7), ('wood', 11)]
48+
```
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
A _dictionary_ is Python's primary mapping type that connects _hashable keys_ with values. The looking up of keys is more efficient than searching through an array, but does require more memory.
2+
3+
## Dict construction
4+
5+
Dictionaries can be created in various ways. You can either use the `dict()` class constructor or the literal declaration of a _dict_.
6+
7+
### Use the `dict()` constructor
8+
9+
```python
10+
>>> bear = dict(name="Black Bear", amount=5, land_animal=True)
11+
{'name': 'Panda', 'amount': 15, 'land_animal': True}
12+
```
13+
14+
### Declare a _dict_ literal
15+
16+
```python
17+
>>> whale = {"name":"Blue Whale", "amount":2, "land_animal":False}
18+
{'name': 'Dolphin', 'amount': 2, 'land_animal': False}
19+
```
20+
21+
With literal declaration keep in mind that _keys_ are replaced with _data types_ and the `=` is replaced with a `:`.
22+
23+
## Accessing values
24+
25+
You can access items in a dictionary in two ways, using the _key_ of the value.
26+
27+
### Using _square brackets_ after the dict object
28+
29+
```python
30+
>>> request_brackets = bear["amount"]
31+
5
32+
```
33+
34+
### Using `.get()`
35+
36+
```python
37+
>>> request_get = whale.get("name")
38+
Blue Whale
39+
```
40+
41+
## Changing values
42+
43+
You can easily change a value of an item using it's _key_.
44+
45+
```python
46+
>>> bear["name"] = "Grizzly Bear"
47+
{'name': 'Grizzly Bear', 'amount': 5, 'land_animal': True}
48+
49+
>>> whale["amount"] = 7
50+
{'name': 'Blue Whale', 'amount': 7, 'land_animal': False}
51+
```
52+
53+
## Looping through a dictionary
54+
55+
Looping through a dictionary using a `for` loop only returns the _keys_ of the items.
56+
57+
```python
58+
>>> for key in bear:
59+
>>> print(key)
60+
name
61+
amount
62+
land_animal
63+
```
64+
65+
But you can also make a `for` loop return the _values_ of a dictionary with a simple trick.
66+
67+
```python
68+
>>> for key in whale:
69+
>>> print(whale[key])
70+
Blue Whale
71+
7
72+
False
73+
```
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"authors": [
3+
{
4+
"github_username": "j08k",
5+
"exercism_username": "j08k"
6+
}
7+
]
8+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Design
2+
3+
## Goal
4+
5+
The goal of this exercise is to teach the basics of the `dict` (dictionary, mapping) data type in Python.
6+
7+
## Things to teach
8+
9+
- create a `dict` via constructor and literal.
10+
- access values in a `dict` via `keys`.
11+
- assign values in a `dict` via key reference.
12+
- check for membership of a key in a given dictionary.
13+
- add new `key`:`value` pairs to the `dict`.
14+
- remove `key`:`value` pairs from the `dict`.
15+
- iterate through a `dict` using `dict.keys()`, `dict.values()`, or `dict.items()`.
16+
- `dict` method `setdefault()`
17+
18+
## Things not to teach
19+
20+
- Dictionary comprehensions
21+
- `dict` methods such as `get()` or `clear()`.
22+
- Built-in functions as they relate to this data structure (_e.g._ `copy()`, `len()`, or `enumerate()`.
23+
- Sorting by `keys` or `values`.
24+
- Swapping `keys` for `values`.
25+
- Knowing that Dictionaries can be _nested_, _-- e.g._ ' a dictionary of dictionaries'.
26+
- Mutability
27+
- `copy()` vs `deepcopy()`
28+
- Related `collections` module with `Counter()` and `defaultdict()`
29+
- Memory and performance characteristics.
30+
31+
## Concepts
32+
33+
- `dicts`
34+
35+
## Prerequisites
36+
37+
- `booleans`
38+
- `for-loops`
39+
- `functions`
40+
- `if-keyword`
41+
- `in-keyword`
42+
- `integers`
43+
- `return-keyword`
44+
- `strings`
45+
- `tuples`
46+
- `lists`
47+
48+
## Representer
49+
50+
This exercise does not require any logic to be added to the [representer][representer]
51+
52+
## Analyzer
53+
54+
This exercise does not require any logic to be added to the [analyzer][analyzer].
55+
56+
[builtin-types]: https://github.com/exercism/v3/tree/master/languages/python/reference/concepts/builtin_types
57+
[data-types]: https://github.com/exercism/v3/blob/master/languages/python/reference/concepts/data_structures.md
58+
[analyzer]: https://github.com/exercism/python-analyzer
59+
[representer]: https://github.com/exercism/python-representer
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
def create_inventory(items):
2+
inventory = dict()
3+
add_items(inventory, items)
4+
return inventory
5+
6+
7+
def add_items(inventory, items):
8+
for item in items:
9+
inventory.setdefault(item, 0)
10+
inventory[item] += 1
11+
return inventory
12+
13+
14+
def delete_items(inventory, items):
15+
for item in items:
16+
inventory.setdefault(item, 0)
17+
inventory[item] = max(inventory[item] - 1, 0)
18+
return inventory
19+
20+
21+
def list_inventory(inventory):
22+
output = list()
23+
for item in sorted(inventory.items()):
24+
if item[1] > 0:
25+
output.append(item)
26+
return output

exercises/concept/dicts/dicts.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def create_inventory(items):
2+
pass
3+
4+
def add_items(inventory, items):
5+
pass
6+
7+
def delete_items(inventory, items):
8+
pass
9+
10+
def list_inventory(inventory):
11+
pass

exercises/concept/dicts/dicts_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import unittest
2+
from dicts import *
3+
4+
class test_inventory(unittest.TestCase):
5+
def test_create_inventory(self):
6+
self.assertEqual(create_inventory(["wood", "iron", "iron", "diamond", "diamond"]),
7+
{"wood":1, "iron":2, "diamond":2})
8+
9+
def test_add_one_item(self):
10+
self.assertEqual(add_items({"wood":4, "iron":2}, ["iron", "iron"]),
11+
{"wood":4, "iron":4})
12+
13+
def test_add_multiple_items(self):
14+
self.assertEqual(add_items({"wood":2, "gold":1, "diamond":3}, ["wood", "gold", "gold"]),
15+
{"wood":3, "gold":3, "diamond":3})
16+
17+
def test_add_new_item(self):
18+
self.assertEqual(add_items({"iron":1, "diamond":2}, ["iron", "wood", "wood"]),
19+
{"iron":2, "diamond":2, "wood":2})
20+
21+
def test_add_from_empty_dict(self):
22+
self.assertEqual(add_items({}, ["iron", "iron", "diamond"]),
23+
{"iron":2, "diamond":1})
24+
25+
def test_delete_items(self):
26+
self.assertEqual(delete_items({"iron":3, "diamond":4, "gold":2},
27+
["iron", "iron", "diamond", "gold", "gold"]),
28+
{"iron":1, "diamond":3, "gold":0})
29+
30+
def test_not_below_zero(self):
31+
self.assertEqual(delete_items({"wood":2, "iron":3, "diamond":1},
32+
["wood", "wood", "wood", "iron", "diamond", "diamond"]),
33+
{"wood":0, "iron":2, "diamond":0})
34+
35+
def test_list_inventory(self):
36+
self.assertEqual(list_inventory({"coal":15, "diamond":3, "wood":67}),
37+
[("coal", 15), ("diamond", 3), ("wood", 67)])
38+
39+
if __name__ == "__main__":
40+
unittest.main()

0 commit comments

Comments
 (0)