I teach a computing subject to high school students using Python as our primary language. One thing that often causes confusion at the start is error messages/exceptions. I think it would lower entry point quite a bit by making error messages more readable to novices. Recent research found reduced frequency of overall errors, errors per student, and repeated errors when error messages were enhanced [1]. This could be implemented by a command-line switch when running python, or a different python executable (along the lines of pythonw.exe vs python.exe) such as python-easy. A simpler error message might get rid of excess information which can confuse the novice (such info might be dumped to a file to allow more advanced users to debug), provide a brief description of what the error might mean, and/or how you might fix it. So a SyntaxError might tell the user that they've probably forgotten a :, and a NameError might say that the item has been defined yet, or they've made a typo. A couple of examples follow: Traceback (most recent call last): File "foo.py", line 2, in <module> l[10]=14 IndexError: list assignment index out of range A better message might be: You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access. Traceback (most recent call last): File "foo.py", line 2, in <module> while name != "quit" and reponse != "quit": NameError: name 'reponse' is not defined A better message might be: You're trying to use the value of 'reponse', but that variable hasn't got a value yet. You can give it a value earlier in the code, or it could be a typo. You have a variable called 'response' - is that the one you meant? Traceback (most recent call last): File "foo.py", line 2, in <module> print(length(l)) NameError: name 'length' is not defined A better message might be: Python doesn't recognise the function "length". Did you mean len?' File "foo.py", line 2 for i in l ^ SyntaxError: invalid syntax A better message might be: You have a for loop without a : (colon). Try adding a colon at the end of the line. Any thoughts? [1]: http://researchrepository.ucd.ie/handle/10197/7583 -- Victor Rajewski
On 2016-11-29 02:58, victor rajewski wrote:
NameError: name 'reponse' is not defined
A better message might be:
You're trying to use the value of 'reponse', but that variable hasn't got a value yet. You can give it a value earlier in the code, or it could be a typo. You have a variable called 'response' - is that the one you meant?
This is a really nice feature. GHC and Clang do it for several things and it usually helps (when a live highlighter isn't available). Given that these are HS students, presumably seeing Python for the first time, shouldn't they be using PyCharm to get used to PEP 8 (no l[10]=14) and other best practices (e.g., such as using 'with' instead of 'try/finally' when possible)? This would provide live syntactic (and some semantic) highlighting with short human-readable messages. Overall, I already find Python's exceptions quite readable, and your suggestions propose some VERY long lines which would certainly wrap at a terminal. Maybe this should be an optional feature. -- Bernardo Sulzbach http://www.mafagafogigante.org/ mafagafogigante@gmail.com
Although there is certainly room good improvement in the error messages, making error messages that work in all cases is hard. For example, functions are just another kind of variable, and it is possible for arbitrary variables to act like functions. So error messages that try to differentiate between the two can't with reliably. Also, for list index errors, the error is created by the list class, and it doesn't know the variable name, and there may not even be a variable. Can you give an error message that will work in your example and also work in this example: sorted(x%i for i, x in enumerate(range(3:999)))[::5].__getitem__(1000) This example seems very different to us but is identical as far as the list class is concerned, so you would need a single error message that works equally well in both cases. Syntax errors are also often hard. Consider your example, but with more lines around it: a = [step %s' % i for i in l ] Now your error message will give the wrong information. It often is very hard to even tell what line a syntax error occurs on, not to mention figure out exactly what went wrong. So yes, better error messages would be great. But the sorts of error messages you describe are not generally possible in practice. There are just too many corner- On Nov 28, 2016 11:58 PM, "victor rajewski" <askvictor@gmail.com> wrote:
I teach a computing subject to high school students using Python as our primary language. One thing that often causes confusion at the start is error messages/exceptions. I think it would lower entry point quite a bit by making error messages more readable to novices. Recent research found reduced frequency of overall errors, errors per student, and repeated errors when error messages were enhanced [1].
This could be implemented by a command-line switch when running python, or a different python executable (along the lines of pythonw.exe vs python.exe) such as python-easy. A simpler error message might get rid of excess information which can confuse the novice (such info might be dumped to a file to allow more advanced users to debug), provide a brief description of what the error might mean, and/or how you might fix it. So a SyntaxError might tell the user that they've probably forgotten a :, and a NameError might say that the item has been defined yet, or they've made a typo. A couple of examples follow:
Traceback (most recent call last):
File "foo.py", line 2, in <module>
l[10]=14
IndexError: list assignment index out of range
A better message might be:
You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access.
Traceback (most recent call last):
File "foo.py", line 2, in <module>
while name != "quit" and reponse != "quit":
NameError: name 'reponse' is not defined
A better message might be:
You're trying to use the value of 'reponse', but that variable hasn't got a value yet. You can give it a value earlier in the code, or it could be a typo. You have a variable called 'response' - is that the one you meant?
Traceback (most recent call last):
File "foo.py", line 2, in <module>
print(length(l))
NameError: name 'length' is not defined
A better message might be:
Python doesn't recognise the function "length". Did you mean len?'
File "foo.py", line 2
for i in l
^
SyntaxError: invalid syntax
A better message might be:
You have a for loop without a : (colon). Try adding a colon at the end of the line.
Any thoughts?
[1]: http://researchrepository.ucd.ie/handle/10197/7583 --
Victor Rajewski
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Sorry, I forgot the subject line! On Tue., 29 Nov. 2016, 3:58 pm victor rajewski, <askvictor@gmail.com> wrote:
I teach a computing subject to high school students using Python as our primary language. One thing that often causes confusion at the start is error messages/exceptions. I think it would lower entry point quite a bit by making error messages more readable to novices. Recent research found reduced frequency of overall errors, errors per student, and repeated errors when error messages were enhanced [1].
This could be implemented by a command-line switch when running python, or a different python executable (along the lines of pythonw.exe vs python.exe) such as python-easy. A simpler error message might get rid of excess information which can confuse the novice (such info might be dumped to a file to allow more advanced users to debug), provide a brief description of what the error might mean, and/or how you might fix it. So a SyntaxError might tell the user that they've probably forgotten a :, and a NameError might say that the item has been defined yet, or they've made a typo. A couple of examples follow:
Traceback (most recent call last):
File "foo.py", line 2, in <module>
l[10]=14
IndexError: list assignment index out of range
A better message might be:
You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access.
Traceback (most recent call last):
File "foo.py", line 2, in <module>
while name != "quit" and reponse != "quit":
NameError: name 'reponse' is not defined
A better message might be:
You're trying to use the value of 'reponse', but that variable hasn't got a value yet. You can give it a value earlier in the code, or it could be a typo. You have a variable called 'response' - is that the one you meant?
Traceback (most recent call last):
File "foo.py", line 2, in <module>
print(length(l))
NameError: name 'length' is not defined
A better message might be:
Python doesn't recognise the function "length". Did you mean len?'
File "foo.py", line 2
for i in l
^
SyntaxError: invalid syntax
A better message might be:
You have a for loop without a : (colon). Try adding a colon at the end of the line.
Any thoughts?
[1]: http://researchrepository.ucd.ie/handle/10197/7583 --
Victor Rajewski _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Victor Rajewski
I'm +1 to the idea of improving error messages :) (but maybe not to the exact new error messages proposed) Raymond Hettinger touched on this topic during his Pycon Canada keynote, as one of the positive contributions that you can do to cpython.
Traceback (most recent call last):
File "foo.py", line 2, in <module>
print(length(l))
NameError: name 'length' is not defined
A better message might be:
Python doesn't recognise the function "length". Did you mean len?'
I recall he gave a similar example to this, where Python could suggest an alternative in case of typo.
Mariatta Wijaya writes:
NameError: name 'length' is not defined
A better message might be:
Python doesn't recognise the function "length". Did you mean len?'
This particular change would be useful to a beginning Python programmer. I've made that error often enough myself (maybe I'm not a good example, though, in Lisp the generic function with the same role *is* called "length", so I make that error even today). But I wonder if it's a good example for the generic case. An error message of the form 'Python doesn't recognize the function "<name>". Did you mean "<name>"?' could easily be misleading. Python has functions, but they're a type of object. "length" is a name, which is not an object. The expected type of the object is not function, it's callable. So consider: class Blog: pass blog = log() NameError: Python doesn't recognize the function "log". Did you mean "Blog"? I suspect that might cause cognitive dissonance in a beginner who thinks of a class as a type or data structure and not as a function. And "doesn't recognize the callable" might be awkward (or beginners might get used to it very quickly, I don't know). Also, how do you propose deciding on the alternative to suggest? In this particular case, I expect most developers would agree intuitively. But the Hamming distance is pretty large: 3 of a length of 6. Would you have a dictionary of common errors, and then scan the namespace for minimum Hamming distance among defined names with the right type of value? How about: class Blog: pass blog = get_blog_for_date(someday) logn = log(blog.size) NameError: Python doesn't recognize the function "log". Did you mean "Blog"? Wouldn't NameError: Python doesn't recognize the name "log". Perhaps you need to import the "math" module? be a better message here? On second thought, that might imply that calling with the unqualified name is generally the best style, and teach the beginner to insert from math import * at the top of the module, thus fixing all such errors. We probably don't want that, so maybe NameError: Python doesn't recognize the name "log". There are functions named "log" in the "math" module and the "cmath" module. would be better yet. I definitely agree that there are times when Python's error messages are quite impenetrable for the beginner, and improvement is desirable. I think that I would probably attack this by looking at the builtin namespace and a few stdlib namespaces (math, string, and maybe cmath come immediately to mind), and create a dictionary of "intuitive beginner errors". Then trap NameErrors, and preferentially emit the message from the dictionary on exact matches. Actually, come to think of it, two dictionaries, one for the builtin namespace, one for the selected stdlib, and the following heuristic: if name in common_builtin_typos: emit(common_builtin_typos[name]) else: errors = small_hamming_distance(name, current_namespace, syntax(name)) if errors: emit(errors) else: errors = exact_matches_in_imported_modules(name) if errors: emit(errors) elif name in common_unimported_stdlib_names: emit(common_unimported_stdlib_names[name]) else: emit(error_you_would_have_emitted_anyway) In other words, I don't see a good systematic way to go about this, just pile up heuristics (and maybe remove some as they prove unuseful!) Steve
There are a couple of project that tried to improved heuristic on some error messages. Two I can think off are: https://github.com/SylvainDe/DidYouMean-Python and https://github.com/dutc/didyoumean I think that better error messages could be implemented only in the repl, and/or by alternative repl. Having it as an opt-in library would be useful to tweak the messages in various context, for example when used for teaching, or if there are concern about overhead. Some alternative even already implement heuristic (Recursions error in IPython are elided with "... last <n> frames repeated, from the frame below ..." which is way less scarier for beginners. Some other attempts have been made with attributes error[1] (similar to what Stephen is proposing), though the traceback info does not have a ref (or even weakref) on the object on which the attributes access is made, so even more heuristic have to be made. Maybe just adding some more information on exception themselves and giving the recipe of custom except hook would be enough. Then just allow users to pip-install packages with heuristics ? -- M [1] https://github.com/ipython/ipython/pull/9073 On Tue, Nov 29, 2016 at 6:14 PM, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Mariatta Wijaya writes:
NameError: name 'length' is not defined
A better message might be:
Python doesn't recognise the function "length". Did you mean len?'
This particular change would be useful to a beginning Python programmer. I've made that error often enough myself (maybe I'm not a good example, though, in Lisp the generic function with the same role *is* called "length", so I make that error even today).
But I wonder if it's a good example for the generic case. An error message of the form 'Python doesn't recognize the function "<name>". Did you mean "<name>"?' could easily be misleading. Python has functions, but they're a type of object. "length" is a name, which is not an object. The expected type of the object is not function, it's callable. So consider:
class Blog: pass
blog = log()
NameError: Python doesn't recognize the function "log". Did you mean "Blog"?
I suspect that might cause cognitive dissonance in a beginner who thinks of a class as a type or data structure and not as a function. And "doesn't recognize the callable" might be awkward (or beginners might get used to it very quickly, I don't know).
Also, how do you propose deciding on the alternative to suggest? In this particular case, I expect most developers would agree intuitively. But the Hamming distance is pretty large: 3 of a length of 6. Would you have a dictionary of common errors, and then scan the namespace for minimum Hamming distance among defined names with the right type of value?
How about:
class Blog: pass
blog = get_blog_for_date(someday)
logn = log(blog.size)
NameError: Python doesn't recognize the function "log". Did you mean "Blog"?
Wouldn't
NameError: Python doesn't recognize the name "log". Perhaps you need to import the "math" module?
be a better message here? On second thought, that might imply that calling with the unqualified name is generally the best style, and teach the beginner to insert
from math import *
at the top of the module, thus fixing all such errors. We probably don't want that, so maybe
NameError: Python doesn't recognize the name "log". There are functions named "log" in the "math" module and the "cmath" module.
would be better yet.
I definitely agree that there are times when Python's error messages are quite impenetrable for the beginner, and improvement is desirable. I think that I would probably attack this by looking at the builtin namespace and a few stdlib namespaces (math, string, and maybe cmath come immediately to mind), and create a dictionary of "intuitive beginner errors". Then trap NameErrors, and preferentially emit the message from the dictionary on exact matches. Actually, come to think of it, two dictionaries, one for the builtin namespace, one for the selected stdlib, and the following heuristic:
if name in common_builtin_typos: emit(common_builtin_typos[name]) else: errors = small_hamming_distance(name, current_namespace, syntax(name)) if errors: emit(errors) else: errors = exact_matches_in_imported_modules(name) if errors: emit(errors) elif name in common_unimported_stdlib_names: emit(common_unimported_stdlib_names[name]) else: emit(error_you_would_have_emitted_anyway)
In other words, I don't see a good systematic way to go about this, just pile up heuristics (and maybe remove some as they prove unuseful!)
Steve
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On 30 November 2016 at 02:14, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
How about:
class Blog: pass
blog = get_blog_for_date(someday)
logn = log(blog.size)
NameError: Python doesn't recognize the function "log". Did you mean "Blog"?
Wouldn't
NameError: Python doesn't recognize the name "log". Perhaps you need to import the "math" module?
... and of course up until this example, I'd assumed you were talking about the log function from the logging module :-) I'm a strong +1 on better error messages, but there's always a risk with heuristics that the resulting messages end up worse, not better. Maybe keep it simpler: NameError: Python doesn't recognize the name "log". Maybe you misspelled the name, or did you mean to import the function from a module? and don't try to guess the user's intent. Paul
On 30 November 2016 at 19:05, Paul Moore <p.f.moore@gmail.com> wrote:
On 30 November 2016 at 02:14, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Wouldn't
NameError: Python doesn't recognize the name "log". Perhaps you need to import the "math" module?
... and of course up until this example, I'd assumed you were talking about the log function from the logging module :-)
I'm a strong +1 on better error messages, but there's always a risk with heuristics that the resulting messages end up worse, not better.
Maybe keep it simpler:
NameError: Python doesn't recognize the name "log". Maybe you misspelled the name, or did you mean to import the function from a module?
and don't try to guess the user's intent.
This brings up a point that I was going to mention earlier: when it comes to specialised learning environments, the folks developing the curriculum also know *what problem the student is working on*, and can tailor their error messages accordingly. The reference interpreter is never going to be able to guess intent like that due to the sheer scope of Python's use cases - by covering everything from students writing "Guess a number" games to mechanical engineers modeling and tuning race car performance to sysadmins automating service deployments to web developers responding to user requests to data analysts trying to make sense of noisy data, we end up being *really* limited in the assumptions we can make about what a user was really trying to do when they accidentally ask for something nonsensical. Tweaking some of the default representations to mention common problems should be OK, though. While some veteran programmers may find such prompts a bit condescending, they'd be better equipped than beginners to opt in to alternative exception display options that omit the hints. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Thanks for all of the thoughtful replies (and for moving to a more useful subject line). <rant> There is currently a big push towards teaching coding and computational thinking to school students, but a lack of skilled teachers to actually be able to support this, and I don't see any initiatives that will address this in a long-term, large-scale fashion (I'm speaking primarily from an Australian perspective, and might be misreading the situation in other countries). It's worth considering a classroom where the teacher has minimal experience in programming, and a portion of the students have low confidence in computing matters. Anything that will empower either the teacher or the students to get past a block will be useful here; and error messages are, in my experience as a teacher, one of more threatening parts of Python for the beginner. </rant> A few clarifications and thoughts arising from the discussion: - I personally find the current error messages quite useful, and they have the advantage of being machine-parseable, so that IDEs such as PyCharm can add value to them. However, the audience of this idea is not me, and probably not you. It is students who are learning Python, and probably haven't done any programming at all. But it might also be casual programmers who never really look at error message as they are too computer-y. - Learning how to parse an error message is a very valuable skill for a programmer to learn. However, I believe that should come later on in their journey. A technical error message when a student is starting out can be a bit overwhelming to some learners, who are already taking in a lot of information. - I'm not suggesting this should become part of the normal operation of Python, particularly if that breaks compatibility or impacts performance. A switch, or a seperate executable would probably work. I'd lean against the idea of tying this to a particular IDE/environment, but if that's the way this can progress, then let's do that to get it moving. However, it has to be dead simple to get it running. - I think this is necessary for scripts as well as the REPL (also other envs like Jupyter notebooks). - It will be almost impossible to deal with all cases, but that isn't the point here. The trick would be to find the most common errors that a beginning programmer will make, find the most common fixes, and provide them as hints, or suggestions. - The examples listed in my original email are simply ideas, without much thought about how feasible (or useful) they are to implement. Going forward, we would identify common errors that beginners make, and what would help them fix these errors. -- Victor Rajewski
On Mon, Dec 5, 2016 at 10:15 AM, victor rajewski <askvictor@gmail.com> wrote:
There is currently a big push towards teaching coding and computational thinking to school students, but a lack of skilled teachers to actually be able to support this, and I don't see any initiatives that will address this in a long-term, large-scale fashion (I'm speaking primarily from an Australian perspective, and might be misreading the situation in other countries). It's worth considering a classroom where the teacher has minimal experience in programming, and a portion of the students have low confidence in computing matters. Anything that will empower either the teacher or the students to get past a block will be useful here; and error messages are, in my experience as a teacher, one of more threatening parts of Python for the beginner.
While I fully support enhancements to error messages (and the possibility of a "programming student" mode that assumes a novice and tweaks the messages accordingly), I don't think it's right to aim at a classroom where *the teacher* doesn't have sufficient programming skills. Would you build a pocket calculator so it can be used in a classroom where even the teacher doesn't know about division by zero? Would you design a violin so a non-musician can teach its use? IMO the right way to teach computer programming is for it to be the day job for people who do all their programming in open source and/or personal projects. There are plenty of people competent enough to teach programming and would benefit from a day job. Design the error messages to minimize the load on the room's sole expert, but assume that there'll always be someone around who can deal with the edge cases. In other words, aim for the 90% or 95%, rather than trying to explain 100% of situations. ChrisA
Chris Angelico writes:
On Mon, Dec 5, 2016 at 10:15 AM, victor rajewski <askvictor@gmail.com> wrote:
There is currently a big push towards teaching coding and computational thinking to school students, but a lack of skilled teachers to actually be able to support this, and I don't see any initiatives that will address this in a long-term, large-scale fashion (I'm speaking primarily from an Australian perspective, and might be misreading the situation in other countries). It's worth considering a classroom where the teacher has minimal experience in programming, and a portion of the students have low confidence in computing matters. Anything that will empower either the teacher or the students to get past a block will be useful here; and error messages are, in my experience as a teacher, one of more threatening parts of Python for the beginner.
While I fully support enhancements to error messages (and the possibility of a "programming student" mode that assumes a novice and tweaks the messages accordingly), I don't think it's right to aim at a classroom where *the teacher* doesn't have sufficient programming skills.
That's not exactly what he said. High school math teachers are likely to be the product of education schools, and may be highly skilled in building PowerPoint presentations, and have some experience in programming, but not as a professional. But nobody expects David Beazley at Pigsty High! So I can easily imagine a teacher responsible for several classes of 40 students for 2 hour-long sessions a week per class, who is unable to "interpret at a glance" many error messages produced by the Python interpreter. This is basically the "aim for 90%" approach you describe, and Victor admits that's the best we can do. And, realistically, in today's ed systems there *will* be teachers far below the level you advocate.
IMO the right way to teach computer programming is for it to be the day job for people who do all their programming in open source and/or personal projects. There are plenty of people competent enough to teach programming and would benefit from a day job.
I don't know where you live, but in both of my countries there is a teacher's union to ensure that nobody without an Ed degree gets near a classroom. More precisely, volunteers under the supervision of somebody with professional teaching credentials, yes, day job, not in this century. And "teaching credentials" == degree from a state- certified 4-year Ed program, not something you can get at a community college in an adult ed program. (Japan is somewhat more lenient than that, but you do need a 4 year degree and a truckload of credits in ed courses -- and it's not a career-track job.)
Design the error messages to minimize the load on the room's sole expert, but assume that there'll always be someone around who can deal with the edge cases. In other words, aim for the 90% or 95%, rather than trying to explain 100% of situations.
I think we all agree on that being the best approach.
Chris Angelico writes:
On Mon, Dec 5, 2016 at 10:15 AM, victor rajewski <askvictor@gmail.com> wrote:
There is currently a big push towards teaching coding and computational thinking to school students, but a lack of skilled teachers to actually be able to support this, and I don't see any initiatives that will address this in a long-term, large-scale fashion (I'm speaking primarily from an Australian perspective, and might be misreading the situation in other countries). It's worth considering a classroom where the teacher has minimal experience in programming, and a portion of the students have low confidence in computing matters. Anything that will empower either the teacher or the students to get past a block will be useful here; and error messages are, in my experience as a teacher, one of more threatening parts of Python for the beginner.
While I fully support enhancements to error messages (and the possibility of a "programming student" mode that assumes a novice and tweaks the messages accordingly), I don't think it's right to aim at a classroom where *the teacher* doesn't have sufficient programming skills.
That's not exactly what he said. High school teachers are likely to be the product of education schools, and may be highly skilled in building PowerPoint presentations, and have some experience in programming, but not as a professional. So I can easily imagine a teacher responsible for several classes of 40 students for 2 hour-long sessions a week per class, and not being able to "interpret at a glance" many error messages produced by the Python interpreter. This is basically the "aim for 90%" approach you describe, and he admits that's the best we can do.
IMO the right way to teach computer programming is for it to be the day job for people who do all their programming in open source and/or personal projects. There are plenty of people competent enough to teach programming and would benefit from a day job.
I don't know where you live, but in both of my countries there is a teacher's union to ensure that nobody without an Ed degree gets near a classroom. More precisely, volunteers under the supervision of somebody with professional teaching credentials, yes, day job, not in this century. And "teaching credentials" == degree from a state- certified 4-year Ed program, not something you can get at a community college in an adult ed program.
Design the error messages to minimize the load on the room's sole expert, but assume that there'll always be someone around who can deal with the edge cases. In other words, aim for the 90% or 95%, rather than trying to explain 100% of situations.
I think we all agree on that.
On Mon, Dec 5, 2016 at 12:40 PM, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
That's not exactly what he said. High school teachers are likely to be the product of education schools, and may be highly skilled in building PowerPoint presentations, and have some experience in programming, but not as a professional. So I can easily imagine a teacher responsible for several classes of 40 students for 2 hour-long sessions a week per class, and not being able to "interpret at a glance" many error messages produced by the Python interpreter. This is basically the "aim for 90%" approach you describe, and he admits that's the best we can do.
Okay, then I misinterpreted. Seems we are indeed in agreement. Sounds good!
IMO the right way to teach computer programming is for it to be the day job for people who do all their programming in open source and/or personal projects. There are plenty of people competent enough to teach programming and would benefit from a day job.
I don't know where you live, but in both of my countries there is a teacher's union to ensure that nobody without an Ed degree gets near a classroom. More precisely, volunteers under the supervision of somebody with professional teaching credentials, yes, day job, not in this century. And "teaching credentials" == degree from a state- certified 4-year Ed program, not something you can get at a community college in an adult ed program.
Sadly, that's probably true here in Australia too, but I don't know for sure. I have no specific qualifications, but I teach online; it's high time the unions got broken IMO... but that's outside the scope of this. If it takes a credentialed teacher to get a job in a school, so be it - but at least make sure it's someone who knows how to interpret the error messages, so that any student who runs into trouble can ask the prof. ChrisA
On 5 December 2016 at 12:35, Chris Angelico <rosuav@gmail.com> wrote:
On Mon, Dec 5, 2016 at 12:40 PM, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
I don't know where you live, but in both of my countries there is a teacher's union to ensure that nobody without an Ed degree gets near a classroom. More precisely, volunteers under the supervision of somebody with professional teaching credentials, yes, day job, not in this century. And "teaching credentials" == degree from a state- certified 4-year Ed program, not something you can get at a community college in an adult ed program.
Sadly, that's probably true here in Australia too, but I don't know for sure. I have no specific qualifications, but I teach online; it's high time the unions got broken IMO... but that's outside the scope of this. If it takes a credentialed teacher to get a job in a school, so be it - but at least make sure it's someone who knows how to interpret the error messages, so that any student who runs into trouble can ask the prof.
Graduate diplomas in Education in Australia are one- or two-year certificate programs, and some state level industry-to-education programs aim to get folks into the classroom early by offering pre-approvals for teaching subjects specifically related to their area of expertise. However, the main problem isn't the credentials, and it's definitely not unions, it's the fact that professional software developers have a lot of options open to them both locally and globally, and "empower the next generation to be the managers of digital systems rather than their servants" has a lot of downsides compared to the alternatives (most notably: you'll get paid a lot more in industry than you will as a teacher, so opting for teaching as a change in career direction here will necessarily be a lifestyle choice based on the non-monetary factors. That's not going to change as long as people assume that teaching is easy and/or not important). That means that we're not at a point in history where we can assume that teachers are going to be more computationally literate than their students - instead, we need to assume that many of the teachers involved will themselves be new to the concepts being taught and work on empowering them *anyway*. I just don't personally think that's feasible on a volunteer basis - you need professional service providers that are familiar not only with the specific concepts and technologies being taught, but also with the bureaucratic context that the particular schools and teachers they serve have to work within. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Sun, Dec 4, 2016 at 6:35 PM, Chris Angelico <rosuav@gmail.com> wrote:
I have no specific qualifications, but I teach online;
nor do I, and I teach for a continuing ed program -- not in high school. But anyway, regardless of official qualifications, good programmers are not neccesray good teachers of programming. At all. If it takes a credentialed teacher to get a job in a school, so
be it - but at least make sure it's someone who knows how to interpret the error messages, so that any student who runs into trouble can ask the prof.
Exactly -- you can't be credentialed to teach Biology, or French, or.... without knowing the subject. That may not yet be true for computer science, as it is still "new" in high school curriculum, but it's still not Python's job to overcome that. All the being said -- I don't think we should try to tailor error messages specifically for newbies in the core interpreter, and the error messages have gotten a lot better with py3, but they could still use some improvement -- I would say that suggestions are welcome. And if they can be made (more) machine readable, so that an beginners IDE would enhance them, that would be great. -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
Note that there is a draft pep https://www.python.org/dev/peps/pep-0473/ that aims at adding structured data to bultin exceptions. I've tried implementing some of those but had a couple of test failures that weren't obvious to me how to solve. On Dec 11, 2016 13:11, "Chris Barker" <chris.barker@noaa.gov> wrote:
On Sun, Dec 4, 2016 at 6:35 PM, Chris Angelico <rosuav@gmail.com> wrote:
I have no specific qualifications, but I teach online;
nor do I, and I teach for a continuing ed program -- not in high school.
But anyway, regardless of official qualifications, good programmers are not neccesray good teachers of programming. At all.
If it takes a credentialed teacher to get a job in a school, so
be it - but at least make sure it's someone who knows how to interpret the error messages, so that any student who runs into trouble can ask the prof.
Exactly -- you can't be credentialed to teach Biology, or French, or.... without knowing the subject. That may not yet be true for computer science, as it is still "new" in high school curriculum, but it's still not Python's job to overcome that.
All the being said -- I don't think we should try to tailor error messages specifically for newbies in the core interpreter, and the error messages have gotten a lot better with py3, but they could still use some improvement -- I would say that suggestions are welcome.
And if they can be made (more) machine readable, so that an beginners IDE would enhance them, that would be great.
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On 11 December 2016 at 19:09, Sebastian Kreft <skreft@gmail.com> wrote:
Note that there is a draft pep https://www.python.org/dev/peps/pep-0473/ that aims at adding structured data to bultin exceptions.
I've tried implementing some of those but had a couple of test failures that weren't obvious to me how to solve.
If you haven't already, note that it's OK to post proposed patches to the tracker even when they're still causing test failures - just note that you know the patch is incomplete, and explain the errors that you're seeing. Core developers will often be able to spot relevant problems through code review, and we're also pretty practiced at interpreting the sometimes cryptic failures that the test suite can emit. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
victor rajewski writes:
- I personally find the current error messages quite useful, and they have the advantage of being machine-parseable, so that IDEs such as PyCharm can add value to them. However, the audience of this idea is not me, and probably not you. It is students who are learning Python, and probably haven't done any programming at all. But it might also be casual programmers who never really look at error message as they are too computer-y.
That's a misconception. You have not yet given up on a change to the Python interpreter, so the audience is *every* user of the Python interpreter (including other programs), and that's why you're getting pushback. The Python interpreter's main job is to execute code. A secondary job is provide *accurate* diagnostics of errors in execution. Interpreting those diagnostics is somebody else's job, typically the programmer's. For experienced programmers, that's usually what you want, because (1) the interpretation is frequently data-dependent and (2) the "obvious" suggestion may be wrong. FYI, a *lot* of effort has gone into making error messages more precise, more accurate, and more informative, eg, by improving stack traces. OTOH, if the diagnostics are accurate and machine-parsable, then the amount of annoying detail that needs to be dealt with in providing a "tutorial" front-end for those messages is small. That suggests to me that the problem really is that interpreting errors, even in "student" programs, is *hard* and rules of thumb are frequently mistaken. That's an excellent tradeoff if there's a teacher looking over the (student) programmer's shoulder. Not a good idea for the interpreter.
- I'm not suggesting this should become part of the normal operation of Python, particularly if that breaks compatibility or impacts performance. A switch, or a seperate executable would probably work. I'd lean against the idea of tying this to a particular IDE/environment, but if that's the way this can progress, then let's do that to get it moving.
It really should be a separate executable. There are multiple implementations of Python, and even restricted to CPython, with even a small amount of uptake this project will move a *lot* faster than CPython does. Every tiny change to the "better living through better errors" database makes a difference to all the students out there, so its release cycle should probably be really fast.
- The examples listed in my original email are simply ideas, without much thought about how feasible (or useful) they are to implement. Going forward, we would identify common errors that beginners make, and what would help them fix these errors.
In other words, you envision a long-term project with an ongoing level of effort. I think that it's worth doing. But I also think it's quite feasible to put it in a separate project, with cooperation from Python-Dev in the matter of ensuring that diagnostics are machine- parseable. Eg, this means that Python-Dev should not randomly change messages that are necessary to interpret an Exception, and in some cases it may be useful to add Exception/Error subtypes to make interpretation more precise (though this will often get pushback).
On 5 December 2016 at 09:15, victor rajewski <askvictor@gmail.com> wrote:
<rant> There is currently a big push towards teaching coding and computational thinking to school students, but a lack of skilled teachers to actually be able to support this, and I don't see any initiatives that will address this in a long-term, large-scale fashion (I'm speaking primarily from an Australian perspective, and might be misreading the situation in other countries). It's worth considering a classroom where the teacher has minimal experience in programming, and a portion of the students have low confidence in computing matters. Anything that will empower either the teacher or the students to get past a block will be useful here; and error messages are, in my experience as a teacher, one of more threatening parts of Python for the beginner. </rant>
Hi Victor, I'm one of the co-coordinators of the PyCon Australia Education Seminar, and agree entirely with what you say here. However, it isn't a problem that *python-dev* is well-positioned to tackle. Rather, it requires ongoing attention from vendors, volunteers and non-profit organisations that are specifically focused on meeting the needs of the educational sector. So your goal is valid, it's only your current choice of audience that is slightly mistargeted. Within Australia specifically, the two main drivers of the improvements in Python's suitability for teachers are Grok Learning (who provide a subscription-based online learning environment directly to schools based on a service originally developed for the annual National Computer Science School) and Code Club Australia (the Australian arm of a UK-based non-profit aimed at providing support for after-school code clubs around Australia, as well as professional development opportunities for teachers needing to cope with the incoming Digital Technologies curriculum).
I'm not suggesting this should become part of the normal operation of Python, particularly if that breaks compatibility or impacts performance. A switch, or a seperate executable would probably work. I'd lean against the idea of tying this to a particular IDE/environment, but if that's the way this can progress, then let's do that to get it moving. However, it has to be dead simple to get it running.
The model adopted by Grok Learning and many other education focused service providers (codesters.com, etc) is to provide the learning environment entirely through the browser, as that copes with entirely locked down client devices, and only requires whitelisting of the vendor's site in the school's firewall settings. The only context where it doesn't work is when the school doesn't have reliable internet connectivity at all, in which case the cheap-dedicated-device model driven by the UK's Raspberry Pi Foundation may be a more suitable option.
It will be almost impossible to deal with all cases, but that isn't the point here. The trick would be to find the most common errors that a beginning programmer will make, find the most common fixes, and provide them as hints, or suggestions. The examples listed in my original email are simply ideas, without much thought about how feasible (or useful) they are to implement. Going forward, we would identify common errors that beginners make, and what would help them fix these errors.
Right, and the folks best positioned to identify those errors empirically, and also to make data-driven improvements based on the typical number of iterations needed for beginners to fix their own mistakes, are the educational service providers. Some of the more sophisticated providers (like Knewton in the US) are even able to adapt their curricula on the fly, offer learners additional problems in areas they seem to be struggling with. Don't get me wrong, there are definitely lots of areas where we can make the default error messages more beginner friendly just by providing relevant information that the interpreter has available, and this is important for helping out the teachers that *don't* have institutional mandates backing them up. But for cases like the Australian Digital Curriculum, it makes sense for schools to look into the local service providers rather than asking teachers to make do with what they can download from the internet (while the latter option is viable in some cases, it really does require a high level of technical skill on the teacher's part) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Hi, Python is optimized for performance. Formatting an error message has a cost on performances. I suggest you to teach your student to use the REPL and use a custom exception handler: sys.excepthook: https://docs.python.org/2/library/sys.html#sys.excepthook Using a custom exception handler, you can run expensive functions, like the feature: "suggest len when length is used". The problem is then when students have to use a Python without the custom exception handler. Victor
The existing docs for errors and exceptions: - https://docs.python.org/2/library/exceptions.html - https://docs.python.org/3/library/exceptions.html - https://hg.python.org/cpython/file/tip/Doc/library/exceptions.rst - https://github.com/python/cpython/blob/master/Doc/library/exceptions.rst - https://docs.python.org/2/tutorial/errors.html - https://docs.python.org/3/tutorial/errors.html - https://hg.python.org/cpython/file/tip/Doc/tutorial/errors.rst - https://github.com/python/cpython/blob/master/Doc/tutorial/errors.rst - https://www.tutorialspoint.com/python/python_exceptions.htm - If the docs don't answer the question (and match to the search terms), they probably should. - [ ] DOC: something about why "except Exception: pass" is usually bad - [ ] DOC: something about SystemExit and atexit: https://docs.python.org/2/library/atexit.html You can get alot more traceback from pytest (w/ pytest-sugar) and/or nose (with nose-progressive). There is extra information in the stack at exception time; but, IIUC, it would take a number of subclasses with class-specific docs and/or class introspection to be as detailed as "you probably wanted .append there because this is a List and the length is n but the key was". Maybe a "learning mode" which automatically calls inspect.getdoc() on Exception would be useful (sys.excepthook)? Practically, I usually just open an extra IPython shell and run `list.append?` for docs or `list.append??` for (Python but not C!) source (inspect.getsource). IPython also prints the function signature with `?` The pdb++ debugger requires funcsigs in order to print function signatures. If pdb++ is installed, it preempts the standard pdb module; so `nosetests --pdb` and `pytest --pdb` launch pdb++ when an error or exception is raised. https://pypi.python.org/pypi/pdbpp/ http://nose.readthedocs.io/en/latest/plugins/debug.html http://doc.pytest.org/en/latest/usage.html https://docs.python.org/2/library/inspect.html Exceptions could be better someday. Testing (and debugging) skills are always good to learn; coincidentally, there are many great tools for it. ... https://westurner.org/wiki/awesome-python-testing#debugging On Tuesday, November 29, 2016, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
I suggest you to teach your student to use the REPL and use a custom exception handler: sys.excepthook: https://docs.python.org/2/library/sys.html#sys.excepthook
Using a custom exception handler, you can run expensive functions, like the feature: "suggest len when length is used".
The problem is then when students have to use a Python without the custom exception handler.
Victor _______________________________________________ Python-ideas mailing list Python-ideas@python.org <javascript:;> https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Tuesday, November 29, 2016, Wes Turner <wes.turner@gmail.com> wrote:
The existing docs for errors and exceptions:
- https://docs.python.org/2/library/exceptions.html - https://docs.python.org/3/library/exceptions.html - https://hg.python.org/cpython/file/tip/Doc/library/exceptions.rst - https://github.com/python/cpython/blob/master/Doc/library/exceptions.rst
- https://docs.python.org/2/tutorial/errors.html - https://docs.python.org/3/tutorial/errors.html - https://hg.python.org/cpython/file/tip/Doc/tutorial/errors.rst - https://github.com/python/cpython/blob/master/Doc/tutorial/errors.rst
- https://www.tutorialspoint.com/python/python_exceptions.htm
- If the docs don't answer the question (and match to the search terms), they probably should.
- [ ] DOC: something about why "except Exception: pass" is usually bad - [ ] DOC: something about SystemExit and atexit: https://docs.python. org/2/library/atexit.html
You can get alot more traceback from pytest (w/ pytest-sugar) and/or nose (with nose-progressive).
There is extra information in the stack at exception time; but, IIUC, it would take a number of subclasses with class-specific docs and/or class introspection to be as detailed as "you probably wanted .append there because this is a List and the length is n but the key was".
Maybe a "learning mode" which automatically calls inspect.getdoc() on Exception would be useful (sys.excepthook)? Practically, I usually just open an extra IPython shell and run `list.append?` for docs or `list.append??` for (Python but not C!) source (inspect.getsource). IPython also prints the function signature with `?`
- [ ] How could I also print out type annotations w/ function signatures and docstrings?/??/??? https://github.com/python/typeshed/blob/master/stdlib/2/typing.pyi
The pdb++ debugger requires funcsigs in order to print function signatures. If pdb++ is installed, it preempts the standard pdb module; so `nosetests --pdb` and `pytest --pdb` launch pdb++ when an error or exception is raised.
https://pypi.python.org/pypi/pdbpp/
http://nose.readthedocs.io/en/latest/plugins/debug.html
http://doc.pytest.org/en/latest/usage.html
https://docs.python.org/2/library/inspect.html
Exceptions could be better someday. Testing (and debugging) skills are always good to learn; coincidentally, there are many great tools for it.
... https://westurner.org/wiki/awesome-python-testing#debugging
On Tuesday, November 29, 2016, Victor Stinner <victor.stinner@gmail.com <javascript:_e(%7B%7D,'cvml','victor.stinner@gmail.com');>> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
I suggest you to teach your student to use the REPL and use a custom exception handler: sys.excepthook: https://docs.python.org/2/library/sys.html#sys.excepthook
Using a custom exception handler, you can run expensive functions, like the feature: "suggest len when length is used".
The problem is then when students have to use a Python without the custom exception handler.
Victor _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me. Even IndexError I'm a bit skeptical about. I can believe that there's code that intentionally generates and then catches IndexError, but AttributeError in my experience is much more performance-sensitive than IndexError, because every failed hasattr call allocates an AttributeError and hasattr is commonly used for feature checks. Yet AttributeError has a much more informative (= expensive) message than IndexError: In [1]: object().a AttributeError: 'object' object has no attribute 'a' In [2]: list()[0] IndexError: list index out of range -n -- Nathaniel J. Smith -- https://vorpus.org
On Tuesday, November 29, 2016, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com <javascript:;>> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me.
Even IndexError I'm a bit skeptical about. I can believe that there's code that intentionally generates and then catches IndexError, but AttributeError in my experience is much more performance-sensitive than IndexError, because every failed hasattr call allocates an AttributeError and hasattr is commonly used for feature checks. Yet AttributeError has a much more informative (= expensive) message than IndexError:
In [1]: object().a AttributeError: 'object' object has no attribute 'a'
In [2]: list()[0] IndexError: list index out of range
https://docs.python.org/2/tutorial/datastructures.html#more-on-lists https://docs.python.org/2/c-api/list.html#c.PyList_SetItem https://github.com/python/cpython/search?utf8=✓&q=PyList_SetItem - https://github.com/python/cpython/blob/master/Include/listobject.h - https://github.com/python/cpython/blob/master/Objects/listobject.c#L208 - https://hg.python.org/cpython/file/tip/Objects/listobject.c#l208 https://docs.python.org/3/library/collections.abc.html#collections-abstract-... - list (typeshed: List) - Sequence - MutableSequence - It would be great if these continue to match: https://www.google.com/search?q=IndexError%3A+list+index+out+of+range
-n
-- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Python-ideas mailing list Python-ideas@python.org <javascript:;> https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On 29 November 2016 at 20:38, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me.
Right, we generally treat error message formatting code as being off the critical performance path. In many (most?) cases, the instances of uninformative error message are just a symptom of the code in question being really *old*, such that it predates the great many improvements made to the low level error reporting machinery over the years. That's not always true (e.g. parser errors are uninformative because the parser doesn't keep track of the state needed to generate nicer messages), but it seems to typically be true for runtime errors where we don't even report the type or representation of a misbehaving value. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Tue, Nov 29, 2016 at 5:48 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
SyntaxErrors in an inner loop? That seems unlikely to me.
Syntax Errors are a special case, as by definition the code isn't being run yet (yes, there could be an eval in there...) So we could at least make those more informative without worrying about performance. Also -- would it be possible to tack on the more informative message at a higher level? Once the Exception bubbles up to the REPL, is there enough information available to make a more informative message? -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
I would consider the speed of the "ultimate error handler" (i.e. whatever prints the traceback and kills the program) in the interpreter to be moot, so long as it takes a small fraction of a second. Optimizing Python's speed it crashes super-fast due to an *unhandled* NameError in your program seems folly. Regarding more informative messages for (e.g.) IndexError, would those just apply to built-in types as they're the most universal, or should some additional introspection be done for similar ducks? If it's useful/there's interest, I could try to do some analysis of Python questions on SO and see what the most common errors are. I'd guess things like "'NoneType' object has no attribute ..." would probably be up there, but that's a whole can of worms as to why someone's trying to call a method on, index, etc. something they accidentally whacked (a = a.sort()). On Tue, Nov 29, 2016 at 11:42 AM, Chris Barker <chris.barker@noaa.gov> wrote:
On Tue, Nov 29, 2016 at 5:48 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
SyntaxErrors in an inner loop? That seems unlikely to me.
Syntax Errors are a special case, as by definition the code isn't being run yet (yes, there could be an eval in there...)
So we could at least make those more informative without worrying about performance.
Also -- would it be possible to tack on the more informative message at a higher level? Once the Exception bubbles up to the REPL, is there enough information available to make a more informative message?
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, 29 Nov 2016 at 10:28 Nick Timkovich <prometheus235@gmail.com> wrote:
I would consider the speed of the "ultimate error handler" (i.e. whatever prints the traceback and kills the program) in the interpreter to be moot, so long as it takes a small fraction of a second. Optimizing Python's speed it crashes super-fast due to an *unhandled* NameError in your program seems folly.
So the performance worry isn't the traceback printer once the call stack fully unwinds but the construction of the exception instance itself. E.g. having to construct an expensive string for every instance of AttributeError is more the worry than printing a traceback.
Regarding more informative messages for (e.g.) IndexError, would those just apply to built-in types as they're the most universal, or should some additional introspection be done for similar ducks?
If it's useful/there's interest, I could try to do some analysis of Python questions on SO and see what the most common errors are. I'd guess things like "'NoneType' object has no attribute ..." would probably be up there, but that's a whole can of worms as to why someone's trying to call a method on, index, etc. something they accidentally whacked (a = a.sort()).
I suspect if we decide to try and go with more informative messages with a solution people are happy with then having an idea of where people get tripped up regularly will be good to help focus the work. And as for the NoneType issue specifically, there's an issue for that: http://bugs.python.org/issue28702 .
On Tue, Nov 29, 2016 at 11:42 AM, Chris Barker <chris.barker@noaa.gov> wrote:
On Tue, Nov 29, 2016 at 5:48 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
SyntaxErrors in an inner loop? That seems unlikely to me.
Syntax Errors are a special case, as by definition the code isn't being run yet (yes, there could be an eval in there...)
So we could at least make those more informative without worrying about performance.
Also -- would it be possible to tack on the more informative message at a higher level? Once the Exception bubbles up to the REPL, is there enough information available to make a more informative message?
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, 29 Nov 2016 at 02:39 Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me.
Even IndexError I'm a bit skeptical about. I can believe that there's code that intentionally generates and then catches IndexError, but AttributeError in my experience is much more performance-sensitive than IndexError, because every failed hasattr call allocates an AttributeError and hasattr is commonly used for feature checks. Yet AttributeError has a much more informative (= expensive) message than IndexError:
In [1]: object().a AttributeError: 'object' object has no attribute 'a'
In [2]: list()[0] IndexError: list index out of range
One way to make this cheap is to have a reasonable default message and use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError ( http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception.
On 2016-11-29 09:43, Brett Cannon wrote:
One way to make this cheap is to have a reasonable default message and use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError (http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception.
I absolutely think this is the way to go. Having the relevant information (the list that was too short, the index that was too big, the key that wasn't there, etc.) is useful in many situations, and it's much better to have that information in a programmatic form than just squashed into an error message. This then makes it relatively easy to write wrappers that take bubbling-up exceptions and try to construct more detailed messages for a less experienced audience. Right now this is difficult or impossible because the exception objects don't record the information that would be needed for these expanded messages. -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown
On 2016-11-29 19:45, Brendan Barnwell wrote:
On 2016-11-29 09:43, Brett Cannon wrote:
One way to make this cheap is to have a reasonable default message and use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError (http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception.
I absolutely think this is the way to go. Having the relevant information (the list that was too short, the index that was too big, the key that wasn't there, etc.) is useful in many situations, and it's much better to have that information in a programmatic form than just squashed into an error message. This then makes it relatively easy to write wrappers that take bubbling-up exceptions and try to construct more detailed messages for a less experienced audience. Right now this is difficult or impossible because the exception objects don't record the information that would be needed for these expanded messages.
Couldn't that result in objects being held for longer, taking up memory, not being collected as promptly, and not releasing resources as quickly?
On Tue, 29 Nov 2016 at 12:32 MRAB <python@mrabarnett.plus.com> wrote:
On 2016-11-29 19:45, Brendan Barnwell wrote:
On 2016-11-29 09:43, Brett Cannon wrote:
One way to make this cheap is to have a reasonable default message and use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError (http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception.
I absolutely think this is the way to go. Having the relevant information (the list that was too short, the index that was too big, the key that wasn't there, etc.) is useful in many situations, and it's much better to have that information in a programmatic form than just squashed into an error message. This then makes it relatively easy to write wrappers that take bubbling-up exceptions and try to construct more detailed messages for a less experienced audience. Right now this is difficult or impossible because the exception objects don't record the information that would be needed for these expanded messages.
Couldn't that result in objects being held for longer, taking up memory, not being collected as promptly, and not releasing resources as quickly?
Sure, just like passing any other object into BaseException's initializer so it gets stored in the args attribute. Notice how my example only used ints, and that was on purpose. If you want to only pass in the repr of the type for the message, then simply enforce that or at least encourage it to prevent/discourage people from using whole objects instead of ints and strings which are cheaper than the whole string message that is currently constructed eagerly.
On Nov 29, 2016 9:43 AM, "Brett Cannon" <brett@python.org> wrote:
On Tue, 29 Nov 2016 at 02:39 Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me.
Even IndexError I'm a bit skeptical about. I can believe that there's code that intentionally generates and then catches IndexError, but AttributeError in my experience is much more performance-sensitive than IndexError, because every failed hasattr call allocates an AttributeError and hasattr is commonly used for feature checks. Yet AttributeError has a much more informative (= expensive) message than IndexError:
In [1]: object().a AttributeError: 'object' object has no attribute 'a'
In [2]: list()[0] IndexError: list index out of range
One way to make this cheap is to have a reasonable default message and
use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError (http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception. It seems like this might need some care, though, to make sure that these extra attributes don't end up pinning objects in memory that shouldn't be? Actually I always assumed that was why AttributeError's message was constructed eagerly... -n
I actually thought about adding 'Exception.__hint__' attribute which would have a longer message explaining what happened and how to fix it. displayhooks can be easily modified to print __hint__ when it's set. We can then add C API to set hints. To address any possible performance concerns, we can disable hints in -O mode (essentially we can make them almost zero-cost). Yury On 2016-11-29 12:43 PM, Brett Cannon wrote:
On Tue, 29 Nov 2016 at 02:39 Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Nov 29, 2016 at 1:05 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances. Sure, but we have to look at this on a case-by-case basis. Is there really important code out there that's generating NameErrors or SyntaxErrors in an inner loop? That seems unlikely to me.
Even IndexError I'm a bit skeptical about. I can believe that there's code that intentionally generates and then catches IndexError, but AttributeError in my experience is much more performance-sensitive than IndexError, because every failed hasattr call allocates an AttributeError and hasattr is commonly used for feature checks. Yet AttributeError has a much more informative (= expensive) message than IndexError:
In [1]: object().a AttributeError: 'object' object has no attribute 'a'
In [2]: list()[0] IndexError: list index out of range
One way to make this cheap is to have a reasonable default message and use attributes on the exceptions trigger the use of the default message. Nearly a year ago I filed a bunch of issues for ideas on providing attributes on exceptions where it made sense, e.g. an index attribute on IndexError ( http://bugs.python.org/issue18162). If we did this then for classes like IndexError there constructor could be `IndexError(index=10, start=0, end=3)` and then __str__() can lazily construct the string representation using a default message, e.g. `"index {} is out of range of{} to {}".format(index, start, end)`. Make the arguments keyword-only and they become backwards-compatible and so the only overhead you pay for these richer messages are keyword-based construction if you simply never access the repr for the exception.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Victor Stinner writes:
Using a custom exception handler, you can run expensive functions, like the feature: "suggest len when length is used".
LGTM.
The problem is then when students have to use a Python without the custom exception handler.
Put the exception handler in an importable module in the stdlib. Usual caveats about high bar, etc, but this should solve the "have Python, no handler" issue going forward. Steve
On Tuesday, November 29, 2016 at 4:08:19 AM UTC-5, Victor Stinner wrote:
Hi,
Python is optimized for performance. Formatting an error message has a cost on performances.
Usually, when an exception is hit that will (probably) crash the program, no one cares about less than a microsecond of performance.
I suggest you to teach your student to use the REPL and use a custom exception handler: sys.excepthook: https://docs.python.org/2/library/sys.html#sys.excepthook
Using a custom exception handler, you can run expensive functions, like the feature: "suggest len when length is used".
The problem is then when students have to use a Python without the custom exception handler.
Victor _______________________________________________ Python-ideas mailing list Python...@python.org <javascript:> https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On 12/24/2016 11:42 AM, Neil Girdhar wrote:
Usually, when an exception is hit that will (probably) crash the program, no one cares about less than a microsecond of performance.
I would probably agree with you in the SyntaxError example, but not for the others. Programming with exceptions is totally standard in Python and they are often used in tight loops. See here: https://docs.python.org/3/glossary.html#term-eafp https://docs.python.org/3/glossary.html#term-lbyl So keeping exceptions fast is definitely important. Cheers, Thomas
On 29/11/2016 04:58, victor rajewski wrote:
Traceback (most recent call last):
File "foo.py", line 2, in <module>
l[10]=14
IndexError: list assignment index out of range
A better message might be:
You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access.
It would make sense to me to upgrade this particular error message to IndexError: list assignment index 10 out of range 0 to 3 if it can be done without too much difficulty or overhead. (An empty list, and perhaps one with only 1 element, would be special cases.) Come to think of it, is the word "assignment" needed? Rob Cliffe
On 11/29/2016 11:32 AM, Rob Cliffe wrote:
On 29/11/2016 04:58, victor rajewski wrote:
Traceback (most recent call last):
File "foo.py", line 2, in <module>
l[10]=14
IndexError: list assignment index out of range
A better message might be:
You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access.
It would make sense to me to upgrade this particular error message to IndexError: list assignment index 10 out of range 0 to 3 if it can be done without too much difficulty or overhead. (An empty list, and perhaps one with only 1 element, would be special cases.) Come to think of it, is the word "assignment" needed?
It would help if the line were "l1[10] = 2 * l2[13] + 3". -- Terry Jan Reedy
On 29/11/2016 20:09, Terry Reedy wrote:
On 11/29/2016 11:32 AM, Rob Cliffe wrote:
On 29/11/2016 04:58, victor rajewski wrote:
Traceback (most recent call last):
File "foo.py", line 2, in <module>
l[10]=14
IndexError: list assignment index out of range
A better message might be:
You tried to use l[10] when l is only 4 elements long. You can add items to l using l.append(value), or check your index value to make sure that's really the position you wanted to access.
It would make sense to me to upgrade this particular error message to IndexError: list assignment index 10 out of range 0 to 3 if it can be done without too much difficulty or overhead. (An empty list, and perhaps one with only 1 element, would be special cases.) Come to think of it, is the word "assignment" needed?
It would help if the line were "l1[10] = 2 * l2[13] + 3".
You're right of course; "assignment" IS meaningful; I missed it.
[][0] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
participants (23)
-
Bernardo Sulzbach
-
Brendan Barnwell
-
Brett Cannon
-
Chris Angelico
-
Chris Barker
-
Mariatta Wijaya
-
Matthias Bussonnier
-
MRAB
-
Nathaniel Smith
-
Neil Girdhar
-
Nick Coghlan
-
Nick Timkovich
-
Paul Moore
-
Rob Cliffe
-
Sebastian Kreft
-
Stephen J. Turnbull
-
Terry Reedy
-
Thomas Nyberg
-
Todd
-
victor rajewski
-
Victor Stinner
-
Wes Turner
-
Yury Selivanov