mapFolding 0.16.0__py3-none-any.whl → 0.16.2__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 (77) hide show
  1. easyRun/A000682.py +25 -0
  2. easyRun/A005316.py +20 -0
  3. easyRun/NOTcountingFolds.py +36 -0
  4. easyRun/__init__.py +0 -0
  5. easyRun/countFolds.py +41 -0
  6. easyRun/meanders.py +69 -0
  7. mapFolding/__init__.py +8 -51
  8. mapFolding/_dataPacking.py +68 -0
  9. mapFolding/_theSSOT.py +33 -37
  10. mapFolding/_theTypes.py +21 -4
  11. mapFolding/algorithms/matrixMeanders.py +86 -517
  12. mapFolding/algorithms/matrixMeandersBeDry.py +182 -0
  13. mapFolding/algorithms/matrixMeandersNumPy.py +333 -0
  14. mapFolding/algorithms/matrixMeandersPandas.py +334 -0
  15. mapFolding/algorithms/oeisIDbyFormula.py +50 -29
  16. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +51 -29
  17. mapFolding/basecamp.py +167 -206
  18. mapFolding/beDRY.py +2 -30
  19. mapFolding/dataBaskets.py +75 -49
  20. mapFolding/oeis.py +11 -32
  21. mapFolding/reference/A000682facts.py +787 -652
  22. mapFolding/reference/A005316facts.py +961 -3
  23. mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
  24. mapFolding/reference/matrixMeandersAnalysis/signatures.py +2030 -0
  25. mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
  26. mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
  27. mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
  28. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +3 -4
  29. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +103 -29
  30. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +18 -14
  31. mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
  32. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +7 -6
  33. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +3 -4
  34. mapFolding/someAssemblyRequired/makingModules_count.py +88 -87
  35. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +10 -9
  36. mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +3 -3
  37. mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
  38. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +63 -0
  39. mapFolding/someAssemblyRequired/toolkitMakeModules.py +37 -37
  40. mapFolding/someAssemblyRequired/transformationTools.py +8 -8
  41. mapFolding/syntheticModules/A007822/algorithm.py +3 -3
  42. mapFolding/syntheticModules/A007822/algorithmNumba.py +1 -2
  43. mapFolding/syntheticModules/A007822/asynchronous.py +6 -4
  44. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +5 -7
  45. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +70 -0
  46. mapFolding/syntheticModules/A007822/asynchronousNumba.py +79 -0
  47. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +15 -3
  48. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +12 -3
  49. mapFolding/syntheticModules/A007822/initializeState.py +1 -2
  50. mapFolding/syntheticModules/A007822/theorem2.py +7 -2
  51. mapFolding/syntheticModules/A007822/theorem2Numba.py +31 -4
  52. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +8 -3
  53. mapFolding/syntheticModules/countParallelNumba.py +5 -2
  54. mapFolding/syntheticModules/dataPacking.py +1 -1
  55. mapFolding/syntheticModules/dataPackingA007822.py +92 -26
  56. mapFolding/syntheticModules/meanders/__init__.py +1 -0
  57. mapFolding/syntheticModules/meanders/bigInt.py +52 -0
  58. mapFolding/syntheticModules/theorem2.py +6 -0
  59. mapFolding/syntheticModules/theorem2Numba.py +8 -2
  60. mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
  61. mapFolding/tests/conftest.py +28 -13
  62. mapFolding/tests/test_computations.py +68 -61
  63. mapFolding/tests/test_oeis.py +6 -6
  64. mapFolding/zCuzDocStoopid/__init__.py +4 -1
  65. mapFolding/zCuzDocStoopid/makeDocstrings.py +35 -28
  66. mapfolding-0.16.2.dist-info/METADATA +99 -0
  67. mapfolding-0.16.2.dist-info/RECORD +115 -0
  68. {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/top_level.txt +1 -0
  69. mapFolding/algorithms/getBucketsTotal.py +0 -137
  70. mapFolding/reference/matrixMeandersAnalysis/evenEven.py +0 -144
  71. mapFolding/reference/matrixMeandersAnalysis/oddEven.py +0 -54
  72. mapFolding/trim_memory.py +0 -62
  73. mapfolding-0.16.0.dist-info/METADATA +0 -85
  74. mapfolding-0.16.0.dist-info/RECORD +0 -100
  75. {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/WHEEL +0 -0
  76. {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/entry_points.txt +0 -0
  77. {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,5 @@
1
1
  from mapFolding.dataBaskets import MapFoldingState
2
+ from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
2
3
 
3
4
  def count(state: MapFoldingState) -> MapFoldingState:
4
5
  while state.leaf1ndex > 4:
@@ -47,4 +48,9 @@ def count(state: MapFoldingState) -> MapFoldingState:
47
48
  state.leaf1ndex += 1
48
49
  else:
49
50
  state.groupsOfFolds *= 2
51
+ return state
52
+
53
+ def doTheNeedful(state: MapFoldingState) -> MapFoldingState:
54
+ state = transitionOnGroupsOfFolds(state)
55
+ state = count(state)
50
56
  return state
@@ -2,7 +2,7 @@ from mapFolding.dataBaskets import Array1DElephino, Array1DLeavesTotal, Array3DL
2
2
  from numba import jit
3
3
 
4
4
  @jit(cache=True, error_model='numpy', fastmath=True, forceinline=True)
5
- def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1ndexCeiling: DatatypeElephino, indexDimension: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, connectionGraph: Array3DLeavesTotal, dimensionsTotal: DatatypeLeavesTotal, leavesTotal: DatatypeLeavesTotal) -> tuple[DatatypeFoldsTotal, DatatypeElephino, DatatypeElephino, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal, Array1DLeavesTotal, Array1DElephino, Array1DLeavesTotal, Array1DLeavesTotal, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal]:
5
+ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1ndexCeiling: DatatypeElephino, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, connectionGraph: Array3DLeavesTotal, dimensionsTotal: DatatypeLeavesTotal, leavesTotal: DatatypeLeavesTotal) -> tuple[DatatypeFoldsTotal, DatatypeElephino, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal, Array1DLeavesTotal, Array1DElephino, Array1DLeavesTotal, Array1DLeavesTotal, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal]:
6
6
  while leaf1ndex > 4:
7
7
  if leafBelow[0] == 1:
8
8
  if leaf1ndex > leavesTotal:
@@ -23,6 +23,12 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
23
23
  countDimensionsGapped[leafConnectee] += 1
24
24
  leafConnectee = connectionGraph[indexDimension, leaf1ndex, leafBelow[leafConnectee]]
25
25
  indexDimension += 1
26
+ if not dimensionsUnconstrained:
27
+ indexLeaf = 0
28
+ while indexLeaf < leaf1ndex:
29
+ gapsWhere[gap1ndexCeiling] = indexLeaf
30
+ gap1ndexCeiling += 1
31
+ indexLeaf += 1
26
32
  indexMiniGap = gap1ndex
27
33
  while indexMiniGap < gap1ndexCeiling:
28
34
  gapsWhere[gap1ndex] = gapsWhere[indexMiniGap]
@@ -43,4 +49,4 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
43
49
  leaf1ndex += 1
44
50
  else:
45
51
  groupsOfFolds *= 2
46
- return (groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal)
52
+ return (groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal)
@@ -1,4 +1,5 @@
1
1
  from mapFolding.dataBaskets import MapFoldingState
2
+ from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
2
3
 
3
4
  def count(state: MapFoldingState) -> MapFoldingState:
4
5
  while state.leaf1ndex > 4:
@@ -41,4 +42,9 @@ def count(state: MapFoldingState) -> MapFoldingState:
41
42
  state.leaf1ndex += 1
42
43
  else:
43
44
  state.groupsOfFolds *= 2
45
+ return state
46
+
47
+ def doTheNeedful(state: MapFoldingState, /) -> MapFoldingState:
48
+ state = transitionOnGroupsOfFolds(state)
49
+ state = count(state)
44
50
  return state
@@ -25,7 +25,7 @@ research domain.
25
25
 
26
26
  from collections.abc import Callable, Generator, Sequence
27
27
  from mapFolding import _theSSOT, getLeavesTotal, makeDataContainer, packageSettings, validateListDimensions
28
- from mapFolding.oeis import dictionaryOEISMapFolding, dictionaryOEISMeanders, oeisIDsImplemented
28
+ from mapFolding.oeis import dictionaryOEIS, dictionaryOEISMapFolding, oeisIDsImplemented
29
29
  from pathlib import Path
30
30
  from typing import Any
31
31
  import numpy
@@ -223,7 +223,7 @@ def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
223
223
  pass
224
224
 
225
225
  @pytest.fixture
226
- def mapShapeTestCountFolds(oeisID: str) -> tuple[int, ...]:
226
+ def mapShapeTestCountFolds(oeisIDmapFolding: str) -> tuple[int, ...]:
227
227
  """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation` if
228
228
  `validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
229
229
 
@@ -239,10 +239,10 @@ def mapShapeTestCountFolds(oeisID: str) -> tuple[int, ...]:
239
239
 
240
240
  """
241
241
  while True:
242
- n = random.choice(dictionaryOEISMapFolding[oeisID]['valuesTestValidation'])
242
+ n = random.choice(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestValidation'])
243
243
  if n < 2:
244
244
  continue
245
- listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisID]['getMapShape'](n))
245
+ listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisIDmapFolding]['getMapShape'](n))
246
246
 
247
247
  try:
248
248
  return validateListDimensions(listDimensionsCandidate)
@@ -278,7 +278,7 @@ def mapShapeTestFunctionality(oeisID_1random: str) -> tuple[int, ...]:
278
278
  pass
279
279
 
280
280
  @pytest.fixture
281
- def mapShapeTestParallelization(oeisID: str) -> tuple[int, ...]:
281
+ def mapShapeTestParallelization(oeisIDmapFolding: str) -> tuple[int, ...]:
282
282
  """For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestParallelization`.
283
283
 
284
284
  Parameters
@@ -292,8 +292,8 @@ def mapShapeTestParallelization(oeisID: str) -> tuple[int, ...]:
292
292
  Map dimensions suitable for testing parallelization features.
293
293
 
294
294
  """
295
- n = random.choice(dictionaryOEISMapFolding[oeisID]['valuesTestParallelization'])
296
- return dictionaryOEISMapFolding[oeisID]['getMapShape'](n)
295
+ n = random.choice(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestParallelization'])
296
+ return dictionaryOEISMapFolding[oeisIDmapFolding]['getMapShape'](n)
297
297
 
298
298
  @pytest.fixture
299
299
  def mockBenchmarkTimer() -> Generator[unittest.mock.MagicMock | unittest.mock.AsyncMock, Any, None]:
@@ -332,7 +332,7 @@ def mockFoldingFunction() -> Callable[..., Callable[..., None]]:
332
332
  return make_mock
333
333
 
334
334
  @pytest.fixture(params=oeisIDsImplemented)
335
- def oeisID(request: pytest.FixtureRequest) -> Any:
335
+ def oeisIDmapFolding(request: pytest.FixtureRequest) -> Any:
336
336
  """Parametrized fixture providing all implemented OEIS sequence identifiers.
337
337
 
338
338
  (AI generated docstring)
@@ -350,11 +350,26 @@ def oeisID(request: pytest.FixtureRequest) -> Any:
350
350
  """
351
351
  return request.param
352
352
 
353
- @pytest.fixture(params=tuple(dictionaryOEISMeanders.keys()))
354
- def oeisIDMeanders(request: pytest.FixtureRequest) -> Any:
355
- """Parametrized fixture providing all implemented Meanders OEIS sequence identifiers.
353
+ @pytest.fixture(params=('A000682', 'A005316'))
354
+ def oeisIDmeanders(request: pytest.FixtureRequest) -> Any:
355
+ """Parametrized fixture providing all Meanders OEIS sequence identifiers.
356
356
 
357
- (AI generated docstring)
357
+ Parameters
358
+ ----------
359
+ request : pytest.FixtureRequest
360
+ The pytest request object containing the current parameter value.
361
+
362
+ Returns
363
+ -------
364
+ sequenceIdentifier : Any
365
+ OEIS sequence identifier for testing across all Meanders sequences.
366
+
367
+ """
368
+ return request.param
369
+
370
+ @pytest.fixture(params=tuple(dictionaryOEIS.keys()))
371
+ def oeisIDother(request: pytest.FixtureRequest) -> Any:
372
+ """Parametrized fixture providing all other OEIS sequence identifiers.
358
373
 
359
374
  Parameters
360
375
  ----------
@@ -364,7 +379,7 @@ def oeisIDMeanders(request: pytest.FixtureRequest) -> Any:
364
379
  Returns
365
380
  -------
366
381
  sequenceIdentifier : Any
367
- OEIS sequence identifier for testing across all implemented Meanders sequences.
382
+ OEIS sequence identifier for testing across all other sequences.
368
383
 
369
384
  """
370
385
  return request.param
@@ -25,67 +25,48 @@ The `test_writeJobNumba` function shows how to test dynamically generated code,
25
25
  which is useful if you're working with the code synthesis features of the package.
26
26
  """
27
27
 
28
- from mapFolding import countFolds, dictionaryOEISMapFolding, dictionaryOEISMeanders, getFoldsTotalKnown, oeisIDfor_n
29
- from mapFolding.algorithms import oeisIDbyFormula
28
+ from mapFolding import countFolds, dictionaryOEIS, dictionaryOEISMapFolding, getFoldsTotalKnown, oeisIDfor_n
29
+ from mapFolding.basecamp import NOTcountingFolds
30
30
  from mapFolding.dataBaskets import MapFoldingState
31
31
  from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
32
32
  from mapFolding.someAssemblyRequired.toolkitNumba import parametersNumbaLight
33
33
  from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
34
34
  from mapFolding.tests.conftest import registrarRecordsTemporaryFilesystemObject, standardizedEqualToCallableReturn
35
35
  from pathlib import Path, PurePosixPath
36
- from typing import TYPE_CHECKING
37
36
  import importlib.util
38
37
  import multiprocessing
39
38
  import pytest
40
39
 
41
- if TYPE_CHECKING:
42
- from collections.abc import Callable
43
-
44
40
  if __name__ == '__main__':
45
41
  multiprocessing.set_start_method('spawn')
46
42
 
47
- def test_aOFn_calculate_value_mapFolding(oeisID: str) -> None:
48
- """Verify OEIS sequence value calculations against known reference values.
49
-
50
- Tests the `oeisIDfor_n` function by comparing its calculated output against
51
- known correct values from the OEIS database. This ensures that sequence
52
- value computations remain mathematically accurate across code changes.
53
-
54
- The test iterates through validation test cases defined in `settingsOEIS`
55
- for the given OEIS sequence identifier, verifying that each computed value
56
- matches its corresponding known reference value.
43
+ @pytest.mark.parametrize('flow', ['algorithm', 'asynchronous', 'asynchronousTheorem2', 'asynchronousTrimmed', 'numba', 'theorem2', 'theorem2Numba', 'theorem2Trimmed'])
44
+ def test_A007822(flow: str) -> None:
45
+ """Test A007822 flow options.
57
46
 
58
47
  Parameters
59
48
  ----------
60
- oeisID : str
61
- The OEIS sequence identifier to test calculations for.
49
+ flow : str
50
+ The computational flow algorithm to validate.
62
51
 
63
52
  """
64
- for n in dictionaryOEISMapFolding[oeisID]['valuesTestValidation']:
65
- standardizedEqualToCallableReturn(dictionaryOEISMapFolding[oeisID]['valuesKnown'][n], oeisIDfor_n, oeisID, n)
66
-
67
- def test_aOFn_calculate_value_meanders(oeisIDMeanders: str) -> None:
68
- """Verify Meanders OEIS sequence value calculations against known reference values.
53
+ oeisID = 'A007822'
54
+ CPUlimit = .5
69
55
 
70
- Tests the functions in `mapFolding.algorithms.oeisIDbyFormula` by comparing their
71
- calculated output against known correct values from the OEIS database for Meanders IDs.
56
+ oeis_n = 2
57
+ for oeis_n in dictionaryOEIS[oeisID]['valuesTestValidation']:
58
+ if oeis_n < 2:
59
+ continue
72
60
 
73
- Parameters
74
- ----------
75
- oeisIDMeanders : str
76
- The Meanders OEIS sequence identifier to test calculations for.
61
+ expected = dictionaryOEIS[oeisID]['valuesKnown'][oeis_n]
77
62
 
78
- """
79
- oeisIDcallable: Callable[[int], int] = getattr(oeisIDbyFormula, oeisIDMeanders)
80
- for n in dictionaryOEISMeanders[oeisIDMeanders]['valuesTestValidation']:
81
63
  standardizedEqualToCallableReturn(
82
- dictionaryOEISMeanders[oeisIDMeanders]['valuesKnown'][n],
83
- oeisIDcallable,
84
- n,
85
- )
64
+ expected
65
+ , NOTcountingFolds, oeisID, oeis_n, flow, CPUlimit
66
+ )
86
67
 
87
68
  @pytest.mark.parametrize('flow', ['daoOfMapFolding', 'numba', 'theorem2', 'theorem2Numba', 'theorem2Trimmed'])
88
- def test_flowControl(mapShapeTestCountFolds: tuple[int, ...], flow: str) -> None:
69
+ def test_countFolds(mapShapeTestCountFolds: tuple[int, ...], flow: str) -> None:
89
70
  """Validate that different computational flows produce valid results.
90
71
 
91
72
  (AI generated docstring)
@@ -105,40 +86,66 @@ def test_flowControl(mapShapeTestCountFolds: tuple[int, ...], flow: str) -> None
105
86
  The computational flow algorithm to validate.
106
87
 
107
88
  """
108
- standardizedEqualToCallableReturn(getFoldsTotalKnown(mapShapeTestCountFolds), countFolds, None, None, None, None, mapShapeTestCountFolds, None, None, flow)
89
+ standardizedEqualToCallableReturn(getFoldsTotalKnown(mapShapeTestCountFolds), countFolds, None, None, None, None, mapShapeTestCountFolds, flow)
109
90
 
110
- @pytest.mark.parametrize('flow', ['daoOfMapFolding', 'numba', 'theorem2', 'theorem2Numba', 'theorem2Trimmed'])
111
- def test_flowControlByOEISid(oeisID: str, flow: str) -> None:
112
- """Validate that different flow paths using oeisID produce valid results.
91
+ @pytest.mark.parametrize('flow', ['matrixNumPy', 'matrixPandas'])
92
+ def test_meanders(oeisIDmeanders: str, flow: str) -> None:
93
+ """Verify Meanders OEIS sequence value calculations against known reference values.
94
+
95
+ Tests the functions in `mapFolding.algorithms.oeisIDbyFormula` by comparing their
96
+ calculated output against known correct values from the OEIS database for Meanders IDs.
113
97
 
114
98
  Parameters
115
99
  ----------
116
- oeisID : str
117
- The OEIS sequence identifier to test.
118
- flow : str
119
- The computational flow algorithm to validate.
100
+ oeisIDMeanders : str
101
+ The Meanders OEIS sequence identifier to test calculations for.
120
102
 
121
103
  """
122
- listDimensions = None
123
- pathLikeWriteFoldsTotal = None
124
- computationDivisions = None
125
- CPUlimit = None
126
- mapShape = None
104
+ dictionary = dictionaryOEISMapFolding if oeisIDmeanders in dictionaryOEISMapFolding else dictionaryOEIS
105
+ for n in dictionary[oeisIDmeanders]['valuesTestValidation']:
106
+ standardizedEqualToCallableReturn(
107
+ dictionary[oeisIDmeanders]['valuesKnown'][n]
108
+ , NOTcountingFolds, oeisIDmeanders, n, flow, None
109
+ )
127
110
 
128
- oeis_n = 2
129
- for oeis_n in dictionaryOEISMapFolding[oeisID]['valuesTestValidation']:
130
- if oeis_n < 2:
131
- continue
111
+ def test_NOTcountingFolds(oeisIDother: str) -> None:
112
+ """Verify Meanders OEIS sequence value calculations against known reference values.
132
113
 
133
- if oeisID in dictionaryOEISMeanders:
134
- expected = dictionaryOEISMeanders[oeisID]['valuesKnown'][oeis_n]
135
- else:
136
- expected = dictionaryOEISMapFolding[oeisID]['valuesKnown'][oeis_n]
114
+ Tests the functions in `mapFolding.algorithms.oeisIDbyFormula` by comparing their
115
+ calculated output against known correct values from the OEIS database for Meanders IDs.
116
+
117
+ Parameters
118
+ ----------
119
+ oeisIDMeanders : str
120
+ The Meanders OEIS sequence identifier to test calculations for.
137
121
 
122
+ """
123
+ dictionary = dictionaryOEISMapFolding if oeisIDother in dictionaryOEISMapFolding else dictionaryOEIS
124
+ for n in dictionary[oeisIDother]['valuesTestValidation']:
138
125
  standardizedEqualToCallableReturn(
139
- expected
140
- , countFolds, listDimensions, pathLikeWriteFoldsTotal, computationDivisions, CPUlimit, mapShape
141
- , oeisID, oeis_n, flow)
126
+ dictionary[oeisIDother]['valuesKnown'][n]
127
+ , NOTcountingFolds, oeisIDother, n, None, None
128
+ )
129
+
130
+ def test_oeisIDfor_n(oeisIDmapFolding: str) -> None:
131
+ """Verify OEIS sequence value calculations against known reference values.
132
+
133
+ Tests the `oeisIDfor_n` function by comparing its calculated output against
134
+ known correct values from the OEIS database. This ensures that sequence
135
+ value computations remain mathematically accurate across code changes.
136
+
137
+ The test iterates through validation test cases defined in `settingsOEIS`
138
+ for the given OEIS sequence identifier, verifying that each computed value
139
+ matches its corresponding known reference value.
140
+
141
+ Parameters
142
+ ----------
143
+ oeisID : str
144
+ The OEIS sequence identifier to test calculations for.
145
+
146
+ """
147
+ for n in dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestValidation']:
148
+ standardizedEqualToCallableReturn(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesKnown'][n], oeisIDfor_n, oeisIDmapFolding, n)
142
149
 
143
150
  @pytest.mark.parametrize('pathFilename_tmpTesting', ['.py'], indirect=True)
144
151
  def test_writeJobNumba(oneTestCuzTestsOverwritingTests: tuple[int, ...], pathFilename_tmpTesting: Path) -> None:
@@ -35,13 +35,13 @@ import random
35
35
  import re as regex
36
36
  import unittest.mock
37
37
 
38
- def test__validateOEISid_valid_id(oeisID: str) -> None:
39
- standardizedEqualToCallableReturn(oeisID, _standardizeOEISid, oeisID)
38
+ def test__validateOEISid_valid_id(oeisIDmapFolding: str) -> None:
39
+ standardizedEqualToCallableReturn(oeisIDmapFolding, _standardizeOEISid, oeisIDmapFolding)
40
40
 
41
- def test__validateOEISid_valid_id_case_insensitive(oeisID: str) -> None:
42
- standardizedEqualToCallableReturn(oeisID.upper(), _standardizeOEISid, oeisID.lower())
43
- standardizedEqualToCallableReturn(oeisID.upper(), _standardizeOEISid, oeisID.upper())
44
- standardizedEqualToCallableReturn(oeisID.upper(), _standardizeOEISid, oeisID.swapcase())
41
+ def test__validateOEISid_valid_id_case_insensitive(oeisIDmapFolding: str) -> None:
42
+ standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.lower())
43
+ standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.upper())
44
+ standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.swapcase())
45
45
 
46
46
  parameters_test_aOFn_invalid_n = [
47
47
  (-random.randint(1, 100), "randomNegative"), # noqa: S311
@@ -1 +1,4 @@
1
- """I mean, you must write docstrings after you write the code because you don't know what the code will do until after you write it."""
1
+ """I mean, you must write docstrings after you write the code because you don't know what the code will do until after you write it.
2
+
3
+ I strongly suspect this directory will slowly evolve into an entire ecosystem of docstring tools.
4
+ """
@@ -2,38 +2,37 @@
2
2
  from astToolkit import Grab, IfThis, Make, NodeChanger, parsePathFilename2astModule, Then
3
3
  from astToolkit.transformationTools import makeDictionaryFunctionDef
4
4
  from hunterMakesPy import raiseIfNone, writeStringToHere
5
- from mapFolding import dictionaryOEISMapFolding, dictionaryOEISMeanders, packageSettings
5
+ from mapFolding import dictionaryOEIS, dictionaryOEISMapFolding, packageSettings
6
6
  from pathlib import Path
7
7
  import ast
8
8
 
9
+ # ----------------- General Settings ----------------------------------------------------------------------------------
9
10
  sourcePrefix: str = 'zCuzDocStoopid'
10
11
 
11
- pathRoot: Path = packageSettings.pathPackage / "algorithms"
12
-
13
- pathFilenameSource: Path = next(iter(pathRoot.glob(f"{sourcePrefix}*.py"))).absolute()
14
- pathFilenameWrite: Path = pathFilenameSource.with_stem(pathFilenameSource.stem.removeprefix(sourcePrefix))
15
-
16
- astModule: ast.Module = parsePathFilename2astModule(pathFilenameSource)
17
- dictionaryFunctionDef: dict[str, ast.FunctionDef] = makeDictionaryFunctionDef(astModule)
12
+ moduleWarning = "NOTE: This is a generated file; edit the source file."
18
13
 
19
- moduleWarning = """
20
- NOTE: This is a generated file; edit the source file.
21
- """
14
+ def transformOEISidByFormula(pathFilenameSource: Path) -> None:
15
+ """Transform the docstrings of functions corresponding to OEIS sequences."""
16
+ pathFilenameWrite: Path = pathFilenameSource.with_stem(pathFilenameSource.stem.removeprefix(sourcePrefix))
17
+ astModule: ast.Module = parsePathFilename2astModule(pathFilenameSource)
18
+ dictionaryFunctionDef: dict[str, ast.FunctionDef] = makeDictionaryFunctionDef(astModule)
22
19
 
23
- oeisID = 'Error during transformation' # `ast.FunctionDef.name` of function in `pathFilenameSource`.
24
- functionOf: str = 'Error during transformation' # The value of `functionOf` is in the docstring of function `oeisID` in `pathFilenameSource`.
20
+ oeisID = 'Error during transformation' # `ast.FunctionDef.name` of function in `pathFilenameSource`.
21
+ functionOf: str = 'Error during transformation' # The value of `functionOf` is in the docstring of function `oeisID` in `pathFilenameSource`.
25
22
 
26
- for oeisID, FunctionDef in dictionaryFunctionDef.items():
27
- dictionaryOEIS = dictionaryOEISMapFolding if oeisID in dictionaryOEISMapFolding else dictionaryOEISMeanders
28
- functionOf = raiseIfNone(ast.get_docstring(FunctionDef))
23
+ for oeisID, FunctionDef in dictionaryFunctionDef.items():
24
+ if not oeisID.startswith('A') or not oeisID[1:7].isdigit():
25
+ continue
26
+ dictionary = dictionaryOEISMapFolding if oeisID in dictionaryOEISMapFolding else dictionaryOEIS
27
+ functionOf = raiseIfNone(ast.get_docstring(FunctionDef))
29
28
 
30
- ImaDocstring= f"""
29
+ ImaDocstring= f"""
31
30
  Compute {oeisID}(n) as a function of {functionOf}.
32
31
 
33
- *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of {oeisID} is: "{dictionaryOEIS[oeisID]['description']}"
32
+ *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of {oeisID} is: "{dictionary[oeisID]['description']}"
34
33
 
35
- The domain of {oeisID} starts at {dictionaryOEIS[oeisID]['offset']}, therefore for values of `n` < {dictionaryOEIS[oeisID]['offset']}, a(n) is undefined. The smallest value of n for which a(n)
36
- has not yet been computed is {dictionaryOEIS[oeisID]['valueUnknown']}.
34
+ The domain of {oeisID} starts at {dictionary[oeisID]['offset']}, therefore for values of `n` < {dictionary[oeisID]['offset']}, a(n) is undefined. The smallest value of n for which a(n)
35
+ has not yet been computed is {dictionary[oeisID]['valueUnknown']}.
37
36
 
38
37
  Parameters
39
38
  ----------
@@ -43,7 +42,7 @@ for oeisID, FunctionDef in dictionaryFunctionDef.items():
43
42
  Returns
44
43
  -------
45
44
  a(n) : int
46
- {dictionaryOEIS[oeisID]['description']}
45
+ {dictionary[oeisID]['description']}
47
46
 
48
47
  Would You Like to Know More?
49
48
  ----------------------------
@@ -51,13 +50,21 @@ for oeisID, FunctionDef in dictionaryFunctionDef.items():
51
50
  https://oeis.org/{oeisID}
52
51
  """
53
52
 
54
- astExprDocstring = Make.Expr(Make.Constant(ImaDocstring))
53
+ astExprDocstring = Make.Expr(Make.Constant(ImaDocstring))
55
54
 
56
- NodeChanger(
57
- findThis = IfThis.isFunctionDefIdentifier(oeisID)
58
- , doThat = Grab.bodyAttribute(Grab.index(0, Then.replaceWith(astExprDocstring)))
59
- ).visit(astModule)
55
+ NodeChanger(
56
+ findThis = IfThis.isFunctionDefIdentifier(oeisID)
57
+ , doThat = Grab.bodyAttribute(Grab.index(0, Then.replaceWith(astExprDocstring)))
58
+ ).visit(astModule)
60
59
 
61
- ast.fix_missing_locations(astModule)
60
+ ast.fix_missing_locations(astModule)
62
61
 
63
- writeStringToHere((ast.unparse(astModule)+"\n"), pathFilenameWrite)
62
+ docstringModule = raiseIfNone(ast.get_docstring(astModule))
63
+ moduleAsString = ast.unparse(astModule) + "\n"
64
+ moduleAsString = moduleAsString.replace(docstringModule,docstringModule + "\n\n" + moduleWarning)
65
+
66
+ writeStringToHere(moduleAsString, pathFilenameWrite)
67
+
68
+ pathRoot: Path = packageSettings.pathPackage / "algorithms"
69
+ pathFilenameSource: Path = next(iter(pathRoot.glob(f"{sourcePrefix}*.py"))).absolute()
70
+ transformOEISidByFormula(pathFilenameSource)
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: mapFolding
3
+ Version: 0.16.2
4
+ Summary: Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations, and analyze computational states.
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,A000560,A000682,A001010,A001011,A001415,A001416,A001417,A001418,A005315,A005316,A007822,A178961,A195646,A223094,A259702,A301620,AST manipulation,JIT compilation,Numba optimization,OEIS,Python optimization,abstract syntax tree,algorithmic combinatorics,algorithmic optimization,arch configurations,automated code generation,bit-packed arrays,bitwise state machines,cache-efficient algorithms,closed meandric numbers,code generation,code optimization,code synthesis,code transformation,codon optimization,combinatorial computing,combinatorial enumeration,combinatorial geometry,combinatorial mathematics,combinatorial problem solver,combinatorics,computational combinatorics,computational geometry,crossing patterns,curve crossings,dataclass transformation,discrete mathematics,dynamic compilation,enumerative combinatorics,folding pattern enumeration,folding problems,high-performance computing,integer sequences,just-in-time compilation,kernel optimization,labeled stamp folding,low-level computation,map folding,mapFolding,mathematical algorithms,mathematical modeling,mathematical optimization,mathematical patterns,mathematical software,mathematical tool,mathematical visualization,meander enumeration,meanders,meandric systems,memory-efficient enumeration,metaprogramming,numerical algorithms,numerical computation,open meandric systems,paper folding mathematics,parallel computing,pattern recognition,performance optimization,permutation patterns,permutations,post-setup optimization,pyproject,scientific computing,semi-meanders,sequence analysis,sequence calculator,sequence enumeration,sequence explorer,sequence generation,source code analysis,stamp folding,symbolic computation,symmetric foldings,topological combinatorics,topological patterns,typed Python
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 :: MacOS
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3 :: Only
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: Implementation :: CPython
27
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
28
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
29
+ Classifier: Topic :: Software Development :: Code Generators
30
+ Classifier: Topic :: Software Development :: Compilers
31
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
32
+ Classifier: Topic :: Software Development :: Pre-processors
33
+ Classifier: Typing :: Typed
34
+ Requires-Python: >=3.12
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: astToolkit
38
+ Requires-Dist: autoflake
39
+ Requires-Dist: hunterMakesPy
40
+ Requires-Dist: isort
41
+ Requires-Dist: numpy
42
+ Requires-Dist: platformdirs
43
+ Provides-Extra: development
44
+ Requires-Dist: memray; sys_platform == "linux" and extra == "development"
45
+ Requires-Dist: mypy; extra == "development"
46
+ Requires-Dist: pyupgrade; extra == "development"
47
+ Requires-Dist: py-spy; extra == "development"
48
+ Requires-Dist: setuptools-scm; extra == "development"
49
+ Provides-Extra: numba
50
+ Requires-Dist: numba; extra == "numba"
51
+ Requires-Dist: numba_progress; extra == "numba"
52
+ Provides-Extra: pandas
53
+ Requires-Dist: pandas; extra == "pandas"
54
+ Requires-Dist: pyarrow; extra == "pandas"
55
+ Requires-Dist: pyarrow-stubs; extra == "pandas"
56
+ Provides-Extra: testing
57
+ Requires-Dist: numba; extra == "testing"
58
+ Requires-Dist: pandas; extra == "testing"
59
+ Requires-Dist: pyarrow; extra == "testing"
60
+ Requires-Dist: pytest-cov; extra == "testing"
61
+ Requires-Dist: pytest-env; extra == "testing"
62
+ Requires-Dist: pytest-xdist; extra == "testing"
63
+ Requires-Dist: pytest; extra == "testing"
64
+ Dynamic: license-file
65
+
66
+ # mapFolding
67
+
68
+ [![pip install mapFolding](https://img.shields.io/badge/pip%20install-mapFolding-gray.svg?colorB=3b434b)](https://pypi.org/project/mapFolding/)
69
+
70
+ Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations and code optimization.
71
+
72
+ I don't know how to write a README.md. Furthermore, the package used to be focused on multidimensional map folding and tools for transforming the algorithm to experiment with optimizations or to explore the algorithm.
73
+
74
+ First, the tools for transforming algorithms became far more sophisticated and powerful than this package. So I moved them to [astToolkit](https://github.com/hunterhogan/astToolkit). But those got so sophisticated, that I create more than half of that package through another layer of meta-programming: [astToolFactory](https://github.com/hunterhogan/astToolFactory).
75
+
76
+ Second, when I finally understood the connections between map folding and meanders, I added meanders to this package, and applied my transformation tools to that algorithm.
77
+
78
+ I used a weaker form of this package to [compute new terms for OEIS A001415](https://oeis.org/A001415), "Number of ways of folding a 2 X n strip of stamps."
79
+ There are cool and powerful tools in here, but as of 2025 September 17, I am dissatisfied with the organization and documentation. It's annoying.
80
+
81
+ ## Finding stuff
82
+
83
+ 1. At the moment, almost every algorithm version eventually runs through "mapFolding/basecamp.py", so it's sort of an overview and you can work backwards to find more details.
84
+ 2. The directory "mapFolding/algorithms" only has "handmade" algorithms. Therefore, most logic for most computations is based on something in that directory.
85
+ 3. The directory "mapFolding/syntheticModules" has code that is generated by the transformation tools.
86
+ 4. Transformation functions are in "mapFolding/someAssemblyRequired."
87
+ 5. The directory "mapFolding/reference" has "reference" materials.
88
+ 6. "mapFolding/tests" has the tests, and I have tried to make it easy for you to add _your_ versions of the algorithms to the tests. Is it actually easy? I'll say it this way: if you were to create your own subclass of `ast.AST` it would be impossible for you to add your subclass to all of the `ast` module tests with just a few lines of code. In contrast, it is possible to fully test your algorithm with in my tests by adding between three and 25 lines of code. So, yeah, it's easy.
89
+
90
+ ## Math and programming
91
+
92
+ I'm not a mathematician. I don't have training in or professional experience as a programmer. I'm not stupid: I'm ignorant.
93
+
94
+ ## My recovery
95
+
96
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
97
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
98
+
99
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)