Hello I need to compare a previous result that I'm getting from an API with the new one. The thing is that I don't know the value that I'll be getting. Therefore, I use a random function and a variable called oldShowNumber that will store the old result from the API and compare it to the new one which I'll call newrandom.
I tried to use a counter so the next time it enters inside the counter > 1 condition. Am I overcomplicating myself?
This is my script:
var array= ["100", "200", "300", "300"]
var newrandom = array[Math.floor(Math.random() * array.length)];
let counter= 1
var oldShowNumber= "";
(function (param){
if(counter <= 1){
oldShowNumber += param
counter +=1
} else if( counter > 1){
if(oldShowNumber === param){
console.log("They are the same it should stop")
}
}
})(newrandom)
console.log(oldShowNumber)
You need to store the information whether you already have an old number and if yes, the value of said number.
A common technique is to initialize a variable with to undefined to refer to the first case and assign a number in the second case.
Therefore: Initialize oldShowNumber with undefined and replace
var oldShowNumber= "";
....
if (counter <= 1) {
...
} else if (counter > 1) {
...
}
with
var oldShowNumber; // identical with: var oldShowNumber = undefined;
....
if (oldShowNumber === undefined) {
...
} else {
...
}
Related
I want to get data from a sensor in milliseconds and then calculate the average value within ten seconds to alert based on the average value. The problem is that this code runs well as long as the while loop been set to less than 1000 or one second and when I set it to larger numbers(I want the loop to work infinitely and stop with a button function). I want to know if there any way to function this infinite loop in Javascript?
Here is my code:
const now = Date.now();
var epochTime = now;
//Arrey of the value
var Arrey = [];
Counter =0
while (epochTime<now+10000000) { //should be set infinite and stop with button
$.get('http://xxx/'+epochTime, function(data){
let myValue= data.data[354708094967841].crosscorrelations[0].value;
document.getElementById("demo").innerHTML +="<br/>"+ myValue ;
Arrey.push(myValue);
console.log(Arrey);
var sum =0;
console.log(epochTime);
if (Counter>=10000 && Counter%10000==0){
for ( i=Counter-10000; i<Counter; i++)
sum = sum + Arrey[i];
valueAverage= sum/10000;
console.log(valueAverage);
document.getElementById("valueAverage").innerHTML +="<br/>"+ valueAverage;
if (valueAverage>0.01){
alert("the value ave is high"); // ----> to check the code
}else{
alert("the value ave is low"); //-----> to check the code
}
}
console.log(Counter);
Counter++;
console.log(myValue); //get data from value in async version
});
epochTime ++;
}
As the comments said: $.get() is asynchronous, so it doesn't wait. What you could do, is wrap the get request in a function and call the function from within the request, thus creating a loop. So sort of like this:
var buttonClicked = false;
//Function simply wraps the get request so that it can be called at anytime
function getSensorData(){
$.get('http://xxx/'+epochTime, function(data){
let myValue = data.data[354708094967841].crosscorrelations[0].value;
document.getElementById("demo").innerHTML += "<br/>" + myValue;
Arrey.push(myValue);
console.log(Arrey);
var sum = 0;
console.log(epochTime);
if (Counter >= 10000 && Counter % 10000 == 0) {
for (i = Counter - 10000; i < Counter; i++)
sum = sum + Arrey[i];
valueAverage = sum / 10000;
console.log(valueAverage);
document.getElementById("valueAverage").innerHTML += "<br/>" + valueAverage;
if (valueAverage > 0.01) {
alert("the value ave is high"); // ----> to check the code
} else {
alert("the value ave is low"); //-----> to check the code
}
}
console.log(Counter);
Counter++;
console.log(myValue); //get data from value in async version
//Now that you're done with everything, you can check if the button is clicked and if it is, don't run the function again.
if (!buttonClicked){
getSensorData();
}
}
}
//Here we check if the button is clicked and change the variable when it is
$("#stopButton").click(function(){
buttonClicked = true;
});
Also, quick note: Variables in javascript are usually camelCase, not Capitalized; constants are the exception because they are generally ALLCAPS.
How can I change the function passed params?
function minus_num(num) {
num -= 1
}
var num_test = 10
while (num > 0){
minus_num(num_test)
}
console.log(num) // there I want to get the 0, but it is infinite loop, because the `num` will have a copy in the function.
How can I change the num_test itself?
You need the function to return the value after being subtracted, and then you need to assign the result of that to num_test.
But num is never explicitly declared in your code. You probably wanted to put num_test in the loop instead:
function minus_num(num) {
return num - 1
}
var num_test = 10
while (num_test > 0){
num_test = minus_num(num_test)
}
console.log(num_test)
Primitives are passed by value, so you cannot change them in place. Instead you must return the changed value from the function and assign it back to the same variable:
function minus_num(num) {
num -= 1;
return num;
}
var num_test = 10
while (num_test > 0) {
num_test = minus_num(num_test)
}
console.log(num_test);
For your current implementation, you will get an error that num is not defined because you never declared it before the usage.
Please read this post to find out more on variable passing to functions.
I think it should be
function minus_num(num) {
return num - 1
}
var num_test = 10
while (num_test > 0){
num_test = minus_num(num_test)
}
console.log(num_test)
I am trying to call a function in jQuery and the variable is coming back as undefined in the console
var divide = function(entry) {
var entry = number
for (var i = 1; i <= entry; i++) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if ( i % 3 === 0) {
return "ping";
} else if (i % 5 === 0 ) {
return "pong";
} else {
return i;
}
}
}
$(document).ready(function(){
$("form#number").submit(function(event){
var number = parseInt($("#userNumber").val());
var pingpong = divide (number);
$("#result").text(pingpong);
event.preventDefault();
});
});
Why do you need a for-loop for this ? Assigning number to entry will not help as number is within the local scope of $(document).ready which will be undefined for divide. As you are passing entry as an argument, use that for conditions
Try this:
var divide = function(i) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if (i % 3 === 0) {
return "ping";
} else if (i % 5 === 0) {
return "pong";
} else {
return i;
}
}
$(document).ready(function() {
$("form#number").submit(function(event) {
var number = parseInt($("#userNumber").val());
var pingpong = divide(number);
$("#result").text(pingpong);
event.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form id='number'>
<input type="number" id='userNumber'>
<input type="submit">
<div id="result"></div>
</form>
Fiddle here
I think you may be confused about how arguments are passed into functions.
You have:
function divide ( entry ) { // defining divide
var entry = number; // this line is counter-productive
...
}
....
var number;
... divide(number); // calling divide
When you call the divide() function, the value of the variable number is automatically copied into the variable entry in divide(). Then you attempt to do the same thing with var entry = number; but number is not available in divide() so this fails. Lets suppose that number was globally available do this line did not cause an error. It might do what you want in this case, but a function whose argument is immediately ignored and overwritten is not very useful. Imagine you wanted to call it with two different values:
divide(number);
...
divide(someothernumber);
that wouldn't work because of the var entry = number; line -- you could never successfully pass someothernumber into divide(). Delete the line:
var entry = number;
from divide() and you will be much happier.
you try to delete "var entry = number"
Background
I'm attempting to check the existence of a value in array A in a second array, B. Each value is an observable number. Each observable number is contained in an observable array. The comparison always returns -1, which is known to be incorrect (insofar as values in A and B overlap). Therefore, there's something wrong with my logic or syntax, but I have not been able to figure out where.
JSBin (full project): http://jsbin.com/fehoq/190/edit
JS
//set up my two arrays that will be compared
this.scores = ko.observableArray();
//lowest is given values from another method that splices from scores
this.lowest = ko.observableArray();
//computes and returns mean of array less values in lowest
this.mean = (function(scores,i) {
var m = 0;
var count = 0;
ko.utils.arrayForEach(_this.scores(), function(score) {
if (!isNaN(parseFloat(score()))) {
//check values
console.log(score());
// always returns -1
console.log(_this.lowest.indexOf(score()));
//this returns an error, 'not a function'
console.log(_this.lowest()[i]());
//this returns undefined
console.log(_this.lowest()[i]);
//only do math if score() isn't in lowest
// again, always returns -1, so not a good check
if (_this.lowest.indexOf(score())<0) {
m += parseFloat(score());
count += 1;
}
}
});
// rest of the math
if (count) {
m = m / count;
return m.toFixed(2);
} else {
return 'N/A';
}
});
Update
#Major Byte noted that mean() is calculated before anything gets pushed to lowest, hence why I get undefined. If this is true, then what might be the best way to ensure that mean() will update based on changes to lowest?
You really just could use a computed for the mean
this.mean = ko.computed(
function() {
var sum = 0;
var count = 0;
var n = 0;
for(n;n < _this.scores().length;n++)
{
var score = _this.scores()[n];
if (_this.lowest.indexOf(score)<0) {
sum += parseFloat(score());
count++;
}
}
if (count > 0) {
sum = sum / count;
return sum.toFixed(2);
} else {
return 'N/A';
}
});
this will trigger when you add to lower(), scores() and change scores().
obligatory jsfiddle.
Update:
Forgot to mention that I change something crucial as well. From you original code:
this.dropLowestScores = function() {
ko.utils.arrayForEach(_this.students(), function(student){
var comparator = function(a,b){
if(a()<b()){
return 1;
} else if(a() > b()){
return -1;
} else {
return 0;
}
};
var tmp = student.scores().sort(comparator).slice(0);
student.lowest = ko.observableArray(tmp.splice((tmp.length-2),tmp.length-1));
});
};
apart from moving the comparator outside of dropLowestScores function, I changed the line:
student.lowest = ko.observableArray(tmp.splice((tmp.length-2),tmp.length-1));
to
student.lowest(tmp.splice((tmp.length-2),tmp.length-1));
student.lowest is an observable array, no need to define it as an observableArray again, in fact that actually breaks the computed mean. (The correction for Drop Lowest Scores as per my previous comment is left out here).
if I have a simple test function that adds even numbers to an array:
function isEven(n){
var enumbers = [];
if (n % 2 == 0){
enumbers.push (n);
}
}
how can I increment my parameter until I have a set number of members in my array? for instance, I've tried this:
function isEven(n){
var enumbers = [];
while ( enumbers.length < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
n = n + 1;
isEven(n);
}
}
isEven(1);
but it seems to just create a new array for each number until it finally throws a range error (maximum call stack size exceeded).
It's creating that array multiple times because you're constantly calling that function with:
isEven(n);
You're also not comparing to the length of the array, just the array. Add .length to enumbers. Try changing to:
var enumbers = [];
while ( enumbers.length < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
}
I'm not sure if I understood your question.
But you shouldn't use global variables, and it is unnecessary to call your function recursively inside a while loop.
The error maximum call stack size exceeded is your browser trying to break a infinity loop.
This is what you need.
Examples here jsFiddle1 and jsFiddle2
function isEven(n) {
var enumbers = [];
while (enumbers.length < 10) {
if (n % 2 == 0) {
enumbers.push(n);
}
n++;
}
return enumbers;
}
Setup a test
var n = 1;
var evenArray = isEven(n); //call isEven function and it returns an array
document.body.innerHTML = evenArray; //2,4,6,8,10,12,14,16,18,20
The problem is that (enumber < 10) apparently always evaluates to true, causing an endless loop. But it is this comparison that is wrong, since you're comparing an integer with an array I think you're trying to get the array length?:
while (enumbers.length < 10) {
Another thing. enumbers is a local variable, so each call to isEven has it's own array. Therefore, the functions is called recursively, over and over again.
I suggest you create the array outside of is even method
I would have written something like:
function isEven(n,enumbers){
while(enumbers < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
n = n + 1;
isEven(n, enumbers);
}
}
var enumbers = [];
isEven(1,enumbers);