From 97f7d58dd71a2aa602f5f038d42d4633407c064e Mon Sep 17 00:00:00 2001 From: S Groesz Date: Sun, 22 Nov 2020 06:30:47 +0000 Subject: [PATCH] Improve doc; add Bit.set and unset methods --- src/bits.py | 254 +++++++++++++++++++++++++++++++++++++++------- tests/test_bit.py | 18 ++++ 2 files changed, 237 insertions(+), 35 deletions(-) diff --git a/src/bits.py b/src/bits.py index 8dd0312..80fd780 100644 --- a/src/bits.py +++ b/src/bits.py @@ -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: """ - 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 - 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) + + />/>/> + + 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) + + />/>/> + + .. 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) + + />/>/> + + .. 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): """ var: Any supported type Supported types: (bool, int, str, Bit) bool: True or False - int: 0 = False, anything else = True - str: "0" = False, anything else = True + int: 0 = False, 1 = True + str: "0" = False, "1" = True Bit: Bit = Bit """ if not isinstance(var, (bool, int, str, Bit)): @@ -45,25 +230,22 @@ class Bit: self.__bit = var def __str__(self): - """ - Return "0" or "1" - """ + """Return '0' or '1'""" return str(int(self.__bit)) def __int__(self): + """Return 0 or 1""" return int(self.__bit) def __bool__(self): + """Returns True or False""" return self.__bit def __repr__(self): return f'{self.__class__.__name__}({int(self.__bit)})' def __eq__(self, compare): - """ - compare (self) to any supported object - """ - # Massage compare to bool + """compare (self) to any supported object""" return bool(self) == bool(Bit(compare)) def __ne__(self, compare): @@ -85,22 +267,24 @@ class Bit: return self.__bit def __hash__(self): - """ - Not very useful, but provided nonetheless - """ + """Not very useful, but provided nonetheless""" return hash(self.__bit) def toggle(self): - """ - (self) = Not (Self) - """ + """Change the state of (self) to Not (self)""" 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 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 diff --git a/tests/test_bit.py b/tests/test_bit.py index 9bee233..39ac409 100644 --- a/tests/test_bit.py +++ b/tests/test_bit.py @@ -64,6 +64,24 @@ class TestBit(TestCase): var.toggle() 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): """ Test that errors are raised for invalid values