numberdb 0.0.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.
- numberdb-0.0.1/LICENSE +21 -0
- numberdb-0.0.1/PKG-INFO +192 -0
- numberdb-0.0.1/README.md +170 -0
- numberdb-0.0.1/numberdb/__init__.py +647 -0
- numberdb-0.0.1/numberdb/_convert.py +141 -0
- numberdb-0.0.1/numberdb/_errors.py +50 -0
- numberdb-0.0.1/numberdb/_http.py +220 -0
- numberdb-0.0.1/numberdb/_limits.py +116 -0
- numberdb-0.0.1/numberdb/_polynomial.py +379 -0
- numberdb-0.0.1/numberdb/_wire.py +396 -0
- numberdb-0.0.1/numberdb/py.typed +0 -0
- numberdb-0.0.1/numberdb/sage.py +165 -0
- numberdb-0.0.1/numberdb.egg-info/PKG-INFO +192 -0
- numberdb-0.0.1/numberdb.egg-info/SOURCES.txt +17 -0
- numberdb-0.0.1/numberdb.egg-info/dependency_links.txt +1 -0
- numberdb-0.0.1/numberdb.egg-info/top_level.txt +1 -0
- numberdb-0.0.1/pyproject.toml +49 -0
- numberdb-0.0.1/setup.cfg +4 -0
- numberdb-0.0.1/tests/test_numberdb.py +1079 -0
numberdb-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Benjamin Matschke
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
numberdb-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: numberdb
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Look a number up in NumberDB and find out whether it is already known
|
|
5
|
+
Author: Benjamin Matschke
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://numberdb.org
|
|
8
|
+
Project-URL: Source, https://github.com/numberdb/numberdb-website
|
|
9
|
+
Project-URL: Issues, https://github.com/numberdb/numberdb-website/issues
|
|
10
|
+
Keywords: mathematics,number theory,constants,sagemath,numberdb
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# numberdb
|
|
24
|
+
|
|
25
|
+
Look a number up in [NumberDB](https://numberdb.org) and find out whether it is
|
|
26
|
+
already known, and where else it appears.
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
$ pip install numberdb
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
>>> import numberdb
|
|
34
|
+
>>> for result in numberdb.search('pi'):
|
|
35
|
+
... print(result.exact_text, '--', result.table.title)
|
|
36
|
+
3.14159265358979323846264338327950288419716939937510582097494 -- Pi
|
|
37
|
+
3.14159265358979323846264338327950288419716939937510582097494 -- Complete elliptic integral ...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## In SageMath
|
|
41
|
+
|
|
42
|
+
The same package, with one import line:
|
|
43
|
+
|
|
44
|
+
```console
|
|
45
|
+
$ sage -pip install numberdb
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
sage: import numberdb.sage as numberdb
|
|
50
|
+
sage: numberdb.search('{n: pi^n for n in [1..5]}')[0].value
|
|
51
|
+
3.141592653589794?
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Everything below that line reads exactly as it would in plain Python — there is
|
|
55
|
+
no mode to set and nothing to pass at each call. `numberdb.sage` re-exports the
|
|
56
|
+
whole package, so it can stand in for it wholesale.
|
|
57
|
+
|
|
58
|
+
It uses the SageMath you already have and installs nothing. **There is no
|
|
59
|
+
`numberdb[sage]` extra, deliberately**: inside a full SageMath it would install
|
|
60
|
+
passagemath over the top, and the passagemath-flint wheel writes 383 files
|
|
61
|
+
under `sage/`, 349 of which already exist there — including compiled
|
|
62
|
+
extensions. pip reports no conflict, because Sage's own files belong to no pip
|
|
63
|
+
distribution.
|
|
64
|
+
|
|
65
|
+
If you have no Sage and still want Sage objects, install passagemath into a
|
|
66
|
+
*fresh* environment, never into an existing Sage.
|
|
67
|
+
|
|
68
|
+
Plain `import numberdb` never imports Sage at all, so it starts instantly; the
|
|
69
|
+
conversion is available per result as `.sage()` when you want it.
|
|
70
|
+
|
|
71
|
+
## What you get back
|
|
72
|
+
|
|
73
|
+
`search()` returns a list of results, each carrying:
|
|
74
|
+
|
|
75
|
+
| | |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `.value` | the number in plain Python (decoded on demand) |
|
|
78
|
+
| `.exact_text` | how the database writes it — the form to quote or paste back into a search |
|
|
79
|
+
| `.str_short` | a short form, comparable across results |
|
|
80
|
+
| `.table` | where it lives (`.tid`, `.title`, `.url`) |
|
|
81
|
+
| `.param` | which entry of that table it is |
|
|
82
|
+
| `.sage()` | the number as a Sage object |
|
|
83
|
+
| `.url()` | where to read about it |
|
|
84
|
+
|
|
85
|
+
`.value` is one of `int`, `Fraction`, `RealInterval`, `ComplexInterval`,
|
|
86
|
+
`PAdic` or `Polynomial`. A `PAdic` carries a `Fraction` — Q_p is not Z_p, so a
|
|
87
|
+
value of negative valuation such as 1/5 in Q_5 has no integer form — and its
|
|
88
|
+
`precision` is **absolute**: the ball is everything congruent to `value` modulo
|
|
89
|
+
`prime ** precision`, matching the `O(p^k)` in its string form. Exact values stay exact: integers are Python `int` (unbounded —
|
|
90
|
+
the database holds integers of over a thousand digits), rationals are
|
|
91
|
+
`Fraction`, and interval endpoints are exact `Fraction`s rather than rounded
|
|
92
|
+
floats. Converting to `float` is your decision, never an accident of transport.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
>>> result.value
|
|
96
|
+
RealInterval(884279719003555/281474976710656, 7074237752028441/2251799813685248)
|
|
97
|
+
>>> float(result.value) # the midpoint, explicitly lossy
|
|
98
|
+
3.141592653589793
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The search itself may have something to say — that it was capped, or that part
|
|
102
|
+
of the expression was rejected:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
>>> results = numberdb.search('...')
|
|
106
|
+
>>> results.messages
|
|
107
|
+
['We only show the first 100 results.']
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### When the server is newer than the package
|
|
111
|
+
|
|
112
|
+
NumberDB will learn new kinds of number. An older package still returns every
|
|
113
|
+
result: values are decoded when you ask for them, so an unfamiliar one costs
|
|
114
|
+
you that value and nothing else, and its `exact_text` is there regardless.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
>>> for result in numberdb.search('...'):
|
|
118
|
+
... if result.is_readable:
|
|
119
|
+
... use(result.value)
|
|
120
|
+
... else:
|
|
121
|
+
... print(result.exact_text) # still perfectly readable
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`results.unreadable` lists them, and every exception the package raises derives
|
|
125
|
+
from `numberdb.NumberDBError`, so one `except` covers it.
|
|
126
|
+
|
|
127
|
+
## Rate limits and API keys
|
|
128
|
+
|
|
129
|
+
Anonymous use is rate limited. A key raises the limit:
|
|
130
|
+
|
|
131
|
+
Keep it out of your worksheet — a shared notebook should not carry its
|
|
132
|
+
author's key:
|
|
133
|
+
|
|
134
|
+
```console
|
|
135
|
+
$ export NUMBERDB_API_KEY=...
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
or, if you must set it in code:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
>>> numberdb.configure(api_key='...')
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
For more than one server or key in a process, use a client directly:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
>>> client = numberdb.Client(api_key='...', base_url='http://localhost:8000/')
|
|
148
|
+
>>> numberdb.search('pi', client=client)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Exceeding the limit raises `numberdb.RateLimited`, which carries `.retry_after`
|
|
152
|
+
in seconds when the server supplies it.
|
|
153
|
+
|
|
154
|
+
## Pointing it somewhere else
|
|
155
|
+
|
|
156
|
+
The default is `https://numberdb.org`. Override it for a development server, or
|
|
157
|
+
a private instance:
|
|
158
|
+
|
|
159
|
+
```console
|
|
160
|
+
$ export NUMBERDB_URL=http://localhost:8000
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
>>> client = numberdb.Client(base_url='https://example.org/numberdb')
|
|
165
|
+
>>> numberdb.search('pi', client=client)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
A trailing slash is optional — a base URL with a path prefix keeps it either
|
|
169
|
+
way.
|
|
170
|
+
|
|
171
|
+
## Other calls
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
>>> numberdb.table('T12') # a whole table, as stored
|
|
175
|
+
>>> numberdb.tag('Irrational') # the tables carrying a tag
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Why a package and not a file to copy
|
|
179
|
+
|
|
180
|
+
The API sends JSON, and turning it into numbers has to happen somewhere. Doing
|
|
181
|
+
it by hand is how the previous example client came to call `loads()` on
|
|
182
|
+
server-supplied bytes — which executes whatever those bytes say, handing code
|
|
183
|
+
execution to anyone able to answer the request. In this package decoding is a
|
|
184
|
+
fixed table: a response can select one of seven decoders and nothing else.
|
|
185
|
+
|
|
186
|
+
Being a package also means it is versioned. When the wire format changes, that
|
|
187
|
+
is a version bump and a clear error telling you to upgrade, rather than an
|
|
188
|
+
exception in the middle of your session.
|
|
189
|
+
|
|
190
|
+
## Licence
|
|
191
|
+
|
|
192
|
+
GPL-3.0-or-later, matching NumberDB.
|
numberdb-0.0.1/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# numberdb
|
|
2
|
+
|
|
3
|
+
Look a number up in [NumberDB](https://numberdb.org) and find out whether it is
|
|
4
|
+
already known, and where else it appears.
|
|
5
|
+
|
|
6
|
+
```console
|
|
7
|
+
$ pip install numberdb
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
>>> import numberdb
|
|
12
|
+
>>> for result in numberdb.search('pi'):
|
|
13
|
+
... print(result.exact_text, '--', result.table.title)
|
|
14
|
+
3.14159265358979323846264338327950288419716939937510582097494 -- Pi
|
|
15
|
+
3.14159265358979323846264338327950288419716939937510582097494 -- Complete elliptic integral ...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## In SageMath
|
|
19
|
+
|
|
20
|
+
The same package, with one import line:
|
|
21
|
+
|
|
22
|
+
```console
|
|
23
|
+
$ sage -pip install numberdb
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
sage: import numberdb.sage as numberdb
|
|
28
|
+
sage: numberdb.search('{n: pi^n for n in [1..5]}')[0].value
|
|
29
|
+
3.141592653589794?
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Everything below that line reads exactly as it would in plain Python — there is
|
|
33
|
+
no mode to set and nothing to pass at each call. `numberdb.sage` re-exports the
|
|
34
|
+
whole package, so it can stand in for it wholesale.
|
|
35
|
+
|
|
36
|
+
It uses the SageMath you already have and installs nothing. **There is no
|
|
37
|
+
`numberdb[sage]` extra, deliberately**: inside a full SageMath it would install
|
|
38
|
+
passagemath over the top, and the passagemath-flint wheel writes 383 files
|
|
39
|
+
under `sage/`, 349 of which already exist there — including compiled
|
|
40
|
+
extensions. pip reports no conflict, because Sage's own files belong to no pip
|
|
41
|
+
distribution.
|
|
42
|
+
|
|
43
|
+
If you have no Sage and still want Sage objects, install passagemath into a
|
|
44
|
+
*fresh* environment, never into an existing Sage.
|
|
45
|
+
|
|
46
|
+
Plain `import numberdb` never imports Sage at all, so it starts instantly; the
|
|
47
|
+
conversion is available per result as `.sage()` when you want it.
|
|
48
|
+
|
|
49
|
+
## What you get back
|
|
50
|
+
|
|
51
|
+
`search()` returns a list of results, each carrying:
|
|
52
|
+
|
|
53
|
+
| | |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `.value` | the number in plain Python (decoded on demand) |
|
|
56
|
+
| `.exact_text` | how the database writes it — the form to quote or paste back into a search |
|
|
57
|
+
| `.str_short` | a short form, comparable across results |
|
|
58
|
+
| `.table` | where it lives (`.tid`, `.title`, `.url`) |
|
|
59
|
+
| `.param` | which entry of that table it is |
|
|
60
|
+
| `.sage()` | the number as a Sage object |
|
|
61
|
+
| `.url()` | where to read about it |
|
|
62
|
+
|
|
63
|
+
`.value` is one of `int`, `Fraction`, `RealInterval`, `ComplexInterval`,
|
|
64
|
+
`PAdic` or `Polynomial`. A `PAdic` carries a `Fraction` — Q_p is not Z_p, so a
|
|
65
|
+
value of negative valuation such as 1/5 in Q_5 has no integer form — and its
|
|
66
|
+
`precision` is **absolute**: the ball is everything congruent to `value` modulo
|
|
67
|
+
`prime ** precision`, matching the `O(p^k)` in its string form. Exact values stay exact: integers are Python `int` (unbounded —
|
|
68
|
+
the database holds integers of over a thousand digits), rationals are
|
|
69
|
+
`Fraction`, and interval endpoints are exact `Fraction`s rather than rounded
|
|
70
|
+
floats. Converting to `float` is your decision, never an accident of transport.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
>>> result.value
|
|
74
|
+
RealInterval(884279719003555/281474976710656, 7074237752028441/2251799813685248)
|
|
75
|
+
>>> float(result.value) # the midpoint, explicitly lossy
|
|
76
|
+
3.141592653589793
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The search itself may have something to say — that it was capped, or that part
|
|
80
|
+
of the expression was rejected:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
>>> results = numberdb.search('...')
|
|
84
|
+
>>> results.messages
|
|
85
|
+
['We only show the first 100 results.']
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### When the server is newer than the package
|
|
89
|
+
|
|
90
|
+
NumberDB will learn new kinds of number. An older package still returns every
|
|
91
|
+
result: values are decoded when you ask for them, so an unfamiliar one costs
|
|
92
|
+
you that value and nothing else, and its `exact_text` is there regardless.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
>>> for result in numberdb.search('...'):
|
|
96
|
+
... if result.is_readable:
|
|
97
|
+
... use(result.value)
|
|
98
|
+
... else:
|
|
99
|
+
... print(result.exact_text) # still perfectly readable
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`results.unreadable` lists them, and every exception the package raises derives
|
|
103
|
+
from `numberdb.NumberDBError`, so one `except` covers it.
|
|
104
|
+
|
|
105
|
+
## Rate limits and API keys
|
|
106
|
+
|
|
107
|
+
Anonymous use is rate limited. A key raises the limit:
|
|
108
|
+
|
|
109
|
+
Keep it out of your worksheet — a shared notebook should not carry its
|
|
110
|
+
author's key:
|
|
111
|
+
|
|
112
|
+
```console
|
|
113
|
+
$ export NUMBERDB_API_KEY=...
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
or, if you must set it in code:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
>>> numberdb.configure(api_key='...')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
For more than one server or key in a process, use a client directly:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
>>> client = numberdb.Client(api_key='...', base_url='http://localhost:8000/')
|
|
126
|
+
>>> numberdb.search('pi', client=client)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Exceeding the limit raises `numberdb.RateLimited`, which carries `.retry_after`
|
|
130
|
+
in seconds when the server supplies it.
|
|
131
|
+
|
|
132
|
+
## Pointing it somewhere else
|
|
133
|
+
|
|
134
|
+
The default is `https://numberdb.org`. Override it for a development server, or
|
|
135
|
+
a private instance:
|
|
136
|
+
|
|
137
|
+
```console
|
|
138
|
+
$ export NUMBERDB_URL=http://localhost:8000
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
>>> client = numberdb.Client(base_url='https://example.org/numberdb')
|
|
143
|
+
>>> numberdb.search('pi', client=client)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
A trailing slash is optional — a base URL with a path prefix keeps it either
|
|
147
|
+
way.
|
|
148
|
+
|
|
149
|
+
## Other calls
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
>>> numberdb.table('T12') # a whole table, as stored
|
|
153
|
+
>>> numberdb.tag('Irrational') # the tables carrying a tag
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Why a package and not a file to copy
|
|
157
|
+
|
|
158
|
+
The API sends JSON, and turning it into numbers has to happen somewhere. Doing
|
|
159
|
+
it by hand is how the previous example client came to call `loads()` on
|
|
160
|
+
server-supplied bytes — which executes whatever those bytes say, handing code
|
|
161
|
+
execution to anyone able to answer the request. In this package decoding is a
|
|
162
|
+
fixed table: a response can select one of seven decoders and nothing else.
|
|
163
|
+
|
|
164
|
+
Being a package also means it is versioned. When the wire format changes, that
|
|
165
|
+
is a version bump and a clear error telling you to upgrade, rather than an
|
|
166
|
+
exception in the middle of your session.
|
|
167
|
+
|
|
168
|
+
## Licence
|
|
169
|
+
|
|
170
|
+
GPL-3.0-or-later, matching NumberDB.
|