Reputation: 47
I'm trying to make program which automatically determines the cheapest method of mailing a package based on its weight.
The code is refusing to run however as I keep getting the following TypeError: '<' not supported between instances of 'function' and 'function'
.
I tried turning the functions into floats with:
if float(cost_ground) < float(cost_drone) and float(cost_ground) < float(cost_premium):
But this returns the following TypeError: float() argument must be a string or a number, not 'function'
.
Any advice and/or explanation on how to solve this?
Here is the full code:
def cheapest(weight):
def cost_ground(weight):
if weight <= 2:
return float((weight * 1.50) + 20)
elif weight <= 6:
return float((weight * 3.00) + 20)
elif weight <= 10:
return float((weight * 4.00) + 20)
else:
return float((weight * 4.75) + 20)
def cost_drone(weight):
if weight <= 2:
return float((weight * 4.50))
elif weight <= 6:
return float((weight * 9.00))
elif weight <= 10:
return float((weight * 12.00))
else:
return float((weight * 14.25))
def cost_premium(weight):
return 125.00
if cost_ground < cost_drone and cost_ground < cost_premium:
return "Ground shipping is the cheapest at $" + cost_ground
if cost_drone < cost_ground and cost_drone < cost_premium:
return "Drone shipping is the cheapest at $" + cost_drone
if cost_premium < cost_ground and cost_premium < cost_drone:
return "Premium ground shipping is the cheapest at $" + cost_premium
Upvotes: 2
Views: 57
Reputation: 5690
You are comparing the actual Python function objects rather than the results returned by those functions. In Python, a function name can be treated like a variable if the function is not invoked. You've already got the weight argument passed to the top-level function cheapest()
, so pass it to functions. So your code:
if cost_ground < cost_drone and cost_ground < cost_premium:
return "Ground shipping is the cheapest at $" + cost_ground
becomes:
if cost_ground(weight) < cost_drone(weight) and cost_ground(weight) < cost_premium(weight):
return "Ground shipping is the cheapest at $" + cost_ground
Also note that comparisons like these can be ganged together. So a simpler way of writing the if
line of the code would be:
if cost_drone(weight) > cost_ground(weight) < cost_premium(weight):
Upvotes: 0
Reputation: 273
Every function when called needs to be given it's parameters. The only situation where a function can be called without any parameters is if the function itself takes no parameters. The following code should make that clear:
def function_a():
print("No parameters required.")
def function_b(parameter_1,parameter_2):
return parameter_1 + parameter_2
function_a()
function_b()
Calling the first function without any parameters will not produce any errors however calling the second function will produce an error since it takes two parameters and it has been given none.
In your code, you are not passing a parameter to the functions. Defined by your ownself, cost_ground()
takes a weigth
parameter. When you are calling that function, you are calling it without the parameter.
Hence it should be:
if float(cost_ground(weight)) < float(cost_drone(weight)) and float(cost_ground(weight)) < float(cost_premium(weight)):
In addition to this when you return the values, you must convert values from float
to string
as follows:
return "Ground shipping is the cheapest at $" + str(cost_ground(weight))
Otherwise it will given the following error:
TypeError: can only concatenate str (not "float") to str
Full code is given below, it should work fine now.
def cheapest(weight):
def cost_ground(weight):
if weight <= 2:
return float((weight * 1.50) + 20)
elif weight <= 6:
return float((weight * 3.00) + 20)
elif weight <= 10:
return float((weight * 4.00) + 20)
else:
return float((weight * 4.75) + 20)
def cost_drone(weight):
if weight <= 2:
return float((weight * 4.50))
elif weight <= 6:
return float((weight * 9.00))
elif weight <= 10:
return float((weight * 12.00))
else:
return float((weight * 14.25))
def cost_premium(weight):
return 125.00
if float(cost_ground(weight)) < float(cost_drone(weight)) and float(cost_ground(weight)) < float(cost_premium(weight)):
return "Ground shipping is the cheapest at $" + str(cost_ground(weight))
if cost_drone < cost_ground and cost_drone < cost_premium:
return "Drone shipping is the cheapest at $" + str(cost_drone(weight))
if cost_premium < cost_ground and cost_premium < cost_drone:
return "Premium ground shipping is the cheapest at $" + str(cost_premium(weight))
Upvotes: 0
Reputation: 87124
cost_ground
, cost_drone
and cost_premium
are all functions. There is no concept of one function being greater than another. For example:
>>> def f1(): return 1
>>> def f2(): return 2
>>> f1 > f2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'function' and 'function'
You meant to call the functions and to do that you need to use parentheses and optionally arguments as defined by the functions. Using the above functions:
>>> f1() > f2()
False
This works because it is the return values of the functions that is being compared, not the function objects.
For example, cost_ground
is defined as accepting an argument named weight
so that needs to be supplied when calling the function; cost_ground(5)
will return a float value 35.0.
So you should be doing this:
weight = 5
if cost_ground(weight) < cost_drone(weight) and cost_ground(weight) < cost_premium(weight):
return f"Ground shipping is the cheapest at ${cost_ground(weight)}"
Upvotes: 2
Reputation: 31
cost_premium and cost_ground are functions and not numbers. They should be called in such a way that they evaluate to numbers:
instead of
ìf cost_premium < cost_ground ...
do if cost_premium(weight) < cost_ground(weight) ...
Upvotes: 0