mapFolding 0.11.0__py3-none-any.whl → 0.11.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 (33) hide show
  1. mapFolding/__init__.py +18 -75
  2. mapFolding/basecamp.py +13 -10
  3. mapFolding/beDRY.py +113 -2
  4. mapFolding/dataBaskets.py +24 -2
  5. mapFolding/{toolboxFilesystem.py → filesystemToolkit.py} +3 -3
  6. mapFolding/infoBooth.py +96 -0
  7. mapFolding/oeis.py +3 -2
  8. mapFolding/someAssemblyRequired/RecipeJob.py +3 -4
  9. mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +187 -22
  10. mapFolding/someAssemblyRequired/__init__.py +10 -5
  11. mapFolding/someAssemblyRequired/_toolIfThis.py +10 -4
  12. mapFolding/someAssemblyRequired/{_toolboxContainers.py → _toolkitContainers.py} +15 -17
  13. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +9 -8
  14. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +5 -3
  15. mapFolding/someAssemblyRequired/{toolboxNumba.py → toolkitNumba.py} +2 -2
  16. mapFolding/someAssemblyRequired/transformationTools.py +17 -50
  17. mapFolding/syntheticModules/countParallel.py +98 -0
  18. mapFolding/syntheticModules/dataPacking.py +1 -1
  19. mapFolding/syntheticModules/numbaCount.py +189 -188
  20. mapFolding/theDao.py +1 -1
  21. mapFolding/theSSOT.py +4 -243
  22. {mapfolding-0.11.0.dist-info → mapfolding-0.11.2.dist-info}/METADATA +16 -8
  23. mapfolding-0.11.2.dist-info/RECORD +56 -0
  24. {mapfolding-0.11.0.dist-info → mapfolding-0.11.2.dist-info}/WHEEL +1 -1
  25. tests/conftest.py +7 -9
  26. tests/test_computations.py +1 -1
  27. tests/test_filesystem.py +1 -2
  28. tests/test_other.py +1 -1
  29. tests/test_tasks.py +1 -3
  30. mapfolding-0.11.0.dist-info/RECORD +0 -54
  31. {mapfolding-0.11.0.dist-info → mapfolding-0.11.2.dist-info}/entry_points.txt +0 -0
  32. {mapfolding-0.11.0.dist-info → mapfolding-0.11.2.dist-info}/licenses/LICENSE +0 -0
  33. {mapfolding-0.11.0.dist-info → mapfolding-0.11.2.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from collections.abc import Sequence
2
+ from astToolkit import ClassIsAndAttribute, extractClassDef
1
3
  from mapFolding import raiseIfNoneGitHubIssueNumber3, The
2
4
  from mapFolding.someAssemblyRequired import (
3
5
  ast_Identifier,
@@ -9,31 +11,36 @@ from mapFolding.someAssemblyRequired import (
9
11
  IfThis,
10
12
  IngredientsFunction,
11
13
  IngredientsModule,
14
+ inlineFunctionDef,
12
15
  LedgerOfImports,
13
16
  Make,
14
17
  NodeChanger,
15
18
  NodeTourist,
16
19
  parseLogicalPath2astModule,
17
20
  parsePathFilename2astModule,
18
- Then,
21
+ removeUnusedParameters,
19
22
  str_nameDOTname,
23
+ Then,
24
+ write_astModule,
25
+ DeReConstructField2ast,
26
+ ShatteredDataclass,
20
27
  )
21
- from mapFolding.someAssemblyRequired.toolboxNumba import decorateCallableWithNumba, parametersNumbaLight
28
+ from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
22
29
  from mapFolding.someAssemblyRequired.transformationTools import (
23
- inlineFunctionDef,
24
30
  removeDataclassFromFunction,
25
- removeUnusedParameters,
26
31
  shatter_dataclassesDOTdataclass,
27
32
  unpackDataclassCallFunctionRepackDataclass,
28
- write_astModule,
29
33
  )
30
34
  from pathlib import PurePath
35
+ from Z0Z_tools import importLogicalPath2Callable
31
36
  import ast
37
+ import dataclasses
32
38
 
33
39
  algorithmSourceModuleHARDCODED = 'daoOfMapFolding'
34
40
  sourceCallableIdentifierHARDCODED = 'count'
35
41
  logicalPathInfixHARDCODED: ast_Identifier = 'syntheticModules'
36
42
  theCountingIdentifierHARDCODED: ast_Identifier = 'groupsOfFolds'
43
+ dataPackingModuleIdentifierHARDCODED: ast_Identifier = 'dataPacking'
37
44
 
38
45
  def makeInitializeGroupsOfFolds() -> None:
39
46
  callableIdentifierHARDCODED = 'initializeGroupsOfFolds'
@@ -118,11 +125,12 @@ def makeDaoOfMapFolding() -> PurePath:
118
125
  doTheNeedful.imports.update(shatteredDataclass.imports)
119
126
  targetCallableIdentifier = daoOfMapFolding.astFunctionDef.name
120
127
  doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
121
- astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(daoOfMapFolding.astFunctionDef)
128
+ astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(daoOfMapFolding.astFunctionDef) # type: ignore
122
129
  if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
123
130
  astTuple.ctx = ast.Store()
131
+ ast.Return()
124
132
 
125
- findThis = IfThis.isAssignAndValueIs(IfThis.isCall_Identifier(targetCallableIdentifier))
133
+ findThis = ClassIsAndAttribute.valueIs(ast.Assign, IfThis.isCall_Identifier(targetCallableIdentifier))
126
134
  doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
127
135
  changeAssignCallToTarget = NodeChanger(findThis, doThat)
128
136
  changeAssignCallToTarget.visit(doTheNeedful.astFunctionDef)
@@ -136,6 +144,160 @@ def makeDaoOfMapFolding() -> PurePath:
136
144
 
137
145
  return pathFilename
138
146
 
147
+ def makeDaoOfMapFoldingParallel() -> PurePath:
148
+ moduleIdentifierHARDCODED: ast_Identifier = 'countParallel'
149
+
150
+ algorithmSourceModule = algorithmSourceModuleHARDCODED
151
+ sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
152
+ logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
153
+
154
+ logicalPathInfix = logicalPathInfixHARDCODED
155
+ moduleIdentifier = moduleIdentifierHARDCODED
156
+
157
+ astModule = parseLogicalPath2astModule(logicalPathSourceModule)
158
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
159
+
160
+ dataclassName: ast.expr | None = NodeTourist(Be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(ingredientsFunction.astFunctionDef)
161
+ if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
162
+ dataclass_Identifier: ast_Identifier | None = NodeTourist(Be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
163
+ if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
164
+
165
+ dataclassLogicalPathModule = None
166
+ for moduleWithLogicalPath, listNameTuples in ingredientsFunction.imports.dictionaryImportFrom.items():
167
+ for nameTuple in listNameTuples:
168
+ if nameTuple[0] == dataclass_Identifier:
169
+ dataclassLogicalPathModule = moduleWithLogicalPath
170
+ break
171
+ if dataclassLogicalPathModule:
172
+ break
173
+ if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
174
+ dataclassInstanceIdentifier = NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef)
175
+ if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
176
+ shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
177
+
178
+ # Start add the parallel state fields to the count function ================================================
179
+ dataclassBaseFields = dataclasses.fields(importLogicalPath2Callable(dataclassLogicalPathModule, dataclass_Identifier)) # pyright: ignore [reportArgumentType]
180
+ dataclass_IdentifierParallel = 'Parallel' + dataclass_Identifier
181
+ dataclassFieldsParallel = dataclasses.fields(importLogicalPath2Callable(dataclassLogicalPathModule, dataclass_IdentifierParallel)) # pyright: ignore [reportArgumentType]
182
+ onlyParallelFields = [field for field in dataclassFieldsParallel if field.name not in [fieldBase.name for fieldBase in dataclassBaseFields]]
183
+
184
+ Official_fieldOrder: list[ast_Identifier] = []
185
+ dictionaryDeReConstruction: dict[ast_Identifier, DeReConstructField2ast] = {}
186
+
187
+ dataclassClassDef = extractClassDef(parseLogicalPath2astModule(dataclassLogicalPathModule), dataclass_IdentifierParallel)
188
+ if not isinstance(dataclassClassDef, ast.ClassDef): raise ValueError(f"I could not find `{dataclass_IdentifierParallel = }` in `{dataclassLogicalPathModule = }`.")
189
+
190
+ for aField in onlyParallelFields:
191
+ Official_fieldOrder.append(aField.name)
192
+ dictionaryDeReConstruction[aField.name] = DeReConstructField2ast(dataclassLogicalPathModule, dataclassClassDef, dataclassInstanceIdentifier, aField)
193
+
194
+ shatteredDataclassParallel = ShatteredDataclass(
195
+ countingVariableAnnotation=shatteredDataclass.countingVariableAnnotation,
196
+ countingVariableName=shatteredDataclass.countingVariableName,
197
+ field2AnnAssign={**shatteredDataclass.field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].astAnnAssignConstructor for field in Official_fieldOrder}},
198
+ Z0Z_field2AnnAssign={**shatteredDataclass.Z0Z_field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].Z0Z_hack for field in Official_fieldOrder}},
199
+ list_argAnnotated4ArgumentsSpecification=shatteredDataclass.list_argAnnotated4ArgumentsSpecification + [dictionaryDeReConstruction[field].ast_argAnnotated for field in Official_fieldOrder],
200
+ list_keyword_field__field4init=shatteredDataclass.list_keyword_field__field4init + [dictionaryDeReConstruction[field].ast_keyword_field__field for field in Official_fieldOrder if dictionaryDeReConstruction[field].init],
201
+ listAnnotations=shatteredDataclass.listAnnotations + [dictionaryDeReConstruction[field].astAnnotation for field in Official_fieldOrder],
202
+ listName4Parameters=shatteredDataclass.listName4Parameters + [dictionaryDeReConstruction[field].astName for field in Official_fieldOrder],
203
+ listUnpack=shatteredDataclass.listUnpack + [Make.AnnAssign(dictionaryDeReConstruction[field].astName, dictionaryDeReConstruction[field].astAnnotation, dictionaryDeReConstruction[field].ast_nameDOTname) for field in Official_fieldOrder],
204
+ map_stateDOTfield2Name={**shatteredDataclass.map_stateDOTfield2Name, **{dictionaryDeReConstruction[field].ast_nameDOTname: dictionaryDeReConstruction[field].astName for field in Official_fieldOrder}},
205
+ )
206
+ shatteredDataclassParallel.fragments4AssignmentOrParameters = Make.Tuple(shatteredDataclassParallel.listName4Parameters, ast.Store())
207
+ shatteredDataclassParallel.repack = Make.Assign([Make.Name(dataclassInstanceIdentifier)], value=Make.Call(Make.Name(dataclass_IdentifierParallel), list_keyword=shatteredDataclassParallel.list_keyword_field__field4init))
208
+ shatteredDataclassParallel.signatureReturnAnnotation = Make.Subscript(Make.Name('tuple'), Make.Tuple(shatteredDataclassParallel.listAnnotations))
209
+
210
+ shatteredDataclassParallel.imports.update(*(dictionaryDeReConstruction[field].ledger for field in Official_fieldOrder))
211
+ shatteredDataclassParallel.imports.addImportFrom_asStr(dataclassLogicalPathModule, dataclass_IdentifierParallel)
212
+ shatteredDataclassParallel.imports.update(shatteredDataclass.imports)
213
+ shatteredDataclassParallel.imports.removeImportFrom(dataclassLogicalPathModule, dataclass_Identifier)
214
+
215
+ # End add the parallel state fields to the count function ================================================
216
+
217
+ ingredientsFunction.imports.update(shatteredDataclassParallel.imports)
218
+ ingredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclassParallel)
219
+
220
+ # Start add the parallel logic to the count function ================================================
221
+
222
+ findThis = ClassIsAndAttribute.testIs(ast.While, ClassIsAndAttribute.leftIs(ast.Compare, IfThis.isName_Identifier('leafConnectee')))
223
+ doThat = Then.extractIt(DOT.body)
224
+ captureCountGapsCodeBlock: NodeTourist[ast.While, Sequence[ast.stmt]] = NodeTourist(findThis, doThat)
225
+ countGapsCodeBlock = captureCountGapsCodeBlock.captureLastMatch(ingredientsFunction.astFunctionDef)
226
+ if countGapsCodeBlock is None: raise raiseIfNoneGitHubIssueNumber3
227
+
228
+ thisIsMyTaskIndexCodeBlock = ast.If(ast.BoolOp(ast.Or()
229
+ , values=[ast.Compare(ast.Name('leaf1ndex'), ops=[ast.NotEq()], comparators=[ast.Name('taskDivisions')])
230
+ , ast.Compare(ast.BinOp(ast.Name('leafConnectee'), op=ast.Mod(), right=ast.Name('taskDivisions')), ops=[ast.Eq()], comparators=[ast.Name('taskIndex')])])
231
+ , body=list(countGapsCodeBlock[0:-1]))
232
+
233
+ countGapsCodeBlockNew: list[ast.stmt] = [thisIsMyTaskIndexCodeBlock, countGapsCodeBlock[-1]]
234
+
235
+ doThat = Grab.bodyAttribute(Then.replaceWith(countGapsCodeBlockNew))
236
+ NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
237
+
238
+ # End add the parallel logic to the count function ================================================
239
+
240
+ ingredientsFunction = removeUnusedParameters(ingredientsFunction)
241
+
242
+ ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
243
+
244
+ # Start unpack/repack the dataclass function ================================================
245
+ sourceCallableIdentifier = The.sourceCallableDispatcher
246
+
247
+ unRepackDataclass: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
248
+ unRepackDataclass.astFunctionDef.name = 'unRepack' + dataclass_IdentifierParallel
249
+ unRepackDataclass.imports.update(shatteredDataclassParallel.imports)
250
+ findThis = ClassIsAndAttribute.annotationIs(ast.arg, IfThis.isName_Identifier(dataclass_Identifier)) # type: ignore
251
+ doThat = Grab.annotationAttribute(Grab.idAttribute(Then.replaceWith(dataclass_IdentifierParallel))) # type: ignore
252
+ NodeChanger(findThis, doThat).visit(unRepackDataclass.astFunctionDef) # type: ignore
253
+ unRepackDataclass.astFunctionDef.returns = Make.Name(dataclass_IdentifierParallel)
254
+ targetCallableIdentifier = ingredientsFunction.astFunctionDef.name
255
+ unRepackDataclass = unpackDataclassCallFunctionRepackDataclass(unRepackDataclass, targetCallableIdentifier, shatteredDataclassParallel)
256
+
257
+ astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef) # type: ignore
258
+ if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
259
+ astTuple.ctx = ast.Store()
260
+ findThis = ClassIsAndAttribute.valueIs(ast.Assign, IfThis.isCall_Identifier(targetCallableIdentifier))
261
+ doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
262
+ changeAssignCallToTarget = NodeChanger(findThis, doThat)
263
+ changeAssignCallToTarget.visit(unRepackDataclass.astFunctionDef)
264
+
265
+ ingredientsDoTheNeedful: IngredientsFunction = IngredientsFunction(
266
+ astFunctionDef = ast.FunctionDef(name='doTheNeedful'
267
+ , args=ast.arguments(args=[ast.arg('state', annotation=ast.Name(dataclass_IdentifierParallel)), ast.arg('concurrencyLimit', annotation=ast.Name('int'))])
268
+ , body=[ast.Assign(targets=[ast.Name('stateParallel', ctx=ast.Store())], value=ast.Call(func=ast.Name('deepcopy'), args=[ast.Name('state')]))
269
+ , ast.AnnAssign(target=ast.Name('listStatesParallel', ctx=ast.Store()), annotation=ast.Subscript(value=ast.Name('list'), slice=ast.Name(dataclass_IdentifierParallel)), value=ast.BinOp(left=ast.List(elts=[ast.Name('stateParallel')]), op=ast.Mult(), right=ast.Attribute(value=ast.Name('stateParallel'), attr='taskDivisions')), simple=1)
270
+ , ast.AnnAssign(target=ast.Name('groupsOfFoldsTotal', ctx=ast.Store()), annotation=ast.Name('int'), value=ast.Constant(value=0), simple=1)
271
+
272
+ , ast.AnnAssign(target=ast.Name('dictionaryConcurrency', ctx=ast.Store()), annotation=ast.Subscript(value=ast.Name('dict'), slice=ast.Tuple(elts=[ast.Name('int'), ast.Subscript(value=ast.Name('ConcurrentFuture'), slice=ast.Name(dataclass_IdentifierParallel))])), value=ast.Dict(), simple=1)
273
+ , ast.With(items=[ast.withitem(context_expr=ast.Call(func=ast.Name('ProcessPoolExecutor'), args=[ast.Name('concurrencyLimit')]), optional_vars=ast.Name('concurrencyManager', ctx=ast.Store()))]
274
+ , body=[ast.For(target=ast.Name('indexSherpa', ctx=ast.Store()), iter=ast.Call(func=ast.Name('range'), args=[ast.Attribute(value=ast.Name('stateParallel'), attr='taskDivisions')])
275
+ , body=[ast.Assign(targets=[ast.Name('state', ctx=ast.Store())], value=ast.Call(func=ast.Name('deepcopy'), args=[ast.Name('stateParallel')]))
276
+ , ast.Assign(targets=[ast.Attribute(value=ast.Name('state'), attr='taskIndex', ctx=ast.Store())], value=ast.Name('indexSherpa'))
277
+ , ast.Assign(targets=[ast.Subscript(value=ast.Name('dictionaryConcurrency'), slice=ast.Name('indexSherpa'), ctx=ast.Store())], value=ast.Call(func=ast.Attribute(value=ast.Name('concurrencyManager'), attr='submit'), args=[ast.Name(unRepackDataclass.astFunctionDef.name), ast.Name('state')]))])
278
+ , ast.For(target=ast.Name('indexSherpa', ctx=ast.Store()), iter=ast.Call(func=ast.Name('range'), args=[ast.Attribute(value=ast.Name('stateParallel'), attr='taskDivisions')])
279
+ , body=[ast.Assign(targets=[ast.Subscript(value=ast.Name('listStatesParallel'), slice=ast.Name('indexSherpa'), ctx=ast.Store())], value=ast.Call(func=ast.Attribute(value=ast.Subscript(value=ast.Name('dictionaryConcurrency'), slice=ast.Name('indexSherpa')), attr='result')))
280
+ , ast.AugAssign(target=ast.Name('groupsOfFoldsTotal', ctx=ast.Store()), op=ast.Add(), value=ast.Attribute(value=ast.Subscript(value=ast.Name('listStatesParallel'), slice=ast.Name('indexSherpa')), attr='groupsOfFolds'))])])
281
+
282
+ , ast.AnnAssign(target=ast.Name('foldsTotal', ctx=ast.Store()), annotation=ast.Name('int'), value=ast.BinOp(left=ast.Name('groupsOfFoldsTotal'), op=ast.Mult(), right=ast.Attribute(value=ast.Name('stateParallel'), attr='leavesTotal')), simple=1)
283
+ , ast.Return(value=ast.Tuple(elts=[ast.Name('foldsTotal'), ast.Name('listStatesParallel')]))]
284
+ , returns=ast.Subscript(value=ast.Name('tuple'), slice=ast.Tuple(elts=[ast.Name('int'), ast.Subscript(value=ast.Name('list'), slice=ast.Name(dataclass_IdentifierParallel))])))
285
+ , imports = LedgerOfImports(Make.Module([ast.ImportFrom(module='concurrent.futures', names=[ast.alias(name='Future', asname='ConcurrentFuture'), ast.alias(name='ProcessPoolExecutor')], level=0),
286
+ ast.ImportFrom(module='copy', names=[ast.alias(name='deepcopy')], level=0),
287
+ ast.ImportFrom(module='multiprocessing', names=[ast.alias(name='set_start_method', asname='multiprocessing_set_start_method')], level=0),])
288
+ )
289
+ )
290
+
291
+ ingredientsModule = IngredientsModule([ingredientsFunction, unRepackDataclass, ingredientsDoTheNeedful]
292
+ , prologue = Make.Module([ast.If(test=ast.Compare(left=ast.Name('__name__'), ops=[ast.Eq()], comparators=[ast.Constant(value='__main__')]), body=[ast.Expr(value=ast.Call(func=ast.Name('multiprocessing_set_start_method'), args=[ast.Constant(value='spawn')]))])])
293
+ )
294
+ ingredientsModule.removeImportFromModule('numpy')
295
+
296
+ pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
297
+
298
+ write_astModule(ingredientsModule, pathFilename, The.packageName)
299
+ return pathFilename
300
+
139
301
  def makeTheorem2() -> PurePath:
140
302
  moduleIdentifierHARDCODED: ast_Identifier = 'theorem2'
141
303
 
@@ -168,7 +330,7 @@ def makeTheorem2() -> PurePath:
168
330
  doThat = Then.removeIt
169
331
  NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
170
332
 
171
- findThis = IfThis.isAttributeNamespace_IdentifierLessThanOrEqual(dataclassInstanceIdentifier, 'leaf1ndex')
333
+ findThis = IfThis.isAttributeNamespace_IdentifierLessThanOrEqual0(dataclassInstanceIdentifier, 'leaf1ndex')
172
334
  doThat = Then.removeIt
173
335
  NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
174
336
 
@@ -266,23 +428,25 @@ def numbaOnTheorem2(pathFilenameSource: PurePath) -> ast.ImportFrom:
266
428
  return astImportFrom
267
429
 
268
430
  def makeUnRePackDataclass(astImportFrom: ast.ImportFrom) -> None:
269
- moduleIdentifierHARDCODED: ast_Identifier = 'dataPacking'
431
+ callableIdentifierHARDCODED: ast_Identifier = 'sequential'
270
432
 
271
433
  algorithmSourceModule = algorithmSourceModuleHARDCODED
272
434
  sourceCallableIdentifier = The.sourceCallableDispatcher
273
435
  logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
274
436
 
275
437
  logicalPathInfix = logicalPathInfixHARDCODED
276
- moduleIdentifier = moduleIdentifierHARDCODED
438
+ moduleIdentifier = dataPackingModuleIdentifierHARDCODED
439
+ callableIdentifier = callableIdentifierHARDCODED
277
440
 
278
- doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
279
- dataclassName: ast.expr | None = NodeTourist(Be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(doTheNeedful.astFunctionDef)
441
+ ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
442
+ ingredientsFunction.astFunctionDef.name = callableIdentifier
443
+ dataclassName: ast.expr | None = NodeTourist(Be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(ingredientsFunction.astFunctionDef)
280
444
  if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
281
445
  dataclass_Identifier: ast_Identifier | None = NodeTourist(Be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
282
446
  if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
283
447
 
284
448
  dataclassLogicalPathModule = None
285
- for moduleWithLogicalPath, listNameTuples in doTheNeedful.imports.dictionaryImportFrom.items():
449
+ for moduleWithLogicalPath, listNameTuples in ingredientsFunction.imports.dictionaryImportFrom.items():
286
450
  for nameTuple in listNameTuples:
287
451
  if nameTuple[0] == dataclass_Identifier:
288
452
  dataclassLogicalPathModule = moduleWithLogicalPath
@@ -290,26 +454,26 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom) -> None:
290
454
  if dataclassLogicalPathModule:
291
455
  break
292
456
  if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
293
- dataclassInstanceIdentifier = NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(doTheNeedful.astFunctionDef)
457
+ dataclassInstanceIdentifier = NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef)
294
458
  if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
295
459
  shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
296
460
 
297
- doTheNeedful.imports.update(shatteredDataclass.imports)
298
- doTheNeedful.imports.addAst(astImportFrom)
461
+ ingredientsFunction.imports.update(shatteredDataclass.imports)
462
+ ingredientsFunction.imports.addAst(astImportFrom)
299
463
  targetCallableIdentifier = astImportFrom.names[0].name
300
- doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
464
+ ingredientsFunction = unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass)
301
465
  if astImportFrom.module is None: raise raiseIfNoneGitHubIssueNumber3
302
466
  targetFunctionDef = extractFunctionDef(parseLogicalPath2astModule(astImportFrom.module), targetCallableIdentifier)
303
467
  if targetFunctionDef is None: raise raiseIfNoneGitHubIssueNumber3
304
- astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)
468
+ astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef) # type: ignore
305
469
  if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
306
470
  astTuple.ctx = ast.Store()
307
471
 
308
- findThis = IfThis.isAssignAndValueIs(IfThis.isCall_Identifier(targetCallableIdentifier))
472
+ findThis = ClassIsAndAttribute.valueIs(ast.Assign, IfThis.isCall_Identifier(targetCallableIdentifier))
309
473
  doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
310
- NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
474
+ NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
311
475
 
312
- ingredientsModule = IngredientsModule(doTheNeedful)
476
+ ingredientsModule = IngredientsModule(ingredientsFunction)
313
477
  ingredientsModule.removeImportFromModule('numpy')
314
478
 
315
479
  pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
@@ -322,4 +486,5 @@ if __name__ == '__main__':
322
486
  pathFilename = trimTheorem2(pathFilename)
323
487
  astImportFrom = numbaOnTheorem2(pathFilename)
324
488
  makeUnRePackDataclass(astImportFrom)
325
- makeDaoOfMapFolding()
489
+ pathFilename = makeDaoOfMapFolding()
490
+ makeDaoOfMapFoldingParallel()
@@ -53,9 +53,6 @@ from astToolkit import (
53
53
  extractClassDef as extractClassDef,
54
54
  extractFunctionDef as extractFunctionDef,
55
55
  Grab as Grab,
56
- ImaCallToName as ImaCallToName,
57
- importLogicalPath2Callable as importLogicalPath2Callable,
58
- importPathFilename2Callable as importPathFilename2Callable,
59
56
  IngredientsFunction as IngredientsFunction,
60
57
  IngredientsModule as IngredientsModule,
61
58
  LedgerOfImports as LedgerOfImports,
@@ -67,12 +64,20 @@ from astToolkit import (
67
64
  parsePathFilename2astModule as parsePathFilename2astModule,
68
65
  str_nameDOTname as str_nameDOTname,
69
66
  Then as Then,
70
- 个 as 个,
67
+ )
68
+
69
+ from Z0Z_tools import importLogicalPath2Callable as importLogicalPath2Callable, importPathFilename2Callable as importPathFilename2Callable
70
+
71
+ from astToolkit.transformationTools import (
72
+ inlineFunctionDef as inlineFunctionDef,
73
+ removeUnusedParameters as removeUnusedParameters,
74
+ unparseFindReplace as unparseFindReplace,
75
+ write_astModule as write_astModule,
71
76
  )
72
77
 
73
78
  from mapFolding.someAssemblyRequired._toolIfThis import IfThis as IfThis
74
79
 
75
- from mapFolding.someAssemblyRequired._toolboxContainers import (
80
+ from mapFolding.someAssemblyRequired._toolkitContainers import (
76
81
  DeReConstructField2ast as DeReConstructField2ast,
77
82
  RecipeSynthesizeFlow as RecipeSynthesizeFlow,
78
83
  ShatteredDataclass as ShatteredDataclass,
@@ -21,7 +21,7 @@ they implement a declarative approach to AST manipulation that separates node id
21
21
 
22
22
  from astToolkit import IfThis as astToolkit_IfThis
23
23
  from collections.abc import Callable
24
- from mapFolding.someAssemblyRequired import ast_Identifier, Be
24
+ from mapFolding.someAssemblyRequired import ast_Identifier, Be, DOT
25
25
  from typing import TypeGuard
26
26
  import ast
27
27
 
@@ -39,15 +39,21 @@ class IfThis(astToolkit_IfThis):
39
39
  @staticmethod
40
40
  def isAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
41
41
  return lambda node: (Be.Compare(node)
42
- and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
42
+ and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(DOT.left(node))
43
43
  and Be.Gt(node.ops[0])
44
44
  and IfThis.isConstant_value(0)(node.comparators[0]))
45
45
  @staticmethod
46
46
  def isIfAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
47
47
  return lambda node: (Be.If(node)
48
- and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
48
+ and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(DOT.test(node)))
49
49
 
50
50
  @staticmethod
51
51
  def isWhileAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
52
52
  return lambda node: (Be.While(node)
53
- and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
53
+ and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(DOT.test(node)))
54
+
55
+ @staticmethod
56
+ def isAttributeNamespace_IdentifierLessThanOrEqual0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
57
+ return lambda node: (Be.Compare(node)
58
+ and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(DOT.left(node))
59
+ and Be.LtE(node.ops[0]))
@@ -18,11 +18,11 @@ The containers work in conjunction with transformation tools that manipulate the
18
18
  specific optimizations and transformations.
19
19
  """
20
20
 
21
- from astToolkit import IngredientsFunction as IngredientsFunction, IngredientsModule as IngredientsModule, LedgerOfImports as LedgerOfImports
22
21
  from collections.abc import Callable
22
+ from astToolkit import ClassIsAndAttribute
23
23
  from copy import deepcopy
24
- from mapFolding.someAssemblyRequired import ast_Identifier, DOT, IfThis, Make, NodeTourist, parseLogicalPath2astModule, str_nameDOTname, Then
25
- from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3, The
24
+ from mapFolding.someAssemblyRequired import ast_Identifier, DOT, IfThis, Make, NodeTourist, parseLogicalPath2astModule, str_nameDOTname, Then, LedgerOfImports
25
+ from mapFolding import raiseIfNoneGitHubIssueNumber3, The
26
26
  from pathlib import Path, PurePosixPath
27
27
  from typing import Any, cast
28
28
  import ast
@@ -158,10 +158,10 @@ class ShatteredDataclass:
158
158
  countingVariableName: ast.Name
159
159
  """AST name node representing the counting variable identifier."""
160
160
 
161
- field2AnnAssign: dict[ast_Identifier, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=dict)
161
+ field2AnnAssign: dict[ast_Identifier, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=lambda: dict[ast_Identifier, ast.AnnAssign | ast.Assign]())
162
162
  """Maps field names to their corresponding AST call expressions."""
163
163
 
164
- Z0Z_field2AnnAssign: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=dict)
164
+ Z0Z_field2AnnAssign: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=lambda: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]]())
165
165
 
166
166
  fragments4AssignmentOrParameters: ast.Tuple = dummyTuple
167
167
  """AST tuple used as target for assignment to capture returned fragments."""
@@ -169,22 +169,22 @@ class ShatteredDataclass:
169
169
  imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
170
170
  """Import records for the dataclass and its constituent parts."""
171
171
 
172
- list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=list)
172
+ list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=lambda: list[ast.arg]())
173
173
  """Function argument nodes with annotations for parameter specification."""
174
174
 
175
- list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=list)
175
+ list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=lambda: list[ast.keyword]())
176
176
  """Keyword arguments for dataclass initialization with field=field format."""
177
177
 
178
- listAnnotations: list[ast.expr] = dataclasses.field(default_factory=list)
178
+ listAnnotations: list[ast.expr] = dataclasses.field(default_factory=lambda: list[ast.expr]())
179
179
  """Type annotations for each dataclass field."""
180
180
 
181
- listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=list)
181
+ listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=lambda: list[ast.Name]())
182
182
  """Name nodes for each dataclass field used as function parameters."""
183
183
 
184
- listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=list)
184
+ listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=lambda: list[ast.AnnAssign]())
185
185
  """Annotated assignment statements to extract fields from dataclass."""
186
186
 
187
- map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=dict)
187
+ map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=lambda: dict[ast.AST, ast.Name]())
188
188
  """Maps AST expressions to Name nodes for find-replace operations."""
189
189
 
190
190
  repack: ast.Assign = dummyAssign
@@ -253,14 +253,12 @@ class DeReConstructField2ast:
253
253
  self.ast_keyword_field__field = Make.keyword(self.name, self.astName)
254
254
  self.ast_nameDOTname = Make.Attribute(Make.Name(dataclassesDOTdataclassInstance_Identifier), self.name)
255
255
 
256
- findThis = IfThis.isAnnAssign_targetIs(IfThis.isName_Identifier(self.name))
257
-
258
- sherpa = NodeTourist(
259
- findThis=findThis
260
- , doThat=Then.extractIt(DOT.annotation)
256
+ sherpa: ast.expr = NodeTourist( # type: ignore
257
+ findThis=ClassIsAndAttribute.targetIs(ast.AnnAssign, IfThis.isName_Identifier(self.name))
258
+ , doThat=Then.extractIt(DOT.annotation) # type: ignore
261
259
  ).captureLastMatch(dataclassClassDef)
262
260
 
263
- if sherpa is None: raise raiseIfNoneGitHubIssueNumber3
261
+ if sherpa is None: raise raiseIfNoneGitHubIssueNumber3 # type: ignore
264
262
  else: self.astAnnotation = sherpa
265
263
 
266
264
  self.ast_argAnnotated = Make.arg(self.name, self.astAnnotation)
@@ -1,4 +1,5 @@
1
- from mapFolding import getPathFilenameFoldsTotal, raiseIfNoneGitHubIssueNumber3, The
1
+ from astToolkit import ClassIsAndAttribute
2
+ from mapFolding import getPathFilenameFoldsTotal, raiseIfNoneGitHubIssueNumber3, The, MapFoldingState
2
3
  from mapFolding.someAssemblyRequired import (
3
4
  ast_Identifier,
4
5
  Be,
@@ -12,12 +13,11 @@ from mapFolding.someAssemblyRequired import (
12
13
  NodeTourist,
13
14
  str_nameDOTname,
14
15
  Then,
16
+ write_astModule,
15
17
  )
16
18
  from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2Numba
17
- from mapFolding.someAssemblyRequired.toolboxNumba import parametersNumbaLight, SpicesJobNumba, decorateCallableWithNumba
18
- from mapFolding.someAssemblyRequired.transformationTools import write_astModule
19
+ from mapFolding.someAssemblyRequired.toolkitNumba import parametersNumbaLight, SpicesJobNumba, decorateCallableWithNumba
19
20
  from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
20
- from mapFolding.dataBaskets import MapFoldingState
21
21
  from pathlib import PurePosixPath
22
22
  from typing import cast, NamedTuple
23
23
  from Z0Z_tools import autoDecodingRLE
@@ -77,7 +77,7 @@ if __name__ == '__main__':
77
77
  ast_argNumbaProgress = ast.arg(arg=spices.numbaProgressBarIdentifier, annotation=ast.Name(id=numba_progressPythonClass, ctx=ast.Load()))
78
78
  ingredientsFunction.astFunctionDef.args.args.append(ast_argNumbaProgress)
79
79
 
80
- findThis = IfThis.isAugAssignAndTargetIs(IfThis.isName_Identifier(job.shatteredDataclass.countingVariableName.id))
80
+ findThis = ClassIsAndAttribute.targetIs(ast.AugAssign, IfThis.isName_Identifier(job.shatteredDataclass.countingVariableName.id)) # type: ignore
81
81
  doThat = Then.replaceWith(Make.Expr(Make.Call(Make.Attribute(Make.Name(spices.numbaProgressBarIdentifier),'update'),[Make.Constant(1)])))
82
82
  countWithProgressBar = NodeChanger(findThis, doThat)
83
83
  countWithProgressBar.visit(ingredientsFunction.astFunctionDef)
@@ -161,10 +161,11 @@ def makeJobNumba(job: RecipeJobTheorem2Numba, spices: SpicesJobNumba) -> None:
161
161
  ingredientsCount: IngredientsFunction = IngredientsFunction(astFunctionDef, LedgerOfImports())
162
162
 
163
163
  # Remove `foldGroups` and any other unused statements, so you can dynamically determine which variables are not used
164
- findThis = IfThis.isAssignAndTargets0Is(IfThis.isSubscript_Identifier('foldGroups'))
164
+ findThis = ClassIsAndAttribute.targetsIs(ast.Assign, lambda list_expr: any([IfThis.isSubscript_Identifier('foldGroups')(node) for node in list_expr ]))
165
+ # findThis = IfThis.isAssignAndTargets0Is(IfThis.isSubscript_Identifier('foldGroups'))
165
166
  doThat = Then.removeIt
166
167
  remove_foldGroups = NodeChanger(findThis, doThat)
167
- remove_foldGroups.visit(ingredientsCount.astFunctionDef)
168
+ # remove_foldGroups.visit(ingredientsCount.astFunctionDef)
168
169
 
169
170
  # replace identifiers with static values with their values, so you can dynamically determine which variables are not used
170
171
  list_IdentifiersStaticValues = list_IdentifiersStaticValuesHARDCODED
@@ -260,7 +261,7 @@ if __name__ == '__main__':
260
261
  """
261
262
 
262
263
  if __name__ == '__main__':
263
- mapShape = (1,46)
264
+ mapShape = (2,4)
264
265
  state = MapFoldingState(mapShape)
265
266
  state = initializeGroupsOfFolds(state)
266
267
  # foldsTotalEstimated = getFoldsTotalKnown(state.mapShape) // state.leavesTotal
@@ -18,6 +18,7 @@ This creates extremely fast, specialized implementations that can be run directl
18
18
  as Python scripts or further compiled into standalone executables.
19
19
  """
20
20
 
21
+ from astToolkit import ClassIsAndAttribute
21
22
  from mapFolding import getPathFilenameFoldsTotal, raiseIfNoneGitHubIssueNumber3, The
22
23
  from mapFolding.someAssemblyRequired import (
23
24
  ast_Identifier,
@@ -32,10 +33,11 @@ from mapFolding.someAssemblyRequired import (
32
33
  NodeTourist,
33
34
  str_nameDOTname,
34
35
  Then,
36
+ write_astModule,
35
37
  )
36
38
  from mapFolding.someAssemblyRequired.RecipeJob import RecipeJob
37
- from mapFolding.someAssemblyRequired.toolboxNumba import parametersNumbaLight, SpicesJobNumba, decorateCallableWithNumba
38
- from mapFolding.someAssemblyRequired.transformationTools import dictionaryEstimates, write_astModule, makeInitializedComputationState
39
+ from mapFolding.someAssemblyRequired.toolkitNumba import parametersNumbaLight, SpicesJobNumba, decorateCallableWithNumba
40
+ from mapFolding.someAssemblyRequired.transformationTools import dictionaryEstimates, makeInitializedComputationState
39
41
  from pathlib import PurePosixPath
40
42
  from typing import cast, NamedTuple
41
43
  from Z0Z_tools import autoDecodingRLE
@@ -95,7 +97,7 @@ if __name__ == '__main__':
95
97
  ast_argNumbaProgress = ast.arg(arg=spices.numbaProgressBarIdentifier, annotation=ast.Name(id=numba_progressPythonClass, ctx=ast.Load()))
96
98
  ingredientsFunction.astFunctionDef.args.args.append(ast_argNumbaProgress)
97
99
 
98
- findThis = IfThis.isAugAssignAndTargetIs(IfThis.isName_Identifier(job.shatteredDataclass.countingVariableName.id))
100
+ findThis = ClassIsAndAttribute.targetIs(ast.AugAssign, IfThis.isName_Identifier(job.shatteredDataclass.countingVariableName.id)) # type: ignore
99
101
  doThat = Then.replaceWith(Make.Expr(Make.Call(Make.Attribute(Make.Name(spices.numbaProgressBarIdentifier),'update'),[Make.Constant(1)])))
100
102
  countWithProgressBar = NodeChanger(findThis, doThat)
101
103
  countWithProgressBar.visit(ingredientsFunction.astFunctionDef)
@@ -17,8 +17,8 @@ performance improvements while preserving code semantics and correctness.
17
17
 
18
18
  from collections.abc import Callable, Sequence
19
19
  from mapFolding import NotRequired, TypedDict
20
- from mapFolding.someAssemblyRequired import ast_Identifier, IngredientsFunction, Make, RecipeSynthesizeFlow, str_nameDOTname
21
- from mapFolding.someAssemblyRequired.transformationTools import makeNewFlow, write_astModule
20
+ from mapFolding.someAssemblyRequired import ast_Identifier, IngredientsFunction, Make, RecipeSynthesizeFlow, str_nameDOTname, write_astModule
21
+ from mapFolding.someAssemblyRequired.transformationTools import makeNewFlow
22
22
  from numba.core.compiler import CompilerBase as numbaCompilerBase
23
23
  from typing import Any, cast, Final
24
24
  import ast