Welcome, Guest. Please Login
Tinderbox
  News:
IMPORTANT MESSAGE! This forum has now been replaced by a new forum at http://forum.eastgate.com and no further posting or member registration is allowed. The forum is still accessible via read-only access for reference purposes. If you wish to discuss content here, please use the new forum. N.B. - posting in the new forum requires a fresh registration in the new forum (sorry - member data can't be ported).
  HomeHelpSearchLogin  
 
Pages: 1
Send Topic Print
'Set it and forget it' - for URL assembly, etc. (Read 5202 times)
Sumner Gerard
Full Member
*
Offline



Posts: 359

'Set it and forget it' - for URL assembly, etc.
Aug 03rd, 2011, 7:05pm
 
I've found TB useful for automating the construction of URLs to be fed into the browser to call up, say, a Google map, or information on a stock, etc.

The websites typically require a base URL in a specific format, to which is appended a varying number of parameters separated from each other by a special  character such as '&' or the pipe character '|'. The fact that the number of parameters in the URL can vary poses string concatenation problems that (for a non-techie like me) are not as simple as they would seem.

Here is a common problem I've encountered. The long and winding journey I took to solve it may be instructive to some on what to do (or not to do).

Say I have three string attributes, $MyStringA, $MyStringB, and $MyStringC. In some cases all three attributes have a value.  In other cases one or more of these attributes are empty, in varying combinations.

For each note, I need to output each combination delimited by '|', ignoring an attribute when it is empty, so the presence of values in A and B and C gives 'A|B|C', but the presence of values in A and C only gives 'A|C', etc.

The obvious $PrelimResult=$MyStringA+"|"+$MyStringB+"|"+$MyStringC works when all three attributes have values but yields extra "|" when some or all of the attributes are empty.  



That's ugly, plus the websites don't like it!



So then I decided I would have to call out what passes for the heavy artillery in my limited coding arsenal: the dreaded "nested if." After much fussing and counting of '}' and hunting down of missing '!' I finally got it to work:




Then I thought there's got to be an easier way, so I tried agents. I ended up with one agent for each case, like this:



That was easier to get up and running. But it still required covering each possible case and doing a lot of typing and correcting of typos. I still thought there's just got to be something better.

Though not really knowing a string from a set, and thinking of sets as useful mainly for things like tags, I remembered format() can do some interesting things in combination with sets and might put those pesky '|' in the right place. After a surprisingly smooth exploration of that thought, I ended up with this:




What I understand this does is start by placing the value of $MyStringA in $MySet if there is a value in $MyStringA and nothing in $MySet if there is no value in $MyStringA. Then to that it appends $MyStringB if there is a value in $MyStringB and appends nothing if there is no value there. Then to that it appends $MyStringC if there is a value in $MyStringC and appends nothing if there is no value there.  As it goes along it adds any necessary ';' delimiters if there is more than one member of the set.  Then the .format replaces the ';' with '|'.

It seems to be just what I needed. If so it's amazing the power a succinct line of TB code can put in the hands of a non programmer! ... If one knows where to start.

Here are the results (alas, TB insists on displaying all aliases in italics, so those '/' are really '|'):




Valid way to do this? Is there an even easier way?
Back to top
 
 
  IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: 'Set it and forget it' - for URL assembly, etc.
Reply #1 - Aug 4th, 2011, 5:55am
 
Your final technique, using ./format() works as long as as the join parameter is the same for all joins.  That's implied but not stated in your tests - otherwise it's an edge case the approach won't handle.

Sets vs. Lists. This is perhaps more confusing to longer term users of TB as the Set attribute type arrived before the List type. However, Lists are lists whilst Set are special form of List with some different properties. Sets are self de-duping and don't necessarily retain original sort order. Generally, sort order is as originally input. In real life however, clean concepts such as above are often mixed into wider processes so do think about the impact of sorting in the wider context of the TBX.

In your case, the input doesn't allow - I think - for duplicated inputs, e.g. adding C twice - but for someone else using your technique this edge case might be an issue. In such a case I'd use a List attribute instead of a Set.  

If the ordering is important to the function of the resultant URL, i.e. A-B-C works but B-C-A doesn't, then again I'd stick with a List type attribute.

If your scenario needs de-duping and sorting that's do-able with some extra coding but let's not head too far from the starting point!

As a side note, another way of making a list (or set) is this:

$MyList = $MyStringA+";"+$MyStringF+";"+$MyNumber.precision(2)+";"+.....

Why/if you might use the the latter is it simply an alternate approach to list creation. However, The method you use of '$MyList=$MyList+...' is the one to try out first.

Note that List and set values can't contain a semi-colon (backslash escaping doesn't work - I tested). A list in TB is a string composed of semicolon delimited sub-strings.
Back to top
 
« Last Edit: Aug 4th, 2011, 6:53am by Mark Anderson »  

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
Sumner Gerard
Full Member
*
Offline



Posts: 359

Re: 'Set it and forget it' - for URL assembly, etc.
Reply #2 - Aug 4th, 2011, 12:59pm
 
Thanks for the helpful comments. I'll notice ';' in everything I read now!

So it seems:

-- If I use the "recursive" method (assuming that's a proper way to describe the $MySet=$MySet+... or $MyList=$MyList+ ...) I should use a set if I want to eliminate duplication and a list if I don't care about duplication and want to be careful about specific order (though it seems in my case I can use the rule to control the order of both a set and a list).

-- If I use the "additive" method ($MySet=$MyStringA+";"+$MyStringB+";"+$MyStringC ...) , which is nicely succinct, it seems I have to use a set, as using a list results in extra ';' as shown here:



Back to top
 
 
  IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: 'Set it and forget it' - for URL assembly, etc.
Reply #3 - Aug 4th, 2011, 2:21pm
 
Sort of. In the additive method you're just adding characters to a string which becomes the list. If you include an empty string (your $MyStringB) then, self evidently you get two successive semicolons. But that doesn't matter, TB's clever enough to work out that means an empty value. Even if you format the list (whose literal value is "A;;C;") TB will return you two items not 3 as I think you're assuming.

BTW, if manually/code constructing set or list strings TB doesn't mind whether there's a semicolon after the last value.
Back to top
 
 

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
Sumner Gerard
Full Member
*
Offline



Posts: 359

Re: 'Set it and forget it' - for URL assembly, etc.
Reply #4 - Aug 4th, 2011, 3:54pm
 
Quote:
If you include an empty string (your $MyStringB) then, self evidently you get two successive semicolons. But that doesn't matter, TB's clever enough to work out that means an empty value.

I think I see. One has to apply something like  $MyResult=$MyList.format("|"), where $MyResult is a string attribute, and then TB will ignore that extra (for my purposes) ';'.  Or I suppose it's really ignoring the empty string between the successive ';'. Clever.

Curious why one ends up with two successive ';' with a list but not with a set.  Is that because it doesn't make sense, logically, to add an empty string to a set but it can be useful to allow adding an empty string to a list?

Anyway, my general takeaway: there are some potentially confusing subtleties, but using lists and sets can save a LOT of work. Thanks for clarifying.
Back to top
 
 
  IP Logged
Mark Anderson
YaBB Administrator
*
Offline

User - not staff!

Posts: 5689
Southsea, UK
Re: 'Set it and forget it' - for URL assembly, etc.
Reply #5 - Aug 4th, 2011, 4:03pm
 
Quote:
Is that because it doesn't make sense, logically, to add an empty string to a set but it can be useful to allow adding an empty string to a list?

I'd assume so. I'm just be happy that it does!

Subtleties indeed, but therein lies some of the magic of the 'deep end' of using TB to analyse out texts.
Back to top
 
 

--
Mark Anderson
TB user and Wiki Gardener
aTbRef v6
(TB consulting - email me)
WWW shoantel   IP Logged
Pages: 1
Send Topic Print