Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ verify_ssl = true

[dev-packages]
flake8 = "*"
flake8-docstrings = "*"
pytest = "*"

[packages]

Expand All @@ -14,3 +14,5 @@ python_version = "3.7"

[scripts]
lint = "python -m flake8"
start = "python -m src"
test = "python -m pytest"
72 changes: 43 additions & 29 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 71 additions & 0 deletions src/coord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from __future__ import annotations

import operator
from typing import NamedTuple, Callable, TypeVar
from functools import partialmethod


class Coord(NamedTuple):
"""
Helper class for managing coordinate values.

Coord overloads many of the numeric operators by mapping
it to the x and y values individually.

param:
x: int -- X position.
y: int -- Y position.

example::

```
c1 = c2 = Coord(1, 1)
c1 + c2
>>> Coord(2, 2)
# For convenience, integers are accepted as well
c1 = Coord(1, 1)
c1 + 1 # 1 is cast to Coord(1, 1)
>>> Coord(2, 2)
```

note:

True divide `round`s in order to remain compatible with tkinter
coordinate values (`int`).
"""

x: int
y: int

Operand = TypeVar('Operand', 'Coord', int)

def __apply(self, op: Callable, other: Coord.Operand) -> Coord:
if isinstance(other, int):
other = Coord(other, other)

x = op(self.x, other.x)
y = op(self.y, other.y)
return Coord(x, y)

def midpoint(self, other: Coord) -> Coord:
"""
The Coord that is equal distance from `self` and `other`.

param:
other: Coord -- The point to consider.

return:
Coord -- The resulting coordinate.
"""
return (self + other) / 2

def __truediv__(self, other):
result = self.__apply(operator.truediv, other)
return Coord(*map(round, result))

__add__ = partialmethod(__apply, operator.add)
__sub__ = partialmethod(__apply, operator.sub)
__mul__ = partialmethod(__apply, operator.mul)
__mod__ = partialmethod(__apply, operator.mod)
__pow__ = partialmethod(__apply, operator.pow)
__floordiv__ = partialmethod(__apply, operator.floordiv)
Empty file removed src/test/__main__.py
Empty file.
39 changes: 39 additions & 0 deletions src/test/test_coord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from ..animation import Coord

coord1 = Coord(1, 1)
coord2 = Coord(1, 1)


def test_add():
assert coord1 + coord2 == Coord(2, 2)
assert coord1 + 1 == Coord(2, 2)


def test_sub():
assert coord1 - coord2 == Coord(0, 0)
assert coord1 - 1 == Coord(0, 0)


def test_mul():
assert coord1 * coord2 == Coord(1, 1)
assert coord1 * 1 == Coord(1, 1)


def test_mod():
assert coord1 % coord2 == Coord(0, 0)
assert coord1 % 1 == Coord(0, 0)


def test_pow():
assert coord1 ** coord2 == Coord(1, 1)
assert coord1 ** 1 == Coord(1, 1)


def test_truediv():
assert coord1 / coord2 == Coord(1, 1)
assert Coord(2, 2) / 3 == Coord(1, 1)


def test_floordiv():
assert coord1 // coord2 == Coord(1, 1)
assert coord1 // 1 == Coord(1, 1)