Lazarus

Programming => General => Topic started by: Jake012345 on July 10, 2020, 12:24:16 am

Title: Back in cycle level
Post by: Jake012345 on July 10, 2020, 12:24:16 am
Hello!

I need to leave a cycle in a cycle but when I use Break/exit, that leave the whole cycle / procedure.

But I need:

Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  var a,b,c:integer;
  3. begin
  4.   for a:=0 to 10 do
  5.    @
  6.     for b:=0 to 10 do begin
  7.      c:=StrToInt(inputbox());
  8.      if c=3 then BackTo('@');
  9.    end;
  10. end;
  11.  
  12.  

I haeard about 'goto' but I couldn't find anything that can help me and working :\
Is there a way to do that?
Title: Re: Back in cycle level
Post by: jamie on July 10, 2020, 12:33:30 am
Look at BREAK and CONTINUE..

Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 12:42:26 am
Hi!

Use the whole syntax that Pascal offers:

Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  var a,b,c:integer;
  3. begin
  4.   for a:=0 to 10 do
  5.   begin    
  6.    b := 0; c := 0;
  7.   while (b  <=10) and (c<>3) do begin
  8.      c:=StrToInt(inputbox());
  9.      inc(b);
  10.    end; // while
  11.  end; // for
  12. end;
  13.  

Winni
Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 01:41:25 am
Sadly pascal does not have named loops like Ada, but in your case break should work, because it breaks the most inner loop (so your b loop):
Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  var a,b,c:integer;
  3. begin
  4.   for a:=0 to 10 do
  5.     for b:=0 to 10 do begin
  6.      c:=StrToInt(inputbox());
  7.      if c=3 then Break;
  8.    end;
  9. end;
Other possibility: merge loops, there is no need for 2 for loops here:
Code: Pascal  [Select][+][-]
  1. a := 0;
  2. b := 0;
  3. while a <= 10 do
  4. begin
  5.   Inc(b);
  6.   if b > 10 then Inc(a)
  7.   else
  8.   begin
  9.     c := StrToInt(inputbox())
  10.     if c = 3 then b := 0;
  11.   end;
  12. end;

If you want to use goto:
Code: Pascal  [Select][+][-]
  1. var a,b,c: Integer;
  2. label bLoop;
  3. begin
  4.   for a := 0 to 10 do
  5.   begin
  6. bLoop:
  7.     for b := 0 to 10 do
  8.     begin
  9.       c := StrToInt(inputbox());
  10.       if c = 3 then goto bLoop;
  11.     end;
  12.   end;
  13. end;
Title: Re: Back in cycle level
Post by: PascalDragon on July 10, 2020, 09:17:40 am
I need to leave a cycle in a cycle but when I use Break/exit, that leave the whole cycle / procedure.

Exit leaves the routine, Break leaves the innermost cycle it is part of.
Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 01:49:59 pm
@Warfley

I dont want to talk about that military-Star-Wars-Language ADA which has now grown to such a monster that it is compatible to nearly everything.

The second example is wrong because every time c hits the condition a is not incremented anymore. There might be conditions that run into an endless loop.

The third example is goto: Goto Basic.

Winni
Title: Re: Back in cycle level
Post by: Blaazen on July 10, 2020, 02:00:29 pm
Alternative with nested procedure:
Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  
  3.   procedure MyNestedProc;
  4.   var b,c:integer;
  5.   begin
  6.     for b:=0 to 10 do begin
  7.       c:=StrToInt(inputbox());
  8.       if c=3 then  break;
  9.     end;
  10.   end;
  11.  
  12. var a: integer;
  13. begin
  14.   for a:=0 to 10 do
  15.     MyNestedProc;
  16. end;      
Title: Re: Back in cycle level
Post by: MarkMLl on July 10, 2020, 02:26:30 pm
Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  var a,b,c:integer;
  3. begin
  4.   for a:=0 to 10 do
  5.     for b:=0 to 10 do begin
  6.      c:=StrToInt(inputbox());
  7.      if c=3 then Break;
  8.    end;
  9. end;

Remember that the value of b becomes undefined if the break is taken.

MarkMLl

Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 02:43:57 pm
Just thought about it again, Break does not work here, because then A will be incremented before the b loop is started again. In the original post, he wants to jump before the b loop, without incrementing a.

I've also seen that my "one" loop solution has some bugs. So I think there are about two valid possibilities:
1. While loop
Code: Pascal  [Select][+][-]
  1.     a := 0;
  2.     b := 0;
  3.     while a <= 10 do
  4.     begin
  5.       c := StrToInt(inputbox())
  6.       if c = 3 then b := 0;
  7.       Inc(b);
  8.       if b > 10 then
  9.       begin
  10.         b := 0;
  11.         Inc(a);
  12.       end;
  13.     end;
or using a structure similar to the original post
Code: Pascal  [Select][+][-]
  1. a := 0;
  2. while a <= 10 do begin
  3.   b := 0;
  4.   while b <= 10 do begin
  5.     c:=StrToInt(inputbox());
  6.     Inc(b);
  7.     if c=3 then b:=0;
  8.   end;
  9.   Inc(a);
  10. end;

2. Goto:
Code: Pascal  [Select][+][-]
  1. var a,b,c: Integer;
  2. label bLoop;
  3. begin
  4.   for a := 0 to 10 do begin
  5. bLoop:
  6.     for b := 0 to 10 do begin
  7.       c := StrToInt(inputbox());
  8.       if c = 3 then goto bLoop;
  9.     end;
  10.   end;
  11. end;

And now a maybe unpopular oppinion, I would go with the goto variant, because the code is 1. shorter and 2. easier to understand then the while loops (case in point, my first version of the while loop was actually buggy). And as long as it leads to better readable code, there is nothing wrong about goto
Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 03:02:37 pm
Hi!

I have show the clear solution above.

Advantage 1: No errors
Advantage 2: pure pascal without  goto or break
Disadvantage: One must understand two condiditions connected with an AND

So again:
Code: Pascal  [Select][+][-]
  1.     procedure MyProcedure;
  2.      var a,b,c:integer;
  3.     begin
  4.       for a:=0 to 10 do
  5.       begin    
  6.        b := 0; c := 0;
  7.       while (b  <=10) and (c<>3) do begin
  8.          c:=StrToInt(inputbox());
  9.          inc(b);
  10.        end; // while
  11.      end; // for
  12.     end;
  13.      

Winni
Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 03:08:47 pm
Hi!

I have show the clear solution above.
Except that this has the same error I did in my first post also, if c is 3, the loop is broken and the a loop will continue which will increase a.

Imagine the following case, inputbox always returns 3. In the goto example (which is basically what the original post did), this would result in an infinite loop, in your example this would result in exactly 11 iterations and then the procedure would finish.

Otherwise, I would choose the break version, because for loops are imho easier to read then while loops.

Also, what does "pure pascal" mean, aren't break and goto parts of the pascal language?
Title: Re: Back in cycle level
Post by: AlanTheBeast on July 10, 2020, 03:11:49 pm
Avoid goto.  Yes, you can have 'tighter' code.  But it ages badly over time.  Why many SQ policies forbid it entirely in HOL.

Recently revised a rather long bit of code that goes through up to 6 states searching for an output (tighter to looser rules) and it was tempting to use goto to get out of the central portion to outskirts of the function.  But, looking at the gen'd assembler it wasn't worth it at all.

Continue/Break are your friends as others mention.
Title: Re: Back in cycle level
Post by: 440bx on July 10, 2020, 03:12:55 pm
2. Goto:
Code: Pascal  [Select][+][-]
  1. var a,b,c: Integer;
  2. label bLoop;
  3. begin
  4.   for a := 0 to 10 do begin
  5. bLoop:
  6.     for b := 0 to 10 do begin
  7.       c := StrToInt(inputbox());
  8.       if c = 3 then goto bLoop;
  9.     end;
  10.   end;
  11. end;

And now a maybe unpopular oppinion, I would go with the goto variant, because the code is 1. shorter and 2.
but.. it has a "small" problem: it causes an infinite loop because "a" is never incremented.  OTH, the solution you suggested using "break" doesn't and seems to solve the OP's problem satisfactorily.

And as long as it leads to better readable code, there is nothing wrong about goto
And _no_ infinite loops. <chuckle>

ETA:
"never" after c = 3

Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 03:18:11 pm
Avoid goto.  Yes, you can have 'tighter' code.  But it ages badly over time.  Why many SQ policies forbid it entirely in HOL.
Nah, goto is only bad if it is used badly, simple as that. While it's true that 99% of the time goto is misused, here we have a case where it is better than any other use (as already discussed, break and continue do not fit here), where it actually improves the code (from a readability point of view, I don't care about the produced assembly, this is the job of the compiler not mine)

but.. it has a "small" problem: it causes an infinite loop because "a" is never incremented.  OTH, the solution you suggested using "break" doesn't and seems to solve the OP's problem satisfactorily.
Which is exactly the behaviour requested in the original post... If he wants code that can loop infinetly often that is none of my problem, maybe he has reasons for this, maybe it's a logical error on his side, he requested how to solve this problem so I think we should give him the *correct* solution (with respect to his question) and not the thing we think he wants. Becaus I don't know about you, but I don't trust my mind reading skills that far that I can read minds through an internet forum
Title: Re: Back in cycle level
Post by: AlanTheBeast on July 10, 2020, 03:24:07 pm
Hi!

I have show the clear solution above.
Except that this has the same error I did in my first post also, if c is 3, the loop is broken and the a loop will continue which will increase a.

Imagine the following case, inputbox always returns 3. In the goto example (which is basically what the original post did), this would result in an infinite loop, in your example this would result in exactly 11 iterations and then the procedure would finish.

Otherwise, I would choose the break version, because for loops are imho easier to read then while loops.

Also, what does "pure pascal" mean, aren't break and goto parts of the pascal language?

With nested loops, breaking out may require flags be set

Code: Pascal  [Select][+][-]
  1.            if break_condition then begin brflag := true; break end;
  2.  

Then use brflag to get out of the outer loop and so on.  (break doesn't "break" begin/end closures, only controlled loops (while, for, repeat).

Some code I recently revised (which doesn't use break, but comes to the same thing...)
Code: Pascal  [Select][+][-]
  1.        // long winded code not shown here ... but you can assume the Repeat's are there...
  2.                                 With P^ do
  3.                                         begin
  4.                                                 Case State of
  5.                                                         0: found := (FPStat=PartialPlay) and (Playtime<TLim);
  6.                                                         1: found := (FPStat=NeverPlayed) and NOT TooNew and (Playtime<TLim);
  7.                                                         2: found := (FPStat<>PlayedThisSession) and NOT TooNew and (Playtime<TLim);
  8.                                                         3: found := (FPStat<>PlayedThisSession) and (Playtime<TLim);
  9.                                                         4: found := Playtime<TLim;
  10.                                                         5: found := true;  // unlikely but need a guaranteed way out.
  11.                                                 end;
  12.                                         end;
  13.                         Until found or (Rc >= GC[Gr]);
  14.                 Until found or (Tlim>now);
  15.         Until found;
  16.         exit(P)
  17. END;
  18.  

Loop control (For, While, Repeat) is an implementation choice for functional, efficient, readable (in that order) code.

I personally will use Repeat more than While if it makes sense ... but that isn't always the most readable code.

And for is for a strict range of choice (even if the range is defined by variables) whereas the others are for things that change state inside the loop(s).

Goto is in the original Wirth Pascal manual but should not be used. 
FPC requires a {$GOTO ON} and label pre-declaration.  AVOID.
Break/Continue are add ons (necessary) to the original language.
Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 03:28:07 pm

Except that this has the same error I did in my first post also, if c is 3, the loop is broken and the a loop will continue which will increase a.


Oh, oh, oh.

This is expected behaviour - look into the first post of Jake012345.

But it is not caught in an endless loop but jumps into then next loop of the a - like he wanted.

First read. Then think. Then write.

Winni
Title: Re: Back in cycle level
Post by: 440bx on July 10, 2020, 03:31:47 pm
I don't trust my mind reading skills that far that I can read minds through an internet forum
That's probably a good thing.  That said, I don't recall anyone ever posting that they need to create an infinite loop and, his request doesn't sound like he wants one:
I need to leave a cycle in a cycle but when I use Break/exit, that leave the whole cycle / procedure.
From what he said, it sounds like he wants to leave the _inner_ loop _only_ and keep executing the outer loop.  Granted his "BackTo('@');" very much sounds like a "goto" but, if he really wanted an infinite loop he wouldn't use an outer "for" loop.  A simple "while true do" gives him a nice shiny infinite loop.
Title: Re: Back in cycle level
Post by: lucamar on July 10, 2020, 03:34:46 pm
Code: Pascal  [Select][+][-]
  1. procedure MyProcedure;
  2.  var a,b,c:integer;
  3. begin
  4.   for a:=0 to 10 do
  5.     for b:=0 to 10 do begin
  6.      c:=StrToInt(inputbox());
  7.      if c=3 then Break;
  8.    end;
  9. end;

Remember that the value of b becomes undefined if the break is taken.

Isn't it just the other way around? If the break is taken then b will keep its current value. It's undefined only if the loop ends normally.
Title: Re: Back in cycle level
Post by: 440bx on July 10, 2020, 03:36:52 pm
Isn't it just the other way around? If the break is taken then b will keep its current value. It's undefined only if the loop ends normally.
You are correct.  The value is undefined if the loop ends normally.
Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 03:37:50 pm


Oh, oh, oh.

This is expected behaviour - look into the first post of Jake012345.

But it is not caught in an endless loop but jumps into then next loop of the a - like he wanted.

First read. Then think. Then write.

Winni

His discription is not very clear (I mean if he wants to continue a, then break should have worked, but according to him it doesnt), but his code is, he basically wants goto.

So I think we can leave it with both possibilities, because either way, he now has a solution.

From what he said, it sounds like he wants to leave the _inner_ loop _only_ and keep executing the outer loop.  Granted his "BackTo('@');" very much sounds like a "goto" but, if he really wanted an infinite loop he wouldn't use an outer "for" loop.  A simple "while true do" gives him a nice shiny infinite loop.

It is only an infinite loop if c is always 3. If no 3 occurs, it will be 11*11
Title: Re: Back in cycle level
Post by: rvk on July 10, 2020, 03:45:29 pm
Remember that the value of b becomes undefined if the break is taken.
Isn't it just the other way around? If the break is taken then b will keep its current value. It's undefined only if the loop ends normally.
Yes, you are correct.
Using break/exit will preserve the loop variable (according to the language specifications).

Letting the loop end normally has an undetermined value.
That can be seen when you do something like this (I can't exceed MaxInt so the loop variable can't be loop_end + 1 which you would expect in other cases).
Code: Pascal  [Select][+][-]
  1. var
  2.   I: Integer;
  3. begin
  4.   for I := MaxInt - 5 to MaxInt do
  5.   begin
  6.     Memo1.Lines.Add(I.ToString);
  7.   end;
  8.   Memo1.Lines.Add('end loop');
  9.   Memo1.Lines.Add(I.ToString); // gives maxint as a result while with for 1 to 10 it will give 11 as result
  10. end;
Title: Re: Back in cycle level
Post by: 440bx on July 10, 2020, 03:53:56 pm
It is only an infinite loop if c is always 3. If no 3 occurs, it will be 11*11
That is true but, the fact that he typed "for a = 1 to 10 do" really gives the impression that he is not interested in a case that results in an infinite loop.

He better not default the return value of InputBox to "3".  :D
Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 04:05:30 pm

It is only an infinite loop if c is always 3. If no 3 occurs, it will be 11*11

So you would buy a cardiac pacemaker where you hope that the 3 does not too often appear????

Oh boy!

Winni
Title: Re: Back in cycle level
Post by: Warfley on July 10, 2020, 04:07:05 pm
That is true but, the fact that he typed "for a = 1 to 10 do" really gives the impression that he is not interested in a case that results in an infinite loop.
He better not default the return value of InputBox to "3".  :D
Sure, I also have the impression he wants to do from 1 to 10 not from 0 to 10 (11 is an akward number of iterations), and having this goto scenario seems pretty odd to me, but maybe InputBox shows a form with the title: "choose your action 1: ... 2: ... 3: Delay this loop for another 11 iterations" and this is everything well thought out, how knows. Or maybe he really wants to annoy his users by adding a trick value which just keeps them in this loop, I mean who doesnt sometimes want to torture his users for choosing stupid input
Title: Re: Back in cycle level
Post by: AlanTheBeast on July 10, 2020, 05:52:56 pm
I don't recall anyone ever posting that they need to create an infinite loop

Useful for realtime or permanent monitors.

True fact: some airlines have received notice that they must turn off the avionics on some aircraft within a specific period (100 hours or so) to avoid bugs related to counters etc. overflowing.  They tend to leave the aircraft hot at the gate between flights (on external APU) including overnight.

New code (in one case) gets around such bugs.
Title: Re: Back in cycle level
Post by: winni on July 10, 2020, 08:15:33 pm


True fact: some airlines have received notice that they must turn off the avionics on some aircraft within a specific period (100 hours or so) to avoid bugs related to counters etc. overflowing.  They tend to leave the aircraft hot at the gate between flights (on external APU) including overnight.


Hi !

That was the Boeing  (Boiiing) 787 Dreamliner.

Lousy Reason:

248 days = 2^31  seconds / 100

Restart minimum 248-1  days.

I don't know if they now fixed it, That was 2015.
It it not so easy to enlarge a 32-bit-integer....

Winni
Title: Re: Back in cycle level
Post by: AlanTheBeast on July 11, 2020, 06:35:53 pm
I was referring to the Scarebus 350, actually and the offending rollover was about 150 days... but coming from the Avionics world such things don't surprise me regardless of model of a/c.  (And Boing and Scarebus buy avionics from many common suppliers re-using tons of code modified for each model and variant...).

As to resetting, fuel load is usually less than, say, 24 hours worth.  So based on various conditions that indicate the aircraft is safely on the ground (squat switches, airspeed_trend, groundspeed, parking_brake_set, etc. and so on) it would be easy enough (though not trivial) to implement resets of certain counters (etc.) after x hours and while state=parked_at_gate.  Of course that becomes a requirement which becomes a testable item which becomes ...  or simply when the offending parameter(s) exceed(s) a threshold (and state=parked_at_gate) then run the reset procedure(s).  Depending on the criticality level of the box, the costs of such could be quite high.

Easier to force that box to re-boot (while safely at the gate, of course).

Depending on what bus(es) a box is connected to, it can "listen" for various parameters even if it is not usually a user of a given parameter.  Otherwise other boxes would have to be programmed to provide the offending box with the reset command (when, ... you know).

(I don't know if it is actually done that way, but that is a way it could be done).
Title: Re: Back in cycle level
Post by: MarkMLl on July 11, 2020, 10:19:47 pm
I was referring to the Scarebus 350, actually and the offending rollover was about 150 days... but coming from the Avionics world such things don't surprise me regardless of model of a/c.  (And Boing and Scarebus buy avionics from many common suppliers re-using tons of code modified for each model and variant...).

I'm pretty sure that there's quite a lot of critical systems with that sort of problem, and IIRC there was something about Shuttle missions not crossing New Year.

Wasn't there something about a prototype fighter (Tornado)? having a squat switch problem which became embarrassingly apparent when the pilot accidentally retracted the undercarriage before its maiden flight.

It's a different world. IIRC the i386DX got a massive life extension because it was the last Intel chip with predictable cycle counts.

MarkMLl
Title: Re: Back in cycle level
Post by: winni on July 12, 2020, 12:36:13 am
Hi!

We can collect a lot of stories. The always try to brush it under the carpe but some funny (??) situations to remark:

In the early days of the 737 it was well definded what < 60 nodes had to happen. And  what > 60 nodes had to happen. But it was never defindet: what about 60 nodes. There was pilot rumor about a "strange second"  while landing and starting. It took some time until they "maintained" it.

When I was a young boy Germany bought a lot of Lockheed F-104 "Starfighter" - because of corruption. They fell doen from heaven - nearly one very week. When I was 13 we had a big party after shool: Number 100 of the starfighters,

After the Starfighters came the Tornados. Some for the Airforce and some for the Marines. Those one for the Marines where at once  out of duty. They had a new super-duper distance sensor on board, which held the plane in a constant distance to the ground - no matter if high voltage cabel, trees or buildings. But on the sea they reacted because of the waves like they flew on a  washbaord. Strange skiffle group. They first had to change the software ...

Winni
Title: Re: Back in cycle level
Post by: skalogryz on July 12, 2020, 08:16:02 am
When I was a young boy Germany bought a lot of Lockheed F-104 "Starfighter" - because of corruption. They fell doen from heaven - nearly one very week.
:o
this is actually a real history (https://en.wikipedia.org/wiki/Lockheed_F-104_Starfighter#German_service)
Widowmaker indeed!
TinyPortal © 2005-2018