WEBVTT

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

00:00:04.660 --> 00:00:11.280
This is episode 180, I can't believe it, recorded April 29th, 2020. It's almost Mayday.

00:00:11.280 --> 00:00:13.160
I am Brian Okken.

00:00:13.160 --> 00:00:14.120
And I'm Michael Kennedy.

00:00:14.120 --> 00:00:19.080
And this episode is brought to you by DigitalOcean, and we'll talk more about them a little later.

00:00:19.080 --> 00:00:27.920
Well, I have some very timely news, because not very long ago, a couple days ago, Ubuntu 20.04 is out.

00:00:27.920 --> 00:00:29.360
What?

00:00:29.360 --> 00:00:29.740
That's cool, right?

00:00:29.880 --> 00:00:31.040
Yeah, the new Ubuntu.

00:00:31.040 --> 00:00:33.260
And it's, why is this big news?

00:00:33.260 --> 00:00:36.480
Well, there's a lot of releases of Ubuntu and whatnot.

00:00:36.480 --> 00:00:42.940
But this is the first new LTS long-term support version in two years.

00:00:42.940 --> 00:00:49.280
So basically, this is the first real production-grade version of Ubuntu that's been out in two years.

00:00:49.280 --> 00:00:50.480
So that's a big deal, I think.

00:00:50.480 --> 00:00:51.520
Oh, yeah, really big deal.

00:00:51.520 --> 00:00:54.260
And it's got something special in it.

00:00:54.260 --> 00:00:55.000
It does.

00:00:55.000 --> 00:00:57.440
It hates legacy Python, but it loves modern Python.

00:00:58.220 --> 00:01:05.380
So one of the things that's bugged me about 1804, which is what I've been using for production, is it was stuck on 3.6.

00:01:05.380 --> 00:01:08.340
I mean, imagine April 2018.

00:01:08.760 --> 00:01:09.920
It's using Python 3.6.

00:01:09.920 --> 00:01:10.740
It didn't change.

00:01:10.740 --> 00:01:13.080
Well, what's the current version now?

00:01:13.080 --> 00:01:14.660
Well, that's Python 3.8.

00:01:14.660 --> 00:01:18.720
Sadly, 3.9 is going to be out really soon.

00:01:18.720 --> 00:01:19.980
And this is 3.8.

00:01:19.980 --> 00:01:22.240
But nonetheless, hey, 3.8 is awesome.

00:01:22.400 --> 00:01:25.260
It has a bunch of cool new features that we can use.

00:01:25.260 --> 00:01:27.400
And yeah, it comes included.

00:01:27.400 --> 00:01:29.420
I don't even think you have to pip install Python.

00:01:29.560 --> 00:01:30.880
I think 3.8 is already there.

00:01:30.880 --> 00:01:31.640
That's really cool.

00:01:31.640 --> 00:01:31.880
Yeah.

00:01:31.880 --> 00:01:37.580
And to get legacy Python, you can get it, but you have to go like apt install it explicitly to say, no, no, I want the old one.

00:01:37.580 --> 00:01:37.840
Yeah.

00:01:37.840 --> 00:01:39.140
Python 3.8.

00:01:39.140 --> 00:01:40.040
Automatic.

00:01:40.040 --> 00:01:41.120
It is now.

00:01:41.120 --> 00:01:41.640
f-strings everywhere.

00:01:41.640 --> 00:01:42.640
That's right.

00:01:42.720 --> 00:01:47.600
Like, it's time to hit all your code with flint and auto F-string all the things.

00:01:47.600 --> 00:01:51.820
So I upgraded all of the servers for Python bytes.

00:01:51.820 --> 00:01:53.820
The servers are pretty small and simple.

00:01:53.820 --> 00:01:57.240
But if you look at all the stuff that I'm running, there's actually a ton of servers.

00:01:57.240 --> 00:02:02.220
And I actually talked about that with Dan Bader on Talk Python episode 215.

00:02:02.220 --> 00:02:07.240
So people really want to look at what we're doing, what I'm doing here, what we're doing for Python bytes.

00:02:07.240 --> 00:02:09.380
In terms of infrastructure, they could do that.

00:02:09.420 --> 00:02:12.880
But upgraded a bunch of servers to 20.04.

00:02:12.880 --> 00:02:15.820
There's a bunch of stuff that kind of built up cruft.

00:02:15.820 --> 00:02:17.180
And I'm like, oh, we could do this way better.

00:02:17.180 --> 00:02:18.960
Redid all that stuff over the weekend.

00:02:18.960 --> 00:02:24.420
And so now everything's on the shiny new versions of Python 3.8 and Ubuntu 20.04.

00:02:24.420 --> 00:02:25.640
And it went really well for me.

00:02:25.640 --> 00:02:26.780
So that's great.

00:02:26.780 --> 00:02:27.180
Yeah.

00:02:27.180 --> 00:02:36.960
And the kernel has been upgraded to 5.4, which adds support for WireGuard, VPNs, better support for like Raspberry Pis and Intel and AMD hardware.

00:02:36.960 --> 00:02:38.860
New version of GNOME.

00:02:39.180 --> 00:02:43.820
You can install the desktop on top of the ZFS file system if you care about that.

00:02:43.820 --> 00:02:46.820
And you talked about DigitalOcean at the top.

00:02:46.820 --> 00:02:49.980
You can go to DigitalOcean right now and just check off.

00:02:49.980 --> 00:02:52.580
I want a new 20.04 droplet.

00:02:52.580 --> 00:02:53.160
Boom.

00:02:53.160 --> 00:02:53.720
Off it goes.

00:02:53.720 --> 00:02:54.420
That's how I got ours.

00:02:54.420 --> 00:02:55.260
Oh, that's great.

00:02:55.260 --> 00:02:55.980
Nice.

00:02:55.980 --> 00:02:56.580
Yeah.

00:02:56.580 --> 00:02:59.580
And actually, we've already had the kernel upgraded.

00:02:59.580 --> 00:03:02.400
The 5.4 kernel upgraded to like a new version.

00:03:02.400 --> 00:03:03.960
I just had to like apply some patches.

00:03:03.960 --> 00:03:06.120
So I guess it's pretty active.

00:03:06.120 --> 00:03:06.920
But here you go.

00:03:07.020 --> 00:03:09.120
So yeah, different topic.

00:03:09.120 --> 00:03:13.380
But for our servers, you have to like pay attention to kernel upgrades and stuff?

00:03:13.380 --> 00:03:13.640
Yeah.

00:03:13.800 --> 00:03:14.460
Apparently, yeah.

00:03:14.460 --> 00:03:17.120
They're not like on a platform as a service type of thing.

00:03:17.120 --> 00:03:17.840
It's not a big deal.

00:03:17.840 --> 00:03:20.280
It's pretty regularly like once a month or whatever.

00:03:20.280 --> 00:03:24.400
I'm usually logged in to one of them every couple of days doing something.

00:03:24.400 --> 00:03:27.080
And it'll say, oh, like either it's already applied.

00:03:27.080 --> 00:03:27.960
It says you got a reboot.

00:03:27.960 --> 00:03:30.760
It'll be like obvious that there's an update when you log in.

00:03:30.900 --> 00:03:34.660
And then I'm like, oh, I should just run that thing that upgrades all of them.

00:03:34.660 --> 00:03:35.340
Okay.

00:03:35.340 --> 00:03:36.620
Once I notice it.

00:03:36.620 --> 00:03:36.820
Yeah.

00:03:36.820 --> 00:03:37.680
So pretty much.

00:03:37.680 --> 00:03:37.880
Yeah.

00:03:37.880 --> 00:03:38.200
Okay.

00:03:38.200 --> 00:03:38.620
Neat.

00:03:38.620 --> 00:03:38.820
Yeah.

00:03:38.820 --> 00:03:39.140
Okay.

00:03:39.140 --> 00:03:40.800
Well, I'm going to switch hats.

00:03:40.800 --> 00:03:44.060
So I want to talk about warnings.

00:03:44.060 --> 00:03:45.900
So warning, I'm going to switch a hat.

00:03:45.900 --> 00:03:50.600
And so Reuven Lerner is a friend of the show and great guy, teaches Python.

00:03:50.600 --> 00:03:53.640
And we wrote an article called Working with Warnings in Python.

00:03:53.640 --> 00:03:57.480
And I like this because I don't think we've talked about warnings much.

00:03:57.480 --> 00:03:58.780
No, not much at all, actually.

00:03:58.780 --> 00:04:03.580
It's a good introduction, but he talks about exceptions and the class hierarchy and printouts

00:04:03.580 --> 00:04:03.980
and stuff.

00:04:03.980 --> 00:04:08.440
But if you want to like, if something goes wrong, you kind of want, you've got options

00:04:08.440 --> 00:04:12.780
of like printing out to the user or throwing an exception, but you also have warnings.

00:04:12.780 --> 00:04:15.260
And how should you treat those?

00:04:15.260 --> 00:04:16.980
And I love what he wrote.

00:04:16.980 --> 00:04:21.800
He said, most of the time, warnings are aimed at developers rather than users.

00:04:22.360 --> 00:04:25.740
Warnings in Python are sort of like the service needed light on a car.

00:04:25.740 --> 00:04:30.920
The user might know that something is wrong, but only a qualified repair person will know

00:04:30.920 --> 00:04:31.460
what to do.

00:04:31.460 --> 00:04:35.100
Developers should avoid showing warnings to end users.

00:04:35.100 --> 00:04:40.280
But one of the things that the warning system is used for is deprecation warnings.

00:04:40.280 --> 00:04:44.520
A lot of projects do this where they kind of want to get rid of a feature so they can

00:04:44.520 --> 00:04:49.480
refactor some stuff and or just doesn't fit in the API very well.

00:04:49.940 --> 00:04:54.620
So they'll deprecate it and they'll issue a deprecation warning when somebody uses it.

00:04:54.620 --> 00:04:55.320
So it's an alert.

00:04:55.320 --> 00:04:58.500
It doesn't stop working, but it alerts people to that.

00:04:58.500 --> 00:04:59.120
There's a warning.

00:04:59.120 --> 00:05:05.100
One of the things I love about warnings is by default, pytest turns on warnings.

00:05:05.100 --> 00:05:10.320
And so you can see those and you can also make them make pytest so that it fails on warnings.

00:05:10.580 --> 00:05:15.340
So this is a good thing to pay attention to, but it doesn't stop your project.

00:05:15.340 --> 00:05:16.260
That's cool.

00:05:16.260 --> 00:05:21.060
I didn't know you can make pytest, like observe and use the warnings as an error.

00:05:21.060 --> 00:05:21.460
Yeah.

00:05:21.460 --> 00:05:23.680
The warning system gives you a whole bunch of stuff.

00:05:23.680 --> 00:05:28.620
Python's warning system, it treats warnings as separate types of output so that we don't

00:05:28.620 --> 00:05:31.480
confuse them with either exceptions or printed texts.

00:05:31.840 --> 00:05:34.760
It lets us indicate what kind of warning we're sending the user.

00:05:34.760 --> 00:05:35.860
So we have different types.

00:05:35.860 --> 00:05:37.460
It's like the exception hierarchy.

00:05:37.460 --> 00:05:38.280
You can have a warning.

00:05:38.280 --> 00:05:39.340
There's a warning hierarchy.

00:05:39.340 --> 00:05:45.240
You can create your own and you can filter on them so that you can screen out stuff that

00:05:45.240 --> 00:05:48.140
you don't care about, selectively fix things.

00:05:48.140 --> 00:05:50.440
Anyway, it's a very powerful system.

00:05:50.440 --> 00:05:52.140
People should use it when they need it.

00:05:52.500 --> 00:05:57.780
The article goes on to give specifics on the syntax of how to use them, how to create

00:05:57.780 --> 00:06:00.260
custom warnings, and how to filter on them.

00:06:00.260 --> 00:06:01.540
And it's a good intro.

00:06:01.540 --> 00:06:05.240
Yeah, this looks super interesting and like something I should be paying more attention to

00:06:05.240 --> 00:06:06.440
than I have so far.

00:06:06.440 --> 00:06:07.960
Is this something I'm not really using?

00:06:07.960 --> 00:06:09.880
I'm more a consumer of warnings.

00:06:09.880 --> 00:06:13.800
I'm like, oh, that library, it started issuing warnings about something.

00:06:13.800 --> 00:06:19.720
And sometimes it's really frustrating because it's like the library being used by the library

00:06:19.720 --> 00:06:22.960
I'm actually trying to use is doing something wrong.

00:06:22.960 --> 00:06:25.620
It says, well, this is going to be deprecated and now you've got to do this.

00:06:25.620 --> 00:06:27.340
I'm like, well, but I'm not doing that.

00:06:27.340 --> 00:06:28.360
I don't want to see this.

00:06:28.360 --> 00:06:32.060
But nonetheless, it looks like way simpler than maybe.

00:06:32.060 --> 00:06:32.920
I just haven't looked at it.

00:06:32.920 --> 00:06:33.480
It looks great.

00:06:33.480 --> 00:06:34.520
So I should use this more.

00:06:34.520 --> 00:06:40.740
One of the cool use cases that I heard recently is using pytest warnings or pytest's knowledge

00:06:40.740 --> 00:06:45.640
of warnings and testing your system when you're upgrading Python so that you can say,

00:06:45.640 --> 00:06:48.800
oh, when we're, because Python will deprecate things too.

00:06:49.360 --> 00:06:55.120
And then you can have a heads up that you need to start fixing your code because it'll

00:06:55.120 --> 00:06:56.320
pinpoint you exactly.

00:06:56.320 --> 00:06:57.660
It's kind of like the exception system.

00:06:57.660 --> 00:06:59.140
It tells you exactly where it's coming from.

00:06:59.140 --> 00:07:01.120
So yeah, that is really nice.

00:07:01.120 --> 00:07:02.960
Do you want to know something else that's nice?

00:07:02.960 --> 00:07:03.580
DigitalOcean.

00:07:03.580 --> 00:07:05.000
DigitalOcean is very nice.

00:07:05.000 --> 00:07:14.160
And DigitalOcean just launched their virtual private cloud or VPC system and new trust platform.

00:07:14.160 --> 00:07:15.420
Ooh, a trust platform.

00:07:15.660 --> 00:07:19.960
Together, these make it easier to architect and run serious business applications with

00:07:19.960 --> 00:07:22.280
even stronger security and confidence.

00:07:22.280 --> 00:07:29.220
VPC allows you to create multiple private networks for your account or your team instead of having

00:07:29.220 --> 00:07:30.380
just one private network.

00:07:30.380 --> 00:07:37.600
DigitalOcean can auto-generate your private networks, IP address range, or you can specify

00:07:37.600 --> 00:07:38.900
your own IPs.

00:07:39.140 --> 00:07:44.240
You can now configure droplets to have, to behave as internet gateways.

00:07:44.240 --> 00:07:44.880
That's cool.

00:07:44.880 --> 00:07:45.160
Yeah.

00:07:45.160 --> 00:07:46.380
It's like your own little baby internet.

00:07:46.380 --> 00:07:47.040
Yeah.

00:07:47.040 --> 00:07:47.580
That's neat.

00:07:47.580 --> 00:07:53.160
And a trust platform is a new microsite that provides one place to get all your security

00:07:53.160 --> 00:07:58.640
and privacy questions answered and download our available security certifications.

00:07:59.280 --> 00:08:01.600
DigitalOcean is your trusted partner in the cloud.

00:08:01.600 --> 00:08:08.240
Visit pythonbytes.fm/DigitalOcean to get $100 credit for new users to build something

00:08:08.240 --> 00:08:08.540
awesome.

00:08:08.540 --> 00:08:08.800
Yeah.

00:08:08.800 --> 00:08:09.500
We love it.

00:08:09.500 --> 00:08:14.160
Like I just said at the outset, put Ubuntu 20.04 on there, and it's been working great

00:08:14.160 --> 00:08:14.760
for so many years.

00:08:14.760 --> 00:08:20.800
Now, one thing that I ran across, there's a few little libraries that are so simple, and

00:08:20.800 --> 00:08:24.720
yet when you come across them, you're like, oh yes, this is so cool.

00:08:24.720 --> 00:08:31.320
One of those that I go on and on about is unsync, how that unifies all the different APIs that

00:08:31.320 --> 00:08:37.840
do asynchronous programming, like asyncio, threaded stuff, multiprocessing stuff, and whatnot.

00:08:37.840 --> 00:08:38.220
Right?

00:08:38.220 --> 00:08:41.480
So this is one I think that kind of is like that.

00:08:41.480 --> 00:08:46.720
It's not about unification, but it's about solving a problem in a way that's kind of transparent

00:08:46.720 --> 00:08:52.200
to the user, but is really, really awesome because it just adds some nice durability to

00:08:52.200 --> 00:08:52.640
your code.

00:08:52.640 --> 00:08:59.480
So there's different levels of like exception handling if you look at it, right?

00:08:59.480 --> 00:09:05.060
So if you look at code, there's probably like the beginner level that has no try except blocks

00:09:05.060 --> 00:09:06.000
anywhere in the code.

00:09:06.000 --> 00:09:08.220
It's just like, I don't know what you call it.

00:09:08.220 --> 00:09:09.560
Is that optimistic programming?

00:09:09.560 --> 00:09:11.700
Like I don't need to do error handling.

00:09:11.700 --> 00:09:12.380
It's going to be fine.

00:09:12.380 --> 00:09:13.160
Everything's fine.

00:09:13.160 --> 00:09:13.820
This is fine.

00:09:13.820 --> 00:09:15.320
That's one way.

00:09:15.740 --> 00:09:19.440
The next level would be to say, okay, I'm going to have some exception handling.

00:09:19.440 --> 00:09:24.420
I'm going to do a try, do a bunch of stuff, except handle the error, right?

00:09:24.420 --> 00:09:24.980
That's good.

00:09:24.980 --> 00:09:26.280
And maybe you're catching different errors.

00:09:26.280 --> 00:09:27.620
Like maybe that's another level.

00:09:27.620 --> 00:09:31.940
I don't know what the making of these levels up a little bit, but even if you are catching

00:09:31.940 --> 00:09:37.100
an error, something could have gone terribly, terribly wrong and corrupted your data along

00:09:37.100 --> 00:09:37.540
the way.

00:09:37.540 --> 00:09:42.680
So there's like durable error handling and there's, it isn't technically crashing at the moment

00:09:42.680 --> 00:09:43.700
error handling, right?

00:09:43.740 --> 00:09:48.040
So the durable error handling, I don't think a lot of people think about nearly as much.

00:09:48.040 --> 00:09:53.500
So simple example is what you would maybe use a transaction for in a database is like,

00:09:53.500 --> 00:09:56.320
I'm going to transfer money from this account to that account.

00:09:56.320 --> 00:09:59.920
But what happens if the transfer to the second account fails?

00:10:00.120 --> 00:10:03.240
I want to make sure I don't actually take the money from the first account, right?

00:10:03.240 --> 00:10:07.560
Or I want to write some piece of data to a file.

00:10:07.560 --> 00:10:11.040
So I'm going to open the file and I'm going to make sure there's a try accept.

00:10:11.040 --> 00:10:12.440
I'm going to put it in a width block.

00:10:12.440 --> 00:10:13.820
So the file pointer gets closed.

00:10:13.820 --> 00:10:14.740
Everything's going to be good.

00:10:14.740 --> 00:10:17.540
I'm going to make one change and another change.

00:10:17.540 --> 00:10:20.380
And then a third change, like write these three things to the file.

00:10:20.880 --> 00:10:23.960
What if the exception happens after the second line?

00:10:23.960 --> 00:10:25.700
You've half written to the file.

00:10:25.700 --> 00:10:26.960
Now what?

00:10:26.960 --> 00:10:27.380
I don't know.

00:10:27.380 --> 00:10:27.940
Wow.

00:10:27.940 --> 00:10:28.700
That's bad, right?

00:10:28.700 --> 00:10:29.220
Yeah.

00:10:29.220 --> 00:10:31.680
So there's all these ways in which, like you still have a try accept.

00:10:31.680 --> 00:10:32.460
You still catch it.

00:10:32.460 --> 00:10:33.500
You still close the file pointer.

00:10:33.500 --> 00:10:34.260
It doesn't matter.

00:10:34.260 --> 00:10:35.080
It's corrupted, right?

00:10:35.080 --> 00:10:40.020
So there's like this another level of error handling of like kind of treating memory and

00:10:40.020 --> 00:10:44.120
files and whatnot as transaction, transactional type things, right?

00:10:44.120 --> 00:10:47.080
If there's an error, they just go back the way they were.

00:10:47.080 --> 00:10:52.280
And so this thing that this long winded introduction is about is called safer.

00:10:52.280 --> 00:10:54.280
So a safer file writer.

00:10:54.280 --> 00:10:58.140
And it's this cool, simple little thing.

00:10:58.140 --> 00:11:04.800
Instead of saying with open file name as file pointer, you say with safer dot open.

00:11:04.800 --> 00:11:06.380
File name as file pointer.

00:11:06.380 --> 00:11:08.240
And then otherwise all your code is identical.

00:11:08.240 --> 00:11:08.720
Okay.

00:11:08.720 --> 00:11:09.100
Okay.

00:11:09.100 --> 00:11:10.640
Here's what it actually does.

00:11:10.640 --> 00:11:16.280
So as you write to the file pointer, it's writing to a temporary file behind the scenes.

00:11:16.280 --> 00:11:22.800
And then if, you know, when you exit a width block, the width block, the exit, the dunder exit

00:11:22.800 --> 00:11:26.200
takes whether or not there was an error on the way out the door.

00:11:26.200 --> 00:11:31.460
So, you know, as you exit the width block, did as, am I leaving because a crash or am I leaving

00:11:31.460 --> 00:11:34.520
because everything is cool and we're done?

00:11:35.060 --> 00:11:40.240
So it uses that information to either throw away the temp file or move the temp file over

00:11:40.240 --> 00:11:42.600
top the thing you thought you were writing on.

00:11:42.600 --> 00:11:42.860
Oh.

00:11:42.860 --> 00:11:43.540
Isn't that cool?

00:11:43.540 --> 00:11:48.320
So if there's an exception in your width block, it still closes up the file pointer and everything,

00:11:48.320 --> 00:11:49.560
but your data is unchanged.

00:11:49.560 --> 00:11:53.280
It's kind of like a transaction with a roll auto rollback for files.

00:11:53.280 --> 00:11:54.060
That's pretty cool.

00:11:54.060 --> 00:11:54.660
Isn't that cool?

00:11:54.660 --> 00:11:57.060
And it's like 28 lines of code that does that little bit.

00:11:57.060 --> 00:11:57.420
Yeah.

00:11:57.420 --> 00:11:59.980
Is it any idea what the time hit is?

00:11:59.980 --> 00:12:01.160
It's got to be a little bit, but.

00:12:01.160 --> 00:12:04.840
It's pretty small because it just uses shutil to replace the file.

00:12:04.840 --> 00:12:07.480
Like it writes to the file just as you would write to the file.

00:12:07.480 --> 00:12:08.520
Okay.

00:12:08.520 --> 00:12:12.300
And then at the very end, it goes, move this file to this destination and overwrite.

00:12:12.740 --> 00:12:17.620
So it's basically adds a file move, which in an SSD is like nothing, right?

00:12:17.620 --> 00:12:18.300
Okay.

00:12:18.300 --> 00:12:19.780
It doesn't matter how big it is.

00:12:19.780 --> 00:12:24.700
It probably just like updates the, I don't know, like the table in the drive, whatever

00:12:24.700 --> 00:12:25.100
that means.

00:12:25.100 --> 00:12:26.300
Yeah.

00:12:26.300 --> 00:12:26.900
Isn't that cool?

00:12:26.900 --> 00:12:27.700
That is very cool.

00:12:27.700 --> 00:12:28.280
I like it.

00:12:28.280 --> 00:12:28.560
Yeah.

00:12:28.560 --> 00:12:31.020
So it seems so easy to use.

00:12:31.020 --> 00:12:32.980
It looks like something that might be worth looking at.

00:12:32.980 --> 00:12:34.640
So I'm linking to a couple of things.

00:12:34.640 --> 00:12:36.920
I'm linking to an article that introduces this.

00:12:36.920 --> 00:12:41.440
And in the beginning, apparently there was like some edge case where something wasn't

00:12:41.440 --> 00:12:42.240
working quite right.

00:12:42.240 --> 00:12:48.340
If you passed like an integer representing a file handle or something funky like that, it

00:12:48.340 --> 00:12:48.860
didn't deal with that.

00:12:48.860 --> 00:12:49.000
Right.

00:12:49.000 --> 00:12:54.920
So there's a, another, like an updated article that doesn't have all the motivation, but then

00:12:54.920 --> 00:12:56.280
talks about this fix.

00:12:56.280 --> 00:12:58.600
And there's also a GitHub repo and you can just pip install it.

00:12:58.600 --> 00:12:59.520
So all those things are good.

00:12:59.520 --> 00:13:03.540
And the final in this section, I'm linking to the actual 28 lines of code.

00:13:03.820 --> 00:13:04.740
Do you have that open?

00:13:04.740 --> 00:13:05.480
I did.

00:13:05.480 --> 00:13:06.480
Click on that really quick.

00:13:06.480 --> 00:13:10.060
Cause I want to talk about a couple of really interesting patterns here.

00:13:10.060 --> 00:13:15.900
Like if you wanted to study 28 lines of code that took and brought together a bunch of interesting

00:13:15.900 --> 00:13:18.020
ideas, like, Whoa, this is pretty crazy.

00:13:18.020 --> 00:13:27.020
So it has a generator expression on an infinite sequence of numbers to find the temporary file,

00:13:27.020 --> 00:13:31.520
which is pretty interesting because it just says, I'm going to call it dot one, dot two,

00:13:31.520 --> 00:13:32.040
dot three.

00:13:32.100 --> 00:13:36.180
And in case those exist, we're just going to go through all of them until one doesn't.

00:13:36.180 --> 00:13:37.440
Isn't this crazy?

00:13:37.440 --> 00:13:39.160
So that's pretty fun.

00:13:39.160 --> 00:13:43.240
And that uses shutil to copy the file over, which is pretty cool.

00:13:43.240 --> 00:13:48.700
It uses yield to automatically return the inner file pointer.

00:13:48.700 --> 00:13:54.040
So when you say with thing as whatever, even though you said safer dot open, it actually

00:13:54.040 --> 00:13:59.020
yields out the underlying pointer file pointer that came from open.

00:13:59.020 --> 00:14:02.480
And there's just a bunch of different layers of, Oh, that's interesting.

00:14:02.480 --> 00:14:03.360
Oh, that's neat.

00:14:03.580 --> 00:14:03.800
Yeah.

00:14:03.800 --> 00:14:05.300
Anyway, I think this is really clever.

00:14:05.300 --> 00:14:08.000
And it seems like a cool little library.

00:14:08.500 --> 00:14:13.220
The reason I think it would probably be useful and not going to give you a big hit.

00:14:13.220 --> 00:14:14.360
It's like, this is literally it.

00:14:14.360 --> 00:14:15.580
You can see it's creating the temp file.

00:14:15.580 --> 00:14:21.060
It writes to the temp file and then it uses OS dot rename the temp file to the actual thing.

00:14:21.520 --> 00:14:25.720
So, you know, not a whole lot of magic going on, but really quite useful.

00:14:25.720 --> 00:14:27.200
I think not a lot of code either.

00:14:27.200 --> 00:14:27.480
Yeah.

00:14:27.480 --> 00:14:27.920
Just.

00:14:27.920 --> 00:14:28.360
Yeah.

00:14:28.360 --> 00:14:28.780
Isn't that crazy?

00:14:28.780 --> 00:14:29.080
Yeah.

00:14:29.080 --> 00:14:29.620
That's pretty cool.

00:14:29.620 --> 00:14:30.100
I love it.

00:14:30.100 --> 00:14:35.180
Useful gives you that sort of durable error handling, almost like transactional files.

00:14:35.180 --> 00:14:36.900
And yet super simple.

00:14:36.900 --> 00:14:37.500
Very good.

00:14:37.500 --> 00:14:39.740
Uses unit test as its test runner, though.

00:14:39.740 --> 00:14:40.460
Oh, my God.

00:14:40.460 --> 00:14:41.100
Well, all right.

00:14:41.100 --> 00:14:43.920
I retract all of my endorsements of this thing.

00:14:43.920 --> 00:14:47.500
All right.

00:14:47.500 --> 00:14:48.220
What's the next one?

00:14:48.220 --> 00:14:48.620
Okay.

00:14:48.620 --> 00:14:49.980
I'm on the other tab.

00:14:49.980 --> 00:14:51.500
So did I distract you?

00:14:51.620 --> 00:14:52.720
Oh, yeah, you did.

00:14:52.720 --> 00:14:54.620
And new article, new hat.

00:14:54.620 --> 00:14:56.040
So code spell.

00:14:56.040 --> 00:15:03.900
So I got this from Christian Klaus, that silly little project I play with on the side called

00:15:03.900 --> 00:15:04.320
Cards.

00:15:04.320 --> 00:15:10.500
I got a pull request against the project to add a pre-commit hook to run code spell.

00:15:10.500 --> 00:15:12.720
And I had never heard of code spell.

00:15:12.720 --> 00:15:16.120
So I was excited to have a new topic for the podcast.

00:15:16.120 --> 00:15:17.840
Also, just it's as neat.

00:15:18.340 --> 00:15:19.000
So code spell.

00:15:19.000 --> 00:15:22.440
What it does is it fixes common misspellings in text files.

00:15:22.440 --> 00:15:27.940
And specifically, it's designed primarily for checking misspelled words in source code.

00:15:27.940 --> 00:15:30.880
But it can be used as other files as well.

00:15:31.100 --> 00:15:43.920
When Christian applied this to the cards project, it noticed that in one of the documentation files I've got, one of the markdown files, I had spelled arguments with an extra U in the middle of it.

00:15:44.440 --> 00:15:55.400
And one of the problems with spelling, I mean, it's embarrassing to do and distracting to have spelling errors in your code or your comments or anything.

00:15:55.660 --> 00:16:06.620
It's hard to deal with because a lot of source code doesn't have, you can't just throw normal spell checkers at source code because it'll just, it'll warn you on your variable names and all sorts of stuff.

00:16:06.620 --> 00:16:06.920
Right.

00:16:06.920 --> 00:16:08.420
You can't drop it in grammarly.

00:16:08.420 --> 00:16:09.340
That's not going to go well.

00:16:09.340 --> 00:16:10.500
It's not going to work.

00:16:10.500 --> 00:16:21.060
But so I'm really excited to try this and to start using it because if it can work for just about anything, it might be able to work for, you know, non-Python programs too as well.

00:16:21.300 --> 00:16:21.640
Why not?

00:16:21.640 --> 00:16:23.280
So yeah, it's pretty cool.

00:16:23.280 --> 00:16:24.120
Yeah, all sorts of documentation.

00:16:24.120 --> 00:16:24.540
That's cool.

00:16:24.540 --> 00:16:25.940
It's an open source project.

00:16:25.940 --> 00:16:29.520
The GitHub repo has the entire dictionary so you can scan through it.

00:16:29.520 --> 00:16:35.060
And there's ways to ignore certain words if you're like, no, that's the correct spelling and it keeps doing stuff.

00:16:35.060 --> 00:16:36.460
You can ignore it.

00:16:36.460 --> 00:16:37.060
Nice.

00:16:37.060 --> 00:16:38.140
Well, that's a really good one.

00:16:38.140 --> 00:16:50.360
The most embarrassing misspelling I've ever done in code was I'd misspelled like a namespace or a class name or package name or something like that.

00:16:50.440 --> 00:16:52.980
I can't remember quite where it was.

00:16:52.980 --> 00:17:00.200
But it was on a project I had been working on for like a year and I misspelled it, but everything was autocomplete.

00:17:00.200 --> 00:17:00.720
And so I don't care.

00:17:00.720 --> 00:17:01.340
I'm like, da, da, da.

00:17:01.340 --> 00:17:02.900
It is just like, okay, autocomplete.

00:17:02.900 --> 00:17:04.820
I'm not even like ever typing that again.

00:17:04.820 --> 00:17:05.080
Right.

00:17:05.080 --> 00:17:05.620
Yeah.

00:17:05.620 --> 00:17:07.780
I guess I just wasn't paying attention to like that.

00:17:07.780 --> 00:17:08.980
I kind of suck at spelling.

00:17:08.980 --> 00:17:11.080
That was like an extra bad case.

00:17:11.680 --> 00:17:16.120
Some new person came on the team and said, dude, why is this misspelled all over the place?

00:17:16.120 --> 00:17:17.800
And I'm like, oh, we got to fix it.

00:17:17.800 --> 00:17:22.780
But it was like other applications depended on that library and they used the misspelling.

00:17:22.780 --> 00:17:28.660
It was so bad because it was like it had become pervasive throughout like all these different things.

00:17:28.720 --> 00:17:30.920
So like we may have to leave that misspelled.

00:17:30.920 --> 00:17:32.340
I think we eventually fixed it.

00:17:32.340 --> 00:17:36.040
But it was like it was quite a bit of work considering what it should have been.

00:17:36.040 --> 00:17:37.320
That's funny.

00:17:37.320 --> 00:17:38.440
That's awesome.

00:17:38.440 --> 00:17:45.020
Well, at least you didn't have like both of the spellings be valid symbols in your program and mean completely different things.

00:17:45.180 --> 00:17:45.580
That's true.

00:17:45.580 --> 00:17:47.780
Yeah.

00:17:47.780 --> 00:17:57.900
So one of the things that's awesome about this podcast is we'll say we'll find some random thing or maybe somebody will send it to us and we'll say, oh, did you even know that this was a thing?

00:17:57.900 --> 00:17:59.020
I had never heard of this.

00:17:59.020 --> 00:18:04.680
And then like five other people shoot us a message and say, yeah, and this variation or this other thing.

00:18:04.680 --> 00:18:05.240
And that's cool.

00:18:05.240 --> 00:18:06.600
But there's also X, Y and Z.

00:18:06.600 --> 00:18:06.800
Right.

00:18:06.800 --> 00:18:07.240
Isn't that awesome?

00:18:07.240 --> 00:18:07.960
Yeah.

00:18:07.960 --> 00:18:08.640
Yeah.

00:18:08.640 --> 00:18:10.140
I learned so much by doing this.

00:18:10.140 --> 00:18:10.740
Yes, I know.

00:18:10.740 --> 00:18:14.500
We just got to throw something we vaguely know about and like people will correct us.

00:18:14.500 --> 00:18:14.820
Yeah.

00:18:14.820 --> 00:18:15.120
Awesome.

00:18:15.820 --> 00:18:25.900
So, no, seriously, we talked about profilers and I talked about scaling, how it was really nice and fast and it did memory profiling and all that.

00:18:25.900 --> 00:18:31.980
Well, friend of the show, Anthony Shaw said, hey, since you're on this kick for profilers, have you heard about Austin?

00:18:31.980 --> 00:18:35.500
To me, Austin is either a guy's name or a town in Texas.

00:18:35.500 --> 00:18:37.220
I hadn't heard about Austin.

00:18:37.220 --> 00:18:37.520
Have you?

00:18:37.520 --> 00:18:38.940
I got a neighbor named Austin.

00:18:38.940 --> 00:18:39.560
Yeah.

00:18:39.560 --> 00:18:41.140
I don't think this is the same thing.

00:18:41.580 --> 00:18:54.360
So, this is like scaling is a frame stack sampler for CPython, meaning it doesn't have like this huge effect of once you run it on your code, it doesn't become 10 times slower as instrumenting.

00:18:54.360 --> 00:18:58.240
You know, it just asks like, hey, what are you up to really quickly?

00:18:58.240 --> 00:18:59.360
So, that's cool.

00:18:59.360 --> 00:19:00.500
It's nice and fast.

00:19:00.500 --> 00:19:02.080
It also is just pure C code.

00:19:02.080 --> 00:19:06.740
There's no real dependencies like other than like the C runtime, which is in all the operating systems.

00:19:07.140 --> 00:19:13.160
So, it looks at running Python code at intervals and then it dumps out whatever it finds, which is cool.

00:19:13.160 --> 00:19:20.360
It has a really simple output, but as you will learn, it has all these interesting ways to visualize that output.

00:19:20.360 --> 00:19:24.780
So, it's sort of base, it's atomic unit of output is a flame graph.

00:19:24.780 --> 00:19:31.840
So, flame graphs are like stacked up sort of things that are colorful and they also have information.

00:19:31.920 --> 00:19:34.080
So, like the color communicates information and the height.

00:19:34.080 --> 00:19:39.440
So, it's kind of like a graph with like color bars type of thing and it has the parts of code they're running.

00:19:39.440 --> 00:19:43.160
If you want to see what that is, just click on the link and it has it right there at the top.

00:19:43.160 --> 00:19:44.060
And that's cool.

00:19:44.060 --> 00:19:54.380
So, it puts that out, but you can build other tools to analyze that or you could even make like a little player application that replays the execution of your application in like slow motion.

00:19:54.580 --> 00:19:56.760
Like replays that flame graph over time.

00:19:56.760 --> 00:19:57.380
Oh, that's neat.

00:19:57.380 --> 00:19:57.880
Isn't that cool?

00:19:57.880 --> 00:19:58.180
Yeah.

00:19:58.180 --> 00:20:05.880
So, now is where it gets really fun because there's a couple of user interfaces on top of this like simple output that can be interpreted.

00:20:05.880 --> 00:20:11.000
So, the first one is called the TUI, the Terminal User Interface.

00:20:11.000 --> 00:20:13.220
Do you see this animated in our little show notes?

00:20:13.220 --> 00:20:13.920
And we'll be in there.

00:20:13.920 --> 00:20:14.200
It's nice.

00:20:14.200 --> 00:20:15.380
Yeah, it's really cool.

00:20:15.380 --> 00:20:15.920
Yeah.

00:20:15.980 --> 00:20:17.400
So, let me try to describe it.

00:20:17.400 --> 00:20:21.720
Like imagine you've opened, I don't know, Emacs or something like that.

00:20:21.720 --> 00:20:30.120
But the top part of it shows the process information, the CPU it's using, the memory it's using, how long it's been running.

00:20:30.120 --> 00:20:38.000
And then a graph, an active like interactive flowing graph across the top of like the performance analysis.

00:20:38.360 --> 00:20:45.820
And then it has something that's a little bit like top maybe, showing you like what it's currently running, how much time it's using.

00:20:45.820 --> 00:20:49.300
Is this time being spent on a sub function call?

00:20:49.300 --> 00:20:54.960
Like did I call a thing that called request that is talking to the network and that's why it's slow because we're waiting on the internet?

00:20:54.960 --> 00:20:59.560
Or is it actually computationally my stuff running in Python or whatever, right?

00:20:59.560 --> 00:21:00.480
So, what do you think?

00:21:00.480 --> 00:21:01.000
That's cool, huh?

00:21:01.000 --> 00:21:08.600
Yeah, that bottom part reminds me of the thing that you put the process explorer on Windows where you look at all your processes.

00:21:08.600 --> 00:21:09.520
Yeah, a little bit.

00:21:09.520 --> 00:21:10.280
Like task manager.

00:21:10.280 --> 00:21:13.440
But it's actually for like your functions instead of other processes.

00:21:13.440 --> 00:21:14.440
Yeah, yeah.

00:21:14.440 --> 00:21:15.360
It's nice.

00:21:15.360 --> 00:21:15.840
That's cool.

00:21:15.840 --> 00:21:18.980
So, that's the TUI, which is going to be a popular one.

00:21:18.980 --> 00:21:20.780
But you may also want to be on the web.

00:21:20.780 --> 00:21:24.780
So, there's WebAustin, which is another example of making this for the web.

00:21:24.780 --> 00:21:36.600
So, you basically can log into wherever you're running it, connect to it, and it has a D3 flame graph that's like animated of what your web app or whatever process you're watching on that remote system is up to.

00:21:36.600 --> 00:21:39.780
So, it's kind of the same thing, but like more visual, more graphical.

00:21:39.780 --> 00:21:42.680
Like the flame graph is there and whatnot.

00:21:42.680 --> 00:21:44.820
So, that's pretty cool.

00:21:44.820 --> 00:21:46.300
People can check that one out.

00:21:46.300 --> 00:21:48.100
You can even pause it and whatnot.

00:21:48.240 --> 00:21:55.020
Then finally, there's this other format called SpeedScope, which can be visualized in other tools.

00:21:55.020 --> 00:22:00.760
And you can convert Austin output into the SpeedScope JSON format.

00:22:00.760 --> 00:22:03.680
And there's a sample for that in the repo.

00:22:03.680 --> 00:22:09.760
If you go look at that, you can load it into the SpeedScope visualizer type of things and have another way to view the data.

00:22:09.760 --> 00:22:14.460
So, this is really nice because so many of these profilers are like, we collected all this information.

00:22:14.940 --> 00:22:17.180
How would you like it as a CSV?

00:22:17.180 --> 00:22:22.320
Or how would you like it as just like random columns in a terminal?

00:22:22.320 --> 00:22:25.460
And this is so much like, I would not like it that way.

00:22:25.460 --> 00:22:30.820
I really like the visualization because it's one thing to gather the information.

00:22:30.820 --> 00:22:33.400
It's another to go, oh, I see.

00:22:33.400 --> 00:22:35.920
Right there is actually where it's slow.

00:22:35.920 --> 00:22:40.560
And if it's just a dump of a bunch of numbers, I mean, yeah, you can like sort it and whatnot.

00:22:40.560 --> 00:22:44.740
And you can use cProfile with different sorting options and get it to mean stuff.

00:22:44.900 --> 00:22:45.680
It is not the same.

00:22:45.680 --> 00:22:47.040
It's like, aha, there's the picture.

00:22:47.040 --> 00:22:47.520
I see.

00:22:47.520 --> 00:22:48.440
It's red right there.

00:22:48.440 --> 00:22:49.080
And it's really tall.

00:22:49.080 --> 00:22:49.980
Let's go figure that out.

00:22:49.980 --> 00:22:50.220
Yeah.

00:22:50.220 --> 00:22:52.960
And the web one, the logo is awesome.

00:22:52.960 --> 00:22:53.740
It's good.

00:22:53.740 --> 00:22:55.120
It is really good.

00:22:55.120 --> 00:22:55.420
Yeah.

00:22:55.420 --> 00:22:56.860
It's like a 70s thing.

00:22:56.860 --> 00:22:58.440
It reminds me of Austin Powers.

00:22:58.440 --> 00:22:59.320
Yeah.

00:22:59.320 --> 00:23:00.420
A little bit, right?

00:23:00.420 --> 00:23:01.080
Yeah.

00:23:01.080 --> 00:23:01.380
Yeah.

00:23:01.380 --> 00:23:04.180
In a non-copyright infringing way.

00:23:04.180 --> 00:23:06.680
Anyway, that's it.

00:23:06.680 --> 00:23:09.860
If people are looking for a profiler, Austin looks pretty cool.

00:23:09.860 --> 00:23:10.880
Check it out.

00:23:10.880 --> 00:23:11.520
Definitely.

00:23:11.520 --> 00:23:13.440
It seems like it's definitely one of the contenders.

00:23:13.940 --> 00:23:14.820
Anthony for sending that in.

00:23:14.820 --> 00:23:15.980
I want to talk about numbers.

00:23:15.980 --> 00:23:17.640
Does this fit in the screen?

00:23:17.640 --> 00:23:17.980
Oh, yeah.

00:23:17.980 --> 00:23:20.740
You got your mathematician hat on now or your wizard hat.

00:23:20.740 --> 00:23:21.460
I can't decide.

00:23:21.460 --> 00:23:23.320
I got this from a man.

00:23:23.320 --> 00:23:24.880
He writes two great stuff.

00:23:24.880 --> 00:23:26.140
First name Mosh.

00:23:26.140 --> 00:23:27.400
Is the last name Zadka?

00:23:27.400 --> 00:23:27.900
Zadka?

00:23:27.900 --> 00:23:30.660
Mosh, you got to contact me and find out.

00:23:30.660 --> 00:23:31.900
Tell me how to pronounce your name.

00:23:32.560 --> 00:23:33.980
But numbers in Python.

00:23:33.980 --> 00:23:35.180
Really great article.

00:23:35.180 --> 00:23:37.860
In Python, you don't really have to think about numbers too much.

00:23:37.860 --> 00:23:38.880
They just sort of work.

00:23:38.880 --> 00:23:39.140
Yeah.

00:23:39.140 --> 00:23:41.160
But you do kind of need to think about them.

00:23:41.160 --> 00:23:45.960
And this article is a really good, quick tutorial about the different things that you need to know.

00:23:45.960 --> 00:23:48.920
Like integers, they turn into floats really easily.

00:23:48.920 --> 00:23:52.780
Like any time there's a division, it'll turn into a float.

00:23:52.940 --> 00:23:57.580
Right, which is unlike other languages, which are like truncating sort of things, right?

00:23:57.580 --> 00:24:00.960
That basically take the floor of whatever the result would be.

00:24:00.960 --> 00:24:01.340
Yeah.

00:24:01.340 --> 00:24:04.820
In earlier Python versions, 2.7 like that.

00:24:04.820 --> 00:24:05.140
Yeah.

00:24:05.140 --> 00:24:05.480
Yeah.

00:24:05.480 --> 00:24:06.780
Like truncated off.

00:24:06.780 --> 00:24:07.440
Right.

00:24:07.440 --> 00:24:11.000
If you want that old type, now you got to double divide, like the two slashes.

00:24:11.000 --> 00:24:11.540
Yeah.

00:24:11.540 --> 00:24:13.680
And I forget about the two slashes thing.

00:24:13.680 --> 00:24:13.880
Yeah.

00:24:13.880 --> 00:24:15.860
I never use the two slashes because that seems wrong.

00:24:15.860 --> 00:24:20.840
Anyway, so the implications are weird though.

00:24:20.840 --> 00:24:24.360
And the other thing, okay, so you got integers, they turn into floats if you divide them.

00:24:24.360 --> 00:24:27.560
You got floats, which are things with decimal points in them.

00:24:27.560 --> 00:24:30.040
They're not the only things with decimal points in them though.

00:24:30.040 --> 00:24:36.260
One of the things you learn early on in programming, but some people are new to programming or numbers,

00:24:36.260 --> 00:24:41.200
so it's a good thing to remember, is floats don't behave like floating point numbers in math.

00:24:41.200 --> 00:24:44.880
Like the subtraction and addition are not inverses.

00:24:44.880 --> 00:24:47.600
And addition is not associative always.

00:24:47.960 --> 00:24:51.160
And you can't multiply and then divide and get the same number.

00:24:51.160 --> 00:24:53.560
Those are weird things you should be aware of.

00:24:53.560 --> 00:25:02.020
The normal thing that I mostly need to remember is don't try to compare floating point numbers with the double equals.

00:25:02.020 --> 00:25:04.700
You have to use something like approximate or something.

00:25:04.860 --> 00:25:05.040
Yeah.

00:25:05.040 --> 00:25:07.180
That's the one that can really catch people out.

00:25:07.180 --> 00:25:13.300
I mean, okay, so I thought I was going to get 14 and I got 13.9999999978.

00:25:13.300 --> 00:25:14.520
Okay.

00:25:14.520 --> 00:25:16.220
Well, it's computers.

00:25:16.220 --> 00:25:19.660
We know that stuff's truncated, but it's really easy to go.

00:25:19.660 --> 00:25:25.020
If X equal equals some number I'm looking for and that never ever happens.

00:25:25.020 --> 00:25:25.360
Right.

00:25:25.420 --> 00:25:28.480
It looks right and it is so wrong.

00:25:28.480 --> 00:25:36.440
And I think just our training for so many years in theoretical mathematics means that it's hard to look at that and go, that's wrong.

00:25:36.440 --> 00:25:37.880
Yeah.

00:25:37.980 --> 00:25:46.780
Well, it's interesting that when you see it in numbers, you can, like, for instance, one of the examples is one plus two minus two minus one is zero.

00:25:46.780 --> 00:25:47.740
Obviously.

00:25:47.740 --> 00:25:48.500
Of course it is.

00:25:48.500 --> 00:25:50.500
If it's floating point numbers, though.

00:25:50.500 --> 00:25:53.180
So floats don't end up with zero.

00:25:53.180 --> 00:25:56.340
You end up with a very small number, but it's not zero.

00:25:56.340 --> 00:25:57.280
Okay.

00:25:57.280 --> 00:25:58.200
So floats are weird.

00:25:58.200 --> 00:25:58.800
Be careful.

00:25:58.800 --> 00:25:59.820
Fractions.

00:25:59.820 --> 00:26:02.060
So if you don't use floats, there's fractions.

00:26:02.060 --> 00:26:03.440
Python has built in fractions.

00:26:03.440 --> 00:26:06.040
I actually have never really used these.

00:26:06.040 --> 00:26:06.660
It's neat.

00:26:06.660 --> 00:26:07.140
They're there.

00:26:07.140 --> 00:26:07.680
They're there.

00:26:07.680 --> 00:26:09.020
I've never used them either.

00:26:09.020 --> 00:26:15.520
But yeah, there's like a class called fraction with a numerator and a denominator or takes another fraction or a floating point.

00:26:15.520 --> 00:26:16.300
Yes.

00:26:16.300 --> 00:26:17.100
Even takes a string.

00:26:17.100 --> 00:26:18.120
How about that?

00:26:18.120 --> 00:26:25.220
The warning in this article is they, fractions take a lot longer than you expect they would for algorithms.

00:26:25.220 --> 00:26:28.340
So you can represent things as fractions.

00:26:28.340 --> 00:26:29.820
It's cool that you can do that.

00:26:29.820 --> 00:26:37.680
Be very careful with any sort of algorithm because it can explode in memory and size and time and stuff like that.

00:26:37.680 --> 00:26:39.220
So probably use floating point.

00:26:39.220 --> 00:26:45.960
That doesn't surprise me because when I have to do like fraction algorithms, in my mind, it takes a lot longer too.

00:26:46.640 --> 00:26:47.200
Yeah.

00:26:47.200 --> 00:26:54.420
The last one that he talks about, and it's something that some people don't realize right away, is that decimals are built in.

00:26:54.420 --> 00:26:58.760
So there's a decimals library that it's probably not surprising.

00:26:58.760 --> 00:27:01.340
One of the reasons it's in there is for financial transactions.

00:27:01.340 --> 00:27:05.140
They're set up to be correct with precision and do the right thing.

00:27:05.440 --> 00:27:06.900
And so I'm really glad it's there.

00:27:06.900 --> 00:27:11.260
Otherwise, we'd have like competing decimal third-party libraries or something like that.

00:27:11.260 --> 00:27:11.900
And we probably do.

00:27:11.900 --> 00:27:13.820
But this one's built in.

00:27:13.820 --> 00:27:30.780
I'm glad the article was written, though, because something weird about decimals that I didn't know about was there's a global state variable called context that holds the precision that's being used for decimal division and stuff.

00:27:30.780 --> 00:27:35.000
It could be anywhere in your program that the precision gets changed.

00:27:35.000 --> 00:27:39.240
So the recommendation in this article is to use a local context.

00:27:39.240 --> 00:27:43.720
So you can do one of those blocks, context, what are those things called?

00:27:43.720 --> 00:27:45.360
Context manager.

00:27:45.360 --> 00:27:47.040
Context manager, yep.

00:27:47.040 --> 00:27:54.600
You can use the context manager, local context, to set a local context precision for your arithmetic.

00:27:54.600 --> 00:27:55.780
So that's good.

00:27:55.780 --> 00:27:58.200
That seems like that should be the required way.

00:27:58.340 --> 00:28:03.420
Because just setting it globally seems really, I don't know, it seems wrong.

00:28:03.420 --> 00:28:06.640
Because, you know, think of the race condition there.

00:28:06.640 --> 00:28:11.900
I was doing math, and then the precision got cut in half, and then it wasn't what I expected anymore.

00:28:11.900 --> 00:28:13.980
Yeah.

00:28:13.980 --> 00:28:17.020
Or, I don't know, maybe there should be a minimum precision.

00:28:17.020 --> 00:28:18.080
This is interesting, though.

00:28:18.080 --> 00:28:21.720
Like, I didn't realize that you could even change the precision of decimals.

00:28:21.960 --> 00:28:34.680
So, like, in the docs it says, unlike hardware-based binary floating point numbers, the decimal module has a user-alterable precision defaulting to 28 places, which can be as large as needed for a given problem.

00:28:34.680 --> 00:28:36.060
So, yeah, you can change it.

00:28:36.060 --> 00:28:47.940
The example in the Python document on the docs show, just globally changing it halfway through a calculation, which seems like a bad, let's kick them down the stairs instead of teaching them to hold on to the handrailing.

00:28:48.080 --> 00:28:53.380
But this is really cool, like, this local context, change it, you can set it really high.

00:28:53.380 --> 00:28:54.080
That's cool.

00:28:54.080 --> 00:28:57.740
I had no idea that you could actually change that to grow as you need it, which is cool.

00:28:57.740 --> 00:29:07.680
Yeah, I guess you could still use the global context as long as you, maybe this isn't safe, but as long as you always remember to set it before you do decimal arithmetic.

00:29:07.980 --> 00:29:09.560
It's safe as long as you're not doing threading.

00:29:09.560 --> 00:29:10.460
Oh, yeah.

00:29:10.460 --> 00:29:11.220
Okay.

00:29:11.220 --> 00:29:14.900
Yeah, because what if somebody, some other thread has the same idea and changes it?

00:29:14.900 --> 00:29:21.000
I think the idea is maybe, it seems to me like possibly it would be better if once set, it couldn't be set again.

00:29:21.000 --> 00:29:25.340
Like, you could set it at the beginning of your program, but it couldn't be altered and altered and altered.

00:29:25.340 --> 00:29:25.720
Yeah.

00:29:25.720 --> 00:29:32.800
Like, right, something along those lines, like, okay, we set it, we're done, it's an exception if you try to set it again to something else and so on.

00:29:32.860 --> 00:29:34.640
I mean, it probably is a convenience.

00:29:34.640 --> 00:29:37.160
Yeah, this is the whole world I didn't even know about.

00:29:37.160 --> 00:29:37.760
This is cool.

00:29:37.760 --> 00:29:43.580
Yeah, I would probably set up some sort of, like, hook or something to make sure that you're only setting it one place if you're doing that.

00:29:43.580 --> 00:29:44.200
Yeah.

00:29:44.200 --> 00:29:44.440
I don't know.

00:29:44.440 --> 00:29:45.720
Yeah, sounds good to me.

00:29:45.720 --> 00:29:46.780
Cool.

00:29:46.780 --> 00:29:51.940
Anyway, yeah, this is actually more interesting than I thought because, like, as usual, I've learned something, which is cool.

00:29:51.940 --> 00:29:57.820
Last thing on this, we're going to link to the standard library documentation for fractions and decimals because you may not have heard of them.

00:29:57.980 --> 00:30:05.060
And then a very old article that if you really care about floating point numbers, you should at least know this article exists.

00:30:05.060 --> 00:30:08.380
Although I don't think I've actually gotten through the whole thing ever.

00:30:08.380 --> 00:30:12.380
But it's what every computer scientist should know about floating point arithmetic.

00:30:12.380 --> 00:30:13.900
That's a good article.

00:30:13.900 --> 00:30:14.500
Yeah, cool.

00:30:14.500 --> 00:30:15.020
All right.

00:30:15.020 --> 00:30:17.360
Any extras for us today, Michael?

00:30:17.360 --> 00:30:18.580
You know, not too much.

00:30:18.580 --> 00:30:21.080
I don't have too much to share right now.

00:30:21.080 --> 00:30:21.880
Nothing personal.

00:30:21.880 --> 00:30:29.520
But I do want to say thank you to everyone who subscribed to the YouTube feed of this podcast because we're breaking every segment.

00:30:29.520 --> 00:30:30.820
We've just covered six things.

00:30:30.820 --> 00:30:32.880
We're breaking that into six different videos.

00:30:32.880 --> 00:30:35.880
And you can see us on video, which is kind of cool.

00:30:35.880 --> 00:30:39.120
A bunch of people are subscribing at pythonbytes.fm/YouTube.

00:30:39.120 --> 00:30:40.360
You all can check that out.

00:30:40.360 --> 00:30:43.520
And you will see that Brian has awesome hats for every segment.

00:30:43.520 --> 00:30:45.780
Well, at least this episode.

00:30:45.780 --> 00:30:46.860
This episode.

00:30:46.860 --> 00:30:48.560
Which, yeah, you got to wait.

00:30:48.560 --> 00:30:49.220
Yeah, for sure.

00:30:49.220 --> 00:30:49.860
This episode.

00:30:49.860 --> 00:30:52.100
So eventually, you'll get to see the hats.

00:30:52.100 --> 00:30:52.460
Okay.

00:30:52.460 --> 00:30:53.840
I'm glad we mentioned that.

00:30:53.840 --> 00:31:03.300
I wanted to mention also that Python 3.9.0 alpha 6 is the last alpha release before we go into betas, I believe.

00:31:03.300 --> 00:31:05.200
And it is available.

00:31:05.200 --> 00:31:10.920
And it has the peg parser that we talked with, I think, last week about a little bit.

00:31:10.920 --> 00:31:11.340
Yeah.

00:31:11.340 --> 00:31:11.500
Yeah.

00:31:11.500 --> 00:31:13.580
We was here and talked about that was really cool.

00:31:13.580 --> 00:31:14.600
The work he's been doing there.

00:31:14.600 --> 00:31:18.080
That's a big long-term upgrade, right?

00:31:18.080 --> 00:31:21.740
That's something that got written in the original version of Python.

00:31:21.740 --> 00:31:24.480
It was unchanged and obviously can be better, right?

00:31:24.480 --> 00:31:29.220
Basically, the syntax was limited by the parser and how much it looked ahead and stuff.

00:31:29.220 --> 00:31:35.740
And so this should open up the language for more complex concepts or make it easier to add concepts to it.

00:31:35.740 --> 00:31:35.920
Yeah.

00:31:36.020 --> 00:31:36.300
All right.

00:31:36.300 --> 00:31:38.120
So I see we have some competing jokes here.

00:31:38.120 --> 00:31:39.060
You want to go first?

00:31:39.060 --> 00:31:39.660
Yeah.

00:31:39.660 --> 00:31:42.480
I just put a call out on Twitter and said I need some more jokes.

00:31:42.480 --> 00:31:45.420
And boy, I got a whole bunch of great ones back.

00:31:45.420 --> 00:31:46.340
I'm going to pick one.

00:31:46.340 --> 00:31:47.640
This one's from James Zabel.

00:31:48.000 --> 00:31:55.060
If you put 1,000 monkeys at 1,000 computers, eventually one will write a Python program and the rest will write Perl.

00:31:55.060 --> 00:31:56.900
That's right.

00:31:56.900 --> 00:32:00.320
I think maybe like 950 of them will write Perl.

00:32:00.320 --> 00:32:03.860
A couple of them are just going to be writing regular expressions like all on their own.

00:32:03.860 --> 00:32:04.920
Yeah.

00:32:04.920 --> 00:32:05.920
That's true.

00:32:05.920 --> 00:32:07.280
All right.

00:32:07.300 --> 00:32:09.300
I have one that's maybe in a similar vein here.

00:32:09.300 --> 00:32:11.800
So, you know, like we talked about Austin.

00:32:11.800 --> 00:32:14.680
It has all these different user interfaces and it's very user friendly.

00:32:14.680 --> 00:32:19.060
Well, you could say that Unix is very user friendly as well.

00:32:19.060 --> 00:32:22.160
It's just very particular about who its friends are.

00:32:22.160 --> 00:32:25.020
Yeah.

00:32:25.020 --> 00:32:26.200
I got friends like that.

00:32:26.200 --> 00:32:26.560
Yeah.

00:32:26.560 --> 00:32:29.340
I got that one from the Pyjoke package.

00:32:29.340 --> 00:32:31.720
So pip install Pyjoke and you can have it too.

00:32:31.720 --> 00:32:32.060
Yeah.

00:32:32.060 --> 00:32:32.700
That's good.

00:32:32.700 --> 00:32:33.680
Yeah.

00:32:33.680 --> 00:32:34.100
Anyway.

00:32:34.100 --> 00:32:34.460
Cool.

00:32:34.460 --> 00:32:34.960
Thanks.

00:32:34.960 --> 00:32:35.380
All right.

00:32:35.380 --> 00:32:36.000
Fun as always.

00:32:36.840 --> 00:32:37.740
Great to be here with you.

00:32:37.740 --> 00:32:37.940
Bye.

00:32:37.940 --> 00:32:38.260
Bye.

00:32:38.260 --> 00:32:40.140
Thank you for listening to Python Bytes.

00:32:40.140 --> 00:32:42.600
Follow the show on Twitter at Python Bytes.

00:32:42.600 --> 00:32:45.640
That's Python Bytes as in B-Y-T-E-S.

00:32:45.640 --> 00:32:48.520
And get the full show notes at Python Bytes.fm.

00:32:48.520 --> 00:32:53.600
If you have a news item you want featured, just visit Python Bytes.fm and send it our way.

00:32:53.600 --> 00:32:55.640
We're always on the lookout for sharing something cool.

00:32:55.640 --> 00:32:58.820
This is Brian Okken and on behalf of myself and Michael Kennedy,

00:32:58.820 --> 00:33:02.120
thank you for listening and sharing this podcast with your friends and colleagues.

