mapFolding 0.3.12__py3-none-any.whl → 0.4.1__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 (46) hide show
  1. mapFolding/__init__.py +40 -38
  2. mapFolding/basecamp.py +50 -50
  3. mapFolding/beDRY.py +336 -336
  4. mapFolding/oeis.py +262 -262
  5. mapFolding/reference/flattened.py +294 -293
  6. mapFolding/reference/hunterNumba.py +126 -126
  7. mapFolding/reference/irvineJavaPort.py +99 -99
  8. mapFolding/reference/jax.py +153 -153
  9. mapFolding/reference/lunnan.py +148 -148
  10. mapFolding/reference/lunnanNumpy.py +115 -115
  11. mapFolding/reference/lunnanWhile.py +114 -114
  12. mapFolding/reference/rotatedEntryPoint.py +183 -183
  13. mapFolding/reference/total_countPlus1vsPlusN.py +203 -203
  14. mapFolding/someAssemblyRequired/__init__.py +5 -1
  15. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +12 -12
  16. mapFolding/someAssemblyRequired/makeJob.py +46 -52
  17. mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +17 -17
  18. mapFolding/someAssemblyRequired/synthesizeNumba.py +343 -633
  19. mapFolding/someAssemblyRequired/synthesizeNumbaGeneralized.py +325 -0
  20. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +173 -0
  21. mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +77 -0
  22. mapFolding/syntheticModules/__init__.py +0 -0
  23. mapFolding/syntheticModules/numba_countInitialize.py +4 -4
  24. mapFolding/syntheticModules/numba_countParallel.py +4 -4
  25. mapFolding/syntheticModules/numba_countSequential.py +4 -4
  26. mapFolding/syntheticModules/numba_doTheNeedful.py +7 -7
  27. mapFolding/theDao.py +165 -165
  28. mapFolding/theSSOT.py +177 -173
  29. mapFolding/theSSOTnumba.py +90 -74
  30. mapFolding-0.4.1.dist-info/METADATA +154 -0
  31. mapFolding-0.4.1.dist-info/RECORD +42 -0
  32. tests/conftest.py +253 -129
  33. tests/test_computations.py +79 -0
  34. tests/test_oeis.py +76 -85
  35. tests/test_other.py +136 -224
  36. tests/test_tasks.py +19 -23
  37. tests/test_types.py +2 -2
  38. mapFolding/someAssemblyRequired/synthesizeNumbaHardcoding.py +0 -188
  39. mapFolding-0.3.12.dist-info/METADATA +0 -155
  40. mapFolding-0.3.12.dist-info/RECORD +0 -40
  41. tests/conftest_tmpRegistry.py +0 -62
  42. tests/conftest_uniformTests.py +0 -53
  43. {mapFolding-0.3.12.dist-info → mapFolding-0.4.1.dist-info}/LICENSE +0 -0
  44. {mapFolding-0.3.12.dist-info → mapFolding-0.4.1.dist-info}/WHEEL +0 -0
  45. {mapFolding-0.3.12.dist-info → mapFolding-0.4.1.dist-info}/entry_points.txt +0 -0
  46. {mapFolding-0.3.12.dist-info → mapFolding-0.4.1.dist-info}/top_level.txt +0 -0
@@ -1,188 +0,0 @@
1
- from synthesizeNumba import *
2
-
3
- def makeNumbaOptimizedFlow(listCallablesInline: List[str], callableDispatcher: Optional[str] = None, algorithmSource: Optional[ModuleType] = None) -> None:
4
- if not algorithmSource:
5
- algorithmSource = getAlgorithmSource()
6
-
7
- formatModuleNameDEFAULT = "numba_{callableTarget}"
8
-
9
- # When I am a more competent programmer, I will make getPathFilenameWrite dependent on makeAstImport or vice versa,
10
- # so the name of the physical file doesn't get out of whack with the name of the logical module.
11
- def getPathFilenameWrite(callableTarget: str
12
- , pathWrite: Optional[pathlib.Path] = None
13
- , formatFilenameWrite: Optional[str] = None
14
- ) -> pathlib.Path:
15
- if not pathWrite:
16
- pathWrite = getPathSyntheticModules()
17
- if not formatFilenameWrite:
18
- formatFilenameWrite = formatModuleNameDEFAULT + '.py'
19
-
20
- pathFilename = pathWrite / formatFilenameWrite.format(callableTarget=callableTarget)
21
- return pathFilename
22
-
23
- def makeAstImport(callableTarget: str
24
- , packageName: Optional[str] = None
25
- , subPackageName: Optional[str] = None
26
- , moduleName: Optional[str] = None
27
- , astNodeLogicalPathThingy: Optional[ast.AST] = None
28
- ) -> ast.ImportFrom:
29
- """Creates import AST node for synthetic modules."""
30
- if astNodeLogicalPathThingy is None:
31
- if packageName is None:
32
- packageName = myPackageNameIs
33
- if subPackageName is None:
34
- subPackageName = moduleOfSyntheticModules
35
- if moduleName is None:
36
- moduleName = formatModuleNameDEFAULT.format(callableTarget=callableTarget)
37
- module=f'{packageName}.{subPackageName}.{moduleName}'
38
- else:
39
- module = str(astNodeLogicalPathThingy)
40
- return ast.ImportFrom(
41
- module=module,
42
- names=[ast.alias(name=callableTarget, asname=None)],
43
- level=0
44
- )
45
-
46
- listStuffYouOughtaKnow: List[youOughtaKnow] = []
47
-
48
- for callableTarget in listCallablesInline:
49
- pythonSource = inspect.getsource(algorithmSource)
50
- parametersNumba = None
51
- unpackArrays = False
52
- match callableTarget:
53
- case 'countParallel':
54
- parametersNumba = parametersNumbaSuperJitParallel
55
- case 'countSequential':
56
- parametersNumba = parametersNumbaSuperJit
57
- unpackArrays = True
58
- case 'countInitialize':
59
- parametersNumba = parametersNumbaDEFAULT
60
- pythonSource = inlineOneCallable(pythonSource, callableTarget, parametersNumba, unpackArrays)
61
- if not pythonSource:
62
- raise Exception("Pylance, OMG! The sky is falling!")
63
-
64
- pathFilename = getPathFilenameWrite(callableTarget)
65
-
66
- listStuffYouOughtaKnow.append(youOughtaKnow(
67
- callableSynthesized=callableTarget,
68
- pathFilenameForMe=pathFilename,
69
- astForCompetentProgrammers=makeAstImport(callableTarget)
70
- ))
71
- pythonSource = autoflake.fix_code(pythonSource, ['mapFolding', 'numba', 'numpy'])
72
- pathFilename.write_text(pythonSource)
73
-
74
- # Generate dispatcher if requested
75
- if callableDispatcher:
76
- pythonSource = inspect.getsource(algorithmSource)
77
- pythonSource = makeDispatcherNumba(pythonSource, callableDispatcher, listStuffYouOughtaKnow)
78
- if not pythonSource:
79
- raise FREAKOUT
80
-
81
- pathFilename = getPathFilenameWrite(callableDispatcher)
82
-
83
- listStuffYouOughtaKnow.append(youOughtaKnow(
84
- callableSynthesized=callableDispatcher,
85
- pathFilenameForMe=pathFilename,
86
- astForCompetentProgrammers=makeAstImport(callableDispatcher)
87
- ))
88
- pythonSource = autoflake.fix_code(pythonSource, ['mapFolding', 'numba', 'numpy'])
89
- pathFilename.write_text(pythonSource)
90
-
91
- def writeJobNumba(listDimensions: Sequence[int], callableTarget: str, algorithmSource: ModuleType, parametersNumba: Optional[ParametersNumba]=None, pathFilenameWriteJob: Optional[Union[str, os.PathLike[str]]] = None, **keywordArguments: Optional[Any]) -> pathlib.Path:
92
- """ Parameters: **keywordArguments: most especially for `computationDivisions` if you want to make a parallel job. Also `CPUlimit`. """
93
- """Notes about the existing logic:
94
- - the synthesized module must run well as a standalone interpreted Python script
95
- - `writeJobNumba` synthesizes a parameter-specific module by starting with code synthesized by `makeNumbaOptimizedFlow`, which improves the optimization
96
- - similarly, `writeJobNumba` should be a solid foundation for more optimizations, most especially compiling to a standalone executable, but the details of the next optimization step are unknown
97
- - the minimum runtime (on my computer) to compute a value unknown to mathematicians is 26 hours, therefore, we ant to ensure the value is seen by the user, but we must have ultra-light overhead.
98
- - perf_counter is for testing. When I run a real job, I delete those lines
99
- - avoid `with` statement
100
- """
101
- stateJob = makeStateJob(listDimensions, writeJob=False, **keywordArguments)
102
- pythonSource = inspect.getsource(algorithmSource)
103
- astModule = ast.parse(pythonSource)
104
-
105
- allImports = UniversalImportTracker()
106
-
107
- for statement in astModule.body:
108
- if isinstance(statement, (ast.Import, ast.ImportFrom)):
109
- allImports.addAst(statement)
110
-
111
- FunctionDefTarget = next((node for node in astModule.body if isinstance(node, ast.FunctionDef) and node.name == callableTarget), None)
112
- if not FunctionDefTarget: raise ValueError(f"I received `{callableTarget=}` and {algorithmSource.__name__=}, but I could not find that function in that source.")
113
-
114
- for pirateScowl in FunctionDefTarget.args.args.copy():
115
- match pirateScowl.arg:
116
- case 'my':
117
- FunctionDefTarget, allImports = evaluate_argIn_body(FunctionDefTarget, pirateScowl, stateJob[pirateScowl.arg], ['taskIndex', 'dimensionsTotal'], allImports)
118
- case 'track':
119
- FunctionDefTarget, allImports = evaluateArrayIn_body(FunctionDefTarget, pirateScowl, stateJob[pirateScowl.arg], allImports)
120
- # TODO remove this after implementing `unrollWhileLoop`
121
- case 'connectionGraph':
122
- FunctionDefTarget, allImports = moveArrayTo_body(FunctionDefTarget, pirateScowl, stateJob[pirateScowl.arg], allImports)
123
- case 'gapsWhere':
124
- FunctionDefTarget, allImports = moveArrayTo_body(FunctionDefTarget, pirateScowl, stateJob[pirateScowl.arg], allImports)
125
- case 'foldGroups':
126
- FunctionDefTarget = removeIdentifierFrom_body(FunctionDefTarget, pirateScowl)
127
-
128
- # Move function parameters to the function body,
129
- # initialize identifiers with their state types and values,
130
- # and replace static-valued identifiers with their values.
131
- FunctionDefTarget, allImports = evaluateAnnAssignIn_body(FunctionDefTarget, allImports)
132
- FunctionDefTarget = astNameToAstConstant(FunctionDefTarget, 'dimensionsTotal', int(stateJob['my'][indexMy.dimensionsTotal]))
133
- FunctionDefTarget = astObjectToAstConstant(FunctionDefTarget, 'foldGroups[-1]', int(stateJob['foldGroups'][-1]))
134
-
135
- FunctionDefTarget = unrollWhileLoop(FunctionDefTarget, 'indexDimension', stateJob['my'][indexMy.dimensionsTotal], stateJob['connectionGraph'])
136
-
137
- FunctionDefTarget, allImports = addReturnJobNumba(FunctionDefTarget, stateJob, allImports)
138
- FunctionDefTarget, allImports = makeDecoratorJobNumba(FunctionDefTarget, allImports, parametersNumba)
139
-
140
- pathFilenameFoldsTotal = getPathFilenameFoldsTotal(stateJob['mapShape'])
141
- # TODO consider: 1) launcher is a function, 2) if __name__ calls the launcher function, and 3) the launcher is "jitted", even just a light jit, then 4) `FunctionDefTarget` could be superJit.
142
- astLauncher = makeLauncherJobNumba(FunctionDefTarget.name, pathFilenameFoldsTotal)
143
-
144
- astImports = allImports.makeListAst()
145
-
146
- astModule = ast.Module(body=cast(List[ast.stmt], astImports + [FunctionDefTarget] + [astLauncher]), type_ignores=[])
147
- ast.fix_missing_locations(astModule)
148
-
149
- pythonSource = ast.unparse(astModule)
150
- pythonSource = autoflake.fix_code(pythonSource, ['mapFolding', 'numba', 'numpy'])
151
-
152
- if pathFilenameWriteJob is None:
153
- filename = getFilenameFoldsTotal(stateJob['mapShape'])
154
- pathRoot = getPathJobRootDEFAULT()
155
- pathFilenameWriteJob = pathlib.Path(pathRoot, pathlib.Path(filename).stem, pathlib.Path(filename).with_suffix('.py'))
156
- else:
157
- pathFilenameWriteJob = pathlib.Path(pathFilenameWriteJob)
158
- pathFilenameWriteJob.parent.mkdir(parents=True, exist_ok=True)
159
-
160
- pathFilenameWriteJob.write_text(pythonSource)
161
- return pathFilenameWriteJob
162
-
163
- def mainBig():
164
- setDatatypeModule('numpy', sourGrapes=True)
165
- setDatatypeFoldsTotal('int64', sourGrapes=True)
166
- setDatatypeElephino('uint8', sourGrapes=True)
167
- setDatatypeLeavesTotal('uint8', sourGrapes=True)
168
- listCallablesInline: List[str] = ['countInitialize', 'countParallel', 'countSequential']
169
- Z0Z_setDatatypeModuleScalar('numba')
170
- Z0Z_setDecoratorCallable('jit')
171
- callableDispatcher = 'doTheNeedful'
172
- makeNumbaOptimizedFlow(listCallablesInline, callableDispatcher)
173
-
174
- def mainSmall():
175
- listDimensions = [6,6]
176
- setDatatypeFoldsTotal('int64', sourGrapes=True)
177
- setDatatypeElephino('uint8', sourGrapes=True)
178
- setDatatypeLeavesTotal('uint8', sourGrapes=True)
179
- from mapFolding.syntheticModules import numba_countSequential
180
- algorithmSource: ModuleType = numba_countSequential
181
- Z0Z_setDatatypeModuleScalar('numba')
182
- Z0Z_setDecoratorCallable('jit')
183
- writeJobNumba(listDimensions, 'countSequential', algorithmSource, parametersNumbaDEFAULT)
184
-
185
- if __name__ == '__main__':
186
- mainBig()
187
-
188
- mainSmall()
@@ -1,155 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: mapFolding
3
- Version: 0.3.12
4
- Summary: Count distinct ways to fold a map (or a strip of stamps)
5
- Author-email: Hunter Hogan <HunterHogan@pm.me>
6
- License: CC-BY-NC-4.0
7
- Project-URL: Donate, https://www.patreon.com/integrated
8
- Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
9
- Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
10
- Keywords: A001415,A001416,A001417,A001418,A195646,folding,map folding,OEIS,stamp folding
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Environment :: Console
13
- Classifier: Intended Audience :: Education
14
- Classifier: Intended Audience :: End Users/Desktop
15
- Classifier: Intended Audience :: Other Audience
16
- Classifier: Intended Audience :: Science/Research
17
- Classifier: Natural Language :: English
18
- Classifier: Operating System :: OS Independent
19
- Classifier: Programming Language :: Python
20
- Classifier: Topic :: Scientific/Engineering :: Mathematics
21
- Classifier: Typing :: Typed
22
- Requires-Python: >=3.10
23
- Description-Content-Type: text/markdown
24
- License-File: LICENSE
25
- Requires-Dist: numba
26
- Requires-Dist: numpy
27
- Requires-Dist: Z0Z_tools
28
- Provides-Extra: testing
29
- Requires-Dist: autoflake; extra == "testing"
30
- Requires-Dist: more_itertools; extra == "testing"
31
- Requires-Dist: mypy; extra == "testing"
32
- Requires-Dist: pytest-cov; extra == "testing"
33
- Requires-Dist: pytest-env; extra == "testing"
34
- Requires-Dist: pytest-mypy; extra == "testing"
35
- Requires-Dist: pytest-xdist; extra == "testing"
36
- Requires-Dist: pytest; extra == "testing"
37
- Requires-Dist: python_minifier; extra == "testing"
38
- Requires-Dist: types-setuptools; extra == "testing"
39
- Requires-Dist: updateCitation; extra == "testing"
40
-
41
- # Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
42
-
43
- The function `mapFolding.countFolds()` counts distinct ways to fold maps and strips of stamps. The function accepts two or more dimensions:
44
-
45
- ```python
46
- from mapFolding import countFolds
47
- foldsTotal = countFolds( [2,10] )
48
- ```
49
-
50
- The directory [mapFolding/reference](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/reference) has
51
-
52
- - a verbatim transcription of Lunnon's "procedure" published in 1971 by _The Computer Journal_,
53
- - multiple referential versions of the procedure with explanatory comments including
54
- - [hunterNumba.py](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/reference), a one-size-fits-all, self-contained, reasonably fast, contemporary algorithm that is nevertheless infected by _noobaceae ignorancium_, and
55
- - miscellaneous notes.
56
-
57
- [![pip install mapFolding](https://img.shields.io/badge/pip%20install-mapFolding-gray.svg?colorB=3b434b)](https://pypi.org/project/mapFolding/) [![Python Tests](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml/badge.svg)](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml) [![Static Badge](https://img.shields.io/badge/stinkin'%20badges-don't%20need-b98e5e)](https://youtu.be/g6f_miE91mk&t=4) ![PyPI - Downloads](https://img.shields.io/pypi/dd/mapFolding) ![Static Badge](https://img.shields.io/badge/issues-I%20have%20them-brightgreen) ![GitHub repo size](https://img.shields.io/github/repo-size/hunterhogan/mapFolding)
58
-
59
- ## Simple, easy usage based on OEIS IDs
60
-
61
- `mapFolding` directly implements some IDs from _The On-Line Encyclopedia of Integer Sequences_ ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/citations/oeis.bibtex) citation).
62
-
63
- ### Usage: command line
64
-
65
- After installing (see below), `OEIS_for_n` will run a computation from the command line.
66
-
67
- ```cmd
68
- (mapFolding) C:\apps\mapFolding> OEIS_for_n A001418 5
69
- 186086600 distinct folding patterns.
70
- Time elapsed: 1.605 seconds
71
- ```
72
-
73
- Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
74
-
75
- ```cmd
76
- (mapFolding) C:\apps\mapFolding> getOEISids
77
-
78
- Available OEIS sequences:
79
- A001415: Number of ways of folding a 2 X n strip of stamps.
80
- A001416: Number of ways of folding a 3 X n strip of stamps.
81
- A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
82
- A001418: Number of ways of folding an n X n sheet of stamps.
83
- A195646: Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.
84
-
85
- Usage examples:
86
- Command line:
87
- OEIS_for_n A001415 8
88
- Python:
89
- from mapFolding import oeisIDfor_n
90
- foldsTotal = oeisIDfor_n('A001415', 8)
91
- ```
92
-
93
- ### Usage: Python module or REPL
94
-
95
- Use `mapFolding.oeisIDfor_n()` to compute a(n) for an OEIS ID.
96
-
97
- ```python
98
- from mapFolding import oeisIDfor_n
99
- foldsTotal = oeisIDfor_n( 'A001418', 4 )
100
- ```
101
-
102
- ### An "advanced" and likely unnecessary feature: clear `mapFolding`'s cache of OEIS data
103
-
104
- Clear _The On-Line Encyclopedia of Integer Sequences_ data from the `mapFolding` cache:
105
-
106
- ```sh
107
- (mapFolding) C:\apps\mapFolding> clearOEIScache
108
- Cache cleared from C:\apps\mapFolding\mapFolding\.cache
109
- ```
110
-
111
- ## Connections to "Multi-dimensional map-folding" by W. F. Lunnon
112
-
113
- ### The typo-laden algorithm published in 1971
114
-
115
- The full paper, W. F. Lunnon, Multi-dimensional map-folding, _The Computer Journal_, Volume 14, Issue 1, 1971, Pages 75–80, [https://doi.org/10.1093/comjnl/14.1.75](https://doi.org/10.1093/comjnl/14.1.75) ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/citations/Lunnon.bibtex) citation) is available at the DOI link. (As of 3 January 2025, the paper is a PDF of images, not text, and can be accessed without cost or login.)
116
-
117
- In [`foldings.txt`](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/reference/foldings.txt), you can find a text transcription of the algorithm as it was printed in 1971. In [`foldings.AA`](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/reference/foldings.AA), I have corrected obvious transcription errors, documented with comments, and I have reformatted line breaks and indentation. For contemporary readers, the result is likely easier to read than the text transcription or the original paper are easy to read. This is especially true if you view the document with semantic highlighting, such as with [Algol 60 syntax highlighter](https://github.com/PolariTOON/language-algol60).
118
-
119
- ### Java implementation(s) and improvements
120
-
121
- [archmageirvine](https://github.com/archmageirvine/joeis/blob/80e3e844b11f149704acbab520bc3a3a25ac34ff/src/irvine/oeis/a001/A001415.java) ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/citations/jOEIS.bibtex) citation) says about the Java code:
122
-
123
- ```java
124
- /**
125
- * A001415 Number of ways of folding a 2 X n strip of stamps.
126
- * @author Fred Lunnon (ALGOL68, C versions)
127
- * @author Sean A. Irvine (Java port)
128
- */
129
- ...
130
- // Implements algorithm as described in "Multi-dimensional map-folding",
131
- // by W. F. Lunnon, The Computer J, 14, 1, pp. 75--80. Note the original
132
- // paper contains a few omissions, so this actual code is based on a C
133
- // implementation by Fred Lunnon.
134
- ```
135
-
136
- ## Map-folding Video
137
-
138
- ~~This caused my neurosis:~~ I enjoyed the following video, which is what introduced me to map folding.
139
-
140
- "How Many Ways Can You Fold a Map?" by Physics for the Birds, 2024 November 13 ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/mapFolding/citations/Physics_for_the_Birds.bibtex) citation)
141
-
142
- [![How Many Ways Can You Fold a Map?](https://i.ytimg.com/vi/sfH9uIY3ln4/hq720.jpg)](https://www.youtube.com/watch?v=sfH9uIY3ln4)
143
-
144
- ## Installation
145
-
146
- ```sh
147
- pip install mapFolding
148
- ```
149
-
150
- ## My recovery
151
-
152
- [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
153
- [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
154
-
155
- [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.svg)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -1,40 +0,0 @@
1
- mapFolding/__init__.py,sha256=XYw6cd3gQLFxoMuSSHwScp9-uFUU5B22Edy2pHNULJ8,1384
2
- mapFolding/basecamp.py,sha256=DISWQIzAF7o7WPUn2QZxMu3Ruwc0zkVPgceeUTUcfqo,3988
3
- mapFolding/beDRY.py,sha256=Gsj7NEBztbPoKszPibhW6pO9xwjAIPgaW411A_Quwz8,18654
4
- mapFolding/oeis.py,sha256=2kFIAnBu0Bs4rHceXqs1RyyEBM6A_5fR5562B4ShxVg,12311
5
- mapFolding/theDao.py,sha256=qzZgXqI68NeKevMNZSFTnar4NsyploGTl-_Wwo8P-2s,14274
6
- mapFolding/theSSOT.py,sha256=hl6VUR3P7e6JF3L4rHI_icnmNR1gJJUAI2rCvlQmCDs,10577
7
- mapFolding/theSSOTnumba.py,sha256=SXPa9Qkr0IUFBb3k5__088IAS0imWHG8Aui2S27XbuE,5689
8
- mapFolding/reference/flattened.py,sha256=6blZ2Y9G8mu1F3gV8SKndPE398t2VVFlsgKlyeJ765A,16538
9
- mapFolding/reference/hunterNumba.py,sha256=HWndRgsajOf76rbb2LDNEZ6itsdYbyV-k3wgOFjeR6c,7104
10
- mapFolding/reference/irvineJavaPort.py,sha256=Sj-63Z-OsGuDoEBXuxyjRrNmmyl0d7Yz_XuY7I47Oyg,4250
11
- mapFolding/reference/jax.py,sha256=rojyK80lOATtbzxjGOHWHZngQa47CXCLJHZwIdN2MwI,14955
12
- mapFolding/reference/lunnan.py,sha256=XEcql_gxvCCghb6Or3qwmPbn4IZUbZTaSmw_fUjRxZE,5037
13
- mapFolding/reference/lunnanNumpy.py,sha256=HqDgSwTOZA-G0oophOEfc4zs25Mv4yw2aoF1v8miOLk,4653
14
- mapFolding/reference/lunnanWhile.py,sha256=7NY2IKO5XBgol0aWWF_Fi-7oTL9pvu_z6lB0TF1uVHk,4063
15
- mapFolding/reference/rotatedEntryPoint.py,sha256=z0QyDQtnMvXNj5ntWzzJUQUMFm1-xHGLVhtYzwmczUI,11530
16
- mapFolding/reference/total_countPlus1vsPlusN.py,sha256=usenM8Yn_G1dqlPl7NKKkcnbohBZVZBXTQRm2S3_EDA,8106
17
- mapFolding/someAssemblyRequired/__init__.py,sha256=3JnAKXfaYPtmxV_4AnZ6KpCosT_0GFV5Nw7K8sz4-Uo,34
18
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=FtJzw2pZS3A4NimWdZsegXaU-vKeCw8m67kcfb5wvGM,894
19
- mapFolding/someAssemblyRequired/makeJob.py,sha256=2RtRAHBMDAiOsJpnj1-J1Yso3beQu5hk8bUfgE367Zs,2592
20
- mapFolding/someAssemblyRequired/synthesizeModuleJAX.py,sha256=TU8lgoMr77pctvvmlfbT-XstQk4j6Jo8JcIuvAiCuMU,1316
21
- mapFolding/someAssemblyRequired/synthesizeNumba.py,sha256=6wQnKLj2hbj-z4enypYoDpS6LcrE6lMDYUQ8eXquv_o,33476
22
- mapFolding/someAssemblyRequired/synthesizeNumbaHardcoding.py,sha256=aOATx1_cUcd7pb6YhdDe9ydL0QB6538NoFgyPKXzYpg,9994
23
- mapFolding/syntheticModules/numba_countInitialize.py,sha256=Cpk3HETqlQhyX431RzmvBSgKOx7nX9ZC4iCyBYHldMA,4274
24
- mapFolding/syntheticModules/numba_countParallel.py,sha256=5qrYl8InirBjzQKQh9eny7ajCU-pHk-oZS11alOxhJs,5517
25
- mapFolding/syntheticModules/numba_countSequential.py,sha256=oMJ9W_ob9sIE-7xfFkFCjG83MeylJJCjmL3_xWHMUdk,3732
26
- mapFolding/syntheticModules/numba_doTheNeedful.py,sha256=xbKeYWACpbVMNitWPQeTr8l-YY6Y228Lu_JRDjsAPfE,1369
27
- tests/__init__.py,sha256=eg9smg-6VblOr0kisM40CpGnuDtU2JgEEWGDTFVOlW8,57
28
- tests/conftest.py,sha256=tGRYkHfwVKGoMklBSQiTD8cTu-QL1wUSZd-52Xlnm50,7676
29
- tests/conftest_tmpRegistry.py,sha256=0XpGe7s2aJcjdEAqKs10vceW0_JAaK-Rp1UoPaL-BIo,2450
30
- tests/conftest_uniformTests.py,sha256=2v9UJbKgbrus3UyWXsanEHLksBskbnP0MD8iKVPaIBo,2178
31
- tests/test_oeis.py,sha256=F89HJ27y54NXcR2wMeBS4ea6R7EaEqpF_GkcU-BrsK4,5694
32
- tests/test_other.py,sha256=UpS0_WUfWA3wONuZwip5AMmzNmmBwYD7reQDZ9ziL_o,12224
33
- tests/test_tasks.py,sha256=ap_tKjHUN95vjzKo3xzBAQ3kMbdMJ_XXbOv9YIBJ5pY,2826
34
- tests/test_types.py,sha256=HklNCGThFiqQ89AOMkE7YkcfAPiZE32DpD3GMDUPQVc,177
35
- mapFolding-0.3.12.dist-info/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
36
- mapFolding-0.3.12.dist-info/METADATA,sha256=y4-lXqgLwjgfGI3mlRHcNsaz3VjiGAsF3RpIFNLcj7g,7785
37
- mapFolding-0.3.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
38
- mapFolding-0.3.12.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
39
- mapFolding-0.3.12.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
40
- mapFolding-0.3.12.dist-info/RECORD,,
@@ -1,62 +0,0 @@
1
- from typing import Any, Generator, Set
2
- import pathlib
3
- import pytest
4
- import shutil
5
- import uuid
6
-
7
- # SSOT for test data paths
8
- pathDataSamples = pathlib.Path("tests/dataSamples")
9
- pathTempRoot = pathDataSamples / "tmp"
10
-
11
- # The registrar maintains the register of temp files
12
- registerOfTempFiles: Set[pathlib.Path] = set()
13
-
14
- def addTempFileToRegister(path: pathlib.Path) -> None:
15
- """The registrar adds a temp file to the register."""
16
- registerOfTempFiles.add(path)
17
-
18
- def cleanupTempFileRegister() -> None:
19
- """The registrar cleans up temp files in the register."""
20
- for pathTemp in sorted(registerOfTempFiles, reverse=True):
21
- try:
22
- if pathTemp.is_file():
23
- pathTemp.unlink(missing_ok=True)
24
- elif pathTemp.is_dir():
25
- shutil.rmtree(pathTemp, ignore_errors=True)
26
- except Exception as ERRORmessage:
27
- print(f"Warning: Failed to clean up {pathTemp}: {ERRORmessage}")
28
- registerOfTempFiles.clear()
29
-
30
- @pytest.fixture(scope="session", autouse=True)
31
- def setupTeardownTestData() -> Generator[None, None, None]:
32
- """Auto-fixture to setup test data directories and cleanup after."""
33
- pathDataSamples.mkdir(exist_ok=True)
34
- pathTempRoot.mkdir(exist_ok=True)
35
- yield
36
- cleanupTempFileRegister()
37
-
38
- @pytest.fixture
39
- def pathTempTesting(request: pytest.FixtureRequest) -> pathlib.Path:
40
- """Create a unique temp directory for each test function."""
41
- # TODO I got rid of this shit. how the fuck is it back?
42
- # Sanitize test name for filesystem compatibility
43
- sanitizedName = request.node.name.replace('[', '_').replace(']', '_').replace('/', '_')
44
- uniqueDirectory = f"{sanitizedName}_{uuid.uuid4()}"
45
- pathTemp = pathTempRoot / uniqueDirectory
46
- pathTemp.mkdir(parents=True, exist_ok=True)
47
-
48
- addTempFileToRegister(pathTemp)
49
- return pathTemp
50
-
51
- @pytest.fixture
52
- def pathCacheTesting(pathTempTesting: pathlib.Path) -> Generator[pathlib.Path, Any, None]:
53
- """Temporarily replace the OEIS cache directory with a test directory."""
54
- from mapFolding import oeis as there_must_be_a_better_way
55
- pathCacheOriginal = there_must_be_a_better_way._pathCache
56
- there_must_be_a_better_way._pathCache = pathTempTesting
57
- yield pathTempTesting
58
- there_must_be_a_better_way._pathCache = pathCacheOriginal
59
-
60
- @pytest.fixture
61
- def pathFilenameFoldsTotalTesting(pathTempTesting: pathlib.Path) -> pathlib.Path:
62
- return pathTempTesting.joinpath("foldsTotalTest.txt")
@@ -1,53 +0,0 @@
1
- from typing import Any, Callable, Sequence, Type, Union
2
- import pytest
3
-
4
- def uniformTestMessage(expected: Any, actual: Any, functionName: str, *arguments: Any) -> str:
5
- """Format assertion message for any test comparison."""
6
- return (f"\nTesting: `{functionName}({', '.join(str(parameter) for parameter in arguments)})`\n"
7
- f"Expected: {expected}\n"
8
- f"Got: {actual}")
9
-
10
- def standardizedEqualTo(expected: Any, functionTarget: Callable, *arguments: Any) -> None:
11
- """Template for tests expecting an error."""
12
- if type(expected) is Type[Exception]:
13
- messageExpected = expected.__name__
14
- else:
15
- messageExpected = expected
16
-
17
- try:
18
- messageActual = actual = functionTarget(*arguments)
19
- except Exception as actualError:
20
- messageActual = type(actualError).__name__
21
- actual = type(actualError)
22
-
23
- assert actual == expected, uniformTestMessage(messageExpected, messageActual, functionTarget.__name__, *arguments)
24
-
25
- def standardizedSystemExit(expected: Union[str, int, Sequence[int]], functionTarget: Callable, *arguments: Any) -> None:
26
- """Template for tests expecting SystemExit.
27
-
28
- Parameters
29
- expected: Exit code expectation:
30
- - "error": any non-zero exit code
31
- - "nonError": specifically zero exit code
32
- - int: exact exit code match
33
- - Sequence[int]: exit code must be one of these values
34
- functionTarget: The function to test
35
- arguments: Arguments to pass to the function
36
- """
37
- with pytest.raises(SystemExit) as exitInfo:
38
- functionTarget(*arguments)
39
-
40
- exitCode = exitInfo.value.code
41
-
42
- if expected == "error":
43
- assert exitCode != 0, \
44
- f"Expected error exit (non-zero) but got code {exitCode}"
45
- elif expected == "nonError":
46
- assert exitCode == 0, \
47
- f"Expected non-error exit (0) but got code {exitCode}"
48
- elif isinstance(expected, (list, tuple)):
49
- assert exitCode in expected, \
50
- f"Expected exit code to be one of {expected} but got {exitCode}"
51
- else:
52
- assert exitCode == expected, \
53
- f"Expected exit code {expected} but got {exitCode}"