Add snap_in/fuzzyval to NeighborList
This commit is contained in:
parent
a514385ff5
commit
7868e57520
@ -242,5 +242,41 @@ class RaiseTests(TestCase):
|
|||||||
self.assertEqual(self.nl.idx, 4)
|
self.assertEqual(self.nl.idx, 4)
|
||||||
|
|
||||||
|
|
||||||
|
class SnapInTests(TestCase):
|
||||||
|
|
||||||
|
"""Tests for the fuzzyval/_snap_in features."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.nl = NeighborList([20, 9, 1, 5])
|
||||||
|
|
||||||
|
def test_bigger(self):
|
||||||
|
self.nl.fuzzyval = 7
|
||||||
|
self.assertEqual(self.nl.nextitem(), 9)
|
||||||
|
self.assertEqual(self.nl.idx, 1)
|
||||||
|
self.assertEqual(self.nl.nextitem(), 1)
|
||||||
|
self.assertEqual(self.nl.idx, 2)
|
||||||
|
|
||||||
|
def test_smaller(self):
|
||||||
|
self.nl.fuzzyval = 7
|
||||||
|
self.assertEqual(self.nl.previtem(), 5)
|
||||||
|
self.assertEqual(self.nl.idx, 3)
|
||||||
|
self.assertEqual(self.nl.previtem(), 1)
|
||||||
|
self.assertEqual(self.nl.idx, 2)
|
||||||
|
|
||||||
|
def test_equal_bigger(self):
|
||||||
|
self.nl.fuzzyval = 9
|
||||||
|
self.assertEqual(self.nl.nextitem(), 9)
|
||||||
|
self.assertEqual(self.nl.idx, 1)
|
||||||
|
self.assertEqual(self.nl.nextitem(), 1)
|
||||||
|
self.assertEqual(self.nl.idx, 2)
|
||||||
|
|
||||||
|
def test_equal_smaller(self):
|
||||||
|
self.nl.fuzzyval = 9
|
||||||
|
self.assertEqual(self.nl.previtem(), 9)
|
||||||
|
self.assertEqual(self.nl.idx, 1)
|
||||||
|
self.assertEqual(self.nl.previtem(), 20)
|
||||||
|
self.assertEqual(self.nl.idx, 0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -21,6 +21,7 @@ Module attributes:
|
|||||||
_UNSET: Used as default argument in the constructor so default can be None.
|
_UNSET: Used as default argument in the constructor so default can be None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import operator
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
_UNSET = object()
|
_UNSET = object()
|
||||||
@ -63,6 +64,7 @@ class NeighborList:
|
|||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
idx: The current position in the list.
|
idx: The current position in the list.
|
||||||
|
fuzzyval: The value which is currently set but not in the list.
|
||||||
_items: A list of all items, accessed through item property.
|
_items: A list of all items, accessed through item property.
|
||||||
_mode: The current mode.
|
_mode: The current mode.
|
||||||
"""
|
"""
|
||||||
@ -90,6 +92,20 @@ class NeighborList:
|
|||||||
else:
|
else:
|
||||||
self.idx = None
|
self.idx = None
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
|
self.fuzzyval = None
|
||||||
|
|
||||||
|
def _snap_in(self, offset):
|
||||||
|
"""Set the current item to the closest item to self.fuzzyval.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
offset: negative to get the next smaller item, positive for the
|
||||||
|
next bigger one.
|
||||||
|
"""
|
||||||
|
op = operator.le if offset < 0 else operator.ge
|
||||||
|
items = [(idx, e) for (idx, e) in enumerate(self._items)
|
||||||
|
if op(e, self.fuzzyval)]
|
||||||
|
close_item = min(items, key=lambda tpl: abs(self.fuzzyval - tpl[1]))
|
||||||
|
self.idx = close_item[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def items(self):
|
def items(self):
|
||||||
@ -113,6 +129,16 @@ class NeighborList:
|
|||||||
self.idx, offset))
|
self.idx, offset))
|
||||||
if not self._items:
|
if not self._items:
|
||||||
raise IndexError("No items found!")
|
raise IndexError("No items found!")
|
||||||
|
if self.fuzzyval is not None:
|
||||||
|
# Value has been set to something not in the list, so we snap in to
|
||||||
|
# the closest value in the right direction and count this as one
|
||||||
|
# step towards offset.
|
||||||
|
self._snap_in(offset)
|
||||||
|
if offset > 0:
|
||||||
|
offset -= 1
|
||||||
|
else:
|
||||||
|
offset += 1
|
||||||
|
self.fuzzyval = None
|
||||||
try:
|
try:
|
||||||
if self.idx + offset >= 0:
|
if self.idx + offset >= 0:
|
||||||
new = self._items[self.idx + offset]
|
new = self._items[self.idx + offset]
|
||||||
|
Loading…
Reference in New Issue
Block a user