I am attempting to have someone input there credit card number and validate if it is a valid number by doing the Luhn Check. I want to be able to check it if they input the whole card number as one big string or if they put spaces in it. In my function validate though I keep getting an error message that there is an illegal return statement for my total variable. Here is my current code.
<script type="text/javascript">
function validate(numbers) {
var sum;
var sum1;
var total;
for (i = 0; i < numbers.length; i++) {
if (numbers.length % 2 == 0) {
sum += numbers[i];
}
else
if ((numbers[i] * 2) >= 10) {
sum1 += numbers[i] - 9;
}
else
sum1 += numbers[i];
}
total = sum + sum1;
return total;
}
function cardnumber() {
var cardnumber = document.getElementById("input").value;
var numbers = cardnumber.split(" ");
var out = "";
for (i = 0; i < numbers.length; i++) {
out += validate(numbers[i]);
if (out % 10 == 0)
return true;
}
}
function getOutput() {
if (cardnumber()) {
alert("You card is valid.");
}
}
</script>
<body>
<h1>I will validate a credit card number</h1>
Card Type:
<input type="radio" id="c1" value="Visa">Visa</input>
Card number: <textarea id="input" style="vertical-align: middle;"></textarea></br>
<input type="button" value="Submit" onclick="getOutput()" /></br></br>
</body>
Your function validate is missing an opening curly brace after the for loop. This made your return statement outside of your function and since a return statement is invalid outside of a function it was an invalid return statement.
function validate(numbers){
var sum;
var sum1;
var total;
for (i=0; i<numbers.length; i++) { // this previous curly brace `{` was missing
if (numbers.length%2==0){
sum += numbers[i];
}
else
if ((numbers[i]*2)>=10){
sum1 += numbers[i] -9;
}
else
sum1 +=numbers[i];
}
total = sum + sum1;
return total;
}
EDIT WITH MORE CORRECTIONS:
There is quite a bit more wrong with the formatting of you functions you also need to include opening and closing curly braces around your other else statements. I would suggest getting a code editor like VS Code and downloading an extension similar to Bracket pair colorizer 2. It will highlight paired brackets together. This will help you with your formatting.
function validate(numbers){
var sum;
var sum1;
var total;
for (i=0; i<numbers.length; i++) {
if (numbers.length%2==0){
sum += numbers[i];
}
else {
if ((numbers[i] * 2) >= 10) {
sum1 += numbers[i] - 9;
}
else {
sum1 += numbers[i];
}
}
}
total = sum + sum1;
return total;
}
function cardnumber(){
var cardnumber= document.getElementById("input").value;
var numbers = cardnumber.split(" ");
var out ="";
for (i = 0; i < numbers.length; i++) {
out += validate(numbers[i]);
}
if (out %10==0)
return true;
}
function getOutput() {
if (cardnumber()) {
alert("You card is valid.");
}
}
These are all the changed lines (the left is new code and the right side is the old code):
Tips for completion
validate function
So, currently if you console.log your numbers are strings when they pass into the validate function. This is fine when they are sent into validate, but when you add the numbers at index i (i.e. numbers[i]) you should use parseInt(numbers[i], 10) to turn them into numbers, so for example sum += parseInt(numbers[i], 10); the same applies when adding to sum1. The other thing to note is that saying var sum will make sum equal the undefined value. When you add a number or string to an undefined value some unexpected things will probably happen, so since you need your sums and totals to be numbers you should instead initialize your sums and totals at 0. Like so:
var sum = 0;
var sum1 = 0;
var total = 0;
The only other thing wrong with your validate function is that your are checking if numbers.length%2==0 which instead you should be checking if i%2==0. You may have to think about why for a moment, but one thing you may notice is the length of numbers never changes during the iteration of the loop where as i does change at each step.
cardnumber function
Your out variable needs to be initialized to zero. Your cardnumber can instead be split by spaces and then joined by the empty string. This handles if the user accidentally types multiple spaces. Then since you join your split array you no longer would need a for loop.
var numbers = cardnumber.split(" ").join('');
var out =0;
out += validate(numbers);
Lines that need changing somehow
Here's a difference of the lines of the old code that where incorrect and need to be changed somehow. I'm not giving you the completed code, but hopefully this will be sufficient to help you figure out the rest on your own (I feel I shouldn't give you all of the solution due to some degree of academic integrity. I would feel I robbed you the opportunity to learn more if I don't at least let you think through and type it out on your own.). If you are wondering what needs to be changed on a specific line that is highlighted red all of it should be above, so best of luck.
Related
I suggest u look at this picture, and then u look at the code I have written:
function addNumbers() {
var splitted = document.getElementById("listInput").value.split(" ");
for(i = 0; i <= splitted.length; i+=1) {
document.getElementById("resultNumberTotal").value = splitted[i];
}
}
I am taking the value from the box which says "Enter list of numbers and/or words" and I am splitting it. I split it so I have all the numbers like this "1 2 3" and so I can add them. I use the for loop for that. The for loop goes through every number and then it adds it. But when I press the button, it shows me undefined.
Why am I getting undefined?
function addNumbers() {
var splitted = document.getElementById("listInput").value.split(" ");
//make sure that the values are in a number format
document.getElementById("resultNumberTotal").value = splitted.reduce(function(a, b) {return Number(a) + Number(b);}, 0)
}
for the best practice make sure that allow number only for the input fields :) good luck
You need to somehow add the numbers up, either using the += operator, or by using something like .reduce() as I have done below.
function addNumbers() {
var val = document.getElementById("listInput").value;
document.getElementById("resultNumberTotal").value = val.split(" ").reduce(function(runningTotal, currentArrayElement) {
// make sure the value they typed is a number
// if not, fail gracefully and simply ignore it
if (!isNaN(Number(currentArrayElement))) {
// if it is a number, add it to the running total
runningTotal+= Number(currentArrayElement);
}
return runningTotal; // return the running total
}, 0); // start with 0 as the initial value for runningTotal
}
<input type="text" id="listInput" placeholder="insert values here..." style="width: 300px;" />
<button onclick="addNumbers()">Add Numbers</button>
<br/>
<br/>
<hr/>
Number Total: <input id="resultNumberTotal"/>
You are getting undefined, because you are displaying the value of the last element of the array and not doing the Sum as you mentioned in the question.
Following code always overrides the value of resultNumberTotal by the value of splitted[i]. Since, your for loop iterates for i <= splitted.length it reaches the index which doesn't exist in the array, when you get a property which doesn't exist on an object, you get undefined
for(i = 0; i < splitted.length; i+=1) {
document.getElementById("resultNumberTotal").value = splitted[i];
}
So, for doing the sum, you need to make the code like
function addNumbers() {
var splitted = document.getElementById("listInput").value.split(" ");
var total = 0;
for(i = 0; i < splitted.length; i++) {
var numberValue = +splitted[i];
if(!isNaN(numberValue)){
total = total + numberValue ;
}
}
document.getElementById("resultNumberTotal").value = total;
}
I am stuck on a problem. I want to print the index of an array which differs from other elements of that array in evenness. To be more specific the input would be like 5 even numbers and 1 odd number. So print the position(index+1) of odd number.
My code
function Test(numbers){
var e = 0; //number of even numbers
var o = 0; //number of odd numbers
console.log(numbers.length);
for(var i = 0; i < numbers.length; i++){
if(numbers[i] % 2 == 0){
e++;
var pose = i; //index of even no
}
else{
o++
var poso = i; //index of odd number
}
}
if(e==1){ //only one even number
console.log(pose+1);
}
else if(o==1){ //only one odd number
console.log(poso+1);
}
else{
console.log("no number differs");
}
}
Test("2 4 7 8 6");
Expected output = '3';
The console prints :
"no number differs".
I have debugged and I found the problem. The console.log(numbers.length); is printing 9. That is it is including blank spaces as well. Same if we put comma ',' in between the numbers. Also if there is a two digit number it treats them as 2 separate elements.
Now I know that i can add code at the beginning to check if i=1,3,5... to break the loop but I would like to know if there is a better solution. Also if the solution is passing array in different format I would like to know how can we correct the code if we want to pass as above.
Pass an array as an argument like below.
function Test(numbers){
var e = 0; //number of even numbers
var o = 0; //number of odd numbers
console.log(numbers.length);
for(var i = 0; i < numbers.length; i++){
if(numbers[i] % 2 == 0){
e++;
var pose = i; //index of even no
}
else{
o++
var poso = i; //index of odd number
}
}
if(e==1){ //only one even number
console.log(pose+1);
}
else if(o==1){ //only one odd number
console.log(poso+1);
}
else{
console.log("no number differs");
}
}
var x = [2,4,7,8,6];
Test(x);
Your Program is absolutely fine.
I guess the problem is with how you are passing data to your function Test.
You are passing a string instead of array.
it should be like:
Test([2,4,7,8,6]);
Also If you want to pass it as string just make sure you split the String with ',' comma and make an array of the numbers and then feed it to your for loop.
In your code you are passing the argument as a string, but I guess you may need to pass an array.
If it is so then you can look into array#forEach method
Hope this snippet will be useful
function Test(numbers) {
// looping through the array
numbers.forEach(function(item, index) {
//checking if it is odd or even
if (item % 2 == 0) {
console.log("current number is Even & its index is " + index);
} else {
//updating index
var modIndex = index+1;
console.log("current number is Odd & its modified index is " + modIndex);
}
})
}
var num = ['2','4','7','8','6']
Test(num);
DEMO
my objective is to use recursion to get sigma notation working. top limit is n(input variable) bottom limit is i=1, and the function is (-i)^(i-1). i got it working with iteration but i cant get the recursion to work.
<!DOCTYPE html>
<head><title>Recursion</title></head>
<body>
<h1>Recursion</h1>
<script = "text/javascript">
var num
var i;
var n;
var total;
total = 0;
i=0;
var b;
b=0;
function formula(n)
{
(Math.pow((-i),(i-1)))
}
function recursion(n)
{
i=i+1;
if ((n-i) == 0)
{
document.writeln("done");
}
else
{
total = total + recursion(formula(n-i));
return total;
//total = total + (Math.pow((-i),(i-1)) + recursion(n-i));
}
}
num = window.prompt("pick a number");
recursion(num);
document.writeln(recursion(num));
//document.writeln(total);
</script>
</body>
</html>
Please avoid any global variables, that makes it very hard to read. Also, indent your code properly; and don't mix the output (document.write) into the computation. If you don't understand the recursion, just use a loop:
var total = 0;
for (var i=1; i<=n; i++)
total += formula(i);
return total; // the result
The same thing, done with recursion:
function sumFormulaUpTo (n) {
if (n <= 0) // the abort condition
return 0;
else
return sumFormulaUpTo(n-1) + formula(n);
}
sumFormulaUpTo(100);
You notice: there is no total variable, only the result of the recursively called function is used.
With an end recursion (more like the loop), it would look like this:
function sumFormulaFromTo(total, i, n) {
if ( i > n )
return total;
else {
var newtotal = total + formula(i);
return sumFormulaFromTo(newtotal, i+1, n);
}
}
sumFormulaFromTo(0, 1, 100);
If you had total and n declared statically outside the function, it would look more like yours. Yet, you forgot to return the result once the end condition is met (you just output something, but return undefined), and you somehow called the recursion with the result of formula - no idea where you got that from. This causes an infinite loop, according to #cbayram.
function averageCalculator (numvalues) {
for(i=0, i <= numvalues, i++>) {
var score = prompt("input the score")
result1 += score;
}
alert(result1 / 3);
}
this function is later triggered by a button with onclick="averageCalculator (2)
<input type="button" value="Click for the average" onclick="averageCalculator (2)">
any ideas why its not working? it should prompt you for 2 values and then alert you with the average. not sure whats wrong.
Your code has multiple issues. The for loop is not well formatted and you need to terminate statements with a semi-colon. Also you need to declare variables. And your loop will run numvalues+1 times which is why i removed the = in your loop. Also if you want to calculate an average you want to divide by numvalues.
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += score;
}
alert(result1 / numvalues);
}
On top of the invalid syntax you will run into a common "problem" with javascript here. The inputs are treated as strings and instead of being added they will be concatenated. Providing 2 and 2 as scores will result in 11. 2 concatenated with 2 = 22 / 2 = 11. You need to cast the value to a number explicitly before adding them together:
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += Number(score);
}
alert(result1 / numvalues);
}
Above code will correctly return 2
The syntax of your for-loop is wrong:
for(i=0, i <= numvalues, i++>) {
should be
for(i=0; i <= numvalues; i++) {
Tip: Also, it's better to use
for(var i=0; i <= numvalues; i++) {
since then i will be a local variable instead of a global one.
Try like this
for(var i=0; i <= numvalues; i++){}
An alternative solution (using a functional programming libary, like Underscore.js):
function averageCalculator(numValues) {
var numbers = _.map(_.range(numValues), function(element) {
return +prompt('input the score');
});
var result = _.reduce(numbers, function(memo, number) {
return memo + number;
}, memo);
alert(result / 3);
}
While a little bit more complicated (and less efficient), you'll get rid of loops altogether.
EDIT
The +prompt('input the score') does effectivly the same as Number(prompt('input the score')).
I have developed this code with help from you guys here on stackoverflow. I have added an extra part to it where it compares two numbers from two different arrays, in this case offhire1 and pro2.
The problem is in my code where I have:
(offhire1[i].value > pro2[i].value)
It only allows me to contine if the numbers match i.e 100=100. But what I'm after is identifing any numbers that are greater than the value only 120 > 100. I have tested if the values are being passed and they are.
What is my mistake here can anyone suss it out.
function validateoffhire(form) {
var num1 = document.getElementById('num1');
var test2Regex = /^[0-9 ]+(([\,\.\- ][a-zA-Z ])?[a-zA-Z]*)*$/;
var accumulator = 0;
var num2 = num1.value;
var i=0;
var offhire1 = [];
var pro2 =[];
for(var i = 0; i < num2; i++) {
offhire1[i] = document.getElementById('offhire1' + i);
pro2[i] = document.getElementById('pro2' + i);
var offhire2 = offhire1[i].value;
// var pro3 = pro2[i].value;
if(!offhire2.match(test2Regex)){
inlineMsg('offhire1' + i,'This needs to be an integer',10);
return false;
}
else if (offhire1[i].value > pro2[i].value) {
alert("You entered: " + pro2[i].value)
inlineMsg('offhire1' + i,'You have off hired to many items',10);
return false;
}
else{
accumulator += parseInt(offhire2);
}
}
if(accumulator <= 0){
inlineMsg('num1' ,'You have not off Hired any items',10);
return false;
}
return true;
}
I'm not quite sure I follow you. If the numbers are the same, the statement won't match.
One issue in your code is that you're comparing strings, not numbers. You may want to change it to:
(parseInt(offhire1[i].value) > parseInt(pro2[i].value))