extendscript object is invalid - extendscript

InDesign scripting question.
I know what need to write with var. I just try to understand what happen...
There is my script:
function myalert(s){
var w = new Window('palette')
ws = w.add('statictext',undefined,s)
w.show()
$.sleep(1000)
w.close()
}
myalert('hello')
alert(ws)
alert:
1. [Object StaticText]
2. JavaScript Error! Object is invalid...
Question: why this happen? Why error after alert? ws already deleted from memory? Then why I see alert? Not deleted? Then why I see error?

First myalert() executes and you see 'hello' alert.
Then myalert() finishes and ws gets deleted along with w (which is local to myalert()).
Then you try accessing ws in global scope - after it was deleted - and get the error.
See:
var w = 100 // global
function myalert(s){
var w = new Window('palette') // local (shadows 100)
ws = w.add('statictext',undefined,s) // global
w.show()
$.sleep(1000)
w.close()
alert('In myalert() w = ' + w)
alert('In myalert() ws = ' + ws)
}
myalert('hello')
alert('Global, w = ' + w)
alert('Global, ws = ' + ws)
If you don't use var, both w and ws will stay in global scope:
function myalert(s){
w = new Window('palette')
ws = w.add('statictext',undefined,s)
w.show()
$.sleep(1000)
w.close()
alert('[myalert] w = ' + w)
alert('[myalert] ws = ' + ws)
}
myalert('hello')
alert('[global] w = ' + w)
alert('[global] ws = ' + ws)
PS. You can also dump objects on console with $.writeln('ws = ' + ws)

Related

Nodejs indexOf with array of arrays

I'd be grateful if someone can explain what I'm doing wrong here. I compare two arrays of geographic coordinates, successfully find the common elements and then try to get the indexes for the first hit. Only arrB works as expected. Although the key is quite clearly at arrA[1], no match is found. I've included loads of logging because I don't quite believe what I'm seeing.
function arrayIntersect(a, b) {
/* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]
console.log(arrA.length + ' ' + Array.isArray(arrA))
console.log(arrB.length + ' ' + Array.isArray(arrB))
console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries
console.log(arrB[0].length + ' ' + Array.isArray(arrB[0]))
res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res))
let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key))
let idxA = arrA.indexOf(key) ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB)
Results
Server started at http://localhost:8080
28 true
53 true
2 true
2 true
res 53.7,-2.45,53.93,-2.77,53.66,-2.75,53.62,-2.96 true
key 53.7,-2.45 true
idxA -1
idxB 13
When you use arrays with objects in it the indexOf function compares then the object reference and not the object itself to get the index value. And remember, in your case you have arrays in arrays but in javascript also arrays are objects so this aplies as well in your case.
Then your arrayIntersect function filters arrB, therefor the originale objects from arrB are stored then in the res array which then only can be used to get back the index in the arrB.
One approach could be to just use find for arrA to get the index and just stringify the objects while comparing:
function arrayIntersect(a, b) {
/* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]
console.log(arrA.length + ' ' + Array.isArray(arrA))
console.log(arrB.length + ' ' + Array.isArray(arrB))
console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries
console.log(arrB[0].length + ' ' + Array.isArray(arrB[0]))
res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res))
let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key))
let idxA = arrA.indexOf(arrA.find(el=>JSON.stringify(el)===JSON.stringify(key))) ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB)

VBA Loop Until ignoring second condition

My RootCheck2 is designed to check if it is in fact a root or instead a vertical asymptote. It seems to be ignoring that second condition as the code is currently outputting both asymptotes and roots. The Oldx that the code outputs gives an fOldx greater than 5, leading me to believe that it's ignoring the second condition. Please let me know if I'm missing anything, thank you
Public Function SearchPsi(ByVal Variables As Range, ByVal x As Double) As Double
Dim Oldx As Double
Dim Checkx As Double
Dim fx As Double
Dim fOldx As Double
Dim fCheckx As Double
Dim RootCheck1 As Boolean
Dim RootCheck2 As Boolean
Do
Oldx = x
x = Oldx + 0.1
Checkx = Oldx + 0.01
fx = PSI(Variables, x)
fOldx = PSI(Variables, Oldx)
fCheckx = PSI(Variables, Checkx)
If (fx * fOldx) < 0 Then
RootCheck1 = True
End If
If Abs(fOldx) < 5 Then
RootCheck2 = True
End If
Loop Until RootCheck1 = True And RootCheck2 = True
SearchPsi = Oldx
End Function
Do
Oldx = x
x = Oldx + 0.1
Checkx = Oldx + 0.01
fx = PSI(Variables, x)
fOldx = PSI(Variables, Oldx)
fCheckx = PSI(Variables, Checkx)
Loop Until (fx * fOldx) < 0 And Abs(fOldx) < 5

SymPy : Cancel out unnecessary variables and coefficients

I have an expression like :
b = IndexedBase('b')
k = IndexedBase('k')
w = IndexedBase('w')
r = IndexedBase('r')
z = IndexedBase('z')
i = symbols("i", cls=Idx)
omega = symbols("omega", cls=Idx)
e_p = (-k[i, omega]*r[i]/w[i] + k[i, omega]*r[i]/(b[omega]*w[i]))**b[omega]*k[i, omega]*r[i]/(-b[omega]*k[i, omega]*k[i, omega]**b[omega]*r[i]*z[omega]/w[i] + k[i, omega]*k[i, omega]**b[omega]*r[i]*z[omega]/w[i])
e_p = simplify(e_p)
print(type(e_p))
print(e_p)
<class 'sympy.core.mul.Mul'>
-(-(b[omega] - 1)*k[i, omega]*r[i]/(b[omega]*w[i]))**b[omega]*k[i, omega]**(-b[omega])*w[i]/((b[omega] - 1)*z[omega])
So k[i, omega] should be canceled out when I use simplify() function but do nothing. How can I get rid of unnecessary variables and coefficients?

Javascript Append to Text File

I have several JavaScript files that when run return no errors, but do not do what is coded inside them. This is one of them. Is there something else I should have installed or enabled on the PC running the .JS files?
function WriteDemo()
{
var fso, f, r;
var ForReading = 1, ForWriting = 2;
fso = CreateObject("Scripting.FileSystemObject");
f = fso.OpenTextFile("c:\\testfile.txt", ForWriting, true);
f.Write("Hello world!");
f.Close();
f = fso.OpenTextFile("c:\\testfile.txt", ForReading);
r = f.ReadLine();
return(r);
}
According to the MSDN article on FileSystemObject, for JavaScript you should use
new ActiveXObject
instead of
CreateObject
(that's for VB).
function WriteDemo()
{
var fso, f, r;
var ForReading = 1, ForWriting = 2;
fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.OpenTextFile("c:\\testfile.txt", ForWriting, true);
f.Write("Hello world!");
f.Close();
f = fso.OpenTextFile("c:\\testfile.txt", ForReading);
r = f.ReadLine();
return(r);
}
And, of course, don't forget to call the function. :)
WriteDemo();

when a spawn object moves across the screen, I want it to despawn once it gets to a certain x value?

I have random spawned objects that automatically moves across the screen. I want it so that when the objects reach a certain x position it despawns itself.
local mRandom = math.random
local objects = {"Vehicle11" ,"Vehicle21","Vehicle31","Vehicle41"}
local objectTag = 0
local object = {}
local function spawncarright()
local rightcar = {408,312}
objectTag = objectTag + 1
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
object[objectTag] = display.newImage(objName..".png") -- see the difference here
object[objectTag].x = 32
object[objectTag].y = rightcar[math.random(1,2)]
object[objectTag].name = objectTag
transition.to(object[objectTag], {time = 3500, x = 348})
end
timer.performWithDelay(2000,spawncarright,0)
so once reaches object[objectTag].x = 348 the object despawn
Try this:
local function deSpawn()
for i=1,objectTag do
if(object[i]~=nil and object[i].x~=nil and object[i].x>=348)then
-- If you want to remove the object, then use the following 2 lines --
object[i]:removeSelf()
print("Removed object["..i.."]")
--or else if you want to reposition the object, then uncomment the following --
--[[
spawncarright()
--]]
end
end
end
Runtime:addEventListener("enterFrame",deSpawn)
Keep coding................... :)
You should do it within the transition.to call:
object[objectTag].deleteSelf = function(self)
object[self.name] = nil -- Remove reference to object in table
display.remove(self)
self = nil
end
local localObj = object[objectTag] -- Do this so the object doesn't change with the objectTag does; if objectTag is incremented, then when the transition ends, it won't be pointing to the same object when we call the function
transition.to(localObj, {time = 3500, x = 348, onComplete = function() localObj:deleteSelf() end})

Resources