mapFolding 0.16.1__py3-none-any.whl → 0.16.4__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 +1 -1
- easyRun/A005316.py +2 -3
- easyRun/NOTcountingFolds.py +6 -5
- easyRun/countFolds.py +1 -1
- easyRun/generateAllModules.py +14 -0
- easyRun/meanders.py +16 -18
- mapFolding/__init__.py +1 -0
- mapFolding/_theSSOT.py +3 -2
- mapFolding/_theTypes.py +3 -0
- mapFolding/algorithms/A086345.py +75 -0
- mapFolding/algorithms/matrixMeanders.py +15 -28
- mapFolding/algorithms/matrixMeandersBeDry.py +34 -116
- mapFolding/algorithms/matrixMeandersNumPy.py +117 -70
- mapFolding/algorithms/matrixMeandersPandas.py +113 -130
- mapFolding/algorithms/oeisIDbyFormula.py +25 -14
- mapFolding/algorithms/symmetricFolds.py +36 -0
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +26 -12
- mapFolding/basecamp.py +152 -323
- mapFolding/dataBaskets.py +136 -34
- mapFolding/filesystemToolkit.py +4 -32
- mapFolding/oeis.py +5 -12
- mapFolding/reference/A000682facts.py +785 -1264
- mapFolding/reference/A005316facts.py +958 -923
- mapFolding/reference/A086345Wu.py +25 -0
- mapFolding/reference/matrixMeandersAnalysis/signatures.py +2033 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +9 -44
- mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +39 -136
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +44 -45
- mapFolding/someAssemblyRequired/RecipeJob.py +78 -18
- mapFolding/someAssemblyRequired/__init__.py +3 -8
- mapFolding/someAssemblyRequired/_toolkitContainers.py +32 -3
- mapFolding/someAssemblyRequired/infoBooth.py +40 -23
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +75 -154
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +56 -88
- mapFolding/someAssemblyRequired/makingModules_count.py +91 -85
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +7 -65
- mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +25 -31
- mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +14 -13
- mapFolding/someAssemblyRequired/toolkitMakeModules.py +10 -10
- mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
- mapFolding/someAssemblyRequired/transformationTools.py +17 -19
- mapFolding/syntheticModules/A007822/algorithm.py +46 -50
- mapFolding/syntheticModules/A007822/asynchronous.py +93 -34
- mapFolding/syntheticModules/A007822/initializeState.py +15 -21
- mapFolding/syntheticModules/A007822/theorem2.py +21 -21
- mapFolding/syntheticModules/A007822/theorem2Numba.py +42 -23
- mapFolding/syntheticModules/A007822/theorem2Trimmed.py +21 -21
- mapFolding/syntheticModules/countParallelNumba.py +3 -7
- mapFolding/syntheticModules/daoOfMapFoldingNumba.py +3 -6
- mapFolding/syntheticModules/meanders/bigInt.py +15 -25
- mapFolding/syntheticModules/theorem2.py +6 -0
- mapFolding/syntheticModules/theorem2Numba.py +26 -2
- mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
- mapFolding/tests/test_computations.py +1 -1
- mapFolding/zCuzDocStoopid/makeDocstrings.py +2 -0
- {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/METADATA +4 -1
- mapfolding-0.16.4.dist-info/RECORD +106 -0
- mapFolding/_dataPacking.py +0 -68
- mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
- mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
- mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
- mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
- mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
- mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
- mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -85
- mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -52
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -53
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -47
- mapFolding/syntheticModules/dataPacking.py +0 -28
- mapFolding/syntheticModules/dataPackingA007822.py +0 -92
- mapfolding-0.16.1.dist-info/RECORD +0 -114
- /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
- {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/WHEEL +0 -0
- {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/top_level.txt +0 -0
|
@@ -1,54 +1,19 @@
|
|
|
1
1
|
from astToolkit import extractFunctionDef, Make # noqa: D100
|
|
2
2
|
from hunterMakesPy import raiseIfNone
|
|
3
|
-
from mapFolding.someAssemblyRequired import
|
|
4
|
-
|
|
5
|
-
identifierDataclassInstanceDEFAULT, logicalPathInfixDEFAULT)
|
|
3
|
+
from mapFolding.someAssemblyRequired import defaultA007822
|
|
4
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import getModule
|
|
6
5
|
import ast
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
identifierCounting: str = identifierCountingDEFAULT
|
|
10
|
-
logicalPathInfixA007822: str = logicalPathInfixDEFAULT + '.A007822'
|
|
11
|
-
sourceCallableDispatcherA007822: str = identifierCallableSourceDispatcherDEFAULT
|
|
12
|
-
sourceCallableIdentifierA007822: str = identifierCallableSourceDEFAULT
|
|
7
|
+
FunctionDef_filterAsymmetricFolds: ast.FunctionDef = raiseIfNone(extractFunctionDef(getModule(logicalPathInfix='algorithms', identifierModule='symmetricFolds'), defaultA007822['function']['filterAsymmetricFolds']))
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
ImaString = f"""
|
|
17
|
-
def {identifier_filterAsymmetricFolds}({identifierDataclass}: MapFoldingState) -> MapFoldingState:
|
|
18
|
-
{identifierDataclass}.indexLeaf = 0
|
|
19
|
-
leafConnectee = 0
|
|
20
|
-
while leafConnectee < {identifierDataclass}.leavesTotal + 1:
|
|
21
|
-
leafNumber = int({identifierDataclass}.leafBelow[{identifierDataclass}.indexLeaf])
|
|
22
|
-
{identifierDataclass}.leafComparison[leafConnectee] = (leafNumber - {identifierDataclass}.indexLeaf + {identifierDataclass}.leavesTotal) % {identifierDataclass}.leavesTotal
|
|
23
|
-
{identifierDataclass}.indexLeaf = leafNumber
|
|
24
|
-
leafConnectee += 1
|
|
25
|
-
|
|
26
|
-
indexInMiddle = {identifierDataclass}.leavesTotal // 2
|
|
27
|
-
{identifierDataclass}.indexMiniGap = 0
|
|
28
|
-
while {identifierDataclass}.indexMiniGap < {identifierDataclass}.leavesTotal + 1:
|
|
29
|
-
ImaSymmetricFold = True
|
|
30
|
-
leafConnectee = 0
|
|
31
|
-
while leafConnectee < indexInMiddle:
|
|
32
|
-
if {identifierDataclass}.leafComparison[({identifierDataclass}.indexMiniGap + leafConnectee) % ({identifierDataclass}.leavesTotal + 1)] != {identifierDataclass}.leafComparison[({identifierDataclass}.indexMiniGap + {identifierDataclass}.leavesTotal - 1 - leafConnectee) % ({identifierDataclass}.leavesTotal + 1)]:
|
|
33
|
-
ImaSymmetricFold = False
|
|
34
|
-
break
|
|
35
|
-
leafConnectee += 1
|
|
36
|
-
{identifierDataclass}.{identifierCounting} += ImaSymmetricFold
|
|
37
|
-
{identifierDataclass}.indexMiniGap += 1
|
|
38
|
-
|
|
39
|
-
return {identifierDataclass}
|
|
40
|
-
""" # noqa: E501
|
|
41
|
-
|
|
42
|
-
FunctionDef_filterAsymmetricFolds: ast.FunctionDef = raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_filterAsymmetricFolds))
|
|
43
|
-
del ImaString
|
|
44
|
-
|
|
45
|
-
ImaString = f"{identifierDataclass} = {identifier_filterAsymmetricFolds}({identifierDataclass})"
|
|
9
|
+
ImaString: str = f"{defaultA007822['variable']['stateInstance']} = {defaultA007822['function']['filterAsymmetricFolds']}({defaultA007822['variable']['stateInstance']})"
|
|
46
10
|
A007822incrementCount = ast.parse(ImaString).body[0]
|
|
47
11
|
del ImaString
|
|
48
12
|
|
|
49
|
-
ImaString = f'{
|
|
50
|
-
A007822adjustFoldsTotal = ast.parse(ImaString).body[0]
|
|
13
|
+
ImaString = f'{defaultA007822['variable']['stateInstance']}.{defaultA007822['variable']['counting']} = ({defaultA007822['variable']['stateInstance']}.{defaultA007822['variable']['counting']} + 1) // 2'
|
|
14
|
+
A007822adjustFoldsTotal: ast.stmt = ast.parse(ImaString).body[0]
|
|
51
15
|
del ImaString
|
|
52
16
|
|
|
53
|
-
|
|
54
|
-
|
|
17
|
+
ExprCallFilterAsymmetricFolds_leafBelow: ast.Expr = Make.Expr(Make.Call(Make.Name(defaultA007822['function']['filterAsymmetricFolds']), listParameters=[Make.Name('leafBelow')]))
|
|
18
|
+
ExprCallFilterAsymmetricFoldsState: ast.Expr = Make.Expr(Make.Call(Make.Name(defaultA007822['function']['filterAsymmetricFolds']), listParameters=[Make.Name(defaultA007822['variable']['stateInstance'])]))
|
|
19
|
+
ExprCallFilterAsymmetricFoldsStateDot_leafBelow: ast.Expr = Make.Expr(Make.Call(Make.Name(defaultA007822['function']['filterAsymmetricFolds']), listParameters=[Make.Attribute(Make.Name(defaultA007822['variable']['stateInstance']), 'leafBelow')]))
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# NOTE The real module is generated from this incomplete module. Comments are not preserved.
|
|
2
|
+
# ruff: noqa: PLW0603
|
|
3
|
+
from copy import deepcopy
|
|
4
|
+
from mapFolding import DatatypeFoldsTotal
|
|
5
|
+
from mapFolding.dataBaskets import SymmetricFoldsState
|
|
6
|
+
from queue import Queue
|
|
7
|
+
from threading import Lock, Thread
|
|
8
|
+
|
|
9
|
+
listThreads: list[Thread] = []
|
|
10
|
+
queueFutures: Queue[SymmetricFoldsState] = Queue()
|
|
11
|
+
symmetricFoldsTotal: int = 0
|
|
12
|
+
LOCKsymmetricFoldsTotal = Lock()
|
|
13
|
+
# TODO There isn't a better way to do this?
|
|
14
|
+
STOPsignal = object()
|
|
15
|
+
|
|
16
|
+
def initializeConcurrencyManager(maxWorkers: int, symmetricFolds: int=0) -> None:
|
|
17
|
+
global listThreads, symmetricFoldsTotal, queueFutures
|
|
18
|
+
listThreads = []
|
|
19
|
+
queueFutures = Queue()
|
|
20
|
+
symmetricFoldsTotal = symmetricFolds
|
|
21
|
+
|
|
22
|
+
indexThread = 0
|
|
23
|
+
while indexThread < maxWorkers:
|
|
24
|
+
thread = Thread(target=_threadDoesSomething, name=f"thread{indexThread}", daemon=True)
|
|
25
|
+
thread.start()
|
|
26
|
+
listThreads.append(thread)
|
|
27
|
+
indexThread += 1
|
|
28
|
+
|
|
29
|
+
def _threadDoesSomething() -> None:
|
|
30
|
+
global symmetricFoldsTotal
|
|
31
|
+
while True:
|
|
32
|
+
state = queueFutures.get()
|
|
33
|
+
if state is STOPsignal:
|
|
34
|
+
break
|
|
35
|
+
state = _filterAsymmetricFolds(state)
|
|
36
|
+
with LOCKsymmetricFoldsTotal:
|
|
37
|
+
symmetricFoldsTotal += state.groupsOfFolds
|
|
38
|
+
|
|
39
|
+
def _filterAsymmetricFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
|
|
40
|
+
"""Add real function during generation; the signature is here to preview its interactions with the module."""
|
|
41
|
+
return state
|
|
42
|
+
|
|
43
|
+
def filterAsymmetricFolds(state: SymmetricFoldsState) -> None:
|
|
44
|
+
queueFutures.put_nowait(deepcopy(state))
|
|
45
|
+
|
|
46
|
+
def getSymmetricFoldsTotal() -> DatatypeFoldsTotal:
|
|
47
|
+
for _thread in listThreads:
|
|
48
|
+
queueFutures.put(STOPsignal) # pyright: ignore[reportArgumentType]
|
|
49
|
+
for thread in listThreads:
|
|
50
|
+
thread.join()
|
|
51
|
+
return symmetricFoldsTotal
|
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
"""addSymmetryCheckAsynchronous."""
|
|
2
|
-
from astToolkit import Be,
|
|
2
|
+
from astToolkit import Be, Grab, identifierDotAttribute, LedgerOfImports, Make, NodeChanger, NodeTourist, Then
|
|
3
3
|
from hunterMakesPy import raiseIfNone
|
|
4
4
|
from mapFolding import packageSettings
|
|
5
|
-
from mapFolding.someAssemblyRequired import
|
|
6
|
-
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import
|
|
7
|
-
A007822adjustFoldsTotal, astExprCall_filterAsymmetricFoldsDataclass, identifier_filterAsymmetricFolds,
|
|
8
|
-
identifierCounting, identifierDataclass, logicalPathInfixA007822, sourceCallableDispatcherA007822,
|
|
9
|
-
sourceCallableIdentifierA007822)
|
|
10
|
-
from mapFolding.someAssemblyRequired.makingModules_count import makeTheorem2, numbaOnTheorem2, trimTheorem2
|
|
5
|
+
from mapFolding.someAssemblyRequired import defaultA007822, IfThis
|
|
6
|
+
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import ExprCallFilterAsymmetricFoldsState
|
|
11
7
|
from mapFolding.someAssemblyRequired.toolkitMakeModules import getModule, getPathFilename, write_astModule
|
|
12
|
-
from os import PathLike
|
|
13
8
|
from pathlib import PurePath
|
|
14
9
|
import ast
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
identifier_initializeConcurrencyManager = 'initializeConcurrencyManager'
|
|
18
|
-
identifier_processCompletedFutures = '_processCompletedFutures'
|
|
11
|
+
# TODO figure out asynchronous + numba.
|
|
19
12
|
|
|
20
|
-
astExprCall_initializeConcurrencyManager: ast.Expr = Make.Expr(Make.Call(Make.Name(
|
|
13
|
+
astExprCall_initializeConcurrencyManager: ast.Expr = Make.Expr(Make.Call(Make.Name(defaultA007822['function']['initializeConcurrencyManager']), listParameters=[Make.Name('maxWorkers')]))
|
|
21
14
|
AssignTotal2CountingIdentifier: ast.Assign = Make.Assign(
|
|
22
|
-
[Make.Attribute(Make.Name(
|
|
23
|
-
, value=Make.Call(Make.Name(
|
|
15
|
+
[Make.Attribute(Make.Name(defaultA007822['variable']['stateInstance']), defaultA007822['variable']['counting'], context=Make.Store())]
|
|
16
|
+
, value=Make.Call(Make.Name(defaultA007822['function']['getSymmetricFoldsTotal']))
|
|
24
17
|
)
|
|
25
18
|
|
|
26
|
-
def addSymmetryCheckAsynchronous(astModule: ast.Module,
|
|
27
|
-
"""
|
|
19
|
+
def addSymmetryCheckAsynchronous(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
20
|
+
"""Make the check for symmetry in each folding pattern in a group of folds asynchronous to the rest of the symmetric map folding algorithm.
|
|
28
21
|
|
|
29
22
|
To do asynchronous filtering, a few things must happen.
|
|
30
23
|
1. When the algorithm finds a `groupOfFolds`, the call to `filterAsymmetricFolds` must be non-blocking.
|
|
@@ -39,16 +32,13 @@ def addSymmetryCheckAsynchronous(astModule: ast.Module, moduleIdentifier: str, c
|
|
|
39
32
|
Each `leafBelow` array will be 28 * 8-bits, so if the queue has only 0.3% of the total calls in it, that is 28 GiB of data.
|
|
40
33
|
"""
|
|
41
34
|
astFunctionDef_count: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
42
|
-
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(
|
|
35
|
+
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(defaultA007822['function']['counting']))
|
|
43
36
|
, doThat = Then.extractIt
|
|
44
37
|
).captureLastMatch(astModule))
|
|
45
38
|
|
|
46
|
-
NodeChanger(Be.Return, Then.insertThisAbove([A007822adjustFoldsTotal])).visit(astFunctionDef_count)
|
|
47
|
-
|
|
48
39
|
NodeChanger(
|
|
49
|
-
|
|
50
|
-
,
|
|
51
|
-
).visit(astFunctionDef_count)
|
|
40
|
+
Be.Assign.valueIs(IfThis.isCallIdentifier(defaultA007822['function']['filterAsymmetricFolds']))
|
|
41
|
+
, Then.replaceWith(ExprCallFilterAsymmetricFoldsState)).visit(astFunctionDef_count)
|
|
52
42
|
|
|
53
43
|
NodeChanger(
|
|
54
44
|
findThis=Be.While.testIs(IfThis.isCallIdentifier('activeLeafGreaterThan0'))
|
|
@@ -56,9 +46,10 @@ def addSymmetryCheckAsynchronous(astModule: ast.Module, moduleIdentifier: str, c
|
|
|
56
46
|
).visit(astFunctionDef_count)
|
|
57
47
|
|
|
58
48
|
NodeChanger(
|
|
59
|
-
findThis=Be.FunctionDef.nameIs(IfThis.isIdentifier(
|
|
49
|
+
findThis=Be.FunctionDef.nameIs(IfThis.isIdentifier(defaultA007822['function']['counting']))
|
|
60
50
|
, doThat=Then.replaceWith(astFunctionDef_count)
|
|
61
51
|
).visit(astModule)
|
|
52
|
+
del astFunctionDef_count
|
|
62
53
|
|
|
63
54
|
astFunctionDef_doTheNeedful: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
64
55
|
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableDispatcher))
|
|
@@ -66,132 +57,44 @@ def addSymmetryCheckAsynchronous(astModule: ast.Module, moduleIdentifier: str, c
|
|
|
66
57
|
).captureLastMatch(astModule))
|
|
67
58
|
|
|
68
59
|
astFunctionDef_doTheNeedful.body.insert(0, astExprCall_initializeConcurrencyManager)
|
|
60
|
+
astFunctionDef_doTheNeedful.args.args.append(Make.arg('maxWorkers', Make.Name('int')))
|
|
69
61
|
|
|
70
62
|
NodeChanger(
|
|
71
63
|
findThis=Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableDispatcher))
|
|
72
64
|
, doThat=Then.replaceWith(astFunctionDef_doTheNeedful)
|
|
73
65
|
).visit(astModule)
|
|
66
|
+
del astFunctionDef_doTheNeedful
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
astModule.body.insert(0, astImportFrom)
|
|
79
|
-
|
|
80
|
-
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
81
|
-
pathFilenameAnnex: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier + 'Annex')
|
|
68
|
+
imports = LedgerOfImports(astModule)
|
|
69
|
+
removeImports = NodeChanger(IfThis.isAnyOf(Be.ImportFrom, Be.Import), Then.removeIt)
|
|
70
|
+
removeImports.visit(astModule)
|
|
82
71
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
ImaString = """from concurrent.futures import Future as ConcurrentFuture, ThreadPoolExecutor
|
|
87
|
-
from hunterMakesPy import raiseIfNone
|
|
88
|
-
from mapFolding import Array1DLeavesTotal
|
|
89
|
-
from queue import Empty, Queue
|
|
90
|
-
from threading import Thread
|
|
91
|
-
import numpy"""
|
|
92
|
-
|
|
93
|
-
astModule = ast.parse(ImaString)
|
|
94
|
-
del ImaString
|
|
95
|
-
|
|
96
|
-
ImaString = f"""concurrencyManager = None
|
|
97
|
-
{identifierCounting}Total: int = 0
|
|
98
|
-
processingThread = None
|
|
99
|
-
queueFutures: Queue[ConcurrentFuture[int]] = Queue()
|
|
100
|
-
"""
|
|
101
|
-
astModule.body.extend(ast.parse(ImaString).body)
|
|
102
|
-
del ImaString
|
|
103
|
-
|
|
104
|
-
ImaString = f"""def {identifier_initializeConcurrencyManager}(maxWorkers: int | None = None, {identifierCounting}: int = 0) -> None:
|
|
105
|
-
global concurrencyManager, queueFutures, {identifierCounting}Total, processingThread
|
|
106
|
-
concurrencyManager = ThreadPoolExecutor(max_workers=maxWorkers)
|
|
107
|
-
queueFutures = Queue()
|
|
108
|
-
{identifierCounting}Total = {identifierCounting}
|
|
109
|
-
processingThread = Thread(target={identifier_processCompletedFutures})
|
|
110
|
-
processingThread.start()
|
|
111
|
-
"""
|
|
112
|
-
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_initializeConcurrencyManager)))
|
|
113
|
-
del ImaString
|
|
114
|
-
|
|
115
|
-
ImaString = f"""def {identifier_processCompletedFutures}() -> None:
|
|
116
|
-
global queueFutures, {identifierCounting}Total
|
|
117
|
-
while True:
|
|
118
|
-
try:
|
|
119
|
-
claimTicket: ConcurrentFuture[int] = queueFutures.get(timeout=1)
|
|
120
|
-
if claimTicket is None:
|
|
121
|
-
break
|
|
122
|
-
{identifierCounting}Total += claimTicket.result()
|
|
123
|
-
except Empty:
|
|
124
|
-
continue
|
|
125
|
-
"""
|
|
126
|
-
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_processCompletedFutures)))
|
|
127
|
-
del ImaString
|
|
128
|
-
|
|
129
|
-
ImaString = f"""def _{identifier_filterAsymmetricFolds}(leafBelow: Array1DLeavesTotal) -> int:
|
|
130
|
-
{identifierCounting} = 0
|
|
131
|
-
leafComparison: Array1DLeavesTotal = numpy.zeros_like(leafBelow)
|
|
132
|
-
leavesTotal = leafBelow.size - 1
|
|
133
|
-
|
|
134
|
-
indexLeaf = 0
|
|
135
|
-
leafConnectee = 0
|
|
136
|
-
while leafConnectee < leavesTotal + 1:
|
|
137
|
-
leafNumber = int(leafBelow[indexLeaf])
|
|
138
|
-
leafComparison[leafConnectee] = (leafNumber - indexLeaf + leavesTotal) % leavesTotal
|
|
139
|
-
indexLeaf = leafNumber
|
|
140
|
-
leafConnectee += 1
|
|
141
|
-
|
|
142
|
-
indexInMiddle = leavesTotal // 2
|
|
143
|
-
indexDistance = 0
|
|
144
|
-
while indexDistance < leavesTotal + 1:
|
|
145
|
-
ImaSymmetricFold = True
|
|
146
|
-
leafConnectee = 0
|
|
147
|
-
while leafConnectee < indexInMiddle:
|
|
148
|
-
if leafComparison[(indexDistance + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexDistance + leavesTotal - 1 - leafConnectee) % (leavesTotal + 1)]:
|
|
149
|
-
ImaSymmetricFold = False
|
|
150
|
-
break
|
|
151
|
-
leafConnectee += 1
|
|
152
|
-
{identifierCounting} += ImaSymmetricFold
|
|
153
|
-
indexDistance += 1
|
|
154
|
-
return {identifierCounting}
|
|
155
|
-
"""
|
|
156
|
-
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), f'_{identifier_filterAsymmetricFolds}')))
|
|
157
|
-
del ImaString
|
|
72
|
+
astModuleAsynchronousAnnex: ast.Module = getModule(logicalPathInfix=defaultA007822['logicalPath']['assembly'], identifierModule='_asynchronousAnnex')
|
|
73
|
+
imports.walkThis(astModuleAsynchronousAnnex)
|
|
74
|
+
removeImports.visit(astModuleAsynchronousAnnex)
|
|
158
75
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
queueFutures.put_nowait(raiseIfNone(concurrencyManager).submit(_{identifier_filterAsymmetricFolds}, leafBelow.copy()))
|
|
163
|
-
"""
|
|
164
|
-
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_filterAsymmetricFolds)))
|
|
165
|
-
del ImaString
|
|
166
|
-
|
|
167
|
-
ImaString = f"""
|
|
168
|
-
def {identifier_getAsymmetricFoldsTotal}() -> int:
|
|
169
|
-
global concurrencyManager, queueFutures, processingThread
|
|
170
|
-
raiseIfNone(concurrencyManager).shutdown(wait=True)
|
|
171
|
-
queueFutures.put(None)
|
|
172
|
-
raiseIfNone(processingThread).join()
|
|
173
|
-
return {identifierCounting}Total
|
|
174
|
-
"""
|
|
175
|
-
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_getAsymmetricFoldsTotal)))
|
|
176
|
-
del ImaString
|
|
177
|
-
|
|
178
|
-
write_astModule(astModule, pathFilenameAnnex, packageSettings.identifierPackage)
|
|
76
|
+
NodeChanger(Be.FunctionDef.nameIs(IfThis.isIdentifier(defaultA007822['function']['filterAsymmetricFolds']))
|
|
77
|
+
, Grab.nameAttribute(Then.replaceWith(f"_{defaultA007822['function']['filterAsymmetricFolds']}"))
|
|
78
|
+
).visit(astModule)
|
|
179
79
|
|
|
180
|
-
|
|
80
|
+
NodeChanger(Be.FunctionDef.nameIs(IfThis.isIdentifier(f"_{defaultA007822['function']['filterAsymmetricFolds']}"))
|
|
81
|
+
, Then.removeIt
|
|
82
|
+
).visit(astModuleAsynchronousAnnex)
|
|
181
83
|
|
|
182
|
-
|
|
84
|
+
astModule.body = [*imports.makeList_ast(), *astModuleAsynchronousAnnex.body, *astModule.body]
|
|
183
85
|
|
|
184
|
-
|
|
185
|
-
pathFilename = addSymmetryCheckAsynchronous(astModule, 'asynchronous', None, logicalPathInfixA007822, sourceCallableDispatcherA007822)
|
|
86
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
|
|
186
87
|
|
|
187
|
-
astModule
|
|
188
|
-
pathFilename = makeTheorem2(astModule, 'asynchronousTheorem2', None, logicalPathInfixA007822, None)
|
|
88
|
+
write_astModule(astModule, pathFilename, packageSettings.identifierPackage)
|
|
189
89
|
|
|
190
|
-
|
|
191
|
-
pathFilename = trimTheorem2(astModule, 'asynchronousTrimmed', None, logicalPathInfixA007822, None)
|
|
90
|
+
return pathFilename
|
|
192
91
|
|
|
193
|
-
|
|
194
|
-
|
|
92
|
+
def makeA007822AsynchronousModules() -> None:
|
|
93
|
+
"""Make asynchronous modules for A007822."""
|
|
94
|
+
astModule: ast.Module = getModule(logicalPathInfix=defaultA007822['logicalPath']['synthetic'], identifierModule=defaultA007822['module']['algorithm'])
|
|
95
|
+
pathFilename: PurePath = addSymmetryCheckAsynchronous(astModule, defaultA007822['module']['asynchronous'], defaultA007822['function']['counting'] # noqa: F841 # pyright: ignore[reportUnusedVariable]
|
|
96
|
+
, defaultA007822['logicalPath']['synthetic'], defaultA007822['function']['dispatcher'])
|
|
195
97
|
|
|
196
98
|
if __name__ == '__main__':
|
|
197
|
-
|
|
99
|
+
makeA007822AsynchronousModules()
|
|
100
|
+
|
|
@@ -1,74 +1,73 @@
|
|
|
1
1
|
"""addSymmetryCheck."""
|
|
2
|
-
from astToolkit import
|
|
2
|
+
from astToolkit import (
|
|
3
|
+
Be, Grab, identifierDotAttribute, LedgerOfImports, NodeChanger, NodeTourist, parsePathFilename2astModule, Then)
|
|
3
4
|
from hunterMakesPy import raiseIfNone
|
|
4
5
|
from mapFolding import packageSettings
|
|
5
|
-
from mapFolding.someAssemblyRequired import
|
|
6
|
-
identifierCallableSourceDEFAULT, identifierCountingDEFAULT, identifierDataclassInstanceDEFAULT, IfThis)
|
|
6
|
+
from mapFolding.someAssemblyRequired import default, defaultA007822, IfThis
|
|
7
7
|
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import (
|
|
8
|
-
A007822adjustFoldsTotal, A007822incrementCount, FunctionDef_filterAsymmetricFolds
|
|
9
|
-
|
|
10
|
-
from mapFolding.someAssemblyRequired.
|
|
11
|
-
|
|
12
|
-
from mapFolding.someAssemblyRequired.makingModules_doTheNeedful import makeInitializeState, makeUnRePackDataclass
|
|
13
|
-
from mapFolding.someAssemblyRequired.toolkitMakeModules import (
|
|
14
|
-
getLogicalPath, getModule, getPathFilename, write_astModule)
|
|
15
|
-
from os import PathLike
|
|
8
|
+
A007822adjustFoldsTotal, A007822incrementCount, FunctionDef_filterAsymmetricFolds)
|
|
9
|
+
from mapFolding.someAssemblyRequired.makingModules_count import makeTheorem2, numbaOnTheorem2, trimTheorem2
|
|
10
|
+
from mapFolding.someAssemblyRequired.makingModules_doTheNeedful import makeInitializeState
|
|
11
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import getModule, getPathFilename, write_astModule
|
|
16
12
|
from pathlib import PurePath
|
|
17
13
|
import ast
|
|
18
14
|
|
|
19
|
-
def addSymmetryCheck(astModule: ast.Module,
|
|
20
|
-
"""
|
|
21
|
-
|
|
15
|
+
def addSymmetryCheck(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
16
|
+
"""Modify the multidimensional map folding algorithm by checking for symmetry in each folding pattern in a group of folds."""
|
|
17
|
+
NodeChanger(Be.Name.idIs(IfThis.isIdentifier(default['variable']['stateDataclass']))
|
|
18
|
+
, Grab.idAttribute(Then.replaceWith(defaultA007822['variable']['stateDataclass']))
|
|
19
|
+
).visit(astModule)
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
NodeChanger(Be.alias.nameIs(IfThis.isIdentifier(default['variable']['stateDataclass']))
|
|
22
|
+
, Grab.nameAttribute(Then.replaceWith(defaultA007822['variable']['stateDataclass']))
|
|
23
|
+
).visit(astModule)
|
|
24
|
+
|
|
25
|
+
FunctionDef_count: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
26
|
+
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(default['function']['counting']))
|
|
25
27
|
, doThat = Then.extractIt
|
|
26
28
|
).captureLastMatch(astModule))
|
|
27
|
-
|
|
29
|
+
FunctionDef_count.name = identifierCallable or defaultA007822['function']['counting']
|
|
28
30
|
|
|
29
|
-
NodeChanger(Be.Return, Then.insertThisAbove([A007822adjustFoldsTotal])).visit(
|
|
31
|
+
NodeChanger(Be.Return, Then.insertThisAbove([A007822adjustFoldsTotal])).visit(FunctionDef_count)
|
|
30
32
|
|
|
31
33
|
NodeChanger(
|
|
32
|
-
findThis=Be.AugAssign.targetIs(IfThis.isAttributeNamespaceIdentifier(
|
|
34
|
+
findThis=Be.AugAssign.targetIs(IfThis.isAttributeNamespaceIdentifier(default['variable']['stateInstance'], default['variable']['counting']))
|
|
33
35
|
, doThat=Then.replaceWith(A007822incrementCount)
|
|
34
|
-
).visit(
|
|
36
|
+
).visit(FunctionDef_count)
|
|
37
|
+
|
|
38
|
+
imports = LedgerOfImports(astModule)
|
|
39
|
+
NodeChanger(IfThis.isAnyOf(Be.ImportFrom, Be.Import), Then.removeIt).visit(astModule)
|
|
40
|
+
imports.addImport_asStr('numpy')
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
# system to replace the `Ingredients` paradigm.
|
|
38
|
-
NodeChanger(Be.ImportFrom, Then.insertThisBelow([FunctionDef_filterAsymmetricFolds])).visit(astModule)
|
|
42
|
+
astModule.body = [*imports.makeList_ast(), FunctionDef_filterAsymmetricFolds, *astModule.body]
|
|
39
43
|
|
|
40
|
-
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix,
|
|
44
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
|
|
41
45
|
|
|
42
46
|
write_astModule(astModule, pathFilename, packageSettings.identifierPackage)
|
|
43
47
|
|
|
44
48
|
return pathFilename
|
|
45
49
|
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
pathFilename: PurePath = makeDaoOfMapFoldingNumba(astModule, 'algorithmNumba', None, logicalPathInfixA007822, sourceCallableDispatcherA007822)
|
|
50
|
+
def makeA007822Modules() -> None:
|
|
51
|
+
"""Make."""
|
|
52
|
+
astModule: ast.Module = getModule(logicalPathInfix='algorithms')
|
|
53
|
+
pathFilename: PurePath = addSymmetryCheck(astModule, defaultA007822['module']['algorithm'], defaultA007822['function']['counting']
|
|
54
|
+
, defaultA007822['logicalPath']['synthetic'], None)
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
astModule = getModule(logicalPathInfix=defaultA007822['logicalPath']['synthetic'], identifierModule=defaultA007822['module']['algorithm'])
|
|
57
|
+
makeInitializeState(astModule, defaultA007822['module']['initializeState']
|
|
58
|
+
, defaultA007822['function']['initializeState'], defaultA007822['logicalPath']['synthetic'], None)
|
|
54
59
|
|
|
55
|
-
astModule = getModule(logicalPathInfix=
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
astModule = getModule(logicalPathInfix=logicalPathInfixA007822, moduleIdentifier='algorithm')
|
|
59
|
-
pathFilename = makeTheorem2(astModule, 'theorem2', None, logicalPathInfixA007822, None)
|
|
60
|
+
astModule = getModule(logicalPathInfix=defaultA007822['logicalPath']['synthetic'], identifierModule=defaultA007822['module']['algorithm'])
|
|
61
|
+
pathFilename = makeTheorem2(astModule, 'theorem2', defaultA007822['function']['counting']
|
|
62
|
+
, defaultA007822['logicalPath']['synthetic'], defaultA007822['function']['dispatcher'])
|
|
60
63
|
|
|
61
64
|
astModule = parsePathFilename2astModule(pathFilename)
|
|
62
|
-
pathFilename = trimTheorem2(astModule, 'theorem2Trimmed',
|
|
65
|
+
pathFilename = trimTheorem2(astModule, 'theorem2Trimmed', defaultA007822['function']['counting']
|
|
66
|
+
, defaultA007822['logicalPath']['synthetic'], defaultA007822['function']['dispatcher'])
|
|
63
67
|
|
|
64
68
|
astModule = parsePathFilename2astModule(pathFilename)
|
|
65
|
-
pathFilename = numbaOnTheorem2(astModule, 'theorem2Numba',
|
|
66
|
-
|
|
67
|
-
# @unRePackDataclass
|
|
68
|
-
|
|
69
|
-
# TODO Make this decorator.
|
|
70
|
-
# astImportFrom: ast.ImportFrom = Make.ImportFrom(getLogicalPath(packageSettings.identifierPackage, logicalPathInfixA007822, 'theorem2Numba'), list_alias=[Make.alias(sourceCallableIdentifierA007822)])
|
|
71
|
-
# makeUnRePackDataclass(astImportFrom, 'dataPackingA007822')
|
|
69
|
+
pathFilename = numbaOnTheorem2(astModule, 'theorem2Numba', defaultA007822['function']['counting']
|
|
70
|
+
, defaultA007822['logicalPath']['synthetic'], defaultA007822['function']['dispatcher'])
|
|
72
71
|
|
|
73
72
|
if __name__ == '__main__':
|
|
74
|
-
|
|
73
|
+
makeA007822Modules()
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
"""Configuration by dataclass."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from astToolkit import
|
|
3
|
+
from astToolkit import identifierDotAttribute, IngredientsFunction, IngredientsModule, parseLogicalPath2astModule
|
|
4
|
+
from astToolkit.transformationTools import pythonCode2ast_expr
|
|
5
|
+
from hunterMakesPy import autoDecodingRLE
|
|
6
|
+
# TODO 'The...' identifiers are a vestigial semiotic system. Do I still need to import `asname`? If so, would different
|
|
7
|
+
# identifiers better integrate into the current semiotics?
|
|
5
8
|
from mapFolding import (
|
|
6
9
|
DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal,
|
|
7
10
|
DatatypeLeavesTotal as TheDatatypeLeavesTotal, getPathFilenameFoldsTotal, getPathRootJobDEFAULT, packageSettings)
|
|
8
11
|
from mapFolding.dataBaskets import MapFoldingState
|
|
9
|
-
from mapFolding.someAssemblyRequired import
|
|
12
|
+
from mapFolding.someAssemblyRequired import DatatypeConfiguration, default
|
|
13
|
+
from mapFolding.someAssemblyRequired._toolkitContainers import ShatteredDataclass
|
|
10
14
|
from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
|
|
11
15
|
from pathlib import Path, PurePosixPath
|
|
16
|
+
from typing import cast
|
|
17
|
+
import ast
|
|
12
18
|
import dataclasses
|
|
13
19
|
|
|
14
|
-
@dataclasses.dataclass
|
|
20
|
+
@dataclasses.dataclass(slots=True)
|
|
15
21
|
class RecipeJobTheorem2:
|
|
16
22
|
"""Configuration recipe for generating map folding computation jobs.
|
|
17
23
|
|
|
@@ -88,17 +94,17 @@ class RecipeJobTheorem2:
|
|
|
88
94
|
shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
89
95
|
"""Deconstructed dataclass metadata for code transformation."""
|
|
90
96
|
|
|
91
|
-
|
|
92
|
-
source_astModule: Module = parseLogicalPath2astModule('
|
|
97
|
+
# ------- Source -----------------------------------------
|
|
98
|
+
source_astModule: ast.Module = parseLogicalPath2astModule(f'{packageSettings.identifierPackage}.{default['logicalPath']['synthetic']}.theorem2Numba') # noqa: RUF009
|
|
93
99
|
"""Parsed AST of the source module containing the generic algorithm."""
|
|
94
|
-
|
|
100
|
+
identifierCallableSource: str = default['function']['counting']
|
|
95
101
|
"""Name of the counting function to extract."""
|
|
96
102
|
|
|
97
|
-
sourceLogicalPathModuleDataclass: identifierDotAttribute = '
|
|
103
|
+
sourceLogicalPathModuleDataclass: identifierDotAttribute = f'{packageSettings.identifierPackage}.dataBaskets'
|
|
98
104
|
"""Logical path to the dataclass module."""
|
|
99
|
-
sourceDataclassIdentifier: str = '
|
|
105
|
+
sourceDataclassIdentifier: str = default['variable']['stateDataclass']
|
|
100
106
|
"""Name of the source dataclass."""
|
|
101
|
-
sourceDataclassInstance: str =
|
|
107
|
+
sourceDataclassInstance: str = default['variable']['stateInstance']
|
|
102
108
|
"""Instance identifier for the dataclass."""
|
|
103
109
|
|
|
104
110
|
sourcePathPackage: PurePosixPath | None = PurePosixPath(packageSettings.pathPackage) # noqa: RUF009
|
|
@@ -106,7 +112,7 @@ class RecipeJobTheorem2:
|
|
|
106
112
|
sourcePackageIdentifier: str | None = packageSettings.identifierPackage
|
|
107
113
|
"""Name of the source package."""
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
# ------- Filesystem, names of physical objects ------------------------------------------
|
|
110
116
|
pathPackage: PurePosixPath | None = None
|
|
111
117
|
"""Override path for the target package."""
|
|
112
118
|
pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT()) # noqa: RUF009
|
|
@@ -116,23 +122,23 @@ class RecipeJobTheorem2:
|
|
|
116
122
|
pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
117
123
|
"""Path for writing fold count results."""
|
|
118
124
|
|
|
119
|
-
|
|
125
|
+
# ------- Logical identifiers, as opposed to physical identifiers ------------------------
|
|
120
126
|
packageIdentifier: str | None = None
|
|
121
127
|
"""Target package identifier."""
|
|
122
128
|
logicalPathRoot: identifierDotAttribute | None = None
|
|
123
129
|
"""Logical path root; probably corresponds to physical filesystem directory."""
|
|
124
130
|
moduleIdentifier: str = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
|
|
125
131
|
"""Target module identifier."""
|
|
126
|
-
countCallable: str =
|
|
132
|
+
countCallable: str = identifierCallableSource
|
|
127
133
|
"""Name of the counting function in generated module."""
|
|
128
|
-
|
|
134
|
+
identifierDataclass: str | None = sourceDataclassIdentifier
|
|
129
135
|
"""Target dataclass identifier."""
|
|
130
|
-
|
|
136
|
+
identifierDataclassInstance: str | None = sourceDataclassInstance
|
|
131
137
|
"""Target dataclass instance identifier."""
|
|
132
138
|
logicalPathModuleDataclass: identifierDotAttribute | None = sourceLogicalPathModuleDataclass
|
|
133
139
|
"""Logical path to target dataclass module."""
|
|
134
140
|
|
|
135
|
-
|
|
141
|
+
# ------- Datatypes ------------------------------------------
|
|
136
142
|
type DatatypeFoldsTotal = TheDatatypeFoldsTotal
|
|
137
143
|
"""Type alias for datatype linked to the magnitude of `foldsTotal`."""
|
|
138
144
|
type DatatypeElephino = TheDatatypeElephino
|
|
@@ -211,5 +217,59 @@ class RecipeJobTheorem2:
|
|
|
211
217
|
if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
212
218
|
self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
|
|
213
219
|
|
|
214
|
-
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.
|
|
215
|
-
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.
|
|
220
|
+
if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.identifierDataclass and self.identifierDataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
|
|
221
|
+
self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.identifierDataclass, self.identifierDataclassInstance)
|
|
222
|
+
|
|
223
|
+
def moveShatteredDataclass_arg2body(identifier: str, job: RecipeJobTheorem2) -> ast.AnnAssign | ast.Assign:
|
|
224
|
+
"""Embed a shattered dataclass field assignment into the function body.
|
|
225
|
+
|
|
226
|
+
(AI generated docstring)
|
|
227
|
+
|
|
228
|
+
This helper retrieves the pre-fabricated assignment for `identifier` from `job.shatteredDataclass`, hydrates the literal
|
|
229
|
+
payload from `job.state`, and returns the node ready for insertion into a generated function body. Scalar entries receive the
|
|
230
|
+
concrete integer value, array entries are encoded using the auto-decoding run-length encoded method from `hunterMakesPy`, and
|
|
231
|
+
other constructors are left untouched so downstream tooling can decide how to finalize them.
|
|
232
|
+
|
|
233
|
+
Parameters
|
|
234
|
+
----------
|
|
235
|
+
identifier : str
|
|
236
|
+
Field name keyed in `job.shatteredDataclass.Z0Z_field2AnnAssign`.
|
|
237
|
+
job : RecipeJobTheorem2
|
|
238
|
+
Job descriptor that supplies the current computation state and shattered metadata.
|
|
239
|
+
|
|
240
|
+
Returns
|
|
241
|
+
-------
|
|
242
|
+
Ima___Assign : ast.AnnAssign | ast.Assign
|
|
243
|
+
Assignment node mutated with state-backed values for the requested field.
|
|
244
|
+
"""
|
|
245
|
+
Ima___Assign, elementConstructor = job.shatteredDataclass.Z0Z_field2AnnAssign[identifier]
|
|
246
|
+
match elementConstructor:
|
|
247
|
+
case 'scalar':
|
|
248
|
+
cast('ast.Constant', cast('ast.Call', Ima___Assign.value).args[0]).value = int(eval(f"job.state.{identifier}")) # noqa: S307
|
|
249
|
+
case 'array':
|
|
250
|
+
dataAsStrRLE: str = autoDecodingRLE(eval(f"job.state.{identifier}"), assumeAddSpaces=True) # noqa: S307
|
|
251
|
+
dataAs_ast_expr: ast.expr = pythonCode2ast_expr(dataAsStrRLE)
|
|
252
|
+
cast('ast.Call', Ima___Assign.value).args = [dataAs_ast_expr]
|
|
253
|
+
case _:
|
|
254
|
+
pass
|
|
255
|
+
return Ima___Assign
|
|
256
|
+
|
|
257
|
+
# TODO Use this concept in general modules, not just custom jobs.
|
|
258
|
+
def customizeDatatypeViaImport(ingredientsFunction: IngredientsFunction, ingredientsModule: IngredientsModule, listDatatypeConfigurations: list[DatatypeConfiguration]) -> tuple[IngredientsFunction, IngredientsModule]:
|
|
259
|
+
"""Customize data types in the given ingredients by adjusting imports.
|
|
260
|
+
|
|
261
|
+
In the ecosystem of "Ingredients", "Recipes", "DataBaskets," and "shattered dataclasses," a ton of code is dedicated to
|
|
262
|
+
preserving _abstract_ names for datatypes, such as `Array1DLeavesTotal` and `DatatypeFoldsTotal`. This function well
|
|
263
|
+
illustrates why I put so much effort into preserving the abstract names. (Normally, Python will _immediately_ replace an alias
|
|
264
|
+
name with the type for which it is a proxy.) Because transformed code, even if it has been through 10 transformations (see,
|
|
265
|
+
for example, `mapFolding.syntheticModules.A007822.asynchronousNumba` or its equivalent), ought to still have the abstract
|
|
266
|
+
names, this function gives you the power to change the datatype from numpy to numba and/or from 8-bits to 16-bits merely by
|
|
267
|
+
changing the import statements. You shouldn't need to change any "business" logic.
|
|
268
|
+
|
|
269
|
+
NOTE This will not remove potentially conflicting existing imports from other modules.
|
|
270
|
+
"""
|
|
271
|
+
for datatypeConfig in listDatatypeConfigurations:
|
|
272
|
+
ingredientsFunction.imports.removeImportFrom(datatypeConfig.typeModule, None, datatypeConfig.datatypeIdentifier)
|
|
273
|
+
ingredientsFunction.imports.addImportFrom_asStr(datatypeConfig.typeModule, datatypeConfig.typeIdentifier, datatypeConfig.type_asname)
|
|
274
|
+
|
|
275
|
+
return ingredientsFunction, ingredientsModule
|