kopia lustrzana https://github.com/peterhinch/micropython-samples
Add bitmap directory.
rodzic
2c5df6912e
commit
4807b7a39a
|
@ -123,6 +123,15 @@ Linux installation and having to compile the Unix build of MicroPython.
|
|||
This describes ways of using the Pyboard to perform precision measurements of
|
||||
analog signals of up to around 50KHz. It is documented [here](./phase/README.md).
|
||||
|
||||
# bitmap: bool arrays and sets of integers
|
||||
|
||||
Classes for non-allocating handling of sets of small integers and small arrays
|
||||
of booleans. Legal member values for a set and array index values are
|
||||
constrained to 0 <= value <= max_value where max_value is a constructor arg.
|
||||
The set and the array are different ways of viewing a bitmap implemented as a
|
||||
bytearray: e.g. if max_value is 255 the bytearray occupies 32 bytes allocated by
|
||||
the constructor.
|
||||
|
||||
# Pyboard D
|
||||
|
||||
An unofficial guide to this board. When official docs emerge this will be
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
# bitmap.py
|
||||
# Ideas for non-allocating classes based around a bitmap. Three classes are
|
||||
# presented:
|
||||
# IntSet: this is a set which is constrained to accept only integers in
|
||||
# a range 0 <= i <= maxval. Provides a minimal set of methods which can readily
|
||||
# be expanded.
|
||||
# SetByte: an even more minimal version of IntSet where the range is
|
||||
# 0 <= i <=255.
|
||||
# BoolList: A list of booleans. The list index is constrained to lie in range
|
||||
# 0 <= i <= maxval.
|
||||
|
||||
class BitMap:
|
||||
def __init__(self, maxval):
|
||||
d, m = divmod(maxval, 8)
|
||||
self._ba = bytearray(d + int(m > 0))
|
||||
self._size = maxval
|
||||
|
||||
def _check(self, i):
|
||||
if i < 0 or i >= self._size:
|
||||
raise ValueError('Index out of range')
|
||||
|
||||
def _val(self, i):
|
||||
self._check(i)
|
||||
return (self._ba[i >> 3] & 1 << (i & 7)) > 0
|
||||
|
||||
def _set(self, i):
|
||||
self._check(i)
|
||||
self._ba[i >> 3] |= 1 << (i & 7)
|
||||
|
||||
def _clear(self, i):
|
||||
self._check(i)
|
||||
self._ba[i >> 3] &= ~(1 << (i &7))
|
||||
|
||||
# Iterate through an IntSet returning members
|
||||
# Iterate through an IntList returning index value of True members
|
||||
def __iter__(self):
|
||||
for i in range(self._size):
|
||||
if self._val(i):
|
||||
yield i
|
||||
|
||||
# if MyIntSet: True unless set is empty
|
||||
# if MyBoolList: True if any element is True
|
||||
def __bool__(self):
|
||||
for x in self._ba:
|
||||
if x:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class IntSet(BitMap):
|
||||
def __init__(self, maxval=256):
|
||||
super().__init__(maxval)
|
||||
|
||||
# if n in MyIntSet:
|
||||
def __contains__(self, i):
|
||||
self._check(i)
|
||||
return self._val(i)
|
||||
|
||||
# MyIntSet.discard(n)
|
||||
def discard(self, i):
|
||||
self._clear(i)
|
||||
|
||||
# MyIntSet.remove(n)
|
||||
def remove(self, i):
|
||||
if i in self:
|
||||
self.discard(i)
|
||||
else:
|
||||
raise KeyError(i)
|
||||
|
||||
# MyIntSet.add(n)
|
||||
def add(self, i):
|
||||
self._set(i)
|
||||
|
||||
# Generator iterates through set intersection. Avoids allocation.
|
||||
def intersec(self, other):
|
||||
for i in other:
|
||||
if i in self:
|
||||
yield i
|
||||
|
||||
class BoolList(BitMap):
|
||||
def __init__(self, maxval=256):
|
||||
super().__init__(maxval)
|
||||
|
||||
# MyBoolList[n] = True
|
||||
def __setitem__(self, bit, val):
|
||||
self._set(bit) if val else self._clear(bit)
|
||||
|
||||
# if MyBoolList[n]:
|
||||
def __getitem__(self, bit):
|
||||
return self._val(bit)
|
||||
|
||||
# if False in MyBoolList:
|
||||
def __contains__(self, i):
|
||||
if i:
|
||||
for b in self._ba:
|
||||
if b:
|
||||
return True
|
||||
else:
|
||||
for b in self._ba:
|
||||
if not b:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Minimal implementation of set for 0-255
|
||||
class SetByte:
|
||||
def __init__(self):
|
||||
self._ba = bytearray(32)
|
||||
|
||||
def __bool__(self):
|
||||
for x in self._ba:
|
||||
if x:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __contains__(self, i):
|
||||
return (self._ba[i >> 3] & 1 << (i & 7)) > 0
|
||||
|
||||
def discard(self, i):
|
||||
self._ba[i >> 3] &= ~(1 << (i &7))
|
||||
|
||||
def add(self, i):
|
||||
self._ba[i >> 3] |= 1 << (i & 7)
|
||||
|
||||
# Test for set intersection
|
||||
bs = IntSet()
|
||||
bs.add(1)
|
||||
bs.add(2)
|
||||
1 in bs
|
||||
c = IntSet()
|
||||
c.add(1)
|
||||
c.add(4)
|
||||
c.add(5)
|
||||
g = bs.intersec(c)
|
||||
next(g)
|
||||
next(g)
|
||||
|
Ładowanie…
Reference in New Issue