Girl in need of javascript help and guidance. Pretty new to javascript

Pretty new to javascript, so bare with me.

http://imgur.com/a/lhMjS

So my friend gave me a format he done using C with a little instructions here and there, so I tried my best to translate it back to javascript, but its not working and I know there is something wrong with my code. Please don’t be too harsh with me as I am still learning and trying. I know my javascript crashed because I done something terribly wrong with it. =(

For the most part for me, its understanding what to write and how to get started.

I’m more comfortable with php but mostly doing forms and things like that. I;m not really good at math problems and out putting the data.

var single, married;

var userStatus = prompt("Are you Single or Married?");

 do {
    var UserIncome = prompt("Enter the income you received (W-2, Investments, 1099") 
    
    Total += useIncome;

    var moreIncome = prompt("Do you have any more additional income to add to your 1040 Tax Form?");
    }

    while (moreIncome === true)

    if(single) userIncome -= 6300(deduction1);
    if(married) userIncome =- 12600(deduction2);

do {
    var single = prompt("Enter your standard deduction for single status.");
    userIncome -= deduction1

    
    var married = prompt("Enter your standard deduction for married status?");
    userIncome -= deduction2
}

    if (userIncome < 9275) userIncome * 0.10;
    }
                         
    else if {
        (userIncome > 37650) userIncome * 0.15; 
    }
    
    else if {
        (userIncome > 91150) userIncome * 0.25; 
    }
                            
    else if 
        (userIncome < 190150) userIncome * 0.28;
    }
                         
    else if {
        (userIncome < 413350) userIncome * 0.33; 
    }
    
    else if {
        (userIncome < 415050) userIncome * 0.35; 
    } 
                            
    else {
        (userIncome > 415050) userIncome * 0.396; 
    } 

    if (userIncome < 18550) userIncome * 0.10;
    }
                         
    else if {
        (userIncome > 75300) userIncome * 0.15; 
    }
    
    else if {
        (userIncome > 151900) userIncome * 0.25; 
    }
                            
    else if 
        (userIncome < 231450) userIncome * 0.28;
    }
                         
    else if {
        (userIncome < 413350) userIncome * 0.33; 
    }
    
    else if {
        (userIncome < 466950) userIncome * 0.35; 
    } 
                            
    else {
        (userIncome > 466950) userIncome * 0.396; 
    }

Before someone resolves your problem, I would like to point
out that you have just invited members to disrobe with you. :mask:

This may well be a pleasant experience in warmer climes. :sunglasses:

But in less temperate parts… :scream:

coothead

4 Likes

Hi @aznsmile, the most important tool to debug JS is the console panel – you’ll find it in the dev tools of your browser. Syntax and reference errors like odd braces and working on undefined variables will quickly become apparent. So first of all you should fix your code one by one until the console doesn’t yield any errors any more; then post your revised code, and we can help you with the logic.

Oh, and welcome to the JavaScript side. :-)

1 Like

@m3g4p0p Thank you for the warm welcome =)

I went back and check my code and tried to strip out the codes where it failed and crashed. After entering the data from the prompt commands, it becomes blank.

http://hills.ccsf.edu/~schow11/cnit133m/practice.html

var userIncome, totalIncome;

var userStatus = prompt("Are you Single or Married?");

 do {
    var UserIncome = prompt("Enter the income you received (W-2, Investments, 1099");
    
    totalIncome += userIncome;

    var moreIncome = prompt("Do you have any more additional income to add to your 1040 Tax Form?");
    }

    while (moreIncome === true) {

    if(moreIncome -= 6300);
    if(moreIncome -= 12600);
    }

First thing is to forget about using prompt() - its use for collecting data ended with Netscape 4 and it was repurposed for debugging - that use became obsolete when the console.log command was introduced.

Use a form for collecting input from the user. You then attach an eventlistener to the submit event on the form to run the JavaScript processing.

She may have to find a new school in that case, for this prompt technique seems to be endemic to some learning institutions.

It depends on whether she is taking the class to learn JavaScript (in which case a new school would be required) or if the subject is one in a larger course that she just needs to pass (in which case she needs to understand that she is taking a JavaScript history class for Netscape 4 and that it isn’t teaching her how to write JavaScript for more modern browsers like IE5).

1 Like

Interesting… could you explain how to use console.log to collect input from the user? Purely for debugging purposes, of course.

2 Likes

Let’s use jsfiddle.net with the OP (original post) code. Using the tidy feature allows us to fix the indenting, which helps us to understand the code better.

The first issue is with single/married - how is userStatus going to be translated in to true/false for single/married?

One suggestion is to use a separate while loop for the prompt, so that you can keep asking until a correct answer is given.

The two separate variables are not be required at all either, for you can just check for one of them and use the else clause for the other. Because the code does single stuff before married, single can be the status that we store.

var single = null;
var userStatus = "";
do {
  userStatus = prompt("Are you Single or Married?");
  userStatus = userStatus.toLowerCase();
  if (userStatus === "single" || userStatus === "married") {
    married = (userStatus === "single");
  } else {
    alert("Please enter single or married as your answer.");
  }
} while (single = null);

For semicolon warriors, please note that the while part of a do-while loop also ends with a semicolon.
Also, variables should only be at the top of a code section like a function, so I’m moving variable declarations to the top for easier management.

Variable names should start with a lowercase letter, as an initial uppercase letter normally indicates that it’s a constructor function instead. The Total and UserIncome variables really should be total and userIncome instead.
Also, as you’ve use userIncome elsewhere I think that you should assign total to useIncome after the loop completes.

The do/while loop is also easier to understand when the while clause is connected up with the closing brace.

Also, the prompt results in a string result, so that while (moreIncome === true) condition is never going to end. The prompt though does give null when cancel is chosen, so you can just check for a truthy or falsy value instead.

By way of example null, undefined, false, 0, and “” are all falsey values. Beware though, for “0” and “false” as strings are considered to be a truthy value, not falsy ones.

do {
  var UserIncome = prompt("Enter the income you received (W-2, Investments, 1099")
  total += useIncome;
  var moreIncome = prompt("Do you have any more additional income to add to your 1040 Tax Form?");
} while (moreIncome);

Because the code carries on to use userIncome, I recommend that those further ones are not changed to total, and instead that the total from the do/while loop is used to replace the last userIncome value.

do {
    ...
} while (moreIncome);
userIncome = total;

With the single/married deductions, it can help to decide how you want to group the code. Do you want all of the single stuff happening, with the married stuff occurring in the else clause?

if (single) {
    // single stuff
    // more single stuff
} else {
    // married stuff
    // more married stuff
}

Or do you want to separate them out so that each thing happens separately?

if (single) {
    // single stuff
} else {
    // married stuff
}
if (single) {
    // more single stuff
} else {
    // more married stuff
}

I’ll go with the latter structure for this example.

The single/married deduction prompt doesn’t seem to make any sense, because you already know if they are married. As a result, you can do without the prompt and take care of it immediately.

if (single) {
  userIncome -= 6300;
} else {
  userIncome -= 12600;
}

With the series of if/else if statements, it can really help to keep the braces properly lined up, to ensure that everything is organised correctly. It can also help to keep the single and married parts separate.

In fact, by putting the single and married tax rates in to separate functions, that can help the code to be easier to understand too.

Here’s the singleTax function for example:

function singleTax(userIncome) {
  if (userIncome < 9275) {
    tax = userIncome * 0.10;
  } else if (userIncome < 37650) {
    tax = userIncome * 0.15;
  } else if (userIncome < 91150) {
    tax = userIncome * 0.25;
  } else if (userIncome < 190150) {
    tax = userIncome * 0.28;
  } else if (userIncome < 413350) {
    tax = userIncome * 0.33;
  } else if (userIncome < 415050) {
    tax = userIncome * 0.35;
  } else {
    tax = userIncome * 0.396;
  }
  return tax;
}

Which along with a marriedTax function, results in code that ends up just being:

if (single) {
  tax = singleTax(userIncome);
} else {
  tax = marriedTax(userIncome);
}

You could then work on making the function easier to work with, such as by having a list of tax rates where you search through them until you come to a value that’s greater than the user’s income.

function singleTax(userIncome) {
  var rates = [
    {tax: 0.10, amount: 9275},
    {tax: 0.15, amount: 37650},
    {tax: 0.25, amount: 91150},
    {tax: 0.28, amount: 190150},
    {tax: 0.33, amount: 413350},
    {tax: 0.35, amount: 415050},
    {tax: 0.396, amount: Number.MAX_VALUE}
  ];
  var taxRate = 0;
  rates.find(function (rate) {
    if (amount < userIncome) {
      taxRate = rate.tax;
    } else {
      return true;
    }
  });
  return userIncome * taxRate;
}

We can now see that the singleTax and marriedTax functions are near identical, all but for the rates themself, so that logic we can move on out to a separate findTaxRate() function instead:

function findTaxRate(rates, userIncome) {
  var taxRate = 0;
  rates.find(function (rate) {
    if (amount < userIncome) {
      taxRate = rate.tax;
    } else {
      return true;
    }
  });
  return taxRate;
}

Also, the tax rates shouldn’t be inside of the function. That’s data that can be stored elsewhere and given to the function instead.

var taxRates = {
  single: [
    {tax: 0.10, amount: 9275},
    {tax: 0.15, amount: 37650},
    {tax: 0.25, amount: 91150},
    {tax: 0.28, amount: 190150},
    {tax: 0.33, amount: 413350},
    {tax: 0.35, amount: 415050},
    {tax: 0.396, amount: Number.MAX_VALUE}
  ],
  married: [
    {tax: 0.10, amount: 18550},
    {tax: 0.15, amount: 75300},
    {tax: 0.25, amount: 151900},
    {tax: 0.28, amount: 231450},
    {tax: 0.33, amount: 413350},
    {tax: 0.35, amount: 466950},
    {tax: 0.396, amount: Number.MAX_VALUE}
  ]
};

So now we can get the appropriate tax rates with taxRates.single, which leaves our singleTax() and ‘marriedTax()’ functions looking identical to each other:

function singleTax(rates, userIncome) {
  return userIncome * findTaxRate(rates, userIncome);
}
function marriedTax(rates, userIncome) {
  return userIncome * findTaxRate(rates, userIncome);
}
...
if (single) {
  tax = singleTax(taxRates.single, userIncome);
} else {
  tax = marriedTax(taxRates.married, userIncome);
}

It’s not a loss though, for they have helped us to extract out useful behaviour. We cannot allow these two identical functions to remain though, so they can be combined in to a single function called getTax()

function getTax(rates, userIncome) {
  return userIncome * findTaxRate(rates, userIncome);
}
...
if (single) {
  tax = getTax(taxRates.single, userIncome);
} else {
  tax = getTax(taxRates.married, userIncome);
}

let us now look at the variables that we have floating around the place:

var single = null;
var userStatus = "";
var userIncome = 0;
var moreIncome = 0;
var total = 0;
var tax = 0;

That’s a lot. We need single, and we need userIncome, and possibly even tax, but the others can be removed by moving their sections of code out to separate functions.

Asking for the marital status, that can be moved in to an askMaritalStatus() function:

function askMaritalStatus() {
  var userStatus = "";
  do {
    userStatus = prompt("Are you Single or Married?");
    userStatus = userStatus.toLowerCase();
    if (userStatus === "single" || userStatus === "married") {
      return (userStatus === "single");
    } else {
      alert("Please enter single or married as your answer.");
    }
  } while (single = null);
}
...
single = askMaritalStatus();

When asking for the user income, we can put that all in to its own askUserIncome() function:

function askUserIncome() {
  var userIncome = 0;
  var total = 0;
  var moreIncome;
  do {
    userIncome = prompt("Enter the income you received (W-2, Investments, 1099");
    total += userIncome;
    moreIncome = prompt("Do you have any more additional income to add to your 1040 Tax Form?");
  } while (moreIncome);
  return total;
}
...
userIncome = askUserIncome();

The improvements can keep on occuring from there, but this is just a taste of how such improvements can be made.

The code after all of these improvements can be found at https://jsfiddle.net/qokphgqh/2/ and is as follows:

function askMaritalStatus() {
  var userStatus = "";
  do {
    userStatus = prompt("Are you Single or Married?");
    userStatus = userStatus.toLowerCase();
    if (userStatus === "single" || userStatus === "married") {
      return (userStatus === "single");
    } else {
      alert("Please enter single or married as your answer.");
    }
  } while (single = null);
}

function askUserIncome() {
  var userIncome = 0;
  var total = 0;
  var moreIncome;
  do {
    userIncome = prompt("Enter the income you received (W-2, Investments, 1099");
    total += userIncome;
    moreIncome = prompt("Do you have any more additional income to add to your 1040 Tax Form?");
  } while (moreIncome);
  return total;
}

function findTaxRate(rates, userIncome) {
  var taxRate = 0;
  rates.find(function (rate) {
    if (amount < userIncome) {
      taxRate = rate.tax;
    } else {
      return true;
    }
  });
  return taxRate;
}
function getTax(rates, userIncome) {
  return userIncome * findTaxRate(rates, userIncome);
}

var single;
var userIncome = 0;
var tax = 0;
var taxRates = {
  single: [
    {tax: 0.10, amount: 9275},
    {tax: 0.15, amount: 37650},
    {tax: 0.25, amount: 91150},
    {tax: 0.28, amount: 190150},
    {tax: 0.33, amount: 413350},
    {tax: 0.35, amount: 415050},
    {tax: 0.396, amount: Number.MAX_VALUE}
  ],
  married: [
    {tax: 0.10, amount: 18550},
    {tax: 0.15, amount: 75300},
    {tax: 0.25, amount: 151900},
    {tax: 0.28, amount: 231450},
    {tax: 0.33, amount: 413350},
    {tax: 0.35, amount: 466950},
    {tax: 0.396, amount: Number.MAX_VALUE}
  ]
};

single = askMaritalStatus();
userIncome = askUserIncome();
if (single) {
  userIncome -= 6300;
} else {
  userIncome -= 12600;
}

if (single) {
  tax = getTax(taxRates.single, userIncome);
} else {
  tax = getTax(taxRates.married, userIncome);
}
5 Likes

You don’t use console.log for collecting info - for debugging purposes you’d set a breakpoint and use the developer console to change the appropriate values.

For real user input you’d use a form.

No need for prompt in either case - I used to always click the “stop executing scripts in this page” checkbox in prompts before I changed my browser settings to just turn off prompts completely.

While it’s admirable that you are wanting to improve how that’s done, the link provided to us earlier is from the City College of San Francisco. It is their curriculum that you are going up against.

By the looks of the colleges Web Development Credit Courses i.e.
https://www.ccsf.edu/en/educational-programs/school-and-departments/school-of-business/business-department/web-development.html

MABS 406 Developing Web Sites - Dreamweaver (3 units)
MABS 407 Developing Web Sites - Expression Web (3 units)

I get the feeling they are more interested in teaching the use of specific tools for RAD than they are in teaching best practice.

Not that sacrificing best practice in the name of pragmatism is a bad thing. Just that I don’t need to worry about ROI and I consider best practice to be a tenet of my personal definition of professionalism.

to be the best way of creating easily maintainable code. Anything less will cost more long term in making maintaining the code much more difficult.

Prompt is perfectly fine. It’s not being abused here for debugging. It’s being used to collect user input, which is exactly what prompt was designed to do.

1 Like

so why does it display debugging options in some browsers - eg the image I posted earlier in this thread?

It really ought to be removed from the language as it doesn’t have any real use any more - even IE5 didn’t need it for collecting user input. Still it is easy enough to turn it off in the browser so that it effectively no longer exists when you are viewing pages (as I have done for all the debugging dialogs so as to skip over them when people accidentally leave them in their live script).

If you want a proper dialog for user input you should create your own or use one of the scripts others have created for the purpose such as sweetalert. These give you full control over how the dialog looks rather than displaying debugging links - plus they are not disabled when someone turns off the built in debugging ones.

alert and prompt have the advantages that they halt execution, which is sometimes handy.

But anyway, I really wish you would stop dragging threads off topic with this standard rant of yours. It’s really not very constructive.

4 Likes

Are you meaning the tick box to stop executing scripts? That’s a safety precaution against malicious websites. It’s not solely for debugging purposes.

Hi Paul,

Thanks for explanation and help. Is there another way to do this without using the prompt?

Like making a form instead of the prompt key? Is this still being used? I was looking at some online tutorial and they used the prompt key.

http://hills.ccsf.edu/~schow11/cnit133m/practice.html

So here’s the final one. Is it suppose to show a blank page after inputting the additional income?

Can you use forms like radio buttons to choose married or single and use something kind of like this to calculate the income?

http://hills.ccsf.edu/~schow11/CNIT133/hw4/hw4part2.html

it’s not displaying the total.

Regarding alert for debugging, if you do decide to use it instead of console.log, be very careful to not use it in loops. eg.

some_array_length  = some_array.length;
for (var i = 0; i < some_array_length; i++) {
  alert{" i is " + i);
}

might not be so bad for small arrays, but there will be an alert to close for each time it loops unless you close the browser down to stop them.

If you do this instead

some_array_length  = some_array.length;
for (var i = 0; i < some_array_length; i++) {
  console.log{" i is " + i);
}

it might fill up your dev tool console, but you’ll be happy you didn’t alert instead.