while- and repeat-Loops
With while- and repeat-loops you don't have automatically incremented counter variables. Instead, you test truth conditions. The while-loop runs while a specific condition is true, the repeat-loop runs until a specific condition is true. This subtle difference is clearly reflected in the syntactic frames of the two loops. Compare the while-loop:
while condition is true code block endwhile
to the repeat-loop:
repeat code block until condition is true
From a different perspective, the difference between a while-loop and a repeat-loop is, that the code block of the repeat-loop is executed at least once, because the condition is tested after each pass. The code block in the while-loop, on the other hand, may never run, because the condition is tested before each pass, so if the condition is false from the start, the while-loop is just ignored and the script continues after
Conditions are usually formulated as comparisons. Praat provides 6 comparison operators to compare two entities:
|<=||less than or equal|
|>=||greater than or equal|
With these operators you may compare literal values (numbers and strings), variables (numeric and string), or (results of) formulas. A simple comparison is one between a numeric variable and a literal number. An example:
|Comparison||x is 9||x is 10||x is 11|
|x = 10||false||true||false|
|x <> 10||true||false||true|
|x < 10||true||false||false|
|x <= 10||true||true||false|
|x > 10||false||false||true|
|x >= 10||false||true||true|
Even simpler but useless in the context of loops (and in most other contexts, too) are comparisons between two literal values, like 7 < 10 or 12 < 10. These are always true (the former) or always false (the latter), therefore not suited for loop conditions. Loop conditions must be able to swap their truth value at some point, so that the loop has a chance to terminate. Somewhere along the line, the condition of a while-loop must become false to stop the loop, while the condition of a repeat-loop must become true to stop the loop. It is your responsibility to implement loops in such a way that the test condition is able to swap its truth value at some (reasonable) point!
As an easy example, let's implement the for-loop functionality with a while-loop:
clearinfo i = 1 while i <= 10 appendInfoLine: i i = i + 1 endwhile
First, the start value 1 is assigned to i, then we tell the while-loop to repeat the code block while i is less than or equal to 10. In the code block, i is written to Praat Info and then incremented by 1. As soon as i is greater than 10 the loop stops. This equivalent to:
clearinfo for i to 10 appendInfoLine: i endfor
Of course, the for-loop is more straightforward in this case. But if you need other increments than 1 you may prefer the while-loop over manipulating the counter variable of a for-loop (see last section). For instance, a start value of 0 with an increment of 0.5 is realized like this:
clearinfo i = 0 while i <= 10 appendInfoLine: i i = i + 0.5 endwhile
Or like this:
clearinfo for i from 0 to 10 appendInfoLine: i i = i - 0.5 endfor
It's up to you which one you choose. And there's even a third option, the repeat-loop:
clearinfo i = 0 repeat appendInfoLine: i i = i + 0.5 until i > 10
The repeat-loop is pretty similar to the while-loop, except for the 'phrasing' of the condition. The while-condition is formulated so that it is true at the beginning (i is less or equal to 10) and becomes false at the chosen point (when i is greater than 10). The repeat-condition is formulated so that it is false at the beginning and becomes true at the chosen point (again, when when i is greater than 10).
Apart from the decision whether you need the condition to be tested before or after the first pass, it's basically a question of taste whether you prefer while- or repeat-loops.
Most of the time, the number of repetitions of a loop can be determined beforehand and most of the time an increment of 1 is exactly what we need. Therefore, for-loops are the standard loop tool in Praat scripts. But in some situations a while- or repeat-loop is better suited. We'll close this session with an example that shows the usefulness of while- and repeat-loops.
Consider you need an even random number. In Praat's formulas tutorial you can find a built-in function called
randomInteger (min, max), which is a good start. The function returns a random integer number between min and max. So, if you need a random number between 1 and 1000 (like throwing a dice with 1000 faces) you do for example:
x = randomInteger (1,1000) writeInfoLine: x
The chance that x is an even number is 50%. To make sure that x is even you need a loop which relentlessly produces random numbers until one is an even number:
repeat x = randomInteger (1,1000) until x is even writeInfoLine: x
Of course, Praat wouldn't understand
x is even, so we need a syntactically correct formulation of the condition. We'll use mod, the modulo operator, which returns the remainder of an integer division: If x is even, x mod 2 (the remainder of x/2) is 0, if x is odd, x mod 2 is 1. This is an example of a comparison between a formula (x mod 2) and a literal value (0):
repeat x = randomInteger (1,1000) until x mod 2 = 0 writeInfoLine: x
Probably, it's also possible to solve this problem with a for-loop but that would be really complicated, because, obviously, we don't know beforehand how often Praat has to throw the dice until an even number shows up. But it's straightforward to implement a while-loop instead of the repeat loop:
x = 1 while x mod 2 <> 0 x = randomInteger (1,1000) endwhile writeInfoLine: x
We only need to instantiate x with some odd number to ensure (1) that x has a value at all before it is used in formula and (2) that the while-condition is true before the first pass through the loop.
Loops are important tools to repeat code blocks (groups of statements). If the number of repetitions can be determined a for-loop is most suitable. For all other cases, Praat provides while- and repeat-loops.
Both, while- and repeat-loops, are dependent on stop conditions. The code block must be implemented such that the stop condition can be fulfilled at some point. While-loops test the stop condition before the first pass, repeat-loops after the first pass. Stop conditions are usually formulated as comparisons.