hunterMakesPy 0.4.8__tar.gz → 0.5.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.
Files changed (127) hide show
  1. huntermakespy-0.5.1/PKG-INFO +289 -0
  2. huntermakespy-0.5.1/README.md +242 -0
  3. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/dicttoolz.c +509 -509
  4. huntermakespy-0.5.1/humpy_cytoolz/dicttoolz.pyi +126 -0
  5. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/dicttoolz.pyx +22 -16
  6. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_dicttoolz.py +96 -34
  7. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/dicttoolz.py +488 -486
  8. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/functoolz.py +28 -31
  9. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/itertoolz.py +43 -43
  10. huntermakespy-0.5.1/humpy_toolz/tests/test_dicttoolz.py +1077 -0
  11. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/dataStructures.py +2 -2
  12. huntermakespy-0.5.1/hunterMakesPy.egg-info/PKG-INFO +289 -0
  13. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy.egg-info/requires.txt +2 -1
  14. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/pyproject.toml +13 -2
  15. huntermakespy-0.4.8/PKG-INFO +0 -125
  16. huntermakespy-0.4.8/README.md +0 -79
  17. huntermakespy-0.4.8/humpy_cytoolz/dicttoolz.pyi +0 -339
  18. huntermakespy-0.4.8/humpy_toolz/tests/test_dicttoolz.py +0 -685
  19. huntermakespy-0.4.8/hunterMakesPy.egg-info/PKG-INFO +0 -125
  20. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/LICENSE +0 -0
  21. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/Notice_of_Copyright.txt +0 -0
  22. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/__init__.pxd +0 -0
  23. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/__init__.py +0 -0
  24. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/__init__.pyi +0 -0
  25. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/_signatures.py +0 -0
  26. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/_signatures.pyi +0 -0
  27. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/cpython.pxd +0 -0
  28. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/curried/__init__.py +0 -0
  29. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/curried/exceptions.py +0 -0
  30. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/curried/exceptions.pyi +0 -0
  31. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/curried/operator.py +0 -0
  32. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/dicttoolz.pxd +0 -0
  33. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/functoolz.c +0 -0
  34. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/functoolz.pxd +0 -0
  35. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/functoolz.pyi +0 -0
  36. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/functoolz.pyx +0 -0
  37. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/itertoolz.c +0 -0
  38. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/itertoolz.pxd +0 -0
  39. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/itertoolz.pyi +0 -0
  40. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/itertoolz.pyx +0 -0
  41. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/py.typed +0 -0
  42. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/recipes.c +0 -0
  43. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/recipes.pxd +0 -0
  44. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/recipes.pyi +0 -0
  45. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/recipes.pyx +0 -0
  46. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/__init__.py +0 -0
  47. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/dev_skip_test.py +0 -0
  48. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_curried.py +0 -0
  49. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_curried_toolzlike.py +0 -0
  50. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_dev_skip_test.py +0 -0
  51. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_docstrings.py +0 -0
  52. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_doctests.py +0 -0
  53. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_embedded_sigs.py +0 -0
  54. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_functoolz.py +0 -0
  55. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_inspect_args.py +0 -0
  56. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_itertoolz.py +0 -0
  57. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_none_safe.py +0 -0
  58. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_recipes.py +0 -0
  59. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_serialization.py +0 -0
  60. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_signatures.py +0 -0
  61. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_stubs.py +0 -0
  62. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_tlz.py +0 -0
  63. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/tests/test_utils.py +0 -0
  64. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/utils.c +0 -0
  65. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/utils.pxd +0 -0
  66. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/utils.pyi +0 -0
  67. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_cytoolz/utils.pyx +0 -0
  68. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_tlz/__init__.py +0 -0
  69. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_tlz/_build_tlz.py +0 -0
  70. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/Notice_of_Copyright.txt +0 -0
  71. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/__init__.py +0 -0
  72. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/__init__.pyi +0 -0
  73. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/_signatures.py +0 -0
  74. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/__init__.py +0 -0
  75. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/__init__.pyi +0 -0
  76. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/exceptions.py +0 -0
  77. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/exceptions.pyi +0 -0
  78. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/operator.py +0 -0
  79. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/curried/operator.pyi +0 -0
  80. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/functoolz.pyi +0 -0
  81. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/itertoolz.pyi +0 -0
  82. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/py.typed +0 -0
  83. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/recipes.py +0 -0
  84. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/recipes.pyi +0 -0
  85. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/__init__.py +0 -0
  86. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/__init__.pyi +0 -0
  87. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/core.py +0 -0
  88. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/core.pyi +0 -0
  89. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/parallel.py +0 -0
  90. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/parallel.pyi +0 -0
  91. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/tests/__init__.py +0 -0
  92. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/tests/test_core.py +0 -0
  93. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/sandbox/tests/test_parallel.py +0 -0
  94. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/__init__.py +0 -0
  95. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_curried.py +0 -0
  96. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_curried_doctests.py +0 -0
  97. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_functoolz.py +0 -0
  98. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_inspect_args.py +0 -0
  99. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_itertoolz.py +0 -0
  100. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_package.py +0 -0
  101. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_recipes.py +0 -0
  102. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_serialization.py +0 -0
  103. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_signatures.py +0 -0
  104. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_tlz.py +0 -0
  105. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/tests/test_utils.py +0 -0
  106. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/utils.py +0 -0
  107. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/humpy_toolz/utils.pyi +0 -0
  108. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/__init__.py +0 -0
  109. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/_theSSOT.py +0 -0
  110. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/coping.py +0 -0
  111. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/filesystemToolkit.py +0 -0
  112. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/parseParameters.py +0 -0
  113. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/py.typed +0 -0
  114. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/semiotics.py +0 -0
  115. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/__init__.py +0 -0
  116. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/conftest.py +0 -0
  117. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/test_coping.py +0 -0
  118. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/test_dataStructures.py +0 -0
  119. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/test_filesystemToolkit.py +0 -0
  120. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/test_parseParameters.py +0 -0
  121. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/tests/test_theTypes.py +0 -0
  122. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/theTypes.py +0 -0
  123. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy/theTypesCallableFunction.py +0 -0
  124. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy.egg-info/SOURCES.txt +0 -0
  125. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy.egg-info/dependency_links.txt +0 -0
  126. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/hunterMakesPy.egg-info/top_level.txt +0 -0
  127. {huntermakespy-0.4.8 → huntermakespy-0.5.1}/setup.cfg +0 -0
@@ -0,0 +1,289 @@
1
+ Metadata-Version: 2.4
2
+ Name: hunterMakesPy
3
+ Version: 0.5.1
4
+ Summary: Easy Python functions making making functional Python functions easier.
5
+ Author-email: Hunter Hogan <HunterHogan@pm.me>
6
+ License-Expression: CC-BY-NC-4.0
7
+ Project-URL: Donate, https://www.patreon.com/integrated
8
+ Project-URL: Homepage, https://github.com/hunterhogan/hunterMakesPy
9
+ Project-URL: Issues, https://github.com/hunterhogan/hunterMakesPy/issues
10
+ Project-URL: Repository, https://github.com/hunterhogan/hunterMakesPy
11
+ Keywords: attribute loading,concurrency limit,configuration,cytoolz,defensive programming,dictionary merging,directory creation,dynamic import,error propagation,file system utilities,input validation,integer parsing,module loading,nested data structures,package settings,parameter validation,pytest,string extraction,test utilities,toolz
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Framework :: Pytest
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Intended Audience :: Other Audience
18
+ Classifier: Natural Language :: English
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: Utilities
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.12
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: autoflake
33
+ Requires-Dist: charset_normalizer
34
+ Requires-Dist: isort
35
+ Requires-Dist: more_itertools
36
+ Requires-Dist: numpy
37
+ Requires-Dist: typing_extensions>=4.10.0
38
+ Provides-Extra: development
39
+ Requires-Dist: astToolkit; extra == "development"
40
+ Requires-Dist: setuptools>=62.3; extra == "development"
41
+ Requires-Dist: pytest-cov; extra == "development"
42
+ Provides-Extra: testing
43
+ Requires-Dist: cython; extra == "testing"
44
+ Requires-Dist: pytest; extra == "testing"
45
+ Requires-Dist: pytest-xdist; extra == "testing"
46
+ Dynamic: license-file
47
+
48
+ # hunterMakesPy
49
+
50
+ Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data. Also includes `humpy_toolz`, `humpy_cytoolz`, and `humpy_tlz`: typed forks of `toolz` and `cytoolz` with curried namespaces and a sandbox.
51
+
52
+ [![pip install hunterMakesPy](https://img.shields.io/badge/pip%20install-hunterMakesPy-gray.svg?colorB=3b434b)](https://pypi.org/project/hunterMakesPy/)
53
+
54
+ ## Validate, Convert, and Parse Inputs
55
+
56
+ ### Convert Mixed Input to Validated Integers
57
+
58
+ Accepts strings, floats, complex numbers, and binary data and returns a list of validated integers. Ambiguous or incompatible values produce descriptive errors.
59
+
60
+ ```python
61
+ from hunterMakesPy.parseParameters import intInnit
62
+
63
+ ports = intInnit(["8080", 443, "22"], "server_ports")
64
+ # Returns: [8080, 443, 22]
65
+ ```
66
+
67
+ ### Calculate Concurrency Limits from Flexible Specifications
68
+
69
+ Pass `0.75` for 75% of CPUs, `True` for 1 CPU, `4` for exactly 4 CPUs, or `-2` to reserve 2 CPUs.
70
+
71
+ ```python
72
+ from hunterMakesPy.parseParameters import defineConcurrencyLimit
73
+
74
+ workers = defineConcurrencyLimit(limit=0.75) # 6 on an 8-core machine
75
+ ```
76
+
77
+ ### Interpret Strings as Boolean or None
78
+
79
+ Parse string values such as `"true"`, `"false"`, or `"none"` into their Python equivalents without raising exceptions on mismatch.
80
+
81
+ ```python
82
+ from hunterMakesPy.parseParameters import oopsieKwargsie
83
+
84
+ oopsieKwargsie("True") # Returns: True
85
+ oopsieKwargsie("none") # Returns: None
86
+ oopsieKwargsie("hello") # Returns: "hello"
87
+ ```
88
+
89
+ ## Eliminate None with Runtime Validation
90
+
91
+ Convert `Type | None` return annotations to `Type` by raising at runtime if the value is `None`. Removes `None`-checking noise from downstream code and satisfies type checkers.
92
+
93
+ ```python
94
+ from hunterMakesPy import raiseIfNone
95
+
96
+ config = raiseIfNone(getConfig(), "Missing configuration")
97
+ ```
98
+
99
+ ## Replace Ambiguous Numeric Literals with Semantic Names
100
+
101
+ Use `decreasing` instead of `-1`, `inclusive` for boundary adjustments, and `zeroIndexed` for index conversions. Intent becomes explicit and the code reads as prose.
102
+
103
+ ```python
104
+ from hunterMakesPy import decreasing, inclusive, zeroIndexed
105
+
106
+ rangeEnd = lengthSequence + inclusive
107
+ indexLast = lengthSequence - zeroIndexed
108
+ step = decreasing
109
+ ```
110
+
111
+ ## Import Modules by Dot-Notation Path or File Path
112
+
113
+ Load functions or classes from `"scipy.signal.windows"` or `"path/to/file.py"` without manual module-loading boilerplate.
114
+
115
+ ```python
116
+ from hunterMakesPy.filesystemToolkit import importLogicalPath2Identifier
117
+
118
+ windowFunction = importLogicalPath2Identifier("scipy.signal.windows", "hann")
119
+ ```
120
+
121
+ ## Create Directories Safely and Write Files with Formatting
122
+
123
+ Write to `"deep/nested/path/file.txt"` and parent directories are created automatically. `writePython` removes unused imports and sorts import statements before writing.
124
+
125
+ ```python
126
+ from hunterMakesPy.filesystemToolkit import writeStringToHere, writePython
127
+
128
+ writeStringToHere("content", "nested/dirs/file.txt") # Creates dirs
129
+ writePython(sourceCode, "output/module.py") # Formats, then writes
130
+ ```
131
+
132
+ ## Extract Strings from Arbitrarily Nested Data
133
+
134
+ Recursively traverse dictionaries, lists, tuples, and sets and collect every string value into a flat list.
135
+
136
+ ```python
137
+ from hunterMakesPy.dataStructures import stringItUp
138
+
139
+ strings = stringItUp({"users": ["alice"], "config": {"host": "localhost"}})
140
+ # Returns: ["users", "alice", "config", "host", "localhost"]
141
+ ```
142
+
143
+ ## Merge Dictionaries with List Values
144
+
145
+ Combine `{"a": [1, 2]}` and `{"a": [3], "b": [4]}` into `{"a": [1, 2, 3], "b": [4]}` with optional deduplication and sorting.
146
+
147
+ ```python
148
+ from hunterMakesPy.dataStructures import updateExtendPolishDictionaryLists
149
+
150
+ merged = updateExtendPolishDictionaryLists(
151
+ {"servers": ["chicago"]},
152
+ {"servers": ["tokyo", "chicago"]},
153
+ destroyDuplicates=True,
154
+ )
155
+ # Returns: {"servers": ["chicago", "tokyo"]}
156
+ ```
157
+
158
+ ## Compress NumPy Arrays to Self-Decoding Strings
159
+
160
+ Encode repetitive patterns and consecutive sequences using run-length encoding and Python `range` syntax. The resulting string evaluates back to the original data.
161
+
162
+ ```python
163
+ from hunterMakesPy.dataStructures import autoDecodingRLE
164
+
165
+ encoded = autoDecodingRLE(arrayTarget)
166
+ ```
167
+
168
+ ## Configure Package Metadata at Runtime
169
+
170
+ `PackageSettings` reads `pyproject.toml` automatically to resolve the package name and installation path.
171
+
172
+ ```python
173
+ from hunterMakesPy import PackageSettings
174
+
175
+ settings = PackageSettings(identifierPackageFALLBACK="myPackage")
176
+ ```
177
+
178
+ ## Reuse Test Suites for Custom Implementations
179
+
180
+ Import parameterized test generators to validate custom functions that match the expected signatures.
181
+
182
+ ```python
183
+ from hunterMakesPy.tests.test_parseParameters import PytestFor_intInnit
184
+
185
+ @pytest.mark.parametrize("test_name,test_func", PytestFor_intInnit(myFunction))
186
+ def test_my_integer_validator(test_name, test_func):
187
+ test_func()
188
+ ```
189
+
190
+ ---
191
+
192
+ ## `humpy_toolz`: Typed Pure-Python Functional Utilities
193
+
194
+ `humpy_toolz` is a typed fork of [`toolz`](https://github.com/pytoolz/toolz). It provides composable functions for iterators, dictionaries, and function composition with full type stubs and docstrings.
195
+
196
+ ### Dictionary Transformations without Mutation
197
+
198
+ Create new mappings by associating, dissociating, filtering, and mapping over keys or values. Nested access is supported through key-path sequences.
199
+
200
+ ```python
201
+ from humpy_toolz import merge, valmap, keyfilter, assoc
202
+
203
+ merged = merge({"a": 1}, {"b": 2}) # {"a": 1, "b": 2}
204
+ doubled = valmap(lambda x: x * 2, {"a": 1}) # {"a": 2}
205
+ evens = keyfilter(lambda k: k > 1, {1: "a", 2: "b"}) # {2: "b"}
206
+ updated = assoc({"x": 10}, "y", 20) # {"x": 10, "y": 20}
207
+ ```
208
+
209
+ ### Compose, Curry, and Thread Functions
210
+
211
+ Build transformation sequences from left or right, partially apply arguments with `curry`, and thread a value through a series of functions.
212
+
213
+ ```python
214
+ from humpy_toolz import compose_left, curry, pipe
215
+
216
+ increment = lambda x: x + 1
217
+ double = lambda x: x * 2
218
+ transform = compose_left(increment, double)
219
+ transform(3) # 8
220
+
221
+ pipe(3, increment, double) # 8
222
+ ```
223
+
224
+ ### Slice, Group, and Deduplicate Iterators
225
+
226
+ Lazy operations over iterables: `take`, `drop`, `partition`, `sliding_window`, `unique`, `interleave`, `groupby`, `frequencies`, and more.
227
+
228
+ ```python
229
+ from humpy_toolz import take, frequencies, groupby, unique
230
+
231
+ list(take(3, range(100))) # [0, 1, 2]
232
+ frequencies(["a", "b", "a", "c"]) # {"a": 2, "b": 1, "c": 1}
233
+ groupby(len, ["cat", "mouse", "dog"]) # {3: ["cat", "dog"], 5: ["mouse"]}
234
+ list(unique([1, 2, 1, 3])) # [1, 2, 3]
235
+ ```
236
+
237
+ ### Curried Namespace for Partial Application
238
+
239
+ Every function in `humpy_toolz.curried` accepts partial arguments and returns a new callable waiting for the rest.
240
+
241
+ ```python
242
+ from humpy_toolz.curried import map, filter, get
243
+
244
+ list(map(str.upper, ["hello", "world"])) # ["HELLO", "WORLD"]
245
+ list(filter(lambda x: x > 2, [1, 2, 3, 4])) # [3, 4]
246
+ list(map(get(0), [(1, 2), (3, 4)])) # [1, 3]
247
+ ```
248
+
249
+ ### Sandbox: Parallel Fold and Equality-Based Hashing
250
+
251
+ `humpy_toolz.sandbox` provides `fold` for unordered parallel reductions and `EqualityHashKey` for hashing otherwise-unhashable types.
252
+
253
+ ```python
254
+ from humpy_toolz.sandbox import fold, EqualityHashKey
255
+ from operator import add
256
+
257
+ fold(add, range(100), default=0) # 4950
258
+ ```
259
+
260
+ ---
261
+
262
+ ## `humpy_cytoolz`: Cython-Accelerated Functional Utilities
263
+
264
+ `humpy_cytoolz` is a typed fork of [`cytoolz`](https://github.com/pytoolz/cytoolz). It exposes the same API as `humpy_toolz` but the core modules (`dicttoolz`, `functoolz`, `itertoolz`, `recipes`, `utils`) are compiled as Cython extension modules for lower overhead on hot paths.
265
+
266
+ ```python
267
+ from humpy_cytoolz import groupby, curry, merge
268
+ ```
269
+
270
+ Install with the `cython` build dependency to compile the extensions. If compilation is unavailable, use `humpy_toolz` directly.
271
+
272
+ ---
273
+
274
+ ## `humpy_tlz`: Automatic Cython-or-Pure Dispatch
275
+
276
+ `humpy_tlz` mirrors the `humpy_toolz` API and imports from `humpy_cytoolz` when available, falling back to `humpy_toolz` otherwise. Use `humpy_tlz` in library code so callers benefit from Cython acceleration without requiring it.
277
+
278
+ ```python
279
+ from humpy_tlz import pipe, curry, groupby
280
+ ```
281
+
282
+ ---
283
+
284
+ ## My recovery
285
+
286
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
287
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
288
+
289
+ [![CC-BY-NC-4.0](https://raw.githubusercontent.com/hunterhogan/hunterMakesPy/refs/heads/main/.github/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -0,0 +1,242 @@
1
+ # hunterMakesPy
2
+
3
+ Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data. Also includes `humpy_toolz`, `humpy_cytoolz`, and `humpy_tlz`: typed forks of `toolz` and `cytoolz` with curried namespaces and a sandbox.
4
+
5
+ [![pip install hunterMakesPy](https://img.shields.io/badge/pip%20install-hunterMakesPy-gray.svg?colorB=3b434b)](https://pypi.org/project/hunterMakesPy/)
6
+
7
+ ## Validate, Convert, and Parse Inputs
8
+
9
+ ### Convert Mixed Input to Validated Integers
10
+
11
+ Accepts strings, floats, complex numbers, and binary data and returns a list of validated integers. Ambiguous or incompatible values produce descriptive errors.
12
+
13
+ ```python
14
+ from hunterMakesPy.parseParameters import intInnit
15
+
16
+ ports = intInnit(["8080", 443, "22"], "server_ports")
17
+ # Returns: [8080, 443, 22]
18
+ ```
19
+
20
+ ### Calculate Concurrency Limits from Flexible Specifications
21
+
22
+ Pass `0.75` for 75% of CPUs, `True` for 1 CPU, `4` for exactly 4 CPUs, or `-2` to reserve 2 CPUs.
23
+
24
+ ```python
25
+ from hunterMakesPy.parseParameters import defineConcurrencyLimit
26
+
27
+ workers = defineConcurrencyLimit(limit=0.75) # 6 on an 8-core machine
28
+ ```
29
+
30
+ ### Interpret Strings as Boolean or None
31
+
32
+ Parse string values such as `"true"`, `"false"`, or `"none"` into their Python equivalents without raising exceptions on mismatch.
33
+
34
+ ```python
35
+ from hunterMakesPy.parseParameters import oopsieKwargsie
36
+
37
+ oopsieKwargsie("True") # Returns: True
38
+ oopsieKwargsie("none") # Returns: None
39
+ oopsieKwargsie("hello") # Returns: "hello"
40
+ ```
41
+
42
+ ## Eliminate None with Runtime Validation
43
+
44
+ Convert `Type | None` return annotations to `Type` by raising at runtime if the value is `None`. Removes `None`-checking noise from downstream code and satisfies type checkers.
45
+
46
+ ```python
47
+ from hunterMakesPy import raiseIfNone
48
+
49
+ config = raiseIfNone(getConfig(), "Missing configuration")
50
+ ```
51
+
52
+ ## Replace Ambiguous Numeric Literals with Semantic Names
53
+
54
+ Use `decreasing` instead of `-1`, `inclusive` for boundary adjustments, and `zeroIndexed` for index conversions. Intent becomes explicit and the code reads as prose.
55
+
56
+ ```python
57
+ from hunterMakesPy import decreasing, inclusive, zeroIndexed
58
+
59
+ rangeEnd = lengthSequence + inclusive
60
+ indexLast = lengthSequence - zeroIndexed
61
+ step = decreasing
62
+ ```
63
+
64
+ ## Import Modules by Dot-Notation Path or File Path
65
+
66
+ Load functions or classes from `"scipy.signal.windows"` or `"path/to/file.py"` without manual module-loading boilerplate.
67
+
68
+ ```python
69
+ from hunterMakesPy.filesystemToolkit import importLogicalPath2Identifier
70
+
71
+ windowFunction = importLogicalPath2Identifier("scipy.signal.windows", "hann")
72
+ ```
73
+
74
+ ## Create Directories Safely and Write Files with Formatting
75
+
76
+ Write to `"deep/nested/path/file.txt"` and parent directories are created automatically. `writePython` removes unused imports and sorts import statements before writing.
77
+
78
+ ```python
79
+ from hunterMakesPy.filesystemToolkit import writeStringToHere, writePython
80
+
81
+ writeStringToHere("content", "nested/dirs/file.txt") # Creates dirs
82
+ writePython(sourceCode, "output/module.py") # Formats, then writes
83
+ ```
84
+
85
+ ## Extract Strings from Arbitrarily Nested Data
86
+
87
+ Recursively traverse dictionaries, lists, tuples, and sets and collect every string value into a flat list.
88
+
89
+ ```python
90
+ from hunterMakesPy.dataStructures import stringItUp
91
+
92
+ strings = stringItUp({"users": ["alice"], "config": {"host": "localhost"}})
93
+ # Returns: ["users", "alice", "config", "host", "localhost"]
94
+ ```
95
+
96
+ ## Merge Dictionaries with List Values
97
+
98
+ Combine `{"a": [1, 2]}` and `{"a": [3], "b": [4]}` into `{"a": [1, 2, 3], "b": [4]}` with optional deduplication and sorting.
99
+
100
+ ```python
101
+ from hunterMakesPy.dataStructures import updateExtendPolishDictionaryLists
102
+
103
+ merged = updateExtendPolishDictionaryLists(
104
+ {"servers": ["chicago"]},
105
+ {"servers": ["tokyo", "chicago"]},
106
+ destroyDuplicates=True,
107
+ )
108
+ # Returns: {"servers": ["chicago", "tokyo"]}
109
+ ```
110
+
111
+ ## Compress NumPy Arrays to Self-Decoding Strings
112
+
113
+ Encode repetitive patterns and consecutive sequences using run-length encoding and Python `range` syntax. The resulting string evaluates back to the original data.
114
+
115
+ ```python
116
+ from hunterMakesPy.dataStructures import autoDecodingRLE
117
+
118
+ encoded = autoDecodingRLE(arrayTarget)
119
+ ```
120
+
121
+ ## Configure Package Metadata at Runtime
122
+
123
+ `PackageSettings` reads `pyproject.toml` automatically to resolve the package name and installation path.
124
+
125
+ ```python
126
+ from hunterMakesPy import PackageSettings
127
+
128
+ settings = PackageSettings(identifierPackageFALLBACK="myPackage")
129
+ ```
130
+
131
+ ## Reuse Test Suites for Custom Implementations
132
+
133
+ Import parameterized test generators to validate custom functions that match the expected signatures.
134
+
135
+ ```python
136
+ from hunterMakesPy.tests.test_parseParameters import PytestFor_intInnit
137
+
138
+ @pytest.mark.parametrize("test_name,test_func", PytestFor_intInnit(myFunction))
139
+ def test_my_integer_validator(test_name, test_func):
140
+ test_func()
141
+ ```
142
+
143
+ ---
144
+
145
+ ## `humpy_toolz`: Typed Pure-Python Functional Utilities
146
+
147
+ `humpy_toolz` is a typed fork of [`toolz`](https://github.com/pytoolz/toolz). It provides composable functions for iterators, dictionaries, and function composition with full type stubs and docstrings.
148
+
149
+ ### Dictionary Transformations without Mutation
150
+
151
+ Create new mappings by associating, dissociating, filtering, and mapping over keys or values. Nested access is supported through key-path sequences.
152
+
153
+ ```python
154
+ from humpy_toolz import merge, valmap, keyfilter, assoc
155
+
156
+ merged = merge({"a": 1}, {"b": 2}) # {"a": 1, "b": 2}
157
+ doubled = valmap(lambda x: x * 2, {"a": 1}) # {"a": 2}
158
+ evens = keyfilter(lambda k: k > 1, {1: "a", 2: "b"}) # {2: "b"}
159
+ updated = assoc({"x": 10}, "y", 20) # {"x": 10, "y": 20}
160
+ ```
161
+
162
+ ### Compose, Curry, and Thread Functions
163
+
164
+ Build transformation sequences from left or right, partially apply arguments with `curry`, and thread a value through a series of functions.
165
+
166
+ ```python
167
+ from humpy_toolz import compose_left, curry, pipe
168
+
169
+ increment = lambda x: x + 1
170
+ double = lambda x: x * 2
171
+ transform = compose_left(increment, double)
172
+ transform(3) # 8
173
+
174
+ pipe(3, increment, double) # 8
175
+ ```
176
+
177
+ ### Slice, Group, and Deduplicate Iterators
178
+
179
+ Lazy operations over iterables: `take`, `drop`, `partition`, `sliding_window`, `unique`, `interleave`, `groupby`, `frequencies`, and more.
180
+
181
+ ```python
182
+ from humpy_toolz import take, frequencies, groupby, unique
183
+
184
+ list(take(3, range(100))) # [0, 1, 2]
185
+ frequencies(["a", "b", "a", "c"]) # {"a": 2, "b": 1, "c": 1}
186
+ groupby(len, ["cat", "mouse", "dog"]) # {3: ["cat", "dog"], 5: ["mouse"]}
187
+ list(unique([1, 2, 1, 3])) # [1, 2, 3]
188
+ ```
189
+
190
+ ### Curried Namespace for Partial Application
191
+
192
+ Every function in `humpy_toolz.curried` accepts partial arguments and returns a new callable waiting for the rest.
193
+
194
+ ```python
195
+ from humpy_toolz.curried import map, filter, get
196
+
197
+ list(map(str.upper, ["hello", "world"])) # ["HELLO", "WORLD"]
198
+ list(filter(lambda x: x > 2, [1, 2, 3, 4])) # [3, 4]
199
+ list(map(get(0), [(1, 2), (3, 4)])) # [1, 3]
200
+ ```
201
+
202
+ ### Sandbox: Parallel Fold and Equality-Based Hashing
203
+
204
+ `humpy_toolz.sandbox` provides `fold` for unordered parallel reductions and `EqualityHashKey` for hashing otherwise-unhashable types.
205
+
206
+ ```python
207
+ from humpy_toolz.sandbox import fold, EqualityHashKey
208
+ from operator import add
209
+
210
+ fold(add, range(100), default=0) # 4950
211
+ ```
212
+
213
+ ---
214
+
215
+ ## `humpy_cytoolz`: Cython-Accelerated Functional Utilities
216
+
217
+ `humpy_cytoolz` is a typed fork of [`cytoolz`](https://github.com/pytoolz/cytoolz). It exposes the same API as `humpy_toolz` but the core modules (`dicttoolz`, `functoolz`, `itertoolz`, `recipes`, `utils`) are compiled as Cython extension modules for lower overhead on hot paths.
218
+
219
+ ```python
220
+ from humpy_cytoolz import groupby, curry, merge
221
+ ```
222
+
223
+ Install with the `cython` build dependency to compile the extensions. If compilation is unavailable, use `humpy_toolz` directly.
224
+
225
+ ---
226
+
227
+ ## `humpy_tlz`: Automatic Cython-or-Pure Dispatch
228
+
229
+ `humpy_tlz` mirrors the `humpy_toolz` API and imports from `humpy_cytoolz` when available, falling back to `humpy_toolz` otherwise. Use `humpy_tlz` in library code so callers benefit from Cython acceleration without requiring it.
230
+
231
+ ```python
232
+ from humpy_tlz import pipe, curry, groupby
233
+ ```
234
+
235
+ ---
236
+
237
+ ## My recovery
238
+
239
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
240
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
241
+
242
+ [![CC-BY-NC-4.0](https://raw.githubusercontent.com/hunterhogan/hunterMakesPy/refs/heads/main/.github/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)