Skip to content

duration

DurationPattern

Bases: _BasePattern

Musical duration pattern.

Implements the following operations:

- `__hash__`
- `__len__`
- `__getitem__`
- `__mul__` against `float`
- `__truediv__` against `float`
Note

All operations return a copy, DurationPatterns are immutable.

Source code in staff/patterns/duration.py
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
class DurationPattern(_BasePattern):
    """Musical duration pattern.

    Implements the following operations:

        - `__hash__`
        - `__len__`
        - `__getitem__`
        - `__mul__` against `float`
        - `__truediv__` against `float`

    Note:
        All operations return a copy, `DurationPattern`s are immutable.
    """

    def __init__(self, pattern: List[Duration]):
        """Initialises a DurationPattern

        Args:
            pattern: The initial pattern

        Raises:
            TypeError: If anything but a Duration is included in the initial list
        """
        for dur in pattern:
            if not isinstance(dur, Duration):
                raise TypeError("DurationPattern can only contain Duration objects")
        self._pat = pattern

    def append(self, value: Duration) -> DurationPattern:
        """Append a duration to the pattern

        Args:
            value: A duration to append

        Raises:
            TypeError: If anything but a Duration is passed in

        Returns:
            A new `DurationPattern` (they are immutable)
        """
        if not isinstance(value, Duration):
            raise TypeError("DurationPattern can only contain Duration objects")
        return DurationPattern([value] + self._pat)

    def prepend(self, value: Duration) -> DurationPattern:
        """Insert a duration value at the start of the pattern.

        Args:
            value: A duration to prepend

        Raises:
            TypeError: If anything but a Duration is passed in

        Returns:
            A new `DurationPattern` (they are immutable)
        """
        if not isinstance(value, Duration):
            raise TypeError("DurationPattern can only contain Duration objects")
        return DurationPattern(self._pat + [value])

    def milliseconds(self, tempo: Tempo) -> float:
        """Total millisecond duration of the pattern.

        Args:
            tempo: The tempo used to measure time

        Returns:
            Total milliseconds
        """
        return sum((dur.milliseconds(tempo) for dur in self._pat))

    def retrograde(self) -> DurationPattern:
        """The pattern's retrograde.

        Returns:
            The pattern's retrograde as a new `DurationPattern` (they are immutable)
        """
        return DurationPattern(pattern=self._pat[::-1])

    def rotate(self, factor: int) -> DurationPattern:
        """Rotates the pattern.

        Args:
            factor: The rotation factor (how many durations to rotate). Can be
                negative to rotate left.

        Raises:
            TypeError: If anything but an `int` is passed for factor

        Returns:
            A new and rotated `DurationPattern` (they are immutable)
        """
        if not isinstance(factor, int):
            raise TypeError("can only rotate by an 'int' factor")
        return DurationPattern(pattern=self._pat[factor:] + self._pat[:factor])

    def prolate(self, factor: Union[int, float]) -> DurationPattern:
        """Stretches or contracts the pattern.

        Args;
            factor: Augment with factor > 1, diminish with 0 < factor < 1

        Returns:
            The prolated pattern (as a copy)
        """
        return self * factor

    def permutations(self) -> List[DurationPattern]:
        return [DurationPattern(list(pat)) for pat in it.permutations(self._pat)]

    def __repr__(self):
        _repr = f"{self.__class__.__name__}(["
        for dur in self._pat:
            _repr += str(dur.denominator)
            _repr += "." * dur.dots
            _repr += "r" if dur.is_rest else ""
            _repr += ", "
        return _repr[:-2] + "])"

    def __mul__(self, other: float) -> DurationPattern:
        return DurationPattern([dur * other for dur in self._pat])

    def __truediv__(self, other: float) -> DurationPattern:
        return DurationPattern([dur / other for dur in self._pat])

__init__(pattern)

Initialises a DurationPattern

Parameters:

Name Type Description Default
pattern List[Duration]

The initial pattern

required

Raises:

Type Description
TypeError

If anything but a Duration is included in the initial list

Source code in staff/patterns/duration.py
27
28
29
30
31
32
33
34
35
36
37
38
39
def __init__(self, pattern: List[Duration]):
    """Initialises a DurationPattern

    Args:
        pattern: The initial pattern

    Raises:
        TypeError: If anything but a Duration is included in the initial list
    """
    for dur in pattern:
        if not isinstance(dur, Duration):
            raise TypeError("DurationPattern can only contain Duration objects")
    self._pat = pattern

append(value)

Append a duration to the pattern

Parameters:

Name Type Description Default
value Duration

A duration to append

required

Raises:

Type Description
TypeError

If anything but a Duration is passed in

Returns:

Type Description
DurationPattern

A new DurationPattern (they are immutable)

Source code in staff/patterns/duration.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def append(self, value: Duration) -> DurationPattern:
    """Append a duration to the pattern

    Args:
        value: A duration to append

    Raises:
        TypeError: If anything but a Duration is passed in

    Returns:
        A new `DurationPattern` (they are immutable)
    """
    if not isinstance(value, Duration):
        raise TypeError("DurationPattern can only contain Duration objects")
    return DurationPattern([value] + self._pat)

milliseconds(tempo)

Total millisecond duration of the pattern.

Parameters:

Name Type Description Default
tempo Tempo

The tempo used to measure time

required

Returns:

Type Description
float

Total milliseconds

Source code in staff/patterns/duration.py
73
74
75
76
77
78
79
80
81
82
def milliseconds(self, tempo: Tempo) -> float:
    """Total millisecond duration of the pattern.

    Args:
        tempo: The tempo used to measure time

    Returns:
        Total milliseconds
    """
    return sum((dur.milliseconds(tempo) for dur in self._pat))

prepend(value)

Insert a duration value at the start of the pattern.

Parameters:

Name Type Description Default
value Duration

A duration to prepend

required

Raises:

Type Description
TypeError

If anything but a Duration is passed in

Returns:

Type Description
DurationPattern

A new DurationPattern (they are immutable)

Source code in staff/patterns/duration.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def prepend(self, value: Duration) -> DurationPattern:
    """Insert a duration value at the start of the pattern.

    Args:
        value: A duration to prepend

    Raises:
        TypeError: If anything but a Duration is passed in

    Returns:
        A new `DurationPattern` (they are immutable)
    """
    if not isinstance(value, Duration):
        raise TypeError("DurationPattern can only contain Duration objects")
    return DurationPattern(self._pat + [value])

prolate(factor)

Stretches or contracts the pattern.

Args; factor: Augment with factor > 1, diminish with 0 < factor < 1

Returns:

Type Description
DurationPattern

The prolated pattern (as a copy)

Source code in staff/patterns/duration.py
109
110
111
112
113
114
115
116
117
118
def prolate(self, factor: Union[int, float]) -> DurationPattern:
    """Stretches or contracts the pattern.

    Args;
        factor: Augment with factor > 1, diminish with 0 < factor < 1

    Returns:
        The prolated pattern (as a copy)
    """
    return self * factor

retrograde()

The pattern's retrograde.

Returns:

Type Description
DurationPattern

The pattern's retrograde as a new DurationPattern (they are immutable)

Source code in staff/patterns/duration.py
84
85
86
87
88
89
90
def retrograde(self) -> DurationPattern:
    """The pattern's retrograde.

    Returns:
        The pattern's retrograde as a new `DurationPattern` (they are immutable)
    """
    return DurationPattern(pattern=self._pat[::-1])

rotate(factor)

Rotates the pattern.

Parameters:

Name Type Description Default
factor int

The rotation factor (how many durations to rotate). Can be negative to rotate left.

required

Raises:

Type Description
TypeError

If anything but an int is passed for factor

Returns:

Type Description
DurationPattern

A new and rotated DurationPattern (they are immutable)

Source code in staff/patterns/duration.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def rotate(self, factor: int) -> DurationPattern:
    """Rotates the pattern.

    Args:
        factor: The rotation factor (how many durations to rotate). Can be
            negative to rotate left.

    Raises:
        TypeError: If anything but an `int` is passed for factor

    Returns:
        A new and rotated `DurationPattern` (they are immutable)
    """
    if not isinstance(factor, int):
        raise TypeError("can only rotate by an 'int' factor")
    return DurationPattern(pattern=self._pat[factor:] + self._pat[:factor])