Code / Reference

Block

A Block is an immutable orthogonal clump (a line segment, rectangle, cuboid etc.) of discrete space defined by any opposite end/corner points A/B.

a: tuple property

Point A

b: tuple property

Point B

dimensions: int property

Property for the number of dimensions of the block

Returns:
  • int( int ) –

    number of dimensions

is_a_unit: bool property

Property set upon creation to flag if the block is a single unit

Returns:
  • bool( bool ) –

    True if the block a single unit in any dimension

is_finite: bool property

Does the block have any open bounds? If so then the block is considered infinite

Returns:
  • bool( bool ) –

    Returns True if the block is finite.

manhattan: int property

Property providing the manhattan distance from A -> B

Returns:
  • int( int ) –

    The sum of the sides

measure: int property

Property providing the length, area, volume (depending on the dimension)

Returns:
  • int( int ) –

    The measure (i.e. length, area, volume)

norm: tuple property

Return the block in its normalised form (A,B)

Returns:
  • tuple( tuple ) –

    (A,B)

side_lengths: tuple property

Property providing the side lengths

Returns:
  • tuple( tuple ) –

    The side lengths of each dimension

__init__(a, b=None)

A block is constructed by supplying the coordinates of the opposite ends/corners A,B

A,B are tuples in the desired dimensions consisting of integers (or inf).

If using just 1 dimension then the wrapping tuple may be omitted. For example Block(3,6) represents the 1D units {3, 4, 5}

If wishing to express an open interval then make use of math.inf (or -math.inf) which is equivalent to float("inf").

If the opposite corner B is not supplied, then we use the ordinates from A in each corresponding dimension and either

  • add +1 if it's an integer, or
  • assume the opposite end (i.e. the multiplicative inverse) if infinity.

So if all ordinates in A are int then we creating a unit block.

Raises:
  • DimensionMismatchError

    If A and B are in different dimensions

  • ValueParsingError

    When supplied arguments to the constructor do not meet expectation, that being integer or float("inf") or a tuple of those.

  • ZeroSpaceError

    If A and B have same value in any given dimensions

parse(input) classmethod

By default the input is sent directly to the Block constructor. The exception being if the input is a sequence, then either it must be a list of arguments or a unit in some dimension.

We assume it's a list of arguments by default, unless

  • the len > 2 in which case it must be a single unit in some dimension
  • or, len == 1 and this only item is also a sequence we will take it to mean a unit
Parameters:
  • input

    Anything

Returns:
  • Block( Self ) –

    The input parsed to a Block object

parse_to_dimension(dimensions, input) classmethod

Same as parse, but with extra validation on the dimension

Parameters:
  • dimensions (int) –

    The expected dimension of the resulting block

  • input (any) –

    Anything

Raises:
  • DimensionMismatchError

    If the input does not match the required dimension

Returns:
  • Self( Self ) –

    Block

in_contact_with(other)

Return True if this block touches the other in any way (vertex, edge, face etc.) or overlaps it.

Shorthand: A @ B

Parameters:
  • other (Block) –

    Another Block instance for comparison

Returns:
  • bool( bool ) –

    True if this block touches the other in any way (vertex, edge, face etc.) or overlaps it

BlockSet

A set of Blocks which are of the same dimension.

Although the class offers methods and behaviour similar to that of a set, the actual construction of the set using Blocks happens via an operation stack which gets resolved during a normalisation process.

In normalized form all the resulting blocks are disjoint and are kept on the operation stack as add operations

The normalisation process resolves overlapping and redundancy such that any 2 sets of equal content (i.e. the same set of pixels) will have the same representation in terms of the blocks used to represent the space.

Methods and operators mirror those of the native set class - Modify the content (add, remove, toggle) - Compare (equality, subset, superset) - Compare operations (intersection, union, difference)

There is some extra validation on some methods to ensure the supplied arguments are, or can be interpreted as a Block/BlockSet and match the dimension of the current content.

Normalisation is required and important (for accurate comparisons) but also costly. We only want to perform it when its absolutely necessary and so clients are advised to group together modification calls as much as possible in order to minimise the amount of normalising required and especially so if performance is of a significant concern.

Some methods/properties will perform normalisation automatically if required.

Once constructed, Block objects can be appended to the operation stack via the add, remove and toggle methods.

dimensions: int property

Returns number of dimensions of the blockset

Returns:
  • int( int ) –

    The dimension of the contained blocks

is_empty: bool property

Returns True if empty

Returns:
  • bool( bool ) –

    True if empty

is_finite: bool property

Returns True if all blocks are finite

Returns:
  • bool( bool ) –

    True if finite

is_normalised: bool property

Return the normalisation state

Returns:
  • bool( bool ) –

    True if the BlockSet is in a Normalised state

measure: int property

Returns the total amount of space the block set is taking up. This is effectively the sum of all the disjoint block measures after normalisation.

Returns:
  • int( int ) –

    unit count = sum of disjoint block measures

block_count: int property

Returns the number of block operations on the stack. After normalisation this is simply the number of blocks

Returns:
  • int( int ) –

    block count

NOTE: This property is deprecated in favour of len() after a normalise() and will not be available as of the first major release.

unit_count: int property

Returns the total amount of space the block set is taking up. This is effectively the sum of all the disjoint block measures after normalisation.

Returns:
  • int( int ) –

    point count

NOTE: This property is deprecated in favour of measure and will not be available as of the first major release.

__init__(dimensions=None)

Create a Blockset, optionally provide the dimensions for more strict and performant use

Parameters:
  • dimensions (int | None, default: None ) –

    Specify the dimensions if you like. Defaults to None.

Raises:
  • InvalidDimensionsError

    If not an integer or < 1

units()

Generator for the unit tuples within all the blocks

Raises:
  • NotFiniteError

    If any of the blocks are infinite

Yields:
  • tuple

    A unit pixel

add(block)

Append an add block operation to the stack

Parameters:
  • block (Block) –

    A block

clear()

Clear the operation stack

remove(block)

Append a remove block operation to the stack

Parameters:
  • block (Block) –

    A block

toggle(block)

Append a toggle block operation to the stack

Parameters:
  • block (Block) –

    A block

normalise()

Normalise the BlockSet

This will analyse all the operations stack and resolve it to a disjoint set of add operations removing redundancy.

difference(other)

Return a new block set representing the difference self - other

Parameters:
  • other (BlockSet) –

    The BlockSet being removed

Raises:
  • ExpectedBlockSetError

    If not given a BlockSet for other

Returns:
  • BlockSet( Self ) –

    self - other

intersection(other)

Return a new block set representing the intersection with the other self & other.

Parameters:
  • other (BlockSet) –

    The BlockSet to intersect with

Returns:
  • BlockSet( Self ) –

    self ∩ other

symmetric_difference(other)

Return a new block set representing the symmetric difference (xor) with the other self ^ other

Parameters:
  • other (BlockSet) –

    The BlockSet being XOR'd

Raises:
  • ExpectedBlockSetError

    If not given a BlockSet for other

Returns:
  • BlockSet( Self ) –

    self ⊕ other

union(other)

Return a new block set representing a union with another self | other

Parameters:
  • other (BlockSet) –

    The BlockSet to union with

Raises:
  • ExpectedBlockSetError

    If not given a BlockSet for other

Returns:
  • BlockSet( Self ) –

    self ∪ other

difference_update(other)

Remove space from self that is in the other.

Parameters:
  • other (BlockSet) –

    The BlockSet being removed

Raises:
  • ExpectedBlockSetError

    If not given a BlockSet for other

Returns:
  • BlockSet( Self ) –

    self

intersection_update(other)

Remove space from self that is not in the other

Parameters:
  • other (BlockSet) –

    The intersecting BlockSet

Returns:
  • BlockSet( Self ) –

    self

symmetric_difference_update(other)

Adds the symmetric differences between self and other

Parameters:
  • other (BlockSet) –

    The differing BlockSet

Raises:
  • ExpectedBlockSetError

    If not given a BlockSet for other

Returns:
  • BlockSet( Self ) –

    self

update(other)

Update this block set with another, effectively applying the union to self

Parameters:
  • other (BlockSet) –

    The BlockSet being added

Returns:
  • BlockSet( Self ) –

    self

isdisjoint(other)

Returns True if the block sets are completely disjoint from each other

Parameters:
Returns:
  • bool( bool ) –

    True if there is no overlapping space

issubset(other)

Returns True if self is a subset of other self <= other

Parameters:
Returns:
  • bool( bool ) –

    True if self is a subset of other

issuperset(other)

Returns True if self is a superset of other self >= other

Parameters:
Returns:
  • bool( bool ) –

    True if self is a superset of other

apply_json_obj(json_obj)

Applies layers from a json object

We expect the json representation to be a list of pairs [operation, block]. Where operation is either +,-,~ and the block is a tuple pair [A,B] where A/B are the coordinates of the opposite corners.

The BlockSetEncoder class can be used to create the json from the blockset

json_str = json.dumps(blockset_object, cls=BlockSetEncoder)

Parameters:
  • json_obj

    Expecting a list of (operation, block) tuples