diff --git a/plotille/_cmaps.py b/plotille/_cmaps.py index c4d2f8b..284d531 100644 --- a/plotille/_cmaps.py +++ b/plotille/_cmaps.py @@ -38,7 +38,7 @@ class Colormap(object): Colormap represents. Scaling the data into the `[0, 1]` interval is responsibility of the caller. """ - def __init__(self, name): + def __init__(self, name, lookup_table=None): """ Parameters ---------- @@ -48,7 +48,7 @@ def __init__(self, name): The number of rgb quantization levels. """ self.name = name - self._lookup_table = None + self._lookup_table = lookup_table self.bad = None self.over = None self.under = None @@ -86,8 +86,7 @@ def _process_value(self, x): class ListedColormap(Colormap): def __init__(self, name, colors): - super(ListedColormap, self).__init__(name) - self._lookup_table = colors + super(ListedColormap, self).__init__(name, lookup_table=colors) @classmethod def from_relative(cls, name, colors): diff --git a/plotille/_figure.py b/plotille/_figure.py index ee1fc9b..43725b4 100644 --- a/plotille/_figure.py +++ b/plotille/_figure.py @@ -31,7 +31,7 @@ from ._colors import color, rgb2byte from ._figure_data import Heat, Histogram, Plot, Span, Text from ._input_formatter import InputFormatter -from ._util import mk_timedelta, timestamp +from ._util import mk_timedelta # TODO documentation!!! # TODO tests @@ -244,7 +244,7 @@ def _limits(self, low_set, high_set, is_height): def _y_axis(self, ymin, ymax, label='Y'): delta = abs(ymax - ymin) if isinstance(delta, timedelta): - y_delta = mk_timedelta(timestamp(delta) / self.height) + y_delta = mk_timedelta(delta.total_seconds() / self.height) else: y_delta = delta / self.height @@ -271,7 +271,7 @@ def _y_axis(self, ymin, ymax, label='Y'): def _x_axis(self, xmin, xmax, label='X', with_y_axis=False): delta = abs(xmax - xmin) if isinstance(delta, timedelta): - x_delta = mk_timedelta(timestamp(delta) / self.width) + x_delta = mk_timedelta(delta.total_seconds() / self.width) else: x_delta = delta / self.width starts = ['', ''] @@ -546,7 +546,7 @@ def _diff(low, high): else: delta = abs(high - low) if isinstance(delta, timedelta): - return mk_timedelta(timestamp(delta) * 0.1) + return mk_timedelta(delta.total_seconds() * 0.1) else: return delta * 0.1 @@ -568,6 +568,7 @@ def _default(low_set, high_set): return low_set, 1.0 # Should never get here! => checked in function before + raise ValueError('Unexpected inputs!') def _choose(low, high, low_set, high_set): @@ -600,3 +601,4 @@ def _choose(low, high, low_set, high_set): return low_set, high + diff # Should never get here! => checked in function before + raise ValueError('Unexpected inputs!') diff --git a/plotille/_input_formatter.py b/plotille/_input_formatter.py index 3e2fdb6..5660a15 100644 --- a/plotille/_input_formatter.py +++ b/plotille/_input_formatter.py @@ -27,7 +27,7 @@ from datetime import date, datetime, time, timedelta import math -from ._util import roundeven, timestamp +from ._util import roundeven class InputFormatter(object): @@ -138,6 +138,7 @@ def _num_formatter(val, chars, delta, left=False): return _int_formatter(val, chars, left) elif isinstance(val, float): return _float_formatter(val, chars, left) + # unreachable def _float_formatter(val, chars, left=False): @@ -206,7 +207,7 @@ def _convert_numbers(v): def _convert_np_datetime(v): # assert isinstance(v, np.datetime64) - return timestamp(v.item()) + return v.item().timestamp() def _convert_date(v): @@ -216,4 +217,4 @@ def _convert_date(v): def _convert_datetime(v): assert isinstance(v, datetime) - return timestamp(v) + return v.timestamp() diff --git a/plotille/_util.py b/plotille/_util.py index 21a12a1..458df21 100644 --- a/plotille/_util.py +++ b/plotille/_util.py @@ -23,9 +23,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from datetime import datetime, timedelta, tzinfo +from datetime import timedelta, tzinfo import math -import time def roundeven(x): @@ -78,7 +77,7 @@ def hist(X, bins): is_datetime = False if isinstance(delta, timedelta): is_datetime = True - delta = timestamp(delta) + delta = delta.total_seconds() xwidth = delta / bins @@ -87,7 +86,7 @@ def hist(X, bins): x_ = _numpy_to_native(x) delta = (x_ - xmin) if isinstance(delta, timedelta): - delta = timestamp(delta) + delta = delta.total_seconds() x_idx = min(bins - 1, int(delta // xwidth)) y[x_idx] += 1 @@ -111,20 +110,6 @@ def dst(self, dt): return self._ZERO -_EPOCH = datetime(1970, 1, 1, tzinfo=_UTC()) - - -def timestamp(v): - """Get timestamp of `v` datetime in py2/3.""" - if isinstance(v, datetime): - if v.tzinfo is None: - return time.mktime(v.timetuple()) + v.microsecond / 1e6 - else: - return (v - _EPOCH).total_seconds() - elif isinstance(v, timedelta): - return v.total_seconds() - - def mk_timedelta(v): seconds = int(v) microseconds = int((v - seconds) * 1e6) diff --git a/poetry.lock b/poetry.lock index 39feea5..fb6bafe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -15,10 +15,10 @@ optional = false python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "colorama" @@ -69,7 +69,7 @@ attrs = ">=19.2.0" flake8 = ">=3.0.0" [package.extras] -dev = ["tox", "coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit"] +dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "tox"] [[package]] name = "flake8-commas" @@ -104,6 +104,7 @@ python-versions = "*" [package.dependencies] pycodestyle = "*" +setuptools = "*" [[package]] name = "flake8-pep3101" @@ -154,8 +155,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "iniconfig" @@ -185,7 +186,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" six = "*" [package.extras] -build = ["twine", "wheel", "blurb"] +build = ["blurb", "twine", "wheel"] docs = ["sphinx"] test = ["pytest", "pytest-cov"] @@ -299,7 +300,7 @@ optional = false python-versions = ">=3.6.8" [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" @@ -336,7 +337,7 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-mock" @@ -382,6 +383,19 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "setuptools" +version = "65.6.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "six" version = "1.16.0" @@ -423,8 +437,8 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" @@ -741,6 +755,10 @@ pytzdata = [ {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, ] +setuptools = [ + {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, + {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, diff --git a/tests/test_data.py b/tests/test_data.py index 0f1114b..8ab0e3a 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -66,7 +66,7 @@ def test_circle(radius): assert Y[0] == pytest.approx(Y[-1], abs=0.001) for x, y in zip(X, Y): - assert math.sqrt(x**2 + y**2) == pytest.approx(radius**10, abs=0.001) + assert math.hypot(x, y) == pytest.approx(radius**10, abs=0.001) equal = 0 for x2, y2 in zip(X, Y): if x2 == x and y2 == y: diff --git a/tests/test_examples.py b/tests/test_examples.py index 735eca0..5aad453 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -7,19 +7,6 @@ import pytest -try: - import numpy # noqa: F401 - have_numpy = True -except ImportError: - have_numpy = False - - -try: - from PIL import Image # noqa: F401 - have_pillow = True -except ImportError: - have_pillow = False - @pytest.fixture def change_to_examples_dir(request): @@ -28,8 +15,6 @@ def change_to_examples_dir(request): os.chdir(str(request.config.invocation_dir)) -@pytest.mark.skipif(not have_numpy, reason='No numpy installed.') -@pytest.mark.skipif(not have_pillow, reason='No pillow installed.') def test_examples(change_to_examples_dir): sys.path.insert(0, '.') for fname in glob('*_example.py'):