WEBVTT

00:00:00.001 --> 00:00:04.560
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:00:04.560 --> 00:00:09.940
This is episode 389, recorded June 24th. I'm Brian Okken.

00:00:09.940 --> 00:00:11.100
And I'm Michael Kennedy.

00:00:11.100 --> 00:00:13.780
This episode is brought to you by Scout APM.

00:00:13.780 --> 00:00:19.080
Listen to their spot later in the show and check them out by going to the show notes and clicking it.

00:00:19.080 --> 00:00:23.140
You can connect with us on Mastodon. We love hearing from you.

00:00:23.140 --> 00:00:29.280
And if you're listening to this later, join us live every once in a while if you want.

00:00:30.000 --> 00:00:36.380
Go to pythonbytes.fm/live to be part of the audience and it'll tell you when the next episode is.

00:00:36.380 --> 00:00:42.900
And I'd like to say thank you to everybody that signed up for the mailing list to get our show notes.

00:00:42.900 --> 00:00:47.140
It's nice to see that little creeping up in listeners.

00:00:47.140 --> 00:00:52.480
And I actually find it quite handy to find those notes later on.

00:00:52.480 --> 00:00:56.880
Absolutely. Brian, I would like to add, we're coming up on a milestone number there.

00:00:56.940 --> 00:01:01.040
And I feel like we should probably do some kind of giveaway or some kind of contest.

00:01:01.040 --> 00:01:04.140
And they'll probably happen in about the next month to six weeks.

00:01:04.140 --> 00:01:09.600
So you got to be on the list to win the prize that we invent for the thing that we'll talk about later.

00:01:09.600 --> 00:01:10.960
So sign up.

00:01:10.960 --> 00:01:11.480
Yeah.

00:01:11.480 --> 00:01:12.200
Go on by side of him.

00:01:12.200 --> 00:01:13.100
Click on newsletter.

00:01:13.100 --> 00:01:14.180
Put your info in.

00:01:14.180 --> 00:01:14.780
All right.

00:01:14.780 --> 00:01:18.040
Well, why don't you kick us off with it's a nice sunny day.

00:01:18.620 --> 00:01:20.600
Maybe some sort of solar topic.

00:01:20.600 --> 00:01:22.240
Yes, let's do it.

00:01:22.240 --> 00:01:22.820
Let's do it.

00:01:22.820 --> 00:01:24.560
How about this, Brian?

00:01:24.560 --> 00:01:26.260
Let's talk about Solera.

00:01:26.260 --> 00:01:29.780
And this one comes to us as a recommendation from a listener.

00:01:29.780 --> 00:01:32.700
So thank you to Florian for sending this in.

00:01:32.700 --> 00:01:34.220
Solera is a...

00:01:34.220 --> 00:01:34.780
Solera?

00:01:34.780 --> 00:01:35.180
Solera?

00:01:35.180 --> 00:01:35.560
I don't know.

00:01:35.560 --> 00:01:36.240
Tomato or tomato?

00:01:36.240 --> 00:01:41.620
Solera is a pure Python framework, but in React style.

00:01:41.620 --> 00:01:48.660
So it is a sort of rapid application development, somewhat data science-y focused front-end framework

00:01:48.660 --> 00:01:55.820
or framework for building front-end UIs that's like React that allows you to write better Jupyter

00:01:55.820 --> 00:01:57.280
and web apps.

00:01:57.280 --> 00:02:04.920
So it does this by basically integrating IPy widgets and other types of React-based APIs,

00:02:04.920 --> 00:02:09.920
programmable, like code, not APIs you call, on top of IPython widgets.

00:02:09.920 --> 00:02:11.260
So that's super cool.

00:02:11.260 --> 00:02:15.980
It can either be stuff that runs inside notebooks that makes them better interactive things,

00:02:15.980 --> 00:02:21.280
or it can just be standalone web apps, like FastAPI or stuff like that.

00:02:21.280 --> 00:02:21.640
Yeah?

00:02:21.640 --> 00:02:22.500
Pretty neat, huh?

00:02:22.500 --> 00:02:23.160
Yeah.

00:02:23.160 --> 00:02:28.200
So we always need more UI frameworks than Python, I believe.

00:02:28.200 --> 00:02:34.340
I would put this if I was considering Streamlit or Dash or something along those lines.

00:02:34.340 --> 00:02:35.960
It's kind of in that realm, okay?

00:02:35.960 --> 00:02:37.480
So let's see.

00:02:37.480 --> 00:02:39.800
It talks about the benefits of putting things together.

00:02:39.900 --> 00:02:45.800
But the most important thing I would recommend to you is probably check out their examples to start.

00:02:45.800 --> 00:02:48.100
So let's check out their examples.

00:02:48.100 --> 00:02:53.460
So in this area, we've got a whole bunch of different examples that don't want to scroll.

00:02:53.460 --> 00:02:54.500
Why won't you scroll?

00:02:54.500 --> 00:02:55.200
Hold on.

00:02:55.200 --> 00:02:55.780
There we go.

00:02:55.780 --> 00:02:56.500
Now it's scrolls.

00:02:56.620 --> 00:02:57.280
Yay, browser.

00:02:57.280 --> 00:02:59.540
So let's pick one of these.

00:02:59.540 --> 00:03:00.920
Let's go to the full screen ones.

00:03:00.920 --> 00:03:01.560
These are fun.

00:03:01.560 --> 00:03:04.300
Jesus, really doesn't like to scroll, does it?

00:03:04.300 --> 00:03:05.040
Full screen.

00:03:05.040 --> 00:03:07.060
Okay, so we've got different ones here.

00:03:07.060 --> 00:03:07.900
You can just pull these up.

00:03:07.900 --> 00:03:11.500
And let's just say the scatter one's kind of interesting.

00:03:11.500 --> 00:03:12.240
Check this out, Brad.

00:03:12.240 --> 00:03:13.020
This is how this works.

00:03:13.340 --> 00:03:18.300
So you take your iPython widgets, your notebook-like stuff.

00:03:18.300 --> 00:03:21.260
And look what you would see on the screen if you load this up.

00:03:21.260 --> 00:03:23.200
It's like a full UI.

00:03:23.200 --> 00:03:25.960
It fills the screen here, right?

00:03:26.120 --> 00:03:29.380
And you can either upload a data set and figure out, I don't know how to figure out what the

00:03:29.380 --> 00:03:32.040
data set's supposed to be, but probably a CSV or something.

00:03:32.040 --> 00:03:34.580
And then you can also just click, show me the sample data.

00:03:34.580 --> 00:03:35.840
And check it out.

00:03:35.840 --> 00:03:38.280
You get this cool interactive, probably plotly.

00:03:38.280 --> 00:03:40.320
Yes, plotly.

00:03:40.320 --> 00:03:41.380
UI here.

00:03:41.380 --> 00:03:45.560
And I can change the size of all these things that it works on.

00:03:45.560 --> 00:03:50.580
I can say, I would like to see, this talks about like GDP, life expectancy by country.

00:03:50.580 --> 00:03:53.940
So I can say, I want to see the life expectancy by country.

00:03:53.940 --> 00:03:55.620
And pull that up.

00:03:55.620 --> 00:03:58.920
Continent, rather, I think is how they have data.

00:03:58.920 --> 00:03:59.720
Where is this?

00:03:59.720 --> 00:04:00.780
It was working just a minute ago.

00:04:00.780 --> 00:04:02.180
Why is this not running for me?

00:04:02.180 --> 00:04:03.840
Maybe I made the size too weird for it.

00:04:03.840 --> 00:04:04.980
Don't know.

00:04:04.980 --> 00:04:06.680
Let's go.

00:04:06.680 --> 00:04:07.500
Country.

00:04:07.500 --> 00:04:10.100
Nah, I guess I'm picking the wrong thing.

00:04:10.100 --> 00:04:11.860
That's just the live demo curse.

00:04:11.860 --> 00:04:12.760
It just won't work.

00:04:12.760 --> 00:04:13.560
It totally is.

00:04:13.560 --> 00:04:14.440
I don't know why it's not working.

00:04:14.440 --> 00:04:15.160
Anyway, there we go.

00:04:15.160 --> 00:04:16.900
I just have to reverse it.

00:04:16.900 --> 00:04:17.220
There we are.

00:04:17.220 --> 00:04:17.800
This is looking good.

00:04:17.800 --> 00:04:22.920
So you can say, show me the life expectancy by country.

00:04:23.060 --> 00:04:26.260
And then you get all these really interesting interactive bits.

00:04:26.260 --> 00:04:27.220
You can resize it.

00:04:27.220 --> 00:04:32.720
So this is all a super easy UI to build, Brian, with this UI framework.

00:04:32.720 --> 00:04:33.920
That's pretty cool.

00:04:33.920 --> 00:04:38.840
And if you go back and look at the example, they'll show you like one of the cells in a

00:04:38.840 --> 00:04:41.820
Jupyter notebook can just be this graph here.

00:04:41.940 --> 00:04:45.500
And it has a full screen option or it can just be like the output of a cell.

00:04:45.500 --> 00:04:47.100
It's one of these interactive apps.

00:04:47.100 --> 00:04:47.820
Oh, neat.

00:04:47.820 --> 00:04:48.720
How wild is that, huh?

00:04:48.720 --> 00:04:49.480
Isn't that crazy?

00:04:49.480 --> 00:04:50.060
Yeah.

00:04:50.060 --> 00:04:54.320
And then you can also go and see, you know, what does a tutorial look like?

00:04:54.320 --> 00:04:56.680
Somewhere.

00:04:56.680 --> 00:04:58.440
I gotta go to get started.

00:04:58.440 --> 00:04:59.100
Quick start.

00:04:59.360 --> 00:05:04.080
So if you go to the quick start, it'll show you basically how to program this stuff.

00:05:04.080 --> 00:05:05.820
And it's super easy.

00:05:05.820 --> 00:05:10.420
You just put a decorator, say this is a component, and it shows up in your page.

00:05:10.420 --> 00:05:14.340
It's really focused on building these little reasonable and composable components.

00:05:14.340 --> 00:05:17.440
So it's a little bit like shiny, actually, I think, actually.

00:05:17.440 --> 00:05:23.400
So anyway, super cool way to build these interactive dashboards and stuff that's more than just a picture,

00:05:23.400 --> 00:05:26.700
but a thing you can actually play with and publish to the web.

00:05:27.020 --> 00:05:32.220
Yeah, especially, I love stuff like this, like, especially if you don't really know how you want to look at the data yet.

00:05:32.220 --> 00:05:35.700
So you can give people lots of options.

00:05:35.700 --> 00:05:36.600
Absolutely.

00:05:36.600 --> 00:05:39.600
And I don't see a price.

00:05:39.600 --> 00:05:41.400
All I see is Staris on GitHub.

00:05:41.400 --> 00:05:47.860
So I think it's just an open source project that you can use for your stuff, not a commercial thing, from what I can tell.

00:05:47.860 --> 00:05:53.420
So one of the things, I was looking at this the other day, and I don't know if you came across an answer to this question,

00:05:53.420 --> 00:06:00.360
but it said a pure Python React-style framework for scaling Jupyter and web apps.

00:06:00.360 --> 00:06:04.020
The and is, like, I was a little bit confused.

00:06:04.020 --> 00:06:09.380
Do I have to be a Jupyter-type programmer to do this, or do you know if I can?

00:06:09.380 --> 00:06:09.500
No.

00:06:09.500 --> 00:06:12.980
If you want to use FastAPI, it can.

00:06:12.980 --> 00:06:15.320
And there's a thing called, what do they call it?

00:06:15.320 --> 00:06:18.920
A Solaris server or something like that.

00:06:19.040 --> 00:06:23.840
So you can run that, and it says, look, it'll run with FastAPI, Starlet, Flask, and so on.

00:06:23.840 --> 00:06:24.360
Okay.

00:06:24.360 --> 00:06:31.560
And I imagine you just create, just basically serve up some common template that, like, starts it all, you know, those kind of things.

00:06:31.560 --> 00:06:36.660
The other thing that's worth pointing out in this whole discussion is, it says built on top of React-ton.

00:06:36.660 --> 00:06:40.380
And React-ton is this interesting project here.

00:06:40.380 --> 00:06:42.900
It says it's like React.

00:06:42.900 --> 00:06:44.140
Yeah, it is.

00:06:44.140 --> 00:06:46.160
It's a really good logo.

00:06:46.160 --> 00:06:54.220
It's a Python logo as the nucleus of an atom, and then a bunch of little small Python logos circling it like electrons.

00:06:54.220 --> 00:06:54.640
That's good.

00:06:55.260 --> 00:07:01.280
So this basically lets you create code for IPython widgets that is in the style of React.

00:07:01.280 --> 00:07:08.420
So if you go down here, you can create, for example, a component, which is a clickable button.

00:07:08.420 --> 00:07:12.580
And you basically initialize the state, and then you write the handler.

00:07:13.140 --> 00:07:15.300
And just like the handful of lines of code.

00:07:15.300 --> 00:07:16.260
Yeah.

00:07:16.260 --> 00:07:16.800
Yeah.

00:07:16.800 --> 00:07:17.440
Yeah, it's pretty neat.

00:07:17.440 --> 00:07:23.620
And so that's what this thing is all about, is creating these little widget-type things or components, and then building up your UI out of it.

00:07:23.620 --> 00:07:26.140
So I say, certainly worth checking out.

00:07:26.140 --> 00:07:31.820
I kind of want to just do one of those, like, just a button that just tells you how many times you've clicked it.

00:07:31.820 --> 00:07:34.320
Exactly.

00:07:34.320 --> 00:07:36.120
I'm not going to do anything.

00:07:36.120 --> 00:07:41.240
After it gets past 100, it'll be like, what are you doing in your life?

00:07:41.240 --> 00:07:42.660
Leave and go do something else.

00:07:42.880 --> 00:07:43.760
Stop clicking me.

00:07:43.760 --> 00:07:44.420
Yeah.

00:07:44.420 --> 00:07:45.240
All right.

00:07:45.240 --> 00:07:46.440
Yeah, people check that out.

00:07:46.440 --> 00:07:46.960
Thanks, Florian.

00:07:46.960 --> 00:07:51.700
Next up, I wanted to talk about coverage a little bit.

00:07:51.700 --> 00:07:52.860
I think?

00:07:52.860 --> 00:07:54.140
No, I'm on the wrong page.

00:07:54.140 --> 00:07:55.880
I do want to talk about coverage.

00:07:55.880 --> 00:08:01.780
So Ned Batchelder wrote an article called Coverage at a Crossroads.

00:08:01.780 --> 00:08:04.960
And so there's a couple things I wanted to point out about this.

00:08:07.680 --> 00:08:18.660
So the gist of it is, Ned wants to make coverage.py faster.

00:08:18.660 --> 00:08:22.440
And one of the issues is with the way coverage is written right now and the way it's composed.

00:08:23.120 --> 00:08:28.400
So he starts the conversation discussing really how coverage works.

00:08:28.400 --> 00:08:37.220
And that's the part where I really like, even if you don't care whether coverage is fast or not, this is a nice, fun article to realize how coverage works.

00:08:37.220 --> 00:08:39.960
And so coverage uses a thing called a trace function.

00:08:40.280 --> 00:08:47.080
So it takes your code and adds these trace functions to every line so that coverage can know when any line gets hit.

00:08:47.080 --> 00:08:49.380
And then coverage also does branch coverage.

00:08:49.380 --> 00:08:54.120
So coverage does branch coverage with allowing a thing called the arcs.

00:08:54.120 --> 00:09:06.620
So it generates these four lines that look like branches, these arcs of like, it could go like your line, you could go from line one to line two or line two to line three, things like that.

00:09:06.620 --> 00:09:08.240
And so it keeps track of all that.

00:09:08.240 --> 00:09:15.100
And the reason why things could be faster is because like, let's say you hit line two already.

00:09:15.100 --> 00:09:18.600
You don't have to, and there's no branches in there or anything.

00:09:18.600 --> 00:09:19.820
It's just a line of code.

00:09:19.820 --> 00:09:27.960
You wouldn't need to actually hit the trace function every time you hit that, but there's no way to take it out.

00:09:27.960 --> 00:09:31.960
So there's some ideas around making it faster.

00:09:31.960 --> 00:09:34.700
And SlipCover, for instance, has a bunch of ways.

00:09:34.700 --> 00:09:41.240
So he uses a bytecode thing that there's a discussion around SlipCover as a different coverage tool.

00:09:41.580 --> 00:09:46.960
There's also discussion around SysDop monitoring that came in in Python 3.12.

00:09:46.960 --> 00:09:53.660
And with SysDop monitoring, you can do something like a trace function, but it's something that you can take away later.

00:09:53.660 --> 00:09:57.280
So the idea, like for line coverage, this would work just great.

00:09:57.280 --> 00:10:06.760
So you could just say with SysDop monitoring every time, if I hit this line, great, now I can take that out so I don't have to worry about that line ever again.

00:10:07.860 --> 00:10:16.460
But there's some discussion that Ned has around how do you deal with branching for that.

00:10:16.460 --> 00:10:21.780
And it's an interesting take on kind of an interesting idea.

00:10:21.780 --> 00:10:28.520
There's an interesting problem set for how to deal with it, kind of like maybe ARCs aren't the right way to do it.

00:10:28.520 --> 00:10:32.000
Maybe there's some other way to deal with branch coverage.

00:10:32.000 --> 00:10:41.700
And it's not trivial because there's an example of a try finally block with a return statement happening in the try.

00:10:41.700 --> 00:10:51.160
So you don't necessarily hit – you always will hit the finally even with the return, but you don't know if you'll hit the line after.

00:10:51.160 --> 00:10:53.240
You know, you'd have to look at the code.

00:10:53.640 --> 00:10:56.000
But really fun discussion.

00:10:56.000 --> 00:11:02.740
There's a call out of where if you want to get involved, you'd like to offer some solutions or just help with the discussion.

00:11:02.740 --> 00:11:03.400
There's that too.

00:11:03.400 --> 00:11:09.780
But even if you're not going to help, I think it's a cool discussion of how coverage works.

00:11:10.320 --> 00:11:16.940
And I just wanted to thank Ned for putting time and effort into making sure coverage is an awesome tool.

00:11:16.940 --> 00:11:17.660
So thanks, Ned.

00:11:17.660 --> 00:11:18.940
Yeah, that's pretty excellent.

00:11:18.940 --> 00:11:26.840
And of course, there's going to be functions and branches of execution that are in some kind of tight loop and run a million times.

00:11:26.840 --> 00:11:30.620
But after the third time, you've already realized it's 100% covered.

00:11:31.000 --> 00:11:39.320
So if you could just – because running with coverage and stuff like that, all this profiling and code coverage stuff puts a serious hurting on the performance.

00:11:39.320 --> 00:11:44.300
So if you could say, all right, that part's done 100%, stop slowing it down, that'd be cool.

00:11:44.300 --> 00:11:54.220
Yeah, I did like this cool idea of – with the other ones of creating like adding no-op statements in just so that for branches,

00:11:54.220 --> 00:11:59.780
so that you just like check to see, you know, if I hit that, then that branch was taken.

00:12:00.060 --> 00:12:01.060
That's kind of a neat idea.

00:12:01.060 --> 00:12:03.260
You could, you know, add these extra little hooks.

00:12:03.260 --> 00:12:05.960
But anyway, cool.

00:12:05.960 --> 00:12:07.040
Awesome, awesome.

00:12:07.040 --> 00:12:11.520
Up next, thank you to Scout APM.

00:12:11.520 --> 00:12:15.520
Let me tell you real quick about Scout APM.

00:12:15.520 --> 00:12:19.180
They're big supporters of Python Bytes, so we appreciate that very much.

00:12:19.180 --> 00:12:25.480
So if you are tired of spending hours trying to find the root cause of issues impacting your performance,

00:12:25.480 --> 00:12:28.280
then you owe it to yourself to check out Scout APM.

00:12:28.620 --> 00:12:37.500
They're a leading Python application performance monitoring tool, APM, that helps you identify and solve performance abnormalities faster and easier.

00:12:37.500 --> 00:12:42.800
Scout APM ties bottlenecks such as memory leaks, slow database queries, background jobs,

00:12:42.800 --> 00:12:48.400
and the dreaded N plus one queries that you can end up if you do lazy loading in your ORM.

00:12:48.400 --> 00:12:50.800
And then you say, oh, no, why is it so slow?

00:12:50.800 --> 00:12:53.140
Why are you doing 200 database queries for what should be one?

00:12:53.140 --> 00:12:54.560
So you can find out things like that.

00:12:54.560 --> 00:13:01.940
And it links it back directly to source code so you can spend less time in the debugger and healing logs and just finding the problems and moving on.

00:13:02.140 --> 00:13:04.940
And you'll love it because it's built for developers by developers.

00:13:04.940 --> 00:13:06.580
It makes it easy to get set up.

00:13:06.580 --> 00:13:09.120
Seriously, you can do it in less than four minutes.

00:13:09.120 --> 00:13:09.940
So that's awesome.

00:13:09.940 --> 00:13:12.980
And the best part is the pricing is straightforward.

00:13:12.980 --> 00:13:18.460
You only pay for the data that you use with no hidden overage fees or per seat pricing.

00:13:19.180 --> 00:13:20.940
And I just learned this, Brian.

00:13:20.940 --> 00:13:26.080
They also have they provide the pro version for free to all open source projects.

00:13:26.080 --> 00:13:33.500
So if you're an open source maintainer and you want to have Scout APM for that project, just shoot them a message or something on their pricing page about that.

00:13:33.500 --> 00:13:37.380
So you can start your free trial and get instant insights today.

00:13:37.380 --> 00:13:40.060
Visit by thembytes.fm slash Scout.

00:13:40.060 --> 00:13:42.300
The link is in your podcast player show notes as well.

00:13:42.300 --> 00:13:43.720
And please use that link.

00:13:43.720 --> 00:13:47.680
Don't just search for them because otherwise they don't think you came from us.

00:13:47.760 --> 00:13:49.260
And then they'd stop supporting the show.

00:13:49.260 --> 00:13:51.820
So please use our link by thembytes.fm slash Scout.

00:13:51.820 --> 00:13:52.760
Check them out.

00:13:52.760 --> 00:13:54.680
It really supports the show.

00:13:54.680 --> 00:13:58.020
This one, Brian, comes to us from another Brian.

00:13:58.020 --> 00:13:58.580
Okay.

00:13:58.580 --> 00:13:59.780
Way in the past, though.

00:13:59.780 --> 00:14:04.640
This is Brian Skin that back in January said, hey, guess what?

00:14:04.640 --> 00:14:07.020
Pep 698 has been accepted.

00:14:07.020 --> 00:14:08.020
How awesome is that?

00:14:08.020 --> 00:14:12.840
And I haven't, it hasn't bubbled to the top of my list until now.

00:14:12.840 --> 00:14:16.480
But I think it's, we're talking about this is in Python 312.

00:14:16.900 --> 00:14:19.280
And yeah, let's, let's check it out.

00:14:19.280 --> 00:14:24.460
So if we go over to the pep, it is an override decorator for static typing.

00:14:24.460 --> 00:14:30.700
So, you know, some languages, C#, I think C++, but it's been a while since I messed with it.

00:14:30.700 --> 00:14:34.740
You know, have explicit override keywords and virtual methods.

00:14:34.740 --> 00:14:36.320
I know C++ has virtual methods.

00:14:36.320 --> 00:14:38.680
I just don't know if you indicate that you're overriding it.

00:14:38.680 --> 00:14:40.540
Tell me, Brian, do you use the override keyword?

00:14:40.540 --> 00:14:42.400
Or do you just, do you just write the function?

00:14:42.400 --> 00:14:44.160
You just, just write it.

00:14:44.320 --> 00:14:45.180
Yeah, that's what I thought.

00:14:45.180 --> 00:14:45.620
Yeah.

00:14:45.860 --> 00:14:46.220
Yeah.

00:14:46.220 --> 00:14:52.460
And in C#, you actually say there's a virtual function in the base class, which is intended to have a potential people overriding.

00:14:52.460 --> 00:15:01.280
And then in the derived classes, you say override instead of virtual to indicate that you have to say that right to say that you're, you're replacing this behavior.

00:15:01.280 --> 00:15:04.540
And you might need to call the base class version and all that kind of stuff.

00:15:04.540 --> 00:15:12.160
Well, basically Python gets that if you want it as a lot of things with typing, it's multiple, it's optional and multiple ways.

00:15:12.160 --> 00:15:14.180
So let's jump over.

00:15:14.180 --> 00:15:16.220
If you scroll down, it's kind of weird to me.

00:15:16.940 --> 00:15:19.840
The PEP says this PEP is here for historical reasons.

00:15:19.840 --> 00:15:21.620
It's now part of Python.

00:15:21.620 --> 00:15:24.000
So please see override.

00:15:24.000 --> 00:15:26.800
When you click it though, it doesn't take you to the Python documentation.

00:15:26.800 --> 00:15:32.440
It takes you a separate typing documentation for Python, but is also in the Python documentation.

00:15:32.440 --> 00:15:33.320
Interesting.

00:15:33.320 --> 00:15:34.580
Which one wins?

00:15:34.580 --> 00:15:35.440
I don't know, but whatever.

00:15:35.440 --> 00:15:38.420
The example here in the link from the PEP is super clear.

00:15:38.580 --> 00:15:45.940
So you had a parent class and you don't say virtual because we don't have that, but you can say at override.

00:15:45.940 --> 00:15:52.280
So the parent class, the base class has a foo function that takes no parameters and returns an integer.

00:15:52.280 --> 00:15:58.560
I'd hear you in the child class, you say override and then as a decorator and then foo, same signature.

00:15:58.560 --> 00:16:04.000
And if you were to say override something that didn't exist, type checking will say there's no signature.

00:16:04.000 --> 00:16:08.000
Your intention is to override this thing, but it doesn't exist.

00:16:08.320 --> 00:16:10.540
Maybe, maybe you meant to type.

00:16:10.540 --> 00:16:13.000
I don't like these examples, but this is what's written here.

00:16:13.000 --> 00:16:13.640
So here we go.

00:16:13.640 --> 00:16:23.120
You overrode foo because that existed, but you tried to override baz, but it's bar and you misspelled it or something like that.

00:16:23.120 --> 00:16:28.120
Now, I don't know what happens if you mismatch the parameters, but you get the name right.

00:16:28.120 --> 00:16:28.860
You know what I mean?

00:16:28.860 --> 00:16:29.660
Like I'm overriding.

00:16:29.660 --> 00:16:30.460
It takes two parameters.

00:16:30.460 --> 00:16:31.480
Like, no, it takes one.

00:16:31.480 --> 00:16:32.960
I don't know.

00:16:32.960 --> 00:16:33.700
I have to test that out.

00:16:33.700 --> 00:16:44.840
But anyway, if you want to have a little bit more validation in your Python typing for your classes and your inheritance, check this out.

00:16:44.840 --> 00:16:45.780
It's part of Python.

00:16:45.780 --> 00:16:47.640
It's nothing special that you add.

00:16:47.640 --> 00:16:51.140
It only executes at definition time for the class.

00:16:51.340 --> 00:16:53.840
So it's not like a runtime type thing.

00:16:53.840 --> 00:16:55.020
So it should be low overhead.

00:16:55.020 --> 00:16:55.540
Yeah.

00:16:55.540 --> 00:16:56.020
Pretty neat.

00:16:56.020 --> 00:16:56.780
Why not use it, right?

00:16:56.780 --> 00:16:57.800
Yeah.

00:16:57.800 --> 00:16:59.140
Low overhead.

00:16:59.140 --> 00:17:00.020
High override.

00:17:00.020 --> 00:17:01.540
High override.

00:17:01.540 --> 00:17:02.100
Low overhead.

00:17:02.100 --> 00:17:02.560
That's right.

00:17:02.560 --> 00:17:03.000
There you go.

00:17:03.000 --> 00:17:03.780
All right.

00:17:03.780 --> 00:17:05.740
Well, thanks, Brian Skin, for sending this in.

00:17:05.740 --> 00:17:07.680
And yeah, interesting.

00:17:07.680 --> 00:17:08.680
Cool.

00:17:08.680 --> 00:17:16.320
One of the other things that's neat is speeding up Python bits.

00:17:16.320 --> 00:17:22.520
And so there's kind of a neat article called from Gage.

00:17:22.520 --> 00:17:25.080
Oh, that must be the group that makes this stuff.

00:17:25.080 --> 00:17:30.720
Anyway, called Parsing Python ASTs 20 Times Faster with Rust.

00:17:30.720 --> 00:17:36.520
So this article is talking about speeding up a tool called TAC.

00:17:36.520 --> 00:17:39.080
Now, TAC is a CLI.

00:17:39.080 --> 00:17:45.120
It says it's a CLI tool that lets you define and enforce import boundaries between Python modules in your project.

00:17:45.120 --> 00:17:45.880
Yeah.

00:17:45.880 --> 00:17:47.540
Remember, I talked about that a few weeks ago.

00:17:47.540 --> 00:17:47.920
Yep.

00:17:47.920 --> 00:17:48.440
Actually, right?

00:17:48.440 --> 00:17:48.820
Yeah.

00:17:48.820 --> 00:17:50.960
Episode 384, you talked about it.

00:17:50.960 --> 00:17:56.820
So yeah, that was just May 21st, just a couple of months ago, or last month.

00:17:56.820 --> 00:17:57.280
Nice.

00:17:57.280 --> 00:17:57.720
Nice.

00:17:57.720 --> 00:18:02.800
Anyway, at first, I'm like, okay, you sped up with Rust.

00:18:02.800 --> 00:18:04.060
We're kind of hearing that.

00:18:04.060 --> 00:18:14.480
Why I'm calling this out, though, is not just that TAC seems cool, is that I really liked the methodology that they're talking through here.

00:18:14.740 --> 00:18:20.660
So they talk about not just how they made it faster, but the process they went through to figure out which parts.

00:18:20.660 --> 00:18:35.460
So they used profiling, but in specific, I think they used a tool called PySpy and SpeedScope to visualize and get flame graphs for performance.

00:18:35.460 --> 00:18:36.260
Interesting.

00:18:36.260 --> 00:18:37.480
I've not heard of either of those.

00:18:37.760 --> 00:18:42.800
I have not, or maybe I have, but we cover a lot of tools, man.

00:18:42.800 --> 00:18:55.060
Anyway, these look slick, but the output of it showed that there was roughly 90% of the total time was taken by a function called get project imports.

00:18:55.060 --> 00:19:02.980
And in that, it spent about two-thirds of the time parsing the ASTs and the remaining one-third traversing them.

00:19:02.980 --> 00:19:15.220
So some great information and some great examples of instead of trying to just throw Rust at it to speed things up or even just using Python to optimizing your own Python,

00:19:15.220 --> 00:19:25.600
taking a look at exactly what you're doing and only speeding up the little bits that are slow, which is a – I love that aspect of this.

00:19:25.600 --> 00:19:28.220
So, okay, so they took those bits.

00:19:28.220 --> 00:19:40.040
Also, went by and there's a discussion of why the AST parsing was slow anyway because that should have been some C code as well.

00:19:40.040 --> 00:19:50.820
But they – there's a little bit of a deep dive into there, but then they jumped into just rewriting it in Rust.

00:19:50.820 --> 00:20:03.260
And then this – we've covered these tools before using PyO3 and Maturin to help get – quickly develop some Rust for a couple functions.

00:20:03.260 --> 00:20:06.560
And, yeah, so that was it.

00:20:06.560 --> 00:20:12.520
And it, like, went from – the example they had was a code base – it was a common code base.

00:20:12.520 --> 00:20:21.920
So, which was it – the Sentry code base, about 3,000 lines of Python files that took, like, 10 seconds to test.

00:20:21.920 --> 00:20:25.600
And with this speed up, it dropped it down to one second.

00:20:25.600 --> 00:20:29.940
So, yeah, 20 – that seems like a pretty fast speed up.

00:20:29.940 --> 00:20:30.620
So, nice.

00:20:30.620 --> 00:20:30.760
Yeah.

00:20:30.760 --> 00:20:31.820
Yeah, it's real nice.

00:20:32.480 --> 00:20:44.480
Also, just kind of a great user example and a short write-up on using these – using profiling to really look at where your bottlenecks are and then maybe throwing Rust at it there.

00:20:44.480 --> 00:20:54.180
Yeah, and it looks like they just basically re-implemented that one function in Rust and then just used it as a dependency, right, with their PyO3 extension.

00:20:54.180 --> 00:20:56.640
Yeah, so I totally want to try that.

00:20:56.640 --> 00:21:06.460
Like, just – that would be a great way to get into Rust a little bit is to just not try to make a Rust application but just replacing, like, one function or something.

00:21:06.460 --> 00:21:09.220
This one algorithm is called a ton of times.

00:21:09.220 --> 00:21:10.800
It's super slow, relatively.

00:21:10.800 --> 00:21:12.080
It's where we spend all our time.

00:21:12.080 --> 00:21:13.700
But it's not that big, right?

00:21:13.700 --> 00:21:17.620
Like, we could write it, probably figure it out in a day or two in Rust, and then off you go.

00:21:17.620 --> 00:21:19.480
Yeah, I don't need to learn all the Rust.

00:21:19.480 --> 00:21:21.420
I just need to make this thing faster.

00:21:21.420 --> 00:21:23.160
Tell me how to do a for loop in Rust.

00:21:23.160 --> 00:21:23.600
Tell me.

00:21:23.600 --> 00:21:23.940
Okay.

00:21:23.940 --> 00:21:27.260
Well, tell me, Brian, do you got extras?

00:21:27.260 --> 00:21:29.100
Do I have extras?

00:21:29.100 --> 00:21:30.580
Let me check.

00:21:30.580 --> 00:21:31.560
Yeah, I do.

00:21:31.560 --> 00:21:33.760
Last – when was it?

00:21:33.760 --> 00:21:35.680
Let's go ahead.

00:21:35.680 --> 00:21:37.240
Episode 388.

00:21:37.240 --> 00:21:38.740
That was just last week, wasn't it?

00:21:38.740 --> 00:21:42.340
It was last week where we talked about not deleting all the repos.

00:21:42.340 --> 00:21:43.020
Yeah.

00:21:43.020 --> 00:21:47.800
Well, one of the things I talked about was – what did I talk about?

00:21:47.800 --> 00:21:53.060
I talked about import by string with packageutil.resolve name.

00:21:53.580 --> 00:21:56.440
Bad on me for not doing my homework a little bit.

00:21:56.440 --> 00:22:08.560
Brett Cannon notes that discussions around this are maybe not really great things because packageutil is deprecated or it's going to be or something.

00:22:09.280 --> 00:22:12.600
So, Brett's recommending not using packageutil.

00:22:12.600 --> 00:22:13.600
Just FYI.

00:22:13.600 --> 00:22:17.200
If it doesn't give you a deprecation warning now, it will someday.

00:22:17.200 --> 00:22:18.500
Don't go that way.

00:22:19.160 --> 00:22:19.760
Okay.

00:22:19.760 --> 00:22:23.860
Next up, really quickly, kind of a fun thing.

00:22:23.860 --> 00:22:32.440
At the Python Language Summit, there was a discussion, should Python adopt calendar versioning?

00:22:32.440 --> 00:22:35.540
And this kind of fun discussion.

00:22:35.700 --> 00:22:39.380
So, we have like Python 3.12 right now.

00:22:39.380 --> 00:22:43.480
Should somehow it be like Cal versioning?

00:22:43.480 --> 00:22:45.900
And if we went to Cal versioning, what would it be?

00:22:45.900 --> 00:22:50.500
And a fun – I think it was Carol Willing.

00:22:50.560 --> 00:23:00.420
Yeah, Carol Willing brought up that we want to at least keep our current versioning through 3.14 because then it would be the Pi version and we can't –

00:23:00.420 --> 00:23:00.660
Yes.

00:23:00.660 --> 00:23:02.700
We've got to do 3.14 now.

00:23:02.700 --> 00:23:03.320
Yeah.

00:23:03.420 --> 00:23:16.540
So, a lot of this boils into a PEP 2026, which is also nice numbering because the shout-out of 2026 is when we would switch.

00:23:16.540 --> 00:23:22.080
So, the idea would be what we've got – oh, there's a table here.

00:23:22.080 --> 00:23:25.560
3.14, no change.

00:23:25.560 --> 00:23:28.400
That comes out in 2025 if we go to this.

00:23:28.400 --> 00:23:33.860
And instead of 3.15, we just make the 2026 version 3.26.

00:23:33.860 --> 00:23:34.640
No.

00:23:34.640 --> 00:23:35.840
Which would –

00:23:35.840 --> 00:23:40.460
We're going to end up with a year 3K problem.

00:23:40.460 --> 00:23:41.760
That's – okay.

00:23:41.760 --> 00:23:46.460
But how – that's like 75 years in the future that we have to care about that.

00:23:46.460 --> 00:23:48.380
I guess they could put a 1.26.

00:23:48.380 --> 00:23:50.780
Then it'll be 1,000 years.

00:23:50.780 --> 00:23:51.840
It probably doesn't matter at that point.

00:23:51.840 --> 00:23:52.880
Oh, yeah.

00:23:52.880 --> 00:23:54.100
We can add it.

00:23:54.100 --> 00:23:54.580
Yeah.

00:23:54.580 --> 00:23:56.860
So, I think we're okay.

00:23:57.580 --> 00:23:58.900
Well, actually, I'm not sure.

00:23:58.900 --> 00:24:00.600
That would be weird, wouldn't it?

00:24:00.600 --> 00:24:01.120
I don't know.

00:24:01.120 --> 00:24:02.260
You could have 126.

00:24:02.260 --> 00:24:08.520
I think you can get to year 2,999 without going too bizarrely out of secrets.

00:24:08.520 --> 00:24:08.720
Yeah.

00:24:08.720 --> 00:24:11.660
Maybe we're ready for Python 4 by then.

00:24:11.660 --> 00:24:12.480
No.

00:24:12.480 --> 00:24:14.240
We're not ready.

00:24:14.240 --> 00:24:15.360
Too soon.

00:24:15.360 --> 00:24:16.940
Too soon.

00:24:16.940 --> 00:24:18.400
So, what do you think of this?

00:24:18.400 --> 00:24:19.620
Should we recover?

00:24:19.620 --> 00:24:21.220
It's a little weird to me.

00:24:21.220 --> 00:24:25.200
Why not just 3.2026, 3.2027?

00:24:25.460 --> 00:24:30.280
Because to me, this doesn't communicate calendar versioning.

00:24:30.280 --> 00:24:35.240
We already have calendar versioning if you don't care about what the number is because it's yearly release cycles.

00:24:35.240 --> 00:24:35.800
Right?

00:24:35.800 --> 00:24:38.700
3.12 means 2024.

00:24:38.700 --> 00:24:41.100
3.13 means 2025.

00:24:41.800 --> 00:24:51.260
And so, if you're not using the calendar numbers, I know 26 is closer to 2026 than 15, but there's still, to me, it's like, well, 16, 27.

00:24:51.260 --> 00:24:51.900
I don't know.

00:24:51.900 --> 00:24:53.660
It's just, like, here's the next year's version.

00:24:53.660 --> 00:24:54.840
Yeah.

00:24:55.200 --> 00:24:55.480
Okay.

00:24:55.480 --> 00:24:56.760
I'm all for it.

00:24:56.760 --> 00:25:06.240
I think we should switch because I think that since we've gone to a one-year release cycle anyway, why not somehow encode that in the number?

00:25:06.240 --> 00:25:07.700
I totally agree with that.

00:25:07.700 --> 00:25:08.440
I agree with that.

00:25:08.440 --> 00:25:14.080
I just, my vote's for 3.2026, like most calendar versioning things.

00:25:14.080 --> 00:25:14.980
Oh, yeah.

00:25:14.980 --> 00:25:15.920
Just do four digits?

00:25:15.920 --> 00:25:16.680
Yeah, exactly.

00:25:16.680 --> 00:25:17.260
That's all I'm saying.

00:25:17.260 --> 00:25:19.460
It's just put four digits so it really is the year on the end.

00:25:19.500 --> 00:25:21.280
And it's really clear that it means the year.

00:25:21.280 --> 00:25:22.680
You don't have to know the code.

00:25:22.680 --> 00:25:24.380
That's all I'm saying.

00:25:24.380 --> 00:25:29.040
But I'm also with Carol on leaving 3.14.

00:25:29.040 --> 00:25:30.740
Yeah.

00:25:30.740 --> 00:25:38.360
I mean, there's nothing saying, since it's bigger, there's nothing saying we could go to two digits and then at some point go, you know, let's just throw four digits in there.

00:25:38.360 --> 00:25:38.900
Yeah.

00:25:38.900 --> 00:25:39.140
Anyway.

00:25:39.140 --> 00:25:40.020
Okay.

00:25:40.020 --> 00:25:48.920
Last thing I want to, last extra is Brett Cannon wrote an article called Saying Thanks to Open Source Maintainers.

00:25:49.260 --> 00:25:51.700
I just want to shout out, this is a really good idea.

00:25:51.700 --> 00:25:54.760
Quickly, what are your ideas?

00:25:54.760 --> 00:25:57.280
First of all, just be nice to the maintainers.

00:25:57.280 --> 00:25:59.960
This is great advice.

00:25:59.960 --> 00:26:05.140
If you disagree with something, be polite, be nice.

00:26:05.140 --> 00:26:05.800
It's good.

00:26:05.800 --> 00:26:06.620
Great advice.

00:26:06.620 --> 00:26:07.520
Start with be nice.

00:26:07.520 --> 00:26:08.400
Be an advocate.

00:26:08.400 --> 00:26:12.240
You don't have to actually thank him directly, but you could advocate for the thing.

00:26:12.240 --> 00:26:17.260
So Brett's involvement with Bioproject.toml, he sees other people promoting it, makes him feel good.

00:26:17.260 --> 00:26:18.080
It's a good thing.

00:26:19.020 --> 00:26:25.000
Produce your own open source code because maybe some of the maintainer might use your stuff now.

00:26:25.000 --> 00:26:26.720
And then actually say thanks.

00:26:26.720 --> 00:26:29.080
Nothing wrong with saying thanks to people.

00:26:29.080 --> 00:26:34.260
And then there's financial support, which is good for some projects that have open source.

00:26:35.460 --> 00:26:37.520
You know, ways to help fund the maintainers.

00:26:37.520 --> 00:26:38.200
Those are good, too.

00:26:38.200 --> 00:26:39.520
But you don't have to fund them.

00:26:39.520 --> 00:26:41.160
You can just be nice to them.

00:26:41.160 --> 00:26:41.740
Say thanks.

00:26:41.740 --> 00:26:42.680
Advocate their thing.

00:26:42.680 --> 00:26:43.300
That's good.

00:26:44.000 --> 00:26:51.060
So in that end, I kind of always forget that Brett was involved with PyProject.toml.

00:26:51.060 --> 00:26:54.100
And we might not be using it as we are today without Brett.

00:26:54.100 --> 00:26:55.340
So thank you, Brett.

00:26:55.340 --> 00:26:56.820
I love PyProject.toml.

00:26:56.820 --> 00:27:00.040
I promote it and encourage everybody to use it.

00:27:00.040 --> 00:27:01.180
Awesome.

00:27:01.180 --> 00:27:01.640
Yeah.

00:27:01.640 --> 00:27:02.060
Thanks, Brett.

00:27:02.060 --> 00:27:02.760
Thanks, everyone.

00:27:02.760 --> 00:27:05.480
There's a lot of people I have to thank in this community for this kind of stuff.

00:27:05.480 --> 00:27:05.920
Yeah.

00:27:06.420 --> 00:27:07.120
Do you have any extras?

00:27:07.120 --> 00:27:08.520
I do.

00:27:08.520 --> 00:27:11.120
Let us check them out.

00:27:11.120 --> 00:27:12.700
I think only one extra.

00:27:12.700 --> 00:27:13.480
Extra.

00:27:13.480 --> 00:27:18.960
And that is last week I talked about the Shiny for Python Reactive Web Dashboard with Shiny,

00:27:18.960 --> 00:27:21.060
that course over at Talk Python.

00:27:21.060 --> 00:27:23.080
I said it was going to be available soon.

00:27:23.080 --> 00:27:25.680
It is now available 100%.

00:27:25.680 --> 00:27:27.600
You can go sign up for it and take that course.

00:27:27.600 --> 00:27:29.940
The course is completely free.

00:27:29.940 --> 00:27:31.080
No strings attached.

00:27:31.080 --> 00:27:36.280
So just click the link and take the course if you want to learn about building interactive dashboards.

00:27:36.380 --> 00:27:40.740
A little bit actually like the Solara stuff, but more full-featured, I suppose.

00:27:40.740 --> 00:27:44.480
And a little more packaged, a little more like Streamlit in that sense.

00:27:44.480 --> 00:27:51.780
And then also I talked about working with PyCharm to get people six months of PyCharm Pro for free,

00:27:51.780 --> 00:27:55.020
as long as you don't already have an account that would have to renew.

00:27:55.020 --> 00:28:00.560
With this course, you could just go to your account page after signing up for this and get that as well.

00:28:00.560 --> 00:28:03.360
So two extras on one tab.

00:28:03.360 --> 00:28:03.900
How about that?

00:28:03.900 --> 00:28:04.520
Nice.

00:28:04.520 --> 00:28:04.980
Yeah.

00:28:04.980 --> 00:28:05.620
All right.

00:28:05.620 --> 00:28:06.080
Brian.

00:28:06.340 --> 00:28:11.240
I need you to put yourself in like a calm and centered place for what is coming next.

00:28:11.240 --> 00:28:11.560
Okay?

00:28:11.560 --> 00:28:12.080
Are you ready?

00:28:12.080 --> 00:28:15.880
This has been recommended to us.

00:28:15.880 --> 00:28:16.480
Oh, my gosh.

00:28:16.480 --> 00:28:17.120
Who sent it in?

00:28:17.120 --> 00:28:18.460
I'm so sorry if I don't have the name here.

00:28:18.460 --> 00:28:19.340
I don't.

00:28:19.340 --> 00:28:21.720
Cohen, I believe it was.

00:28:21.720 --> 00:28:23.820
If I got it wrong, I'll correct it next time.

00:28:23.820 --> 00:28:26.780
This is the Tao of Programming.

00:28:26.880 --> 00:28:27.420
This is a big, big book.

00:28:27.420 --> 00:28:31.920
This is a big, long book here that covers many things.

00:28:31.920 --> 00:28:34.680
But I will, because we may come back to this, right?

00:28:34.680 --> 00:28:34.920
Okay.

00:28:34.920 --> 00:28:39.780
But I want to start with book one, The Silent Void, and just read you a few bits of it.

00:28:39.780 --> 00:28:46.840
And if you visit this webpage, folks, this is best viewed in Netscape Navigator 4.0 or older.

00:28:47.700 --> 00:28:57.840
Because it's got like the digital noise background and all sorts of like, whoever thought like this arts and craft paper was the proper background for reading.

00:28:57.840 --> 00:28:58.740
But here we are.

00:28:59.240 --> 00:29:00.540
Oh, and it also has a frame.

00:29:00.540 --> 00:29:01.940
There's a frame inside of it.

00:29:01.940 --> 00:29:03.500
So it's just missing the blink tag.

00:29:03.500 --> 00:29:04.660
Nonetheless, here we go.

00:29:04.660 --> 00:29:06.800
Here is the introduction for the chapter.

00:29:06.800 --> 00:29:09.200
Thus spake the master programmer.

00:29:09.200 --> 00:29:13.820
When you have learned to snatch the error code from the trap frame, it will be your time.

00:29:13.820 --> 00:29:15.300
It will be time for you to leave.

00:29:15.300 --> 00:29:18.060
So let me just read you a couple little sections from this.

00:29:18.060 --> 00:29:19.340
1.1.

00:29:19.340 --> 00:29:21.420
Something mysterious is formed.

00:29:21.420 --> 00:29:22.940
Born in the silent void.

00:29:22.940 --> 00:29:28.100
Waiting alone and unmoving, it is at once still and yet in constant motion.

00:29:28.400 --> 00:29:29.940
It is the source of all programs.

00:29:29.940 --> 00:29:31.420
I do not know its name.

00:29:31.420 --> 00:29:33.400
So I will call it the Tau of programming.

00:29:33.400 --> 00:29:36.140
If the Tau is great, the operating system is great.

00:29:36.140 --> 00:29:39.560
If the operating system is great, the compiler is great.

00:29:39.560 --> 00:29:42.960
If the compiler is great, then the application is great.

00:29:42.960 --> 00:29:45.480
The user is pleased and there is harmony in the world.

00:29:45.480 --> 00:29:49.260
The Tau of programming flows far and returns on the wind of morning.

00:29:49.260 --> 00:29:50.620
Oh dear.

00:29:50.620 --> 00:29:53.240
I think it's a little easy.

00:29:53.240 --> 00:29:55.800
This one's good, Ali.

00:29:55.800 --> 00:29:56.920
This is one too.

00:29:56.920 --> 00:29:57.640
This is the last one.

00:29:57.880 --> 00:29:59.920
The Tau gave birth to machine language.

00:29:59.920 --> 00:30:02.180
Machine language gave birth to the assembler.

00:30:02.180 --> 00:30:04.380
The assembler gave birth to the compiler.

00:30:04.380 --> 00:30:05.940
Now there are 10,000 languages.

00:30:05.940 --> 00:30:08.680
Each language has its purpose, however humble.

00:30:08.680 --> 00:30:11.900
Each language expresses the yin and the yang of software.

00:30:11.900 --> 00:30:14.420
Each language has its place within the Tau.

00:30:14.420 --> 00:30:16.880
But do not program in Cobalt if you can avoid it.

00:30:16.880 --> 00:30:20.460
And Fortran and Burl.

00:30:20.460 --> 00:30:20.640
Exactly.

00:30:20.640 --> 00:30:22.860
Anyway, this goes on and on.

00:30:22.860 --> 00:30:24.220
There's books of this stuff.

00:30:24.220 --> 00:30:25.160
People check it out.

00:30:25.160 --> 00:30:25.480
It's fun.

00:30:25.480 --> 00:30:26.200
Nine books.

00:30:27.060 --> 00:30:27.540
Exactly.

00:30:27.540 --> 00:30:29.240
Dear.

00:30:29.240 --> 00:30:33.480
Well, that's the joke for today.

00:30:33.480 --> 00:30:34.280
If you will.

00:30:34.280 --> 00:30:36.140
It's the entertainment segment, Liz.

00:30:36.140 --> 00:30:36.900
I'm not sure it's a joke.

00:30:36.900 --> 00:30:37.960
Yeah.

00:30:37.960 --> 00:30:39.000
No, it's good.

00:30:39.000 --> 00:30:39.760
I like it.

00:30:39.760 --> 00:30:42.140
It's the meditation section, Brian.

00:30:42.140 --> 00:30:44.020
All right.

00:30:44.520 --> 00:30:51.860
So with that, I'd like to encourage everyone out there to send us good programming jokes because we're running dry.

00:30:51.860 --> 00:30:54.880
No, that was good.

00:30:54.880 --> 00:30:59.780
But also, yeah, I always love good programming jokes and dad jokes all together.

00:30:59.780 --> 00:31:00.620
So keep them coming.

00:31:00.620 --> 00:31:01.680
Yeah, they're always good.

00:31:01.680 --> 00:31:05.040
As always, really enjoyed talking with you.

00:31:05.040 --> 00:31:07.340
Enjoy talking with everybody in the community.

00:31:08.140 --> 00:31:11.060
And yeah, keep on going and having fun.