I have a small problem with regards to scope. In the program below I have declared two variables in the .js file, countRows and countCols. Inside the saveTable(). However their value is 0 when after the function when I log them.
Why do they not hold their value from the function?
var table = document.getElementById("table");
var countRows = 0;
var countCols = 0;
function saveTable() {
countRows = table.rows.length;
countCols = table.rows[0].cells.length;
var data = "";
for(var i = 0; i < table.rows.length; i++) {
for(var j = 0; j < table.rows[i].cells.length; j++) {
data += table.rows[i].cells[j].innerHTML + ",";
}
}
document.cookie = data;
}
console.log(countRows); //These equal 0
console.log(countCols);
To add to #Steven Stark answer, it happens because you didn't call the function before logging the variable, they share the scope here. Example below:
let a = 0;
// This change a, because the function is directly accessing the a declared in the parent scope
function changeA() {
a = 3;
}
changeA();
console.log(a)
// This doesn't change a
function changeAParameter(a) {
// because this 'a' only exists in the scope of this function
a = 5;
}
changeAParameter(a);
console.log(a);
You can have more information about closure (which is beyond topic here), but is interesting: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
You have to invoke the function
var table = document.getElementById("table");
var countRows = 0;
var countCols = 0;
function saveTable() {
countRows = table.rows.length;
countCols = table.rows[0].cells.length;
var data = "";
for(var i = 0; i < table.rows.length; i++) {
for(var j = 0; j < table.rows[i].cells.length; j++) {
data += table.rows[i].cells[j].innerHTML + ",";
}
}
document.cookie = data;
}
// Call the function
saveTable();
console.log(countRows); //These equal 0
console.log(countCols);
I was trying to put some information of my sheet in a array, to use in a graphic later. But this error keeps showing :(
Error: Syntax error (line 8, archive "Código")
function onOpen() {
var proposta = SpreadsheetApp.getActive().getSheetByName('Proposta de solução');
var ids = proposta.getRange('A10:A26');
var names = proposta.getRange('B10:B26');
var esforcos = proposta.getRange('F10:F26');
var name = [
for (var i = 0; i < 17; i++) {
names.getCell(i, 1).getValue();
}
]
var id = [
for(var j = 0; j < 17; j++) {
ids.getCell(j,1).getValue();
}
]
var esforco = [
for(var k = 0; k < 17; k++) {
esforcos.getCell(k,1).getValue();
}
]
}
This should get the results you want:
function onOpen() {
var proposta = SpreadsheetApp.getActive().getSheetByName('Proposta de solução');
var ids = proposta.getRange('A10:A26');
var names = proposta.getRange('B10:B26');
var esforcos = proposta.getRange('F10:F26');
var name = [];
var id = [];
var esforco = [];
for (var i = 0; i < 17; i++) {
name.push(names.getCell(i, 1).getValue());
id.push(ids.getCell(i, 1).getValue());
esforco.push(esforcos.getCell(i, 1).getValue());
}
}
Writing a small script that pulls messages with a label and outputs the subject to a Slack channel.
I've gotten it down ( customized to from someone ) but need further help on where to get the time from.
/* Credit: gist.github.com/andrewmwilson */
function sendEmailsToSlack() {
var label = GmailApp.getUserLabelByName('!urgent');
var messages = [];
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
messages = messages.concat(threads[i].getMessages())
}
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
Logger.log(message);
var output = '*State Change Detected*';
output += '\n*subject:* ' + message.getSubject();
Logger.log(output);
You can use the getDate() method on a message:
var message = messages[0]; // Get first message
Logger.log(message.getDate()); // Log date and time of the message
the script running in the background to a google form is returning a new folder and email for every question answered instead of just 1 folder and 1 email.... can anybody help to see where i went wrong!
function onSubmit() {
var form = FormApp.openById('123456789abcdefghij');
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
var DriveFolder = DriveApp.getFolderById("0B2eMBrrkabcdefghij");
var foldername = itemResponses[2].getResponse();
var folderpath = DriveFolder.createFolder(foldername).getUrl();
var to = itemResponses[1].getResponse();}
MailApp.sendEmail(
to,"Change Management Request", "Thank you for Submitting Step 1. Please fill out Step 2 (https://drive.google.com/open?id=0B2eMBrrkabcdefji) and upload to" +folderpath);
}}
Reformatting the code shows that the parts for creating the folder sending the mail are nested too deep within the for loops:
function onSubmit() {
var form = FormApp.openById('123456789abcdefghij');
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log(
'Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
var DriveFolder = DriveApp.getFolderById("0B2eMBrrkabcdefghij");
var foldername = itemResponses[2].getResponse();
var folderpath = DriveFolder.createFolder(foldername).getUrl();
var to = itemResponses[1].getResponse();
}
MailApp.sendEmail(
to,
"Change Management Request",
"Thank you for Submitting Step 1. Please fill out Step 2 (https://drive.google.com/open?id=0B2eMBrrkabcdefji) and upload to" +folderpath);
}
}
Probably you want to move them out, but without knowing which field you want for calculating the folder name, I can only guess:
function onSubmit() {
var form = FormApp.openById('123456789abcdefghij');
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log(
'Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
}
}
var DriveFolder = DriveApp.getFolderById("0B2eMBrrkabcdefghij");
var folderAndToResponse = formResponses[formResponses.length - 1].getItemResponses();
var foldername = folderAndToResponse[2].getResponse();
var folderpath = DriveFolder.createFolder(foldername).getUrl();
var to = folderAndToResponse[1].getResponse();
MailApp.sendEmail(
to,
"Change Management Request",
"Thank you for Submitting Step 1. Please fill out Step 2 (https://drive.google.com/open?id=0B2eMBrrkabcdefji) and upload to" + folderpath);
}
I've tried to rewrite neural network found here to javascript. My javascript code looks like this.
function NeuralFactor(weight) {
var self = this;
this.weight = weight;
this.delta = 0;
}
function Sigmoid(value) {
return 1 / (1 + Math.exp(-value));
}
function Neuron(isInput) {
var self = this;
this.pulse = function() {
self.output = 0;
self.input.forEach(function(item) {
self.output += item.signal.output * item.factor.weight;
});
self.output += self.bias.weight;
self.output = Sigmoid(self.output);
};
this.bias = new NeuralFactor(isInput ? 0 : Math.random());
this.error = 0;
this.input = [];
this.output = 0;
this.findInput = function(signal) {
var input = self.input.filter(function(input) {
return signal == input.signal;
})[0];
return input;
};
}
function NeuralLayer() {
var self = this;
this.pulse = function() {
self.neurons.forEach(function(neuron) {
neuron.pulse();
});
};
this.neurons = [];
this.train = function(learningRate) {
self.neurons.forEach(function(neuron) {
neuron.bias.weight += neuron.bias.delta * learningRate;
neuron.bias.delta = 0;
neuron.input.forEach(function(input) {
input.factor.weight += input.factor.delta * learningRate;
input.factor.delta = 0;
})
})
}
}
function NeuralNet(inputCount, hiddenCount, outputCount) {
var self = this;
this.inputLayer = new NeuralLayer();
this.hiddenLayer = new NeuralLayer();
this.outputLayer = new NeuralLayer();
this.learningRate = 0.5;
for(var i = 0; i < inputCount; i++)
self.inputLayer.neurons.push(new Neuron(true));
for(var i = 0; i < hiddenCount; i++)
self.hiddenLayer.neurons.push(new Neuron());
for(var i = 0; i < outputCount; i++)
self.outputLayer.neurons.push(new Neuron());
for (var i = 0; i < hiddenCount; i++)
for (var j = 0; j < inputCount; j++)
self.hiddenLayer.neurons[i].input.push({
signal: self.inputLayer.neurons[j],
factor: new NeuralFactor(Math.random())
});
for (var i = 0; i < outputCount; i++)
for (var j = 0; j < hiddenCount; j++)
self.outputLayer.neurons[i].input.push({
signal: self.hiddenLayer.neurons[j],
factor: new NeuralFactor(Math.random())
});
this.pulse = function() {
self.hiddenLayer.pulse();
self.outputLayer.pulse();
};
this.backPropagation = function(desiredResults) {
for(var i = 0; i < self.outputLayer.neurons.length; i++) {
var outputNeuron = self.outputLayer.neurons[i];
var output = outputNeuron.output;
outputNeuron.error = (desiredResults[i] - output) * output * (1.0 - output);
}
for(var i = 0; i < self.hiddenLayer.neurons.length; i++) {
var hiddenNeuron = self.hiddenLayer.neurons[i];
var error = 0;
for(var j = 0; j < self.outputLayer.neurons.length; j++) {
var outputNeuron = self.outputLayer.neurons[j];
error += outputNeuron.error * outputNeuron.findInput(hiddenNeuron).factor.weight * hiddenNeuron.output * (1.0 - hiddenNeuron.output);
}
hiddenNeuron.error = error;
}
for(var j = 0; j < self.outputLayer.neurons.length; j++) {
var outputNeuron = self.outputLayer.neurons[j];
for(var i = 0; i < self.hiddenLayer.neurons.length; i++) {
var hiddenNeuron = self.hiddenLayer.neurons[i];
outputNeuron.findInput(hiddenNeuron).factor.delta += outputNeuron.error * hiddenNeuron.output;
}
outputNeuron.bias.delta += outputNeuron.error * outputNeuron.bias.weight;
}
for(var j = 0; j < self.hiddenLayer.neurons.length; j++) {
var hiddenNeuron = self.hiddenLayer.neurons[j];
for(var i = 0; i < self.inputLayer.neurons.length; i++) {
var inputNeuron = self.inputLayer.neurons[i];
hiddenNeuron.findInput(inputNeuron).factor.delta += hiddenNeuron.error * inputNeuron.output;
}
hiddenNeuron.bias.delta += hiddenNeuron.error * hiddenNeuron.bias.weight;
}
};
this.train = function(input, desiredResults) {
for(var i = 0; i < self.inputLayer.neurons.length; i++) {
var neuron = self.inputLayer.neurons[i];
neuron.output = input[i];
}
self.pulse();
self.backPropagation(desiredResults);
self.hiddenLayer.train(self.learningRate);
self.outputLayer.train(self.learningRate);
};
}
Now I'm trying to learn it how to resolve XOR problem. I'm teaching it like this:
var net = new NeuralNet(2,2,1);
var testInputs = [[0,0], [0,1], [1,0], [1,1]];
var testOutputs = [[1],[0],[0],[1]];
for (var i = 0; i < 1000; i++)
for(var j = 0; j < 4; j++)
net.train(testInputs[j], testOutputs[j]);
function UseNet(a, b) {
net.inputLayer.neurons[0].output = a;
net.inputLayer.neurons[1].output = b;
net.pulse();
return net.outputLayer.neurons[0].output;
}
The problem is that all results that I get is close to 0.5 and pretty random, no matter what arguments I use. For example:
UseNet(0,0) => 0.5107701166677714
UseNet(0,1) => 0.4801498747476413
UseNet(1,0) => 0.5142463167153447
UseNet(1,1) => 0.4881829364416052
What can be wrong with my code?
This network is big enough for the XOR problem and I can't see any obvious mistakes, so I suspect it's getting stuck in a local minimum.
Try going through the training set 10,000 times instead of 1000; this gives it a better chance of breaking out of any minima and converging. You can also increase convergence a lot by upping the number of hidden neurons, tweaking η (the learning rate) or adding momentum. To implement the latter, try using this as your training function:
this.train = function(learningRate) {
var momentum = 0 /* Some value, probably fairly small. */;
self.neurons.forEach(function(neuron) {
neuron.bias.weight += neuron.bias.delta * learningRate;
neuron.bias.delta = 0;
neuron.input.forEach(function(input) {
input.factor.weight += (input.factor.delta * learningRate) + (input.factor.weight * momentum);
input.factor.delta = 0;
})
})
}
I've had good results changing the learning rate to 1.5 (which is pretty high) and momentum to 0.000001 (which is pretty small).
(Incidentally, have you tried running the .NET implementation with a few different seeds? It can take quite a while to converge too!)
This system uses fuzzy logic. As it says in the article don't use integers instead use "close" real numbers as the article suggests -- try
UseNet(0.1,0.1) =>
UseNet(0.1,0.9) =>
UseNet(0.9,0.1) =>
UseNet(0.9,0.9) =>
For the results anything above 0.5 is a 1 and below is 0
Hmmmm
Try instead of:
var testInputs = [[0,0], [0,1], [1,0], [1,1]];
var testOutputs = [[1],[0],[0],[1]];
This:
var testInputs = [[0.05,0.05], [0.05,0.95], [0.95,0.05], [0.95,0.95]];
var testOutputs = [[1],[0],[0],[1]];
or
var testInputs = [[0,0], [0,1], [1,0], [1,1]];
var testOutputs = [[0.95],[0.05],[0.05],[0.95]];