-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dc4203a
Showing
8 changed files
with
787 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Python-generated files | ||
__pycache__ | ||
*.py[oc] | ||
build/ | ||
dist/ | ||
wheels/ | ||
*.egg-info | ||
|
||
# Virtual environments | ||
.venv | ||
|
||
# Test artifacts | ||
.mypy_cache | ||
.hypothesis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[ISC License] | ||
|
||
Copyright 2024 Gregory Werbin | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
= N-vector Lite | ||
|
||
== About | ||
|
||
N-vector Lite is a simple, flexible, and permissively-licensed implementation | ||
of the https://www.ffi.no/en/research/n-vector["n-vector" horizontal position | ||
system] in Python and Numpy. It is currently **alpha quality**. | ||
|
||
Note that this project is developed/maintained as a side project in my spare | ||
time. See `+LICENSE.txt+` for license terms, including a total disclaimer of | ||
warranty. Contributions of bugfixes and features are accepted, but I make no | ||
promises about the timeliness of my response. | ||
|
||
For an explanation of the n-vector system, refer to the `+nvector_lite.py+` docstring. | ||
|
||
This library is designed to work with arbitrary-shape/size Numpy arrays. By | ||
comparison, the original https://pypi.org/project/nvector[nvector] | ||
implementation has inconsistent and unclear support for arrays of multiple | ||
points, i.e. anything other than shape `+(3, 1)+`. | ||
|
||
N-vector Lite is meant to be useful for "batch" computation over datasets of | ||
points stored in Numpy arrays, Pandas data frames, etc. — with much faster | ||
performance than you would be able to achieve with the original `+nvector+` | ||
library. | ||
|
||
This is also useful for SQL-like database/query engines that support | ||
batched/vectorized Python UDFs, such as PySpark, DuckDB, and Snowflake. | ||
|
||
== Installation | ||
|
||
I will set up PyPI publishing and a stable versioning scheme eventually. | ||
For now, install https://pip.pypa.io/en/stable/topics/vcs-support/#git[directly from Git using Pip]: | ||
|
||
[,shell] | ||
---- | ||
pip install git+https://github.com/gwerbin/nvector-lite | ||
---- | ||
|
||
== Development | ||
|
||
Development requires https://hatch.pypa.io/[Hatch]. | ||
|
||
First, clone the Git repository. | ||
|
||
Then, set up our Hatch environments: | ||
|
||
[,shell] | ||
---- | ||
hatch python install all | ||
hatch env create dev | ||
---- | ||
|
||
Technically this is optional and will be done automatically by `+hatch run+`. | ||
But it's nice to have everything set up and ready to avoid a long wait for the | ||
first command. | ||
|
||
Run tests: | ||
|
||
[,shell] | ||
---- | ||
hatch run dev:pytest | ||
---- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
## Pytest config | ||
|
||
import pytest | ||
import hypothesis | ||
|
||
# Load the Hypothesis plugin here, because we disabled it in in pyproject.toml, in order | ||
# to ensure that pytest-cov is loaded first. | ||
# If we don't do this, coverage reports will be wrong. | ||
# See: https://hypothesis.readthedocs.io/en/latest/strategies.html#interaction-with-pytest-cov | ||
pytest_plugins = [ | ||
"hypothesis.extra.pytestplugin", | ||
] | ||
|
||
|
||
def pytest_addoption(parser: pytest.Parser) -> None: | ||
parser.addoption("--max-examples", default=None, type=int, help="Hypothesis max_examples setting.") | ||
|
||
|
||
def pytest_configure(config: pytest.Config) -> None: | ||
test_max_examples = ( | ||
config.getoption("--max-examples") | ||
or _getenv_positive_integer("TEST_MAX_EXAMPLES") | ||
or 100 | ||
) | ||
hypothesis.settings.register_profile("dev", print_blob=True, max_examples=test_max_examples) | ||
hypothesis.settings.load_profile("dev") | ||
print(hypothesis.settings.get_profile("dev")) | ||
|
||
|
||
## Helpers | ||
|
||
import os | ||
from typing import NewType | ||
|
||
PositiveInt = NewType("PositiveInt", int) | ||
|
||
|
||
def _convert_positive_integer(y: int) -> PositiveInt: | ||
if y <= 0: | ||
raise ValueError("A positive integer was expected.") | ||
return PositiveInt(y) | ||
|
||
|
||
def _parse_positive_integer(x: str) -> PositiveInt: | ||
return _convert_positive_integer(int(x)) | ||
|
||
|
||
def _getenv_positive_integer(k: str) -> PositiveInt | None: | ||
if (val := os.environ.get(k)) is not None: | ||
return _parse_positive_integer(val) | ||
else: | ||
return None |
Oops, something went wrong.