So as the title hopefully suggest, this is for an example in said book. I'm still new to programming and having difficulty debugging. With that said any criticism is welcomed, specially if it shows a more efficient way of coding; just keep in mind that I'm still new so there's a good chance i might not know what you're referring to if you toss me a new built-in function or something.
So the point of this exercise is to write a function, giving it three arguments, to determine if those three arguments form a triangle. Here's my code:
def is_triangle(a,b,c):
num_list = [a,b,c]
biggest = max(num_list)
other_two = num_list.remove(biggest)
sum_of_two = sum(other_two)
if sum_of_two > biggest:
print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
elif sum_of_two == biggest:
print 'That forms a degenerate triangle!'
else:
print 'That does\'t make any sort triangle... >:['
def sides():
side1 = raw_input('Please input side numero Juan: ')
side2 = raw_input('Now side two: ')
side3 = raw_input('...aaaannnd three: ')
import time
time.sleep(1)
print 'Thanks >:]'
side1 = int(side1)
side2 = int(side2)
side3 = int(side3)
is_triangle(side1,side2,side3)
sides()
Whenever i run it, however, i get the following:
Traceback (most recent call last):
File "A:/Python/is_triangle.py", line 27, in <module>
sides()
File "A:/Python/is_triangle.py", line 25, in sides
is_triangle(side1,side2,side3)
File "A:/Python/is_triangle.py", line 5, in is_triangle
sum_of_two = sum(other_two)
TypeError: 'NoneType' object is not iterable
My guess is the sum_of_two line but i don't know what's wrong with it. Could someone help me debug this?
I spend a good hour rewriting it with out the built_in function (in various ways, bunch of or
s everywhere). But it looked terrible and I'd rather learn to write this way.
The problem is the fact that remove
modifies the underlying list - it doesn't return a new list. Change it to:
num_list.remove(biggest)
sum_of_two = sum(num_list)
To see exactly why this happens, try the following in IDLE:
>>> x = [1,2,3,4,5]
>>> x.remove(1)
>>> x
[2,3,4,5]
Sincenum_list.remove(biggest)
returns None
, Consider this instead
other1, other2, biggest = sorted(num_list)
sum_of_two = other1 + other2
It looks like the if
block needs to be indented too
def is_triangle(a, b, c):
num_list = [a, b, c]
other1, other2, biggest = sorted(num_list)
sum_of_two = other1 + other2
if sum_of_two > biggest:
print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
elif sum_of_two == biggest:
print 'That forms a degenerate triangle!'
else:
print 'That does\'t make any sort triangle... >:['
You just made a very common mistake, a simple one. In Python, when a function causes a change in a data structure, it does not return the changed structure. Usually it returns None
. If the function gets a new data structure or new value, it returns it.
So, str.lower()
doesn't actually change a string; it returns a new string where the characters are lower-case. If you have some list named lst
and you run sorted(lst)
, it doesn't change the list; it returns a new list that is sorted. But lst.sort()
sorts the list in-place, so it doesn't return a reference to the list; it returns None
.
In the comments below, @lvc pointed out that list.pop()
removes a value from a list and returns the value. So, this is an example of a function that changes a data structure and returns something other than None
, but it still definitely does not return a reference to the changed data structure.
The list.remove()
function changes a list, and it returns None
. All you need to do is change your function to use the same list for everything: first use the list to find the max, then remove the max value from the list, then pass the list to sum()
.
The reason Python does things this way is to obey the "Command/Query Separation" principle.
http://en.wikipedia.org/wiki/Command%E2%80%93query_separation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With