## Algorithms and Lazarus

### Structural Elements: ITERATION

Repetition is one thing computers are very good at. One of many reasons that they now control many aspects of manufacture is their ability to repeat actions (without error hopefully) over long periods of time. Iteration in a programming system can be subtle or explicit – in effect your whole system is continually waiting until you do something – it is stuck in an execution cycle.

 POST-TESTED INDEFINITE do the task and then ask if you should do it again Use this sort of loop when you need to do the task AT LEAST once, but possibly lots of times repeat ... until PRE-TESTED INDEFINITE ask if you have finished doing the task yet - if not, do the dask Use this loop when unsure if you need to perform the task at all while ..do PRE-TESTED DEFINITE perform the task a fixed number of times Use this type of loop when you can determine, beforehand, how many times the task needs to be performed for... to .. do TIMER-BASED each tick, do the task

There are a number of different classifications of iterative processes (or loops)

definite
where the exact number of 'cycles' are known before-hand
indefinite

where it is not known how many times the loop is to be performed.

event-driven

where some regular (or programmed) event triggers the task to be done again (like a timer tick). It is worth noting that most forms of iteration must be very carefully used in an event-driven program as, generally, they are EXCLUSIVE processes (ie. nothing else can be happening while the loop is being executed) - this is different to timer-based iteration.

2 different standard iterative strategies are common:

 pre-tested loop post-tested loop

### REPEAT...UNTIL - post-tested, indefinite

```
Syntax:  repeat
[statement] {;
[statement] }
until p

where p is a BOOLEAN expression (something that can be true or false).
```

Inside the loop, there must be the ability for p to become TRUE; otherwise ENDLESS LOOP.

```               eg.    x := 2;
repeat
showmessage ('One more time');
until x > 10;  {is an endless loop}

eg2.   repeat
showmessage ('Over and Over');
until FALSE;  {also endless}```

Endless loops are only deployed for good reasons.

It is possible for multiple statements between the repeat and until. The repeat ... until behaves in much the same way as a begin ... end in encapsulating a parcel of tasks.

It is possible to use a variable to control the loop. Such a variable is often termed a loop variable. By changing the value of the loop variable, it is possible to create the conditons necessary for the loop to terminate

```     eg3.
procedure TForm1.Button1Click(Sender: TObject);
x : integer;
begin
x := 1;
repeat
inc(x)
until x > 10
end;  ```

Repeat..until is used when UNCERTAIN of the number of repetitions SO LONG AS AT LEAST ONE is required.

Case Study: Write a buttonclick handler that repeatedly asks for test scores (out of 30), terminating with a ZERO (0), and then printing out class average.

```         procedure TForm1.Button1Click(Sender: TObject);
{prompts for test scores out of 30, terminating with }
{a zero, and then reports average}

var       total, average    :  real;
numinclass        :  integer;
mark, result      :  string;

begin
{initialisation}
total        := 0;
numinclass   := 0;

{input loop}
repeat
mark := inputbox('Data Entry','Please enter a score','0');
if mark <> '0'
then  begin
inc(numinclass);         {tally of num of marks}
total := total + strtoint(mark)    {tally of marks}

end
until mark = '0';  {the sentinel value}

{output}
average := total/(numinclass);
result  := 'Class average = ' + floattostr(average);
showmessage(result)
end;```
Notice the above program is buggy as it will accept zero scores and blithely attempt to calculate the average of zero scores (dividing by zero and freaking out the machine in the process) - can you devise a test to prevent this? This event handler does not check the score is out of 30 - can you make it do so?
 CLASS AVERAGE Repeatedly ask for marks out of 100 for a test, tallying as you go until a sentinel value is reached, then output the average for that group. Error trap as much as possible. See a SDC Solution McMENU Repeatedly ask users for choices off a menu of 4 items, each time the user makes a selection, update the tally for that product. When the user indicates they are finished the order (via a sentinel value, present an itemised bill BUZZY BEE Place a TShape (our Honeypot) somewhere on the screen, then randomly place a Button (our bee) on the screen, then continually update the position of the Button (randomly) until it lands on the TShape - report the number of re-positions necessary to achieve this See a SDC Solution

### WHILE...DO - pre-tested, indefinite

```   Syntax:  while p do
[ statement ]

where p is BOOLEAN, and statement may be compound (ie. begin
.... end)```

A while..do loop is used if the statements inside the loop may not need executing at all (ie 0..many iterations). The while determines if the statement needs to be executed - if the while returns a true, then the statement is executed, otherwise the next part of your program is executed.

They are used when it is difficult to predict how many iterations are necessary. They are NOT the same as repeat..until statements which execute the enclosed task at least once.

```       eg1.  procedure TForm1.Button1Click(Sender: TObject);
var
a       : integer;
begin
a := 1;
while a <= 10 do
begin
answer := inttostr(a)+'^2 = '+ inttostr(a*a);
inc(a);
end
end;
```

### FOR..DO - pre-tested, definite

```   Syntax:
for identifier := val1 [down]to val2 do
[ statement ]

eg1:
procedure TForm1.Button1Click(Sender: TObject);
var counter : byte;
begin
for counter := 1 to 10 do
begin
answer := inttostr(counter)+ ': over and over';
end;
end;```

We use for..do loops in situations when we know how many times we want a task executed. These loops are very commonly used for many different things (especially when dealing with compound data types like arrays).

A for..do loop uses an ordinal loop variable to control the loop, and can either ascend or descend in value according to the loop declaration

The identifier must be declared the same type as the values

```   eg2: procedure TForm1.Button1Click(Sender: TObject);
var nam : char;
begin
for nam := 'A' to 'E' do
showmessage(nam)
end;```

The identifier used as the counter of the loop can also be used inside the loop.

```   eg3:  procedure TForm1.Button1Click(Sender: TObject);
num    : integer;
begin
for num := 1 to 5 do
begin
end;
end;```

The loop cycles exactly as many times as there are values for the identifier

The statement may be compound (eg begin .. end)

If val1 > val2 then loop will not be entered at all in standard form.

```   eg4:     for thing := 20 to 10 do ...        DO ISN'T ENTERED

but   for thing := 20 downto 10 do ...    IS ENTERED```

NEVER artificially alter the loop variables value inside the loop.

```   eg5:  for i := 1 to 10 do
begin
showmessage ('hello');
inc(i)             <-------ERROR
end```

If there is a need to manually change the value of the loop variable, then the FOR..DO loop is not the one to use. (most likely you want to use a while do instead)

To step up by increments other than 1, probably best to use another loop structure. An 'acceptable solution' may be:

```   eg6:  procedure TForm1.Button1Click(Sender: TObject);
var val, step, counter : integer;
begin
val := 1;    step := 3;
for counter := 1 to 5 do
begin
val := val + step     <-----not changing the
end;                              loop variable
end;
```

Premature exit from the loop is ABSOLUTELY FORBIDDEN

DON'T assume that the loop variable finishes up (after the loop terminates normally) at the last value assigned --> this is not standard.

wonko@wonko.info