mapFolding 0.12.1__py3-none-any.whl → 0.12.3__py3-none-any.whl
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.
- mapFolding/__init__.py +46 -20
- mapFolding/_theSSOT.py +81 -0
- mapFolding/_theTypes.py +148 -0
- mapFolding/basecamp.py +62 -47
- mapFolding/beDRY.py +100 -73
- mapFolding/dataBaskets.py +226 -31
- mapFolding/filesystemToolkit.py +161 -107
- mapFolding/oeis.py +388 -174
- mapFolding/reference/flattened.py +1 -1
- mapFolding/someAssemblyRequired/RecipeJob.py +146 -20
- mapFolding/someAssemblyRequired/__init__.py +60 -38
- mapFolding/someAssemblyRequired/_toolIfThis.py +125 -35
- mapFolding/someAssemblyRequired/_toolkitContainers.py +125 -44
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py +35 -26
- mapFolding/someAssemblyRequired/infoBooth.py +37 -2
- mapFolding/someAssemblyRequired/makeAllModules.py +785 -0
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +161 -74
- mapFolding/someAssemblyRequired/toolkitNumba.py +218 -36
- mapFolding/someAssemblyRequired/transformationTools.py +125 -58
- mapfolding-0.12.3.dist-info/METADATA +163 -0
- mapfolding-0.12.3.dist-info/RECORD +53 -0
- {mapfolding-0.12.1.dist-info → mapfolding-0.12.3.dist-info}/WHEEL +1 -1
- tests/__init__.py +28 -44
- tests/conftest.py +66 -61
- tests/test_computations.py +64 -89
- tests/test_filesystem.py +25 -1
- tests/test_oeis.py +37 -7
- tests/test_other.py +29 -2
- tests/test_tasks.py +30 -2
- mapFolding/datatypes.py +0 -18
- mapFolding/someAssemblyRequired/Z0Z_makeAllModules.py +0 -433
- mapFolding/theSSOT.py +0 -34
- mapfolding-0.12.1.dist-info/METADATA +0 -184
- mapfolding-0.12.1.dist-info/RECORD +0 -53
- {mapfolding-0.12.1.dist-info → mapfolding-0.12.3.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.12.1.dist-info → mapfolding-0.12.3.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.12.1.dist-info → mapfolding-0.12.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mapFolding
|
|
3
|
+
Version: 0.12.3
|
|
4
|
+
Summary: Map folding algorithm with code transformation framework for optimizing numerical computations.
|
|
5
|
+
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
|
+
License: CC-BY-NC-4.0
|
|
7
|
+
Project-URL: Donate, https://www.patreon.com/integrated
|
|
8
|
+
Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
|
|
9
|
+
Project-URL: Issues, https://github.com/hunterhogan/mapFolding/issues
|
|
10
|
+
Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
|
|
11
|
+
Keywords: A000136,A001415,A001416,A001417,A001418,A195646,AST manipulation,Numba optimization,OEIS,algorithmic optimization,code generation,code transformation,combinatorics,computational geometry,dataclass transformation,folding pattern enumeration,just-in-time compilation,map folding,performance optimization,source code analysis,stamp folding
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
25
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
26
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Typing :: Typed
|
|
29
|
+
Requires-Python: >=3.12
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: astToolkit>=0.5.0
|
|
33
|
+
Requires-Dist: hunterMakesPy
|
|
34
|
+
Requires-Dist: numba
|
|
35
|
+
Requires-Dist: numba_progress
|
|
36
|
+
Requires-Dist: numpy
|
|
37
|
+
Requires-Dist: platformdirs
|
|
38
|
+
Provides-Extra: development
|
|
39
|
+
Requires-Dist: mypy; extra == "development"
|
|
40
|
+
Requires-Dist: pyupgrade; extra == "development"
|
|
41
|
+
Requires-Dist: setuptools-scm; extra == "development"
|
|
42
|
+
Provides-Extra: testing
|
|
43
|
+
Requires-Dist: pytest; extra == "testing"
|
|
44
|
+
Requires-Dist: pytest-cov; extra == "testing"
|
|
45
|
+
Requires-Dist: pytest-env; extra == "testing"
|
|
46
|
+
Requires-Dist: pytest-xdist; extra == "testing"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# mapFolding
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/mapFolding/)
|
|
52
|
+
[](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml)
|
|
53
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
54
|
+
|
|
55
|
+
A computational framework that starts with Lunnon's 1971 algorithm for counting distinct ways to fold maps and improves it. Plus there is a comprehensive AST transformation system for transforming algorithms for optimization and research.
|
|
56
|
+
|
|
57
|
+
(Yo, the rest is AI generated and I don't have the energy to proofread it. This package helped me compute two previously unknown values: I'm sure others can improve it.)
|
|
58
|
+
|
|
59
|
+
## The Mathematical Problem
|
|
60
|
+
|
|
61
|
+
Map folding is a combinatorial problem: given a rectangular grid of unit squares, how many distinct ways can you fold it? "Distinct" means that foldings producing identical final shapes are counted as one. This problem connects to combinatorial geometry, integer sequences, and computational complexity theory.
|
|
62
|
+
|
|
63
|
+
The calculations extend the Online Encyclopedia of Integer Sequences (OEIS):
|
|
64
|
+
|
|
65
|
+
- **A001415**: 2×n strips (computed through n=20 for the first time)
|
|
66
|
+
- **A001418**: n×n squares
|
|
67
|
+
- **A001416**: 3×n strips
|
|
68
|
+
- **A001417**: n-dimensional hypercubes
|
|
69
|
+
- **A195646**: 3×3×...×3 hypercubes
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from mapFolding import oeisIDfor_n
|
|
73
|
+
|
|
74
|
+
# How many ways can you fold a 2×4 strip?
|
|
75
|
+
foldsTotal = oeisIDfor_n('A001415', 4)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## The Computational Challenge
|
|
79
|
+
|
|
80
|
+
For larger maps, these calculations require hours or days to complete. A 2×20 strip requires processing leaves through billions of recursive operations. The package addresses this through systematic algorithm transformation: converting readable Python implementations into specialized, Numba-optimized modules that achieve order-of-magnitude performance improvements.
|
|
81
|
+
|
|
82
|
+
## What This Package Provides
|
|
83
|
+
|
|
84
|
+
### Core Functionality
|
|
85
|
+
|
|
86
|
+
- **Complete implementation** of Lunnon's recursive algorithm
|
|
87
|
+
- **Mathematical validation** through OEIS integration and caching
|
|
88
|
+
- **Type-safe computational state** management with automatic initialization
|
|
89
|
+
- **Result persistence** for long-running calculations
|
|
90
|
+
|
|
91
|
+
### Algorithm Transformation System
|
|
92
|
+
|
|
93
|
+
- **AST manipulation framework** for converting dataclass-based algorithms to optimized implementations
|
|
94
|
+
- **Automatic code generation** that produces standalone, highly optimized computation modules
|
|
95
|
+
- **Dataclass decomposition** to enable Numba compatibility while preserving readable source code
|
|
96
|
+
- **Comprehensive optimization** including dead code elimination, static value embedding, and aggressive compilation settings
|
|
97
|
+
|
|
98
|
+
### Educational Resources
|
|
99
|
+
|
|
100
|
+
- **Historical implementations** showing algorithm evolution from 1971 to present
|
|
101
|
+
- **Performance comparison** studies demonstrating optimization techniques
|
|
102
|
+
- **Complete test suite** with patterns for validating custom implementations
|
|
103
|
+
- **Reference documentation** for extending the transformation framework
|
|
104
|
+
|
|
105
|
+
## Use Cases
|
|
106
|
+
|
|
107
|
+
**Mathematical Research**: Explore folding pattern properties, extend known sequences, or validate theoretical results against computed values.
|
|
108
|
+
|
|
109
|
+
**Algorithm Optimization Learning**: Study a complete transformation pipeline that converts high-level algorithms into production-ready optimized code.
|
|
110
|
+
|
|
111
|
+
**Performance Computing Education**: Examine techniques for achieving maximum Python performance through Numba integration, AST manipulation, and specialized code generation.
|
|
112
|
+
|
|
113
|
+
**Combinatorial Problem Solving**: Use the framework as a template for optimizing other recursive combinatorial algorithms.
|
|
114
|
+
|
|
115
|
+
## Example Usage
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from mapFolding import countFolds
|
|
119
|
+
|
|
120
|
+
# Count folding patterns for a 3×3 square
|
|
121
|
+
result = countFolds([3, 3])
|
|
122
|
+
|
|
123
|
+
# Access OEIS sequences directly
|
|
124
|
+
from mapFolding import oeisIDfor_n
|
|
125
|
+
strip_foldings = oeisIDfor_n('A001415', 6) # 2×6 strip
|
|
126
|
+
|
|
127
|
+
# Generate optimized code for specific dimensions
|
|
128
|
+
from mapFolding.someAssemblyRequired import makeJobTheorem2Numba
|
|
129
|
+
# Creates specialized modules for maximum performance
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Repository Structure
|
|
133
|
+
|
|
134
|
+
- `mapFolding/`: Core implementation with modular architecture
|
|
135
|
+
- `reference/`: Historical algorithm implementations and performance studies
|
|
136
|
+
- `someAssemblyRequired/`: AST transformation framework
|
|
137
|
+
- `tests/`: Comprehensive validation suite
|
|
138
|
+
- `jobs/`: Generated optimized modules for specific calculations
|
|
139
|
+
|
|
140
|
+
## Performance Characteristics
|
|
141
|
+
|
|
142
|
+
- **Pure Python baseline**: Educational implementations for understanding
|
|
143
|
+
- **NumPy optimization**: ~10× improvement through vectorized operations
|
|
144
|
+
- **Numba compilation**: ~100× improvement through native code generation
|
|
145
|
+
- **Specialized modules**: ~1000× improvement through static optimization and embedded constants
|
|
146
|
+
|
|
147
|
+
Actual performance varies by map dimensions and available hardware.
|
|
148
|
+
|
|
149
|
+
## My recovery
|
|
150
|
+
|
|
151
|
+
[](https://HunterThinks.com/support)
|
|
152
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
153
|
+
|
|
154
|
+
## How to code
|
|
155
|
+
|
|
156
|
+
Coding One Step at a Time:
|
|
157
|
+
|
|
158
|
+
0. WRITE CODE.
|
|
159
|
+
1. Don't write stupid code that's hard to revise.
|
|
160
|
+
2. Write good code.
|
|
161
|
+
3. When revising, write better code.
|
|
162
|
+
|
|
163
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
mapFolding/__init__.py,sha256=dl3HR2zoipFo0UstEJn3iWTkXlA_XeCQw_zfw2fk4qE,3643
|
|
2
|
+
mapFolding/_theSSOT.py,sha256=dloMAsIOhUnIE7-SFJbQYyl6IYo7CdCAyBZPqMuckko,3380
|
|
3
|
+
mapFolding/_theTypes.py,sha256=rT8UTm-I_haMQlUGaJ4yvqIMt6FUOvWH-VUYNud6UN4,5495
|
|
4
|
+
mapFolding/basecamp.py,sha256=VuX0hLrXkY-XEcV9trd4aSdzxTfUNMR6kTnYo8-6tJw,9474
|
|
5
|
+
mapFolding/beDRY.py,sha256=Iikg3U4zQjx6JOKL62R7Tb0CpOm3JkPSIewAByco9GA,14777
|
|
6
|
+
mapFolding/daoOfMapFolding.py,sha256=ncTIiBfTsM8SNVx9qefZ0bBcBtviWLSk4iPv3Z9nGiE,5442
|
|
7
|
+
mapFolding/dataBaskets.py,sha256=ch-8jVvZ57nJ52pB8N_u3Egz-56IfA2t8Ct0ba7SXOY,14252
|
|
8
|
+
mapFolding/filesystemToolkit.py,sha256=Ex5tyugRQurXIgUNVtkQYfWMq8fM4e-izX01MBXU5_8,11006
|
|
9
|
+
mapFolding/oeis.py,sha256=zw_Aua57-VAXbtS0soG_xfBR1PozmsYLQCoy_Vq5WAU,23026
|
|
10
|
+
mapFolding/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
mapFolding/reference/__init__.py,sha256=GKcSgYE49NcTISx-JZbELXyq-eRkMeTL5g4DXInWFw0,2206
|
|
12
|
+
mapFolding/reference/flattened.py,sha256=0eHgLFIeIeVUsI5zF5oSy5iWYrjOMzxr7KjDxiTe01k,16078
|
|
13
|
+
mapFolding/reference/hunterNumba.py,sha256=iLfyqwGdAh6c5GbapnKsWhAsNsR3O-fyGGHAdohluLw,7258
|
|
14
|
+
mapFolding/reference/irvineJavaPort.py,sha256=UEfIX4QbPLl5jnyfYIyX5YRR3_rYvPUikK8jLehsFko,4076
|
|
15
|
+
mapFolding/reference/jaxCount.py,sha256=TuDNKOnyhQfuixKmIxO9Algv7dvy7KMGhgsV3h96FGE,14853
|
|
16
|
+
mapFolding/reference/lunnonNumpy.py,sha256=mMgrgbrBpe4nmo72ThEI-MGH0OwEHmfMPczSXHp2qKo,4357
|
|
17
|
+
mapFolding/reference/lunnonWhile.py,sha256=ZL8GAQtPs5nJZSgoDl5USrLSS_zs03y98y1Z9E4jOmQ,3799
|
|
18
|
+
mapFolding/reference/rotatedEntryPoint.py,sha256=5ughpKUT2JQhoAKgoDUdYNjgWQYPGV8v-7dWEAdDmfE,10274
|
|
19
|
+
mapFolding/reference/total_countPlus1vsPlusN.py,sha256=yJZAVLVdoXqHag2_N6_6CT-Q6HXBgRro-eny93-Rlpw,9307
|
|
20
|
+
mapFolding/reference/jobsCompleted/__init__.py,sha256=TU93ZGUW1xEkT6d9mQFn_rp5DvRy0ZslEB2Q6MF5ZDc,2596
|
|
21
|
+
mapFolding/reference/jobsCompleted/[2x19]/p2x19.py,sha256=_tvYtfzMWVo2VtUbIAieoscb4N8FFflgTdW4-ljBUuA,19626
|
|
22
|
+
mapFolding/reference/jobsCompleted/p2x19/p2x19.py,sha256=eZEw4Me4ocTt6VXoK2-Sbd5SowZtxRIbN9dZmc7OCVg,6395
|
|
23
|
+
mapFolding/someAssemblyRequired/RecipeJob.py,sha256=Gi8H1z68rtl2PQShMb6D1JFug9S_edFxipWUuc0K1EQ,10949
|
|
24
|
+
mapFolding/someAssemblyRequired/__init__.py,sha256=UNDh6O86jT5ywlw9LgeWsUHwOfNvoMJRDAzYXbwCbeM,5779
|
|
25
|
+
mapFolding/someAssemblyRequired/_toolIfThis.py,sha256=VDZC10Xo3E1Y5n6FmaBBbOBR-rinV9DFkpgw8zrDyzg,6339
|
|
26
|
+
mapFolding/someAssemblyRequired/_toolkitContainers.py,sha256=ymqEWH5oO_gNjvRjpRELCzahXfU74fhHZspnv6GGLiE,13680
|
|
27
|
+
mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=tY0-2K0BFkwLAAjSrFJLPoG8CevDHOFc3OH3TxXANzg,2806
|
|
28
|
+
mapFolding/someAssemblyRequired/infoBooth.py,sha256=GWiqnHbqk7te_pvVuk4G_gbFa_W2aeSx19w4pakvqfM,2300
|
|
29
|
+
mapFolding/someAssemblyRequired/makeAllModules.py,sha256=E5d1YoP8wOGBCknyjR9uDx2xxHEp18UAjDPxIf6PeKg,44351
|
|
30
|
+
mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py,sha256=T3xopmCckvDJqdbEXL7IzQLYmfulp0EO5-kdpyjxWZs,19027
|
|
31
|
+
mapFolding/someAssemblyRequired/toolkitNumba.py,sha256=UNLFadfRl6sHCHVEGbCu4sCPpnLKVqMd1U5ULWcEyis,14855
|
|
32
|
+
mapFolding/someAssemblyRequired/transformationTools.py,sha256=nPGZsvb5GquaCCxdDh_XzNIZYSiVJpWKd7wfhfRvxnk,11512
|
|
33
|
+
mapFolding/syntheticModules/__init__.py,sha256=evVFqhCGa-WZKDiLcnQWjs-Bj34eRnfSLqz_d7dFYZY,83
|
|
34
|
+
mapFolding/syntheticModules/countParallel.py,sha256=OK_IB9w4yy9MMAiGvkei5ezPm_00v2nYjPrQZ_IlELg,7733
|
|
35
|
+
mapFolding/syntheticModules/daoOfMapFolding.py,sha256=cfWPABtXyCxJ0BwPI7rhfLh_2UYV_XKAL8lJ4GLNXaQ,5896
|
|
36
|
+
mapFolding/syntheticModules/dataPacking.py,sha256=m_eOZ7sMXIQ9jY5EvC3qgitQTY60n6rksy0ACMJOIC8,2292
|
|
37
|
+
mapFolding/syntheticModules/initializeCount.py,sha256=nWSlJMMfIM3DvZxMn6ISQusUJqRYAjKQyLF5hwLEdBQ,3119
|
|
38
|
+
mapFolding/syntheticModules/theorem2.py,sha256=9jrbZNNX4BWYZW1S0JjvRY2k7RU7I1RNUMV7JdCt1ZY,3017
|
|
39
|
+
mapFolding/syntheticModules/theorem2Numba.py,sha256=-cKjNyxgUMFhEyFVs0VJ7hw4LfrV0WSNK5tPYbQ1oNU,3369
|
|
40
|
+
mapFolding/syntheticModules/theorem2Trimmed.py,sha256=DHW3NxBdtABQYBKm2WRvfQ5kzc2_UwGI2h4ePuYEJoM,2685
|
|
41
|
+
mapfolding-0.12.3.dist-info/licenses/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
|
|
42
|
+
tests/__init__.py,sha256=5RdiZYAl8nPIM1sxB_D0CsN6J8173LOZ0hpR3geTHAU,1312
|
|
43
|
+
tests/conftest.py,sha256=eBo0IIm98402hl_XW5nT06cUvW25ciItv1_zZdM152E,11126
|
|
44
|
+
tests/test_computations.py,sha256=9We4l3JcyQy-LGHdCIL2fP_v6mXfdnPcD7YIp5C9Um8,5845
|
|
45
|
+
tests/test_filesystem.py,sha256=IXTeyfifXe6vLizCo8BiSn5Yx9DEKYEc_hoJRKhQFNk,3899
|
|
46
|
+
tests/test_oeis.py,sha256=CA0f8vHDwm_pLX4SMQN3_hTfy6elU2Hgm0d-jrxFoqE,6299
|
|
47
|
+
tests/test_other.py,sha256=ELIMRO8NbuQzzleVRN4zhC1bWYK3KTzFQhS_GOKrnnk,4945
|
|
48
|
+
tests/test_tasks.py,sha256=g80zHTjpv8zb5ptIIbJro9aY4McMn0gYMXj00MqY7vw,4042
|
|
49
|
+
mapfolding-0.12.3.dist-info/METADATA,sha256=nZn2rzN0f5NDTIg_tS6Sb5cWS5wLfpuW5gjWIxLuANg,7884
|
|
50
|
+
mapfolding-0.12.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
51
|
+
mapfolding-0.12.3.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
|
|
52
|
+
mapfolding-0.12.3.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
|
|
53
|
+
mapfolding-0.12.3.dist-info/RECORD,,
|
tests/__init__.py
CHANGED
|
@@ -1,44 +1,28 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### For Custom Recipes (RecipeSynthesizeFlow):
|
|
31
|
-
Copy and adapt the `syntheticDispatcherFixture` and associated tests from
|
|
32
|
-
`test_computations.py` to validate your customized code transformation assembly lines.
|
|
33
|
-
|
|
34
|
-
### For Custom Jobs (RecipeJob):
|
|
35
|
-
Copy and adapt the `test_writeJobNumba` function to test specialized job modules
|
|
36
|
-
for specific map shapes with your custom configurations.
|
|
37
|
-
|
|
38
|
-
The entire test infrastructure is built on fixtures and utilities that handle
|
|
39
|
-
complex setup and validation, allowing you to focus on your implementation details
|
|
40
|
-
while leveraging the existing validation framework.
|
|
41
|
-
|
|
42
|
-
See the module docstrings in `test_computations.py` and `conftest.py` for detailed
|
|
43
|
-
guidance on adapting these tests for your own purposes.
|
|
44
|
-
"""
|
|
1
|
+
"""Test suite for the mapFolding package.
|
|
2
|
+
|
|
3
|
+
This test suite provides comprehensive validation of map folding computations,
|
|
4
|
+
file system operations, OEIS integration, task division, and foundational
|
|
5
|
+
utilities. The tests are designed to support multiple audiences and use cases.
|
|
6
|
+
|
|
7
|
+
Test Module Organization:
|
|
8
|
+
- conftest.py: Testing infrastructure and shared fixtures
|
|
9
|
+
- test_computations.py: Core mathematical validation and algorithm testing
|
|
10
|
+
- test_filesystem.py: File operations and path management
|
|
11
|
+
- test_oeis.py: OEIS sequence integration and caching
|
|
12
|
+
- test_other.py: Foundational utilities and data validation
|
|
13
|
+
- test_tasks.py: Task division and work distribution
|
|
14
|
+
|
|
15
|
+
For Contributors:
|
|
16
|
+
The test suite follows Domain-Driven Design principles, organizing tests around
|
|
17
|
+
mathematical concepts rather than implementation details. Use the existing
|
|
18
|
+
patterns as templates when adding new functionality.
|
|
19
|
+
|
|
20
|
+
For Users Adding Custom Modules:
|
|
21
|
+
The test_computations.py module provides the most relevant examples for testing
|
|
22
|
+
custom computational approaches. The standardized testing functions in conftest.py
|
|
23
|
+
ensure consistent error reporting across all tests.
|
|
24
|
+
|
|
25
|
+
For AI Assistants:
|
|
26
|
+
The testing framework emphasizes readable, predictable patterns that maintain
|
|
27
|
+
mathematical correctness while supporting code evolution and optimization.
|
|
28
|
+
"""
|
tests/conftest.py
CHANGED
|
@@ -1,62 +1,30 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- `syntheticDispatcherFixture`: Tests with generated Numba-optimized implementation
|
|
25
|
-
|
|
26
|
-
2. **Test Data Fixtures**:
|
|
27
|
-
- `oeisID`, `oeisID_1random`: Provide OEIS sequence identifiers for testing
|
|
28
|
-
- `listDimensionsTestCountFolds`: Provides dimensions suitable for algorithm testing
|
|
29
|
-
- `listDimensionsTestParallelization`: Provides dimensions suitable for parallel testing
|
|
30
|
-
- `mapShapeTestFunctionality`: Provides map shapes suitable for functional testing
|
|
31
|
-
|
|
32
|
-
3. **Path Fixtures**:
|
|
33
|
-
- `pathTmpTesting`: Creates a temporary directory for test-specific files
|
|
34
|
-
- `pathFilenameTmpTesting`: Creates a temporary file with appropriate extension
|
|
35
|
-
- `pathCacheTesting`: Creates a temporary OEIS cache directory
|
|
36
|
-
|
|
37
|
-
### Standardized Test Utilities
|
|
38
|
-
|
|
39
|
-
The module provides utilities that create consistent test outputs:
|
|
40
|
-
|
|
41
|
-
- `standardizedEqualToCallableReturn`: Core utility that handles testing function return values
|
|
42
|
-
or exceptions with uniform error messages
|
|
43
|
-
- `standardizedSystemExit`: Tests code that should exit the program with specific status codes
|
|
44
|
-
- `uniformTestMessage`: Creates consistent error messages for test failures
|
|
45
|
-
|
|
46
|
-
## Using These Fixtures for Custom Tests
|
|
47
|
-
|
|
48
|
-
The most important fixtures for testing custom implementations are:
|
|
49
|
-
|
|
50
|
-
1. `syntheticDispatcherFixture`: Creates and patches a Numba-optimized module from a recipe
|
|
51
|
-
2. `pathTmpTesting`: Provides a clean temporary directory for test files
|
|
52
|
-
3. `standardizedEqualToCallableReturn`: Simplifies test assertions with clear error messages
|
|
53
|
-
|
|
54
|
-
These can be adapted by copying and modifying them to test custom recipes and jobs.
|
|
55
|
-
See the examples in `test_computations.py` for guidance on adapting these fixtures.
|
|
1
|
+
"""Test framework infrastructure and shared fixtures for mapFolding.
|
|
2
|
+
|
|
3
|
+
This module serves as the foundation for the entire test suite, providing standardized
|
|
4
|
+
fixtures, temporary file management, and testing utilities. It implements the Single
|
|
5
|
+
Source of Truth principle for test configuration and establishes consistent patterns
|
|
6
|
+
that make the codebase easier to extend and maintain.
|
|
7
|
+
|
|
8
|
+
The testing framework is designed for multiple audiences:
|
|
9
|
+
- Contributors who need to understand the test patterns
|
|
10
|
+
- AI assistants that help maintain or extend the codebase
|
|
11
|
+
- Users who want to test custom modules they create
|
|
12
|
+
- Future maintainers who need to debug or modify tests
|
|
13
|
+
|
|
14
|
+
Key Components:
|
|
15
|
+
- Temporary file management with automatic cleanup
|
|
16
|
+
- Standardized assertion functions with uniform error messages
|
|
17
|
+
- Test data generation from OEIS sequences for reproducible results
|
|
18
|
+
- Mock objects for external dependencies and timing-sensitive operations
|
|
19
|
+
|
|
20
|
+
The module follows Domain-Driven Design principles, organizing test concerns around
|
|
21
|
+
the mathematical concepts of map folding rather than technical implementation details.
|
|
22
|
+
This makes tests more meaningful and easier to understand in the context of the
|
|
23
|
+
research domain.
|
|
56
24
|
"""
|
|
57
25
|
|
|
58
26
|
from collections.abc import Callable, Generator, Sequence
|
|
59
|
-
from mapFolding import getLeavesTotal,
|
|
27
|
+
from mapFolding import getLeavesTotal, makeDataContainer, validateListDimensions
|
|
60
28
|
from mapFolding.oeis import oeisIDsImplemented, settingsOEIS
|
|
61
29
|
from pathlib import Path
|
|
62
30
|
from typing import Any
|
|
@@ -68,7 +36,7 @@ import unittest.mock
|
|
|
68
36
|
import uuid
|
|
69
37
|
|
|
70
38
|
# SSOT for test data paths and filenames
|
|
71
|
-
pathDataSamples = Path("tests/dataSamples").absolute()
|
|
39
|
+
pathDataSamples: Path = Path("tests/dataSamples").absolute()
|
|
72
40
|
pathTmpRoot: Path = pathDataSamples / "tmp"
|
|
73
41
|
pathTmpRoot.mkdir(parents=True, exist_ok=True)
|
|
74
42
|
|
|
@@ -102,7 +70,7 @@ def setupTeardownTmpObjects() -> Generator[None, None, None]:
|
|
|
102
70
|
@pytest.fixture
|
|
103
71
|
def pathTmpTesting(request: pytest.FixtureRequest) -> Path:
|
|
104
72
|
# "Z0Z_" ensures the directory name does not start with a number, which would make it an invalid Python identifier
|
|
105
|
-
pathTmp = pathTmpRoot / ("Z0Z_" + str(uuid.uuid4().hex))
|
|
73
|
+
pathTmp: Path = pathTmpRoot / ("Z0Z_" + str(uuid.uuid4().hex))
|
|
106
74
|
pathTmp.mkdir(parents=True, exist_ok=False)
|
|
107
75
|
|
|
108
76
|
registrarRecordsTmpObject(pathTmp)
|
|
@@ -153,7 +121,15 @@ def setupWarningsAsErrors() -> Generator[None, Any, None]:
|
|
|
153
121
|
@pytest.fixture
|
|
154
122
|
def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
|
|
155
123
|
"""For each `oeisID_1random` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation`
|
|
156
|
-
if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
|
|
124
|
+
if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
|
|
125
|
+
|
|
126
|
+
This fixture provides a single test case to avoid issues with tests that write to the same
|
|
127
|
+
output files. It's particularly useful when testing code generation or file output functions
|
|
128
|
+
where multiple concurrent tests could interfere with each other.
|
|
129
|
+
|
|
130
|
+
The returned map shape is guaranteed to be computationally feasible for testing purposes,
|
|
131
|
+
avoiding cases that would take excessive time to complete during test runs.
|
|
132
|
+
"""
|
|
157
133
|
while True:
|
|
158
134
|
n = random.choice(settingsOEIS[oeisID_1random]['valuesTestValidation'])
|
|
159
135
|
if n < 2:
|
|
@@ -235,13 +211,42 @@ def oeisID_1random() -> str:
|
|
|
235
211
|
return random.choice(oeisIDsImplemented)
|
|
236
212
|
|
|
237
213
|
def uniformTestMessage(expected: Any, actual: Any, functionName: str, *arguments: Any) -> str:
|
|
238
|
-
"""Format assertion message for any test comparison.
|
|
214
|
+
"""Format assertion message for any test comparison.
|
|
215
|
+
|
|
216
|
+
Creates standardized, machine-parsable error messages that clearly display
|
|
217
|
+
what was expected versus what was received. This uniform formatting makes
|
|
218
|
+
test failures easier to debug and maintains consistency across the entire
|
|
219
|
+
test suite.
|
|
220
|
+
|
|
221
|
+
Parameters
|
|
222
|
+
expected: The value or exception type that was expected
|
|
223
|
+
actual: The value or exception type that was actually received
|
|
224
|
+
functionName: Name of the function being tested
|
|
225
|
+
arguments: Arguments that were passed to the function
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
formattedMessage: A formatted string showing the test context and comparison
|
|
229
|
+
"""
|
|
239
230
|
return (f"\nTesting: `{functionName}({', '.join(str(parameter) for parameter in arguments)})`\n"
|
|
240
231
|
f"Expected: {expected}\n"
|
|
241
232
|
f"Got: {actual}")
|
|
242
233
|
|
|
243
234
|
def standardizedEqualToCallableReturn(expected: Any, functionTarget: Callable[..., Any], *arguments: Any) -> None:
|
|
244
|
-
"""Use with callables that produce a return or an error.
|
|
235
|
+
"""Use with callables that produce a return or an error.
|
|
236
|
+
|
|
237
|
+
This is the primary testing function for validating both successful returns
|
|
238
|
+
and expected exceptions. It provides consistent error messaging and handles
|
|
239
|
+
the comparison logic that most tests in the suite rely on.
|
|
240
|
+
|
|
241
|
+
When testing a function that should raise an exception, pass the exception
|
|
242
|
+
type as the `expected` parameter. For successful returns, pass the expected
|
|
243
|
+
return value.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
expected: Expected return value or exception type
|
|
247
|
+
functionTarget: The function to test
|
|
248
|
+
arguments: Arguments to pass to the function
|
|
249
|
+
"""
|
|
245
250
|
if type(expected) is type[Exception]:
|
|
246
251
|
messageExpected = expected.__name__
|
|
247
252
|
else:
|