5 ms·
His coding style is not common to most writers of Python. He's using overly terse, poorly descriptive variable names, not using multiline strings for docstring
by aaronchall 11y ago
His coding style is not common to most writers of Python.
He's using overly terse, poorly descriptive variable names, not using multiline strings for docstrings, not indenting where he should, and one-lining if/elif statements and function definitions. This style does not contribute to readability.
This is not how I would want someone just learning Python to learn it.
- gknoy 11y agoWhile that's true, he also tends to write fairly idiomatic Python -- using base data types a lot, list comprehensions, etc, and his comments and overall insight make them Very worthwhile to read -- especially once you're familiar enough reading it to recognize what he's doing. The spellchecker still blows my mind, and I don't yet understand the Sudoku puzzle. We can always take the code and re-format / re-name variables to aid our understanding.
- merlincorey 11y agoMaybe it's because I am also something of a lisper (like Norvig), but I don't see anything wrong with inline ifs (after all, that is how if works in lisp, with returns for a conditional, like the ternary operator) or lambda functions. In fact, I find that improves readability dramatically because it more declaratively says what you are trying to accomplish in many cases. For example: absolute_path = lambda path: path if path.startswith('/') else '/' + path To me this is perfectly clearly a simple function whose only purpose is to prepend forward slashes to unix-style paths. Is the following really so much more readable? def absolute_path(path): if not path.startswith('/'): path = '/' + path return path To my eyes and mind, the second example is not any more readable at the expense of several lines of code.
- aaronchall 11y agoThe former is absolutely identical (semantically) to the latter, with two exceptions: 1) the former function does not know its own name and 2) the latter function can (and should) be documented with a docstring. I find the latter eminently more readable, and I work daily in a code base under development by 3000 Python developers for over 5 years. Considering that the creator of the Python language considered getting rid of lambdas because they are essentially limited functions and thus violate Python's "one obvious way to do it" philosophy, I'd rather those learning Python to be shown the latter, rather than the former. From a development and version control perspective, as soon as the lambda function requires more than a simple expression, i.e. a compound statement (https://docs.python.org/2/reference/compound_stmts.html https://docs.python.org/2/reference/compound_stmts.html), you have to trash the whole line, instead of adding perhaps a single extra line of content.
- merlincorey 11y ago> The former is absolutely identical to the latter Oh, really? Let's compare: >>> absolute_0 = lambda path: path if path.startswith('/') else '/' + path >>> def absolute_1(path): ... '''Return the absolute unix path from a given path name''' ... if not path.startswith('/'): ... path = '/' + path ... return path >>> import dis >>> dis.dis(absolute_0) 2 0 LOAD_FAST 0 (path) 3 LOAD_ATTR 0 (startswith) 6 LOAD_CONST 1 ('/') 9 CALL_FUNCTION 1 12 POP_JUMP_IF_FALSE 19 15 LOAD_FAST 0 (path) 18 RETURN_VALUE >> 19 LOAD_CONST 1 ('/') 22 LOAD_FAST 0 (path) 25 BINARY_ADD 26 RETURN_VALUE >>> dis.dis(absolute_1) 4 0 LOAD_FAST 0 (path) 3 LOAD_ATTR 0 (startswith) 6 LOAD_CONST 1 ('/') 9 CALL_FUNCTION 1 12 POP_JUMP_IF_TRUE 28 5 15 LOAD_CONST 1 ('/') 18 LOAD_FAST 0 (path) 21 BINARY_ADD 22 STORE_FAST 0 (path) 25 JUMP_FORWARD 0 (to 28) 6 >> 28 LOAD_FAST 0 (path) 31 RETURN_VALUE These functions are actually not identical in their computation - only their result. > 1) the former function does not know its own name If you think that is really important (hint: it's not [from a lisper perspective, anyway]), Python thankfully allows you to do this: >>> absolute_0.__name__ '<lambda>' >>> absolute_0.__name__ = '<lambda "absolute_0">' >>> absolute_0.__name__ '<lambda "absolute_0">' > 2) the latter function can be documented with a docstring >>> absolute_0.__doc__ >>> absolute_0.__doc__ = 'Return the absolute unix path from a given path name' >>> help(absolute_0) Help on function <lambda "absolute_0">: <lambda "absolute_0">(path) Return the absolute unix path from a given path name Of course the only reason you can't put docstrings on a lambda function in python is because the forced indentation of code and implicit return with no indented block available is what Guido went with for Lambda. > Considering that the creator of the Python language considered getting rid of lambdas Guido is not a proponent of functional programming in general and claims that map, reduce, and filter are so much harder to understand than list comprehensions (which implement some common map, reduce, and filter, operations with special optimized syntax) that he tried to get them removed from the language too. Thankfully for us users of the language, this view did not win through and we can still use map, reduce, and filter in python, if we choose.
- srean 11y agoTo me the first is far more quicker to read and understand, and I am no lisper. There is something immediately gratifying about the first that I find missing in the more laborious ponderous prose of the latter.
- Xephyrous 11y agoI'd write that function like this: def absolute_path(path): if not path.startswith('/'): return '/' + path return path This way you don't have to keep track of mutating the path variable. I do find that more readable - it's clearer that there are two paths through the code. That said, this example is trivial enough that I'd probably do it with an inline if/else statement, although still probably not a lambda: def absolute_path(path): return path if path.startswith('/') else '/' + path This way it's more obvious at a glance that you're defining a function. It's easier to follow someone else's code if they generally adhere to standards, and Python is a very convention-oriented language.
- srean 11y agoWell, between a run of the mill programmer who happens to indent where he/she should vs Norvig, I will likely choose the latter If I could. Reminds me of that blog thread where this design pattern guru hemmed and hawed from his high horse over several posts about how to write constrained based solvers and still did not get to a piece of code that actually solved the problem, whereas Norvig just posted a simple solution. A few non-idiomatic indents here and there (although his style has never been a problem for me) are nothing really.
- vram22 11y ago>Well, between a run of the mill programmer who happens to indent where he/she should vs Norvig, I will likely choose the latter If I could. Right. >Reminds me of that blog thread where this design pattern guru hemmed and hawed from his high horse I read a similar story a while ago. Two programmers are given the task of writing a program for some non-trivial problem. One of them, Hoity Toity Harry, tries to apply many of the latest and greatest algorithms, techniques, paradigms, etc., to impress people (of course). The other, Down To Earth Dan, just strives for a good implementation, with reasonably good algorithms, etc. After a while, Dan finishes his program and does a test run. It works well enough for the task. Meanwhile, Harry is not even near to finishing his code, due to struggling with complexities of the techniques he has tried to use. The boss comes in, sees the results, and congratulates Down To Earth Dan. Hoity Toity Harry, of course, has to protest, trying to put down Down To Earth Dan's implementation, saying that it uses simple algorithms, etc., while his own code uses sophisticated, state of the art techniques. Dan replies: "Yes, I could also have used those things. But my program runs, and yours doesn't." Okay, I changed the programmers' names for fun and effect, but I really did read the story, in some good (and pragmatic) software book, a while ago.
- abecedarius 11y agoSpeaking of which, I once saw a user review of Norvig's book PAIP complaining about the unsophisticated code -- no monads, etc. (I forget what other patterns the reviewer wanted to see.)
- rectangletangle 11y agoI'm personally a fan of conditional expressions, they're easy to read IMO as long as you're not nesting them. For instance, I find this unnecessarily difficult to read. >>> 0 if True else 1 if True else 2 0 But breaking it up like this keeps it reasonably concise, while retaining readability. if True: a = 0 if True else 1 else: a = 2 print(a) They can also be combined with comprehensions, which can be useful. >>> import random >>> ['a' if random.choice((True, False)) else 'b' for _ in range(6)] ['a', 'a', 'a', 'a', 'a', 'b']