To start a new thread, I'm always trying to keep a list of some common "gotchas" that beginning students run across when using Python, or things that teachers should keep in mind when teaching with the language. I have in mind commands that do not generate runtime errors, but are likely to lead to logical errors that are not apparent to students, and most of these are legal due to the very flexible nature of the Python language. Some classicss are data.sort # no-op data = data.sort() # bye-bye data result = result.upper # probably not what you expect if answer.isupper: # always true ("but I entered a lowercase answer") This semester, I ran across a new one that took me quite some time to figure out what was happening. This started with a habit that too many students have of wanting to compare boolean values to True/False literals, rather than just using the boolean as a condition. That is, students seem drawn to the syntax if answer.isupper() == True: rather than the preferred if answer.isupper(): These complaints are more of style than substance, as the two versions are logically equivalent. But then a student came to me with code that wasn't behaving. The syntax they used was something akin to if x > y == True: however the condition was not being triggered, even when we verified that x was indeed greater than y. You can try this out with explicit values as follows.
if 5 > 4 == True: ... print "Good"
You will find that the body is not executed. More directly, you can look at the conditional value directly as
5 > 4 True 5 > 4 == True False
This baffled me for an hour before finally seeing what was happening. I'll leave this as a puzzle for readers (many of whom I'm sure will be quicker than I was to see the solution). For those who give up, I offer the following link as a spoiler. http://docs.python.org/reference/expressions.html#comparisons With regard, Michael +----------------------------------------------- | Michael H. Goldwasser, Ph.D. | Associate Professor | Director of Computer Science | Dept. Mathematics and Computer Science | Saint Louis University | 220 North Grand Blvd. | St. Louis, MO 63103-2007 | | Office: Ritter Hall 108 | Email: goldwamh@slu.edu | URL: http://cs.slu.edu/~goldwasser | Phone: (314) 977-7039 | Fax: (314) 977-1452
Hi, I really like it that python allows me to write if 10 < x <= b: ... impossible in many other languages. But all things come at a cost:
if x > y == True:
I think this is a real gotcha, because it might get you, because you _know too much_:
if 4: print True
True
So all things different from 0, '', ... are considered True by python. But.....
spoiler ahead ;-)
4==True
False
Cheers Christian
Hi, I agree that the behavior of booleans in Python can sometimes lead to subtle errors, but I think it's important to stress to students that writing things like: if x>y == True: is _really_ bad style. After pointing that out, I start taking points away for doing this. Code like this shows that the writer really does not understand Boolean types and their use. Expressions like this can cause subtle errors in just about any language, even those that are statically typed to prevent this sort of confusion. In Java, (x>y==true) is not a valid expression, so it won't compile. But consider this loop that seems to use done as a boolean flag:: boolean done = false; while(done = false){ // do some stuff here } The loop body will never execute. This sort of error in a strongly typed language is often very hard to spot, since we assume the compiler should catch it. If the condition is simply written as: while(!done){ then you can't go wrong. My point is that while I agree this is a "gotcha" in Python, there are similar gotchas in just about all languages. The real culprit in the original example is poor coding style, not the language semantics per se. --John ________________________________________ From: edu-sig-bounces+john.zelle=wartburg.edu@python.org [edu-sig-bounces+john.zelle=wartburg.edu@python.org] on behalf of Christian Mascher [christian.mascher@gmx.de] Sent: Tuesday, March 29, 2011 10:12 AM To: edu-sig@python.org Subject: Re: [Edu-sig] Interesting "gotcha" Hi, I really like it that python allows me to write if 10 < x <= b: ... impossible in many other languages. But all things come at a cost:
if x > y == True:
I think this is a real gotcha, because it might get you, because you _know too much_:
if 4: print True
True
So all things different from 0, '', ... are considered True by python. But.....
spoiler ahead ;-)
4==True
False
Cheers Christian _______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig
On Mon, Mar 28, 2011 at 10:06 PM, Michael H. Goldwasser <goldwamh@slu.edu>wrote:
To start a new thread, I'm always trying to keep a list of some common "gotchas" that beginning students run across when using Python, or things that teachers should keep in mind when teaching with the language.
Sincere applause -- exactly the kind of thread edu-sig should include in the weave. This mystr.isupper( ) == True: stuff is quite common. One also gets veterans of other languages wanting to use while instead for for loops: cnt = 0 while cnt < len(mylist): theword = mylist[cnt] of theword.isupper( ) == True: is_upper.append(theword) cnt += 1 instead of is_upper = [ theword for theword in mylist if theword.isupper() ] I was at one of David Goodger's talks which was all about getting more idiomatic. Knowing the default behavior of dicts means you know you can say for key in thedict: instead of for key in thedict.keys(): Sometimes I'll think a student is using an idiom that looks odd and so isn't "Pythonic" (as if I were the only judge). Like: mydict.update({key:value}) instead of mydict[key] = value but then I'll do a search and see enough authors using the idiom to update my own ideas of what's idiomatic. Teachers have a privileged position, getting to see the same solutions over and over but in slightly (or greatly) different styles. edu-sig makes a useful repository for those wishing to share from this perspective. Kirby
My experience of confusing boolean expressions was the code:
1 == 2 in [2, False] False
which, when parenthesised the two possible ways
(1 == 2) in [2, False] True 1 == (2 in [2, False]) True results in sensible values (although the second one's sensibility is debatable)
I couldn't figure it out quickly either. In fact, I ended up decompiling to byte code to figure out what was going on. As far as other 'gotcha's in addition to the ones already mentioned: Calling a file the same name as a module in the standard library. Import <name> will get the local file, not the stdlib one, which is confusing if you wanted the stdlib one. I've noticed that students will somtimes put import statements inside a function - right before they need to use whatever they imported: def area(r): import math return math.pi*r*r Cheers, Carl. On 29 March 2011 18:06, Michael H. Goldwasser <goldwamh@slu.edu> wrote:
To start a new thread, I'm always trying to keep a list of some common "gotchas" that beginning students run across when using Python, or things that teachers should keep in mind when teaching with the language. I have in mind commands that do not generate runtime errors, but are likely to lead to logical errors that are not apparent to students, and most of these are legal due to the very flexible nature of the Python language. Some classicss are
data.sort # no-op
data = data.sort() # bye-bye data
result = result.upper # probably not what you expect
if answer.isupper: # always true ("but I entered a lowercase answer")
This semester, I ran across a new one that took me quite some time to figure out what was happening. This started with a habit that too many students have of wanting to compare boolean values to True/False literals, rather than just using the boolean as a condition. That is, students seem drawn to the syntax
if answer.isupper() == True:
rather than the preferred
if answer.isupper():
These complaints are more of style than substance, as the two versions are logically equivalent. But then a student came to me with code that wasn't behaving. The syntax they used was something akin to
if x > y == True:
however the condition was not being triggered, even when we verified that x was indeed greater than y. You can try this out with explicit values as follows.
if 5 > 4 == True: ... print "Good"
You will find that the body is not executed. More directly, you can look at the conditional value directly as
5 > 4 True 5 > 4 == True False
This baffled me for an hour before finally seeing what was happening. I'll leave this as a puzzle for readers (many of whom I'm sure will be quicker than I was to see the solution). For those who give up, I offer the following link as a spoiler. http://docs.python.org/reference/expressions.html#comparisons
With regard, Michael
+----------------------------------------------- | Michael H. Goldwasser, Ph.D. | Associate Professor | Director of Computer Science | Dept. Mathematics and Computer Science | Saint Louis University | 220 North Grand Blvd. | St. Louis, MO 63103-2007 | | Office: Ritter Hall 108 | Email: goldwamh@slu.edu | URL: http://cs.slu.edu/~goldwasser | Phone: (314) 977-7039 | Fax: (314) 977-1452
_______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig
What is a Python module? #========================== Common answer is "a file containing Python source code?", but I'm questioning whether that's sufficient definition. How about an importable .pyc or .pyd, with no .py in the picture. That's a module too, no? ** Import Star #==================================== When is import * a good idea? There's all this righteous moralistic hoopla that gets built up against specific idioms, to where eval( ) appears to be fighting for its very existence... Mary wants to keep her little lambda. So I'd rather phrase these in the positive, as in when IS it a good idea... e.g. to use semi-colons between statements. ** Another student question: #========================= Why does all([]) return True by default? Is this a case of half full versus half empty? ** Correcting a misconception #======================== No, docstrings do NOT have to be triple quoted. Kirby
So 'in' is a comparison "operator", is it? I am annoyed at how long it took me to verify that Python treats it as such, and I am also annoyed that it is so. http://docs.python.org/tutorial/datastructures.html 5.7. More on Conditions¶ The conditions used in while and if statements can contain any operators, not just comparisons. The comparison operators in and not in check whether a value occurs (does not occur) in a sequence. I never cared for the misleading a<b<c notation anyway, and won't use it. On Tue, Mar 29, 2011 at 19:09, Carl Cerecke <carl@free.org.nz> wrote:
My experience of confusing boolean expressions was the code:
1 == 2 in [2, False] False
which, when parenthesised the two possible ways
(1 == 2) in [2, False] True 1 == (2 in [2, False]) True results in sensible values (although the second one's sensibility is debatable)
I couldn't figure it out quickly either. In fact, I ended up decompiling to byte code to figure out what was going on.
As far as other 'gotcha's in addition to the ones already mentioned:
Calling a file the same name as a module in the standard library. Import <name> will get the local file, not the stdlib one, which is confusing if you wanted the stdlib one.
I've noticed that students will somtimes put import statements inside a function - right before they need to use whatever they imported: def area(r): import math return math.pi*r*r
Cheers, Carl.
On 29 March 2011 18:06, Michael H. Goldwasser <goldwamh@slu.edu> wrote:
To start a new thread, I'm always trying to keep a list of some common "gotchas" that beginning students run across when using Python, or things that teachers should keep in mind when teaching with the language. I have in mind commands that do not generate runtime errors, but are likely to lead to logical errors that are not apparent to students, and most of these are legal due to the very flexible nature of the Python language. Some classicss are
data.sort # no-op
data = data.sort() # bye-bye data
result = result.upper # probably not what you expect
if answer.isupper: # always true ("but I entered a lowercase answer")
This semester, I ran across a new one that took me quite some time to figure out what was happening. This started with a habit that too many students have of wanting to compare boolean values to True/False literals, rather than just using the boolean as a condition. That is, students seem drawn to the syntax
if answer.isupper() == True:
rather than the preferred
if answer.isupper():
These complaints are more of style than substance, as the two versions are logically equivalent. But then a student came to me with code that wasn't behaving. The syntax they used was something akin to
if x > y == True:
however the condition was not being triggered, even when we verified that x was indeed greater than y. You can try this out with explicit values as follows.
if 5 > 4 == True: ... print "Good"
You will find that the body is not executed. More directly, you can look at the conditional value directly as
5 > 4 True 5 > 4 == True False
This baffled me for an hour before finally seeing what was happening. I'll leave this as a puzzle for readers (many of whom I'm sure will be quicker than I was to see the solution). For those who give up, I offer the following link as a spoiler. http://docs.python.org/reference/expressions.html#comparisons
With regard, Michael
+----------------------------------------------- | Michael H. Goldwasser, Ph.D. | Associate Professor | Director of Computer Science | Dept. Mathematics and Computer Science | Saint Louis University | 220 North Grand Blvd. | St. Louis, MO 63103-2007 | | Office: Ritter Hall 108 | Email: goldwamh@slu.edu | URL: http://cs.slu.edu/~goldwasser | Phone: (314) 977-7039 | Fax: (314) 977-1452
_______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig
_______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig
-- Edward Mokurai (默雷/धर्ममेघशब्दगर्ज/دھرممیگھشبدگر ج) Cherlin Silent Thunder is my name, and Children are my nation. The Cosmos is my dwelling place, the Truth my destination. http://www.earthtreasury.org/
On Wed, Mar 30, 2011 at 11:31 AM, Edward Cherlin <echerlin@gmail.com> wrote:
So 'in' is a comparison "operator", is it? I am annoyed at how long it took me to verify that Python treats it as such, and I am also annoyed that it is so.
http://docs.python.org/tutorial/datastructures.html 5.7. More on Conditions¶
The conditions used in while and if statements can contain any operators, not just comparisons.
As you no doubt know, in triggers the rib __contains__ in the cosmic backbone of Python's special names list, whereas operators like ==,
and < trigger their own specially named reflexes:
class Foo: def __contains__(self, value): print ("Yes {} is in the bar".format(value)) return True
bar = Foo() "Joe" in bar Yes Joe is in the bar True
class Average: def __lt__(self, value): print("Yes {} is better than Average".format(value)) return True
bar = Average() "Joe's bar" > bar Yes Joe's bar is better than Average True
The comparison operators in and not in check whether a value occurs (does not occur) in a sequence.
I never cared for the misleading a<b<c notation anyway, and won't use it.
heretic! Kirby
participants (7)
-
Carl Cerecke
-
Christian Mascher
-
Edward Cherlin
-
John Zelle
-
kirby urner
-
Kirby Urner
-
Michael H. Goldwasser