[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![License: MIT](https://img.shields.io/badge/License-MIT-blueviolet.svg)](https://opensource.org/licenses/MIT)
[![codecov](https://codecov.io/gh/tybruno/modifiable-items-dictionary/branch/main/graph/badge.svg?token=ZO94EJFI3G)](https://codecov.io/gh/tybruno/modifiable-items-dictionary)
# modifiable-items-dict
A simple, fast, typed, and tested implementation for a python3.6+ Modifiable
Items dictionary. `ModifiableItemsDict`
extends `dict` with the ability to modify key's and value's on creation,
insertion, and retrieval.
This class extends and maintains the original functionality of the
builtin `dict`.
#### Key Features:
* **Easy**: Flexable and easy to add Key and/or Value modifiers to
the `ModifiableItemsDict`
* **Great Developer Experience**: Being fully typed makes it great for editor
support.
* **Fully Tested**: Our test suit fully tests the functionality to ensure
that `ModifiableItemsDict` runs as expected.
* **There is More!!!**:
* [CaselessDict](https://github.com/tybruno/caseless-dictionary): `CaselessDict`
extends `ModifiableItemsDict` which
is a `CaselessDict` which ignores the case of the keys.
## Installation
`pip install modifiable-items-dictionary`
## Simple Example
```python
from modifiable_items_dictionary import ModifiableItemsDict
def _add_1(_value):
if isinstance(_value, int):
_value += 1
return _value
def _case_fold_string(_value):
if isinstance(_value, str):
_value = _value.casefold()
return _value
ModifiableItemsDict._key_modifiers = [str.casefold]
ModifiableItemsDict._value_modifiers = (
_add_1, _case_fold_string)
# Or
# ModifiableItemsDict._key_modifiers = staticmethod(str.casefold)
# ModifiableItemsDict._value_modifiers = [_case_fold_string, _add_1]
modifiable_items_dictionary = ModifiableItemsDict(
{"lower": 1, "UPPER": 2},
CamelCase=3,
snake_case="FoUR"
)
print(
modifiable_items_dictionary
) # {'lower': 2, 'upper': 3, 'camelcase': 4, 'snake_case': 'four'}
del modifiable_items_dictionary["LOWER"]
del modifiable_items_dictionary["UPPER"]
modifiable_items_dictionary.pop("SNAKE_CAse")
modifiable_items_dictionary["HeLLO"] = 5
print(modifiable_items_dictionary) # {'camelcase': 4, 'hello': 6}
```
## Example
Let's say that there is a `.json` file that has Url hosts and their IP address.
Our Goal is to load the json data into a dictionary like structure that will
have it's items modified during creation,
insertion, and retrieval.
This example highlights how to inherit from `ModifiableItemsDict` and had key
and value modifiers.
```python
import ipaddress
from modifiable_items_dictionary import ModifiableItemsDict
class HostDict(ModifiableItemsDict):
_key_modifiers = [str.casefold, str.strip]
_value_modifiers = [ipaddress.ip_address]
# Or
# _value_modifiers = @staticmethod(ipaddress.ip_address)
browsers = HostDict(
{
" GooGle.com ": "142.250.69.206",
" duckDUCKGo.cOM ": "52.250.42.157",
}
)
print(browsers)
# {'google.com': IPv4Address('142.250.69.206'), 'duckduckgo.com': IPv4Address('52.250.42.157')}
_old_browser = browsers.pop(" gOOgle.com ")
# or
# del host_dict[" GooGle.com "]
browsers[" BrAvE.com "] = "2600:9000:234c:5a00:6:d0d2:780:93a1"
print(browsers)
# {'duckduckgo.com': IPv4Address('52.250.42.157'), 'brave.com': IPv6Address('2600:9000:234c:5a00:6:d0d2:780:93a1')}
```
### Threading Example
It is easy to add Threading to a `ModifiableItemsDict`.
*NOTE: Since `ModifiableItemsDict` is not pickable it does not work with
Multiprocessing. It only works with Multithreading.*
```python
import multiprocessing.pool
import string
import time
from modifiable_items_dictionary import ModifiableItemsDict
pool = multiprocessing.pool.ThreadPool(10)
def _slow_function(x):
time.sleep(.05)
return x
class TimeDictWithThreading(ModifiableItemsDict):
_key_modifiers = (_slow_function,)
_value_modifiers = (_slow_function,)
_map_function = pool.imap_unordered
# or if order matters
# _map_function = pool.imap
class TimeDict(ModifiableItemsDict):
_key_modifiers = (_slow_function,)
_value_modifiers = (_slow_function,)
iterable = {_letter: _index for _index, _letter in
enumerate(string.ascii_letters)}
# Without Threading
start = time.perf_counter()
TimeDict(iterable)
end = time.perf_counter()
print(f"{end - start:.2f} seconds") # 5.54 seconds
# With Threading
start = time.perf_counter()
TimeDictWithThreading(iterable)
end = time.perf_counter()
print(f"{end - start:.2f} seconds") # 0.64 seconds
```
## Reference
This project was inspired by Raymond
Hettinger ([rhettinger](https://github.com/rhettinger)).
- Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.
Raw data
{
"_id": null,
"home_page": "https://github.com/tybruno/modifiable-items-dictionary",
"name": "modifiable-items-dictionary",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "python dict dictionary mapping key-mangling",
"author": "Tyler Bruno",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/73/4f/128091f3bbca06b361dc4c2a24461646c9c40e6c22ffe64b08569e48c3f4/modifiable-items-dictionary-2.0.3.tar.gz",
"platform": null,
"description": "[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)\n[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blueviolet.svg)](https://opensource.org/licenses/MIT)\n[![codecov](https://codecov.io/gh/tybruno/modifiable-items-dictionary/branch/main/graph/badge.svg?token=ZO94EJFI3G)](https://codecov.io/gh/tybruno/modifiable-items-dictionary)\n\n# modifiable-items-dict\n\nA simple, fast, typed, and tested implementation for a python3.6+ Modifiable\nItems dictionary. `ModifiableItemsDict`\nextends `dict` with the ability to modify key's and value's on creation,\ninsertion, and retrieval.\nThis class extends and maintains the original functionality of the\nbuiltin `dict`.\n\n#### Key Features:\n\n* **Easy**: Flexable and easy to add Key and/or Value modifiers to\n the `ModifiableItemsDict`\n* **Great Developer Experience**: Being fully typed makes it great for editor\n support.\n* **Fully Tested**: Our test suit fully tests the functionality to ensure\n that `ModifiableItemsDict` runs as expected.\n* **There is More!!!**:\n * [CaselessDict](https://github.com/tybruno/caseless-dictionary): `CaselessDict`\n extends `ModifiableItemsDict` which\n is a `CaselessDict` which ignores the case of the keys.\n\n## Installation\n\n`pip install modifiable-items-dictionary`\n\n## Simple Example\n\n```python\nfrom modifiable_items_dictionary import ModifiableItemsDict\n\n\ndef _add_1(_value):\n if isinstance(_value, int):\n _value += 1\n return _value\n\n\ndef _case_fold_string(_value):\n if isinstance(_value, str):\n _value = _value.casefold()\n return _value\n\n\nModifiableItemsDict._key_modifiers = [str.casefold]\nModifiableItemsDict._value_modifiers = (\n _add_1, _case_fold_string)\n# Or\n# ModifiableItemsDict._key_modifiers = staticmethod(str.casefold)\n# ModifiableItemsDict._value_modifiers = [_case_fold_string, _add_1]\n\nmodifiable_items_dictionary = ModifiableItemsDict(\n {\"lower\": 1, \"UPPER\": 2},\n CamelCase=3,\n snake_case=\"FoUR\"\n)\n\nprint(\n modifiable_items_dictionary\n) # {'lower': 2, 'upper': 3, 'camelcase': 4, 'snake_case': 'four'}\n\ndel modifiable_items_dictionary[\"LOWER\"]\ndel modifiable_items_dictionary[\"UPPER\"]\nmodifiable_items_dictionary.pop(\"SNAKE_CAse\")\n\nmodifiable_items_dictionary[\"HeLLO\"] = 5\n\nprint(modifiable_items_dictionary) # {'camelcase': 4, 'hello': 6}\n```\n\n## Example\n\nLet's say that there is a `.json` file that has Url hosts and their IP address.\nOur Goal is to load the json data into a dictionary like structure that will\nhave it's items modified during creation,\ninsertion, and retrieval.\nThis example highlights how to inherit from `ModifiableItemsDict` and had key\nand value modifiers.\n\n```python\nimport ipaddress\n\nfrom modifiable_items_dictionary import ModifiableItemsDict\n\n\nclass HostDict(ModifiableItemsDict):\n _key_modifiers = [str.casefold, str.strip]\n _value_modifiers = [ipaddress.ip_address]\n # Or\n # _value_modifiers = @staticmethod(ipaddress.ip_address)\n\n\nbrowsers = HostDict(\n {\n \" GooGle.com \": \"142.250.69.206\",\n \" duckDUCKGo.cOM \": \"52.250.42.157\",\n }\n)\n\nprint(browsers)\n# {'google.com': IPv4Address('142.250.69.206'), 'duckduckgo.com': IPv4Address('52.250.42.157')}\n\n_old_browser = browsers.pop(\" gOOgle.com \")\n# or \n# del host_dict[\" GooGle.com \"]\n\nbrowsers[\" BrAvE.com \"] = \"2600:9000:234c:5a00:6:d0d2:780:93a1\"\n\nprint(browsers)\n# {'duckduckgo.com': IPv4Address('52.250.42.157'), 'brave.com': IPv6Address('2600:9000:234c:5a00:6:d0d2:780:93a1')}\n```\n\n### Threading Example\n\nIt is easy to add Threading to a `ModifiableItemsDict`.\n\n*NOTE: Since `ModifiableItemsDict` is not pickable it does not work with\nMultiprocessing. It only works with Multithreading.*\n\n```python\nimport multiprocessing.pool\nimport string\nimport time\n\nfrom modifiable_items_dictionary import ModifiableItemsDict\n\npool = multiprocessing.pool.ThreadPool(10)\n\n\ndef _slow_function(x):\n time.sleep(.05)\n return x\n\n\nclass TimeDictWithThreading(ModifiableItemsDict):\n _key_modifiers = (_slow_function,)\n _value_modifiers = (_slow_function,)\n _map_function = pool.imap_unordered\n # or if order matters\n # _map_function = pool.imap\n\n\nclass TimeDict(ModifiableItemsDict):\n _key_modifiers = (_slow_function,)\n _value_modifiers = (_slow_function,)\n\n\niterable = {_letter: _index for _index, _letter in\n enumerate(string.ascii_letters)}\n\n# Without Threading\nstart = time.perf_counter()\nTimeDict(iterable)\nend = time.perf_counter()\nprint(f\"{end - start:.2f} seconds\") # 5.54 seconds\n\n# With Threading\nstart = time.perf_counter()\nTimeDictWithThreading(iterable)\nend = time.perf_counter()\nprint(f\"{end - start:.2f} seconds\") # 0.64 seconds\n```\n\n## Reference\n\nThis project was inspired by Raymond\nHettinger ([rhettinger](https://github.com/rhettinger)).\n\n- Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Typed and Tested Modifiable Items Dict which allows keys and values to be modified at run time.",
"version": "2.0.3",
"project_urls": {
"Homepage": "https://github.com/tybruno/modifiable-items-dictionary"
},
"split_keywords": [
"python",
"dict",
"dictionary",
"mapping",
"key-mangling"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bf9715ad37ec284bc42c0b925fdd34d28dbeeb1dddb2bc5249d5fb86e1bea162",
"md5": "b81b583c559b3fcdb598050850cb5839",
"sha256": "9ce5e63cb82149f4bdb21b1312237ec7a6fb5798f70f678fa0ff69e07a55d82e"
},
"downloads": -1,
"filename": "modifiable_items_dictionary-2.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b81b583c559b3fcdb598050850cb5839",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 7021,
"upload_time": "2023-10-16T14:56:00",
"upload_time_iso_8601": "2023-10-16T14:56:00.043702Z",
"url": "https://files.pythonhosted.org/packages/bf/97/15ad37ec284bc42c0b925fdd34d28dbeeb1dddb2bc5249d5fb86e1bea162/modifiable_items_dictionary-2.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "734f128091f3bbca06b361dc4c2a24461646c9c40e6c22ffe64b08569e48c3f4",
"md5": "e334c9ef39c04511cb0a654c66507e65",
"sha256": "68e3f2fb1eb428ae2f06682a2cbb4869642b3d93013d606efc259c8a1a7ed6fd"
},
"downloads": -1,
"filename": "modifiable-items-dictionary-2.0.3.tar.gz",
"has_sig": false,
"md5_digest": "e334c9ef39c04511cb0a654c66507e65",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 8726,
"upload_time": "2023-10-16T14:56:01",
"upload_time_iso_8601": "2023-10-16T14:56:01.665481Z",
"url": "https://files.pythonhosted.org/packages/73/4f/128091f3bbca06b361dc4c2a24461646c9c40e6c22ffe64b08569e48c3f4/modifiable-items-dictionary-2.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-16 14:56:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tybruno",
"github_project": "modifiable-items-dictionary",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "modifiable-items-dictionary"
}