Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 136, recorded June 19, 2019.
I'm Michael Kennedy.
And I'm Brian Okken.
And this episode is brought to you by Datadog.
Check them out at pythonbytes.fm/datadog.
Get a cool shirt.
More on that later.
Brian, how you been?
I am doing well.
Good, good.
Same here.
Rolling into summer.
Kids are home.
Working from home is now chaos, but it's all right.
Yeah.
It's a little cooler today, too.
It's nice.
Yeah, it's beautiful.
So you've got some kind of magic trick lined up for us for this first thing?
What's going on here?
Well, actually, I think it's just going to be me trying to pronounce a French word.
So I think, is it, I know it's not voila.
Voila?
Do you pronounce the V?
I don't know.
Voila.
I think so.
Voila?
Viola.
No.
Voila is a new project.
It's a newly announced project from the Jupyter Notebook people.
Cool.
So the idea is Jupyter Notebooks in standalone applications or dashboards.
So people that are used to working with notebooks and they want to share what they found with other people and you want to have people be able to interact with it and have it be a little bit interactive, but not allow people to change your code.
How do you do that?
That's where Voila steps in.
It's a pretty cool project.
I was playing around with it a little bit.
You can have custom, or at least reading about it, custom widgets to set up your page and even like templates and grid layouts.
But you don't have to be a web developer.
It's like drag and drop stuff.
This is cool.
I like the idea of presenting the interactive plots and graphs and stuff and also being able to have people be able to run the code and do selectors and things, but not let people change the code.
So that's pretty cool.
Yeah.
You just take your notebook and you just turn it into a web application.
That's pretty awesome.
And it has nice restrictions like does not permit execution of arbitrary code by consumers of the dashboard.
It's language agnostic.
So you could have C++ code up there in addition to Python or whatever, you know, Jupyter does.
That's pretty sweet.
Yeah.
I could see a lot of people using this, even for dashboards for like peeking into databases and stuff.
Nice.
So Voila, and you have a website.
Voila.
I have a Jupyter notebook and here it is.
Cool.
Awesome.
I don't think we covered this.
I kind of tried to sort of intentionally didn't want to go too far into it because it didn't seem super productive, but there was a presentation back at the language summit called Python, something like cleaning up Python's dead batteries or something to that effect.
Did you catch that?
Yeah.
So the idea was there are some modules and parts of Python that are outdated.
Their existence puts pressure on the core developers in ways that doesn't let them focus on what they need to be doing.
It also makes it super hard for people to contribute.
Like, for example, there's a color sys module in Python in the standard library.
I'm going to pick on this thing a lot during this little segment.
And it has the very important purpose of converting CSS colors between coordinate systems.
Super important to have that in the standard library, right?
I don't know.
Maybe, maybe not.
At one point, you know, Python standard library was really the goal of it was to come with everything you need because installing extra stuff like downloading it, getting it, like running the setup and all that was really tricky.
Right?
Now everything's pip install one away.
So, like, it looks a little bit weird.
And if, say, you wanted to fix or change the color sys module, it's not the same as if you want to go contribute to some random thing on GitHub.
No, you've got to be a core developer.
There's a lot of steps that go through this.
It only ships every 16 months, or sorry, 18 months for new content and new things, changes.
So, how much do you really care to make a contribution or change to color sys?
Right?
Probably not very much for all those reasons, right?
It's slow on purpose.
It's hard to make changes to and so on.
But the problem is, like, it has things like color sys that probably don't make a lot of sense to be there anymore.
So, Amber Brown and some other folks were making a case that maybe we should take some stuff away.
And it was pretty controversial.
There was some, like, heated disagreements at the actual presentation and stuff.
And I don't care about that.
I don't want to go into it.
But that approach was, we have stuff in Python that maybe shouldn't be there.
Let's talk about what we can take out.
And Glyph wrote a cool article called Toward a Kernel Python.
And I've talked about this before.
I don't know if I talked about it on Python Bytes or on Talk Python.
But I think there should be some kind of subset of Python that is defined to be, like, the minimum subset of Python that is guaranteed to be everywhere.
So, for example, if you work with PyPy, you get one variant of mostly Python.
If you work with CircuitPython or MicroPython, you get another variant of mostly Python, but not all of it, right?
Yeah.
If you work with Python or some of the JavaScript versions that run in the browsers, again, similar subset but not the same.
So, if we had, like, a smaller sort of essential Python standard language definition and library that was, like, I don't know what's the right number, but a smaller amount that you could guarantee was identical across all those platforms.
And then opt in to bringing the other stuff in.
So, Glyph's main idea was, like, could we say, instead of, like, take what we have and hack away a few things that don't make sense, rather trim it down to this kernel, to this essence.
And then, I don't know, pip install the rest of the libraries or something like that, the rest of the standard library.
You want the networking stack, you pip install networking.
I don't know.
Like, I'm just making up parts that we would do that for.
But that was his idea, that basically there's a PEP, PEP594, that's about removing, obviously, obsolete and dead stuff from the standard library.
And that's all well and good.
But it actually turns out that having things like ColorSys in the standard library mean that the core devs have to deal with a bunch of stuff.
So, he runs Twisted.
So, he talks about, like, how is Twisted doing on keeping up with PRs?
And let's look at CPython over there.
And they have 429 tickets currently awaiting review over on GitHub.
I think it's in GitHub.
It says the oldest PR awaiting review hasn't been touched since February 2nd, 2018.
It's almost 500 days old.
But when you look at it, the PRs, there's 25 PRs that are out on address or whatever.
14 were about the standard library and 10 were about CPython.
So, why are the core devs having to deal with this stuff when there's typically a replacement?
Like, there is a built-in HTTP library, but people just use requests or AIOHTP or whatever, right?
Like, there should be a way to maybe create this essence of it and then bring more in.
What do you think?
I definitely think there's an idea there.
Like you said, there's kind of like a Venn diagram.
There's a common set that most people need or you'll need for lots of different domains.
But then for a web domain, for web stuff, you're going to need different stuff than for, like, working with audio files or working with text files.
Or the different problem domains are going to use different bits and you don't need everything else.
Yeah.
Interesting idea.
The install, the how do beginners install stuff is an interesting, how do you deal with that, though?
Yeah, absolutely.
And he does address that.
And I do think it is a challenge.
He says, look, probably the stuff you go get when you download off python.org or you brew install Python, that probably should just be everything, right?
But it doesn't mean that it can't be comprised of smaller things that potentially ship on a different schedule.
If you're going to install, like, Visual Studio or something like that, you always have options of, do you want to install this stuff and this other stuff also?
Yeah.
You can opt out.
And we could do something similar to that with Python of, like, do you want to install the web stuff?
Do you want to install the audio stuff and whatever?
Right.
You could have these full distributions that you install.
But if you look at, say, Linux, for example, if you go to an empty Ubuntu machine and you try to create a virtual environment, depending on the version you have, it may not work.
You may get an error that says, you need to apt install Python 3-venv.
It's like, wait, that part of Python wasn't shipped?
Okay, well, we'll do that.
Or if you try to even pip install something, it might say, you might have to apt install Python 3-pip, right?
So they've already done this on Linux.
There's other examples as well.
For example, the .NET Core in the Microsoft space basically is like this, right?
Like, you use their package management system to bring in, like, significant parts of what is their standard library.
Yeah.
I do think it's a problem for beginners.
I think it makes it harder, right?
It's like saying, well, we just run JavaScript over in Node and it's easy.
But then you see all this require.js and all these, like, patterns.
You're like, why is this so hard?
What happened to print hello world?
You know, like, I do think there's a danger.
But if the standard way that people get Python is they get this big bundle, but maybe those bundles are not all maintained by the same team, which is the core developers, right?
And then, like, what can we hack out of the system?
Could we hack out ColorSys?
Yes or no?
Let's talk about that.
Well, right.
And also, just there's some stuff, like ColorSys, it's surprising that it needs to be there.
And then there's stuff that's not in the core or in the standard library that, like, why is that not there?
Like, set up tools and wheel.
I'm always surprised that I have to pip install wheel to create a wheel.
Yeah, and speaking of pip, Cliff did mention that when you get Python, it comes with pip.
Like, installing Python lets you type pip install a thing.
But pip is actually maintained by a different group and shipped on a different cycle, right?
That's PyPA, not the core developers, for example.
So, it's like that a little bit.
But if it was more like that, you could make a change.
You could join the team for, I don't know, the networking or ColorSys or whatever you want, work on that, and maybe push changes more rapidly than the core CPython runtime.
Right.
We could do something like the PyPA, but do, like, the Python standard library authority or something like that.
Yeah, exactly.
It's a pretty interesting idea, and it definitely seems better than, seems more like the outcome will be better than trying to just hack away at a few dead batteries.
If you will.
Yep.
Cool.
This next one that you're talking about, I recently ran into this as an error.
I'm like, wait, what did I type wrong?
And then I realized, this might be a cool feature.
Why don't you tell people about this?
Like, for instance, with pytest, it comes as a standalone script.
You can say, you can just write pytest on the command line.
But you can also say Python-M pytest.
And a lot of pip installable things, you can do that.
You can say –M, the thing name, and it works.
I didn't know how to do this, actually.
I never really thought, how do I do this, and how do I figure it out?
And all it is to put a Dunder main file in your project.
I didn't know it was that easy.
So I'm linking to an article that pretty much says, we use the convention of if Dunder name equals Dunder main, then run the main program or something.
But you can use the Dunder main.py file itself in your project.
And that dash M thing just works.
And that's pretty simple, right?
I'm like, it can't really be that easy.
So this morning, I did a little flip project, a flip-based project.
And then threw a Dunder main in there with just a print statement and installed it and went somewhere else.
And sure enough, it works just awesome.
So neat.
Yeah, that's super cool.
Yeah, I ran across this by accidentally saying Python and saying run a directory instead of a file.
I'm like, oh, it said it couldn't find Dunder main.
I'm like, .py.
I'm like, wait, it was looking for it?
That's pretty cool.
Maybe there's something to be done here.
Yeah, that's great.
I'm glad you pointed it out.
If you have a Dunder main in there, you can just say Python and the directory name and it works?
I have not verified that, but it seems like the error message would indicate that it might work.
Yeah, I mean, it was like a full path.
It wasn't just a standard directory either.
Okay.
Yeah, so pretty cool.
Neat.
I don't know how useful it is to people,
but I'll run across it every once in a while.
Yeah, that and entry points always really nice.
Now, speaking of nice, Diddy Dog is supporting our show and they got some nice products.
So let me tell you about them really quickly.
And so they're a cloud scale monitoring platform that unifies metrics, logs, traces, all that kind of stuff.
Monitors your Python apps in real time.
Helps you find bottlenecks with detailed flame graphs, trace requests as they cross over service boundaries.
All right.
So if you have microservices, you're talking to database or queuing, things like that.
Plus, it also does automatic instrumentation for popular frameworks like Django, AsyncIO, and Flask.
So you can quickly get started without too much setup.
So get started today.
There's a 14-day free trial at pythonbytes.fm/datadog.
And you get a cool Datadog t-shirt, which is always fun.
Thanks for that, Dom.
Mine's a nice purple color.
And my kids always comment when I wear it.
They like the shirt.
Yeah, I love it.
So this next one I want to talk about, the name might sound a little derogatory, but it's not really meant that way.
So maybe simplistic sounds better.
But the thing I want to talk about is this article by Chris Wellens entitled, The CPython Byte Compiler is Dumb.
Simplistic is maybe better.
But what you might not know, depending on how much you dig into it, is there's excruciatingly small amounts of optimization when CPython runs your code.
So there's a compilation step, actually, right?
The bytecode and compiler talks about some kind of compilation.
So when you run your code, you probably see the Dunder PyCache folders.
And in there you have the PYC files.
So that's taking your source code, turn it into bytecode, and put it there.
But then instead of, say, compiling that onto machine instructions, the interpreter takes that, feeds it through this ginormous switch statement that's like 3,000 lines long in the CPython runtime.
And it just goes, well, what case is this?
We're jumping to that, right?
It's pretty wild.
There's a file called cval.c.
Check it out.
However, there's very little optimization that happens here.
So Chris decided to compare this against Lua and one other similar, maybe Ruby.
I can't remember what the other one that he compared it against was.
But he talked about, you know, like, if I write this code, what happens to it?
So there are optimizations like what are called peephole optimizations and a few memory allocation optimizations in CPython.
But they're pretty limited.
So if you look at some examples, like let's take an example where we have a function.
It's called foo.
Defines two variables.
X equals zero.
Y equals one.
Return X.
That seems simple, right, Brian?
Yeah.
Except for Y is not needed.
But yeah, sure.
Exactly.
So when you see that, if Y is unused and this is not making any change, it's just literally creating a variable which is effectively an entry in, you know, like a module name lookup or a locals lookup, right?
Like, why does that need to be done?
Doesn't seem like a whole lot's happening.
So for example, the CPython bytecode compiler could just go, well, forget that line.
And it could say, well, X never changes its value.
So why don't we just inline that to say, basically, the whole function is return zero, right?
Inline the X, drop the Y.
It's good to go.
But if you go and throw that into the disassembler, you'll see that, no, that's not what happens.
It literally just takes it step by step by step.
Okay.
Wild, right?
So it loads the constant.
It stores it into a field called X.
It loads the constant.
It stores into a field called Y.
Then it loads the constant again, the value for X again.
And then it calls return val as the bytecode instructions, right?
Instead of just load constant zero, return value, right?
Like, it could be a lot quicker.
So I find that this is, it's honestly a little bit surprising.
I mean, Python is 25 years old and it doesn't take steps like this.
Now, Darius Beacon did point out that Guido himself said Python is about having the simplest,
dumbest compiler imaginable.
And there's some links to that.
So some references there if you want to go check that out.
So I think, you know, maybe it's by design to keep it simple.
It's easy for people to contribute to.
But it certainly seems like there could be a layer, like, between parsing the bytecode and executing the bytecode that says,
we're not running into debugger or something like that.
So let's go crazy and, like, just, you know, convert stuff like that to return zero.
There's also a bunch of other interesting examples in there.
This is just one that's really obvious that's good for talking that I pulled out.
And optimization levels is something that CS people have been doing with compilers for a long time.
So it's not like we'd have to invent it ourselves.
Right.
Yeah, yeah.
C has had plenty of it.
C#, the JIT compiled languages, their JIT compiler is a place where a lot of that happens.
Things like this, right?
Did you say that there was a comparison to other languages?
Do other languages do more optimization?
No, not really.
They're all pretty much the same.
For better or worse, they're all the same.
So there's an interesting point that he makes that I do want to, like, just comment on real quick.
It says, so the consensus seems to be that if you want or need better performance, don't use Python.
Go use another language.
I'm like, dude, no, you were, like, so close.
You were so close as well.
You could use, maybe don't use CPython, right?
Maybe use PyPy, P-Y-P-Y.
But the most obvious optimization to me that just can change the game is Cython.
Yeah.
You could write, like, one or two slow functions in Cython, and boom, it goes to machine instructions, and it's, you know, it nears the speed of C.
So I like the article.
I don't like that it says, oh, if things are a little bit slow, just run away.
Like, no, there's probably a package that has a C extension that already works better.
Or, you know, there's a data structure you should be using that would be better.
Or there's Cython or, you know, on and on.
There's a lot of improvements before Python's not the answer.
Or be aware that this is doing this and do your own optimization.
And for the most part, use a profiler and really tell where the optimization needs to be.
Exactly.
Like, only 10% of your code needs to be fast at all, if that much, most of the time, right?
It's usually, like, one little bit, like, oh, if this were faster, it would change the game.
Yeah.
I mean, I learned assembly in college, and I'm glad I've never had to use it.
For sure.
So, final comment here.
Brett Cannon, when I interviewed him recently, you know, he's on the steering council, core developer, and so on.
He did talk about, you know, how would adoption of Python 3 change?
How would adoption of Python in general change if we could make Python two or four times faster than it is today?
Like, most of the time, it doesn't matter.
But if it could be faster in some interesting ways, what would that mean, right?
In terms of upgrading more quickly to the new versions and just general, like, people not saying, oh, I have to use Go because I need AsyncIO or something like this.
So, it seems like if the compiler is this absent, if optimizations are this absent from the compiler, like, there's some low-hanging fruit to, like, do some simple CS compiler optimizations and make stuff faster, right?
I mean, you could make this silly foo method, like, probably three times as fast, right?
Because you could drop most of the bytecode operations.
Yeah, definitely.
It's worth looking at.
It's interesting that there is some people thinking about performance.
Yeah.
I mean, we had that conversation around the idea of Rust and maybe what if we used Rust instead of C in certain situations.
But, like, this seems like low-hanging fruit already right here.
And regardless of whether it lands in Rust or C, when it's executed, not executing code is a lot faster than executing it.
Yeah.
Cool.
What's the next one?
EdgeDB is something that came up on my radar a couple years ago.
I saw the EdgeDB people had a booth at one of the PyCons, and they were talking about it, but at the time, it wasn't around for people to actually play with.
So the other day, I saw an article called A Path to a 10x Database put out by the EdgeDB people.
One, there was a download link, which I was happy for.
There's an alpha one available.
And people that are following along and are kind of excited about what they're doing, they've published a roadmap of the features they have done, what they're working on.
And it's kind of cool.
I'm looking forward to being able to play with it more.
So people that don't know what it is, they call it a next generation relational database.
It's based on Postgres.
I don't know what that means if they're using Postgres or if they're used the design of Postgres as a base.
I haven't dug that far.
But it features a different kind of data model and an advanced query language.
And there are a whole bunch of features built into it already, and I'm pretty excited about a lot of it.
But the thing that really excites me is that they completely replaced SQL, the query language.
It's a different kind of language, and it looks more natural to me.
I mean, people aren't really writing SQL a lot of times because they're using SQLAlchemy or something like that.
And partly, those things exist because people don't want to write SQL.
But maybe if we had a better query language, we wouldn't need the middle layer so much.
Yeah, it definitely looks interesting.
I don't have a real good sense of how it compares to both of those.
The query syntax does look nice.
The joins look super cool, or the subqueries possibly is more like an analogy.
But yeah, it looks really neat.
It sort of sells itself as a hybrid between document databases like Mongo and relational ones like Postgres.
So yeah, it's cool to see innovation there for sure.
Outside of Mongo, seeing some innovation on the SQL side or the relational side is nice.
We'll see if it's really a 10x improvement.
But yeah, we can't just stick around for nothing.
I did actually try to play with it because I'm like, I want to play with this because it's got Python bindings.
But I couldn't get it to install on my Mac.
So yeah.
Yeah, well, would you have to suffer for being out on the cutting edge, Brian?
Price you pay.
Yep.
All right.
So this last one is going to be just a quick roundup of some stuff.
Then maybe this combo will help some folks.
This guy, Wakwas Jonas, worked for a software, sorry, healthcare startup in the US.
And he wrote this cool blog post called 16 Python Libraries that Helped a Healthcare Startup Grow.
Oh, neat.
Yeah.
So it's just like a paragraph or two about different packages or even modules that they use to kind of solve some problem within their startup.
So we have Paramiko, which lets you basically issue commands over SSH to other servers.
So like on my computer, I could like use Python and talk over SSH to run processes or copy files, stuff between servers.
Anything I can SSH to.
That's pretty cool.
The built-in CSV module.
You know, that's always good for parsing CSV files.
Really nice.
You mentioned SQLAlchemy.
So they use SQLAlchemy as well, requests and beautiful soup for APIs and web scraping.
I like to say that every website is an API, even if it doesn't know it.
So if it doesn't have an API, it has data and you just have to do the right request to it.
Now it's an API.
Here's one for you, Brian.
Test scenarios, which is a PyUnit extension for dependency injection.
So that's kind of cool.
Dependency injection is not that huge of a thing that people make use of in Python, but, you know, it has its place, I guess.
Yeah.
HL7.
So a simple library for parsing health level 7 files into Python objects.
That's cool.
I suppose like doing that yourself probably is not fun.
So having a library that does it is great.
Python phone numbers, which is a library for parsing, formatting, and validating international phone numbers.
That's pretty sweet.
It's based on a Google library.
It's like a Python port of it.
G event for networking and asynchronous code.
Python dash date util for parsing date times.
Like anytime I have to work with date times, I'm like, okay, this project now requires Python dash date util because parsing date time sucks without it, right?
But this one you just say pars and like that right answer just seems to always come out as great.
So Matt Plotlev for graphs.
Python magic.
Have you heard of Python magic?
I don't know.
I hadn't.
And so what you can do is you can give it a file, some random binary file or even text file, and it'll tell you what file type it is.
Oh, neat.
So like suppose somebody gives you an image and they've named it .jpg, but it's really a PNG.
Like you could feed it something to something like Python magic.
It would say PNG.
So you can give it like PDFs or zip files, and it'll tell you like what file it is.
Okay.
But magic?
That seems like a bad name for it.
But yeah.
It's Python magic.
Well, I mean, the reason is it's based on a thing called lib magic.
But yeah.
It's just like the criticism just transitively follows to lib magic, I guess.
All right.
Another one.
Django.
Obviously, that doesn't need a lot of introduction, but yeah, they must use Django.
Bodo, which is the API for interacting with all things AWS.
So if you're doing anything with that, that's super cool.
Like I use Bodo for automatic transcoding, like re-encoding in different formats, videos for my courses, or downloading, say, MP3s to a caching server, stuff like that.
And then finally, Mailgun for sending email, and Twilio's Python API for sending, both of those were sending reminders, one over email, one over text.
But it's kind of a cool combo of things, right?
Mailgun's just a great name.
We've been starting to use Paramount at work, too, but for the SSH features.
It's good.
Oh, yeah.
Nice.
Yeah, I feel like this, you know, you don't necessarily have to pick what he picked, but it's cool to see how those all fit together and think of like, well, what packages run this company, basically.
Articles like this are neat of different people solving different problems.
What are they using from Python?
Yeah, exactly.
Like it.
All right.
So that's it for our main items.
Got any extras you want to share with us?
No.
Do you?
I thought I didn't, but I'm going to share one thing with you all.
I just recorded an episode with the United States Digital Service for Talk Python.
Okay.
What is that?
I hadn't heard of that either.
But this is like a little stealth startup type thing inside the government.
President Obama set it up and it was basically the tech team brought in to solve the healthcare.gov crashing problems like that whole big fail to launch for the Obamacare stuff.
There was a group of people brought in to fix it and then they did.
They're like, well, why can't we just apply this to all the other broken things in the government?
So it's a really cool service where like you can go do like a three month tour of duty at the U.S. Digital Service and like not even have to leave your job.
Just take a like unpaid leave to go fix something in the government or whatever.
It's pretty cool.
I have an episode coming out, but I hadn't heard of it and I thought that was kind of cool.
So I thought I'd throw it out there.
Yeah, this is neat.
It is for sure.
I have a, it's almost a joke.
It's not exactly a joke.
It's more maybe mocking, but how can you tell the difference between machine learning and AI, Brian?
I don't know.
If it's written in Python, it's probably machine learning.
If it's written in PowerPoint, it's probably AI.
What?
Written in PowerPoint?
Like as in it's just like a presentation with ideas, but no code and no implementation yet.
Oh, okay.
Yeah.
Okay.
Got it.
So basically if it's real, it's machine learning.
If it's, if it's like, we're going to use magic, computer magic to solve this problem, it's AI and it's in PowerPoint.
That's funny.
I have a question for you when I, it's not a joke, but way back in the dark ages when I was going to college, all the AI work was done in like Lisp.
Yes, it was.
Are there still people doing AI in Lisp or is that not a thing anymore?
Do you know?
I think people are still doing it.
I think people are still doing it, but I don't think the neural network people have stayed there.
Right.
I think the neural network people mostly have moved to Python and things like TensorFlow and the other GP based things.
But I'm sure that there's like different kinds of AI.
Yeah.
Because you're right.
It was all, you had to be a Lisp programmer if you wanted to do anything with AI.
And AI was always this like amorphous, weird thing.
Like you don't really know what it is, but probably if we can like set up a blind chat with it over IRC, then it might seem like it's alive and then it'll be AI.
Right.
Like that, you know, the whole Turing test and all that, that stuff.
And now it's like, that's cute.
Car, drive here.
The car will go out.
You know, like that's with Python and like TensorFlow and the Lisp one that's doing the chat.
Right.
Like I feel like that's kind of where it is, but I'm sure people are still doing cool stuff with Lisp that I don't know or really want to read the code for.
Okay.
I'm glad there's probably not any Lisp programmers that listen to this.
No, but we're probably going to be posted in a negative way on some Lisp forum.
Sorry about that.
Sorry.
All right.
Well, thanks for being here, Brian.
And thanks for sharing everything.
Thank you.
You bet.
Bye, everyone.
Bye.
Thank you for listening to Python Bytes.
Follow the show on Twitter via at Python Bytes.
That's Python Bytes as in B-Y-T-E-S.
And get the full show notes at pythonbytes.fm.
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
We're always on the lookout for sharing something cool.
On behalf of myself and Brian Okken, this is Michael Kennedy.
Thank you for listening and sharing this podcast with your friends and colleagues.