numclassify 0.1.1__tar.gz → 0.2.1__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 (36) hide show
  1. {numclassify-0.1.1 → numclassify-0.2.1}/.gitignore +2 -0
  2. {numclassify-0.1.1 → numclassify-0.2.1}/CHANGELOG.md +13 -0
  3. numclassify-0.2.1/CONTRIBUTING.md +71 -0
  4. {numclassify-0.1.1 → numclassify-0.2.1}/PKG-INFO +73 -45
  5. {numclassify-0.1.1 → numclassify-0.2.1}/README.md +68 -42
  6. numclassify-0.2.1/docs/api.md +25 -0
  7. numclassify-0.2.1/docs/changelog.md +3 -0
  8. numclassify-0.2.1/docs/cli.md +22 -0
  9. numclassify-0.2.1/docs/index.md +23 -0
  10. numclassify-0.2.1/examples/basic_usage.py +6 -0
  11. numclassify-0.2.1/examples/custom_type.py +12 -0
  12. numclassify-0.2.1/examples/find_perfect_numbers.py +9 -0
  13. numclassify-0.2.1/examples/random_classify.py +6 -0
  14. numclassify-0.2.1/examples/stream_large_range.py +7 -0
  15. numclassify-0.2.1/mkdocs.yml +26 -0
  16. numclassify-0.2.1/numclassify/__init__.py +181 -0
  17. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_registry.py +3 -0
  18. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/cli.py +79 -3
  19. numclassify-0.2.1/numclassify/py.typed +0 -0
  20. {numclassify-0.1.1 → numclassify-0.2.1}/pyproject.toml +10 -4
  21. numclassify-0.1.1/numclassify/__init__.py +0 -63
  22. {numclassify-0.1.1 → numclassify-0.2.1}/.github/workflows/ci.yml +0 -0
  23. {numclassify-0.1.1 → numclassify-0.2.1}/.github/workflows/publish.yml +0 -0
  24. {numclassify-0.1.1 → numclassify-0.2.1}/LICENSE +0 -0
  25. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/__main__.py +0 -0
  26. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/__init__.py +0 -0
  27. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/combinatorial.py +0 -0
  28. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/digital.py +0 -0
  29. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/divisors.py +0 -0
  30. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/figurate.py +0 -0
  31. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/number_theory.py +0 -0
  32. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/powers.py +0 -0
  33. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/primes.py +0 -0
  34. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/recreational.py +0 -0
  35. {numclassify-0.1.1 → numclassify-0.2.1}/numclassify/_core/sequences.py +0 -0
  36. {numclassify-0.1.1 → numclassify-0.2.1}/tests/test_registry.py +0 -0
@@ -1,3 +1,4 @@
1
+ .pytest_cache/
1
2
  __pycache__/
2
3
  *.pyc
3
4
  *.pyo
@@ -8,3 +9,4 @@ dist/
8
9
  *.egg-info/
9
10
  .env
10
11
  .venv
12
+ site/
@@ -6,6 +6,19 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
6
6
 
7
7
  ---
8
8
 
9
+ ## [0.2.0] - 2026-05-11
10
+
11
+ ### Added
12
+ - `classify(n)` — returns `{"number": n, "true_properties": [...], "score": int}`
13
+ - `classify_batch(numbers)` — classify a list of numbers in one call
14
+ - `random_number(max_n=10000)` — classify a random number
15
+ - `find_by_property(start, end, **filters)` — query numbers by property name/value
16
+ - `stream(start, end)` — memory-safe generator yielding classify results
17
+ - `numclassify compare <a> <b> [--json]` — new CLI command showing shared/exclusive properties
18
+ - Windows ANSI color fix via `SetConsoleMode` VT100 flag
19
+ - `py.typed` marker added (PEP 561 compliant)
20
+ - Full type hints on all public API functions
21
+
9
22
  ## [0.1.1] - 2026-05-06
10
23
  ### Fixed
11
24
  - cli.py: Fixed imports to use numclassify._core instead of numclassify
@@ -0,0 +1,71 @@
1
+ # Contributing to numclassify
2
+
3
+ ## Adding a New Number Type
4
+
5
+ The fastest way to contribute is adding a new number type using the `@register` decorator.
6
+
7
+ ### Step 1 \u2014 Write your function
8
+
9
+ ```python
10
+ from numclassify import register
11
+
12
+ @register(name="My Type", category="recreational")
13
+ def is_my_type(n: int) -> bool:
14
+ return n > 0 and n % 7 == 0
15
+ ```
16
+
17
+ That's it. Your type is now available via:
18
+ - `nc.get_all_properties(n)`
19
+ - `nc.get_true_properties(n)`
20
+ - `nc.find_in_range(nc.is_my_type, 1, 1000)`
21
+ - `numclassify find my_type` in the CLI
22
+
23
+ ### Step 2 \u2014 Add it to the right module
24
+
25
+ Place your function in the appropriate file under `numclassify/_core/`:
26
+
27
+ | Module | Types |
28
+ |---|---|
29
+ | `primes.py` | Prime families |
30
+ | `figurate.py` | Polygonal/figurate numbers |
31
+ | `divisors.py` | Divisor-based (perfect, abundant...) |
32
+ | `digital.py` | Digit-based (Armstrong, Harshad...) |
33
+ | `sequences.py` | Number sequences (Fibonacci, Lucas...) |
34
+ | `powers.py` | Powers and sums |
35
+ | `number_theory.py` | Number theory properties |
36
+ | `combinatorial.py` | Combinatorial numbers |
37
+ | `recreational.py` | Recreational/fun types |
38
+
39
+ ### Step 3 \u2014 Add a test
40
+
41
+ Add a test in `tests/` following the existing pattern:
42
+
43
+ ```python
44
+ def test_is_my_type():
45
+ assert nc.is_my_type(7) == True
46
+ assert nc.is_my_type(1) == False
47
+ ```
48
+
49
+ ### Step 4 \u2014 Submit a PR
50
+
51
+ ```bash
52
+ git checkout -b add-my-type
53
+ git add .
54
+ git commit -m "Add My Type number classification"
55
+ git push origin add-my-type
56
+ ```
57
+
58
+ Then open a pull request on GitHub.
59
+
60
+ ## Running Tests
61
+
62
+ ```bash
63
+ cd numclassify
64
+ python -m pytest tests/ -v
65
+ ```
66
+
67
+ ## Code Style
68
+
69
+ - Pure Python, no external dependencies
70
+ - Type hints required on all functions
71
+ - Function name must start with `is_` for boolean classifiers
@@ -1,15 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: numclassify
3
- Version: 0.1.1
4
- Summary: The most comprehensive Python library for number classification 3000+ number types
3
+ Version: 0.2.1
4
+ Summary: The most comprehensive Python library for number classification - 3000+ number types
5
5
  Project-URL: Homepage, https://github.com/aratrikghosh2011-tech/numclassify
6
6
  Project-URL: Repository, https://github.com/aratrikghosh2011-tech/numclassify
7
+ Project-URL: Documentation, https://aratrikghosh2011-tech.github.io/numclassify/
7
8
  Project-URL: Issues, https://github.com/aratrikghosh2011-tech/numclassify/issues
8
9
  Author-email: Aratrik Ghosh <aratrikghosh2011@gmail.com>
9
10
  License: MIT
10
11
  License-File: LICENSE
11
12
  Keywords: armstrong,classification,figurate,mathematics,number-theory,prime
12
- Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Development Status :: 4 - Beta
13
14
  Classifier: Intended Audience :: Education
14
15
  Classifier: Intended Audience :: Science/Research
15
16
  Classifier: License :: OSI Approved :: MIT License
@@ -20,32 +21,34 @@ Classifier: Programming Language :: Python :: 3.9
20
21
  Classifier: Programming Language :: Python :: 3.10
21
22
  Classifier: Programming Language :: Python :: 3.11
22
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
23
25
  Classifier: Topic :: Scientific/Engineering :: Mathematics
24
26
  Requires-Python: >=3.8
25
27
  Description-Content-Type: text/markdown
26
28
 
27
29
  # numclassify
28
30
 
29
- > The most comprehensive Python library for number classification — 3000+ number types, zero dependencies.
31
+ The most comprehensive Python library for number classification — 3000+ number types, zero dependencies.
30
32
 
31
33
  [![PyPI version](https://img.shields.io/pypi/v/numclassify)](https://pypi.org/project/numclassify/)
34
+ [![Downloads](https://img.shields.io/pypi/dm/numclassify)](https://pypi.org/project/numclassify/)
32
35
  [![Python versions](https://img.shields.io/pypi/pyversions/numclassify)](https://pypi.org/project/numclassify/)
33
36
  [![License MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/aratrikghosh2011-tech/numclassify/blob/main/LICENSE)
34
37
  [![Tests](https://img.shields.io/github/actions/workflow/status/aratrikghosh2011-tech/numclassify/ci.yml?label=tests)](https://github.com/aratrikghosh2011-tech/numclassify/actions/workflows/ci.yml)
35
38
 
36
39
  ---
37
40
 
38
- ## Why numclassify?
41
+ ## Overview
39
42
 
40
- Most number-theory libraries — `labmath`, `eulerlib`, `pyntlib` — answer *computational* questions: factor this, find the GCD, generate primes up to N.
43
+ Most number-theory libraries — `labmath`, `eulerlib`, `pyntlib` — are built around computation: factoring integers, finding GCDs, generating primes. `numclassify` solves a different problem: **given a number, what is it?**
41
44
 
42
- `numclassify` answers a different question: **what kind of number is this?**
43
-
44
- - `153` Armstrong, Narcissistic, Harshad, Triangular, Abundant…
45
- - `1729` Taxicab (Hardy-Ramanujan), Zeisel, Carmichael…
46
- - `28` → Perfect, Triangular, Hexagonal, Semiprime…
45
+ ```
46
+ 153 → Armstrong, Harshad, Triangular, Abundant ...
47
+ 1729 Taxicab (Hardy-Ramanujan), Carmichael, Zeisel ...
48
+ 28 Perfect, Triangular, Hexagonal, Semiprime ...
49
+ ```
47
50
 
48
- Over **3000 named number types**, instant lookup, no external dependencies.
51
+ Over **3000 named number types** are supported, with instant lookup, no external dependencies, and a fully typed API.
49
52
 
50
53
  ---
51
54
 
@@ -55,7 +58,7 @@ Over **3000 named number types**, instant lookup, no external dependencies.
55
58
  pip install numclassify
56
59
  ```
57
60
 
58
- Or clone and install in editable mode:
61
+ To install from source in editable mode:
59
62
 
60
63
  ```bash
61
64
  git clone https://github.com/aratrikghosh2011-tech/numclassify.git
@@ -71,20 +74,32 @@ pip install -e .
71
74
  import numclassify as nc
72
75
 
73
76
  # Boolean checks
74
- nc.is_prime(17) # True
75
- nc.is_armstrong(153) # True
76
- nc.is_perfect(28) # True
77
+ nc.is_prime(17) # True
78
+ nc.is_perfect(28) # True
79
+
80
+ # Classify a single number
81
+ nc.classify(1729)
82
+ # {'number': 1729, 'true_properties': ['Taxicab', 'Carmichael', ...], 'score': 22}
83
+
84
+ # Classify multiple numbers at once
85
+ nc.classify_batch([6, 28, 496])
86
+
87
+ # Query by property
88
+ nc.find_by_property(start=1, end=1000, Perfect=True)
89
+ # [6, 28, 496]
90
+
91
+ # Memory-safe streaming over large ranges
92
+ for result in nc.stream(1, 1_000_000):
93
+ if result['score'] > 30:
94
+ print(result)
95
+
96
+ # Random number classification
97
+ nc.random_number()
77
98
 
78
99
  # All true properties of a number
79
100
  nc.get_true_properties(1729)
80
- # ['taxicab', 'zeisel', 'carmichael', 'odd', 'composite',
81
- # 'deficient', 'squarefree', 'cubefree', 'powerful_not_perfect_power']
82
-
83
- # Search a range
84
- nc.find_in_range(nc.is_armstrong, 1, 10000)
85
- # [1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474]
86
101
 
87
- # Pretty-print everything about a number
102
+ # Pretty-print everything
88
103
  nc.print_properties(153)
89
104
  # ┌─────────────────────────────────────────┐
90
105
  # │ Properties of 153 │
@@ -132,6 +147,16 @@ $ numclassify range 1 20 --filter prime
132
147
  2, 3, 5, 7, 11, 13, 17, 19
133
148
  ```
134
149
 
150
+ **Compare two numbers:**
151
+ ```bash
152
+ $ numclassify compare 6 28
153
+ Comparing 6 and 28
154
+ ──────────────────
155
+ Shared (13): Perfect, Triangular, Hexagonal, ...
156
+ Only in 6 (21): Armstrong, Factorial, Palindrome, ...
157
+ Only in 28 (8): Happy, Keith, Padovan, ...
158
+ ```
159
+
135
160
  **List all registered types in a category:**
136
161
  ```bash
137
162
  $ numclassify list --category primes
@@ -156,23 +181,23 @@ Examples: 1, 2, 3, 153, 370, 371, 407, 1634, 8208, 9474
156
181
 
157
182
  | Category | Count | Examples |
158
183
  |---|---|---|
159
- | Polygonal (figurate) | 998 | Triangular, Square, Pentagonal Chiliagonal |
160
- | Centered Polygonal | 998 | Centered Triangular, Centered Hexagonal |
161
- | Prime families | 41 | Twin, Mersenne, Sophie Germain, Wilson, Safe |
162
- | Digital invariants | 10 | Armstrong, Spy, Harshad, Disarium, Happy, Neon |
163
- | Divisor-based | 27 | Perfect, Abundant, Weird, Amicable, Practical |
164
- | Sequences | 15 | Fibonacci, Lucas, Catalan, Bell, Padovan |
165
- | Powers | 13 | Perfect Square, Taxicab, Sum of Two Squares |
166
- | Number theory | 14 | Evil, Carmichael, Keith, Autobiographical |
167
- | Combinatorial | 10 | Factorial, Primorial, Subfactorial, Catalan |
168
- | Recreational | 5 | Kaprekar, Automorphic, Palindrome |
184
+ | Polygonal (figurate) | 998 | Triangular, Square, Pentagonal, Chiliagonal |
185
+ | Centered Polygonal | 998 | Centered Triangular, Centered Hexagonal |
186
+ | Prime families | 41 | Twin, Mersenne, Sophie Germain, Wilson, Safe |
187
+ | Digital invariants | 10 | Armstrong, Spy, Harshad, Disarium, Happy, Neon |
188
+ | Divisor-based | 27 | Perfect, Abundant, Weird, Amicable, Practical |
189
+ | Sequences | 15 | Fibonacci, Lucas, Catalan, Bell, Padovan |
190
+ | Powers | 13 | Perfect Square, Taxicab, Sum of Two Squares |
191
+ | Number theory | 14 | Evil, Carmichael, Keith, Autobiographical |
192
+ | Combinatorial | 10 | Factorial, Primorial, Subfactorial, Catalan |
193
+ | Recreational | 5 | Kaprekar, Automorphic, Palindrome |
169
194
  | **Total** | **3000+** | |
170
195
 
171
196
  ---
172
197
 
173
- ## Adding Your Own Number Type
198
+ ## Adding Custom Number Types
174
199
 
175
- The `@register` decorator lets you plug in custom types in 6 lines:
200
+ The `@register` decorator lets you define and integrate your own number types in a few lines. Once registered, the type is automatically available through the full API and CLI.
176
201
 
177
202
  ```python
178
203
  from numclassify import register
@@ -181,7 +206,6 @@ from numclassify import register
181
206
  def is_my_type(n: int) -> bool:
182
207
  return n > 0 and n % 7 == 0 and str(n)[0] == "4"
183
208
 
184
- # Now works everywhere
185
209
  import numclassify as nc
186
210
  nc.is_my_type(49) # False (doesn't start with 4)
187
211
  nc.is_my_type(42) # True
@@ -194,24 +218,28 @@ nc.get_true_properties(42) # [..., 'my_type', ...]
194
218
 
195
219
  | Function | Description |
196
220
  |---|---|
197
- | `is_prime(n)` | Returns `True` if `n` is a standard prime |
198
- | `is_armstrong(n)` | Returns `True` if `n` is a narcissistic/Armstrong number |
199
- | `get_all_properties(n)` | Dict of every registered type `True`/`False` |
200
- | `get_true_properties(n)` | List of only the properties that are `True` |
221
+ | `classify(n)` | Returns a dict with the number, its true properties, and a score |
222
+ | `classify_batch(numbers)` | Classify a list of numbers; returns a list of dicts |
223
+ | `random_number(max_n)` | Classify a randomly selected number up to `max_n` |
224
+ | `find_by_property(start, end, **filters)` | Find numbers in a range matching given property filters |
225
+ | `stream(start, end)` | Generator yielding classify results one at a time; memory-safe |
226
+ | `is_prime(n)` | Returns `True` if `n` is prime |
227
+ | `is_armstrong(n)` | Returns `True` if `n` is an Armstrong (narcissistic) number |
228
+ | `get_all_properties(n)` | Dict mapping every registered type to `True` or `False` |
229
+ | `get_true_properties(n)` | List of only the properties that hold for `n` |
201
230
  | `print_properties(n)` | Pretty-prints a formatted property table to stdout |
202
231
  | `find_in_range(fn, lo, hi)` | All integers in `[lo, hi]` where `fn` returns `True` |
203
- | `find_all_in_range(lo, hi)` | Dict mapping every number in range to its true properties |
204
- | `count_properties(n)` | Count of how many types apply to `n` |
205
- | `most_special_in_range(lo, hi)` | The number in `[lo, hi]` with the most true properties |
232
+ | `count_properties(n)` | Number of types that apply to `n` |
233
+ | `most_special_in_range(lo, hi)` | Number in `[lo, hi]` with the greatest count of true properties |
206
234
 
207
- Full API docs: [github.com/aratrikghosh2011-tech/numclassify](https://github.com/aratrikghosh2011-tech/numclassify)
235
+ Full API documentation: [github.com/aratrikghosh2011-tech/numclassify](https://github.com/aratrikghosh2011-tech/numclassify)
208
236
 
209
237
  ---
210
238
 
211
239
  ## Requirements
212
240
 
213
241
  - Python 3.8 or higher
214
- - Zero external dependencies
242
+ - No external dependencies
215
243
 
216
244
  ---
217
245
 
@@ -1,25 +1,26 @@
1
1
  # numclassify
2
2
 
3
- > The most comprehensive Python library for number classification — 3000+ number types, zero dependencies.
3
+ The most comprehensive Python library for number classification — 3000+ number types, zero dependencies.
4
4
 
5
5
  [![PyPI version](https://img.shields.io/pypi/v/numclassify)](https://pypi.org/project/numclassify/)
6
+ [![Downloads](https://img.shields.io/pypi/dm/numclassify)](https://pypi.org/project/numclassify/)
6
7
  [![Python versions](https://img.shields.io/pypi/pyversions/numclassify)](https://pypi.org/project/numclassify/)
7
8
  [![License MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/aratrikghosh2011-tech/numclassify/blob/main/LICENSE)
8
9
  [![Tests](https://img.shields.io/github/actions/workflow/status/aratrikghosh2011-tech/numclassify/ci.yml?label=tests)](https://github.com/aratrikghosh2011-tech/numclassify/actions/workflows/ci.yml)
9
10
 
10
11
  ---
11
12
 
12
- ## Why numclassify?
13
+ ## Overview
13
14
 
14
- Most number-theory libraries — `labmath`, `eulerlib`, `pyntlib` — answer *computational* questions: factor this, find the GCD, generate primes up to N.
15
+ Most number-theory libraries — `labmath`, `eulerlib`, `pyntlib` — are built around computation: factoring integers, finding GCDs, generating primes. `numclassify` solves a different problem: **given a number, what is it?**
15
16
 
16
- `numclassify` answers a different question: **what kind of number is this?**
17
-
18
- - `153` Armstrong, Narcissistic, Harshad, Triangular, Abundant…
19
- - `1729` Taxicab (Hardy-Ramanujan), Zeisel, Carmichael…
20
- - `28` → Perfect, Triangular, Hexagonal, Semiprime…
17
+ ```
18
+ 153 → Armstrong, Harshad, Triangular, Abundant ...
19
+ 1729 Taxicab (Hardy-Ramanujan), Carmichael, Zeisel ...
20
+ 28 Perfect, Triangular, Hexagonal, Semiprime ...
21
+ ```
21
22
 
22
- Over **3000 named number types**, instant lookup, no external dependencies.
23
+ Over **3000 named number types** are supported, with instant lookup, no external dependencies, and a fully typed API.
23
24
 
24
25
  ---
25
26
 
@@ -29,7 +30,7 @@ Over **3000 named number types**, instant lookup, no external dependencies.
29
30
  pip install numclassify
30
31
  ```
31
32
 
32
- Or clone and install in editable mode:
33
+ To install from source in editable mode:
33
34
 
34
35
  ```bash
35
36
  git clone https://github.com/aratrikghosh2011-tech/numclassify.git
@@ -45,20 +46,32 @@ pip install -e .
45
46
  import numclassify as nc
46
47
 
47
48
  # Boolean checks
48
- nc.is_prime(17) # True
49
- nc.is_armstrong(153) # True
50
- nc.is_perfect(28) # True
49
+ nc.is_prime(17) # True
50
+ nc.is_perfect(28) # True
51
+
52
+ # Classify a single number
53
+ nc.classify(1729)
54
+ # {'number': 1729, 'true_properties': ['Taxicab', 'Carmichael', ...], 'score': 22}
55
+
56
+ # Classify multiple numbers at once
57
+ nc.classify_batch([6, 28, 496])
58
+
59
+ # Query by property
60
+ nc.find_by_property(start=1, end=1000, Perfect=True)
61
+ # [6, 28, 496]
62
+
63
+ # Memory-safe streaming over large ranges
64
+ for result in nc.stream(1, 1_000_000):
65
+ if result['score'] > 30:
66
+ print(result)
67
+
68
+ # Random number classification
69
+ nc.random_number()
51
70
 
52
71
  # All true properties of a number
53
72
  nc.get_true_properties(1729)
54
- # ['taxicab', 'zeisel', 'carmichael', 'odd', 'composite',
55
- # 'deficient', 'squarefree', 'cubefree', 'powerful_not_perfect_power']
56
-
57
- # Search a range
58
- nc.find_in_range(nc.is_armstrong, 1, 10000)
59
- # [1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474]
60
73
 
61
- # Pretty-print everything about a number
74
+ # Pretty-print everything
62
75
  nc.print_properties(153)
63
76
  # ┌─────────────────────────────────────────┐
64
77
  # │ Properties of 153 │
@@ -106,6 +119,16 @@ $ numclassify range 1 20 --filter prime
106
119
  2, 3, 5, 7, 11, 13, 17, 19
107
120
  ```
108
121
 
122
+ **Compare two numbers:**
123
+ ```bash
124
+ $ numclassify compare 6 28
125
+ Comparing 6 and 28
126
+ ──────────────────
127
+ Shared (13): Perfect, Triangular, Hexagonal, ...
128
+ Only in 6 (21): Armstrong, Factorial, Palindrome, ...
129
+ Only in 28 (8): Happy, Keith, Padovan, ...
130
+ ```
131
+
109
132
  **List all registered types in a category:**
110
133
  ```bash
111
134
  $ numclassify list --category primes
@@ -130,23 +153,23 @@ Examples: 1, 2, 3, 153, 370, 371, 407, 1634, 8208, 9474
130
153
 
131
154
  | Category | Count | Examples |
132
155
  |---|---|---|
133
- | Polygonal (figurate) | 998 | Triangular, Square, Pentagonal Chiliagonal |
134
- | Centered Polygonal | 998 | Centered Triangular, Centered Hexagonal |
135
- | Prime families | 41 | Twin, Mersenne, Sophie Germain, Wilson, Safe |
136
- | Digital invariants | 10 | Armstrong, Spy, Harshad, Disarium, Happy, Neon |
137
- | Divisor-based | 27 | Perfect, Abundant, Weird, Amicable, Practical |
138
- | Sequences | 15 | Fibonacci, Lucas, Catalan, Bell, Padovan |
139
- | Powers | 13 | Perfect Square, Taxicab, Sum of Two Squares |
140
- | Number theory | 14 | Evil, Carmichael, Keith, Autobiographical |
141
- | Combinatorial | 10 | Factorial, Primorial, Subfactorial, Catalan |
142
- | Recreational | 5 | Kaprekar, Automorphic, Palindrome |
156
+ | Polygonal (figurate) | 998 | Triangular, Square, Pentagonal, Chiliagonal |
157
+ | Centered Polygonal | 998 | Centered Triangular, Centered Hexagonal |
158
+ | Prime families | 41 | Twin, Mersenne, Sophie Germain, Wilson, Safe |
159
+ | Digital invariants | 10 | Armstrong, Spy, Harshad, Disarium, Happy, Neon |
160
+ | Divisor-based | 27 | Perfect, Abundant, Weird, Amicable, Practical |
161
+ | Sequences | 15 | Fibonacci, Lucas, Catalan, Bell, Padovan |
162
+ | Powers | 13 | Perfect Square, Taxicab, Sum of Two Squares |
163
+ | Number theory | 14 | Evil, Carmichael, Keith, Autobiographical |
164
+ | Combinatorial | 10 | Factorial, Primorial, Subfactorial, Catalan |
165
+ | Recreational | 5 | Kaprekar, Automorphic, Palindrome |
143
166
  | **Total** | **3000+** | |
144
167
 
145
168
  ---
146
169
 
147
- ## Adding Your Own Number Type
170
+ ## Adding Custom Number Types
148
171
 
149
- The `@register` decorator lets you plug in custom types in 6 lines:
172
+ The `@register` decorator lets you define and integrate your own number types in a few lines. Once registered, the type is automatically available through the full API and CLI.
150
173
 
151
174
  ```python
152
175
  from numclassify import register
@@ -155,7 +178,6 @@ from numclassify import register
155
178
  def is_my_type(n: int) -> bool:
156
179
  return n > 0 and n % 7 == 0 and str(n)[0] == "4"
157
180
 
158
- # Now works everywhere
159
181
  import numclassify as nc
160
182
  nc.is_my_type(49) # False (doesn't start with 4)
161
183
  nc.is_my_type(42) # True
@@ -168,24 +190,28 @@ nc.get_true_properties(42) # [..., 'my_type', ...]
168
190
 
169
191
  | Function | Description |
170
192
  |---|---|
171
- | `is_prime(n)` | Returns `True` if `n` is a standard prime |
172
- | `is_armstrong(n)` | Returns `True` if `n` is a narcissistic/Armstrong number |
173
- | `get_all_properties(n)` | Dict of every registered type `True`/`False` |
174
- | `get_true_properties(n)` | List of only the properties that are `True` |
193
+ | `classify(n)` | Returns a dict with the number, its true properties, and a score |
194
+ | `classify_batch(numbers)` | Classify a list of numbers; returns a list of dicts |
195
+ | `random_number(max_n)` | Classify a randomly selected number up to `max_n` |
196
+ | `find_by_property(start, end, **filters)` | Find numbers in a range matching given property filters |
197
+ | `stream(start, end)` | Generator yielding classify results one at a time; memory-safe |
198
+ | `is_prime(n)` | Returns `True` if `n` is prime |
199
+ | `is_armstrong(n)` | Returns `True` if `n` is an Armstrong (narcissistic) number |
200
+ | `get_all_properties(n)` | Dict mapping every registered type to `True` or `False` |
201
+ | `get_true_properties(n)` | List of only the properties that hold for `n` |
175
202
  | `print_properties(n)` | Pretty-prints a formatted property table to stdout |
176
203
  | `find_in_range(fn, lo, hi)` | All integers in `[lo, hi]` where `fn` returns `True` |
177
- | `find_all_in_range(lo, hi)` | Dict mapping every number in range to its true properties |
178
- | `count_properties(n)` | Count of how many types apply to `n` |
179
- | `most_special_in_range(lo, hi)` | The number in `[lo, hi]` with the most true properties |
204
+ | `count_properties(n)` | Number of types that apply to `n` |
205
+ | `most_special_in_range(lo, hi)` | Number in `[lo, hi]` with the greatest count of true properties |
180
206
 
181
- Full API docs: [github.com/aratrikghosh2011-tech/numclassify](https://github.com/aratrikghosh2011-tech/numclassify)
207
+ Full API documentation: [github.com/aratrikghosh2011-tech/numclassify](https://github.com/aratrikghosh2011-tech/numclassify)
182
208
 
183
209
  ---
184
210
 
185
211
  ## Requirements
186
212
 
187
213
  - Python 3.8 or higher
188
- - Zero external dependencies
214
+ - No external dependencies
189
215
 
190
216
  ---
191
217
 
@@ -0,0 +1,25 @@
1
+ # API Reference
2
+
3
+ ## classify(n)
4
+ Returns dict with number, true_properties list, and score.
5
+
6
+ ## classify_batch(numbers)
7
+ Classify a list of integers.
8
+
9
+ ## random_number(max_n=10000)
10
+ Classify a random integer up to max_n.
11
+
12
+ ## find_by_property(start, end, **filters)
13
+ Find numbers matching property filters.
14
+
15
+ ## stream(start, end)
16
+ Memory-safe generator over large ranges.
17
+
18
+ ## Utilities
19
+ - get_all_properties(n)
20
+ - get_true_properties(n)
21
+ - print_properties(n)
22
+ - count_properties(n)
23
+ - most_special_in_range(lo, hi)
24
+ - find_in_range(fn, lo, hi)
25
+ - is_prime(n), is_armstrong(n), is_perfect(n)
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ See the full changelog on GitHub.
@@ -0,0 +1,22 @@
1
+ # CLI Reference
2
+
3
+ ## check
4
+ numclassify check 1729
5
+ numclassify check 1729 --json
6
+
7
+ ## compare
8
+ numclassify compare 6 28
9
+ numclassify compare 6 28 --json
10
+
11
+ ## find
12
+ numclassify find armstrong --limit 10
13
+
14
+ ## range
15
+ numclassify range 1 100 --filter prime
16
+
17
+ ## info
18
+ numclassify info armstrong
19
+
20
+ ## list
21
+ numclassify list
22
+ numclassify list --category primes
@@ -0,0 +1,23 @@
1
+ # numclassify
2
+
3
+ The most comprehensive Python number classification library - 3000+ types, zero dependencies.
4
+
5
+ ## Installation
6
+
7
+ pip install numclassify
8
+
9
+ ## Quick Start
10
+
11
+ import numclassify as nc
12
+ nc.classify(1729)
13
+ nc.classify_batch([6, 28, 496])
14
+ nc.find_by_property(start=1, end=1000, Perfect=True)
15
+ nc.random_number()
16
+
17
+ ## Why numclassify?
18
+
19
+ - 153: Armstrong, Narcissistic, Harshad, Triangular...
20
+ - 1729: Taxicab, Carmichael, Dodecagonal...
21
+ - 28: Perfect, Triangular, Hexagonal, Keith...
22
+
23
+ 3000+ named number types. Instant lookup. Zero dependencies.
@@ -0,0 +1,6 @@
1
+ import numclassify as nc
2
+
3
+ print(nc.classify(1729))
4
+ print(nc.classify_batch([6, 28, 496]))
5
+ print(nc.get_true_properties(153))
6
+ print(nc.count_properties(28))
@@ -0,0 +1,12 @@
1
+ from numclassify import register
2
+ import numclassify as nc
3
+
4
+ # Add a custom number type using the @register decorator
5
+ @register(name="Lucky Seven Multiple", category="recreational")
6
+ def is_lucky_seven_multiple(n: int) -> bool:
7
+ return n > 0 and n % 7 == 0 and "7" in str(n)
8
+
9
+ # Now works across the entire API
10
+ print(nc.is_lucky_seven_multiple(77)) # True
11
+ print(nc.is_lucky_seven_multiple(14)) # False
12
+ print("Lucky Seven Multiples under 200:", nc.find_in_range(nc.is_lucky_seven_multiple, 1, 200))
@@ -0,0 +1,9 @@
1
+ import numclassify as nc
2
+
3
+ # Find all perfect numbers under 10000
4
+ perfect = nc.find_by_property(start=1, end=10000, Perfect=True)
5
+ print("Perfect numbers:", perfect)
6
+
7
+ # Find numbers that are both perfect and odious
8
+ perfect_odious = nc.find_by_property(start=1, end=10000, Perfect=True, Odious=True)
9
+ print("Perfect and Odious:", perfect_odious)
@@ -0,0 +1,6 @@
1
+ import numclassify as nc
2
+
3
+ # Classify 5 random numbers
4
+ for _ in range(5):
5
+ result = nc.random_number(max_n=100000)
6
+ print(f"{result['number']}: {result['score']} properties \u2014 {result['true_properties'][:3]}")
@@ -0,0 +1,7 @@
1
+ import numclassify as nc
2
+
3
+ # Memory-safe streaming over large range
4
+ # Print any number with score > 30
5
+ for result in nc.stream(1, 10000):
6
+ if result["score"] > 30:
7
+ print(f"{result['number']}: score={result['score']}, types={result['true_properties'][:5]}")
@@ -0,0 +1,26 @@
1
+ site_name: numclassify
2
+ site_description: The most comprehensive Python number classification library - 3000+ types
3
+ site_url: https://aratrikghosh2011-tech.github.io/numclassify/
4
+ repo_url: https://github.com/aratrikghosh2011-tech/numclassify
5
+ repo_name: aratrikghosh2011-tech/numclassify
6
+
7
+ theme:
8
+ name: material
9
+ palette:
10
+ primary: indigo
11
+ accent: indigo
12
+ features:
13
+ - navigation.tabs
14
+ - navigation.top
15
+ - content.code.copy
16
+
17
+ nav:
18
+ - Home: index.md
19
+ - API Reference: api.md
20
+ - CLI: cli.md
21
+ - Changelog: changelog.md
22
+
23
+ markdown_extensions:
24
+ - pymdownx.highlight
25
+ - pymdownx.superfences
26
+ - tables
@@ -0,0 +1,181 @@
1
+ """
2
+ numclassify
3
+ ~~~~~~~~~~~
4
+ The most comprehensive Python library for number classification.
5
+ Importing this package triggers registration of all built-in classification
6
+ functions via their ``@register`` decorators.
7
+
8
+ Public API
9
+ ----------
10
+ .. autosummary::
11
+ is_prime
12
+ is_armstrong
13
+ is_perfect
14
+ get_all_properties
15
+ get_true_properties
16
+ print_properties
17
+ find_in_range
18
+ find_all_in_range
19
+ count_properties
20
+ most_special_in_range
21
+ classify
22
+ classify_batch
23
+ random_number
24
+ find_by_property
25
+ stream
26
+ """
27
+
28
+ from __future__ import annotations
29
+ del annotations
30
+
31
+ __version__ = "0.2.1"
32
+
33
+ # --- Import all _core submodules so @register decorators fire at import time ---
34
+ from numclassify._core import primes as _primes # noqa: F401
35
+ from numclassify._core import figurate as _figurate # noqa: F401
36
+ from numclassify._core import digital as _digital # noqa: F401
37
+ from numclassify._core import recreational as _recreational # noqa: F401
38
+ from numclassify._core import divisors as _divisors # noqa: F401
39
+ from numclassify._core import sequences as _sequences # noqa: F401
40
+ from numclassify._core import powers as _powers # noqa: F401
41
+ from numclassify._core import number_theory as _number_theory # noqa: F401
42
+ from numclassify._core import combinatorial as _combinatorial # noqa: F401
43
+
44
+ # --- Re-export key functions at top level ---
45
+ from numclassify._core.primes import is_prime # noqa: F401
46
+ from numclassify._core.digital import is_armstrong # noqa: F401
47
+ from numclassify._core.divisors import is_perfect # noqa: F401
48
+ from numclassify._registry import register # noqa: F401
49
+ from numclassify._registry import ( # noqa: F401
50
+ get_all_properties,
51
+ get_true_properties,
52
+ print_properties,
53
+ find_in_range,
54
+ find_all_in_range,
55
+ count_properties,
56
+ most_special_in_range,
57
+ )
58
+
59
+ # ---------------------------------------------------------------------------
60
+ # Dynamic attribute fallback — allows nc.<any_registered_type>() to work
61
+ # ---------------------------------------------------------------------------
62
+
63
+ def __getattr__(name: str):
64
+ """Fallback: look up *name* in the global registry as a normalised key."""
65
+ from numclassify._registry import REGISTRY, _normalize
66
+
67
+ key = _normalize(name)
68
+ if key in REGISTRY:
69
+ return REGISTRY[key].func
70
+ raise AttributeError(f"module 'numclassify' has no attribute {name!r}")
71
+
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # New features
75
+ # ---------------------------------------------------------------------------
76
+
77
+ def classify(n: int) -> dict:
78
+ """
79
+ Returns a summary dict for a single integer.
80
+
81
+ Returns
82
+ -------
83
+ {
84
+ "number": n,
85
+ "true_properties": [list of property names that are True],
86
+ "score": int, # count of True properties
87
+ }
88
+ """
89
+ raw = get_true_properties(n)
90
+ if isinstance(raw, dict):
91
+ true_props = [k for k, v in raw.items() if v]
92
+ else:
93
+ true_props = list(raw)
94
+
95
+ return {
96
+ "number": n,
97
+ "true_properties": true_props,
98
+ "score": len(true_props),
99
+ }
100
+
101
+
102
+ def classify_batch(numbers: list) -> list:
103
+ """Returns a list of classify(n) dicts, one per number, same order."""
104
+ return [classify(n) for n in numbers]
105
+
106
+
107
+ def random_number(max_n: int = 10000) -> dict:
108
+ """Picks a random int between 1 and max_n inclusive, returns classify(n)."""
109
+ import random as _random
110
+ n = _random.randint(1, max_n)
111
+ return classify(n)
112
+
113
+
114
+ def find_by_property(start: int = 1, end: int = 1000,
115
+ limit: int | None = None, **filters: bool) -> list:
116
+ """
117
+ Query numbers by property values within [start, end].
118
+
119
+ Parameters
120
+ ----------
121
+ start, end : int
122
+ Inclusive search range.
123
+ limit : int, optional
124
+ Stop after finding this many matches.
125
+ **filters : bool
126
+ Property name to required bool value mapping.
127
+
128
+ Returns
129
+ -------
130
+ list of int
131
+
132
+ Example
133
+ -------
134
+ find_by_property(start=1, end=1000, Perfect=True, Odious=True)
135
+ """
136
+ results = []
137
+ for n in range(start, end + 1):
138
+ if not filters:
139
+ results.append(n)
140
+ else:
141
+ props = get_all_properties(n)
142
+ if all(props.get(k) == v for k, v in filters.items()):
143
+ results.append(n)
144
+ if limit is not None and len(results) >= limit:
145
+ break
146
+ return results
147
+
148
+
149
+ def stream(start: int, end: int):
150
+ """Generator. Yields classify(n) for each n in [start, end]. Memory-safe for large ranges."""
151
+ for n in range(start, end + 1):
152
+ yield classify(n)
153
+
154
+
155
+ # ---------------------------------------------------------------------------
156
+ # Public API
157
+ # ---------------------------------------------------------------------------
158
+
159
+ __all__ = [
160
+ "__version__",
161
+ "is_prime",
162
+ "is_armstrong",
163
+ "is_perfect",
164
+ "get_all_properties",
165
+ "get_true_properties",
166
+ "print_properties",
167
+ "find_in_range",
168
+ "find_all_in_range",
169
+ "count_properties",
170
+ "most_special_in_range",
171
+ "classify",
172
+ "classify_batch",
173
+ "random_number",
174
+ "find_by_property",
175
+ "stream",
176
+ ]
177
+
178
+ # Clean up internal names that leak into dir(nc)
179
+ del (_primes, _figurate, _digital, _recreational,
180
+ _divisors, _sequences, _powers, _number_theory,
181
+ _combinatorial, _core, _registry)
@@ -123,6 +123,9 @@ def register(
123
123
  key = _normalize(name)
124
124
  with _REGISTRY_LOCK:
125
125
  REGISTRY[key] = entry
126
+ # Also register under the function's __name__ so
127
+ # nc.<func_name>() works via __getattr__ fallback
128
+ REGISTRY[_normalize(func.__name__)] = entry
126
129
  for alias in _aliases:
127
130
  REGISTRY[_normalize(alias)] = entry
128
131
  return func
@@ -21,6 +21,9 @@ info <type_name>
21
21
 
22
22
  list [--category <cat>]
23
23
  List all registered types, optionally filtered by category.
24
+
25
+ compare <a> <b> [--json]
26
+ Compare two numbers: show shared and exclusive properties.
24
27
  """
25
28
 
26
29
  from __future__ import annotations
@@ -345,6 +348,46 @@ def cmd_list(args: argparse.Namespace) -> None:
345
348
  print()
346
349
 
347
350
 
351
+ def cmd_compare(args: argparse.Namespace) -> None:
352
+ """Handle: numclassify compare <a> <b> [--json]."""
353
+ nc, _, _ = _lazy_import()
354
+
355
+ try:
356
+ a = int(args.a)
357
+ b = int(args.b)
358
+ except ValueError:
359
+ _die("a and b must be integers.")
360
+
361
+ props_a = set(nc.get_true_properties(a))
362
+ props_b = set(nc.get_true_properties(b))
363
+
364
+ shared = sorted(props_a & props_b)
365
+ only_a = sorted(props_a - props_b)
366
+ only_b = sorted(props_b - props_a)
367
+
368
+ if args.json:
369
+ payload = {
370
+ "a": a,
371
+ "b": b,
372
+ "shared": shared,
373
+ "only_a": only_a,
374
+ "only_b": only_b,
375
+ }
376
+ print(json.dumps(payload, indent=2))
377
+ return
378
+
379
+ header = f"Comparing {a} and {b}"
380
+ print(_bold(header))
381
+ print(_rule(len(header)))
382
+
383
+ def _fmt_list(items: List[str]) -> str:
384
+ return ", ".join(items) if items else "(none)"
385
+
386
+ print(f"Shared ({len(shared)}): {_fmt_list(shared)}")
387
+ print(f"Only in {a} ({len(only_a)}): {_fmt_list(only_a)}")
388
+ print(f"Only in {b} ({len(only_b)}): {_fmt_list(only_b)}")
389
+
390
+
348
391
  # ---------------------------------------------------------------------------
349
392
  # Argument parser
350
393
  # ---------------------------------------------------------------------------
@@ -475,8 +518,28 @@ def build_parser() -> argparse.ArgumentParser:
475
518
  )
476
519
  p_list.set_defaults(func=cmd_list)
477
520
 
478
- return parser
521
+ # -- compare -------------------------------------------------------------
522
+ p_compare = sub.add_parser(
523
+ "compare",
524
+ help="Compare properties of two numbers side by side.",
525
+ description=(
526
+ "Show shared and exclusive properties between two integers.\n\n"
527
+ "Examples:\n"
528
+ " numclassify compare 6 28\n"
529
+ " numclassify compare 6 28 --json"
530
+ ),
531
+ formatter_class=argparse.RawDescriptionHelpFormatter,
532
+ )
533
+ p_compare.add_argument("a", help="First integer.")
534
+ p_compare.add_argument("b", help="Second integer.")
535
+ p_compare.add_argument(
536
+ "--json",
537
+ action="store_true",
538
+ help="Output results as JSON with keys a, b, shared, only_a, only_b.",
539
+ )
540
+ p_compare.set_defaults(func=cmd_compare)
479
541
 
542
+ return parser
480
543
 
481
544
  # ---------------------------------------------------------------------------
482
545
  # Entry point
@@ -500,7 +563,20 @@ def main() -> None:
500
563
  )
501
564
 
502
565
  # ------------------------------------------------------------------
503
- # 2. Enable colour + Unicode only when writing to a real terminal.
566
+ # 2. Enable VT100 ANSI escape processing on Windows consoles.
567
+ # On older Windows 10 builds and Wine, ANSI codes are printed
568
+ # literally unless the console mode flag is set explicitly.
569
+ # ------------------------------------------------------------------
570
+ if sys.platform == "win32":
571
+ import ctypes
572
+ try:
573
+ kernel32 = ctypes.windll.kernel32
574
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
575
+ except Exception:
576
+ pass
577
+
578
+ # ------------------------------------------------------------------
579
+ # 3. Enable colour + Unicode only when writing to a real terminal.
504
580
  # Subprocesses/pipes get plain ASCII — no ✓, no ─, no ANSI codes.
505
581
  # ------------------------------------------------------------------
506
582
  if sys.stdout.isatty():
@@ -522,4 +598,4 @@ def main() -> None:
522
598
 
523
599
 
524
600
  if __name__ == "__main__":
525
- main()
601
+ main()
File without changes
@@ -4,15 +4,15 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "numclassify"
7
- version = "0.1.1"
8
- description = "The most comprehensive Python library for number classification 3000+ number types"
7
+ version = "0.2.1"
8
+ description = "The most comprehensive Python library for number classification - 3000+ number types"
9
9
  authors = [{name = "Aratrik Ghosh", email = "aratrikghosh2011@gmail.com"}]
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.8"
12
12
  license = {text = "MIT"}
13
13
  keywords = ["number-theory", "mathematics", "classification", "armstrong", "prime", "figurate"]
14
14
  classifiers = [
15
- "Development Status :: 3 - Alpha",
15
+ "Development Status :: 4 - Beta",
16
16
  "Intended Audience :: Education",
17
17
  "Intended Audience :: Science/Research",
18
18
  "Topic :: Scientific/Engineering :: Mathematics",
@@ -22,6 +22,7 @@ classifiers = [
22
22
  "Programming Language :: Python :: 3.10",
23
23
  "Programming Language :: Python :: 3.11",
24
24
  "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
25
26
  "License :: OSI Approved :: MIT License",
26
27
  "Operating System :: OS Independent",
27
28
  ]
@@ -29,7 +30,12 @@ classifiers = [
29
30
  [project.urls]
30
31
  Homepage = "https://github.com/aratrikghosh2011-tech/numclassify"
31
32
  Repository = "https://github.com/aratrikghosh2011-tech/numclassify"
33
+ Documentation = "https://aratrikghosh2011-tech.github.io/numclassify/"
32
34
  Issues = "https://github.com/aratrikghosh2011-tech/numclassify/issues"
33
35
 
34
36
  [project.scripts]
35
- numclassify = "numclassify.cli:main"
37
+ numclassify = "numclassify.cli:main"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["numclassify"]
41
+ include = ["numclassify/py.typed"]
@@ -1,63 +0,0 @@
1
- """
2
- numclassify
3
- ~~~~~~~~~~~
4
- The most comprehensive Python library for number classification.
5
- Importing this package triggers registration of all built-in classification
6
- functions via their ``@register`` decorators.
7
-
8
- Public API
9
- ----------
10
- .. autosummary::
11
- is_prime
12
- is_armstrong
13
- is_perfect
14
- get_all_properties
15
- get_true_properties
16
- print_properties
17
- find_in_range
18
- find_all_in_range
19
- count_properties
20
- most_special_in_range
21
- """
22
- from __future__ import annotations
23
-
24
- __version__ = "0.1.0"
25
-
26
- # --- Import all _core submodules so @register decorators fire at import time ---
27
- from numclassify._core import primes # noqa: F401
28
- from numclassify._core import figurate # noqa: F401
29
- from numclassify._core import digital # noqa: F401
30
- from numclassify._core import recreational # noqa: F401
31
- from numclassify._core import divisors # noqa: F401
32
- from numclassify._core import sequences # noqa: F401
33
- from numclassify._core import powers # noqa: F401
34
- from numclassify._core import number_theory # noqa: F401
35
- from numclassify._core import combinatorial # noqa: F401
36
-
37
- # --- Re-export key functions at top level ---
38
- from numclassify._core.primes import is_prime # noqa: F401
39
- from numclassify._core.digital import is_armstrong # noqa: F401
40
- from numclassify._core.divisors import is_perfect # noqa: F401
41
- from numclassify._registry import ( # noqa: F401
42
- get_all_properties,
43
- get_true_properties,
44
- print_properties,
45
- find_in_range,
46
- find_all_in_range,
47
- count_properties,
48
- most_special_in_range,
49
- )
50
-
51
- __all__ = [
52
- "__version__",
53
- "is_prime",
54
- "is_armstrong",
55
- "is_perfect",
56
- "get_all_properties",
57
- "get_true_properties",
58
- "print_properties",
59
- "find_in_range",
60
- "find_all_in_range",
61
- "count_properties",
62
- "most_special_in_range",
63
- ]
File without changes