Improve doc; add Bit.set and unset methods

This commit is contained in:
S Groesz 2020-11-22 06:30:47 +00:00
parent 1226400c2d
commit 97f7d58dd7
2 changed files with 237 additions and 35 deletions

View File

@ -1,33 +1,218 @@
# -*- coding: utf-8 -*-
"""
============================
Binary manipulation classes
============================
Provides classes that assist in managing, comparing, transforming and working
with binary data in general.
-----------------
Provided Classes
-----------------
Bit
===
The Bit is the smallest representation of binary data and represents True or
False. This class provides methods to perform binary comparisons and
conversions between different types that can be used to represent a single
binary value.
Byte
====
A Byte is the representation of 8 Bits. The Byte class provides methods to
compare a single binary Byte to other data types. The Class also provides
binary math functions and allows getting and setting the state of individual
Bits.
Bytes
=====
The Bytes class allows an arbitrary amount of binary data to be represented.
The Bytes class provides access to each byte using the Byte class, which
further allows all the methods to be used on the binary data provided by the
Byte and Bit classes. Bytes can be compared and converted between several
different data types.
"""
class Bit: class Bit:
""" """
Provide a flexible bit representation. ====
Extended description of function.
Parameters
----------
var : bool | int | str | Bit
Any of the supported objects which can be converted to a Bit object.
bool: True or False
int: 0 = False, anything else = True
str: "0" = False, anything else = True
BIT: Bit = Bit
Returns
-------
Bit Bit
A binary representation of True or False with additional useful ====
features.
A single binary bit representation of True or False
A Bit object can be compared and converted to int, str, bool and other Bit
objects. The Bit class is backed by a single bool variable. This backing
bool object is converted as necessary to provide conversions and
comparisons with other data types. Keep this in mind as converting an
object to Bit and then attempting to convert back to the original object
may not yield the exact same value.
In the case of comparisons, the object being compared is cast as a Bit
object, and the two Bit objects are then compared with each other and the
result of the comparison is returned.
----------------
Type Conversion
----------------
The objects that can be converted to and from a Bit include *bool*, *int*,
*str* and other *Bit* objects.
Convert *bool* to *Bit*:
.. code-block:: python
/>/>/> a_bit = Bit(True)
/>/>/> a_bit
Bit(1)
/>/>/>
Convert *Bit* to *bool*:
.. code-block:: python
/>/>/> a_bool = bool(Bit(True))
/>/>/> a_bool
True
/>/>/> type(a_bool)
<class 'bool'>
/>/>/>
Convert *int* to *Bit*:
.. code-block:: python
/>/>/> unset_bit = Bit(0)
/>/>/> unset_bit
Bit(0)
/>/>/> set_bit = Bit(1)
/>/>/> set_bit
Bit(1)
/>/>/>
Convert *Bit* to *int*:
.. code-block:: python
/>/>/> my_int = int(Bit(1))
/>/>/> my_int
1
/>/>/> type(my_int)
<class 'int'>
/>/>/>
.. note:: The only values allowed for *int* are **0** and **1**
Convert *str* to *Bit*:
.. code-block:: python
/>/>/> unset_bit = Bit("0")
/>/>/> unset_bit
Bit(0)
/>/>/> set_bit = Bit("1")
/>/>/> set_bit
Bit(1)
/>/>/>
Convert *Bit* to *str*:
.. code-block: python
/>/>/> my_str = str(Bit(False))
/>/>/> my_str
'0'
/>/>/> type(my_str)
<class 'str'>
/>/>/>
.. note:: The only *str* characters allowed are a single **0** or **1**
------------
Comparisons
------------
A Bit object can be compared to any object which can be cast to a Bit
.. code-block: python
/>/>/> 0 == Bit(False) == Bit("0") == Bit(0) == False
True
/>/>/>
.. note:: Comparing an object with a value that cannot be cast to Bit will
return a ValueError.
-----------------
Rich Comparisons
-----------------
Bit objects also support "rich comparisons". For example:
.. code-block: python
/>/>/> Bit(False) < 1
True
/>/>/> Bit(True) <= 1
True
/>/>/> Bit(False) <= "1"
True
/>/>/> Bit(False) != True
True
/>/>/> Bit(True) >= False
False
/>/>/>
--------
Methods
--------
The action method `toggle` is provided for convenience.
.. code-block: python
/>/>/> Bit(False).toggle()
Bit(1)
/>/>/> Bit(True).toggle() == False
True
/>/>/> int(Bit(False).toggle())
1
/>/>/>
The `set` and `unset` methods are also provided to explicitely set the
value of Bit.
.. code-block: python
/>/>/> a_bit = Bit(0)
/>/>/> a_bit
Bit(0)
/>/>/> a_bit.set()
/>/>/> a_bit
Bit(1)
/>/>/> a_bit.unset()
/>/>/> a_bit
Bit(0)
/>/>/>
-----------
Properties
-----------
The `lie` property returns the opposite value of Bit as a *bool*. Unlike
the `toggle` method, `lie` does not change the value of the Bit.
.. code-block: python
/>/>/> Bit(1).lie
False
/>/>/>
""" """
def __init__(self, var): def __init__(self, var):
""" """
var: Any supported type var: Any supported type
Supported types: (bool, int, str, Bit) Supported types: (bool, int, str, Bit)
bool: True or False bool: True or False
int: 0 = False, anything else = True int: 0 = False, 1 = True
str: "0" = False, anything else = True str: "0" = False, "1" = True
Bit: Bit = Bit Bit: Bit = Bit
""" """
if not isinstance(var, (bool, int, str, Bit)): if not isinstance(var, (bool, int, str, Bit)):
@ -45,25 +230,22 @@ class Bit:
self.__bit = var self.__bit = var
def __str__(self): def __str__(self):
""" """Return '0' or '1'"""
Return "0" or "1"
"""
return str(int(self.__bit)) return str(int(self.__bit))
def __int__(self): def __int__(self):
"""Return 0 or 1"""
return int(self.__bit) return int(self.__bit)
def __bool__(self): def __bool__(self):
"""Returns True or False"""
return self.__bit return self.__bit
def __repr__(self): def __repr__(self):
return f'{self.__class__.__name__}({int(self.__bit)})' return f'{self.__class__.__name__}({int(self.__bit)})'
def __eq__(self, compare): def __eq__(self, compare):
""" """compare (self) to any supported object"""
compare (self) to any supported object
"""
# Massage compare to bool
return bool(self) == bool(Bit(compare)) return bool(self) == bool(Bit(compare))
def __ne__(self, compare): def __ne__(self, compare):
@ -85,22 +267,24 @@ class Bit:
return self.__bit return self.__bit
def __hash__(self): def __hash__(self):
""" """Not very useful, but provided nonetheless"""
Not very useful, but provided nonetheless
"""
return hash(self.__bit) return hash(self.__bit)
def toggle(self): def toggle(self):
""" """Change the state of (self) to Not (self)"""
(self) = Not (Self)
"""
self.__bit = not self.__bit self.__bit = not self.__bit
def set(self):
"""Set Bit to True"""
self.__bit = True
def unset(self):
"""Set Bit to False"""
self.__bit = False
@property @property
def lie(self): def lie(self):
""" """Return the opposite of bit, without changing the state of (self)"""
Return the opposite of bit, without changing the state of (self)
"""
return not self.__bit return not self.__bit

View File

@ -64,6 +64,24 @@ class TestBit(TestCase):
var.toggle() var.toggle()
self.assertTrue(var, "Bit(False).toggle() == True") self.assertTrue(var, "Bit(False).toggle() == True")
def test_set(self):
"""Test the set() method"""
var = Bit(False)
var.set()
self.assertTrue(var, "Bit(False).set() == True")
var = Bit(True)
var.set()
self.assertTrue(var, "Bit(True).set() == True")
def test_unset(self):
"""Test the unset() method"""
var = Bit(True)
var.unset()
self.assertFalse(var, "Bit(True).unset() == False")
var = Bit(False)
var.unset()
self.assertFalse(var, "Bit(False).unset() == False")
def test_errors(self): def test_errors(self):
""" """
Test that errors are raised for invalid values Test that errors are raised for invalid values