Skip to content

Commit 947fc84

Browse files
committed
TR updates
1 parent cd2fb59 commit 947fc84

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

python-range/float_range.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import math
21
from dataclasses import dataclass, field
2+
from math import ceil, isclose
33

44

55
@dataclass
66
class FloatRange:
7+
"""Range of numbers that allows floating point numbers."""
8+
79
start: float | int
8-
stop: float | int = None
10+
stop: float | int | None = None
911
step: float | int = 1.0
1012

1113
def __post_init__(self):
@@ -20,7 +22,7 @@ def __post_init__(self):
2022
raise ValueError("'start' must be a floating point number")
2123
if not isinstance(self.stop, float | int):
2224
raise ValueError("'stop' must be a floating point number")
23-
if not isinstance(self.step, float | int) or self.step == 0:
25+
if not isinstance(self.step, float | int) or isclose(self.step, 0):
2426
raise ValueError("'step' must be a non-zero floating point number")
2527

2628
def __iter__(self):
@@ -35,21 +37,23 @@ def __contains__(self, element):
3537
offset = (element - self.start) % self.step
3638
if self.step > 0:
3739
return self.start <= element < self.stop and (
38-
math.isclose(offset, 0) or math.isclose(offset, self.step)
40+
isclose(offset, 0) or isclose(offset, self.step)
3941
)
4042
else:
4143
return self.stop < element <= self.start and (
42-
math.isclose(offset, 0) or math.isclose(offset, self.step)
44+
isclose(offset, 0) or isclose(offset, self.step)
4345
)
4446

4547
def __len__(self):
4648
"""Calculate the number of elements in the range."""
4749
if any(
48-
self.step > 0 and self.stop <= self.start,
49-
self.step < 0 and self.stop >= self.start,
50+
[
51+
self.step > 0 and self.stop <= self.start,
52+
self.step < 0 and self.stop >= self.start,
53+
]
5054
):
5155
return 0
52-
return math.ceil((self.stop - self.start) / self.step)
56+
return ceil((self.stop - self.start) / self.step)
5357

5458
def __getitem__(self, index):
5559
"""Get an element in the range based on its index."""
@@ -58,7 +62,11 @@ def __getitem__(self, index):
5862
return self.start + index * self.step
5963

6064
def __reversed__(self):
61-
"""Create a FloatRange with elements in the reverse order."""
65+
"""Create a FloatRange with elements in the reverse order.
66+
67+
Any number 0 < x < self.step can be used as offset. Use 0.1 when
68+
possible as an "esthetically nice" offset.
69+
"""
6270
cls = type(self)
6371
offset = (1 if self.step > 0 else -1) * min(0.1, abs(self.step) / 2)
6472
return cls(
@@ -80,17 +88,25 @@ def index(self, element):
8088

8189
@dataclass
8290
class _FloatRangeIterator:
83-
start: int
84-
stop: int
85-
step: int
91+
"""Non-public iterator. Should only be initialized by FloatRange."""
92+
93+
start: float | int
94+
stop: float | int
95+
step: float | int
8696
_num_steps: int = field(default=0, init=False)
8797

98+
def __iter__(self):
99+
"""Initialize the iterator."""
100+
return self
101+
88102
def __next__(self):
89103
"""Calculate the next element in the iteration."""
90104
element = self.start + self._num_steps * self.step
91105
if any(
92-
self.step > 0 and element >= self.stop,
93-
self.step < 0 and element <= self.stop,
106+
[
107+
self.step > 0 and element >= self.stop,
108+
self.step < 0 and element <= self.stop,
109+
]
94110
):
95111
raise StopIteration
96112
self._num_steps += 1

0 commit comments

Comments
 (0)