We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Writing Zenlike Python

00:00

Formal Metadata

Title
Writing Zenlike Python
Subtitle
Write beautiful, Pythonic code with insights from the legendary Zen of Python
Title of Series
Number of Parts
130
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
There's a profound gap between working code and Pythonic code. To the developer whose first language is NOT Python, the distinction can appear blurry, even arbitrary. What is this "one obvious way" all those Python nerds are going on about? Most of us are familiar with the "Zen of Python", Tim Peters's legendary, if tongue-in-cheek, set of guiding principles for the Python language. But can they actually inform Pythonic code? In this talk, Jason C. McDonald will unpack how the twenty principles (including the unwritten rule) of the Zen can guide you to write beautiful, maintainable code, by treating Python AS Python! This talk is intended primarily for developers who have come to Python from another language, no matter their experience level. McDonald will shed light on how to work WITH Python's type system, statements, and iterative tools, rather than against them. You'll walk away with a new appreciation of the language, and an understanding of what Pythonic really means; an understanding which will empower you to find the One Obvious Way to solve any problem in Python.
61
Thumbnail
26:38
95
106
WritingSoftware developerHypermediaComplex (psychology)Population densityPersonal digital assistantRule of inferenceCurvatureError messageImplementationPauli exclusion principleSqueeze theoremCodeLengthFormal languageDifferent (Kate Ryan album)CodeThread (computing)WebsiteCASE <Informatik>Goodness of fitNamespaceInternetworkingWeightTwitterElectronic mailing listAuthorizationBitGame theoryInterpreter (computing)Electronic program guideMultiplication signArithmetic meanSource codeEaster egg <Programm>SpeicherbereinigungSoftware maintenanceError messageOpen sourceLogicEducational softwareStatement (computer science)NeuroinformatikImplementationOrder (biology)Squeeze theoremWeb-DesignerComputer programmingEntire functionRule of inferenceMusical ensembleBeat (acoustics)Gastropod shellHypermediaComplex (psychology)Control flowSparse matrixMatching (graph theory)QuicksortElement (mathematics)CountingCompilation albumPauli exclusion principleStack (abstract data type)CurvatureRight angleMeeting/InterviewComputer animation
Formal languageComputer programmingMathematical optimizationSoftware developerCore dumpCodePauli exclusion principleOptimization problemFocus (optics)Modal logicFormal languageInterior (topology)CodeDivisorRight angleElectronic program guideProgramming languageMultiplication signView (database)ImplementationTerm (mathematics)Computer programmingMereologyLatent heatSelf-organizationArithmetic meanSoftware maintenanceStrategy gameCore dumpPauli exclusion principleMoment (mathematics)DemosceneRankingInterpreter (computing)WebsiteComputer animation
Line (geometry)NP-hardSpacetimeOperator (mathematics)Line (geometry)Condition numberEmailElectronic mailing listCASE <Informatik>Suite (music)Dependent and independent variablesCodeStatement (computer science)Computer animation
ImplementationParameter (computer programming)Matching (graph theory)Expert systemLatent heatElectronic mailing listDefault (computer science)MereologyTrailSound effectInternetworkingRandomizationCodePoint (geometry)BitFormal languageComputer scienceImplementationNP-hardFunctional (mathematics)Order (biology)Reading (process)Rule of inferenceProcess (computing)NeuroinformatikCache (computing)Computer animation
Electronic mailing listLine (geometry)ParsingBitImplementationComputer fileCodeLogical constantInformationNamespaceComputer animation
NamespaceAcoustic shadowJava appletNamespaceMoment (mathematics)Functional (mathematics)Formal languageSound effectModule (mathematics)Information overloadComputer animation
Simultaneous localization and mappingNamespaceModule (mathematics)Open setFunctional (mathematics)Simultaneous localization and mappingLevel (video gaming)WindowComputer fileResultantNamespaceComplete metric spaceGoodness of fitAcoustic shadowComputer animation
Code refactoringComplex (psychology)AlgorithmReading (process)Functional (mathematics)Statement (computer science)Point (geometry)Moment (mathematics)Electronic mailing listMultiplication signDemosceneCodeAbstractionQuicksortLibrary (computing)Term (mathematics)Programmer (hardware)Software bugDisk read-and-write headReal numberProcess (computing)Link (knot theory)Computer animation
Complex (psychology)Sound effectPC CardComplex (psychology)Loop (music)Ferry CorstenSystem callLogicoutputClassical physicsControl flowLevel (video gaming)InfinityFunctional (mathematics)CodeComputer animation
Complex (psychology)Complex (psychology)TwitterMultiplication signCodeComputer animation
Complex (psychology)LogicObject-oriented programmingCodeLogicSet (mathematics)CASE <Informatik>Greatest common divisorGroup actionMultiplication signElectronic mailing listComputer animation
Complex (psychology)ImplementationCodeCurvatureCodeActive contour modelImplementationLine (geometry)Data structureSpacetimeMultiplication signComplex (psychology)Point (geometry)MereologySet (mathematics)Universal product codeComputer animation
Error messageCurvatureNP-hardLimit (category theory)Line (geometry)Limit (category theory)Level (video gaming)MultiplicationCodeSpacetimeInterior (topology)Line (geometry)Loop (music)Multiplication signProduct (business)Text editorError messageCurvatureLibrary (computing)Computer animation
Population densitySparse matrixCodeDynamical systemMusical ensembleSpacetimeCodeSymbol tableSparse matrixPopulation densityLogicComputer animation
Population densitySparse matrixParsingSpacetimeSpacetimeCodeSpring (hydrology)Multiplication signComplex (psychology)Computer animation
Error messageState of matterException handlingPattern languageLine (geometry)Source codeAbstractionLibrary (computing)Code refactoringPersonal digital assistantRule of inferenceUniqueness quantificationBeat (acoustics)WritingLibrary (computing)Error messageState of matterSource codeLine (geometry)AbstractionVirtual machineSoftware testingCodeEntire functionRevision controlException handlingLie groupGame theoryRun time (program lifecycle phase)Software industryInternet forumArithmetic meanVideo game10 (number)Module (mathematics)Reading (process)Computer programmingPoint (geometry)Rule of inferenceImplementationOrder (biology)Standard deviationSoftware maintenanceStability theoryMultiplication signTerm (mathematics)Control flowBeat (acoustics)CASE <Informatik>SpacetimeMereologySoftwareEmailRight angleComplex (psychology)WritingComputer animation
PiRoutingCodeCASE <Informatik>Meeting/Interview
Data managementBitPoint (geometry)Meeting/Interview
Transcript: English(auto-generated)
There we go. Now we can see my talk. That is awesome. Okay, so, um So the question is, what does it mean to write Pythonic code? If you've been using the Python language for any length of time, you have probably noticed that there is a canyon of difference between
Functioning code and Pythonic code. Tim Peter's now famous, or should I say infamous poem, Zen of Python, is considered one of the pithiest summaries of what constitutes Pythonic code, but I think sometimes it seems a bit open to interpretation.
So in this talk, I'm going to be Breaking down how I believe the 20 aphorisms, yes 20, I swear that's not enough by one error, of the Zen of Python can be applied to your code right now.
Even though this is, it says on the guide, this is geared towards beginners, I think this is something that anyone can benefit from. So a little bit about me, like it was mentioned previously, I am the CEOly developer of Mouse Palm Media, which is my own open source startup. We make educational software and we are working on building an open source game engine as well.
I'm the author of Dead Simple Python, which is soon to be a book from No Starch Press, early in 2021, hopefully, and I can be found all over the internet as codemouse92. I'm especially visible on Dev and
Python's chat room on Freenode IRC, but you can find me all over the net, you know, Stack Overflow, GitHub, Twitter, very active there. You can find the complete list of all the things I do in all the places I am at my website and adeliblebluepen.com.
So in case you've never read the Zen of Python, or if it's been a while, I'll just go ahead and read it to you now. Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts.
Special cases aren't special enough to break the rules, although practicality beats purity. Errors should never pass silently unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one and preferably only one obvious way to do it, although that way may not be obvious at first, unless you're Dutch.
Now is better than never, although never is often better than right now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea. Let's do more of those.
So to understand the Zen of Python, we have to start with understanding where this thing even came from to begin with and this showed up in a June 1999 comp Lang Python thread, which was rehashing an eight year old debate about garbage collection. And developer Patrick Phelan suggested that Guido van Rossum and Tim Peters should work out some sort
of elements of style for Python, to which Tim responded with a notably snarky humorous attempt at it. It wasn't until 2004, though, that actually gained the name the Zen of Python and was codified as the pep 20 we know and love. And fun fact, although you may already know this, if you run import this in any Python shell, that'll display the Zen.
Funny thing, though, is if you read the source code for that Easter egg, it doesn't even follow any of its own advice intentionally because we all love irony. But before I can really break down the Zen of Python, we have to answer
this question about whether or not Tim Peters was actually being serious when he wrote it. Well, as Tim later described to Barry Warsaw, it was a throwaway Python list post, but like all great triumphs of literature, it was written during commercial breaks while watching professional wrestling on TV and munching on a ham sandwich. All true.
That's Tim Peters for you. Ironically, his post initially fell on deaf ears as that garbage collection wrestling match raged on. Like I said, it was until 2004 that was really codified. But whether this was intended as a joke or not, as Barry Warsaw pointed out, the Zen of Python captured the language's aesthetic through the eyes of one of the earliest Pythonistas.
By the way, I should mention that Barry Warsaw also set this thing to music this past May. So you can find that on his website. He recorded a song, the Zen of Python, which I think we should all learn how to sing. Maybe we should sing that at our next conference, our anthem.
So I'm going to break down this statement by statement, but instead of going in order. I'm going to address several related concepts together and I want to start right in the middle as I believe the entire Zen of Python hangs on this one statement. Readability counts. Pythonic code is readable above all else.
Because see, the computer is not picky. It's happiest with binary any day. Programming is really the art of converting human thought to computer logic. Code exists for people, whether
they be co-workers, future maintainers, people learning from our code, or just ourselves, two years from now. And it's really tempting when we're coding to try and write clever code. It feels cool to write clever code. It makes us feel smart. But as you're going to see throughout this talk, clever is kind of the very
antithesis to Pythonic. It doesn't mean that we shouldn't be writing brilliant code, but clever code can be a bit of a problem. Especially because it often sacrifices readability. Brian Kerrigan, the co-author of the C programming language. Don't knock it. Python was written in C, or at least the main interpreter was.
He said, everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? I would like to add, if you can't debug it, how was your successor supposed to? So later on in the Zen, Tim says there
should be one and preferably only one obvious way to do it. It's one of the most quoted parts of the Zen, but what is obvious. Well, obvious is, I believe, all about finding the optimal solution to a specific problem.
What is the best possible way to solve this specific thing I'm trying to solve in my code? The trouble with obvious is that it's not always obvious looking into it. It's only obvious looking back retrospectively. Reading the code, you go, oh yeah, that makes sense. Why did I think of doing it any other way? That's what obvious means in Python.
As you'll see in a moment. Now, our mantra in Python is there's only one way to do it. This contrasts with some languages like Perl, where they say there's more than one way to do it. And we save this in C++ too, which is my other language.
But the trouble is both Python and Perl ships working code, maintainable code. So who's right? I would actually argue that Python and Perl are not really on opposing sides at all and understanding this will help make this concept of obviousness more
easier to understand. Apparently, Guido van Rossum doesn't think that that these two languages are on opposing sides either. As he said, when asked about it, the funny thing is that while there's a lot of animosity in the lower ranks, I've actually been very friendly with Larry Wall and Tom Christensen ever since we met five years ago at the VHLL symposium that Tom organized.
So if Guido's getting along with the creator of Perl, we probably should too. So like I said, these are not on opposing sides and I'll show that by breaking down kind of these two mantras. So in Python, like I said, we say there's only one way to do it.
We are looking for the one obvious way for each unique situation. The trouble is we don't necessarily know this right off because remember obvious is retrospective. So we have to try things out. We have to experiment to find the best way to do it.
Over in Perl, they say there's more than one way to do it. And this is a way of keeping people from shutting down experimentation because, well, we've always done it this way. But the goal is still looking for the best solution to that particular problem. It's not that we're just looking for any solution, it's that we're still looking for the best one.
So you see that this is the same strategy, it's just the opposite focus. Python says find the optimal solution and experiment if necessary. Perl says experiment to find the optimal solution. So really it's the same thing in many ways.
And on this whole note of obvious, like I said, that one obvious way is retrospective, which is why Tim says, although that way may not be obvious at first, unless you're Dutch. Once we know the solution, once we see the working code, then it all becomes clear. Now, Python's implementation details do advise this. When you understand how Python does things behind the scenes, it helps you pick
better approaches for your particular situation. But we're not all core developers. We don't all know the inner workings of Python necessarily. You know, we don't understand it better than most of us, ergo, unless you're Dutch. So he'll get to the obvious way probably before most of us will.
But then there's also this factor that the one obvious way is continually evolving. I have a copy of the Python Cookbook from Python 2.4, ancient history, and all the solutions in there, of course, were the obvious way at the time. Python Cookbook was very popular at that time, but
it's no longer, none of these are any longer the one obvious way. The one obvious way has changed as the language has changed. So it's important to remember, too, that what's obvious yesterday may not continue to be the obvious solution tomorrow. So Python code is readable and it's obvious.
It's also beautiful. Beautiful is better than ugly. Trouble is, what is beautiful code? View these in the eye of the beholder. It's a little hard to nail down. But however you define it, beautiful code is always a pleasure to read because we don't want to sacrifice readability.
It can be really hard to nail down what beautiful code is sometimes, but you know beautiful code when you see it and you know ugly code when you see it. Most people would agree, given one piece of code that, yeah, yeah, that's pretty bad or yeah, that's pretty good.
And in terms of writing this, this is why we have the pep8 style guide to begin with, to help advise writing beautiful code, although that's not the whole picture of beautiful code, but it's a it's a good chunk. So this is this makes the most sense with some actual code. So Here's some ugly code.
And I've said I take full responsibility for writing this monstrosity. What are the problems? Poor spacing, for one thing. The lines are crammed together. We have multiple statements in one line and defining N and R on the same line if
Just, you know, the, the conditionals that the header and the header and the suite are on the same line. This is just nasty. It's over complicated. Besides that, it's hard to read. I'm using, I'm not using any of Python's particular abilities. I'm just writing C code in Python. Basically, this is not nice.
Here's the same goal, but done beautifully. So this employs better spacing, especially around those operators. As you see later, white space is important. There's one thought per line. So it's much easier to break down what is going on. It's idiomatic. I'm using Python as Python. I'm using this list comprehension. I'm using the star operator.
If you don't know what these are, of course, you may have to read the documentation. But once you know the syntax, then it's very obvious what I'm doing. And this is easy to read besides that. Now, that is not to say that all list comprehensions are automatically beautiful, but I think this is one
case where they are. So Pythonic code is readable. It's obvious. It's beautiful. What else? Pythonic code is explicit. Surprising behavior was always a problem. By the way, a little bit of a relevant rabbit trail. This is why I'm well known around the internet for my dislike of JavaScript.
It's not because I'm picking on JavaScript or because, you know, just some random personal dislikes of syntax. My issue with JavaScript is simply that it has too much surprising behavior. And even if experts will admit this, surprises are bad in any language. Most of our issues with Python even come from surprising behavior. If you've ever tried to pass a list
as a default argument to a function, you know what I'm talking about. Mutability can be surprising. So we want to avoid surprising behavior. And besides that, if you have to comment what the code is doing
in order for it to be clear, then you really need to be rewriting the code. The code's not Pythonic at that point. Now that's not to say I don't believe in comments, but comments have a specific purpose. They should be describing the intention. Comment why, not what. I like to use the rule that the
comments, excuse me, should describe the behavior without having any reference to the actual implementation. And in effect, you're a good comment is part of a living specification. And if the comment doesn't match the code, then you assume both are wrong and you check and rewrite both to make the match.
And then, of course, there's this issue of naming, because usually when you're reading code, you're looking for a given behavior and the name is one of the first places you're going to look. Never send a comment to do a name's job. And yes, naming is hard. Fully acknowledging Phil Carlson's famous quote, there's only two hard things in computer science, cache invalidation and naming things.
So here's an example of some implicit code where this becomes very clear. The names are vague. We're parsing data. What data? What are we parsing out of the data? Who knows? Where is this sep coming from? I don't see it defined. Okay, maybe it's coming from that star
import, but if I have more than one import, then that gets a bit foggy. And what is this even doing? I have no idea. We're parsing data out of some file, I guess. Here's the same code, simply rewritten to be explicit. I've changed none of the implementation.
So the names now reflect the purpose. I'm parsing a name out of a line. Those lines are coming from a list I'm putting into a list called speakers. Okay, this is coming from file. This is making more sense. And I've clarified that sep import. That's coming from constants. So that's useful information. I know where that is defined. It's very obvious what
this is doing. And if it weren't already, that comment makes it much clearer what the goal is. So focusing a little bit on that import situation. So explicit is better than implicit and adding to that namespaces are one honking great idea. Let's do more of those.
See, the thing is that import star I showed a moment ago is absolutely insidious. First of all, because Python doesn't have any concept of overloaded functions, like you may be familiar with from languages like C++ or Java.
Instead, it just shadows the previous function. You can't have two functions named spam. The second one is going to hide the first one. And this can have some pretty unexpected side effects and consequences and working backwards is really hard when you don't even know what module something is defined in. So an example of namespacing being important is here.
So we're starting importing from two modules door and window. Who knows what we're importing It's unclear what we're even really doing. Am I opening the door or closing the
door or the window. And open, by the way, fun fact that's coming from window. I defined it in door and window in complete defiance of could sense and it happens. And that, of course, completely shadows the built in open function. Which then means, okay, this is going to be surprising if we now try to open a file later on.
Or if I want to edit slam. Where do I edit that what module does that come out of And if we were to import star this module that you're looking at here, then all of these problems would just replicate up to the next level. So this is bad. Let's fix that.
No more star imports and as a result, we no more. We no longer have shadowing we're using explicit namespace is door dot open. Okay, so I could use the built in open function just fine now. It's also clear what I'm doing. I'm opening a dorm slamming the door intent is much more obvious and it's clear where this stuff is originating from as well.
So if I want to edit slam I go into door so On this same point in the face of ambiguity refuse the temptation to guess. So when you come up against code that is not overly explicit
You need to insist on knowing what's happening abstractions are not there to save us Thinking they're there to save us typing. You still need to understand when a link list is being used versus a Versus an array because that's going to have implications on the performance of your sorting algorithms
or even whether or not use the built in sorting algorithm. What algorithm does it use You know, how does that function you're relying on actually operate behind the scenes, you should have some understanding of this because it's critical to the to the debugging process and to writing good solid maintainable code.
Guessing what's going to happen is just going to lead to bugs and misunderstandings If it's not your code, you're dealing with you're dealing with a library you're dealing with Python itself, which has unfortunately some surprises in it, read the documentation. If the documentation is sparse read the code, find out what's actually going on abstractions are there to save us typing not to save us thinking
But if it's your ambiguity. If it's your team's ambiguity just fix it explicit is better than implicit Okay, so Python code is readable obvious beautiful and explicit. Ideally, it's also simple. We write code to be maintainable not to be clever.
Um, and I think you're gonna see an example of this here. You got that voice in your head that says, well, real programmer. Don't you hate that term. A real programmer wouldn't use it if statement and you wind up spending all this time looking up some sort of advanced way of handling What an if statement would have done perfectly well doing and and I guarantee almost every person
in this audience has had a moment like that sooner or later. I know I have many times But you have to understand it takes more skill to write simple maintainable code than to write clever code. So let the simplicity be your show skill. It's hard to read clever code. It's hard to understand it ergo clever
The basics are your friends. So here's some complex code. This isn't necessarily bad, but you see, I tried to make this dry by taking this input logic and putting into its own function. But I'm only using it once. So this is dry nearing absolutely arid it's this is this is terrible.
Because now I have to add this extra level of complexity. I have to do this sys exit call Which works. But what if there's some unexpected side effects of sys exit that I'm not thinking about. So this is Adding complexity that while it's okay to ship this it doesn't need to be there. I can just stick with the classics. The infinite
while loop with a break statement. This is easy to read easy to maintain stick this in my main function and I'm good to go. So the simple solutions are sometimes the best. In fact, if you have a simple solution. It's probably better to do that than a complex one.
But complex is better than complicated while simple is best. It isn't always possible to go for simple and you don't want to confuse elegance of obfuscation. I don't know where I picked this this up somewhere on Twitter, but I loved it elegance is not obfuscation Complex code still needs to be readable beautiful and obvious. It might take you more time to
read it, but it should not take more effort to read it as long as it's Pythonic So this is bad code. This is complicated code. Once again, this is kind of like writing C code in Python. Oops. Sorry about that.
There's too many steps here. First of all, I'm not even going to support your, your intelligence by breaking this down the logic is obfuscated I'm completely ignoring all of the all the wonderful syntax that Python offers to simplify this. This is just plain nasty. Okay, so what if I wrote code for finding greatest common factor and I made it just complex, but not complicated. What would that look like.
Oh, much better tighten the logic up. First of all, first and foremost, it's very clear what this is doing. You don't have to struggle to understand this. It just takes more time to read it and I'm utilizing the syntactic sugar. I've got a set comprehension. I've got a conditional in this comprehension.
So this is much cleaner and it works just as well. So And again, you can get set comprehensions list comprehensions to get away from you to be careful of them. But this is a good case of a nice clean set comprehension in action. This is good complex code. There's no simpler way to do this that I know
So Python code is simple or it's complex and it is obvious. So with those in mind, if the implementation is hard to explain. It's a bad idea.
That is if you are having a hard time explaining the code. It's not obvious and it's not simple. It's probably not even complex at that point it's getting towards complicated. The problem with cleverness is basically that it's exclusionary. That's the poison. Because it feels clever because you're part of a select set that can understand this, you have
the prowess to understand what is going on here. And that is just, that's just terrible so cleverness is exclusionary. Don't be clever. You wind up excluding yourself sooner or later because in two in six months, you're not going to remember what that clever code did
But there's an important corollary here. If the implementation is easy to explain it may be a good idea because we're all Python code is easy to explain, not all easy to explain code is actually good or Pythonic And just as all Python code is obvious, but not all obvious code is Pythonic.
This is kind of along the same lines as all snakes or reptiles, but not all reptiles or snakes. So your code should be easy to explain, but it needs to fulfill the other criteria as well. So are you still with me. Pythonic code is readable beautiful obvious explicit and simple or at least complex to that aim Pythonic code is flat.
Why is that because it's hard to read deep nesting, especially in production code. We can't read white space. And when it gets deep and complex. It's really easy to make mistakes and get it wrong. Is this in the outer else or the inner if. And by the way, this only applies to code, not to your data, not to your folder structures in your collections. This is for code.
This is overly nested code here. I don't need to say much about this here, but this is really prone to indentation errors. It's hard to reason about what's going on in a multi nested for loop and the line limits are now getting painful true sad story. I worked with the Python developer who switched to 120 line limits and to space indentation because he was nesting all the time.
That's it. You need to do that you're nesting too much. So just keep it flat. I'm instead of this multiple nesting thing I'm using inner tools product inner tools is a great built in library.
Please use it. It's very helpful. This is much easier to reason about quick glance the documentation and the line limits are not a problem. We have one level of indentation very unlikely to mess that up. Meanwhile sparse is better than dense skilled musician or composer will tell you the single most important symbol in
music is the rest as Beethoven says the music is not in the notes, but in the silence between The silence defines rhythm. It defines dynamics and one note for the next without it. Music is just a cacophony. The same is true of code white space gives us a chance to pause and consider what
we've read allows us to organize the code logically. And again, while one liners make us feel clever. Don't be clever. It sacrifices readability. Do I even need to say anything. This is obviously pretty dense. This is hard to read, even though it's decent Python code at the white spacing is just terrible. So let's fix that.
Same code. I haven't changed a single character in this code, except the white space. This is much easier to parse. It's broken down into logical chunks. And, you know, it's okay that it's a bit longer vertical spaces there to use a side note if anyone's thinking that's not Python. If
you could have just reverse the spring. Hey, I optimize for time and space complexity on this one. So this is Python for my goal. For checking for palindrome I'm gonna Get through this here as quickly as I can. Then I don't have any questions yet. If anyone does have any questions, put it in there. I don't get any of those. I'll probably go towards them. I'll probably use a little more of my time. So the, the term exception is meaningful.
Errors should never pass silently. An error is an exceptional state means we've left the happy path and we're now into a territory where we need intelligent intervention to resolve it correctly. So if there is no intelligent intervention.
It's best to just crash the program at that point and error caught at its origin is always going to be easier to debug than errors created with an when an exceptional state moves forward blindly. And I like how Python developer Mike for not calls this the diaper anti pattern. Whenever you have this catch all
because you're, you're catching all of the errors and you're silencing them all the exact opposite at this point of design. Mike says in the harsh and unforgiving real world. The source may be tens, hundreds, or even thousands of lines away. Buried under umpteen layers of abstractions in a different module or worse in some third party library.
When it fails, just as diapers fail, it'll fail in the small hours of the night when we would rather be sleeping and someone important will make an awful fuss about it. It will not be fun. So all that to say You know, don't
Just, you know, don't, don't let them pass silently. Let them explode where they're happening unless Explicitly silenced. It's okay to explicitly silence an error, but only if you've already applied intelligent intervention or you've otherwise resolved the exceptional state. So if you already know, okay, I don't have to worry about
key errors here because I'm just going to return none. That's fine. Silence that error and move on. But if there's an unexpected error there, perhaps you get a runtime error, which if you're getting that on a dictionary read you got bigger problems than errors, but You need to be specific silence only the error you resolve and let everything else continue to blow up at the source just
because it works on your machine and to pass the test does not mean that it's actually going to be safe and safe. So be very aware of that explicit is better than implicit Okay, so these next two aphorisms really aren't so much about Pythonic code as about Python and coding.
And the biggest lie we tell ourselves, I think, is the is I will do it later. So Tim says no now is better than never. Because when you say I'll do it later. You probably won't. And the longer you
wait, the more you're going to have to refactor your code to pull it off. So the important thing is to do. Do whatever you're thinking about while you're thinking about it while the idea is fresh in your mind just implemented, or at least set yourself up to be able to easily implemented later. A really good example of this is at my software company.
We are building a game and we have some features who want to add a later version. We don't want to add them right now we're trying to limit our feature set for one point out. So we simply left spaces for us in the code and we structured certain parts of the code to allow us to do these things down the road. We aren't doing them right now, but we have the space to do them.
But important and perhaps confusing corollary, although never is often better than right now. Isn't this a contradiction to now is better than never? No, because of the other lie we tell ourselves, it'll only take a minute. Yeah, right.
If you have to drop everything to add a bell, a whistle or a gong, it's just not worth adding. So this is all about priorities. You need to ask yourself, is it really needed or are we just piling on needless features? I can't remember who coined this phrase, but someone said that all software will naturally evolve until it is capable of sending email.
So I want to be very careful not to let unnecessary features creep in and push out more important things. Special cases aren't special enough to break the rules, Tim says about this whole Zen. But my code is different, you say.
Okay, great. But that's not actually an excuse because new code is really the only code worth writing. It may be a similar goal, but your code is new, hopefully your approach is new. So if novelty were an excuse, there would be no point in having a standard at all. But we need a standard in order to make things same.
Corollary, although practicality beats purity. Because you have to remember the aim of the Zen or any good standard is to protect and enforce readability, maintainability, stability and performance.
And if the rules are detracting from these goals, we may be justified in breaking the rules. So you can break the rules, but you have to have an objective reason to do so. And that reason can only come from the end. You know, do you need to break a rule in order to keep this code stable, perhaps, or maintainable?
Okay, then go ahead and break the rule. But if the only reason you're breaking the rule, you have to think carefully about this. The reason you're breaking the rule is because of how you chose to implement your code. What needs to change is not the rule, but your implementation.
So make sure you are only getting your exceptions from the end and not means. Okay, so on the label, I said 20 aphorisms, but the Zen only has 19. Like I said, don't worry, this is not an off by one error, because, as Tim said in his original post, 20 counting the one I'm leaving for Guido to fill in.
He left a spot for the benevolent dictator for life to add something, but Guido never did. And perhaps this is just as well, because Python really isn't the work of just one person, it's the work of the entire community. It's always changing and growing and evolving. Just imagine what EuroPython 2030 is going to look like. It's going to be phenomenal.
There's going to be ideas here that are just completely new to us. And it's going to make all the trendy and new and fresh stuff from this conference feel really dusty and outdated. The Zen of Python fits neatly inside the principle of Pythonic code, but you really can't contain Pythonic into any one document.
There's a certain flavor to it that the Zen somewhat approximates, but can't fully encapsulate. Pythonic is just something you learn from experience. It's always being debated, parsed, rehashed, reworked, challenged, improved.
But interestingly, since 1999, the Zen has remained completely unchanged. Pythonic code is always readable, obvious, beautiful, explicit, and simple or complex. We'll just find different ways of doing these things and better ways of doing these things.
So I really hope by explaining the Zen of Python to you, I've given you some practical insights on how you can improve your code using this rather infamously snarky little poem. So, yeah, thank you very much.
So I do have one question here. And if anyone else wants to chat with me after this, I'll be in the Talk Writing Zen Like Python channel over on Discord. And I'll be happy to chat with you all there. So I have one question from Martin. He says, what's your opinion on
code formatters like black that make code universally readable, but in some cases ugly? I would say, well, like with most things, it just depends on what you're doing. Personally, I like black. That's my own take on it. I rather like it because it generally makes my code more readable and not less.
But if you are consistently discovering that your code is not being improved by black, then this is why we have other tools. This is why we have, you know, PyFlakes and or not PyFlakes. Well, we have PEP8 and we have various other tools that can, names are
escaping me right now, that you can customize to meet your needs more specifically. So, you know, if black doesn't work for you, just find something else or, you know, you can go the old fashioned route and just memorize PEP8. It's actually not hard to get used to once you've been working with it for a little while.
And then you can just apply it yourself and not worry about your auto formatter and its opinions on things. So, yeah, I'm actually finishing a little bit early here, which is okay. That's awesome. So stay tuned because coming up next, we have our keynote speaker, Jessica McKellar.
And I'm actually going to turn things over at this point to the next session manager. So it's been awesome seeing you all here and I will answer any other questions you all have over in Discord.