I'm trying to change the background each 4 seconds but it jumps directly to the second condition and doesn't change anymore. Why is this happening?
var time = 1;
var func = function () {
'use strict';
if (time === 1) {
document.getElementById("top-background").style.backgroundColor = "#000";
time += 1;
}
if (time === 2) {
document.getElementById("top-background").style.backgroundColor = "#aaa";
time += 1;
}
if (time === 3) {
document.getElementById("top-background").style.backgroundColor = "#d5d5d5";
time -= 2;
}
};
setInterval(func, 4000);
Try using else if
var func = function () {
'use strict';
if (time === 1) {
document.getElementById("top-background").style.backgroundColor = "#000";
time += 1;
}
else if (time === 2) {
document.getElementById("top-background").style.backgroundColor = "#aaa";
time += 1;
}
else if (time === 3) {
document.getElementById("top-background").style.backgroundColor = "#d5d5d5";
time -= 2;
}
};
When time equals 1, you add 1 to time. This makes time equal 2. After that, you check if time equals 2, which it is! This makes you continue upwards until you reach the point where time equals to 3, and then you reset it to 1 again.
You need a way to check for only one condition. You could do this using if and elseifs:
if (time == 1) {
// Code...
} else if (time == 2) {
// Code...
} else {
// Code...
// Because it's not equal to 1 or 2, it must be 3.
}
Or, you can also use Javascript's Switch statements.
switch(time) {
case 1:
// Code...
break;
case 2:
// Code...
break;
case 3:
// Code...
break;
default:
// Something went wrong and it's not 1, 2, or 3
}
Related
how come the following is not accurately logging whether a number is prime or not?
function isPrime2(num) {
for(let i = 2; i < num; i++) {
if(num % i === 0) {
return console.log(false); break;
} else{return console.log(true)}
}
}
isPrime2(33)returns true, even though it is a prime number.
If i = 2, then the console will log true since 33/2 = 16.5
But since the loop isn't over, the next i value is i=3,
so shouldn't the console log false and then break out of the loop completely, leaving the final answer to be false?
There are two problems here.
Your logic is broken
function isPrime2(num) {
for (let i = 2; i < num; i++) {
const remainder = num % i;
console.log({
remainder
});
if (remainder === 0) {
return console.log(false);
break;
} else {
return console.log(true)
}
}
}
isPrime2(33);
i starts at 2.
if(num % i === 0) is false, so we go to else
else{return console.log(true)} causes it to log true and exit the function.
Your failure condition is triggered when the first test fails instead of waiting for the loop to finish with a success condition for any of the tests.
33 is not a prime
It is divisible by 3 and 11.
function isPrime2(num) {
for (let i = 2; i < num; i++) {
const remainder = num % i;
console.log({
remainder
});
if (remainder === 0) {
return console.log(false);
break;
}
}
return console.log(true)
}
isPrime2(33);
I am trying to solve the Fizz Buzz question with an extra layer.
This is what I have so far. All this works fine but I need one more extra condition.
It's JS Unit testing
For any other input (valid or otherwise) return a string representation of the input
printFizzBuzz = function(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
} else if (i % 3 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else {
console.log(i);
}
}
};
Thank you!
You can use .toString() (JS toString) to change the number in string:
function printFizzBuzz(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
} else if (i % 3 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else {
console.log(i.toString());
}
}
};
printFizzBuzz();
Looking at the question, it is not asking for a loop, it is asking for any value passed to the function. So the answer should look more like this
function printFizzBuzz(input) {
// Your code goes here
if (typeof input !== ‘number’) {
return String(input)
}
let by3 = input % 3
let by5 = input % 5
switch(0) {
case by3 + by5:
return "FizzBuzz"
case by3:
return "Fizz"
case by5:
return "Buzz"
default:
return input.toString()
}
}
}
If I was the interviewer, I would prefer the answer to look more like this
function printFizzBuzz(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
let by3 = i % 3
let by5 = i % 5
switch(0) {
case by3 + by5:
console.log("FizzBuzz")
break
case by3:
console.log("Fizz")
break
case by5:
console.log("Buzz")
break
default:
console.log(i.toString())
}
}
}
}
printFizzBuzz()
I am trying to write a program that prints the numbers from 100 to 200, with three exceptions:
If the number is a multiple of 3, the string "yes" should be returned instead of the number.
If the number is a multiple of 4, the string "yes and yes" instead of the number should be returned.
If the number is a multiple of both 3 and 4, the string "yes, yes and yes" instead of the number.
I am new to JavaScript so I try to do this step by step.
I wrote this code to print the numbers from 100 to 200:
function hundredTwoHundred() {
result = [];
for (let i = 100; i <= 200; i++) {
result.push(i);
}
return result;
}
console.log(hundredTwoHundred());
Then I tried to use else/if for the exceptions:
function hundredTwoHundred() {
result = [];
for (let i = 100; i <= 200; i++) {
if (i % 3 == 0) {
console.log("yes");
} else if (i % 4 == 0) {
console.log("yes and yes")
} else if (i % 3 == 0 && i % 4 == 0) {
console.log("yes, yes and yes");
} else {
result.push(i)
}
}
return result;
}
console.log(hundredTwoHundred());
The code of course, does not work. I have tried moving result.push(i) around, but I don't want to just mindlessly move things around, without knowing the reasoning behind it.
How do I use conditional operators to find these exceptions? What am I doing wrong?
Thank you.
You need to test if the number is (divisible by 3 and divisible by 4) before checking whether it's (individually) divisible by 3 or 4, otherwise the first condition if (i % 3 == 0) will evaluate to true and you'll get yes rather than yes, yes and yes. You should also push to the result in the conditionals rather than console.logging in the conditionals, since you want to create an array of numbers and yeses and then console.log the whole constructed array afterwards.
Also make sure to declare the result with const (or var, for ES5) - it's not good to implicitly create global variables.
Also, although it doesn't matter in this case, when comparing, it's good to rely on === by default rather than == - best to only use == when you deliberately want to rely on implicit type coercion, which can result in confusing behavior.
function hundredTwoHundred() {
const result = [];
for (let i = 100; i <= 200; i++) {
if (i % 3 === 0 && i % 4 === 0) {
result.push("yes, yes and yes");
} else if (i % 3 === 0) {
result.push("yes");
} else if (i % 4 === 0) {
result.push("yes and yes")
} else {
result.push(i)
}
}
return result;
}
console.log(hundredTwoHundred());
If a number is a multiple of 3 and 4, then it is a multiple of 12. I’d also use a switch statement, so you can rewrite as follow:
for (let i = 100; i <= 200; i = i + 1) {
switch (0) {
case i % 12: console.log('yes, yes and yes'); break;
case i % 4: console.log('yes and yes'); break;
case i % 3: console.log('yes'); break;
default: console.log(i);
}
}
If you want it as an array:
// Fill an array with numbers from 100 to 200
const arr = Array(101).fill().map((_, i) => i + 100);
// Map it to numbers and strings
const hundredTwoHundred = arr.map(i => {
switch (0) {
case i % 12: return 'yes, yes and yes';
case i % 4: return 'yes and yes';
case i % 3: return 'yes';
default: return i
}
});
// Print it:
console.log(hundredTwoHundred);
When you have a complex set of conditions you need to be careful with the order in which you evaluate them.
function logExceptions(start, end) {
var divisibleByThree, divisibleByFour;
for (var i = start; i <= end; ++i) {
divisibleByThree = i % 3 == 0;
divisibleByFour = i % 4 == 0;
if (divisibleByThree && divisibleByFour) {
console.log("yes, yes and yes");
}
else if (divisibleByThree) {
console.log("yes");
}
else if (divisibleByFour) {
console.log("yes and yes");
}
else {
console.log(i);
}
}
}
logExceptions(100, 200);
If you want to save the result in an array and only later print it:
function logExceptions(start, end) {
var result = [];
var divisibleByThree, divisibleByFour;
for (var i = start; i <= end; ++i) {
divisibleByThree = i % 3 == 0;
divisibleByFour = i % 4 == 0;
if (divisibleByThree && divisibleByFour) {
result.push("yes, yes and yes");
}
else if (divisibleByThree) {
result.push("yes");
}
else if (divisibleByFour) {
result.push("yes and yes");
}
else {
result.push(i);
}
}
return result;
}
console.log(logExceptions(100, 200).toString());
I'm trying to solve a problem similar to the popular fizzbuzz or pingpong question. I already figured out how to write this portion of the code, however I also need to make a counter in which the user inputs their number and the page gives back 1 to the number they input, as well as the fizzbuzz/popcorn numbers. I think the code is something along the lines of
for (i = 1; i <= 20; i++) {...}
But I don't know how to combine this with my other code
var pingpong = function(number) {
if (number % 15 === 0) {
return 'pingpong';
} else if (number % 5 === 0) {
return 'pong';
} else if (number % 3 === 0) {
return 'ping';
} else {
return false;
}
};
Sorry, I know this is a super beginner question, but I'm just starting out and am having a hard time figuring out how everything works together.
You are close. To read more about JavaScripts loops.
var pingpong = function(number) {
if (number % 15 === 0) {
return 'pingpong';
} else if (number % 5 === 0) {
return 'pong';
} else if (number % 3 === 0) {
return 'ping';
} else {
return false;
}
};
for (var i = 1; i <= 20; i++) {
var num = pingpong(i);
// Just show it on the screen
document.body.innerHTML += i + ': ' + num + '<br />';
}
I am building an app that allow the user to set a duration to work (workSecs) and when completed a sound alerts the user (buzzer.mp3) and then a break duration (breakSecs) also set by the user begins, and when the break is completed a sound alerts the user (timer.mp3). I am using a switch statement to test when workSecs === 0 and when breakSecs === 0 and the unique alerts go off when either condition is true.
I have a setInterval function for my clock, strangely when I place my switch statement in the setInterval the sound works but it's repetitive because it's in the setInterval function, but when I remove it from within the setInterval function the alert does not work when the condition is true in the switch statement.
I am not sure if it's a scope issue because there are no errors in chrome's developer or firebug.
//audiotype object declare and sound method property
var Audiotypes = {
"mp3": "audio/mpeg",
"mp4": "audio/mp4",
"ogg": "audio/ogg",
"wav": "audio/wav",
soundbits: function (sound) {
var audio_element = document.createElement('audio')
if (audio_element.canPlayType) {
for (var i = 0; i < arguments.length; i++) {
var source_element = document.createElement('source')
source_element.setAttribute('src', arguments[i])
if (arguments[i].match(/\.(\w+)$/i)) source_element.setAttribute('type', Audiotypes[RegExp.$1])
audio_element.appendChild(source_element)
}
audio_element.load()
audio_element.playclip = function () {
audio_element.pause()
audio_element.currentTime = 0
audio_element.play()
}
return audio_element
}
}
}
// Clock object declared
var Clock = {
workSeconds: 0,
breakSeconds: 0,
// startTimer function begins here
startTimer: function () {
var self = this,
workSecs = this.workSeconds + 1,
breakSecs = this.breakSeconds + 1;
//workSecs and breakSecs switch statement begins here
switch (true) {
case (workSecs === 0):
alert('workSecs now 0')
var buzz = Audiotypes.soundbits('sounds/buzzer.mp3');
buzz.play();
break;
case (breakSecs === 0):
alert('breakSecs now 0')
var timer = Audiotypes.soundbits('sounds/timer.mp3');
timer.play();
}
// startTimer interval function begins here
this.interval = setInterval(function () {
if (workSecs > 0) {
workSecs--;
mins.html(Math.floor(workSecs / 60 % 60));
secs.html(parseInt(workSecs % 60));
} else if (breakSecs > 0) {
breakSecs--;
mins.html(Math.floor(breakSecs / 60 % 60));
secs.html(parseInt(breakSecs % 60));
} else if (breakSecs === 0) {
workSecs = self.workSeconds + 1;
breakSecs = self.breakSeconds + 1;
}
self.workSeconds = workSecs;
if (mins.html().length === 1) {
mins.html('0' + mins.html());
}
if (secs.html().length === 1) {
secs.html('0' + secs.html());
}
}, 1000)
}, //there is more code after this point but it's irrelevant to the problem
From your code, I assume you want to count down workSecs again after breakSecs ends and self.workSeconds = workSecs; is unintentional, since next time workSecs basically starts from 0.
The problem with your code is, that the switch statement only gets executed once when you call startTimer, but at that time your workSecs and breakSecs are this.workSeconds + 1 and this.breakSeconds + 1 which will never be zero (except if you set this.workSeconds and this.breakSeconds to -1).
When you put your switch statement into the interval handler, you didn't use proper conditions, and that's why it played it repetitively.
When it was counting breakSecs down to 0, workSecs was always zero and your sound played every second.
I changed your startTimer function to properly count down and use the proper conditions to play the sounds.
var Clock = {
workSeconds: 6,
breakSeconds: 3,
startTimer: function () {
var self = this,
workSecs = this.workSeconds,
breakSecs = this.breakSeconds;
this.interval = setInterval(function () {
if (breakSecs == self.breakSeconds && workSecs === 0) {
var buzz = Audiotypes.soundbits('sounds/buzzer.mp3');
buzz.play();
} else if (breakSecs == 0 && workSecs === 0) {
var timer = Audiotypes.soundbits('sounds/timer.mp3');
timer.play();
workSecs = self.workSeconds,
breakSecs = self.breakSeconds;
}
if (workSecs > 0) {
var m = Math.floor(workSecs / 60 % 60);
var s = workSecs % 60;
mins.text(m < 10 ? '0'+m : m);
secs.text(s < 10 ? '0'+s : s);
workSecs--;
} else if (breakSecs > 0) {
var m = Math.floor(breakSecs / 60 % 60);
var s = breakSecs % 60;
mins.text(m < 10 ? '0'+m : m);
secs.text(s < 10 ? '0'+s : s);
breakSecs--;
}
}, 1000);
},
};
I hope that's what you wanted.