Javascript: Dynamically rendering a list [Beginner] - javascript

I'm building a word count tracker and would like to show how many words needed per day to reach a target within 30 days. For example if someone enters in 50,000 as their target, they'll have to complete 1667 words per day. I want to create a list element that would say:
Day 1: 1667
Day 2: 3334
Day 3....etc.
My current plan was to create an array that contained the list elements, but the script seems to be causing the site to break entirely! I'm not sure what's going on here.
let wordsPerDay = 0;
function wordsPerDayF(x) {
wordsPerDay = x / 30;
wordsPerDay = Math.round(wordsPerDay)
document.getElementById('wordsNeeded').innerHTML = wordsPerDay.toString();
};
// Above functions finds the word count needed per day
let milestones = []
let finalMilestones = [];
function createMilestones() {
let newWordCount = wordsPerDay;
for (let w = 1; w <= 30; w++) {
milestones.push(newWordCount)
newWordCount += newWordCount;
};
let count = 1;
for (let z = 0; z = milestones.length; z++) {
finalMilestones.push("Day " + count + ": " + milestones[z]);
count++;
};
};
function final() {
createMilestones();
let str = '<ul>'
finalMilestones.forEach(function(item) {
str += '<li>' + item + '</li>';
});
str += '</ul>';
document.getElementById("wordsNeeded").innerHTML = str;
};
final();
<div id="wordsNeeded"></div>
I'm new to coding, so apologies if this code is rough or hard to understand.

z = milestones.length should be z < milestones.length.
You never call wordsPerDayF().
newWordCount += newWordCount will double the word count each day, but that's not what you really want. You just want to add newWordCount to a total. You can also use w * newWordCount to get the total for each day.
let wordsPerDay = 0;
function wordsPerDayF(x) {
wordsPerDay = x / 30;
wordsPerDay = Math.round(wordsPerDay)
document.getElementById('wordsNeeded').innerHTML = wordsPerDay.toString();
};
// Above functions finds the word count needed per day
let milestones = []
let finalMilestones = [];
function createMilestones() {
let newWordCount = wordsPerDay;
for (let w = 1; w <= 30; w++) {
milestones.push(newWordCount * w)
};
let count = 1;
for (let z = 0; z < milestones.length; z++) {
finalMilestones.push("Day " + count + ": " + milestones[z]);
count++;
};
};
function final() {
wordsPerDayF(50000);
createMilestones();
let str = '<ul>'
finalMilestones.forEach(function(item) {
str += '<li>' + item + '</li>';
});
str += '</ul>';
document.getElementById("wordsNeeded").innerHTML = str;
};
final();
<div id="wordsNeeded"></div>

Related

Adding asterisks to array?

I'm trying to add elements as asterisks inside array based on number of elements. Basically If numberOfRows is 3 then I want this output:
[
' * ',
' *** ',
'*****'
]
I'm struggling on setting asterisks using the index. Can anyone point me in the right direction? Thanks a lot!
Here's my code:
function myFunction(numberOfRows) {
var arr = [];
var value = "";
var asterisk = "*"; // Need to update this based on number of rows
for (var i = 1; i <= numberOfRows; i++) {
value += asterisk;
arr.push(value);
}
return arr;
}
Got it working! Here's a perfect solution.
function myFunction(n) {
let arr = [];
for(let f = 1; f <= n; f++) {
arr.push(' '.repeat(n - f) + '*'.repeat(f + f - 1) + ' '.repeat(n - f));
}
return arr;
}
console.log(myFunction(3));
Try something like this;
function myFunction(numberOfRows) {
var arr = [];
var value = "";
var slots = numberOfRows * 2 - 1;
var spaceSlots, asteriskSlots, spaces;
for (var i = 0; i < numberOfRows; i++) {
asteriskSlots = i * 2 + 1;
spaceSlots = Math.floor((slots - asteriskSlots)/2);
spaces = new Array(spaceSlots).fill(' ').join('');
value = spaces + '*'.repeat(asteriskSlots) + spaces;
arr.push(value);
}
return arr;
}
console.log(myFunction(20));

How to console.log multiplication table without repeating x*y=z, y*x=z

How to make multiplication table without repeating reverse calculations like this xy=z yx=z? I tried to use if else with !== operator but it shows nothing. My code:
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {
var result = x * i;
if (result !== result){
console.log(x + ' * ' + i + ' = ' + result);
}
else {
}
}
}
Pretty simple :
for (var x = 1; x <= 10; x++) {
for (var i = x; i <= 10; i++) {
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
Replace i = 1 by i = x on the second line so that it starts later and ignores all the previous calculations it already did.
E.G.: When you're calculating the table 3, you can start with 3*3 as you already already did 3*1 (1*3) with table 1 and 3*2 (2*3) with table 2
You could keep track of the calculations you've already done in an hash table. If it's already in the table - skip that calculation. Something like this:
var doneCalculations = {};
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {;
if (doneCalculations[i+'x'+x]) continue;
doneCalculations[x+'x'+i] = true;
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
start the second loop with first loop variable
for (var x = 1; x <= 10; x++) {
for (var i = x; i <= 10; i++) {
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
You want to print full multiplication table for each values of x, 1 to 10. Use memoization to avoid recalculation
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.
var doneCalculations = {};
var calculations = {};
var doneCalculations = {};
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {;
if (doneCalculations[i+'x'+x]) {
result = calculations[i+'x'+x]
}
else {
doneCalculations[x+'x'+i] = true;
var result = x * i;
calculations[x+'x'+i] = result;
}
console.log(x + ' * ' + i + ' = ' + result);
}
}
console.log(calculations)

Nested Loop to add numbers

I am currently trying to create a double nested loop that adds a number to itself, given the number of instances you want it to be added by.
So when you input something in the Number, for example "5" and you input "3" for the number of instances, then the following would be printed:
5=5
5+5=10
5+5+5=15
More information on my JsFiddle
<div>
<h2>Loop</h2>
Number
<input type='text' id='tbox'>
<br>
Number of Instances
<input type='text' id='theNumber'>
<button onclick=doubleLoop;>
Add Numbers.
</button>
</div>
<div id="content">
</div>
<script>
function doubleLoop(){
var theText = document.getElementById('tbox').value;
var theNumber = document.getElementById('theNumber').value;
var content = document.getElementById('content');
content.innerHTML = '';
for (var i = 0; i < theNumber; i++) {
content.innerHTML = content.innerHTML + (i + 1) + ')';
//start of the second part of the Double Loop
for (var j = 0; j < (i + 1); j++){
if (i === 0){
content.innerHTML = content.innerHTML + theText + '=' + theText + '<br>';
} else if (i > 0) {
content.innerHTML = content.innerHTML + theText.repeat(j) + '=' + (theText * (i+1));
}
}
}
}
</script>
Here you go
https://jsfiddle.net/mkarajohn/qkn2ef4L/
function createString(number, times) {
/*
* We will create each side of the equation separately and we will concatenate them at the end
*/
var leftSide = '',
rightSide = '',
i;
for (i = 1; i <= times; i++) {
leftSide += number.toString();
if ((times > 1) && (i < times)) {
leftSide += '+';
}
}
rightSide = number * times
return (leftSide + '=' + rightSide);
}
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
output += createString(theText, i);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
If there is something that is not clear feel free to ask.
EDIT: If you are hell bent on doing it with two nested loops, here's how it would go:
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
var leftSide = '',
rightSide = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
leftSide = '';
for (var j = 1; j <= i; j++) {
leftSide += theText.toString();
if ((i > 1) && (j < i)) {
leftSide += '+';
}
}
rightSide = theText * i;
output += (leftSide + '=' + rightSide);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
First things first: You're naming your variables very poorly, it's really difficult to understand what you're trying to do, specially when you don't say what you want directly in the question. doubleLoop says how your function works but not what it does. getMultiplicationProcess would have been a better name. Also, you could be passing the values as arguments and just returning the result, it would look A LOT better.
Anyway, I couldn't figure how you were trying to achieve this. I've renamed your variables and did everything my way. Never name a variable theNumber or theText because doing so says nothing about what information it holds. You could have named them firstInput and secondInput but even that way it would not be clear.
Here's the code, scroll down for explanation:
var submit = document.getElementById("submit"),
firstInput = document.getElementById("tbox"),
secondInput = document.getElementById("theNumber"),
answerField = document.getElementById("content");
submit.addEventListener("click", function () {
answerField.innerHTML = getMultiplicationProcess(Number(firstInput.value), Number(secondInput.value), "<br/>");
});
function getMultiplicationProcess(multiplicand, multiplier, lineBreak) {
var result = "";
for (var i = 0; i < multiplier; ++i) {
for (var j = 0; j < i + 1; ++j) {
if (i === j) {
result += multiplicand + " = " + (multiplicand * (i + 1));
} else result += multiplicand + " + ";
}
result += lineBreak || "\n";
}
return result;
}
JSFiddle
Explanation:
The outer for loop runs as many times as the second input, or multiplier. So if you input 5 and 3 respectively this loop will run three times. It represents each line of the resulting string.
The inner loop runs as many times as the current iteration number of the outer loop more one. So for our example inputs it will run like this:
0: 1; 1: 2; 2: 3;
I use it to place the multiplicand multiple times in the current line.
The first line will contain a single 5 (not including the answer for this multiplication) so j is i + 1 which is 1 because during the first iteration from the outer loop i equals 0:
5 = 5
The second line contains 2 5s and i is 1 because we're in the second iteration for the outer loop, so j = i + 1 = 2 which is how many fives we'll place in the string:
5 + 5 = 10
if it's the last iteration of the inner loop instead of adding "5 + " to the resulting string it places "5 = (i + 1) * multiplier" which will be the result for the current line. Then the inner loop ends, the outer loop adds a line break and restarts the process for the next line.

Javascript for loop sums

I want to find the sums of a set of numbers from a for loop
I currently have
var num = "";
for(var i = 1; i < 11; i +=1){
num = num + i;
}
console.log(num)
which gives me 12345678910 in the JS console
I want to produce 1+2+3+4+5+6+7+8+9+10=SUM
I have tried adding a "+" string:
num = num + i + "+";
but it gives me 1+2+3+4+5+6+7+8+9+10+
My question is how to add the "+" and "=" into the code and get the sum.
If you want the + to display AND the actual sum, then do this
var realSum = 0;
var num = "1";
for(var i = 2; i < 11; i +=1){
realSum = realSum + i;
num = num + "+" + i;
}
num = num + "=" + realSum;
Try this : http://jsfiddle.net/kx9b7qu7/2
Using Eval
var num = [];
for(var i = 1; i < 11; i +=1){
num.push(i)
}
var equation = num.join('+');
var sum = eval(equation);
console.log('Method 1: ',equation + '=' + sum)
Without using Eval
var num = [];
var sum = 0;
for(var i = 1; i < 11; i +=1){
num.push(i)
sum += i
}
var equation = num.join('+');
console.log('Method 2: ',equation + '=' + sum)
Make an util out of it for later use ;) There are also other ways that make use of functional approach (reduce, map) and things that aren't widely supported yet (generators, array comprehensions).
Here are some example functions for consideration and tweaking:
// kind of usual
var sumRange = function (from, to, step) {
var i,
sum = from,
str = from;
for (i = from + step; i <= to; i += step) {
sum += i;
str += '+' + i;
};
str += '=' + sum;
return str;
};
// sum of elements in arithmetic progression
var sumRangeAP = function (from, to, step) {
var i,
n,
str = from;
n = ((to - from) / step) + 1;
for (i = from + step; i <= to; i += step) {
str += '+' + i;
};
str += '=' + ((from + to) / 2) * n;
return str;
};
// memory efficiency (not creating hell a lot of strings) together with some functional stuff
// on the other hand it looks like assignment operators (+, +=) win with .join in terms of speed sometimes
// in many cases, I think, you may not give a shit about whether you use this or that
var sumRangeME = function (from, to, step) {
var i,
sum = from,
str = [from];
for (i = from + step; i <= to; i += step) {
str.push(i);
};
return str.join('+') + '=' + str.reduce(function (prevVal, curVal) { return prevVal + curVal; });
};
console.log(sumRange(0,20,1));
console.log(sumRangeAP(0,20,1));
console.log(sumRangeME(0,20,1));
console.log(sumRange(1,21,1));
console.log(sumRangeAP(1,21,1));
console.log(sumRangeME(1,21,1));
console.log(sumRange(7,36,1));
console.log(sumRangeAP(7,36,1));
console.log(sumRangeME(7,36,1));
In javascript + can also concatenate a string, if that's what seems best - it thinks you are putting two strings together so it concatenates them. Make num start as 0 instead, that should fix it.
Instead of var num="" try with var num=0, because this way the operator + is used as string concatenation. num=0 will do the job.
EDIT: I thought you wanted to see the "math" equation try the following:
var numbers = 0;
for (var i = 1; i < 11; i += 1){
numbers += i;
}
console.log(numbers);
Try this:
var numbers = [];
for (var i = 1; i < 11; i += 1){
numbers.push(i);
}
var string = numbers.join("+");
string += "=" + eval(numbers.join("+"));
console.log(string);
If you're really trying to concatenate then
num = num + "+" + i;

getRange : Cannot convert Nan to Class

I tried parseInt but i really don't know where is the right place to put it in the code :
Here's the code :
function projectTime(QuelProjet) {
var tabUsers = getUsersList();
var ss = SpreadsheetApp.getActive();
var ProjectSheet = ss.getSheetByName("Liste Projets");
for (i = 1; i < 13; i++) {
//Nombre de jours du mois
var date = new Date(i + "/01/" + year);
var numProjects = getProjectNumber();
var currentMonthSheet = getSheetByMonth(tabMonth[i - 1]);
for (l = 0; l < tabUsers.length; l++) {
var firstLine = 1 + (l + 1) * 10 - 10 + (l + 1) * numProjects - numProjects;
Logger.log("Fline " + l + " : " + firstLine);
var QuelPro = parseInt(QuelProjet);
Logger.log("Quelpro : " + QuelPro);
var nbDays = getNbJours(date);
var sommeproject = 0;
var som1 = new Array(1000);
for (k = 1; k < nbDays + 1; k++) {
var Row = parseInt(firstLine + QuelPro);
Logger.log("Row : " + Row + " QuelProjet : " + QuelPro);
var Column = k + 1;
Logger.log("Column : " + Column);
var range = currentMonthSheet.getRange(Row, Column);
som1[k] = range.getValues();
//sommeproject = sommeproject + currentMonthSheet.getRange(firstLine + QuelProjet, k + 1).getValues();
}
}
}
var sommeproject = 1;
sommeproject = sommeproject + som1;
return sommeproject;
}
The problem is in this line :
var range = currentMonthSheet.getRange(Row, Column);
QuelProjet is a argument that I put like an integer in the function* when i call it in the spreadsheet
Thanks for your time
If the error is that cannot convert NaN to class, it means that either variable Row or Column or both are not integers. Your issue comes from Row not being an integer.
Since I don't know what getProjectNumber(), I can't fully debug, but this methodology should let you debug.
Use: Logger.log(typeof(variable_name)) so that you can pinpoint where the issue is.
Log the types of the following variables after defining them: numProjects, firstLine, quelPro, and row.
the logger should log 'number' each time. When it doesn't you've found your error.
If all results are 'number' it's possible that your numbers are not whoel numbers since I don't know what getProjectNumber() returns, and the getRange() function needs whole numbers

Categories