<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def dynamics(start, end=None):
 """ Apply dynamics to a sequence. If end is specified, it will crescendo or diminuendo linearly from start to end dynamics. You can pass any of these strings as dynamic markers: ['pppppp', 'ppppp', 'pppp', 'ppp', 'pp', 'p', 'mp', 'mf', 'f', 'ff', 'fff', ''ffff] Args: start: beginning dynamic marker, if no end is specified all notes will get this marker end: ending dynamic marker, if unspecified the entire sequence will get the start dynamic marker Example usage: s1 | dynamics('p') # play a sequence in piano s2 | dynamics('p', 'ff') # crescendo from p to ff s3 | dynamics('ff', 'p') # diminuendo from ff to p """

    def _(sequence):
        if start in _dynamic_markers_to_velocity:
            start_velocity = _dynamic_markers_to_velocity[start]
            start_marker = start
        else:
            raise ValueError("Unknown start dynamic: %s, must be in %s" % (start, _dynamic_markers_to_velocity.keys()))

        if end is None:
            end_velocity = start_velocity
            end_marker = start_marker
        elif end in _dynamic_markers_to_velocity:
            end_velocity = _dynamic_markers_to_velocity[end]
            end_marker = end
        else:
            raise ValueError("Unknown end dynamic: %s, must be in %s" % (start, _dynamic_markers_to_velocity.keys()))

        retval = sequence.__class__([Point(point) for point in sequence._elements])

        velocity_interval = (float(end_velocity) - float(start_velocity)) / (len(retval) - 1) if len(retval) > 1 else 0
        velocities = [int(start_velocity + velocity_interval * pos) for pos in range(len(retval))]

        # insert dynamics markers for lilypond
        if start_velocity > end_velocity:
            retval[0]["dynamic"] = "diminuendo"
            retval[-1]["dynamic"] = end_marker
        elif start_velocity < end_velocity:
            retval[0]["dynamic"] = "crescendo"
            retval[-1]["dynamic"] = end_marker
        else:
            retval[0]["dynamic"] = start_marker

        for point, velocity in zip(retval, velocities):
            point["velocity"] = velocity

        return retval
    return _