Changes

A change is a means for getting from one row to another. It works by swapping over pairs of bells, and no bell may move more than one place.

The normal way of representing a change is by place notation; a single change is represented by a series of numbers which each correspond to a place being made; for example, 12 means that all bells swap, apart from the 1 and the 2, which stay in the same place. If all the bells swap, the place notation is X.

The Change Class

class ringing.Change([spec[, change]])

Constructs a Change.

Parameters:
  • spec (Change or int or string) –

    Specification for constructing the change. This might be:

    • Nothing. Constructs a change on zero bells.

    • Another change. Constructs a copy.

    • An integer number of bells. See the change parameter.

  • change

    Change to read. This might be:

    • Nothing. Constructs a change where all bells lie still (no swaps).

    • A string (unicode or bytes) representation of a change.

__lt__(change)
__le__(change)
__eq__(change)
__ne__(change)
__gt__(change)
__ge__(change)

Compare a change to another.

Parameters:

change (Change or string) – value to compare; strings are parsed as changes on the same number of bells

Returns:

result

Return type:

boolean

__mul__(bell)

Returns the effect of applying the change to the bell b. For example, 3 * Change(4, '34') == 3. This is useful in tracing the path of one particular bell through a series of changes.

Parameters:

bell (Bell or string or int) – bell to apply

Returns:

result

Return type:

int

Raises:

ValueError if bell is out of range

set(num, pn)

Sets the change to a new value.

Parameters:
  • num (int) – number of bells

  • pn (string) – place notation

Returns:

None

reverse()

Returns the reverse of a change; that is, the change is flipped over so that on 8 bells for example, 2nds place becomes 7ths place and so on.

Returns:

result

Return type:

Change

bells

Number of bells on which the change is defined.

sign()

Returns the sign of the change.

Returns:

-1 if an odd number of pairs are swapped, +1 if an even number of pairs are swapped

Return type:

int

find_swap(b)

Determines whether a position is swapped by the change.

Parameters:

b (Bell or string or int) – position to check

Returns:

True if the change swaps positions b and b+1, and False otherwise

Return type:

boolean

Raises:

IndexError if b is out of range

find_place(b)

Determines whether a place is made.

Parameters:

b (Bell or string or int) – position to check

Returns:

True if the change doesn’t move the bell in the bth place (i.e. if bths place is made), and False otherwise

Return type:

boolean

Raises:

IndexError if b is out of range

swap_pair(b)

If the change doesn’t currently swap positions b and b+1, then this will add that swap. If those positions are swapped, this will remove the swap. If the positions b-1 and b, or b+1 and b+2, are currently swapped, those swaps are removed.

This function makes it possible for the user to edit changes in such a way that they will always end up in a sensible state.

Parameters:

b (Bell or string or int) – position to check

Returns:

True if after the function call, the pair of positions b and b+1 are swapped, and False otherwise

Return type:

boolean

Raises:

IndexError if b is out of range

internal()

Checks whether the change contains internal places.

Returns:

True if the change contains internal places, and False otherwise

Return type:

boolean

count_places()

Returns the number of places made in the change

Returns:

number of places made

Return type:

int

Blocks of Rows

The RowBlock class is an array of rows which has associated with it a reference to an array of changes, and can recalculate itself from those changes. For example, suppose that the variable c, a list of changes, holds one lead of a method; then it is possible to define a variable of type RowBlock which, once it is told what the lead head is, will calculate the rows for one lead of the method.

class ringing.RowBlock(changes[, starting_row])

Creates a block of rows using the changes in changes, starting from the row given in starting_row (or rounds if starting_row is not provided).

Row blocks support several standard sequence operations:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> rb[0]
Row('12345')
>>> for r in rb:
...     print(r)
...
12345
21354
23145
32415

Operation

Result

r in rb

True if an item of rb is equal to r, else False

r not in rb

False if an item of rb is equal to r, else True

rb[i]

ith row of rb, origin 0

rb[i] = Row('12345')

sets ith row of rb

len(rb)

length (size) of rb

list(rb)

list of rows in rb

Parameters:
  • changes ([Change] or Method) – changes to associate with the block

  • starting_row (Row) – optional starting row

size

Number of rows which the row block contains:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> rb.size
4
changes

List of changes associated with the row block:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> rb.changes
[Change(5, '3'), Change(5, '1'), Change(5, '5')]

It’s also possible to assign a new set of changes:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> list(rb)
[Row('12345'), Row('21354'), Row('23145'), Row('32415')]
>>> rb.changes = [Change(5, pn) for pn in ['5', '3']]
>>> list(rb)
[Row('12345'), Row('21435'), Row('12453')]
set_start(starting_row)

Assigns a new row for the start of the row block. Other rows remain unmodified; call recalculate() to update them:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> list(rb)
[Row('12345'), Row('21354'), Row('23145'), Row('32415')]
>>> rb.set_start('54321')
>>> list(rb)
[Row('54321'), Row('21354'), Row('23145'), Row('32415')]
>>> rb.recalculate()
>>> list(rb)
[Row('54321'), Row('45312'), Row('43521'), Row('34251')]
Parameters:

starting_row (Row or int or string) – new starting row

Returns:

None

recalculate([start])

Recalculates the rows within the row block:

>>> from ringing import RowBlock, Change
>>> rb = RowBlock([Change(5, '3'), Change(5, '1'), Change(5, '5')])
>>> list(rb)
[Row('12345'), Row('21354'), Row('23145'), Row('32415')]
>>> rb[2] = '54321'
>>> list(rb)
[Row('12345'), Row('21354'), Row('54321'), Row('32415')]
>>> rb.recalculate(2)
>>> list(rb)
[Row('12345'), Row('21354'), Row('54321'), Row('45231')]
Parameters:

start (int) – if supplied, only rows after this index will be recalculated

Returns:

None

Raises:

IndexError if start is out of range