"Find" - in a field problems

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
sbonham
Posts: 16
Joined: Wed May 17, 2006 3:29 pm

"Find" - in a field problems

Post by sbonham » Fri Apr 28, 2017 3:18 am

I am experiencing a "bug" that I hope is easy to fix...

I am using the following code (within dashed lines) within a repeat loop to build an display of related parts;
1. arm
2. head
3. torso
4. pelvis
5. UpperLeg
6. LowerLeg

img2display is a variable filename - "110head.jpg" for instance
Field "ImageData" is an "array" of 300+ images and XY coordinates for pivot points (joint articulations) in that image
-----------------------------
find string comma & img2Display in fld "ImageData"
put the value of the foundLine into ImgData
answer "ImgData is " & return & ImgData
put item 4 of ImgData & "," & item 5 of ImgData into IntOffsetHV
put item 6 of ImgData & "," & item 7 of ImgData into ExtOffsetHV
-----------------------------
the thing is it works beautifully ***on every ODD numbered repeat*** - (so arm, torso & UpperLeg are displayed properly) and NOT on the even ones (for head, pelvis, and LowerLeg the data is not retrieved).
Do I need to exit the field or something so that the next find command works?
I've tried including the following in the script at the end of the repeat loop...
click at the loc of fld "imageData" --(which is locked)
but that doesn't solve the problem.

Thoughts?/suggestions appreciated!

Steve

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9669
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: "Find" - in a field problems

Post by dunbarx » Fri Apr 28, 2017 3:29 am

Can you post the actual code? I cannot see what is going on with the snippet here.

Craig Newman

sbonham
Posts: 16
Joined: Wed May 17, 2006 3:29 pm

Re: "Find" - in a field problems

Post by sbonham » Fri Apr 28, 2017 5:58 am

Craig,

Here is an abbreviated version to provide more insight...

=======

Code: Select all

Global ArmPOS,HeadPOS,TorsoPOS,PelvisPOS,UpperLegPOS,LowerLegPOS -- These values are all degrees in increments of 10 (0-350°)

 put "Arm,Head,Torso,Pelvis,UpperLeg,LowerLeg"  into BodySegments -- 
   put 1 into ItemNo
   repeat with t=1 to the number of items of BodySegments
      put item itemNo of BodySegments into SegmentVar
      -- CREATE name of image to be displayed----------------------------------
      if segmentVar is "Arm" then
if ArmPOS = 0 then 
               put ArmPOS & "ArmHandClosed.jpg" into Img2Display
            else
               put ArmPOS & "0" & "ArmHandClosed.jpg" into Img2Display
            end if
else
 --these nested IF-THEN-ELSE have been omitted but there are several more for each body part
end if

 --FIND IMAGE OFFSET DATA -------------------------------------------------------------
   find string comma & img2Display in fld "ImageData" 
-------data in fld ImageData looks like...--------------------------
-------Img,190,190UpperLeg.jpg,-6,-37,8,37
-------Img,200,200ArmHandClosed.jpg,-18,-51,16,45
-------Img,200,200ArmHandOpen.jpg,-17,-46,16,49
------------------------------------------------------------------------------
   put the value of the foundLine into ImgData --so a search would find one line of data from fld "imageData"
   answer "ImgData is " & return & ImgData 
-- I was debugging (with the answer line above) and discovered that on the first repeat pass when "Arm" 
-- was SegmentVar LiveCode retrieved data and for item 2 -
-- "Head" it did not - this pattern repeated for every other repeat - successfully getting data for Arm, Torso & UpperLeg
-- and getting zilch for the odd numbered items between
   put item 4 of ImgData & "," & item 5 of ImgData into IntOffsetHV
   put item 6 of ImgData & "," & item 7 of ImgData into ExtOffsetHV
   
   --Position images to be displayed to overlap pivot points (joints)----------------------------------
   if SegmentVar is in "Arm,Torso,Pelvis,UpperLeg,LowerLeg" then
           add Item 1 of IntOffsetHV to item 1 of CurrLoc
      add Item 2 of IntOffsetHV to item 2 of CurrLoc
      Show img Img2display at CurrLoc --"current location" is an X,Y coordinate
    else -- SegmentVar is "head"
      --do stuff for head image (which has only the single neck pivot point)
   end if

   add 1 to ItemNo
end repeat

Hope this helps

sbonham
Posts: 16
Joined: Wed May 17, 2006 3:29 pm

Re: "Find" - in a field problems

Post by sbonham » Fri Apr 28, 2017 6:06 am

...a related question

I've heard that searching/retrieving data from a variable is faster than from a field
so I'd simply put fld "ImageData" into a var named ImageData
but then - how do the find commands differ?

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: "Find" - in a field problems

Post by Klaus » Fri Apr 28, 2017 10:17 am

Hi Steve,

here some hints:
1. Hit the TAB key from time to time in the script editor!
This way LC will format your script nicely and you will also get an visual hint if something might not be correct, like any END XXX not indented as the starting XXX:

Code: Select all

...
   put "Arm,Head,Torso,Pelvis,UpperLeg,LowerLeg"  into BodySegments -- 
   put 1 into ItemNo
   repeat with t=1 to the number of items of BodySegments
      put item itemNo of BodySegments into SegmentVar
      -- CREATE name of image to be displayed----------------------------------
      if segmentVar is "Arm" then
         if ArmPOS = 0 then 
            put ArmPOS & "ArmHandClosed.jpg" into Img2Display
         else
            put ArmPOS & "0" & "ArmHandClosed.jpg" into Img2Display
         end if
      else
         --these nested IF-THEN-ELSE have been omitted but there are several more for each body part
      end if
   end if
...
Same code as yours, but much better readable.

2. To avoid a LOT of IF END IF clauses that will make your script hard to read (and you may have to count all END IFs to match the IFs :-),
use the SWITCH CASE statement, which will fit great in yor case, like this:

Code: Select all

...
   put "Arm,Head,Torso,Pelvis,UpperLeg,LowerLeg"  into BodySegments -- 
   put 1 into ItemNo
   repeat with t=1 to the number of items of BodySegments
      put item itemNo of BodySegments into SegmentVar
      -- CREATE name of image to be displayed----------------------------------
      switch SegmentVar
         case "Arm"
            if ArmPOS = 0 then 
               put ArmPOS & "ArmHandClosed.jpg" into Img2Display
            else
               put ArmPOS & "0" & "ArmHandClosed.jpg" into Img2Display
            end if
            break
         case "Head"
            if HeadPOS = xxx then
               ##
            else
               ###
            end if
            break
         case "Torso"
            if TorsoPOS = xxx then
               ###
            else
               ##
            end if
            break
            ## More CASEs here...
      end switch
   end repeat
...
3. I never use FIND but rather LINEOFFSET or even FILTER LINES OF ..., which will work with fields and variables!

Code: Select all

...
put fld "ImageData" into YourVariable
put lineoffset(img2Display,YourVariable) into tLineNumber
if tLineNumber <> 0 then
  put line tLineNumber of YourVariable into ImgData
end if
...
Or with filter:

Code: Select all

...
put fld "ImageData" into YourVariable
filter lines of YourVariable with ("*" & img2Display & "*")
## Filter will only keep the lines matching your parameters in the variable or field:
if YourVariable <> EMPTY then
  ## YourVariable now has the SAME content as ImgData in the previous example!
end if
...
Best

Klaus

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9669
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: "Find" - in a field problems

Post by dunbarx » Fri Apr 28, 2017 2:05 pm

Hi.

Hard to decipher what is happening, since I do not have the contents of such controls of, say, fld "imageToDisplay". But the handler runs without error, once I supply the referenced controls mentioned.

This is one of those times, since you are obviously competent with LC, where you simply have to step through your handler and dig out the problem. I assume you have done this. The fact that your index seems to skip should be easily tracked down. Try it again with a "repeat with..." construction, which will manage the incrementing index automatically.

Craig

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: "Find" - in a field problems

Post by Klaus » Fri Apr 28, 2017 2:13 pm

Hi Steve,

thanks to Craig I see the problem, which I had completely overlooked before!

The loop -> repeat with t=1 to the number of items of BodySegments
does the counting for you, so your line -> add 1 to tItemNumber
will result in the problem you described -> ...every ODD numbered repeat...

No need for any manual counter when using this syntax -> repeat with ...!

Do this:

Code: Select all

...
## put 1 into ItemNo
 repeat with t = 1 to the number of items of BodySegments
     ## put item itemNo of BodySegments into SegmentVar
     put item t of BodySegments into SegmentVar
     ...
     ## add 1 to tItemNumber
end repeat 
...
Best

Klaus

sbonham
Posts: 16
Joined: Wed May 17, 2006 3:29 pm

Re: "Find" - in a field problems

Post by sbonham » Fri Apr 28, 2017 3:30 pm

Thanks guys! GREAT stuff!! Very helpful!
Have an awesome day.

AxWald
Posts: 578
Joined: Thu Mar 06, 2014 2:57 pm

Re: "Find" - in a field problems

Post by AxWald » Fri Apr 28, 2017 4:01 pm

Hi,

I got bored writing the same code over and over, so some days ago I took the time & hammered me a small function - for a very similar case. Finding an occurrence of a certain string in a certain item of a list, and returning the line number; similar to "lineoffset", but more flexible.

Since such was topic here, I'll post it. It's simple, small & fast, maybe it's of use for someone:

Code: Select all

function findLine what, myStrg, myField, theDelim
   -- finds "what" in the items of a CSV-Variable (Char-Delimited-Values) "myStrg",
   --    and returns the line number of the first find, or empty if nothing found.
   -- myField [Int]: the number of the field/ item in whom "what" should
   --    be searched. Default: 1
   -- theDelim [Str]: Anything you can set the itemdel to ;-)
   --    Exp.: ",", comma, numToChar(44) ... Default: Tab
   
   if myField is empty then put 1 into myField 
   if theDelim is empty then put tab into theDelim
   
   set itemdel to theDelim
   put 0 into myVar
   repeat for each line myLine in myStrg
      add 1 to myVar
      if (item myField of myLine) = what then return myVar
   end repeat
   
   return empty
end findLine
Have fun!
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9669
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: "Find" - in a field problems

Post by dunbarx » Fri Apr 28, 2017 6:24 pm

Rinaldi was my hero in olden times. LC pretty much put him out of business, since most of his externals are native now. But when I first migrated (mostly) from HC to LC, one of the first things I did as an exercise was to write something like his "fullFind" XFCN:

Code: Select all

function revFullFind tText,tFind,exactly --RETURNS LINE NUMBER & "," & WORD NUMBER
   put 0 into counter
   switch exactly
      case "true"
         repeat for each line tline in tText
            add 1 to counter
            if tFind = tline then
               put counter & return after tResult
            end if
         end repeat
         break
      case "false"
      case empty
         repeat for each line tline in tText
            add 1 to counter
            if tFind is in tline then
               repeat with y = 1 to the number of words in tLine
                  if word y of tLine = tFind then put y & "," after temp
               end repeat
               delete last char of temp
               put counter & "," & temp & return after tResult
               put "" into temp
            end if
         end repeat
         break
   end switch
   return tResult
end revFullFind
I use it all the time, just because I am used to how it outputs what it finds.

Craig

capellan
Posts: 654
Joined: Wed Aug 15, 2007 11:09 pm

Re: "Find" - in a field problems

Post by capellan » Sat Apr 29, 2017 1:43 am

I am surprised that a control named "ImageData" does not produce
an error, because imagedata is a property of images. :shock:

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9842
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: "Find" - in a field problems

Post by FourthWorld » Sat Apr 29, 2017 5:19 am

capellan wrote:I am surprised that a control named "ImageData" does not produce
an error, because imagedata is a property of images. :shock:
Quote string values are safe. It's the unquoted values we need to worry about, which is why I advise newcomers to get into the habit of quoting literals even where LC's forgiving enough to not need the quotes, because sooner or later you'll come across a situation where they are. :)
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: "Find" - in a field problems

Post by [-hh] » Sat Apr 29, 2017 10:40 am

Hi Steve.

Probably you need speed for that in an animation.
So it may be better to use arrays so that you don't have to do a find:

-------data in fld "ImageData" looks like...---------
-------Img,190,190UpperLeg.jpg,-6,-37,8,37
-------Img,200,200ArmHandClosed.jpg,-18,-51,16,45
-------Img,200,200ArmHandOpen.jpg,-17,-46,16,49

Code: Select all

local iData

on mouseUp
  put fld "ImageData" into tmp
  repeat for each line L in tmp
    put L into iData[item 3 of L]
  end repeat
end mouseUp
Now iData is an array containing all the data (in a local variable ... or you could set a custom property to iData).
The keys are the item 3 of each line and you can simply call the values, nothing to find.

For example:

Code: Select all

  put iData[ArmPOS & "0ArmHandClosed.jpg"] into ImgData
  -- now ImgData is exactly the line you wish to "find"
  -- that is the variable in your original "find"-code
  put item 4 to 5 of ImgData into IntOffsetHV
  put item 6 to 7 of ImgData into ExtOffsetHV
HTH, Hermann
shiftLock happens

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”