study 04 of 10
Variables and memory
A variable holds a number. What sets OType's variables apart is how long they keep it: for one run, from one press to the next, or for the life of a live script. This study builds a rhythm that turns a little further on each press, and a function that alternates between two patterns.
Giving a variable a value
A line that starts with a variable gives it a value; anywhere else, the variable is read.
def count_up
menu "LEARN" >> "COUNT UP"
a 5
a add a 1 # read a, add 1, store the result back in a
b mul a 2
msg "A" a "B" bOutput · what the simulator prints for $ otype.py run count_up
count_up seed 1 (--seed) pattern A01 len 16 (default) track 1
(no track holds anything)
X trig ! one-shot o trigless trig - trigless lock l locks only . none
part: tempo 120
msg: "A 6 B 12"
end box: "A 6 B 12" (the last msg, instead of DONE)
cost: 6/6 random draws: rand 0 toss 0 prob 0 drunk 0 file 0There is nothing to declare for the one-letter variables: they are always there, and start at 0.
Four kinds of letters
| names | kind | keeps its value |
|---|---|---|
a b c d | local | for one run of one function. Every call has its own: a function you call cannot change yours. 0 at the start of each run. |
x y z t | global | from one press to the next, shared by every function in every file. 0 when the machine starts. |
i j | counters | set by the loops (i the inner loop, j the one around it); read-only |
Use a b c d for working values, and keep x y z t for what really has to survive the
press, since every function can change them.
One press A, the next press B
not x is 1 when x is 0, and 0 otherwise. Storing it back in x on each
press makes x alternate: 1, 0, 1, 0…
def ab_rhythm
menu "LEARN" >> "A/B"
x not x
tr.clr
if x: l 1 16: if er 5 16 i: tr.add i
else: l 1 16: if er 3 8 i: tr.add iOutput · what the simulator prints for $ otype.py run ab_rhythm
ab_rhythm seed 1 (--seed) pattern A01 len 16 (default) track 1
T1 1 5 9 13
X...X..X..X..X..
X trig ! one-shot o trigless trig - trigless lock l locks only . none
part: tempo 120
cost: 181/225 random draws: rand 0 toss 0 prob 0 drunk 0 file 0Variables with a name: var
When a function needs to remember something of its own, give it a named variable. var name start
goes at the top of the function, before the first statement; the variable starts at start when the
scripts are loaded and keeps its value from one press to the next. Unlike x y z t, it belongs to its
function alone. A function may have up to 16 of them.
def rotate
menu "LEARN" >> "ROTATE"
var shift 0
shift wrap add shift 1 0 15
tr.clr
l 1 16: if er.r 5 16 shift i: tr.add i
msg "SHIFT" shiftOutput · what the simulator prints for $ otype.py run rotate
rotate seed 1 (--seed) pattern A01 len 16 (default) track 1
T1 1 5 9 13
.X...X..X..X..X.
X trig ! one-shot o trigless trig - trigless lock l locks only . none
part: tempo 120
msg: "SHIFT 1"
end box: "SHIFT 1" (the last msg, instead of DONE)
cost: 186/230 random draws: rand 0 toss 0 prob 0 drunk 0 file 0er.r is er with one more value, a rotation. wrap … 0 15 brings 16 back
to 0, so the rhythm comes round after sixteen presses.
Names you can read but not change
A param, a const and the arguments of a function are read like variables, but cannot
be assigned: gap 3 on a param gap is an error. You will meet const and
arguments in functions.
Values that move by themselves
Three words read like variables but change each time they are read. Each function has its own, kept between presses.
| read | gives | set with |
|---|---|---|
flip | 0, 1, 0, 1… one more at each read | flip 0 |
o | a counter: 0, 1, 2… up to o.max (63), then round again | o 0 · o.min · o.max · o.inc · o.wrap |
drunk | a random walk: one step down, none or one step up at each read | drunk 64 · drunk.min · drunk.max · drunk.wrap |
def wander
menu "LEARN" >> "WANDER"
drunk.max 15
drunk 12
tr.clr
l 1 16:
tr.add i
pl.set i amp.vol add 7 mul drunk 8Output · what the simulator prints for $ otype.py run wander -v --seed 2
wander seed 2 (--seed) pattern A01 len 16 (default) track 1
T1 1 5 9 13
XXXXXXXXXXXXXXXX
step 1: amp.vol 103 step 2: amp.vol 111 step 3: amp.vol 111 step 4: amp.vol 111
step 5: amp.vol 111 step 6: amp.vol 103 step 7: amp.vol 103 step 8: amp.vol 95
step 9: amp.vol 103 step 10: amp.vol 95 step 11: amp.vol 103 step 12: amp.vol 95
step 13: amp.vol 95 step 14: amp.vol 103 step 15: amp.vol 95 step 16: amp.vol 95
X trig ! one-shot o trigless trig - trigless lock l locks only . none
part: tempo 120
cost: 338/338 random draws: rand 0 toss 0 prob 0 drunk 16 file 0drunk walks between 0 and 15 here; add 7 mul drunk 8 turns each of its steps into
a clear change of volume, from 7 to 127.
What you learned
a 5·a add a 1- a variable first on a line gets a value
a b c d- local to one run of one function
x y z t- global, kept between presses
i j- loop counters, read-only
var name start- a named variable of one function, kept between presses
flip·o·drunk- values that move at each read
er.r k n r s- a Euclidean rhythm, rotated by r
Try it
- Make
ab_rhythmcycle through three rhythms, withx wrap add x 1 0 2. - Rewrite
rotatewithoinstead ofvar. - Keep
wanderloud: raisedrunk.minto 8.