WEBVTT

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

00:00:04.860 --> 00:00:10.680
This is episode 240, recorded July 1st, 2021, How Time Does Fly.

00:00:10.680 --> 00:00:11.800
I'm Michael Kennedy.

00:00:11.800 --> 00:00:12.940
And I'm Brian Okken.

00:00:12.940 --> 00:00:14.180
And I'm Chris Moffitt.

00:00:14.180 --> 00:00:16.420
Hey, Chris. Welcome to the show.

00:00:16.420 --> 00:00:18.080
Thank you. Great to be here.

00:00:18.080 --> 00:00:19.400
Yeah, it's great to have you here.

00:00:19.400 --> 00:00:28.140
We've had you talking about the missteps of Excel and how the Python data tools chain can make that better over on Talk Python a few times.

00:00:28.140 --> 00:00:30.040
This is your first time on Python Bytes, right?

00:00:30.040 --> 00:00:31.140
It is. Yes.

00:00:31.140 --> 00:00:32.840
Yeah. Exciting to have you here.

00:00:32.840 --> 00:00:33.720
Definitely. Definitely.

00:00:33.720 --> 00:00:35.840
But maybe you want to go ahead and kick us off.

00:00:35.840 --> 00:00:38.420
I want to talk about subclassing today.

00:00:38.420 --> 00:00:41.660
But Hinnick wrote an article called Subclassing in Python.

00:00:41.660 --> 00:00:46.640
And, you know, dealing with classes is just everywhere in Python.

00:00:46.640 --> 00:00:55.100
Even if you're not using classes, Python itself has all sorts of classes and objects that you're using all the time, whether you know it or not.

00:00:55.100 --> 00:01:05.020
But when you start getting into larger design, there is a question around, you know, composition versus inheritance and stuff.

00:01:05.020 --> 00:01:13.560
So I really like this article that Hinnick put together because I think people should think about the ramifications more.

00:01:14.000 --> 00:01:19.840
So the general gist is he prefers composition over inheritance and I do, too.

00:01:19.840 --> 00:01:34.340
And but then goes through if you have to do inheritance when sometimes you do in Python, for instance, the greatest the greatest example I know of is when you're having exception hierarchies.

00:01:34.340 --> 00:01:39.560
And it's really it's really easy to build up exception hierarchies in Python.

00:01:39.560 --> 00:01:45.100
And it's there's like nothing there is except for like the class definitions and their inheritance.

00:01:45.100 --> 00:01:47.060
And that's the easiest class you've ever created.

00:01:47.060 --> 00:01:48.800
Class exception name path.

00:01:48.800 --> 00:01:49.660
Yeah.

00:01:49.660 --> 00:01:52.440
And but it's useful to do that.

00:01:52.480 --> 00:02:05.040
But then if you want to go further, there's other there's other design patterns and stuff, especially from the C world, C++ world where people might be thinking, well, I want to do something similar in Python and stuff.

00:02:05.040 --> 00:02:09.640
And so this is this is actually kind of a really great article to discussion about it.

00:02:09.640 --> 00:02:10.320
It's pretty long.

00:02:10.320 --> 00:02:13.600
I don't want to summarize it too much, but I'll jump into the three types.

00:02:13.600 --> 00:02:19.780
So he talks about three types of subclassing that's often happens subclassing for code sharing.

00:02:19.780 --> 00:02:26.560
And the short answer is it's just people are trying to do the drive principle and try to share code.

00:02:26.560 --> 00:02:29.800
And it's just it ends up being a bad idea, essentially.

00:02:29.800 --> 00:02:32.220
And there's a bunch of references for it.

00:02:32.220 --> 00:02:37.960
And if you don't, I think if you don't believe me or him, read, read this article and read a bunch.

00:02:37.960 --> 00:02:41.180
He's got a whole bunch of linked articles to that discuss it.

00:02:41.180 --> 00:02:43.620
But but I kind of agree.

00:02:43.620 --> 00:02:51.380
The the second type is inherited in is abstract data types or interfaces in a lot of languages are called the interfaces.

00:02:51.380 --> 00:02:54.800
And this is kind of a neat use of it.

00:02:54.800 --> 00:02:56.240
And there's a bunch of things.

00:02:56.240 --> 00:03:00.740
But it's it's and I thought, OK, yeah, you definitely will use.

00:03:01.960 --> 00:03:05.720
It's a little bit of inheritance and composition for for data type stuff.

00:03:05.720 --> 00:03:19.980
But there's in his discussion, he talks about some of the cool things that Python has that allow you to to have these sort of hierarchies without actually doing subclassing.

00:03:19.980 --> 00:03:28.300
So there's there's some cool features of Python, like the protocol syntax that came in recently in in typing dot protocol.

00:03:28.300 --> 00:03:33.280
Yeah, protocols like formal duck typing, which is an odd thing to combine.

00:03:33.280 --> 00:03:33.700
But yes.

00:03:33.700 --> 00:03:34.220
Yeah.

00:03:34.220 --> 00:03:37.920
But it's it's kind of really cool how it's put together in Python.

00:03:37.920 --> 00:03:38.800
So I like that.

00:03:38.800 --> 00:03:41.520
And then lastly is a specialization.

00:03:41.520 --> 00:03:44.180
And that's where kind of the exception hierarchies come in.

00:03:44.180 --> 00:03:49.820
But also he's got a great discussion about structuring data classes that have common elements.

00:03:49.820 --> 00:03:53.340
And and I think that's an interesting discussion, too.

00:03:53.340 --> 00:03:56.340
And I I think I already said this.

00:03:56.340 --> 00:04:05.580
The summary really it's really hard to summarize this article other than it's good to think about your design, especially if you're going to try to bring subclassing into it.

00:04:05.760 --> 00:04:06.820
So let's do that.

00:04:06.820 --> 00:04:07.160
Yeah.

00:04:07.160 --> 00:04:07.440
Awesome.

00:04:07.440 --> 00:04:11.320
I haven't had a chance to dive into this article, but I do want to read it and explore it.

00:04:11.320 --> 00:04:17.160
You know, it touches on a couple of things like it touches on namespaces and modules, which I think is pretty interesting.

00:04:17.160 --> 00:04:25.860
So many people coming from C++, C#, Java, et cetera, like all these really strongly OOP, especially C# and Java, where everything has to be a class.

00:04:25.860 --> 00:04:31.000
They you'll see people creating classes just for things like static variables and so on.

00:04:31.000 --> 00:04:31.440
Right.

00:04:31.440 --> 00:04:32.520
Or static functions.

00:04:32.520 --> 00:04:35.080
If you just have a bunch of static functions, you know what works really well for that?

00:04:35.400 --> 00:04:36.980
A module that has functions in it.

00:04:36.980 --> 00:04:37.160
Right.

00:04:37.160 --> 00:04:38.380
That's the same thing.

00:04:38.380 --> 00:04:39.360
You import module.

00:04:39.360 --> 00:04:45.480
Then you say module dot function name is the same as from module import class, class dot static function name.

00:04:45.480 --> 00:04:45.660
Right.

00:04:45.660 --> 00:04:48.620
Like it's just a layer that doesn't really need to be there.

00:04:48.620 --> 00:04:51.060
So the article touches on that, which I think is neat.

00:04:51.060 --> 00:04:52.860
Like sometimes you just don't need those.

00:04:52.860 --> 00:04:56.740
And then also the composition over inheritance.

00:04:56.740 --> 00:05:04.580
I think composition over inheritance is a really important thing to think about, because so often people say, well, you can't use OOP because it's horrible in all these ways.

00:05:04.580 --> 00:05:07.380
And you end up with like a robotic duck that can't quack.

00:05:07.380 --> 00:05:07.560
Right.

00:05:07.600 --> 00:05:09.600
Like you end up with these weird situations.

00:05:09.600 --> 00:05:14.860
If you like derive too many things and you put a weird specialty on the end, you're like a duck is an animal.

00:05:14.860 --> 00:05:16.940
And then like, but it has wings.

00:05:16.940 --> 00:05:18.080
But wait, now it's a robot.

00:05:18.080 --> 00:05:19.200
Now, why does it eat water?

00:05:19.200 --> 00:05:20.540
You know, it's like what happened to it?

00:05:20.540 --> 00:05:20.700
Right.

00:05:20.960 --> 00:05:27.940
But the composition allows for you to keep things much more tight and small in the inheritance stack, but still put them together in meaningful ways.

00:05:27.940 --> 00:05:29.920
So anyway, yeah, I want to see more about this.

00:05:29.920 --> 00:05:30.520
This looks great.

00:05:30.520 --> 00:05:35.360
And I'm coming from a standpoint of I'm a C++ person as well.

00:05:35.360 --> 00:05:37.300
And I've done both extremes.

00:05:37.300 --> 00:05:45.200
I've like gone way down the inheritance hierarchy thing and had like seven deep in hierarchy, maybe not seven, but like five deep.

00:05:45.200 --> 00:05:47.320
And it gets to be a nightmare.

00:05:47.540 --> 00:05:52.880
So then I got went to the other direction and didn't do any inheritance at all in a design.

00:05:52.880 --> 00:05:54.940
But there's there's problems there, too.

00:05:54.940 --> 00:05:59.640
So thinking about it and doing it smartly is you just need to.

00:05:59.640 --> 00:05:59.860
Yeah.

00:05:59.860 --> 00:06:01.820
So it's often like salt.

00:06:01.820 --> 00:06:03.920
I could see it's really good when you have some.

00:06:03.920 --> 00:06:05.540
You try to go like salt.

00:06:05.540 --> 00:06:05.840
It's great.

00:06:05.840 --> 00:06:06.700
I'm going to have that for dinner.

00:06:06.700 --> 00:06:08.100
Like, no, you shouldn't do that.

00:06:08.100 --> 00:06:17.360
I think the other thing that's really important about this is depending on how long you've been working in Python, sometimes you kind of get stuck in a rut.

00:06:17.360 --> 00:06:19.200
And you're always doing the same thing.

00:06:19.200 --> 00:06:21.920
And the language has evolved and grown over time.

00:06:21.920 --> 00:06:31.560
And so I think articles like this kind of force you to take a step back and see if you're using all the new features in a way that maybe aren't idiomatic.

00:06:31.560 --> 00:06:33.780
Also, quick comment out there from the live stream.

00:06:33.780 --> 00:06:35.680
Paul says, first time watching the live stream.

00:06:35.680 --> 00:06:36.360
Hey, Paul.

00:06:36.360 --> 00:06:38.820
Weird seeing everyone when they say the intro.

00:06:38.820 --> 00:06:40.040
Indeed, it is kind of weird.

00:06:40.200 --> 00:06:42.880
But I want to highlight this one to say hi to Paul.

00:06:42.880 --> 00:06:43.500
Thanks for being here.

00:06:43.500 --> 00:06:47.660
But also, if you're listening, you're like, hey, I'd kind of like to see what's on the screen while you're all talking about this.

00:06:47.660 --> 00:06:48.860
You'll follow us on YouTube.

00:06:48.860 --> 00:06:51.800
There's like a live stream menu right on Pythonbytes.fm.

00:06:51.800 --> 00:06:53.760
So it's easy to sign up for that.

00:06:53.760 --> 00:07:00.680
And also, Sam out there in the live stream following up on that says, currently maintaining a library with a deep templated class and hierarchies.

00:07:00.680 --> 00:07:02.580
It's very hard to keep track of it all.

00:07:03.340 --> 00:07:04.580
Yeah, I hear you that.

00:07:04.580 --> 00:07:05.280
That's for sure.

00:07:05.280 --> 00:07:06.140
All right.

00:07:06.140 --> 00:07:08.640
Let's switch over to the next one.

00:07:08.640 --> 00:07:09.740
Now, I tried.

00:07:09.740 --> 00:07:11.460
I tried to resist this, Brian.

00:07:11.460 --> 00:07:12.780
I promise I did.

00:07:12.780 --> 00:07:16.940
But I've ended up with an extra extra with seven more extras.

00:07:16.940 --> 00:07:18.040
Hear all about it.

00:07:18.040 --> 00:07:21.700
And it just had to become a main item because otherwise we'd be here for hours.

00:07:21.700 --> 00:07:23.040
It's not the idea of the show.

00:07:23.040 --> 00:07:24.840
So we've got an extra extra.

00:07:24.840 --> 00:07:25.840
Hear all about it.

00:07:25.840 --> 00:07:26.940
Nine extras.

00:07:26.940 --> 00:07:28.200
Let's pull them up.

00:07:28.200 --> 00:07:29.180
Action number one.

00:07:29.180 --> 00:07:30.880
We've talked about Pyodide.

00:07:31.000 --> 00:07:34.920
I had a whole talk Python episode on Pyodide, which is an interesting thing.

00:07:34.920 --> 00:07:39.780
It is this project by Mozilla where you take Python and you run it in the browser.

00:07:39.780 --> 00:07:46.820
And then you take many of the data science packages like NumPy and Matplotlib and stuff and compile them into the browser.

00:07:46.820 --> 00:07:51.660
And then you basically have client side Python data science, which is really interesting.

00:07:51.660 --> 00:07:56.160
This project is being spun out as its own topic, as its own project.

00:07:56.160 --> 00:07:57.580
It's no longer under Mozilla.

00:07:57.580 --> 00:07:59.660
Usually that doesn't sound good to me.

00:07:59.740 --> 00:08:01.340
It kind of sounds like it's been orphaned.

00:08:01.340 --> 00:08:04.240
I have no idea what the status of Pyodide is.

00:08:04.240 --> 00:08:05.260
People can check that out.

00:08:05.260 --> 00:08:06.960
But it's no longer under Mozilla.

00:08:06.960 --> 00:08:09.380
It's its own separate thing, as they say.

00:08:09.380 --> 00:08:11.040
So it's cruising out there.

00:08:11.040 --> 00:08:13.420
And also, it didn't get compiled to JavaScript.

00:08:13.420 --> 00:08:17.360
It got compiled to WebAssembly, which is interesting because that's faster.

00:08:17.360 --> 00:08:17.900
All right.

00:08:17.900 --> 00:08:18.540
That's number one.

00:08:18.540 --> 00:08:23.360
Number two, I just, as in a couple hours ago, released a brand new course, Python powered chat

00:08:23.360 --> 00:08:25.300
apps with Wilio and SendGrid.

00:08:25.300 --> 00:08:29.760
So the idea is if you want to have some kind of chat bot, but a lot of that conversation

00:08:29.760 --> 00:08:34.860
has to involve your database and your data and verifying things.

00:08:34.860 --> 00:08:40.380
Like the app that we built here is a tech savvy bakery where you can order cakes by sending

00:08:40.380 --> 00:08:41.380
it a WhatsApp message.

00:08:41.380 --> 00:08:43.320
And then it'll say, hey, you want a cake?

00:08:43.320 --> 00:08:44.500
Well, here's the menu.

00:08:44.500 --> 00:08:46.700
And it actually gets the menu from our Flask app.

00:08:46.940 --> 00:08:48.560
And then they pick something off the menu.

00:08:48.560 --> 00:08:51.640
And once they pick all the details, they said like this.

00:08:51.640 --> 00:08:52.400
Okay, great.

00:08:52.400 --> 00:08:55.840
We send it back to our website and figure out how much that's going to cost.

00:08:55.840 --> 00:08:56.780
They order it.

00:08:56.780 --> 00:08:57.500
It goes back.

00:08:57.500 --> 00:09:02.060
We send them a, if once they accept it, they get like a customized pretty email.

00:09:02.060 --> 00:09:03.540
It goes back to the backend.

00:09:03.540 --> 00:09:04.560
The bakers bake it.

00:09:04.560 --> 00:09:06.200
It sends them another message to let them know.

00:09:06.200 --> 00:09:11.280
So if you want to build kind of like that workflow, if Wilio and SendGrid, check it out.

00:09:11.280 --> 00:09:12.360
This course is super fun.

00:09:12.360 --> 00:09:14.520
It's six hours and it's 100% free.

00:09:14.860 --> 00:09:16.680
So people can check that out.

00:09:16.680 --> 00:09:19.400
I think if you're trying to build that kind of thing, that'll be a lot of fun.

00:09:19.400 --> 00:09:20.880
So links in the show notes there.

00:09:20.880 --> 00:09:21.880
I had something.

00:09:21.880 --> 00:09:22.440
Yes.

00:09:22.440 --> 00:09:24.920
If I can't afford free, can I get a discount code?

00:09:24.920 --> 00:09:28.360
I will give anyone listening 50% off that.

00:09:28.360 --> 00:09:33.580
So I have this really cool tweet and Twitter is broken from what I can tell for everything

00:09:33.580 --> 00:09:34.660
that's not the homepage.

00:09:34.660 --> 00:09:37.200
So something went wrong, but let me describe it.

00:09:37.200 --> 00:09:42.440
So when you look at it in the show notes, you'll be able to see there's a really cool tweet

00:09:42.440 --> 00:09:45.620
from Nick Maul, who was on the guest on the show last week.

00:09:45.620 --> 00:09:46.860
Oh, you got it.

00:09:46.860 --> 00:09:48.080
How can you get this to work?

00:09:48.080 --> 00:09:49.320
You've got some sort of magic.

00:09:49.320 --> 00:09:49.640
All right.

00:09:49.640 --> 00:09:51.520
Well, so thanks for putting on your screen.

00:09:51.520 --> 00:10:00.740
So here we have Will McGuigan showing an animation of basically this really cool, like collapsible

00:10:00.740 --> 00:10:06.620
sidebar and like scrolling within sub windows inside of textual.

00:10:06.760 --> 00:10:06.880
Right.

00:10:06.880 --> 00:10:08.420
We talked about textual as well.

00:10:08.420 --> 00:10:12.520
And it's just such a cool graphic that says like, wow, you can build some pretty amazing

00:10:12.520 --> 00:10:13.660
applications there.

00:10:13.660 --> 00:10:14.140
What do you think?

00:10:14.140 --> 00:10:16.620
Will's just knocking it out of the park with this.

00:10:16.620 --> 00:10:18.880
It's fun to watch him go so fast.

00:10:18.880 --> 00:10:19.520
Absolutely.

00:10:19.520 --> 00:10:20.680
Well done there, Will.

00:10:20.680 --> 00:10:22.500
I'll switch back to mine for a moment.

00:10:22.500 --> 00:10:22.960
Okay.

00:10:22.960 --> 00:10:24.720
Ars Technica works on my computer.

00:10:25.140 --> 00:10:29.960
So remember we did an episode and I titled it something like Flock No or something like

00:10:29.960 --> 00:10:30.300
that.

00:10:30.300 --> 00:10:38.060
So Flock, Federated Learning of Cohorts, is something that Google was trying to do so that they can

00:10:38.060 --> 00:10:40.040
replace third-party cookies.

00:10:40.040 --> 00:10:40.580
Why?

00:10:40.580 --> 00:10:46.840
Because people are running ad blockers or like I am right now, a VPN that at the network

00:10:46.840 --> 00:10:50.520
level blocks all the ad tracking and third-party cookies.

00:10:50.720 --> 00:10:53.900
So they're just basically not working very well anymore.

00:10:53.900 --> 00:10:57.680
So they need to, they're going to cancel third-party cookies from, which means they're

00:10:57.680 --> 00:10:59.580
canceling for the net, the internet.

00:10:59.580 --> 00:11:04.200
And, but because they're Google and they're based on ad revenue primarily, they can't just

00:11:04.200 --> 00:11:05.720
go and we canceled tracking.

00:11:05.720 --> 00:11:06.500
Hooray.

00:11:06.500 --> 00:11:09.500
We're all winning on privacy, right?

00:11:09.500 --> 00:11:14.400
It has to be replaced with some other form of tracking, which they call this Federated Learning

00:11:14.400 --> 00:11:14.860
of Cohorts.

00:11:15.000 --> 00:11:20.140
But the Federated Learning of Cohorts has all these almost more negative consequences.

00:11:20.140 --> 00:11:24.260
And I don't want to go too much into that because we went into quite a lot of detail.

00:11:24.260 --> 00:11:29.400
But for example, you can say, I would like to target, you know, lesbians who just got divorced.

00:11:29.400 --> 00:11:30.780
You run an ad on that.

00:11:30.780 --> 00:11:32.220
People show up on your site.

00:11:32.220 --> 00:11:33.180
They sign up.

00:11:33.180 --> 00:11:33.900
You have an email.

00:11:33.900 --> 00:11:35.240
And now guess what?

00:11:35.240 --> 00:11:38.240
Not only do you know what their email is, you know that they're in this group.

00:11:38.360 --> 00:11:40.720
And maybe this is the very first time you've ever met them, right?

00:11:40.720 --> 00:11:45.020
So really weird, creepy stuff that you could like pull out with this.

00:11:45.020 --> 00:11:49.380
Anyway, the big news is Google delays the rollout till 2023 because you know what?

00:11:49.380 --> 00:11:50.420
People don't like it.

00:11:50.420 --> 00:11:52.400
They're not super keen about it.

00:11:52.400 --> 00:11:56.860
So there's a whole bunch of people who are against that.

00:11:56.860 --> 00:12:00.960
But you're saying they're just delaying it, not stopping it?

00:12:00.960 --> 00:12:02.760
Yes, for now.

00:12:02.760 --> 00:12:06.280
Like, let me, this is a great article that people should check out.

00:12:06.280 --> 00:12:08.420
Like, let me read the first sentence or two.

00:12:08.420 --> 00:12:12.360
Google's plan to up in web advertising and user tracking by dropping third party cookie

00:12:12.360 --> 00:12:13.880
support in Chrome has been delayed.

00:12:13.880 --> 00:12:18.720
Most browsers block third party tracking cookies now as the VPN, like I mentioned.

00:12:18.720 --> 00:12:22.500
But Google, the world's largest advertising company, it wasn't going to follow suit without

00:12:22.500 --> 00:12:24.080
protecting its business model first.

00:12:24.080 --> 00:12:27.180
But there's a lot of challenges with this.

00:12:27.180 --> 00:12:28.920
A lot of people have come out against it.

00:12:28.920 --> 00:12:32.740
And yeah, it's not going to work out super well.

00:12:32.740 --> 00:12:35.520
So they decided to delay it.

00:12:35.640 --> 00:12:36.300
That's what they said.

00:12:36.300 --> 00:12:38.720
Stage two starts mid 2023.

00:12:38.720 --> 00:12:42.280
Google says it's received substantial feedback.

00:12:42.280 --> 00:12:44.040
Including from us.

00:12:44.040 --> 00:12:51.000
And other companies out there are like, we kind of want to keep tracking too, but we're not

00:12:51.000 --> 00:12:52.320
really excited about this.

00:12:52.320 --> 00:12:53.600
So we're just going to not say anything.

00:12:53.600 --> 00:12:56.340
Like Apple, Opera, Mozilla, Microsoft.

00:12:56.340 --> 00:12:58.640
Yeah, they're like, ah, what is I sure about this?

00:12:58.640 --> 00:13:01.020
Anyway, yeah, they've received substantial feedback.

00:13:01.220 --> 00:13:02.740
So hooray, I think for now.

00:13:02.740 --> 00:13:08.140
One thing that we don't talk very often about in Python is what if you want to ship your code

00:13:08.140 --> 00:13:11.600
to somebody and it has sensitive algorithms in it, right?

00:13:12.080 --> 00:13:16.960
It's not that common, but you could get Py2.exe or Py2.app bundle up your code and give it to somebody.

00:13:16.960 --> 00:13:19.880
For example, Dropbox does something to this effect, right?

00:13:19.880 --> 00:13:22.320
Got your Python code running up in your little menu bar.

00:13:22.320 --> 00:13:23.500
There's other ones as well.

00:13:23.500 --> 00:13:26.800
But you might want to encrypt how that works or protect how that works.

00:13:26.800 --> 00:13:30.380
So people can't just open the PY files and look around.

00:13:30.480 --> 00:13:32.060
So there's this thing called Source Defender.

00:13:32.060 --> 00:13:34.800
I'll be clear, this is a paid commercial product.

00:13:34.800 --> 00:13:37.680
I have no affiliation, but they pointed out, they sent me a message.

00:13:37.680 --> 00:13:38.700
Hey, we're doing this thing.

00:13:38.700 --> 00:13:39.200
What do you think?

00:13:39.200 --> 00:13:40.720
It looks kind of interesting.

00:13:40.720 --> 00:13:44.460
I think it's going to be a pretty limited set of people who actually care about this.

00:13:44.460 --> 00:13:47.620
Like if you're running on Docker, you're running on the server, you probably don't care.

00:13:47.620 --> 00:13:49.000
Maybe you do, but probably not.

00:13:49.000 --> 00:13:53.940
But if you'd like to be able to encrypt your source code so it's much harder to see and then

00:13:53.940 --> 00:13:56.900
ship that to somebody, you can use this thing as part of their paid service.

00:13:56.900 --> 00:13:57.740
So that's kind of cool.

00:13:57.740 --> 00:13:58.800
People can check that out.

00:13:59.080 --> 00:14:00.880
Let's see, oh, there's a play noise.

00:14:00.880 --> 00:14:01.320
I don't want that.

00:14:01.320 --> 00:14:05.860
So I was recently interviewed on a day in the life and a work from home Pythonista, which

00:14:05.860 --> 00:14:09.120
is a cool series being done by the folks in the Philippines.

00:14:09.120 --> 00:14:12.920
If you want a tour of the behind the scenes studio and all the work from home stuff, people

00:14:12.920 --> 00:14:13.600
can check that out.

00:14:13.600 --> 00:14:16.400
Python 396 was just released.

00:14:16.400 --> 00:14:19.000
We can check out the change log and see what's happening there.

00:14:19.000 --> 00:14:25.280
There's a security HTTP client about what I think is like a denial of service.

00:14:25.280 --> 00:14:28.880
It sounds like it avoids an infinite loop sort of thing.

00:14:28.880 --> 00:14:30.940
So that might matter to people.

00:14:30.940 --> 00:14:33.040
Probably not, but maybe it does.

00:14:33.040 --> 00:14:38.700
Then a bunch of changes that are happening here, including platform specific ones.

00:14:38.700 --> 00:14:41.360
So if you're running Python 39, and why wouldn't you be?

00:14:41.360 --> 00:14:42.100
Update that.

00:14:42.100 --> 00:14:43.560
Because you're running 310.

00:14:43.560 --> 00:14:44.460
Yes, that's right.

00:14:44.460 --> 00:14:45.440
You're already ahead of the world.

00:14:45.440 --> 00:14:46.600
You're in the future.

00:14:46.660 --> 00:14:54.040
So also, we had Calvin on from six feet up a while ago, and we talked about the conference

00:14:54.040 --> 00:14:55.440
that he was putting together.

00:14:55.440 --> 00:14:59.380
Well, the videos from that conference are out as a YouTube playlist, so people can check

00:14:59.380 --> 00:14:59.700
that out.

00:14:59.700 --> 00:15:01.560
I don't remember how many videos there are.

00:15:01.560 --> 00:15:02.560
Let's click on it and see.

00:15:02.560 --> 00:15:08.300
There are 61 videos, including one on the Python memory deep dive talk that I gave.

00:15:08.300 --> 00:15:10.300
So if you want to check that out, they can.

00:15:10.300 --> 00:15:11.060
Let's see.

00:15:11.060 --> 00:15:12.320
Oh, this one.

00:15:12.320 --> 00:15:13.240
Check this out, Brian.

00:15:13.240 --> 00:15:13.940
Have you seen this?

00:15:14.180 --> 00:15:15.700
Did you know you can pip install Python bytes?

00:15:15.700 --> 00:15:16.340
Yeah.

00:15:16.340 --> 00:15:25.440
You can literally pip install Python bytes because of Scott Stoltzman created this for us as a

00:15:25.440 --> 00:15:25.660
joke.

00:15:25.660 --> 00:15:26.700
He was listening to one of our episodes.

00:15:26.700 --> 00:15:28.340
I can't remember what we talked about.

00:15:28.340 --> 00:15:33.460
This was episode 239, but we must have talked about packaging and pip and things like that.

00:15:33.460 --> 00:15:35.640
So he created a package called Python bytes.

00:15:35.640 --> 00:15:41.140
And what it does is basically you give it a number, like 240, and it would download this

00:15:41.140 --> 00:15:45.060
version as an MP3 file and put it right next to whatever the working directory is.

00:15:45.060 --> 00:15:50.760
So if you want to pip install Python bytes and then python bytes.downloadepisode instead

00:15:50.760 --> 00:15:52.980
of using a podcast player, we're all for that.

00:15:52.980 --> 00:15:53.840
You can check that out.

00:15:53.840 --> 00:15:54.320
Yeah.

00:15:54.320 --> 00:15:54.480
Yeah.

00:15:54.480 --> 00:15:54.920
And that's it.

00:15:54.920 --> 00:15:56.720
That's extra, extra, extra, extra.

00:15:56.720 --> 00:15:57.820
Well, many, many extras.

00:15:57.820 --> 00:15:58.360
Yeah.

00:15:58.440 --> 00:16:03.440
So the Python bytes package is just sort of, it was for fun, but it also, it's really

00:16:03.440 --> 00:16:03.940
small.

00:16:03.940 --> 00:16:09.860
And one of the things I like about it is it's just a really cool example of like with Python,

00:16:09.860 --> 00:16:14.780
you got something that downloads MP3 files off of a feed somewhere.

00:16:14.780 --> 00:16:15.940
It's that easy.

00:16:15.940 --> 00:16:17.360
It's just, that's pretty cool.

00:16:17.360 --> 00:16:18.000
Yeah.

00:16:18.000 --> 00:16:18.620
That's fantastic.

00:16:18.620 --> 00:16:19.100
Absolutely.

00:16:19.100 --> 00:16:20.140
All right.

00:16:20.140 --> 00:16:21.080
Let's see.

00:16:21.080 --> 00:16:22.680
A couple of things from the live stream.

00:16:22.680 --> 00:16:26.820
Sam says, things have happened with Mozilla the last two years that really shook my confidence

00:16:26.820 --> 00:16:27.260
with them.

00:16:27.260 --> 00:16:32.800
I am still a big fan of Firefox and I support their mission, but yeah, it's, I want to see

00:16:32.800 --> 00:16:33.380
them succeed.

00:16:33.380 --> 00:16:34.280
Let's see.

00:16:34.280 --> 00:16:36.000
Another one from the live stream.

00:16:36.000 --> 00:16:38.040
Antonio said, Hey guys, have you mentioned Kivy before?

00:16:38.040 --> 00:16:39.760
Hey, GUIs and Kivy.

00:16:39.760 --> 00:16:40.180
There you go.

00:16:40.180 --> 00:16:42.100
I watched a video about this week.

00:16:42.100 --> 00:16:45.740
It's a GUI that's compatible with many things, including the mobile devices.

00:16:45.740 --> 00:16:46.360
I do.

00:16:46.360 --> 00:16:52.580
My feeling is that Kivy is, is a lot about, it's more about building almost game-like interactions.

00:16:52.580 --> 00:16:56.180
Whereas a lot of GUIs people want, they want like, here's a text box.

00:16:56.260 --> 00:16:57.140
I type in the text box.

00:16:57.140 --> 00:16:58.540
Here's a button I drop in, you know?

00:16:58.540 --> 00:17:00.020
So, but yeah, pretty cool.

00:17:00.020 --> 00:17:01.240
Well, let's see.

00:17:01.240 --> 00:17:06.140
Kim Venwick says, as an aside, shipping a Docker image won't obfuscate the Python.

00:17:06.140 --> 00:17:08.520
The image can be taken apart in files like that.

00:17:08.520 --> 00:17:09.120
That's true.

00:17:09.120 --> 00:17:10.360
They absolutely can.

00:17:10.360 --> 00:17:13.340
I was just thinking like, you're probably just running on like a container service.

00:17:13.340 --> 00:17:15.880
But yeah, if you're shipping it to someone, it's the same.

00:17:15.880 --> 00:17:21.380
Nick Harvey out in the live stream says, could just send the PYC files with no PY.

00:17:21.800 --> 00:17:24.020
It's not foolproof, but it does require more work.

00:17:24.020 --> 00:17:24.320
You're right.

00:17:24.320 --> 00:17:28.640
You'd basically be down to like this dot this and like reading the byte code.

00:17:28.640 --> 00:17:29.920
Yeah, for sure.

00:17:29.920 --> 00:17:31.060
Let's see.

00:17:31.060 --> 00:17:31.900
Final one.

00:17:31.900 --> 00:17:35.820
Rahan says, if it ends up running code on your machine, you can read it.

00:17:35.820 --> 00:17:37.940
It's about putting enough barriers that people won't bother.

00:17:37.940 --> 00:17:39.660
Yeah, that's definitely true.

00:17:39.740 --> 00:17:44.000
I mean, you think of C++ and things like that being completely opaque and yet people take

00:17:44.000 --> 00:17:44.800
that apart all the time.

00:17:44.800 --> 00:17:50.820
But there is also a difference from I'm literally shipping you the source files here to, you know,

00:17:50.820 --> 00:17:53.200
because then you could go in like, oh, here's where the license check is.

00:17:53.200 --> 00:17:55.640
Let's just, you know, command slash comment that out.

00:17:55.640 --> 00:17:56.180
All right.

00:17:56.180 --> 00:17:57.020
Now we're ready to run.

00:17:57.020 --> 00:17:57.440
Yeah.

00:17:57.440 --> 00:17:57.960
Right.

00:17:57.960 --> 00:18:00.460
You want to make it a little bit of a challenge, at least I suspect.

00:18:00.460 --> 00:18:02.600
Anyway, thanks for all the feedback out there, everyone.

00:18:02.600 --> 00:18:06.260
That's the everything extra, extra nine times.

00:18:06.260 --> 00:18:08.460
All right, Chris, what's your first one here?

00:18:08.820 --> 00:18:09.240
All right.

00:18:09.240 --> 00:18:14.980
So the first one is from Andreas Kanz, I think is how you pronounce it.

00:18:14.980 --> 00:18:18.460
And it's a library called Clib, I believe.

00:18:18.460 --> 00:18:21.480
I wasn't sure if it's K-Lib or Clib, but I think it's Clib.

00:18:21.480 --> 00:18:26.060
And it's for automated cleaning of Pandas data frames.

00:18:26.060 --> 00:18:28.940
I guess I should even say it's a little bit more than just cleaning.

00:18:28.940 --> 00:18:30.300
It's automated analysis.

00:18:30.300 --> 00:18:36.080
And, you know, I'll be the first to say I'm a little skeptical about some things that try

00:18:36.080 --> 00:18:37.940
and automate the process.

00:18:37.940 --> 00:18:39.260
But I was playing around with it.

00:18:39.260 --> 00:18:42.240
And there's some pretty cool things that it does.

00:18:42.240 --> 00:18:49.180
The documentation, probably the best way to learn about it is the Towards Data Science article

00:18:49.180 --> 00:18:53.700
that he wrote, which gives a pretty nice overview of what it does.

00:18:53.700 --> 00:19:01.040
It has some, as I mentioned, some pretty nice cleaning features as well as analysis features.

00:19:01.040 --> 00:19:07.440
So I was going to kind of go through a couple of the, describe a couple of things.

00:19:07.660 --> 00:19:15.140
The first one that I thought was really interesting is the, there's this function called data cleaning.

00:19:15.140 --> 00:19:18.580
And it essentially does, you can control what it does.

00:19:18.580 --> 00:19:20.180
So it can clean the column names.

00:19:20.180 --> 00:19:21.620
It can convert data types.

00:19:21.620 --> 00:19:22.540
It can drop missing.

00:19:23.380 --> 00:19:32.980
So one of the things that pandas does is it's not really aggressive about the size or the data types that it uses.

00:19:32.980 --> 00:19:39.900
So when you read in data, it will just kind of assign it maybe to a float or, you know, an object.

00:19:40.580 --> 00:19:42.640
But if you want, you can get in there.

00:19:42.640 --> 00:19:48.820
And if it's a value, if it's a column, let's say that has only values from, you know, less than 100.

00:19:48.820 --> 00:19:51.800
If you convert it to an integer, it saves memory.

00:19:51.800 --> 00:19:55.280
If you save enough memory, then you can actually speed up your code.

00:19:55.280 --> 00:20:04.500
And so this goes behind the scenes and takes your data frame and converts it essentially to the smallest value, NumPy value that it can store.

00:20:05.140 --> 00:20:18.380
And then, you know, I took a random data set and sure enough, it did reduce the memory footprint quite a bit, which I thought was pretty interesting because it's one of those things that is very tedious to do on your own by hand.

00:20:18.380 --> 00:20:20.780
Does it do like if you have the same string?

00:20:20.780 --> 00:20:24.720
Does it just create a pointer to one copy instead of having that many times, stuff like that?

00:20:24.720 --> 00:20:28.440
It can do that by converting it to a category type.

00:20:28.440 --> 00:20:31.220
That's essentially what pandas is doing when you create a category.

00:20:31.220 --> 00:20:36.460
It does that to kind of string to like a list conversion.

00:20:36.460 --> 00:20:38.800
And it's, you know, it's pretty effective.

00:20:38.800 --> 00:20:49.380
And yeah, I've used the category piece before, but I haven't actually gone in and tried to, you know, shorten up the numeric columns, which is really useful.

00:20:49.380 --> 00:20:50.720
The other thing...

00:20:50.720 --> 00:20:52.720
You just convert them to all the integers and then it'll just be shorter.

00:20:52.720 --> 00:20:54.220
So you don't have to worry about the size.

00:20:54.220 --> 00:20:55.120
I'm just teasing.

00:20:55.120 --> 00:20:55.600
Yeah.

00:20:55.600 --> 00:21:04.320
But I mean, it does even do, it's like, it can do even like int 16s or int 32s or int 8.

00:21:04.320 --> 00:21:04.920
Oh yeah, interesting.

00:21:04.920 --> 00:21:08.480
Like it'll shrink to the size that'll like, oh, these are all under 256.

00:21:08.480 --> 00:21:10.020
So we'll go to like one byte.

00:21:10.020 --> 00:21:10.860
Exactly.

00:21:10.860 --> 00:21:11.700
Exactly.

00:21:11.700 --> 00:21:18.840
You know, and I haven't looked at the code to see, you know, how it actually figures it out, but I had a fairly large data frame and it was pretty quick.

00:21:19.640 --> 00:21:22.700
The other one that was interesting is the clean column names.

00:21:22.700 --> 00:21:29.060
So I think there are some other libraries out there that will like strip spaces or special characters from column names.

00:21:29.240 --> 00:21:37.680
But what this one will actually do is actually, if you have a column name that has, let's say camel case, it'll convert it to all underscore.

00:21:37.680 --> 00:21:47.760
Or it will just essentially normalize all of your column names, which, you know, you could have a debate about whether you want to do that.

00:21:47.760 --> 00:21:53.800
But when you have a data frame that has a lot of columns and you're just looking at it the first time, that can really be helpful.

00:21:53.800 --> 00:22:04.440
And then the other function that it does that works pretty well is for cleaning duplicate data or empty data.

00:22:04.440 --> 00:22:15.480
So if you have a lot of columns that have no values in it or just, you know, maybe 90% of the values are empty, you can set thresholds and just clean that all out.

00:22:15.480 --> 00:22:18.640
So I was playing around with it and I was pretty impressed.

00:22:18.640 --> 00:22:30.260
And I kind of wanted to call it out because the documentation right now is mostly around the Jupyter notebooks that he has.

00:22:30.260 --> 00:22:35.980
So I think, you know, it would be nice if we could get some more docs in there and some more examples.

00:22:36.660 --> 00:22:40.100
But overall, I was really impressed with the library.

00:22:40.100 --> 00:22:47.460
And I think people should kind of take a look at it and see if it's something they want to use for some of their own processes.

00:22:47.460 --> 00:22:48.080
Yeah.

00:22:48.080 --> 00:22:52.060
Some of them sound interesting, even if you don't have to trust it, right?

00:22:52.060 --> 00:22:57.760
Like the shrink to the smallest data set, data type, for example, or normalized column names.

00:22:57.760 --> 00:23:01.040
Those don't seem as risky as, you know, clean it up.

00:23:01.040 --> 00:23:02.060
Exactly.

00:23:02.060 --> 00:23:02.940
Find the wrong data.

00:23:03.460 --> 00:23:03.860
Exactly.

00:23:03.860 --> 00:23:08.500
And then I forgot to mention, it also has some nice correlation plots.

00:23:08.500 --> 00:23:18.300
And some of these things you can already do with Seaborn or Matplotlib, but I found that it gives you a little more control and it's just a little bit easier to do it.

00:23:18.300 --> 00:23:22.180
There are certainly other tools out there that do this as well.

00:23:22.960 --> 00:23:35.420
So, oh, and then the categorical data plots I thought was a nice summary of the data and gives you some nice graphs and it helps you understand where you've got some missing values.

00:23:35.420 --> 00:23:36.380
But yeah.

00:23:36.380 --> 00:23:36.600
Yeah.

00:23:36.600 --> 00:23:39.220
The visualizing the missing data is a really interesting feature.

00:23:39.600 --> 00:23:39.780
Yeah.

00:23:39.780 --> 00:23:44.880
And there is another Pandas data frame called MissingNo that does this and does it well.

00:23:44.880 --> 00:23:53.500
But I think this is a unique combination, especially some of the data, the memory saving features that it has are pretty neat.

00:23:53.500 --> 00:23:53.900
Yeah.

00:23:53.900 --> 00:23:58.540
So the cleaning features, though, have a lot of, there's a lot of parameters to it.

00:23:58.580 --> 00:24:00.080
So it looks like you have a lot of control.

00:24:00.080 --> 00:24:05.660
And one of the, I mean, again, this is open source, so it isn't that magical.

00:24:05.660 --> 00:24:07.760
You can just look at the source and see what it's doing.

00:24:07.760 --> 00:24:08.800
So it looks.

00:24:08.800 --> 00:24:09.880
Exactly.

00:24:09.880 --> 00:24:10.200
Yeah.

00:24:10.200 --> 00:24:14.840
And that was one of the things I was looking at is like data cleaning, I think is kind of the top level.

00:24:14.840 --> 00:24:17.260
And you can just run that wide open and it'll do everything.

00:24:17.260 --> 00:24:20.780
And it actually prints out a pretty nice summary of what it does.

00:24:20.780 --> 00:24:28.420
But you can also go in there and specify parameters, like you said, to control it so that maybe it doesn't rename the columns.

00:24:28.420 --> 00:24:30.600
Or drop some of the missing data.

00:24:30.600 --> 00:24:37.140
The other thing that I tried to play with that seemed really interesting is this pool duplicate subsets.

00:24:37.140 --> 00:24:45.480
And essentially what it tries to do, and I had a little bit of trouble with this because I think I put too much data at it.

00:24:45.480 --> 00:24:53.320
But it tries to, maybe if you have 10 columns of data, it says, well, you know what, four or five of them are very heavily correlated.

00:24:53.600 --> 00:24:58.940
So we're going to drop them and just give you the four or five that are actually most useful.

00:24:58.940 --> 00:25:05.520
And so I think that's some interesting tools to use when you get some data that maybe you haven't worked with before.

00:25:05.520 --> 00:25:06.120
Yeah.

00:25:06.120 --> 00:25:06.640
Yeah.

00:25:06.640 --> 00:25:07.140
Very nice.

00:25:07.140 --> 00:25:08.640
What a good find.

00:25:08.640 --> 00:25:09.820
Brian, you got the next one?

00:25:09.820 --> 00:25:10.440
Sure.

00:25:10.440 --> 00:25:10.880
Yeah.

00:25:10.880 --> 00:25:12.020
Just a second.

00:25:12.960 --> 00:25:17.840
So I wanted to remind people to every once in a while, look at functools.

00:25:18.640 --> 00:25:27.180
Because I've experienced functools as kind of an interesting library that's built in.

00:25:27.180 --> 00:25:30.240
That is, it kind of grows with you.

00:25:30.240 --> 00:25:34.140
So if you're new to Python and you look at it, it's going to be confusing.

00:25:34.140 --> 00:25:37.080
It's like all intermediate stuff in there.

00:25:38.680 --> 00:25:48.740
But as you learn and experience more Python programming, come back to it every once in a while because there's stuff in there that you'll use that you didn't think about before.

00:25:48.740 --> 00:25:51.520
So I'm going to go through a few things.

00:25:51.520 --> 00:25:59.720
And actually, I wanted to call out, there was an article by Martin Hines that I read that kind of reminded me to go through and look this.

00:25:59.720 --> 00:26:01.060
So I want to shout out to him.

00:26:01.060 --> 00:26:01.480
Thanks.

00:26:02.520 --> 00:26:04.300
We've talked about some of this stuff before.

00:26:04.300 --> 00:26:14.140
We talked about function overloading and using single dispatch as one of the ways you can do function overloading in Python, which is cool.

00:26:14.140 --> 00:26:15.340
And that's part of functools.

00:26:15.340 --> 00:26:18.660
And hopefully people are familiar with wraps.

00:26:18.660 --> 00:26:24.940
Wraps is a way to create decorators that act like the thing that you decorated.

00:26:24.940 --> 00:26:29.220
And so if you're writing decorators, make sure you check out wraps.

00:26:29.220 --> 00:26:30.860
And then caching as well.

00:26:30.860 --> 00:26:33.780
I think, I'm sure we've talked about LRU cache.

00:26:33.780 --> 00:26:35.040
I'm sure we have, yeah.

00:26:35.040 --> 00:26:35.620
Yeah.

00:26:35.620 --> 00:26:39.140
So that's in functools, the caching.

00:26:39.140 --> 00:26:44.360
And new in 3.9, there's just a simple cache.

00:26:44.360 --> 00:26:45.960
You don't have to say LRU cache.

00:26:45.960 --> 00:26:49.220
And it's just a convenience wrapper around LRU cache.

00:26:49.220 --> 00:26:52.160
But it also, there's no max size.

00:26:52.160 --> 00:26:56.680
So you don't want to do that for things that you actually want to throw items away.

00:26:57.280 --> 00:26:59.220
But caching is super cool.

00:26:59.220 --> 00:27:01.200
So check that out.

00:27:01.200 --> 00:27:01.900
And then I didn't.

00:27:01.900 --> 00:27:05.640
When I first saw the LRU cache, I'm like, whoa, I got to go figure out what this LRU is.

00:27:05.640 --> 00:27:08.320
And it's not like, rather than just like cache the response.

00:27:08.320 --> 00:27:09.320
Yeah.

00:27:09.520 --> 00:27:14.740
I guess the other question, though, you might be is like, well, what if you pass two variable or two arguments or sets of arguments?

00:27:14.740 --> 00:27:15.320
How do those?

00:27:15.320 --> 00:27:15.700
Yeah.

00:27:15.700 --> 00:27:19.260
So either way, it's kind of not 100% totally obvious what's going to happen.

00:27:19.260 --> 00:27:20.040
Yeah, it's very cool.

00:27:20.380 --> 00:27:20.460
Yeah.

00:27:20.460 --> 00:27:24.400
So there's a bunch of caching stuff in there, like the LRU cache.

00:27:24.400 --> 00:27:26.120
But then you can also cache a property.

00:27:26.120 --> 00:27:29.600
And actually, the property one I hadn't used before.

00:27:29.600 --> 00:27:31.840
But I was playing with it this morning.

00:27:31.840 --> 00:27:33.320
And it's really cool.

00:27:33.320 --> 00:27:46.900
So like, for instance, if you've got a data class or any class that has a bunch of stuff, and some of the things, you have an expensive read on one of those because you have to calculate the value.

00:27:46.900 --> 00:27:53.720
You can throw a cache property on it, and it looks pretty cool.

00:27:54.560 --> 00:28:00.620
One of the neat things about it is, so it only reads it once, and then it caches the value of the property.

00:28:00.620 --> 00:28:08.400
And if you need it to refresh, you call delete on it, which is kind of a weird but kind of cool also.

00:28:08.400 --> 00:28:14.640
But it's odd to call delete on something that you want to still be there, and it'll just reread it next time.

00:28:14.640 --> 00:28:15.760
So that's how that works.

00:28:15.760 --> 00:28:16.820
That is weird.

00:28:16.820 --> 00:28:17.880
That's definitely weird.

00:28:17.880 --> 00:28:20.740
Total ordering, I didn't realize, was there.

00:28:21.900 --> 00:28:31.660
So if you have some data type that you want to be able to compare, you can use total ordering to define equal and one other operator.

00:28:31.660 --> 00:28:35.360
And then you get all of the comparison operators to show up.

00:28:35.360 --> 00:28:36.180
You can use that.

00:28:36.180 --> 00:28:50.440
And then the last one I wanted to highlight is partial method, which partial and partial method, which these are kind of neat in that, like, let's say you've got a function that takes a whole bunch of arguments.

00:28:50.440 --> 00:28:56.980
But you want to pre-fill some of those in and create a new function that has some of the arguments pre-filled in.

00:28:56.980 --> 00:29:00.620
You can do that with this, and it's pretty neat.

00:29:00.620 --> 00:29:01.460
Yeah.

00:29:01.460 --> 00:29:02.500
Okay, interesting.

00:29:02.500 --> 00:29:05.440
I see you partially supply some of the arguments, but not all of them.

00:29:05.440 --> 00:29:06.200
Yeah.

00:29:06.200 --> 00:29:12.780
So, yeah, just a shout out to this, that, yeah, these are intermediate or advanced topics.

00:29:12.780 --> 00:29:21.980
But, but there, as, so as you learn more Python, come back to this every once in a while and you, you might use, find it useful.

00:29:21.980 --> 00:29:22.500
Yep.

00:29:22.500 --> 00:29:22.920
Indeed.

00:29:22.920 --> 00:29:26.940
I was like, how did I miss this hashed property thing?

00:29:26.940 --> 00:29:33.680
Like, surely I would have paid attention to that because what, so often these properties that are like computed things, but they, you know, often don't change.

00:29:33.740 --> 00:29:34.120
Right.

00:29:34.120 --> 00:29:35.340
You get something back from the database.

00:29:35.340 --> 00:29:37.500
You want to, it has time sorted in seconds.

00:29:37.500 --> 00:29:38.840
You want to know how many days it is.

00:29:38.840 --> 00:29:40.840
So if something happens, you might have a day's property.

00:29:40.840 --> 00:29:41.060
Right.

00:29:41.060 --> 00:29:41.920
But that's probably not good.

00:29:41.920 --> 00:29:43.680
So having that hashed is cool.

00:29:43.680 --> 00:29:45.280
If you're sure it's not going to change.

00:29:45.280 --> 00:29:46.760
But I'm like, how did I miss it?

00:29:46.760 --> 00:29:47.520
It's new in 3.8.

00:29:47.520 --> 00:29:47.960
Yeah.

00:29:47.960 --> 00:29:49.120
So it's not, it's not super old.

00:29:49.480 --> 00:29:59.060
And like Chris said, one of the reasons to revisit a lot of these things and pay attention to the news on Python is because the language changes like this.

00:29:59.060 --> 00:29:59.820
So, yeah.

00:29:59.820 --> 00:30:00.680
Yeah, for sure.

00:30:00.680 --> 00:30:04.940
Kim out there in live streams says, also worth looking at intertools from time to time.

00:30:04.940 --> 00:30:05.540
Definitely.

00:30:05.540 --> 00:30:06.160
Great.

00:30:06.160 --> 00:30:06.400
Indeed.

00:30:06.400 --> 00:30:09.900
It's in the same level of complexity, but for collection.

00:30:09.900 --> 00:30:13.560
It's kind of like, you wouldn't first go there, but eventually like, oh yeah, this is what I wanted.

00:30:13.560 --> 00:30:14.280
I just didn't know it.

00:30:14.280 --> 00:30:18.940
Speaking of things you didn't know it, let me scare you all a little, make you all delighted.

00:30:19.140 --> 00:30:19.400
I don't know.

00:30:19.400 --> 00:30:20.460
You tell me how you take to this.

00:30:20.460 --> 00:30:22.480
So let me set the stage.

00:30:22.480 --> 00:30:24.600
GitHub has a little bit of source code.

00:30:24.600 --> 00:30:26.840
Much of it actually public, right?

00:30:26.840 --> 00:30:29.440
Like it's public repos and whatnot.

00:30:29.440 --> 00:30:36.000
So it can be analyzed and talked about and shared or used to train an artificial intelligence, which is pretty crazy.

00:30:36.000 --> 00:30:43.320
And if you look at the artificial intelligence around text, there's the GPT-3 stuff, which is like scary, good text-based AI.

00:30:43.320 --> 00:30:48.760
Well, they decided, what if, you know, our parent company also makes this editor?

00:30:48.800 --> 00:30:58.720
What if we hit an AI based on understanding the source code from GitHub, like all the source code from GitHub and put it into VS Code and then it did stuff?

00:30:58.720 --> 00:30:59.660
Have you all seen this?

00:30:59.660 --> 00:31:00.940
It's called GitHub Copilot.

00:31:00.940 --> 00:31:01.620
Yeah.

00:31:01.620 --> 00:31:02.300
Yeah.

00:31:02.300 --> 00:31:02.560
Yeah.

00:31:02.560 --> 00:31:03.680
I haven't done it yet.

00:31:03.680 --> 00:31:06.400
I was going to put the link in there and you beat me to it.

00:31:06.400 --> 00:31:07.120
Oh yeah.

00:31:07.120 --> 00:31:08.400
I was on top of it.

00:31:08.400 --> 00:31:14.540
So if you go over here, there actually works for TypeScript, Go, Ruby, Python, a couple other languages.

00:31:14.540 --> 00:31:18.620
It says it works for many languages, but it's best on those, of course.

00:31:18.620 --> 00:31:27.840
But if you just look like at their homepage, the copilot.github.com, they've got this little animation and it says, I'm going to write a function that says parse expenses.

00:31:27.840 --> 00:31:29.200
And it takes some kind of text.

00:31:29.460 --> 00:31:32.460
And you put a doc string, literally a doc string in Python.

00:31:32.460 --> 00:31:37.400
It says, parse the list of expenses and return the list of tuples, date, value, currency.

00:31:37.400 --> 00:31:39.120
Ignore a line starting with hash.

00:31:39.120 --> 00:31:40.520
Parse using date time.

00:31:40.520 --> 00:31:41.660
Here's some examples.

00:31:41.660 --> 00:31:42.420
Tab.

00:31:42.420 --> 00:31:46.200
And then it writes the code that does that.

00:31:46.560 --> 00:31:48.460
And let's see, what is it going to do?

00:31:48.460 --> 00:31:50.260
It says, it's in the middle of animation.

00:31:50.260 --> 00:31:52.100
It creates a list of expenses.

00:31:52.100 --> 00:31:53.900
It goes through each line on split.

00:31:53.900 --> 00:31:56.820
It says, if the line starts with hash, this is all Python code.

00:31:56.820 --> 00:31:58.500
Continue on your loop.

00:31:58.500 --> 00:32:01.200
Otherwise, date, value, currency equals split it.

00:32:01.200 --> 00:32:03.840
And then it knows how to parse the date one.

00:32:03.840 --> 00:32:07.900
Convert the value to a float and then store the currency as a string.

00:32:07.900 --> 00:32:10.020
And it's not just that sometimes it'll do this.

00:32:10.020 --> 00:32:16.500
You can actually get alternate implementations by tabbing through its recommended solution, which is,

00:32:16.500 --> 00:32:17.260
pretty crazy.

00:32:17.260 --> 00:32:20.820
So this is powered by OpenAIs.

00:32:20.820 --> 00:32:24.280
It's called Codec or something like that.

00:32:24.280 --> 00:32:25.760
I don't see it right here right now.

00:32:25.760 --> 00:32:27.320
Anyway, I'll probably run across it in a second.

00:32:27.320 --> 00:32:28.560
That's what it's powered by.

00:32:28.560 --> 00:32:31.320
And it says things like, you're the pilot.

00:32:31.320 --> 00:32:33.700
So with GitHub Copilot, you're always in charge.

00:32:33.700 --> 00:32:40.700
You can cycle through alternative suggestions and choose which to accept or reject and then manually edit the suggested code.

00:32:40.700 --> 00:32:41.300
Oh, yeah.

00:32:41.300 --> 00:32:42.180
And it learns from you.

00:32:42.180 --> 00:32:44.080
So I don't know.

00:32:44.080 --> 00:32:46.000
This is wild, y'all.

00:32:46.100 --> 00:32:47.380
This is pretty wild stuff here.

00:32:47.380 --> 00:32:48.100
What do you think?

00:32:48.100 --> 00:32:51.720
I think it's really impressive.

00:32:51.720 --> 00:32:55.940
I mean, it will be interesting to see what it's like when you use it in real life.

00:32:55.940 --> 00:32:59.740
And I think that there could certainly be limitations.

00:32:59.740 --> 00:33:02.320
But I don't know about you.

00:33:02.320 --> 00:33:10.020
But whenever I'm programming, there's always these things I just need to go and look at the documentation or look at Stack Overflow to refresh my memory.

00:33:10.020 --> 00:33:11.300
You've got to connect to SQLAlchemy.

00:33:11.300 --> 00:33:15.120
And I totally forgot how to do those three steps for that connection string sequence.

00:33:15.120 --> 00:33:15.500
Right?

00:33:15.500 --> 00:33:16.240
Exactly.

00:33:16.240 --> 00:33:16.920
Yeah.

00:33:17.280 --> 00:33:27.120
And I've seen, I saw on Twitter where someone was throwing a little shade at that example that you're walking through because they said, well, why are you storing the currency as a float?

00:33:27.120 --> 00:33:31.960
It should be a decimal because if you store a currency as a float, you're going to have all the rounding issues.

00:33:31.960 --> 00:33:33.340
So...

00:33:33.340 --> 00:33:36.060
That's how Superman makes all his money or the evil villain in Superman.

00:33:36.060 --> 00:33:36.580
What was it?

00:33:36.580 --> 00:33:37.400
One of those shows.

00:33:37.400 --> 00:33:37.880
Yeah.

00:33:37.880 --> 00:33:41.480
Richard Pryor in one of the original Superman.

00:33:41.480 --> 00:33:41.880
Yeah.

00:33:41.880 --> 00:33:44.300
Yeah.

00:33:44.300 --> 00:33:45.960
And it's not just based on the doc string.

00:33:45.960 --> 00:33:51.660
Like the example I first spoke about was you wrote complex doc string and then say, do that thing.

00:33:51.660 --> 00:33:55.220
But you can do it based just on function name.

00:33:55.220 --> 00:33:57.620
You can just type a meaningful function name.

00:33:57.620 --> 00:34:00.300
What was the example they used?

00:34:00.300 --> 00:34:00.880
I can't remember.

00:34:00.880 --> 00:34:09.000
But yeah, so you basically just write a doc string, a comment, a function name, or even some code to give more context to it.

00:34:09.000 --> 00:34:10.160
And then off it goes.

00:34:10.160 --> 00:34:11.560
So yeah, pretty neat.

00:34:11.560 --> 00:34:14.660
Codex, that's the name of the AI system behind it.

00:34:14.660 --> 00:34:19.440
So basically, this is a plugin for VS Code, but a really nice one.

00:34:19.440 --> 00:34:21.240
So here's some examples we'll all be familiar with.

00:34:21.240 --> 00:34:22.240
So fetch tweets.

00:34:22.240 --> 00:34:29.740
And the example here is you literally write def fetch underscore tweets underscore from underscore user have.

00:34:29.740 --> 00:34:33.260
And then what it auto completes with is, oh, you're going to need to pass the username in.

00:34:33.260 --> 00:34:37.400
And then here's how you authorize with Tweepy, set up the API credentials.

00:34:37.400 --> 00:34:39.160
And then here's the code you write.

00:34:39.160 --> 00:34:39.680
Oh, yeah.

00:34:39.680 --> 00:34:40.920
And here's your return.

00:34:40.920 --> 00:34:42.500
Or I want to do a scatter plot.

00:34:42.660 --> 00:34:48.000
And you write import, import matplotlib dot pyplot as plot, draw scatter plot, have.

00:34:48.000 --> 00:34:49.460
And then boom, there it is.

00:34:49.460 --> 00:34:50.600
Or memoization.

00:34:50.600 --> 00:34:53.140
I wanted to point this one out because of what you're covering, Brian.

00:34:53.140 --> 00:35:00.280
It says, oh, here's how you memoize a function, which is to, if it's past a set of arguments, it's always going to return the same answer.

00:35:00.280 --> 00:35:01.660
So just give that answer.

00:35:01.760 --> 00:35:04.540
Like, remember, these arguments equal this return value once it's run.

00:35:04.620 --> 00:35:11.320
And it shows how to create a complex decorator that is going to have a function that remembers the values using caching.

00:35:11.320 --> 00:35:14.720
It could just go at funktools dot cache.

00:35:14.720 --> 00:35:15.700
You know what I mean?

00:35:15.700 --> 00:35:18.100
Like, so there's things like that that is missing, right?

00:35:18.100 --> 00:35:23.880
Because you could achieve the exact same outcome with funktools cache decorators, right?

00:35:23.880 --> 00:35:26.100
Instead of trying to write a bunch of code that reimplements that.

00:35:26.260 --> 00:35:28.680
But anyway, pretty, pretty wild thing.

00:35:28.680 --> 00:35:29.900
I don't know really how to feel about that.

00:35:29.900 --> 00:35:30.740
I've been thinking about this today.

00:35:30.740 --> 00:35:32.860
It's kind of freaking me out, but it's also kind of cool.

00:35:32.860 --> 00:35:33.460
Yeah.

00:35:33.460 --> 00:35:45.780
I wanted to point out a comic that people have been pointing out with relation to this is, is the, you know, I wish we could have just specify what we wanted to do, the computer to do.

00:35:45.780 --> 00:35:47.620
And, and it just does it.

00:35:47.620 --> 00:35:49.180
And we already have that.

00:35:49.180 --> 00:35:50.000
It's called code.

00:35:50.000 --> 00:35:50.920
So anyway.

00:35:50.920 --> 00:35:52.320
Yeah.

00:35:52.320 --> 00:35:56.040
I, I don't think this, you know, people often say things like.

00:35:56.040 --> 00:35:58.200
I remember hearing this 20 years ago.

00:35:58.200 --> 00:36:02.980
Oh, this low code thing where you create these little boxes that do stuff and you drag and drop between them.

00:36:02.980 --> 00:36:04.700
We're not going to need programmers anymore.

00:36:04.700 --> 00:36:06.720
We're all just going to become drag or droppies.

00:36:06.720 --> 00:36:08.660
And then like you programmers won't be needed.

00:36:08.660 --> 00:36:11.640
The business people will just drag you drop either way the future.

00:36:11.640 --> 00:36:13.860
And that never, ever happened.

00:36:13.860 --> 00:36:14.160
Right.

00:36:14.160 --> 00:36:15.940
Because people got to put them in production.

00:36:15.940 --> 00:36:17.000
They've got to debug them.

00:36:17.000 --> 00:36:18.140
They've got to scale them.

00:36:18.140 --> 00:36:19.020
And so on.

00:36:19.020 --> 00:36:20.200
Yeah.

00:36:20.200 --> 00:36:20.720
Yeah.

00:36:20.720 --> 00:36:21.520
I think the same thing here.

00:36:21.520 --> 00:36:22.300
Like sure.

00:36:22.300 --> 00:36:25.960
It wrote it once, but you can't have a write only experience.

00:36:25.960 --> 00:36:26.880
For your code.

00:36:26.880 --> 00:36:30.220
You have to understand your code and be able to evolve your code and work with.

00:36:30.220 --> 00:36:33.880
So this might power you into a solution faster.

00:36:33.880 --> 00:36:37.520
But I don't think it escapes the need of people doing meaningful software work.

00:36:37.520 --> 00:36:39.220
The person that pointed out.

00:36:39.220 --> 00:36:43.140
And several people pointed out the example of using money.

00:36:43.140 --> 00:36:44.320
Floats and money.

00:36:45.080 --> 00:36:49.120
That does highlight one of the problems with something like this, though, that everybody

00:36:49.120 --> 00:36:51.940
needs to be careful of is the code that's generated.

00:36:51.940 --> 00:36:57.940
Now you have to like, you were already creating, carefully thinking about it when you were creating

00:36:57.940 --> 00:36:58.140
it.

00:36:58.140 --> 00:37:02.180
But if something else creates it, you've got to scrutinize that to make sure that's really

00:37:02.180 --> 00:37:03.280
doing the right thing.

00:37:03.280 --> 00:37:09.420
And so you're code reviewing some AI code while you're coding your own stuff.

00:37:09.420 --> 00:37:11.160
That's just a different part of your brain.

00:37:11.240 --> 00:37:13.060
You've got to make sure that you're really paying attention.

00:37:13.060 --> 00:37:13.600
Yeah.

00:37:13.600 --> 00:37:13.940
Yeah.

00:37:13.940 --> 00:37:17.280
And even I was looking at that matplotlib example.

00:37:17.280 --> 00:37:21.660
And I would even argue that's not really the way you should do a scatterplot in matplotlib.

00:37:21.660 --> 00:37:26.200
Because you should use the object-oriented interface in matplotlib.

00:37:26.200 --> 00:37:27.740
I mean, the code will work.

00:37:27.740 --> 00:37:30.680
But I wouldn't advocate that you use that code.

00:37:31.100 --> 00:37:37.780
And so to your point, I think it will be interesting to see if it does learn on your own coding style.

00:37:37.780 --> 00:37:42.820
So does it start to recognize those things that you're always, you know, like you said, connecting

00:37:42.820 --> 00:37:47.580
to a database or fetching a file or doing a certain pandas function?

00:37:47.580 --> 00:37:49.820
Will it start to learn that?

00:37:49.820 --> 00:37:51.700
And then that would be really interesting.

00:37:51.700 --> 00:37:55.200
I think there's something about it adapting to you and it learning from what you're doing.

00:37:55.200 --> 00:37:57.040
But I have no idea what that actually means.

00:37:57.040 --> 00:37:57.580
Yeah.

00:37:57.580 --> 00:37:58.660
Hopefully it's paying attention.

00:37:58.660 --> 00:38:03.980
So if it generates something and you change it to the different method and everybody else

00:38:03.980 --> 00:38:08.940
is doing that also, maybe they'll stop suggesting the old one and start suggesting the new one.

00:38:09.200 --> 00:38:09.380
Yeah.

00:38:09.380 --> 00:38:13.780
I'll, you know, Chris, your point about having to, maybe it was you, Brian, sorry.

00:38:13.780 --> 00:38:17.200
Whoever said about, you've got to like criticize this and you didn't write it.

00:38:17.200 --> 00:38:20.940
So you basically have to study it and then, then understand or understand it and study it

00:38:20.940 --> 00:38:22.680
to make sure it's doing the right thing.

00:38:22.680 --> 00:38:27.700
You know, I, a couple of years ago, I don't know, a while ago, I was river floating and

00:38:27.700 --> 00:38:31.320
broke my hand on some rocks, broke my finger in a bunch of places.

00:38:31.320 --> 00:38:35.240
And like my fingers were completely wrapped up all the way to the very tips.

00:38:35.240 --> 00:38:38.360
There was no like, oh, little pecking typing while my hand healed.

00:38:38.460 --> 00:38:41.820
It was like, nope, no one handed, really slow.

00:38:41.820 --> 00:38:47.660
So to keep things going, I used voice to text to try to like, at least keep email flowing

00:38:47.660 --> 00:38:49.060
for a month or something, you know?

00:38:49.060 --> 00:38:52.480
And what I found was I could write pretty decent emails.

00:38:52.480 --> 00:38:56.040
It's hard to like stop and think in whole sentences the way the little tools like it to

00:38:56.040 --> 00:38:57.960
work, but you can get it to work pretty well.

00:38:57.960 --> 00:39:03.760
But the mistakes it makes that are phonetically correct, but actually what you mean wrong, like

00:39:03.760 --> 00:39:08.440
they and they, or, or something that sounds like what you said, but is actually not

00:39:08.440 --> 00:39:10.920
what you mean to say is incredibly hard.

00:39:10.920 --> 00:39:14.100
It's much harder to understand and edit than you would think.

00:39:14.100 --> 00:39:18.020
And so things like this, like, well, I wanted it to do that and I hit tab and I, okay, it's

00:39:18.020 --> 00:39:20.820
doing, I feel like there's going to be a lot of blind spots.

00:39:20.820 --> 00:39:21.400
Yeah.

00:39:21.400 --> 00:39:22.320
Well, it did what it says.

00:39:22.320 --> 00:39:22.660
It didn't.

00:39:22.660 --> 00:39:24.380
I typed the thing and it seems right.

00:39:24.380 --> 00:39:26.260
And like, how do you really, really know?

00:39:26.320 --> 00:39:31.400
I, it just seems like in the same type of situation, it's going to be harder than normal code to

00:39:31.400 --> 00:39:31.640
check.

00:39:31.640 --> 00:39:34.020
Cause you didn't have to think through it to create it.

00:39:34.020 --> 00:39:34.440
You know?

00:39:34.440 --> 00:39:35.300
Yeah.

00:39:35.300 --> 00:39:36.600
A couple of comments from the live stream.

00:39:36.900 --> 00:39:39.360
Ray Han, don't, don't give him ideas.

00:39:39.360 --> 00:39:42.780
It says, greeting Dr. Falcon.

00:39:42.780 --> 00:39:45.200
Gosh, where have you been?

00:39:45.200 --> 00:39:48.540
Let's play thermonuclear war as a dock string.

00:39:49.380 --> 00:39:54.120
And Nick says, I can't help but think of Microsoft pay, which Microsoft pay was this really cool

00:39:54.120 --> 00:39:58.040
bot that was like super good at adapting this stuff and they put it on Twitter, but people

00:39:58.040 --> 00:40:01.560
decided to like be mean to, to, to it instead of teach it.

00:40:01.560 --> 00:40:07.980
I think in like Japanese Twitter, it became a very kind and intelligent bot, but on like English

00:40:07.980 --> 00:40:12.820
Twitter, it got turned into like a racist, horrible creature like right away.

00:40:12.820 --> 00:40:14.280
And they actually had to cancel the project.

00:40:14.280 --> 00:40:14.840
So yeah.

00:40:16.360 --> 00:40:21.860
And then Arthur says, next April fool, April, April fool's day prank.

00:40:21.860 --> 00:40:24.380
Everyone start writing terrible code that influences the AI.

00:40:24.380 --> 00:40:27.560
And this, this is why English day went down the tubes.

00:40:27.560 --> 00:40:30.660
Let's see.

00:40:30.660 --> 00:40:34.400
And then Sam, for goodness sakes, don't trade it on GitHub code.

00:40:34.400 --> 00:40:37.220
It'll arbitrarily turn on debug mode.

00:40:37.220 --> 00:40:37.960
Yeah, perhaps.

00:40:37.960 --> 00:40:39.220
Yeah.

00:40:39.220 --> 00:40:42.380
Kim thinks this is both very impressive and vaguely unsettling.

00:40:42.380 --> 00:40:44.320
And that captures what I was thinking.

00:40:44.980 --> 00:40:47.760
Rahen, will it go and talk to the marketing people for me?

00:40:47.760 --> 00:40:48.620
No.

00:40:48.620 --> 00:40:50.600
I'm good with people.

00:40:50.600 --> 00:40:51.440
That's what I do.

00:40:51.440 --> 00:40:52.180
Yeah.

00:40:52.180 --> 00:40:52.520
Okay.

00:40:52.520 --> 00:41:00.060
Another thing that's not mentioned here explicitly, but I think is interesting is this code is coming

00:41:00.060 --> 00:41:00.560
from GitHub.

00:41:00.560 --> 00:41:01.100
Yeah.

00:41:01.100 --> 00:41:08.280
When I go and I'm saying like, I'm working on super secret commercial project for large organization

00:41:08.280 --> 00:41:10.820
that has lots of people trying to scrutinize it.

00:41:10.820 --> 00:41:13.120
And I hit memoize tab.

00:41:13.120 --> 00:41:14.800
It's going to write some amazing code.

00:41:14.800 --> 00:41:16.420
Oh, by the way, was that GPL?

00:41:16.420 --> 00:41:17.820
Where did that code come from?

00:41:17.820 --> 00:41:18.180
Right?

00:41:18.180 --> 00:41:20.820
Like what's the license of the code that was on GitHub?

00:41:20.820 --> 00:41:25.980
Did I just now all of a sudden grab something that turned, you know, like if I was doing this

00:41:25.980 --> 00:41:28.640
on Windows and I hit tab is Windows now open source.

00:41:28.640 --> 00:41:29.460
I don't know.

00:41:29.800 --> 00:41:30.940
That's a really interesting point.

00:41:30.940 --> 00:41:34.960
And you would think if it was a small startup, someone will probably sue them.

00:41:34.960 --> 00:41:37.420
But, you know, this is Microsoft now.

00:41:37.420 --> 00:41:37.680
Yeah.

00:41:37.680 --> 00:41:38.560
Exactly.

00:41:38.560 --> 00:41:38.960
Yeah.

00:41:38.960 --> 00:41:39.420
Yeah.

00:41:39.420 --> 00:41:42.100
Anyway, so I agree with Kim.

00:41:42.100 --> 00:41:43.100
This is both very impressive.

00:41:43.660 --> 00:41:45.860
If this is the start, like where will it go?

00:41:45.860 --> 00:41:46.680
It would be very amazing.

00:41:46.680 --> 00:41:49.560
But it's also vaguely unsettling at the same time.

00:41:49.560 --> 00:41:51.160
And I don't know how I feel about it.

00:41:51.160 --> 00:41:53.940
Other than I wish it was in PyCharm so I could play with it more often.

00:41:53.940 --> 00:41:56.300
All right.

00:41:56.300 --> 00:41:57.440
Chris, you got the last one?

00:41:57.440 --> 00:41:58.300
I do.

00:41:58.300 --> 00:42:02.680
So this is another library called Cats.

00:42:02.680 --> 00:42:06.760
And it's a time series analysis library.

00:42:06.760 --> 00:42:08.640
And it's made by the same.

00:42:08.640 --> 00:42:09.780
Well, it's from Facebook.

00:42:10.540 --> 00:42:16.280
And a lot of people may have heard of Profit, which is a library for time series forecasting.

00:42:16.280 --> 00:42:24.060
And one of the things that's interesting to me about Profit and Cats is I think time series

00:42:24.060 --> 00:42:27.540
forecasting is something that's really common in the business world.

00:42:27.540 --> 00:42:34.040
I mean, you think about trying to forecast sales or maybe inventory movements or stock prices,

00:42:34.040 --> 00:42:37.220
a whole bunch of different use cases for it.

00:42:37.220 --> 00:42:45.560
And I think in general, most organizations don't have a group of PhDs that are really sophisticated

00:42:45.560 --> 00:42:46.680
in their analysis.

00:42:46.680 --> 00:42:50.340
So people use Excel and kind of come up with their own approaches.

00:42:50.340 --> 00:42:53.080
And that's why I thought Profit was interesting.

00:42:53.080 --> 00:42:57.300
And I think this is interesting because it does come from Facebook.

00:42:57.300 --> 00:43:01.840
And you have to assume that they've got a lot of smart people that are doing a lot of forecasting.

00:43:02.220 --> 00:43:09.340
And they've taken some of the things that Profit was good at and added some additional tools.

00:43:09.340 --> 00:43:16.580
So before I go too much into Cats, one thing I wanted to mention is I did write an article

00:43:16.580 --> 00:43:17.360
about Profit.

00:43:17.360 --> 00:43:27.400
But I think other people, this gentleman, Peter Cotton, wrote an article about Profit and essentially

00:43:27.400 --> 00:43:29.180
questioning how good it was.

00:43:29.180 --> 00:43:34.240
And this is a really long, really well thought out article.

00:43:34.240 --> 00:43:37.500
And some of the math and some of the concepts are way over my head.

00:43:37.500 --> 00:43:41.980
But I do encourage people, if you're looking at time series forecasting, take a look at this.

00:43:41.980 --> 00:43:49.260
But what Cats does is instead of just doing forecasting with Profit, it has a couple of different models

00:43:49.260 --> 00:43:50.260
that you can use.

00:43:50.260 --> 00:43:58.480
You can also do some more just basic time series analysis with it to detect seasonality patterns

00:43:58.480 --> 00:44:00.500
and change points and other trends.

00:44:00.500 --> 00:44:06.020
There's also, if you want to incorporate this in some of your other machine learning algorithms

00:44:06.020 --> 00:44:11.140
to pull out features from your time series data, you can do that with this library as well.

00:44:11.500 --> 00:44:18.360
And there's a whole bunch of other libraries or utilities to build like ensemble models and

00:44:18.360 --> 00:44:20.740
other approaches for time series forecasting.

00:44:20.740 --> 00:44:24.800
This is another one where it is relatively new.

00:44:24.800 --> 00:44:31.140
So there's not a whole lot of documentation, but it's a whole bunch of different Python notebooks,

00:44:31.140 --> 00:44:32.580
Jupyter notebooks, I mean.

00:44:33.120 --> 00:44:38.280
And like one of the things I think is interesting is from a forecasting perspective, you can use Profit,

00:44:38.280 --> 00:44:46.280
but use the same API and use Cerema, I think, Cerema and Holt Winners, as well as some other

00:44:46.280 --> 00:44:47.400
ensemble models.

00:44:47.400 --> 00:44:50.440
You can backtest, you can tune your hyperparameters.

00:44:50.440 --> 00:44:57.760
And then you can also, it's got several of these other algorithms for change point detection.

00:44:58.400 --> 00:45:05.440
And, you know, a lot of this, like I said, is I'm not an expert on the math, but I am interested in how you

00:45:05.440 --> 00:45:10.540
figure out how to take these tools and apply them to those real world business problems.

00:45:10.540 --> 00:45:15.840
And so I think it's really great when we have some of these libraries out there that are developed by

00:45:15.840 --> 00:45:20.500
really smart people that do understand the state of the art, that can maybe make it a little simpler

00:45:20.500 --> 00:45:23.020
for others to apply to their own unique challenges.

00:45:23.020 --> 00:45:25.480
Yeah, this looks really nice to bundle these all together.

00:45:25.840 --> 00:45:29.280
What's a type of problem you might answer with this?

00:45:29.280 --> 00:45:30.320
I think so.

00:45:30.320 --> 00:45:39.040
One example could be help me figure out what my blog or my website traffic is going to look like in six months

00:45:39.040 --> 00:45:39.480
from now.

00:45:39.480 --> 00:45:48.300
So I need to figure out, do I need to, you know, resize my servers or upgrade my disk space or...

00:45:48.300 --> 00:45:50.400
What's my AWS bandwidth bill going to be?

00:45:50.780 --> 00:45:51.300
Exactly.

00:45:51.300 --> 00:45:57.100
You know, the other one that I think it's probably used a lot in inventory.

00:45:57.100 --> 00:46:00.780
So trying to figure out, okay, what do I think sales is going to look like?

00:46:00.780 --> 00:46:07.060
What do I need to reorder so that I actually have enough product so that we don't stock out?

00:46:07.060 --> 00:46:11.000
I think those are some pretty common use cases.

00:46:11.260 --> 00:46:15.340
A lot of the examples here are the airline flight data.

00:46:15.340 --> 00:46:22.320
So anything that you have that's over a period of time, typically kind of on a daily basis over multiple years,

00:46:22.320 --> 00:46:27.620
you can then start to forecast out what the future, what those future numbers would look like.

00:46:27.620 --> 00:46:31.240
Then you have this magic prediction power for the executives.

00:46:31.680 --> 00:46:32.120
Exactly.

00:46:32.120 --> 00:46:38.740
And I think what's interesting about it is most of these, I think most times when people do prediction in Excel,

00:46:38.740 --> 00:46:43.140
it's kind of you put the numbers in there and kind of do your linear line.

00:46:43.140 --> 00:46:48.360
But these tend to give you more error bars so you can give a range.

00:46:48.360 --> 00:46:58.180
So I think a prediction like this is much more valuable when you say it could be between, you know, 100 and 110 versus it's going to be 101.5.

00:46:58.180 --> 00:47:02.900
And when you do that, it conveys a lot more precision than is really there.

00:47:02.900 --> 00:47:04.560
Yeah, that makes a lot of sense.

00:47:04.560 --> 00:47:06.860
Comment from the live stream, Sam Morley says,

00:47:06.860 --> 00:47:14.280
when I was experimenting with time series data, I managed to get better results with a fairly simple, naive Dharma model than I did using profit.

00:47:14.280 --> 00:47:23.400
And I think that's exactly what this article, I don't know if he's read this article, but this, the article from Dr. Cotton,

00:47:23.400 --> 00:47:29.160
that's essentially what he says is some of the more simple models did outperform profit.

00:47:29.160 --> 00:47:30.180
Yeah. Interesting.

00:47:30.180 --> 00:47:30.820
Well, cool.

00:47:30.820 --> 00:47:31.360
All right.

00:47:31.360 --> 00:47:32.820
Brian, is that it for all of our items?

00:47:32.820 --> 00:47:33.680
It is.

00:47:33.680 --> 00:47:35.600
Got any extra stuff you want to throw out there?

00:47:35.600 --> 00:47:38.500
Oh, I just had a, just a quick one.

00:47:38.500 --> 00:47:43.380
Somebody on Twitter last week asked, why did I write a second edition of the book?

00:47:43.380 --> 00:47:46.340
And so I thought, well, that's a reasonable question.

00:47:46.340 --> 00:47:51.500
So at pytestBook.com, you can go and I've added a, why a second edition section.

00:47:51.500 --> 00:47:53.000
So I think I'll read that.

00:47:53.000 --> 00:48:02.340
New built-in fixtures, new flags, package scope features, f-strings, types, all sorts of good things are available that weren't available then, right?

00:48:02.340 --> 00:48:02.840
Yep.

00:48:02.840 --> 00:48:03.320
Yeah.

00:48:03.320 --> 00:48:05.100
There's all sorts of reasons.

00:48:05.100 --> 00:48:07.220
Always good to see Pathlib there.

00:48:07.220 --> 00:48:08.220
I love Pathlib.

00:48:08.220 --> 00:48:10.760
It makes my life so much easier when dealing with files.

00:48:10.760 --> 00:48:11.480
Yeah.

00:48:11.480 --> 00:48:13.220
I finally made the move.

00:48:13.220 --> 00:48:16.980
I've put down os.path and I'm now all about the Pathlib.

00:48:16.980 --> 00:48:17.540
Loving it.

00:48:17.540 --> 00:48:18.160
That's good.

00:48:18.160 --> 00:48:18.660
Yeah.

00:48:18.660 --> 00:48:20.500
Chris, anything else you want to throw out there?

00:48:20.500 --> 00:48:22.420
I was going to throw out one other.

00:48:22.420 --> 00:48:32.200
I was doing some research for working with units of measure.

00:48:32.200 --> 00:48:32.680
UNYT.

00:48:32.680 --> 00:48:32.680
UNYT.

00:48:32.680 --> 00:48:33.880
UNYT.

00:48:33.880 --> 00:48:34.200
UNYT.

00:48:34.200 --> 00:48:35.520
UNYT.

00:48:35.520 --> 00:48:35.960
UNYT.

00:48:35.960 --> 00:48:40.480
That allows you to do things like convert kilometers to miles.

00:48:41.480 --> 00:48:48.100
it works with numpy it works with all the scientific stack and that was um i i hadn't

00:48:48.100 --> 00:48:51.380
heard of that one i thought it was kind of interesting and want to put that out there

00:48:51.380 --> 00:48:57.180
next time you need to actually do something with units and convert uh back and forth might want to

00:48:57.180 --> 00:49:02.560
consider that and then it looks like there's a lot of like physics and chemistry type things like

00:49:02.560 --> 00:49:07.480
the mass of the earth the radius of the earth as constants probably pi and e and all those things

00:49:07.480 --> 00:49:12.660
yes exactly and i think it's when you start getting into it there's probably temptation just

00:49:12.660 --> 00:49:17.640
to code it all yourself just put those constants in there but uh when it starts to get more

00:49:17.640 --> 00:49:22.980
complicated i think something like this could be really uh useful and then there's another approach

00:49:22.980 --> 00:49:29.540
called pint which also works there we go uh which also works with units and it has a little bit

00:49:29.540 --> 00:49:34.820
different uh approach and so i i think it's good to take a look at both of them and if you have a need

00:49:34.820 --> 00:49:39.840
then you can decide which api is going to work best for your unique situation yeah these are cool i

00:49:39.840 --> 00:49:46.300
haven't looked at unit but i love pint and i think the name is so good yes uh because my wife asked me

00:49:46.300 --> 00:49:53.080
like how many else's are in a pound or how many pints are in a liter i'll be like or even in i don't know

00:49:53.080 --> 00:49:59.300
a court or vice versa i'm like i have no idea i just these are such messed up volume measures and so

00:49:59.300 --> 00:50:03.040
it's like here's the thing that takes the thing you don't really know about and allows you to convert it

00:50:03.040 --> 00:50:07.460
to the others in a safe way it's good exactly i got one more quick extra to throw out as well for

00:50:07.460 --> 00:50:12.360
you chris there i forgot to mention that you were the author of the move to from excel to python

00:50:12.360 --> 00:50:17.320
with pandas course over at talk python trainings which is a really popular course basically it's

00:50:17.320 --> 00:50:22.740
a intro to pandas course disguised as solving problems you might with excel right exactly yeah

00:50:22.740 --> 00:50:27.460
yeah no thanks and uh i've had a lot of good feedback from folks so hopefully it's uh

00:50:27.460 --> 00:50:32.460
interesting to the listeners that haven't had a chance to check it out i might have to buy that for

00:50:32.460 --> 00:50:39.560
my boss maybe you can get that discount code yeah yeah the discount code all right you ready for

00:50:39.560 --> 00:50:45.680
some jokes my twitter came back so i can show the twitter joke now yeah all right so dean who is

00:50:45.680 --> 00:50:51.400
often but i don't see him this day today on the live stream sent a joke over and said do you know how

00:50:51.400 --> 00:50:59.860
they say async in italian async yo or async io which i thought was a pretty good one async io i think you

00:50:59.860 --> 00:51:05.460
love italian all right um you guys got another one out there i saw one in the notes another joke but i

00:51:05.460 --> 00:51:12.120
didn't see who put it there i i've got one um so does anyone know why cryptocurrency engineers

00:51:12.500 --> 00:51:19.720
allowed to vote no i don't know because they're minors oh that's a good dad joke yeah it is

00:51:19.720 --> 00:51:27.180
absolutely well on that high note let's uh let's call a show what do you what do you say

00:51:27.180 --> 00:51:31.800
yep right thanks as always chris thanks for joining us this time thank you very much really appreciate

00:51:31.800 --> 00:51:36.780
it yeah bye everyone thank you for listening to python bytes follow the show on twitter via at

00:51:36.780 --> 00:51:44.380
python bytes that's python bytes as in b-y-t-e-s and get the full show notes at pythonbytes.fm if you

00:51:44.380 --> 00:51:49.660
have a news item you want featured just visit pythonbytes.fm and send it our way we're always on the lookout for

00:51:49.660 --> 00:51:54.820
sharing something cool on behalf of myself and brian aukin this is michael kennedy thank you for

00:51:54.820 --> 00:51:57.440
listening and sharing this podcast with your friends and colleagues