How to improve my code (Connect arguments in Functions) - Beginner in JavaScript

Viewed 76

I'm starting to learn how to code and I created a simple program to rate tests.

The problem is that I have to change four arguments for each "test" to make the code work properly. What can I change so that I only need to change two?

I hope I explained myself, English isn't my first language. And sorry for the undescriptive title but I didn't know how to phrase it.

function score (pointsObt, pointsTest) {
    return 100 / pointsTest * pointsObt;
};

function verdict (pointsObt, pointsTest){
  if (score (pointsObt, pointsTest) >= 75) {
    return 'Yay, you did it'
  }
  else {
    return "You did it! But bad."
  }
};

console.log (verdict(50, 50));
console.log ('Your score: ' + score(50, 50));

4 Answers

You can make the verdict function return both the score and the verdict in one data structure. That could be an array with two values or a plain object with two properties. Here is how the latter idea would work:

function score (pointsObt, pointsTest) {
    return 100 / pointsTest * pointsObt;
};

function verdict (pointsObt, pointsTest) {
  let percentage = score (pointsObt, pointsTest);
  let message = percentage >= 75 ? "Yay, you did it" : "You did it! But bad.";
  return { percentage, message };
};

let { percentage, message } = verdict(50, 50);
console.log (message);
console.log ('Your score: ' + percentage);

Explanation

I changed the if...else construct to an expression that uses the ternary operator (? and :). That way you can make one assignment and yet make the distinction between the two outcomes.

In the return statement a new object is created having two properties which correspond exactly to what the variables with the same names have as values (this is a short object literal notation introduced in EcmaScript 2015)

The caller in the main code can get that object from the call. I have used a destructuring assignment to immediately extract the two properties from the returned object into two variables having the same names as the object properties.

Advantages

In your implementation you not only provide the same arguments twice, but -- possibly more importantly -- you calculate the same score twice. In the proposed solution, score is no longer called twice, but just once.

You could use a variable to make it work

function score (pointsObt, pointsTest) {
    return 100 / pointsTest * pointsObt;
};

function verdict (pointsObt, pointsTest){
  if (score (pointsObt, pointsTest) >= 75) {
    return 'Yay, you did it'
  }
  else {
    return "You did it! But bad."
  }
};

var pointsObt= 50;
var pointsTest= 50;

console.log (verdict(pointsObt, pointsTest));
console.log ('Your score: ' + score(pointsObt, pointsTest));

You can do all that with one function. No need to have another function score with return from it.

One function will give you both score and verdict separately.

Using one function only with score and verdict

//Global vars
let percScore; //Score will be stored here
let myNumber = 50; //Change this number only to see different verdict and and score

function verdict(pointsObt, pointsTest) {
  //Score
  percScore = 100 / pointsObt * pointsTest
  //Verdict
  if (percScore >= 75) {
    return 'Yay, you did it'
  } else {
    return "You did it! But bad."
  }
};

console.log(verdict(myNumber, myNumber));
console.log('Your score: ' + percScore);

Using global Variable with separate functions with score and verdict separately.

Details

Just change the myNumber global var and your will see score and verdict change as well. Read more about global variables here

let myNumber = 50; //Change this number only to see different verdict and and score

function score(pointsObt, pointsTest) {
  return 100 / pointsTest * pointsObt;
};

function verdict(pointsObt, pointsTest) {
  if (100 / pointsObt * pointsTest >= 75) {
    return 'Yay, you did it'
  } else {
    return "You did it! But bad."
  }
};

console.log(verdict(myNumber, myNumber));
console.log('Your score: ' + score(myNumber, myNumber));

You are right, this can be simplified a lot.

This is just one option.

// Merge the two functions
function verdict(pointsObt, pointsTest){
  // Get the score (well, percentage) 
  var score = (100 / pointsTest * pointsObt);
  // Use a ternary as there are only the two options to
  // work out what to print.
  var msg = (score >= 75) ? "Yay, you did it" : "You did it! But bad." ;
  // Only a single console.log() call is needed if you
  // use a \n (new line) at the correct point
  console.log(msg+"\nYour score: "+score+"%");
};

// Call 3 different results.
verdict(50, 50);
verdict(5, 50);
verdict(40, 50);

// You could even do this. Drop all the results in to
// an array, then loop the array. Assuming all results
// are out of a max of 50.
var results = [45,35,26,48];
results.forEach(r => verdict(r,50));

Related