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