mapFolding 0.17.1__py3-none-any.whl → 0.18.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 (248) hide show
  1. easyRun/NOTcountingFolds.py +7 -11
  2. easyRun/countFolds.py +11 -10
  3. easyRun/meanders.py +6 -8
  4. mapFolding/__init__.py +24 -36
  5. mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_hypothesis.py +189 -0
  6. mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_p2d6.py +143 -0
  7. mapFolding/_e/Z0Z_analysisPython/__init__.py +4 -0
  8. mapFolding/_e/Z0Z_analysisPython/exclusionData/__init__.py +0 -0
  9. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200.py +369 -0
  10. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2001.py +694 -0
  11. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/211.py +514 -0
  12. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/2111.py +480 -0
  13. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214.py +511 -0
  14. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/2141.py +515 -0
  15. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/211.py +485 -0
  16. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/2111.py +442 -0
  17. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/211.py +313 -0
  18. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2111.py +343 -0
  19. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214.py +400 -0
  20. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/2141.py +497 -0
  21. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/211.py +463 -0
  22. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/2111.py +441 -0
  23. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266.py +35 -0
  24. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/2661.py +35 -0
  25. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200.py +382 -0
  26. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2001.py +630 -0
  27. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/211.py +488 -0
  28. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/2111.py +475 -0
  29. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214.py +473 -0
  30. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/2141.py +500 -0
  31. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +465 -0
  32. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +439 -0
  33. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/211.py +599 -0
  34. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2111.py +536 -0
  35. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214.py +506 -0
  36. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/2141.py +533 -0
  37. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/211.py +489 -0
  38. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/2111.py +474 -0
  39. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200.py +1186 -0
  40. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001.py +2158 -0
  41. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001Negative.py +2158 -0
  42. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200Negative.py +1186 -0
  43. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211.py +1397 -0
  44. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111.py +1291 -0
  45. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111Negative.py +1291 -0
  46. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211Negative.py +1397 -0
  47. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214.py +1240 -0
  48. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141.py +1420 -0
  49. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141Negative.py +1420 -0
  50. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214Negative.py +1240 -0
  51. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211.py +1366 -0
  52. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111.py +1274 -0
  53. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +1274 -0
  54. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +1366 -0
  55. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211.py +1186 -0
  56. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111.py +1186 -0
  57. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111Negative.py +1186 -0
  58. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211Negative.py +1186 -0
  59. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214.py +1102 -0
  60. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141.py +1422 -0
  61. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141Negative.py +1422 -0
  62. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214Negative.py +1102 -0
  63. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211.py +1240 -0
  64. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111.py +1228 -0
  65. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111Negative.py +1228 -0
  66. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211Negative.py +1240 -0
  67. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266.py +32 -0
  68. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661.py +1162 -0
  69. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661Negative.py +1162 -0
  70. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266Negative.py +32 -0
  71. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200.py +1186 -0
  72. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001.py +1926 -0
  73. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001Negative.py +1926 -0
  74. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200Negative.py +1186 -0
  75. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211.py +1291 -0
  76. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111.py +1176 -0
  77. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +1176 -0
  78. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +1291 -0
  79. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214.py +1228 -0
  80. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141.py +1324 -0
  81. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +1324 -0
  82. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +1228 -0
  83. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +1274 -0
  84. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +1038 -0
  85. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +1038 -0
  86. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +1274 -0
  87. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211.py +2158 -0
  88. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111.py +1926 -0
  89. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111Negative.py +1926 -0
  90. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211Negative.py +2158 -0
  91. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214.py +1422 -0
  92. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141.py +1364 -0
  93. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141Negative.py +1364 -0
  94. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214Negative.py +1422 -0
  95. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211.py +1420 -0
  96. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111.py +1324 -0
  97. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +1324 -0
  98. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +1420 -0
  99. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200.py +3133 -0
  100. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001.py +6039 -0
  101. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001Negative.py +6039 -0
  102. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200Negative.py +3133 -0
  103. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211.py +3527 -0
  104. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111.py +2300 -0
  105. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111Negative.py +2300 -0
  106. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211Negative.py +3527 -0
  107. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214.py +3597 -0
  108. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141.py +3317 -0
  109. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141Negative.py +3317 -0
  110. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214Negative.py +3597 -0
  111. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211.py +3161 -0
  112. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111.py +2877 -0
  113. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +2877 -0
  114. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +3161 -0
  115. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211.py +2981 -0
  116. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111.py +3055 -0
  117. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111Negative.py +3055 -0
  118. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211Negative.py +2981 -0
  119. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214.py +3221 -0
  120. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141.py +3988 -0
  121. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141Negative.py +3988 -0
  122. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214Negative.py +3221 -0
  123. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211.py +3652 -0
  124. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111.py +2863 -0
  125. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111Negative.py +2863 -0
  126. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211Negative.py +3652 -0
  127. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200.py +2485 -0
  128. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001.py +4566 -0
  129. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001Negative.py +4566 -0
  130. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200Negative.py +2485 -0
  131. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211.py +3006 -0
  132. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111.py +2485 -0
  133. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +2485 -0
  134. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +3006 -0
  135. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214.py +3304 -0
  136. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141.py +3015 -0
  137. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +3015 -0
  138. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +3304 -0
  139. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +2939 -0
  140. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +2589 -0
  141. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +2589 -0
  142. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +2939 -0
  143. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211.py +3899 -0
  144. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111.py +2996 -0
  145. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111Negative.py +2996 -0
  146. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211Negative.py +3899 -0
  147. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214.py +3223 -0
  148. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141.py +3020 -0
  149. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141Negative.py +3020 -0
  150. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214Negative.py +3223 -0
  151. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211.py +3250 -0
  152. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111.py +2667 -0
  153. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +2667 -0
  154. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +3250 -0
  155. mapFolding/_e/Z0Z_analysisPython/measure.py +162 -0
  156. mapFolding/_e/Z0Z_analysisPython/positionAnalysis.py +403 -0
  157. mapFolding/_e/Z0Z_analysisPython/positionAnalysisPileRanges2d6.py +110 -0
  158. mapFolding/_e/Z0Z_analysisPython/theExcluderBeast.py +640 -0
  159. mapFolding/_e/Z0Z_analysisPython/toolkit.py +166 -0
  160. mapFolding/_e/Z0Z_analysisPython/toolkitCSVsequences.py +188 -0
  161. mapFolding/_e/Z0Z_analysisPython/workBenchPatternFinder.py +284 -0
  162. mapFolding/_e/Z0Z_notes/__init__.py +0 -0
  163. mapFolding/_e/Z0Z_notes/knowledgeDump.py +214 -0
  164. mapFolding/_e/__init__.py +45 -0
  165. mapFolding/_e/_beDRY.py +547 -0
  166. mapFolding/_e/_dataDynamic.py +1164 -0
  167. mapFolding/_e/_measure.py +579 -0
  168. mapFolding/_e/_semiotics.py +363 -0
  169. mapFolding/_e/_theTypes.py +31 -0
  170. mapFolding/_e/algorithms/__init__.py +1 -0
  171. mapFolding/_e/algorithms/constraintPropagation.py +158 -0
  172. mapFolding/_e/algorithms/elimination.py +118 -0
  173. mapFolding/_e/algorithms/eliminationCrease.py +66 -0
  174. mapFolding/_e/algorithms/iff.py +584 -0
  175. mapFolding/_e/basecamp.py +89 -0
  176. mapFolding/_e/dataBaskets.py +123 -0
  177. mapFolding/_e/dataRaw/__init__.py +0 -0
  178. mapFolding/_e/easyRun/__init__.py +0 -0
  179. mapFolding/_e/easyRun/eliminateFolds.py +72 -0
  180. mapFolding/_e/easyRun/pinning.py +62 -0
  181. mapFolding/_e/filters.py +384 -0
  182. mapFolding/_e/pin2/344/270/212nDimensions.py +882 -0
  183. mapFolding/_e/pin2/344/270/212nDimensionsAnnex.py +551 -0
  184. mapFolding/_e/pin2/344/270/212nDimensionsByCrease.py +190 -0
  185. mapFolding/_e/pin2/344/270/212nDimensionsByDomain.py +459 -0
  186. mapFolding/_e/pinIt.py +436 -0
  187. mapFolding/_semiotics.py +42 -0
  188. mapFolding/_theSSOT.py +11 -56
  189. mapFolding/_theTypes.py +52 -67
  190. mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
  191. mapFolding/algorithms/oeisIDbyFormula.py +4 -4
  192. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
  193. mapFolding/basecamp.py +11 -80
  194. mapFolding/beDRY.py +107 -111
  195. mapFolding/dataBaskets.py +0 -56
  196. mapFolding/filesystemToolkit.py +15 -11
  197. mapFolding/oeis.py +17 -16
  198. mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +2 -2
  199. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineV2.py +0 -1
  200. mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +8 -10
  201. mapFolding/someAssemblyRequired/RecipeJob.py +5 -5
  202. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +5 -2
  203. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +9 -11
  204. mapFolding/someAssemblyRequired/mapFoldingModules/makeMapFoldingModules.py +2 -1
  205. mapFolding/someAssemblyRequired/transformationTools.py +1 -1
  206. mapFolding/tests/Z0Z_test_e_excluder.py +155 -0
  207. mapFolding/tests/conftest.py +193 -314
  208. mapFolding/tests/dataSamples/A001417.py +455 -0
  209. mapFolding/tests/dataSamples/__init__.py +1 -0
  210. mapFolding/tests/dataSamples/measurementData.py +1818 -0
  211. mapFolding/tests/dataSamples/p2DnDomain3_2_/351/246/226/344/270/200_/351/246/226/351/233/266/344/270/200.py +17 -0
  212. mapFolding/tests/dataSamples/p2DnDomain3_/351/246/226/344/270/200.py +17 -0
  213. mapFolding/tests/dataSamples/p2DnDomain5_4.py +17 -0
  214. mapFolding/tests/dataSamples/p2DnDomain6_5.py +17 -0
  215. mapFolding/tests/dataSamples/p2DnDomain6_7_5_4.py +17 -0
  216. mapFolding/tests/dataSamples/p2DnDomain7_6.py +17 -0
  217. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214.py +17 -0
  218. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +17 -0
  219. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +15 -0
  220. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/272/214_/351/246/226/344/272/214.py +15 -0
  221. mapFolding/tests/dataSamples/semioticsData.py +135 -0
  222. mapFolding/tests/test_computations.py +134 -80
  223. mapFolding/tests/test_e_computations.py +42 -0
  224. mapFolding/tests/test_e_dataDynamic.py +189 -0
  225. mapFolding/tests/test_e_measurements.py +257 -0
  226. mapFolding/tests/test_e_pinning.py +61 -0
  227. mapFolding/tests/test_e_semiotics.py +128 -0
  228. mapFolding/tests/test_filesystem.py +39 -17
  229. mapFolding/tests/{test_other.py → test_parameterValidation.py} +3 -3
  230. mapFolding/tests/{test_tasks.py → test_taskDivisions.py} +42 -23
  231. mapFolding/zCuzDocStoopid/makeDocstrings.py +3 -2
  232. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/METADATA +11 -8
  233. mapfolding-0.18.0.dist-info/RECORD +305 -0
  234. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
  235. easyRun/eliminateFolds.py +0 -60
  236. mapFolding/algorithms/constraintPropagation.py +0 -184
  237. mapFolding/algorithms/elimination.py +0 -131
  238. mapFolding/algorithms/eliminationCount.py +0 -26
  239. mapFolding/algorithms/eliminationPinned.py +0 -35
  240. mapFolding/algorithms/iff.py +0 -206
  241. mapFolding/algorithms/patternFinder.py +0 -280
  242. mapFolding/algorithms/pinning2Dn.py +0 -345
  243. mapFolding/algorithms/pinning2DnAnnex.py +0 -43
  244. mapFolding/tests/verify.py +0 -323
  245. mapfolding-0.17.1.dist-info/RECORD +0 -112
  246. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
  247. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
  248. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
mapFolding/beDRY.py CHANGED
@@ -1,40 +1,103 @@
1
1
  """Oft-needed computations or actions, especially for multi-dimensional map folding."""
2
2
 
3
- from collections.abc import Iterable, Iterator, Sequence
3
+ from collections.abc import Sequence
4
4
  from functools import cache
5
- from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
6
- from mapFolding import NumPyIntegerType
7
- from more_itertools import extract
5
+ from hunterMakesPy.parseParameters import defineConcurrencyLimit, intInnit, oopsieKwargsie
6
+ from mapFolding import Array1DLeavesTotal, Array2DLeavesTotal, Array3DLeavesTotal, inclusive, NumPyIntegerType
8
7
  from numpy import dtype as numpy_dtype, int64 as numpy_int64, ndarray
9
8
  from sys import maxsize as sysMaxsize
10
9
  from typing import Any
11
10
  import numpy
12
11
 
13
- def exclude[个](iterable: Sequence[个], indices: Iterable[int]) -> Iterator[个]:
14
- """Yield items from `iterable` whose positions are not in `indices`."""
15
- lengthIterable: int = len(iterable)
16
- def normalizeIndex(index: int) -> int:
17
- if index < 0:
18
- index = (index + lengthIterable) % lengthIterable
19
- return index
20
- indicesInclude: list[int] = sorted(set(range(lengthIterable)).difference(map(normalizeIndex, indices)))
21
- return extract(iterable, indicesInclude)
12
+ #======== Flow control ======================================
22
13
 
23
- @cache
24
- def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
25
- """Calculate the total number of leaves in a map with the given dimensions.
14
+ def defineProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
15
+ """Compute the CPU usage limit for concurrent operations; for `numba` managed concurrency, set the global limit.
16
+
17
+ Parameters
18
+ ----------
19
+ CPUlimit : Any | None
20
+ Please see the documentation in `countFolds` for details. I know it is annoying, but I want to be sure you
21
+ have the most accurate information.
22
+ concurrencyPackage : str | None = None
23
+ Specifies which concurrency package to use.
24
+ - `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
25
+ - `'numba'`: Uses Numba's threading system.
26
+
27
+ Returns
28
+ -------
29
+ concurrencyLimit : int
30
+ The actual concurrency limit that was set.
31
+
32
+ Raises
33
+ ------
34
+ TypeError
35
+ If `CPUlimit` is not of the expected types.
36
+ NotImplementedError
37
+ If `concurrencyPackage` is not supported.
38
+
39
+ Notes
40
+ -----
41
+ If using `'numba'` as the concurrency package, the maximum number of processors is retrieved from
42
+ `numba.get_num_threads()` rather than by polling the hardware. If Numba environment variables limit available
43
+ processors, that will affect this function.
44
+
45
+ When using Numba, this function must be called before importing any Numba-jitted function for this processor limit
46
+ to affect the Numba-jitted function.
47
+
48
+ """
49
+ # TODO How do I clarify the type and sanitize the value of CPUlimit?
50
+ if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
51
+ CPUlimit = oopsieKwargsie(CPUlimit)
52
+
53
+ match concurrencyPackage:
54
+ case 'numba':
55
+ from numba import get_num_threads, set_num_threads # noqa: PLC0415
56
+ concurrencyLimit: int = defineConcurrencyLimit(limit=CPUlimit, cpuTotal=get_num_threads())
57
+ set_num_threads(concurrencyLimit)
58
+ concurrencyLimit = get_num_threads()
59
+ case 'multiprocessing' | None | _:
60
+ concurrencyLimit = defineConcurrencyLimit(limit=CPUlimit)
61
+ return concurrencyLimit
26
62
 
27
- The total number of leaves is the product of all dimensions in the map shape.
63
+ #======== map folding ===================================
64
+
65
+ def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
66
+ """Create a properly typed connection graph for the map folding algorithm.
28
67
 
29
68
  Parameters
30
69
  ----------
31
70
  mapShape : tuple[int, ...]
32
71
  A tuple of integers representing the dimensions of the map.
72
+ leavesTotal : int
73
+ The total number of leaves in the map.
74
+ datatype : type[NumPyIntegerType]
75
+ The NumPy integer type to use for the array elements, ensuring proper memory usage and compatibility with the
76
+ computation state.
77
+
78
+ Returns
79
+ -------
80
+ connectionGraph : ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]
81
+ A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) with the specified `datatype`,
82
+ representing all possible connections between leaves.
83
+
84
+ """
85
+ connectionGraph: Array3DLeavesTotal = _makeConnectionGraph(mapShape, leavesTotal)
86
+ return connectionGraph.astype(datatype)
87
+
88
+ @cache
89
+ def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
90
+ """The definitive calculation of the total number of leaves in a map with the given dimensions.
91
+
92
+ Parameters
93
+ ----------
94
+ mapShape : tuple[int, ...]
95
+ A tuple of integers with the length of each dimension of the map.
33
96
 
34
97
  Returns
35
98
  -------
36
99
  leavesTotal : int
37
- The total number of leaves in the map, calculated as the product of all dimensions.
100
+ The definitive total number of leaves in the map.
38
101
 
39
102
  Raises
40
103
  ------
@@ -42,12 +105,18 @@ def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
42
105
  If the product of dimensions would exceed the system's maximum integer size. This check prevents silent numeric
43
106
  overflow issues that could lead to incorrect results.
44
107
 
108
+ Notes
109
+ -----
110
+ It is impossible to overstate the importance of `leavesTotal` in every algorithm for counting folds. Therefore, in this
111
+ package, this function is the ***only*** permissible way to compute `leavesTotal`.
112
+
113
+ The total number of leaves is the product of all dimensions in `mapShape`.
45
114
  """
46
115
  productDimensions = 1
47
116
  for dimension in mapShape:
48
117
  # NOTE this check is one-degree short of absurd, but three lines of early absurdity is better than invalid output later. I'd add more checks if I could think of more.
49
118
  if dimension > sysMaxsize // productDimensions:
50
- message = f"I received `{dimension = }` in `{mapShape = }`, but the product of the dimensions exceeds the maximum size of an integer on this system."
119
+ message: str = f"I received `{dimension = }` in `{mapShape = }`, but the product of the dimensions exceeds the maximum size of an integer on this system."
51
120
  raise OverflowError(message)
52
121
  productDimensions *= dimension
53
122
  return productDimensions
@@ -90,18 +159,18 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
90
159
  strComputationDivisions = strComputationDivisions.lower()
91
160
  match strComputationDivisions:
92
161
  case 'maximum':
93
- taskDivisions = leavesTotal
162
+ taskDivisions: int = leavesTotal
94
163
  case 'cpu':
95
164
  taskDivisions = min(concurrencyLimit, leavesTotal)
96
165
  case _:
97
- message = f"I received '{strComputationDivisions}' for the parameter, `computationDivisions`, but the string value is not supported."
166
+ message: str = f"I received '{strComputationDivisions}' for the parameter, `computationDivisions`, but the string value is not supported."
98
167
  raise ValueError(message)
99
168
  case _:
100
169
  message = f"I received {computationDivisions} for the parameter, `computationDivisions`, but the type {type(computationDivisions).__name__} is not supported."
101
170
  raise ValueError(message)
102
171
 
103
172
  if taskDivisions > leavesTotal:
104
- message = f"Problem: `{taskDivisions = }`, is greater than `{leavesTotal = }`, which will cause duplicate counting of the folds.\n\nChallenge: you cannot directly set `taskDivisions` or `leavesTotal`: they are derived from parameters that may or may not be named `computationDivisions`, `CPUlimit` , and `listDimensions` and from my dubious-quality Python code." # noqa: E501
173
+ message = f"Problem: `{taskDivisions = }`, is greater than `{leavesTotal = }`, which will cause duplicate counting of the folds.\n\nChallenge: you cannot directly set `taskDivisions` or `leavesTotal`: they are derived from parameters that may or may not be named `computationDivisions`, `CPUlimit` , and `listDimensions` and from my dubious-quality Python code."
105
174
  raise ValueError(message)
106
175
  return int(max(0, taskDivisions))
107
176
 
@@ -130,22 +199,22 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
130
199
  conditions, and dimensional constraints.
131
200
 
132
201
  """
133
- dimensionsTotal = len(mapShape)
134
- cumulativeProduct = numpy.multiply.accumulate([1, *list(mapShape)], dtype=numpy_int64)
135
- arrayDimensions = numpy.array(mapShape, dtype=numpy_int64)
136
- coordinateSystem = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=numpy_int64)
202
+ dimensionsTotal: int = len(mapShape)
203
+ cumulativeProduct: Array1DLeavesTotal = numpy.multiply.accumulate([1, *list(mapShape)], dtype=numpy_int64)
204
+ arrayDimensions: Array1DLeavesTotal = numpy.array(mapShape, dtype=numpy_int64)
205
+ coordinateSystem: Array2DLeavesTotal = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=numpy_int64)
137
206
  for indexDimension in range(dimensionsTotal):
138
- for leaf1ndex in range(1, leavesTotal + 1):
207
+ for leaf1ndex in range(1, leavesTotal + inclusive):
139
208
  coordinateSystem[indexDimension, leaf1ndex] = (((leaf1ndex - 1) // cumulativeProduct[indexDimension]) % arrayDimensions[indexDimension] + 1)
140
209
 
141
- connectionGraph = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=numpy_int64)
210
+ connectionGraph: Array3DLeavesTotal = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=numpy_int64)
142
211
  for indexDimension in range(dimensionsTotal):
143
- for activeLeaf1ndex in range(1, leavesTotal + 1):
144
- for connectee1ndex in range(1, activeLeaf1ndex + 1):
145
- isFirstCoord = coordinateSystem[indexDimension, connectee1ndex] == 1
146
- isLastCoord = coordinateSystem[indexDimension, connectee1ndex] == arrayDimensions[indexDimension]
147
- exceedsActive = connectee1ndex + cumulativeProduct[indexDimension] > activeLeaf1ndex
148
- isEvenParity = (coordinateSystem[indexDimension, activeLeaf1ndex] & 1) == (coordinateSystem[indexDimension, connectee1ndex] & 1)
212
+ for activeLeaf1ndex in range(1, leavesTotal + inclusive):
213
+ for connectee1ndex in range(1, activeLeaf1ndex + inclusive):
214
+ isFirstCoord: bool = coordinateSystem[indexDimension, connectee1ndex] == 1
215
+ isLastCoord: bool = coordinateSystem[indexDimension, connectee1ndex] == arrayDimensions[indexDimension]
216
+ exceedsActive: bool = connectee1ndex + cumulativeProduct[indexDimension] > activeLeaf1ndex
217
+ isEvenParity: bool = (coordinateSystem[indexDimension, activeLeaf1ndex] & 1) == (coordinateSystem[indexDimension, connectee1ndex] & 1)
149
218
 
150
219
  if (isEvenParity and isFirstCoord) or (not isEvenParity and (isLastCoord or exceedsActive)):
151
220
  connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex
@@ -155,29 +224,6 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
155
224
  connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex + cumulativeProduct[indexDimension]
156
225
  return connectionGraph
157
226
 
158
- def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
159
- """Create a properly typed connection graph for the map folding algorithm.
160
-
161
- Parameters
162
- ----------
163
- mapShape : tuple[int, ...]
164
- A tuple of integers representing the dimensions of the map.
165
- leavesTotal : int
166
- The total number of leaves in the map.
167
- datatype : type[NumPyIntegerType]
168
- The NumPy integer type to use for the array elements, ensuring proper memory usage and compatibility with the
169
- computation state.
170
-
171
- Returns
172
- -------
173
- connectionGraph : ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]
174
- A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) with the specified `datatype`,
175
- representing all possible connections between leaves.
176
-
177
- """
178
- connectionGraph = _makeConnectionGraph(mapShape, leavesTotal)
179
- return connectionGraph.astype(datatype)
180
-
181
227
  def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerType]) -> ndarray[Any, numpy_dtype[NumPyIntegerType]]:
182
228
  """Create any data container as long as it is a `numpy.ndarray` full of zeroes of type `numpy.integer`.
183
229
 
@@ -198,59 +244,6 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerT
198
244
  """
199
245
  return numpy.zeros(shape, dtype=datatype)
200
246
 
201
- def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
202
- """Set the CPU usage limit for concurrent operations.
203
-
204
- Parameters
205
- ----------
206
- CPUlimit : Any | None
207
- Please see the documentation in `countFolds` for details. I know it is annoying, but I want to be sure you
208
- have the most accurate information.
209
- concurrencyPackage : str | None = None
210
- Specifies which concurrency package to use.
211
- - `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
212
- - `'numba'`: Uses Numba's threading system.
213
-
214
- Returns
215
- -------
216
- concurrencyLimit : int
217
- The actual concurrency limit that was set.
218
-
219
- Raises
220
- ------
221
- TypeError
222
- If `CPUlimit` is not of the expected types.
223
- NotImplementedError
224
- If `concurrencyPackage` is not supported.
225
-
226
- Notes
227
- -----
228
- If using `'numba'` as the concurrency package, the maximum number of processors is retrieved from
229
- `numba.get_num_threads()` rather than by polling the hardware. If Numba environment variables limit available
230
- processors, that will affect this function.
231
-
232
- When using Numba, this function must be called before importing any Numba-jitted function for this processor limit
233
- to affect the Numba-jitted function.
234
-
235
- """
236
- if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
237
- CPUlimit = oopsieKwargsie(CPUlimit)
238
-
239
- match concurrencyPackage:
240
- case 'multiprocessing' | None:
241
- # When to use multiprocessing.set_start_method
242
- # https://github.com/hunterhogan/mapFolding/issues/6 # noqa: ERA001
243
- concurrencyLimit: int = defineConcurrencyLimit(limit=CPUlimit)
244
- case 'numba':
245
- from numba import get_num_threads, set_num_threads # noqa: PLC0415
246
- concurrencyLimit = defineConcurrencyLimit(limit=CPUlimit, cpuTotal=get_num_threads())
247
- set_num_threads(concurrencyLimit)
248
- concurrencyLimit = get_num_threads()
249
- case _:
250
- message = f"I received `{concurrencyPackage = }` but I don't know what to do with that."
251
- raise NotImplementedError(message)
252
- return concurrencyLimit
253
-
254
247
  def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
255
248
  """Validate and normalize dimensions for a map folding problem.
256
249
 
@@ -279,7 +272,7 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
279
272
 
280
273
  """
281
274
  if not listDimensions:
282
- message = "`listDimensions` is a required parameter."
275
+ message: str = "`listDimensions` is a required parameter."
283
276
  raise ValueError(message)
284
277
  listOFint: list[int] = intInnit(listDimensions, 'listDimensions')
285
278
  mapDimensions: list[int] = []
@@ -307,3 +300,6 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
307
300
  """
308
301
  # NOTE Do NOT sort the dimensions.
309
302
  return tuple(mapDimensions)
303
+
304
+
305
+
mapFolding/dataBaskets.py CHANGED
@@ -25,62 +25,6 @@ from mapFolding import (
25
25
  getConnectionGraph, getLeavesTotal, makeDataContainer)
26
26
  import dataclasses
27
27
 
28
- @dataclasses.dataclass(slots=True)
29
- class EliminationState:
30
- """Computational state for algorithms to compute foldsTotal by elimination.
31
-
32
- Attributes
33
- ----------
34
- mapShape : tuple[DatatypeLeavesTotal, ...]
35
- Dimensions of the map being analyzed for folding patterns.
36
- groupsOfFolds : DatatypeFoldsTotal = DatatypeFoldsTotal(0)
37
- Current count of distinct folding pattern groups: each group has `leavesTotal`-many foldings.
38
- dimensionsTotal : DatatypeLeavesTotal
39
- Unchanging total number of dimensions in the map.
40
- leavesTotal : DatatypeLeavesTotal
41
- Unchanging total number of leaves in the map.
42
- """
43
-
44
- mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
45
- """Dimensions of the map being analyzed for folding patterns."""
46
-
47
- groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
48
- """Current count of distinct folding pattern groups: each group has `leavesTotal`-many foldings."""
49
-
50
- listPinnedLeaves: list[dict[int, int]] = dataclasses.field(default_factory=list[dict[int, int]], init=True)
51
- """column: leaf or pile: indexLeaf"""
52
- pile: DatatypeLeavesTotal = DatatypeLeavesTotal(-1) # noqa: RUF009
53
- pinnedLeaves: dict[int, int] = dataclasses.field(default_factory=dict[int, int], init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
54
- """column: leaf or pile: indexLeaf"""
55
-
56
- subsetsTheorem2: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
57
- subsetsTheorem3: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
58
- subsetsTheorem4: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
59
-
60
- columnLast: DatatypeLeavesTotal = dataclasses.field(init=False)
61
- dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
62
- """Unchanging total number of dimensions in the map."""
63
- leavesTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
64
- """Unchanging total number of leaves in the map."""
65
-
66
- @property
67
- def foldsTotal(self) -> DatatypeFoldsTotal:
68
- """The total number of possible folding patterns for this map.
69
-
70
- Returns
71
- -------
72
- foldsTotal : DatatypeFoldsTotal
73
- The complete count of distinct folding patterns achievable with the current map configuration.
74
-
75
- """
76
- return DatatypeFoldsTotal(self.leavesTotal) * self.groupsOfFolds * self.subsetsTheorem2 * self.subsetsTheorem3 * self.subsetsTheorem4
77
-
78
- def __post_init__(self) -> None:
79
- """Ensure all fields have a value."""
80
- self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
81
- self.leavesTotal = DatatypeLeavesTotal(getLeavesTotal(self.mapShape))
82
- self.columnLast = self.leavesTotal - DatatypeLeavesTotal(1)
83
-
84
28
  @dataclasses.dataclass(slots=True)
85
29
  class MapFoldingState:
86
30
  """Core computational state for map folding algorithms.
@@ -24,10 +24,14 @@ solutions to their map folding challenges.
24
24
  from mapFolding import packageSettings
25
25
  from os import PathLike
26
26
  from pathlib import Path, PurePath
27
- from sys import modules as sysModules
27
+ from sys import modules as sysModules, stdout
28
+ from typing import TYPE_CHECKING
28
29
  import os
29
30
  import platformdirs
30
31
 
32
+ if TYPE_CHECKING:
33
+ from io import TextIOWrapper
34
+
31
35
  def getFilenameFoldsTotal(mapShape: tuple[int, ...]) -> str:
32
36
  """Create a standardized filename for a computed `foldsTotal` value.
33
37
 
@@ -173,18 +177,18 @@ def saveFoldsTotal(pathFilename: PathLike[str] | PurePath, foldsTotal: int) -> N
173
177
  _saveFoldsTotal(pathFilename, foldsTotal)
174
178
  except Exception as ERRORmessage: # noqa: BLE001
175
179
  try:
176
- print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n") # noqa: T201
177
- print(ERRORmessage) # noqa: T201
178
- print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n") # noqa: T201
179
- randomnessPlanB = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
180
- filenameInfixUnique = ''.join(randomnessPlanB)
181
- pathFilenamePlanB = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt') # noqa: PTH109, PTH118
182
- writeStreamFallback = open(pathFilenamePlanB, 'w') # noqa: PTH123, SIM115
180
+ stdout.write(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
181
+ stdout.writelines(str(ERRORmessage))
182
+ stdout.write(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
183
+ randomnessPlanB: list[str] = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
184
+ filenameInfixUnique: str = ''.join(randomnessPlanB)
185
+ pathFilenamePlanB: str = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt') # noqa: PTH109, PTH118
186
+ writeStreamFallback: TextIOWrapper = open(pathFilenamePlanB, 'w') # noqa: PTH123, SIM115
183
187
  writeStreamFallback.write(str(foldsTotal))
184
188
  writeStreamFallback.close()
185
- print(str(pathFilenamePlanB)) # noqa: T201
189
+ stdout.write(str(pathFilenamePlanB))
186
190
  except Exception: # noqa: BLE001
187
- print(foldsTotal) # noqa: T201
191
+ stdout.write(str(foldsTotal))
188
192
 
189
193
  def saveFoldsTotalFAILearly(pathFilename: PathLike[str] | PurePath) -> None:
190
194
  """Preemptively test file write capabilities before beginning computation.
@@ -220,7 +224,7 @@ def saveFoldsTotalFAILearly(pathFilename: PathLike[str] | PurePath) -> None:
220
224
 
221
225
  """
222
226
  if Path(pathFilename).exists():
223
- message = f"`{pathFilename = }` exists: a battle of overwriting might cause tears."
227
+ message: str = f"`{pathFilename = }` exists: a battle of overwriting might cause tears."
224
228
  raise FileExistsError(message)
225
229
  if not Path(pathFilename).parent.exists():
226
230
  message = f"I received `{pathFilename = }` 0.000139 seconds ago from a function that promised it created the parent directory, but the parent directory does not exist. Fix that now, so your computation doesn't get deleted later. And be compassionate to others."
mapFolding/oeis.py CHANGED
@@ -25,21 +25,20 @@ completes the journey from configuration foundation to mathematical discovery.
25
25
  """
26
26
 
27
27
  from datetime import datetime, timedelta, UTC
28
- from hunterMakesPy import writeStringToHere
28
+ from hunterMakesPy.filesystemToolkit import writeStringToHere
29
29
  from itertools import chain
30
- from mapFolding import countFolds, MetadataOEISid, MetadataOEISidMapFolding, packageSettings
30
+ from mapFolding import MetadataOEISid, MetadataOEISidMapFolding, packageSettings
31
31
  from mapFolding._theSSOT import pathCache
32
+ from mapFolding.basecamp import countFolds
32
33
  from pathlib import Path
33
34
  from typing import Final
35
+ from urllib.error import HTTPError, URLError
34
36
  from urllib.request import urlopen
35
37
  import argparse
36
38
  import sys
37
39
  import time
38
40
  import warnings
39
41
 
40
- oeisIDsImplemented: Final[list[str]] = sorted([oeisID.upper().strip() for oeisID in packageSettings.OEISidMapFoldingManuallySet])
41
- """Directly implemented OEIS IDs; standardized, e.g., 'A001415'."""
42
-
43
42
  def _standardizeOEISid(oeisID: str) -> str:
44
43
  """Standardize an OEIS sequence ID to uppercase and without whitespace.
45
44
 
@@ -56,6 +55,9 @@ def _standardizeOEISid(oeisID: str) -> str:
56
55
  """
57
56
  return str(oeisID).upper().strip()
58
57
 
58
+ oeisIDsImplemented: Final[list[str]] = sorted(map(_standardizeOEISid, packageSettings.OEISidMapFoldingManuallySet))
59
+ """Directly implemented OEIS IDs; standardized, e.g., 'A001415'."""
60
+
59
61
  def _getFilenameOEISbFile(oeisID: str) -> str:
60
62
  """Generate the filename for an OEIS b-file given a sequence ID.
61
63
 
@@ -145,10 +147,13 @@ def _getOEISofficial(pathFilenameCache: Path, url: str) -> None | str:
145
147
  message = "URL must start with 'http:' or 'https:'"
146
148
  raise ValueError(message)
147
149
 
148
- with urlopen(url) as response: # noqa: S310
149
- oeisInformationRaw = response.read().decode('utf-8')
150
- oeisInformation = str(oeisInformationRaw)
151
- writeStringToHere(oeisInformation, pathFilenameCache)
150
+ try:
151
+ with urlopen(url) as response: # noqa: S310
152
+ oeisInformationRaw = response.read().decode('utf-8')
153
+ oeisInformation = str(oeisInformationRaw)
154
+ writeStringToHere(oeisInformation, pathFilenameCache)
155
+ except (HTTPError, URLError):
156
+ oeisInformation = pathFilenameCache.read_text(encoding="utf-8")
152
157
 
153
158
  if not oeisInformation:
154
159
  warnings.warn(f"Failed to retrieve OEIS sequence information for {pathFilenameCache.stem}.", stacklevel=2)
@@ -230,7 +235,7 @@ def getOEISidInformation(oeisID: str) -> tuple[str, int]:
230
235
  listDescriptionDeconstructed: list[str] = []
231
236
  offset = None
232
237
  for lineOEIS in oeisInformation.splitlines():
233
- lineOEIS = lineOEIS.strip() # noqa: PLW2901
238
+ lineOEIS = lineOEIS.strip()
234
239
  if not lineOEIS or len(lineOEIS.split()) < 3:
235
240
  continue
236
241
  fieldCode, sequenceID, fieldData = lineOEIS.split(maxsplit=2)
@@ -279,9 +284,6 @@ def _makeDictionaryOEISMapFolding() -> dict[str, MetadataOEISidMapFolding]:
279
284
  description=descriptionSherpa,
280
285
  offset=offsetSherpa,
281
286
  getMapShape=packageSettings.OEISidMapFoldingManuallySet[oeisID]['getMapShape'],
282
- valuesBenchmark=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesBenchmark'],
283
- valuesTestParallelization=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesTestParallelization'],
284
- valuesTestValidation=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesTestValidation'] + list(range(offsetSherpa, 2)),
285
287
  valuesKnown=valuesKnownSherpa,
286
288
  valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1
287
289
  )
@@ -339,8 +341,8 @@ def _formatHelpText() -> str:
339
341
  A formatted string containing complete usage information and examples.
340
342
 
341
343
  """
342
- exampleOEISid: str = oeisIDsImplemented[0]
343
- exampleN: int = dictionaryOEISMapFolding[exampleOEISid]['valuesTestValidation'][-1]
344
+ exampleOEISid: str = 'A001415'
345
+ exampleN: int = 6
344
346
 
345
347
  return (
346
348
  "\nAvailable OEIS sequences:\n"
@@ -485,7 +487,6 @@ def _makeDictionaryOEIS() -> dict[str, MetadataOEISid]:
485
487
  description=descriptionSherpa,
486
488
  offset=offsetSherpa,
487
489
  valuesKnown=valuesKnownSherpa,
488
- valuesTestValidation=[*(packageSettings.OEISidManuallySet[oeisID]['valuesTestValidation']), offsetSherpa],
489
490
  valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1,
490
491
  )
491
492
  return dictionary
@@ -1,6 +1,6 @@
1
1
  # ruff: noqa
2
- # ================= analyze aligned ===================================================================================
3
- # ======= if bitsAlpha > 1 and bitsZulu > 1 and (bitsAlphaIsEven or bitsZuluIsEven) =====
2
+ #================== analyze aligned ===================================================================================
3
+ #======== if bitsAlpha > 1 and bitsZulu > 1 and (bitsAlphaIsEven or bitsZuluIsEven) =====
4
4
  """NOTE find `bitsAlpha > 1 and bitsZulu > 1 and (bitsAlphaIsEven or bitsZuluIsEven)` without bitsAlpha or bitsZulu.
5
5
  - `bitsAlpha` is even IFF `arcCode` is even.
6
6
  - `bitsAlpha` > 1, so arcCode's LSB is irrelevant; locatorBits ends with 0b101, so arcCode's 2° LSB is irrelevant.
@@ -121,7 +121,6 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
121
121
  bifurcationZulu ^= XOrHere2makePair
122
122
 
123
123
  # Cases 1, 2, and 3 all compute curveLocationAnalysis
124
- # TODO https://github.com/hunterhogan/mapFolding/issues/19
125
124
  curveLocationAnalysis = ((bifurcationZulu >> 2) << 1) | bifurcationAlphaShiftRight2 # pyright: ignore[reportPossiblyUnboundVariable]
126
125
  if curveLocationAnalysis < curveLocationsMAXIMUM:
127
126
  dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
@@ -169,7 +169,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
169
169
 
170
170
  allocateBridgesAligned: int = int(numpy.count_nonzero(selectBridgesAligned))
171
171
 
172
- # ----------------------------------------------- bridgesSimple -------------------------------------------------------
172
+ #------------------------------------------------ bridgesSimple -------------------------------------------------------
173
173
  curveLocationsBridgesSimpleLessThanMaximum: DataArray1D = arrayCurveGroups[:, columnGroupZulu].copy()
174
174
  numpy.left_shift(curveLocationsBridgesSimpleLessThanMaximum, 1, out=curveLocationsBridgesSimpleLessThanMaximum)
175
175
  numpy.bitwise_or(curveLocationsBridgesSimpleLessThanMaximum, arrayCurveGroups[:, columnGroupAlpha], out=curveLocationsBridgesSimpleLessThanMaximum)
@@ -179,14 +179,14 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
179
179
 
180
180
  allocateBridgesSimple: int = int(numpy.count_nonzero(curveLocationsBridgesSimpleLessThanMaximum))
181
181
 
182
- # ----------------------------------------------- arrayCurveLocations -------------------------------------------------
182
+ #------------------------------------------------ arrayCurveLocations -------------------------------------------------
183
183
  rowsAllocatedTotal: int = allocateGroupAlphaCurves + allocateGroupZuluCurves + allocateBridgesSimple + allocateBridgesAligned
184
184
  arrayCurveLocations: DataArray2columns = numpy.zeros((rowsAllocatedTotal, columnsArrayCurveLocations), dtype=arrayCurveGroups.dtype)
185
185
 
186
186
  rowsAggregatedTotal: int = 0
187
187
  rowsDeallocatedTotal: int = 0
188
188
 
189
- # ----------------------------------------------- bridgesSimple -------------------------------------------------------
189
+ #------------------------------------------------ bridgesSimple -------------------------------------------------------
190
190
  rowsAggregatedTotal = aggregateBridgesSimple2CurveLocations(arrayCurveLocations
191
191
  , rowsAggregatedTotal
192
192
  , curveLocationsBridgesSimpleLessThanMaximum
@@ -200,7 +200,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
200
200
  del allocateBridgesSimple
201
201
  goByeBye()
202
202
 
203
- # ----------------------------------------------- groupAlpha ----------------------------------------------------------
203
+ #------------------------------------------------ groupAlpha ----------------------------------------------------------
204
204
  selectGroupAlphaCurves: SelectorBoolean = arrayCurveGroups[:, columnGroupAlpha] > numpy.uint64(1)
205
205
  curveLocationsGroupAlpha: DataArray1D = arrayCurveGroups[selectGroupAlphaCurves, columnGroupAlpha].copy()
206
206
 
@@ -210,7 +210,6 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
210
210
  numpy.bitwise_or(curveLocationsGroupAlpha, arrayCurveGroups[selectGroupAlphaCurves, columnGroupAlpha], out=curveLocationsGroupAlpha)
211
211
  numpy.right_shift(curveLocationsGroupAlpha, 2, out=curveLocationsGroupAlpha)
212
212
  # NOTE (groupAlpha >> 2) | (groupZulu << 3) | ((1 - (groupAlpha & 1)) << 1)
213
- # TODO eliminate temporary arrayLockbox
214
213
  arrayLockbox: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint8]] = numpy.full_like(a=curveLocationsGroupAlpha, fill_value=numpy.uint8(0b111), dtype=numpy.uint8)
215
214
  numpy.bitwise_and(arrayLockbox, curveLocationsGroupAlpha, out=arrayLockbox, dtype=numpy.uint8)
216
215
  numpy.right_shift(curveLocationsGroupAlpha, 3, out=curveLocationsGroupAlpha)
@@ -237,14 +236,13 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
237
236
  selectGroupAlphaCurves = None; del selectGroupAlphaCurves # pyright: ignore[reportAssignmentType] # noqa: E702
238
237
  goByeBye()
239
238
 
240
- # ----------------------------------------------- groupZulu -----------------------------------------------------------
239
+ #------------------------------------------------ groupZulu -----------------------------------------------------------
241
240
  selectGroupZuluCurves: SelectorBoolean = arrayCurveGroups[:, columnGroupZulu] > numpy.uint64(1)
242
241
  curveLocationsGroupZulu: DataArray1D = arrayCurveGroups[selectGroupZuluCurves, columnGroupAlpha].copy()
243
242
  numpy.left_shift(curveLocationsGroupZulu, 2, out=curveLocationsGroupZulu)
244
243
  # NOTE (groupAlpha << 2)
245
244
 
246
245
  numpy.bitwise_or(curveLocationsGroupZulu, numpy.subtract(numpy.uint64(1), numpy.bitwise_and(arrayCurveGroups[selectGroupZuluCurves, columnGroupZulu], 1)), out=curveLocationsGroupZulu)
247
- # TODO | (1 - (groupZulu & 1))
248
246
 
249
247
  # NOTE | (groupZulu >> 1)
250
248
  numpy.left_shift(curveLocationsGroupZulu, 1, out=curveLocationsGroupZulu)
@@ -267,7 +265,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
267
265
  selectGroupZuluCurves = None; del selectGroupZuluCurves # pyright: ignore[reportAssignmentType] # noqa: E702
268
266
  goByeBye()
269
267
 
270
- # ----------------------------------------------- bridgesAligned ------------------------------------------------------
268
+ #------------------------------------------------ bridgesAligned ------------------------------------------------------
271
269
  # `bridgesAligned` = `bridgesGroupAlphaPairedToOdd` UNION WITH `bridgesGroupZuluPairedToOdd` UNION WITH `bridgesAlignedAtEven`
272
270
 
273
271
  # bridgesAligned -------------------------------- bridgesGroupAlphaPairedToOdd ----------------------------------------
@@ -301,7 +299,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
301
299
 
302
300
  # NOTE: All computations for `bridgesAlignedAtEven` are handled by the computations for `bridgesAligned`.
303
301
 
304
- # ----------------------------------------------- bridgesAligned ------------------------------------------------------
302
+ #------------------------------------------------ bridgesAligned ------------------------------------------------------
305
303
 
306
304
  curveLocationsBridgesAlignedLessThanMaximum: DataArray1D = numpy.zeros((selectBridgesAligned.sum(),), dtype=numpy.uint64)
307
305
  numpy.right_shift(arrayCurveGroups[selectBridgesAligned, columnGroupZulu], 2, out=curveLocationsBridgesAlignedLessThanMaximum)
@@ -330,7 +328,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
330
328
  selectBridgesAligned = None; del selectBridgesAligned # pyright: ignore[reportAssignmentType] # noqa: E702
331
329
  goByeBye()
332
330
 
333
- # ----------------------------------------------- aggregation ---------------------------------------------------------
331
+ #------------------------------------------------ aggregation ---------------------------------------------------------
334
332
  arrayCurveGroups = aggregateCurveLocations2CurveGroups(arrayCurveLocations)
335
333
 
336
334
  arrayCurveLocations = None; del arrayCurveLocations # pyright: ignore[reportAssignmentType] # noqa: E702