I have a working formula that calculates PMT based on the interest rates, I see that it's working because the output in the console.log is correct. My question is, how can I take the results in the console.log and place each amount into it's own div?
For example, the first div is 4.125%, I want to display the dollar amount in the div right after it, then for the 3.125%, I want to display the dollar amount right after it and so on
Here is what I have http://jsfiddle.net/yecDj/19/
var p = 1000;
var thirtyYear = parseFloat(-Math.abs(360)); /*30 YR term in months*/
for (var i = 1; i < 5; i++) {
var costPerThousand = "$" + (p * ((parseFloat(document.getElementById('rate' + i).innerHTML) / 100 / 12) / (1 - (Math.pow((1 + (parseFloat(document.getElementById('rate' + i).innerHTML) / 100 / 12)), thirtyYear))))).toFixed(2);
console.log(costPerThousand);
}
I'm looking to do this in javascript only
Replace your console.log with:
document.querySelector('#rate' + i).textContent = costPerThousand;
querySelector
textContent
Fiddle
Related
**Hi, apologies for what some might seem as an easy question as I am quite new to Javascript coding. So here goes...on my html I have three input fields: Duct size, Insulation and Number of Holes. I want to show an array of measurements on the HTML in relation to the amount of holes, insulation and duct size entered. E.g first hole measurement, second hole, third hole etc... however the first measurement is calculated differently to the remaining measurements. Maybe this can clear up the formula and what I want to show on the screen:
1.Enter a measurement in duct size.
2.Enter insulation thickness.
3.Enter number of holes. With this information I want to calculate and display the measurements based off the number of holes and duct size measurement.
Here is an example:
Duct size: 400 mm
Insulation: 50 mm
Number of holes: 4
Insulation(50) * 2 - Duct size e.g 400 - 100 = 300 then 300 / 4 (number of holes) = 75 (want to show this number on HTML as: "Hole spacing = 75 mm ")
For first measurement(first Hole Spacing)=(spacing Of Holes)75 /2 + 50 (insulation) = 87.5 mm(This will be the first measurement to show on DOM).
Then for all other measurements relative (determined by number of holes >element)add spacing Of Holes to first Hole Spacing and display this.
E.g 87.5 + 75 = 162.5 (this is the second hole measurement displayed)
162.5 + 75 = 237.5 (this is the third hole measurement displayed)
237.5 + 75 = 312.5 (this the third hole measurement displayed)**
function ductPitotHoleCalculate() {
var ductSize = document.getElementById("duct-size").value;
var insulation = document.getElementById("insulation").value;
var amountOfHoles = document.getElementById("number-of-holes").value;
//It should multiply insulation by 2 and subtract from ductsize
var subtractInsulation = parseFloat(ductSize) - parseFloat(insulation) * 2;
//It should find the measurement between holes by dividing numberofHoles and subtractInsulation.
var spacingOfHoles = subtractInsulation / parseFloat(amountOfHoles);
//It should use the spacingOfHoles number and divide by 2 and add insulation for first hole and show on DOM
var firstHoleSpacing = spacingOfHoles / 2 + parseFloat(insulation);
// It should use a for loop to parse amountOfHoles and add spacingofHoles to firstHoleSpacing
var newAmount = parseFloat(amountOfHoles) - 2;
var myArray = [];
for (var i = 0; i < newAmount; i + spacingOfHoles) {
myArray.push(firstHoleSpacing + spacingOfHoles);
}
document.getElementById("answer-5").innerHTML = myArray;
}
<section id = "VSD-calculator">
<div id = "pitot-holes">
<h2> Calculate pitot hole duct measurements (type 0 for no insulation)
</h2>
<h2 id="answer-5"></h2>
<input type = "number" id = "duct-size" placeholder="Duct size in
mm"class="mytext">
<input type = "number" id = "insulation" placeholder="Insulation in
mm"class="mytext">
<input type = "number" id = "number-of-holes" placeholder="Number of
Holes"class="mytext">
<button onclick="ductPitotHoleCalculate()"id="calc-button" class = "calc"
>Calculate</button>
</div>
</section>
Thanks to all who helped me, I have solved this now! I think by explaining it and typing it down helped me make sense of it and write the code. I ended up using a while loop instead.
function ductPitotHoleCalculate() {
var ductSize = document.getElementById("duct-size").value;
var insulation = document.getElementById("insulation").value;
var amountOfHoles = document.getElementById("number-of-holes").value;
//It should multiply insulation by 2 and subtract from ductsize
var subtractInsulation = parseFloat(ductSize) - parseFloat(insulation) * 2;
//It should find the measurement between holes by dividing numberofHoles and
subtractInsulation.
var spacingOfHoles = subtractInsulation / parseFloat(amountOfHoles);
//It should use the spacingOfHoles number and divide by 2 and add insulation for
first
hole and show on DOM
var firstHoleSpacing = spacingOfHoles.toFixed(2) / 2 + parseFloat(insulation);
var i = 0;
var strHoles = parseFloat(amountOfHoles);
var myArray = '';
while (i < strHoles) {
myArray += firstHoleSpacing + (i * spacingOfHoles) + ' mm, ' + '<br />';
i++;
}
document.getElementById("answer-5").innerHTML = `Hole spacing = ${spacingOfHoles}
mm
` + '<br />' + myArray;
}
In my current project, I am creating random mathematics questionnaires for abacus student. So the exam page will serve sums one by one. Based on the student level I am generationg sums at front end using jquery and rendering to get student answer for validation. In a particular level I need to generate divisions with zero remainder.
So, I am using below function to generate the sum which is returning undefined sometimes.
tripleDigitSingleDigitWithoutRemainder: function()
{
var dividend = BOBASSESSMENT.general.randomIntFromInterval(100, 999);
var divisor = BOBASSESSMENT.general.randomIntFromInterval(2, 9);
console.log("out: " + dividend + "_" + divisor);
console.log("remainder: " + (dividend % divisor));
var result_val = "";
// result_val = dividend % divisor;
if(dividend % divisor != 0)
{
console.log('loop_again');
BOBASSESSMENT.general.tripleDigitSingleDigitWithoutRemainder();
}else{
result_val = dividend + "_" + divisor;
console.log("return: " + result_val);
}
console.log("final_return: " + result_val);
return result_val;
}
hence, please help me here to do further.
the requirement is to show question one by one and I need a dividend value and divisor value which does give remainder as 0. It means 16 % 2 = 0 not like 16 % 3 = 1.
Can you please some one help here.
As discussed in the comments here's a way to use a loop to try again with different values instead of recursion:
tripleDigitSingleDigitWithoutRemainder: function()
{
for(;;)
{
var dividend = BOBASSESSMENT.general.randomIntFromInterval(100, 999);
var divisor = BOBASSESSMENT.general.randomIntFromInterval(2, 9);
if(dividend % divisor == 0)
{
var result_val = dividend + "_" + divisor;
console.log("return: " + result_val);
return result_val;
}
}
}
Here we have an infinite loop and we keep looping until we have a valid problem and then immediately return when we do. for(;;) is one way of writing an infinite loop: there are others e.g. while (true) { ... } if that's clearer - up to you.
(However I prefer the approach in Wimanicesir's answer which constructs a correct value rather than just trying repeatedly until we find one, which may take many more goes.)
As said in the comments. Isn't it better to just create a working division by creating it with a product?
function generate() {
// Numbers [2-9]
var small = Math.floor(Math.random() * 8) + 2
// This will give the limit of current divider
var limit = Math.ceil(900 / small)
// We check the minimum now
var minimum = Math.floor(100 / small)
// We create a new random with given limit
var big = Math.ceil(Math.random() * limit) + minimum
// Create the product
var product = big * small;
return { question: product + ' / ' + small, answer: big }
}
console.log(generate())
I am working on a calculator that calculates simple interest and compounding interest. All good, with the simple interest, but I can't seem to be able to solve the problem with the compounding interest, using a loop. I need a loop, because pushing the data into an array to use it in a chart later.
I have the formula from here: https://www.moneysmart.gov.au/managing-your-money/saving/compound-interest
I am using this as reference: https://www.bankrate.com/calculators/retirement/roi-calculator.aspx
The code is in work here: http://www.course0001.com/fiverr/iddqd
I have this so far(updated):
// Inputs from user:
// Initial deposit (starting balance)
// Number of years
// Interest
// Frequent Deposit amount
// Deposit and compound frequency (monthly, weekly, yearly)
// Calculations
var investedCapitalArray = [];
var simpleInterestArray = [];
var compoundInterestArray = [];
var compoundPrincipal = 0;
var years = [];
var accumulatedInvestment;
function calculate() {
years = [];
let interest = rateNumeric.getNumber() / 100; // annual interest rate
let additionalDeposit = additionalNumeric.getNumber(); // Regular deposit
let frequency = freqInput.value; // Frequency of regular deposit
let initialDeposit = initialNumeric.getNumber();
let taxRate = taxNumeric.getNumber();
// Invested captal amount first year
investedCapitalArray = [];
investedCapitalArray.push(initialDeposit + (frequency * additionalDeposit));
// simple interest first year
simpleInterestArray = [];
simpleInterestArray.push((investedCapitalArray[0] * ( (interest) / 100)) * (1 - taxRate));
// compund interest first year
compoundInterestArray = [];
let firstYearInvestment = investedCapitalArray[0]; // First deposit + regular deposits in first year
for (let i = 1 ; i < yearsInput.value ; i++) {
// Invested capital over the years (correct results)
investedCapitalArray.push( (investedCapitalArray[i-1]) +
(frequency * additionalDeposit) );
// simple interest over the years (correct results)
simpleInterestArray.push( simpleInterestArray[i-1] +
((firstYearInvestment +
((frequency) * additionalDeposit) * i ) * interest) );
// compound interest over the years (incorrect results)
compoundInterestArray.push( investedCapitalArray[i-1] *
Math.pow(1 + interest / 100, i) - initialDeposit);
years.push('Year' +i);
}
}
The issue is with the paranthesis you should use (investedCapitalArray[i - 1] + compoundInterestArray[i - 1]) * (1 + 0.07). Thanks
I think the problem is with unboxing the object. Try this:
compoundInterestArray.push( compoundInterestArray[i-1] + (parseInt(investedCapitalArray[i-1]) + parseInt(simpleInterestArray[i-1])) * ( rateNumberic.getNumber() / 100)) );
Thank you everyone for the inputs, after thoroughly researching the compounding interest topic, I wrote an algorithm that works perfectly. It's actually quite simple.
My algorithm is based on this explanation:
"What Is Compound Interest? Compound interest (or compounding interest) is interest calculated on the initial principal, which also includes all of the accumulated interest of previous periods of a deposit or loan."
Therefore it works like this in a loop:
compoundInterest += (((simpleInterestArray[i - 1] + compoundInterest) * (interest));
Full code below.
for (let i = 1; i < yearsInput.value; i++) {
// Invested capital over the years (works fine)
investedCapital = (investedCapitalArray[i - 1]) +
(frequency * additionalDeposit);
investedCapitalArray.push(investedCapital);
// imple interest over the years (works fine)
simpleInterest = simpleInterestArray[i - 1] +
((firstYearInvestment + (frequency * additionalDeposit) * i) * interest);
simpleInterestArray.push(simpleInterest);
// compound interest over the years (correct results)
compoundInterest += (((simpleInterestArray[i - 1] + compoundInterest) * (interest)));
compoundInterestArray.push(compoundInterest);
}
I'm currently producing a JavaScript driven mathematics package, which focuses on rounding to various significant figures (S.F.) but I've run into a problem that I'm struggling to solve.
More on this problem later, but first some background for you.
The program is designed to select a completely random number within a given range and then automatically work out that number's relevant significant figures; for example:
Random Number: 0.097027 S.Fs: 9, 7, 0, 2, 7
Here is a screenshot of what I have produced to give you a visual representation:
As you can see, once the user has selected their number, they are then given the opportunity to click on four separate 'SF' buttons to view their random number presented to 1, 2, 3 and 4 S.Fs respectively.
For each S.F (1-4) the random number is rounded down, rounded up and rounded off to X SF and a scale below gives the user a more visual presentation to show why the SF value has been chosen by the program.
I've already written the vast majority of the code for this and tested it and so far the numbers are coming out how I'm expecting them to. Well nearly...
In the example I've given (0.097027); as you can see on the image I've included, the data for 4 S.F is absolutely correct and outputted accurately.
When I click on to the 3 SF button, I'd expect to see the following:
Random Number: 0.097027 3 S.F Rounded Up/Down/Off: 0.0970
However, what I'm actually getting is:
Random Number: 0.097027 3 S.F Rounded Up/Down/Off: 0.097
The program hasn't displayed the additional zero. This is a perfect example of a number in my program ending in a zero and in this case the zero is really significant and must be displayed.
The data is usually correct but there appears to be an issue with outputting significant zeros at the right time. I've researched the toFixed(x) method and if I assign toFixed(4) I get the correct required output, but because my numbers are generated randomly each time, they can range from a length of 5 figures, e.g. 89.404 up to > 10, e.g. `0.000020615.
So it looks like the toFixed method needs to be flexible/dynamic, e.g. toFixed(n) with a function run beforehand to determine exactly how many trailing zeros are needed?
Here are some key excerpts from my current solution for your consideration:
function generateNum() {
do {
genNumber = Math.random() * Math.pow (10, randomRange(-5, 5));
//Round
genNumber = roundToNSF(genNumber, 5, 0);
// This number must contain >1 digit which is 1 to 9 inclusive otherwise we may have e.g. 100. Rounding 100
}
while (!countNonZero(genNumber) || genNumber < 1E-05 || genNumber == 0);
//Round
genNumber = roundToNSF(genNumber, 5, 0);
genNumber = String(genNumber);
genNumber = Number(genNumber);
}
//----------------------------------------------------------------------------
function randomRange(min, max) {
/**
* Returns a random integer between min (inclusive) and max (inclusive)
* Using Math.round() will give you a non-uniform distribution!
*/
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//---------------------------------------------------------------------------
//Click SF3 Button to reveal the data
function showSF3() {
//Remove any CSS properties on the buttons from previous use
removeButtonCSS();
document.getElementById('SFRounded').style.display = "block";
document.getElementById('scale').style.display = "block";
document.getElementById("SF3").className = document.getElementById("SF3").className + "buttonClick"; // this removes the blue border class
//Clear text
deleteRounded();
deleteScale();
//Run calculation
calculateAnswer();
//alert(genNumber.toFixed(4));
for (i = 3; i < 4; i++)
{
//Add The new data
sfRoundedTextBlock = document.getElementById('SFRounded');
//alert(downArray[i].toFixed(4));
//Data output to HTML.
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + downArray[i] + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + upArray[i] + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ roundedArray[i] + '</br>' + '(See the scale below for why we choose <strong>' + roundedArray[i] + '</strong> as the rounded off value.)</p>';
}
}
//----------------------------------------------------------------------
var roundedArray = [];
var upArray = [];
var downArray = [];
var temp;
function calculateAnswer() {
//Clear Arrays
roundedArray = [];
upArray = [];
downArray = [];
// Work out the answer:
for (i = 0; i < 4; i++) {
var nSF = i + 1;
// Round OFF ...
temp = roundToNSF(genNumber, nSF, 0);
// We actually have to do this twice ...
roundedArray[nSF] = roundToNSF(temp, nSF, 0);
// Round UP ...
upArray[nSF] = roundToNSF(genNumber, nSF, 1);
// Round DOWN ...
downArray[nSF] = roundToNSF(genNumber, nSF, -1);
// e.g. x = 0.0098 rounded to 1SF is 0.010 initially (take the log of 0.0098 and try it!).
};
};
//-------------------------------------------------------------------------
//Globals
var aNumber;
var digits;
var way;
function roundToNSF(aNumber, digits, way){
// Round a number to n significant figures (can use roundToNDP provided we know how many decimal places):
if (way == undefined) { way = 0; }; // default is round off
if (aNumber !=0) {
if (aNumber > 0)
{
z = log10(aNumber);
}
else
{
z = log10(-aNumber);
};
z = Math.floor(z);
var nDP = digits - z - 1; // Rounding to nDP decimal places is equivalent to rounding to digits significant figures ...
var roundedNumber = roundToNDP(aNumber, nDP, way);
}
else {
roundedNumber = aNumber; // Number is zero ...
};
return Number(roundedNumber);
};
//---------------------------------------------------------------------------------
Update:
I'm still continuing to try and find a solution for this problem and an approach I have recently taken is to convert my randomly generated number into a searchable string variable and then use the indexOf(".") command to find the position of the decimal point (dp).
Then I've searched through my number, starting from the position of the dp to find the first instance of a significant, non-zero number [1-9].
var genNumber = 0.097027;
var rString = String(genNumber);
var positionofDP = rString.indexOf(".");
var regexp = /[1-9]/;
var positionofNonZero = Number(rString.search(regexp, positionofDP)); // Output would be '5'
I have then been able to target my search further, to determine whether my first significant number has any 'problematic' zeros in the immediate digits after it.
If there are any, then I set a Boolean variable to 'true' and then in a separate function create further text strings of my rounded off/down/up numbers, so I can then physically choose to add a '0' on to the end of the existing numerical characters.
This approach does work for me in isolated cases, but with my random number length ranging from 5-12 digits long, it still isn't dealing with all scenarios.
Maybe I need to create a dynamic toFixed(i) function? Any ideas would be greatly welcomed.
Instead of playing with the fixed points on an Int, you could manage the string directly.
Here's a link to a little fiddle: http://jsfiddle.net/5rw5G/4/
This not intended to completely/accurately solve your problem, but might help you see another solution.
function getRoundedSFs(num, SFCount) {
// Match every "leading zeros" before and after the .
var matches = num.toString().match(/^-?(0+)\.(0*)/);
// starting with "0."
if (matches) {
var firstIndex = matches[0].length;
var prefix = matches[0];
sf = Number(num.toString().substring(firstIndex, firstIndex + SFCount + 1));
sf = Math.round(sf / 10);
sf = prefix + sf.toString();
return Number(sf).toFixed(matches[2].length+SFCount);
}
// starting with something else like -5.574487436097115
else {
matches = num.toString().match(/^(-?(\d+))\.(\d+)/);
var decimalShift = SFCount - matches[2].length;
var rounded = Math.round(num * Math.pow(10, decimalShift));
rounded /= Math.pow(10, decimalShift);
return rounded.toFixed(decimalShift);
}
}
I've gone away again and I think I have now finally managed solve my initial problem.
There was a degree of confusion on my part surrounding when to use toFixed and toPrecision. I had previously attempted to convert my rounded up, down and off numbers into strings and then subsequently search through each of these to find the decimal point (".") and then work out the amount of trailing numbers, in order to then generate the correct toFixed point.
However, this was very hit and miss, given that my random number could be up to 12 digits, so what I've now done is to properly utilise toPrecision instead. For each 'SF button' (1-4) I have used the corresponding toPrecision point, e.g for SF1:
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + downArray[i].toPrecision(1) + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + upArray[i].toPrecision(1) + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ roundedArray[i].toPrecision(1) + '</br>' + '(See the scale below for why we choose <strong>' + roundedArray[i].toPrecision(1) + '</strong> as the rounded off value.)</p>';
//Add The new scale data (Rounded Down)
downTextBlock = document.getElementById('down');
document.getElementById("down").innerHTML = String(downArray[i].toPrecision(1));
//Add The new scale data (Rounded Up)
upTextBlock = document.getElementById('up');
document.getElementById("up").innerHTML = String(upArray[i].toPrecision(1));
This was now giving me accurate results on every occasion, but there was still one hurdle left to jump. Occasionally I would reach a random scenario where scientific notation would have to be included in my outputted answer, e.g. 21819 rounded down to 1 SF, would read out at 2e+4 instead of 20000.
To combat this I setup my up, down and rounded figures into searchable strings, and then looked through these to find any illegal/scientific characters [a-z]. If I found any, I executed a slightly different version of my output which made use of parseFloat, which stripped out the scientific notation and displayed the correct figures:
//Convert Up, Down and Rounded into Strings based on their precision
var upString = String(upArray[i].toPrecision(1));
var downString = String(downArray[i].toPrecision(1));
var roundedString = String(roundedArray[i].toPrecision(1));
//Set up a regexp to search for characters [a-z], i.e. non-numeric
var regexp = /[a-z]/g;
//Search the up, down and rounded strings for non-numeric characters
var upResult = upString.match(regexp);
var downResult = downString.match(regexp);
var roundedResult = roundedString.match(regexp);
//If any of these strings contain a letter (non-numeric) we need to add in parseFloat to strip away the scientific notation included.
var containsChar = false;
if (upResult != null || downResult != null || roundedResult != null)
{
containsChar = true;
//alert("There is SN included here");
}
//Add The new data
sfRoundedTextBlock = document.getElementById('SFRounded');
if (containsChar == true)
{
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + parseFloat(downArray[i].toPrecision(1)) + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + parseFloat(upArray[i].toPrecision(1)) + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ parseFloat(roundedArray[i].toPrecision(1)) + '</br>' + '(See the scale below for why we choose <strong>' + parseFloat(roundedArray[i].toPrecision(1)) + '</strong> as the rounded off value.)</p>';
//Add The new scale data (Rounded Down)
downTextBlock = document.getElementById('down');
document.getElementById("down").innerHTML = String(parseFloat(downArray[i].toPrecision(1)));
//Add The new scale data (Rounded Up)
upTextBlock = document.getElementById('up');
document.getElementById("up").innerHTML = String(parseFloat(upArray[i].toPrecision(1)));
}
Having tested this extensively it seems to be working as hoped.
If I have an array of buttons, how can I tell which button was clicked?
example below
var i=0
CreateButton = new function () {
savebutton[i]=NewButton()
i++
}
every time a user runs the function a new button is generated.
the first button is savebutton[0] the second is savebutton[1] and so on potentially infinity times.
when later the user presses the button I want the screen to alert it's index number (or 'i').
is there any way to make this work in arrays?
this : savebutton[i].click(alert(this))
and this: savebutton[i].onClick(alert(this))
do not work
the code is entirely written in RephaelJs and contains absolutely no DOM elements.
I use RaphaelJS and my HTML document contains no DOM elements. everything is scripted.
the entire function that generates the buttons:
var insertframe = function () {
ww = WindowWidth
mw = mywindoww
zx = zone.getBBox().x
zy = zone.getBBox().y
zw = zone.getBBox().width
zh = zone.getBBox().height
sh = screen.getBBox().height
sw = screen.getBBox().width
py = picy
px = picx
srw = screenratiow
srh = screenratioh
savebutton[i] = paper.image(imageurl)
savebutton[i].attr(
{
'width': px * (framewidth * miniframesize) / zw,
'height': py * (frameheight * miniframesize) / zh,
'x': ((srw*520) + (i * 120) * srw) - zx * (frameheight * miniframesize) / zh,
'y': srh*600 - zy * (framewidth * miniframesize) / zw,
'clip-rect': (srw*520) + (i * 120) * srw + "," + srh * 600 + "," + framewidth * miniframesize + ',' + frameheight * miniframesize
})
savebutton[i].click(alert(this))
i++
}
When you create the button, you can assign its index from the array as an attribute of the button and then when it's clicked on, you can examine that attribute of the clicked on button to see where it is positioned in the array.
If you don't want to do that, you can also search the array and find where the current button is in the array.
You can use a 2d array with each element having an ID and an identifier. Can't say too much more without seeing your code.
I think JQuery might help you achieve that way easier. Check out this:
http://api.jquery.com/index/
Hope this helps!