Miscellaneous

Logging Integration

The fixedpoint package uses standard logging constructs to generate warnings and debug logs. The following specifications allow you to customize the logging schemes, handlers, formats, etc. to your liking.

Warnings

fixedpoint warnings are generated using the logging package.

fixedpoint.logging.WARNER_CONSOLE_HANDLER
Type

logging.StreamHandler

Value
  • stream is set to sys.stderr

  • level is set to logging.DEBUG.

fixedpoint.logging.WARNER
Type

logging.Logger

Value
  • name is FP.CONSOLE

  • level defaults to logging.WARNING

You can retrieve this logger with logging.getLogger("FP.CONSOLE").

The WARNER_CONSOLE_HANDLER is added to WARNER.

Additionally, each FixedPoint object has a unique serial number associated with it that is available in the LogRecord instance as the key sn. This is described in more detail here as the extra keyword.

Debug Logging

Logging is also used for debug purposes.

fixedpoint.logging.LOGGER
Type

logging.Logger

Value
  • name is FP

  • level defaults to logging.CRITICAL

fixedpoint.logging.DEFAULT_FILE_HANDLER
Type

logging.FileHandler

Value
  • filename is set to fixedpoint.log located in the same directory as the source code

  • mode is set to ‘w’

  • delay is set to True, thus no file is generated (or overwritten) until logging is enabled with fixedpoint.FixedPoint.enable_logging()

  • level defaults to logging.DEBUG

The DEFAULT_FILE_HANDLER is added to the LOGGER.

On initial import, LOGGER’s level is set to logging.CRITICAL. Since no critical level logs are made within fixedpoint, it essentially disables debug logging.

When FixedPoint.enable_logging() is called, LOGGER’s level is set to logging.DEBUG.

When FixedPoint.disable_logging() is called, LOGGER’s level is set back to logging.CRITICAL.

Typing

The fixedpoint package is typed (see PEP 484) and supported by mypy, PyCharm, etc.

Subclassing FixedPoint is also supported.

Numpy Integration

While not specifically tested, integration with numpy should be possible as long as unsupported operators (like @, /, //, %, etc.) are not used.

Examples taken from the numpy.convolve documentation:

>>> import numpy as np
>>> a = [FixedPoint(1), FixedPoint(2), FixedPoint(3)]
>>> b = [FixedPoint(0), FixedPoint(1), FixedPoint(0.5)]
>>> x = np.convolve(a, b)
>>> [float(fp) for fp in x]
[0.0, 1.0, 2.5, 4.0, 1.5]

>>> y = np.convolve(a, b, 'same')
>>> [float(fp) for fp in y]
[1.0, 2.5, 4.0]

>>> z = np.convolve(a, b, 'valid')
>>> [float(fp) for fp in z]
[2.5]

Serialization

JSON

class fixedpoint.json.JSONEncoder
class fixedpoint.json.JSONDecoder
>>> from fixedpoint.json import FixedPointEncoder, FixedPointDecoder
>>> import random, json
>>> L = 52
>>> signed = random.randrange(2)
>>> m = random.randrange(L)
>>> n = L - m
>>> original = FixedPoint(hex(random.getrandbits(L)), signed, m, n)
>>> serialized = json.dumps(original, cls=FixedPointEncoder)
>>> deserialized = json.loads(serialized, cls=FixedPointDecoder)
>>> original == deserialized
True

Pickle

The pickle scheme works out of the box:

>>> import random, pickle
>>> L = 52
>>> signed = random.randrange(2)
>>> m = random.randrange(signed, L)
>>> n = L - m
>>> original = FixedPoint(hex(random.getrandbits(L)), signed, m, n)
>>> pickled = pickle.dumps(original)
>>> unpickled = pickle.loads(pickled)
>>> original == unpickled
True