R
runsun
Sun, Apr 19, 2015 2:39 AM
Spent some time digging into the built-in search()
http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Search
: search( /match_value , string_or_vector [, num_returns_per_match [,
index_col_num ] ]/ )Conclusion first: complicated, buggy, unpredictable,
giving out unnecessary warnings. Take notes for 2 points on its design:1.
match_value is set to: 1.1. Can be a single value or vector of
values. 1.2. Strings are treated as vectors-of-characters to iterate
over; 1.3. If match_value is a vector of strings, search will look for
exact string matches. In practical, match_value can be: list, number,
string (treated as a collection of characters)2. The return should be
either a list, when:/ num_returns_per_match/ is unset or set to 1:
search( "a","abcdabcd" )= [0] search( "abc","abcdabcd" )= [0, 1, 2]
or a list of lists, when:/ num_returns_per_match/ is set to anything other
than 1 : search( "a","abcdabcd",0 )= [[0, 4]] search(
"abc","abcdabcd",0 )= [[0, 4], [1, 5], [2, 6]] data4= [["a", 1], ["b",
2], ["c", 3], ["a", 4], ["b", 5]] search( "abc",data4,2 )= [[0, 3], [1,
4], [2]]Observations:A. Since a match_value is treated as a list of chars,
the following 2 should give same results: search( "abc","abcdabcd" )= [0,
1, 2] search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [],
[]]B. The following searches give same return. Users have no way to know
what are matched: search( "bc","abcdabcd" )= [1, 2] search(
"xbc","abcdabcd" )= [1, 2] search( "xbzjck","abcdabcd" )= [1, 2]C. Users
can't possibly predict the following return: data9= [ ["cat", 1], ["b",
2], ["c", 3], ["dog", 4] , ["a", 5], ["b", 6], ["c", 7],
["d", 8] , ["e", 9], ["apple", 10], ["a", 11] ] q= ["b",
"zzz", "a", "c", "apple", "dog"] search( "cat",data9 ) want: [2,4] got:
[0, 4] This also gives out a warning: WARNING: search term not
found: "t"D. This is unpredictable, too: a1=
[["ab",1],["bc",2],["cd",3]] search( "ab", a1) want: [ ] got: [0, 1]E.
This gives correct answer, but showing two warnings: WARNING: search
term not found: "p" WARNING: search term not found: "q" search(
"pq",a1 )= [ ]F. Inconsistent return when match not found: search(
"e","abcdabcd" )= [] search( ["zzz"],data9 )= [[]] Since [[]] is
treated as true, the following would be impossible: search(...) ?
do_found : do_not_foundSo what I think so far are:1) It is very difficult to
understand how it works. 2) It is still buggy.3) Would make a lot of effort
for users to understand it, and a lot of effort trying to debug, if
possible. My conclusion is that search() is still buggy and it would
probably not a good idea for it in the release yet. What I believe is that
it tries to accommodate too many usages in a single. For example,
/match_value/ could have been designed as just a value (one of number,
string or list), but not list of values. Since we have list comprehension,
it'd be extremely easy to achieve this: [ for (m in match_values) search(
m, ...) ]This will take away a large chunk of complication inside the coding
of search().
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Spent some time digging into the built-in search()
<http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Search>
: search( /*match_value* , string_or_vector [, num_returns_per_match [,
index_col_num ] ]/ )*Conclusion first:* complicated, buggy, unpredictable,
giving out unnecessary warnings. Take notes for 2 points on its design:1.
match_value is set to: 1.1. Can be a single value or vector of
values. 1.2. Strings are treated as vectors-of-characters to iterate
over; 1.3. If match_value is a vector of strings, search will look for
exact string matches. In practical, match_value can be: list, number,
string (treated as a collection of characters)2. The *return should be
either a list*, when:/ num_returns_per_match/ is unset or set to 1:
search( "a","abcdabcd" )= [0] search( "abc","abcdabcd" )= [0, 1, 2]
*or a list of lists*, when:/ num_returns_per_match/ is set to anything other
than 1 : search( "a","abcdabcd",0 )= [[0, 4]] search(
"abc","abcdabcd",0 )= [[0, 4], [1, 5], [2, 6]] data4= [["a", 1], ["b",
2], ["c", 3], ["a", 4], ["b", 5]] search( "abc",data4,2 )= [[0, 3], [1,
4], [2]]Observations:A. Since a match_value is treated as a list of chars,
the following 2 should give same results: search( "abc","abcdabcd" )= [0,
1, 2] search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [],
[]]B. The following searches give same return. Users have no way to know
what are matched: search( "bc","abcdabcd" )= [1, 2] search(
"xbc","abcdabcd" )= [1, 2] search( "xbzjck","abcdabcd" )= [1, 2]C. Users
can't possibly predict the following return: data9= [ ["cat", 1], ["b",
2], ["c", 3], ["dog", 4] , ["a", 5], ["b", 6], ["c", 7],
["d", 8] , ["e", 9], ["apple", 10], ["a", 11] ] q= ["b",
"zzz", "a", "c", "apple", "dog"] search( "cat",data9 ) want: [2,4] got:
[0, 4] This also gives out a warning: WARNING: search term not
found: "t"D. This is unpredictable, too: a1=
[["ab",1],["bc",2],["cd",3]] search( "ab", a1) want: [ ] got: [0, 1]E.
This gives correct answer, but showing two warnings: WARNING: search
term not found: "p" WARNING: search term not found: "q" search(
"pq",a1 )= [ ]F. Inconsistent return when match not found: search(
"e","abcdabcd" )= [] search( ["zzz"],data9 )= [[]] Since [[]] is
treated as true, the following would be impossible: search(...) ?
do_found : do_not_foundSo what I think so far are:1) It is very difficult to
understand how it works. 2) It is still buggy.3) Would make a lot of effort
for users to understand it, and a lot of effort trying to debug, if
possible. My conclusion is that search() is still buggy and it would
probably not a good idea for it in the release yet. What I believe is that
it tries to accommodate too many usages in a single. For example,
/match_value/ could have been designed as just a value (one of number,
string or list), but not list of values. Since we have list comprehension,
it'd be extremely easy to achieve this: [ for (m in match_values) search(
m, ...) ]This will take away a large chunk of complication inside the coding
of search().
-----
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Sun, Apr 19, 2015 3:49 AM
1.2. Strings are treated as vectors-of-characters to iterate over;
</br>
1.3. If match_value is a vector of strings, search will look for exact
string matches.
</br>
Observations:
</br>
</br>
A. Since a match_value is treated as a list of chars, the following 2
should give same results:
<pre>
<code>
search( "abc","abcdabcd" )= [0, 1, 2]
search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [], []]
See 1.3 above. "a" <> "abcdabcd"
</code>
</pre>
B. The following searches give same return. Users have no way to know what
are matched:
<pre>
<code>
search( "bc","abcdabcd" )= [1, 2]
search( "xbc","abcdabcd" )= [1, 2]
search( "xbzjck","abcdabcd" )= [1, 2]
</code>
</pre>
See 1.2 above, b is at pos 1, c is at pos 2.
wiki: By default, search only looks for one match per element of match_value
to return as a list of indices
C. Users can't possibly predict the following return:
<pre>
<code>
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
q= ["b", "zzz", "a", "c", "apple", "dog"]
search( "cat",data9 ) want: [2,4] got: [0, 4]
</code>
</pre>
This also gives out a warning: WARNING: search term not found: "t"
</br>
</br>
1.2 again, c is at 0, a is at 4, t is not found.
D. This is unpredictable, too:
<pre>
<code>
a1= [["ab",1],["bc",2],["cd",3]]
search( "ab", a1) want: [ ] got: [0, 1]
</code>
</pre>
1.2 again, a is at 0,b is at 1.
Wiki:
If num_returns_per_match = 0, search returns a list of lists of all matching
index values for each element of match_value.
index_col_num (default: 0): When string_or_vector is a vector-of-vectors,
multidimensional table or more complex list-of-lists construct, the
match_value may not be found in the first (index_col_num=0) column.
So as index_col_num=0 & num_returns_per_match=0, it looks for "a" and "b" in
the index_col_num (0) element of the vector a1. Hence [0, 1] is where it
found "a" & "b".
E. This gives correct answer, but showing two warnings:
<pre>
<code>
WARNING: search term not found: "p"
WARNING: search term not found: "q"
search( "pq",a1 )= [ ]
</code>
</pre>
So, that is what it does.??
F. Inconsistent return when match not found:
<pre>
<code>
search( "e","abcdabcd" )= []
search( ["zzz"],data9 )= want: [] got: [[]]
</code>
</pre>
Since [[]] is treated as true, the following would be impossible:
<pre>
<code>
search(...) ? do_found : do_not_found
</code>
</pre>
Wiki:
If num_returns_per_match = 0, search returns a list of lists of all matching
index values for each element of match_value.
It returna a list, the outside [ ... ], of lists of all matching values, no
match=[], hence [ [] ].
So what I think so far are:
</br>
- It is very difficult to understand how it works.
</br>
- Would make a lot of effort for users to understand it, and a lot of
effort trying to debug, if possible.
</br>
Yes & No (no need to debug)
My conclusion is that search() is still buggy and it would probably not a
good idea for it in the release yet.
</br>
It has been released for a looong time. I suspect you may be reacting to the
change to remove the Warnings??
What I believe is that it tries to accommodate too many usages in a single
function. For example,
could have been designed as just a value (one of number, string or list),
but not list of values. Since we have list comprehension, it'd be
extremely easy to achieve this:
<pre>
<code>
[ for (m in match_values) search( m, ...) ]
</code>
</pre>
This will take away a large chunk of complication inside the coding of
search().
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12422.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
runsun wrote
> 1.2. Strings are treated as vectors-of-characters to iterate over;
> </br>
> 1.3. If match_value is a vector of strings, search will look for exact
> string matches.
> </br>
> Observations:
> </br>
> </br>
> A. Since a match_value is treated as a list of chars, the following 2
> should give same results:
> <pre>
> <code>
> search( "abc","abcdabcd" )= [0, 1, 2]
> search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [], []]
See 1.3 above. "a" <> "abcdabcd"
>
> </code>
> </pre>
> B. The following searches give same return. Users have no way to know what
> are matched:
> <pre>
> <code>
> search( "bc","abcdabcd" )= [1, 2]
> search( "xbc","abcdabcd" )= [1, 2]
> search( "xbzjck","abcdabcd" )= [1, 2]
> </code>
> </pre>
See 1.2 above, b is at pos 1, c is at pos 2.
wiki: By default, search only looks for one match per element of match_value
to return as a list of indices
> C. Users can't possibly predict the following return:
> <pre>
> <code>
> data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
> , ["a", 5], ["b", 6], ["c", 7], ["d", 8]
> , ["e", 9], ["apple", 10], ["a", 11] ]
> q= ["b", "zzz", "a", "c", "apple", "dog"]
>
> search( "cat",data9 ) want: [2,4] got: [0, 4]
> </code>
> </pre>
>
> This also gives out a warning: WARNING: search term not found: "t"
> </br>
> </br>
1.2 again, c is at 0, a is at 4, t is not found.
> D. This is unpredictable, too:
> <pre>
> <code>
> a1= [["ab",1],["bc",2],["cd",3]]
>
> search( "ab", a1) want: [ ] got: [0, 1]
> </code>
> </pre>
1.2 again, a is at 0,b is at 1.
Wiki:
If num_returns_per_match = 0, search returns a list of lists of all matching
index values for each element of match_value.
index_col_num (default: 0): When string_or_vector is a vector-of-vectors,
multidimensional table or more complex list-of-lists construct, the
match_value may not be found in the first (index_col_num=0) column.
So as index_col_num=0 & num_returns_per_match=0, it looks for "a" and "b" in
the index_col_num (0) element of the vector a1. Hence [0, 1] is where it
found "a" & "b".
> E. This gives correct answer, but showing two warnings:
> <pre>
> <code>
> WARNING: search term not found: "p"
> WARNING: search term not found: "q"
>
> search( "pq",a1 )= [ ]
> </code>
> </pre>
So, that is what it does.??
> F. Inconsistent return when match not found:
> <pre>
> <code>
> search( "e","abcdabcd" )= []
> search( ["zzz"],data9 )= want: [] got: [[]]
> </code>
> </pre>
> Since [[]] is treated as true, the following would be impossible:
> <pre>
> <code>
> search(...) ? do_found : do_not_found
> </code>
> </pre>
Wiki:
If num_returns_per_match = 0, search returns a list of lists of all matching
index values for each element of match_value.
It returna a list, the outside [ ... ], of lists of all matching values, no
match=[], hence [ [] ].
> So what I think so far are:
> </br>
> 1) It is very difficult to understand how it works.
> </br>
Yes.
> 2) It is still buggy.
> </br>
No.
> 3) Would make a lot of effort for users to understand it, and a lot of
> effort trying to debug, if possible.
> </br>
Yes & No (no need to debug)
> My conclusion is that search() is still buggy and it would probably not a
> good idea for it in the release yet.
> </br>
It has been released for a looong time. I suspect you may be reacting to the
change to remove the Warnings??
> What I believe is that it tries to accommodate too many usages in a single
> function. For example,
/
> match_value
/
> could have been designed as just a value (one of number, string or list),
> but not list of values. Since we have list comprehension, it'd be
> extremely easy to achieve this:
> <pre>
> <code>
> [ for (m in match_values) search( m, ...) ]
> </code>
> </pre>
> This will take away a large chunk of complication inside the coding of
> search().
-----
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12422.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
AP
Andrew Plumb
Sun, Apr 19, 2015 4:47 AM
Hi Runsun,
Let me lead by saying thank you for taking the time to collect and share your thoughts and observations. It is very much appreciated!
A few comments/history behind my original writing of search():
When I wrote it (in 2012):
1. The ‘undef’ didn’t exist as a return option so I settled on returning empty lists which could be detected (list of length 0) as ‘no match’ conditions - it predated the Value rewrite of the code-base.
2. The ‘concat’ list construction operator didn’t exist; I needed a way to search for a string-of-characters (aka. an ordered list of character values) and get the results back in order, as a list.
3. The ‘let’ operator didn’t exist.
4. Lists were statically defined; [ for() … ] dynamically generated lists weren’t possible.
5. Function recursion was (and still is to some degree) dog-slow for more ‘elegant’ list construction approaches.
6. The text() module didn’t exist.
- See example023.scad combined with MCAD/fonts.scad for insight into how I was generating text, and the original motivation behind coding up search().
7. The no-match warnings are gone as of last week; you’ll have to build from source to see that.
It’s not buggy, just written within the constraints of the time. ;-)
All that said, I agree that now would be a good time to simplify+rewrite!
Rough outline of hypothetical simplified behaviour I’ll start looking at implementing:
- search( substring, string):
- return list of substring match indices
Example 1:
string1=”abcdabcabcdd”;
search(“abc”,string1);
[0,4,7]
search(“efg”,string1);
undef
- search( fullstring, vector_of_strings):
- return list of indices (set of ‘i’ values) where fullstring == vector_of_strings[i]
- do not attempt substring matches since [ for() …] list traversal and construction works
Example 2:
list2=[“caterpillar”,3,”cat”,2,”dog”,2,”cattle”,5,”cod”,42];
search(“cat”, list2);
[2]
search(2,list2);
[3,5]
search(“bird”,list2);
undef
- search( match_value, vector_of_vectors [, index_col_num] ):
- return list of indices (set of ‘i’ values) where match_value == vector[i][index_col_num]
- this simplification should make it even more powerful+useful for hash-style table lookup operations
Example 3:
table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
search(“cat”, table3);
[1]
search(2,table3,1);
[1,2]
search(“bird",table3);
undef
- search( match_vector, string_or_vector [, index_col_num]):
- deprecate confusing legacy behaviour
Example 4:
search([“abc”],string1);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
search([“cat”],list2);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
search([“cat”],table3);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
Just to re-iterate, thank you for taking the time to collect and share your thoughts and observations. Please do continue this!
This is very much in the spirit of keeping OpenSCAD compact, more synthesizable HDL-like than bloating into a poor substitute for a scripting language like Python.
Gotta pick your battles. :-)
Andrew.
On Apr 18, 2015, at 10:39 PM, runsun runsun@gmail.com wrote:
Spent some time digging into the built-in search() http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Search :
search( match_value , string_or_vector [, num_returns_per_match [, index_col_num ] ] )
Conclusion first: complicated, buggy, unpredictable, giving out unnecessary warnings.
Take notes for 2 points on its design:
-
match_value is set to:
1.1. Can be a single value or vector of values.
1.2. Strings are treated as vectors-of-characters to iterate over;
1.3. If match_value is a vector of strings, search will look for exact string matches.
In practical, match_value can be: list, number, string (treated as a collection of characters)
-
The return should be either a list, when: num_returns_per_match is unset or set to 1:
search( "a","abcdabcd" )= [0]
search( "abc","abcdabcd" )= [0, 1, 2]
or a list of lists, when: num_returns_per_match is set to anything other than 1 :
search( "a","abcdabcd",0 )= [[0, 4]]
search( "abc","abcdabcd",0 )= [[0, 4], [1, 5], [2, 6]]
data4= [["a", 1], ["b", 2], ["c", 3], ["a", 4], ["b", 5]]
search( "abc",data4,2 )= [[0, 3], [1, 4], [2]]
Observations:
A. Since a match_value is treated as a list of chars, the following 2 should give same results:
search( "abc","abcdabcd" )= [0, 1, 2]
search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [], []]
B. The following searches give same return. Users have no way to know what are matched:
search( "bc","abcdabcd" )= [1, 2]
search( "xbc","abcdabcd" )= [1, 2]
search( "xbzjck","abcdabcd" )= [1, 2]
C. Users can't possibly predict the following return:
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
q= ["b", "zzz", "a", "c", "apple", "dog"]
search( "cat",data9 ) want: [2,4] got: [0, 4]
This also gives out a warning: WARNING: search term not found: "t"
D. This is unpredictable, too:
a1= [["ab",1],["bc",2],["cd",3]]
search( "ab", a1) want: [ ] got: [0, 1]
E. This gives correct answer, but showing two warnings:
WARNING: search term not found: "p"
WARNING: search term not found: "q"
search( "pq",a1 )= [ ]
F. Inconsistent return when match not found:
search( "e","abcdabcd" )= []
search( ["zzz"],data9 )= [[]]
Since [[]] is treated as true, the following would be impossible:
search(...) ? do_found : do_not_found
So what I think so far are:
- It is very difficult to understand how it works.
- It is still buggy.
- Would make a lot of effort for users to understand it, and a lot of effort trying to debug, if possible.
My conclusion is that search() is still buggy and it would probably not a good idea for it in the release yet.
What I believe is that it tries to accommodate too many usages in a single. For example, match_value could have been designed as just a value (one of number, string or list), but not list of values. Since we have list comprehension, it'd be extremely easy to achieve this:
[ for (m in match_values) search( m, ...) ]
This will take away a large chunk of complication inside the coding of search().
$ http://forum.openscad.org/mailing_list/MailingListOptions.jtp?forum=1 Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github https://github.com/runsun/openscad_doctest, Thingiverse https://www.thingiverse.com/thing:410831 )
$ -- hash parameter model: here http://forum.openscad.org/parameterized-models-td8303.html#a8306, here http://forum.openscad.org/Can-I-get-some-code-review-up-in-here-tp12341p12355.html
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
View this message in context: Digging into search( ) http://forum.openscad.org/Digging-into-search-tp12421.html
Sent from the OpenSCAD mailing list archive http://forum.openscad.org/ at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Hi Runsun,
Let me lead by saying thank you for taking the time to collect and share your thoughts and observations. It is very much appreciated!
A few comments/history behind my original writing of search():
When I wrote it (in 2012):
1. The ‘undef’ didn’t exist as a return option so I settled on returning empty lists which could be detected (list of length 0) as ‘no match’ conditions - it predated the Value rewrite of the code-base.
2. The ‘concat’ list construction operator didn’t exist; I needed a way to search for a string-of-characters (aka. an ordered list of character values) and get the results back in order, as a list.
3. The ‘let’ operator didn’t exist.
4. Lists were statically defined; [ for() … ] dynamically generated lists weren’t possible.
5. Function recursion was (and still is to some degree) dog-slow for more ‘elegant’ list construction approaches.
6. The text() module didn’t exist.
- See example023.scad combined with MCAD/fonts.scad for insight into how I was generating text, and the original motivation behind coding up search().
7. The no-match warnings are gone as of last week; you’ll have to build from source to see that.
It’s not buggy, just written within the constraints of the time. ;-)
All that said, I agree that now would be a good time to simplify+rewrite!
Rough outline of hypothetical simplified behaviour I’ll start looking at implementing:
1. search( substring, string):
- return list of substring match indices
Example 1:
string1=”abcdabcabcdd”;
search(“abc”,string1);
[0,4,7]
search(“efg”,string1);
undef
2. search( fullstring, vector_of_strings):
- return list of indices (set of ‘i’ values) where fullstring == vector_of_strings[i]
- do not attempt substring matches since [ for() …] list traversal and construction works
Example 2:
list2=[“caterpillar”,3,”cat”,2,”dog”,2,”cattle”,5,”cod”,42];
search(“cat”, list2);
[2]
search(2,list2);
[3,5]
search(“bird”,list2);
undef
3. search( match_value, vector_of_vectors [, index_col_num] ):
- return list of indices (set of ‘i’ values) where match_value == vector[i][index_col_num]
- this simplification should make it even more powerful+useful for hash-style table lookup operations
Example 3:
table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
search(“cat”, table3);
[1]
search(2,table3,1);
[1,2]
search(“bird",table3);
undef
4. search( match_vector, string_or_vector [, index_col_num]):
- deprecate confusing legacy behaviour
Example 4:
search([“abc”],string1);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
search([“cat”],list2);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
search([“cat”],table3);
undef // Throw WARNING about deprecated usage; use new list comprehension capabilities.
Just to re-iterate, thank you for taking the time to collect and share your thoughts and observations. Please *do* continue this!
This is very much in the spirit of keeping OpenSCAD compact, more synthesizable HDL-like than bloating into a poor substitute for a scripting language like Python.
Gotta pick your battles. :-)
Andrew.
> On Apr 18, 2015, at 10:39 PM, runsun <runsun@gmail.com> wrote:
>
>
> Spent some time digging into the built-in search() <http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Search> :
>
> search( match_value , string_or_vector [, num_returns_per_match [, index_col_num ] ] )
>
> Conclusion first: complicated, buggy, unpredictable, giving out unnecessary warnings.
>
>
> Take notes for 2 points on its design:
>
> 1. match_value is set to:
>
> 1.1. Can be a single value or vector of values.
> 1.2. Strings are treated as vectors-of-characters to iterate over;
> 1.3. If match_value is a vector of strings, search will look for exact string matches.
>
> In practical, match_value can be: list, number, string (treated as a collection of characters)
>
> 2. The return should be either a list, when: num_returns_per_match is unset or set to 1:
>
> search( "a","abcdabcd" )= [0]
> search( "abc","abcdabcd" )= [0, 1, 2]
>
> or a list of lists, when: num_returns_per_match is set to anything other than 1 :
>
> search( "a","abcdabcd",0 )= [[0, 4]]
> search( "abc","abcdabcd",0 )= [[0, 4], [1, 5], [2, 6]]
>
> data4= [["a", 1], ["b", 2], ["c", 3], ["a", 4], ["b", 5]]
> search( "abc",data4,2 )= [[0, 3], [1, 4], [2]]
>
>
>
> Observations:
>
> A. Since a match_value is treated as a list of chars, the following 2 should give same results:
>
> search( "abc","abcdabcd" )= [0, 1, 2]
> search( ["a","b","c"],"abcdabcd" ) want: [0, 1, 2] got: [[], [], []]
>
> B. The following searches give same return. Users have no way to know what are matched:
>
> search( "bc","abcdabcd" )= [1, 2]
> search( "xbc","abcdabcd" )= [1, 2]
> search( "xbzjck","abcdabcd" )= [1, 2]
>
> C. Users can't possibly predict the following return:
>
> data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
> , ["a", 5], ["b", 6], ["c", 7], ["d", 8]
> , ["e", 9], ["apple", 10], ["a", 11] ]
> q= ["b", "zzz", "a", "c", "apple", "dog"]
>
> search( "cat",data9 ) want: [2,4] got: [0, 4]
>
> This also gives out a warning: WARNING: search term not found: "t"
>
> D. This is unpredictable, too:
>
> a1= [["ab",1],["bc",2],["cd",3]]
>
> search( "ab", a1) want: [ ] got: [0, 1]
>
> E. This gives correct answer, but showing two warnings:
>
> WARNING: search term not found: "p"
> WARNING: search term not found: "q"
>
> search( "pq",a1 )= [ ]
>
> F. Inconsistent return when match not found:
>
> search( "e","abcdabcd" )= []
> search( ["zzz"],data9 )= [[]]
>
> Since [[]] is treated as true, the following would be impossible:
>
> search(...) ? do_found : do_not_found
>
>
> So what I think so far are:
>
> 1) It is very difficult to understand how it works.
> 2) It is still buggy.
> 3) Would make a lot of effort for users to understand it, and a lot of effort trying to debug, if possible.
>
> My conclusion is that search() is still buggy and it would probably not a good idea for it in the release yet.
>
> What I believe is that it tries to accommodate too many usages in a single. For example, match_value could have been designed as just a value (one of number, string or list), but not list of values. Since we have list comprehension, it'd be extremely easy to achieve this:
>
> [ for (m in match_values) search( m, ...) ]
>
> This will take away a large chunk of complication inside the coding of search().
>
>
> $ <http://forum.openscad.org/mailing_list/MailingListOptions.jtp?forum=1> Runsun Pan, PhD
> $ -- OpenScad_DocTest: doc and unit test ( Github <https://github.com/runsun/openscad_doctest>, Thingiverse <https://www.thingiverse.com/thing:410831> )
> $ -- hash parameter model: here <http://forum.openscad.org/parameterized-models-td8303.html#a8306>, here <http://forum.openscad.org/Can-I-get-some-code-review-up-in-here-tp12341p12355.html>
> $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
>
> View this message in context: Digging into search( ) <http://forum.openscad.org/Digging-into-search-tp12421.html>
> Sent from the OpenSCAD mailing list archive <http://forum.openscad.org/> at Nabble.com.
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
R
runsun
Sun, Apr 19, 2015 7:37 PM
Hi Michael, thx for your quick reply. It reveals to me that, even after I
spent a lot of effort doing relatively extensive tests trying to understand
how to use search(), I still miss something:
(1) search( "abc","abcdabcd" )= [0, 1, 2]
(2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
but the 2nd will match the entire "abcdabcd".
That is, given a whole string will match partial string, but given a list
of partial strings will match the whole string. This already complicated
enough.
I am pretty sure that it already pass the boundary of my limited brain
power. But that's not where the complication stops.
(3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[], [],
[]]
Didn't we say " If match_value is a vector of strings, search will look for
exact string matches" ???
Where is the exact string match of the 3rd item, "abcdabcd" ?
(4) And another one:
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
search( "act", data9, 0 )
| want:
| [[0, 4, 9, 10], [0, 2, 6], [0]]
| got:
| [[4, 9, 10], [0, 2, 6], []]
As we mentioned, "act" is treated as vector of chars, and iterate over. It
means, "a" and "t"
should have found a match in ["cat",1], but they don't.
(5) Another example:
search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0], [0, 1]]
| got:
| [[0], [1]]
search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0, 1], [1, 2]]
| got:
| [[1], [2]]
It seems to me that, other than the already-complicated rule: "given a
whole string will match partial string, but given a list of partial strings
will match the whole string", in come cases it matches an item of a list of
strings to the BEGINNING of a whole string.
Up to this point, I am too tired trying to figure out yet another rule.
You mentioned : " I suspect you may be reacting to the change to remove the
Warnings?? "
Well, in fact, I haven't even started covering it yet. In the 2nd argument,
/string_or_vectors/, I only covered string and "list of lists", [ ["abc",1],
["def",2]...]. I haven't even covered my real concern : a flat list: [
"abc",1, "def",2... ], where my original "request of suppressing warning"
lies on.
Besides, I am using a nightly version in which the warning that bothered me
in the first place has already been fixed.
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12432.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Hi Michael, thx for your quick reply. It reveals to me that, even after I
spent a lot of effort doing relatively extensive tests trying to understand
how to use search(), I still miss something:
(1) search( "abc","abcdabcd" )= [0, 1, 2]
(2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
but the 2nd will match the entire "abcdabcd".
That is, *given a whole string will match partial string, but given a list
of partial strings will match the whole string*. This already complicated
enough.
I am pretty sure that it already pass the boundary of my limited brain
power. But that's not where the complication stops.
(3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[], [],
[]]
Didn't we say " If match_value is a vector of strings, search will look for
exact string matches" ???
Where is the exact string match of the 3rd item, "abcdabcd" ?
(4) And another one:
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
search( "act", data9, 0 )
| want:
| [[0, 4, 9, 10], [0, 2, 6], [0]]
| got:
| [[4, 9, 10], [0, 2, 6], []]
As we mentioned, "act" is treated as vector of chars, and iterate over. It
means, "a" and "t"
should have found a match in ["cat",1], but they don't.
(5) Another example:
search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0], [0, 1]]
| got:
| [[0], [1]]
search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0, 1], [1, 2]]
| got:
| [[1], [2]]
It seems to me that, other than the already-complicated rule: "*given a
whole string will match partial string, but given a list of partial strings
will match the whole string*", in come cases it matches an item of a list of
strings to the *BEGINNING of a whole string*.
Up to this point, I am too tired trying to figure out yet another rule.
You mentioned : " I suspect you may be reacting to the change to remove the
Warnings?? "
Well, in fact, I haven't even started covering it yet. In the 2nd argument,
/string_or_vectors/, I only covered string and "list of lists", [ ["abc",1],
["def",2]...]. I haven't even covered my real concern : a flat list: [
"abc",1, "def",2... ], where my original "request of suppressing warning"
lies on.
Besides, I am using a nightly version in which the warning that bothered me
in the first place has already been fixed.
-----
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12432.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Sun, Apr 19, 2015 8:30 PM
Yes, search is way too complicated for me to use as well. I just roll my
own with recursion if I need to search.
On 19 April 2015 at 20:37, runsun runsun@gmail.com wrote:
Hi Michael, thx for your quick reply. It reveals to me that, even after I
spent a lot of effort doing relatively extensive tests trying to understand
how to use search(), I still miss something:
(1) search( "abc","abcdabcd" )= [0, 1, 2]
(2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
but the 2nd will match the entire "abcdabcd".
That is, given a whole string will match partial string, but given a list
of partial strings will match the whole string. This already complicated
enough.
I am pretty sure that it already pass the boundary of my limited brain
power. But that's not where the complication stops.
(3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[], [],
[]]
Didn't we say " If match_value is a vector of strings, search will look for
exact string matches" ???
Where is the exact string match of the 3rd item, "abcdabcd" ?
(4) And another one:
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
search( "act", data9, 0 )
| want:
| [[0, 4, 9, 10], [0, 2, 6], [0]]
| got:
| [[4, 9, 10], [0, 2, 6], []]
As we mentioned, "act" is treated as vector of chars, and iterate over. It
means, "a" and "t"
should have found a match in ["cat",1], but they don't.
(5) Another example:
search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0], [0, 1]]
| got:
| [[0], [1]]
search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0, 1], [1, 2]]
| got:
| [[1], [2]]
It seems to me that, other than the already-complicated rule: "given a
whole string will match partial string, but given a list of partial strings
will match the whole string", in come cases it matches an item of a list
of
strings to the BEGINNING of a whole string.
Up to this point, I am too tired trying to figure out yet another rule.
You mentioned : " I suspect you may be reacting to the change to remove the
Warnings?? "
Well, in fact, I haven't even started covering it yet. In the 2nd argument,
/string_or_vectors/, I only covered string and "list of lists", [
["abc",1],
["def",2]...]. I haven't even covered my real concern : a flat list: [
"abc",1, "def",2... ], where my original "request of suppressing warning"
lies on.
Besides, I am using a nightly version in which the warning that bothered me
in the first place has already been fixed.
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context:
http://forum.openscad.org/Digging-into-search-tp12421p12432.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Yes, search is way too complicated for me to use as well. I just roll my
own with recursion if I need to search.
On 19 April 2015 at 20:37, runsun <runsun@gmail.com> wrote:
> Hi Michael, thx for your quick reply. It reveals to me that, even after I
> spent a lot of effort doing relatively extensive tests trying to understand
> how to use search(), I still miss something:
>
> (1) search( "abc","abcdabcd" )= [0, 1, 2]
> (2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
>
> The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
> but the 2nd will match the entire "abcdabcd".
>
> That is, *given a whole string will match partial string, but given a list
> of partial strings will match the whole string*. This already complicated
> enough.
>
> I am pretty sure that it already pass the boundary of my limited brain
> power. But that's not where the complication stops.
>
> (3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[], [],
> []]
>
> Didn't we say " If match_value is a vector of strings, search will look for
> exact string matches" ???
>
> Where is the exact string match of the 3rd item, "abcdabcd" ?
>
> (4) And another one:
>
> data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
> , ["a", 5], ["b", 6], ["c", 7], ["d", 8]
> , ["e", 9], ["apple", 10], ["a", 11] ]
>
> search( "act", data9, 0 )
> | want:
> | [[0, 4, 9, 10], [0, 2, 6], [0]]
> | got:
> | [[4, 9, 10], [0, 2, 6], []]
>
> As we mentioned, "act" is treated as vector of chars, and iterate over. It
> means, "a" and "t"
> should have found a match in ["cat",1], but they don't.
>
> (5) Another example:
>
> search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
> | want:
> | [[0], [0, 1]]
> | got:
> | [[0], [1]]
> search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
> | want:
> | [[0, 1], [1, 2]]
> | got:
> | [[1], [2]]
>
> It seems to me that, other than the already-complicated rule: "*given a
> whole string will match partial string, but given a list of partial strings
> will match the whole string*", in come cases it matches an item of a list
> of
> strings to the *BEGINNING of a whole string*.
>
> Up to this point, I am too tired trying to figure out yet another rule.
>
> You mentioned : " I suspect you may be reacting to the change to remove the
> Warnings?? "
>
> Well, in fact, I haven't even started covering it yet. In the 2nd argument,
> /string_or_vectors/, I only covered string and "list of lists", [
> ["abc",1],
> ["def",2]...]. I haven't even covered my real concern : a flat list: [
> "abc",1, "def",2... ], where my original "request of suppressing warning"
> lies on.
>
> Besides, I am using a nightly version in which the warning that bothered me
> in the first place has already been fixed.
>
>
>
> -----
>
> $ Runsun Pan, PhD
>
> $ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
>
> $ -- hash parameter model: here , here
>
> $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
>
>
>
>
> --
> View this message in context:
> http://forum.openscad.org/Digging-into-search-tp12421p12432.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
R
runsun
Sun, Apr 19, 2015 10:22 PM
Hi Andrew, thx for your effort to make search() in the first place.
I forgot to mention that:
(1) my tests were done with the new nightly built, after the unnecessary
Wanring is supposed to be suppressed (but, as you can see in my examples
above, there are at least two more warnings)
(2) Judging from all examples on the doc, I assume that the design of
search() aims at searching matches against a list of lists/vectors:
[ ["abc",1],["def",2] ...] #1
but not from a flat list:
[ "abc",1, "def",2 ...] #2
Therefore, my tests haven't covered #2 situation yet. But as you can see,
it's already complicated enough.
I understand that it's not fair to judge its features based on the current
spirit of OpenSCAD, since the OpenSCAD has been upgraded a lot. It's good to
know that a change in the implementation is under considerations.
clothbot wrote
- search( substring, string):
- return list of substring match indices
Example 1:
string1=”abcdabcabcdd”;
search(“abc”,string1);
[0,4,7]
search(“efg”,string1);
undef
What's the answer to : search( "ae", string1 ) ? will it be [0, undef] ? or
just [0] ?
If it's just [0] (means, the unmatched will just no-show), then, users won't
be able to tell what are actually matched ( [0] for "a" or for "e" ???)
Note that this, in fact, is doing list comprehension's job :
abc = "abc";
[ for( i=[0:len(abc)-1] ) search( abc[i], string1) ]
means that it is still redundant. I'd suggest to get rid of this feature
completely. Means, when match_value="abc", just search for "abc", but not
"a", "b", "c".
clothbot wrote
- search( fullstring, vector_of_strings):
- return list of indices (set of ‘i’ values) where fullstring ==
vector_of_strings[i]
- do not attempt substring matches since [ for() …] list traversal and
construction works
Example 2:
list2=[“caterpillar”,3,”cat”,2,”dog”,2,”cattle”,5,”cod”,42];
search(“cat”, list2);
[2]
search(2,list2);
[3,5]
search(“bird”,list2);
undef
I see that list2 is a flat list. This is new to the original design. Will it
be treated the same way in ALL situations as a list of vectors ?
clothbot wrote
- search( match_value, vector_of_vectors [, index_col_num] ):
- return list of indices (set of ‘i’ values) where match_value ==
vector[i][index_col_num]
- this simplification should make it even more powerful+useful for
hash-style table lookup operations
Example 3:
table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
search(“cat”, table3);
[1]
search(2,table3,1);
[1,2]
search(“bird",table3);
undef
I believe the 2nd case should have read: search(2,table3,1,1)
Also note that this will create confusion with Example 1, since in Example
1, a string is treated as a collection of chars, but here it's treated as a
whole. It'd be extremely hard for users to remember that.
Still, I'd strongly suggest that not to try to treat a string as iteratible.
Iterating though a string match_value creates lots of problems, it's hard
for users to understand in the firsts place, and it's hard to come up with a
clear answer (See Example 1 above). Thus users might as well roll up their
own. IMHO, that defeats the purpose of making it a built-in.
SIDE NOTE: Judging from the existence of lookup and search as built-ins,
I strongly believe that a hash-like data structure is needed:
h={ abc:1, def:2 }
h["abc"]
g = update(h, {ghi:3} )
g
[ ["abc",1], ["def",2], ["ghi",3] ]
Hi Andrew, thx for your effort to make search() in the first place.
I forgot to mention that:
(1) my tests were done with the new nightly built, after the unnecessary
Wanring is supposed to be suppressed (but, as you can see in my examples
above, there are at least two more warnings)
(2) Judging from all examples on the doc, I assume that the design of
search() aims at searching matches against a list of lists/vectors:
[ ["abc",1],["def",2] ...] #1
but not from a flat list:
[ "abc",1, "def",2 ...] #2
Therefore, my tests haven't covered #2 situation yet. But as you can see,
it's already complicated enough.
I understand that it's not fair to judge its features based on the current
spirit of OpenSCAD, since the OpenSCAD has been upgraded a lot. It's good to
know that a change in the implementation is under considerations.
clothbot wrote
> 1. search( substring, string):
> - return list of substring match indices
>
> Example 1:
>
> string1=”abcdabcabcdd”;
> search(“abc”,string1);
> [0,4,7]
> search(“efg”,string1);
> undef
What's the answer to : search( "ae", string1 ) ? will it be [0, undef] ? or
just [0] ?
If it's just [0] (means, the unmatched will just no-show), then, users won't
be able to tell what are actually matched ( [0] for "a" or for "e" ???)
Note that this, in fact, is doing list comprehension's job :
abc = "abc";
[ for( i=[0:len(abc)-1] ) search( abc[i], string1) ]
means that it is still redundant. I'd suggest to get rid of this feature
completely. Means, when match_value="abc", just search for "abc", but not
"a", "b", "c".
clothbot wrote
> 2. search( fullstring, vector_of_strings):
> - return list of indices (set of ‘i’ values) where fullstring ==
> vector_of_strings[i]
> - do not attempt substring matches since [ for() …] list traversal and
> construction works
>
> Example 2:
>
> list2=[“caterpillar”,3,”cat”,2,”dog”,2,”cattle”,5,”cod”,42];
> search(“cat”, list2);
> [2]
> search(2,list2);
> [3,5]
> search(“bird”,list2);
> undef
I see that list2 is a flat list. This is new to the original design. Will it
be treated the same way in ALL situations as a list of vectors ?
clothbot wrote
> 3. search( match_value, vector_of_vectors [, index_col_num] ):
> - return list of indices (set of ‘i’ values) where match_value ==
> vector[i][index_col_num]
> - this simplification should make it even more powerful+useful for
> hash-style table lookup operations
>
> Example 3:
>
> table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
> search(“cat”, table3);
> [1]
> search(2,table3,1);
> [1,2]
> search(“bird",table3);
> undef
I believe the 2nd case should have read: search(2,table3,1,1)
Also note that this will create confusion with Example 1, since in Example
1, a string is treated as a collection of chars, but here it's treated as a
whole. It'd be extremely hard for users to remember that.
Still, I'd strongly suggest that not to try to treat a string as iteratible.
Iterating though a string match_value creates lots of problems, it's hard
for users to understand in the firsts place, and it's hard to come up with a
clear answer (See Example 1 above). Thus users might as well roll up their
own. IMHO, that defeats the purpose of making it a built-in.
SIDE NOTE: Judging from the existence of *lookup* and *search* as built-ins,
I strongly believe that a hash-like data structure is needed:
> >>> h={ abc:1, def:2 }
> >>> h["abc"]
> 1
> >>> g = update(h, {ghi:3} )
> >>> g
> { abc:1, def:2, ghi:3 }
> >>> keys( g )
> ["abc","def","ghi"]
> >>> values( g )
> [1,2,3]
> >>> kvs( g )
> [ ["abc",1], ["def",2], ["ghi",3] ]
_______________________________________________
OpenSCAD mailing list
Discuss@.openscad
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-----
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12435.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Mon, Apr 20, 2015 5:24 AM
Example 3:
table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
search(“cat”, table3);
[1]
search(2,table3,1);
[1,2]
search(“bird",table3);
undef
Also note that using a flat list like above is error-prone:
table4 = [ “abc","def","def",3 ];
search( “def”,table3 )= want:[2] got:[1]
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12438.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
clothbot wrote
> Example 3:
>
> table3 =[ [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
> search(“cat”, table3);
> [1]
> search(2,table3,1);
> [1,2]
> search(“bird",table3);
> undef
Also note that using a flat list like above is error-prone:
table4 = [ “abc","def","def",3 ];
search( “def”,table3 )= want:[2] got:[1]
-----
$ Runsun Pan, PhD
$ -- OpenScad_DocTest: doc and unit test ( Github , Thingiverse )
$ -- hash parameter model: here , here
$ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12438.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Mon, Apr 20, 2015 6:44 AM
Hi Michael, thx for your quick reply. It reveals to me that, even after I
spent a lot of effort doing relatively extensive tests trying to
understand how to use search(), I still miss something:
(1) search( "abc","abcdabcd" )= [0, 1, 2]
(2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
but the 2nd will match the entire "abcdabcd".
That is,
given a whole string will match partial string, but given a list of
partial strings will match the whole string
. This already complicated enough.
(2) is Wiki: Note: If match_value is a vector of strings, search will look
for exact string matches.
I am pretty sure that it already pass the boundary of my limited brain
power. But that's not where the complication stops.
(3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[],
[], []]
Didn't we say " If match_value is a vector of strings, search will look
for exact string matches" ???
Where is the exact string match of the 3rd item, "abcdabcd" ?
Why do you expect [0]?
The "abcdabcd" not found part is unexpected. (bug or not designed for that)
(4) And another one:
data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
, ["a", 5], ["b", 6], ["c", 7], ["d", 8]
, ["e", 9], ["apple", 10], ["a", 11] ]
search( "act", data9, 0 )
| want:
| [[0, 4, 9, 10], [0, 2, 6], [0]]
| got:
| [[4, 9, 10], [0, 2, 6], []]
As we mentioned, "act" is treated as vector of chars, and iterate over. It
means, "a" and "t"
should have found a match in ["cat",1], but they don't.
wiki:
match_value:
Can be a single value or vector of values.
Strings are treated as vectors-of-characters to iterate over; the search
function does not search for substrings.
So "a" & "t" do not match "cat", but "c" does. Not saying it's sensible.
Change "cat" to "tac" and the "t" matches.
(5) Another example:
search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0], [0, 1]]
| got:
| [[0], [1]]
search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
| want:
| [[0, 1], [1, 2]]
| got:
| [[1], [2]]
It seems to me that, other than the already-complicated rule: "
given a whole string will match partial string, but given a list of
partial strings will match the whole string
", in come cases it matches an item of a list of strings to the
BEGINNING of a whole string
Seems the match is as you say, the beginning. Possibly an implementation
error when the match test was written.
Up to this point, I am too tired trying to figure out yet another rule.
You mentioned : " I suspect you may be reacting to the change to remove
the Warnings?? "
That was in regard to you saying it wasn't ready for release. So I presumed
you saw the change and assumed search() was not released yet.
Well, in fact, I haven't even started covering it yet. In the 2nd
argument,
, I only covered string and "list of lists", [ ["abc",1], ["def",2]...]. I
haven't even covered my real concern : a flat list: [ "abc",1, "def",2...
], where my original "request of suppressing warning" lies on.
Besides, I am using a nightly version in which the warning that bothered
me in the first place has already been fixed.
search() worked for what I wanted it too do. I wrote that bit at the bottom
of the wiki "Getting the right results" to figure it out myself, some time
ago.
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12439.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
runsun wrote
> Hi Michael, thx for your quick reply. It reveals to me that, even after I
> spent a lot of effort doing relatively extensive tests trying to
> understand how to use search(), I still miss something:
>
> (1) search( "abc","abcdabcd" )= [0, 1, 2]
> (2) search( ["a","b","c"],"abcdabcd" ) = [[], [], []]
>
> The 1st will match individual "a","b","c" to ANY CHARS in "abcdabcd"
> but the 2nd will match the entire "abcdabcd".
>
> That is,
*
> given a whole string will match partial string, but given a list of
> partial strings will match the whole string
*
> . This already complicated enough.
(2) is Wiki: Note: If match_value is a vector of strings, search will look
for exact string matches.
> I am pretty sure that it already pass the boundary of my limited brain
> power. But that's not where the complication stops.
>
> (3) search( ["a","bc","abcdabcd"],"abcdabcd" ) = want: [0] got: [[],
> [], []]
>
> Didn't we say " If match_value is a vector of strings, search will look
> for exact string matches" ???
>
> Where is the exact string match of the 3rd item, "abcdabcd" ?
Why do you expect [0]?
The "abcdabcd" not found part is unexpected. (bug or not designed for that)
> (4) And another one:
>
> data9= [ ["cat", 1], ["b", 2], ["c", 3], ["dog", 4]
> , ["a", 5], ["b", 6], ["c", 7], ["d", 8]
> , ["e", 9], ["apple", 10], ["a", 11] ]
>
> search( "act", data9, 0 )
> | want:
> | [[0, 4, 9, 10], [0, 2, 6], [0]]
> | got:
> | [[4, 9, 10], [0, 2, 6], []]
>
>
> As we mentioned, "act" is treated as vector of chars, and iterate over. It
> means, "a" and "t"
> should have found a match in ["cat",1], but they don't.
wiki:
match_value:
Can be a single value or vector of values.
Strings are treated as vectors-of-characters to iterate over; the search
function does not search for substrings.
So "a" & "t" do not match "cat", but "c" does. Not saying it's sensible.
Change "cat" to "tac" and the "t" matches.
>
>
> (5) Another example:
>
> search( "ab",[["ab",1],["bc",2],["cd",3]], 0 )
> | want:
> | [[0], [0, 1]]
> | got:
> | [[0], [1]]
> search( "bc",[["ab",1],["bc",2],["cd",3]], 0 )
> | want:
> | [[0, 1], [1, 2]]
> | got:
> | [[1], [2]]
>
> It seems to me that, other than the already-complicated rule: "
*
> given a whole string will match partial string, but given a list of
> partial strings will match the whole string
*
> ", in come cases it matches an item of a list of strings to the
*
> BEGINNING of a whole string
*
> .
Seems the match is as you say, the beginning. Possibly an implementation
error when the match test was written.
> Up to this point, I am too tired trying to figure out yet another rule.
>
> You mentioned : " I suspect you may be reacting to the change to remove
> the Warnings?? "
That was in regard to you saying it wasn't ready for release. So I presumed
you saw the change and assumed search() was not released yet.
> Well, in fact, I haven't even started covering it yet. In the 2nd
> argument,
/
> string_or_vectors
/
> , I only covered string and "list of lists", [ ["abc",1], ["def",2]...]. I
> haven't even covered my real concern : a flat list: [ "abc",1, "def",2...
> ], where my original "request of suppressing warning" lies on.
>
> Besides, I am using a nightly version in which the warning that bothered
> me in the first place has already been fixed.
search() worked for what I wanted it too do. I wrote that bit at the bottom
of the wiki "Getting the right results" to figure it out myself, some time
ago.
-----
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12439.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Mon, Apr 20, 2015 6:48 AM
Example 3:
table3 =[
[“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
search(“cat”, table3);
[1]
search(2,table3,1);
[1,2]
search(“bird",table3);
undef
Also note that using a flat list like above is error-prone:
table4 = [ “abc","def","def",3 ];
search( “def”,table4 )= want:[2] got:[1]
Why do you expect [2]?
[1] is the "d" of match_value "def" match to the first "def"
wiki: num_returns_per_match (default: 1)
So it only returns 1 match.
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12440.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
runsun wrote
>
> clothbot wrote
>> Example 3:
>>
>> table3 =[
>> [“caterpillar”,3],[“cat”,2],[“dog”,2],[“cattle”,5],[“cod”,42]];
>> search(“cat”, table3);
>> [1]
>> search(2,table3,1);
>> [1,2]
>> search(“bird",table3);
>> undef
> Also note that using a flat list like above is error-prone:
>
> table4 = [ “abc","def","def",3 ];
> search( “def”,table4 )= want:[2] got:[1]
Why do you expect [2]?
[1] is the "d" of match_value "def" match to the first "def"
wiki: num_returns_per_match (default: 1)
So it only returns 1 match.
-----
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12440.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Mon, Apr 20, 2015 7:01 AM
Actually I get
WARNING: Invalid entry in search vector at index 0, required number of
values in the entry: 1. Invalid entry: "abc"
table4 = [ “abc","def","def",3 ];
echo(search( “def”,table4 )); // = want:[2] got:[1]
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12441.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Actually I get
WARNING: Invalid entry in search vector at index 0, required number of
values in the entry: 1. Invalid entry: "abc"
table4 = [ “abc","def","def",3 ];
echo(search( “def”,table4 )); // = want:[2] got:[1]
-----
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.
The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/
--
View this message in context: http://forum.openscad.org/Digging-into-search-tp12421p12441.html
Sent from the OpenSCAD mailing list archive at Nabble.com.