Sal's shipping - why am I getting the wrong result?

Hi,

I’m a beginner at Python. I had a stab at Sal’s shipping but I am getting the wrong results.
For the weight 8.4lb I should return $53.60 - instead I am returning $32.6

What am I missing? Thanks.

ppp = price per lb

weight = 8.4

#Ground Shipping
if weight > 0 <= 2:
  ppp = 1.50
  flat_charge = 20
  cost_ground = weight * ppp + flat_charge

elif weight > 2 <= 6:
  ppp = 3.00
  flat_charge = 20
  cost_ground = weight * ppp + flat_charge

elif weight > 6 <= 10:
  ppp = 4.00
  flat_charge = 20
  cost_ground = weight * ppp + flat_charge

elif weight > 10:
  ppp = 4.75
  flat_charge = 20
  cost_ground = weight * ppp + flat_charge

else:
  weight = 0
  print("Weight cannot be 0")
  
print(cost_ground)

In many programming languages (e.g. JavaScript, C), expressions involving chained operators are evaluated differently than how we use them in mathematics.

For example, in mathematics 0 < 3 < 5 is considered as:    0 < 3    AND    3 < 5

In JavaScript the expression would be evaluated as:

0 < 3 < 5
(0 < 3) < 5
true < 5  // Type coercion
1 < 5
true

// Evaluation doesn't follow the mathematical logic we hoped
3 < 0 < 5
(3 < 0) < 5
false < 5
0 < 5
true

I only mentioned the above so that you recognize that how expressions are evaluated can vary significantly across different programming languages.

Python is one of the languages which does carry out chained comparisons similar to how we interpret expressions in mathematics.
Documentation: https://docs.python.org/3/reference/expressions.html#comparisons

So expressions like 0 < 3 < 5 will be evaluated as:    0 < 3    AND    3 < 5.
If both comparisons are True, then the overall expression will also be True.

With the above in mind, your expression will be evaluated in Python as:

weight = 8.4

weight > 0 <= 2
(weight > 0) AND (0 <= 2)
True AND True
True

Therefore, the condition if weight > 0 <= 2: evaluates as True, and the statements in this block are executed. ppp = 1.50 is used and consequently, cost_ground is calculated as 32.6

Instead you should write your condition as:

if 0 < weight <= 2:

This will be evaluated as:

(0 < weight) AND (weight <= 2)

The same sort of modifications need to be made to the elif expressions as well e.g,

# You wrote:
elif weight > 2 <= 6:

# It should be:
elif 2 < weight <= 6:
4 Likes

Just to reinforce the above example:

     > 0 < 3 < 2
    <- true

Of course, we know this is not the case, however to JS, 1 is less than 2.

Bottom line, in JS, especially, never use the compound comparison.

if (0 < x && x < 6) {}

will give results that we can trust on the face of it, without worrying how JS is evaluating it.

2 Likes

Thanks so much for the comprehensive answer - I understand it now. You would think I should have known given the the last topic was about true/false!

3 Likes