Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Share your Pick Tricks

1,305 views
Skip to first unread message

Tony Gravagno

unread,
Sep 17, 2019, 3:32:33 PM9/17/19
to Pick and MultiValue Databases


 Ian McGowan wrote:
... I think a lot of programmers get tired of typing BASIC BP BLAH over and over ;-)  I have a TCL stack wrapper that lets me keep a "program stack" so I can do /B13 to compile and catalog the 13th entry in my list of programs.

That's great, Ian. As passionate as people are about this platform, I'm stunned that more people aren't using the available tools like that.

Rather than responding to that in the other thread, I thought I'd start a new thread on the topic of things we do to make our lives easier with this platform.
Share a quick tip - see if it sticks! :)


Here's one related to the command-line topic.

I've overloaded some verbs in my development environment and a couple client systems so that the most recently used file is stored in the D3 environment (shell) variable @FILE. So I can do something like this:
  create-file log,190917a 101
  copy log (iosd
  (@file
For that specific function I'll shorten it even more into an Archive verb. Also note the O option on copy makes it write faster because it avoids a read for each item to see if the item exists so that it can throw an error. (Well, that used to be how it worked.) Suppressing item IDs also makes it go a Lot faster because the operation speed isn't limited to how fast it can output the list of items and other messages.
The point is that with Create-File overloaded as a BASIC program that sets the @var, other commands that follow no longer need to explicitly know what that file name is. I'll often set one or more @vars to shortcut other cumbersome typing.

For more information about @VARs (which I SOOOO wish all platforms supported!!!) see the documentation which Rocket Software has cleverly hidden so that no one will find it:
I've also blogged a couple pages with more rigorous usage, which again, I'm always frustrated because this stuff isn't cross-platform.


HTH
T

Tony Gravagno

unread,
Sep 20, 2019, 10:25:34 PM9/20/19
to Pick and MultiValue Databases
With the dazzlingly enthusiastic response to the first post here, I thought I'd try another.

Did you know that you can make two D3 systems look like one using the OSFI?

The HOSTS file has items C, D, and E, so that you can read/write with the local Windows drive.
It has items BIN and UNIX and DOS - often referenced and occasionally mis-used.
So you can do this:

LIST c:/temp
SELECT /var/www/html with A0 "[.html"
ED unix:/home/myuser myscript.sh

You can also setup one D3 system as a host, and then access it from another D3 system:

COPY OTHERHOST:MY_ACCOUNT,BP
to: (LOCAL.BP

And to make file access more transparent, setup a q-pointer, like this one called REMOTE.BP:
Q
OTHERHOST:MY_ACCOUNT,BP,

Then:

COPY REMOTE.BP
to: (LOCAL.BP

Or
CATALOG REMOTE.BP FOO
'FOO' catalogued!
: FOO

^^^ Yeah, that's the command-line in your local system running a program/object-code that's resident in another system.


It looks like it's all happening in the same system but your data can be sourced from another server anywhere in the world - one of yours or a client's.

Hey, do you need to do something in another D3 system in your company network?

LOGTO HOST123:MY_ACCOUNT
LIST SOME.FILE

LOGTO HOST456:MY_ACCOUNT
LIST SOME.FILE

Combine this with the environment variable tip...

SET SYS1=HOST456:MY_ACCOUNT
SET SYS2=HOST123,MY_ACCOUNT
COPY @SYS1,SOME.FILE,
to: (@SYS2,SOME.FILE,

And yes, combining the above tips, you can get your local D3 system to reach into the OS and local network of another networked D3 system ... as long as security permissions don't get in the way.

I've intentionally not paid much attention to getting the detailed syntax exactly right. This is a tip, not a full tutorial. If you think the concept has value to you, try it and let's chat about it in a separate thread or mvTalk.

Enjoy!
T

izzizman

unread,
Sep 23, 2019, 7:17:56 PM9/23/19
to mvd...@googlegroups.com

   Ok, have a trick that I think is pretty good (at least for me ) I guess we'll see. Working for a school who doesn't have any money (won't buy a real signature pad) ! Manage 400 computers that need repairs, want loaners (laptops, AC adapters, etc...). When I got here everything was on paper, you understand the frustration, ready to quit in a week ! I came in and built a Linux Mint server with QM . It evolved to where from a green screen  I can print Barcode labels, and if they take loaners, etc... I call a standard linux app from BASIC to use a WACOM tablet to sign for it and save it in a type 1 file, read the ID from the DICT of the file and write that to the LOANERS file. If I bring up the student and look at his loaners, I use another linux app to view the signature if there are any questions.

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/05541c17-424f-4431-ab1e-9d9e876397ff%40googlegroups.com.

Tony Gravagno

unread,
Sep 24, 2019, 2:09:39 PM9/24/19
to Pick and MultiValue Databases
That's great, Izzi. I rolled my own solution many years ago but it was not as elegant as yours, and if done today, I'd prefer your approach.
FWIW, these days I use PrintWizard for barcode solutions. Dirt simple, but not free. Again, I like your approach.
Thanks.
T

 Izzi Zman wrote:
... It evolved to where from a green screen I can print Barcode labels, and if they take loaners, etc... I call a standard linux app from BASIC to use a WACOM tablet to sign for it and save it in a type 1 file, read the ID from the DICT of the file and write that to the LOANERS file. If I bring up the student and look at his loaners, I use another linux app to view the signature if there are any questions.

Ian McGowan

unread,
Sep 26, 2019, 2:03:05 PM9/26/19
to Pick and MultiValue Databases
The trick that gets the single best reaction for me from customers is not related to basic programming at all.  It's setting up a virtual printer to email print jobs to the current user, or to a named user for nightly processes.  Can't emphasize enough how big a deal this can be for users that are doing a lot of reports/printing, spread out across multiple offices or working remote.  It really takes a lot of pain out of trying to manage all those printers or doing slave printing.

This may only be applicable for Linux or Unix folks, but I'm sure there's a windows equivalent trick.  It's a little dependent on environment how to do, but basically there's two parts:

1) At the O/S level setup a virtual printer connected to a shell script (this will be different depending on your O/S, but Linux, AIX and HP/UX all have ways of doing this).


2) Inside your application (unfortunately, I only have experience with Unidata so can't speak to other flavors) arrange for the spooler to pass along a flag to the O/S virtual printer telling it where to email.  I use "-o OWNER", "-o ian.m...@gmail.com", "-o ac...@bigco.com,fin...@bigco.com" for example in the SETPTR command.  I think this might be the most tricky part, depending on the database and application in use.  Failing everything else, you could write the destination email address to a temp file and have the script pick it up from there.

It can be a pain to setup, but if your userbase is still routinely printing reports to actual paper, this can be a huge efficiency improvement.  Dumping extracts to Excel and emailing is a related trick that's also popular, especially with accounting teams ;-)

Kevin Powick

unread,
Oct 2, 2019, 10:49:33 PM10/2/19
to Pick and MultiValue Databases
Or you could just use Print Wizard.

--
Kevin Powick

euobeto .

unread,
Oct 3, 2019, 8:01:29 AM10/3/19
to mvd...@googlegroups.com
I`m about to finishe a Pdf writer build in pick.. create build export a pdf report

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.


--
Alberto  Leal
T.I  Campo Grande
LPI ID: LPI000191272
E-mail: alb...@tecwebcg.com
Gmail:  ees....@gmail.com
          

Kevin King

unread,
Oct 12, 2019, 12:19:10 PM10/12/19
to mvd...@googlegroups.com
We have a tool called REMEMBER that allows you to take a backup of a set of data before doing something that could damage it, and then restore that set of data if the worst happens.  It's one of the best CYA tools we have, and invaluable for testing.


Kevin King, President / Chief Technologist
Precision Solutions, Inc.
630 15th Ave Suite 201, Longmont, CO 80501
Phone: 303-651-7050  Fax: 720-442-9204
Ke...@PrecisOnline.com | https://www.PrecisOnline.com

 

 



Darren W

unread,
Oct 12, 2019, 2:48:29 PM10/12/19
to Pick and MultiValue Databases
REMEMBER sounds useful but only if you 'REMEMBER' every file that could be affected by a routine going wrong.

On a Reality system with transaction logging enabled one could force a manual clean log switch with the TL-AUTOSWITCH command from TCL in SYSMAN to draw a line in the sand before running the process and another switch immediately after. Then in the event of a problem a restore from filesave plus clean log restore right up until that particular clean log would get you back to before things went wrong. Alternatively, selective TL-RESTORE could be run using previous clean logs to restore any files or items that got corrupted...or indeed just listed out for forensic purposes to spot which files and items were updated by the rogue process.

Standalone TL (logging and restore) works as per the above without any $$ licence fees in Reality contrary to what some might think. You only need to pay for feature keys if you want failsafe or DR... Standalone transaction logging even works on an EVAL licence!

I only mention this as many people overlook the value of having standalone TL running and the forensic analysis of a system which clean logs provide. They are not all about mirroring to a replicant system or recovering data after a system crash...they can also be useful for debugging and monitoring file updates system wide under normal conditions.

Anyway, I am veering off topic so I shall leave you all with the above.

Cheers
Darren

Technical Support Consultant - Reality USA

Tom M

unread,
Jan 4, 2020, 12:29:17 PM1/4/20
to Pick and MultiValue Databases
I couldn't find anywhere the equivalent to BITAND, BITOR, or BITXOR so I had to roll my own to do 32 bit bitwise operations.  Painfully slow in Basic (even flashed), is there no access to bitwise operations in AP?

Tom

Ben Cramer

unread,
Jan 4, 2020, 1:48:03 PM1/4/20
to Pick and MultiValue Databases
Hi Tom,

Had a similar issue as well with the BITAND, etc.  It's probably not much of a help if you're on AP but QM has all of the bitwise operations

-Ben

Peter McMurray

unread,
Jan 4, 2020, 6:39:33 PM1/4/20
to Pick and MultiValue Databases
Hi
I am intrigued by some of the responses. I see a tremendous difference between TG's proper use of existing tools and people simply re-inventing the wheel.
Why on earth would anyone try and write a true PDF from Basic when PrintWizard has decades of development and $150 buys a server version that can handle multiple printers with complex overlays plus simplify existing prints. It also does Barcodes and fancy prints with email. All so fast that you need to go down to milliseconds and still get dozens of files output on a standard Intel PC.
Email has umpteen apps available SWITHMAIL that I use is free. I found it so good I mad a donation.
Bit manipulation. Now there's a thing. I started my commercial programming life using binary coded hexadecimal back in 1972. In the mid 80's before mastercard I was handling 11 bit info for in house credit cards. Ten years ago when I did Unicode my immediate thought was bit manipulation then I realised it was simple maths that Basic is very good at. Editing a field with forward and back arrow and the like is extraordinarily simple.
That is not to say there is not some arcane need in a specialist area however has the option been considered.
Let us not forget Pick is a commercial database - yes debits and credits for business not moon shots or the Large Hadron Collider.
Time is money. Before writing something new has the market need been considered? What will be the bottom line benefit. Polishing some thing that is used for a few minutes a month is a pointless exercise that may result in pain if the original was written by someone else. I still remember having to fix the mess that somebody made of the DOS transfer program back in R83. The newbie decide to redim the file for every record instead of just changing the extra byte that the new DOS required. Luckily I had the old beautifully written and commented program and was able to rectify the situation.
At this stage of internet development far too many are selling the sizzle and the actual need for the sausage has been forgotten. The User interface in green screen is far more efficient over the cloud then heavy thick clients.
D3 in particular excels at file handling using small single purpose Basic CRUD subroutines that handle the back end leaving the front free for the artistic without losing control of the database.

Tony Gravagno

unread,
Jan 6, 2020, 11:27:30 AM1/6/20
to Pick and MultiValue Databases
AP?  *Gasp*  Do you mean D3?

Yeah, it's surprising that bitwise operations aren't built-in by now. But with no one even discussing the topic, except for the once-per-decade request for using the OSFI "BIN" host, it's no surprise that it hasn't been on the D3 list of priority enhancements. If people asked PS/RD/TL/RS about features like this, they'd at least see the topic on the radar. When no one asks, they have no idea that features like this are desired.

Tom - credit to ya for doing it in BASIC and noting that it's not fast enough even with Flash. I trust your algorithms are right but surprised that flashing wasn't helpful, so it seems like "something" could be optimized.

For D3 v10, consider using Python functions where bit manipulation is as simple as using one or two characters.

For all D3, consider integrating an existing C or .NET library and calling it with %functions. Yeah, I know, C isn't BASIC and such things aren't popular in MV-land, but it's an option ... and bitwise operations in C and .NET are native and dirt-simple.

As a last-ditch approach of desperation: stringify an equation like CALC= VALUE : ">>2" (right shift 2 bits), pass it to the command-line, and use an OS utility to do it. ( I know ... SLOW )

This is probably a good time to re-mention my FOSS that converts any base to any other base, like decimal to binary, octal to hex, even compression to base 36:
So, call to that to get data to binary, use your own function to do the bitwise ops, and then call the routine to convert back. And it will work in AP! :)

BTW, in D3v10 we have user-defined BASIC functions now. So it's much easier to do something like RESULT=XOR(BINARY(VAR)).

HTH
T

Tom M

unread,
Jan 6, 2020, 11:44:18 AM1/6/20
to Pick and MultiValue Databases
Hi Tony,

I lumped D3 and AP together (old habit). Sorry if that caused any confusion.

We're using D3 10.2 on Linux.  We have built in functions? Is it documented anywhere? How do you call Python from within D3?  I use %popen to execute PHP scripts. Would it be the same technique?

For XOR I found UX.XOR in ABS and it takes 2 32 bit hex numbers and does the conversion.  Yay, that's one down.

For AND/OR, I used string based truth tables and do the lookup. It's much faster than the mathematical equivalent of doing MOD 32 times (once for each place)

I left out most of the lead up, but the gist is:

085   BEGIN CASE
086     CASE OP='XOR'
087       X = OCONV(A:CHAR(254):B,'U$UX.XOR')
088       RETURN
089     CASE OP='AND'
090        TBL='0000000000000000010101010101010100220022002200220123012301230123000044440000444401014545010145450022446600224
    4660123456701234567000000008888888801010101898989890022002288AA88AA0123012389AB89AB000044448888CCCC010145458989CDCD002244
    6688AACCEE0123456789ABCDEF'
091     CASE OP='OR'
092       TBL='0123456789ABCDEF1133557799BBDDFF23236767ABABEFEF33337777BBBBFFFF45674567CDEFCDEF55775577DDFFDDFF67676767EFEFEF
    EF77777777FFFFFFFF89ABCDEF89ABCDEF99BBDDFF99BBDDFFABABEFEFABABEFEFBBBBFFFFBBBBFFFFCDEFCDEFCDEFCDEFDDFFDDFFDDFFDDFFEFEFEFE
    FEFEFEFEFFFFFFFFFFFFFFFFF'
093     CASE 1
094       RETURN
095   END CASE
096 * BINARY BITWISE OPERATORS USE THE APPROPRIATE TRUTH TABLE
097   X = '00000000'
098   FOR I = 1 TO 8
099     AI = XTD(A[I,1])
100     BI = XTD(B[I,1])
101     X[I,1] = TBL[AI*16+1+BI,1]
102   NEXT I

From my experiments and doing it multitude of different ways in Basic, this performs the best.  I might get a little better moving each table to 16 cell arrays and making smaller string lookups, but it's just splitting hairs now.  Yes, a %cfunction call would be fastest, but I'm trying to keep the code portable across multiple versions including my own basic interpreter in C++.

Tom

Tony Gravagno

unread,
Jan 6, 2020, 1:02:10 PM1/6/20
to Pick and MultiValue Databases
Dang dude, congrats on finding that user exit. Makes me want to poke around in psym or abs to see what else we can use. (Note to D3Windows users, I think user exits are slow and maybe discouraged because they rely on the VME and are thus quite slow. Use other methods to achieve similar goals. I haven't looked at this in years. If you're concerned, please start a new thread.)
Tom - Given that you're on a supported release I strongly suggest you ask RS Support if they can provide a table of user exits for bit manipulation. Tell them I suggested you ask, they'll love us for it. :) Really, if all this takes is the documentation for existing functionality then you may have uncovered something very useful here.

About Python - this is a topic that RS has been marketing about for a couple years. They have periodic webinars, and their MV forum has some posts on the topic. Alas, the word 'python' isn't in the 10.3 D3 Reference manual. (Why does a company need to be told that their product documentation doesn't reference a feature that is a top focus of their Marketing efforts? Sigh) Docs for Python and other features are available here:
As required, I recommend you contact RS Support for info about this topic as well. I think it's important for them to know that people are interested in these interfaces, both as a reaffirmation that they didn't waste their time, and as encouragement to continue ensuring that it works and that it's well documented.

About user-defined BASIC functions, yeah, new in v10. Finally! I've been asking about this for years. There are two kinds of functions, internal (like GOSUB) and external (like CALL). Both look the same: FOO(BAR). Internally they're using pre-compilation to convert code into calls and subs ... which is what Mark Brown and others have done for years. The D3 Ref only documents external functions. I've worked with this a good deal with awesome help from Brian Cram at RS, and he and others are working to update D3Ref with more complete details. So, hang tight for a bit. I will post something on the topic soon but the docs should be available soon too.

HTH
T

Tom M

unread,
Jan 7, 2020, 11:38:53 AM1/7/20
to Pick and MultiValue Databases
When I discovered this a few years ago, I wanted to see how it worked.  I used tcpdump to watch traffic, studied the rp.h include file and built an interface to picknfs that follows osfi.  I couldn't figure out the password hash method at the time so I used triggers to execute code that could only be run in the pick environemnt and voila, I had remote access to my pick data from anywhere that I could write a C program including a php extension.  I recently figured out the hash algorithm so I could dispense with the trigger workaround, but since it ain't broke, I didn't fix it.

Tom

Tony Gravagno

unread,
Jan 7, 2020, 1:36:32 PM1/7/20
to Pick and MultiValue Databases
That's some awesome hackery but I don't see it as being necessary since there are other completely normal and supported ways to CRUD and process execution with D3 from outside. I've always complained that the Open Systems File Interface is not "Open". They have never published the API, and yet I've provided many examples which demonstrate how OSFI can be used to extend D3 in really powerful ways.

I have to step into other shoes now and note that you've publlished a vector which implies a security vulnerability. Thankfully, D3v10.3 uses SSL to encrypt the tunnel. I'm sure you can still do what you want there, Tom, but when you upgrade to 10.3 you'll need to re-apply your apparently artful skills to using different approach.

Regards,
T

[AD] Nebula R&D is an authorized provider of D3 licenses and support, and provides full site maintenance services (as "VAR on record with Rocket Software"), advanced development, and strategic management consultation for MV-related IT resources.
TG can be found @
Nebula-RnD
add .com to that

Tom M

unread,
Jan 7, 2020, 2:06:17 PM1/7/20
to Pick and MultiValue Databases
Tony,

I wasn't really considering 10.3.  As for security, I send everything through stunnel to keep it secure.  Brian is supposed to call me back to today talk about the bit stuff. I'll post the results when we're done.

tom

Tom M

unread,
Jan 7, 2020, 4:27:20 PM1/7/20
to Pick and MultiValue Databases
The response from Rocket regarding bitwise operators availability:

"I checked. There isn't one. probably have to write your own"

Ah well.




On Tuesday, January 7, 2020 at 10:36:32 AM UTC-8, Tony Gravagno wrote:

Peter McMurray

unread,
Jan 8, 2020, 10:53:18 PM1/8/20
to Pick and MultiValue Databases
Hi
The tax department has just issued a warning never write the date as 1.1.20 always use the full century 1.1.2020 because people may alter the short century to 2019 or 18 whatever.
Those of us that use the Pick internal have no problem knowing but some may be slack in printing to PDF for example or outputting on invoices or the like.I have run into major banking systems that do not even validate the input!!
My two penn'orth accept any input type but always expand for display on validation or print output
initialise
A.FCONV = "D";A.FMASK = "R#11"
Edit
CASE A.FTYP = "D";* DATE
    A.IN = ICONV(A.IN,"D");* Date European
    IF A.IN = NOVAL THEN
       A.ERR = A.ERROR(5)
    END
output if correct
 A.DISPLAY = OCONV(A.IN,A.FCONV) A.FMASK
 CRT @(A.FX,A.FY):A.DISPLAY

I am still intrigued as to what system needs bit manipulation in this day and age: Would appreciate an example although I would use Python now if it arose/
Message has been deleted

Peter McMurray

unread,
Jan 10, 2020, 8:33:57 PM1/10/20
to Pick and MultiValue Databases
Thank you Tom for answering my question about why bit manipulation was required.
MD5 and SHA1 encryption is a valid reason. I discussed this with Mark Brown many years ago and abandoned the idea in Pick for a number of reasons
1 The clients did not want it even though I pointed out credit card issues so I simply do not store passwords for them. Perhaps they had got too used to the Gilbarco credit cards that were produced in house and worked off a list of 4 digit numbers. Drivers frequently left the cards in the cab with the pass written on them!!
2 The account passwords were adequate at the Pick support level. In fact I installed an N(typically 30) day setting and only one used it most cussed it and I have even seen postit notes on terminals for them.
3 Pick Basic can be decompiled with ease so any programmer could work around it as one would have to put the seed somewhere. I would be happy to be disproved on this.

Also why was my post regarding use of short dates deleted I have seen many systems where it is relevant and the ATO are certainly worried about it. 

MarZ

unread,
Feb 4, 2020, 8:21:32 PM2/4/20
to Pick and MultiValue Databases
For those who want BASIC (external) functions now or will not upgrade to 10.3 D3 then perhaps this will be of some use to you.

Use existing functions OCONV or ICONV to emulate or is that simulate the desired outcome.
For example CRT \Function result \ : OCONV(MYVAR,'CALL MYSUBFUN')
This calls the subroutine MYSUBFUN passing MYVAR as the single argument by value.
Thus allowing use of the subroutine after the assignment operator.

John Doe

unread,
Feb 5, 2020, 2:50:44 AM2/5/20
to Pick and MultiValue Databases
Hi Tom,
For code at line 097+  the following changes will significantly improve speed  (at least on my system does it 3 times faster).
A and B should be 8 bytes each otherwise XTD would be undefined therefore initializing X to zero is not necessary.
"X :=" is much faster than "X[I,1] = "
Concatenation of "AI:BI" is much faster than a call to XTD
The slowest part is "AI*16 + BI" calculation.

  X = ''                         
  FOR I = 1 TO 8                 
    AI = A[I,1]                  
    BI = B[I,1]                  
    X := TBL[XTD(AI:BI)+1,1]     
  NEXT                           

John Doe

unread,
Feb 6, 2020, 3:26:27 PM2/6/20
to Pick and MultiValue Databases
Sorry, measuring error.
On Universe and QM the improvement is only 3%.  :(
On jBASE the improvement is 90%.(ninety)
Mea culpa.

Tony Gravagno

unread,
Feb 6, 2020, 5:44:34 PM2/6/20
to Pick and MultiValue Databases
We've recently seen a couple examples recently where Google auto-deletes posts that look spammy. We have no control over this and the deleted posts are not accessible to admins.
My practice and advice is to always copy text that's posted into a web browser before clicking to send/post. Save the text for a few days just in case. Yeah, I'm paranoid, but this has saved bacon many times.
In short, I'm sorry if any posts are removed but please know we do not exercise any form of censorship, nor even "moderation" which results in deletion. I haven't removed anything in at least a year, and if I do I email people to notify them of what has happened.
HTH
T

Kevin Powick

unread,
Feb 6, 2020, 6:29:52 PM2/6/20
to Pick and MultiValue Databases

On Thursday, 6 February 2020 17:44:34 UTC-5, Tony Gravagno wrote:
We've recently seen a couple examples recently where Google auto-deletes posts that look spammy. 

It's happened to me too.  I tried to post some MV resources, which was mostly links to various websites.  Google binned it immediately.

Oh, well.

--
Kevin Powick 

Tom M

unread,
Feb 7, 2020, 4:58:52 PM2/7/20
to Pick and MultiValue Databases
Hi John,

I have to respectfully disagree.  I ran a benchmark of 1 million iterations of the two methods on my D3 Linux 10.2 64 bit machine.

The concatenate and DTX method took 21 seconds while the overlay with multiply and offset took 16 seconds


Tom

John Doe

unread,
Feb 8, 2020, 8:39:18 AM2/8/20
to Pick and MultiValue Databases
Hi Tom,
Looks like there are significant differences in how each MV system implements various functions.
What is fast on one is slow on other implementation.
I've seen a huge difference in how fast code is run on Universe/QM versus jBASE therefore I am not surprised that on D3 you get different results.  Well, at least I've tried.

P.S. Sorry, I don't have access to a D3 machine.

Tony Gravagno

unread,
Apr 1, 2020, 10:41:33 AM4/1/20
to Pick and MultiValue Databases
Another tip for D3 and ...? The other day I was sharing code with a colleague (yeah, in the Pick world, Wow!) and he noted some code that he had never seen before. But this is a normal part of my daily repertoire. If this is new to anyone else here then this thread has paid off. :)

CMD = \SELECT FOO\
CMD<1,2> = \SAVE-LIST BAR\
CMD<2> = \GET-LIST BAR\
EXECUTE CMD

This is equivalent to proc:
H primary command
STON
H secondary command that uses the results of the first
P ... execute them both
H and now for something completely different ...
P

Compare to :

DATA \SAVE-LIST BAR\
DATA \GET-LIST BAR\
EXECUTE \SELECT FOO\

That code has always confused people, and it's difficult to work with.

Finally, no new tricks here, I'll rarely build a stack in-line:

execute "select foo" : @VM : "save-list bar"

I always prefer separating the command from the execute, because when it comes time to modify the command, and it happens, the command is already separated:

cmd = "select foo" : @VM : "save-list bar"
execute cmd

And of course to just build a sequence, I most commonly use the -1 syntax:

cmd = \select foo\
cmd<1,-1> = \save-list bar\
cmd<-1> = \get-list bar\

That way it's easy to insert new commands into the stack without concern about the value or attribute number.

So ... is this new for anyone? :)

HTH
T

Tony Gravagno

unread,
Apr 1, 2020, 10:52:58 AM4/1/20
to Pick and MultiValue Databases
I forgot to add Why I use value marks...

If you use attributes in a stack, the command may always get executed.
If you use values, then the secondary command is always executed on the results of what came before it.
So...

cmd = \select foo with adi = "blah"\
cmd<-1> \save-list bar\
cmd<-1> = \get-list bar\
cmd<-1> = \delete foo\
execute cmd

In that sequence, it's ambiguous what will happen if no items are selected by the first command, at least to the eye. If there are no foo items selected, what gets deleted? All items? No items? Will it get stuck at a prompt? Let's not focus on exactly what will or will not happen. The point is that with everything executing off primary stack we aren't exactly sure, and the results may be platform-specific. When we're using the secondary stack we have more certainty that the secondary command is being executed on the results of the primary.

I'll note that a sequence of DATA statements presents the same ambiguity, which results in code like this:

DATA \SAVE-LIST BAR\
EXECUTE \SELECT FOO WITH ADI = "BLAH"\
DATA \GET-LIST BAR\
EXECUTE \DELETE FOO\

So I revise the above to:

cmd = \select foo with adi = "blah"\
cmd<1,-1> \save-list bar\
cmd<2> = \get-list bar\
cmd<2,-1> = \delete foo\
execute cmd

With that code, the intent is clear and the execution should be as well.

Tony Gravagno

unread,
Apr 1, 2020, 11:08:01 AM4/1/20
to Pick and MultiValue Databases
Here's another tip ... about appreciation of the backslash.

The quote characters are: "   '   \
We all know the single and double quotes. Not many people use backslashes.

Consider this query

SELECT FOO WITH ADI = "BLAH"

Now wrap it in quotes. Typically we'd do this:

CMD = 'SELECT FOO WITH ADI = "BLAH"'

The first single quote is obvious, the second gets lost at the end after the double quote. I try to avoid that visual stumble with backslashes.

CMD = \SELECT FOO WITH ADI = "BLAH"\

That also frees up the single quote to be used in code:

CMD = \SORT FOO NOT 'BAR' WITH ADI "BLAH" HEADING "Report Foo'cl'Dated 'd' Page 'pnc'"\

While the AQL syntax itself occasionally requires the single+double combination, the BASIC statement is easy to read.

I've seen a lot of code playing games with alternative quotes, then using a Swap/Change statement to fix them. Or building commands with different quotes to avoid conflict:

CMD = "SORT FOO NOT 'BAR' WITH ADI "
BLAH = ' "BLAH" '
CMD = CMD : BLAH : ' HEADING "Report..." '

That's tough to read and completely unnecessary.
It took some time for me to get familiar with the backslash but now we're good friends. Sure, there are occasional requirements to juggle the characters but not nearly as many occasions as when just using two of the three.

Another tip on this... We sometimes find code, like in this forum and in this post, with quotes embedded. Some text editors or readers will convert the double quotes to smart curly quote. That's such an annoyance. You paste the code into your editor, save, and the compile fails. You do a global search/replace and then it works. Using the backslash helps to eliminate that stumbling block as well. It makes online code easier to use and thus more useful to those for whom we publish.

HTH
T

Tony Gravagno

unread,
Apr 1, 2020, 11:31:09 AM4/1/20
to Pick and MultiValue Databases
OK, let's go for three tips for the day... This one is simple.

How often do you see code like this?

FILES = "FIRST"
FILES<-1> = "SECOND"
FILES<-1> = "THIRD" ...

Try this instead:

FILES = "FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH"
FILES = CHANGE(FILES," ",@AM)

Or:

FILES = "FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH"
CONVERT ' ' TO @AM IN FILES

Or:

FILES = change("FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH", " " , @AM)

Notice how this code went from three elements to seven and it still only occupies one line of code.

I like reducing the number of statements, but there's another concept hidden in there. You may have seen similar code like this:

FILES = change("FIRST,SECOND,THIRD,FOURTH,FIFTH,SIXTH,SEVENTH",",",@AM)

There are two things I don't like about that. The first is that the line doesn't wrap well. With spaces it gracefully wraps at the "word" break in the string. The second (contrived for this example but common) is that the comma delimiter of the Change function is lost in the syntax without spaces:
",",",@AM
There's no need for that. It's easier to read this:
",  " " ,  @AM

And with reference to one of my other notes today, if we change the delimiters it becomes even more readable:

FILES = change( \FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH\ , " " , @AM)

The technique of delimiting with spaces and then splitting with Change lends itself to quick changes, like when we decide we want to use a value-delimited array rather than attributes. It also easily adapts to strings that include spaces ... just use another character for the delimiter:
\FIRST AND SECOND,THIRD AND FOURTH\
Compare that to:
\FIRST AND SECOND\ : @vm : \THIRD AND FOURTH\

This style isn't great for all sequences, and unnecessary when there are only a couple values as seen just above. But it's a nice tool to have in the box when you have something other than a nail and you don't want to bang it with a hammer. :)

Bonus tip: You see the Change function when you might be used to Swap in D3. They're equivalent. I used to use Swap all the time but I switched to Change because it's more cross-platform compatible. That's one less thing to be concerned about if there is any chance that the system will be moved from D3 to another MV platform.

HTH
T

Ian McGowan

unread,
Apr 1, 2020, 12:02:32 PM4/1/20
to mvd...@googlegroups.com
This one is so true!  I use backslash exclusively for EXECUTE's, because that's where you might typically want to use a mix of double and single quotes, and single quotes everywhere else (because no shift, but copy-and-paste smart quotes is a good reason too!).  I've seen code using CHAR(34) to build a string, because they didn't know about backslash as a delimiter.

My favourite code thing that I don't see that often in other's code is EXIT and CONTINUE - saves setting and checking unnecessary variables, and deep IF .. THEN .. ELSE

LOOP
  READNEXT ID ELSE EXIT
 ....
REPEAT

FOR F=1 TO DCOUNT(ATB<1>,@VM)  ;* I know, I know
  KEY=ATB<3,F>
  READ REC FROM FVAR, KEY ELSE CONTINUE
  IF REC<99> = "GOOD" THEN CONTINUE
  ...
NEXT F


--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/6cd81ba7-db9a-4302-952b-ef1c9da9162a%40googlegroups.com.

Ian McGowan

unread,
Apr 1, 2020, 12:08:22 PM4/1/20
to mvd...@googlegroups.com
Like this one, but there's something about seeing a nicely lined up list of "things" that is strangely satisfying.

Speaking of, this extension is great for aligning "things", if you're using vscode: https://marketplace.visualstudio.com/items?itemName=yo1dog.cursor-align

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.

izzizman

unread,
Apr 1, 2020, 12:44:00 PM4/1/20
to mvd...@googlegroups.com
Here's a tool/trick I'm sure everyone has their own variant of or has needed in the past, but this has been with me for 30+ years:  A way to globally change/delete an attribute of a file for certain records using an active select list.  The code as used is at the bottom. I'm not the author of the original but modified it to handle multi-value items.

Here's a quick example: Using an active select list change the attribute RETIRE.DATE to  04/15/20 in the items required.

:GL FOO
100 record(s) selected to select list 0
::CHG
ENTER FILE NAME ?STUDENT_MASTER
ATTR NAME       ?RETIRE.DATE
MV POSITION     ?
VALUE TO STORE  ?04/20/2020

WE ARE GOING TO STORE THE VALUE '04/20/20'
INTO ITEMS IN THE 'STUDENT_MASTER' FILE INTO RETIRE.DATE
WHICH IS ATTRIBUTE NUMBER 18
MULTIVALUE POSITION 1

O.K. ?
?Y

100 items processed.
100 items changed.
:
Program Code:

01: *
02: * STORE A CONSTANT VALUE IN SELECTED ITEMS
03: * UTILITY
04: * Modify for changing multi-valued fields. (ajz)
05: *
06: 1:    CLEAR
07:       EQU AST TO "*"
08: *
09:       FLAG=""
10:       EQU VM TO CHAR(253)
11:       PORT = '' ; OPNO = ''
12: *
13:       DIM A(200)
14: 5:    PRINT "ENTER FILE NAME ":
15:       INPUT FNAME
16:       IF FNAME EQ "" THEN STOP
17:       OPEN "",FNAME TO F1 ELSE PRINT "NO FILE ":FNAME ; GOTO 5
18:       OPEN "DICT",FNAME TO F2 ELSE NULL
19: 10:   PRINT "ATTR NAME       ":
20:       INPUT ATTR
21:       MATREAD A FROM F2,ATTR ELSE PRINT "NO ATTR ":ATTR ; GOTO 10
22:       AMC = A(2)
23:       CNV = A(3)
24: *      IF A(1) NE "D" THEN PRINT "NOT AN 'D' ATTR" ; GOTO 10
25: 12:   PRINT "MV POSITION     ":
26:       INPUT MVC
27:       IF MVC = '' THEN
28:          MVC = 1
29:       END ELSE
30:          IF MVC = 'A' THEN
31:             MVC = -1
32:          END
33:       END
34: 15:   PRINT "VALUE TO STORE  ":
35:       INPUT VALUE
36:       XVALUE = VALUE
37:       IF VALUE NE "DEL" THEN
38:          IF CNV NE "" THEN VALUE = ICONV(VALUE,CNV) ; XVALUE = OCONV(VALUE,CNV)
39:       END
40:       IF VALUE NE "DEL" THEN
41:          PRINT
42:          PRINT "WE ARE GOING TO STORE THE VALUE '":XVALUE:"'"
43:          PRINT "INTO ITEMS IN THE '":FNAME:"' FILE INTO ":ATTR
44:          PRINT "WHICH IS ATTRIBUTE NUMBER ":AMC
45:          PRINT "MULTIVALUE POSITION ":MVC
46:          PRINT
47:       END ELSE
48:          PRINT
49:          PRINT "WE ARE GOING TO DELETE"
50:          PRINT "MULTIVALUE POSITION ":MVC
51:          PRINT "WHICH IS ATTRIBUTE NUMBER ":AMC
52:          PRINT "INTO ITEMS IN THE '":FNAME:"' FILE INTO ":ATTR
53:          PRINT
54:       END
55:       PRINT "O.K. ?"
56:       INPUT ADV
57:       IF ADV NE "" AND ADV NE "Y" THEN GOTO 1
58:       CNT = 0
59:       CHGCNT=0
60: 20:   READNEXT ID ELSE GOTO 900
61:       CNT = CNT + 1
62:       IF MVC NE '' THEN
63:          READ REC FROM F1, ID ELSE NULL
64:          IF VALUE EQ "DEL" THEN
65:             DEL REC<AMC,MVC>
66:          END ELSE
67:             REC<AMC,MVC> = VALUE
68:          END
69:          WRITE REC ON F1, ID
70:       END ELSE
71:          WRITEV VALUE ON F1,ID,AMC
72:       END
73:       CHGCNT=CHGCNT+1
74:       GOTO 20
75: 900:  PRINT
76:       PRINT CNT:" items processed. "
77:       PRINT CHGCNT:" items changed."
78:       STOP
79:    END
80:

Hope this is valuable to someone
Regards,
Izzi
--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.

Don Robinson

unread,
Apr 1, 2020, 3:27:20 PM4/1/20
to mvd...@googlegroups.com
Hello all,
Here's one of my favorites, a program that compiles and runs a small BASIC program from TCL.
This is common in a lot of other languages but not Pick.
I remember this being discussed a few years ago but I think it's worth repeating.
My version is limited to one line of code but with the ";" char, you can get fairly complex.
This version works in Universe, you might need to make changes for other flavors.

CT BP RUNBASIC
* Utility program to compile and run a small BASIC program
* from the command line.
* Written by Don Robinson a long time ago.
* Last update April 1, 2020, no fooling!
* Example usage:
* RUNBASIC OPEN 'XXXX' TO F.XXXX THEN CRT 'OK' ELSE CRT 'XXXX IS MISSING'
*
PROGRAM.FILE = 'BP'  ;* Change as desired.
OPEN PROGRAM.FILE TO F.PROGRAMS ELSE
   CRT 'ERROR, unable to open the ': PROGRAM.FILE: ' file.'
   STOP
END
SENT = @SENTENCE[10,9999]  ;* Get rid of RUNBASIC.
*
WRITE SENT TO F.PROGRAMS, 'RUNBASIC.TEMP'
EXECUTE 'BASIC ': PROGRAM.FILE: ' RUNBASIC.TEMP' CAPTURING JUNK
IF INDEX(JUNK, 'No Object', 1) THEN
   CRT JUNK
END ELSE
   CRT '============== Results =============='
   EXECUTE 'RUN ': PROGRAM.FILE: ' RUNBASIC.TEMP'
END
END

Please excuse the UPPERCASE code, old habits are hard to break!

Here's a more complex example:
RUNBASIC OPEN 'MD' TO FILE THEN FOR N = 1 TO 5; PRINT N: ' ': FILEINFO(FILE, N); NEXT N; ELSE PRINT "Can't open MD file."
============== Results ==============
1 MD
2 d:\universe\accounts\dons/VOC
3 1
4 17
5 47

FILEINFO is a Universe function that returns various file info where 1 is the Pick name (MD is a Q pointer in Universe), 2 is the OS path, etc.

I claim no copyright or originality, use as desired.

Don Robinson


James A

unread,
Apr 1, 2020, 4:53:16 PM4/1/20
to mvd...@googlegroups.com
EXIT/CONTINUE are bit too much like 'goto' for me: easy to miss in complex code; and it's not always clear where they're 'exiting' to.

I prefer WHILE/UNTIL when possible; and in UV (not sure about other platforms) they work in FOR loops too. (and all our code uses lower-case keywords so it's not 'yelling' at 'modern' programmers; and we out-dent the 'while/until' for readability):

  for x = 1 to 10
      crt x
    while x < 5 do
      y = x + 10
  next x


You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/CAM49hkNZmuvXAYRAdbYx9BwfPTo39Gq0nYksXZxeLzHkKUMsWg%40mail.gmail.com.

jlab...@paradigm-systems.us

unread,
Apr 1, 2020, 5:18:31 PM4/1/20
to mvd...@googlegroups.com

I too like to use WHILE/UNTIL and LOOP/DO/REPEAT as much as possible.

 

I also use the backslash exclusively within my code so the single and double quotes are readily available as needed.

 

Has anyone assembled a document outlining these best practices for MV programming? If not, I think it would be a valuable reference to create one.

 

Regards,

Jay LaBonte

geneb

unread,
Apr 1, 2020, 5:22:26 PM4/1/20
to mvd...@googlegroups.com
On Wed, 1 Apr 2020, jlab...@paradigm-systems.us wrote:

> I too like to use WHILE/UNTIL and LOOP/DO/REPEAT as much as possible.
>

If you need to hop out of a for..next loop, you can't beat this:

for x = 1 to 10 until y = <value>
if <condition> then then y = <value>
next x

g.

--
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
http://www.diy-cockpits.org/coll - Go Collimated or Go Home.
Some people collect things for a hobby. Geeks collect hobbies.

ScarletDME - The red hot Data Management Environment
A Multi-Value database for the masses, not the classes.
http://scarlet.deltasoft.com - Get it _today_!

Don Robinson

unread,
Apr 1, 2020, 5:49:38 PM4/1/20
to mvd...@googlegroups.com
Gene,

I think this is simpler and avoids creating a separate variable:

for x = 1 to 10
    if <condition> then exit
next x

Of course, this is why there are a 1000 programming languages, we all have our favorites!

Regards,
Don Robinson



--
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+unsub...@googlegroups.com

For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+unsub...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/alpine.LRH.2.21.2004011419160.19221%40sidewinder.deltasoft.com.

Ian McGowan

unread,
Apr 1, 2020, 6:40:18 PM4/1/20
to mvd...@googlegroups.com
It's a really old technique, but worth knowing if you have truly huge dynamic arrays to process - use "REMOVE X FROM ARR SETTING MORE" is significantly faster than a standard for-loop.


--
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

For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.

Ian McGowan

unread,
Apr 1, 2020, 6:46:35 PM4/1/20
to mvd...@googlegroups.com
This is not quite a best practices document, but Rex Gozar had a very good coding standards document that I still refer to[1].  Even if you don't agree 100% with what's in here, if you're in a shop with more than one or two programmers it's worth documenting your own local standards and producing something similar...


Rex has several good pages about general programming on the wiki, all are worth a read: https://www.pickwiki.com/index.php/Rex_Gozar

Steve Trimble

unread,
Apr 1, 2020, 8:59:06 PM4/1/20
to mvd...@googlegroups.com
i became a huge fan of the 'backslash' character for quoting when I started programming html.
it also is MUCH easier for my eyes

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


Gerd Förthmann

unread,
Apr 2, 2020, 5:22:52 AM4/2/20
to mvd...@googlegroups.com

Even though I have used EXIT and CONTINUE on occasion I wouldn't have in the examples below.
In my opinion they are just a substitute for GOTO.
OK READNEXT ID ELSE EXIT  may be an option for D3 since WHILE READNEXT ID DO doesn't compile but I prefer WHILE and UNTIL especially if there are multiple conditions.
I nevertheless prefer a flag.

VAR = 0
LOOP
   READNEXT ID ELSE VAR=1
UNTIL VAR DO
   ...
REPEAT

In the FOR ... NEXT loop I would have written this:

C=DCOUNT(ATB<1>,@VM)
FOR X=1 TO C
   READ REC FROM FVAR, KEY THEN
      IF REC<99> # "GOOD" THEN
          ...
      END
   END ELSE NULL
NEXT X

IMHO that is much more readable for me and the 32K limit for Basic code doesn't apply any more.

Just my 2 cents

You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/CAM49hkNZmuvXAYRAdbYx9BwfPTo39Gq0nYksXZxeLzHkKUMsWg%40mail.gmail.com.

Tony Gravagno

unread,
Apr 2, 2020, 3:14:10 PM4/2/20
to Pick and MultiValue Databases
Jay, I think the concept of "best practices" is always arguable. Someone might want to post proposals in PickWiki.com, then create a new thread here to discuss each proposal. A link can be put in the wiki to link to the discussion.
Actually, the wiki itself is an ideal medium for this, as it already has a Discussion page for every page published. This is how wiki works. Either way is fine.

I kinda hope this thread isn't used too much for preferences, but more for concepts that others might not even know about. There is certainly overlap but I think we have ventured from one to the other when we go from "I never knew about that" to "we know about it and the best way to do that is ...".

It's alway better to create a new thread with its own topic than to have discussions lost under a different topic name.

Just musing....
T

Tony Gravagno

unread,
Apr 2, 2020, 3:22:45 PM4/2/20
to Pick and MultiValue Databases
It is indeed very helpful to be able to do that. I wrote one like this that performs the operation in a set of specified accounts, and also optionally sends the commands to phantoms rather than doing it all synchronously on the same port. It has other features added over a period of time. Stuff like this has a tendency to get so many cool features that it becomes too unweildy to use. :)

dgr...@dagconsulting.com

unread,
Apr 2, 2020, 3:30:18 PM4/2/20
to mvd...@googlegroups.com

Here is an easy way to check typos in your zip codes:

 

LIST CM WITH Country_Code = “CAN” AND WITH Zip UNLIKE “1A1N1A‘ ’1N1A1N” Name Zip

Or

LIST CM WITH Country_Code = “USA” AND WITH Zip UNLIKE “5N OR 9N OR 5N‘-’4N” Name Zip

 

 

David A. Green

DAG Consulting

(480) 201-7953

 

 

Tony Gravagno

unread,
Apr 3, 2020, 2:22:05 PM4/3/20
to Pick and MultiValue Databases
Good tip, David. Unfortunately that doesn't work the same in D3 as it does in U2.

For D3 the AQL syntax is more convoluted and limited:
list cpSites eval "oconvs(postalcode,'p(1a1n1a)')" fmt "'In Canada'" postalcode stprcode countrycode.

That results in the following kind of result:

cpSites... In Canada postalcode...... countrycode

1056                 38354 CEDEX      FR
1067                 75195 CEDEX 04   FR
1078                 69303 CEDEX 07   FR
1089                 30006 CEDEX 4    FR
1100       N8M       N8M              CA
1111                 36005            ES
1122                 75675 CEDEX 14   FR
1133                 25705            US
1144       K4K       K4K              CA
1155                 47336            MX
1166                 94724            MX
1177       V3B       V3B              CA
1188                 PH43             GB
1199                 1171             AU
1210                 94364 CEDEX      FR
1221       G7S       G7S              CA



The lack of elegance in D3 can be addressed using a Phrase. I don't think I've ever seen people use the Phrase feature in D3, though it is used in other platforms. Here is an example related to pattern matching and postal codes:

:u  dict cpSites in.canada
DICT cpSites  'in.canada' size = 123
01 h
02  with eval "oconvs(postalcode,'p(1a1n1a)')" # ""
03  or with eval "oconvs(postalcode,'p(1n1a1n)')" # ""



:list cpSites in.canada postalcode countrycode

cpSites... postalcode...... countrycode

1100       N8M              CA
1144       4K4              CA
1177       V3B              CA
1221       G7S              CA
1243       B3T              CA



Lots of tips in these notes .. I hope people don't miss them. :)
T

frosty

unread,
Apr 3, 2020, 4:59:05 PM4/3/20
to Pick and MultiValue Databases
On Wednesday, April 1, 2020 at 8:41:33 AM UTC-6, Tony Gravagno wrote:

CMD = \SELECT FOO\
CMD<1,2> = \SAVE-LIST BAR\
CMD<2> = \GET-LIST BAR\
EXECUTE CMD
[snip]
 
Compare to :

DATA \SAVE-LIST BAR\
DATA \GET-LIST BAR\
EXECUTE \SELECT FOO\

That code has always confused people, and it's difficult to work with.
 
Agreed. The MV command approach is nice! Hopefully it's not an April Fool's prank. =`:^p

Here's what I use:

CMD = \SELECT FOO\
DATA \SAVE-LIST BAR\
DATA \GET-LIST BAR\
EXECUTE CMD

It works, the commands are in the code in the logical order, and I don't have to remember if the next command is the next attribute or the next value.

--
frosty

Marcus Rhodes

unread,
Apr 12, 2020, 1:08:03 PM4/12/20
to Pick and MultiValue Databases
So, attached is a 'tip' (or trick) (depending on your perspective) that I use a lot.  It's a universal keyboard handler for when I don't want to bother with SB or ATW's GUI.  It enables all the special keys in my programs, including all the levels of function keys, and, when ATW is used, the mouse, too.

There's a driver (EMV_KEY_GET_TST) just to see what it does, as well as to see what keys your terminal offers.

Further instructions and details are in the comments of each program.

I like it.  It works great on my OpenQM system, and forms the core of my CUI.  Adjustment for your flavor and host should be pretty easy, and I'd love it if you share such adjustments with us.  I promise to include any such help with credit because this is open-source, free to all.

Coming (hopefully) soon: A universal terminal output handler, complete with all 'attributes' and even a 'screen buffer'.


EMV_KEY.tar.gz

Peter McMurray

unread,
Apr 12, 2020, 5:19:20 PM4/12/20
to Pick and MultiValue Databases
Hi
 Thanks for the eval clarification. I trust that users will spot oconvS and tranS and that they require proper Attribute dictionaries not Synonym dicts. So many do not make this distinction.

Regarding stacking the commands for execute. I would caution against this for selections as one could spend time looking for the wrong error if the selection fails. I prefer to use system(11) after the selection and then act accordingly.

Regarding the use of LOOP. I find this one of the most useful commands in the language and suggest the following format clarifies the issue mentioned.

id = ""
loop;* record control
   readnext id else id = @am;* Id an id can never be an AM so safer than count
while id ne @am do
   do lots of things including loops and for nexts but always label wisely
   for cntFields
   next cntFiields never for a = 1 to 99 I have seen a programmer come to me for assistance after looking for a day. They had used for A etc on a long loop and in the middle gone to a subroutine that also used for A etc!!
repeat;* end of record control loop

I wonder what Gerd means by the 32k basic limit. I hope that nobody would have a loop that long. However I have seen a dreadful program that had an include of over 1000 lines that refereed to lines in the main routine to get an extra long program to compile. Better to redesign the program in my opinion.



Steve Trimble

unread,
Apr 12, 2020, 6:21:37 PM4/12/20
to mvd...@googlegroups.com
Peter:
how about:
LOOP
 READNEXT ID FROM IDLIST ELSE EXIT -- or READNEXT ID ELSE EXIT
 READ..... etc
REPEAT

I am like you. love the loop. not real crazy using WHILE (ever)
just me though
be well and Happy Easter all!


Computerized Data Mgmt Inc
Steve Trimble
(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+un...@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.

Ian McGowan

unread,
Apr 13, 2020, 1:01:09 PM4/13/20
to mvd...@googlegroups.com
This is amazing, and I'll be trying this out on Unidata.  If you had a github/gitlab/bitbucket repo somewhere it would be much easier to share any adjustments/enhancements.  TonyG has a collection of software at https://bitbucket.org/foss4mv/.

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/7bd57d95-b010-480c-81ea-4b5547dc9748%40googlegroups.com.

Ian McGowan

unread,
Apr 13, 2020, 1:12:42 PM4/13/20
to mvd...@googlegroups.com
"wonder what Gerd means by the 32k basic limit" - in the bad old days (80's, maybe early 90's?), your compiled object code had to be less than 32K, so for bigger programs (or programs with lots of includes) there was much anguish and trickery to stay below this limit. Subroutines were considered slow, so breaking up the program was a last resort, CHAIN'ing was preferred. There was a lot of cargo culting - different places I worked had different ideas about performance. Some didn't allow dynamic arrays, some insisted that all OPEN's be to a common block, some used single letter variables to "save space". All of which had some basis in history..

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.

Ian McGowan

unread,
Apr 13, 2020, 1:24:39 PM4/13/20
to mvd...@googlegroups.com
I love EXIT and CONTINUE and consider them more "structured" than setting and checking a variable, since there's no doubt about what will happen when you hit these statements.  But some think of them as hidden goto's and eschew them.  It's personal taste, I have to deal with code using both techniques, I just try and stay consistent with whatever the code base does.

You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/CAJDLGm54PDfYd-VPeWdR_hxXqZC2CrZz-aHGn8hKYrFUEYKyxQ%40mail.gmail.com.

Tony Gravagno

unread,
Apr 13, 2020, 1:36:59 PM4/13/20
to Pick and MultiValue Databases
Marcus - I see what you're doing but I'm not getting my head wrapped around the EMV concept. I'm hoping you will create a new thread to describe this. It seems like you had some context in your head that isn't communicated by the software itself. I mean, please start with "What are the initials 'EMV' for?". Then, how would one use the code that you have generously provided.

For someone using AccuTerm with D3 or QM, I created a page with keyboard mappings that allow full/near-full natural keyboard usage at TCL, UP, and SED.

Thanks.
T



On Sunday, April 12, 2020 at 10:08:03 AM UTC-7, Marcus Rhodes wrote:
So, attached is a 'tip' (or trick) (depending on your perspective) that I use a lot.  It's a universal keyboard handler for when I don't want to bother with SB or ATW's GUI....

Tony Gravagno

unread,
Apr 13, 2020, 1:40:30 PM4/13/20
to Pick and MultiValue Databases


On Monday, April 13, 2020 at 10:01:09 AM UTC-7, Ian McGowan wrote:
 TonyG has a collection of software at https://bitbucket.org/foss4mv/.


Um, to be entirely correct.... Yes, I do have a collection of software at FOSS4MV, but that is just one collection amongst many FOSS offerings contributed by other people. Kevin Powick created FOSS4MV. I just wish more people in the MV industry appreciated MV FOSS and participated in the model.

Gerd Förthmann

unread,
Apr 13, 2020, 3:50:17 PM4/13/20
to mvd...@googlegroups.com

To solve the 32K Basic limit riddle.

In the beginning of Pick the problem was that source code files like any other data record couldn't exceed 32K.
Object code and spooler entries were the only files that could be larger.

So writing code using a minimum number of characters became a challenge for programmers in the 80s.
No comments, multiple commands in one line, short variable names, no indentation - anything to stop a growing program from exceeding the 32K limit.
Chaining multiple source code files was usually the last option when a program grew too long.
Unfortunately the code became more and more unreadable that way.

Some of these tricks remind me of those days.
Without 32K limitation it doesn't makes sense to me to use such techniques any longer; it is more important that "the next programmer" can understand the code not how few Bytes the source code has. And that may even be yourself trying to make sense of code you wrote a few years ago.

Well, and we only had ED as editor then.
These days with modern editors with syntax high-lighting and indent functionality writing well structured loops and conditions makes even more sense.

You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/CAM49hkN3C_NYgK6uTbrM2d5SfibTot3k--VLKA9cYpcN2gx6CA%40mail.gmail.com.

antlists

unread,
Apr 13, 2020, 4:47:30 PM4/13/20
to mvd...@googlegroups.com
On 13/04/2020 18:24, Ian McGowan wrote:
> I love EXIT and CONTINUE and consider them more "structured" than
> setting and checking a variable, since there's no doubt about what will
> happen when you hit these statements.  But some think of them as hidden
> goto's and eschew them.

If EXIT and CONTINUE aren't acceptable, then why is LOOP acceptable? or
FOR NEXT? :-) After all, they're just hidden gotos too ... :-)

Cheers,
Wol

Rob Allen

unread,
Apr 13, 2020, 8:07:17 PM4/13/20
to Pick and MultiValue Databases
I tend to use:

LOOP WHILE READNEXT ID FROM THELIST DO
*  --stuff
REPEAT

Marcus Rhodes

unread,
Apr 14, 2020, 10:06:43 AM4/14/20
to Pick and MultiValue Databases
Yeah, I suppose I could have been more verbose.

EMV is the TLA for my 'company': Evolution/MV.  It serves two purposes: 1) Branding, and 2) Conflict avoidance.  I hate it when I try to install my personal suite of tools on a system only to find that they already have programs with the same names as mine.  It really complicates life.  Prefixing everything with EMV sidesteps all of that.

As for the how-to, as I wrote earlier, it's all extensively documented in the code, in particular the main 'program': EMV_KEY_EQU

In there, you find (among a lot of other rambling), this:

! Examples: INCLUDE EMV_KEY_EQU

!           LOOP

!              CALL EMV_KEY_GET( YOUR_KEY )

!              BEGIN CASE

!                 CASE YOUR_KEY EQ KC_HOME     ; GOSUB JUMP.TO.TOP
!                 CASE YOUR_KEY EQ KC_END      ; GOSUB JUMP.TO.END
!                 CASE YOUR_KEY EQ K_PAGE_UP   ; GOSUB PAGE.UP
!                 CASE YOUR_KEY EQ K_PAGE_DOWN ; GOSUB PAGE.DOWN
!                 CASE YOUR_KEY EQ K_UP        ; GOSUB LINE.UP
!                 CASE YOUR_KEY EQ K_DOWN      ; GOSUB LINE.DOWN
!                 CASE YOUR_KEY EQ K_HOME      ; GOSUB LINE.BEG
!                 CASE YOUR_KEY EQ K_END       ; GOSUB LINE.END
!                 CASE YOUR_KEY EQ K_BACKSPACE ; GOSUB DELETE.LFT
!                 CASE YOUR_KEY EQ K_DELETE    ; GOSUB DELETE.RGT
!                 CASE YOUR_KEY EQ K_INSERT    ; GOSUB TOGGLE.INSERT
!                 CASE YOUR_KEY EQ K_ESC       ; EXIT
!                 CASE OTHERWISE               ; GOSUB ADD.TO.TEXT

!              END CASE

!           REPEAT
Message has been deleted

Marcus Rhodes

unread,
Apr 14, 2020, 10:19:38 AM4/14/20
to Pick and MultiValue Databases
I agree about folded, compound lines obscuring critical changes in program flow.  Finding no viable solution in coding style, I modified my nano profile, instead, to highlight all such commands in bold and red.  Now, they never hide from me.

WED also allows something similar in its Settings/Highlight dialog-box, though not as dramatic or as extensive as my nano solution.

TonyG Test

unread,
Apr 14, 2020, 1:50:38 PM4/14/20
to Pick and MultiValue Databases
On Monday, April 13, 2020 at 5:07:17 PM UTC-7, Rob Allen wrote:
> I tend to use:
>LOOP WHILE READNEXT ID FROM THELIST DO
>*  --stuff
>REPEAT

Rob - This assumes there's an implicit return value on the Readnext operation, which I've never seen documented, and on which I would not rely. I just tried it in D3 and it fails with an unassigned variable error. The variable is really the implicit expression, which is undefined. D3 does not accept a statement as an expression, other platforms may, and again that may depend on if there is a defined implicit return value.

EXECUTE "SELECT MD = P]"
LOOP WHILE (READNEXT VERB) ; * << "unassigned variable at runtime
 CRT VERB
REPEAT

I think what's happening there is that it's looking for variable READNEXT (because we can do that) and it's trying to apply another variable VERB as a mask, like VAR "L#10".

Tossing in my own 2 cents while I still think all of this should be in a different thread... I struggle with the Loop construct too. It always seems uncomfortable in this context of processing a select list. I'd like to do this:

LOOP READNEXT ID WHILE ID # "" DO
or
LOOP READNEXT ID UNTIL ID = "" DO

But I have never fully trusted ID to be reset to null when the readnext fails - I always rely on the ELSE clause. I haven't read the docs on this but I don't recall any notes that say the value is set to anything on ELSE. So my tip on this is to be explicit, never assume.

BUT! You nerds are gonna like this ... we all assume that we need WHILE/UNTIL and DO on a LOOP, but this is not the case with D3 where all of them are optional. << Another tip!
Example:

LOOP
  READNEXT ID
WHILE ID # "" ; * no DO
  CRT ID
REPEAT

01 EXECUTE "SELECT MD = O]"
02 LOOP READNEXT VERB THEN CRT VERB ELSE EXIT REPEAT ; * only LOOP+REPEAT!

To be crystal clear: We traditionally want a loop where we are defining the exit condition. The exit condition is already present in the READNEXT (note, where we also have a THEN clause). But then out of habit we double-up on that to provide a conditional exit to the LOOP as well. What we see above is that we don't Need to use the WHILE/UNTIL+DO construct of LOOP redundantly with READNEXT. Yes, we need an EXIT, but it's sitting right next to the REPEAT, so it's not inelegant. Let's break it up a little:

LOOP
 READNEXT VERB THEN GOSUB PROCESS ELSE EXIT
REPEAT

Now it's very obvious that the LOOP/REPEAT is just there to support the loop. There's no decisions. There is no awkward requirement for a DO block, even an empty one. And keeping this modular, the PROCESS subroutine handles all of the functional bits while this routine is entirely responsible for looping on the list. To me, that's Elegant!

Now - go forth all ye, please verify this syntax on your own platforms and tell us what works and does not.

HTH
T


Ian McGowan

unread,
Apr 14, 2020, 1:54:11 PM4/14/20
to mvd...@googlegroups.com
I have a program that does 1/100 of what this subroutine is doing, hardcoded with values for wyse and vt100 terminals.  Just enough to make my TCL bash-equivalent bearable.


But I've always wanted to press home instead of CTRL-A or end instead of CTRL-E so I'm going to give it a try...

 

--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.

Peter McMurray

unread,
Apr 14, 2020, 6:28:59 PM4/14/20
to Pick and MultiValue Databases
Ah the 32kb limit. I had a suspicion that that was what was referred to. A typical demonstration of the failure to grasp Pick by many, not Gerd obviously.
It was the item size. Since that represents over 1000 lines of source code. Time to rethink the program. As for short variable names that came from interpretive basic a compiled object was much shorter.
Definitely dimensioned arrays are invariably better than string reads because of the brilliant way Pick stores overflowed variables. I well remember DataMail in the late '70s wrecking the system frequently because some clown thought it was a great idea to include all the transactions as an extra line in the debtors' master items. Net result dead slow and then crash as the best customers had the most transactions and string extraction is dramatically slower even today. Plus inevitably the item for the best customer exceeded 32kb or I should say KIB these days.
Dimensioned arrays set aside a set of sequential 10 byte variables in memory. Thus instant access to any position. Plus the brilliant Pick overflow handling of individual variables maximises the benefits.
Short subroutine calls also maximise the benefit of paging systems.

Marcus Rhodes

unread,
Apr 14, 2020, 9:00:35 PM4/14/20
to Pick and MultiValue Databases
Glad to help!

Here's something else you might find useful in conjunction with that, provided you're using AccuTerm.

I've attached a template that I use to map any terminal's dead keys to something useful.  It's essentially the keyboard definition section of a .atcf file, but with ALL the cool keys mapped, including many that your terminal already has.  All you have to do is remove any of those existing keys from this template, then replace your .atcf file's '[Keyboard]' section with whatever's left.  So, say you want keys like Ctrl+Home, Shift+Right, etc. for your hard-coded, Wyse 50-compatible programs, this trick will provide that, but without fouling up existing programs, including TCL, that still expect to see what few Wyse key codes they're used to seeing.
To unsubscribe, email to: mvd...@googlegroups.com

For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvd...@googlegroups.com.
ATW_KEYS.atcf

Ian McGowan

unread,
Apr 15, 2020, 2:56:26 AM4/15/20
to mvd...@googlegroups.com
Yep, remapping keyboard in terminal emulator is good if you're in a "stable relationship" with your Pick system. Unfortunately for me I spend most of my time remoting in to other people's networks, and there's a hodgepodge of TE's in use.  If I can I download MobaXterm portable or Putty (and VSCode, if they let me), that makes things bearable...

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

For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to a topic in the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mvdbms/7qG7zRmhLvE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/4a2e4c8e-8775-49f9-b8d6-997e7ee82ae3%40googlegroups.com.

Marcus Rhodes

unread,
Apr 15, 2020, 10:44:05 AM4/15/20
to Pick and MultiValue Databases
EMV_KEY work beautifully with PuTTY, too.

Tony Gravagno

unread,
Apr 15, 2020, 12:24:07 PM4/15/20
to Pick and MultiValue Databases
Marcus, any interest in documenting that mapping so that we can get it up on the PickWiki page?

Marcus Rhodes

unread,
Apr 15, 2020, 1:29:55 PM4/15/20
to Pick and MultiValue Databases
I'll get right on that, Tony.  What else is needed beyond what I already wrote here?

chandru murthi

unread,
Apr 15, 2020, 3:37:56 PM4/15/20
to Pick and MultiValue Databases
I hate the use of EQ, NE, etc instead of, as Pascal intended = , # etc.
As with using mixed case, there's probably studies proving why the change from alphabetics to non-alpha and back is much more readable.
And it's less typing ;).

Chandru

On Tuesday, April 14, 2020 at 7:06:43 AM UTC-7, Marcus Rhodes wrote:
Yeah, I suppose I could have been more verbose.

Charlie Noah

unread,
Apr 15, 2020, 3:55:08 PM4/15/20
to mvd...@googlegroups.com
I agree with you completely, Chandru. =, #, etc. seem to jump out at me, at least to my tired old eyes. I'm all for less typing, since I only have 1 hand to work with.

Struggling through Stay At Home,
Charlie
--
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
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mvdbms/fae92f75-2c87-4809-8432-e3bf55434495%40googlegroups.com.

John Lorentz

unread,
Apr 15, 2020, 5:24:10 PM4/15/20
to mvd...@googlegroups.com
On Wed, Apr 15, 2020 at 12:55 PM Charlie Noah <cwn...@comcast.net> wrote:
I agree with you completely, Chandru. =, #, etc. seem to jump out at me, at least to my tired old eyes. I'm all for less typing, since I only have 1 hand to work with.

Whereas, I find EQ and NE much more readable when I'm looking at a program that's new to me.

John 

Wols Lists

unread,
Apr 15, 2020, 7:23:58 PM4/15/20
to mvd...@googlegroups.com
Is that the FORTRAN programmer in you? I don't like = and # in if
statements because - certainly as far as = goes - it's also the
assignment operator. Say what you like, eq and ne are unambiguous
comparison operators.

Cheers,
Wol

Marcus Rhodes

unread,
Apr 15, 2020, 7:35:19 PM4/15/20
to Pick and MultiValue Databases
Hear!  Hear!  Operator overloading is madness.  Programming is already too much like playing chess in your head.  Why further complicate it by having to mentally process which operation is meant every time you see it?  And that extends to variable and label names, too.

Charlie Noah

unread,
Apr 16, 2020, 10:12:02 AM4/16/20
to mvd...@googlegroups.com
Hi Wol,

I've never programmed in FORTRAN, although I'm familiar with it. I
started off in 1978 using Microdata Reality. Since I'd found the best
environment in the world, I quit looking at others.

VAR = 1     is a variable assignment statement
IF VAR = 1 THEN     here VAR = 1 is an expression, which evaluates to a
Boolean
   do something
END ELSE
   do something else
END

I have never had a problem using =, etc. They just came naturally to me.
Different strokes...

Charlie

Tony Gravagno

unread,
Apr 16, 2020, 1:04:07 PM4/16/20
to Pick and MultiValue Databases
Nothin, bud. It's a wiki. :)  Contribute whatever you can, whatever you desire, and whatever you have the time for. There's also no shame in slapping it up there with little documentation and asking others to help. Cuz ... It's a wiki. :)

Thanks!
T

Tony Gravagno

unread,
Apr 16, 2020, 1:13:05 PM4/16/20
to Pick and MultiValue Databases
"FOR I=..."
"FOR J=..."
"FOR N=..."
This is a typical convention used by BASIC programmers who have never seen Fortran.
Why? Because those letters meant Integer while others were FP.

T << your community floating point?

Rob Allen

unread,
Apr 16, 2020, 4:10:02 PM4/16/20
to Pick and MultiValue Databases
Thanks, Tony. I didn't know this syntax was unique. I'm using Reality (the ADP/CDK variant).

Scott Ballinger

unread,
Apr 19, 2020, 1:33:22 PM4/19/20
to Pick and MultiValue Databases
As has been pointed out recently is a couple of other threads, using rec<-1> slows down severely when dealing with 100s of thousands of appends.  When processing a large number of items I often leave behind a save-list of the new or changed records; if I am dealing with a lot of them then updating my save-list with <-1> quickly becomes the slowest part of the program. (This is mostly a D3 issue, as UV seems quite fast when appending with @am.) My fix is to build the save-list as a series of dynamic arrays inside of a dimensioned array. D3 allows re-dimensioning the array on the fly, so it can grow as large as needed (I have created save-lists this way with 10s of millions of ids with no slowdown).

Here is my code snippet that I paste in when needed:

big.save-list
* build a very large save-list as dimensioned array
* paste into your program...

* initialize
dim svlist.array(svlist.no)
svlist.array(1) = ""

* update loop
svlist.array(svlist.no)<-1> = id
if len(svlist.array(svlist.no)) gt 4000 then  ;* < 1 frame?
  svlist.no += 1
  dim svlist.array(svlist.no)
  svlist.array(svlist.no) = ""
end

* write
if svlist.array(1) ne "" then
  open "pointer-file" to pf else stop 201,"pointer-file"
  write svlist.array on pf,"your-list-name"
end

IIRC a little testing shows that the max length (4,000 above) doesn't make much difference until above 50K or so.

/Scott Ballinger
Pareto Corporation
Edmonds WA USA

Marcus Rhodes

unread,
Apr 19, 2020, 2:18:52 PM4/19/20
to Pick and MultiValue Databases
And, if your save-list file is a directory, sequential writes to that directory not only approach RAM speeds, but save RAM, and leave a save-list when you're done.
Reply all
Reply to author
Forward
0 new messages