so i want to calculate the standard deviation of 10 values from input types. I am collecting them into an array and want to calculate my standard deviation.
Problem is, it always shows NaN when i run the function (with action "oninput")
My code is the following:
function s10() {
var n1 = parseFloat(document.getElementById('input1').value);
var n2 = parseFloat(document.getElementById('input2').value);
var n3 = parseFloat(document.getElementById('input3').value);
var n4 = parseFloat(document.getElementById('input4').value);
var n5 = parseFloat(document.getElementById('input5').value);
var n6 = parseFloat(document.getElementById('input6').value);
var n7 = parseFloat(document.getElementById('input7').value);
var n8 = parseFloat(document.getElementById('input8').value);
var n9 = parseFloat(document.getElementById('input9').value);
var n10 = parseFloat(document.getElementById('input10').value);
var arr = [{
key: 'n1',
value: parseFloat(document.getElementById('input1').value)
}, {
key: 'n2',
value: parseFloat(document.getElementById('input2').value)
}, {
key: 'n3',
value: parseFloat(document.getElementById('input3').value)
}, {
key: 'n4',
value: parseFloat(document.getElementById('input4').value)
}, {
key: 'n5',
value: parseFloat(document.getElementById('input5').value)
}, {
key: 'n6',
value: parseFloat(document.getElementById('input6').value)
}, {
key: 'n7',
value: parseFloat(document.getElementById('input7').value)
}, {
key: 'n8',
value: parseFloat(document.getElementById('input8').value)
}, {
key: 'n9',
value: parseFloat(document.getElementById('input9').value)
}, {
key: 'n10',
value: parseFloat(document.getElementById('input10').value)
}, ];
const mean = arr.reduce((s, n) => s n) / arr.length;
const variance = arr.reduce((s, n) => s (n - mean) ** 2, 0) / (arr.length - 1);
document.getElementById('s').value = Math.sqrt(variance);
}
<input type="text" id="input1"/>
<input type="text" id="input2"/>
<input type="text" id="input3"/>
<input type="text" id="input4"/>
<input type="text" id="input5"/>
<input type="text" id="input6"/>
<input type="text" id="input7" />
<input type="text" id="input8" />
<input type="text" id="input9" />
<input type="text" id="input10" oninput="s10();" />
<input type="text" id="s" placeholder="standardDeviation" />
CodePudding user response:
Below is a modified example of your code. A couple of notes:
- When calculating the mean and variance, you were using
n
in thereduce
callbacks, rather thann.value
- The first
reduce
function needed an initial value of 0 - I used
number
type inputs to make it easier to step through values n.value || 0
will use0
when the input is empty to prevent errors during addition
<script>
function s10() {
var n1 = parseFloat(document.getElementById("input1").value);
var n2 = parseFloat(document.getElementById("input2").value);
var n3 = parseFloat(document.getElementById("input3").value);
var n4 = parseFloat(document.getElementById("input4").value);
var n5 = parseFloat(document.getElementById("input5").value);
var n6 = parseFloat(document.getElementById("input6").value);
var n7 = parseFloat(document.getElementById("input7").value);
var n8 = parseFloat(document.getElementById("input8").value);
var n9 = parseFloat(document.getElementById("input9").value);
var n10 = parseFloat(document.getElementById("input10").value);
var arr = [
{
key: "n1",
value: parseFloat(document.getElementById("input1").value),
},
{
key: "n2",
value: parseFloat(document.getElementById("input2").value),
},
{
key: "n3",
value: parseFloat(document.getElementById("input3").value),
},
{
key: "n4",
value: parseFloat(document.getElementById("input4").value),
},
{
key: "n5",
value: parseFloat(document.getElementById("input5").value),
},
{
key: "n6",
value: parseFloat(document.getElementById("input6").value),
},
{
key: "n7",
value: parseFloat(document.getElementById("input7").value),
},
{
key: "n8",
value: parseFloat(document.getElementById("input8").value),
},
{
key: "n9",
value: parseFloat(document.getElementById("input9").value),
},
{
key: "n10",
value: parseFloat(document.getElementById("input10").value),
},
];
const mean = arr.reduce((s, n) => s (n.value || 0), 0) / arr.length;
const variance = arr.reduce((s, n) => s ((n.value || 0) - mean) ** 2, 0) / (arr.length - 1);
document.getElementById("s").value = Math.sqrt(variance);
}
</script>
<input type="number" id="input1" />
<input type="number" id="input2" />
<input type="number" id="input3" />
<input type="number" id="input4" />
<input type="number" id="input5" />
<input type="number" id="input6" />
<input type="number" id="input7" />
<input type="number" id="input8" />
<input type="number" id="input9" />
<input type="number" id="input10" oninput="s10();" placeholder="Type here" />
<input type="text" id="s" placeholder="standardDeviation" />
CodePudding user response:
Okay a couple of small bugs in your code:
When using your arr
, you should keep in mind the number is located in arr[item].value
, an is not the item itself. You tried counting with objects, which results in NaN
.
When calculating the mean
, you did not pass in an initial value, which means you started counting with undefined
, which gives NaN
, which propagates to all your code. So
const mean = arr.reduce((s, n) => s n) / arr.length;
should be
const mean = arr.reduce((s, n) => s n.value, 0) / arr.length;
The same rule applies for your average
calculation, where arr[item].value
is your value, not the item itself.
function s10() {
var n1 = parseFloat(document.getElementById('input1').value);
var n2 = parseFloat(document.getElementById('input2').value);
var n3 = parseFloat(document.getElementById('input3').value);
var n4 = parseFloat(document.getElementById('input4').value);
var n5 = parseFloat(document.getElementById('input5').value);
var n6 = parseFloat(document.getElementById('input6').value);
var n7 = parseFloat(document.getElementById('input7').value);
var n8 = parseFloat(document.getElementById('input8').value);
var n9 = parseFloat(document.getElementById('input9').value);
var n10 = parseFloat(document.getElementById('input10').value);
var arr = [{
key: 'n1',
value: parseFloat(document.getElementById('input1').value)
}, {
key: 'n2',
value: parseFloat(document.getElementById('input2').value)
}, {
key: 'n3',
value: parseFloat(document.getElementById('input3').value)
}, {
key: 'n4',
value: parseFloat(document.getElementById('input4').value)
}, {
key: 'n5',
value: parseFloat(document.getElementById('input5').value)
}, {
key: 'n6',
value: parseFloat(document.getElementById('input6').value)
}, {
key: 'n7',
value: parseFloat(document.getElementById('input7').value)
}, {
key: 'n8',
value: parseFloat(document.getElementById('input8').value)
}, {
key: 'n9',
value: parseFloat(document.getElementById('input9').value)
}, {
key: 'n10',
value: parseFloat(document.getElementById('input10').value)
}, ];
const mean = arr.reduce((s, n) => s n.value, 0) / arr.length;
const variance = arr.reduce((s, n) => s (n.value - mean) ** 2, 0) / (arr.length - 1);
document.getElementById('s').value = Math.sqrt(variance);
}
<input type="text" id="input10" oninput="s10();" />
<input type="number" id="input1" value="1" />
<input type="number" id="input2" value="2" />
<input type="number" id="input3" value="3" />
<input type="number" id="input4" value="4" />
<input type="number" id="input5" value="5" />
<input type="number" id="input6" value="6" />
<input type="number" id="input7" value="7" />
<input type="number" id="input8" value="8" />
<input type="number" id="input9" value="9" />
<input type="number" id="s" placeholder="standardDeviation" />
CodePudding user response:
I am not a JavaScript practionner, but I suggest the following:
- In case the user inputs only one value then std = 0
- In case it is more than one value the call to the calculations should be done everywhere for simplicity and real-time calculation.
- Building the array can be done dynamically for more inputs such that the input id is defined as
input{i}
. - Checking for NaN is mandatory before accepting any value.
So the code could be,
<input type="text" id="input1" oninput="s10();"/>
<input type="text" id="input2" oninput="s10();"/>
<input type="text" id="input3" oninput="s10();"/>
<input type="text" id="input4" oninput="s10();"/>
<input type="text" id="input5" oninput="s10();"/>
<input type="text" id="input6" oninput="s10();"/>
<input type="text" id="input7" oninput="s10();" />
<input type="text" id="input8" oninput="s10();" />
<input type="text" id="input9" oninput="s10();" />
<input type="text" id="input10" oninput="s10();" />
<input type="text" id="s" placeholder="standardDeviation" />
function s10() {
let arr = [];
N = 10; // Can be changed to be identified dynamically
for(i=1; i<=N; i ) {
let input_id = "input" String(i);
let val = parseFloat(document.getElementById(input_id).value);
if (!isNaN(val)) {
arr.push(val);
};
};
if (arr.length == 0) {
document.getElementById('s').value = NaN;
}
else if (arr.length == 1) {
const variance = 0;
document.getElementById('s').value = Math.sqrt(variance);
} else {
const mean = arr.reduce((s, n) => s n) / arr.length;
const variance = arr.reduce((s, n) => s (n - mean) ** 2, 0) / (arr.length - 1);
document.getElementById('s').value = Math.sqrt(variance);
};
}
```