I'm having trouble getting a letter grade from my JavaScript code

I created a JavaScript function that should display a letter grade once the average of 5 subjects is calculated, but for some reason, it's not working as expected. I'm feeling quite lost at the moment.

The fourth function I implemented isn't generating any letter grades. Apart from this issue, I believe everything else in my code is correct.

function getHandleValue(idName) {
  const value = parseInt(document.getElementById(idName).value);
  console.log(value);
  return value;
}

function getTotal() {
  //console.log("app js starts loading")
  let english = getHandleValue('english');
  let math = getHandleValue('math');
  let physics = getHandleValue('physics');
  let computer = getHandleValue('computer');
  let science = getHandleValue('science');
  //console.log("app js ends loading")
  let total = english + math + physics + computer + science;
  document.getElementById('total').innerHTML = total;
  return total;

}

function getAverage() {
  // option  1
  // const total = parseInt(document.getElementById('total').innerHTML);
  // const average = total / 5;
  // document.getElementById('average').innerHTML = average;

  // option 2
  const average = getTotal() / 5;
  document.getElementById('average').innerHTML = average;
}

function letterGrade() {
  letterGrade;
  if (grade >= 90 && grade <= 100)
    letterGrade = 'A';

  else if (grade >= 80 && grade <= 89)
    letterGrade = 'B';

  else if (grade >= 70 && grade <= 79)
    letterGrade = 'C';

  else if (grade >= 60 && grade <= 69)
    letterGrade = 'D';

  else if (grade > 1 && grade <= 59)
    letterGrade = 'F';

  let average = letterGrade;
  document.getElementById('Grade').innerHTML = Grade;
}

Answer №1

The declaration of the variable letterGrade is incorrect, please use the following code:

let letterGrade = ' '

This line properly declares the letterGrade variable.

Answer №2

You need to define the lettergrade variable first. Simply replace letterGrade; with let letterGrade;

Once you make this change, your code will appear like this:

function getHandleValue(idName) {
  const value = parseInt(document.getElementById(idName).value);
  console.log(value);
  return value;
}

function getTotal() {
  let english = getHandleValue('english');
  let math = getHandleValue('math');
  let physics = getHandleValue('physics');
  let computer = getHandleValue('computer');
  let science = getHandleValue('science');
  
  let total = english + math + physics + computer + science;
  document.getElementById('total').innerHTML = total;
  return total;

}

function getAverage() {
  const average = getTotal() / 5;
  document.getElementById('average').innerHTML = average;
}

function letterGrade() {
  let letterGrade;
  if (grade >= 90 && grade <= 100)
    letterGrade = 'A';

  else if (grade >= 80 && grade <= 89)
    letterGrade = 'B';

  else if (grade >= 70 && grade <= 79)
    letterGrade = 'C';

  else if (grade >= 60 && grade <= 69)
    letterGrade = 'D';

  else if (grade > 1 && grade <= 59)
    letterGrade = 'F';

  let average = letterGrade;
  document.getElementById('Grade').innerHTML = Grade;
}

Answer №3

Challenges

After reviewing comments and responses, it appears that the function letterGrade() is using an incorrect variable, Grade, which is undefined. Additionally, the variable grade is not defined, passed as a parameter, or within scope. The breakdown of letterGrade() can be found in Figure I.

Figure I


function letterGrade() {
  /**
   * ISSUE 1 * Naming a Variable
   * Do not name a variable with the same name as the function in which it 
   * resides within
   * ISSUE 2 * Declaring or Defining a Variable
   * Use identifier var (not recommended), let, or const
   *   ex. let letter;
   */
  letterGrade; 
  /**
   * ISSUE 3 * Declaring or Defining Variables
   * grade isn't declared
   *   ex. let grade;
   * grade isn't defined
   *   ex. let grade = 0;
   * grade isn't a parameter
   *   ex. function letterGrade(grade) {...
   * grade isn't within scope
   *   ex. let grade = 0;
   *       function letterGrade() {...
   */
  if (grade >= 90 && grade <= 100)
    letterGrade = 'A';

  else if (grade >= 80 && grade <= 89)
    letterGrade = 'B';

  else if (grade >= 70 && grade <= 79)
    letterGrade = 'C';

  else if (grade >= 60 && grade <= 69)
    letterGrade = 'D';

  else if (grade > 1 && grade <= 59)
    letterGrade = 'F';
  
  /**
   * ISSUE 4 * Passing by Value
   * average is never used. If average is a reference to the value calculated 
   * by function getAverage(), then...
   *   - getAverage() should return that value, 
   *   - then that value must be defined outside of getAverage() 
   *   - or passed as a parameter of letterGrade() (recommennded).
   *     ex. ..::OUTSIDE OF letterGrade()::..
   *         function getAverage() {
   *           ...
   *           return average;
   *         }
   *         // Option A
   *         let average = getAverage()
   *         letterGrade(average)
   *         // Option B (recommended)
   *         letterGrade(getAverage)
   *
   *         ..::INSIDE OF letterGrade()::..
   *         function letterGrade(average) {
   *           let grade = typeof average === "number" ? grade : 0;
   *           ...
   *         }
   * Even if average was to be used, it would be useless as the value of
   * letterGrade, there's no point in reassigning it to another variable
   * unless it's to create a copy of another variable declared or defined 
   * outside of the function. 
   */
  let average = letterGrade;
  /**
   * ISSUE 5 * Defining or Declaring Variables
   * Grade variable has the same problem as ISSUE 3
   */
  document.getElementById('Grade').innerHTML = Grade;
}

Solutions

Here are two examples (Example A and Example B) that require understanding certain methods, properties, events, and techniques. Refer to the Appendix at the end of this response for detailed explanations. Both examples include step-by-step instructions within the source code.

Example A

Example A showcases a working example featuring:

  • a <form> tag
  • an
    <input type="range">
  • two <output> tags
  • an event handler getGrade(e)
  • a functional letterGrade(score)

Note the logical flow control pattern in Example A:

if (CONDITION) return LETTER;
if (CONDITION) return LETTER;
if (CONDITION) return LETTER;
if (CONDITION) return LETTER;
if (CONDITION) return LETTER;
return "";

The concept of short-circuiting is employed where once a condition is met, the corresponding action is taken, and the function terminates without executing further.

Example B

Example B encompasses:

  • a <form>
  • five
    <input type="number">
  • two <output>
  • an event handler calc(e)
  • a concise version of letterGrade(avg) utilizing ternary expressions

Appendix

Answer №4

REMARKS

  • This serves as a complete illustration of how you can compute grades in a universal manner without relying on identifiers for each subject input.
  • By structuring it this way, additional subjects can be included without altering the calculation process.
  • If a subject is left blank, it will not be factored into the final calculations.

TAGS USED

<div>
    <section><label>Total:</label><span id="total">0</span></section>
    <section><label>Average:</label><span id="average">0</span></section>
    <section><label>Grade:</label><span id="grade">-</span></section>
</div>
<br />
<form onsubmit="return false;">
    <label>English:</label><input type="number" min="0" max="100" step="1" name="english" value="0" /><br />
    <label>Math:</label><input type="number" min="0" max="100" step="1" name="math" value="0" /><br />
    <label>Physics:</label><input type="number" min="0" max="100" step="1" name="physics" value="0" /><br />
    <label>Computer:</label><input type="number" min="0" max="100" step="1" name="computer" value="0" /><br />
    <label>Science:</label><input type="number" min="0" max="100" step="1" name="science" value="0" /><br />

    <br />
    <button onclick="calculateGrades(this)">Calculate Grade</button>
</form>

CSS STYLING

label {
    display: inline-block;
    width: 4rem;
    margin-right: 2rem;
    padding: 0.25rem 1rem;
}

JAVASCRIPT LOGIC

const totalElement = document.getElementById("total");
const averageElement = document.getElementById("average");
const gradeElement = document.getElementById("grade");

// Function to calculate grades
function calculateGrades(btn) {

    // find inputs
    const form = btn.closest("form");
    const inputs = form.getElementsByTagName("input");

    // variables initialization
    let total = 0;
    let used = 0;
    let average = 0;

    // loop through inputs
    for (const input of inputs) {
        // exclude if value is 0
        if (input.value == 0) continue;

        // convert input to number and add to total
        total += Number( input.value );

        // increment count of used subjects
        used++;
    }

    // calculate average grade
    average = total / used;

    // display values
    totalElement.innerText = total;
    averageElement.innerText = average;

    // get letter grade
    letterGrade( average );
}

// Function to determine the letter grade
function letterGrade(value) {

    // variable declaration
    let letterGrade = null;

    // return if no value
    if ( !value ) return letterGrade;

    // assign letter based on value range
    switch (true) {
        case value >= 90:
            letterGrade = "A";
            break;
        case value >= 80:
            letterGrade = "B";
            break;
        case value >= 70:
            letterGrade = "C";
            break;
        case value >= 60:
            letterGrade = "D";
            break;
        default:
            letterGrade = "F";
            break;
    }

    // display grade
    gradeElement.innerText = letterGrade;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to incorporate knockout.js within a Node.js environment by utilizing .fn extensions in custom modules?

I'm currently exploring the possibility of implementing the knockout.mapping.merge library in node.js, but I seem to be facing a challenge when it comes to extending ko objects within the module's scope. I am struggling to figure out how to exten ...

Problem with accessing state in React 16

In my code snippet below, I am encountering an issue. When the button is clicked and 'streaming' appears on the UI, the console.log within the 'process' function displays false. Can you help me identify what might be causing this discre ...

A regular expression in Javascript that can be used to identify at least one word starting with a number among multiple words, with a

Currently, I am utilizing JavaScript Regex to validate an input field based on specific conditions: The value must consist of only alphabets and numbers There should be a minimum of two words (more than two are allowed) Only one word can start with a num ...

The Bootstrap modal will not appear when the parent container's position is fixed

I am having an issue with a bootstrap modal that I am using as an instruction guide. My goal is to keep it fixed at the top-right corner of the viewport, so I tried using the fixed position. However, when I do this, the modal turns grey. On the other han ...

How can I organize a dictionary based on a specified key order in Jinja2?

Suppose I need to showcase the following data: • b is foo • a is bar • c is baz ...however, my dataset is structured like this (or any other sequence due to JSON's flexibility): { "a": "bar", "b": "foo", "c": "baz" } How can I utilize Jinja2 ...

What is the best way to create an onwheel event that produces an up and down effect using JavaScript?

Looking for a way to trigger a function or loop when scrolling up or down using the onwheel event. Check out the code snippet below: let demo = document.querySelector('#demo'); let c = 0; window.onwheel = function() { c ++; demo.innerHTML ...

prompting users in a node.js application

I need help with querying the user multiple times in my Node.js application. Currently, all responses get printed out together and the first response is processed by both functions. I suspect this issue arises from the asynchronous nature of Node.js. Can s ...

Include an HTML header and footer on every page when printing an HTML document

I designed an HTML page with a header, content, and footer. When I attempted to print the page, it spanned across 2 pages with the header on the first page and the footer on the last page. My goal is to have the header and footer display on every page, si ...

Is it beneficial to incorporate keys into an express instance for improved functionality?

If I want to pass information from my index.js file to multiple endpoints across different routes, is it sufficient to attach a custom key to the express instance (app)? For instance, if I am using socket.io and want multiple endpoints to emit from the i ...

Ways to resolve the issue of iOS Safari showcasing 'a' tag styling differently compared to other browsers

Here's a simple question for you. Take a look at the images below for reference. Check out the iOS Safari browser on my phone https://i.sstatic.net/o9jOe.jpg and compare it to my desktop browser, both screenshots were taken live from the server. ...

Javascript - Iterating through nested arrays and objects to apply filtering

I am currently trying to fetch specific arrays based on a certain criterion. I am a bit unsure about how to go about filtering the arrays, so I thought I would seek clarification here. Essentially, I have a list of courses and I want to extract all the c ...

Utilizing three columns within a <div> element

As I work on my Website using ASP.NET, I am customizing the MasterPage to divide the content into three columns within a div with specific widths for each column. However, I am facing an issue where the third column, which should be on the right, is instea ...

How to Create a Dynamic CSS Mobile Menu Animation

After checking out some online tutorials, I managed to get a hamburger menu working. However, I encountered an issue with the X icon not being symmetrical after the animation from 3 bars to an X. Here is the comparison: Before: https://gyazo.com/351864d8 ...

Personalizing Twitter Bootstrap Directly from the Bootstrap Source Directory

As I work on developing a responsive web application using Twitter Bootstrap, my goal is to customize the Bootstrap framework to fit my specific needs. To do so, I have downloaded the Bootstrap source files from getbootstrap.com. My plan is to customize B ...

The function json.stringify fails to invoke the toJson method on every object nested within the main object

When using IE 11, I encountered an issue where calling Stringify on my objects did not recursively call toJson on all objects in the tree. I have implemented a custom toJson function. Object.prototype.toJSON = function() { if (!(this.constructor.name == ...

Is it possible to display a thumbnail image in a separate full-sized window by using CSS or JavaScript?

I am currently utilizing a program called WebWorks 2020.1 that automatically creates <img> tags from my FrameMaker source input when published to DHTML. Unfortunately, I do not have the ability to directly modify the HTML <img> or <a> tag ...

Create an Angular 2 webpack production project and ensure that the dist folder does not contain any source code

I am currently developing a web application using Angular 2 with TypeScript and angular-cli. I needed to test the application on the server without uploading the source code, so I used the command "ng build --prod". Despite deleting all .map files from the ...

Designing a webpage layout using Bootstrap 4 that includes a horizontal/inline form and two columns

Just when I felt confident in my understanding of bootstrap, it seems to be giving me trouble :( I am aiming to create a layout with 2 columns, each containing a question followed by a small text box for entering a number. Here is an example of the layou ...

Tips for centering a resized image within a container:

I adjusted the width and height to "max" for my images inside the container, and while wider images fit perfectly, taller ones seem to shift left of the container. I tried researching about adjusting using "max-width" but still facing issues. Here's t ...

Tips for adjusting the background and text color of Bootstrap dropdowns using CSS

I've been experimenting with different approaches to modify the background color and text color of the dropdown menu (dropdown-menu & dropdown-item), but I haven't had any success so far. Currently, the dropdown has a very light grey background c ...