HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
Raymond Hettinger - Beyond PEP 8 -- Best practices for beautiful intelligible code - PyCon 2015

PyCon 2015 · Youtube · 269 HN points · 34 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention PyCon 2015's video "Raymond Hettinger - Beyond PEP 8 -- Best practices for beautiful intelligible code - PyCon 2015".
Youtube Summary
"Speaker: Raymond Hettinger

Distillation of knowledge gained from a decade of Python consulting, Python training, code reviews, and serving as a core developer. Learn to avoid some of the hazards of the PEP 8 style guide and learn what really matters for creating beautiful intelligible code.



Slides can be found at: https://speakerdeck.com/pycon2015 and https://github.com/PyCon/2015-slides"
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
To follow up on this, if you've got a spare hour, one of the python core developers has a great demo of how pep8 can sometimes be blinding to larger issues https://www.youtube.com/watch?v=wf-BqAjZb8M

That said, most of what pep8 says is great to follow in the vast majority of cases.

There can be a good intellectual challenge in refactoring code like that to be both efficient and readable (although at some extremes, and depending on the programming language, perhaps there'll be conflict between those two goals).

All the better if that refactoring is in a FOSS application/library to save other people the repeat effort (and potentially gather further improvements).

Your question reminded me of Raymond Hettinger's excellent 2015 PyCon talk about refactoring functional-but-messy Python code: https://www.youtube.com/watch?v=wf-BqAjZb8M

(as previously discussed on HN: https://news.ycombinator.com/item?id=10023818)

Jul 12, 2022 · 1 points, 0 comments · submitted by jka
For an alternative perspective, allow me to present some classic talks from Raymond Hettinger.

First, some generic tips on how to write Python code that's pleasant to work with: https://youtu.be/OSGv2VnC0go

And then this one digs more specifically into how not to write Python like it's Java, starting at 12:40 (with talking about why leading up to that): https://youtu.be/wf-BqAjZb8M

These are a few videos which present Pythonic style. They do not form a proper curriculum, but they are example-heavy and give a good insight to a very Pythonic mind.

1. Beyond PEP 8 https://www.youtube.com/watch?v=wf-BqAjZb8M

2. Transforming Code into Beautiful, Idiomatic Python https://www.youtube.com/watch?v=OSGv2VnC0go

Formatting and readability are two separate concepts (as other replies have pointed out). I'd like to specifically point to a fantastic example of what we mean when we say "readability": https://www.youtube.com/watch?v=wf-BqAjZb8M

Someone with readability in a language, who keeps up with the style recommendations, will generally produce code that is easier to read by other engineers.

> Ever start a new job with a bulk of code you didn't write? Worse, ever take over code written by novices who ignore common conventions?

Yes, I have seen lots of this in scientific computing. However, things like too many/not enough spaces, line widths, etc, are never a huge hindrance for me.

What does make code "hard to read" are things like bad and inconsistent variable/function/class names, bad inheritance practices, bad file organization, and not adhering to common language idioms. That stuff is rarely, if ever, caught by linters.

Great talk by Raymond Hettinger about this: https://www.youtube.com/watch?v=wf-BqAjZb8M

This is a good talk that demos NamedTuple: https://www.youtube.com/watch?v=wf-BqAjZb8M
Raymond Hettinger talks about this in "Beyond PEP8", which is one of my favorite conference talks

https://www.youtube.com/watch?v=wf-BqAjZb8M

sturadnidge
That talk is fantastic, and I don’t even write Python. Thanks for sharing!
None
None
May 24, 2021 · dec0dedab0de on Writing Pythonic Rust
Another by Raymond Hettinger that is fantastic.

Beyond PEP 8 -- Best practices for beautiful intelligible code - PyCon 2015

https://www.youtube.com/watch?v=wf-BqAjZb8M

kzrdude
This is the best one :)
This isn't what you asked for, but any time I need to explain to somebody what good code review is, I just tell them to watch this video[0]: "Beyond PEP8 - Best practices for beautiful intelligible code" by Raymond Hettinger.

[0]: https://www.youtube.com/watch?v=wf-BqAjZb8M

How to write idiomatic Python? This talk is often recommended: https://www.youtube.com/watch?v=wf-BqAjZb8M
>Can you think of another where the author goes from mistake to mistake and then finally gets it right?

Not a book, but Raymond Hettinger often presents in this way and it's fantastic: https://www.youtube.com/watch?v=wf-BqAjZb8M

Mar 24, 2020 · 1 points, 0 comments · submitted by ducaale
That's pretty lazy thinking, imho. "Person x doesn't care about their code because they didn't use the formatting I like"

Worrying about or judging code based on PEP8 is missing the forest for the trees[0]

[0] https://www.youtube.com/watch?v=wf-BqAjZb8M

frosted-flakes
It's not that, it's that they use inconsistent and non-standard formatting.

For example, in JavaScript, there is always a space before a function's opening curly bracket. This is pretty much a global standard, and it's rare to see code that doesn't follow this rule.

However, I'll occasionally see code on Stack Overflow that randomly excludes these spaces. It honestly makes it so much harder to read, and I'm less willing to put in the effort to help them, because they didn't even go to the effort of properly formatting their code. Inconsistent indentation especially kills me because it makes code impossible to read.

cuddlecake
Technically, one could spend his life learning and perfecting JS or Python skills, without ever learning how other people format code. If you don't have a reference, you cannot align.

Also, imagine blind people coding. I imagine they have a completely different stance on how code should be formatted.

Raymond Hettinger - Beyond PEP 8 -- Best practices for beautiful intelligible code - PyCon 2015 https://www.youtube.com/watch?v=wf-BqAjZb8M
in the python world, i really like Raymond Hettinger’s talk “beyond pep8”, in which he advocates “90-ish” as a line width to shoot for, rather than a slavish fetishism for 80.

This especially matters when you start doing dumb things to codebases like 1-space indents, abbreviated variable names, etc. for the sole purpose of making a linter shut up.

https://m.youtube.com/watch?v=wf-BqAjZb8M

notacoward
> This especially matters when you start doing dumb things to codebases like 1-space indents

Too-small indents are bad for many of the same reasons as too-long lines, only even more so. The main argument in favor seems to be the desire to cram as much as possible into each line, which is a code smell of the first order. The main argument against (which I find much more compelling) is that it becomes really hard to match up the indentation levels to see the true structure of code without artificial aids. Besides being ugly, those faint vertical lines won't be there in every situation, such as when you're looking at code in a review tool or in gdb or a "primitive" editor while you scramble to fix a problem on a production machine that doesn't (and shouldn't) have your favorite heavyweight IDE installed. Ergonomics matters, and it's about more than personal preference.

You may be able to refute their recommendations with this video where Raymond Hettinger sympathizes. https://www.youtube.com/watch?v=wf-BqAjZb8M
throaway54321
funny, I started to post this as a response in one of those epic PR threads, but then deleted it because I didn't want to be inflammatory. Being new to the team and in this unfortunate position, I think it may be wiser to just roll over than fight. I'm in this unfortunate mode of minimizing the interaction if I can.
Yes, just like that. Check out this fantastic talk on being pythonic: https://www.youtube.com/watch?v=wf-BqAjZb8M
> The first one is horrible and super un-pythonic (it even violates PEP8[1]).

I'm not really concerned with PEP. I'm concerned with if the idea being expressed is cleaner then the original. My first iteration was cleaner then the original comprehension (despite the comprehension being PEP8). It also let me see what I was really doing and I was able to turn my map and filter into a much nicer list comprehension.

Also, pointing out lambdas instead of defs is silly. It was done for an example. Most of the time you'll be operating on data structures with built in functions or supporting functions you will have written making it cleaner to use the map and filter paradigms.

    money = sum(user.get_payed_balance() for user in users if
                                           user.has_paid_bills() and 
                                           user.is_still_subscribed())
bs

    clients = sum(map(User.get_payed_balance,
                  filter(User.is_still_subscribed,
                      filter(User.has_paied_bills, users))))
I much prefer the filters to the list comprehension in this case. I'll think "User's money for user in users if user has paid their bill and subscribed". I'm going to think "Sum the get_payed_balance for every user who is_still_subscribed and who has_paid_bills" for the functional implementation. If I had complex tuple arraignments then (like the OP's post) then I agree LCs will be the better way forward. If you're dealing with objects or functional-fitting problems I prefer map and filter.

> But perhaps even more important, it doesn't even work since a map-function can only take one argument (not two).

The concept still stands. Just use `from itertools import starmap`. Starmap is like map that calls the * operator on arguments.

    >>> a = lambda a, b: 10
    >>> list(map(a, ((1, 2), (3, 4))))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: <lambda>() missing 1 required positional argument: 'b'
    >>> list(starmap(a, ((1, 2), (3, 4))))
    [10, 10]
> Using functional programming paradigms like this often advised against in Python.

I'm not concerned with if it's "Advised against". I'm concerned with a) will someone be able to understand this better then the implementation that currently exists) and b) will I be able to come back in 10 years and tell what this is doing if need be.

You should check out this talk [1] before going around trying to use PEP8's inconsequential clauses to call something "horrible" code.

[1] - https://www.youtube.com/watch?v=wf-BqAjZb8M

Three... 2 is dying (and should be!)

As for resources, you can already program, so ... Browse the manual (it is quite good), look at some pythonic* style videos* , browse the giant standard library and do some stuff with it... (the last part is key)

= yes, that is a genuine keyword, that can be googled and youtubed.. * * = this is good https://www.youtube.com/watch?v=wf-BqAjZb8M

As for "2 works as good as 3", yes, if you only care about English text.

Bytes are what is on the disk, byte value 229 could be "å" (in latin1) , "ĺ" in latin2, or different things in other encodings... Only the lower 127 are "standard" (unless you are in EBCDIC on a mainframe where code 78 is "+" instead of "N")..

If you know the encoding of the bytes (i.e. what language/text type are they), you can "decode" the bytes to a string type, which is unicode glyphs (not utf8, which is also a byte encoding)... When you want to get back to bytes, you just encode it again....

I don't get it, why people find it so hard...

"There's an extremely important piece missing from existing styling tools: the maximum line length. Sure, you can tell eslint to warn you when you have a line that's too long, but that's an after-thought (eslint never knows how to fix it). The maximum line length is a critical piece the formatter needs for laying out and wrapping code."

I'd disagree. See https://www.youtube.com/watch?v=wf-BqAjZb8M

Jan 05, 2017 · bbtony on Grumpy: Go running Python
In every introductory python course tuples are presented as just immutable lists. However a "more accurate" way of describing tuples is if you think of them as records with no field names. When you see tuples as records then the fact that are inmutable make sense, since the order and quantity of the items matters (it remains constant). Records usually have field names and here is where namedtuples comes in handy. Also helps to clarify what the tuples wear (see https://youtu.be/wf-BqAjZb8M?t=44m45s), just 2 minutes clip. If you are thinking why don't define a class, I will tell you a couple of reasons:

1) You know before hand that the number of items won't be modified and the order matters since you are handling records. So it is a simple way of accomplishing that constraint.

2) Because they extend tuple they are inmutable too and therefore they don't store attributes per instance __dict__, field names are stored in the class so if you have tons of instances you save a lot of space.

Why creating a class if you just probably need a read-only interaction? But what about if you need some method? Then you can extend your namedtuple class and add the functionality you want. If for example you want to control the values of the fields when you are creating the namedtuple you can create your own namedtuple by overriding __new__. At that point it is worth it to take a look at https://pypi.python.org/pypi/recordclass.

> Yet again, they admitted an important feature was missing. Again, I am not familiar with Java 8 but I suspect their implementation is horribly wrong.

Admitting something is broken does not mean it sucks. See this comment: https://news.ycombinator.com/item?id=13216187

Also, please read this before you wave it off: http://stackoverflow.com/a/1073427

> I have. I guess I have just logged more time in Java than others.

Java is probably my most used language and that's saying something as I work as a TA for a Python class, use python for most personal projects, and also use many other languages. Java consumes the most time because it has the most polished toolings and standards for developers. Now they may not always be ovserved but if you stay in your own walled garden everything is all honky-dory.

You will never make these mistakes if you follow basic practices in Java's naming conventions. All lower case classpaths, all uppercase class names, lower then cammel function names, etc. You'll never be able to mistake Test() for Test.test() as they are instinctivly different names.

> Please tell me how to do it properly. IE, if I have a variable of type Foo that is holding a value of type Bar, how do I invoke the function with Bar instead of Foo in the signature?

    void something(Foo f) {
        if (f instanceof Bar) {
            (Bar-Specific commands)
        }
        (generic commands)
    }
Or better yet use your magic want: Abstraction. Wave it around and use your super powers to move that functionality into Foo and in anything that needs a specific handling of that function, override that.

> My point exactly. Other languages just use globals. Because they are useful and people need them. Java makes you invent a new programming paradigm to overcome its artificial limitations.

Well if you want to resort to global constants you can. Use a static import. LWJGL makes heavy use of this anthough I dislike it. I'd rather have an abstract interface into the library rather then have a global constant.

> And what do you do when you blow out the 80-char limit on columns? Oh let me guess. You like your 1024-char limit on columns because you are using a superior IDE.

Yes very much so. Please see this: https://www.youtube.com/watch?v=wf-BqAjZb8M

Line length != good code. Now granted, that doesn't mean run wild but I do have some code written that is perfectly good code, I've just ended up using some long variable names. This happens in Python as well. And no, you don't need an IDE for this, I write most of my prototype Python in nano before moving it into an IDE as Python IDEs are extremely sub-par.

> I don't recall that being an option. I do know that people used to prefer the curly brace format but that turned out to cause memory leaks.

I don't remember `new int[] {};` causing memory leaks but yes you can even do a static import to do the following: `asList(1, 2, 3, 4)`.

> The issue with inner classes is that so many thing are contrary to expectations. I started to list them all but it got too long. I'll have to revisit it and try to condense it down.

I'd love to hear it, and I'd love to define a set of "sane" sub-features of sub-classing in Java. I've working with libraries that where HORRIBLY written that have used sub-classes and I've also worked with amazing ones.

> The point is the reason why they do it is because it's easier to write, test and debug these other languages than Java. People know that coding in native Java is slow and cumbersome and time-consuming with no significant benefit.

I don't think this is the case. Enterprise Java came about because design patterns, like viruses, spread through code bases. You should look at this: https://www.youtube.com/watch?v=JxAXlJEmNMg

David goes through the history of development and I find it enlightening. He mentions it VERY breifly but many government contractors and researchers ended up using XML a lot. It came from another standard that they developed. As such, it was easier for them to write XML templating.

Then again this isn't a bad thing for two reasons:

    1. Someone else being bad at writing Java doesn't mean Java is bad.
    2. Sometimes XML is the correct way to do things. Do you write ALL of your web pages in Javascript adding elements in with document.createNode....()? No you use an XML notation. 
Java has gotten out of hand with XML because monkey-see-money-do but that doesn't mean the language is bad. I blanket refuse to use XML-requiring libraries. I just right my own implementation if it's required. I've done it for a game I'm working on. I've tossed all UI libraries as they all need XML and I think it's a waste of my time. I can write the library, and then use the library faster then I can read all the documentation about writing their stupid XML format.

> What claims need numbers? LLVM and PyPy exist. JS with JIT kicks the pants off of almost everything --- because it is compiled down to native machine code. Go look them up for yourself. JIT is the new fad, and it's a huge deal.

I've worked a lot with NodeJS, I've worked a lot with LLVM, and I'm about to do a lot of work with libdill (you'd like it if you've not seen it). I love lazy evaluated, JITed, and optimized languages. Runtime or no. That's why I love Java.

Java, especially after Jigsaw, will have major opprotunities to blow other languages out of the water. Java is great in runtime performance but horrible in startup performance. For server applications you can't get much better.

> Name one.

http://www.dnsjava.org/

I think Commons has one but I like this better as it's not-Commons. In my book that's a feature.

> I write code to get the job done so I can get paid, my company's stock price can go up, and I can get money. It's a job. Yes, I love programming, but I prefer to get as much done with as little work as possible. > Yeah, you strike me as someone who only knows Java. Let me know if I'm wrong.

My resume includes Python, JavaScript, C++ (now), C, Java, PHP, X86/ARM Assembly, LISP-Like languages and a few other things that I'm not remembering off the top of my head. I've got one project coming up in Go as well. This is in order of most-recent-project. Today I wrote something that will search craigslist and ebay for a x220t with an I7 and email me all of the results under $200. I'm looking for one and I'm in college so I'll just wait it out for the price to be right. Anyway, that was a Python project.

I also TA for a Python class at my university which I've successfully shot down trick questions from that one way-too-smart student that we all were once a time (He tried to tell the prof to use xrange instead of range for a performance boost and I had to bud in and say "xrange was removed" since he was stuck in the land of Python 2). I've also ported over Python code bases from 2 to 3. I mention Python so much because it seems as if you're a fan.

I hope that well establishes my programmer-cred.

>Let me change your example:

   class Test {
   	private final int i;
   	public Test(int i) {
   		this.i = i;
   	}
   	public Test() {
                this.test(7);
   		this(10);
   	}
   
   	private void test(long number) {}
   }
This is the best behavior to have. If you haven't initialized the state of a class you shouldn't acess it's methods. I'd rather have this rather then have an uncertianty about the contents of uninitialized state.
These two made an impression on me, especially regarding the delicate trade off between implicit and explicit.

Among other things, how and why to making things more implicit:

http://youtube.com/watch?v=wf-BqAjZb8M (Beyond PEP8 by Raymond Hettinger)

When implicit goes too far:

https://www.destroyallsoftware.com/talks/wat (wat by Gary Bernhardt)

I'd also add Raymond Hettinger's talks on Python with my favorite one being this famous one:

Beyond PEP 8 - Best practices for beautiful intelligible code

https://www.youtube.com/watch?v=wf-BqAjZb8M

Raymond Hettinger's talk about good code reviews -- https://www.youtube.com/watch?v=wf-BqAjZb8M

Carmack's talk about functional programming and Haskell -- https://www.youtube.com/watch?v=1PhArSujR_A

Jack Diederich's "Stop Writing Classes" -- https://www.youtube.com/watch?v=o9pEzgHorH0

All with a good sense of humor.

someone7x
Came here to add "Stop Writing Classes", a fantastic talk to show how to refactor away from dogmatic OOP.
mixmastamyk
Yes, RH's Beyond PEP8 is great, even if you don't do Python. Will put the others in my queue.

I'm reminded of Crockford's "Good Parts" of Javascript, I believe where he introduced me to the "Mother of all Demos."

johnhenry
Everything I've seen by Crockford is great!
For pythonistas:

Raymond Hettinger - Beyond PEP 8 -- Best practices for beautiful intelligible code - https://www.youtube.com/watch?v=wf-BqAjZb8M

I've not used it in recent years, but PolarSSL (now mbed TLS) was quite nice for a crypto library. It's a light, simple and clear C library.

Not directly code, but the "Beyond pep 8" talk at PyCon 2015 by Raymond Hettinger is quite nice (https://www.youtube.com/watch?v=wf-BqAjZb8M). It gives interesting tips on how to separate "business logic" (the high level problem you try to solve) from the "purely technical stuff".

If you're a Python programmer, Raymond Hettinger's "Beyond PEP 8" was pretty interesting:

https://www.youtube.com/watch?v=wf-BqAjZb8M

monkeyshelli
This looks intereting, thanks :)
At first read this is a pretty reasonable doc for some things to consider. I also recommend watching the linked "PEP8" YouTube presentation from PyCON: https://www.youtube.com/watch?v=wf-BqAjZb8M

From past projects, I got way more adherance-to-the-letter type patches versus "make this code pythonic and elegant" type patches, and the latter IMHO is more of the point of where things should go.

It's a bit of a long/slow talk, so if you find yourself getting bored, switch it up to 2x speed on youtube and I think many of you will like it.

My personal PEP8 ignore list was:

-pep8 -r --ignore=E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E225,E261,E241 lib/ bin/

Which is quite a lot of it :)

Codebases are easier to understand when everybody's consistent within the codebase, but things need to be idiomatic well beyond PEP8 and it's easy to have a forrest vs trees scenario.

Similarly, I really enjoyed Raymond Hettinger's 2015 PyCon talk, which also had a fair amount of live coding.

https://www.youtube.com/watch?v=wf-BqAjZb8M

There's a great talk on this [1] by Raymond Hettinger where he argues that style guides (e.g. PEP8) are no alternative to thinking hard about the code. Blindly following rules (like a bot would do) just gives a false sense of security that it's good code.

[1] https://www.youtube.com/watch?v=wf-BqAjZb8M

I would suggest following the work and talks of Raymond Hettinger @raymondh Such as: Raymond Hettinger - Beyond PEP 8 -- Best practices for beautiful intelligible code - PyCon 2015 https://www.youtube.com/watch?v=wf-BqAjZb8M
Aug 07, 2015 · 262 points, 160 comments · submitted by nharada
azeirah
Excellent talk. Would recommend to developers outside the python community as well.

Some takeaways; 1. Adhere to a great style guide 2. Can you predict what the code does? Can you trace a path through the function calls, if statements and for loops? 3. Can you explain to someone what the code -means-? Why is it the way it is?

    p = (170, .1, .6);
    if p[1] > .5:
      print("bright!")
    elif p[2] > .5:
      print("light")
That's ok, right? Pretty nice. I can see that it'll print "light".

Good enough? No, not really. How are "bright" and "light" related to (170, .1, .6) and .5?

How about this?

    color = Color(hue=170, saturation=.1, luminosity=.6)
    if color.saturation > .5:
      print("bright!")
    elif color.luminosity > .5:
      print("light!")
Far better! I know now that saturation is related to brightness, and that luminosity is related to lightness. It takes about the same time to write, yet is far more legible.
agumonkey
I guess Color is a namedtuple. I'm often tempted to [ab]use binding.

    def qualify(color):
        hue, saturation, luminosity = color
        if hue ... or saturation:
            ...
        ...
xorcist
The obvious question a newcomer would have to that particular code is "Can't a color be bright and light at the same time? Why?".

Those things are better explained in a comment, I'd think.

Comments are needed, but should not explain what the code does (as in "add 1 to n") and instead exaplin why it does it (as in "fn expects indices to start from 1").

azeirah
Yeah sorry, that was my mistake in copying from the video. It was supposed to be an if statement. I'll leave it now because of the discussion on the issue
coldtea
>The obvious question a newcomer would have to that particular code is "Can't a color be bright and light at the same time? Why?".

It can and the code in question will print both "bright" and "light" if passed a color that matches that.

Where did you see that it's an either-or affair in the example?

Besides, the key point, is that the code talks about luminocity and brightness levels, and the second example makes that explicit. No comments needed if you know what HSV is. And if you don't, comments are usually not the place to learn about it.

isp
In Python, "elif" means "else if". At most one of "bright!" or "light!" will print.

  $ python
  >>> if True:
  ...   print "First"
  ... elif True:
  ...   print "Second"
  ... 
  First
  >>>
coldtea
I know what elif means in Python (been doing it since 1998 -- remember Zope?).

That's not the code in his example. Here's that code:

https://youtu.be/wf-BqAjZb8M?t=40m41s

coldtea
>Apologies - I think we've been talking at cross purposes.

Yeah, didn't pay close attention to it, thought it was the same as the one I saw in the presentation.

isp
Apologies - I think we've been talking at cross purposes. I was referring to the code up-thread in https://news.ycombinator.com/item?id=10025412 , which (unlike the presentation) uses "elif".
berdario

    if color.saturation > .5:
      print("bright!")
    elif color.luminosity > .5:
      print("light!")
it's an `elif`... it will never print both "bright" and "light"

This kind of mistake really detracts from the point that was argued here about code being "intelligible"

coldtea
That's not his code.
jmartinpetersen
In the presentation it was two if's, not an if and an elif. Someone up-thread misrepresented it.

I didn't read it carefully here, as I had already seen the presentation and it wasn't until your disagreement I realized the code was different.

berdario
Yup... my comment about "detracting from the point" was about such an important semantic change to slip through unnoticed. (not about the points delivered in the talk itself or anything)

There's nothing wrong with if/elses, but I strongly prefer pattern matching, where available. And even more, I think it's important to keep computation and presentation separate... that is, to not entagle IO with the rest of the code.

(Unfortunately Haskell is the only language I know of that gives you a tool to tackle that)

Obviously this was just a small example, but I've seen unintended IO byte back the developer in real world (Python) code.

And another small comment: since I haven't bothered to comment on Hettinger's talk before now.

I liked it (but played it back at 1.5x)... but since it's not first talk by Raymond Hettinger I saw, I knew that his delivery is good. Some of the stuff (should?) be obvious to every (Python) developer (but repetita juvant). I didn't like the jab at Java for the mistake of iterating over indexes: there's no excuse to writing that code not even there (look at the Iterator and Iterable interfaces)

mixmastamyk
I recommend watching these types of long-form videos at 1.25x or faster.

For some reason youtube didn't let me change the speed of this video. Instead I downloaded it with youtube-dl and watched it with vlc.

markrages
You can do that with low-content videos, but not Raymond Hettinger videos.
agumonkey
I don't even download anymore, I pipe youtube-dl video source url to mpv (which, IIRC is obsolete since mpv gained the ability to find it with the original youtube url).
andreasvc
I can change the speed if I watch with HTML5; with Flash the option doesn't show (Firefox on Linux).
seanmcdirmid
In my own editor written for my own work, I've implemented language-aware line wrapping, which seems to work pretty well (it is aware of paren blocks, and wraps them together). This is only possible since the editor is semi-structured, but it feels like future. I've also begun experimenting with sub-80 column lines, actually, columns whose widths are completely configurable in real time (sometimes I want wider when focusing, sometimes I need narrower when reading and have other things on the screen).

As an example, check out the 7th example in http://research.microsoft.com/en-us/um/people/smcdirm/apx/in....

octatoan
Nice. But, seriously, use / for division, please.
compostor42
Seriously tempted to print out the Pythonic NetworkElement code vs the Java style code and put it on my wall. Perfectly embodies why I love Python so much.

A humbling reminder of how far I have to go to be even near this guy's level.

alangpierce
In fairness, Java doesn't need to be as verbose as the "Java-style code" from the talk, especially now that Java 8 (with lambdas) is out. Here's how I would write the code in Java:

    runWithNetworkElement("171.0.2.45", networkElement -> {
        for (Route route : networkElement.routingTable()) {
            System.out.printf("%15s -> %s%n", route.name(), route.ipaddr());
        }
    });
agumonkey
Yes, Java pre 2010 is a thing to forget. All the fanatic ceremony can retire nobody will miss it. All languages, as soon as they have the right linguistic construct can achieve the same level of expressiveness. Turns out first class functions were priceless, and anonymous classes weren't a good enough incarnation of that, especially in the late 90s.
coldtea
What's this name() and ipaddr()?

Sure, Java 8 has lambads, but have their disposed of getters and setters and added some kind of properties?

If not, then the idiomatic way is not name(), it's getName().

(Of course without "unified property access", it's not that much different)

alangpierce
No, there aren't any special language features behind route.name() or route.ipaddr(), they're just getters without the "get" name. While methods of the form "getFoo" have plenty of history in Java, it's also fairly common to drop the "get", especially when the class is being used as an immutable value type.

For example, both Google's AutoValue library and the Immutables library show examples of getters that drop the "get" prefix:

https://github.com/google/auto/tree/master/value

http://immutables.github.io/

One argument against the prefix is that immutable value types don't have setters, so it's not as important to distinguish between them. Another argument is that immutable values aren't really objects in the object-oriented sense, so accessing a field really is just a data access as oppose to an action being performed by the class instance.

(I guess one aspect of Java that makes this less awkward to implement is that methods and fields have independent namespaces, so nothing stops the Route class from having both a "name" field and a "name()" method. That's possible because Java doesn't have first-class functions, so you can always determine from usage whether something is a field or a method.)

sigzero
"PEP8 unto thyself and not unto others" --- Yes!
mapleoin
This is a great talk and I really like the second part where he promotes writing your own adapters for non-idiomatic third-party libraries.

That being said, I almost couldn't get past the obnoxious rant at the beginning against maximum line length. The reasons for the rule are made very clear in pep8 as well as the fact that it's not a hard rule and it's fine to override it in your team if you all agree on longer lines.

JustSomeNobody
I don't think it was obnoxious. But, anytime someone is going to bring up code formatting, others will get their panties all in a twist. It's what people like to argue about when they don't want to argue about real problems.
cafard
Many years ago I worked as a copy editor. For a while I imagined, as many copy editors did, that my task was to enforce the rules of the University of Chicago's Manual of Style, especially regarding placement of punctuation with respect to quotation marks, "which" v. "that", etc. Eventually, I understood that making such changes was useful, but not really what editing should be about. It is possible to have unreadable or awkward prose with perfect comma placement, semicolon discipline, and no "which"es without a comma before them.

I doubt that I was or am nearly as good an editor as he is a coder. Yet I think that there is a logical progression (not a natural progression, since we don't all make it) from knowing the rules to knowing what the rules are for, to having the confidence to break them when it makes sense.

None
None
coldtea
>The reasons for the rule are made very clear in pep8

And are still BS with today's monitors (including laptop monitors).

Besides, PEP8 itself goes on to say: " For code maintained exclusively or primarily by a team that can reach agreement on this issue, it is okay to increase the nominal line length from 80 to 100 characters (effectively increasing the maximum length to 99 characters), provided that comments and docstrings are still wrapped at 72 characters."

masklinn
> And are still BS with today's monitors (including laptop monitors).

My 15" laptop monitor can only (readably to me) fit two 100-wide buffers in a visually barebone editor (emacs), move to an editor or IDE where the UI takes more horizontal space because of sidebars (Atom, IntelliJ) and the buffers are close to 80-wide, so 80-wide is a perfectly fine limit as far as I'm concerned.

Until I have to perform a 3-way merge, then 80-wide doesn't fit anymore.

And age will eventually catch up to me and make things worse.

coldtea
Missing the point that you don't have to have ALL your lines > 80. Just the few that need to be so.

And for those, you can always either wrap or scroll a little to see them in a 3 way merge, it's not a big deal.

Heck, in the eighties that you champion and that they got that rule, they worked with a single 80-wide terminal view, not 2 100-wide side by side and no 3 way merges.

tdicola
I recently saw a good summary of PyCon 2015 talks that included this and a lot of other top notch ones: https://www.fusionbox.com/blog/detail/pycon-2015-talks-you-s...
wldcordeiro
This was one of my favorite talks from this year's Pycon, it really opens your eyes up and lets you see the forest from the trees. It's really easy to get caught up worrying about general PEP8 code style without noticing the non-idiomatic code elsewhere.
agumonkey
He really built up the second part nicely with the count-the-passes video.
asafira
Someone posted the pycon videos a few months ago on hackernews, and this was actually the only one I watched. What's nice about this IMO is that he's entertaining when talking about a topic that I would normally fall asleep to. It's not that I don't care about code quality --- my coworkers can tell you I definitely care --- but it can be a pretty dry subject. Kudos to Raymond.

A few months ago I started to get into some networking and saw that there were a few free online courses available. Unfortunately, despite choosing my favorite one, I ended up falling asleep 3 times already listening to the lectures. Man, I sound like I'm getting old...

harshulj
I like the indentation part of PEP 8. Especially the ways to organise arguments while defining functions. Having a common way of writing those is really helpful when reading the code. https://www.python.org/dev/peps/pep-0008/#indentation
scrollaway
One of my work projects has this huge, three-page document for style guidelines. All the bells and whistles including the 80 character limit.

And then I realized this is all BS. I wrote a very short styleguide with a linkback to pep8 for any "questions" one might have. Problem solved. You don't need to decide every little detail of how your code is going to look in advance, unless there is a solid reason to do so.

The styleguide, for those curious: https://github.com/jleclanche/fireplace/blob/master/CONTRIBU...

Edit: What a great talk. Really embraces the way I've been thinking about pythonic coding. Loved it.

japhyr
My code is cleaner, and much more intelligible after attending this talk.
rajathagasthya
This is a great talk. I attended a couple of Python training classes at work by Raymond Hettinger and my Python code quality changed dramatically!
kkmickos
I always use 80 character limit as long lines makes it hard to for me follow the flow, and it's not unusual to lose track of which line I was on when going to the next line.

Sure there are huge monitors with insane dpi allowing a ridiculous amount of text, but I'm not getting younger and find myself increasing font size every now and then to be able to read.

Getting old sucks sometimes.

avinassh
I want to understand why makes remarks about PEP8 and core library and sending a PR to fix them. Why shouldn't someone send a PR by changing code which adheres to PEP8? As long as tests are passing and core library follows PEP8, then is there anything to worry?
rtpg
I agree with this sentiment. If your policy is to keep all your code PEP8 (ideally by making it part of your test suite), then the amount of commit messages which are "PEP8-ify" will be pretty small.

If you take a blatantly non-compliant codebase and PEP8-ify it, you'll have many "pep8" lines in your git blame for a point, but by integrating it in your process that will disappear pretty clean.

cafard
Glad to have seen this, and I will be keeping it in mind in the next few weeks.
pekk
"Beyond the prevailing code standards, yet another proposal for doing things my way instead of the standard way"
coldtea
The whole point of the talk went flying over your head.

In fact, he proposed the total inverse of what you say.

He said, code standards like PEP8 are good, and should be followed. But those are only code formatting standards.

The beyond part wasn't about doing things "his way instead of the standard way" but about doing things the Python way (idiomatic Python) instead of ad-hoc or mimicking other languages you're familiar with way.

What he showed are common standard Python approaches to solving issues, taking advantage of what Python offers instead of writing in C or Java etc style.

Really, your comment couldn't be further from the spirit and content of the talk.

pekk
Not at all, when the talk starts out quibbling about the 80-column standard.
coldtea
That's just the intro and is said as an aside. Far from being the essense of the talk.

(Of course this is already obvious since the 80-column thing is about PEP8, whereas the essense of the talk is how to better structure your code BEYOND PEP8's formatting rules).

Not to mention that even PEP8 concedes that you can raise the max line length limit up to 100 if your team agrees.

atriix
This is some good pep talk
sago
One little quibble in an excellent talk: 80 cols exists for a reason. It means people don't have to lay out their editor and shell to match your code. Your editor can be set to 80 col, your shell can too, and then you can leave it and it should work across languages, code-bases, and libraries. An extra line break here or there is preferable to having to drag windows around to read your code. At 80 cols I can get three editor windows on screen, allowing me great views of a lot of relevant code for the bit I'm writing, or a shell in place of one editor that I can be running tests on. Once 82 cols is okay, why not 84, or 90, or 100? What about when the middle column needs 84 cols, and I have to drag everything around. That's rude and productivity sapping.

I know some people program with one editor maximised and can have 200 character lines if they like, but a specific width as a convention is helpful. And the convention that is already widely used is going to make fewer people have to accommodate you. The 'ish' is useless in that regard.

coldtea
>One little quibble in an excellent talk: 80 cols exists for a reason. It means people don't have to lay out their editor and shell to match your code. Your editor can be set to 80 col, your shell can too, and then you can leave it and it should work across languages, code-bases, and libraries.

Yeah, that was nice for 80 line terminals in 1986.

This is 2015. We have 27" screens. Two of them for most of us.

And on our lowly laptops, we have hi-dpi fonts (which makes smaller fonts sizes read great) and widescreens.

sago
Right, and that means we can have more code on screen, and docs and tests, and shell. Where is the rule that you have to have one window open at a time? That's the real throwback to terminal interfaces.

The number of programmers I see manically toggling through their code in one window is crazy. I think this is part of the legacy of some high-profile IDEs that gave you one window at a time.

What proportion of your code lines are > 80 cols? Multiply that by the amount of extra width to get the wasted screen estate. I'll take that and put more code/docs/tests/output on my screen at the same time and have to toggle less.

The idea that this is about teletype is very amusing, but rather naive.

johnmaguire2013
I rarely find myself wishing to split my screen. It's not that I don't know that I can, and occasionally I will (especially if two pieces of code happen to be VERY tightly coupled, with lots of passing back and forth between the two). In general, however, I find that since I am only reading one line of code at a time, having two editor windows up is pointless. It's like having two browser windows instead of two tabs in a browser window.

Plus, with most editors that can jump in / out of functions, it's not like I'm losing my place. In fact, my editors all save my place in files on exit.

sago
Interesting, do you do much unit testing for code you write?

And you know you can put different parts of the same file in columns too? I often need to write code that is coupled to another part of the same file.

brianclements
80 columns of text is wonderful in my dual window vim with NERDTree on the left. All my screens are some version of the 1680x1050 aspect ratio and it fits perfectly. I'm always using 2 windows for simultaneous code/test writing, diffing, and multiple windows into different parts of the same buffer, multiple files open etc.
johnmaguire2013
Unfortunately, at my current job, we don't seem to believe much in unit testing. There's some indication this may change in the near future.

Additionally, I have two screens, and since I mainly use a tiling window manager, 80 columns works... okay. But 80 columns isn't usually where my splits end.

Interesting point with the same file in columns. It's rather that I do that. More often I'll be looking at the same file across two branches. I am kind of surprised that we don't see more plugins doing 80 column lines, in sequence, to fill the screen however. More lines on the screen seems to be the craving that vertical monitors + high-res monitors aim to satiate.

coldtea
>Where is the rule that you have to have one window open at a time? That's the real throwback to terminal interfaces.

Even on a widescreen laptop you can have 2 > 100 lines windows side by side. And for multi-monitor setups you can go even wilder.

>The number of programmers I see manically toggling through their code in one window is crazy. I think this is part of the legacy of some high-profile IDEs that gave you one window at a time.

If you have tons of junk in front of you, you're not focusing on your code as you should be.

sago
Right, I can fit 2x100 cols, or 3x80 cols + a project view. So I can see my code, its tests, and either the shell (i.e. test results, ipython, debugger, tail -f logfile) or a web browser for documentation.

Is that junk?

How many of your lines require that 100 columns, in your average code?

Of course, this can just descend into a pissing contest. The point isn't who-has-the-most-windows, but that the logic of 80cols has a practical point, and programmers who continue with the default have reasons that aren't just about teletype or not moving with the times.

coldtea
>* So I can see my code, its tests, and either the shell (i.e. test results, ipython, debugger, tail -f logfile) or a web browser for documentation.*

Did someone stole the lower part of your screen? Or do you have all views in parallel, instead of say stacked vertically?

sago
I could cut half of my editors off, of course. But then I'm loosing even more context. And I have a shell output that is full width but not very tall, so I can't see as much context, and I have to scroll my code more. Again, this isn't a pissing contest. The point is that there are reasons people prefer it. What are you trying to argue? It seemed you were trying to suggest it is purely a historic throwback and pointless.

It all comes back to this question: what proportion of lines in your code use more than 80 cols? If it is a small proportion, the geometry is simple: you waste more screen by having longer lines.

coldtea
>It all comes back to this question: what proportion of lines in your code use more than 80 cols? If it is a small proportion, the geometry is simple: you waste more screen by having longer lines.

It's obviously always gonna be a small proportion. Nobody write > 80 lines all the time (or should).

But just because you accept > 80 lines doesn't mean you have to have the editor to > 80 width. You can just let it either wrap them or cut some lines off and scroll when you want to check them (what I do).

I don't buy that somehow this "80 characters per page" is some magic number that holds true from the teletype days to today, and it should be respected regardless of font size, monitor width, etc.

None
None
sago
> it should be respected regardless of font size, monitor width, etc.

I don't think anyone would suggest it is magic. It is a convention that is somewhere near to being good, and is so widely used that it is heavily tool supported, so you should have a good reason not to use it.

Actually, 80 is a bit of a misnomer, PEP8 has it at 79, git convention is 72 (50 for first line, to allow git log to display sha-summary inline and fit into 80 cols), etc.

> You can just let it either wrap them or cut some lines off and scroll when you want to check them (what I do).

Ah, I see. In which case I take back many of my objections. I see what you're saying now. Thanks.

Retra
My concern with 80 cols is that it is not friendly to dynamic languages that allow nested definitions, or long variable names.

    if __name__ == '__main__':
        def this_is_a_function(*args, **kwargs):
            def this_is_a_helper_function(arg1, 
                                          arg2=('this line is already indented 39 '
                                                'chars!')):
                this_long_variable = ("Don't put an expression here unless you "
                                      "want to use useless intermediate variabls.")
                return this_long variable if var else 'really short here'
            return 1

And some people want to insist on 8 char indents!
bpicolo
Then use better whitespace rules. Not to mention the helper isn't capturing any closure here so it's not particularly useful inline, and even when they are you can refactor variable capture to new functions. Nested definitions in python are pretty rare, and oft unnecessary

    if __name__ == '__main__':
        def this_is_a_function(*args, **kwargs):
            def this_is_a_helper_function(
                arg1, 
                arg2='this line is now indented 12 chars!'
            ):
                this_long_variable = (
                    "Don't put an expression here unless you "
                    "want to use useless intermediate variabls."
                )
                return this_long variable if var else 'really short here'
            return 1
JadeNB
Surely the fact that there are two typos in your code, one of them in the name of a variable (`this_long_variable` vs `this_long variable`), indicates that things can go wrong when you abstract out a literal to a variable?
bpicolo
I literally copy pasted from the other guy and added whitespace.
None
None
nvader
To quote the Zen of Python:

    Flat is better than nested.
Too many levels of nesting is definitely a code smell. Often it's better to pull those helper functions out, and/or create function or method factory functions at a higher level of organization.
Retra
You can't really do that if you're writing closures.
zo1
Have you had a look at https://docs.python.org/2/library/functools.html#functools.p... ?

Anywho, do you have a genuine example of where a closure is helpful for you in python? I'm very curious.

Retra
I don't understand the question. Your link has examples of closures right in it, so naturally if you're doing anything like that, you'll want them.
None
None
sago
Why not follow pep 8's indentation rules:

    def this_is_a_function(*args, **kws):
        def this_is_a_helper_function(
                arg1,
                arg2='this line is indented 12 chars!'):
            this_long_variable = (
                'Don\'t put an expression here unless you '
                'want to use useless intermediate variables')
            return this_long_variable if var else 'really short here'
        return 1
(for the same number of lines) or better still follow some basic common sense:

1. Local functions should be short and have short names since their scope is limited.

2. Local variables, similarly

3. Don't put long explicit strings in code.

and get

    messages = dict(
        long_default = \
            'Don\'t write strings that may wrap in ugly ways on 80 col shells.',
        short_default = 'Keep it short'
        )

    def this_is_a_function(parameter):
        def message(long, message='this is only 36 chars'):
            long_message = messages.long_default
            short_message = message or messages.short_default
            return long_message if long else short_message
        # Do something here.
        return 1
And if you have an expression that is more than 80 characters long, breaking bits of that expression and assigning them to temporary variables is not 'useless', it makes code clearer and is only rarely a performance hit.
coldtea
If I see a "\" I close the editor and delete the source file.
None
None
sago
How impressive of you.
Retra
Those are great suggestions, but may point is more that "too much on one line" isn't necessarily better than "too little over too many lines." It can be hard to get a good overview of what is happening when you've got to resort to splitting one significant token per line.

In other words, I try to use vertical space for higher-level work than horizontal space, and when you have to fit both into vertical space, you lose some clarity in high-level in order to gain it in low-level.

sago
Sorry, I know that putting code up is an invitation for people to pick at the wrong feature, so I realised I was being churlish.

But I think these things do have to be addressed with examples. There are few people willing to put an actual example up that a) is frequent enough to mean that 80cols can't be easily used (note, not 'preferred', we're talking about a standard, plenty of people 'prefer' 80 cols) and b) is pythonic enough that it isn't better written in more explicit steps.

Retra
Eighty columns is a good standard, I just think people forget how small it can be, and why it isn't always a problem. I've written tons of code that looks fantastic, if only I could use 85 columns, but rewriting it to use less just makes use of some pretty clunky constructs. All these extra "()"s and "/"s aren't actually helping make the line more readable, it just makes it fit into a rather arbitrary column limit. And at that point, you'd be thinking that the best way to make your code the most readable it can be is to use more columns.

So I don't think 80 cols is a hard limit, anymore than I think writing code in a terminal is a hard limit. I use a non-terminal text editor. I do it because it makes it easier to read code and format it how I like. I see little reason why anyone should be jumping through hoops to accommodate that. By using a terminal editor, you've already decided you won't get the best formatting, because you sacrifice the flexibility that allows it in exchange for something else. You should be expecting things to wrap around awkwardly on occasion.

Eighty columns is a good target width, but it's not worth proliferating clunky constructs to conform to. That's no better than having code wrap. (Of course, someone could also write terminal editors that allow text to go longer than 80 lines. Why are you using an editor like that if it can't do something this simple?)

sago
Thanks again. I agree, I've written a lot of code that would be clearer in 85 cols than 80, and some code that would have been clearer in 160 cols too.

I think we're agreeing mostly.

The problem with 'ish' is that I see it as worse than useless. 80cols-ish is what? 90 cols max? Why not just use 90 cols as the standard? If I have to scroll my whole window or resize it to read your line, is that really better than if it had an extra break? Some people may think so, but I don't, personally.

Retra
Ok, cool. What I do is just put a column marker at 79, make my window 82 cols wide, and then just write it as beautifully as I can. No hard limits. Just the natural "I can't read that over there, I should maybe rewrite it."
david-given
One size doesn't fit all --- if a particular language culture is focused around shell terminals, it'll probably go for 80. If it's focused around IDEs, like Java, it'll probably be about 100.

(Go, for some reason, doesn't like splitting lines at all, no matter how wide. I've had code reviewers criticise me splitting lines at 200, which I don't understand at all.)

rectangletangle
There's a certain point where an expression becomes difficult to read, because it's too long. If you're pushing 100, it likely means you should separate the logic out into a few smaller expressions.
andreasvc
When you have a function with a large number of parameters, splitting into expressions does not help, but splitting over multiple lines looks much clearer.
dilap
Word processors have soft-wrapped since like forever.

Recently code-editors have started to learn how. Don't wrap your lines at all; let the editor do that, in realtime, and you can have your windows at whatever width you want.

BurningFrog
> 80 cols exists for a reason

As far as I can tell, that reason is the IBM 80 column punch card standard launched in 1928:

https://en.wikipedia.org/wiki/Punched_card#IBM_80-column_pun...

woofyman
Only the first 72 columns were available for code. The last 8 were reserved for the collation sequence. Which was handy if you dropped your card deck.
rectangletangle
I agree that a standard is useful. However, monitors have changed drastically since the 80 column standard was agreed upon. I'm fond of 120, I think it strikes an ideal balance.
andreasvc
Optimal readability is attained with 60-70 characters. This is due to human psychology, and technology such as monitor size does not change it.

When lines are longer it becomes more difficult for your eyes to keep track of where the next line is. Furthermore, code is not formatted as paragraphs but as separate lines, so you end up wasting a lot of screen estate for those few long lines. Having a low maximum means it will be close to the average and a larger proportion of the screen is utilized.

mistursinistur
> Optimal readability is attained with 60-70 characters. This is due to human psychology

Actually this claim is disputed: http://psychology.wichita.edu/surl/usabilitynews/72/LineLeng...

andreasvc
Interesting. It might be that reading from screen works differently than from paper, where the 60-70 limit is a tradition. However, reading news is very different from reading code, so it doesn't go without saying that this result can be generalized to code.
ngokevin
My MBP15 with split panes only fits 96.
sago
So set up at 120, and then look at someone's code that's used 128 consistently. And then reformat for those few lines that went that long. See the point?

You can't standardise based on what you are fond of. That's the point of a standard. When such a large proportion of people, and the standard library, and most shells, use 80, then using 120 will inconvenience them. If you load my 80col code into your 120 col editor, it will not inconvenience you at all, barring an occasional extra line break.

rectangletangle
I get that. But a large section of the Python community has standardized on 120, and I'm adding to it in hopes of hitting critical mass.
andreasvc
I don't see the problem. There are aspects of PEP8 which I don't like, so I don't follow them. Why would you need to convince others of your coding preferences?
sago
In your average code, what proportion of lines of code are > 80 cols?
rectangletangle

    >>py34 lns.py
    total lines: 2099
    0.063% over 80
Not many apparently, and a significant portion of them are hard coded URLs/strings in scripts. I guess I stand corrected, 120 isn't that useful...

    import os

    from pathlib import Path

    def walklines(glob='**/*.py'):
        for filename in Path(os.getcwd()).glob(glob):
            with open(str(filename)) as file:
                for line in file.readlines():
                    yield line

    if __name__ == '__main__':
        alllines = [line for line in walklines()
                    if line]

        totallines = len(alllines)

        cutoff = 80

        total_long_lines = len([line for line in alllines
                                if len(line) > cutoff])

        prcnt_long = total_long_lines / totallines

        print('total lines: {}'.format(totallines))
        print('{:.3f}% over {}'.format(prcnt_long, cutoff))
sago
One thing I find that makes a big difference is using the PEP8 indentation rules for writing lines of the form

    variable = some_function((some nested expression that is very long
                              and needs to wrap))
as

    variable = some_function((
        some nested expression that is very long but may not need to wrap
        but if it does there's tons more room for it))
I.e. you don't have to differentiate between 'syntax indents' and 'expression indents', every thing is just an indent of the same size. Which has the advantage that almost every editor can indent it correctly, and it works with both space and tab indents, whereas you're at the mercy of your Python editing mode whether the 'indent to sibling' works for everyone (and if not, the programmer has to sit tapping space to line it up right). Both approaches are in PEP8, but i find that simple change removes 99% of all >80 line cases for me.

The only caveat, also covered in PEP 8 is for function definitions.

    def some_descriptive_function_name(one_parameter,
                                       another_parameter):
        some_functionality()
becomes

    def some_descriptive_function_name(
            one_parameter, another_parameter):
        some_functionality()
i.e. the parameter lines are double indented.
j-kidd
Double indentation looks rather ugly though. I like the "K&R" style much better (as shown in comment from bpicolo):

    def some_descriptive_function_name(
        one_parameter,
        another_parameter,
    ):
        some_functionality()
Anyway, either one is superior to 'indent to sibling', where the lines are now tightly coupled to each other.
sago
We each have different tastes, yes.

But, coding standards aren't about tastes, they are about coordinating large numbers of programmers to write code in consistent ways. PEP 8 gives the 'double indentation' as standard, rather than the 'K&R' style.

You're free to write however you want to, and if you're the tech director of a company, you can tell everyone else to follow your aesthetics. But you'll be doing a lot of work with code written according to PEP8. In my experience, learning and disciplining your team to use the standard is better than having a house-style. But YMMV, of course.

PEP8 isn't my 'ideal' aesthetic for Python either, but I'd need a far better reason than 'I think that looks ugly' for not using it.

I also agree 'indent to sibling' is poor, and not very universally tool-supported, even though it is part of the PEP8 style.

coldtea
>So set up at 120, and then look at someone's code that's used 128 consistently. And then reformat for those few lines that went that long. See the point?

No.

>You can't standardise based on what you are fond of.

Sure you can. That's why company and team-wide standards are for.

Nobody has to be forced to use some BS 70's throwback rules just because they are in PEP8.

rbanffy
> 80 cols exists for a reason

I like to joke God made The VT52 with 80 columns because that's how terminals should be.

Another I use is that "80 columns should be enough for anyone".

Now, seriously, code that's too wide (or too long) is a code smell. You probably should name your variables better, have fewer them in scope or just refactor the code to be more readable. Remember: code is executed by very cheaply and read by very expensive humans. Optimize for the latter.

kashif
Another reason that 80 cols mattered was because code could be printed properly on an 80 col dot matrix printer - way back then. Today, you can set your editor/ide to wrap it for you and you should - just 80 is such a waste of space on a modern display.
sago
> 80 is such a waste of space on a modern display.

You're assuming you have just one window open, aren't you? There's less wasted space with 80 cols if you have multiple columns (of the same file, or different files). The math is elsewhere in this thread.

Too
Python frequently gets away with 80 because you don't have 8 characters of wasted indentation for namespace and classes as you do in say C# or Java. But then again it compensates for that by adding underscores_in_every_variable_name. Anyway, for me anything below 100 just encourages violation of the rule or crappy variable naming, you can still have at least 2 files + project explorer open per monitor.
__clazz__
When people don't wrap at a reasonable width, IntelliJ's soft wrap settings are the next-best thing:

Settings > Editor > General:

* check "Use soft wraps in editor"

* check "Use original line's indent for wrapped parts"

* enter 4 for "Additional shift"

* if you open huge files with wide lines, check "Show soft wraps for current line only" to prevent slowness

masklinn
Are… are you a wizard? I didn't know about this setting, thanks, I'm pretty sure it's going to change my life for the better.
jakeogh
I'm sure you know it's an old design decision that was practical at the time. 100 years from now are we still going to be stuck with 80col's? In your example making the interface smarter could remove the need to manually resize boxes.

I like standards, but 80 chars just isnt enough and never was. Is 96 the next reasonable number?

sago
'Stuck with'? I don't think we're stuck with anything. I think 80 cols is a very practical width.

Most lines in code that is well structured and simple are less than 80 cols wide. Lines that require more than that can be broken. I think in 20 years of Python I've only seen a couple of cases where there wasn't an obvious semantic break point, most of the time such breaks are easy to place at logical points.

When you have 80 cols you have more code in your window. You can use the resolution to have taller windows and more windows side-by-side. 1920 pixels gives you nicely 3x80 col editors. Which allows you to look at the code, and its tests, and the shell at the same time, for example.

jakeogh
"1920 pixels gives you nicely 3x80 col editors"

Depending on your font. I use 1920 (-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO10646-1), and I get almost 4x80 col's, 3x96 works nice.

sago
Right, I have a pair of 1920s portrait so I can have more drops on my desktop, but on my 17inch MBP, more than 3 drops is too small for my middle-aged eyes.

As the commenter above stated, he found considerably less than 1% of his lines required > 80 cols, so rather than go 96 cols and have 17% of my screen real estate wasted, I'll have the extra column of code or documentation or tests, or output, and have to toggle less.

teddyh
80 columns was chosen because it fits well with documents produced for old-style fixed-with manual mechanichal typewriter paper. (If you look at the old text files, like the oldest RFC’s, they match this style, and early terminals were made by hooking electric typewriters to computers and supplying a very large spool of paper.)

I’ve seen 66 characters recommended as a maximum line width as a style guide for typewritten documents. You also want some extra room for extra margins, line numbering, etc. If 66 is taken as a good minimal number, then 64 (2⁶) is too small, so let’s add, say, 16 to 64, giving 80 columns.

Paper documents have the form that they do for a reason. You never saw someone writing sideways on a paper (landscape alignment). This is because readability suffers when lines are too long. Even if boxes resized automatically, it’s the line length that’s the problem, not the resizing or scrolling.

bsder
> One little quibble in an excellent talk: 80 cols exists for a reason.

Ayup. That reason is teletypewriters (aka ttys).

The biggest problem I have with most programmers is naming things well. 80 columns is anathema to good naming. People start using mbl instead of maxExchangeBufferLengthBytes.

No, I'm not a Java guy. I spend a LOT of time chewing through embedded C code. I don't even have good autocomplete in most embedded IDE's, and I STILL prefer maxExchangeBufferLengthBytes. Here's why--that name tells me many things at a glance:

max--limit of some form, probably should be positive

ExchangeBuffer--a buffer and it's functional purpose

LengthBytes--a length (so likely unsigned and if I see differently I should pause) in bytes (not items). You would be amazed at the number of bugs this circumvents.

That's a huge amount of information conveyed in 30 bytes. But that's almost half of 80 columns. Add in something like 8 column indents and you can't even name things well.

And, that still probably doesn't give me enough information. I need to look at that to see if that is constant, and I probably need to see if I can touch that without concurrency considerations.

I read code far more often than I type it. I read code after I have forgotten about it far more often than when it is fresh.

Naming things to enable me to come back to my code 6 years later, refresh my memory, and not screw up while doing it is the single most important task in my programming.

80 columns is simply not conducive to that.

sago
Can you give an actual example of some well-written Python code that you can't fit maxExchangeBufferLengthBytes in?

It's a bit handwavey otherwise. I'm also a long-names fan, sometimes I go overboard, but in 20 years I've not been able to logically break my line in an obvious place only once or twice.

RussianCow
If you add two of those variables and assign the result to another variable, you're already at about 96 characters before considering whitespace. I don't think it's that hard to exceed 80 characters doing very simple things.
sago
You mean

    this_is_my_very_long_variable_name = (
        this_is_one_variable_that_goes_into_calculating_it + 
        this_is_another_variable_that_needs_considering)
The issue wasn't the fact that some expressions are longer than 80 cols (that one is longer than 120, even, its 136 characters minimum), but that they can't be clearly and appropriately written in 80 cols.
RussianCow
That example is pretty trivial, but I'd hate to read code where every other logical line is broken up into multiple. It breaks up the flow of the code and makes it much harder to read, especially with how the indentation constantly changes (which is especially important in a language like Python, because I've trained my eyes to the special meaning of whitespace, so seeing non-significant indentation adds additional noise).
sago
Right, but again, can you see you've just gone abstract and handwavey. I'd also hate to read code where every other line is broken midway through an expression. Can you give an example of code that 80cols would force that on, which doesn't have deeper issues of clarity and structure?

It's not a trick question. I've written millions of lines of code over 20 years, and I've been renowned for using overly long names (compared to most Python coders), but I've not found that issue. Some breaks, yes, but never 'every other line', or even nearly that.

RussianCow
You're right, I don't write much Python anymore and don't have an example on hand. But I write Swift for a living now, and I know that if I restricted my lines to 80 characters wide, I would have to split up a lot of lines, including most method definitions. I much prefer the long lines, because if the details aren't important, they're easier to skip, and they're much easier to scan through when you're trying to read a large amount of code at once.
sago
Thanks, its a good point. I've only played with swift, but I've written a fair amount of objective C, and I didn't put 80 cols in coding standards for my company for that. We got away with that because the environment was fixed. And the path of least resistance was to use it in the way Apple told you to. You couldn't even split XCode more than two ways back then (iirc). So the issue of different tools, different screen layouts, and different workflows didn't raise. So yeah, 80cols isn't a panacea across all languages.
pjtr
Can I ask about a similar real problem I had a few times? How would you format this code?

    class Batman():
        # ...
        def handle_jokes(self, villains):
            for villain in villains:
                if villain.supports_jokes:
                    formats, transports = villain.query_joke_formats_and_transports()
                    # ...
That long line is 82 characters. Assume there's a good reason formats and transports are queried together. In practice this leads to variable names f and t. :(
mherrmann
I would rename query_joke_formats_and_transports to jokes.
1wd
What if that's part of a published interface? One that maybe also contains things like query_joke_history(), format_joke(), transport_joke() and execute_practical_joke().
mherrmann
If it's painful enough, I would write an adapter as done in the video.
sago

    query = villain.query_joke_formats_and_transports()
    formats, transports = query
or

    formats, transports = (
        villain.query_joke_formats_and_transports())
or

    formats, transports = \
        villain.query_joke_formats_and_transports()
Of which, we tend to do the first.

Again, the longer version is clearer and simpler, but the shorter version is not so confounding that it is a slamdunk argument for longer lines, particularly as, for any length line, you could get this problem, so you'll have to do something like it eventually. If you're seeing this all over the place, it may be worth wrapping the API in more pythonic terms. 'Getters' taking no arguments, for example, are often a code-smell in python, though queries (as in your case) are a good exception, since it is also not great to have properties do expensive work (like querying a DB, say).

pjtr
In reality there are multiple arguments to these functions, I just omitted them here to simplify the example.

What other more pythonic terms could be used? The proposed rename to jokes is completely unrealistic.

It seems kind of sad to butcher such nice simple code for these artificial non-reasons.

bsder
> Can you give an actual example of some well-written Python code that you can't fit maxExchangeBufferLengthBytes in?

Sure:

thisIsAnOutgoingBuffer = this_is_a_function(descriptiveKeywordArg = maxExchangeBufferLengthBytes, ...)

It's been a while, but I seem to recall that Python would require a continuation character to break anywhere prior to the comma.

zo1
This is how I do stuff like this, and I very rarely have to use funny line-continuation characters:

    thisIsAnOutgoingBuffer = this_is_a_function(
      descriptiveKeywordArg=maxExchangeBufferLengthBytes,
      more_long_param=a_nested_function_call_with_long_params(
        inner_param=55,
        another_inner_param="Asdf"
      )
    )
sago
No continuation character needed

    outgoing_buffer = a_function(
        descriptive_keyword=max_exchange_buffer_length_bytes
        ...)
Breaks nice and semantically. Calling functions with arguments on new lines is very pythonic, so much so that it is a lot of the examples of indentation in PEP8. For functions with more arguments, it is readable for the same reason that you might want to define variables on successive lines.

Interestingly, notice that in your quick back-of-the-envelope example your variable and function names are quite redundant. I know it was throwaway and it wasn't your point: I'm not suggesting you were holding it up as good naming, but it is interesting that the toy examples being quoted have to work quite hard to make it bad. That suggests to me that a lot of the problem is manufactured, in practice.

bsder
Huh? I could have sworn that Python didn't allow a break after a function call. There is something odd in the grammar that does weird things that I have tripped over that forced me to use a continuation character where I really wanted to just use a line break. And, it should be Python because what I'm remembering would need to be a whitespace-delimited language. I'll leave it up to the language lawyers to find. :)

> Interestingly, notice that in your quick back-of-the-envelope example your variable and function names are quite redundant.

Agreed.

The keyword argument is likely to specify things like "maxBufferLengthBytes" even as the variable does. The problem is that they serve two different purposes. The variable is moving around the program and needs to carry it's meaning with it, while the keyword argument serves to document the API that the function is part of. Because they are orthogonal, they are redundant.

In the end, the goal is productivity. I can live in 80 characters if I have to, but, if I'm in charge, it's 120-130.

Raymond's warning about reformatting introducing bugs is spot on though.

pyre
From current production code:

  class VendorOrderShipmentResource():
      ...

      def post(...):
          ...

          for item in data.order_items:
              ...

              if not shipment_qty: 
                  abort(400, message='All order_items must have a quantity_to_ship.')
That line goes out to col 86. I realize that it's possible to break it like this (#1):

  abort(
      400, message='All order_items must have a quantity_to_ship.')
or this (#2):

  abort(
      400,
      message='All order_items must have a quantity_to_ship.'
  )
or this (#3):

  msg = 'All order_items must have a quantity_to_ship.'
  abort(400, message=msg)
or this (#4):

  abort(400, message='All order_items must have a '
        'quantity_to_ship')
I'm not really a fan of any of those:

1. I'm not a fan of this one, in this case at least, because it "looks weird" due to the mismatch between the length of the function name, and the length of the next line. Also, I'm not a fan of "hiding" the closing parenthesis at the end of the line, rather than putting it on new line at the original indent level (like #2).

2. I'm not really a fan of this because the first argument and the function name are so much shorter than the message argument, that it looks really lopsided.

3. I'm not a fan of this because it seems stupid to create a new variable just to use it on the next line (and never again).

4. I'm not really a fan of breaking strings up this way, but sometimes I'm forced to. Breaking strings up this way tends to be really fragile when you want to modify them, and might need to reflow the entire wrap.

Personally, I'm just a fan of increasing line length to ~100. The number of things that go over 100 columns (in practice) is much smaller than the number of things that go over 80 columns.

kevin_thibedeau
Just let the line run long. These are only guidelines. There is inherent wiggle room. I break lines that feel too long and casually ignore the 80 column margin. Inserting unnatural breaks is just as bad as excessive line length.
pyre
It's different if you're using a tool (e.g. pep8) to ensure coding style. You can tell it to ignore long lines, or you can configure it to have a "better" line length than 80.

Telling it to ignore all long lines means absurdly long lines are accepted too, but configuring it for a particular number makes it a hard limit. The best option is to pick a number that is a good trade-off.

rtpg
In my case I am a fan of:

    abort(400,
          message='All order_items must have a quantity_to_ship.')
(not giving the parens an entire line)

I'm not a fan of 80 characters, but I am a fan of less than 120 characters, if simply that there is a point where a line won't fit in a terminal thats in half of a "standard laptop" screen (i.e. the limit to where I could put two files next to each other)

s_kilk
This is why I dislike Pythons standard of using four spaces for indentation. By the time you've declared a class, a method and a for-loop and a conditional you're already 16 characters down and struggling to fit code into the remaining space.
tedunangst
Regarding your last point, it's iteratively true. The number of things that go over 120 is much less than the number that go over 100. One always seems to need just a little more space.
pyre
I wasn't very clear, but I meant to say that the number of lines that will naturally end up between 80 ~ 100 columns is greater (in practice) than the number of lines that will go over 100 columns. I.e. I think that 100 is a better "sweet spot" than 80 or 120.
sago
Thank you.

Why is 3 stupid? That would be my preference. It is clear, simple and gets compiled away (in many cases). I alias in variables frequently, to make things more explicit. For example, I might write

    iterations = 300
    for _ in range(iterations):
        ...
which makes it less likely I'll end up repeating things or copy and pasting when new cases come up, e.g.

    if not shipment_qty:
        abort(400, message)
    elif shipment_qty < 0:
        abort(400, message)
What happens in your case if you come back and edit the message and add a few characters, exceeding your longer line length?

When I'm forced to break a string it is usually an indication that I need a better way of defining text than inline in expressions in code.

BurningFrog
I think 3 is bad because it is more complex than the natural code. It's not incomprehensible, of course, but clearly more complex.

I like introducing named variables for readability a lot. But this doesn't help readability. It just adds complexity for the sake of fitting into 80 characters.

sago
> But this doesn't help readability. It just adds complexity for the sake of fitting into 80 characters.

But 'for the sake of' implies that it has no other purpose. But the purpose is readability. It will help readability for the vast population of programmers who have 80 col editors or shells, and who code according to PEP8, won't it? Isn't that the point? Of course you can say 'It would be more readable if you guessed my window width preference correctly'. But what should I guess? If I look at your code and see a 90 col line somewhere, how do I know you won't drop a 100 col line in and hurt the readability again? Do I have to read your README to find how big to make my windows? Or do I just take the readability hit for the sake of your preference?

Chris_Newton
It will help readability for the vast population of programmers who have 80 col editors or shells

Isn’t that the premise that is being challenged here, though? There’s plenty of variety in which editors and shells experienced programmers prefer to use, but do any of those tools really still have a hard 80 column limit in 2015?

I would guess most developers now use screens that can show at least two (and often three or even four) source files side by side and still cope with longer lines than that, and I would guess most could switch their editor or shell to cope with those wider lines in a fraction of a second with a single keyboard shortcut.

I can see cases where line length could still be a limiting factor, but I’m not sure giving up general readability improvements from allowing somewhat longer lines so it’s easier to do a three-way merge on a laptop with a smaller screen is a good trade.

sago
Nobody is suggesting that people Can't view more than 80 cols. But many people have their machines and environments set up for 80 cols. They have their windows laid out based on the code they're writing, and then they load a new file and have to drag and resize their environment to accommodate you.

If there's a way to change window size and position from 3 columns of 80 + a project browser into 120 col with a single keypress, then I'd like to know. It isn't a major problem, but it is an unnecessary problem.

Nobody is forced to use long lines either, and if you want to lay out your environment to support 120 cols and you get my 80 col source code it will work without even a keypress or a second thought. You won't even notice it.

Chris_Newton
If there's a way to change window size and position from 3 columns of 80 + a project browser into 120 col with a single keypress, then I'd like to know.

In case it’s of any interest:

I use Sublime Text as my main editor. One of its nice features is that you can switch how the window is divided up with a single keyboard shortcut or menu command (View -> Layout). You can also easily define custom layouts in addition to the standard 2/3/4 columns, 2/3 rows, and 2x2 grid. I usually run with the editor maximised on my largest screen and 2–4 different panes open. The one feature it’s missing in this area that I’d really like to have is similarly clean support for multiple windows and therefore multiple screens. I’m not an Emacs expert, but colleagues who use it regularly do seem to have similar features available.

I also use a tool called WinSplit Revolution, which provides a somewhat similar feature for general Windows applications, letting you define some preset regions of your screen and then snap the current window to any of them with a quick keyboard shortcut. It can also shift windows between multiple monitors if you have them, again with a single quick shortcut. I can therefore instantly resize windows for things like shells, history/diff tools, and so on if I need them to be a bit wider for whatever files I’m currently working with.

BurningFrog
1. I don't remember when I last ran into anyone who voluntarily limited their code to 80 characters. I doubt it was this century. I worked for a while at a Major Company that had an 80 character coding standard. It was universally despised on my team, where everyone had 2x27" monitors.

Clearly you work in a different environment with different standards. I think more or less formal coding standards are important for any dev team. But they can be very different in different teams. Don't assume what you have grown used to and comfortable with is some universal truth that must fit everyone for all times.

> But what should I guess? If I look at your code and see a 90 col line somewhere, how do I know you won't drop a 100 col line in and hurt the readability again?

If we work on the same team, that is a discussion we'd need to have. Until then, let's continue being happy in our respective circumstances, OK?

2. By "Readability" I mostly mean "cognitive load" for the human reader of the code. What to fit in a line is mostly decided by what's an easily digestible chunk. If you can fit "one thought" into one line, that's ideal. Line length is a factor, but just one of many, not one that overrides every other.

So, come to think of it, I actually would break out a variable solely for line length reasons. Absolutely not for the sake of 1 character, but probably for 20.

zo1
Have you thought about:

    message = "Shipment seems fine"

    if not_shipment_qty:
        message = "Shipment is not fine"
    elif shipment_qty < 0:
        message = "No quantity"

    abort(400, message)
pyre
That is semantically different. It always calls abort(). In this case abort() raises an exception that returns a HTTP 400. I'm not going to abort if everything seems fine. :P

If you wanted to do this pattern, it would look more like this:

  message = None

  if not_shipment_qty:
      message = "Shipment is not fine"
  elif shipment_qty < 0:
      message = "No quantity"

  if message:
    abort(400, message=message)
(Note: In this case the keyword argument form of message is required, because all keyword args get packaged up into a JSON body of the response.)
pyre
> Why is 3 stupid?

Just to be clear, I do use that pattern in practice, but I usually feel 'dirty' about it. Sometimes I also do things like this:

  is_admin = (membership.type == 'master')
  is_current_group = (membership.group == session.group)

  if is_admin or is_current_group:
    do_something()
but I find this easier to justify because I'm adding something more than just the breakup of a line. I'm adding semantic meaning to other developers reading the code. In the example I gave, saying "message=msg" doesn't add anything (as opposed to say "message=bad_shipment_msg", but maybe the definition of "bad_shipment_msg" pushes the string past 80 columns by itself).

As for the example of reusing the message, maybe it's bad practice, but I would end up with tailored messages describing the edge case (e.g.):

  if not shipment_qty:
      abort(400, message='Must pass a quantity')
  elif shipment_qty < 0:
      abort(400, message='Quantity must be > 0')
Edit: I do the boolean definition thing more then "sometimes" because I prefer to make complex boolean operations easy to understand, and to also convey the meaning of what you want to achieve.
sago
I think it is pretty essential for boolean expressions too, yes, anything that isn't a single comparison, at least.

Interesting you find aliasing in variables 'dirty'.

Would you feel dirty writing something like

    def my_method(self):
        contents = self.contents
        ... etc ...
which I use often if I'm going to use self.contents a lot in that method. It has some performance benefit in rare cases, but mostly it reduces clutter, makes lines smaller, and means I type less. But again, it is 'pointless', in one sense.

From the current code open on my machine, even one character variable names!:

    w, h = self.width, self.height
    ...
Dirty? Stupid? (I'm not being facetious, I'm genuinely interested in your aesthetic sense here).
coldtea
With autocomplete you don't get anything with "one character var names" (leave those for i, j, k etc).

And no reason to pollute the local namespace with both self.contents and contents.

What if you do this somewhere lower for example:

contents = contents[:limit]

did you mean to NOT change self.contents? Because that's what you got. Whereas:

self.contents = self.contents[:limit]

would propagate it.

sago
> (leave those for i, j, k etc)

Why use them then if you have autocomplete? Since character variable names are useful as very short conventions, I'd never want to see them used generally. Someone working in this code would have to know the meaning immediately from the name, as for any variable. In my application area x,y,w,h,r (radius) and c (context - which is domain specific, but is present in about 50% of LOC in my current code-base) are all as ubiquitous as i and j (I'd probably not be comfortable with k, too deep nesting). i and j are much rarer in python, either using sequences of underscore for 'don't care'.

On the second point, there is reason, as I pointed out. It makes code shorter, clearer, and in some cases more performant (when contents is a property, for example). Don't get me wrong, I was following up on the specific point, I wasn't trying to recommend this style as good general practice (alias all your self variables at the top of a method - erm, no).

The lack of 'const'ing in python is a risk, yes. We use immutable data structures whenever possible, including immutable classes, because we try to ensure as much code is written without side effects on data. I'd want to not alias variables that have side effects applied to them, yes.

But you're right that it makes it easier for a sloppy edit to mess things up. In most cases the 'sloppy' would be adding the side effects at all, however, which either version has.

Still, in pages of such code, it helps to write

    cos_t = math.cos(theta)
    sin_t = math.sin(theta)
    x, y = self.position.x, self.position.y
    return x*cos_t - y*sin_t, x*sin_t + y*cos_t 
rather than

    cos_theta = math.cos(theta)
    sin_theta = math.sin(theta)
    return self.position.x * cos_theta - self.position.y * sin_theta, self.position.x * sin_theta + self.position.y * cos_theta
particularly as the number of uses of x and y increase beyond two in a functon.

Ultimately code-quality and maintainability can't be mandated by a PEP or any universal rule. But like any field, you have to understand the purpose of the rule, and weigh up its risks and benefits before you break it.

coldtea
Well, for mathematics and such cases (physics etc), yes, I agree that x vs self.position.x etc is handier.

But I wouldn't ever do it for the "more performant" part, unless I have profiled the code and it indeed makes a non trivial difference (I know aliasing to a local makes a difference it itself - but I mean it should be significant when the whole program is taken into account, even if it was 1000x faster to access the aliased local, it wouldn't make sense to optimize a part of the program with it, if said part is only responsible for 1% of the total running time).

For the general case, I suggested i, j, k only because they are well known conventions, so their meaning will be instantly understood (and of course, if one can avoid such indexes altogether, e.g. with a "for item in" loop, one should).

pyre
> Interesting you find aliasing in variables 'dirty'.

I don't find aliasing by itself to be dirty. It is just in this example, it would not be adding semantic meaning (as in the "named boolean expressions" example) and it would be used in only a single place (immediately on the next line) so I find it to be the least justified use of aliasing.

DonaldFisk
It isn't just a historical accident. There's a good reason why they were about eighty columns. It's because the eye can't comfortably scan much further.

That's why pilots are recommended to scan horizontally no more than about 10 degrees at a time when looking out for other aircraft: http://www.skybrary.aero/index.php/Visual_Scanning_Technique

bsder
> There's a good reason why they were about eighty columns. It's because the eye can't comfortably scan much further.

Except that you are wrong.

One of the links in the comments here has research that shows that reading speed increases significantly to at least 90 characters and may increase further than that.

DonaldFisk
This?

http://psychology.wichita.edu/surl/usabilitynews/72/LineLeng...

I had to move my head with every line I read. (The PDF is somewhat easier on the eyes.) Not a single reference to aviation, the context where most of the related research has been done, and where research matters most, as people's lives depend upon it.

The article was specifically about reading news on-line, and was a very small study. Reading code is somewhat different to reading prose in natural language such as news. To understand a portion of code at all, you need to take in every token. With very long lines, this means having to move your eyes back and forward. Laying it out vertically makes scanning a lot easier.

adrusi
That's... true, but lines of code don't actually reach nearly 80 characters in length when you limit lines to 80 characters. Once you subtract the indentation, the remaining width of the line between the termination and the 80 character mark, and the fact that many/most lines won't be hitting the line limit in the first place, you'll find that a limit of 80 characters makes the average line length roughly 50 or 60 characters of actual code.

Having lines be too short is also a concern for legibility, because even when lines are short, there's always the risk of the reader missing the next line at every line break.

The 80 character line is actually an artifact of punch cards, which supported 80 characters per card. And that's probably a remnant of some automatic loom that for some design reason, worked best with instructions fed in chunks of 80s.

DonaldFisk
You should have the whole context comfortably within view, which means all the characters in the lines above and below should be in the same 10 degree visual block, i.e. about 80 characters.

The exact value of 80 characters might be because of IBM punched cards, but that value was chosen because printed media already had that limit, or a smaller limit, e.g. broadsheet newspaper columns. People have been writing that way for millennia.

Two other points:

(1) 70 or 90 might have been acceptable alternatives, but 80 was chosen. It's approximate. Fewer limits the amount of information per line, and more limits the font size you need to scan comfortably. A wider screen allow you to open up several windows. Having one big window isn't such a good idea.

(2) I have never been bothered by this limit, except when others break it and I have to read their code. Occasionally, sticking to it requires some thought regarding program layout. If you find yourself exceeding 80 columns often, you're probably doing something wrong. You might be nesting your code too deeply when you could call a function which handles some of your conditional logic, or your function names are too long, which suggests the underlying functions are doing too much and should be split up.

st3fan
80 columns is for old people.
pekk
Because old people are bad and lame, right? How is this kind of remark allowed on HN?
st3fan
I'm old.
pekk
As a black man, <insert negative remark about black people>.
antimora
It kinda bothers me when in his presentation Raymond says make NP P. A problem is and have always been in P if there is an algorithm for the problem that solves in polynomial time. You can have an algorithm for the same problem that does not solve in polynomial time but this does not change the nature of the problem.
Lord_DeathMatch
T'was a joke; Non-Pythonic vs Pythonic (NP v P)
linsomniac
This is the best talk from PyCon2015 that I've seen. Raymond is a great speaker, but he really hit it out of the ballpark with this one.

Whenever I try to think "How would someone smarter than me solve this?", Raymond is one of the people I am thinking about. I'd highly recommend this talk.

Aside: A few days after seeing this, a co-worker asked for my recommendations on a Python project he was working on. Which involved some Python code that was translated over from Java. Pretty much exactly what Raymond was talking about fixing here. I told my coworker he should watch it. A week later he comes to me following up on it, I ask if he's watched it. No... Then he proceeds to ask me what sort of indentation style he should use and what format for the inline docs.

A number of these answers are highly unidiomatic, symptoms of people coming from another language to Python. Trying to shoe horn one language's patterns into another is fraught with problems, not only are you going to be less effective in the new language but experienced coders of that language are going to hate working with your code.

Raymond Hettinger's PyCon 2015 talk "Beyond PEP 8 -- Best practices for beautiful intelligible code" has an excellent example of a Java -> Python case: https://www.youtube.com/watch?v=wf-BqAjZb8M

msellout
Which answers in particular?

I thought most of the answers were quite prescient of features that would be introduced to the standard library some years later.

Apr 13, 2015 · 3 points, 2 comments · submitted by krig
mattbillenstein
He kinda mailed this one in no? Skimmed this and for 50+ minutes got almost nothing out of it...
krig
I thought it was a pretty nice demonstration on what pythonic means. But I agree that it was weaker than his usual talks.
HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.