WEBVTT

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

00:00:04.760 --> 00:00:10.980
This is episode 216, recorded January 13th, 2021.

00:00:10.980 --> 00:00:12.500
I'm Michael Kennedy.

00:00:12.500 --> 00:00:13.480
I'm Brian Okken.

00:00:13.480 --> 00:00:15.420
And Brian, we have a special guest, Yousef.

00:00:15.420 --> 00:00:16.000
Welcome.

00:00:16.000 --> 00:00:16.580
Hi.

00:00:16.580 --> 00:00:17.640
Great to have you here.

00:00:17.640 --> 00:00:22.200
You want to just take a quick moment and tell folks about yourself, maybe about your podcast real quick?

00:00:22.200 --> 00:00:22.800
Yeah, sure.

00:00:22.800 --> 00:00:26.340
Thanks for even being able to participate in this podcast.

00:00:26.340 --> 00:00:27.740
So my name is Yousef.

00:00:28.300 --> 00:00:31.340
I might not be well known as you guys are, for sure.

00:00:31.340 --> 00:00:33.140
I'm a mechanical engineer from Germany.

00:00:33.140 --> 00:00:34.640
I'm based in Germany as well.

00:00:34.640 --> 00:00:40.260
And I'm working for an IT company called SimScale, who are providing cloud-based simulation technology.

00:00:40.260 --> 00:00:43.060
On the site, I'm hosting a podcast called Engineered Mind.

00:00:43.060 --> 00:00:45.240
And I'm working on a bunch of other stuff.

00:00:45.240 --> 00:00:49.980
For example, my thesis, which we'll extensively cover, let's see, in this podcast.

00:00:49.980 --> 00:00:50.740
Yeah, yeah.

00:00:50.740 --> 00:00:55.380
You used a couple of cool libraries and stuff over there, which we'll feature here.

00:00:55.380 --> 00:00:56.000
All right.

00:00:56.000 --> 00:01:04.620
Well, the very first item, Brian, let's talk about maybe doing a pip search a lot.

00:01:04.620 --> 00:01:05.280
Yeah.

00:01:05.280 --> 00:01:12.540
Well, I kind of forgot pip search was the thing, because when I'm looking for PyPI stuff, I go to pypi.org.

00:01:12.540 --> 00:01:13.760
Yeah, so do I.

00:01:13.760 --> 00:01:14.780
Yeah, exactly.

00:01:14.780 --> 00:01:16.280
It's really fast there.

00:01:16.660 --> 00:01:20.300
Yeah, but there's a feature called pip.

00:01:20.300 --> 00:01:30.560
You can do a pip search, which the documentation says it's supposed to search for PyPI packages whose name or summary contains whatever query.

00:01:30.740 --> 00:01:39.680
So I can say pip search pytest, for instance, and it should show me if pytest is a package on PyPI.

00:01:39.680 --> 00:01:43.900
But right now, if you do that, it comes back with a big traceback.

00:01:43.900 --> 00:01:48.580
And it says, fault, what, minus 32500?

00:01:48.580 --> 00:01:49.620
Runtime error.

00:01:50.360 --> 00:01:52.180
The PyPI's XML.

00:01:52.180 --> 00:01:53.880
Anyway, the API is broken.

00:01:53.880 --> 00:01:56.000
So this is on purpose.

00:01:56.000 --> 00:02:03.960
What happened is, actually, I don't know really what's happened, but the service is getting swamped.

00:02:03.960 --> 00:02:07.380
The search endpoint is getting hit extremely hard.

00:02:07.800 --> 00:02:15.820
Yeah, I saw some message or some tweet that was to the effect of, is somebody out there running an insane number of searches against this endpoint?

00:02:15.820 --> 00:02:17.080
Please don't.

00:02:17.080 --> 00:02:18.820
Yeah, I don't know what's going on.

00:02:18.820 --> 00:02:20.320
So there's some guesses.

00:02:20.320 --> 00:02:26.900
Maybe it's a rogue continuous integration server or something weird's going on.

00:02:26.900 --> 00:02:36.700
But in the meantime, right now, we're going to link to a Python infrastructure status page, which has an update on this.

00:02:36.700 --> 00:02:40.280
So if anybody wants to follow, you can check that out.

00:02:40.280 --> 00:02:46.180
It says that the search endpoint remains disabled due to ongoing request volume.

00:02:46.180 --> 00:02:51.360
And I think this really started becoming a problem mid-December.

00:02:51.360 --> 00:02:54.080
And so I'm not sure what happened then.

00:02:55.140 --> 00:03:00.840
And then there's a related issue on GitHub for pip.

00:03:00.840 --> 00:03:05.100
So there's an issue open saying remove the pip search command.

00:03:05.100 --> 00:03:13.060
So I think the end result is, and even the error message says the search endpoint will be deprecated in the near future.

00:03:13.060 --> 00:03:18.080
So I think that this way to do pip search is just going to go away.

00:03:18.080 --> 00:03:24.380
That's actually a little surprising because usually a lot of these things are so backwards compatible.

00:03:24.880 --> 00:03:25.160
Yeah.

00:03:25.160 --> 00:03:29.260
And there's quite a discussion on the issue thread.

00:03:29.660 --> 00:03:36.720
But the gist of it is the current architecture is never designed to handle the volume it's getting right now.

00:03:36.720 --> 00:03:49.860
So there's a comment at the end of the thread that says, if you've got an idea for how to do this algorithm better or a way to do it scaled, go ahead and discuss it.

00:03:49.940 --> 00:03:50.940
But there's a link to it.

00:03:50.940 --> 00:03:51.580
But there's a link to it.

00:03:51.580 --> 00:03:53.220
We're not going to put that link in the show notes.

00:03:53.220 --> 00:04:00.300
But in the IPI thread or the GitHub thread, there's a link to it if you want to comment on that.

00:04:00.300 --> 00:04:02.400
But basically, we're bringing this up.

00:04:02.400 --> 00:04:07.160
You may have figured out it might be a fluke or whatever, but it's really going on.

00:04:07.500 --> 00:04:11.700
And a plea to look at your continuous integration scripts.

00:04:11.700 --> 00:04:13.940
And if you're doing a pip search in there, take those out.

00:04:13.940 --> 00:04:15.040
It ain't going to work anyway.

00:04:15.380 --> 00:04:21.200
It's got to be some kind of bot, some automatic thing like this, because it's already given the error message.

00:04:21.200 --> 00:04:25.360
Like, people would stop, you know, if it wasn't.

00:04:25.360 --> 00:04:30.000
Maybe somebody's trying, like, constantly trying to scrape all of the PIPI data out.

00:04:30.000 --> 00:04:30.620
I don't know.

00:04:30.620 --> 00:04:31.980
Yeah, why do a search?

00:04:31.980 --> 00:04:33.020
That's just weird.

00:04:33.020 --> 00:04:33.800
Yeah, exactly.

00:04:33.800 --> 00:04:35.300
I don't know what's going on here.

00:04:35.300 --> 00:04:37.540
But I guess don't do it.

00:04:37.540 --> 00:04:38.240
Don't do it.

00:04:38.240 --> 00:04:40.200
Doctor, it hurts when I do this.

00:04:40.200 --> 00:04:40.840
Stop doing that.

00:04:40.840 --> 00:04:52.200
So the next one I want to talk about is QPython, not QTPython or Qt or anything like that, but QPython, which is a way to do Python on Android.

00:04:52.200 --> 00:04:55.740
So we've talked about a couple of interesting applications.

00:04:55.740 --> 00:04:57.740
We've talked about Carnets or Carnet.

00:04:57.740 --> 00:05:00.500
I think it's French pronunciation, I've been told.

00:05:00.500 --> 00:05:03.480
And that's a really cool way to do Jupyter on iPad.

00:05:03.480 --> 00:05:04.400
So local.

00:05:04.400 --> 00:05:07.540
All these are local, obviously, not just running in the browser.

00:05:07.540 --> 00:05:10.780
There's Pythonista, which is really interesting.

00:05:11.280 --> 00:05:14.460
And QPython is also an interesting one for a couple reasons.

00:05:14.460 --> 00:05:20.120
Because you get an SDK and a REPL for your Android device, which is pretty interesting.

00:05:20.120 --> 00:05:23.460
But the reason I'm covering it, I think it's interesting.

00:05:23.460 --> 00:05:25.480
Somebody, I think somebody sent this over.

00:05:25.480 --> 00:05:26.940
No, I ran across this myself.

00:05:26.940 --> 00:05:35.080
Anyway, is it allows you just to integrate with the underlying Android APIs and features for automation.

00:05:35.080 --> 00:05:36.460
Yeah, cool, right?

00:05:36.460 --> 00:05:41.240
So you can do things like check the system.

00:05:41.240 --> 00:05:43.380
You can send out toast notifications.

00:05:43.380 --> 00:05:45.340
You can interact with applications.

00:05:45.340 --> 00:05:46.880
You can mess with the clipboard.

00:05:46.880 --> 00:05:57.820
You can do barcode scanning, speech recognition, send emails, like all those kinds of things around even, you know, screen brightness or checking your battery or whatever.

00:05:58.180 --> 00:06:05.760
So if you want to get access and automate your Android things, Python, well, here's a cool little app to do it.

00:06:05.760 --> 00:06:06.320
Okay.

00:06:06.320 --> 00:06:07.720
Wait a second.

00:06:07.720 --> 00:06:10.000
So I'm not an Android user that much.

00:06:10.000 --> 00:06:11.600
I've got like one Android tablet.

00:06:11.600 --> 00:06:13.380
But I didn't know it can make toast.

00:06:13.380 --> 00:06:14.240
Yeah.

00:06:14.400 --> 00:06:21.840
Well, it really prefers sourdough, but it will go even as far as rye if you have to.

00:06:21.840 --> 00:06:23.240
No, what's toast?

00:06:23.240 --> 00:06:24.140
Do you know what toast is?

00:06:24.140 --> 00:06:25.960
It's like a pop-up notification, I think.

00:06:25.960 --> 00:06:26.720
Oh, okay.

00:06:26.720 --> 00:06:32.880
Yosef, are you an Android person or an iPhone person?

00:06:32.880 --> 00:06:35.120
I have to confess I'm an iPhone person.

00:06:35.440 --> 00:06:40.680
I used to be completely against iPhone, but once you're in the ecosystem, you never get out.

00:06:40.680 --> 00:06:42.120
It's like the godfather.

00:06:42.120 --> 00:06:43.940
They just keep pulling you back in, man.

00:06:43.940 --> 00:06:44.900
Yeah.

00:06:44.900 --> 00:06:49.140
I just recently got a new iPhone as well, and I'm general about it.

00:06:49.140 --> 00:06:56.840
But because we have our mobile apps, the training for the courses, I've got an Android tablet and I've got an Android phone and so on.

00:06:56.840 --> 00:07:00.140
Oh, also, we've got a comment here on YouTube.

00:07:00.580 --> 00:07:05.580
So is it an own framework or can you use it in Android, Kotlin, and Java?

00:07:05.580 --> 00:07:11.520
I believe it's more like an app that you run, and then within that, you can do little jobs and stuff.

00:07:11.520 --> 00:07:12.620
So way to aesthetic.

00:07:12.620 --> 00:07:19.600
It's not something you can bring in that I'm aware of because you install it from Google Play, for example, to get started and so on.

00:07:19.600 --> 00:07:21.120
But maybe you can plug it in.

00:07:21.120 --> 00:07:27.720
They do talk about having an SDK, so possibly, but I got the sense that it's more for writing code outside than getting it on your device.

00:07:27.720 --> 00:07:29.260
But yeah, pretty cool.

00:07:29.400 --> 00:07:34.100
So if you're into Android and you want to do Python automation on it, this is pretty cool.

00:07:34.100 --> 00:07:34.780
It's free.

00:07:34.780 --> 00:07:35.960
Get it on the Android store.

00:07:35.960 --> 00:07:38.360
Apparently, it has ads, but it's also open source.

00:07:38.360 --> 00:07:39.640
So go with that.

00:07:39.640 --> 00:07:41.860
Do you know if there's a counterpart for iOS?

00:07:41.860 --> 00:07:44.400
I don't know about the automation side.

00:07:44.400 --> 00:07:48.080
There's a thing called Carnets, which is really cool.

00:07:48.080 --> 00:07:49.780
Let's see if I can find that.

00:07:49.780 --> 00:07:51.520
Carnets app.

00:07:51.520 --> 00:07:52.920
I believe that's how you spell it.

00:07:52.920 --> 00:07:53.440
Yes.

00:07:53.440 --> 00:07:55.140
That's Jupyter on the App Store.

00:07:55.540 --> 00:07:59.400
And that thing, I don't really want to open the App Store, but apparently I have to.

00:07:59.400 --> 00:08:00.620
Well, so much for that.

00:08:00.620 --> 00:08:02.540
But Carnets, it's here.

00:08:02.540 --> 00:08:06.140
Oh, and it's also on Google Play.

00:08:06.140 --> 00:08:07.020
Is that the same thing?

00:08:07.020 --> 00:08:08.360
No, that's a totally different thing.

00:08:08.360 --> 00:08:13.520
But Carnets or Carnet is a very cool app that lets you do something similar.

00:08:13.520 --> 00:08:14.840
There's also Pythonista.

00:08:14.840 --> 00:08:16.420
Those are the two I know for iOS.

00:08:16.840 --> 00:08:17.400
All right.

00:08:17.400 --> 00:08:26.020
So moving along, Yosef, maybe tell us a little bit about your research and then one of the libraries you've been working with here.

00:08:26.020 --> 00:08:27.020
Yeah, sure.

00:08:27.020 --> 00:08:29.940
So Open3D is one of the possibilities to visualize.

00:08:29.940 --> 00:08:30.620
There you go.

00:08:30.620 --> 00:08:31.480
3D.

00:08:31.480 --> 00:08:32.260
I had it out of order.

00:08:32.260 --> 00:08:32.680
Yeah, yeah.

00:08:32.680 --> 00:08:34.340
Let's talk about PyTorch first.

00:08:34.340 --> 00:08:34.560
Sorry.

00:08:34.560 --> 00:08:35.420
That's fine.

00:08:35.420 --> 00:08:37.340
So PyTorch 3D is basically an option.

00:08:37.340 --> 00:08:39.120
Let's say if you work with meshes.

00:08:39.780 --> 00:08:46.780
Let's say a mesh consists of edges and points, for example, and these edges connect all the points and what you get at the end is a mesh.

00:08:46.780 --> 00:08:57.220
So PyTorch, which is for Facebook, Facebook AI research, and they created this framework, so to speak, to be able to work efficiently with 3D data.

00:08:57.220 --> 00:08:59.640
So unfortunately, I'm using point cloud data.

00:08:59.640 --> 00:09:17.400
But the beautiful thing is that if you use PyTorch native application, which you produce for your 3D geometry, it runs, I wouldn't say significantly, but roughly 10 times slower than this PyTorch 3D, which is implemented especially for 3D problems.

00:09:17.400 --> 00:09:17.660
Oh, wow.

00:09:17.660 --> 00:09:18.240
Okay.

00:09:18.240 --> 00:09:20.500
So what kind of problem do people solve?

00:09:20.500 --> 00:09:23.280
What problem are you solving when you're working with this?

00:09:23.280 --> 00:09:23.700
Yeah.

00:09:23.700 --> 00:09:26.640
So in the beginning, it was like I was doing some kind of research.

00:09:26.740 --> 00:09:35.180
Unfortunately, they are coming out paper like every day and not too many, actually, in the field of deep learning, especially when it comes to point cloud or like geometric data.

00:09:35.180 --> 00:09:45.040
And the goal, just to inform the audience a bit, is my goal is basically to use deep learning and use some kind of or create an assistant system for engineers and designers.

00:09:45.040 --> 00:09:48.780
That means, let's say you're an engineer and we have this CAD model.

00:09:48.780 --> 00:09:51.160
So CAD, which stands for Computer Aided Design.

00:09:51.160 --> 00:09:54.800
So you would create a model, for example, of a gear, and then you would have that gear.

00:09:54.940 --> 00:09:59.120
But sometimes we have this differentiation between implicit knowledge and explicit knowledge.

00:09:59.120 --> 00:10:02.840
Explicit knowledge means this is existing knowledge, which we already know about.

00:10:02.840 --> 00:10:05.320
Let's say this knowledge can sit in a database.

00:10:05.320 --> 00:10:08.340
And sometimes we are not making use out of it.

00:10:08.340 --> 00:10:09.740
And then we have this implicit knowledge.

00:10:09.740 --> 00:10:14.340
Let's say an engineer comes into a company, is completely new, and he brings knowledge with him to the company.

00:10:14.340 --> 00:10:21.340
Now, the problem I want to tackle is because we're having so many data and we're accumulating geometric data in a company, we have to make use of that.

00:10:21.660 --> 00:10:35.800
And my approach is, hopefully, when I'm at the end of the thesis, which is like in roughly two months, is that I have a system or web application as a front end where the engineer or designer picks or starts a design or picks a point cloud or a design.

00:10:35.800 --> 00:10:41.760
And then it would suggest the engineer or designer with a probability of what they want to model.

00:10:41.760 --> 00:10:42.840
Let's say he picks a gear.

00:10:42.840 --> 00:10:48.660
Or maybe you want to have like an arrangement of gears or any specific big component.

00:10:48.660 --> 00:10:50.120
Or let's say you take a wheel.

00:10:50.120 --> 00:10:51.520
Okay, for example, what would you...

00:10:51.520 --> 00:10:52.600
Like for a transmission or something?

00:10:52.980 --> 00:10:57.940
Exactly, for a transmission or they pick a wheel and it could be a Tesla or it could be any other car.

00:10:57.940 --> 00:10:59.420
And then it would give you a probability.

00:10:59.420 --> 00:11:01.220
Okay, this wheel is maybe from a Tesla.

00:11:01.220 --> 00:11:05.820
And then it would suggest you Tesla with a, for example, 89% probability.

00:11:05.820 --> 00:11:07.780
And then you would click on the web application.

00:11:07.780 --> 00:11:08.740
This is the idea.

00:11:08.740 --> 00:11:12.940
And then it would pop the geometry into the web browser in the front end.

00:11:12.940 --> 00:11:14.080
Oh, that's pretty cool.

00:11:14.080 --> 00:11:21.820
So it basically, it's like image recognition, but instead of for pictures, it's image recognition for 3D CAD outlines.

00:11:21.820 --> 00:11:22.580
Exactly.

00:11:22.580 --> 00:11:29.840
It's so cool that you mentioned it because there's a big difference between doing a convolutional neural networks or deep learning for images because images are 2D.

00:11:29.840 --> 00:11:31.140
It's like a 2D matrix.

00:11:31.140 --> 00:11:34.740
But if you have a point cloud, then you have a tensor of higher dimensionality.

00:11:34.740 --> 00:11:39.040
And then you are kind of forced to use, for example, NumPy and all these kind of things.

00:11:39.680 --> 00:11:45.980
And if you're lucky, you could use something like PyTorch, PyTorch 3D, which you can also use CUDA on to be way more efficient.

00:11:45.980 --> 00:11:46.520
Yeah.

00:11:46.520 --> 00:11:47.000
Yeah.

00:11:47.000 --> 00:11:47.400
Wow.

00:11:47.400 --> 00:11:47.940
That's really cool.

00:11:47.940 --> 00:11:49.560
So it looks like a neat thing.

00:11:49.560 --> 00:11:55.420
This is, you know, I haven't done any 3D work for a while, but yeah, it looks, looks pretty cool.

00:11:55.420 --> 00:11:58.100
I would love to see, I don't know, some pictures and stuff.

00:11:58.100 --> 00:11:59.540
It would not be neat, but yeah.

00:11:59.540 --> 00:12:08.860
They have a very good, like if someone is interested in seeing what PyTorch 3D can do, Facebook AI Research has an own YouTube channel and they pitched PyTorch 3D on that channel.

00:12:09.200 --> 00:12:11.840
And they really do a nice, they show you what you can do with it.

00:12:11.840 --> 00:12:13.000
So it's really interesting.

00:12:13.000 --> 00:12:13.480
Yeah.

00:12:13.480 --> 00:12:14.240
Oh, awesome.

00:12:14.240 --> 00:12:21.160
Well, I guess I'd never really thought about applying, you know, AI, ML stuff to 3D meshes, but it makes perfect sense.

00:12:21.160 --> 00:12:23.060
And I can see it's totally different than images.

00:12:23.060 --> 00:12:23.620
Yeah.

00:12:23.620 --> 00:12:24.080
Yeah.

00:12:24.080 --> 00:12:24.620
Very cool.

00:12:24.620 --> 00:12:27.420
Brian, do you guys do any, you don't do any CAD stuff with your devices, do you?

00:12:27.420 --> 00:12:29.220
Well, I mean, yeah, some people do.

00:12:29.220 --> 00:12:30.620
Not me either.

00:12:30.620 --> 00:12:33.820
There's a lot of CAD that goes on in the ASIC design and stuff.

00:12:33.820 --> 00:12:35.220
Yeah, I can imagine.

00:12:35.220 --> 00:12:35.700
Yeah.

00:12:35.700 --> 00:12:36.000
Cool.

00:12:36.560 --> 00:12:36.820
All right.

00:12:36.820 --> 00:12:40.080
Now, before we get to the next one, I want to get something sorted out, Brian.

00:12:40.080 --> 00:12:40.580
Okay.

00:12:40.580 --> 00:12:42.220
I want to talk about Datadog.

00:12:42.220 --> 00:12:43.680
So they're back to support the show.

00:12:43.680 --> 00:12:44.480
Thank you, Datadog.

00:12:44.480 --> 00:12:44.980
Yay.

00:12:44.980 --> 00:12:52.940
And so they're really about helping you troubleshoot latency, CPU, memory bottlenecks in your apps.

00:12:52.940 --> 00:13:03.520
And if you don't know where it's coming from, Datadog will seamlessly correlate the logs and the traces at the level of individual requests, cross systems, allowing you to quickly troubleshoot your Python app.

00:13:03.520 --> 00:13:12.660
And they have a continuous profiler that allows you to find the most resource consuming parts of your app in production, just running all the time at any scale.

00:13:12.660 --> 00:13:14.160
And it has very little overhead.

00:13:14.160 --> 00:13:14.980
So that's pretty cool.

00:13:14.980 --> 00:13:20.480
Instead of trying to debug it and then deploy it and hope that kind of translates to production, just turn it on and watch.

00:13:20.480 --> 00:13:20.940
Yeah.

00:13:20.940 --> 00:13:21.940
So, yeah, that's cool.

00:13:21.940 --> 00:13:25.480
So be the hero that got that app back on track at your company.

00:13:25.480 --> 00:13:30.540
Get started with a free trial and support the podcast at pythonbytes.fm/Datadog.

00:13:30.540 --> 00:13:33.240
Or just click the link in your podcast player show notes.

00:13:33.240 --> 00:13:35.020
Now that that's sorted out, Brian.

00:13:35.500 --> 00:13:35.900
Yeah.

00:13:35.900 --> 00:13:36.980
Yeah.

00:13:36.980 --> 00:13:37.720
So sorting.

00:13:37.720 --> 00:13:39.800
Sorting's a thing.

00:13:39.800 --> 00:13:43.560
And the default Python containers are not sorted.

00:13:43.560 --> 00:13:47.540
And there's reasons behind that.

00:13:47.540 --> 00:13:48.980
But sometimes you need to sort stuff.

00:13:48.980 --> 00:13:54.240
So there's a Python library or a package called sorted containers.

00:13:54.240 --> 00:13:55.680
I like it.

00:13:55.680 --> 00:13:57.460
It's a very, I mean, I like the name at least.

00:13:57.460 --> 00:13:59.700
It's a very easy to remember sort of thing.

00:13:59.700 --> 00:14:02.800
But this is amazing.

00:14:02.800 --> 00:14:03.940
I looked into this.

00:14:04.020 --> 00:14:09.280
So this was recommended by Fanch and Bao recently for us to take a look at.

00:14:09.280 --> 00:14:14.580
And it's a pure Python based sorted collections library.

00:14:14.580 --> 00:14:20.340
And it's as fast as other packages that are built using C extensions.

00:14:20.340 --> 00:14:21.100
Wow.

00:14:21.100 --> 00:14:22.960
That's the impressive part.

00:14:22.960 --> 00:14:26.540
It's also fairly memory safe.

00:14:26.540 --> 00:14:29.740
But the documentation is pretty cool.

00:14:29.740 --> 00:14:32.380
There's a whole bunch of different benchmarks.

00:14:32.600 --> 00:14:36.300
So you can take a look at how it deals with large, large things.

00:14:36.300 --> 00:14:37.940
But it's really pretty zippy.

00:14:37.940 --> 00:14:39.720
It was pretty cool.

00:14:39.720 --> 00:14:43.160
The right on the front page, there's some, there's some example.

00:14:43.160 --> 00:14:45.200
And we're going to throw this in the show notes too.

00:14:45.200 --> 00:14:49.860
Of just, there's, you've got, it handles a handful of different data types.

00:14:49.860 --> 00:14:54.320
It shows sorted lists, sorted dictionaries, and sorted set.

00:14:54.320 --> 00:14:57.460
There's also a sorted key list.

00:14:57.460 --> 00:15:00.020
And I had to look that up to figure out what that was.

00:15:00.020 --> 00:15:06.700
So sorted, the sorted function within Python allows you to pass in a key,

00:15:06.800 --> 00:15:12.980
which the key really is a function to use to create a key for sorting.

00:15:12.980 --> 00:15:14.060
And.

00:15:14.060 --> 00:15:14.480
Right.

00:15:14.480 --> 00:15:17.360
Because the things in there might not have a natural sort, right?

00:15:17.360 --> 00:15:21.180
Like if you put a bunch of order objects in there, well, how do you sort those?

00:15:21.180 --> 00:15:22.440
Do you sort them by price?

00:15:22.440 --> 00:15:24.240
Do you sort them by date?

00:15:24.240 --> 00:15:24.820
Right.

00:15:24.820 --> 00:15:25.020
Right.

00:15:25.020 --> 00:15:26.100
So you select out that element.

00:15:26.100 --> 00:15:26.300
Yeah.

00:15:26.400 --> 00:15:26.600
Yeah.

00:15:26.600 --> 00:15:31.620
You should have it selected out or you can, you can do something like they might be sortable

00:15:31.620 --> 00:15:35.480
by default, but you want it to be like a reverse sort or something like that.

00:15:35.480 --> 00:15:35.840
Right.

00:15:35.840 --> 00:15:40.260
So, so, and there's some, some caveats listed so that you have to make sure that your,

00:15:40.260 --> 00:15:46.140
the key that you pass in, it follows some conventions like two identical items should be,

00:15:46.140 --> 00:15:48.700
should have the same key, stuff like that.

00:15:48.700 --> 00:15:54.940
It's all reasonable things, but it's a, it's a fairly easy, easy and complete package to just

00:15:54.940 --> 00:15:55.780
use.

00:15:55.780 --> 00:16:02.020
It looks, it acts just sort of like a normal, the normal thing, containers like lists and

00:16:02.020 --> 00:16:02.880
dictionaries and sets.

00:16:02.880 --> 00:16:05.640
It just, it just remains sorted all the time.

00:16:05.640 --> 00:16:07.160
And this is pretty incredible.

00:16:07.160 --> 00:16:07.620
So.

00:16:07.620 --> 00:16:08.140
Yeah.

00:16:08.140 --> 00:16:13.000
I can totally see bugs get into your code because you're like, well, we put stuff into this list

00:16:13.000 --> 00:16:14.380
and oh, I want the latest one.

00:16:14.380 --> 00:16:18.600
So it's the last one, but maybe, you know, you forgot to sort it before you did that or

00:16:18.600 --> 00:16:21.200
the first one's the last cause you reversed it or whatever.

00:16:21.200 --> 00:16:24.660
So what are the things that confused me when I first look at the, at this, I was

00:16:24.660 --> 00:16:25.960
scratching my head for a second.

00:16:25.960 --> 00:16:31.700
Cause it looks like a fairly simple set of like examples with just like a small set of

00:16:31.700 --> 00:16:32.380
elements in it.

00:16:32.380 --> 00:16:39.760
So like the first one is a, a list of like AB, E, A, C, D, B, just, you know, a few characters.

00:16:39.760 --> 00:16:43.420
And, you know, it's a whole bunch of these examples with just a little small amounts.

00:16:43.420 --> 00:16:49.440
And it says, underneath, this is all, all of the demo listed above, takes

00:16:49.440 --> 00:16:50.420
a gigabyte of memory.

00:16:50.420 --> 00:16:52.180
And I'm like, what the heck?

00:16:52.180 --> 00:16:54.300
Why is it taking so much memory?

00:16:55.020 --> 00:16:56.920
It's only five things.

00:16:56.920 --> 00:16:57.320
Come on.

00:16:57.320 --> 00:16:57.460
Yeah.

00:16:57.460 --> 00:16:58.420
I mean, like why?

00:16:58.420 --> 00:16:58.940
It's cheap.

00:16:58.940 --> 00:16:59.580
Don't worry about it.

00:16:59.580 --> 00:17:01.260
But there's hidden in there.

00:17:01.260 --> 00:17:09.000
There's an example of, that five character list sorted list that gets multiplied,

00:17:09.000 --> 00:17:11.080
by 10, 10 million.

00:17:11.320 --> 00:17:17.180
So it's a 10, like a 50 million, a million characters in a list that got sorted.

00:17:17.180 --> 00:17:17.480
Right.

00:17:17.480 --> 00:17:17.980
Yeah.

00:17:17.980 --> 00:17:22.300
So, and then like things like, and then all the operations like count.

00:17:22.300 --> 00:17:24.860
So you can say, count all the C's in there.

00:17:24.860 --> 00:17:26.220
It'll tell you how many there are.

00:17:26.220 --> 00:17:31.380
and all of, a lot of these operations like counting stuff with, with a sorted set take,

00:17:31.380 --> 00:17:33.300
uh, you know, less than linear time.

00:17:33.300 --> 00:17:34.580
So, yeah.

00:17:34.580 --> 00:17:38.960
So there's, there's, there's times you need sort and this is a cool one to check out.

00:17:38.960 --> 00:17:39.200
Yeah.

00:17:39.200 --> 00:17:39.500
It's cool.

00:17:39.500 --> 00:17:40.780
It's nice that it's pure Python.

00:17:40.960 --> 00:17:42.580
super easy to install.

00:17:42.580 --> 00:17:42.860
Right.

00:17:42.860 --> 00:17:45.300
And it's not going to have any like weirdness around that.

00:17:45.300 --> 00:17:49.480
Like if you say got an M1 computer and thing won't compile or whatever.

00:17:49.480 --> 00:17:51.780
No, this looks really cool.

00:17:51.780 --> 00:17:52.620
Yosef, what do you think?

00:17:52.620 --> 00:17:53.720
Yeah, this looks amazing.

00:17:53.720 --> 00:17:59.300
I'm also, I'm in touch with my brother, on the side and he's also watching our podcast

00:17:59.300 --> 00:17:59.820
at the moment.

00:17:59.820 --> 00:18:03.620
And he's also saying because of the one gigabyte memory for sorting is, it's incredible.

00:18:03.620 --> 00:18:04.540
It's crazy.

00:18:04.540 --> 00:18:06.020
Yeah.

00:18:06.020 --> 00:18:07.040
That's, that's pretty awesome.

00:18:07.040 --> 00:18:07.480
Yeah.

00:18:07.480 --> 00:18:10.220
I guess it's just showing like you can have a ton and it's all nice.

00:18:10.600 --> 00:18:14.840
So it's, I mean, it seems really straightforward, but having these things sorted, we just got

00:18:14.840 --> 00:18:16.980
dictionaries that would stay put.

00:18:16.980 --> 00:18:19.780
So, having sort of dictionaries is also cool.

00:18:19.780 --> 00:18:21.220
Yeah.

00:18:21.220 --> 00:18:22.160
Right.

00:18:22.220 --> 00:18:26.360
It used to be that they sort of, if they had the same keys and stuff or they wouldn't

00:18:26.360 --> 00:18:29.700
necessarily retain their order, of the things you added, but now they do.

00:18:29.700 --> 00:18:30.160
Right.

00:18:30.160 --> 00:18:33.400
So if people are confused and think, well, aren't dictionaries already sorted?

00:18:33.400 --> 00:18:34.200
No, they're there.

00:18:34.200 --> 00:18:36.700
They just stay in the order that they were created.

00:18:36.700 --> 00:18:37.900
Exactly.

00:18:38.300 --> 00:18:39.320
So yeah.

00:18:39.320 --> 00:18:39.360
Yeah.

00:18:39.360 --> 00:18:41.900
Similar, but not exactly the same thing.

00:18:41.900 --> 00:18:42.940
Yeah.

00:18:42.940 --> 00:18:43.520
All right.

00:18:43.520 --> 00:18:48.320
so I want to, this next one, I want to riff a little bit on typing and I want to do

00:18:48.320 --> 00:18:54.940
that around a tweet, which I think I've got to put into a different type of, hold on.

00:18:54.940 --> 00:18:59.940
For some reason, Twitter has stopped showing me like the entire conversation of things.

00:19:00.180 --> 00:19:02.660
I don't know why, but I guess it doesn't really matter.

00:19:02.660 --> 00:19:07.100
So Lucas Lenga responded to a tweet that went out there.

00:19:07.100 --> 00:19:09.720
You know, Lucas is obviously he's core developer.

00:19:09.720 --> 00:19:13.340
He's been doing really important stuff, but one of the main focuses that he's been working

00:19:13.340 --> 00:19:17.300
on is around type hints and typing with things like my pie.

00:19:17.300 --> 00:19:23.440
He was instrumental in bringing typing to Facebook and the Instagram code bases and things like

00:19:23.440 --> 00:19:23.600
that.

00:19:23.600 --> 00:19:30.020
So, there's a tweet that says controversial take types in a Python code base are a net negative.

00:19:30.220 --> 00:19:31.540
That's not Lucas.

00:19:31.540 --> 00:19:34.820
This is his, he's about to have a whole long conversation about this that I'm going to

00:19:34.820 --> 00:19:35.520
talk about.

00:19:35.520 --> 00:19:37.300
But, Brian, what do you think?

00:19:37.300 --> 00:19:39.060
You retweeted this.

00:19:39.060 --> 00:19:40.580
Them's fighting words.

00:19:40.580 --> 00:19:42.300
Them's is fighting words.

00:19:42.300 --> 00:19:43.780
Yeah.

00:19:43.780 --> 00:19:45.500
So yeah, what do you think?

00:19:45.500 --> 00:19:48.400
I think that, I think that they're good too.

00:19:48.400 --> 00:19:49.840
Yeah, I do too.

00:19:49.840 --> 00:19:54.000
I think when I first saw them, I was a little concerned, like, oh my goodness, this is going

00:19:54.000 --> 00:19:58.780
to potentially, you know, turn Python into something like TypeScript.

00:19:59.020 --> 00:20:05.040
And while I appreciate what TypeScript does to make JavaScript much better, I almost always

00:20:05.040 --> 00:20:08.780
walk away from working with TypeScript with a feeling of like, ah, that kind of hurt and

00:20:08.780 --> 00:20:09.240
was painful.

00:20:09.240 --> 00:20:14.200
I wonder why it had to go that way, you know, because the TypeScript requires, it's like,

00:20:14.200 --> 00:20:16.000
it's like C# or C++.

00:20:16.000 --> 00:20:18.520
The types have to match and they have to be there.

00:20:18.520 --> 00:20:21.580
And if they don't match at all, then it just won't work.

00:20:21.580 --> 00:20:21.980
Right.

00:20:21.980 --> 00:20:22.860
It's super frustrating.

00:20:22.860 --> 00:20:24.340
Oh, this thing is not defined.

00:20:24.480 --> 00:20:27.460
And, you know, there's, cause there's libraries that might not have types and then how do

00:20:27.460 --> 00:20:28.060
you work with them?

00:20:28.060 --> 00:20:30.820
And it's just, if I find it, there's always some little edge case.

00:20:30.820 --> 00:20:33.780
It's like, ah, this is frustrating, but I never feel that way with Python.

00:20:33.780 --> 00:20:36.660
And I really have come to love Python's type hints.

00:20:37.120 --> 00:20:42.480
And obviously Lucas starts out his conversation saying, this is easily disproven.

00:20:42.480 --> 00:20:48.240
If you ever use PyCharm or VS Code, the code completion in there is based on type annotations.

00:20:48.240 --> 00:20:53.500
If you've ever seen your editor highlight a function and squiggly say, this expects something

00:20:53.500 --> 00:20:57.500
else than what you're giving it, you know, besides the number of variables, but like you're

00:20:57.500 --> 00:21:00.640
giving it a string and it wants a number or something like that.

00:21:00.640 --> 00:21:05.080
You're using type annotations and you can enhance your code by doing that.

00:21:05.140 --> 00:21:08.140
Right. So I was actually talking to Yusuf about this yesterday.

00:21:08.140 --> 00:21:12.480
My philosophy, or maybe my, my rule of thumb is you don't have to always do it this way,

00:21:12.480 --> 00:21:18.460
but you know, if you're working in your editor and you have to type more than say three characters

00:21:18.460 --> 00:21:21.640
to get some kind of symbol to come up, you're probably doing it wrong.

00:21:21.640 --> 00:21:27.140
So like if you have email service and you want to have email service, send account email,

00:21:27.140 --> 00:21:30.940
you should be able to say dot S A E S A E, right.

00:21:31.020 --> 00:21:35.440
Send account email and it should know the type that's been returned, what an email service

00:21:35.440 --> 00:21:38.920
is, that it has this property and just write it for you.

00:21:38.920 --> 00:21:43.200
Right. So to me, a lot of the typing stuff, I know, I mean, this comment is somewhat about

00:21:43.200 --> 00:21:45.800
bugs. Like I never found a good bug because of this.

00:21:45.800 --> 00:21:48.140
To me, that's almost like a side benefit.

00:21:48.300 --> 00:21:53.000
It's about quickly generating code without stopping to go look at the code definition,

00:21:53.000 --> 00:21:56.960
without going over to the documentation to see what I could have typed over here.

00:21:56.960 --> 00:22:00.140
You know, it's for example, AWS people.

00:22:00.580 --> 00:22:05.880
This is insanely frustrating to work with AWS because you get these like weird, create this

00:22:05.880 --> 00:22:10.000
service and you give it a name and then you get an S3 service back, but it has no idea that it's

00:22:10.000 --> 00:22:16.000
an S3 service. So you get zero help on what anything, even I think go to definition doesn't

00:22:16.000 --> 00:22:20.220
quite work because it's, you know, use some factory method to reach down some weird place

00:22:20.220 --> 00:22:25.960
and get the thing. So I think really driving the code generation experience without being in

00:22:25.960 --> 00:22:30.680
documentation, without jumping around and reading all the source, just go forward. I think it's

00:22:30.680 --> 00:22:34.680
super nice. So to me, like that is the biggest win of all of this stuff.

00:22:34.680 --> 00:22:38.600
So let me give you the entire thread is very interesting. So yeah.

00:22:38.600 --> 00:22:42.940
Yeah. So let me touch on a couple of the points of the thread because I can't get it to come up in

00:22:42.940 --> 00:22:48.260
the screen share, but that's fine. I took notes luckily. So some of the things he pointed on, he's

00:22:48.260 --> 00:22:54.200
like, here's tweet one of 10. So number one, put enough annotations and then the tooling will

00:22:54.200 --> 00:22:59.340
connect the dots and make plenty of errors evident as well as like heighten this code

00:22:59.340 --> 00:23:05.500
generation auto magic, right? That's one. The most common types of errors though, that'll creep in

00:23:05.500 --> 00:23:10.920
is if, if none is being used where you expect a concrete, concrete type and things like my pie

00:23:10.920 --> 00:23:16.080
will say you're using a type that is an optional of something, but you're not checking to see if it's

00:23:16.080 --> 00:23:20.500
none before you dereference it. You're probably going to end up at some point with an attribute.

00:23:21.260 --> 00:23:25.880
None type does not contain attribute, whatever you tried to do, you know, upper or whatever,

00:23:25.880 --> 00:23:26.220
right?

00:23:26.220 --> 00:23:29.240
None is, none is not scriptable or something.

00:23:29.240 --> 00:23:35.240
Yes. So yeah. Something like that, right. Or callable or any of the things. Also another

00:23:35.240 --> 00:23:42.280
common bug is the return case. So if you've got a function, you can, you know, maybe check

00:23:42.280 --> 00:23:47.480
something and return one value, check something else, return another value. But if you forget at the

00:23:47.480 --> 00:23:51.960
end and you fall through and you don't put up some kind of concrete return type, Python

00:23:51.960 --> 00:23:56.680
functions just return none. Like this actually blew me away when I learned Python and I learned

00:23:56.680 --> 00:24:01.020
about functions that they always, always, always return something. There's no such thing as a

00:24:01.020 --> 00:24:02.140
void function in Python.

00:24:02.140 --> 00:24:02.600
Yeah.

00:24:02.600 --> 00:24:06.800
As a C++ person, that probably surprised you too, right? Like with your C++ background.

00:24:06.800 --> 00:24:09.560
I did a bunch of other Perl and stuff like that.

00:24:09.700 --> 00:24:16.820
But the return type is actually one of the greatest documentation features as well, because

00:24:16.820 --> 00:24:21.840
sometimes you can try to, you can kind of figure out what the parameters are going to look,

00:24:21.840 --> 00:24:26.800
think, you know, you can guess, but what's the return type? Is it going to be a list? Is it going

00:24:26.800 --> 00:24:31.260
to be a tuple? Is it going to be a single element? What if there's more than one element? Yeah.

00:24:31.260 --> 00:24:35.420
Having type hints around the return types is a great feature.

00:24:35.420 --> 00:24:40.620
Yeah, absolutely. All right. Let me touch on a couple more and I see some listener comments in

00:24:40.620 --> 00:24:45.400
the stream as well. Squiggly lines in your editor. Anyone like I just got this the other day. I,

00:24:45.400 --> 00:24:51.280
I thought I was supposed to pass an object ID, the primary key manga, but we'd overridden it. And

00:24:51.280 --> 00:24:55.320
it's actually a string. It said, you're passing a object ID when you expect a string. I'm like,

00:24:55.320 --> 00:24:59.860
Oh yeah, I guess I am. All right. Well change that. Right. That's really nice. Instead of that

00:24:59.860 --> 00:25:06.820
being a runtime error. And he talks about the work with TypeScript and Anders Hausberg and what he did

00:25:06.820 --> 00:25:11.260
to help build that. And TypeScript, like I said, is pretty neat. But he also points out that, you know,

00:25:11.260 --> 00:25:16.840
the same company, Microsoft is developing powerful type checking and code completion for Python with

00:25:16.840 --> 00:25:22.020
VS Code. And they're, you know, they have one of the Python steering council folks working on there.

00:25:22.020 --> 00:25:28.760
And maybe that's Brett. And also possibly the Python creator himself, Weido. So do you think those two

00:25:28.760 --> 00:25:32.860
people would be working on something that just provides the illusion of productivity? Probably

00:25:32.860 --> 00:25:38.720
not. So let's see a couple of comments. Chris May. Hey, Chris, happy to see you out there. He says,

00:25:38.720 --> 00:25:42.980
code completion is such a confidence builder too. I think it's so awesome because for me,

00:25:42.980 --> 00:25:47.640
it's both amazing for beginners because they can type dot and go now what? And for experts,

00:25:47.640 --> 00:25:52.760
they can just blast out code so quickly because you just type dot the few things and you know,

00:25:52.760 --> 00:25:54.720
like you said, with confidence, you just keep going.

00:25:55.220 --> 00:26:03.900
A lot of these features, you get them if everybody around you writing the code that you're using is

00:26:03.900 --> 00:26:09.940
using type hints. You don't necessarily need to use type hints yourself, but then you're being a bad

00:26:09.940 --> 00:26:14.960
citizen and not helping the people out that you're sharing code with. So if you don't share code at all,

00:26:14.960 --> 00:26:19.100
and you're only working on projects with yourself, then, you know, go ahead. Don't use type hints.

00:26:19.260 --> 00:26:24.080
It's up to you, right? Yeah, absolutely. Yusuf, what do you think? Do you guys use

00:26:24.080 --> 00:26:25.580
type hints on your project?

00:26:25.580 --> 00:26:30.840
No, not really. Like it's not something that's in our conscious mind, I would say. I'm not sure if

00:26:30.840 --> 00:26:35.000
that's also something really because you're an engineer. I wouldn't want to generalize, but

00:26:35.000 --> 00:26:39.940
engineers are usually bothered with the problem itself rather than digging down on the types,

00:26:39.940 --> 00:26:42.560
for example. It depends. It depends on what language we use.

00:26:42.940 --> 00:26:48.720
Yeah, it's a bit of a computer science-y topic, I can see. But yeah, I just, like I said, I love how

00:26:48.720 --> 00:26:56.460
it generates the content so much easier. Magnuson also commented, I love, for example, Pydantic,

00:26:56.460 --> 00:27:01.220
but I agree with Romalo, Luciano Romalo, who was in this thread. Hopefully it won't be required

00:27:01.220 --> 00:27:06.180
in Python to help people get started. Yeah. So I think the typing stuff is really interesting. Like

00:27:06.180 --> 00:27:10.820
Pydantic, we've talked about a bunch. It's a super interesting example of really using typing

00:27:10.820 --> 00:27:17.280
to generate cool data ingestion and processing. Like if you say I've got a Pydantic model and one

00:27:17.280 --> 00:27:21.900
of its fields is a list of integers, but you give it a list and the things in the list happen to be

00:27:21.900 --> 00:27:26.200
strings that could be integers, it'll automatically convert it and stuff like that is really fantastic.

00:27:26.200 --> 00:27:29.680
Yeah, I think that's always going to be an add-on type of thing.

00:27:29.680 --> 00:27:35.600
Yeah, even though I'm a fan of typants, I don't use them all the time and I would be very opposed

00:27:35.600 --> 00:27:37.080
to having them be required.

00:27:37.500 --> 00:27:41.620
Yes, I would too. I would too. I don't think they need to be on the whole code base. I mean,

00:27:41.620 --> 00:27:47.620
it depends if your goal is to say, I want to use them for mypy or mypyc and like completely generate

00:27:47.620 --> 00:27:52.320
stuff. But if your goal really is to get a little bit of help with editors, just having it on the

00:27:52.320 --> 00:27:56.820
boundaries, like here's the data access layer, the things that come out of there return whatever,

00:27:56.960 --> 00:28:00.420
like you don't have to do anything else and the editors will pick it up and run.

00:28:00.420 --> 00:28:00.840
Yeah.

00:28:00.840 --> 00:28:01.260
Yeah.

00:28:01.260 --> 00:28:06.080
All right. One quick question. What is a function return? If there's no return, it returns none.

00:28:06.080 --> 00:28:09.860
It returns none. So that's why you don't have to just say whether there's a return type. It always

00:28:09.860 --> 00:28:15.160
returns none. All right. Next up, I guess we got the one I tried to open with there,

00:28:15.160 --> 00:28:18.440
Yousef, is Open3D. That looks fun.

00:28:18.840 --> 00:28:23.100
Yeah. This is basically a library which you could use in Jupyter, which I tried to use,

00:28:23.100 --> 00:28:28.920
but somehow they at the moment have problems using Open3D. So what you can do is you call Open3D in

00:28:28.920 --> 00:28:33.520
your Jupyter notebook and then have the point cloud visualized. However, there are some ways around it,

00:28:33.520 --> 00:28:38.240
but Open3D, I think if I would start all over again, I would probably use Open3D to visualize my

00:28:38.240 --> 00:28:43.020
point cloud, which I'm actually working with in my Jupyter notebook. I'm not sure if using a Jupyter

00:28:43.020 --> 00:28:46.740
notebook is also something you would recommend personally, maybe Brian and Michael,

00:28:47.040 --> 00:28:50.020
if you're a fan of Jupyter notebooks. I think it depends on the application, right?

00:28:50.020 --> 00:28:55.840
Yeah. I think it depends as well. And to me, it really depends on what I'm trying to do

00:28:55.840 --> 00:29:01.160
and the kind of code. Am I trying to explore data and does it have a really strong visualization

00:29:01.160 --> 00:29:07.940
component or is it like a utility type thing? So for example, one of the things that I wrote

00:29:07.940 --> 00:29:12.600
recently that I would never put into a Jupyter notebook, but I find really helpful is we've got

00:29:12.600 --> 00:29:19.780
literally thousands of video files, MP4s and whatnot for the online courses. And in order to

00:29:19.780 --> 00:29:25.360
import them, one of the things I have to tell the database is how many, how long in seconds is each

00:29:25.360 --> 00:29:29.960
file and where does it live and stuff. So I've got a little script and I just say, go, go to this

00:29:29.960 --> 00:29:36.460
directory and generate a little JSON output for all of the files and by and parse them and tell me how

00:29:36.460 --> 00:29:40.400
long they are like that kind of app doesn't belong there. Right. It's just, that's a command line type

00:29:40.400 --> 00:29:45.680
of utility type of thing. But if I want to visualize something like this, I think it may well be really

00:29:45.680 --> 00:29:47.620
good for it actually. So I think it varies.

00:29:48.400 --> 00:29:55.580
Yeah. There's a lot of application parts of my work that I think using a Jupyter notebook actually might be

00:29:55.580 --> 00:30:02.860
more beneficial. So I'm often taking big, huge trace data and stuff for like a spectrum traces and

00:30:02.860 --> 00:30:09.660
there, those could easily be driven from a Jupyter notebook and with the visualization stuff would be good.

00:30:09.660 --> 00:30:19.880
Yeah. Yeah. Cool. So this thing is a set of both C++ and Python libraries for basically working with 3D meshes, right?

00:30:19.880 --> 00:30:26.700
Mostly 3D data. For example, if you use a LIDAR, so when you work with a laser and this looks, for example, great.

00:30:26.700 --> 00:30:32.400
I never watched the video, but if you scan objects in your surroundings, usually what you get is a point cloud

00:30:32.400 --> 00:30:38.180
and which you can then visualize using Open3D. And the big disadvantage with point clouds is that

00:30:38.180 --> 00:30:43.460
they're kind of unstructured. So you could have one matrix representing one point cloud and you could

00:30:43.460 --> 00:30:48.500
have the same matrix switching two points, but the matrix would be different. This is also a problem

00:30:48.500 --> 00:30:53.020
that a lot of papers try to tackle and make sure that, you know, get around the spot.

00:30:53.020 --> 00:31:02.400
Yeah. Nice. Yeah. The example video here is using Open3D for 3D object detection, which is, that's pretty wild.

00:31:02.400 --> 00:31:03.500
Yeah. Nice.

00:31:03.500 --> 00:31:04.920
The things people do these days.

00:31:04.920 --> 00:31:10.940
I know. I think it's really interesting, all this image processing and analysis stuff. Yeah.

00:31:10.940 --> 00:31:15.400
Good question, Brian, by the way. This is what I ask myself when I listen to Python bytes. As an engineer,

00:31:15.400 --> 00:31:17.040
what are you guys doing? It's great.

00:31:17.040 --> 00:31:25.060
Absolutely. Cool. All right. Well, that's it for all of our main items. Brian, you got anything extra

00:31:25.060 --> 00:31:25.880
that you want to throw out there?

00:31:26.380 --> 00:31:32.980
Yeah. I just wanted a couple of things. One, 2021 has been exhausting so far. Yeah. I don't know if

00:31:32.980 --> 00:31:38.880
anybody else has got the same experience, but wow. And also I've got a lot of extra projects,

00:31:38.880 --> 00:31:43.080
side projects that I'm working on right now. Python bytes is one of them, but there's other stuff going

00:31:43.080 --> 00:31:50.160
on as well, trying to do more writing. And because of that testing code is, has shifted to an every other

00:31:50.160 --> 00:31:57.160
week cadence. So it's not going away. I know a lot of, oddly enough, I've had a lot of feedback in the

00:31:57.160 --> 00:32:02.580
last couple of months of people saying, thank you for the podcast. I've learned so much. So I do not,

00:32:02.580 --> 00:32:06.220
I don't want to shut it down. I want to keep it going and there's no plans on shutting it down.

00:32:06.220 --> 00:32:11.040
It's just slowing down so that I have room in my life for other, other projects as well. So just

00:32:11.040 --> 00:32:12.080
wanted to let people know that.

00:32:12.160 --> 00:32:17.820
Yeah. Yeah. I try to, for Talk Python, batch it up and do a whole bunch, just to say this week, I'm just

00:32:17.820 --> 00:32:22.360
going to get nothing done, but I'll do a ton of recording and then just roll them out. I had three

00:32:22.360 --> 00:32:26.940
months of stuff done in like a week and a half. I was, I really needed a break after that, but then I,

00:32:26.940 --> 00:32:27.520
I was good.

00:32:27.520 --> 00:32:28.100
Yeah, cool.

00:32:28.100 --> 00:32:32.880
Yeah. Cool. Well, thanks for the update. Yusef, anything you want to share on the way,

00:32:32.880 --> 00:32:34.080
way out into the show?

00:32:34.080 --> 00:32:39.960
I just want to say thank you for letting me or being able to participate in this quick and brief podcast.

00:32:40.420 --> 00:32:44.400
Keep doing what you do guys. I follow you both on Twitter and what you share and what you do is really

00:32:44.400 --> 00:32:48.720
amazing. So it's really inspiring for an engineer who wants to delve into the field of Python and

00:32:48.720 --> 00:32:53.560
all fancy kind of things to, to listen to your podcast, taking your courses or following you

00:32:53.560 --> 00:32:58.360
on social media. It's really great. You learn a lot and I actually have to learn more to be honest

00:32:58.360 --> 00:32:58.920
myself.

00:32:58.920 --> 00:33:00.860
You know, I have to learn more.

00:33:00.860 --> 00:33:01.260
Yeah.

00:33:01.260 --> 00:33:03.780
It never stops. It never stops.

00:33:03.780 --> 00:33:06.440
Yeah. But that's awesome. Thank you so much. Really appreciate that.

00:33:06.440 --> 00:33:07.360
How about you, Michael?

00:33:07.840 --> 00:33:14.260
I have one quick thing, driven by yours, a comment you had last time. So Francisco Silva

00:33:14.260 --> 00:33:22.020
pointed out, we had talked about some of the num pic, Pythonic, the idiomatic numpy stuff that you

00:33:22.020 --> 00:33:27.400
might do and how like, instead of looping over stuff, you can just like add say like two numpy arrays

00:33:27.400 --> 00:33:32.380
and it'll add them or you can, you know, dot product them and whatnot. Right. So one of the things you can do,

00:33:32.380 --> 00:33:37.300
uh, I guess we also talked about like ones and zeros to generate a prebuilt list of those.

00:33:37.300 --> 00:33:43.260
So one of the things he talked about is the all close method. So if you've got floating point numbers,

00:33:43.260 --> 00:33:47.920
one of the things that's really frustrating is like, are these equal? Well, does it mean floating point

00:33:47.920 --> 00:33:53.820
numbers equal, right? Like they could be so nearly the same, but not the same, right? They could be within

00:33:53.820 --> 00:34:00.100
an insane amount of closeness, right? Like 10 decimal places and then a one, right? So all close is like,

00:34:00.100 --> 00:34:05.000
well, if they're within, you know, one, one thousandth of each other call, consider them the same.

00:34:05.000 --> 00:34:10.220
Well, all close takes a bunch of parameters that you can, you can specify the tolerance though. So yeah.

00:34:10.220 --> 00:34:11.380
Anyway, I thought that was cool.

00:34:11.380 --> 00:34:17.500
Yeah. Hey, while we're on the topic, I may as well throw out, I've got it. I've got it. So I tried to use this method

00:34:17.500 --> 00:34:22.600
of using NumPy and, I ran into a problem. So I'm hoping some data science people can help me

00:34:22.600 --> 00:34:27.600
figure out how to solve it. So my problem is just the simple thing. If I've got two, two arrays,

00:34:27.600 --> 00:34:32.960
I want to see if all of the elements are element wise, less than or equal to the other element in the

00:34:32.960 --> 00:34:39.600
other array. Okay. I can do that with NumPy, but what I can't, that assumes that all of the elements are

00:34:39.600 --> 00:34:46.160
the same data type, like comparable. If, if there are strings thrown in there, it doesn't work. So

00:34:46.160 --> 00:34:51.820
obviously, I don't know if it's obvious, but so I gotta, I had to do some cleanup at a time,

00:34:51.820 --> 00:34:55.960
but I don't know what the most, the best way is. So reach out to me if you've got an answer.

00:34:55.960 --> 00:34:59.980
Awesome. Yeah. I don't have an answer, but I'm sure people do. And, quick, quick comment,

00:34:59.980 --> 00:35:05.940
uh, here, this is the one on my show. Magnus Carlson, says tip. I found out about

00:35:05.940 --> 00:35:12.380
copier and alternative to cookie cutter that can be run later as well to update the project to a newer

00:35:12.380 --> 00:35:18.720
template. That's pretty cool. I hadn't heard of that. And, also Toml spec has reached 1.0.

00:35:18.720 --> 00:35:22.880
parser might be added, added to the standard lib. Also haven't covered that, but that's cool news.

00:35:22.880 --> 00:35:28.160
Thanks for sharing you guys. Yeah. And, I guess thanks for being here. Yousef, thanks for joining

00:35:28.160 --> 00:35:32.680
us and Brian. Thank you as always, man. Thank you. Thank you so much, guys. Bye everyone. Bye.