mapFolding 0.5.1__tar.gz → 0.6.0__tar.gz

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 (25) hide show
  1. {mapfolding-0.5.1 → mapfolding-0.6.0}/PKG-INFO +5 -4
  2. {mapfolding-0.5.1 → mapfolding-0.6.0}/README.md +1 -1
  3. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/__init__.py +7 -4
  4. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/basecamp.py +1 -3
  5. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/beDRY.py +7 -37
  6. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/oeis.py +53 -57
  7. mapfolding-0.6.0/mapFolding/theConfiguration.py +58 -0
  8. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/theDao.py +1 -1
  9. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/theSSOT.py +12 -34
  10. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/theSSOTdatatypes.py +15 -16
  11. mapfolding-0.6.0/mapFolding/theWrongWay.py +7 -0
  12. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/PKG-INFO +5 -4
  13. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/SOURCES.txt +4 -0
  14. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/requires.txt +1 -0
  15. {mapfolding-0.5.1 → mapfolding-0.6.0}/pyproject.toml +4 -3
  16. {mapfolding-0.5.1 → mapfolding-0.6.0}/tests/test_oeis.py +2 -4
  17. {mapfolding-0.5.1 → mapfolding-0.6.0}/tests/test_other.py +18 -2
  18. {mapfolding-0.5.1 → mapfolding-0.6.0}/tests/test_tasks.py +1 -0
  19. {mapfolding-0.5.1 → mapfolding-0.6.0}/LICENSE +0 -0
  20. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding/py.typed +0 -0
  21. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/dependency_links.txt +0 -0
  22. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/entry_points.txt +0 -0
  23. {mapfolding-0.5.1 → mapfolding-0.6.0}/mapFolding.egg-info/top_level.txt +0 -0
  24. {mapfolding-0.5.1 → mapfolding-0.6.0}/setup.cfg +0 -0
  25. {mapfolding-0.5.1 → mapfolding-0.6.0}/tests/test_computations.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mapFolding
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: Count distinct ways to fold a map (or a strip of stamps)
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -16,12 +16,12 @@ Classifier: Intended Audience :: Other Audience
16
16
  Classifier: Intended Audience :: Science/Research
17
17
  Classifier: Natural Language :: English
18
18
  Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
19
21
  Classifier: Programming Language :: Python :: 3.10
20
22
  Classifier: Programming Language :: Python :: 3.11
21
23
  Classifier: Programming Language :: Python :: 3.12
22
24
  Classifier: Programming Language :: Python :: 3.13
23
- Classifier: Programming Language :: Python :: 3
24
- Classifier: Programming Language :: Python
25
25
  Classifier: Topic :: Scientific/Engineering :: Mathematics
26
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
27
  Classifier: Typing :: Typed
@@ -35,6 +35,7 @@ Provides-Extra: testing
35
35
  Requires-Dist: autoflake; extra == "testing"
36
36
  Requires-Dist: mypy; extra == "testing"
37
37
  Requires-Dist: more_itertools; extra == "testing"
38
+ Requires-Dist: numba_progress; extra == "testing"
38
39
  Requires-Dist: pytest-cov; extra == "testing"
39
40
  Requires-Dist: pytest-env; extra == "testing"
40
41
  Requires-Dist: pytest-xdist; extra == "testing"
@@ -153,4 +154,4 @@ Available OEIS sequences:
153
154
  [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
154
155
  [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
155
156
 
156
- [![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/)
157
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -108,4 +108,4 @@ Available OEIS sequences:
108
108
  [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
109
109
  [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
110
110
 
111
- [![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/)
111
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -41,10 +41,10 @@ _dictionaryListsImportFrom['mapFolding.theSSOT'].extend([
41
41
  'computationState',
42
42
  'EnumIndices',
43
43
  'getDispatcherCallable',
44
- 'getPathPackage',
45
44
  'indexMy',
46
45
  'indexTrack',
47
46
  'myPackageNameIs',
47
+ 'pathPackage',
48
48
  ])
49
49
 
50
50
  # Datatype management
@@ -60,17 +60,21 @@ _dictionaryListsImportFrom['mapFolding.theSSOT'].extend([
60
60
 
61
61
  # Synthesize modules
62
62
  _dictionaryListsImportFrom['mapFolding.theSSOT'].extend([
63
- 'formatFilenameModuleDEFAULT',
63
+ 'additional_importsHARDCODED',
64
+ 'formatFilenameModule',
64
65
  'getAlgorithmDispatcher',
65
66
  'getAlgorithmSource',
66
67
  'getPathJobRootDEFAULT',
67
68
  'getPathSyntheticModules',
69
+ 'listCallablesDispatchees',
68
70
  'moduleOfSyntheticModules',
71
+ 'Z0Z_filenameModuleWrite',
72
+ 'Z0Z_filenameWriteElseCallableTarget',
69
73
  'Z0Z_getDatatypeModuleScalar',
70
74
  'Z0Z_getDecoratorCallable',
75
+ 'Z0Z_identifierCountFolds',
71
76
  'Z0Z_setDatatypeModuleScalar',
72
77
  'Z0Z_setDecoratorCallable',
73
- 'Z0Z_identifierCountFolds',
74
78
  ])
75
79
 
76
80
  # Parameters for the prima donna
@@ -101,4 +105,3 @@ if TYPE_CHECKING:
101
105
  from oeis import *
102
106
  from theDao import *
103
107
  from theSSOT import *
104
- from theSSOTdatatypes import *
@@ -7,7 +7,6 @@ def countFolds(listDimensions: Sequence[int]
7
7
  , pathLikeWriteFoldsTotal: str | PathLike[str] | None = None
8
8
  , computationDivisions: int | str | None = None
9
9
  , CPUlimit: int | float | bool | None = None
10
- , **keywordArguments: str | bool
11
10
  ) -> int:
12
11
  """Count the total number of possible foldings for a given map dimensions.
13
12
 
@@ -18,7 +17,6 @@ def countFolds(listDimensions: Sequence[int]
18
17
  computationDivisions (None):
19
18
  Whether and how to divide the computational work. See notes for details.
20
19
  CPUlimit (None): This is only relevant if there are `computationDivisions`: whether and how to limit the CPU usage. See notes for details.
21
- **keywordArguments: Datatype management. See `outfitCountFolds` for details.
22
20
  Returns:
23
21
  foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
24
22
 
@@ -39,7 +37,7 @@ def countFolds(listDimensions: Sequence[int]
39
37
  N.B.: You probably don't want to divide the computation into tasks.
40
38
  If you want to compute a large `foldsTotal`, dividing the computation into tasks is usually a bad idea. Dividing the algorithm into tasks is inherently inefficient: efficient division into tasks means there would be no overlap in the work performed by each task. When dividing this algorithm, the amount of overlap is between 50% and 90% by all tasks: at least 50% of the work done by every task must be done by _all_ tasks. If you improve the computation time, it will only change by -10 to -50% depending on (at the very least) the ratio of the map dimensions and the number of leaves. If an undivided computation would take 10 hours on your computer, for example, the computation will still take at least 5 hours but you might reduce the time to 9 hours. Most of the time, however, you will increase the computation time. If logicalCores >= leavesTotal, it will probably be faster. If logicalCores <= 2 * leavesTotal, it will almost certainly be slower for all map dimensions.
41
39
  """
42
- stateUniversal: computationState = outfitCountFolds(listDimensions, computationDivisions=computationDivisions, CPUlimit=CPUlimit, **keywordArguments)
40
+ stateUniversal: computationState = outfitCountFolds(listDimensions, computationDivisions=computationDivisions, CPUlimit=CPUlimit)
43
41
 
44
42
  dispatcher = getDispatcherCallable()
45
43
  dispatcher(**stateUniversal)
@@ -7,13 +7,10 @@ from mapFolding import (
7
7
  hackSSOTdtype,
8
8
  indexMy,
9
9
  indexTrack,
10
- setDatatypeElephino,
11
- setDatatypeFoldsTotal,
12
10
  setDatatypeLeavesTotal,
13
- setDatatypeModule,
14
11
  )
15
12
  from collections.abc import Sequence
16
- from numba import get_num_threads, set_num_threads # type: ignore
13
+ from numba import get_num_threads, set_num_threads
17
14
  from numpy import dtype, integer, ndarray
18
15
  from numpy.typing import DTypeLike, NDArray
19
16
  from pathlib import Path
@@ -24,7 +21,7 @@ import numpy
24
21
  import os
25
22
 
26
23
  def getFilenameFoldsTotal(mapShape: Sequence[int] | ndarray[tuple[int], dtype[integer[Any]]]) -> str:
27
- """Imagine your computer has been counting folds for 70 hours, and when it tries to save your newly discovered value,
24
+ """Imagine your computer has been counting folds for 9 days, and when it tries to save your newly discovered value,
28
25
  the filename is invalid. I bet you think this function is more important after that thought experiment.
29
26
 
30
27
  Make a standardized filename for the computed value `foldsTotal`.
@@ -45,7 +42,7 @@ def getFilenameFoldsTotal(mapShape: Sequence[int] | ndarray[tuple[int], dtype[in
45
42
  mapShape: A sequence of integers representing the dimensions of the map.
46
43
 
47
44
  Returns:
48
- filenameFoldsTotal: A filename string in format 'pNxM.foldsTotal' where N,M are sorted dimensions
45
+ filenameFoldsTotal: A filename string in format 'pMxN.foldsTotal' where M,N are sorted dimensions
49
46
  """
50
47
  return 'p' + 'x'.join(str(dimension) for dimension in sorted(mapShape)) + '.foldsTotal'
51
48
 
@@ -220,7 +217,10 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: DTypeLike | None =
220
217
  else:
221
218
  raise NotImplementedError("Somebody done broke it.")
222
219
 
223
- def outfitCountFolds(listDimensions: Sequence[int], computationDivisions: int | str | None = None, CPUlimit: bool | float | int | None = None, **keywordArguments: str | bool | None) -> computationState:
220
+ def outfitCountFolds(listDimensions: Sequence[int]
221
+ , computationDivisions: int | str | None = None
222
+ , CPUlimit: bool | float | int | None = None
223
+ ) -> computationState:
224
224
  """
225
225
  Initializes and configures the computation state for map folding computations.
226
226
 
@@ -228,40 +228,10 @@ def outfitCountFolds(listDimensions: Sequence[int], computationDivisions: int |
228
228
  listDimensions: The dimensions of the map to be folded
229
229
  computationDivisions (None): see `getTaskDivisions`
230
230
  CPUlimit (None): see `setCPUlimit`
231
- **keywordArguments: Datatype management, it's complicated: see the code below.
232
231
 
233
232
  Returns:
234
233
  stateInitialized: The initialized computation state
235
234
  """
236
- # keywordArguments START
237
- kwourGrapes = keywordArguments.get('sourGrapes', None)
238
- if kwourGrapes:
239
- sourGrapes = True
240
- else:
241
- sourGrapes = False
242
-
243
- ImaSetTheDatatype = keywordArguments.get('datatypeElephino', None)
244
- if ImaSetTheDatatype:
245
- ImaSetTheDatatype = str(ImaSetTheDatatype)
246
- setDatatypeElephino(ImaSetTheDatatype, sourGrapes)
247
-
248
- ImaSetTheDatatype = keywordArguments.get('datatypeFoldsTotal', None)
249
- if ImaSetTheDatatype:
250
- ImaSetTheDatatype = str(ImaSetTheDatatype)
251
- setDatatypeFoldsTotal(ImaSetTheDatatype, sourGrapes)
252
-
253
- ImaSetTheDatatype = keywordArguments.get('datatypeLeavesTotal', None)
254
- if ImaSetTheDatatype:
255
- ImaSetTheDatatype = str(ImaSetTheDatatype)
256
- setDatatypeLeavesTotal(ImaSetTheDatatype, sourGrapes)
257
-
258
- # NOTE well: this might be only hypothetical because as of this writing, `makeDataContainer` only makes numpy.zeros. But it's here in case things change.
259
- ImaSetTheDatatype = keywordArguments.get('datatypeModule', None)
260
- if ImaSetTheDatatype:
261
- ImaSetTheDatatype = str(ImaSetTheDatatype)
262
- setDatatypeModule(ImaSetTheDatatype, sourGrapes)
263
- # keywordArguments END
264
-
265
235
  my = makeDataContainer(len(indexMy), hackSSOTdtype('my'))
266
236
 
267
237
  mapShape = tuple(sorted(validateListDimensions(listDimensions)))
@@ -1,11 +1,11 @@
1
1
  """Everything implementing the The Online Encyclopedia of Integer Sequences (OEIS); _only_ things that implement _only_ the OEIS."""
2
2
  from collections.abc import Callable
3
3
  from datetime import datetime, timedelta
4
- from mapFolding import countFolds, getPathPackage
5
- from typing import Any, Final, TYPE_CHECKING
4
+ from mapFolding import countFolds, pathPackage
5
+ from pathlib import Path
6
+ from typing import Any, cast, Final, TYPE_CHECKING
6
7
  import argparse
7
8
  import pathlib
8
- from pathlib import Path
9
9
  import random
10
10
  import sys
11
11
  import time
@@ -23,7 +23,7 @@ cacheDays = 7
23
23
  """
24
24
  Section: make `settingsOEIS`"""
25
25
 
26
- _pathCache: Path = getPathPackage() / ".cache"
26
+ pathCache: Path = pathPackage / ".cache"
27
27
 
28
28
  class SettingsOEIS(TypedDict):
29
29
  description: str
@@ -36,38 +36,37 @@ class SettingsOEIS(TypedDict):
36
36
  valueUnknown: int
37
37
 
38
38
  settingsOEIShardcodedValues: dict[str, dict[str, Any]] = {
39
- 'A001415': {
40
- 'getMapShape': lambda n: sorted([2, n]),
41
- 'valuesBenchmark': [14],
42
- 'valuesTestParallelization': [*range(3, 7)],
43
- 'valuesTestValidation': [random.randint(2, 9)],
44
- },
45
- 'A001416': {
46
- 'getMapShape': lambda n: sorted([3, n]),
47
- 'valuesBenchmark': [9],
48
- 'valuesTestParallelization': [*range(3, 5)],
49
- 'valuesTestValidation': [random.randint(2, 6)],
50
- },
51
- 'A001417': {
52
- 'getMapShape': lambda n: [2] * n,
53
- 'valuesBenchmark': [6],
54
- 'valuesTestParallelization': [*range(2, 4)],
55
- 'valuesTestValidation': [random.randint(2, 4)],
56
- },
57
- 'A195646': {
58
- 'getMapShape': lambda n: [3] * n,
59
- 'valuesBenchmark': [3],
60
- 'valuesTestParallelization': [*range(2, 3)],
61
- 'valuesTestValidation': [2],
62
- },
63
- 'A001418': {
64
- 'getMapShape': lambda n: [n, n],
65
- 'valuesBenchmark': [5],
66
- 'valuesTestParallelization': [*range(2, 4)],
67
- 'valuesTestValidation': [random.randint(2, 4)],
68
- },
39
+ 'A001415': {
40
+ 'getMapShape': cast(Callable[[int], list[int]], lambda n: sorted([2, n])), # type: ignore
41
+ 'valuesBenchmark': [14],
42
+ 'valuesTestParallelization': [*range(3, 7)],
43
+ 'valuesTestValidation': [random.randint(2, 9)],
44
+ },
45
+ 'A001416': {
46
+ 'getMapShape': cast(Callable[[int], list[int]], lambda n: sorted([3, n])), # type: ignore
47
+ 'valuesBenchmark': [9],
48
+ 'valuesTestParallelization': [*range(3, 5)],
49
+ 'valuesTestValidation': [random.randint(2, 6)],
50
+ },
51
+ 'A001417': {
52
+ 'getMapShape': cast(Callable[[int], list[int]], lambda n: [2] * n), # type: ignore
53
+ 'valuesBenchmark': [6],
54
+ 'valuesTestParallelization': [*range(2, 4)],
55
+ 'valuesTestValidation': [random.randint(2, 4)],
56
+ },
57
+ 'A195646': {
58
+ 'getMapShape': cast(Callable[[int], list[int]], lambda n: [3] * n), # type: ignore
59
+ 'valuesBenchmark': [3],
60
+ 'valuesTestParallelization': [*range(2, 3)],
61
+ 'valuesTestValidation': [2],
62
+ },
63
+ 'A001418': {
64
+ 'getMapShape': cast(Callable[[int], list[int]], lambda n: [n, n]), # type: ignore
65
+ 'valuesBenchmark': [5],
66
+ 'valuesTestParallelization': [*range(2, 4)],
67
+ 'valuesTestValidation': [random.randint(2, 4)],
68
+ },
69
69
  }
70
-
71
70
  oeisIDsImplemented: Final[list[str]] = sorted([oeisID.upper().strip() for oeisID in settingsOEIShardcodedValues.keys()])
72
71
  """Directly implemented OEIS IDs; standardized, e.g., 'A001415'."""
73
72
 
@@ -180,7 +179,7 @@ def getOEISidValues(oeisID: str) -> dict[int, int]:
180
179
  IOError: If there is an error reading from or writing to the local cache.
181
180
  """
182
181
 
183
- pathFilenameCache: Path = _pathCache / getFilenameOEISbFile(oeisID)
182
+ pathFilenameCache: Path = pathCache / getFilenameOEISbFile(oeisID)
184
183
  url: str = f"https://oeis.org/{oeisID}/{getFilenameOEISbFile(oeisID)}"
185
184
 
186
185
  oeisInformation: None | str = getOEISofficial(pathFilenameCache, url)
@@ -191,7 +190,7 @@ def getOEISidValues(oeisID: str) -> dict[int, int]:
191
190
 
192
191
  def getOEISidInformation(oeisID: str) -> tuple[str, int]:
193
192
  oeisID = validateOEISid(oeisID)
194
- pathFilenameCache: Path = _pathCache / f"{oeisID}.txt"
193
+ pathFilenameCache: Path = pathCache / f"{oeisID}.txt"
195
194
  url: str = f"https://oeis.org/search?q=id:{oeisID}&fmt=text"
196
195
 
197
196
  oeisInformation: None | str = getOEISofficial(pathFilenameCache, url)
@@ -199,26 +198,23 @@ def getOEISidInformation(oeisID: str) -> tuple[str, int]:
199
198
  if not oeisInformation:
200
199
  return "Not found", -1
201
200
 
202
- description_parts: list[str] = []
201
+ listDescriptionDeconstructed: list[str] = []
203
202
  offset = None
204
- for line in oeisInformation.splitlines():
205
- if line.startswith('%N'):
206
- parts = line.split()
207
- if parts[1] == oeisID:
208
- desc_part = ' '.join(parts[2:])
209
- description_parts.append(desc_part)
210
- elif line.startswith('%O'):
211
- parts: list[str] = line.split()
212
- if parts[1] == oeisID:
213
- offset_str: str = parts[2].split(',')[0]
214
- offset = int(offset_str)
215
- if not description_parts:
203
+ for ImaStr in oeisInformation.splitlines():
204
+ ImaStr = ImaStr.strip() + "I am writing code to string parse machine readable data because in 2025, people can't even spell enteroperableity."
205
+ secretCode, title, secretData =ImaStr.split(maxsplit=2)
206
+ if secretCode == '%N' and title == oeisID:
207
+ listDescriptionDeconstructed.append(secretData)
208
+ if secretCode == '%O' and title == oeisID:
209
+ offsetAsStr: str = secretData.split(',')[0]
210
+ offset = int(offsetAsStr)
211
+ if not listDescriptionDeconstructed:
216
212
  warnings.warn(f"No description found for {oeisID}")
217
- description_parts.append("No description found")
213
+ listDescriptionDeconstructed.append("No description found")
218
214
  if offset is None:
219
215
  warnings.warn(f"No offset found for {oeisID}")
220
216
  offset = -1
221
- description: str = ' '.join(description_parts)
217
+ description: str = ' '.join(listDescriptionDeconstructed)
222
218
  return description, offset
223
219
 
224
220
  def makeSettingsOEIS() -> dict[str, SettingsOEIS]:
@@ -326,13 +322,13 @@ def OEIS_for_n() -> None:
326
322
 
327
323
  def clearOEIScache() -> None:
328
324
  """Delete all cached OEIS sequence files."""
329
- if not _pathCache.exists():
330
- print(f"Cache directory, {_pathCache}, not found - nothing to clear.")
325
+ if not pathCache.exists():
326
+ print(f"Cache directory, {pathCache}, not found - nothing to clear.")
331
327
  return
332
328
  for oeisID in settingsOEIS:
333
- ( _pathCache / f"{oeisID}.txt" ).unlink(missing_ok=True)
334
- ( _pathCache / getFilenameOEISbFile(oeisID) ).unlink(missing_ok=True)
335
- print(f"Cache cleared from {_pathCache}")
329
+ ( pathCache / f"{oeisID}.txt" ).unlink(missing_ok=True)
330
+ ( pathCache / getFilenameOEISbFile(oeisID) ).unlink(missing_ok=True)
331
+ print(f"Cache cleared from {pathCache}")
336
332
 
337
333
  def getOEISids() -> None:
338
334
  """Print all available OEIS sequence IDs that are directly implemented."""
@@ -0,0 +1,58 @@
1
+ from types import ModuleType
2
+ from mapFolding.theWrongWay import *
3
+ from sys import modules as sysModules
4
+ from pathlib import Path
5
+ from importlib import import_module as importlib_import_module
6
+ from inspect import getfile as inspect_getfile
7
+ from typing import Final
8
+ """
9
+ evaluateWhenPACKAGING
10
+ evaluateWhenINSTALLING
11
+ """
12
+ try:
13
+ import tomli
14
+ TRYmyPackageNameIs: str = tomli.load(Path("../pyproject.toml").open('rb'))["project"]["name"]
15
+ except Exception:
16
+ TRYmyPackageNameIs: str = myPackageNameIsPACKAGING
17
+
18
+ myPackageNameIs: Final[str] = TRYmyPackageNameIs
19
+
20
+ def getPathPackageINSTALLING() -> Path:
21
+ pathPackage = Path(inspect_getfile(importlib_import_module(myPackageNameIs)))
22
+ if pathPackage.is_file():
23
+ pathPackage: Path = pathPackage.parent
24
+ return pathPackage
25
+
26
+ pathPackage: Path = getPathPackageINSTALLING()
27
+
28
+ moduleOfSyntheticModules: Final[str] = "syntheticModules"
29
+ formatNameModule = "numba_{callableTarget}"
30
+ formatFilenameModule = formatNameModule + ".py"
31
+ dispatcherCallableName = "doTheNeedful"
32
+ nameModuleDispatcher: str = formatNameModule.format(callableTarget=dispatcherCallableName)
33
+ Z0Z_filenameModuleWrite = 'numbaCount.py'
34
+ Z0Z_filenameWriteElseCallableTarget: str = 'count'
35
+
36
+ def getDispatcherCallable():
37
+ logicalPathModule: str = f"{myPackageNameIs}.{moduleOfSyntheticModules}.{nameModuleDispatcher}"
38
+ moduleImported: ModuleType = importlib_import_module(logicalPathModule)
39
+ return getattr(moduleImported, dispatcherCallableName)
40
+
41
+ def getAlgorithmSource() -> ModuleType:
42
+ logicalPathModule: str = f"{myPackageNameIs}.{algorithmSourcePACKAGING}"
43
+ moduleImported: ModuleType = importlib_import_module(logicalPathModule)
44
+ return moduleImported
45
+ # from mapFolding import theDao
46
+ # return theDao
47
+
48
+ # TODO learn how to see this from the user's perspective
49
+ def getPathJobRootDEFAULT() -> Path:
50
+ if 'google.colab' in sysModules:
51
+ pathJobDEFAULT: Path = Path("/content/drive/MyDrive") / "jobs"
52
+ else:
53
+ pathJobDEFAULT = pathPackage / "jobs"
54
+ return pathJobDEFAULT
55
+
56
+ listCallablesDispatchees: list[str] = listCallablesDispatcheesHARDCODED
57
+
58
+ additional_importsHARDCODED.append(myPackageNameIs)
@@ -147,7 +147,7 @@ def countParallel(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[A
147
147
 
148
148
  taskDivisionsPrange = myPARALLEL[indexMy.taskDivisions.value]
149
149
 
150
- for indexSherpa in prange(taskDivisionsPrange):
150
+ for indexSherpa in prange(taskDivisionsPrange): # type: ignore
151
151
  groupsOfFolds: int = 0
152
152
 
153
153
  gapsWhere = gapsWherePARALLEL.copy()
@@ -3,7 +3,6 @@ from mapFolding.theSSOTdatatypes import *
3
3
  from numba.core.compiler import CompilerBase as numbaCompilerBase
4
4
  from numpy import dtype, integer, ndarray
5
5
  from pathlib import Path
6
- from sys import modules as sysModules
7
6
  from types import ModuleType
8
7
  from typing import Any, Final, TYPE_CHECKING, cast
9
8
 
@@ -21,50 +20,29 @@ else:
21
20
  - Configuration Registry
22
21
  - Write-Once, Read-Many (WORM) / Immutable Initialization
23
22
  - Lazy Initialization
24
- - Separation of configuration from business logic
23
+ - Separate configuration from business logic
24
+
25
+ theSSOT and yourSSOT
25
26
 
26
27
  delay realization/instantiation until a concrete value is desired
27
28
  moment of truth: when the value is needed, not when the value is defined
28
29
  """
29
30
 
30
- myPackageNameIs = "mapFolding"
31
-
32
- moduleOfSyntheticModules = "syntheticModules"
33
- # TODO I'm not sure if this is the right tool for the job.
34
- formatFilenameModuleDEFAULT = "numba_{callableTarget}.py"
35
- # TODO figure out how to implement this
36
- dispatcherCallableNameDEFAULT = "doTheNeedful"
37
-
38
- def getPathPackage() -> Path:
39
- import importlib, inspect
40
- pathPackage = Path(inspect.getfile(importlib.import_module(myPackageNameIs)))
41
- if pathPackage.is_file():
42
- pathPackage = pathPackage.parent
43
- return pathPackage
44
-
45
- def getPathJobRootDEFAULT() -> Path:
46
- if 'google.colab' in sysModules:
47
- pathJobDEFAULT = Path("/content/drive/MyDrive") / "jobs"
48
- else:
49
- pathJobDEFAULT = getPathPackage() / "jobs"
50
- return pathJobDEFAULT
31
+ """
32
+ listDimensions: list[int]
33
+ mapShape
34
+ tupleDimensions: tuple[int, ...]
35
+ dimensionsTuple
36
+ dimensionTuple
37
+ """
51
38
 
52
39
  def getPathSyntheticModules() -> Path:
53
- pathSyntheticModules = getPathPackage() / moduleOfSyntheticModules
54
- return pathSyntheticModules
55
-
56
- def getAlgorithmSource() -> ModuleType:
57
- from mapFolding import theDao
58
- return theDao
40
+ return pathPackage / moduleOfSyntheticModules
59
41
 
60
42
  def getAlgorithmDispatcher() -> Callable[..., None]:
61
- algorithmSource = getAlgorithmSource()
43
+ algorithmSource: ModuleType = getAlgorithmSource()
62
44
  return cast(Callable[..., None], algorithmSource.doTheNeedful) # 'doTheNeedful' is duplicated and there is not a SSOT for it
63
45
 
64
- def getDispatcherCallable() -> Callable[..., None]:
65
- from mapFolding.syntheticModules import numba_doTheNeedful
66
- return cast(Callable[..., None], numba_doTheNeedful.doTheNeedful)
67
-
68
46
  # NOTE I want this _concept_, not necessarily this method, to be well implemented and usable everywhere: Python, Numba, Jax, CUDA, idc
69
47
  class computationState(TypedDict):
70
48
  connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]]
@@ -1,3 +1,4 @@
1
+ from mapFolding.theConfiguration import *
1
2
  from collections import defaultdict
2
3
  from typing import Any, cast, Final
3
4
  import enum
@@ -42,19 +43,17 @@ _datatypeDefault: Final[dict[str, str]] = {
42
43
  'leavesTotal': 'uint16',
43
44
  }
44
45
  _datatypeModule: str = ''
45
- _datatypeModuleDEFAULT: Final[str] = 'numpy'
46
-
47
- _datatype: dict[str, str] = defaultdict(str)
46
+ _registryOfDatatypes: dict[str, str] = defaultdict(str)
48
47
 
49
48
  def reportDatatypeLimit(identifier: str, datatype: str, sourGrapes: bool | None = False) -> str:
50
- global _datatype
51
- if not _datatype[identifier]:
52
- _datatype[identifier] = datatype
53
- elif _datatype[identifier] == datatype:
49
+ global _registryOfDatatypes
50
+ if not _registryOfDatatypes[identifier]:
51
+ _registryOfDatatypes[identifier] = datatype
52
+ elif _registryOfDatatypes[identifier] == datatype:
54
53
  pass
55
54
  elif sourGrapes:
56
- raise Exception(f"Datatype is '{_datatype[identifier]}' not '{datatype}', so you can take your ball and go home.")
57
- return _datatype[identifier]
55
+ raise Exception(f"Datatype is '{_registryOfDatatypes[identifier]}' not '{datatype}', so you can take your ball and go home.")
56
+ return _registryOfDatatypes[identifier]
58
57
 
59
58
  def setDatatypeModule(datatypeModule: str, sourGrapes: bool | None = False) -> str:
60
59
  global _datatypeModule
@@ -76,20 +75,20 @@ def setDatatypeLeavesTotal(datatype: str, sourGrapes: bool | None = False) -> st
76
75
  return reportDatatypeLimit('leavesTotal', datatype, sourGrapes)
77
76
 
78
77
  def _get_datatype(identifier: str) -> str:
79
- global _datatype
80
- if not _datatype[identifier]:
78
+ global _registryOfDatatypes
79
+ if not _registryOfDatatypes[identifier]:
81
80
  if identifier in indexMy._member_names_:
82
- _datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
81
+ _registryOfDatatypes[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
83
82
  elif identifier in indexTrack._member_names_:
84
- _datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
83
+ _registryOfDatatypes[identifier] = _datatypeDefault.get(identifier) or _get_datatype('elephino')
85
84
  else:
86
- _datatype[identifier] = _datatypeDefault.get(identifier) or _get_datatype('foldsTotal')
87
- return _datatype[identifier]
85
+ _registryOfDatatypes[identifier] = _datatypeDefault.get(identifier) or _get_datatype('foldsTotal')
86
+ return _registryOfDatatypes[identifier]
88
87
 
89
88
  def getDatatypeModule() -> str:
90
89
  global _datatypeModule
91
90
  if not _datatypeModule:
92
- _datatypeModule = _datatypeModuleDEFAULT
91
+ _datatypeModule = datatypeModulePACKAGING
93
92
  return _datatypeModule
94
93
 
95
94
  def setInStone(identifier: str) -> type[Any]:
@@ -0,0 +1,7 @@
1
+ from typing import Final
2
+
3
+ datatypeModulePACKAGING: Final[str] = 'numpy'
4
+ myPackageNameIsPACKAGING: str = "mapFolding"
5
+ listCallablesDispatcheesHARDCODED: list[str] = ['countInitialize', 'countParallel', 'countSequential']
6
+ additional_importsHARDCODED: list[str] = ['numba']
7
+ algorithmSourcePACKAGING: str = 'theDao'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mapFolding
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: Count distinct ways to fold a map (or a strip of stamps)
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -16,12 +16,12 @@ Classifier: Intended Audience :: Other Audience
16
16
  Classifier: Intended Audience :: Science/Research
17
17
  Classifier: Natural Language :: English
18
18
  Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
19
21
  Classifier: Programming Language :: Python :: 3.10
20
22
  Classifier: Programming Language :: Python :: 3.11
21
23
  Classifier: Programming Language :: Python :: 3.12
22
24
  Classifier: Programming Language :: Python :: 3.13
23
- Classifier: Programming Language :: Python :: 3
24
- Classifier: Programming Language :: Python
25
25
  Classifier: Topic :: Scientific/Engineering :: Mathematics
26
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
27
  Classifier: Typing :: Typed
@@ -35,6 +35,7 @@ Provides-Extra: testing
35
35
  Requires-Dist: autoflake; extra == "testing"
36
36
  Requires-Dist: mypy; extra == "testing"
37
37
  Requires-Dist: more_itertools; extra == "testing"
38
+ Requires-Dist: numba_progress; extra == "testing"
38
39
  Requires-Dist: pytest-cov; extra == "testing"
39
40
  Requires-Dist: pytest-env; extra == "testing"
40
41
  Requires-Dist: pytest-xdist; extra == "testing"
@@ -153,4 +154,4 @@ Available OEIS sequences:
153
154
  [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
154
155
  [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
155
156
 
156
- [![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/)
157
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -6,17 +6,21 @@ pyproject.toml
6
6
  ./mapFolding/beDRY.py
7
7
  ./mapFolding/oeis.py
8
8
  ./mapFolding/py.typed
9
+ ./mapFolding/theConfiguration.py
9
10
  ./mapFolding/theDao.py
10
11
  ./mapFolding/theSSOT.py
11
12
  ./mapFolding/theSSOTdatatypes.py
13
+ ./mapFolding/theWrongWay.py
12
14
  mapFolding/__init__.py
13
15
  mapFolding/basecamp.py
14
16
  mapFolding/beDRY.py
15
17
  mapFolding/oeis.py
16
18
  mapFolding/py.typed
19
+ mapFolding/theConfiguration.py
17
20
  mapFolding/theDao.py
18
21
  mapFolding/theSSOT.py
19
22
  mapFolding/theSSOTdatatypes.py
23
+ mapFolding/theWrongWay.py
20
24
  mapFolding.egg-info/PKG-INFO
21
25
  mapFolding.egg-info/SOURCES.txt
22
26
  mapFolding.egg-info/dependency_links.txt
@@ -6,6 +6,7 @@ Z0Z_tools
6
6
  autoflake
7
7
  mypy
8
8
  more_itertools
9
+ numba_progress
9
10
  pytest-cov
10
11
  pytest-env
11
12
  pytest-xdist
@@ -13,12 +13,12 @@ classifiers = [
13
13
  "Intended Audience :: Science/Research",
14
14
  "Natural Language :: English",
15
15
  "Operating System :: OS Independent",
16
+ "Programming Language :: Python",
17
+ "Programming Language :: Python :: 3",
16
18
  "Programming Language :: Python :: 3.10",
17
19
  "Programming Language :: Python :: 3.11",
18
20
  "Programming Language :: Python :: 3.12",
19
21
  "Programming Language :: Python :: 3.13",
20
- "Programming Language :: Python :: 3",
21
- "Programming Language :: Python",
22
22
  "Topic :: Scientific/Engineering :: Mathematics",
23
23
  "Topic :: Software Development :: Libraries :: Python Modules",
24
24
  "Typing :: Typed",]
@@ -42,6 +42,7 @@ optional-dependencies = { testing = [
42
42
  "autoflake",
43
43
  "mypy",
44
44
  "more_itertools",
45
+ "numba_progress",
45
46
  "pytest-cov",
46
47
  "pytest-env",
47
48
  "pytest-xdist",
@@ -53,7 +54,7 @@ readme = { file = "README.md", content-type = "text/markdown" }
53
54
  requires-python = ">=3.10"
54
55
  scripts = { getOEISids = "mapFolding.oeis:getOEISids", clearOEIScache = "mapFolding.oeis:clearOEIScache", OEIS_for_n = "mapFolding.oeis:OEIS_for_n" }
55
56
  urls = { Donate = "https://www.patreon.com/integrated", Homepage = "https://github.com/hunterhogan/mapFolding", Repository = "https://github.com/hunterhogan/mapFolding.git" }
56
- version = "0.5.1"
57
+ version = "0.6.0"
57
58
 
58
59
  [tool.coverage]
59
60
  report = { exclude_lines = [
@@ -9,16 +9,14 @@ from tests.conftest import (
9
9
  validateOEISid,
10
10
  )
11
11
  from mapFolding import oeisIDfor_n, getOEISids, clearOEIScache
12
+ from pathlib import Path
13
+ from typing import Any, NoReturn
12
14
  from urllib.error import URLError
13
15
  import io
14
- from typing import Any, NoReturn
15
- from pathlib import Path
16
16
  import pytest
17
17
  import random
18
18
  import re as regex
19
- import unittest
20
19
  import unittest.mock
21
- import urllib
22
20
  import urllib.request
23
21
 
24
22
  @pytest.mark.parametrize("badID", ["A999999", " A999999 ", "A999999extra"])
@@ -1,5 +1,21 @@
1
+ from collections.abc import Callable, Generator
1
2
  from contextlib import redirect_stdout
2
- from tests.conftest import *
3
+ from pathlib import Path
4
+ from typing import Any, Literal
5
+ import unittest.mock
6
+ from tests.conftest import (
7
+ PytestFor_intInnit,
8
+ PytestFor_oopsieKwargsie,
9
+ getLeavesTotal,
10
+ hackSSOTdtype,
11
+ makeConnectionGraph,
12
+ makeDataContainer,
13
+ parseDimensions,
14
+ saveFoldsTotal,
15
+ setCPUlimit,
16
+ standardizedEqualTo,
17
+ validateListDimensions,
18
+ )
3
19
  from Z0Z_tools import intInnit
4
20
  import io
5
21
  import itertools
@@ -61,7 +77,7 @@ def test_getLeavesTotal_edge_cases() -> None:
61
77
  # Immutability
62
78
  listOriginal = [2, 3]
63
79
  standardizedEqualTo(6, getLeavesTotal, listOriginal)
64
- standardizedEqualTo([2, 3], lambda x: x, listOriginal) # Check that the list wasn't modified
80
+ standardizedEqualTo([2, 3], lambda x: x, listOriginal) # type: ignore # Check that the list wasn't modified
65
81
 
66
82
  @pytest.mark.parametrize("nameOfTest,callablePytest", PytestFor_intInnit())
67
83
  def testIntInnit(nameOfTest: str, callablePytest: Callable[[], None]) -> None:
@@ -1,3 +1,4 @@
1
+ from typing import Literal
1
2
  from tests.conftest import *
2
3
  import pytest
3
4
 
File without changes
File without changes