mapFolding 0.8.3__py3-none-any.whl → 0.8.5__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.
Files changed (38) hide show
  1. mapFolding/__init__.py +6 -3
  2. mapFolding/basecamp.py +13 -7
  3. mapFolding/beDRY.py +241 -68
  4. mapFolding/oeis.py +4 -4
  5. mapFolding/reference/hunterNumba.py +1 -1
  6. mapFolding/someAssemblyRequired/__init__.py +40 -20
  7. mapFolding/someAssemblyRequired/_theTypes.py +53 -0
  8. mapFolding/someAssemblyRequired/_tool_Make.py +99 -0
  9. mapFolding/someAssemblyRequired/_tool_Then.py +72 -0
  10. mapFolding/someAssemblyRequired/_toolboxAntecedents.py +358 -0
  11. mapFolding/someAssemblyRequired/_toolboxContainers.py +334 -0
  12. mapFolding/someAssemblyRequired/_toolboxPython.py +62 -0
  13. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +2 -2
  14. mapFolding/someAssemblyRequired/newInliner.py +22 -0
  15. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +158 -0
  16. mapFolding/someAssemblyRequired/toolboxNumba.py +358 -0
  17. mapFolding/someAssemblyRequired/transformationTools.py +289 -698
  18. mapFolding/syntheticModules/numbaCount_doTheNeedful.py +36 -33
  19. mapFolding/theDao.py +13 -11
  20. mapFolding/theSSOT.py +83 -128
  21. mapFolding/toolboxFilesystem.py +219 -0
  22. {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/METADATA +4 -2
  23. mapfolding-0.8.5.dist-info/RECORD +48 -0
  24. {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/WHEEL +1 -1
  25. tests/conftest.py +56 -52
  26. tests/test_computations.py +42 -32
  27. tests/test_filesystem.py +4 -4
  28. tests/test_other.py +2 -2
  29. tests/test_tasks.py +2 -2
  30. mapFolding/filesystem.py +0 -129
  31. mapFolding/someAssemblyRequired/ingredientsNumba.py +0 -206
  32. mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +0 -211
  33. mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +0 -413
  34. mapFolding/someAssemblyRequired/transformDataStructures.py +0 -168
  35. mapfolding-0.8.3.dist-info/RECORD +0 -43
  36. {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/entry_points.txt +0 -0
  37. {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/licenses/LICENSE +0 -0
  38. {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapFolding
3
- Version: 0.8.3
3
+ Version: 0.8.5
4
4
  Summary: Map folding algorithm with code transformation framework for optimizing numerical computations
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -35,6 +35,7 @@ Requires-Dist: more_itertools
35
35
  Requires-Dist: numba_progress
36
36
  Requires-Dist: numba
37
37
  Requires-Dist: numpy
38
+ Requires-Dist: platformdirs
38
39
  Requires-Dist: python_minifier
39
40
  Requires-Dist: tomli
40
41
  Requires-Dist: Z0Z_tools
@@ -45,6 +46,7 @@ Requires-Dist: pytest-cov; extra == "testing"
45
46
  Requires-Dist: pytest-env; extra == "testing"
46
47
  Requires-Dist: pytest-xdist; extra == "testing"
47
48
  Requires-Dist: pyupgrade; extra == "testing"
49
+ Requires-Dist: ruff; extra == "testing"
48
50
  Dynamic: license-file
49
51
 
50
52
  # mapFolding: Algorithms for enumerating distinct map/stamp folding patterns 🗺️
@@ -131,7 +133,7 @@ The package provides a sophisticated transformation framework that bridges the g
131
133
  - Study the functional state-transformation approach in `theDao.py` with clear, isolated functions
132
134
  - Explore the semantic decomposition in `reference/flattened.py` to understand algorithm sections
133
135
 
134
- - **Code Transformation Pipeline**:
136
+ - **Code Transformation Assembly-line**:
135
137
  - **AST Manipulation**: Analyzes and transforms the algorithm's abstract syntax tree
136
138
  - **Dataclass "Shattering"**: Decomposes complex state objects into primitive components
137
139
  - **Optimization Applications**: Applies domain-specific optimizations for numerical computation
@@ -0,0 +1,48 @@
1
+ mapFolding/__init__.py,sha256=LBgk-iW95pzqkFGY8PbcnU0oHy0AXwJGo18mM0g8wEw,2227
2
+ mapFolding/basecamp.py,sha256=-__EJ2to84ssS4Fm0CAuQjRnghI9VA4cXZoWGYud1r0,4782
3
+ mapFolding/beDRY.py,sha256=2GPO4A8XcxoEJXB_3sro4ZFQ5gcU7ywc1-c8HLEvEv0,15280
4
+ mapFolding/noHomeYet.py,sha256=UKZeWlyn0SKlF9dhYoud7E6gWXpiSEekZOOoJp88WeI,1362
5
+ mapFolding/oeis.py,sha256=EzEnbRi_4qt8Na2tiMcvL23FXpcJEkXTwuXDYDFH_XI,12631
6
+ mapFolding/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ mapFolding/theDao.py,sha256=MVopt1LzhdIQYA97SEoq9bdzct6hbK0lEyPxBAAlVTc,9934
8
+ mapFolding/theSSOT.py,sha256=i3R_G702U7VQOil61ky60JGGsSEOk_x1555rg8yI0Tc,11978
9
+ mapFolding/toolboxFilesystem.py,sha256=WoqRjXqTXy5GYNmbfzWtzv1uufm7vYcgT4zJ9ffhRYY,9982
10
+ mapFolding/reference/__init__.py,sha256=UIEU8BJR_YDzjFQcLel3XtHzOCJiOUGlGiWzOzbvhik,2206
11
+ mapFolding/reference/flattened.py,sha256=QK1xG9SllqCoi68e86Hyl9d9ATUAAFNpTQI-3zmcp5I,16072
12
+ mapFolding/reference/hunterNumba.py,sha256=iLfyqwGdAh6c5GbapnKsWhAsNsR3O-fyGGHAdohluLw,7258
13
+ mapFolding/reference/irvineJavaPort.py,sha256=UEfIX4QbPLl5jnyfYIyX5YRR3_rYvPUikK8jLehsFko,4076
14
+ mapFolding/reference/jaxCount.py,sha256=TuDNKOnyhQfuixKmIxO9Algv7dvy7KMGhgsV3h96FGE,14853
15
+ mapFolding/reference/lunnanNumpy.py,sha256=mMgrgbrBpe4nmo72ThEI-MGH0OwEHmfMPczSXHp2qKo,4357
16
+ mapFolding/reference/lunnanWhile.py,sha256=ZL8GAQtPs5nJZSgoDl5USrLSS_zs03y98y1Z9E4jOmQ,3799
17
+ mapFolding/reference/rotatedEntryPoint.py,sha256=5ughpKUT2JQhoAKgoDUdYNjgWQYPGV8v-7dWEAdDmfE,10274
18
+ mapFolding/reference/total_countPlus1vsPlusN.py,sha256=yJZAVLVdoXqHag2_N6_6CT-Q6HXBgRro-eny93-Rlpw,9307
19
+ mapFolding/reference/jobsCompleted/__init__.py,sha256=TU93ZGUW1xEkT6d9mQFn_rp5DvRy0ZslEB2Q6MF5ZDc,2596
20
+ mapFolding/reference/jobsCompleted/[2x19]/p2x19.py,sha256=_tvYtfzMWVo2VtUbIAieoscb4N8FFflgTdW4-ljBUuA,19626
21
+ mapFolding/reference/jobsCompleted/p2x19/p2x19.py,sha256=eZEw4Me4ocTt6VXoK2-Sbd5SowZtxRIbN9dZmc7OCVg,6395
22
+ mapFolding/someAssemblyRequired/__init__.py,sha256=c2GFI2HSId2_R_aoJWBID-P9AMF3zoHJzOc10XS6DHc,2669
23
+ mapFolding/someAssemblyRequired/_theTypes.py,sha256=SG82WTtQy83BmInlHZHY8Nh3Kp161NcEFSA6-UU5wuE,4623
24
+ mapFolding/someAssemblyRequired/_tool_Make.py,sha256=8ezrMDAdUY6m1raFp-G8vNXrHEr8IGfnZJ-aMVKzGf0,7092
25
+ mapFolding/someAssemblyRequired/_tool_Then.py,sha256=QxuoBqj4iOeKWITjV3DcV8c25fLx3Q6mhUORD7-mCzc,2758
26
+ mapFolding/someAssemblyRequired/_toolboxAntecedents.py,sha256=GEAuniYRj6yOtrJO_6sGZMzsVARdejts8NXhR_0np_c,21914
27
+ mapFolding/someAssemblyRequired/_toolboxContainers.py,sha256=iPLZbFcGB6dKtX3WkopnM-2OtMcVuxXQT46iFhzpdfY,17815
28
+ mapFolding/someAssemblyRequired/_toolboxPython.py,sha256=za30092eT00tj5ctqUCRrEuq5DGeJZN-vV9T4Dro-1w,3483
29
+ mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=9RPU6vK_eUg64GtVFI_nZnvUryXw8gfHJs9NyDYHIvg,2745
30
+ mapFolding/someAssemblyRequired/newInliner.py,sha256=Tm9PSzt66oIXPVrN9VdQwEYBba2iEOF5X3aEsOOF-FE,946
31
+ mapFolding/someAssemblyRequired/synthesizeNumbaJob.py,sha256=0L5ccqBusof6MzKatKnpUmFUNkAtbapzl_Fxmofi4DE,8684
32
+ mapFolding/someAssemblyRequired/toolboxNumba.py,sha256=rluEmsSJOQCl2L6LlJzIc3AfeRxU6cp-sCf-rQFW-og,22613
33
+ mapFolding/someAssemblyRequired/transformationTools.py,sha256=iIvRxSL45qTyl0d0ztHa9BP1MrOikfXE4HBqLlNMENc,20081
34
+ mapFolding/syntheticModules/__init__.py,sha256=evVFqhCGa-WZKDiLcnQWjs-Bj34eRnfSLqz_d7dFYZY,83
35
+ mapFolding/syntheticModules/numbaCount_doTheNeedful.py,sha256=3thXThbv2Xo0t_cRGzMbHPFXTBmLClmKejR_Ibu_jOo,15697
36
+ mapfolding-0.8.5.dist-info/licenses/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
37
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ tests/conftest.py,sha256=LfogHLu7PULSECwhLQgGCgqSvDMBc5b9RGWBls3YBrM,11364
39
+ tests/test_computations.py,sha256=XjCej6M6lesfKB_ulWq3O-ryXBsJuuwnJ6_XjKOvgDY,3552
40
+ tests/test_filesystem.py,sha256=YEHNU6tUCTj9C65cKs3ETgt3OZTGVnNjxgu4aH6C9uU,3164
41
+ tests/test_oeis.py,sha256=uxvwmgbnylSDdsVJfuAT0LuYLbIVFwSgdLxHm-xUGBM,5043
42
+ tests/test_other.py,sha256=O05PFAK70Skf-k99Wcg4ASLpMpBH-WkELtk6MnynDx0,4293
43
+ tests/test_tasks.py,sha256=S-6PNfM__Npw0zVojgzn5M-6ODBKDyRH5ccMTqQF9C4,2865
44
+ mapfolding-0.8.5.dist-info/METADATA,sha256=vrusTb9uu8FQ3UksfFkVZ3txtYPNufYa3db-Rk6H1y0,9359
45
+ mapfolding-0.8.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
46
+ mapfolding-0.8.5.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
47
+ mapfolding-0.8.5.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
48
+ mapfolding-0.8.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
tests/conftest.py CHANGED
@@ -1,16 +1,14 @@
1
- from importlib import import_module as importlib_import_module
2
1
  from collections.abc import Callable, Generator, Sequence
3
- from types import ModuleType
4
-
5
- import numpy
6
- from mapFolding.theSSOT import ComputationState, The, getPackageDispatcher
7
2
  from mapFolding.beDRY import getLeavesTotal, validateListDimensions, makeDataContainer
8
3
  from mapFolding.oeis import oeisIDsImplemented, settingsOEIS
9
- from mapFolding.someAssemblyRequired import RecipeSynthesizeFlow
10
- from mapFolding.someAssemblyRequired.synthesizeNumbaFlow import makeNumbaFlow
4
+ from mapFolding.someAssemblyRequired import importLogicalPath2Callable, RecipeSynthesizeFlow
5
+ from mapFolding.theSSOT import ComputationState, The, getPackageDispatcher
11
6
  from pathlib import Path, PurePosixPath
12
- from typing import Any, ContextManager
7
+ from types import ModuleType
8
+ from typing import Any
9
+ import importlib
13
10
  import importlib.util
11
+ import numpy
14
12
  import pytest
15
13
  import random
16
14
  import shutil
@@ -18,8 +16,9 @@ import unittest.mock
18
16
  import uuid
19
17
 
20
18
  # SSOT for test data paths and filenames
21
- pathDataSamples = Path("tests/dataSamples")
19
+ pathDataSamples = Path("tests/dataSamples").absolute()
22
20
  pathTmpRoot: Path = pathDataSamples / "tmp"
21
+ pathTmpRoot.mkdir(parents=True, exist_ok=True)
23
22
 
24
23
  # The registrar maintains the register of temp files
25
24
  registerOfTemporaryFilesystemObjects: set[Path] = set()
@@ -100,7 +99,22 @@ def setupWarningsAsErrors() -> Generator[None, Any, None]:
100
99
  warnings.resetwarnings()
101
100
 
102
101
  @pytest.fixture
103
- def listDimensionsTestCountFolds(oeisID: str):
102
+ def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
103
+ """For each `oeisID_1random` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation`
104
+ if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts."""
105
+ while True:
106
+ n = random.choice(settingsOEIS[oeisID_1random]['valuesTestValidation'])
107
+ if n < 2:
108
+ continue
109
+ listDimensionsCandidate = list(settingsOEIS[oeisID_1random]['getMapShape'](n))
110
+
111
+ try:
112
+ return validateListDimensions(listDimensionsCandidate)
113
+ except (ValueError, NotImplementedError):
114
+ pass
115
+
116
+ @pytest.fixture
117
+ def listDimensionsTestCountFolds(oeisID: str) -> tuple[int, ...]:
104
118
  """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation`
105
119
  if `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts."""
106
120
  while True:
@@ -115,7 +129,7 @@ def listDimensionsTestCountFolds(oeisID: str):
115
129
  pass
116
130
 
117
131
  @pytest.fixture
118
- def mapShapeTestFunctionality(oeisID_1random: str):
132
+ def mapShapeTestFunctionality(oeisID_1random: str) -> tuple[int, ...]:
119
133
  """To test functionality, get one `listDimensions` from `valuesTestValidation` if
120
134
  `validateListDimensions` approves. The algorithm can count the folds of the returned
121
135
  `listDimensions` in a short enough time suitable for testing."""
@@ -159,17 +173,6 @@ def mockFoldingFunction() -> Callable[..., Callable[..., None]]:
159
173
  return mock_countFolds
160
174
  return make_mock
161
175
 
162
- @pytest.fixture
163
- def mockDispatcher() -> Callable[[Any], ContextManager[Any]]:
164
- """Context manager for mocking dispatcher callable."""
165
- def wrapper(mockFunction: Any) -> ContextManager[Any]:
166
- dispatcherCallable = getPackageDispatcher()
167
- return unittest.mock.patch(
168
- f"{dispatcherCallable.__module__}.{dispatcherCallable.__name__}",
169
- side_effect=mockFunction
170
- )
171
- return wrapper
172
-
173
176
  @pytest.fixture(params=oeisIDsImplemented)
174
177
  def oeisID(request: pytest.FixtureRequest) -> Any:
175
178
  return request.param
@@ -198,46 +201,47 @@ def useThisDispatcher() -> Generator[Callable[..., None], Any, None]:
198
201
  basecamp.getPackageDispatcher = dispatcherOriginal
199
202
 
200
203
  def getAlgorithmDispatcher() -> Callable[[ComputationState], ComputationState]:
201
- moduleImported: ModuleType = importlib_import_module(The.logicalPathModuleSourceAlgorithm)
202
- dispatcherCallable = getattr(moduleImported, The.dispatcherCallable)
204
+ moduleImported: ModuleType = importlib.import_module(The.logicalPathModuleSourceAlgorithm)
205
+ dispatcherCallable = getattr(moduleImported, The.sourceCallableDispatcher)
203
206
  return dispatcherCallable
204
207
 
205
208
  @pytest.fixture
206
209
  def useAlgorithmSourceDispatcher(useThisDispatcher: Callable[..., Any]) -> Generator[None, None, None]:
207
210
  """Temporarily patches getDispatcherCallable to return the algorithm dispatcher."""
208
- useThisDispatcher(getAlgorithmDispatcher())
211
+ useThisDispatcher(importLogicalPath2Callable(The.logicalPathModuleSourceAlgorithm, The.sourceCallableDispatcher))
209
212
  yield
210
213
 
211
214
  @pytest.fixture
212
215
  def syntheticDispatcherFixture(useThisDispatcher: Callable[..., Any], pathTmpTesting: Path) -> Callable[..., Any]:
213
- """Generate synthetic Numba-optimized dispatcher module and patch the dispatcher"""
214
- # Configure synthesis flow to use test directory
215
- recipeFlow = RecipeSynthesizeFlow(
216
- pathPackage=PurePosixPath(pathTmpTesting.absolute()),
217
- Z0Z_flowLogicalPathRoot=None,
218
- moduleDispatcher="test_dispatcher",
216
+ """Generate synthetic Numba-optimized dispatcher module and patch the dispatcher"""
217
+ from mapFolding.someAssemblyRequired.toolboxNumba import makeNumbaFlow
218
+
219
+ TESTINGrecipeFlow = RecipeSynthesizeFlow(
220
+ pathPackage=PurePosixPath(pathTmpTesting.absolute()),
221
+ logicalPathFlowRoot=None,
222
+ moduleDispatcher="test_dispatcher",
219
223
  # Figure out dynamic flow control to synthesized modules https://github.com/hunterhogan/mapFolding/issues/4
220
- # dispatcherCallable="dispatcherSynthetic",
221
- )
222
-
223
- # Generate optimized module in test directory
224
- makeNumbaFlow(recipeFlow)
225
-
226
- # Import synthesized dispatcher
227
- importlibSpecificationDispatcher = importlib.util.spec_from_file_location(
228
- recipeFlow.moduleDispatcher,
229
- Path(recipeFlow.pathFilenameDispatcher),
230
- )
231
- if importlibSpecificationDispatcher is None or importlibSpecificationDispatcher.loader is None:
232
- raise ImportError("Failed to load synthetic dispatcher module")
233
-
234
- moduleSpecificationDispatcher = importlib.util.module_from_spec(importlibSpecificationDispatcher)
235
- importlibSpecificationDispatcher.loader.exec_module(moduleSpecificationDispatcher)
236
- callableDispatcherSynthetic = getattr(moduleSpecificationDispatcher, recipeFlow.dispatcherCallable)
237
-
238
- # Patch dispatcher and return callable
239
- useThisDispatcher(callableDispatcherSynthetic)
240
- return callableDispatcherSynthetic
224
+ # dispatcherCallable="dispatcherSynthetic",
225
+ )
226
+
227
+ # Generate optimized module in test directory
228
+ makeNumbaFlow(TESTINGrecipeFlow)
229
+
230
+ # Import synthesized dispatcher
231
+ importlibSpecificationDispatcher = importlib.util.spec_from_file_location(
232
+ TESTINGrecipeFlow.moduleDispatcher,
233
+ Path(TESTINGrecipeFlow.pathFilenameDispatcher),
234
+ )
235
+ if importlibSpecificationDispatcher is None or importlibSpecificationDispatcher.loader is None:
236
+ raise ImportError("Failed to load synthetic dispatcher module")
237
+
238
+ moduleSpecificationDispatcher = importlib.util.module_from_spec(importlibSpecificationDispatcher)
239
+ importlibSpecificationDispatcher.loader.exec_module(moduleSpecificationDispatcher)
240
+ callableDispatcherSynthetic = getattr(moduleSpecificationDispatcher, TESTINGrecipeFlow.callableDispatcher)
241
+
242
+ # Patch dispatcher and return callable
243
+ useThisDispatcher(callableDispatcherSynthetic)
244
+ return callableDispatcherSynthetic
241
245
 
242
246
  def uniformTestMessage(expected: Any, actual: Any, functionName: str, *arguments: Any) -> str:
243
247
  """Format assertion message for any test comparison."""
@@ -1,53 +1,63 @@
1
1
  from mapFolding.basecamp import countFolds
2
- from mapFolding.filesystem import getPathFilenameFoldsTotal
2
+ from mapFolding.toolboxFilesystem import getPathFilenameFoldsTotal
3
+ from mapFolding.beDRY import validateListDimensions
3
4
  from mapFolding.noHomeYet import getFoldsTotalKnown
4
5
  from mapFolding.oeis import settingsOEIS, oeisIDfor_n
5
- # from mapFolding.someAssemblyRequired import writeJobNumba
6
- from pathlib import Path
6
+ from mapFolding.someAssemblyRequired.transformationTools import makeInitializedComputationState
7
+ from pathlib import Path, PurePosixPath
7
8
  from tests.conftest import standardizedEqualToCallableReturn, registrarRecordsTmpObject
8
9
  from types import ModuleType
9
10
  import importlib.util
10
11
  import multiprocessing
12
+ import threading
13
+ from copy import deepcopy
11
14
  import pytest
12
15
 
13
16
  if __name__ == '__main__':
14
17
  multiprocessing.set_start_method('spawn')
15
18
 
16
19
  def test_algorithmSourceParallel(listDimensionsTestParallelization: list[int], useAlgorithmSourceDispatcher: None) -> None:
17
- standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestParallelization)), countFolds, listDimensionsTestParallelization, None, 'maximum', None)
20
+ standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestParallelization)), countFolds, listDimensionsTestParallelization, None, 'maximum', None)
18
21
 
19
22
  def test_algorithmSourceSequential(listDimensionsTestCountFolds: tuple[int, ...], useAlgorithmSourceDispatcher: None) -> None:
20
- standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestCountFolds)), countFolds, listDimensionsTestCountFolds)
23
+ standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestCountFolds)), countFolds, listDimensionsTestCountFolds)
21
24
 
22
25
  def test_aOFn_calculate_value(oeisID: str) -> None:
23
- for n in settingsOEIS[oeisID]['valuesTestValidation']:
24
- standardizedEqualToCallableReturn(settingsOEIS[oeisID]['valuesKnown'][n], oeisIDfor_n, oeisID, n)
26
+ for n in settingsOEIS[oeisID]['valuesTestValidation']:
27
+ standardizedEqualToCallableReturn(settingsOEIS[oeisID]['valuesKnown'][n], oeisIDfor_n, oeisID, n)
25
28
 
26
29
  def test_syntheticParallel(syntheticDispatcherFixture: None, listDimensionsTestParallelization: list[int]):
27
- standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestParallelization)), countFolds, listDimensionsTestParallelization, None, 'maximum')
30
+ standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestParallelization)), countFolds, listDimensionsTestParallelization, None, 'maximum')
28
31
 
29
32
  def test_syntheticSequential(syntheticDispatcherFixture: None, listDimensionsTestCountFolds: list[int]) -> None:
30
- standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestCountFolds)), countFolds, listDimensionsTestCountFolds)
31
-
32
- # @pytest.mark.parametrize('pathFilenameTmpTesting', ['.py'], indirect=True)
33
- # def test_writeJobNumba(listDimensionsTestCountFolds: list[int], pathFilenameTmpTesting: Path) -> None:
34
- # from mapFolding.syntheticModules import numbaCount
35
- # algorithmSourceHARDCODED: ModuleType = numbaCount
36
- # algorithmSource = algorithmSourceHARDCODED
37
- # callableTargetHARDCODED = 'countSequential'
38
- # callableTarget = callableTargetHARDCODED
39
- # pathFilenameModule = writeJobNumba(listDimensionsTestCountFolds, algorithmSource, callableTarget, pathFilenameWriteJob=pathFilenameTmpTesting.absolute())
40
-
41
- # Don_Lapre_Road_to_Self_Improvement = importlib.util.spec_from_file_location("__main__", pathFilenameModule)
42
- # if Don_Lapre_Road_to_Self_Improvement is None:
43
- # raise ImportError(f"Failed to create module specification from {pathFilenameModule}")
44
- # if Don_Lapre_Road_to_Self_Improvement.loader is None:
45
- # raise ImportError(f"Failed to get loader for module {pathFilenameModule}")
46
- # module = importlib.util.module_from_spec(Don_Lapre_Road_to_Self_Improvement)
47
-
48
- # module.__name__ = "__main__"
49
- # Don_Lapre_Road_to_Self_Improvement.loader.exec_module(module)
50
-
51
- # pathFilenameFoldsTotal = getPathFilenameFoldsTotal(listDimensionsTestCountFolds)
52
- # registrarRecordsTmpObject(pathFilenameFoldsTotal)
53
- # standardizedEqualToCallableReturn(str(getFoldsTotalKnown(tuple(listDimensionsTestCountFolds))), pathFilenameFoldsTotal.read_text().strip)
33
+ standardizedEqualToCallableReturn(getFoldsTotalKnown(tuple(listDimensionsTestCountFolds)), countFolds, listDimensionsTestCountFolds)
34
+
35
+ @pytest.mark.parametrize('pathFilenameTmpTesting', ['.py'], indirect=True)
36
+ def test_writeJobNumba(oneTestCuzTestsOverwritingTests: list[int], pathFilenameTmpTesting: Path) -> None:
37
+ from mapFolding.someAssemblyRequired.toolboxNumba import RecipeJob, SpicesJobNumba
38
+ from mapFolding.someAssemblyRequired.synthesizeNumbaJob import makeJobNumba
39
+ mapShape = validateListDimensions(oneTestCuzTestsOverwritingTests)
40
+ state = makeInitializedComputationState(mapShape)
41
+
42
+ pathFilenameModule = pathFilenameTmpTesting.absolute()
43
+ pathFilenameFoldsTotal = pathFilenameModule.with_suffix('.foldsTotalTesting')
44
+ registrarRecordsTmpObject(pathFilenameFoldsTotal)
45
+
46
+ jobTest = RecipeJob(state
47
+ , pathModule=PurePosixPath(pathFilenameModule.parent)
48
+ , moduleIdentifier=pathFilenameModule.stem
49
+ , pathFilenameFoldsTotal=PurePosixPath(pathFilenameFoldsTotal))
50
+ spices = SpicesJobNumba()
51
+ makeJobNumba(jobTest, spices)
52
+
53
+ Don_Lapre_Road_to_Self_Improvement = importlib.util.spec_from_file_location("__main__", pathFilenameModule)
54
+ if Don_Lapre_Road_to_Self_Improvement is None:
55
+ raise ImportError(f"Failed to create module specification from {pathFilenameModule}")
56
+ if Don_Lapre_Road_to_Self_Improvement.loader is None:
57
+ raise ImportError(f"Failed to get loader for module {pathFilenameModule}")
58
+ module = importlib.util.module_from_spec(Don_Lapre_Road_to_Self_Improvement)
59
+
60
+ module.__name__ = "__main__"
61
+ Don_Lapre_Road_to_Self_Improvement.loader.exec_module(module)
62
+
63
+ standardizedEqualToCallableReturn(str(getFoldsTotalKnown(mapShape)), pathFilenameFoldsTotal.read_text().strip)
tests/test_filesystem.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from contextlib import redirect_stdout
2
- from mapFolding.filesystem import getFilenameFoldsTotal, getPathFilenameFoldsTotal, saveFoldsTotal
2
+ from mapFolding.toolboxFilesystem import getFilenameFoldsTotal, getPathFilenameFoldsTotal, saveFoldsTotal
3
3
  from mapFolding.beDRY import validateListDimensions
4
- from mapFolding.theSSOT import getPathJobRootDEFAULT
4
+ from mapFolding.toolboxFilesystem import getPathRootJobDEFAULT
5
5
  from pathlib import Path
6
6
  import io
7
7
  import pytest
@@ -33,14 +33,14 @@ def test_getPathFilenameFoldsTotal_defaultPath(mapShapeTestFunctionality: tuple[
33
33
  pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShapeTestFunctionality)
34
34
  assert pathFilenameFoldsTotal.is_absolute(), "Path should be absolute"
35
35
  assert pathFilenameFoldsTotal.name == getFilenameFoldsTotal(mapShapeTestFunctionality), "Filename should match getFilenameFoldsTotal output"
36
- assert pathFilenameFoldsTotal.parent == getPathJobRootDEFAULT(), "Parent directory should match default job root"
36
+ assert pathFilenameFoldsTotal.parent == getPathRootJobDEFAULT(), "Parent directory should match default job root"
37
37
 
38
38
  def test_getPathFilenameFoldsTotal_relativeFilename(mapShapeTestFunctionality: tuple[int, ...]) -> None:
39
39
  """Test getPathFilenameFoldsTotal with relative filename."""
40
40
  relativeFilename = Path("custom/path/test.foldsTotal")
41
41
  pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShapeTestFunctionality, relativeFilename)
42
42
  assert pathFilenameFoldsTotal.is_absolute(), "Path should be absolute"
43
- assert pathFilenameFoldsTotal == getPathJobRootDEFAULT() / relativeFilename, "Relative path should be appended to default job root"
43
+ assert pathFilenameFoldsTotal == getPathRootJobDEFAULT() / relativeFilename, "Relative path should be appended to default job root"
44
44
 
45
45
  def test_getPathFilenameFoldsTotal_createsDirs(pathTmpTesting: Path, mapShapeTestFunctionality: tuple[int, ...]) -> None:
46
46
  """Test that getPathFilenameFoldsTotal creates necessary directories."""
tests/test_other.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from collections.abc import Callable
2
- from mapFolding.beDRY import getLeavesTotal, setCPUlimit, validateListDimensions
2
+ from mapFolding.beDRY import getLeavesTotal, setProcessorLimit, validateListDimensions
3
3
  from mapFolding.theSSOT import The
4
4
  from tests.conftest import standardizedEqualToCallableReturn
5
5
  from typing import Any, Literal
@@ -81,4 +81,4 @@ def testOopsieKwargsie(nameOfTest: str, callablePytest: Callable[[], None]) -> N
81
81
  ])
82
82
  def test_setCPUlimitNumba(CPUlimit: None | float | bool | Literal[4] | Literal[-2] | Literal[0] | Literal[1], expectedLimit: Any | int) -> None:
83
83
  numba.set_num_threads(multiprocessing.cpu_count())
84
- standardizedEqualToCallableReturn(expectedLimit, setCPUlimit, CPUlimit, 'numba')
84
+ standardizedEqualToCallableReturn(expectedLimit, setProcessorLimit, CPUlimit, 'numba')
tests/test_tasks.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from collections.abc import Callable
2
2
  from mapFolding.basecamp import countFolds
3
- from mapFolding.beDRY import getTaskDivisions, setCPUlimit, validateListDimensions, getLeavesTotal
3
+ from mapFolding.beDRY import getTaskDivisions, setProcessorLimit, validateListDimensions, getLeavesTotal
4
4
  from mapFolding.noHomeYet import getFoldsTotalKnown
5
5
  from tests.conftest import standardizedEqualToCallableReturn
6
6
  from typing import Literal
@@ -49,4 +49,4 @@ def test_getTaskDivisions(computationDivisions: None | list[str] | Literal['maxi
49
49
  ])
50
50
  def test_setCPUlimitMalformedParameter(expected: type[ValueError] | Literal[2], parameter: list[int] | tuple[int] | set[int] | dict[str, int] | Literal['2']) -> None:
51
51
  """Test that invalid CPUlimit types are properly handled."""
52
- standardizedEqualToCallableReturn(expected, setCPUlimit, parameter)
52
+ standardizedEqualToCallableReturn(expected, setProcessorLimit, parameter)
mapFolding/filesystem.py DELETED
@@ -1,129 +0,0 @@
1
- """
2
- Filesystem utilities for managing map folding computation results.
3
-
4
- This module provides functions for standardized handling of files related to the mapFolding
5
- package, with a focus on saving, retrieving, and naming computation results. It implements
6
- consistent naming conventions and path resolution strategies to ensure that:
7
-
8
- 1. Computation results are stored in a predictable location
9
- 2. Filenames follow a consistent pattern based on map dimensions
10
- 3. Results can be reliably retrieved for future reference
11
- 4. The system handles file operations safely with appropriate error handling
12
-
13
- The module serves as the interface between the computational components of the package
14
- and the filesystem, abstracting away the details of file operations and path management.
15
- """
16
- from pathlib import Path, PurePath
17
- from typing import Any
18
- from os import PathLike
19
- import os
20
-
21
- def getFilenameFoldsTotal(mapShape: tuple[int, ...]) -> str:
22
- """
23
- Create a standardized filename for a computed `foldsTotal` value.
24
-
25
- This function generates a consistent, filesystem-safe filename based on map dimensions.
26
- Standardizing filenames ensures that results can be reliably stored and retrieved,
27
- avoiding potential filesystem incompatibilities or Python naming restrictions.
28
-
29
- Parameters:
30
- mapShape: A sequence of integers representing the dimensions of the map.
31
-
32
- Returns:
33
- filenameFoldsTotal: A filename string in format 'pMxN.foldsTotal' where M,N are sorted dimensions.
34
-
35
- Notes:
36
- The filename format ensures:
37
- - No spaces in the filename
38
- - Safe filesystem characters
39
- - Unique extension (.foldsTotal)
40
- - Python-safe strings (no starting with numbers, no reserved words)
41
- - The 'p' prefix preserves compatibility with Lunnan's original code.
42
- """
43
- return 'p' + 'x'.join(str(dimension) for dimension in sorted(mapShape)) + '.foldsTotal'
44
-
45
- def getPathFilenameFoldsTotal(mapShape: tuple[int, ...], pathLikeWriteFoldsTotal: str | PathLike[str] | None = None) -> Path:
46
- """
47
- Get a standardized path and filename for the computed foldsTotal value.
48
-
49
- This function resolves paths for storing computation results, handling different
50
- input types including directories, absolute paths, or relative paths. It ensures
51
- that all parent directories exist in the resulting path.
52
-
53
- Parameters:
54
- mapShape: List of dimensions for the map folding problem.
55
- pathLikeWriteFoldsTotal (getPathJobRootDEFAULT): Path, filename, or relative path and filename.
56
- If None, uses default path. If a directory, appends standardized filename.
57
-
58
- Returns:
59
- pathFilenameFoldsTotal: Absolute path and filename for storing the foldsTotal value.
60
-
61
- Notes:
62
- The function creates any necessary directories in the path if they don't exist.
63
- """
64
- from mapFolding.theSSOT import getPathJobRootDEFAULT
65
-
66
- if pathLikeWriteFoldsTotal is None:
67
- pathFilenameFoldsTotal = getPathJobRootDEFAULT() / getFilenameFoldsTotal(mapShape)
68
- else:
69
- pathLikeSherpa = Path(pathLikeWriteFoldsTotal)
70
- if pathLikeSherpa.is_dir():
71
- pathFilenameFoldsTotal = pathLikeSherpa / getFilenameFoldsTotal(mapShape)
72
- elif pathLikeSherpa.is_file() and pathLikeSherpa.is_absolute():
73
- pathFilenameFoldsTotal = pathLikeSherpa
74
- else:
75
- pathFilenameFoldsTotal = getPathJobRootDEFAULT() / pathLikeSherpa
76
-
77
- pathFilenameFoldsTotal.parent.mkdir(parents=True, exist_ok=True)
78
- return pathFilenameFoldsTotal
79
-
80
- def saveFoldsTotal(pathFilename: str | PathLike[str], foldsTotal: int) -> None:
81
- """
82
- Save `foldsTotal` value to disk with multiple fallback mechanisms.
83
-
84
- This function attempts to save the computed `foldsTotal` value to the specified
85
- location, with backup strategies in case the primary save attempt fails.
86
- The robustness is critical since these computations may take days to complete.
87
-
88
- Parameters:
89
- pathFilename: Target save location for the `foldsTotal` value
90
- foldsTotal: The computed value to save
91
-
92
- Notes:
93
- If the primary save fails, the function will attempt alternative save methods:
94
- 1. Print the value prominently to stdout
95
- 2. Create a fallback file in the current working directory
96
- 3. As a last resort, simply print the value
97
- """
98
- try:
99
- pathFilenameFoldsTotal = Path(pathFilename)
100
- pathFilenameFoldsTotal.parent.mkdir(parents=True, exist_ok=True)
101
- pathFilenameFoldsTotal.write_text(str(foldsTotal))
102
- except Exception as ERRORmessage:
103
- try:
104
- print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal=}\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
105
- print(ERRORmessage)
106
- print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal=}\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
107
- randomnessPlanB = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
108
- filenameInfixUnique = ''.join(randomnessPlanB)
109
- pathFilenamePlanB = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt')
110
- writeStreamFallback = open(pathFilenamePlanB, 'w')
111
- writeStreamFallback.write(str(foldsTotal))
112
- writeStreamFallback.close()
113
- print(str(pathFilenamePlanB))
114
- except Exception:
115
- print(foldsTotal)
116
- return None
117
-
118
- def writeStringToHere(this: str, pathFilename: str | PathLike[Any] | PurePath) -> None:
119
- """
120
- Write a string to a file, creating parent directories if needed.
121
-
122
- Parameters:
123
- this: The string content to write to the file
124
- pathFilename: The target file path where the string should be written
125
- """
126
- pathFilename = Path(pathFilename)
127
- pathFilename.parent.mkdir(parents=True, exist_ok=True)
128
- pathFilename.write_text(str(this))
129
- return None