Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 345, recorded July 26th. Is that right? July 26th, 2023. I am Brian Okken.
I'm Michael Kennedy.
And you know, 345 episodes, you'd think I wouldn't have to read that, but I still do because I messed up.
Anyway, a lot of fun topics today.
Our sponsors today are us.
The courses that Talk Python Training, we'll talk about those.
And the new Python People podcast and our Patreon supporters, of course.
Thank you, everybody, for continuing to support us.
And everybody that's listening to this, usually, so this is a Wednesday morning, but usually it's Tuesday at 11 Pacific is when we're recording.
And if you are around at that time, we'd love to have you join the show.
Just go to pythonbytes.fm/live, and you can see when the next episode is going to get recorded.
Yeah, Brian, I usually try to.
I'm not always successful.
Also, sometimes I just don't know.
I usually try to schedule the next live stream soon as we're done with this one.
Yeah.
And so if you go to YouTube, you can click notify me for just that event if you want to come to the next week's one or something.
So that's kind of the best way to know when the next live stream is.
Yeah.
And I appreciate people to show up and add comments.
It's nice.
So, Michael, why don't you kick us off with the first topic?
Yes, indeed.
This is a very, very exciting one.
So the next topic, the first topic is the third version of Cython, not CPython.
I didn't drop a P on accident.
Cython.
Many people know what Cython is, but I suspect sufficiently many don't that it justifies me saying what the heck it is.
So Cython, let's do a throwback, Brian.
This will be fun.
You've done plenty of C.
Do you remember inline assembler when like little sections of C code had to be like really close to the metal?
And so you would write like a little bit of assembly inside of a C function or make a function in assembly and call it something crazy like that.
We're talking like 90s.
Yeah.
Well, Cython is kind of like that for Python.
If you've got some part of your code that's not fast enough, well, one of the options is to do what a lot of people are doing is go like, well, I'm going to go learn Rust and I'm going to write this section in Rust and then I'm going to import it into Python.
And there are certainly tools for doing so.
But what if you could write Python and make it as fast as C almost?
And that's what Cython is.
And it's kind of like this inline bit, like this function or this module, I need to be in closer to C speed farther from Python speed, especially in the math type of scenario.
So that's what Cython is.
It lets you write Python code that gets compiled to C and use very, very slight variations in the Python syntax.
It used to be way different.
You'd have to have your own types and they were imported from Cython.
So instead of having a traditional PyObject derived integer type, you would actually have a Cython int, which was like a local int, and you would express that in different ways.
And they've been moving towards what they call pure Python mode, where the code that you write for Cython is actually still valid Python if you wanted to just run it that way.
And that's pretty cool, right?
Yeah.
That involves things like type int.
So if you want to say, oh, here's a thing that's an int, instead of importing some specialized int type from Cython, you would just say x colon int.
And guess what?
That's how it works in modern Python.
So the news for this week is that Cython goes 3.0.
And this news comes to us from, let's see.
Oh, no, I ran across this with other ones sent over.
They're both new releases with lots of details.
So sorry.
Yeah.
So anyway, this one, the headline here is this is long in development.
That's in like five years.
It's been working on this.
And so it sheds legacy Python support.
That is Python 2.
Look, see that legacy Python.
People are starting to adopt our term.
I don't know if we have anything to do with it, but we should have tried to popularize that view of Python 2, didn't we?
Yep.
And it has a lot of boost for this pure Python mode that I talked about.
So you might say, okay, well, that's interesting that you have this pure Python mode, but why would I really care?
Because if the goal is to make it faster, I don't want to run it in pure Python.
I want to run it in Cython.
So compile it to see and then, you know, behind the scenes is part of your building of the wheel and all that.
Yeah.
The reason you might want to do that is what if you care about mypy or you care about Rough or you care about Black or all these other tools that are Python tooling to understand the Python code or even PyCharm or VS Code.
Right.
You want it to look at that and be able to lint it and format it and understand it.
Right.
So the pure Python mode allows you to do things like keep your linting tools.
Right.
So yeah, and also just there's been discussions basically that if we had type hints when Cython started, they probably would have used them to start with instead of their own thing.
Yeah.
They had no alternative.
So they came up with something.
It's just interesting that it kind of came.
I mean, I guess it compiles to see.
So it makes sense that it had like a really strong C flavor in the way that you wrote it.
Yeah.
So what else is notable here?
It said there's major NumPy support improvements.
So Cython's have worked well with NumPy, but now with Cython 3, it gives you the ability to write NumPy ufunks.
Don't do enough NumPy to know the why I care about ufunks, but you can write them directly in Cython.
So my understanding is basically that instead of going through the Python API and layer to work with NumPy, it drops down to the C layer.
And so it's like C to C interoperability when you're doing NumPy within Cython.
That's pretty cool.
Another thing that's not mentioned in this article that I'm linking to on InfoWorld that's really cool about NumPy, about Cython, is you can remove the GIL.
You can go no GIL.
There's a context manager that's just called no GIL.
So I can say, like, with this section, I'm going to do a bunch of code, and I want to release the GIL for other parallel processing stuff.
So if multiple bits of code call that into that function, and they're being done within threads, they can run truly in parallel on hardware right on the cores, right?
True OS thread parallelism, which is pretty excellent.
Now, the limitation there is that you can't be working directly with the Python API, right?
Like, say, list or something, because those assume that they're thread safe because of the gill, right?
But if you're just doing, like, your own algorithm, right, then you can, which is pretty cool.
And, yeah, that's pretty much it.
So well done, folks, on that.
It sounds like a ton of work, but, yeah.
If you are interested in Cython, check this out.
Bye-bye.
Cero in the audience says Cython is great for waiting for HPY output.
Nice.
Mm-hmm.
All right.
Well, that's number one.
Okay.
Which is actually number three.
Oh, yeah, because it's Cython 3.
Exactly.
So I want to talk about reading code.
And I kind of agree.
So this is an article by Eric Mathis, and he's the dude that wrote Python Crash Course.
And it's on its third edition now.
It's a pretty good book.
Anyway, reading code, an important but seldom discussed skill.
And I have to agree with that.
I've had many discussions in the past about coding standards within teams.
And I try to have them be lightweight.
It's better to just teach people how to read code.
And so I'm mostly bringing this up because I definitely agree that we need to talk about it more,
especially when teaching people, reading code and reading.
Like, we often tell people go out and read the source code for some popular third-party libraries or packages
or even the internal Python, standard Python library.
But it does take some skill to read code.
So anyway, he takes an example of a lottery example or something.
It doesn't really matter.
But there's a few techniques, a couple techniques that he lists that I really like.
So if you just look at code, you've got a whole bunch of comments.
You've got a whole bunch of stuff going on often.
And one of the things he says to start with is ignore the function definitions, which is interesting
because the function definition is where the name of the function is.
But just sort of ignore that for now.
And he doesn't say this, but in his example, he said, ignore all the comments.
I mean, he took out all the comments and the function definition.
And just so that you can just see the code and not everything else.
And I actually, I had a code base once where I had, there were so many comments that I wrote a little script
that would strip the comments out so that I could read the code better.
Anyway, it does, it's a, you can mentally do it when you, when you're kind of have a,
when you get used to doing this.
And also IDs help, but that's a great way to just sort of simplify what you're looking at
so that you can mentally see what's going on.
The second technique is to simplify repetitive blocks.
Like in the example we're showing, there's a couple big print blocks.
And he, his example says, mentally, you can just lump this into print a message.
And, and that helps you.
And then there's really not that much code left when you're looking at it.
And so that, that he talks about trying to make sense of it.
I'm not going to throw any, I'm not going to discuss really what I think of the quality of the code he's showing.
It's fine.
But, and then the, the, the last thing, or one of the next to the last is to talk about using an IDE.
And so the, I do this a lot with many IDs.
I think all of them now.
You can, like, just instead of hiding the, the function definition, you can hide everything but the function definition on the, on a lot of functions.
And if, especially if you're, if you've got a whole bunch of helper functions that are cluttering up the, your workspace, you can, or in weird places, you can just hide them so that you can see.
So like in this example, we've got get winning ticket, check ticket, and make random ticket.
And then you, you can kind of see a part of one of the functions, but maybe I also want to see like one other function.
So if, especially if you're looking at two functions, you can hide the rest of them.
It makes it nice.
Yeah.
It usually goes under the term of code folding.
Yeah.
Code folding.
That's it.
Yeah.
But then off a great discussion of, think about this.
Think about that.
People are going to read your code and try to understand it.
So think about that when you're writing code.
So writing, writing readable code.
One of the things he didn't bring up that I want to make sure about is, so this technique of like hiding the function definition.
One of the things, one of the powerful things about this is because we have mentally, when we're reading code, at least when I am, and I think this applies to a lot of people, we believe the function name.
And we believe the variable name because somebody chose it.
But, so therefore it really needs to be accurate.
It should be, it's hard to name functions and variables, but sometimes they drift.
Sometimes the, like, it'll say like set name or something, but it does a whole bunch of other stuff.
So if it does a whole bunch of other stuff, you're going to have to change the name of the function.
Because if the function's name is not accurate, people are going to fold it up and just assume that's what it does.
So I would say, I would add to this, make sure your function and variable names are descriptive and change them when the body of the function changes.
So, yeah.
And it's interesting.
I just had Eric on Talk Python, which is not yet out.
So, you know, time travel podcast.
He was both there and is not there.
It's sort of an Heisen Eric sort of thing going on there.
But a couple thoughts on this.
I think if, it's kind of a big if in the comments or hinting towards this in the live stream as well.
If the naming is super good, I kind of prefer the second way, like collapse all the functions and then expand them.
As you're like, that's not clear what this is doing.
Like, let me dive into that.
Like, you know, print header.
Like, okay, well, we're going to assume that that prints the header and just go on, you know, or things like that, right, where it's pretty straightforward.
There's not a lot of, I wonder what the algorithm does there.
It's like, eh, not too much.
So then I like to kind of fold it down.
But if, I'm not sure that I would take away the function names.
I guess it would be like a unique IDE plugin where you could say like inline everything.
And even if there's repetition, just inline it and just like, you know, and then work backwards as a way to understand.
Don't do that in the main branch.
But that'd be interesting to do.
But kind of in the reverse, a lot of times what you'll end up with is a function that's like super long and poorly structured if you're trying to understand it.
If just reading the function name doesn't work, it's usually because it's a big glob of a mess, right?
Not always, but often.
And so the part where he says, comment out this, instead of having all the steps of like print the winning thing, and here's like the seven things it does, you just like have a comment, print the winning thing.
What I like to do for that is as I'm trying to understand it, I'll grab like that section and refactor to a function and say print the winner.
Grab the other part, refactor, print, print loser or something along those lines, right?
And it actually will start to have the same effect as like replace it with a comment, but you end up with running code that is still like understandable and consistent as you kind of like play with it.
So I'll go through something like big and go, okay, this section, this should be its own little thing with a name.
Hey, how about I can make a function that has that name and the IDE just a highlight, right click, you know, control T or whatever.
Do it and give it the name that you were going to make the comment.
And that works a little bit better for me because it doesn't destroy the running code in case you're like, well, but now I need to run it to see what this other part does.
Yeah.
Another thing that you're, I was thinking of other tips when I, so I learned to program mostly doing a lot of C code and in there you've got to, you've got to have, if you're writing helper functions, they need to go ahead above the, the normal, the other function.
So that like, because it's not declared when it has to be visible to the function, that's not true with Python.
And, and so I've liked to have the reverse.
So if I've like, one of the suggestions is to break out, if you've got a bunch of helper functions and it's confusing you to put them in another file.
I don't actually like to do that, especially if it's only one file using it, I'd rather put it, put them below the, the function that they're helping.
Um, and especially if there's just a couple main, functions that are used in this module that are the, that are used externally, but those I'd like to put those at the top and then all the helpers at the bottom or something like that.
Um, I used to have a coding style to do the reverse and I think it was inherited from C code style, but, Python's different.
Um, and I, I don't necessarily, I, I guess I, I'm not sure what I feel about the, hiding the function name, but I guess maybe don't trust the function name.
Yeah.
Verify.
Um, yeah, there's a couple of comments like that.
David pool says a quote I once read is if the code and comments disagree, both are wrong.
That's kind of similar to the function names as well as given sufficient times, the code and the comments, maybe function names as well.
We'll start to lie, which is interesting there.
What?
And I also see that people are like more reluctant to change somebody else's comment than they are to change their code.
And I'm like, you gotta get over that.
If the comments are on, go feel free to change it.
That's, that's a perfectly fine refactoring.
So anyway, yeah, let's move to the next.
Absolutely.
I, I totally agree with you about putting the most sort of the organizing, coordinating high level stuff first.
Um, you know, maybe what would be in the dunder, if, if name, dunder name equals dunder main, whatever that is, make that a function and put it at the top.
I, I totally agree that that's the way to go.
Yeah.
Cool.
All right, next, how about another release this time?
Something very small with lots of, lots of effort.
So this is the one that I was thinking that comes from Matt Trentini and let me pull it up.
Cause that's some good stats in it.
It says after 10 months, a thousand mainline commits and a hunt over a hundred contributors.
We have a new version of micro Python.
So thank you, Matt, for sending that into us.
That's a pretty big release, a hundred contributors.
And so the reason I brought that up is that the GitHub announcement for the release doesn't point out like how big of a release this was like almost a year's worth of work.
So micro Python, the one that runs on embedded devices, not, not phones, but like incredibly small and cheap devices, you know, like five, $10 chips.
Yeah.
It's awesome.
It's awesome that you can run Python there.
Right.
And so micro Python and circuit Python are, you know, similar projects, one fork from the other, I believe, but they've deviated a little bit.
Circuit Python being more beginner, educational friendly, micro Python being more production device, you know, creating devices to do actual jobs type of friendly.
But I think they're working a lot together.
There's been a lot of merging back.
So that's, that's pretty cool.
So this release of micro Python introduces a lightweight package manager called MIP instead of pip.
You've got MIP.
It uses a custom protocol, the query install packages that's optimized for embedded systems.
So that's pretty cool.
It's easier to get packages involved.
It's like if you've done micro Python stuff before, it's not as easy as just pip install this thing.
It's a little bit, a little bit trickier than that.
Also, the core runtime and built-in types have been compressed to only including C-level type structs for as much as possible.
So that's shrunken the size of it.
Not by a lot, but it's so small that, you know, losing kilobytes actually makes a difference, which is a pretty interesting way to think about it.
Because we don't worry about the size varying by kilobytes in CPython.
Right.
And then there's a bunch of like small changes like Bluetooth low energy changes, SSL settings.
By the way, SSL is way harder over there than you would imagine it would be.
There's a bunch of different ports, like the ESP32 is the one that I've worked with.
And so for each of the different ports that it goes through, there's sort of a summary of like, how has it changed for that one?
And I'd also like to just remind people, like, while this is awesome for embedded devices, you might think, ah, I don't do, you know, small chip programming.
So it doesn't matter to me.
You also might be interested in PyScript, right?
And so one of the things that they're trying to do is work to get MicroPython to be one of the possible foundations, the runtimes and WebAssembly for PyScript.
And when this thing is 100K or 75K, whatever it is, all of a sudden you can run PyScript in the browser nearly on par with JavaScript, right?
Traditional PyScript used the full CPython, at least as much as you can get into WebAssembly, which has meant a 10 meg download.
And then in the browser, I had to parse and start up that whole thing.
If that goes to MicroPython, that becomes incredibly fast to download 75K.
That's like JavaScript size.
Right. So all these changes are not just like, I don't think, oh, I don't do this embedded device programming, so it's not for me.
It may well be for all of us soon instead of JavaScript, which is very exciting.
So there are many changes, like, Ryan, see the scroll bar size as I'm going through this list?
I am not going to go through them, but if you care, I just want to point out, like, there's a massive new release of MicroPython.
You can go and see what's changed for the different ports.
And then in the core, right, like there's just, you know, almost, I don't know how many pages that is, but it's many, many, many pages.
So check out the linked release notes from the MicroPython team.
Congrats to them as well.
Damien George and others.
Yeah, this is really cool.
I love to see that basically also that the project is continuing and we all benefit from Python-enabled devices and stuff, and people can invent new things better.
And yeah, the Internet of Things being in Python is better than having a different language.
Absolutely.
Also, just want to, you know, sort of a time travel sort of thing as well.
I think Matt sent this over quite a while ago, and it's been sort of on our list.
I finally pulled it off our list and made it a topic.
So this is from the end of April.
It's a couple months old, but still, you know, almost a year's worth of work is worth celebrating, even if it's, you know, a couple months later.
Yeah, pretty cool.
All right.
Are we ready for the last, our last topic?
Yeah, bring it on.
I wanted to just, so I'm, you know, I shouldn't even qualify this.
I am, I was going to say I'm not a sucker for listicles, but I kind of am.
So this is an article called Advanced Python Tips for Development.
But when I was reading it, so this is by Schofield Idahen.
And when I was reading it, there's 15 tips, and some of them don't really seem that advanced.
Like the top one, use list comprehensions.
Okay, you should do that.
But there's a few that I wanted to point out that I thought were that I just wanted reminders of to use more often.
So list comprehensions are awesome.
And I kind of forget that they aren't obvious to people now because I've been using them for so long.
So they're great.
But one of the things, the next step, so tip one is use list comprehensions.
Tip two is leverage generator expressions for memory efficiency.
And I don't use generator expressions enough, and I think I should.
And one of the cool things about this article is it shows side by side a list comprehension and a generator expression.
And they look identical except for there's brackets versus parentheses.
So parentheses?
Yeah, parens.
And I kind of forget about generator expressions.
So generator expressions, are list comprehensions not generators?
I thought they were.
No, no.
No.
Okay.
Well, the list comprehension executes it all into memory.
And then the generator one, you have to start iterating through it to create it, which it's cool that they're so similar.
I'm sure it's caused untold amounts of challenges for people to go, they look the same.
You can do both.
It doesn't seem to matter until it really matters, you know?
Yeah.
And also, it's not, I mean, when you get used to list comprehensions, generator expressions kind of looks like a tuple expression.
Yeah.
Well, and then you put curly braces on it and it becomes a set comprehension.
Yeah.
The grant reminded us that.
Don't forget set comprehensions.
Yeah, yeah, yeah.
Okay.
So let's hop down.
The enumerate function, this is just take advantage of enumerate function.
This is just remember to teach people that are coming from C or other for I equals 1 to 10 sort of languages that enumerates around.
So if you need the index, also use enumerate.
Don't be a dork and get the length of a list.
Counter equals 1.
For I equals 1 to length of a list.
Yeah, yeah.
Don't do that.
Also, enumerate can, if you need it to be a, so enumerate does 0 through whatever.
If you need it to be 1 through whatever, you can give it a start.
Enumerate takes a starting point, so you can make it start at 1 if you need it.
Right.
If you're working with indexes, the default is good.
But if you're trying to print thing 1, thing 2, thing 3, then start equals 1 is the way to go.
Yeah.
Or if you're using it to get into some other data structure or something.
Anyway, I'm going to hop down to, so that's true.
Hop down to 5, which is the zip function.
And I just, so zip is great for parallel, iterating through parallel lists.
And you can do more than, this is showing name and age as two different lists and going through them.
My tip is just practice this several times and unfrequently if you need it.
Because this was a hard one to pound into my brain, is to remember how zip works.
Because it's not that confusing, but it's tripped me up for some reason.
And it's not, so you'll take several lists and it just makes, if you zip them, you end up with a, what is it, a list of tuples?
Or some sort of iterable, I don't know if it's an actual list, an iterable of tuples that you can pull out different parts of it or something.
And then you can, in this example, it says for name, last age.
So that's unpacking it after you get it.
And it works great.
I just always forget to use it.
So a good reminder.
And then now I'm going to jump down to my 12, one of the things, 12, but 8 is kind of funny because it's a formatting problem.
But anyway, use counters.
Counters are good.
12 is, what is 12?
Oh, one of the things, 11 is decorate, use decorate, decorate functions with static method and class method.
I just hardly ever do this.
Do you use static method or class method that much, Michael?
Yeah, quite a bit, actually.
Oh, really?
Okay.
Yeah.
And I guess one of the neat things, yeah, anyway, I just don't use it much.
Maybe I'll try to explore where I can use it more often.
The number 12 is use slots to reduce memory usage.
And I kind of forget to do this, too.
So this is a good reminder to use slots when you're...
And this is great, especially if you know ahead of time what, you know, your classes aren't going to add new data as it goes on.
It's not going to be dynamically generating new fields, yeah.
And I guess here I just use the adders.
So anyway.
Yeah, it's worth pointing out that slots don't just reduce memory.
They also make attribute access faster.
So like thing.field, getting and setting that value is also faster with slots.
Okay.
Yeah, that is good to remember.
Anyway, some fun tips.
14.
Use pytest.
It says use unit test or pytest.
Ignore the first part.
Use pytest.
There's a typo there.
Is that what you're saying?
There's some typos.
So use unit test or take out the unit test or.
And also it says for unit testing, just automated testing, just for all your automated testing, not just unit testing.
Yeah.
Well, those are our topics.
Do you want to talk about some extras, Michael?
I do have some.
So I feel like, Brian, it's not time for a joke yet, but there is a pretty good joke on that page we might have to come back to.
Well, do you want to explore it now?
Oh, not yet.
Not yet.
We can do it later.
Okay.
Let's do it later.
All right.
So, you know, people have different faces, Brian.
You know, sometimes you got your sort of like neutral face.
You got your happy face.
You got your sad face.
How about your hugging face?
What's your hugging face look like?
So there's this project created by Agustin.
Let me pull it up here.
The source code's linked at the bottom.
By Agustin Pekiris or Agus, as his friends call him.
Sent in, hey, I was looking to play with the hugging face API.
And so I'm like, well, what could I work with?
What if I turn a large language model or semantic search loose on Talk Python To Me and their transcripts?
That's cool, huh?
Yeah.
So he created this project.
You got to go and get a free hugging face API token because it uses hugging face.
I was joking around.
But then it says you can ask a question.
For example, what's my advanced options?
Oh, yeah.
I can see how many things I could get back.
Let's make that 10.
Focus, folks.
Come on.
So you can go things and say, who uses MicroPython in production, for example.
All right.
I can type that into the search field.
And then I can say submit.
And sometimes it takes a second.
Sometimes it's pretty quick.
But we're going to see what we get.
There's a little running character.
Although they can't choose their sport.
It's like rowing and then swimming and then it's running and then it's biking.
That's what the like on.
Here we go.
It's like a decathlon.
I guess you're right.
And so here comes the answer back.
It says over on Talk Python, you should check out PyScript powered by MicroPython.
And MicroPython plus CircuitPython.
You might be thinking, well, it's just searching titles.
But then empowering developers by embedding Python by Nina Zakarenko.
And then there's a weird one by Brian called 30 Amazing Python Projects and so on.
Or even the year in review.
Isn't that cool?
That is neat.
So if you want to play with this stuff, either because you want to build a thing like this
for something else, or you want to just go ask questions about Talk Python, you can go
and check out this app.
The source code is linked at the bottom.
I guess another comment that maybe it's a good idea to have transcripts for people to be
able to use is search.
Exactly.
We didn't have transcripts.
We weren't able to do this cool project, right?
So yeah.
Excellent.
So that's one.
And yeah, that's it for me for my extras.
You got any?
Yeah.
One, I just wanted to, I guess, remind people that Python People is a thing.
Python People is a new podcast.
And episode three is out with Brett Cannon.
And one of the quotes from him is, I came for the language, but I stayed for the community.
We explored that and what was the situation when he talked about that.
And we talked about a whole bunch of stuff, like what is the meaning of backbaking and toque,
things like that.
So check it out.
Oh, nice.
I had forgotten to, for people listening, I had forgotten to actually show the episode on the screen.
I could go back and search Talk Python again for this and see if we find Python people.
You would find a ton of Brett Cannon over there.
And we have an episode for him coming up very soon.
Yeah.
But no.
I switched it over to yours.
Next, I didn't.
There's a, oh, that's the wrong thing.
Oh.
I deleted the thing I wanted to talk about.
So I guess that's it from extras for me.
It's gone from the internet.
It is gone.
So.
I'll have a joke for us.
Okay.
Well, let's, before we do the joke, we didn't do any sponsors.
One of the sponsors, of course, is Python people, or it's us.
But I'd like people to check it out.
We have like maybe three listeners so far.
No, it's bigger than that.
But I'd like it to grow.
I also wanted to give a shout out to everybody on Patreon.
So if you go to any of Python Bytes pages, especially ones without any advertising, like
today's or episode 343, you can see Become a Patreon.
And you can click on it and become a member and help support the show for a buck.
That's great.
I also wanted to give a shout out to all of the amazing courses at Talk Python Training.
Michael has done a great job.
Plus, pulling in amazing other people to teach courses like me at Talk Python Training.
There's some great stuff.
So check it out.
Now we can do a joke.
Yeah, I've got some new courses coming from some really awesome people.
All right, on to the joke.
On to the joke.
So this one is a meme somebody put together.
I have two jokes here that we can even do the third joke that you had on screen a little
bit ago.
So HTMX.
If you all are familiar with HTMX, if you're not, you should definitely check out our HTMX
and Flask course.
This thing is so awesome.
I had so much fun learning it.
And I'm like, where is the next project I can use HTMX on?
Because it's great.
The idea with HTMX is instead of doing JavaScript, you just write attributes.
And then that magically through HTMX gets turned into server calls.
Like if I need to rebuild a table, as somebody interacts with some other part of the page,
that could just be done on the server and just send little fragments back.
It's incredible, right?
So it means you don't have to write JavaScript.
So the joke is, there's a guy that's back in dev.
And then this other dude, that's HTMX.
HTMX says, look at me.
Look at me back in dev.
You're full stack now.
You're full stack.
Stand up for yourself, man.
Don't let those.
Don't feel like you can only write it back in code.
You're full stack now.
HTMX.
Isn't that good?
Yeah.
The other joke, before we get to the one that you had on the page, is what is happening to Twitter?
Did a child try to rebrand this?
It is so incredibly bad.
No, it's like branded by a high school band.
It's so bad.
Let's call ourselves X.
That'd be so cool, man.
Yeah, man.
And so like, for example, people might be thinking, I go, you're overreacting.
They tried to take the Twitter logo down and replace it with an X.
And then the police came and stopped them because they didn't have the Twitter employees doing it.
Didn't have a permit to drive a crane around downtown San Francisco.
So it was like half the Twitter logo is like half removed.
There's no X, nor is there Twitter.
It says tweet.
I'm on Twitter.com, but there's an X.
But, you know, sometimes like, what do you call these?
Are there supposed to be X's?
You know, usually X's is kind of a bad.
I mean, it's just like.
And if you share another one, is it a re-X?
Yes, exactly.
And there's some random person who has X as a handle on Twitter.
And they're like, what's going on?
Am I going to be like Twitter?
I heard that they don't, I don't know for sure on this one, but they don't seem to have
the intellectual property rights to like trademark the letter X.
Well, you can't.
I know.
And this X looks like, I think the X11 logo.
If you go look at that, I think that was the one.
It's like, it's like a thick right slanty versus a thin left slanty, which is, you know, one's
hollow, one's solid.
Other than that, they're kind of.
Anyway, there's.
Well, that's sort of a meta joke.
On the good side, current employees and those that are laid off are all X employees now.
Exactly.
Look at all the people that work for Twitter now.
They're all X employees.
All right.
So that was just because this came from Twitter.
I'm going to open up like, wow.
This is getting.
This is getting janky.
It's X news.
So it has to be part of our extras.
It absolutely does.
All right.
Do you want to just give a quick shout out to what was on that page before?
So what were you referring to?
The only valid measurement of code quality.
Oh, yeah.
The WTFs per minute.
Okay.
Yeah.
WTFs per minute.
It's true.
Oh, that's the.
Yeah.
You need the full one.
Oh, wow.
You lost it now.
That was an ad.
It was an ad.
Yeah.
It was a code review.
And behind the door, you could just hear WTF.
What WTF?
And the good code only had a couple.
The bad code was just like overwhelmed with them.
That was the joke.
Yeah.
All right.
Well, this episode was no joke.
It was a lot of fun.
Thanks, Brian.
Thank you.
And thanks, everybody, for showing up at a weird time.
I really appreciate it.
It's great.
So.
Yeah.
See you later.