Miscellaneous Thought

Hello Everybody,

While attempting to convert a Pan6 procedure to PanX, I have come across a quirk that perhaps is unknown to other users. Since I wish to have PanX as accurate and stable as possible, here is the issue (which you can replicate).

Prepare a simple database with a Date field and another field. Call it “Untitled”.
image

In another database, copy and run the following code:

Local t1

//   OPTION 1
setactivedatabase "Untitled.pandb"
Find «Date» = table("Untitled.pandb","Date",
    date("10/13/2016"),"Date",0,0)
message «Net»

//OPTION 2
setactivedatabase "Untitled.pandb"
t1 = table("Untitled.pandb","Date",
    date("10/13/2016"),"Date",0,0)
Find «Date» = t1
message «Net»

RTN

In Pan6, both options return the same result. But PanX fails Option 1, and always returns the first record in the database. The Option 2 workaround is trivial although not elegant, BUT ONLY IF YOU KNOW THERE IS A PROBLEM.

Here is the point of this topic. As you might imagine, tracking this error down was a real bear without single stepping. I never imagined the error could be in this section of code at all - it seemed so straight-forward. So I was focusing on the rest of the code and getting nowhere.

Jim has stated many times that single stepping is not going to happen for some time. It must be a very difficult problem, or he would have already implemented it. But I fear PanX will not reach its full potential until single-stepping is resurrected. I hope Jim has an epiphany - a brilliant flash of perception - which gives him the key to solving this issue.

In the meanwhile, I think I must put PanX away again, at least until the next beta update. It is just too frustrating to find and debug the aberrant sections of code which work differently from the Pan6 code.

Best regards,
Vic

If I insert a selectall into your code, both options deliver same result “goodbye”.

local t1

//   OPTION 1
selectall
setactivedatabase "Untitled.pandb"
find «Date» = table("Untitled.pandb","Date",date("13.10.2016"),"Date",0,0)
message «Net»

//OPTION 2
selectall
setactivedatabase "Untitled.pandb"
t1 = table("Untitled.pandb","Date",
    date("13.10.2016"),"Date",0,0)
find «Date» = t1
message «Net»

RTN

… and if I insert the selectall after the setactivedatabase, the wrong result is back! :rage:

local t1

//   OPTION 1
setactivedatabase "Untitled.pandb"
selectall
find «Date» = table("Untitled.pandb","Date",date("13.10.2016"),"Date",0,0)
message «Net»

//OPTION 2
setactivedatabase "Untitled.pandb"
selectall
t1 = table("Untitled.pandb","Date",
    date("13.10.2016"),"Date",0,0)
find «Date» = t1
message «Net»

RTN

The first option is a very poor way to implement this algorithm. In running the Find statement, Panorama will scan the entire database over and over again, which means the table( function will run over and over again. The table( function has to scan the entire database. In this example there are only a few records, so that won’t matter, but presumably in a real database there will be hundreds or thousands of records, so the performance hit would be substantial. For example if there were 1,000 records that would mean Panorama would scan a million times, instead of only a thousand. This is really not a correct use of the table( function, certainly it was never tested this way on any version of Panorama. The fact that this apparently worked sort of the way you wanted on Panorama 6 is a happy accident.

If you just need to display the correct value of Net, here is how I would write this code:

message date("Untitled","Date",date("10/13/2016"),"Net","")

Just one line of code, and it will only scan the database once, no matter how many records there are.

Notice also that .pandb is not needed when referencing an open database, and it is not recommended (though it will work).

To be clear, single stepping is no longer a planned feature for Panorama X. The single step tool has been removed from the toolbar. Single stepping just isn’t feasible with the way that Panorama interacts with the macOS UI code. It never worked correctly in earlier versions of Panorama, and despite it being a priority for Panorama X it was a failure. No further resources will be expended on this.

In this specific case, I fail to see how single stepping would have been helpful in tracking this down. Even if it did work in some situations, it would not ever be compatible with secret windows, which you are using here.

Please keep in mind that it is not a goal of Panorama X to 100% duplicate the behavior of Panorama 6, especially when it comes to code that only worked in the first place by accident. It’s now a dozen years since Panorama X was released, and a half decade or more since most users stopped using Panorama 6. Yes, there are a small number of people that have delayed this transition, but the focus of Panorama X development is now firmly looking forward, not backwards at previous versions of Panorama.

Surely you meant

message lookup("Untitled","Date",date("10/13/2016"),"Net","")

Ouch! Actually I meant

message table("Untitled","Date",date("10/13/2016"),"Net","")

Hello Jim,
Thanks for taking the time to respond.

I did not know that the table function scans the entire database multiple times. But in my procedure, the actual database scanned never contains more than a dozen records - maybe in unusual circumstances 20-30. But rarely more. Scan search time is not an issue.

And in any event, the lookup( function you suggested would absolutely not work. In almost all cases, there will not be an actual match. The procedure needs to find the previous record earlier than the inputted date. (I make sure to sort the database beforehand.) As I understand it, table( is the only way to do that. Note that the simple example I showed did not have an exact match.

I know you have previously stated that single-stepping is difficult (impossible?) in PanX. But don’t discount getting a flash of insight, which sometimes comes to us when we least expect it. The greatest feats of creativity often hit us when we solve something that is “impossible” to solve (relativity, quantum physics, the nature of light, etc.).

I did not mean the topic thread to be a criticism, by any means. Your effort with PanX has been Herculean, and I continue to expect great things moving forward. Who knows, maybe someday in future, you will see the way to attack this problem, and think to yourself - “It’s so obvious! Why didn’t I think of this before?”

Best regards,
Vic

The table( function does not scan the database multiple times, just once. But in putting this function in the Find statement, that statement invokes the table( function multiple times – once per record. This serves no purpose because it will return the same value every time. Much better to simply determine the value once in advance.

I didn’t suggest the lookup( function. My original response mistakenly suggested the date( function, which was a “brain fart” typo. I corrected that to the table( function.

I don’t think this is a “flash of insight” type of problem. It’s hard to make analogies, but this is more of a “logistical” problem than an “insight needed” problem (this is not a great analogy, but it’s all I can think of at the moment). I’ve already expended a huge amount of resources on trying to make this work – at some point it’s time to stop throwing the good after the bad and move on to productive endeavors.

However, I promise that in the unlikely event that I do have a “flash of insight” on this topic I will follow it up.

Vic, you can do something equivalent to single stepping through your procedures: Insert a nsnotify to display some value for the step you want to test, then a stop statement. If this step delivers the expected result, move both statements forward to the next step you want to check.

Hello KJM,

Yes, I know about nsnotify.

Some of my most important financial macros first download a web page (using the loadurl function), and then manipulate the source page text with various TAG functions. In almost all such cases, the resulting variables created are multi-line text arrays. Not well-handled by nsnotify.

The main method of debugging I had used in Pan6 was to write or debug macros in a special database, called “Macro Debugger”, with a “Display” field. At various points in my macro, I would put a variable into that field («Display» = myvar), followed by a debug statement. A Form in that database showed the contents of the Display field. If everything looked good, I continued the macro from that debug point to the next debug point. This allowed me to see the entire text array variable at once, to make sure any ARRAYFILTER action I used was giving me expected results. In fact, this method allowed me to see several single-line variables at once.

«Display» = myvar1 +¶+ myvar2 + etc.

I am using the same method in PanX to follow variable values. Of course, this method will not show whether an action, such as “Find”, was completed correctly. But it does give immediate feedback that an ARRAYBUILD statement was entered with the correct formula, or a TAGARRAY is working correctly.

Is there a target date for the next beta update, Jim? I may wait for that update before plunging into the water again.

Vic

Panorama 10.2 includes a new system that is similar to the technique you have been using. For me it has been a revolution for debugging.

Wow, Jim. That zlog feature is really something. And very well documented!!

But I think it may be beyond my capabilities. At age 80, my physical and mental processes have slowed (old dog,…new tricks …).

For now, I’ll probably just stay with what I’m used to.

Vic

I highly doubt that’s the case.

If you do find it challenging, I highly recommend the Mastering Panorama 10.2 video course, which you can purchase from the Video Training window. This course walks you step by step through setting up and using the Debug Instrumentation feature.