Round to closest multiple of fraction (worded terribly) - javascript

Say I have this code for a simple timer:
var a = document.getElementById("a")
var start = Date.now()
window.onload = function() {
setInterval(()=>{
a.innerHTML = ((Date.now() - start)/1000).toFixed(3)
}, 1)
}
<p id="a">0.000</p>
I've always wanted a timer that counts in multiples of 1/30, so therefore it would go .033, .067, .100, .167, etc. I cannot modify the setInterval just to do this because of how inaccurate it is, so how can I round what the current time is so that the decimal ends in a valid value?
I know this is terribly worded, I apologize

Related

How to create number suffixes such as "100K" without having to be repetitive?

I've been having a problem that when my auto clicker in my clicker game goes fast enough to get to 200 thousand, it starts to lag, and then it doesn't function properly, or as fast.
Is there a way to make 100 thousand turn into 100K, and 101 thousand turn into 101K without being repetitive?
I tried this with my original code, and realized putting up to 1000 suffixes into each function would be a little too hard:
if (number >= 100000) {
document.getElementById(ID).innerHTML = "100K"
}
if (number >= 101000) {
document.getElementById(ID).innerHTML = "101K"
}
and on and on.
I don't want multiple if statements!
This would work, but it would take up way too much space, and I know there is an easier way to it, but I just couldn't find it. Can anyone provide a way to do this?
Try separating the job of formatting your number into a different function.
SUFFIXES = 'KMBTqQsSOND' // or whatever you'd like them to be
function getSuffixedNumber(num) {
var power = Math.floor(Math.log10(num));
var index = Math.floor(power / 3);
num = Math.round(num / Math.pow(10, (index * 3))); // first 3 digits of the number
return num + (SUFFIXES[index - 1] || ''); // default to no suffix if we get an out of bounds index
}
You can call the function like this: var x = getSuffixedNumber(101000), the value of x will be "101K".

Score counter doesn't count scores properly

First off, I have to say that I am very new to Javascript and programming in general so it's possible that the issue is related to my (current) lack of knowledge.
I've tried to make a simple game where a computer thinks of a random number between 0 and 10 and the user tries to guess that number by typing his guess in the text field. If the number is correct, the user gets the message that they guessed the number correctly and otherwise, they get the message that the numbers are not correct.
The first part works as intended. The problem is the score counter.
So this is the part of the HTML code that I wrote for the counter:
<p id="points">Number of points: </p><span id="points-number">0</span>
And this is the code that I wrote in JS:
<script type="text/javascript">
document.getElementById("instructions").onclick = function() {
alert("You need to guess the number that your computer imagined. Viable numbers are between 0 and 10. Every time you guess the number, score increases by 1 and every time you miss, you will lose a point")
}
document.getElementById("guess-number").onclick = function() {
var ourNumber;
var randomNumber;
var pointsNumber = 0;
randomNumber = Math.floor(Math.random() * 10);
ourNumber = document.getElementById("input").value;
if (ourNumber == randomNumber) {
alert("The numbers are equal!");
pointsNumber+=1;
var result = document.getElementById("points-number");
result.innerHTML = pointsNumber;
} else {
alert("The numbers are not equal! The number that your computer imagined is:" + randomNumber + ", and our number is: " + ourNumber);
pointsNumber-=1;
var result = document.getElementById("points-number");
result.innerHTML = pointsNumber;
}
}
</script>
Now here's the problem...whenever the user misses the number, the number of points goes to -1. But if he misses the second time, it stays at -1, it doesn't decrease further. After the user guesses the number, the value changes from -1 to 1. But, if he guesses again, it doesn't increase to 2, it stays at 1. Then when he misses, it jumps back to -1 and vice versa.
So, I believe I am missing something here, what should I do to make the counter work as intended? In other words, to make the score increase by 1 every time the user guesses the random number and make it decrease by 1 every time he doesn't get it right?
Thanks in advance.
basically, you are always starting with
var pointsNumber = 0;
instead, you should use:
var pointsNumber = + document.getElementById("points-number").innerHTML;
bonus:
and yes instead of:
randomNumber = Math.floor(Math.random() * 10);
use:
randomNumber = Math.floor(Math.random() * 11);
because, Math.random() lies between 0 (inclusive) and 1 (EXCLUSIVE), so could never reach 10.
see more about Math.random() at: https://www.w3schools.com/js/js_random.asp
You need to declare pointsNumber outside of the function:
var pointsNumber = 0;
document.getElementById("guess-number").onclick = function() {
var ourNumber;
var randomNumber;
Otherwise, each time the onclick function is called, you declare pointsNumber and set it to 0. Then it gets +1 or -1 depending on the if/else, which explains the behavior you are observing.

how to get percentage a day to more precision from javascript momentjs.asHours()?

I have table like this:
The total of the Percentage column must be 100%, but I'm getting 100.01%.
Here's my code:
var hourSlow = $("#input-me-slow").val();
var slowTime = moment.duration(hourSlow).asHours();
// slow time return 2.1666666666666665
var hourIdle = $("#input-me-idle").val();
var idleTime = moment.duration(hourIdle).asHours()
// idle time return 1
var hourEco = $("#input-me-eco").val();
var ecoTime = moment.duration(hourEco).asHours();
// ecoTime return 20.166666666666668
var hourSpeed = $("#input-me-speed").val();
var speedTime = moment.duration(hourSpeed).asHours();
// speedTime return 0.6666666666666666
var fTime = "24:00"
var dfTime = moment.duration(fTime).asHours();
// dfTime return 24
var totalTime = dfTime-speedTime-ecoTime-slowTime-idleTime;
// totalTime return -2.220446049250313e-15
// Here for display it to table, the problem is here
var fPercent = toHour(fullTime); //return 2.78
var ePercent = toHour(ecoTime); //return 84.03
var sPercent = toHour(slowTime); //return 9.03
var iPercent = toHour(idleTime); //return 4.17
$("#me_fullpercen").text(addCommas(fPercent));
$("#me_ecopercen").text(addCommas(ePercent));
$("#me_slowpercen").text(addCommas(sPercent));
$("#me_idlepercen").text(addCommas(iPercent));
// here the function of toHour (I dont know maybe the problem is here)
function toHour(num) {
var result = (num / 24) * 100;
return result ;
}
I would rather not round the percentage to 100%, as that would be less precise.
How can I make my percentage 100% instead of 100.01%?
This is a common problem, and no matter how precise you try to be, the computer will need to round numbers with repeating decimals at some point. Here's some posts that deal with it:
How to make rounded percentages add up to 100%
How to deal with the sum of rounded percentage not being 100?
In those posts you can read about many complex ways to get very close to 100%, but basically there is no right way to do this - when it's all boiled down it's still going to be an estimate - not exactly precise because we're dealing with not-precise numbers. That's just the nature of the beast.
Your program is going to round numbers the wrong way because it's a computer, and it's not intelligent.
Depending on your application, you may want to invest time into reading how to do those complex methods, and maybe you'll get really close.
Add a Footnote
Any path you choose, you'll probably end up putting a footnote explaining this problem anyway. Something like this:
*Because of rounding, these values may not add up to 100%.

Simple javascript counter no frills, just count

I have the number 3,453,500 it needs to increase by +1 every 4 seconds.
Need to keep the formatting the same (commas in the right place)
(also is there a way that this can count continuously without the refreshing to the lowest number on page refresh?)
Should be pretty simple...
Retrieve the number from local storage and display it
var num = +localStorage.getItem('num') || 3453500;
document.getElementById('display').innerHTML = num.toLocaleString();
Setup an interval to update the number every 4 seconds, save it and display it
setInterval(function() {
num++;
document.getElementById('display').innerHTML = num.toLocaleString();
localStorage.setItem('num', num);
}, 4000);
JSFiddle

Adding leading zeros to a Javascript timer

I'm attempted to add leading zeros to the seconds value and I keep running into errors. I've tried a number of selected solutions posted here and can't seem to make it work.
I'm pulling values from the spans because those values are coming from the database.
var timer = $('.timer');
$('.prev-button,.next-button').hide();
setInterval(function () {
var m = $('.min', timer),
s = $('.sec', timer);
if (m.length == 0 && parseInt(s.html()) <= 0) {
timer.html('Proceed to the Next Slide');
$('.prev-button,.next-button').fadeIn();
}
if (parseInt(s.html()) <= 0) {
m.html(parseInt(m.html() - 1));
s.html(60);
}
if (parseInt(s.html()) < 10) {
$('.sec').prepend(0)
}
if (parseInt(m.html()) <= 0) {
timer.html('Time remaining for this slide - <span class="sec">59</span> seconds')
}
s.html(parseInt(s.html() -1));
}, 1000);
http://jsfiddle.net/certainstrings/a2uJ2/1/
I've modified your Fiddle to make it work. http://jsfiddle.net/a2uJ2/3/
You should store the time in javascript int vars instead of reading it from the html elements every time. This causes maintainability problem as you are attaching logic to the layout of your html document.
I haven't fixed all your code but i've created two variables that are used to perform the calculations instead.
Couple of things: You'd be better off registering a start time, and comparing against that inside the interval function. Timers are not guaranteed to be precise, but will instead trigger on or after the interval you specify. If the computer's busy, the timer might be late.
Also, if you're using parseInt, always, always specify a radix argument (the number base). If you don't, the string "08" will will be parsed to "0" because a leading zero is intepreted as an octal (base-8). So use parseInt(string, 10) to parse to a normal base-10 number.
As for adding the leading zero, I'd say you should keep a couple variable for total amount of seconds, rather than reading/writing to the elements all the time.
Updated you jsfiddle
var duration, startTime, interval;
duration = parseInt($(".min").text(), 10) * 60 + parseInt($(".sec").text(), 10);
startTime = (new Date()).getTime();
function countDown() {
var elapsed, remaining, m, s;
elapsed = ((new Date()).getTime() - startTime) / 1000;
remaining = duration - elapsed;
if(remaining <= 0) {
clearInterval(interval);
$(".timer").text('Proceed to the Next Slide');
$('.prev-button,.next-button').fadeIn();
} else {
m = String(Math.round(remaining / 60));
s = String(Math.round(remaining % 60));
if( s < 10 ) {
s = "0" + s;
}
$(".min").text(m);
$(".sec").text(s);
}
}
interval = setInterval(countDown, 500);
This is just a minimal change from you code. I'd probably do something fundamentally different to keep the markup and JS as separate as possible, and so on and so forth, but this works too.
try it like this:
if (parseInt(s.html()) < 10) {
$('.sec').val('0' + $('.sec').val());
}
You're going to need to treat the value as a string rather than as an int. JavaScript is pretty aggressive about converting things that look like numbers into numbers, and that's what's happening here.

Categories

Resources