RecursiveNamespaceV2 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ PYTHONPATH=./src
@@ -0,0 +1,2 @@
1
+ _version.py export-subst
2
+ src/recursivenamespace/_version.py export-subst
@@ -0,0 +1,70 @@
1
+ # This workflow will upload a Python Package to PyPI when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release-build:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.x"
28
+
29
+ - name: Build release distributions
30
+ run: |
31
+ # NOTE: put your own distribution build steps here.
32
+ python -m pip install flit
33
+ python -m flit build
34
+
35
+ - name: Upload distributions
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: release-dists
39
+ path: dist/
40
+
41
+ pypi-publish:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-build
45
+ permissions:
46
+ # IMPORTANT: this permission is mandatory for trusted publishing
47
+ id-token: write
48
+
49
+ # Dedicated environments with protections for publishing are strongly recommended.
50
+ # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
+ environment:
52
+ name: pypi
53
+ # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
+ # url: https://pypi.org/p/YOURPROJECT
55
+ #
56
+ # ALTERNATIVE: if your GitHub Release name is the PyPI project version string
57
+ # ALTERNATIVE: exactly, uncomment the following line instead:
58
+ # url: https://pypi.org/project/YOURPROJECT/${{ github.event.release.name }}
59
+
60
+ steps:
61
+ - name: Retrieve release distributions
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: release-dists
65
+ path: dist/
66
+
67
+ - name: Publish release distributions to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+ with:
70
+ packages-dir: dist/
@@ -0,0 +1,176 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # Ruff stuff:
171
+ .ruff_cache/
172
+
173
+ # PyPI configuration file
174
+ .pypirc
175
+
176
+ out/
@@ -0,0 +1,15 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Python Debugger: Current File",
9
+ "type": "debugpy",
10
+ "request": "launch",
11
+ "program": "${file}",
12
+ "console": "integratedTerminal"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Jan.2025 VienPQ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.3
2
+ Name: RecursiveNamespaceV2
3
+ Version: 0.0.1
4
+ Summary: Recursive Namespace. An extension of SimpleNamespace. Enhance get/set and parse from JSON
5
+ Author-email: VienPQ <pasxd245@gmail.com>
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Dist: pytest>=6.0 ; extra == "test"
12
+ Requires-Dist: coverage>=7.0 ; extra == "test"
13
+ Project-URL: repository, https://github.com/pasxd245/RecursiveNamespaceV2
14
+ Provides-Extra: test
15
+
16
+ # RecursiveNamespace
17
+
18
+ ## Description
19
+ **RecursiveNamespace** is an extension of Python's **SimpleNamespace** that provides enhanced functionality for working with nested namespaces and dictionaries. This package allows easy access and manipulation of deeply nested data structures in an intuitive and Pythonic way.
20
+
21
+ ## Installation
22
+ To install **RecursiveNamespaceV2** from PyPI use the following command.
23
+ ```bash
24
+ pip install RecursiveNamespaceV2
25
+ ```
26
+
27
+ If you want to use the github clone, use the following.
28
+ ```bash
29
+ git clone https://github.com/pasxd245/RecursiveNamespaceV2.git
30
+ cd RecursiveNamespaceV2
31
+ python -m venv .venv # to setup a virtual env.
32
+ pip install -r .\requirements.txt
33
+ ```
34
+
35
+ # Usage
36
+
37
+ The **RecursiveNamespace** class can be used in the same way as Python's **SimpleNamespace** class, but in a recursive fashion. The **RecursiveNamespace** class can be instantiated with a dictionary or keyword arguments. The **RecursiveNamespace** class also provides a `to_dict()` method that returns a dictionary representation of the namespace.
38
+
39
+ ## Basic Usage
40
+ One of the best use cases of this module is converting `dict` into a recursive namespace, and back to `dict`.
41
+ Another usage is to convert a dictionary to a recursive namespace.
42
+
43
+ ```python
44
+ from recursivenamespace import RNS # or RecursiveNamespace
45
+
46
+ data = {
47
+ 'name': 'John',
48
+ 'age': 30,
49
+ 'address': {
50
+ 'street': '123 Main St',
51
+ 'city': 'Anytown'
52
+ },
53
+ 'friends': ['Jane', 'Tom']
54
+ }
55
+
56
+ rn = RNS(data)
57
+ print(type(rn)) # <class 'recursivenamespace.main.recursivenamespace'>
58
+ print(rn) # RNS(name=John, age=30, address=RNS(street=123 Main St, city=Anytown))
59
+ print(rn.name) # John
60
+ print(rn.address.city) # Anytown
61
+ print(rn.friends[1]) # Tom, yes it does recognize iterables
62
+
63
+ # convert back to dictionary
64
+ data2 = rn.to_dict()
65
+ print(type(data2)) # <class 'dict'>
66
+ print(data2 == data) # True
67
+ print(data2['address']['city']) # Anytown
68
+ print(data2['friends'][1]) # Tom
69
+ ```
70
+
71
+ You can use the key or namespace interchangeably
72
+ ```python
73
+ print(rn.friends[1] is rn['friends'][1]) # True
74
+ ```
75
+
76
+
77
+ You can also use it with YAML.
78
+ ```python
79
+ import yaml
80
+ from recursivenamespace import RNS
81
+ datatext = """
82
+ name: John
83
+ age: 30
84
+ address:
85
+ street: 123 Main St
86
+ city: Anytown
87
+ friends:
88
+ - Jane
89
+ - Tom
90
+ """
91
+ data = yaml.safe_load(datatext)
92
+ rn = RNS(data)
93
+ print(rn) # RNS(name=John, age=30, address=RNS(street=123 Main St, city=Anytown))
94
+
95
+ # convert back to YAML
96
+ data_yaml = yaml.dump(rn.to_dict())
97
+ ```
98
+
99
+ Let's see other use cases. You can make a nested rns.
100
+ ```python
101
+ from recursivenamespace import RNS
102
+ results = RNS(
103
+ params=rns(
104
+ alpha=1.0,
105
+ beta=2.0,
106
+ ),
107
+ metrics=rns(
108
+ accuracy=98.79,
109
+ f1=97.62
110
+ )
111
+ )
112
+ ```
113
+
114
+ Access elements as dictionary keys or namespace attributes.
115
+ ```python
116
+ print(results.params.alpha is results.params['alpha']) # True
117
+ print(results['metrics'].accuracy is results.metrics['accuracy']) # True
118
+ ```
119
+
120
+ Convert only the metrics to dictionary.
121
+ ```python
122
+ metrics_dict = results.metrics.to_dict()
123
+ print(metrics_dict) # {'accuracy': 98.79, 'f1': 97.62}
124
+ ```
125
+ Or convert all to a nested dictionary.
126
+ ```python
127
+ from pprint import pprint
128
+ output_dict = results.to_dict()
129
+ pprint(output_dict)
130
+ # {'metrics': {'accuracy': 98.79, 'f1': 97.62},
131
+ # 'params': {'alpha': 1.0, 'beta': 2.0}}
132
+ ```
133
+ Flatten the dictionary using a separator for keys.
134
+ ```python
135
+ flat_dict = results.to_dict(flatten_sep='_')
136
+ pprint(flat_dict)
137
+ # {'metrics_accuracy': 98.79,
138
+ # 'metrics_f1': 97.62,
139
+ # 'params_alpha': 1.0,
140
+ # 'params_beta': 2.0}
141
+ ```
142
+ Add more fields on the fly.
143
+ ```python
144
+ results.experiment_name = 'experiment_name'
145
+ results.params.dataset_version = 'dataset_version'
146
+ results.params.gamma = 0.35
147
+ ```
148
+
149
+ The character '-' in a key will be converted to '_'
150
+ ```python
151
+ results.params['some-key'] = 'some-value'
152
+ print(results.params.some_key) # some-value
153
+ print(results.params['some-key'] is results.params.some_key) # True
154
+ print(results.params['some-key'] is results.params['some_key']) # True
155
+ ```
156
+
157
+ # Testing
158
+ To run tests, navigate to the project's root directory and execute:
159
+ ```bash
160
+ pytest -s
161
+ # or with coverage:
162
+ coverage run -m pytest
163
+ ```
164
+
165
+ The `test_recursive_namespace.py` file contains tests for the **RecursiveNamespace** class.
166
+
167
+ # Contributing
168
+ Contributions to the **RecursiveNamespace** project are welcome! Please ensure that any pull requests include tests covering new features or fixes.
169
+
170
+ # License
171
+ This project is licensed under the MIT License - see the `LICENSE` file for details.
172
+
173
+ You should copy the actual content from examlpes scripts (founde under `./examples/` directory) and paste it into the respective sections of the README. This provides users with immediate examples of how to use your package. The Testing section explains how to run the unit tests, encouraging users to check that everything is working correctly.
@@ -0,0 +1,158 @@
1
+ # RecursiveNamespace
2
+
3
+ ## Description
4
+ **RecursiveNamespace** is an extension of Python's **SimpleNamespace** that provides enhanced functionality for working with nested namespaces and dictionaries. This package allows easy access and manipulation of deeply nested data structures in an intuitive and Pythonic way.
5
+
6
+ ## Installation
7
+ To install **RecursiveNamespaceV2** from PyPI use the following command.
8
+ ```bash
9
+ pip install RecursiveNamespaceV2
10
+ ```
11
+
12
+ If you want to use the github clone, use the following.
13
+ ```bash
14
+ git clone https://github.com/pasxd245/RecursiveNamespaceV2.git
15
+ cd RecursiveNamespaceV2
16
+ python -m venv .venv # to setup a virtual env.
17
+ pip install -r .\requirements.txt
18
+ ```
19
+
20
+ # Usage
21
+
22
+ The **RecursiveNamespace** class can be used in the same way as Python's **SimpleNamespace** class, but in a recursive fashion. The **RecursiveNamespace** class can be instantiated with a dictionary or keyword arguments. The **RecursiveNamespace** class also provides a `to_dict()` method that returns a dictionary representation of the namespace.
23
+
24
+ ## Basic Usage
25
+ One of the best use cases of this module is converting `dict` into a recursive namespace, and back to `dict`.
26
+ Another usage is to convert a dictionary to a recursive namespace.
27
+
28
+ ```python
29
+ from recursivenamespace import RNS # or RecursiveNamespace
30
+
31
+ data = {
32
+ 'name': 'John',
33
+ 'age': 30,
34
+ 'address': {
35
+ 'street': '123 Main St',
36
+ 'city': 'Anytown'
37
+ },
38
+ 'friends': ['Jane', 'Tom']
39
+ }
40
+
41
+ rn = RNS(data)
42
+ print(type(rn)) # <class 'recursivenamespace.main.recursivenamespace'>
43
+ print(rn) # RNS(name=John, age=30, address=RNS(street=123 Main St, city=Anytown))
44
+ print(rn.name) # John
45
+ print(rn.address.city) # Anytown
46
+ print(rn.friends[1]) # Tom, yes it does recognize iterables
47
+
48
+ # convert back to dictionary
49
+ data2 = rn.to_dict()
50
+ print(type(data2)) # <class 'dict'>
51
+ print(data2 == data) # True
52
+ print(data2['address']['city']) # Anytown
53
+ print(data2['friends'][1]) # Tom
54
+ ```
55
+
56
+ You can use the key or namespace interchangeably
57
+ ```python
58
+ print(rn.friends[1] is rn['friends'][1]) # True
59
+ ```
60
+
61
+
62
+ You can also use it with YAML.
63
+ ```python
64
+ import yaml
65
+ from recursivenamespace import RNS
66
+ datatext = """
67
+ name: John
68
+ age: 30
69
+ address:
70
+ street: 123 Main St
71
+ city: Anytown
72
+ friends:
73
+ - Jane
74
+ - Tom
75
+ """
76
+ data = yaml.safe_load(datatext)
77
+ rn = RNS(data)
78
+ print(rn) # RNS(name=John, age=30, address=RNS(street=123 Main St, city=Anytown))
79
+
80
+ # convert back to YAML
81
+ data_yaml = yaml.dump(rn.to_dict())
82
+ ```
83
+
84
+ Let's see other use cases. You can make a nested rns.
85
+ ```python
86
+ from recursivenamespace import RNS
87
+ results = RNS(
88
+ params=rns(
89
+ alpha=1.0,
90
+ beta=2.0,
91
+ ),
92
+ metrics=rns(
93
+ accuracy=98.79,
94
+ f1=97.62
95
+ )
96
+ )
97
+ ```
98
+
99
+ Access elements as dictionary keys or namespace attributes.
100
+ ```python
101
+ print(results.params.alpha is results.params['alpha']) # True
102
+ print(results['metrics'].accuracy is results.metrics['accuracy']) # True
103
+ ```
104
+
105
+ Convert only the metrics to dictionary.
106
+ ```python
107
+ metrics_dict = results.metrics.to_dict()
108
+ print(metrics_dict) # {'accuracy': 98.79, 'f1': 97.62}
109
+ ```
110
+ Or convert all to a nested dictionary.
111
+ ```python
112
+ from pprint import pprint
113
+ output_dict = results.to_dict()
114
+ pprint(output_dict)
115
+ # {'metrics': {'accuracy': 98.79, 'f1': 97.62},
116
+ # 'params': {'alpha': 1.0, 'beta': 2.0}}
117
+ ```
118
+ Flatten the dictionary using a separator for keys.
119
+ ```python
120
+ flat_dict = results.to_dict(flatten_sep='_')
121
+ pprint(flat_dict)
122
+ # {'metrics_accuracy': 98.79,
123
+ # 'metrics_f1': 97.62,
124
+ # 'params_alpha': 1.0,
125
+ # 'params_beta': 2.0}
126
+ ```
127
+ Add more fields on the fly.
128
+ ```python
129
+ results.experiment_name = 'experiment_name'
130
+ results.params.dataset_version = 'dataset_version'
131
+ results.params.gamma = 0.35
132
+ ```
133
+
134
+ The character '-' in a key will be converted to '_'
135
+ ```python
136
+ results.params['some-key'] = 'some-value'
137
+ print(results.params.some_key) # some-value
138
+ print(results.params['some-key'] is results.params.some_key) # True
139
+ print(results.params['some-key'] is results.params['some_key']) # True
140
+ ```
141
+
142
+ # Testing
143
+ To run tests, navigate to the project's root directory and execute:
144
+ ```bash
145
+ pytest -s
146
+ # or with coverage:
147
+ coverage run -m pytest
148
+ ```
149
+
150
+ The `test_recursive_namespace.py` file contains tests for the **RecursiveNamespace** class.
151
+
152
+ # Contributing
153
+ Contributions to the **RecursiveNamespace** project are welcome! Please ensure that any pull requests include tests covering new features or fixes.
154
+
155
+ # License
156
+ This project is licensed under the MIT License - see the `LICENSE` file for details.
157
+
158
+ You should copy the actual content from examlpes scripts (founde under `./examples/` directory) and paste it into the respective sections of the README. This provides users with immediate examples of how to use your package. The Testing section explains how to run the unit tests, encouraging users to check that everything is working correctly.
@@ -0,0 +1,51 @@
1
+ from pprint import pprint
2
+
3
+ # from recursivenamespace import recursivenamespace
4
+ # or
5
+ from recursivenamespace import RNS
6
+
7
+ # I prefer to use as the following
8
+ results = RNS(
9
+ params=RNS(
10
+ alpha=1.0,
11
+ beta=2.0,
12
+ ),
13
+ metrics=RNS(accuracy=98.79, f1=97.62),
14
+ )
15
+ # I can access elements as dictionary keys or namespace attributes
16
+ print(results.params.alpha) # 1.0
17
+ print(results.params["alpha"]) # 1.0
18
+ print(results["metrics"].accuracy) # 98.79
19
+
20
+
21
+ # I can convert just the metrics to dictionary
22
+ metrics_dict = results.metrics.to_dict()
23
+ print(metrics_dict) # {'accuracy': 98.79, 'f1': 97.62}
24
+
25
+ # Or I can convert all of it to a nested dictionary
26
+ output_dict = results.to_dict()
27
+ pprint(output_dict)
28
+ # {'metrics': {'accuracy': 98.79, 'f1': 97.62},
29
+ # 'params': {'alpha': 1.0, 'beta': 2.0}}
30
+
31
+ # I can also flatten the keys using a separator
32
+ flat_dict = results.to_dict(flatten_sep="_")
33
+ pprint(flat_dict)
34
+ # {'metrics_accuracy': 98.79,
35
+ # 'metrics_f1': 97.62,
36
+ # 'params_alpha': 1.0,
37
+ # 'params_beta': 2.0}
38
+
39
+ # I can add more fields on the fly
40
+ results.experiment_name = "experiment_name"
41
+ results.params.dataset_version = "dataset_version"
42
+ results.params.gamma = 0.35
43
+
44
+ # If I add a key that contains '-' it will be converted to '_'
45
+ results.params["classifier-name"] = "some-random-classifier"
46
+ print(results.params.classifier_name) # some-random-classifier
47
+ print(
48
+ results.params["classifier-name"]
49
+ == results.params["classifier-name"]
50
+ == results.params.classifier_name
51
+ ) # True