How to think like a computer scientist exercise

Since the title, I hope, will suggest, this is an example for the specified book. I am still new to programming and am having difficulty debugging. With that said, any criticism is welcome, especially if it shows a more efficient way of coding; just keep in mind that I'm still a beginner, so I have a good chance that I don’t know what you mean if you drop me a new built-in function or something like that.

So, the point of this exercise is to write a function that gives three arguments to determine if these three arguments form a triangle. Here is 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() 

However, when I run it, 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 string sum_of_two, but I don’t know what is wrong with it. Can someone help me debug this?

I spend a good hour rewriting it using the built-in function (differently, with a bouquet of or ). But it looked awful, and I'd rather learn to write like that.

+7
source share
3 answers

The problem is that remove modifies the base list - it does not return a new list. Change it to:

 num_list.remove(biggest) sum_of_two = sum(num_list) 

To find out why this is happening, try the following in IDLE:

 >>> x = [1,2,3,4,5] >>> x.remove(1) >>> x [2,3,4,5] 
+5
source

Since num_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 should 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... >:[' 
+2
source

You just made a very common mistake, simple. In Python, when a function causes a change in the data structure, it does not return the changed structure. Usually it returns None . If the function receives a new data structure or a new value, it returns it.

So str.lower() doesn't actually change the line; it returns a new line where the characters are lowercase. If you have a list named lst and you run sorted(lst) , it will not change the list; it returns a new list that is sorted. But lst.sort() sorts the list in place, so it does not return a link to the list; it returns None .

In the comments below, @lvc indicated that list.pop() removes the value from the list and returns the value. So this is an example of a function that changes the data structure and returns something other than None , but it still definitely does not return a link to the changed data structure.

The list.remove() function modifies the list and returns None . All you have to do is change your function to use the same list for everything: first use the list to find max, then remove the maximum value from the list, and then pass the list to sum() .

The reason Python does it this way is to obey the principle of "Command / Query Separation".

http://en.wikipedia.org/wiki/Command%E2%80%93query_separation

+2
source

All Articles