Help with my first code


#1


Hello, I'm very new to coding, I have finished "Introduction to Javascript - Functions" part and before adding new notions I want to test what I have learned so far.

So I have coded the following very basic cash register from scratch:


var itemPrice1 = 27.12;
var itemPrice2 = 1.21;

var payment = 50;

function getTotal() {
  return itemPrice1 + itemPrice2;
}

function getChange() {
  return payment - getTotal();
}


console.log('TOTAL: ' + getTotal());
console.log('CHANGE: ' + getChange());

The problem is that for some combinations (like the one above) of not integer item prices the result looks like:

TOTAL: 28.330000000000002 (instead of 28.33)
CHANGE: 21.669999999999998 (instead of 21.67)

what's the reason?

Thank you very much.


#2

This is known as floating point arithmetic error, which as we can see is very, very small.

Computers are binary, and do all their math in binary which does not have decimal fractions. To compensate for this, the computer has a very complex math operation built in, and a special math processor to do the heavy lifting. I won't attempt to go into the details, but you can search for the terms if you want the detailed explanation. The act of converting a binary back to the a decimal results in this very tiny error in many instances.

JavaScript has a built in function, toFixed which we can use to charify our result in currency terms.

getTotal().toFixed(2)

Now let's discuss your variables. They are in global scope, so yes, visible inside the function, but this limits the usefulness of the function. That is where parameters and arguments come into play:

function getTotal(a, b) {
    return (a + b).toFixed(2);
}
function getChange(t, p) {
    return p - t > 0 ? p - t : p - t < 0 ? "short " + p - t : 0;
}

console.log(getChange(getTotal(itemPrice1, itemPrice2), payment));

Ideally, the items would be accumulated to an array or object. Instead of passing in two prices, we would pass in the entire object. This will allow an object of any length, not just two (mandatory) items.

function getTotal(list) {    // assumes an array of prices
    total = 0;
    for (var i = 0; i < list.length; i++) {
        total += list[i];
    }
    return total.toFixed(2);
}

Starting to make sense?


#3

Really good explanation! But I'm not sure, is it correct syntax for JS?


#4

D'oh! No, it is not. Thanks for pointing that out. I'll fix it.


#5

Hello mtf, many thanks for your detailed reply. It's all experience for me.

So now my code is:

function getTotal(a, b) {
    return (a + b).toFixed(2);
}
function getChange(t, p) {
    return p - t > 0 ? p - t : p - t < 0 ? "short " + p - t : 0;
}

console.log('TOTAL: ' + getTotal(27.12, 1.21));
console.log('CHANGE: ' + getChange(getTotal(27.12, 1.21), 50));

and give the correct result:

TOTAL: 28.33
CHANGE: 21.67

this line was new to me:

return p - t > 0 ? p - t : p - t < 0 ? "short " + p - t : 0

and I have understood the meaning. But if I set p < t, in the result "short" is not displayed because is not a number (NaN). I can remove it and show only the negative number, but is there a way to show also text?

Array is a new notion for me. I hope to see it tomorrow. Then I will study your code :slight_smile:

Thanks for your time!!


#6

Since you are calling getTotal twice, maybe better to cache it...

 total = getTotal(27.12, 1.21);
 change = getChange(total, payment);

Sorry, didn't mean to confuse you. The above is known as a ternary expression and is similar to the following:

if (p - t > 0) {
    return p - t;
}
else if (p - t < 0) {
    return "short " + (p - t).toString(10);
} else {
    return 0;
}

We don't really cover ternary expressions so I should not have included that. Doesn't hurt to broaden our horizons ever so slightly now and then.

That is because it didn't group the math.

"short " + (p - t)

will convert the number to a string behind the scenes. In my example above, we convert to string explicitly.


#7

Hello mtf, I'm stuck with array and loop.
I don't understand why this code doesn't work :frowning:

var list = [22, 1.20, 0.35, 15, 0.21];

getTotal(list) {
  total = 0;
  for (var i = 0; i < list.length; i++) {
    total += list[i];
  } 
  return total.toFixed(2);
}

function getChange(t, p) {
    if (p - t > 0) {
    return p - t;
}
else if (p - t < 0) {
    return "short " + ((p - t).toFixed(2));
} else {
    return 0;
}
}

change= getChange(total, 50);
console.log('TOTAL: ' + total);
console.log('CHANGE: ' + change);

#8

This one works!

var list = [22, 5, 0.35, 15, 0.21];
var total = 0

for (var i = 0; i < list.length; i++) {
    total += list[i];
}

function getChange(t, p) {
    if (p - t > 0) {
    return (p - t).toFixed(2);
}
else if (p - t < 0) {
    return "short " + ((p - t).toFixed(2));
} else {
    return 0;
}
}

change= getChange(total, 100);
console.log('TOTAL: ' + total);
console.log('CHANGE: ' + change);

#9

getTotal(list) should be a function:

function getTotal(arr) {
  total = 0;
  for (var i = 0; i < arr.length; i++) {
    total += arr[i];
  } 
  return total.toFixed(2);
}
 
// now you can call it:
var total = getTotal(list);

#10

Thanks danys!!
I always forget something grrrr

var list = [22, 1.20, 0.35, 15, 0.21];
var total = getTotal(list);

function getTotal(list) {
  total = 0;
  for (var i = 0; i < list.length; i++) {
    total += list[i];
  } 
  return total.toFixed(2);
}

#11

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.