I became curious if it's possible to implement such kind of triangle oscillator without conditions and enumerations. Well, one option is the following:
def oscillator(magnitude):
i = 0
x = y = -1
double_magnitude = magnitude + magnitude
while True:
yield i
x = (x + 1) * (1 - (x // (double_magnitude - 1))) # instead of (x + 1) % double_magnitude
y = (y + 1) * (1 - (y // (magnitude - 1))) # instead of (y + 1) % magnitude
difference = x - y # difference ∈ {0, magnitude}
derivative = (-1 * (difference > 0) + 1 * (difference == 0))
i += derivative
The idea behind this is to take 2 sawtooth waves with different periods and subtract one from another. The result will be a square wave with values in {0, magnitude}. Then we just substitute {0, magnitude} with {-1, +1} respectively to get derivative values for our target signal.
Let's look at example with magnitude = 5
:
o = oscillator(5)
[next(o) for _ in range(21)]
This outputs [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
.
If abs()
is allowed, it can be used for simplicity. For example, the following code gives the same output as above:
[abs(5 - ((x + 5) % 10)) for x in range(21)]
TypeError: unsupported operand type(s) for +: 'range' and 'range'
. This will only work in Python 2 – Motilerange(100, 0, -1)
does not actually producerange(0, 100, 1)
in reverse. If you meant to go from0
through to99
included, then from99
back to0
, userange(99, -1, -1)
.range(100)
is the shorter form forrange(0, 100, 1)
, it is good practice to use that instead. And there is norange(0, infinity)
syntax, you'd usefor i in itertools.count():
perhaps to create an infinite counter, orwhile True:
to create an endless loop. – Malversation