mapFolding 0.2.6__py3-none-any.whl → 0.3.0__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 (39) hide show
  1. {mapFolding-0.2.6.dist-info → mapFolding-0.3.0.dist-info}/METADATA +23 -7
  2. mapFolding-0.3.0.dist-info/RECORD +20 -0
  3. mapFolding-0.3.0.dist-info/top_level.txt +3 -0
  4. someAssemblyRequired/__init__.py +3 -0
  5. someAssemblyRequired/countInitialize.py +45 -0
  6. someAssemblyRequired/countParallel.py +52 -0
  7. someAssemblyRequired/countSequential.py +59 -0
  8. mapFolding/someAssemblyRequired/inlineAfunction.py → someAssemblyRequired/synthesizeModules.py +76 -41
  9. mapFolding/__init__.py +0 -12
  10. mapFolding/babbage.py +0 -35
  11. mapFolding/beDRY.py +0 -319
  12. mapFolding/importSelector.py +0 -7
  13. mapFolding/lovelace.py +0 -213
  14. mapFolding/oeis.py +0 -323
  15. mapFolding/someAssemblyRequired/jobsAndTasks.py +0 -47
  16. mapFolding/someAssemblyRequired/makeNuitkaSource.py +0 -99
  17. mapFolding/someAssemblyRequired/makeNumbaJob.py +0 -144
  18. mapFolding/startHere.py +0 -50
  19. mapFolding/theSSOT.py +0 -76
  20. mapFolding-0.2.6.dist-info/RECORD +0 -33
  21. mapFolding-0.2.6.dist-info/top_level.txt +0 -2
  22. tests/__init__.py +0 -1
  23. tests/conftest.py +0 -343
  24. tests/pythons_idiotic_namespace.py +0 -1
  25. tests/test_oeis.py +0 -194
  26. tests/test_other.py +0 -282
  27. tests/test_tasks.py +0 -31
  28. {mapFolding/benchmarks → benchmarks}/benchmarking.py +0 -0
  29. {mapFolding-0.2.6.dist-info → mapFolding-0.3.0.dist-info}/WHEEL +0 -0
  30. {mapFolding-0.2.6.dist-info → mapFolding-0.3.0.dist-info}/entry_points.txt +0 -0
  31. {mapFolding/reference → reference}/flattened.py +0 -0
  32. {mapFolding/reference → reference}/hunterNumba.py +0 -0
  33. {mapFolding/reference → reference}/irvineJavaPort.py +0 -0
  34. {mapFolding/reference → reference}/jax.py +0 -0
  35. {mapFolding/reference → reference}/lunnan.py +0 -0
  36. {mapFolding/reference → reference}/lunnanNumpy.py +0 -0
  37. {mapFolding/reference → reference}/lunnanWhile.py +0 -0
  38. {mapFolding/reference → reference}/rotatedEntryPoint.py +0 -0
  39. {mapFolding/reference → reference}/total_countPlus1vsPlusN.py +0 -0
tests/test_other.py DELETED
@@ -1,282 +0,0 @@
1
- import pathlib
2
- from tests.conftest import *
3
- from tests.pythons_idiotic_namespace import *
4
- from typing import List, Optional, Any
5
- import itertools
6
- import numba
7
- import numpy
8
- import pytest
9
- import random
10
- import sys
11
- import unittest.mock
12
- import io
13
- from contextlib import redirect_stdout
14
-
15
- @pytest.mark.parametrize("listDimensions,expected_intInnit,expected_parseListDimensions,expected_validateListDimensions,expected_getLeavesTotal", [
16
- (None, ValueError, ValueError, ValueError, ValueError), # None instead of list
17
- (['a'], ValueError, ValueError, ValueError, ValueError), # string
18
- ([-4, 2], [-4, 2], ValueError, ValueError, ValueError), # negative
19
- ([-3], [-3], ValueError, ValueError, ValueError), # negative
20
- ([0, 0], [0, 0], [0, 0], NotImplementedError, 0), # no positive dimensions
21
- ([0, 5, 6], [0, 5, 6], [0, 5, 6], [5, 6], 30), # zeros ignored
22
- ([0], [0], [0], NotImplementedError, 0), # edge case
23
- ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], 120), # sequential
24
- ([1, sys.maxsize], [1, sys.maxsize], [1, sys.maxsize], [1, sys.maxsize], sys.maxsize), # maxint
25
- ([7.5], ValueError, ValueError, ValueError, ValueError), # float
26
- ([1] * 1000, [1] * 1000, [1] * 1000, [1] * 1000, 1), # long list
27
- ([11], [11], [11], NotImplementedError, 11), # single dimension
28
- ([13, 0, 17], [13, 0, 17], [13, 0, 17], [13, 17], 221), # zeros handled
29
- ([2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], 16), # repeated dimensions
30
- ([2, 3, 4], [2, 3, 4], [2, 3, 4], [2, 3, 4], 24),
31
- ([2, 3], [2, 3], [2, 3], [2, 3], 6),
32
- ([2] * 11, [2] * 11, [2] * 11, [2] * 11, 2048), # power of 2
33
- ([3, 2], [3, 2], [3, 2], [2, 3], 6), # return value is the input when valid
34
- ([3] * 5, [3] * 5, [3] * 5, [3, 3, 3, 3, 3], 243), # power of 3
35
- ([None], TypeError, TypeError, TypeError, TypeError), # None
36
- ([True], TypeError, TypeError, TypeError, TypeError), # bool
37
- ([[17, 39]], TypeError, TypeError, TypeError, TypeError), # nested
38
- ([], ValueError, ValueError, ValueError, ValueError), # empty
39
- ([complex(1,1)], ValueError, ValueError, ValueError, ValueError), # complex number
40
- ([float('inf')], ValueError, ValueError, ValueError, ValueError), # infinity
41
- ([float('nan')], ValueError, ValueError, ValueError, ValueError), # NaN
42
- ([sys.maxsize - 1, 1], [sys.maxsize - 1, 1], [sys.maxsize - 1, 1], [1, sys.maxsize - 1], sys.maxsize - 1), # near maxint
43
- ([sys.maxsize // 2, sys.maxsize // 2, 2], [sys.maxsize // 2, sys.maxsize // 2, 2], [sys.maxsize // 2, sys.maxsize // 2, 2], [2, sys.maxsize // 2, sys.maxsize // 2], OverflowError), # overflow protection
44
- ([sys.maxsize, sys.maxsize], [sys.maxsize, sys.maxsize], [sys.maxsize, sys.maxsize], [sys.maxsize, sys.maxsize], OverflowError), # overflow protection
45
- (range(3, 7), [3, 4, 5, 6], [3, 4, 5, 6], [3, 4, 5, 6], 360), # range sequence type
46
- (tuple([3, 5, 7]), [3, 5, 7], [3, 5, 7], [3, 5, 7], 105), # tuple sequence type
47
- ])
48
- def test_listDimensionsAsParameter(listDimensions: None | list[str] | list[int] | list[float] | list[None] | list[bool] | list[list[int]] | list[complex] | range | tuple[int, ...], expected_intInnit: type[ValueError] | list[int] | type[TypeError], expected_parseListDimensions: type[ValueError] | list[int] | type[TypeError], expected_validateListDimensions: type[ValueError] | type[NotImplementedError] | list[int] | type[TypeError], expected_getLeavesTotal: type[ValueError] | int | type[TypeError] | type[OverflowError]) -> None:
49
- """Test both validateListDimensions and getLeavesTotal with the same inputs."""
50
- standardComparison(expected_intInnit, intInnit, listDimensions)
51
- standardComparison(expected_parseListDimensions, parseDimensions, listDimensions)
52
- standardComparison(expected_validateListDimensions, validateListDimensions, listDimensions)
53
- standardComparison(expected_getLeavesTotal, getLeavesTotal, listDimensions)
54
-
55
- def test_getLeavesTotal_edge_cases() -> None:
56
- """Test edge cases for getLeavesTotal."""
57
- # Order independence
58
- standardComparison(getLeavesTotal([2, 3, 4]), getLeavesTotal, [4, 2, 3])
59
-
60
- # Immutability
61
- listOriginal = [2, 3]
62
- standardComparison(6, getLeavesTotal, listOriginal)
63
- standardComparison([2, 3], lambda x: x, listOriginal) # Check that the list wasn't modified
64
-
65
- @pytest.mark.parametrize("foldsValue,writeFoldsTarget", [
66
- (756839, "foldsTotalTest.txt"), # Direct file
67
- (2640919, "foldsTotalTest.txt"), # Direct file
68
- (7715177, None), # Directory, will use default filename
69
- ])
70
- def test_countFolds_writeFoldsTotal(
71
- listDimensionsTestFunctionality: List[int],
72
- pathTempTesting: pathlib.Path,
73
- mockFoldingFunction,
74
- foldsValue: int,
75
- writeFoldsTarget: Optional[str]
76
- ) -> None:
77
- """Test writing folds total to either a file or directory."""
78
- # For directory case, use the directory path directly
79
- if writeFoldsTarget is None:
80
- pathWriteTarget = pathTempTesting
81
- filenameFoldsTotalExpected = getFilenameFoldsTotal(listDimensionsTestFunctionality)
82
- else:
83
- pathWriteTarget = pathTempTesting / writeFoldsTarget
84
- filenameFoldsTotalExpected = writeFoldsTarget
85
-
86
- foldsTotalExpected = foldsValue * getLeavesTotal(listDimensionsTestFunctionality)
87
- mock_countFolds = mockFoldingFunction(foldsValue, listDimensionsTestFunctionality)
88
-
89
- with unittest.mock.patch("mapFolding.babbage._countFolds", side_effect=mock_countFolds):
90
- returned = countFolds(listDimensionsTestFunctionality, pathishWriteFoldsTotal=pathWriteTarget)
91
-
92
- # standardComparison(foldsValue, lambda: returned) # Check return value
93
- standardComparison(str(foldsTotalExpected), lambda: (pathTempTesting / filenameFoldsTotalExpected).read_text()) # Check file content
94
-
95
- def test_intInnit() -> None:
96
- """Test integer parsing using the test suite generator."""
97
- for testName, testFunction in makeTestSuiteIntInnit(intInnit).items():
98
- testFunction()
99
-
100
- def test_oopsieKwargsie() -> None:
101
- """Test handling of unexpected keyword arguments."""
102
- for testName, testFunction in makeTestSuiteOopsieKwargsie(oopsieKwargsie).items():
103
- testFunction()
104
-
105
- @pytest.mark.parametrize("CPUlimit, expectedLimit", [
106
- (None, numba.config.NUMBA_DEFAULT_NUM_THREADS), # type: ignore
107
- (False, numba.config.NUMBA_DEFAULT_NUM_THREADS), # type: ignore
108
- (True, 1),
109
- (4, 4),
110
- (0.5, max(1, numba.config.NUMBA_DEFAULT_NUM_THREADS // 2)), # type: ignore
111
- (-0.5, max(1, numba.config.NUMBA_DEFAULT_NUM_THREADS // 2)), # type: ignore
112
- (-2, max(1, numba.config.NUMBA_DEFAULT_NUM_THREADS - 2)), # type: ignore
113
- (0, numba.config.NUMBA_DEFAULT_NUM_THREADS), # type: ignore
114
- (1, 1),
115
- ])
116
- def test_setCPUlimit(CPUlimit, expectedLimit) -> None:
117
- standardComparison(expectedLimit, setCPUlimit, CPUlimit)
118
-
119
- def test_makeConnectionGraph_nonNegative(listDimensionsTestFunctionality: List[int]) -> None:
120
- connectionGraph = makeConnectionGraph(listDimensionsTestFunctionality)
121
- assert numpy.all(connectionGraph >= 0), "All values in the connection graph should be non-negative."
122
-
123
- @pytest.mark.parametrize("datatype", [numpy.int16, numpy.uint64])
124
- def test_makeConnectionGraph_datatype(listDimensionsTestFunctionality: List[int], datatype) -> None:
125
- connectionGraph = makeConnectionGraph(listDimensionsTestFunctionality, datatype=datatype)
126
- assert connectionGraph.dtype == datatype, f"Expected datatype {datatype}, but got {connectionGraph.dtype}."
127
-
128
-
129
- """5 parameters
130
- listDimensionsTestFunctionality
131
-
132
- computationDivisions
133
- None
134
- random: int, first included: 2, first excluded: leavesTotal
135
- maximum
136
- cpu
137
-
138
- CPUlimit
139
- None
140
- True
141
- False
142
- 0
143
- 1
144
- -1
145
- random: 0 < float < 1
146
- random: -1 < float < 0
147
- random: int, first included: 2, first excluded: (min(leavesTotal, 16) - 1)
148
- random: int, first included: -1 * (min(leavesTotal, 16) - 1), first excluded: -1
149
-
150
- datatypeDefault
151
- None
152
- numpy.int64
153
- numpy.intc
154
- numpy.uint16
155
-
156
- datatypeLarge
157
- None
158
- numpy.int64
159
- numpy.intp
160
- numpy.uint32
161
-
162
- """
163
-
164
- @pytest.fixture
165
- def parameterIterator():
166
- """Generate random combinations of parameters for outfitCountFolds testing."""
167
- parameterSets = {
168
- 'computationDivisions': [
169
- None,
170
- 'maximum',
171
- 'cpu',
172
- ],
173
- 'CPUlimit': [
174
- None, True, False, 0, 1, -1,
175
- ],
176
- 'datatypeDefault': [
177
- None,
178
- numpy.int64,
179
- numpy.intc,
180
- numpy.uint16
181
- ],
182
- 'datatypeLarge': [
183
- None,
184
- numpy.int64,
185
- numpy.intp,
186
- numpy.uint32
187
- ]
188
- }
189
-
190
- def makeParametersDynamic(listDimensions):
191
- """Add context-dependent parameter values."""
192
- parametersDynamic = parameterSets.copy()
193
- leavesTotal = getLeavesTotal(listDimensions)
194
- concurrencyLimit = min(leavesTotal, 16)
195
-
196
- # Add dynamic computationDivisions
197
- parametersDynamic['computationDivisions'].extend(
198
- [random.randint(2, leavesTotal-1) for iterator in range(3)]
199
- )
200
-
201
- # Add dynamic CPUlimit values
202
- parameterDynamicCPU = [
203
- random.random(), # 0 to 1
204
- -random.random(), # -1 to 0
205
- ]
206
- parameterDynamicCPU.extend(
207
- [random.randint(2, concurrencyLimit-1) for iterator in range(2)]
208
- )
209
- parameterDynamicCPU.extend(
210
- [random.randint(-concurrencyLimit+1, -2) for iterator in range(2)]
211
- )
212
- parametersDynamic['CPUlimit'].extend(parameterDynamicCPU)
213
-
214
- return parametersDynamic
215
-
216
- def generateCombinations(listDimensions):
217
- parametersDynamic = makeParametersDynamic(listDimensions)
218
- parameterKeys = list(parametersDynamic.keys())
219
- parameterValues = [parametersDynamic[key] for key in parameterKeys]
220
-
221
- # Shuffle each parameter list
222
- for valueList in parameterValues:
223
- random.shuffle(valueList)
224
-
225
- # Use zip_longest to iterate, filling with None when shorter lists are exhausted
226
- for combination in itertools.zip_longest(*parameterValues, fillvalue=None):
227
- yield dict(zip(parameterKeys, combination))
228
-
229
- return generateCombinations
230
- # Must mock the set cpu count to avoid errors on GitHub
231
- # def test_outfitCountFolds_basic(listDimensionsTestFunctionality, parameterIterator):
232
- # """Basic validation of outfitCountFolds return value structure."""
233
- # parameters = next(parameterIterator(listDimensionsTestFunctionality))
234
-
235
- # stateInitialized = outfitCountFolds(
236
- # listDimensionsTestFunctionality,
237
- # **{k: v for k, v in parameters.items() if v is not None}
238
- # )
239
-
240
- # # Basic structure tests
241
- # assert isinstance(stateInitialized, dict)
242
- # assert len(stateInitialized) == 7 # 6 ndarray + 1 tuple
243
-
244
- # # Check for specific keys
245
- # requiredKeys = set(computationState.__annotations__.keys())
246
- # assert set(stateInitialized.keys()) == requiredKeys
247
-
248
- # # Check types more carefully
249
- # for key, value in stateInitialized.items():
250
- # if key == 'mapShape':
251
- # assert isinstance(value, tuple)
252
- # assert all(isinstance(dim, int) for dim in value)
253
- # else:
254
- # assert isinstance(value, numpy.ndarray), f"{key} should be ndarray but is {type(value)}"
255
- # assert issubclass(value.dtype.type, numpy.integer), \
256
- # f"{key} should have integer dtype but has {value.dtype}"
257
-
258
- def test_pathJobDEFAULT_colab():
259
- """Test that pathJobDEFAULT is set correctly when running in Google Colab."""
260
- # Mock sys.modules to simulate running in Colab
261
- with unittest.mock.patch.dict('sys.modules', {'google.colab': unittest.mock.MagicMock()}):
262
- # Force reload of theSSOT to trigger Colab path logic
263
- import importlib
264
- import mapFolding.theSSOT
265
- importlib.reload(mapFolding.theSSOT)
266
-
267
- # Check that path was set to Colab-specific value
268
- assert mapFolding.theSSOT.pathJobDEFAULT == pathlib.Path("/content/drive/MyDrive") / "jobs"
269
-
270
- # Reload one more time to restore original state
271
- importlib.reload(mapFolding.theSSOT)
272
-
273
- def test_saveFoldsTotal_fallback(pathTempTesting: pathlib.Path) -> None:
274
- foldsTotal = 123
275
- pathFilename = pathTempTesting / "unwritable" / "foldsTotal.txt"
276
- with unittest.mock.patch("pathlib.Path.write_text", side_effect=OSError("Simulated write failure")):
277
- with unittest.mock.patch("os.getcwd", return_value=str(pathTempTesting)):
278
- capturedOutput = io.StringIO()
279
- with redirect_stdout(capturedOutput):
280
- saveFoldsTotal(pathFilename, foldsTotal)
281
- fallbackFiles = list(pathTempTesting.glob("foldsTotalYO_*.txt"))
282
- assert len(fallbackFiles) == 1, "Fallback file was not created upon write failure."
tests/test_tasks.py DELETED
@@ -1,31 +0,0 @@
1
- from .conftest import *
2
- import pytest
3
- from typing import List, Dict, Tuple
4
-
5
- # TODO add a test. `C` = number of logical cores available. `n = C + 1`. Ensure that `[2,n]` is computed correctly.
6
- # Or, probably smarter: limit the number of cores, then run a test with C+1.
7
-
8
- def test_countFolds_computationDivisions(listDimensionsTest_countFolds: List[int], foldsTotalKnown: Dict[Tuple[int, ...], int]) -> None:
9
- standardComparison(foldsTotalKnown[tuple(listDimensionsTest_countFolds)], countFolds, listDimensionsTest_countFolds, None, 'maximum')
10
-
11
- def test_defineConcurrencyLimit() -> None:
12
- testSuite = makeTestSuiteConcurrencyLimit(defineConcurrencyLimit)
13
- for testName, testFunction in testSuite.items():
14
- testFunction()
15
-
16
- @pytest.mark.parametrize("CPUlimitParameter", [{"invalid": True}, ["weird"]])
17
- def test_countFolds_cpuLimitOopsie(listDimensionsTestFunctionality: List[int], CPUlimitParameter: Dict[str, bool] | List[str]) -> None:
18
- standardComparison(ValueError, countFolds, listDimensionsTestFunctionality, None, 'cpu', CPUlimitParameter)
19
-
20
- def test_countFolds_invalid_computationDivisions(listDimensionsTestFunctionality: List[int]) -> None:
21
- standardComparison(ValueError, countFolds, listDimensionsTestFunctionality, None, {"wrong": "value"})
22
-
23
- @pytest.mark.parametrize("computationDivisions, concurrencyLimit, listDimensions, expectedTaskDivisions", [
24
- (None, 4, [9, 11], 0),
25
- ("maximum", 4, [7, 11], 77),
26
- ("cpu", 4, [3, 7], 4),
27
- (["invalid"], 4, [19, 23], ValueError),
28
- (20, 4, [3,5], ValueError)
29
- ])
30
- def test_getTaskDivisions(computationDivisions, concurrencyLimit, listDimensions, expectedTaskDivisions) -> None:
31
- standardComparison(expectedTaskDivisions, getTaskDivisions, computationDivisions, concurrencyLimit, None, listDimensions)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes