What is wrong with my code to calculate a standard deviation? - node.js

I'm trying to calculate the standard deviation of a set of numbers as Excel would with the STDEVPA() function, but I'm not getting the correct result. I'm following this formula:
Here is my [Node] code:
var _ = require('underscore');
var prices = [
1.37312,
1.35973,
1.35493,
1.34877,
1.34853,
1.35677,
1.36079,
1.36917,
1.36769,
1.3648,
1.37473,
1.37988,
1.37527,
1.38053,
1.37752,
1.38652,
1.39685,
1.39856,
1.39684,
1.39027
];
var standardDeviation = 0;
var average = _(prices).reduce(function(total, price) {
return total + price;
}) / prices.length;
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
});
var standardDeviation = Math.sqrt(squaredDeviations / prices.length);
console.log(standardDeviation);
When I run this, I get 0.26246286981807065, and instead I should get 0.0152.
Please note that I posted on StackOverflow and not the Mathematics site because, in my opinion, this is more geared toward programming than mathematics. If I post there, they will tell me to post here because this is related to programming.

If you console.log(total) inside your calculation of squaredDeviations, you'll see you're starting out with the value 1.37312, namely the first thing in your list. You need to explicitly tell it to start at 0, which is the third optional argument to reduce. Just replace:
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
});
with
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
}, 0);
See the underscore documentation for more details. In particular, note that things work when calculating the mean without passing this additional argument because, in said case, the iteratee function will not be applied to the first element.

Related

NodeJS Scripting issue with value sum definition

The home gas-meter is providing the actual gas count. With the subtraction (last minus before) I get 'Delta_Gas'. This is working.
Now I am trying to sum up gas these consumption values greater 0. In a typical cycle after gas burner ON max.10 values need to be summed up every minute. With burner OFF gas consumption should be set to zero(0).
Finally I want to see the gas consumption values for each single burner ON/OFF cycle.
Who can support my approach as I am a little bit lost?
var v1 = dp('/User Registers/Delta_Gas');
var sum = dp('/User Registers/Sum_Gas')
var s1;
AddValues(s1);
setInterval(AddValues, 3600000, s1); //1h Laufzeit
function AddValues(s1)
const add = add + v1
const sum = add
{
if(v1 > 0) { for (var i = 0; i < 10; i++) {
console.log(sum)
}else{
console.log(0)
}

Wrong hour difference between 2 timestamps (hh:mm:ss)

Using moment.js, I want to get the time difference between 2 timestamps.
Doing the following,
var prevTime = moment('23:01:53', "HH:mm:SS");
var nextTime = moment('23:01:56', "HH:mm:SS");
var duration = moment(nextTime.diff(prevTime)).format("HH:mm:SS");
I get this result :
01:00:03
Why do I have a 1 hour difference? seconds and minutes seem to work well.
After doing that, I tried the following :
function time_diff(t1, t2) {
var parts = t1.split(':');
var d1 = new Date(0, 0, 0, parts[0], parts[1], parts[2]);
parts = t2.split(':');
var d2 = new Date(new Date(0, 0, 0, parts[0], parts[1], parts[2]) - d1);
return (d2.getHours() + ':' + d2.getMinutes() + ':' + d2.getSeconds());
}
var diff = time_diff('23:01:53','23:01:56');
output is : 1:0:3
The problem you are having here is that when putting the nextTime.diff() in a moment constructor, you are effectively feeding milliseconds to moment() and it tries to interpret it as a timestamp, which is why you don't get the expected result.
There is no "nice way" of getting the result you want apart from getting a time and manually reconstructing what you are looking for :
var dur = moment.duration(nextTime.diff(prevTime));
var formattedDuration = dur.get("hours") +":"+ dur.get("minutes") +":"+ dur.get("seconds");
And a more elegant version that will give you zero padding in the output :
var difference = nextTime.diff(prevTime);
var dur = moment.duration(difference);
var zeroPaddedDuration = Math.floor(dur.asHours()) + moment.utc(difference).format(":mm:ss");
Should make you happier!
EDIT : I have noticed you use HH:mm:SS for your format, but you should instead use HH:mm:ss. 'SS' Will give you fractional values for the seconds between 0 and 999, which is not what you want here.

How to Convert a parseFloat string number to a floating point with 2 decimal places

In the following question/answer:
Configure Cart Price Update
The response gives an example that provides a working method - however, I had to change it to allow for floating point math.
The problem now is that I cannot convert the answer to 2 decimal places. The answer is sometimes given with 15! decimal places.
Here is my modified java code from the original - how do I get it to output to 2 decimals?
<script type="text/javascript">
$(document).ready(function(){
var basePrice = 39.95;
$("#baseCost").text(basePrice);
$("#sumTotal").text(basePrice);
});
function calculateTotals(){
var basePrice = parseFloat($("#baseCost").text(), 10);
var upgradePrice = 0.00;
$("#options select").each(function(){
var optionVal = $(this).val();
upgradePrice += parseFloat(optionVal.substr(optionVal.indexOf("_") + 1, optionVal.length - 1), 10);
});
$("#upgradeCost").text(upgradePrice);
$("#sumTotal").text(basePrice + upgradePrice);
}
</script>
Every number variable has a method called toFixed.
var sumTotal = basePrice + upgradePrice;
$("#sumTotal").text(sumTotal.toFixed(2));
Edit: Changed answer to something more specific.

Grabbing text from webpage and storing as variable

On the webpage
http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463
It lists prices for a particular item in a game, I wanted to grab the "Current guide price:" of said item, and store it as a variable so I could output it in a google spreadsheet. I only want the number, currently it is "643.8k", but I am not sure how to grab specific text like that.
Since the number is in "k" form, that means I can't graph it, It would have to be something like 643,800 to make it graphable. I have a formula for it, and my second question would be to know if it's possible to use a formula on the number pulled, then store that as the final output?
-EDIT-
This is what I have so far and it's not working not sure why.
function pullRuneScape() {
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var number = page.match(/Current guide price:<\/th>\n(\d*)/)[1];
SpreadsheetApp.getActive().getSheetByName('RuneScape').appendRow([new Date(), number]);
}
Your regex is wrong. I tested this one successfully:
var number = page.match(/Current guide price:<\/th>\s*<td>([^<]*)<\/td>/m)[1];
What it does:
Current guide price:<\/th> find Current guide price: and closing td tag
\s*<td> allow whitespace between tags, find opening td tag
([^<]*) build a group and match everything except this char <
<\/td> match the closing td tag
/m match multiline
Use UrlFetch to get the page [1]. That'll return an HTTPResponse that you can read with GetBlob [2]. Once you have the text you can use regular expressions. In this case just search for 'Current guide price:' and then read the next row. As to remove the 'k' you can just replace with reg ex like this:
'123k'.replace(/k/g,'')
Will return just '123'.
https://developers.google.com/apps-script/reference/url-fetch/
https://developers.google.com/apps-script/reference/url-fetch/http-response
Obviously, you are not getting anything because the regexp is wrong. I'm no regexp expert but I was able to extract the number using basic string manipulation
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var TD = "<td>";
var start = page.indexOf('Current guide price');
start = page.indexOf(TD, start);
var end = page.indexOf('</td>',start);
var number = page.substring (start + TD.length , end);
Logger.log(number);
Then, I wrote a function to convert k,m etc. to the corresponding multiplying factors.
function getMultiplyingFactor(symbol){
switch(symbol){
case 'k':
case 'K':
return 1000;
case 'm':
case 'M':
return 1000 * 1000;
case 'g':
case 'G':
return 1000 * 1000 * 1000;
default:
return 1;
}
}
Finally, tie the two together
function pullRuneScape() {
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var TD = "<td>";
var start = page.indexOf('Current guide price');
start = page.indexOf(TD, start);
var end = page.indexOf('</td>',start);
var number = page.substring (start + TD.length , end);
Logger.log(number);
var numericPart = number.substring(0, number.length -1);
var multiplierSymbol = number.substring(number.length -1 , number.length);
var multiplier = getMultiplyingFactor(multiplierSymbol);
var fullNumber = multiplier == 1 ? number : numericPart * multiplier;
Logger.log(fullNumber);
}
Certainly, not the optimal way of doing things but it works.
Basically I parse the html page as you did (with corrected regex) and split the string into number part and multiplicator (k = 1000). Finally I return the extracted number. This function can be used in Google Docs.
function pullRuneScape() {
var pageContent = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var matched = pageContent.match(/Current guide price:<.th>\n<td>(\d+\.*\d*)([k]{0,1})/);
var numberAsString = matched[1];
var multiplier = "";
if (matched.length == 3) {
multiplier = matched[2];
}
number = convertNumber(numberAsString, multiplier);
return number;
}
function convertNumber(numberAsString, multiplier) {
var number = Number(numberAsString);
if (multiplier == 'k') {
number *= 1000;
}
return number;
}

Divide up money evenly in C# using a functional approach

I have these 2 values:
decimal totalAmountDue = 1332.29m;
short installmentCount = 3;
I want to create 3 installments that have an even amount based on the totalAmountDue (extra pennies apply starting with the lowest installment number going to the highest installment number) using this class:
public class Installment
{
public Installment( short installmentNumber, decimal amount )
{
InstallmentNumber = installmentNumber;
Amount = amount;
}
public short InstallmentNumber { get; private set; }
public decimal Amount { get; private set; }
}
The installments should be as follows:
{ InstallmentNumber = 1, Amount = 444.10m }
{ InstallmentNumber = 2, Amount = 444.10m }
{ InstallmentNumber = 3, Amount = 444.09m }
I am looking for an interesting way to create my 3 installments. Using a simple LINQ to objects method would be nice. I have been trying to understand more about functional programming lately and this seems like it could be a fairly good exercise in recursion. The only decent way I can think of doing this is with a traditional while or for loop at the moment...
There's not a whole lot here that is "functional". I would approach the problem like this:
var pennies = (totalAmountDue * 100) % installmentCount;
var monthlyPayment = totalAmountDue / installmentCount;
var installments = from installment in Enumerable.Range(1, installmentCount)
let amount = monthlyPayment + (Math.Max(pennies--, 0m) / 100)
select new Installment(installment, amount);
You might be able to work something out where you constantly subtract the previous payment from the total amount and do the division rounding up to the nearest penny. In F# (C# is too wordy for this) it might be something like:
let calculatePayments totalAmountDue installmentCount =
let rec getPayments l (amountLeft:decimal) = function
| 0 -> l
| count -> let paymentAmount =
(truncate (amountLeft / (decimal)count * 100m)) / 100m
getPayments (new Installment(count, paymentAmount)::l)
(amountLeft - paymentAmount)
(count - 1)
getPayments [] totalAmountDue installmentCount
For those unfamiliar with F#, what that code is doing is setting up a recursive function (getPayments) and bootstrapping it with some initial values (empty list, starting values). Using match expressions it sets up a terminator (if installmentCount is 0) returning the list so far. Otherwise it calculates the payment amount and calls the recursive method adding the new installment to the front of the list, subtracting the payment amount from the amount left, and subtracting the count.
This is actually building the list in reverse (adding on to the front each time), so we throw away the extra pennies (the truncate) and eventually it catches up with us so the penny rounding works as expected. This is obviously more math intensive than the add/subtract code above since we divide and multiply in every iteration. But it is fully recursive and takes advantage of tail recursion so we'll never run out of stack.
The trouble with C# here is that you want a sequence of installments and recursion and there's no idiomatic built-in structure for doing that in C#. Here I'm using F#'s list which is immutable and O(1) operation to prepend.
You could possibly build something using the Scan() method in the Reactive Extensions to pass state from once instance to another.
Talljoe,
I think you are pushing me in the right direction. This code below seems to work. I had to switch out how the penny math was working but this looks pretty good (I think)
decimal totalAmountDue = 1332.29m;
short installmentCount = 8;
var pennies = (totalAmountDue * 100) % installmentCount;
var monthlyPayment = Math.Floor(totalAmountDue / installmentCount * 100);
var installments = from installmentNumber in Enumerable.Range(1, installmentCount)
let extraPenny = pennies-- > 0 ? 1 : 0
let amount = (monthlyPayment + extraPenny) / 100
select new Installment(installmentNumber, amount);

Resources