* * *

Author Topic: [SOLVED] loop based on string ?  (Read 1336 times)

scons

  • Jr. Member
  • **
  • Posts: 91
[SOLVED] loop based on string ?
« on: April 10, 2017, 09:14:42 am »
Hi,

I have another question. This one is about loops in fpc. Here is my situation:

I have a stringlist and I want to  loop in that stringlist, I figured out how to do that loop, but it goes through the whole stringlist from start to end each time again.
So I need to build in some kind of stop that shifts each time to the next time this stop occurs in the stringlist.

Now I get some kind of loop, but it does not do a selection. It goes through the whole loop, and it multiplies each time it goes through the loop.

So my question is: how do i do that ? Tell the loop to stop somewhere (based on text) and continue somewhat further in the loop from that point, and so on ...

Di need to use repeat ... until ? Or is another option better ?

My file so far in attached.

Thanks
« Last Edit: April 12, 2017, 03:36:46 pm by scons »
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

Thaddy

  • Hero Member
  • *****
  • Posts: 3987
Re: loop based on string ?
« Reply #1 on: April 10, 2017, 09:35:53 am »
Look at break (stops a loop).
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

scons

  • Jr. Member
  • **
  • Posts: 91
Re: loop based on string ?
« Reply #2 on: April 10, 2017, 09:46:31 am »
yes I tried that but (and it worked) but then I got something like this:

000001
1
000002
1
1
000003
1
1
1

so there has to be some kind of intelligence in the selection where to start and stop, because with a simple break, it started again at the start of the stringlist.
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

howardpc

  • Hero Member
  • *****
  • Posts: 2190
Re: loop based on string ?
« Reply #3 on: April 10, 2017, 12:28:36 pm »
I have another question. This one is about loops in fpc.

Not really. Your fundamental question is about how to parse string data, how to construct new strings based on what is found, and how to persist the new data.
Data-related questions cannot be adequately answered without access to the data.
What is your data?
What should it look like after you have processed it?
No doubt various loops will be involved in the processing, but the basic issue you are dealing with is how to process string data intelligently, i.e. to devise a parsing (and string-reconstruction) algorithm that does what you want.

scons

  • Jr. Member
  • **
  • Posts: 91
Re: loop based on string ?
« Reply #4 on: April 10, 2017, 12:49:55 pm »

Data-related questions cannot be adequately answered without access to the data.
What is your data?
What should it look like after you have processed it?


Have you looked at the attached ?
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

Thaddy

  • Hero Member
  • *****
  • Posts: 3987
Re: loop based on string ?
« Reply #5 on: April 10, 2017, 01:38:29 pm »
You can also use exit. That exits all loops currently executing....
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

jmm72

  • Jr. Member
  • **
  • Posts: 79
  • Very experienced in being a beginner...
Re: loop based on string ?
« Reply #6 on: April 10, 2017, 10:27:08 pm »
Basically you should learn to use Continue and Break (Exit is for all loops and exits the function/procedure as well, optionally setting the result), in some cases with saving some data before continuing/breaking the loop.

However in your case there's no need for it, that's for when you have several loops, but in your case I'd do it with one. Explaining it abstractly:

You should have a main loop checking every line. Inside the loop look for start and stop conditions. As long as the stop condition is not reached, accumulate data (in a similar way to how you seem to be doing in your code). When the stop condition is reached, then e.g. call a function with the start, stop, and/or accumulated data to do something (add a new node with child nodes from the accumulated data), then reset everything and let the loop keep going.

Separating the 'look for data' and 'do something with the data' as I said will also make the loop look cleaner so you can see better the logic implied with all your if-then and assigning start/stop/accumulated data.

Hope that advice helps you move forward.
Lazarus 1.6.4 + FPC 3.0.2 64bits under Windows 7 64bits
Only as a hobby nowadays
Current proyect release: TBA

howardpc

  • Hero Member
  • *****
  • Posts: 2190
Re: loop based on string ?
« Reply #7 on: April 11, 2017, 02:16:35 pm »
Have you looked at the attached ?

Sorry, I overlooked the data you had provided outside the project directory.
With parsing the devil is always in the detail.
The attached project shows how you might go about this task with your data. It assumes a1.wrl is in the project directory (but you can obviously change this).
I have not bothered with checkboxes and icons etc. in the treeview.

Thaddy

  • Hero Member
  • *****
  • Posts: 3987
Re: loop based on string ?
« Reply #8 on: April 11, 2017, 03:21:56 pm »
Let me guess wihout reading: exit
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

scons

  • Jr. Member
  • **
  • Posts: 91
Re: loop based on string ?
« Reply #9 on: April 12, 2017, 11:19:10 am »
However in your case there's no need for it

Some more learning curve for me, but you are correct. In this particular case it is not really needed to get the same(ish) result.

I eventually tried something like this because I had the loop trouble and it worked pretty good (might not be really programmatically correct though), I might make it some better.

some code extracted:

Code: Pascal  [Select]
  1.   I := 0;
  2.   if TreeView1.Items.Count = 0 then
  3.   begin
  4.     vNode0 := Treeview1.Items.Add(nil, 'World Node');
  5.     vNode0.ImageIndex := 0;
  6.     vNode0.SelectedIndex := 0;
  7.   end;
  8.   TreeView1.BeginUpdate;
  9.   List := TStringList.Create;
  10.   Temp := TStringList.Create;
  11.   Temp1 := TStringList.Create;
  12.   try
  13.     List.LoadFromFile('a1.wrl');
  14.     writeln('loaded');
  15.     for I := 0 to List.Count - 1 do
  16.       if Pos('DEF', List[I]) <> 0 then
  17.         Temp.Add(List[I]);
  18.     for I := 0 to Temp.Count - 1 do
  19.     begin
  20.       if Pos('Separator { # sep1', Temp[I]) <> 0 then
  21.       begin
  22.         x1 := Pos('DEF', Temp[I]);
  23.         x2 := Pos('Separator { # sep1', Temp[I]);
  24.         Result1 := Copy(Temp[I], x1 + 4, x2 - 6);
  25.         //writeln(Result1);
  26.         a1 := treeview1.Items.Count;
  27.         s1 := Result1;
  28.         vNode1 := Treeview1.Items.AddChild(vNode0, s1);
  29.         vNode1.ImageIndex := 1;
  30.         vNode1.SelectedIndex := 1;
  31.       end;
  32.       if Pos('Separator { # sep2', Temp[I]) <> 0 then
  33.       begin
  34.         x3 := Pos('DEF', Temp[I]);
  35.         x4 := Pos('Separator { # sep2', Temp[I]);
  36.         Result2 := Copy(Temp[I], x3 + 4, x4 - 6);
  37.         //writeln(Result2);
  38.         a2 := treeview1.Items.Count;
  39.         s2 := Result2;
  40.         vNode2 := Treeview1.Items.AddChild(vNode1, s2);
  41.         vNode2.ImageIndex := 2;
  42.         vNode2.SelectedIndex := 2;
  43.       end;
  44.       if Pos('Separator { # sep3', Temp[I]) <> 0 then
  45.       begin
  46.         x5 := Pos('DEF', Temp[I]);
  47.         x6 := Pos('Separator { # sep3', Temp[I]);
  48.         Result3 := Copy(Temp[I], x5 + 4, x6 - 6);
  49.         //writeln(Result3);
  50.         a3 := treeview1.Items.Count;
  51.         s3 := Result3;
  52.         vNode3 := Treeview1.Items.AddChild(vNode2, s3);
  53.         vNode3.ImageIndex := 3;
  54.         vNode3.SelectedIndex := 3;
  55.       end;
  56.       if Pos('IndexedFaceSet {', Temp[I]) <> 0 then
  57.       begin
  58.         x7 := Pos('DEF', Temp[I]);
  59.         x8 := Pos('IndexedFaceSet {', Temp[I]);
  60.         Result4 := Copy(Temp[I], x7 + 4, x8 - 18);
  61.         //writeln(Result4);
  62.         a4 := treeview1.Items.Count;
  63.         s4 := Result4;
  64.         vNode4 := Treeview1.Items.AddChild(vNode3, s4);
  65.         vNode4.ImageIndex := 4;
  66.         vNode4.SelectedIndex := 4;
  67.       end;
  68.       if Pos('Extrusion {', Temp[I]) <> 0 then
  69.       begin
  70.         x9 := Pos('DEF', Temp[I]);
  71.         x10 := Pos('Extrusion {', Temp[I]);
  72.         Result5 := Copy(Temp[I], x9 + 4, x10 - 18);
  73.         //writeln(Result5);
  74.         a5 := treeview1.Items.Count;
  75.         s5 := Result5;
  76.         vNode4 := Treeview1.Items.AddChild(vNode3, s5);
  77.         vNode4.ImageIndex := 5;
  78.         vNode4.SelectedIndex := 5;
  79.       end;
  80.  

Learned again a few things !

Thanks for looking into it.
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

scons

  • Jr. Member
  • **
  • Posts: 91
Re: loop based on string ?
« Reply #10 on: April 12, 2017, 11:29:11 am »

Sorry, I overlooked the data you had provided outside the project directory.


Don't be sorry, I am just glad this excellent forum exists for beginners like me, and that it is a very responsive forum !

Looking at your code, it seems I was a little off from the start, but I see now how to handle these kind of loops.
Thanks for that.

One question though:
When I scroll down in your treeview, I get a warning: WARNING: TResourceCacheItem.IncreaseRefCount 1000 TPenHandleCache

What does this mean ?
I had the same warning in my own latest try.
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

howardpc

  • Hero Member
  • *****
  • Posts: 2190
Re: loop based on string ?
« Reply #11 on: April 12, 2017, 01:45:45 pm »
When I scroll down in your treeview, I get a warning: WARNING: TResourceCacheItem.IncreaseRefCount 1000 TPenHandleCache
What does this mean ?
I had the same warning in my own latest try.

I don't see this (on Linux). Are you on Windows?
The LCL checks resource usage (unless DisableChecks is defined) and notes that over 1000 pen handles are in use.
Perhaps it indicates a bug in the TTreeView painting implementation.
It seems unlikely that it is caused by a flaw in your or my code since neither of us does any direct painting or allocation of widget handles (however, always suspect your own code first). It is certainly true that your large data file will instantiate well over a 1000 treeview nodes. However, one would have thought the same pen could be used to draw the text of each of them. Huge data files of this sort are actually quite good stress tests for the LCL.

scons

  • Jr. Member
  • **
  • Posts: 91
Re: loop based on string ?
« Reply #12 on: April 12, 2017, 03:36:25 pm »
yes Windows 10

All default warnings and other stuff from the debugger are on.

I think it is just a warning. I just tried with a slightly bigger file (8.080.000+ lines) and everything seems to show up ok.
Windows 10-64bit Lazarus 1.6.4 FPC 3.0.2

jmm72

  • Jr. Member
  • **
  • Posts: 79
  • Very experienced in being a beginner...
Re: [SOLVED] loop based on string ?
« Reply #13 on: April 12, 2017, 04:20:24 pm »
Glad you got to it. That's one reason why I don't like fixing code, just pointing how to do stuff. That way people learn instead of having everything chewed and digested. I still learn everyday I write code and I need to find how to do certain stuff. Specially since now that I only program as hobby I'm doing much more advanced things than what I ever did when I worked as programmer using other languages.
Lazarus 1.6.4 + FPC 3.0.2 64bits under Windows 7 64bits
Only as a hobby nowadays
Current proyect release: TBA

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus