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.
- easyRun/A000682.py +25 -0
- easyRun/A005316.py +20 -0
- easyRun/NOTcountingFolds.py +36 -0
- easyRun/__init__.py +0 -0
- easyRun/countFolds.py +41 -0
- easyRun/meanders.py +69 -0
- mapFolding/__init__.py +8 -51
- mapFolding/_dataPacking.py +68 -0
- mapFolding/_theSSOT.py +33 -37
- mapFolding/_theTypes.py +21 -4
- mapFolding/algorithms/matrixMeanders.py +86 -517
- mapFolding/algorithms/matrixMeandersBeDry.py +182 -0
- mapFolding/algorithms/matrixMeandersNumPy.py +333 -0
- mapFolding/algorithms/matrixMeandersPandas.py +334 -0
- mapFolding/algorithms/oeisIDbyFormula.py +50 -29
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +51 -29
- mapFolding/basecamp.py +167 -206
- mapFolding/beDRY.py +2 -30
- mapFolding/dataBaskets.py +75 -49
- mapFolding/oeis.py +11 -32
- mapFolding/reference/A000682facts.py +787 -652
- mapFolding/reference/A005316facts.py +961 -3
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
- mapFolding/reference/matrixMeandersAnalysis/signatures.py +2030 -0
- mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
- mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +3 -4
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +103 -29
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +18 -14
- mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +7 -6
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +3 -4
- mapFolding/someAssemblyRequired/makingModules_count.py +88 -87
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +10 -9
- mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +3 -3
- mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
- mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +63 -0
- mapFolding/someAssemblyRequired/toolkitMakeModules.py +37 -37
- mapFolding/someAssemblyRequired/transformationTools.py +8 -8
- mapFolding/syntheticModules/A007822/algorithm.py +3 -3
- mapFolding/syntheticModules/A007822/algorithmNumba.py +1 -2
- mapFolding/syntheticModules/A007822/asynchronous.py +6 -4
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +5 -7
- mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +70 -0
- mapFolding/syntheticModules/A007822/asynchronousNumba.py +79 -0
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +15 -3
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +12 -3
- mapFolding/syntheticModules/A007822/initializeState.py +1 -2
- mapFolding/syntheticModules/A007822/theorem2.py +7 -2
- mapFolding/syntheticModules/A007822/theorem2Numba.py +31 -4
- mapFolding/syntheticModules/A007822/theorem2Trimmed.py +8 -3
- mapFolding/syntheticModules/countParallelNumba.py +5 -2
- mapFolding/syntheticModules/dataPacking.py +1 -1
- mapFolding/syntheticModules/dataPackingA007822.py +92 -26
- mapFolding/syntheticModules/meanders/__init__.py +1 -0
- mapFolding/syntheticModules/meanders/bigInt.py +52 -0
- mapFolding/syntheticModules/theorem2.py +6 -0
- mapFolding/syntheticModules/theorem2Numba.py +8 -2
- mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
- mapFolding/tests/conftest.py +28 -13
- mapFolding/tests/test_computations.py +68 -61
- mapFolding/tests/test_oeis.py +6 -6
- mapFolding/zCuzDocStoopid/__init__.py +4 -1
- mapFolding/zCuzDocStoopid/makeDocstrings.py +35 -28
- mapfolding-0.16.2.dist-info/METADATA +99 -0
- mapfolding-0.16.2.dist-info/RECORD +115 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/top_level.txt +1 -0
- mapFolding/algorithms/getBucketsTotal.py +0 -137
- mapFolding/reference/matrixMeandersAnalysis/evenEven.py +0 -144
- mapFolding/reference/matrixMeandersAnalysis/oddEven.py +0 -54
- mapFolding/trim_memory.py +0 -62
- mapfolding-0.16.0.dist-info/METADATA +0 -85
- mapfolding-0.16.0.dist-info/RECORD +0 -100
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/WHEEL +0 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/licenses/LICENSE +0 -0
easyRun/A000682.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
# pyright: basic
|
|
3
|
+
from mapFolding.basecamp import NOTcountingFolds
|
|
4
|
+
import sys
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
if sys.version_info >= (3, 14):
|
|
8
|
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
oeisID = 'A000682'
|
|
12
|
+
n=45
|
|
13
|
+
print(NOTcountingFolds(oeisID, n, 'matrixNumPy'))
|
|
14
|
+
|
|
15
|
+
from mapFolding import dictionaryOEIS
|
|
16
|
+
if n < dictionaryOEIS[oeisID]['valueUnknown']:
|
|
17
|
+
print(dictionaryOEIS[oeisID]['valuesKnown'][n])
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
main()
|
|
21
|
+
|
|
22
|
+
r"""
|
|
23
|
+
deactivate && C:\apps\mapFolding\.vtail\Scripts\activate.bat && title good && cls
|
|
24
|
+
title running && start "running" /B /HIGH /wait py -X faulthandler=0 -X tracemalloc=0 -X frozen_modules=on easyRun\A000682.py && title I'm done || title Error
|
|
25
|
+
"""
|
easyRun/A005316.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
# pyright: basic
|
|
3
|
+
from mapFolding.basecamp import NOTcountingFolds
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
|
7
|
+
|
|
8
|
+
n=25
|
|
9
|
+
print(NOTcountingFolds('A005316', n))
|
|
10
|
+
|
|
11
|
+
from mapFolding import dictionaryOEIS
|
|
12
|
+
|
|
13
|
+
if n < dictionaryOEIS['A005316']['valueUnknown']:
|
|
14
|
+
print(dictionaryOEIS['A005316']['valuesKnown'][n])
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
r"""
|
|
18
|
+
deactivate && C:\apps\mapFolding\.vtail\Scripts\activate.bat && title good && cls
|
|
19
|
+
|
|
20
|
+
"""
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
from mapFolding import dictionaryOEIS
|
|
3
|
+
from mapFolding.basecamp import NOTcountingFolds
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
if __name__ == '__main__':
|
|
8
|
+
def _write() -> None:
|
|
9
|
+
sys.stdout.write(
|
|
10
|
+
f"{(match:=countTotal == dictionaryOEIS[oeisID]['valuesKnown'][n])}\t"
|
|
11
|
+
f"\033[{(not match)*91}m"
|
|
12
|
+
f"{n}\t"
|
|
13
|
+
f"{countTotal}\t"
|
|
14
|
+
f"{time.perf_counter() - timeStart:.2f}\t"
|
|
15
|
+
"\033[0m\n"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
CPUlimit: bool | float | int | None = -2
|
|
19
|
+
# oeisID: str | None = None
|
|
20
|
+
oeis_n: int | None = None
|
|
21
|
+
flow: str | None = None
|
|
22
|
+
|
|
23
|
+
oeisID = 'A007822'
|
|
24
|
+
|
|
25
|
+
flow = 'asynchronous'
|
|
26
|
+
flow = 'algorithm'
|
|
27
|
+
flow = 'asynchronousNumba'
|
|
28
|
+
flow = 'theorem2Numba'
|
|
29
|
+
flow = 'asynchronousTrimmed'
|
|
30
|
+
|
|
31
|
+
for n in range(3,9):
|
|
32
|
+
|
|
33
|
+
timeStart = time.perf_counter()
|
|
34
|
+
countTotal = NOTcountingFolds(oeisID, n, flow, CPUlimit)
|
|
35
|
+
|
|
36
|
+
_write()
|
easyRun/__init__.py
ADDED
|
File without changes
|
easyRun/countFolds.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
# pyright: basic
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from mapFolding import countFolds, dictionaryOEISMapFolding
|
|
5
|
+
from os import PathLike
|
|
6
|
+
from pathlib import PurePath
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
if __name__ == '__main__':
|
|
11
|
+
def _write() -> None:
|
|
12
|
+
sys.stdout.write(
|
|
13
|
+
f"{(match:=foldsTotal == dictionaryOEISMapFolding[oeisID]['valuesKnown'][n])}\t"
|
|
14
|
+
f"\033[{(not match)*91}m"
|
|
15
|
+
f"{n}\t"
|
|
16
|
+
f"{foldsTotal}\t"
|
|
17
|
+
f"{time.perf_counter() - timeStart:.2f}\t"
|
|
18
|
+
"\033[0m\n"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
listDimensions: Sequence[int] | None = None
|
|
22
|
+
pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
|
|
23
|
+
computationDivisions: int | str | None = None
|
|
24
|
+
CPUlimit: bool | float | int | None = None
|
|
25
|
+
# mapShape: tuple[int, ...] | None = None
|
|
26
|
+
flow: str | None = 'theorem2Numba'
|
|
27
|
+
|
|
28
|
+
oeisID: str = 'A001415'
|
|
29
|
+
for n in range(3,8):
|
|
30
|
+
|
|
31
|
+
mapShape: tuple[int, ...] = dictionaryOEISMapFolding[oeisID]['getMapShape'](n)
|
|
32
|
+
|
|
33
|
+
timeStart = time.perf_counter()
|
|
34
|
+
foldsTotal: int = countFolds(listDimensions=listDimensions
|
|
35
|
+
, pathLikeWriteFoldsTotal=pathLikeWriteFoldsTotal
|
|
36
|
+
, computationDivisions=computationDivisions
|
|
37
|
+
, CPUlimit=CPUlimit
|
|
38
|
+
, mapShape=mapShape
|
|
39
|
+
, flow=flow)
|
|
40
|
+
|
|
41
|
+
_write()
|
easyRun/meanders.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# ruff: noqa
|
|
2
|
+
# pyright: basic
|
|
3
|
+
from mapFolding import dictionaryOEIS
|
|
4
|
+
from mapFolding.basecamp import NOTcountingFolds
|
|
5
|
+
import gc
|
|
6
|
+
import multiprocessing
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
def write() -> None:
|
|
12
|
+
sys.stdout.write(
|
|
13
|
+
f"{(booleanColor:=(countTotal == dictionaryOEIS[oeisID]['valuesKnown'][n]))}\t"
|
|
14
|
+
f"\033[{(not booleanColor)*91}m"
|
|
15
|
+
f"{n}\t"
|
|
16
|
+
# f"{countTotal}\t"
|
|
17
|
+
# f"{dictionaryOEISMeanders[oeisID]['valuesKnown'][n]}\t"
|
|
18
|
+
f"{time.perf_counter() - timeStart:.2f}\t"
|
|
19
|
+
"\033[0m\n"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if __name__ == '__main__':
|
|
23
|
+
multiprocessing.set_start_method('spawn')
|
|
24
|
+
if sys.version_info >= (3, 14):
|
|
25
|
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
|
26
|
+
|
|
27
|
+
flow = 'matrixMeanders'
|
|
28
|
+
flow = 'matrixPandas'
|
|
29
|
+
flow = 'matrixNumPy'
|
|
30
|
+
|
|
31
|
+
for oeisID in [
|
|
32
|
+
# 'A005316',
|
|
33
|
+
'A000682',
|
|
34
|
+
]:
|
|
35
|
+
sys.stdout.write(f"\n{oeisID}\n")
|
|
36
|
+
|
|
37
|
+
"""TODO Identifiers. improve
|
|
38
|
+
"generate up to four targets."
|
|
39
|
+
1. Adding a new loop.
|
|
40
|
+
2. Dragging up a loop end.
|
|
41
|
+
3. Dragging down a loop end.
|
|
42
|
+
4. Connect ends across the line.
|
|
43
|
+
|
|
44
|
+
flipTheExtra_0b1AsUfunc: what is extra?
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
nList: list[int] = []
|
|
48
|
+
nList.extend(range(2, 10))
|
|
49
|
+
# nList.extend(range(2, 28))
|
|
50
|
+
nList.extend(range(28,33))
|
|
51
|
+
# nList.extend(range(33,38))
|
|
52
|
+
# nList.extend(range(38,43))
|
|
53
|
+
# nList.extend(range(43,45))
|
|
54
|
+
# nList.extend(range(47,57))
|
|
55
|
+
|
|
56
|
+
for n in nList:
|
|
57
|
+
gc.collect()
|
|
58
|
+
timeStart = time.perf_counter()
|
|
59
|
+
countTotal = NOTcountingFolds(oeisID, n, flow)
|
|
60
|
+
if n < dictionaryOEIS[oeisID]['valueUnknown']:
|
|
61
|
+
write()
|
|
62
|
+
else:
|
|
63
|
+
sys.stdout.write(f"{n} {countTotal} {time.perf_counter() - timeStart:.2f}\n")
|
|
64
|
+
|
|
65
|
+
r"""
|
|
66
|
+
deactivate && C:\apps\mapFolding\.vtail\Scripts\activate.bat && title good && cls
|
|
67
|
+
title running && start "meanders" /B /HIGH /wait py -X faulthandler=0 -X tracemalloc=0 -X frozen_modules=on easyRun\meanders.py && title I'm done || title Error
|
|
68
|
+
|
|
69
|
+
"""
|
mapFolding/__init__.py
CHANGED
|
@@ -1,63 +1,24 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
(AI generated docstring)
|
|
4
|
-
|
|
5
|
-
The mapFolding package provides a complete implementation of Lunnon's 1971 algorithm
|
|
6
|
-
for counting distinct folding patterns in multi-dimensional maps. This toolkit
|
|
7
|
-
transforms the complex combinatorial mathematics of map folding into accessible
|
|
8
|
-
computational tools, enabling researchers and practitioners to analyze folding
|
|
9
|
-
patterns across dimensions from simple 2D strips to complex multi-dimensional
|
|
10
|
-
hypercubes.
|
|
11
|
-
|
|
12
|
-
The package architecture follows Domain-Driven Design principles, organizing
|
|
13
|
-
functionality around mathematical concepts rather than implementation details.
|
|
14
|
-
The computational framework integrates type safety, persistent result storage,
|
|
15
|
-
and mathematical validation through OEIS sequence integration.
|
|
16
|
-
|
|
17
|
-
Core Transformation Tools:
|
|
18
|
-
countFolds: Primary interface for computing folding pattern counts
|
|
19
|
-
MapFoldingState: Computational state management for recursive analysis
|
|
20
|
-
Connection graph generation: Mathematical foundation for folding relationships
|
|
21
|
-
Task division utilities: Experimental parallel computation options
|
|
22
|
-
OEIS integration: Mathematical validation and sequence discovery
|
|
23
|
-
|
|
24
|
-
Primary Use Cases:
|
|
25
|
-
Mathematical research into folding pattern properties and relationships
|
|
26
|
-
Educational exploration of combinatorial mathematics concepts
|
|
27
|
-
Computational validation of theoretical results
|
|
28
|
-
Extension of known mathematical sequences through new discoveries
|
|
29
|
-
|
|
30
|
-
The package handles the full spectrum of map folding analysis, from simple
|
|
31
|
-
educational examples to research-grade computations requiring multi-day processing
|
|
32
|
-
time. Results integrate seamlessly with the mathematical community through
|
|
33
|
-
comprehensive OEIS connectivity and standardized result persistence.
|
|
34
|
-
|
|
35
|
-
For researchers: The computational foundation supports both replication of
|
|
36
|
-
established results and discovery of new mathematical relationships.
|
|
37
|
-
|
|
38
|
-
For educators: The clear interfaces and type safety enable confident exploration
|
|
39
|
-
of combinatorial concepts without computational complexity barriers.
|
|
40
|
-
|
|
41
|
-
For practitioners: The robust result persistence and type safety ensure
|
|
42
|
-
reliable completion of complex analytical tasks.
|
|
43
|
-
"""
|
|
1
|
+
"""Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations, and analyze computational states."""
|
|
44
2
|
|
|
45
3
|
from mapFolding._theTypes import (
|
|
46
4
|
Array1DElephino as Array1DElephino,
|
|
47
5
|
Array1DFoldsTotal as Array1DFoldsTotal,
|
|
48
6
|
Array1DLeavesTotal as Array1DLeavesTotal,
|
|
49
7
|
Array3DLeavesTotal as Array3DLeavesTotal,
|
|
8
|
+
axisOfLength as axisOfLength,
|
|
50
9
|
DatatypeElephino as DatatypeElephino,
|
|
51
10
|
DatatypeFoldsTotal as DatatypeFoldsTotal,
|
|
52
11
|
DatatypeLeavesTotal as DatatypeLeavesTotal,
|
|
12
|
+
MetadataOEISid as MetadataOEISid,
|
|
13
|
+
MetadataOEISidManuallySet as MetadataOEISidManuallySet,
|
|
53
14
|
MetadataOEISidMapFolding as MetadataOEISidMapFolding,
|
|
54
15
|
MetadataOEISidMapFoldingManuallySet as MetadataOEISidMapFoldingManuallySet,
|
|
55
|
-
MetadataOEISidMeanders as MetadataOEISidMeanders,
|
|
56
|
-
MetadataOEISidMeandersManuallySet as MetadataOEISidMeandersManuallySet,
|
|
57
16
|
NumPyElephino as NumPyElephino,
|
|
58
17
|
NumPyFoldsTotal as NumPyFoldsTotal,
|
|
59
18
|
NumPyIntegerType as NumPyIntegerType,
|
|
60
|
-
NumPyLeavesTotal as NumPyLeavesTotal
|
|
19
|
+
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
20
|
+
ShapeArray as ShapeArray,
|
|
21
|
+
ShapeSlicer as ShapeSlicer)
|
|
61
22
|
|
|
62
23
|
from mapFolding._theSSOT import packageSettings as packageSettings
|
|
63
24
|
|
|
@@ -69,10 +30,6 @@ from mapFolding.beDRY import (
|
|
|
69
30
|
setProcessorLimit as setProcessorLimit,
|
|
70
31
|
validateListDimensions as validateListDimensions)
|
|
71
32
|
|
|
72
|
-
from mapFolding.dataBaskets import (
|
|
73
|
-
MapFoldingState as MapFoldingState,
|
|
74
|
-
MatrixMeandersState as MatrixMeandersState)
|
|
75
|
-
|
|
76
33
|
from mapFolding.filesystemToolkit import (
|
|
77
34
|
getFilenameFoldsTotal as getFilenameFoldsTotal,
|
|
78
35
|
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
|
@@ -83,8 +40,8 @@ from mapFolding.filesystemToolkit import (
|
|
|
83
40
|
from mapFolding.basecamp import countFolds as countFolds
|
|
84
41
|
|
|
85
42
|
from mapFolding.oeis import (
|
|
43
|
+
dictionaryOEIS as dictionaryOEIS,
|
|
86
44
|
dictionaryOEISMapFolding as dictionaryOEISMapFolding,
|
|
87
|
-
dictionaryOEISMeanders as dictionaryOEISMeanders,
|
|
88
45
|
getFoldsTotalKnown as getFoldsTotalKnown,
|
|
89
46
|
getOEISids as getOEISids,
|
|
90
47
|
OEIS_for_n as OEIS_for_n,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
3
|
+
from typing import Any
|
|
4
|
+
import astToolkit
|
|
5
|
+
import dataclasses
|
|
6
|
+
import functools
|
|
7
|
+
import inspect
|
|
8
|
+
|
|
9
|
+
r"""Notes
|
|
10
|
+
Goal: create a decorator, `unRePackMapFoldingState`, that will unpack `MapFoldingState`, pass only the parameters in the decorated function, receive the
|
|
11
|
+
values returned by the function, and repack `MapFoldingState`.
|
|
12
|
+
|
|
13
|
+
You must use dynamic programming. If the datatype or the field name changes, for example, that should not affect the decorator.
|
|
14
|
+
|
|
15
|
+
To use in, for example, C:\apps\mapFolding\mapFolding\syntheticModules\A007822\theorem2Numba.py. Analogous to
|
|
16
|
+
`Z0Z_tools.waveformSpectrogramWaveform`, see
|
|
17
|
+
https://github.com/hunterhogan/Z0Z_tools/blob/2c393c2831382dfe6f3e742cf56db39e71126cbc/Z0Z_tools/ioAudio.py
|
|
18
|
+
|
|
19
|
+
For examples of manipulating `dataclasses`, see also:
|
|
20
|
+
C:\apps\mapFolding\mapFolding\someAssemblyRequired\_toolkitContainers.py and
|
|
21
|
+
C:\apps\mapFolding\mapFolding\someAssemblyRequired\transformationTools.py
|
|
22
|
+
|
|
23
|
+
- `TypeVar` may be useful.
|
|
24
|
+
|
|
25
|
+
- `dataclasses` has inspection tools.
|
|
26
|
+
|
|
27
|
+
- `return MapFoldingState(...` Check if the field is init=True
|
|
28
|
+
|
|
29
|
+
Prototype. Eventual home will probably be "beDry.py".
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def unRePackMapFoldingState[CallableTargetType: Callable[..., Any]](callableTarget: CallableTargetType) -> Callable[[MapFoldingState], MapFoldingState]:
|
|
33
|
+
signatureTargetFunction: inspect.Signature = inspect.signature(callableTarget)
|
|
34
|
+
parametersTargetFunction: list[str] = list(signatureTargetFunction.parameters.keys())
|
|
35
|
+
|
|
36
|
+
fieldsMapFoldingState: tuple[dataclasses.Field[Any], ...] = dataclasses.fields(MapFoldingState)
|
|
37
|
+
|
|
38
|
+
fieldsInitializable: dict[str, dataclasses.Field[Any]] = {field.name: field for field in fieldsMapFoldingState if field.init}
|
|
39
|
+
|
|
40
|
+
@functools.wraps(callableTarget)
|
|
41
|
+
def decoratedFunction(mapFoldingStateInstance: MapFoldingState, **additionalKeywordArguments: Any) -> MapFoldingState:
|
|
42
|
+
dataclassAsDict: dict[str, Any] = dataclasses.asdict(mapFoldingStateInstance)
|
|
43
|
+
|
|
44
|
+
argumentsForTargetFunction: list[Any] = []
|
|
45
|
+
for parameterName in parametersTargetFunction:
|
|
46
|
+
if parameterName in dataclassAsDict:
|
|
47
|
+
argumentsForTargetFunction.append(dataclassAsDict[parameterName])
|
|
48
|
+
elif parameterName in additionalKeywordArguments:
|
|
49
|
+
argumentsForTargetFunction.append(additionalKeywordArguments[parameterName])
|
|
50
|
+
else:
|
|
51
|
+
errorMessage = f"Parameter '{parameterName}' not found in MapFoldingState or additional arguments"
|
|
52
|
+
raise ValueError(errorMessage)
|
|
53
|
+
|
|
54
|
+
returnedFromTargetFunction: Any = callableTarget(*argumentsForTargetFunction)
|
|
55
|
+
|
|
56
|
+
argumentsForMapFoldingStateConstructor: dict[str, Any] = {fieldName: dataclassAsDict[fieldName] for fieldName in fieldsInitializable}
|
|
57
|
+
|
|
58
|
+
if len(parametersTargetFunction) == 1:
|
|
59
|
+
singleParameterName: str = parametersTargetFunction[0]
|
|
60
|
+
if singleParameterName in fieldsInitializable:
|
|
61
|
+
argumentsForMapFoldingStateConstructor[singleParameterName] = returnedFromTargetFunction
|
|
62
|
+
elif isinstance(returnedFromTargetFunction, tuple) and len(returnedFromTargetFunction) == len(parametersTargetFunction):
|
|
63
|
+
updatedFieldsFromReturn: dict[str, Any] = {parameterName: returnedValue for parameterName, returnedValue in zip(parametersTargetFunction, returnedFromTargetFunction, strict=True) if parameterName in fieldsInitializable}
|
|
64
|
+
argumentsForMapFoldingStateConstructor.update(updatedFieldsFromReturn)
|
|
65
|
+
|
|
66
|
+
return MapFoldingState(**argumentsForMapFoldingStateConstructor)
|
|
67
|
+
|
|
68
|
+
return decoratedFunction
|
mapFolding/_theSSOT.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Access and configure package settings and metadata."""
|
|
2
2
|
|
|
3
3
|
from hunterMakesPy import PackageSettings
|
|
4
|
-
from mapFolding._theTypes import
|
|
4
|
+
from mapFolding._theTypes import MetadataOEISidManuallySet, MetadataOEISidMapFoldingManuallySet
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
import dataclasses
|
|
7
7
|
import random
|
|
@@ -27,14 +27,14 @@ class mapFoldingPackageSettings(PackageSettings):
|
|
|
27
27
|
Package identifier for concurrent execution operations.
|
|
28
28
|
OEISidMapFoldingManuallySet : dict[str, MetadataOEISidMapFoldingManuallySet]
|
|
29
29
|
Settings that are best selected by a human instead of algorithmically.
|
|
30
|
-
|
|
30
|
+
OEISidManuallySet : dict[str, MetadataOEISidMeandersManuallySet]
|
|
31
31
|
Settings that are best selected by a human instead of algorithmically for meander sequences.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
34
|
OEISidMapFoldingManuallySet: dict[str, MetadataOEISidMapFoldingManuallySet] = dataclasses.field(default_factory=dict[str, MetadataOEISidMapFoldingManuallySet])
|
|
35
35
|
"""Settings that are best selected by a human instead of algorithmically."""
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
OEISidManuallySet: dict[str, MetadataOEISidManuallySet] = dataclasses.field(default_factory=dict[str, MetadataOEISidManuallySet])
|
|
38
38
|
"""Settings that are best selected by a human instead of algorithmically for meander sequences."""
|
|
39
39
|
|
|
40
40
|
cacheDays: int = 30
|
|
@@ -42,50 +42,44 @@ class mapFoldingPackageSettings(PackageSettings):
|
|
|
42
42
|
|
|
43
43
|
concurrencyPackage: str = 'multiprocessing'
|
|
44
44
|
"""Package identifier for concurrent execution operations."""
|
|
45
|
-
|
|
45
|
+
# ruff: noqa: S311
|
|
46
46
|
# TODO I made a `TypedDict` before I knew how to make dataclasses and classes. Think about other data structures.
|
|
47
47
|
OEISidMapFoldingManuallySet: dict[str, MetadataOEISidMapFoldingManuallySet] = {
|
|
48
48
|
'A000136': {
|
|
49
49
|
'getMapShape': lambda n: (1, n),
|
|
50
50
|
'valuesBenchmark': [14],
|
|
51
|
-
'valuesTestParallelization': [
|
|
52
|
-
'valuesTestValidation': [random.randint(2, 9)],
|
|
51
|
+
'valuesTestParallelization': [random.randint(3, 7)],
|
|
52
|
+
'valuesTestValidation': [random.randint(2, 9)],
|
|
53
53
|
},
|
|
54
54
|
'A001415': {
|
|
55
55
|
'getMapShape': lambda n: (2, n),
|
|
56
56
|
'valuesBenchmark': [14],
|
|
57
|
-
'valuesTestParallelization': [
|
|
58
|
-
'valuesTestValidation': [random.randint(2, 9)],
|
|
57
|
+
'valuesTestParallelization': [random.randint(3, 7)],
|
|
58
|
+
'valuesTestValidation': [random.randint(2, 9)],
|
|
59
59
|
},
|
|
60
60
|
'A001416': {
|
|
61
61
|
'getMapShape': lambda n: (3, n),
|
|
62
62
|
'valuesBenchmark': [9],
|
|
63
|
-
'valuesTestParallelization': [
|
|
64
|
-
'valuesTestValidation': [random.randint(2, 6)],
|
|
63
|
+
'valuesTestParallelization': [random.randint(3, 5)],
|
|
64
|
+
'valuesTestValidation': [random.randint(2, 6)],
|
|
65
65
|
},
|
|
66
66
|
'A001417': {
|
|
67
67
|
'getMapShape': lambda n: tuple(2 for _dimension in range(n)),
|
|
68
68
|
'valuesBenchmark': [6],
|
|
69
|
-
'valuesTestParallelization': [
|
|
70
|
-
'valuesTestValidation': [random.randint(2, 4)],
|
|
69
|
+
'valuesTestParallelization': [random.randint(2, 4)],
|
|
70
|
+
'valuesTestValidation': [random.randint(2, 4)],
|
|
71
71
|
},
|
|
72
72
|
'A195646': {
|
|
73
73
|
'getMapShape': lambda n: tuple(3 for _dimension in range(n)),
|
|
74
74
|
'valuesBenchmark': [3],
|
|
75
|
-
'valuesTestParallelization': [
|
|
75
|
+
'valuesTestParallelization': [2],
|
|
76
76
|
'valuesTestValidation': [2],
|
|
77
77
|
},
|
|
78
78
|
'A001418': {
|
|
79
79
|
'getMapShape': lambda n: (n, n),
|
|
80
80
|
'valuesBenchmark': [5],
|
|
81
81
|
'valuesTestParallelization': [*range(2, 4)],
|
|
82
|
-
'valuesTestValidation': [random.randint(2, 4)],
|
|
83
|
-
},
|
|
84
|
-
'A007822': {
|
|
85
|
-
'getMapShape': lambda n: (1, 2 * n),
|
|
86
|
-
'valuesBenchmark': [7],
|
|
87
|
-
'valuesTestParallelization': [*range(2, 4)],
|
|
88
|
-
'valuesTestValidation': [random.randint(2, 8)], # noqa: S311
|
|
82
|
+
'valuesTestValidation': [random.randint(2, 4)],
|
|
89
83
|
},
|
|
90
84
|
}
|
|
91
85
|
|
|
@@ -95,29 +89,31 @@ identifierPackageFALLBACK = "mapFolding"
|
|
|
95
89
|
packageSettings = mapFoldingPackageSettings(identifierPackageFALLBACK=identifierPackageFALLBACK, OEISidMapFoldingManuallySet=OEISidMapFoldingManuallySet)
|
|
96
90
|
"""Global package settings."""
|
|
97
91
|
|
|
98
|
-
# TODO integrate into packageSettings
|
|
99
|
-
pathCache: Path = packageSettings.pathPackage / ".cache"
|
|
100
92
|
"""Local directory path for storing cached OEIS sequence data and metadata."""
|
|
101
|
-
|
|
102
|
-
'A000560': {'valuesTestValidation': [
|
|
103
|
-
'A000682': {'valuesTestValidation': [
|
|
104
|
-
'A001010': {'valuesTestValidation': [
|
|
105
|
-
'A001011': {'valuesTestValidation': [
|
|
106
|
-
'A005315': {'valuesTestValidation': [
|
|
107
|
-
'A005316': {'valuesTestValidation': [
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
'
|
|
93
|
+
OEISidManuallySet: dict[str, MetadataOEISidManuallySet] = {
|
|
94
|
+
'A000560': {'valuesTestValidation': [random.randint(3, 12)]},
|
|
95
|
+
'A000682': {'valuesTestValidation': [random.randint(3, 12), 32]},
|
|
96
|
+
'A001010': {'valuesTestValidation': [3, 4, random.randint(5, 11)]},
|
|
97
|
+
'A001011': {'valuesTestValidation': [3, 4, random.randint(5, 7)]},
|
|
98
|
+
'A005315': {'valuesTestValidation': [random.randint(3, 9)]},
|
|
99
|
+
'A005316': {'valuesTestValidation': [random.randint(3, 13)]},
|
|
100
|
+
'A007822': {'valuesTestValidation': [random.randint(2, 8)]}, #, 'valuesBenchmark': [7], 'valuesTestParallelization': [*range(2, 4)]},
|
|
101
|
+
'A060206': {'valuesTestValidation': [random.randint(3, 9)]},
|
|
102
|
+
'A077460': {'valuesTestValidation': [3, 4, random.randint(5, 8)]},
|
|
103
|
+
'A078591': {'valuesTestValidation': [random.randint(3, 10)]},
|
|
104
|
+
'A178961': {'valuesTestValidation': [random.randint(3, 11)]},
|
|
105
|
+
'A223094': {'valuesTestValidation': [random.randint(3, 11)]},
|
|
106
|
+
'A259702': {'valuesTestValidation': [random.randint(3, 13)]},
|
|
107
|
+
'A301620': {'valuesTestValidation': [random.randint(3, 11)]},
|
|
115
108
|
}
|
|
116
109
|
|
|
117
110
|
# Recreate packageSettings with meanders settings included
|
|
118
111
|
packageSettings = mapFoldingPackageSettings(
|
|
119
112
|
identifierPackageFALLBACK=identifierPackageFALLBACK,
|
|
120
113
|
OEISidMapFoldingManuallySet=OEISidMapFoldingManuallySet,
|
|
121
|
-
|
|
114
|
+
OEISidManuallySet=OEISidManuallySet,
|
|
122
115
|
)
|
|
123
116
|
"""Global package settings."""
|
|
117
|
+
|
|
118
|
+
# TODO integrate into packageSettings
|
|
119
|
+
pathCache: Path = packageSettings.pathPackage / ".cache"
|
mapFolding/_theTypes.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from numpy import dtype, int_ as numpy_int, integer, ndarray, uint64 as numpy_uint64
|
|
5
|
-
from
|
|
5
|
+
from types import EllipsisType
|
|
6
|
+
from typing import Any, Final, NamedTuple, TypeAlias, TypedDict, TypeVar
|
|
6
7
|
|
|
7
8
|
NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
|
|
8
9
|
"""Any NumPy integer type, which is usually between 8-bit signed and 64-bit unsigned."""
|
|
@@ -65,7 +66,7 @@ class MetadataOEISidMapFoldingManuallySet(TypedDict):
|
|
|
65
66
|
"""List of index values, 'n', to use when testing validation performance."""
|
|
66
67
|
|
|
67
68
|
class MetadataOEISidMapFolding(TypedDict):
|
|
68
|
-
"""Settings for an
|
|
69
|
+
"""Settings for an OEIS ID that may be computed by a multidimensional map folding algorithm."""
|
|
69
70
|
|
|
70
71
|
description: str
|
|
71
72
|
"""The OEIS.org description of the integer sequence."""
|
|
@@ -85,7 +86,7 @@ class MetadataOEISidMapFolding(TypedDict):
|
|
|
85
86
|
"""The smallest value of 'n' for for which `foldsTotal` is unknown."""
|
|
86
87
|
|
|
87
88
|
# ruff: noqa: ERA001
|
|
88
|
-
class
|
|
89
|
+
class MetadataOEISidManuallySet(TypedDict):
|
|
89
90
|
"""Settings that are best selected by a human instead of algorithmically."""
|
|
90
91
|
|
|
91
92
|
# valuesBenchmark: list[int]
|
|
@@ -95,7 +96,7 @@ class MetadataOEISidMeandersManuallySet(TypedDict):
|
|
|
95
96
|
valuesTestValidation: list[int]
|
|
96
97
|
"""List of index values, 'n', to use when testing validation performance."""
|
|
97
98
|
|
|
98
|
-
class
|
|
99
|
+
class MetadataOEISid(TypedDict):
|
|
99
100
|
"""Settings for an implemented OEIS sequence."""
|
|
100
101
|
|
|
101
102
|
description: str
|
|
@@ -112,3 +113,19 @@ class MetadataOEISidMeanders(TypedDict):
|
|
|
112
113
|
"""List of index values, 'n', to use when testing validation performance."""
|
|
113
114
|
valueUnknown: int
|
|
114
115
|
"""The smallest value of 'n' for for which `foldsTotal` is unknown."""
|
|
116
|
+
|
|
117
|
+
# TODO Figure out how to have a SSOT for the axis order.
|
|
118
|
+
axisOfLength: Final[int] = 0
|
|
119
|
+
|
|
120
|
+
class ShapeArray(NamedTuple):
|
|
121
|
+
"""Always use this to construct arrays, so you can reorder the axes merely by reordering this class."""
|
|
122
|
+
|
|
123
|
+
length: int
|
|
124
|
+
indices: int
|
|
125
|
+
|
|
126
|
+
class ShapeSlicer(NamedTuple):
|
|
127
|
+
"""Always use this to construct slicers, so you can reorder the axes merely by reordering this class."""
|
|
128
|
+
|
|
129
|
+
length: EllipsisType | slice
|
|
130
|
+
indices: int
|
|
131
|
+
|