An almost beginner-level question

218 views
Skip to first unread message

Kevin Doiron

unread,
Apr 3, 2017, 4:20:32 PM4/3/17
to Pick and MultiValue Databases
Hi everyone,

I'm finding myself back in the Pick world after an extended absence to work on other systems. It's almost like riding a bicycle, but a few things keep throwing me off, especially the syntax differences between UniBasic and Python (where I was focused for the last decade),

Anyway, I'm reviewing some code that I need to figure out, and I came across the following line:
  • LOCATE('!@#$',SOMEDATA<1>,1;PCNT) ELSE PCNT=PCNT-1

In this case, "SOMEDATA" is a single attribute data item, with multiple values (e.g., '413ý428ý457'), that seems to be sorted in ascending order. Of course, my target string ('!@#$') does nt exist in this attribute.  As a result, PCNT has a value of 3 after this command. I've been able to figure out that the command is effectively saying "tell me how many values are in this attribute", but is there a reason (perhaps performance) for using this convoluted format instead of something simpler like
  • PCNT=DCOUNT(SOMEDATA<1>,@VM)

Kevin Powick

unread,
Apr 3, 2017, 4:33:24 PM4/3/17
to Pick and MultiValue Databases
Yes, using DCOUNT with @VM would be the more idiomatic way to count the values in an attribute.

--
Kevin Powick 

Kevin King

unread,
Apr 3, 2017, 4:59:17 PM4/3/17
to mvd...@googlegroups.com
Locate will tell the location where the string is found in the dynamic array. If the search string is not found in the string, many (most?) MV platforms will set the location to ... I think it's one past the last value. I may be mistaken on that last part; I don't trust the value in the location variable on the else.

--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+unsubscribe@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms

Ed Clark

unread,
Apr 3, 2017, 9:35:37 PM4/3/17
to mvd...@googlegroups.com
When LOCATE doesn’t find the element it's searching for, it returns the position where the element *should* be inserted. If it’s a simple locate, then it will be 1 past the last attribute/value/subvalue. If you used locate with an ascending or descending flag on a sorted array then it will be the sorted location. In either case the returned pointer from LOCATE is appropriate and trustworthy to use with an insert:
  INS “!@$#” BEFORE SOMEDATA<1,PCNT)
which will add the element in sorted order.

In the example, of course, it looks like they used it just as a silly way to get the dcount, and it has to be a lot less efficient, UNLESS for some reason “!@#$” is sometimes actually used in the application as a marker for a special location, in witch case the code returns either the value before the point, or the last value. Who knows—I’ve seen stranger code.

To unsubscribe, email to: mvdbms+un...@googlegroups.com

George Gallen

unread,
Apr 4, 2017, 9:56:12 AM4/4/17
to mvd...@googlegroups.com

Locate is one of those that is very different from D3/Reality vs Prime/Information


D3 - LOCATE SOMETHING IN DYNARR BY 'AR' SETTING POS ELSE CLAUSE   to Search using AM as the delimiter in the entire Array

INFORMATION - LOCATE SOMETHING IN DYNARR<1> BY 'AR' SETTING POS ELSE CLAUSE  to Search using AM as the delimiter in the entire Array


I only don't trust the POS marker on the ELSE if the array is non-sorted - but if the array was created and

is sorted, I've found it to be reliable.



From: 'Ed Clark' via Pick and MultiValue Databases <mvd...@googlegroups.com>
Sent: Monday, April 3, 2017 9:35 PM
To: mvd...@googlegroups.com
Subject: Re: [mvdbms] An almost beginner-level question
 

Kevin King

unread,
Apr 4, 2017, 3:30:25 PM4/4/17
to mvd...@googlegroups.com
George, good clarification. I agree wholeheartedly. However, just because the insert uses AR, AL,DR, DL doesn't mean the results will be in sorted order UNLESS the starting array was originally in sorted order. That's no fault of the LOCATE as much as a misunderstanding about the sort order of the source data.

Anthony Youngman

unread,
Apr 4, 2017, 4:38:39 PM4/4/17
to mvd...@googlegroups.com
The thing to remember is that AL etc *assume the array is already sorted*!

Once you've got your head around a "location sort", it's easy to
understand how AL etc work.

FOR II = 1 TO DCOUNT( ARRAY, @FM)
VALUE = ARRAY<II>
LOCATE VALUE IN ARRAY<1> BY "AL" SETTING POSN
IF II <> POSN THEN
DEL ARRAY<II>
INSERT VALUE BEFORE ARRAY<POSN>
END
NEXT

(When trying to understand this code, just remember that POSN cannot be
greater than II :-)

I wouldn't recommend actually using this sort, it'll be horribly slow,
but it's a perfect example of using a sort-ed/ing locate.

(Oh, and I can't remember the details, 9.6 was a long time ago, but
there was a bug in the UV implementation that would sort "substring"
AFTER "substringexample", but only SOMETIMES. Perfectly reproducible,
but different behaviour in different use-cases.)

Cheers,
Wol

On 04/04/17 20:30, Kevin King wrote:
> George, good clarification. I agree wholeheartedly. However, just
> because the insert uses AR, AL,DR, DL doesn't mean the results will be
> in sorted order UNLESS the starting array was originally in sorted
> order. That's no fault of the LOCATE as much as a misunderstanding about
> the sort order of the source data.
>
> On Apr 4, 2017 7:56 AM, "George Gallen" <g_ga...@hotmail.com
> <mailto:g_ga...@hotmail.com>> wrote:
>
> Locate is one of those that is very different from D3/Reality vs
> Prime/Information
>
>
> D3 - LOCATE SOMETHING IN DYNARR BY 'AR' SETTING POS ELSE CLAUSE to
> Search using AM as the delimiter in the entire Array
>
> INFORMATION - LOCATE SOMETHING IN DYNARR<1> BY 'AR' SETTING POS ELSE
> CLAUSE to Search using AM as the delimiter in the entire Array
>
>
> I only don't trust the POS marker on the ELSE if the array is
> non-sorted - but if the array was created and
>
> is sorted, I've found it to be reliable.
>
>
> ------------------------------------------------------------------------
> *From:* 'Ed Clark' via Pick and MultiValue Databases
> <mvd...@googlegroups.com <mailto:mvd...@googlegroups.com>>
> *Sent:* Monday, April 3, 2017 9:35 PM
> *To:* mvd...@googlegroups.com <mailto:mvd...@googlegroups.com>
> *Subject:* Re: [mvdbms] An almost beginner-level question
>
> When LOCATE doesn’t find the element it's searching for, it returns
> the position where the element *should* be inserted. If it’s a
> simple locate, then it will be 1 past the last
> attribute/value/subvalue. If you used locate with an ascending or
> descending flag on a sorted array then it will be the sorted
> location. In either case the returned pointer from LOCATE is
> appropriate and trustworthy to use with an insert:
> INS “!@$#” BEFORE SOMEDATA<1,PCNT)
> which will add the element in sorted order.
>
> In the example, of course, it looks like they used it just as a
> silly way to get the dcount, and it has to be a lot less efficient,
> UNLESS for some reason “!@#$” is sometimes actually used in the
> application as a marker for a special location, in witch case the
> code returns either the value before the point, or the last value.
> Who knows—I’ve seen stranger code.
>
>> On Apr 3, 2017, at 4:59 PM, Kevin King <precis...@gmail.com
>> <mailto:precis...@gmail.com>> wrote:
>>
>> Locate will tell the location where the string is found in the
>> dynamic array. If the search string is not found in the string,
>> many (most?) MV platforms will set the location to ... I think
>> it's one past the last value. I may be mistaken on that last part;
>> I don't trust the value in the location variable on the else.
>>
>> On Apr 3, 2017 2:20 PM, "Kevin Doiron" <kdoir...@gmail.com
>> <mailto:kdoir...@gmail.com>> wrote:
>>
>> Hi everyone,
>>
>> I'm finding myself back in the Pick world after an extended
>> absence to work on other systems. It's almost like riding a
>> bicycle, but a few things keep throwing me off, especially the
>> syntax differences between UniBasic and Python (where I was
>> focused for the last decade),
>>
>> Anyway, I'm reviewing some code that I need to figure out, and
>> I came across the following line:
>>
>> * LOCATE('!@#$',SOMEDATA<1>,1;PCNT) ELSE PCNT=PCNT-1
>>
>>
>> In this case, "SOMEDATA" is a single attribute data item, with
>> multiple values (e.g., '413ý428ý457'), that seems to be sorted
>> in ascending order. Of course, my target string ('!@#$') does
>> nt exist in this attribute. As a result, PCNT has a value of
>> 3 after this command. I've been able to figure out that the
>> command is effectively saying "tell me how many values are in
>> this attribute", but is there a reason (perhaps performance)
>> for using this convoluted format instead of something simpler like
>>
>> * PCNT=DCOUNT(SOMEDATA<1>,@VM)
>>
>>
>>
>> --
>> You received this message because you are subscribed to
>> the "Pick and MultiValue Databases" group.
>> To post, email to: mvd...@googlegroups.com
>> <mailto:mvd...@googlegroups.com>
>> To unsubscribe, email to: mvdbms+un...@googlegroups.com
>> <mailto:mvdbms%2Bunsu...@googlegroups.com>
>> For more options, visit http://groups.google.com/group/mvdbms
>> <http://groups.google.com/group/mvdbms>
>>
>>
>> --
>> You received this message because you are subscribed to
>> the "Pick and MultiValue Databases" group.
>> To post, email to: mvd...@googlegroups.com
>> <mailto:mvd...@googlegroups.com>
>> To unsubscribe, email to: mvdbms+un...@googlegroups.com
>> <mailto:mvdbms+un...@googlegroups.com>
>> For more options, visit http://groups.google.com/group/mvdbms
>> <http://groups.google.com/group/mvdbms>
>
> --
> You received this message because you are subscribed to
> the "Pick and MultiValue Databases" group.
> To post, email to: mvd...@googlegroups.com
> <mailto:mvd...@googlegroups.com>
> To unsubscribe, email to: mvdbms+un...@googlegroups.com
> <mailto:mvdbms%2Bunsu...@googlegroups.com>
> For more options, visit http://groups.google.com/group/mvdbms
> <http://groups.google.com/group/mvdbms>
>
> --
> You received this message because you are subscribed to
> the "Pick and MultiValue Databases" group.
> To post, email to: mvd...@googlegroups.com
> <mailto:mvd...@googlegroups.com>
> To unsubscribe, email to: mvdbms+un...@googlegroups.com
> <mailto:mvdbms%2Bunsu...@googlegroups.com>
> For more options, visit http://groups.google.com/group/mvdbms
> <http://groups.google.com/group/mvdbms>
>
> --
> You received this message because you are subscribed to
> the "Pick and MultiValue Databases" group.
> To post, email to: mvd...@googlegroups.com
> To unsubscribe, email to: mvdbms+un...@googlegroups.com

Ed Clark

unread,
Apr 4, 2017, 10:13:08 PM4/4/17
to mvd...@googlegroups.com
If I remember correctly, in the information variety the number you give is the starting position: 
  …IN DYNARR<2>
means search at the attribute level starting from attribute 2. In the pick version the indexes between <> work like EXTRACT/REPLACE and there’s a separate indicator for starting position:
  …IN DYNARRAY,2
which might be why some people prefer to use the form of locate that looks like a function, because that form is pretty much the same between the two.

If you’re using LOCATE on a sorted array and care about the returned position (instead of just the then/else) it would be assumed that the array was created and maintained sorted by consistently using LOCATE. If you don’t know where the array came from then you can’t trust the sorted state.

Kevin Doiron

unread,
Apr 5, 2017, 10:47:39 AM4/5/17
to Pick and MultiValue Databases
Thanks to everyone for your answers.

"!@#$" is not a value that would ever be in this list - the values are account numbers.  The values in SOMEDATA<1> are typically sorted (they're all numeric, they're sorted in increasing order, but not always the same length - either 7 or 8 digits), although this particular program never adds anything to "SOMEDATA".

As Ed suggested, it looks like it was a silly way to get a DCOUNT.

I think because it was part of a commercial software package, it was done that way to deliberately obfuscate the code and confuse developers who have to maintain it.

Thanks again, everyone.

Kevin Powick

unread,
Apr 5, 2017, 3:48:01 PM4/5/17
to Pick and MultiValue Databases


On Wednesday, 5 April 2017 09:47:39 UTC-5, Kevin Doiron wrote:

I think because it was part of a commercial software package, it was done that way to deliberately obfuscate the code and confuse developers who have to maintain it.

More likely that the original programmer was inexperienced, or unaware of the DCOUNT function.

--
Kevin Powick

Scott Ballinger

unread,
Apr 5, 2017, 6:16:17 PM4/5/17
to Pick and MultiValue Databases
I've seen that used in a lot of CUBS programs... I presume it predates when the DCOUNT function was widely available and was thus an attempt to be platform agnostic.

/Scott Ballinger

Charlie Noah

unread,
Apr 5, 2017, 6:35:22 PM4/5/17
to mvd...@googlegroups.com
AFAIK, COUNT has been around in all platforms a long time, and this might be about as platform agnostic as it gets:
IF var # '' THEN VM.CNT = COUNT(var, VM) + 1 ELSE VM.CNT = 0

I agree with Kevin. It was probably an inexperienced programmer. I have seen deliberately obfuscation, though, and programmers who follow that practice should be shot.

Charlie

--

Kevin Powick

unread,
Apr 6, 2017, 12:08:37 AM4/6/17
to Pick and MultiValue Databases


On Wednesday, 5 April 2017 17:16:17 UTC-5, Scott Ballinger wrote:
I've seen that used in a lot of CUBS programs... I presume it predates when the DCOUNT function was widely available and was thus an attempt to be platform agnostic.

Good point.  Not all MV implementations may have introduced the DCOUNT function at the same time.

Then again, LOCATE() is a function that even today is implemented differently across various MV platforms. So, I'm somewhat doubtful that the programmer was trying to write platform agnostic code.

--
Kevin Powick  

Anthony Youngman

unread,
Apr 9, 2017, 3:24:41 PM4/9/17
to mvd...@googlegroups.com
On 05/04/17 23:35, Charlie Noah wrote:
> AFAIK, COUNT has been around in all platforms a long time, and this
> might be about as platform agnostic as it gets:
> IF var # '' THEN VM.CNT = COUNT(var, VM) + 1 ELSE VM.CNT = 0
>
Actually, it's more likely to be

VM.CNT = COUNT( VAR, @VM) + ( VAR <> "")

I remember using that logic in a "Beginner's C" course, and the
instructor was amazed. It was actually very hard to get him to write it
on the board properly because he kept writing what he thought I was
saying, not what I was actually saying (the example was counting hearts
in a hand of cards).

Oh - and I thought DCOUNT was a (relatively :-) new function so that
code probably predates it.

> I agree with Kevin. It was probably an inexperienced programmer. I have
> seen deliberately obfuscation, though, and programmers who follow that
> practice should be shot.
>
> Charlie
>
> On 04-05-2017 5:16 PM, Scott Ballinger wrote:
>> I've seen that used in a lot of CUBS programs... I presume it predates
>> when the DCOUNT function was widely available and was thus an attempt
>> to be platform agnostic.
>>
Cheers,
Wol

Charlie Noah

unread,
Apr 9, 2017, 7:03:43 PM4/9/17
to mvd...@googlegroups.com
Hey Wol,

I had forgotten that method. It just shows what retirement does to the memory. ;-)

I don't know which method is faster, and with today's machines, it doesn't really matter. Your method is certainly better for I-descriptors.

Charlie

Will Johnson

unread,
Apr 11, 2017, 3:30:00 PM4/11/17
to Pick and MultiValue Databases
HELP is your friend

At TCL type

HELP LOCATE

or on some systems you have to type

HELP BASIC LOCATE

Peter McMurray

unread,
Apr 11, 2017, 7:54:40 PM4/11/17
to Pick and MultiValue Databases

Will Said "HELP is your friend"
Sorry Will but even an old codger like me knows that D3Ref vanished many years ago :-)
For some years i kept reloading it from old file-saves but for a long time I have just used the PDF manual.
Nice and simple windows key plus right arrow flips it up beside the accuterm development session on any decent sized screen.

Steve Trimble

unread,
Apr 12, 2017, 8:08:03 AM4/12/17
to mvd...@googlegroups.com


Steve Trimble
Computerized Data Mgmt Inc
(501) 772-3450 cell / text

--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+unsubscribe@googlegroups.com

Will Johnson

unread,
Apr 13, 2017, 1:09:51 PM4/13/17
to Pick and MultiValue Databases
D3 has no embedded HELP command?

That is Crazy! (with a capital C)

I'm on Universe, and I use HELP almost every day (my memory is slipping, I'm 53)
Reply all
Reply to author
Forward
0 new messages