When can you call yourself a professional developer?
Sure, getting paid to write code is probably part of the formula,
but when is your skill set up to that level?
Many folks in the industry suffer from imposter syndrome or other types of uncertainty.
Yet, there are real techniques and skills you should know before you meet this bar.
Dane Hillard is here to share his take on the practices of the Python Pro.
We'll discuss concrete steps as well as abstract design concepts
to help your code make the jump to pro level.
This is Talk Python to Me, episode 246, recorded December 5th, 2019.
Welcome to Talk Python to Me, a weekly podcast on Python,
the language, the libraries, the ecosystem, and the personalities.
This is your host, Michael Kennedy.
Follow me on Twitter where I'm @mkennedy.
Keep up with the show and listen to past episodes at talkpython.fm
and follow the show on Twitter via at Talk Python.
This episode is brought to you by Tidelift and Linode.
Please check out what they're offering during their segments.
It really helps support the show.
Dane, welcome to Talk Python to Me.
Hey, thanks.
It's great to have you here.
I'm really excited about this topic, actually.
I think you've got something good going on here.
It'd be fun to talk about.
Yeah, thanks a lot.
Thanks for having me.
Yeah, we're going to learn what a pro means.
I mean, there's a lot of debate about titles and when are you no longer a beginner or you're
actually a professional programmer and all these things.
So that's going to be a lot of fun to dig into.
But before we get to that, let's start with your story.
How'd you get into programming in Python?
For programming in general, I followed a fairly traditional path.
I went to school for computer engineering, mostly learning C++ at the time, MATLAB, things
like that.
And then computer engineering is kind of this mix of hardware and software disciplines, which
I've mostly not made use of since school.
So I've stuck very much to the software side.
But since I got out of school, I've been doing everything from Perl and PHP and C++ and C
to Python and JavaScript as well.
That sounds fun.
You know, the whole hardware side of computers, it's kind of a black box to me.
And it's just something that I've never really learned.
I mean, obviously, I understand what RAM is and a disk is and buses and all that.
But I couldn't build one or design one or even understand what the little parts mean when
I take it apart other than this goes in the PCI slot.
So that's probably fun to know that level, right?
It is.
And I've admittedly forgotten more than I would like.
But, you know, I think I still try to keep with it for things like Raspberry Pi and Arduino
and things like that from time to time.
So it's sort of fun to keep as a hobby.
Yeah.
It's a bit of a renaissance for that, right?
I mean, it used to be you had to be Dell or somebody like this to make these things.
And now you can spend five bucks and get a little microchip.
Yeah, absolutely.
It's kind of cool.
It's an empowering time in that regard.
Yeah, absolutely.
So you got out of school and you're working with all these different languages.
How did you come to Python?
I want to say that there was a short precursor to my time with Python that was learning Ruby.
And that was kind of at the behest of a friend of mine who was doing a hackathon and wanted
to build some, I think like a domain specific language of some kind on top of Ruby for something.
And I had never used sort of a dynamically typed language or anything like that.
And Ruby was kind of a refreshing experience from what I knew at the time.
And I think around that time, I was also looking for a new language to write my personal website in.
The current iteration was in PHP at the time.
And I had tried Java Spring a bit and didn't like that too much.
So I decided to try Django.
And I think Django was sort of my first major foray into Python because I remember learning a lot of Python stuff at the same time I was learning Django.
Right, right, right.
That's cool.
Well, I think a lot of people come into Python because of Django.
Yeah, I would agree.
I want to do something on the web.
I heard Django is easy and cool.
Let's try that.
Oh, I guess I have to learn Python.
Well, that wasn't too hard.
It's kind of easy language to learn.
But, you know, that also touches a little bit on the subject of what we're going to cover, right?
Some people say, oh, you can learn Python in a weekend.
It's so easy.
And yet, just weekly, I'm learning new things on Python.
And I spend all day diving into it and looking at all the edge cases.
And you can't learn Python in a weekend.
But you can sort of get it together.
And I think there's a really interesting spectrum there from, hey, I made this website.
And I kind of know the language, too.
I'm really good at this language and the ecosystem and so on.
It's broader than it first seems or harder than it first seems.
Yeah, absolutely.
And I mean, I think there's plenty of people out there, too, who don't want or need to get to that depth for a given language.
Especially people who are kind of polyglot, if you will, and need to know a bevy of languages.
Sometimes just knowing enough of that language to solve the problems in those various domains is totally, totally good.
So, yeah, there's such a spectrum of situations and experiences there.
Yeah, for sure.
And then there's the folks who are doing something else.
Economics, biology.
And they just need enough to get through their biology problem or to run that economic simulation.
And that they don't care about the nuances of generators.
They just want to know whether, like, they can get pandas to spit out the answer they need or map plot to, like, show the graph that they need so they can carry on.
Yeah, exactly.
For sure.
All right.
So, before we get to the main topic, maybe just tell us what you do day to day so people know where you come from.
Yeah.
So, I'm still very much into the web side of things these days.
I'm working on jstor.org.
It's an academic research platform, kind of a journal database.
And I've been there for about five years now.
Before that, I was actually in biology to some degree.
I was doing some bioinformatics work.
And I did do a little bit of Python scripting there, but a lot of database administration and things like that also.
And before that, I was doing some radar telemetry.
So, it's quite the spectrum of stuff.
Yeah.
I feel like bioinformatics would actually be really interesting.
Yeah, it really was.
And I think, to me, that's often, like, the joy of programming is that you're both solving problems with code directly, but also kind of picking up these secondhand areas of knowledge about some different subject.
Right?
So, people have a chance to kind of explore beyond just knowing how to write code.
Right.
If you get bored of writing bank software, you can go write, you know, renewable energy software or take your bank.
Yeah, exactly.
Yeah, that's actually pretty awesome.
Because unlike many jobs, developers are in demand across all the industries.
Basically, there's this quote by Satya Nadella that every company is a software company these days.
And I kind of feel like that's right.
Yeah, that resonates with me, too.
I think it's, you know, every company has some area, whether it's, I don't know, it ranges from mundane to interesting.
But every company has this area where they can use software to augment whatever it is that they're doing, whether it's to do directly what they need for their business, or if it's just to make their business better in some way, faster, more efficient.
If they're thinking, well, we need to hire 10 people to like manually do this thing, because it's really slow and tedious.
Well, maybe people shouldn't be doing that thing.
Maybe they should be overseeing the machines doing that thing or something to that effect.
Yeah.
So, let's get into this topic.
We're going to talk about your book, Practices of the Professional Python Pro.
And let's just start with that last word there.
Like, what makes a developer a pro?
I mean, you've had a lot of experiences, a lot of different types of companies.
What do you think?
What's the indicator for you?
Yeah.
So, the title is almost kind of got this double entendre to it.
It gets at this idea that there are practices that can make you a more effective developer.
There are things you can think about as you're developing code to improve the outcomes that you get.
And that is stuff that over time, sometimes decades, right, whole careers, you can build and learn and never run out of stuff to start learning.
But at the same time, I think a lot of these things are things anybody writing code could start to pick up bits and pieces of right away.
And so, in that regard, everyone who's paid to do something is a professional, right?
Right.
Like, if that's you, congrats, you've made it.
And so, I think some of what the book is about also is just like, hey, if you're new and you just want to know what people in the industry are kind of thinking about,
maybe you haven't done software professionally before, maybe you've used it in your biology work or something like that, or you're switching fields altogether.
It's kind of a way to get some insight into the kinds of things you might want to be thinking about.
Yeah, absolutely.
And what I like the title, I do like how it sort of puts that out there is,
these are the things that you would expect somebody who really cares about their craft, either because they love it or because they're paid enough that they're supposed to pay attention to that.
Whatever reason, these are the techniques and things that they do.
You probably are not doing all of them.
Probably you've come from some other industry or you're new to the industry, or maybe even you've been a professional C++ developer for 20 years.
And all of a sudden, somebody told you compilers are out and you're going to go write this funny language with no semicolons.
What do these people do in their pro side of things, right?
Right.
And as experts here, I think there's a lot to take away for a lot of folks.
But yeah, this idea of just what is a pro or maybe, you know, more broadly, so we're not hung up on the money side of it, just like an expert in a language or, you know, in Python.
It's an interesting question of when you can call yourself a developer, when you call yourself a professional developer or something like that.
I don't really know where that is.
We can think a little bit more about that.
But I do know that beginners get frustrated really easily when they're trying to work.
And I'm thinking more beginner programmers, not beginner just in Python.
They've got to solve some problem.
They're like, oh, my gosh, I just heard I have to use a database for this.
I don't even know what a database is.
Not really.
So what do I do now?
And it can be really frustrating.
So I don't know.
What are your thoughts for folks who are not at this level?
But, you know, maybe things like this book would help them get there.
What would you tell them?
Yeah, I think that a lot of the source of frustration as a developer or as a beginning developer is that sometimes you aren't not only do you not know the answer, but sometimes you don't even know the question.
Yeah.
So you're often kind of trying to think about what it is you even are trying to know, whether it's because an error you saw is too obscure or you just can't quite ask the right question.
And so, like my general advice outside the book or sort of tangential to the book is to start figuring out how to search better, like for your problems.
Yes.
So now let me just let me stop you for a second, because I agree with that.
But I feel like a lot of people who are new probably perceive searching for a fix as giving up or I failed to like get this understanding correctly.
Yeah.
I think and I don't mean this in a negative way, but I think that there's this whole sort of hidden realm that a lot of people don't see where it's Googling like crazy.
As a professional software developer, you're like, okay, I got to use this library.
I don't know anything about it.
Let me take a shot.
Nope, that didn't work.
Let's take that error.
Let's search the heck out of that.
Oh, no, I'm over here.
Oh, wait, this is another thing that seems better.
I'm going to search.
It's just there's a lot of searching.
And really soon, at least in my world, when I'm like, if this is not working and I don't have an answer in two minutes, I'm on the Internet trying to find it because often that works.
Yeah, I think that's a really great thing to dispel because it doesn't go away and perhaps only increases as your sort of breadth of knowledge grows or at least breadth of awareness of what's out there and your search skills grow.
You kind of have a bigger surface area to explore and you have to figure out which piece to hone in on to maybe find your problem.
And so it's hard to say just go learn how to search better, I guess.
Yeah, that's one of the elements, but I think it's part of it.
Yeah.
And there is also that danger, right, that you land on either the incorrect answer or something as a beginner that you wouldn't necessarily know how to assess the validity of.
Yes, that's true.
From just plain wrong to malicious or something, right?
Or even just it's a perfectly good answer, but it's not the same situation.
Yeah.
But you don't have the nuance to know that's not actually what I'm looking for.
It's the next Stack Overflow one I got to go after.
Yeah.
So unfortunately, the answer there sometimes is that there's a lot of trial and error.
But again, that sort of sticks with you throughout your career, I think.
Yeah.
I did a show back on 203 with Ned Batchelder and some other folks about beginners and experts in this panel talking about a bunch of beginners.
And I had Ned as the expert.
And it was a really interesting conversation.
And a few of the things that I sort of condensed out of that conversation was there's a lot of things that beginners perceive as a, this is me doing it wrong or this is me not good at it.
But it's just that's how it feels.
Like, for example, being stuck and trying to get a library to work when it's not or trying to get some, like the compiler to work if you're in a compiled language or whatever.
Just being stuck or feeling kind of lost is just part of the journey.
And just like, as a professional, as a pro, you're like, oh, we're in this part of the journey.
We're in the next half hour is going to suck.
And I'm going to be on Google a lot.
But here we go.
And then you just know if you just keep hitting that problem, eventually you'll be gone through it.
Another one, I think knowing data structures is really, really good for people.
And then, like you said, kind of having these battle scars of, yeah, it looks like they're talking about your problem, but that's not the problem.
It's this other thing.
Because I've tried four times that way, and that was really a bad week.
And that didn't work.
So now we're over here.
And some of those you can learn, like just knowing that, well, if you're stuck, you just pound through it.
And that's just part of the journey.
It's fine.
The building up the battle scars, like that just takes time, I think.
Yeah, absolutely.
And like you said, when you see a Stack Overflow answer and you think it might be the one to solve your problem, there's a similar thing as you're using like third-party libraries.
Yes, true.
You can't get it to work.
You can't get it to work, but you don't yet know if it's because of something you did or if it's really because there's a bug.
And getting to uncovering that bug can sometimes be an exciting moment, even though it's frustrating getting there because you're like, oh, I actually exercised a problem that other people might be experiencing.
And then you can sort of contribute back to that discussion.
And if that bug's already been filed or something, you can say, hey, I ran into this too.
And it just kind of grows the community in that way.
Yeah, it's interesting.
I just got an email today from GitHub.
I had filed an issue for PyInstaller.
I was trying to combine it with something else.
And it wasn't quite working right.
I was doing something weird.
Or no, it wasn't PyInstaller.
It was GUI.
I was using those two together.
And I got a message today.
Somebody else said, I'm having exactly the same problem.
What can we do about it?
I'm like, oh, I still can't solve it for you.
But I started the conversation six months ago or whatever it was.
Yeah.
So let me ask.
It's serendipitous sometimes.
Yeah, it definitely is.
It definitely is.
It's aha moments.
Yeah, it's funny.
This portion of Talk Python to Me is brought to you by Tidelift.
Tidelift is the first managed open source subscription, giving you commercial support and maintenance
for the open source dependencies you use to build your applications.
And with Tidelift, you not only get more dependable software, but you pay the maintainers of the exact
packages you're using, which means your software will keep getting better.
The Tidelift subscription covers millions of open source projects across Python, JavaScript,
Java, PHP, Ruby, .NET, and more.
And the subscription includes security updates, licensing, verification, and indemnification,
maintenance and code improvements, package selection and version guidance, roadmap input,
and tooling and cloud integration.
The bottom line is you get the capabilities you'd expect and require from commercial software.
But now for all the key open source software you depend upon, just visit talkpython.fm
slash Tidelift to get started today.
Another bad feeling is when you're searching for something that you don't quite understand how it works.
And the best answer you can find is something you've written before.
That's also bad.
The cup lost.
All hope is lost now.
So let me ask you, thinking back, I'm not sure if you can remember clearly to this,
but when was the first time you felt like,
I'm actually a professional software developer.
Like, I'm a pro now.
I fit in with all these people who used to seem way smarter than me and I couldn't figure out what they were talking about.
It's a great question.
I don't know that I have sort of this decisive moment.
So I guess one place that I had a kind of clear division line was from my first job,
everyone was kind of a generation older than me at my office.
And I mean, they were all great mentors and I learned a ton of stuff,
but I definitely realized my own shortcomings often.
And then sort of at my next position, people were more my peers in age and experience.
And I think when mostly it was that kind of process of solving things together.
And like collectively, we all knew about the same amount of stuff.
And suddenly people are asking you to like, not only execute on a solution,
but actually figure out what the solution is supposed to be.
Right.
I think that's really where it starts to make you grow as a developer.
So I would say that's, to me, that's kind of the hinging moment.
Yeah, that's interesting.
Like, Dane, we've elected that you're going to write the e-commerce part of the website.
You're like, I've never done that one.
Neither have we.
So someone's got to figure it out.
So we've elected you.
We got trusted you, right?
I guess for me, there's probably, I guess there's probably two experiences.
One, the first time I got paid a good salary to set and work on software
and create applications for this company was so awesome.
I was so excited.
But I kept thinking, man, I better figure some of this stuff out before they realize,
I don't know what I'm doing.
They're going to kick me out of here.
You know what I mean?
So that was sort of the first step in the door.
Like, wow, I'm really getting paid to write and create software.
And it's fantastic, right?
But I didn't really feel that totally solid.
And I guess where I really felt like, okay, I guess I'm a pro, I guess,
was when I was giving user group talks on subjects, design patterns or testing or whatever it was.
And I went to, you know, all these people are enthusiastic.
They go to meetups and stuff and gave a talk.
And they're like, that was really great.
I learned some stuff.
And they didn't laugh at me.
I'm like, that was great.
Apparently, I, you know, present ideas to people.
And just, you know, there's a couple of those milestones I can think of.
But yeah, it's really hard to put a clear demarcation on it.
Yeah, I mean, going back to your point about feeling like people are going to find you out, right?
Like, that is the epitome of imposter syndrome, which I think is, especially in knowledge work and like that kind of area.
I think people experience that to a large degree.
So that's another thing to call out as like a beginning developer.
If you have this constant feeling that somebody is going to call you out for being a fake, like that's real.
That's a thing and that sometimes doesn't really go away either.
I know I certainly feel it at least from time to time still, right?
Yeah, for sure.
It's hard for that to go away.
But at the same time, you know, if you're making steady progress and learning a little bit more and learning a little bit more,
if you're delivering what people want from you, just because you don't know how to factor that database into a third normal form,
if that's not your job at the moment, you're probably fine.
You know what I mean?
Yeah, exactly.
Cool.
So speaking of topics and things like third normal form you should know or design patterns or software design and all that,
let's dig into some of the ideas behind your book because I thought you did a good job laying out some of these things.
And again, I don't think it's professional development,
but more like what do you really need to be kind of an expert in software development in general and Python in particular, right?
Probably the right focus, huh?
Yep, I would say so.
Yeah.
So why do you write this?
The impetus for this, I think, was seeing a few of my friends who were not in sort of the traditional path to software switching into a career in software.
And seeing kind of how they thought about problems and the kinds of questions they were asking me at the time,
that sort of insight into the kinds of things people were experiencing made me kind of interested in helping other people who were in that same situation.
One of my friends was using Python to solve computational biology problems, computational chemistry problems, if I remember correctly.
And it was sort of asking me to review his code from time to time and ask like what he was doing wrong or what he could do better.
And it's sometimes hard to answer that question, right?
If it's someone who isn't in software, you don't necessarily want to dump the entire world of, you know, you should format your code this way or you should optimize for readability or you should comment your code for these reasons.
Like it can overload people.
So I figured a book could be a more digestible thing that people can kind of jump in and out of as needed.
And I tried to organize it in a way that they could sort of pick areas that they want to get better at and read about that topic without having to know everything.
Right. It does seem like it's a little bit of this cookbook feel like you can drop in and I need to work on design.
I need to work on testing or whatever it happens to be.
Yeah. Nice.
So let's start at the beginning, I guess.
And you talk a lot about design and planning and software architecture to get started.
And I guess one of the challenges, I guess it's probably two challenges that are really tricky for people right away is first, like what the heck is software design?
You know, like if you know, when you see that it's not designed, if there's just a, there's no functions, there's no comments, there's bad variable.
Like, you know, this is not designed and this is not professional.
And probably this other thing, if I go to GitHub and, you know, pull down Flask and I look at its code, it probably is designed, but that's a little bit tricky.
But knowing, you know, how much energy to put into it, what are the first steps that you take?
What do you think about that?
Yeah. I mean, I definitely emphasize in the book that to the point about energy, like things,
are always trade-offs as you develop software, right?
You only have so much time in your day.
And realistically, you do need to ship software sometime.
There's always a trade-off between how much time you spend upfront designing things versus how much time you spend actually implementing things and getting them out the door.
So that is worth stating, I think, explicitly here.
And then sort of generally, I think about design often the way you sort of think about solving problems in general, right?
Like the problem is often too big to solve in one go.
And so we typically break problems down into smaller chunks that we can solve.
And that is a lot of what software design is too, right?
Like this idea of separation of concerns and things like that, encapsulation, abstraction.
They're all about not doing the whole world at one time.
Sure. I've tried to boil the ocean before.
It's not so fun.
Like I remember there's this project that a whole team of us worked on for years, at least a year.
And I somehow discovered this cool linting tool that would come along and tell you all the issues, even security issues, performance issues, and ran it against that.
And it found like a thousand problems.
And I started to work on a couple and it took like 10 minutes per one.
Like, yep, we're not doing this.
Just throw that away.
We're just going to just keep going the way it's going.
We can't take the next half year off and just make it the same, but slightly better.
So there is this real tension of, I know this could be better.
Maybe I should refactor this to use not deep inheritance, but I should use composition.
Or I should refactor this so this is a separate package and then we can all use that and things along those lines.
But one of the challenges with software design, I think, is it's almost got this creativity, this art aspect to it, where you could just keep polishing or keep sculpting indefinitely, right?
I could continually refactor this code or restructure it basically indefinitely.
And so, you know, you need to know maybe some reasons or triggers that say it's time now to go put a little effort into this or it's time to stop.
Yeah, I could probably could refactor that as well.
But you know what?
Nobody touches that part.
It doesn't really matter.
Yeah, that's a great point.
And I think a lot of newcomers, as they learn sort of new tricks, if you will, tend to try to use them as much as they can, which is it's a great way to continue learning that subject and understand more of the nuances around it.
But sometimes if a nuance around, like you said, when to stop or when things are good enough is missed, you can certainly continue much too far down that track.
Yeah, so let me throw out a couple of ideas on what I might think of as like clues there and you can comment or add to it.
Yeah.
So if I'm trying to add a feature and it's super hard to add the feature without causing a bug, I need to make a change and I got to touch a bunch of places or something like that.
That seems like I need to redesign something so that doesn't happen too much.
Or there's a part that bugs keep coming back to or something like that.
If it's really problematic and every time you need to make a change, I got to spend 10, 15 minutes on this section just to make sure it doesn't break or to make sure it's in sync over and over and over again.
I guess if you feel annoyed at your code, you're like, this is really, you're like, wait a minute, maybe that's a signal that I should take that frustration and fix rather than just endure this code.
Yeah, that's exactly right.
I think the squeaky wheel gets the grease in that sense, right?
Like as you go about your day-to-day work, if you find an area of code that's commonly the thing causing you grief, that is a pretty strong signal.
And to the point about going too far, I think if it is giving you grief at that time and you choose to attack it, like it's very easy to get tunnel vision and want to solve it to its extremity, but try to focus on solving the thing that was causing you pain.
And, you know, if you need to change some peripheral things to solve that direct problem, that's okay.
But try not to fix every problem until they really jump out at you.
Yeah.
And you probably also need some guide rails, maybe safety nets is a better analogy here.
If you're going to start tearing stuff up, maybe you want to have tests to make sure that it still works or something like that, right?
Like it's not every bit of code needs testing, but if you're going to start really, really pounding on it, you know, might be worth putting some basic rough.
Does this kind of still sort of work tests in place before you do that?
Right.
These are like these characterization tests, right?
Like you want to make sure that the most important aspects of your code continue to stay.
Right.
If this breaks, it's going to be really bad.
In line with your expectations.
Right.
Or the MetaBank, the core trading engine that decides buy or sell, that part can't break.
So we better fuck this up now.
I'm sure I'm going to hear of it if I switch a minus to a plus the wrong way.
Yeah.
That's not one you want to hear about with a production error going up.
No, no, it's definitely not.
I guess when it comes to this design and like restructuring your code.
So I kind of try to follow what I guess I'd call the Boy Scout rule.
I was never a Boy Scout.
So maybe I'm mischaracterizing them, but just leave the code slightly nicer than I found it.
You know, if I come in here, instead of making it worse, what could I do in a little bit here and there to make it better than when I, if I got to touch it anyway.
How do I make it a little bit better?
Yeah.
And I think the corollary of that is that that's a great place to start incrementally improving your code if you're not sure where to start.
Like as you're working on something already, whether it's to add a feature or to fix a bug, why not use that place where you're already working as the place to improve?
So if it feels like there's too much and you need to fix everything, start by fixing where you're already going.
Right.
Yeah, that's a good point.
So you call it some interesting things, some considerations of making software good as a user and as a developer.
And I think these can also guide this design thinking and this refactoring story.
So some of the considerations as a user of how the software is designed.
I mean, you as a user, hopefully you don't see the code, you know, you see the buttons and the widgets and whatnot, but you still get a sense of like, I can tell you there's certain times where I've worked with certain websites.
I'm like, whoa, this is one shady, crappy website right here.
Or other ones are like, this thing is super slick and maybe it's crummy underneath, but it feels like at least pretty well put together.
And some of those for the user or like speed, you know, how quickly does it respond to me?
Or data integrity, does the data get corrupted?
And is it accurate in terms of resources?
Maybe if it's a website, you don't see these, but certainly if it's a desktop app or something, you would.
And, you know, does it feel secure, right?
So these are certainly things that people can think about as well, right?
I talk a little bit in the book about when is good enough to the point of speed.
Things are often down to your user's perception, right?
You don't necessarily need to continue making something faster from 100 milliseconds to one millisecond.
If it's, for instance, some sort of UI interaction, like human perception doesn't go much faster than about 100 milliseconds, right?
So there's heuristics, if you will, that can kind of help guide where you should shoot for.
Yeah, and that's interesting.
Certainly, there's the single user speed and then there's the scalability speed, you know.
On Friday, nobody can use the website because everyone's entering their timesheet or something like that, right?
But on Monday, it's really fast.
That's also another one to consider.
At least in the web world, maybe even in apps for APIs and stuff.
There's a lot of stuff that doesn't, it seems like it's sort of some weird side case.
I don't really care about this.
For example, if I'm working on a website and I want to make it fast and the page loads in 150 milliseconds, I could optimize indices.
I could refactor databases.
I could do cluster.
I could do all sorts of stuff.
But if there's a bunch of JavaScript and a bunch of CSS and a bunch of images that don't have the right cache setting and the page appears to me as a user in one and a half seconds, whether I shave 10, 20 milliseconds off it, I don't care.
The thing is super, super slow.
I'm not going to call any companies out, but there's so many professional sites out there.
Big companies are like, why is this so bad?
It's inconceivable to me that it is this bad.
And I actually have a recommendation for people.
I don't know if you're familiar with this, but you know PageSpeed Insights from Google?
Yeah.
So that's a really great place.
You can just put your domain or actually put any particular page in there and it'll tell you how fast your site is.
So, for example, the training site that I run, the Talk Python training, its response time is super fast.
I've got that dialed in so well and it was responded in like 15 milliseconds, right?
Out the other side of the web server.
That seemed like, well, I can't do much better than that.
No one's going to perceive that last five milliseconds.
I throw it into PageSpeed Insight and it says, your pages, it's average to slow.
I'm like, wait, wait, wait, wait, wait, wait.
What is it?
Like, it's 15 milliseconds.
What are you talking about?
And then there's all these other things like, well, this type of caching does this.
And these images are like 1,200 pixels.
But when you put them into a phone, the phone has to resize it and that makes it render more slowly and stuff.
So I did actually a ton of work and now I've got it down to 95 on mobile and 99 out of 100 on its speed.
Higher is better, right?
So there's actually different levels, right?
Like, you can get really focused in on, well, let me make the database query fast and it should be fast.
But there might be bigger problems that are actually easier to solve.
That's a really good point.
That process that you described sounds very familiar to me.
Did you put something into PageSpeed Insight?
You're like, I thought this was good.
What is the problem here?
This is not what I expected.
Yeah, exactly.
And like Google Webmaster Tools start to incorporate some of that data too.
So you can see like how often you're terrible.
Yeah.
Well, and to put a little more fire under people to like try this out, Google is starting to use that for rank.
Absolutely.
Right?
So it's an advantage.
Yeah.
They're including things like on mobile, if you have an icon-based navigation menu or something, if the icons are too close together, they'll ding you because it's difficult to touch the icon you meant to, right?
Especially for people with mobility issues or things like that.
So they're really starting to, like you said, incorporate that back into how well you're actually ranked.
Yeah.
So I guess to wrap it up is like, you definitely want a fast website, fast app, whatever, but make sure you're viewing it from the user perspective.
What does fast really mean?
You know, if something is running quick, but another part is really slow, make sure that the way the user feels it is actually the way you want them to feel it, I guess.
Yeah.
Well said.
Yeah.
This portion of Talk Python to Me is brought to you by Linode.
Whether you're working on a personal project or managing your enterprise's infrastructure, Linode has the pricing, support, and scale that you need to take your project to the next level.
With 11 data centers worldwide, including their newest data center in Sydney, Australia, enterprise-grade hardware, S3-compatible storage, and the next-generation network, Linode delivers the performance that you expect at a price that you don't.
Get started on Linode.
And you'll be able to take your time to have a lot of data center in the next level.
And you'll be able to take your time to learn.
And you'll be able to learn.
So that was considerations as a user.
Speed, integrity, resources, security.
But as a developer who's working on this project.
Be it a library or an application or whatever.
There's a different set of considerations, right?
Yeah.
I mean, from the developer perspective.
In the book.
Sort of a famous idiom.
It's like, make it work.
Make it right.
Make it fast.
So often we get to the make it work, right?
Like that's the software we often ship.
Or the software we often write to start.
Yeah.
And I think part of the problem is also the project managers.
They're like, oh, I see it working.
Our sprint is almost over.
You can pick another item out of the sprint.
You're like, no, no, no, no.
You don't understand the technical debt that is deep within this beast.
I have nowhere near done.
Right?
I actually ended up at some point, not lying, but just when somebody says, how long is this
going to take?
It's not like how long to minimal viable feature.
It is how long to feature plus unit test plus refactoring.
That's what I'm going to tell them in the estimate it is because otherwise I'm going to hate life
in six months.
It's like that builds up.
Yeah.
In my experience, the best time to incorporate those things is as you're writing the code,
because at least then you can't, you have some leverage because things aren't shipped
yet.
Right?
Yeah.
And, you know, six months from now, if you didn't address the tech debt back then,
it's really often difficult.
And, you know, it's understandable, right?
Because at the end of the day, most of us work for some sort of business and they do have
to have value to keep the lights on.
And so that's why I kind of encourage people to bring this in as an iterative part of their
day-to-day programming process, because again, that's kind of the best time to do it, especially
because you have all the context and everything that's easy to lose after, you know, even a
couple hours after leaving some code.
So yeah, it's hard to get that back.
It's like, it's much easier to keep your credit card paid off than it is to deal with
it when it's maxed out.
Yeah, exactly.
I mean, you've had the same amount of money over the same period of time, but it doesn't
feel the same.
Yeah.
And so like, as you start shipping stuff, you also then, as a developer, you've hopefully
already worked on the ideas of speed and security and things like that as part of the feature
you've developed.
But sort of under all of that is the actual code that you wrote.
If ever you need to return to it to add another feature or fix a bug or fix performance, the way
you've designed your code is sort of when it becomes really important.
Because I often find if I haven't put a lot of thought into some code, when I come back
to it later, I'm kind of viewing it for the first time, even if I was the one who wrote
it, you know?
What is that saying?
Like code as if a person inheriting this code in six months is a psychopath and they know
where you live or something like that?
Right.
Yeah.
I mean, but that sort of applies to you as well, because you'll forget, right?
You'll forget.
And it seems so clear and simple at the time when it was all perfectly balanced in your mind.
But then when you haven't picked it up for a long time, you're like, why is this still
not working?
It's like a whack-a-mole game.
Yeah.
The best is when you like get blame a line and you're like, oh, I did that.
This is wrong.
Who wrote this?
Get blame.
Oh, yeah.
All right.
I mean, the worst to me is when I'm like trying to understand some stanza of code and I'm like,
I need to go ask someone what this does.
It's like, who should I ask?
Well, I guess I need a time machine.
Yes, exactly.
If it says you wrote it, then well, you're kind of out of luck because the buck stops
there.
That's right.
Yeah.
So I think these are all really interesting ideas.
I do feel like one of the areas you should focus most on is make it easy to add new features.
And some of the things that come out of that are maybe loose coupling and extensibility.
Because if one little change means I have to change five other parts of the application,
well, then you do have to hold a lot of those things in your mind.
But if you've got a very clear structure, like, well, here's all the strategies we have
for this part of our app.
And at another one, you just kind of clone this thing and derive from that and register
it there.
And now there's another option in the UI or whatever, right?
You can definitely help yourself or hurt yourself in that regard.
Yeah.
I mean, we often talk about software complexity as a sort of like this inherently bad thing,
which I wouldn't necessarily agree is true.
I mean, you can sort of argue the semantics of it, I suppose.
But to me, like the danger of complexity is that people, not software and code, but people
have trouble understanding it and keeping it all in their head.
And they will inevitably not have the full context when they make some change.
And so bugs become an inevitability and security failures become an inevitability.
And that's where things really break down.
So the value in kind of breaking down complexity is often for people's benefit.
It's nothing about the code itself, if that makes sense.
Right.
Absolutely.
And with the right design, you can control how much of that complexity has to be cached
in your brain.
Yeah.
Right.
Like the software may be super complex, but you just got to work with this little part.
And you know, if I'm working this part, it interacts with this other thing through this
clear way.
And long as I have that in my mind, I can't mess up the rest of it.
Or you design it poorly and you change it 10 places because somebody's hard coded a string
duplicated in four places.
That means something.
And now you better not forget that fourth place or you're, you know, in trouble.
Yeah.
And so I think new people often pretty readily understand the value of writing a function,
right?
Like here, you need this six times.
And instead of writing it six times, you can write it one time.
And so they get the value of that kind of statement.
And then this book kind of tries to bring that concept along to layers of abstraction and encapsulation
and things as concepts that you can further use to kind of get that same benefit at a larger
scale on more complex systems, right?
Yeah, that's a good point.
Obviously, functions are probably the lowest level that people generally have that thought
process.
But yeah, you have a whole section where you talk about separation of concerns and talk about
functions, but there's also classes and there's modules and there's packages.
And probably the whole step from different modules, I feel like not everyone, but there's a lot of
folks in the Python space that are hesitant to have many files that make up their application.
They'd prefer to have just one like 2000 line file, even if it's got a bunch of functions and
classes in it.
And I don't know, there's just this reticence to do that.
So certainly focusing on modules and then even maybe packages for broader reuse makes a lot
of sense.
Yeah.
And I think it's easy to go crazy with those as well.
You could go to the other extreme and have like one function per module and have a thousand
modules, right?
Again, it's kind of this balance that you have to strike and it's whatever.
At the end of the day, it's always like the goal is always whatever helps people understand what they need to
understand when they need to understand it and no more, no less.
Right.
If I could say group five actions and a few pieces of data into a module, and then if all
the people have to think about is I use this module, it solves this problem.
It takes this input.
It has this output, right?
They no longer have to worry about the details or what changes there or anything.
And while that's useful on one level, if you can break your whole way of thinking your program
about that, you can just think at a different level and the building blocks become much more
easy to think about how you position them and how you use them and so on.
And I think changing the way people think about problems is a really important part of this
separation of concerns and this design thinking.
If you can change the building blocks as people perceive it to be large and clear rather than many,
many small pieces, that's huge.
Even through the course of this book, my sense of that concept has definitely grown.
It's very easy to think of the value of refactoring or pulling out functions and things as strictly
for reuse purposes.
Or testing purposes or something.
Yeah.
And so I've come to kind of feel that instead the real value definitely is that sort of cognitive
load aspect.
Yeah.
I find the similar value with design patterns.
If instead of thinking of these 10 lines of code, I can think of it as a strategy or a
something else, right?
It's even though design patterns are not used that often in the Python space, it's just a
little bit simpler.
So many of the design patterns are about solving the inflexibility of static languages.
And so you don't have to really think about them as much, but there's certainly many cases
where design patterns are super valuable.
You know, even just things like passing a Lambda function to a list to sort it rather than
getting in there and trying to deal with it yourself or whatever.
It's pretty nice.
My experience is that it just takes a lot of trial and error to get there.
I don't know.
I think there's a lot of design patterns applied from things like Java and C++ and C# that
are just, they just don't belong.
Right?
Like really complicated singleton patterns where, you know what, that could just be a global
variable in a module.
All right.
What's next?
You know what I mean?
Yep.
It's the same thing.
Yeah.
And so I kind of, in the book, I deliberately kind of skirt around this idea of design patterns
explicitly.
I do kind of mention it at the end as something to learn more about for sure.
But I think like the value they provide is taking some concept and naming it.
Like once you have a name for a thing and everyone agrees what that name is, like you
can start to have conversations about it and whether it's the right thing or the wrong thing.
Right.
And it has, it has clear trade-offs, you know, well, like for singleton, it has the trade-off
that you have shared data and it could be really tricky to test it or other things, but it also
is really clear how you use it.
And so I think it's not just the name, it's that the name plus known trade-off, like these
are the positives.
These are the pros and these are the cons.
Do we use that here?
Like that's really valuable to bring in quickly.
Yeah.
And so like, if you didn't have a name for that, you couldn't even start to apply those
traits and trade-offs.
Right.
So even if you aren't using design patterns per se in your code, it's good to at least
understand.
I mean, there will be patterns of some kind, right?
Whether they're design patterns that have a name or not.
Right.
Are they organic or are they like well-known ones?
Yeah.
Right.
So they give you the name just gives you kind of the hook around which you can, you can
explore more.
Yeah.
The nomenclature.
That's cool.
Yeah.
So another thing you talk about in the book is designing for performance.
Do you want to touch on some of the highlights from that?
Yeah.
I think that goes back to what you said earlier about using, knowing and using the right data
types for jobs, right?
Right.
And understanding a little bit about complexity and about how to do things as iterative chunks
of work rather than trying to read, you know, large files into memory and things like this.
That in part is where you do become so-called more professional in a language at least.
Yeah.
Is when you, I think, have a good handle on those data types and when they're useful or expensive.
You know, I think there's a lot of people who in the industry these days who are just kind
of, they don't know how to address this kind of broader conversation in hiring people or
assessing skills.
And they kind of fall back to just testing algorithms.
And, you know, a lot of the technical interviews seem to be like, well, implement quick sort
on a whiteboard.
Like, you know what?
Nobody needs to implement quick sort on a whiteboard.
But one thing I do think really is an important skill and it's an indicator of how effective you're
going to be is, do you know what a dictionary is?
Do you want a set is?
Do you want a list is?
Do you know when to use a dictionary over a set?
When should I use a list over a dictionary?
Like those types of things can just dramatically change the complexity of the code you got to
write, the speed that you write it in or speed that it runs in, maybe both.
But those seem like these data, these simple common data structures seem just so valuable.
Yeah.
And I think that's a thing you can translate to most any language, right?
You can carry that with you wherever you go.
So you just, most times if you have a background in one language with those in another language,
it's really just learning the syntax to produce those.
And so, I mean, sometimes they vary names, whether it's a hash or a map or a dictionary,
that kind of thing, but largely, largely the same.
So, yeah, I definitely remember an experience where we were storing some data in a list and
we had to look up some feature about it.
So we would iterate through the list and then go find it and then work with it.
And that was happening over and over and over.
And the code was supposed to be something kind of like real time.
And it was just too slow.
The other thing you talk about in there is profiling.
So I actually threw into a profiler and I found, oh my gosh, it's spending 80% of its time in
this list finding the item.
80%.
It was a huge complicated thing.
80% was one line trying to find the item in the list to go do something with it.
And I switched it to a dictionary and that 80% went to like 1% or something.
Because you know what?
Dictionaries are awesome looking up by feature and getting the real thing back.
Right?
And it's just like, ever since that, I'm just like, oh boy, I'm going to pay so much better
attention to data structures.
I think that was 20 years ago or something, but it really still stuck with me because, wow.
Yeah.
It's pretty interesting.
I emphasize the benefits, I guess, of profiling in the book, because I do think the situation
you describe is sometimes difficult to find, even if you're familiar with your code.
And certainly as someone maybe less familiar with data types and things like that, it would
sort of be a needle in the haystack kind of search.
And so profiling really gives you that.
People are really bad at estimating what, if you show them code, like where is this slow?
Even if you're pretty experienced, you could still get it quite wrong.
Yeah.
We build up these very subjective views of these things in our minds, I think.
And the profiler is a way to kind of strip away all of that.
And it's nice too, because it's much easier to take feedback from a computer, I find.
That's right.
It removes a lot of the guesswork.
And so I emphasize definitely shoot for, always profile and gather some kind of evidence for
your changes that are performance related, at least.
And as you're changing things and looking at the profiling data, shoot for things that are
like order of magnitude changes and not just beating it with a hammer bit by bit until
it gets roughly where you want, right?
Yeah.
Because there's certainly different things that you can do.
And knowing, I guess the first thing is, if you've got, let's say a thousand lines of code
and you look at it and you say, I think this five lines of this function is where it's slow.
If it turns out that that's only 2% of the time, it doesn't matter if you can make it infinitely
faster.
You're only going to make it 2% faster, right?
That's the upper bound.
If you can make it go to zero, that's as fast, that's as good as it gets.
So knowing where to put that energy, that's what I find the value of the profiling is like,
maybe not saying this algorithm is bad or whatever, but just like, we should focus here because
80% of the time is on this little bit.
And I don't know what the fix is.
Maybe it's to use a different library.
Maybe it's to rewrite this part in Cython.
Maybe it's to just use a different data structure, but this is where the energy and effort should
go because we can optimize the rest all day.
Maybe introduce a bunch of bugs and it won't get much faster.
Yeah.
It's often true too, that trying to eek performance out of something necessarily makes the code
more difficult, right?
Because you are either going closer to the middle or doing these kinds of
hoop jumping that doesn't really result in clear code.
Right.
You're like, well, this library that we could just call and get the answer to, well, now
we've got to rewrite it because we need to have more control over it.
But now, you know, all of a sudden, what's what one or two lines is now many, many lines
that is your baby to take care of.
Right.
Yeah.
Cool.
So definitely profiling.
I think it's really good.
Another thing to think about, I guess, is test data versus real data.
You know, how many times have there been website launches where, oh, it seemed like
it was fine, but now it's down because there are actually more than, you know, 10 rows in
the database and they forgot to put indexes.
I don't know how people can forget to put indexes because they're like magic to databases.
They're like speed magic.
You can just give them and it's like a thousand times faster.
Like, so as soon as you see it slow, put an index on it.
Now, now let's go worry about what's next.
Right.
But still, this happens all the time.
Yeah.
And I don't know.
Indexes are sort of notoriously, notoriously hard, even when you are thinking about them.
You can have situations where you're like, you know, it did this index didn't cover it
right because we were sorting this way.
It actually used a different index.
We had to give it a hint.
I'm not talking about that.
I'm talking about we've got a million rows that we're doing a query with no index, which
I think happens more than people want to admit, you know?
Yeah, definitely.
And I guess to the point about real data also sort of at the, at the product and user
and social level, there's a bunch of videos where people of color can't use a product because
they didn't test it on people with that.
Like those automatic hand dispenser, sand soap dispenser things and all sorts of stuff.
Yeah, exactly.
It's fresh.
It's got to be super frustrating.
Those things already frustrate me.
And yeah.
So I mean, I'm not only, yeah.
Yeah.
It not only like manifests as a cost to you as the business, but absolutely like impacts
people in the real world in very negative ways.
Yeah.
Well, I can speak to a hardware testing of that sort.
But one thing that I've, I found Bob Belderbos introduced me to this is this place called
Mockaroo.
You know Mockaroo?
I'm not familiar.
Mockaroo.
Make sure I spell it right for people.
Yeah.
Mock A-R-O-O.
Yeah.
And what you can do is they have all these different types of data and you can say,
go generate me certain amounts.
So you can ask for like first name, last name, email, but you can also thing, ask for all different
kinds of stuff.
There's so many.
So I could ask for like cars, VIN numbers.
I could ask for, let's see, for commerce.
I could ask for currency codes or stock names or, you know, and it'll generate as many of
those as you want.
I want a million of those in a JSON format like this.
Give it to me.
And it looks real and it feels real.
So, you know, you can definitely generate some quick data with Mockaroo and it's, it's pretty
awesome.
Yeah.
That is really cool.
There's a couple of plugins I know for Django that do something similar meant exactly for
that, that same reason.
Like testing, testing often is people espouse like testing in isolation and testing just
the, just this part or that part.
And there's like unit testing and integration testing and all sorts of varieties of that stuff.
But I don't think this point is talked about enough, which is like test it in isolation,
but also use values that make sense.
Right.
Maybe don't just test with a first name and a last name.
Some names, it's like a three part name or something like that, you know?
And if you're splitting on the space, that's probably not going to come out.
Okay.
Right.
Yep.
So yeah, yeah, definitely testing.
Yeah.
Or if you, you're always using like foo, the string as your test variable, like maybe you
won't uncover your bugs that are throughout your code when there's Unicode characters and
things like that.
Yeah.
True.
Test with emojis, test with emojis as well, I guess.
That's pretty awesome.
So we're kind of getting near the end of our time to talk about all this.
Let me throw out a quick rule of thumb that I use a lot of times around this.
And I just want to hear your thoughts on it.
You can disagree with it if you want.
But one of the rules of thumbs that I have is that if a function or a class or some part of
code needs a comment, it's probably broken.
Yeah.
That's interesting.
I'm not talking to doc string, right?
Like if you want to document it, that's a different thing.
But if you're like, well, we got to do this weird thing because, or the function is named
so badly, there's a comment saying what the function name should have really just been,
you know, something like that.
Yep.
So I would agree that like comments that are redundant to what the code around it could
have been or could have said are definitely an anti-pattern.
I don't mind when a comment says the why of the code.
So like code often expresses simply the how or the what.
But if you can't get all of that just by your variable names or your class names and stuff
like comments, giving you that extra context are okay.
Yeah.
Maybe you're calling some API and it returns a dictionary and you're like, this looks weird,
but we have to do this thing because sometimes it does this and sometimes we don't control it.
We got to live with it, but just please leave this check here because I know it looks like it's
not necessary, but on the first month, first day of the month, it always goes weird.
So we're going to just need it.
Right.
That's cool.
Postal's law is like this idea that you should be liberal in what you accept and conservative
in what you send.
Right.
Sometimes being liberal in what you accept means exactly that.
We have this API we have no control over, but we want to use it because it provides us other
value.
And so we're going to accept this reality and we wrote this code to deal with it.
And here's the situation.
Yeah.
Pretty cool.
And those comments make perfect sense, right?
Like, please don't take this out.
It's I'm going to hide that away in a function.
So hopefully you don't look at it, but if you got to get in there, here's what we're doing.
So look out.
Yeah.
Pretty cool.
All right.
Well, it's been really fun to think about these design concepts.
And I think a lot of what we talked about is actually pretty broadly applicable, although
we did talk about some stuff that very much is Pythonic, right?
We talked about comprehensions and whatnot a little bit.
Yeah.
So it's great.
Yeah.
I think this major chunk of the book, I would say, is very translatable to other languages.
I use Python as sort of the vehicle of teaching the concepts, if you will.
Yeah.
Sure.
Not that people shouldn't use Python.
It's an awesome language, right?
But, you know, even I think it's just, these are just, I guess the point I'm trying to
make is these ideas transcend individual languages.
Knowing this kind of stuff will help you across if now you're a Python developer and later you're
going to go learn C#, or you're going to learn Java, or you're going to do C++, knowing
a lot of the stuff is really applicable.
Yeah, absolutely.
And I think that's also maybe one of the pro things, right?
When you're a beginner, you're very much focused on the syntax of the language and just making
the tools do their thing and not worried about these higher order general ways of thinking.
So that's probably another little indicator there, like we started at the beginning.
Yeah.
And I think sort of parallel to design patterns, there's just these patterns of languages and
patterns of ways of thinking about systems that only come sort of with time.
And as you learn the names for those concepts, you can, again, have those conversations.
Yeah, absolutely.
All right.
Cool.
Well, let me ask you the two last questions before you get out of here.
If you're going to write some Python code, what editor do you use?
So I would say I split my time fairly evenly between PyCharm and VI.
Okay.
I have, I guess when I'm working in a larger context and I need to be flipping between a lot
of files and jumping through code a little more often, or if I want to attach a debugger,
I usually will use PyCharm.
And then if I'm just doing some quick things, I prefer VI because I like moving around the text
that way.
There are like VI bindings for PyCharm and I might be happy with that.
Can you bring those worlds together?
Yeah.
I don't know.
You know, speaking of debuggers, I suspect, I don't know if you cover it anywhere in the
book.
I don't recall.
But using like consider a debugger is probably not a bad piece of recommendation.
Yeah.
That's a really great advice.
If you can sort of understand what it's doing and why you would want to step through your
individual lines of code.
Like it's a great way to solve problems.
There is a tendency for some people to use it as a crutch almost to just not really think
it through.
It is just like, well, the debugger will show me.
But I think there's a bigger tendency of people to put 20 print statements, not because it really
has had some timing issue and you really have to have the print statements.
It's just like, well, I'm not in a thing that debugs easily or I didn't set it up right
in VS Code.
So there's no button to press, even though like you could just go and set up a run configuration,
whatever they call it.
So yeah, I think definitely that's probably something in there as well.
Yeah.
And it can help you like kind of bisect where the problem is.
Like if you, if you have a suspicion about where the problem is, but don't know exactly
what's going wrong, picking a couple of like starting points and then slowly moving your
break points until you really find like the line that was mucking things up.
It is a really nice way to solve problems.
It comes back to just having less in your head at once.
You're like, well, it's down to these three lines.
What do I have to think about for these three lines, right?
Yeah, sure.
Cool.
And then notable PyPI package, not necessarily something super popular, but something you
came across.
You're like, oh, this thing was so sweet.
I can't believe I found it.
We've developed a couple of services in FastAPI recently.
Okay.
Yeah.
I've heard tons of good things about FastAPI.
It seems like there's a lot of momentum around it.
It's really kind of a joy to work with.
There's sort of some underlying packages that it uses, Starlette and things like that.
But there's also some that it works in tandem with.
Pedantic is one.
Pedantic is really cool.
Yeah.
It's like a data modeling related library and just love them all.
Yeah.
You can put a little pedantic constraints on it.
Decorators and then decorators, I think.
Right.
And then it's a little bit like data classes with validators, if you will.
Yes, exactly.
It's, it's looks super cool.
I haven't had a chance to use it, but I just really kind of got the zen of it a while ago
and I want to know.
Yeah.
Especially if you're working in microservices and things like that.
Asynchronous microservices kind of where it shines.
Yeah.
That's super cool.
Awesome.
Well, those are some good recommendations as well.
All right.
So final call to action.
People are inspired about this design stuff.
What's your advice to them?
What do they do?
I mean, there's a couple of other sort of seminal works that I would say to read.
There's like the Gang of Four book and other things like that.
If you're interested in Python, I would certainly hope you'll take a look at this book.
Yeah.
And I'll put your book, I'll link to your book in the show notes so people can get to it easily.
Yeah.
Fantastic.
And I think once you get beyond that or maybe even in parallel, this idea about testing and
refactoring are both super valuable, super valuable bits.
So Martin Fowler has a good book about refactoring.
It's got a pretty straightforward title, Refactoring from 1999.
It's still totally valid though.
It's a great book.
Yeah.
And there's Working Effectively with Legacy Code.
I think Michael Feathers maybe is the name of the author.
Yeah.
Michael Feathers wrote that.
That's a really good book.
If you've got a large code base and you're like, you know, the problem I described where
there's a thousand issues and we're just like, well, we're not fixing these.
Like if you're in that situation, but you want to carve out a part that behaves better,
his book is beautiful for that.
Yep.
So those are even the ones I'm reading to some degree now.
So super.
All right.
Well, Dane, thanks for being on the show.
It was really great to have this chat with you.
Yeah.
I really appreciate it.
It was a lot of fun.
Yep.
You bet.
Bye.
Yeah.
Take care.
This has been another episode of Talk Python to Me.
Our guest on this episode is Dane Hillard, and it's been brought to you by Tidelift and Linode.
If you run an open source project, Tidelift wants to help you get paid for keeping it going
strong.
Just visit talkpython.fm/Tidelift.
Search for your package and get started today.
Start your next Python project on Linode's state-of-the-art cloud service.
Just visit talkpython.fm/Linode, L-I-N-O-D-E.
You'll automatically get a $20 credit when you create a new account.
Want to level up your Python?
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.
Or if you're looking for something more advanced, check out our new Async course that digs into
all the different types of Async programming you can do in Python.
And of course, if you're interested in more than one of these, be sure to check out our
Everything Bundle.
It's like a subscription that never expires.
Be sure to subscribe to the show.
Open your favorite podcatcher and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play,
and the direct RSS feed at /rss on talkpython.fm.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
I really appreciate it.