Tuesday, November 19, 2019

#1 2019-10-13 06:46:14 pm

hansolo625
Member
Registered: 2019-04-17
Posts: 21

Bug? Defining a variable as number and it's "memorized"

This is very hard to describe over text but I will do my best. I also must preface that I'm rather novice so forgive me if I'm not using proper terminology. Here goes:

I made a web scraper for work and one of the items I'm scraping isn't static/constant but would always be one of the following: a) Two different numbers b) Two of the same numbers c) Only one number d) No number at all.

If there are two numbers presented, I'm required to scrape the larger value. So here's the part of the script

Applescript:


try
   set Num1 to ScrapeByClass("html_class", 0) as number
   set Num2 to ScrapeByClass("html_class", 1) as number
   if Num2 is greater than Num1 then
       set varNum to Num2
   else
       set varNum to Num1
   end if
on error
   try
       set varNum to Num1
   on error
       set varNum to "N/A"
   end try
end try

return varNum

NOTE: ScrapeByClass is a handler that uses JavaScript to scrape a webpage

Applescript:


to ScrapeByClass(elementClass, num)
   tell application "Safari" to do JavaScript "document.getElementsByClassName('" & elementClass & "')[" & num & "].innerHTML;" in document 1
end ScrapeByClass

So I start with scenario a) where there are two different numbers and I use a if statement to define the larger value, or if it's the same (scenario b), it would just define it as one of the numbers presented. In scenario c) where there's only one number given, it goes in the error loop and simply scrape the given single value. Lastly, if none is given, it sets the variable to "N/A" for final result.

The script seems to work fine with the exception of this one issue (or bug?). If I run the script, scrape a value and print it, when I run the script again that has scenario d) with no numbers given. It would still print the last scraped value despite nothing is presented on the webpage. This is not observed when I run the script for the first time on a scenario d) with no numbers.

After spending couple hours messing around, I noticed that when I remove "as number" at the beginning of my script (line 2 and 3). This error is no longer observed. However, because the web scraper handler defines the variable as a string and two strings cannot be compared for a "larger" value, the if condition is broken. So then I'm stuck in between.

Has anyone ever experience such thing?

Initially I thought it's related to browser caching issue because of the handler. However, this is not the case as I have tried clearing Safari browser data/cache (completely) but the script still remembers the last value scraped when the webpage doesn't have a value. Also, in my research, I learned that you cannot declare a variable as undefined in AppleScript so it's not possible to do "If variable is null/nil/"" then ..."

I'm at a lost at the fact that AppleScript is "memorizing" a value when the script never involved any data structure or storage.

Any insight/advice is largely appreciated!!!

Last edited by hansolo625 (2019-10-13 06:49:29 pm)

Offline

 

#2 2019-10-13 07:27:25 pm

maro
Member
From:: Nerima, Tokyo, Japan
Registered: 2004-05-30
Posts: 34
Website

Re: Bug? Defining a variable as number and it's "memorized"

You can compare strings as numbers by using "considering numeric strings" clause.
How about this?

Applescript:


set a to "10.1"
set b to "2"

considering numeric strings
   set c1 to (a > b)
end considering

set c2 to (a > b)

return {c1, c2}

Model: MacBook Pro 2012
AppleScript: 2.7
Browser: Safari 13.0.1
Operating System: macOS 10.14


I wrote thousands of AppleScript to realize my idea. Natural language interface, voice recognition commander and so on. Though my mother toungue is strange language, Japanese, my most frequently write language is AppleScript. I believe it is for making things easy and powerful.


Filed under: compare

Offline

 

#3 2019-10-14 05:57:11 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5105

Re: Bug? Defining a variable as number and it's "memorized"

hansolo625 wrote:

If I run the script, scrape a value and print it, when I run the script again that has scenario d) with no numbers given. It would still print the last scraped value despite nothing is presented on the webpage. This is not observed when I run the script for the first time on a scenario d) with no numbers.


Hi.

It's a feature (peculiarity?) of AppleScript that when a script's run, the values of any properties, globals, or "run handler" variables are saved back to the script file and are there next time the script's run. The variables in your script are all "run handler" variables — that is, they're all set in the main body of the script. So on subsequent runs, Num1, Num2, and varNum start with the values they had at the end of the previous run. If the script errors while trying to set Num1, and Num1 already exists with a value, the existing value's retained and varNum is set to that.

The easiest cure would be to declare Num1 (and Num2 and varNum if you like, although this doesn't affect the working of the script) as local at the top of the script, so that it ceases to exist when the script's finished and its value isn't saved back to the file:

Applescript:

local Num1, Num2, varNum

try
   set Num1 to ScrapeByClass("html_class", 0) as number
   set Num2 to ScrapeByClass("html_class", 1) as number
   if Num2 is greater than Num1 then
       set varNum to Num2
   else
       set varNum to Num1
   end if
on error
   try
       set varNum to Num1
   on error
       set varNum to "N/A"
   end try
end try

return varNum


to ScrapeByClass(elementClass, num)
   tell application "Safari" to do JavaScript "document.getElementsByClassName('" & elementClass & "')[" & num & "].innerHTML;" in document 1
end ScrapeByClass


NG

Offline

 

#4 2019-10-14 07:58:32 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 219

Re: Bug? Defining a variable as number and it's "memorized"

Nigel Garvey wrote:

The easiest cure would be to declare Num1 (and Num2 and varNum if you like, although this doesn't affect the working of the script) as local at the top of the script, so that it ceases to exist when the script's finished and its value isn't saved back to the file:


This is an interesting approach, which hadn't occurred to me before. Sometimes I include an unnecessary handler in a simple script just to prevent a variable from being saved back to the script file. In those cases, making the variable local is a much better solution.

Nigel Garvey wrote:

It's a feature (peculiarity?) of AppleScript that when a script's run, the values of any properties, globals, or "run handler" variables are saved back to the script file and are there next time the script's run.


There probably are instances in which a script benefits from remembering the value of a variable--the choose-folder command might be an instance. When writing an important script, I guess we should decide which variables should be saved and which shouldn't.

Last edited by peavine (2019-10-14 09:53:53 am)


2018 Mac mini - macOS Mojave

Offline

 

#5 2019-10-14 04:39:54 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6034

Re: Bug? Defining a variable as number and it's "memorized"

peavine wrote:

When writing an important script, I guess we should decide which variables should be saved and which shouldn't.



It's a bit more complicated than that, in that there's not always a choice. The values aren't saved if the script does UI scripting, or uses AppleScriptObjC variables at the top level, or is in a locked/read-only directory, or is code-signed.

Outside applets it's useful and benign, but applets that change their contents are quite the anachronism, and if I were a betting man, I'd say their days are numbered. The applet shell could be rewritten to save, say, property values elsewhere, but the more likely result is it will just stop happening in applets, as it has in some cases already.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#6 2019-10-14 06:06:14 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 219

Re: Bug? Defining a variable as number and it's "memorized"

Shane Stanley wrote:

Outside applets it's useful and benign, but applets that change their contents are quite the anachronism, and if I were a betting man, I'd say their days are numbered.


Shane. I hope your prediction is correct, but I'll use this as an opportunity to rant about one of my pet peeves, which I'll do by example.

I save the following script as an applet and, after running it on a moderately-sized folder, the script file size goes from 101KB to 280KB. There may be some useful purpose for this but I don't know what it is. Anyways, making the variable (theFiles) local is a simple solution for this issue, and I'll either do that or include it in a handler.

Applescript:


set theFolder to choose folder
tell application "Finder"
   set theFiles to every file of the entire contents of theFolder
end tell


2018 Mac mini - macOS Mojave

Offline

 

#7 2019-10-15 03:36:22 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5105

Re: Bug? Defining a variable as number and it's "memorized"

peavine wrote:

Sometimes I include an unnecessary handler in a simple script just to prevent a variable from being saved back to the script file. In those cases, making the variable local is a much better solution.


In scripts for my own use, I find it simpler to do the opposite: put the main body of the code in an ordinary handler and limit the run handler code to a call to that handler. That way, all the variables used are local unless I explicitly declare them otherwise. Apart from the file bloat, I've always found it annoying to have a script's modification date change every time I run it.  wink

Shane Stanley wrote:

The values aren't saved if the script does UI scripting, or uses AppleScriptObjC variables at the top level


I'm seeing modification date changes with scripts that use UI scripting (setting run handler variables to returned System Events specifiers), but not with scripts which have any "persistent" variable set to an AppleScriptObjC value. If the auto-save behaviour in Script Editor's anything to go by, an attempt's still made to save persistent values in the latter case, but it errors before any are written to the file.


NG

Offline

 

#8 2019-10-15 05:05:20 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6034

Re: Bug? Defining a variable as number and it's "memorized"

Nigel Garvey wrote:

I'm seeing modification date changes with scripts that use UI scripting



That was my understanding, until some here pointed out that it wasn't happening in their scripts in Mojave, and I did a check and found the same thing. I don't have any such scripts I use, so I haven't checked again.

Nigel Garvey wrote:

If the auto-save behaviour in Script Editor's anything to go by, an attempt's still made to save persistent values in the latter case, but it errors before any are written to the file.



Right. In fact when ASObjC first came out, the error wasn't silent.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#9 2019-10-15 09:42:47 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 219

Re: Bug? Defining a variable as number and it's "memorized"

Nigel Garvey wrote:

In scripts for my own use, I find it simpler to do the opposite: put the main body of the code in an ordinary handler and limit the run handler code to a call to that handler. That way, all the variables used are local unless I explicitly declare them otherwise.


Thanks Nigel--the simplicity of your approach makes it most useful and the script file size remains unchanged.

Applescript:

runScript()

on runScript()
   set theFolder to choose folder
   tell application "Finder"
       set theFiles to every file of the entire contents of theFolder
   end tell
   --other stuff
end runScript

Last edited by peavine (2019-10-15 01:16:31 pm)


2018 Mac mini - macOS Mojave

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)