Michael von Aichberger <[EMAIL PROTECTED]> wrote: > based on 24 flags that can be set or not set, the user should be able > to define a logical formula that is used as a filter. > > My file names contain the 6-digit hex code and some other numbers > > "give me that particular picture if it has either a cat or a dog > in it and is yellow" > > I don't see why I should run through all files with the one > question and then through all the files again with the other > question.
Hi Michael, It seems to me that you need two distinct operations: * one to formulate the question * and one to ask that question of each of the files. Suppose you are working with a simpler set of criteria, with only six variables, each represented by a bit: 1: TRUE if picture includes a dog 2: TRUE if picture includes a cat 3: TRUE if picture includes a human being 4: TRUE if picture is mostly yellow 5: TRUE if picture is mostly blue 6: TRUE if picture is mostly red The bits could be called: dog cat human yellow blue green To formulate your question, you could create a list of all the numbers that would satisfy the query: Either 1 or 2 must be set to TRUE 3 can be set to TRUE or FALSE 4 must be TRUE 5 and 6 must be false since they are mutually exclusive with 4 Here are the numbers that satisfy the query: Binary Hex Decimal 010100 14 20 dog +yellow 011100 1C 28 dog+human+yellow 100100 24 36 cat +yellow 101100 2C 44 cat +human+yellow 110100 34 52 cat+dog +yellow 111100 3C 60 cat+dog+human+yellow The first operation would therefore be to build the list [20, 28, 36, 44, 52, 60] from the selection criteria. The second operation would be to test if the hex number associated with each file is one of the numbers in the list. In pseudo-Lingo: on findMatches(aSetOfCriteria) matchingImages = [] matchingNumberList = buildListOfMatchingNumbers(aSetOfCriteria) tCount = the number of images repeat with i = 1 to tCount tImage = image[i] numberPartOfImageName = getNumberPart(tImage.name) if matchingNumberList.getPos(numberPartOfImageName) then matchingImages.append(tImage) end if end repeat return matchingImages end The question then becomes: how do you code the buildListOfMatchingNumbers() handler? > I don't see why I should run through all files with the one > question and then through all the files again with the other > question. Using the two operations I described above, you won't need to run through all the *files* more than once, but you will need a multiple-pass system for determining all the numbers that match the query. It is easy to deal queries that are formulated in terms of MUST, MUST NOT and IRRELEVANT. However, your initial query also includes a condition: if not dog then cat. This is much harder to deal with, but it can be broken down into two queries each of which uses MUST, MUST NOT and IRRELEVANT. The items in the two results may overlap: > "give me that particular picture if it has either a cat or a dog > in it and is yellow" 1: "give me that particular picture if it has a CAT in it and is YELLOW" 2: "give me that particular picture if it has a DOG in it and is YELLOW" Combining the results will give you duplicates where there is both a cat and a dog. It is easy enough to filter out such duplicates. Your buildListOfMatchingNumbers() handler could look like this: on buildListOfMatchingNumbers(aSetOfCriteria, aMatchesList) ---------- -- INPUT: <aSetOfCriteria> should be a list with the format -- [<0 | 1 | 2>, <0 | 1 | 2>, ... <0 | 1 | 2>], where -- there are the same number of items as there are criteria -- for the user to choose from, and where the values -- indicate: -- 0: MUST NOT -- 1: MUST -- 2: IRRELEVANT (either) -- It can also be a list of such lists, in which case, each -- sub-list is treated recursively and the results -- accumulated -- <aMatchesList> may be a linear list of numbers -- OUTPUT: <aMatchesList>, the linear list of numbers which -- match the search criteria --------------------------------------------------------------------- if ilk(aSetOfCriteria) <> #list then -- Can't proceed exit else if not aSetOfCriteria.count then -- There are no criteria exit end if if ilk(aMatchesList) <> #list then aMatchesList = [] aMatchesList.sort() end if -- Determine whether this is a list of integers or a list of lists i = aSetOfCriteria.count tItem = aSetOfCriteria[1] if ilk(tItem, #list) then -- Consider aSetOfCriteria to be a list of lists: treat each -- each item separately using recursion repeat while i buildListOfMatchingNumbers(aSetOfCriteria[i], aMatchesList) i = i - 1 end repeat return aMatchesList else -- Consider aSetOfCriteria to be a list of integers: create the -- list of numbers associated with the query. tList = [0] tCount = 1 tPower = 1 repeat while i tValue = aSetOfCriteria[i] case tValue of 0: -- MUST NOT: leave this bit value at 0 1: -- MUST: set this bit value to 1 repeat with j = 1 to tCount tList[j] = tList[j] + tPower end repeat 2: -- IRRELEVANT (either): set bit value to 1 and 0 repeat with j = 1 to tCount tList.append(tList[j]) -- add new item with bit at 0 tList[j] = tList[j] + tPower -- set bit to 1 end repeat tCount = tCount * 2 -- we've doubled the items in the list end case tPower = tPower * 2 -- value of next bit to be set i = i - 1 end repeat -- Add items in tList to aMatchesList, ignoring any duplicates i = tList.count repeat while i tMatch = tList[i] if not aMatchesList.getPos(tMatch) then aMatchesList.add(tMatch) end if i = i - 1 end repeat return aMatchesList end if end buildListOfMatchingNumbers Test this by typing the following into the Message window: tCatsAndMaybeDogs = [1,2,2,1,0,0] -- maybe humans, must be yellow tDogsAndMaybeCats = [2,1,2,1,0,0] -- maybe humans, must be yellow put buildListOfMatchingNumbers([tCatsAndMaybeDogs, tDogsAndMaybeCats]) -- [20, 28, 36, 44, 52, 60] Is this the sort of answer you were looking for? Cheers, James [To remove yourself from this list, or to change to digest mode, go to http://www.penworks.com/lingo-l.cgi To post messages to the list, email [EMAIL PROTECTED] (Problems, email [EMAIL PROTECTED]). Lingo-L is for learning and helping with programming Lingo. Thanks!]