QB64 Phoenix Edition
Why does my Loop end after 11 Loops? - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Why does my Loop end after 11 Loops? (/showthread.php?tid=1448)

Pages: 1 2 3 4 5 6 7


Why does my Loop end after 11 Loops? - Dimster - 02-06-2023

I have a file with over 28,000 data items. They are stored in the file in groups of 7. I have often OPENed this file, Inputed 7 items at a time and worked on each item before grabbing the next 7 data items.

The code goes

Open File
  Do While Not EOF
     For i = 1 to 7:Input DataItem(i): Next
     Call Subroutine to work on these 7 data items
   Loop

I have never had a problem looping thru the entire data file however recently I been working with Recursion and changed the routine to 


Open File
Recur

Sub Recur
LoopRecur = LoopRecur + 1
Seek #1, 1
for i = 1 to 7:Input DataItem(i):Next
 DataCount = DataCount + 7
Call Subroutine to work on these 7 data items
if DataCount < 4000 then Recur
End Sub


So I'm scratching my head when this recursive routine only performs 11 loops and the program just stops running. That number 11 brings to mind a possible un-dimensioned variable or perhaps a dynamic array that has gobbled up memory. I can't find anything like that in my program (which has thousands of lines of code so I could be missing it). On the other hand, could this recursive code simply be the culprit in memory munch whereas the original Do While did not munch memory?


RE: Why does my Loop end after 11 Loops? - mnrvovrfc - 02-06-2023

Your code has something fundamentally wrong. You should check "EOF()" after every "INPUT" preferably because the program could suddenly end with "input past end" error with is irritating. There's no need for recursion, simply count the number of items that were read from the file. Do away with the "FOR... NEXT" loop which is a source of confusion. Put the counter inside the "DO WHILE NOT EOF()... LOOP" and keep checking for how many items to acquire. The program could perhaps offer a warning after it closes the file, if it couldn't get seven items in the last pass.

Why do you need a "SEEK" statement? That is one thing that is bombing your algorithm. "DataCount" needs to be declared as "DIM SHARED", or as "STATIC" inside the subprogram "Recur" and a condition to set it to zero before the processing. Otherwise, as I've said, recursion is not needed for this.


RE: Why does my Loop end after 11 Loops? - TerryRitchie - 02-06-2023

(02-06-2023, 07:08 PM)Dimster Wrote: I have a file with over 28,000 data items. They are stored in the file in groups of 7. I have often OPENed this file, Inputed 7 items at a time and worked on each item before grabbing the next 7 data items.

The code goes

Open File
  Do While Not EOF
     For i = 1 to 7:Input DataItem(i): Next
     Call Subroutine to work on these 7 data items
   Loop

I have never had a problem looping thru the entire data file however recently I been working with Recursion and changed the routine to 


Open File
Recur

Sub Recur
LoopRecur = LoopRecur + 1
Seek #1, 1
for i = 1 to 7:Input DataItem(i):Next
 DataCount = DataCount + 7
Call Subroutine to work on these 7 data items
if DataCount < 4000 then Recur
End Sub


So I'm scratching my head when this recursive routine only performs 11 loops and the program just stops running. That number 11 brings to mind a possible un-dimensioned variable or perhaps a dynamic array that has gobbled up memory. I can't find anything like that in my program (which has thousands of lines of code so I could be missing it). On the other hand, could this recursive code simply be the culprit in memory munch whereas the original Do While did not munch memory?

You need to set up the subroutine Recur as static:

SUB Recur() Static

Without the STATIC keyword the value for LoopRecur and DataCount will not get preserved between calls.


RE: Why does my Loop end after 11 Loops? - Dimster - 02-06-2023

Hello mnrvovrfc ... love this handle ... you said "There's no need for recursion" and "Why do you need a "SEEK" statement"... the point was to change the Do Loop to a Recursive Loop. I agree that Do Loop works well but Recursion appears to have the advantage of avoiding multiple Open and Closing of the same file through out the run of my program so I'm trying to replace the Do Loop with a Recursive routine. I thought only the Seek statement, in a recursive loop, could get me back to the beginning of the file data. Is there another way to move the pointer of the Input statement back to the beginning of the file? Maybe this is the cause of my recursive loop looping only 11 times where it should loop 4000 times. Recursion is limited to 11 times unless that Static statement is used

Thanks for that heads up Terry. Actually both you guys pointed out Static was needed here. I'm back to the drawing board.

Thanks very much for the help.


RE: Why does my Loop end after 11 Loops? - SpriggsySpriggs - 02-06-2023

It also looks like you might be SEEKing back to the first byte each time you run your sub. Maybe.


RE: Why does my Loop end after 11 Loops? - bplus - 02-06-2023

(02-06-2023, 09:55 PM)Balderdash Wrote: It also looks like you might be SEEKing back to the first byte each time you run your sub. Maybe.

Looked that way to me also.

Recur can also work as goSub but then variables are public and therefore need to be different from ones in main if you change them in gosub part and don't want them changed in main, index i is an example.


RE: Why does my Loop end after 11 Loops? - mnrvovrfc - 02-06-2023

Code: (Select All)
dim ditem(1 to 7) as long
dim as long ff, count, total

count = 1
ff = freefile
open "example.dat" for input as ff
do until eof(ff)
    total = total + 1
    input #ff, ditem(count)
    count = count + 1
    if count > 7 then
        count = 1
        gosub dosomethingwithdataitems
    end if
    if total >= 4000 then exit do
loop
close ff

if total < 4000 then
    print "Unexpected end of data items"
    if count > 1 then print "Incomplete data set"
end if
end

dosomethingwithdataitems:
'put code here to do something with ditem()
return

This is how I would have done things, as I've studied from the first post of this topic. As I've said, no need for recursion. No need to seek back to the beginning of the file.


RE: Why does my Loop end after 11 Loops? - bplus - 02-07-2023

EDIT: Never mind this whole thing is such a bad idea...


RE: Why does my Loop end after 11 Loops? - SMcNeill - 02-07-2023

I'm guessing your program is structured like the following, and that you're looking for something like this?

Code: (Select All)
DIM SHARED AS LONG DataCount, DataItem(4000)
OPEN "someFile.txt" FOR INPUT AS #1
DataCount = 1
Recur

SUB Recur
    IF DataCount = 1 THEN SEEK #1, 1 'move to the start of the file 'may need to change to 0 for 0 index counting
    FOR i = 1 TO 7
        INPUT DataItem(i)
    NEXT
    DataCount = DataCount + 7
    CALL WorkSub
    IF DataCount < 4000 THEN Recur
END SUB

SUB WorkSub
    'work on these specific data items
END SUB


Now, my question here is: Why do we even do a file seek at all here?  There doesn't appear to be any file input at all going on.  It's all being handled with an user INPUT.  Do you actually want to do an INPUT #1, DataItem(i)?


RE: Why does my Loop end after 11 Loops? - SMcNeill - 02-07-2023

(02-07-2023, 12:03 AM)bplus Wrote: EDIT: Never mind this whole thing is such a bad idea...

I don't think it's the way any of us would do this type of thing, but sometimes folks just want to move beyond what they're comfortable with so they can learn new commands and new skills.  As a step towards trying to learn recursion and SEEK commands, I don't see this as a bad idea at all.  Wink