Unexpected behaviour of glob-fs glob.readdirSync - javascript

I have the following nodejs code. The client first calls /api/demosounds then call /api/testsounds.
var glob = require('glob-fs')({ gitignore: true });
app.get('/api/demosounds',function(req,res){
var demosounds = []
var demosoundlist = glob.readdirSync('src/assets/demosounds/*.wav');
demosounds = demosounds.concat(demosoundlist)
for (var i = 0; i < demosounds.length; i++) {
demosounds[i] = demosounds[i].replace("src/assets/","/api/static/")
}
demosounds = demosounds.sort()
res.json(demosounds)
})
app.get('/api/testsounds',function(req,res){
var listofsounds = []
var folderlist = ['01_sinus','02_pulse_train','03_contour_le','04_contour_fel','05_variable','06_complex_le','07_complex_fel']
for (var x = 0; x < folderlist.length; x++){
var testsoundlist = glob.readdirSync('src/assets/' + folderlist[x] +'/*.wav');
listofsounds = listofsounds.concat(testsoundlist)
}
When doing glob.readdirSync('src/assets/01_sinus/*.wav') I would expect to get only path starting with src/assets/01_sinus/ and yet testsoundlist starts as the following:
[ 'src/assets/demosounds/electricity.wav',
'src/assets/demosounds/phone.wav',
'src/assets/demosounds/water.wav',
'src/assets/demosounds/wind.wav',
'src/assets/01_sinus/02_sin1_0065_0.16923076923076924.wav',
'src/assets/01_sinus/04_sin1_0065_0.7692307692307693.wav',
'src/assets/01_sinus/05_sin1_0065_1.0615384615384615.wav',
'src/assets/01_sinus/07_sin1_0165_0.07272727272727272.wav',
I have no idea why this is happening :(
UPDATE
Somewhat closer to the problem, the code below
var glob = require('glob-fs')({ gitignore: true });
var folderlist = ['01_sinus','02_pulse_train','03_contour_le','04_contour_fel','05_variable','06_complex_le','07_complex_fel']
for (var x = 0; x < folderlist.length; x++){
console.log((glob.readdirSync('src/assets/' + folderlist[x] +'/*.wav').length))
}
Outputs this, as if glob would remember the previous globs.
49
98
147
196
245
294
343

The library doesn't seem to be maintained anymore and there is a hanging issue with exactly the same problem, so it seems like this is a bug.
A solution is to simply use glob, glob.sync() in this case.

Related

Backpropagation in an Tensorflow.js Neural Network

When I have been attempting to implement this function tf.train.stg(learningRate).minimize(loss)into my code in order to conduct back-propagation. I have been getting multiple errors such The f passed in variableGrads(f) must be a function. How would I implement the function above into the code bellow successfully? and Why does this error even occur?
Neural Network:
var X = tf.tensor([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
var Y = tf.tensor([[0,0,0],[0,0,0], [1,1,1]])
var m = X.shape[0]
var a0 = tf.zeros([1,3])
var y_hat = tf.zeros([1,3])
var parameters = {
"Wax": tf.randomUniform([1,3]),
"Waa": tf.randomUniform([3,3]),
"ba": tf.zeros([1,3]),
"Wya": tf.randomUniform([3,3]),
"by": tf.zeros([1,3])
}
function RNN_cell_Foward(xt, a_prev, parameters){
var Wax = parameters["Wax"]
var Waa = parameters["Waa"]
var ba = parameters["ba"]
var a_next = tf.sigmoid(tf.add(tf.add(tf.matMul(xt, Wax), tf.matMul(a_prev , Waa)),ba))
return a_next
}
function RNN_FowardProp(X, a0, parameters){
var T_x = X.shape[0]
var a_next = a0
var i = 1
var Wya = parameters["Wya"]
var by = parameters["by"]
var l = 1
for(; i <= T_x; i++){
var X_i = X.slice([i-1,0],[1,-1])
for(; l <= X.shape[1]; l++){
var xt = X_i.slice([0,l-1],[1,1])
var a_next = RNN_cell_Foward(xt, a_next, parameters)
}
var y_pred = tf.sigmoid((tf.add(tf.matMul(a_next, Wya), by)))
l = 1
if (i == 1){
var y_pred1 = y_pred
} else if (i == 2) {
var y_pred2 = y_pred
} else if (i == 3) {
var y_pred3 = y_pred
}
}
var y_predx = tf.concat([y_pred1, y_pred2, y_pred3])
return y_predx
}
const learningRate = 0.01;
var optimizer = tf.train.sgd(learningRate);
var model = RNN_FowardProp(X, a0, parameters)
var loss = tf.losses.meanSquaredError(Y, model)
for (let f = 0; f < 10; f++) {
optimizer.minimize(loss)
}
This is a neural network for sentiment classification which has a many to one structure.
The error says it all:
The f passed in variableGrads(f) must be a function
optimizer.minimize is expecting a function as parameter and not a tensor. Since the code is trying to minimize the meanSquaredError, the argument of minimize can be a function that computes the meanSquaredError between the predicted value and the expected one.
const loss = (pred, label) => pred.sub(label).square().mean();
for (let f = 0; f < 10; f++) {
optimizer.minimize(() => tf.losses.meanSquaredError(Y, model))
}
Does it solve the issue, not completely yet ? The error will change for something like:
variableGrads() expects at least one of the input variables to be trainable
What does it mean ? When the optimizer is used, it expects the function passed as argument to contains variables whose values will be updated to minimize the function output.
Here is the changes to be made:
var Y = tf.tensor([[0,0,0],[0,0,0], [1,1,1]]).variable() // a variable instead
// var loss = tf.losses.meanSquaredError(Y, model)
// computed below in the minimize function
const learningRate = 0.01;
var optimizer = tf.train.sgd(learningRate);
var model = RNN_FowardProp(X, a0, parameters);
const loss = (pred, label) => pred.sub(label).square().mean();
for (let f = 0; f < 10; f++) {
optimizer.minimize(() => tf.losses.meanSquaredError(Y, model))
}

Zapier scripting - for loops

I cant seem to figure this out. Here is my working JSfiddle code that sends data to console perfectly. I know my zapier app is passing authentication. I'm getting a 200-success if I just return
var stuff =
{
"uri":"some URL here",
"action":"EXPORT",
"result":
{
"column_order":["Name","email","TimeStamp"],
"rows":[
["ted2","ted2#example.com","06 Feb, 2018 04:37:16"],
["jimf","jimf#example.com","06 Feb, 2018 19:03:39"]
]
}
};
var results2 = [];
for (var j = 0; j < stuff.result.rows.length; j++)
{
var result = {};
for (var i = 0; i < stuff.result.column_order.length; i++)
{
result['"' + stuff.result.column_order[i] + '"'] = stuff.result.rows[j][i];
}
results2.push(result);
}
console.log(results2);
It spits out:
{
"Name": "ted2",
"email": "ted2#example.com",
"TimeStamp": "06 Feb, 2018 04:37:16"
}{
"Name": "jimf",
"email": "jimf#example.com",
"TimeStamp": "06 Feb, 2018 19:03:39"
}
Now if I try to convert this to a Zapier Post POLL function, I keep getting errors: Javascript Exception: TypeError: Cannot read property 'rows' of undefined.
Here is my Zapier Post Poll function. What am I missing? For loops just wont work the same.
email_post_poll: function(bundle){
var response = z.JSON.parse(bundle.response.content);
var results2 = [];
for (var j = 0; j < response.result.rows.length; j++)
{
var result = {};
for (var i = 0; i < response.result.column_order.length; i++)
{
result['"' + response.result.column_order[i] + '"'] = response.rows[j][i];
}
results2.push(result);
}
return results2 || [];
}
David here, from the Zapier Platform team.
Your issue is in the for loop, you're calling = response.rows[j][i], which should be = response.result.rows[j][i]. If that doesn't clear it up, I'd suggest using console.log to make sure you know what is actually coming in the response.
As a side note, arrays are truthy in js, so results2 || [] will never return the empty array on the right.
I got this working. bundle.response.content had a parent array of "response" on top of everything. So i actually had to call "response.response." for everything. Using the console.log suggestion from Dave helped me solve this but you can only see the console log inside of the scripting tool and then "Bundle logs". Just a learning curve for the platform i guess.
email_post_poll: function(bundle){
var response = z.JSON.parse(bundle.response.content);
var results2 = [];
console.log(response.response.result.rows.length);
for (var j = 0; j < response.response.result.rows.length; j++)
{
var results3 = {};
for (var i = 0; i < response.response.result.column_order.length; i++)
{
results3['"' + response.response.result.column_order[i] + '"'] = response.response.result.rows[j][i];
}
results2.push(results3);
}
return results2;

Copy array --> stack or heap overflow?

I have an array named globalArrayAllTrades as you see below. I simply like to INVERT the date in a new copy of the array. So I loop through, create a new object and add it to the new array - simple.
Then function does exactly as expected. BUT if the array contains too many objects the code fails with a "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".
My laptop has 8 GB of memory...When the NODEJS process crashes it uses about 1.5 GB and about 70% of of totally amount of available memory is used.
I do run the NODEJS app with the parameter: --max_old_space_size=5000 which normally fixes every thing. But not this one and i have tried MANY different ways to code the same function - BUT each and every time - it fails...unless the original array is smaller.
How can I fix this issue?
function invertTrades(){
var original = globalArrayAllTrades.slice();
globalArrayAllTrades.length = 0;
globalListAllTrades.length = 0;
for(var i = 0; i < original.length; i++){
var objS = original[i];
var objE = original[original.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalArrayAllTrades.push(objInv);
globalListAllTrades[objInv.matchdate] = objInv;
}
}
You can save some memory by making original just contain the properties you need to invert, not the whole TradePoint object. Then you don't need to construct new TradePoint objects, you can modify them in place.
var original = globalArrayAllTrades.map(function(trade) {
return {
trade.price,
trade.size,
trade.issell
};
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
trade.price = original[i].price;
trade.size = original[i].size;
trade.issell = original[i].issell;
});
And since all the objects were modified in place, there's no need to update globalListAllTrades.
Another way is to swap the price, size, and issell properties in place between the pairs of elements:
var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var temp = objS.price;
objS.price = objE.price;
objE.price = temp;
temp = objS.size;
objS.size = objE.size;
objE.size = temp;
temp = objS.issell;
objS.issell = objE.issell;
objE.issell = temp;
}
Have you considered just doing this?
// Copy array and then reverse it
var newArray = [].concat(original).reverse();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
I would suggest avoiding to copy that array:
function getInverse(i) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalListAllTrades[objInv.matchdate] = objInv;
return objInv;
}
function invertTrades(){
globalListAllTrades.length = 0;
for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
var j = globalArrayAllTrades.length-1-i;
var a = getInverse(i);
var b = getInverse(j);
globalArrayAllTrades[i] = a;
globalArrayAllTrades[j] = b;
}
}

JS check if the value of object exists

So, I have following js setup:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
Then,
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (NAMES[my_name] !== 185){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}
alert(JSON.stringify(NAMES , null, 4));
Here is a screenshot of the alert:
I hardcoded the number "185" for this example. I need to check if the id of 185 exists, then skip to else. I am not sure how to check it. I tried typeof, undefinedetc. but no luck.
(In other words, I should only have one "185").
Any help? Thanks!
If I understood correctly what you are trying to achieve, you have to iterate over NAMES and check every element. For example, you could do it using [].some javascript function:
if (!NAMES.some(function(v){return v[my_name]})) {
...
} else {
}
If you want to remove duplication you can just use NAMES as an object instead of array like this
var all_names = [185, 185, 181],
NAMES = {};
for (var j = 0; j < all_names.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
NAMES[my_name] = ["sean","sdfsd","sdfsfd"];
}
alert(JSON.stringify(NAMES, null, 4));
First of all I would recommend making a JS Fiddle or CodePen out of this so people can see the code running.
I believe that the issue is that NAMES[my_name] is not doing what you think it is. NAMES is an Array so when you say NAMES[my_name] you are really asking for the ITEM in the array so you are getting the entire object that you create in the INFO function. What you really want is to see if the object has an attribute that matches the value (e.g. "185" from the my_names array).
This is not the prettiest code but it will show you how to do what you really want to do:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
all_names = ["185", "186", "185"]
for (var j = 0; j < all_names.length; j++) {
var my_name = all_names[j];
if (NAMES.length == 0) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
} else {
var match = false;
for (var x = 0; x < NAMES.length; x++) {
console.log(NAMES[x][my_name] + ' : ' + my_name);
if(NAMES[x][my_name]) {
match = true;
}
}
if (!match) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}
}
}
alert(JSON.stringify(NAMES , null, 4));
Note the if that looks at NAMES[x][my_name] - this is asking if the item at array index 'x' has an attribute of 'my_name' (e.g. "185"). I believe this is really what you are trying to do. As its after midnight I assure you that there is more concise and pretty JS to do this but this should show you the basic issue you have to address.
Try this code using hasOwnProperty method :
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (!NAMES[my_name].hasOwnProperty("185")){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}

JavaScript - Hard copying primitive

I'm trying to copy a variable to a new one, NOT by reference, but by hard copy. In my understanding, JavaScript does a hard copy of primitive types by default. However, I get a reference copy if I do it like this:
var u = [0, 12, 34, 56];
var v = u[1];
u[1] = 85;
console.log(v); // returns 85, I want it to return 12
So I guess u[1] isn't a primitive type, after all (even though it's just a 12, which is a number, which should be primitive in my understanding). Is there a way I can make a hard copy? I've tried severeal methods I've found here. v = u[1].slice() seems to be the obvious choice, it doesn't work however, and there has to be an easier method for this than the 20 line custom functions some advise.
Thank you for your help!
EDIT: Apparently it works this way, so here's more of the code(without some unimportant parts):
var G = [[1, 2, 34, 56],[2, 345, 67, 8],[3, 4],[4, 65, 87]...]; // G contains 99 entries originally
var v;
var u;
var m = 99;
var alt;
var n = edges.length;
G[0].l = 0;
u = G[0].slice(); // now u = [1, 2, 34, 56]
u.l = G[0].l;
//... ...(some code not doing anything with v and u)
for (i = 1; i < ( u.length - 1 ) ; i++) {
alt = u.l + 1;
console.log(u[i]);
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
Res[j].l = alt;
Res[j].previous = u;
}
}
}
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
G[j].l = alt;
G[j].previous = u;
}
}
}
}
return v; //returns 9999999 instead of anythign from the original u, or G for that matter
Well these two lines are inside of a loop:
from your fiddle https://jsfiddle.net/7vjf82oa/1
//reduced to the core problem
while(/*whatever*/){
for(var i=1; i<u.length-1; ++i){
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
}
}
return v;
you overwrite the values in the first itertion and access them in any further one.
What are you trying to achieve with your code? It seems messed up in so many ways. Maybe we can help to solve the underlying problem.
Like this part:
for ( k = 0; k < m ; k++ ) {
if ( G[k].l < min ) {
mini = G[k][0];
u = G[mini].slice();
u.l = G[mini].l;
}
}
G.splice(mini, 1);
m--;
mini = 0;
mini seems to reference the index-position of something min.
The way you build G, G[k][0] would reference the index-Position inside of G, and mini = G[k][0] could be replaced as mini = k, except that since you remove Elements from G the indices are completely messed up, so that referencing u = G[mini].slice() would result in some sort of fancy shuffle.
Except for the fact that the surrounding condition can never be true. why?
G[/*any*/].l is initialized as Infinite.
u.l is initialized as 0 and counting up.
G[0].l = 0;
u = G[0].slice();
u.l = G[0].l;
//...
alt = u.l + 1;
//...
G[j].l = alt;
min is initialized as 0 and is never changed.
neither 0..99 nor Infinite can ever be lower than 0
so that G.splice(mini, 1); is just a substitute for G.shift();
so again, what are you trying to build? maybe we can help
if you want to clone an object or deep copy ,
there is a few ways to do it.
function clone(a) {
return JSON.parse(JSON.stringify(a));
}

Categories