Convert 3 output to one input at NODE-RED - node.js

Question is about Node-RED for raspberry pi 3. I have 3 input that give acceleration of X,Y,Z axis. I want to make one output from these 3 inputs. For this , I use √X^2+Y^2+Z^2 formula. According to my function my output is still 3 piece and giving NaN output when i debug. What should i do in Acc to Freq function
Here is my collecting X,Y,Z info from my sql.
var str = msg.payload;
str = str[0]['IX']; // Choose last data from IX column
a = str * 10; // Scaling the value
msg.payload = a
return msg;
var str = msg.payload;
str = str[0]['IY']; // Choose last data from IY column
b = str * 10; // Scaling the value
msg.payload = b
return msg;
var str = msg.payload;
str = str[0]['IZ']; // Choose last data from IZ column
c = str * 10; // Scaling the value
msg.payload = c
return msg;
And the function that i m try to calculate one output ( Acc to Freq )
var str = msg.payload;
var a;
var b;
var c;
str = Math.pow(a^2+b^2+c^2);
d = str * 10;
msg.payload = d;
return msg;

The point to remember is that a function node runs every time a message arrives, if you send it 3 separate messages then it will run 3 times. Also each function node is totally independent of all others, you can't declare a variable in one and use it in another (well there is something called the Context, but that's not particularly useful here)
You've not actually shown your flow so we are going to have to guess a little here, but you imply that all the starting values are coming from a single SQL query that returns multiple columns. If this is the case then you have 2 options.
Just do all the calculations in one place e.g. one function node with the following:
var str = msg.payload;
var strA = str[0]['IX']; // Choose last data from IX column
var a = strA * 10; // Scaling the value
var strB = str[0]['IY']; // Choose last data from IY column
var b = strB * 10; // Scaling the value
var strC = str[0]['IZ']; // Choose last data from IZ column
var c = strC * 10; // Scaling the value
var strC = Math.pow(a^2+b^2+c^2);
var d = strC * 10;
msg.payload = d;
return msg;
You can run the output of your current 3 function nodes into a Join node set to collect 3 values. This will generate a new msg object with a payload containing an array of the 3 values. You can then modify your final function node as follows:
var a = msg.payload[0];
var b = msg.payload[1];
var c = msg.payload[2];
var d = Math.pow(a^2+b^2+c^2) * 10 ;
msg.payload = d;
return msg;

Related

Get Last Column in Visible Views Index - Excel - Office-JS

I'm trying to filter the last column on a worksheet but I can't seem to get the Index of the column. To be clear, I need the index relative to the worksheet, no the range. I used VisibleView to find the Column, but there may be hidden rows, so my plan is to then load that column via getRangeByIndexes but I need the relative columnIndex to the worksheet.
I've tried a bunch of variations of the below, but I either get Object doesn't support 'getColumn' or columnIndex is undefined
Note: In the below example I've hardcoded 7 as that will be the last column relative to the VisibleView (Columns and rows are already hidden), but I'd like this to by dynamic for other functions and just returnthe "last visible column index".
var ws = context.workbook.worksheets.getActiveWorksheet()
var visible_rng = ws.getUsedRange(true).getVisibleView()
visible_rng.load(["columnCount", "columnIndex"])
await context.sync();
console.log('visible_rng.columnIndex')
console.log(visible_rng.getCell(0,7).columnIndex)
console.log(visible_rng.getColumn(7).columnIndex)
Well this method seems a bit hacky, please share if you know a better way! But, first thing I found was that getVisibleView only metions rows in the Description.
Represents the visible rows of the current range.
I decided to try getSpecialCells and was able to load the address property. I then had to use split and get the last column LETTER and convert this to the Index.
I also wanted the columnCount but this wasn't working w/ getSpecialCells so I polled that from getVisibleView and return an Object relating to Visible Views that I can build on the function later if I need more details.
Here it is:
async function Get_Visible_View_Details_Obj(context, ws) {
var visible_rng = ws.getUsedRange(true).getSpecialCells("Visible");
visible_rng.load("address")
var visible_view_rng = ws.getUsedRange(true).getVisibleView()
visible_view_rng.load("columnCount")
await context.sync();
var Filter_Col_Index = visible_rng.address
var Filter_Col_Index = Filter_Col_Index.split(",")
var Filter_Col_Index = Filter_Col_Index[Filter_Col_Index.length - 1]
var Filter_Col_Index = Filter_Col_Index.split("!")[1]
if (Filter_Col_Index.includes(":") == true) {
var Filter_Col_Index = Filter_Col_Index.split(":")[1]
}
var Filter_Col_Index = Get_Alpha_FromString(Filter_Col_Index)
var Filter_Col_Index = Get_Col_Index_From_Letters(Filter_Col_Index)
var Filter_Col_Index_Obj = {
"last_col_ws_index": Filter_Col_Index,
"columnCount": visible_view_rng.columnCount,
}
return Filter_Col_Index_Obj
}
Helper Funcs:
function Get_Alpha_FromString(str) {
return str.replace(/[^a-z]/gi, '');
}
function Get_Col_Index_From_Letters(str) {
str = str.toUpperCase();
let out = 0, len = str.length;
for (pos = 0; pos < len; pos++) {
out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - pos - 1);
}
return out - 1;
}

adding strings as numbers

I'm trying to add together two large numbers, stored as strings.
Here's what I have so far:
function addBigNums(a,b){
c = ""; // output
o = 0; // carryover
startLen = a.length-1;
for(i = startLen; i >= 0; i--) {
sum = parseInt(a[i], 10) + parseInt(b[i], 10) + o;
c = (sum % 10) + c;
o = sum >= 10;
}
if(o === true) c = "1" + c;
return c;
}
I'm running into two issues:
1 ) my carry is not always functioning properly, primarily when:
2 ) the numbers length differ.
Right now I think I would have to prepend 0's onto the shorter number in order to get this to function as expected.
Any better alternatives to this?
Simple, straightforward integer addition like you would do it manually:
a = "123456"; // input a
b = "123456"; // input b
c = ""; // target-string
o = 0; // overflow-bit
// traverse string from right to left
for(i = a.length - 1; i >= 0; i--) {
// do the calculation (with overflow bit)
sum = parseInt(a[i]) + parseInt(b[i]) + o;
// prepend resulting digit to target
c = (sum % 10) + c;
// set overflow bit for next round
o = sum >= 10;
}
// prepend another "1" if last overflow-bit is true
if(o == true) c = "1" + c;
If strings a and b are not equal length (but you stated that they are), you should prepend the shorter string with zeros before calculation.
Consider both numbers to be an array of digits. Add them up right-to-left handling overflow flag. Demo. Assuming your numbers are of the same length
function getNumber(len) {
return Array.apply(null, new Array(len)).map(function(){
return Math.floor(Math.random()*9);
}).join('');
}
var len = 600,
a = getNumber(len), //use your numbers here
b = getNumber(len),
flag = 0;
var c = [].reduceRight.call(a, function(acc, val, idx) {
val = +val + (+b.charAt(idx)) + flag;
flag = val / 10 | 0;
val %= 10;
return val + acc;
}, '');
c = (flag ? 1: '') + c;
console.log(a, b, c);

Repeating a function down a list, without repeating code

I've written a script in google docs to use =importXML function and return the value on its own rather than leaving the function there loading on opening and every hour slowing the thing down.
Basically it uses the data in row D (hidden), sticks the formula in B2, then, overwrites B2 with the value of the formula. I then wanted to repeat this going down the list but just didn't know how - currently I've just repeated the function and changed the cell ID, which I'm aware is a travesty. Could someone guide a noob on how to do it efficiently?
function pullValues()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cellref1 = sheet.getRange("D2");
var ID = cellref1.getValue();
var apistring = "http://api.eve-central.com/api/marketstat?usesystem=30000142&typeid=" + ID;
var command = "importxml(\"" + apistring + "\", \"/evec_api/marketstat/type/sell/min\")";
var cellref2 = sheet.getRange("B2");
cellref2.setFormula(command);
var val = cellref2.getValue();
cellref2.setValue(val);
}
https://docs.google.com/spreadsheet/ccc?key=0AjZlH_sGnj6vdDU4QWdyZTVTd2E4RUFXZnVEZlZJS3c#gid=0
You have to iterate through all rows in the spreadsheet using a for loop. There are many ways to do it, the following code is one of them:
function pullValues()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var startRow = 2; // First row of data to process
var lastRow = sheet.getLastRow(); // Last row of data to process
for (var i = startRow; i <= lastRow; i++)
{
var cellref1 = sheet.getRange("D" + i);
var ID = cellref1.getValue();
var apistring = "http://api.eve-central.com/api/marketstat?usesystem=30000142&typeid=" + ID;
var command = "=ImportXML(\"" + apistring + "\", \"/evec_api/marketstat/type/sell/min\")";
var cellref2 = sheet.getRange("B" + i);
cellref2.setFormula(command);
var val = cellref2.getValue();
cellref2.setValue(val);
}
}

c# : selecting a variable from several, randomly

I have several independant int variables in my program. Is there a way I can feed randomly the value of one of them into a new int variable or an int array ? Thanks in Advance.
EDIT:
here's a pseudocode to demonstrate:
int A1 = 1;
int A2 = 3;
int RESULT = 0;
Random rand = new Random();
Result = rand.Next(0, A1 || A2)]; //Result holds the value/variable name of A1 or A2
You could put all the ints you want to choose from in a new array and then select a random value from it. For example:
int value1 = 3;
int anotherValue = 5;
int value2 = 1;
int[] selectableInts = new int[3] { value1, anotherValue, value2 };
Random rand = new Random();
int randomValue = selectableInts[rand.Next(0, selectableInts.Length)];
How about this:
// create an array of your variables
int[] A = new int[] {1,3};
// Instantiate Random object.
Random rand = new Random();
// Get a value between 0 and the lenght of your array.
// This is equivalent to select one of the elements of the array.
int index = rand.Next(0,A.Length);
// Get the value from the array that was selected at random.
int Result = A[index];
I had some trouble myself and found this thread, but its code is for Ints only, so I was stuck for some time to make it work for other than ints.
I think #David gave me some idea how to make it work.
This is my version for using types other than ints.
Vector2 down = new Vector2(0, 1);
Vector2 left = new Vector2(-1, 0);
Vector2 right = new Vector2(1, 0);
List<Vector2> possibleDirections = new List<Vector2>()
{
down,
left,
right
};
Random random = new Random();
Vector2 selectedRandomDirection = possibleDirections[random.Next(0, possibleDirections.Count)];
// this is the result
Vector2 direction = selectedRandomDirection;

String comparison number of characters in same order

I have
Str A = "abcdef"
Str B = "abcdf"
I need a function(stA, stB) that returns 5 (ie. the number of characters matched), note that these characters need to be in same order.
For example:
Str A = "abcdef"
Str B = "fedcba",
function(stA, stB) would only return 1 for the 'a'
Pseudo code is good...
Oh btw given that all my strings will have <= 40 characters, O(n^2) might even be better than a O(41n) algorithm..
I haven't fully tested it, but this seems to be working (in JavaScript) for your test cases:
function compare(a, b)
{
var aChars = a.split('');
var bChars = b.split('');
var matches = [];
var bStart = 0;
for (var i=0; i < aChars.length; i++)
{
for (var j=bStart; j < bChars.length; j++)
{
if(aChars[i] == bChars[j])
{
matches.push(aChars[i]);
bStart = j;
break;
}
}
}
return matches.length;
}
compare('abcdef', 'abcdf'); // returns 5
compare('abcdef', 'fedcba'); // returns 1
Basically I'm starting at position 0 for string A and position 0 for string B. When a match is found, I change the start position for searching string B so that it skips the previous section.

Resources