Recent

Author Topic: [solved] looping direction controlled by flag  (Read 1443 times)

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1422
[solved] looping direction controlled by flag
« on: April 18, 2025, 02:57:59 pm »
hi I'm trying to make a function that can iterate through an array with direction controlled by a boolean flag. so far i have this but it doesn't compile
Code: Pascal  [Select][+][-]
  1. FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL(CONST IS_FIRST:BOOLEAN):TCONTROL;
  2.          VAR X:INTEGER;
  3. BEGIN
  4. IF IS_FIRST
  5.    THEN FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  6.             IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X])
  7.    ELSE FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO
  8.             IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  9. ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');
  10. END;

does anyone have any idea of how to do this?
« Last Edit: April 20, 2025, 01:16:34 pm by Joanna from IRC »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

MarkMLl

  • Hero Member
  • *****
  • Posts: 8393
Re: looping direction controlled by flag
« Reply #1 on: April 18, 2025, 03:14:47 pm »
What error message are you getting? Also note that you've got a dangling else in the middle of it.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16945
  • Ceterum censeo Trump esse delendam
Re: looping direction controlled by flag
« Reply #2 on: April 18, 2025, 03:43:47 pm »
@Joanna
I am pretty sure that is just your capslock being stuck 8-)
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1422
Re: looping direction controlled by flag
« Reply #3 on: April 18, 2025, 04:08:20 pm »
The error is illegal assignment to a loop variable on the line with the else. In other words it seems to think the second loop is the else condition for the if statement inside the loop.. Definitely wrong
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

MarkMLl

  • Hero Member
  • *****
  • Posts: 8393
Re: looping direction controlled by flag
« Reply #4 on: April 18, 2025, 04:42:08 pm »
The error is illegal assignment to a loop variable on the line with the else. In other words it seems to think the second loop is the else condition for the if statement inside the loop.. Definitely wrong

Let's try to rearrange it a bit.

Code: Pascal  [Select][+][-]
  1. FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL(CONST IS_FIRST:BOOLEAN):TCONTROL; VAR X:INTEGER;
  2.  
  3. BEGIN
  4.     IF IS_FIRST THEN
  5.         FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  6.             IF PROVIDES_SQL(AR_CONTROLS[X]) THEN
  7.                 EXIT(AR_CONTROLS[X])
  8.             ELSE
  9.                 FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO
  10.                     IF PROVIDES_SQL(AR_CONTROLS[X]) THEN
  11.                         EXIT(AR_CONTROLS[X]);
  12.     ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');
  13. END;
  14.  

Can you see it now?

MarkMLl




MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Josh

  • Hero Member
  • *****
  • Posts: 1374
Re: looping direction controlled by flag
« Reply #5 on: April 18, 2025, 04:42:41 pm »
your trying to use same x variable in a loop that isalreadyin an x loop
reformatting inyour CAPS style, hopefully helps

Code: Pascal  [Select][+][-]
  1. IF IS_FIRST THEN
  2.   FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  3.     IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X])
  4.     ELSE
  5.       FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO  // <<- You creating a new x foor loop,while still in thef irst x loop
  6.         IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);        

If the below code is what your after,by adding a ;
Code: Pascal  [Select][+][-]
  1. IF IS_FIRST THEN FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);       // added;
  2. ELSE FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  3.          
Or easier to read IMO, as ZORAN suggests

Code: Pascal  [Select][+][-]
  1. IF IS_FIRST THEN
  2. BEGIN // GOING UP
  3.   FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  4.   BEGIN
  5.     IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  6.   END;
  7. END
  8. ELSE
  9. BEGIN  // GOING DOWN
  10.   FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO
  11.   BEGIN
  12.     IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  13.   END;
  14. END;
« Last Edit: April 18, 2025, 05:39:49 pm by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Zoran

  • Hero Member
  • *****
  • Posts: 1948
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: looping direction controlled by flag
« Reply #6 on: April 18, 2025, 05:16:26 pm »
does anyone have any idea of how to do this?

This is not Python, the "else" is always connected to the last "if" before it. See Mark's post, it should make it very clear for you.
Putting begin-end where appropriate certainly solves this.

Then, you are lucky that you used the same variable in both loops (as Josh spotted) which turned it to compile time error, not only semantic error which could go unnoticed.

Make a habit of using begin-end with if statement.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

MarkMLl

  • Hero Member
  • *****
  • Posts: 8393
Re: looping direction controlled by flag
« Reply #7 on: April 18, 2025, 06:12:27 pm »
This is not Python, the "else" is always connected to the last "if" before it. See Mark's post, it should make it very clear for you.
Putting begin-end where appropriate certainly solves this.

Steady on: I don't think Joanna knows Python (and if she does, she likes it less than any of us). I'm hoping that she gives me an opportunity to work through what she's done (when compared with what she /thinks/) she's done in some detail, so that she doesn't fall into this trap again.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1422
Re: looping direction controlled by flag
« Reply #8 on: April 18, 2025, 11:15:07 pm »
thanks for the replies. it was indeed getting confused by the THEN inside the loop. the redundancy still bothers me but how about this?
Code: Pascal  [Select][+][-]
  1. FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL(CONST IS_FIRST:BOOLEAN):TCONTROL;
  2.          VAR X:INTEGER;
  3. BEGIN
  4. IF IS_FIRST
  5.    THEN FOR X:= LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  6.             IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  7. IF NOT IS_FIRST
  8.    THEN FOR X:= HIGH(AR_CONTROLS) DOWNTO LOW(AR_CONTROLS) DO
  9.             IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  10. ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');
  11. END;    
it seems that there is no way to choose which loop to execute for the same line of code that follows...
« Last Edit: April 19, 2025, 12:44:04 am by Joanna from IRC »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Josh

  • Hero Member
  • *****
  • Posts: 1374
Re: looping direction controlled by flag
« Reply #9 on: April 19, 2025, 12:30:30 am »
Add a Y var for main loop, assign x value according to direction, and check in loop to inc or dec x

Note this harder to follow, and will be slower..... Y for loop will be optimized as value likely store in register,but the inc/dec of x may not be, plus addition of check code inside loop

Something like
Code: Pascal  [Select][+][-]
  1. if IS_FIRST then x:=low(AR_CONTROLS) else x:=high(AR_CONTROLS);    // set x initial value
  2. for y:=low(AR_CONTROLS) to high(AR_CONTROLS) do
  3. begin
  4.   if PROVIDES_SQL(AR_CONTROLS[X])THEN Exit(AR_CONTROLS[X]);
  5.   if IS_FIRST then inc(x) else dec(x); // adjust x based on direction
  6. end;
  7. ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');      
« Last Edit: April 19, 2025, 01:07:51 am by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

TBMan

  • Full Member
  • ***
  • Posts: 134
Re: looping direction controlled by flag
« Reply #10 on: April 19, 2025, 01:15:12 am »
I would do something like this (in semi psuedo code):
(I prefer to use begins and ends even though you don't always have to. It makes for an easier read. And I try to remember
to label the "ends" to match the "begins"

Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.  X,GotIt:integer;
  4.  
  5. if IsFirst then
  6.   begin
  7.      for x := low to high do
  8.        begin
  9.          if condition then
  10.             begin
  11.               Gotit := X;
  12.               break;
  13.             end; // end if
  14.        end; // for
  15.   end
  16.   else // IsFirst
  17.   begin
  18.       for x := high to low do
  19.       begin
  20.          if condition then
  21.             begin
  22.                 GotIt := x;
  23.                 break;
  24.            end; // endIf
  25.      end; // for
  26.   end; // else  
  27. result := Whatever(GotIt);
« Last Edit: April 19, 2025, 04:06:07 am by TBMan »

TRon

  • Hero Member
  • *****
  • Posts: 4369
Re: looping direction controlled by flag
« Reply #11 on: April 19, 2025, 05:28:51 am »
Add a Y var for main loop, assign x value according to direction, and check in loop to inc or dec x
That was a nudge in the good direction but did you know that there exist delta airlines and they use planes that can fly in different directions and make use of planes that can have other ranges ? While that is good to know that you could also choose for another airline ?

feeling a bit cryptic today...  :)

Today is tomorrow's yesterday.

cdbc

  • Hero Member
  • *****
  • Posts: 2138
    • http://www.cdbc.dk
Re: looping direction controlled by flag
« Reply #12 on: April 19, 2025, 07:46:42 am »
Hi
Another possibility would be to utilize 'case', like this:
Code: Pascal  [Select][+][-]
  1. var x: integer;
  2. begin
  3.   case IsFirst of
  4.     false: begin
  5.              for x:= ControlCount-1 downto 0 do
  6.                if Controls[x].Name = 'Memo1' then exit(Controls[x]);
  7.            end;
  8.     true: begin
  9.             for x:= 0 to ControlCount-1 do
  10.               if Controls[x].Name = 'Edit1' then exit(Controls[x]);
  11.           end
  12.   end;
  13.   Result:= nil;
  14.   fPresenter.Provider.NotifySubscribers(prStatus,nil,Str2Pch('(!) Attention: Control was not found! '));
  15. end;
  16.  
I hope you get the gist of the algorithm, 'cause I really don't wanna mess with your caps-locked-code...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Josh

  • Hero Member
  • *****
  • Posts: 1374
Re: looping direction controlled by flag
« Reply #13 on: April 19, 2025, 08:28:24 am »
Using Delta Airlines. Avoids the comparison check in loop

add A DeltaAirlines Var
Code: Pascal  [Select][+][-]
  1. DeltaAirlines:=1; // DeltaAirlines is Going to its Destination
  2. x:=low(AR_CONTROLS); // set x initial value
  3. if Not IS_FIRST then
  4. begin
  5.   DeltaAirlines:=-1; // DeltaAirlines is going its Origin
  6.   x:=high(AR_CONTROLS); // set x initial value
  7. end;
  8. for y:=low(AR_CONTROLS) to high(AR_CONTROLS) do
  9. begin
  10.   if PROVIDES_SQL(AR_CONTROLS[X])THEN Exit(AR_CONTROLS[X]);
  11.   x:=x+DeltaAirlines; // adjust x based on DeltaAirlines direction
  12. end;
  13. ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');

And as function

Code: Pascal  [Select][+][-]
  1. FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL(CONST IS_FIRST:BOOLEAN):TCONTROL;
  2. VAR X,Y,DELTA_AIRLINES:INTEGER; // ADD EXTRA VARS
  3. BEGIN
  4.   DELTA_AIRLINES:=1; // DELTA_AIRLINES IS GOING TO ITS DESTINATION
  5.   X:=LOW(AR_CONTROLS); // SET X INITIAL VALUE
  6.   IF NOT IS_FIRST THEN
  7.   BEGIN
  8.     DELTA_AIRLINES:=-1; // DELTA_AIRLINES IS GOING TO ITS ORIGIN
  9.     X:=HIGH(AR_CONTROLS); // SET X INITIAL VALUE
  10.   END;
  11.   FOR Y:=LOW(AR_CONTROLS) TO HIGH(AR_CONTROLS) DO
  12.   BEGIN
  13.     IF PROVIDES_SQL(AR_CONTROLS[X])THEN EXIT(AR_CONTROLS[X]);
  14.     X:=X+DELTA_AIRLINES; // ADJUST X BASED ON DELTA_AIRLINES DIRECTION
  15.   END;
  16.   ERROR_HALT('FUNCTION TCASCADING_FLOWPANEL.GET_THE_CONTROL');
  17. END;    
« Last Edit: April 19, 2025, 09:05:23 am by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

TRon

  • Hero Member
  • *****
  • Posts: 4369
Re: looping direction controlled by flag
« Reply #14 on: April 19, 2025, 09:03:34 am »
Bravo Josh.

With a bit of abstraction it might even end up something like
Code: Pascal  [Select][+][-]
  1. var
  2.   Flight  : TIterate;
  3.   Airport : sizeint;
  4. begin
  5.   if isNormalRoute
  6.    // The following can be abstracted as well, f.e. by adding a direction (delta) parameter
  7.    then Flight := TIterate.Create(low(Destinations), high(Destinations))
  8.   else Flight := TIterate.Create(high(Destinations), low(Destinations));
  9.  
  10.   while Flight.Next(Airport) do
  11.     if NeedToLand(Destinations[Airport])
  12.       then exit(Destinations[Airport]);
  13. end;
  14.  

Not the fastest solution to use a self made iterator but certainly pleasant to read/understand. The omitted iterator record uses the same mechanism as per Josh's example.
Today is tomorrow's yesterday.

 

TinyPortal © 2005-2018