Wrong output when using a function - javascript

I have a function that calculates the price something.
When the age < 5 then price = 0,
when the age < 15 the price = price/2
and when age > 15 the price = price + price*0.15. The first 2 are working fine but the last one has a problem. When for example a put 100 on the price input and 26 on the age input the answer that it gives me is 10015.
<script>
function add(x, y) {
return x+y;
}
function Subtract(x, y) {
return x-y;
}
function Divide(x, y) {
return x/y;
}
function Multiply(x, y) {
return x*y;
}
var plusPrice = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
var plusButton = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
function updateClickCount() {
document.getElementById("clicks").innerHTML = plusButton();
if (document.getElementById("price").value !== '') {
document.getElementById("input").innerHTML = plusPrice();
}
}
function checkInputs() {
var price = document.getElementById("price").value;
var age = document.getElementById("age").value;
if( parseInt(price) < 0 || isNaN(parseInt(price))) {
window.alert("Please insert a valid price");
price = '';
}
if(parseInt(age) > 100 || parseInt(age) < 0 || isNaN(parseInt(age))){
window.alert("Please insert a valid age");
age = '';
}
}
function Calculate() {
var price = document.getElementById("price").value;
var age = document.getElementById("age").value;
if (document.getElementById("price").value !== '' && document.getElementById("age").value !== '') {
if (age<5) {
document.getElementById("demo").innerHTML = Subtract(price,price);
} else if (age < 15 && age >= 5) {
document.getElementById("demo").innerHTML = Divide(price,2);
} else {
document.getElementById("demo").innerHTML = add(price,Multiply(price,0.15));
}
} else {
window.alert("Please fill both age and price to calculate the amount you have to pay");
}
}
</script>
<body>
Please enter the price: <br>
<input type="text" id="price"><button onclick="document.getElementById('price').value = ''">Clear input field</button><br><br>
Please enter your age: <br>
<input type="text" id="age"><button onclick="document.getElementById('age').value = ''">Clear input field</button><br><br>
<button onclick="checkInputs(); updateClickCount(); Calculate();">Calculate price</button>
<p id="totalPrice">The total amount you have to pay is: </p><br>
<p id="demo"></p>
<p>Button Clicks: <a id="clicks">0</a></p>
<p>Correct Price Fill Count: <span id="input">0</span></p>
</body>

Apparently, price is a string. Replace
var price = document.getElementById("price").value;
with
var price = parseFloat(document.getElementById("price").value);
The function has already worked for subtraction and division, because operators - and / can't be applied to strings, so JS coerces them to numbers. The +, however, has a string-compatible interpretation (string concatenation), so type coercion doesn't happen.

or do this
var price = Number(document.getElementById("price").value);

In JavaScript the + symbol can be used both for numeric addition and string concatenation, depending on the variables either side. For example,
console.log('value:' + 4); // 'value:4'
console.log(3 + 1); // 4
console.log('value:' + 4 + '+' + 1); // 'value:4+1'
console.log('value:' + 4 + 1); // 'value:41'
console.log('value:' + (3 + 1)); // 'value:4'
console.log(4 + ' is the value'); // '4 is the value
Hence convert your operands to numeric type before proceeding with addition so that they are not concatenated.
Hope this clarifies.

Related

Countdown from 100 to the number (N) and separate even and odd numbers. Show even numbers in the first line and odd numbers in the second line

<div id="counter">100</div>
<script>
function myFunction() {
var person = prompt("Please enter One number (N) where (N) is a positive integer.", "");
if (person != null) {
document.getElementById("demo").innerHTML =
"Hello " + person + "! How are you today?";
}
}
function countdown() {
var i = document.getElementById('counter');
i.innerHTML = parseInt(i.innerHTML) - 1;
if (parseInt(i.innerHTML) == 95) {
clearInterval(timerId);
}
}
var timerId = setInterval(function () { countdown(); }, 1000);
</script>
<p id="demo"></p>
Example Test Cases:
Input: 10
Output:
100 98 96 94 92
99 97 95 93 91
Another one:
Input: 5
Output:
100 98 96
99 97
I have made my own script which counts down from 100-0, and places each number into an Array variable depending on whether it's Odd/Even.
Here it is:
var even = [];
var odd = [];
var number = 100;
changeNumber();
function changeNumber() {
document.getElementById("counter").innerText = number;
if (checkParity(number) == "even") {
console.log("even");
even.push(number);
} else {
console.log("odd");
odd.push(number);
}
if (number == 0) {
console.log("[Finished]");
console.log("Even numbers:");
console.log(even);
console.log("Odd numbers:");
console.log(odd);
} else {
setTimeout(function () {
number--;
changeNumber();
}, 100);
}
}
function checkParity(n) {
if (n % 2 == 0) {
return "even"
} else {
return "odd"
}
}
<div id="counter">100</div>
I hope that can help.
(function () {
const input = prompt("Please enter One number (N) where (N) is a positive integer.", "");
let count = 100;
if (isNaN(input) || input < 1) return;
const inerval = setInterval(() => {
count--;
if (count % 2 == 0) {
console.log('This is even Numbers ' + count);
} else {
console.log('This is odd Numbers ' + count);
}
if (input == count) return clearInterval(inerval);
}, 1000);
})();
I think this is a possible solution, without many changes to your original code:
<div id="counter">100</div>
<p id="results"></p>
<script>
var input = parseInt(prompt("Please enter One number (N) where (N) is a positive integer.", ""));
var half = parseInt(input / 2);
var i = document.getElementById('counter');
var res = document.getElementById('results');
res.innerHTML += "Even: ";
if (parseInt(i.innerHTML) % 2 == 0) {
res.innerHTML += i.innerHTML;
input--;
}
function countdown() {
if (input == 0) {
clearInterval(timerId);
return;
}
if (input == half) {
var newValue;
if (input % 2) {
newValue = parseInt(i.innerHTML) + input * 2 - 3;
}
else {
newValue = parseInt(i.innerHTML) + input * 2 - 1;
}
i.innerHTML = newValue;
res.innerHTML += "</br> Odd: ";
}
else {
i.innerHTML = parseInt(i.innerHTML) - 2;
}
res.innerHTML += " " + i.innerHTML;
input--;
}
var timerId = setInterval(function(){ countdown(); }, 1000);
</script>
<p id="demo"></p>
Basically you decrease it by 2 till you reach the half, then you go back to the start - 1, looping through the odd numbers (or even, if the counter value was odd at first).

Undefined JS password generator

I'm making a simple password generator that prompts the user for conditions for a password such as case, symbols, and numbers then generates a password on click.
I have set up functions to handle these, however, cannot get the password to actually generate.
I'm getting an error where the password that's generated is undefined?
//Password option input
const resultEl = document.getElementById("result");
var characters = prompt("How many characters should the password containt (8-128)");
var upperCase = prompt("Should the password contain uppercase Letters?");
var lowerCase = prompt("Should the password contain lowercase Letters");
var numbers = prompt("Should the password contain numbers?");
var symbols = prompt("Should the password contain symbols?");
var generateEl = document.getElementById("generate");
function randomFunc(input) {
if (input === "hasUpper") {
console.log("upper");
return getRandomUpper();
}
if (input === "hasLower") {
getRandomLower();
console.log("lower")
}
if (input === "hasNumbers") {
getRandomNumber();
console.log("numbers")
}
if (input === "hasSymbols") {
getRandomSymbol();
console.log("symbols")
}
}
if (characters > 7 && characters < 129) {
var length = parseInt(characters, 10);
console.log("length: " + length);
} else {
var length = false;
alert("Invalid Password length");
}
// if input is "yes" return true
if (upperCase.toLowerCase() === 'yes') {
var hasUpper = true;
console.log("upper: " + hasUpper);
}
if (lowerCase.toLowerCase() === 'yes') {
var hasLower = true;
console.log("lower: " + hasLower);
}
if (numbers.toLowerCase() === 'yes') {
var hasNumbers = true;
console.log("number: " + hasNumbers);
}
if (symbols.toLowerCase() === 'yes') {
var hasSymbols = true;
console.log("symbol: " + hasSymbols);
}
generateEl.addEventListener('click', function() {
resultEl.innerText = generatePassword(hasUpper, hasLower, hasNumbers, hasSymbols, length);
console.log("generatebut");
});
//Generate password function
function generatePassword(hasUpper, hasLower, hasNumbers, hasSymbols, length) {
//1. initialise password variable
let generatedPassword = '';
const typesCount = hasUpper + hasLower + hasNumbers + hasSymbols;
//console.log('typesCount ', typesCount);
const typesArr = [{
hasUpper
}, {
hasLower
}, {
hasNumbers
}, {
hasSymbols
}]
//3. loop over length call generator function for each type
for (let i = 0; i < length; i += typesCount) {
typesArr.forEach(function(type) {
const funcName = Object.keys(type)[0];
console.log('funcNames ', funcName);
generatedPassword = randomFunc(funcName);
});
}
//4. Add final password to password variable and return
const finalPassword = generatedPassword;
console.log("password: " + generatedPassword);
return finalPassword;
}
// Password generator functions
function getRandomLower() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
function getRandomUpper() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 65);
}
function getRandomNumber() {
return String.fromCharCode(Math.floor(Math.random() * 10) + 48);
}
function getRandomSymbol() {
const symbols = "!##$%^&*()<>?,."
return symbols[Math.floor(Math.random() * symbols.length)];
}
<main class="container">
<header>
<h1 class="title">Password Generator</h1>
</header>
<section class="generator-box">
<h2 class="sub-title">Generate a Password</h2>
<div class="pass-div pass-hold">
<h3>Your secure Password</h3>
<span id="result"></span>
</div>
<section class="button-div">
<button href="#" class="button" id="generate">Generate</button>
</section>
</section>
</main>
The randomFunc function is only returning a character for the "hasUpper" condition. You need to explicitly return a character regardless of case like so:
function randomFunc(input) {
let randomChar;
if (input === "hasUpper") {
randomChar = getRandomUpper();
}
if (input === "hasLower") {
randomChar = getRandomLower();
}
if (input === "hasNumbers") {
randomChar = getRandomNumber();
}
if (input === "hasSymbols") {
randomChar = getRandomSymbol();
}
return randomChar;
}
The generatePassword function is overwriting the generatedPassword variable on every loop. So even if you were returning characters from randomFunc your final password would only ever be 1 character. I modified that and removed the redundant finalPassword variable like so:
function generatePassword(hasUpper, hasLower, hasNumbers, hasSymbols, length) {
let generatedPassword = '';
const typesCount = hasUpper + hasLower + hasNumbers + hasSymbols;
const typesArr = [{ hasUpper }, { hasLower }, { hasNumbers }, { hasSymbols }]
for (let i = 0; i < length; i += typesCount) {
typesArr.forEach(function(type) {
const funcName = Object.keys(type)[0];
generatedPassword = generatedPassword + randomFunc(funcName);
});
}
return generatedPassword;
}

Javascript adding to array using readline

I'm trying to repeatedly get 2 inputs and store them into an array until the word 'end' is typed. However, I'm getting undefined at the console.log(studentList[i]);
EDIT: With the help of you guys, I was able to store the values into the array. Right now what I want to do is to give a 'grade' to each of the marks that was entered. However no matter what number i entered, i was getting 'HD' for all the grades.
const readline = require('readline-sync');
var name, marks;
var studentList = [];
Input();
function printList(list) {
for (let i = 0; i < studentList.length; i += 1) {
var grade;
if ((marks <= 100) && (marks => 80)){
grade = 'HD'
studentList[i][2] = grade;
}
else if ((marks <= 79) && (marks => 70))
{
grade = 'D'
studentList[i][2] = grade;
}
else if ((marks <= 69) && (marks =>60))
{
grade = 'C'
studentList[i][2] = grade;
}
else if ((marks <= 59) && (marks =>51))
{
grade = 'P'
studentList[i][2] = grade;
}
else if ((marks < 50) && (marks =>0))
{
grade = 'N'
studentList[i][2] = grade;
}
console.log(studentList[i]);
}
}
function Input()
{
while(true) {
console.log("Please enter the student name (or \"end\" to end): ");
name = readline.question("Student Name: ");
if (name === 'end') {
printList(studentList)
break
}
console.log("Student Name is" , name);
marks = readline.question("Enter marks for " + name + ": ");
if (marks === 'end') {
printList(studentList)
break
}
console.log("Marks for " + name + " is " + marks );
studentList.push([name, marks]);
}
}
Any advice would be much appreciated! Thanks!
You mainly need to change .Length to .length and you have to use a while loop combined with a break (once 'end' is typed) that comes out of the while loop to give you the list you want to print. By changing the location of the if statements you are able to adjust when the break can occur and when it reads from users input.
const readline = require('readline-sync');
var name, marks;
var studentList = [];
Input();
function printList(list) {
for (let i = 0; i < list.length; i += 1) {
console.log('list[i]', list[i]);
}
}
function Input()
{
while(true) {
console.log("Please enter the student name (or \"end\" to end): ");
name = readline.question("Student Name: ");
if (name === 'end') {
printList(studentList)
break
}
console.log("Student Name is" , name);
marks = readline.question("Enter marks for " + name + ": ");
if (marks === 'end') {
printList(studentList)
break
}
console.log("Marks for " + name + " is " + marks );
studentList.push([name, marks]);
}
}
I don't think you know how many students there are ahead of time, so you will need to loop until "end" is detected.
This might help:
const readline = require('readline-sync');
var name, marks;
var studentList = [];
Input();
function Input() {
while (true) {
console.log("Please enter the student name (or \"end\" to end): ");
name = readline.question("Student Name: ");
if (name === 'end') break;
console.log("Student Name is", name);
marks = readline.question("Enter marks for " + name + ": ");
console.log("Marks for " + name + " is " + marks);
studentList.push([name, marks]);
}
}
for (var i = 0; i <= studentList.Length; i++) {
console.log(studentList[i]);
}

Resetting InnerHTML

I've been looking at past submissions regarding this and haven't been able to find a solution that seems to work.
I have a simple form that calculates and then increments a value. The innerHTML output ("YourAmount") works fine the first time the form is submitted. However, if I resubmit the form with another amount, the original output flickers the old calculated results with the new one. How do I reset the innerHTML output?
Thanks!
// function for formatting numbers in currency format
function CurrencyFormatted(amount) {
var i = parseFloat(amount);
if (isNaN(i)) {
i = 0.00;
}
var minus = '';
if (i < 0) {
minus = '-';
}
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if (s.indexOf('.') < 0) {
s += '.00';
}
if (s.indexOf('.') == (s.length - 2)) {
s += '0';
}
s = minus + s;
s = CommaFormatted(s)
return s;
}
// function for formatting numbers with embedded commas
function CommaFormatted(amount) {
var delimiter = ","; // replace comma if desired
var a = amount.split('.', 2)
var d = a[1];
var i = parseInt(a[0]);
if (isNaN(i)) {
return '';
}
var minus = '';
if (i < 0) {
minus = '-';
}
i = Math.abs(i);
var n = new String(i);
var a = [];
while (n.length > 3) {
var nn = n.substr(n.length - 3);
a.unshift(nn);
n = n.substr(0, n.length - 3);
}
if (n.length > 0) {
a.unshift(n);
}
n = a.join(delimiter);
if (d.length < 1) {
amount = n;
} else {
amount = n + '.' + d;
}
amount = minus + amount;
return amount;
}
function calculate() {
var NumStores = document.getElementById('NumStores').value;
var result = document.getElementById('result');
var baseProfit = NumStores * 50.00;
result.value = baseProfit;
var baseProfitOverYear = baseProfit * 360; // base profit (stores x cost) over 360 days
var result2 = document.getElementById('result2');
result2.value = baseProfitOverYear;
var amount = baseProfitOverYear; // load from server
var delay = 1000; // milliseconds
var incAmount = 20; // change to the amount by which you wish to increment
var tId = setInterval(function() {
document.getElementById("YourAmount").innerHTML = "$" + CurrencyFormatted(amount += incAmount);
}, delay)
}
// disable enter key
$(document).keypress(
function(event) {
if (event.which == '13') {
event.preventDefault();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="thisForm">
<input id="NumStores" type="number" required />
<input type="button" onClick="calculate()" value="Calculate">
</form>
<br><br>
<p id="YourAmount">Your Amount Is 0</p>
First, you should create a span tag within the paragraph tag to hold the value. Then make sure you only have one interval occurring at a time.
// Document elements and variables
var numStores = document.getElementById('num-stores'),
result = document.getElementById('result-1'),
result2 = document.getElementById('result-2'),
yourAmount = document.getElementById('your-amount'),
intervalId = null; // We need to rember this...
// Constants
var profitMargin = 50.00,
numberOfDays = 360,
incAmount = 20, // change to the amount by which you wish to increment
timerDelay = 1000; // milliseconds
function calculate() {
var inputValue = numStores.value;
var baseProfit = inputValue * profitMargin;
var baseProfitOverYear = baseProfit * numberOfDays; // base profit (stores x cost) over 360 days
var amount = baseProfitOverYear; // load from server
result.value = baseProfit;
result2.value = baseProfitOverYear;
clearInterval(intervalId); // Clear the GLOBAL interval, before we start a new one.
intervalId = setInterval(function() {
yourAmount.innerHTML = "$" + CurrencyFormatted(amount += incAmount);
}, timerDelay);
}
// Disable enter key
$(document).keypress(function(event) {
if (event.which == '13') {
event.preventDefault();
}
});
// function for formatting numbers in currency format
function CurrencyFormatted(amount) {
var i = parseFloat(amount);
if (isNaN(i)) {
i = 0.00;
}
var minus = '';
if (i < 0) {
minus = '-';
}
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if (s.indexOf('.') < 0) {
s += '.00';
}
if (s.indexOf('.') == (s.length - 2)) {
s += '0';
}
s = minus + s;
s = CommaFormatted(s)
return s;
}
// function for formatting numbers with embedded commas
function CommaFormatted(amount) {
var delimiter = ","; // replace comma if desired
var a = amount.split('.', 2)
var d = a[1];
var i = parseInt(a[0]);
if (isNaN(i)) {
return '';
}
var minus = '';
if (i < 0) {
minus = '-';
}
i = Math.abs(i);
var n = new String(i);
var a = [];
while (n.length > 3) {
var nn = n.substr(n.length - 3);
a.unshift(nn);
n = n.substr(0, n.length - 3);
}
if (n.length > 0) {
a.unshift(n);
}
n = a.join(delimiter);
if (d.length < 1) {
amount = n;
} else {
amount = n + '.' + d;
}
amount = minus + amount;
return amount;
}
label { font-weight: bold; }
.input-field { display: block; }
.input-field label { display: inline-block; width: 7.667em;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="this-form">
<label>Number of Stores</label> <input id="num-stores" type="number" required />
<input type="button" onClick="calculate()" value="Calculate">
</form>
<br>
<p>Your amount is: <span id="your-amount">$0.00</span></p>
<div class="input-field"><label>Base Profit</label> <input type="text" id="result-1" /></div>
<div class="input-field"><label>Annual Profit</label> <input type="text" id="result-2" /></div>

more than currency input field

I have this input tag where you put the total of your receipt :
<input type="text" name="currency" id="currency" class="text-input" onBlur="this.value=formatCurrency(this.value);" />
The Javascript is as follows:
<script type="text/javascript">
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num)) {
num = "0";
}
sign = (num == (num = Math.abs(num)));
num = Math.floor(num*100+0.50000000001);
cents = num % 100;
num = Math.floor(num/100).toString();
if(cents < 10) {
cents = "0" + cents;
}
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++) {
num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));
}
return (((sign)?'':'-') + '$' + num + '.' + cents);
}
</script>
Users can only enter receipts more than $10.00 bucks, how can I set that on my script? Also they need to know they can not enter currency less than $10.
From what I can gather from your question I think you are looking for something like this. Basically if we have a valid entry such as $100.00 we continue, return true etc, else if we have something that looks like an int or float we can reformat this and recurse the function, else hint user for of vaild entry
var foo = document.getElementById('foo');
foo.addEventListener('blur', function(e) {
var val = e.target.value;
var err = document.getElementById('err');
var errMsg = 'please enter a value $10.00 or greater';
var patt = /^\$\d+\.\d{2}$/;
var amount = parseInt(val.replace(/\$|\./g, ''));
if (val !== '') {
if (patt.test(val)) {
if (amount < 1000) {
err.textContent = errMsg;
} else {
document.getElementById('suc')
.textContent = 'processing request';
}
} else if (typeof amount == 'number' && !/[a-z]/g.test(val)) {
if (/\.\d{2}/.test(val)) {
e.target.value = '$' + (amount / 100);
} else {
e.target.value = '$' + amount + '.00';
}
arguments.callee(e);
} else {
err.textContent = errMsg;
}
}
});
here is a demo
You can apply a validation function when submitting the form to test if the value is below a threshold, such as:
function validate()
{
value = document.getElementById('currency');
if (value <= 10.00)
{
return false
} else
{
return true;
}
}
You could also apply this to the onblur event, but my preference is to present validation errors when the form is submitted.
It looks like you're trying to parse a string, convert it nicely into dollars and cents, and reject it if it's less than 10. There's a much nicer way to do that:
function formatCurrency(num) {
// Remove the dollar sign
num = num.replace("$", "");
// Change the string to a float, and limit to 2 decimal places
num = parseFloat(num);
Math.round(num * 100) / 100;
// If its less than 10, reject it
if(num < 10) {
alert("Too small!");
return false;
}
// Return a nice string
return "$" + num;
}
At the end, are you trying to return -$99.94 if the number is negative?

Categories

Resources