WEBVTT

00:00:00.001 --> 00:00:04.680
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to

00:00:04.680 --> 00:00:11.840
your earbuds. This is episode 243, recorded July 21st, 2021. And I'm Brian Okken.

00:00:11.840 --> 00:00:13.020
And I'm Michael Kennedy.

00:00:13.020 --> 00:00:14.320
And I'm Simon Willison.

00:00:14.320 --> 00:00:17.220
Welcome, Simon. Thanks for agreeing to show up today.

00:00:17.220 --> 00:00:19.400
No problem at all. I've been looking forward to this.

00:00:19.400 --> 00:00:23.480
If anybody doesn't know who you are, can we do a quick, who's Simon?

00:00:23.480 --> 00:00:28.440
Sure. So yeah, my name's Simon Willison. I've been doing Python bits and pieces for

00:00:28.440 --> 00:00:33.960
around about 20 years now. So I'm a co-creator of the Django web framework from many,

00:00:33.960 --> 00:00:38.480
many years ago. I think Django has definitely celebrated its 15th birthday now.

00:00:38.480 --> 00:00:42.940
But more recently, I've been working on a set of open source tools around the site.

00:00:42.940 --> 00:00:48.660
This project I have called Dataset, which is a web application for exploring a relational database,

00:00:48.660 --> 00:00:52.580
a SQLite database. But it also has tools for publishing those databases online,

00:00:52.580 --> 00:00:56.000
building those databases out of lots of different sources of data. I'm trying to

00:00:56.000 --> 00:01:02.140
bootstrap an entire ecosystem of data and analytics tooling around SQLite, because it turns out

00:01:02.140 --> 00:01:06.360
everyone in the world has SQLite, even though they don't necessarily know that they have it.

00:01:06.360 --> 00:01:08.400
And there's some really cool stuff that you can do with it.

00:01:08.400 --> 00:01:09.840
Yeah, it's a really cool project.

00:01:09.840 --> 00:01:13.160
Yeah, it is. If you wanted to create your own personal search engine, that would let you just

00:01:13.160 --> 00:01:18.900
go and say, search your Gmail, your Twitter, your Instagram, and your file system all at once.

00:01:18.900 --> 00:01:19.440
Yep.

00:01:19.500 --> 00:01:20.400
That's pretty much it, right?

00:01:20.400 --> 00:01:25.060
That's part of the tooling. Yeah, there's a whole side of it, which I've called dog sheep

00:01:25.640 --> 00:01:30.160
ridiculous reasons. But the dog sheep project is about personal analytics, it's about getting

00:01:30.160 --> 00:01:36.260
your personal tweets and messages and all of the personal data about yourself into one place.

00:01:36.260 --> 00:01:40.280
So you've got essentially a little mini data warehouse on your laptop that you can use to

00:01:40.280 --> 00:01:45.000
query aspects of your own life. And that's been a really fun way of driving features in the software,

00:01:45.000 --> 00:01:48.700
which can then be applied to like company databases and so forth as well.

00:01:49.060 --> 00:01:50.720
Yeah, super cool.

00:01:50.720 --> 00:01:55.160
Well, if I didn't want to do SQLite, I might want to use Mongo. What do you think?

00:01:55.160 --> 00:02:03.000
You may want to. And so there's some big news around MongoDB. MongoDB 5 is out, which, you know,

00:02:03.000 --> 00:02:08.620
I'm all about MongoDB, which makes me super excited. Probably won't switch right, right away because I

00:02:08.620 --> 00:02:13.160
don't actually need the features that are there, but I'm super excited to see things going strong.

00:02:13.160 --> 00:02:18.700
So some of the things that are relevant, and I think they're really relevant to Python people,

00:02:18.700 --> 00:02:25.080
especially the data science side. So basically there's, there's two important things. One has

00:02:25.080 --> 00:02:31.080
to do with working with time series and the other has to do with stability of the app that you don't

00:02:31.080 --> 00:02:36.040
want to keep changing so that you can upgrade your database, right? Like if the database API

00:02:36.040 --> 00:02:40.180
slightly changes, you don't want to have to deal with those incompatibilities until you're ready to take

00:02:40.180 --> 00:02:45.880
advantage of the benefits of making those changes. So one of the things that comes with is in the

00:02:45.880 --> 00:02:52.040
database that are native time series schemas and collection types. That's incredible. Yeah. So

00:02:52.040 --> 00:02:58.860
you can do really interesting things like a moving average as a query with across like data and stored

00:02:58.860 --> 00:03:03.500
data in a format that's meant to make that incredibly fast and low latency, but you can also do like,

00:03:03.500 --> 00:03:10.440
I would like the numerical derivative over time as a moving average, as a query or the integral

00:03:10.440 --> 00:03:17.620
of this collection has it. So you can do like math as part of your query and get it to calculate those

00:03:17.620 --> 00:03:22.560
things in really interesting ways. So the time series has things like clustered indexes and window

00:03:22.560 --> 00:03:28.680
functions and all sorts of interesting things. So that's one. it automatically optimizes your schema

00:03:28.680 --> 00:03:33.720
for high efficient storage, which is pretty cool. That's think independent of the time series, but not

00:03:33.720 --> 00:03:39.560
a hundred percent sure. it has the other big thing is the versioned API for future proof apps.

00:03:39.560 --> 00:03:44.600
So suppose you build against version, I guess five is the one that has it. Do you build against version

00:03:44.600 --> 00:03:49.740
five of MongoDB? And then eventually some point like version seven comes along and like, Oh, you can do this

00:03:49.740 --> 00:03:53.980
new way of querying, but it's going to break some stuff. So you want to use it. You got to fix your app.

00:03:53.980 --> 00:04:00.060
You can just say, I want the database to look like version five forever. And no matter what version

00:04:00.060 --> 00:04:05.240
is in production, it'll, it'll behave the right way according to what you said you wanted it to

00:04:05.240 --> 00:04:09.260
behave right. So you could say, I want version seven to be like five for me, but it can be version seven

00:04:09.260 --> 00:04:13.500
for someone else. That kind of thing. Yeah. The other thing, the way that you talk to it, the way that you

00:04:13.500 --> 00:04:19.380
interact with it is through just a terminal app you fired up or a command prompt app and you talk to it.

00:04:19.380 --> 00:04:24.980
And traditionally this thing has been gross. It's been like, it's fine, but it has zero syntax

00:04:24.980 --> 00:04:31.040
highlighting. It has zero autocomplete those types of things, right? So they're introducing a new shell.

00:04:31.040 --> 00:04:37.260
So traditionally you would have typed Mongo, enter connected. Now you type Mongo SH because the old

00:04:37.260 --> 00:04:42.580
one is still there for compatibility reasons, but that one now has syntax highlighting, better error

00:04:42.580 --> 00:04:48.020
checking, pretty printing, autocomplete, things like that. So if you're going to do stuff on the shell,

00:04:48.020 --> 00:04:50.880
then you really should just run the new one. That's pretty cool. I'm going to go with

00:04:50.880 --> 00:04:52.620
Mongo SH as the,

00:04:52.620 --> 00:04:58.760
Oh my gosh. Oh my gosh. What are you doing? Yeah. I'm running the shell, the new one. I know that's

00:04:58.760 --> 00:05:05.160
pretty awesome. And then also they, they're talking about having serverless, serverless instances.

00:05:05.160 --> 00:05:10.240
So like Lambda, Lambda type functions where you don't actually have to manage the database or things

00:05:10.240 --> 00:05:14.760
like that. So I didn't know a whole lot about it. You can also watch the, keynote and actually

00:05:14.760 --> 00:05:19.620
their whole conference, the keynote is probably most relevant here. It turns out that it's for a

00:05:19.620 --> 00:05:24.180
public billion dollar company or whatever they're worth. It's incredibly amateur amateurish and,

00:05:24.180 --> 00:05:29.580
and like more like a talent fair of like a high school or something like that, but whatever you'll

00:05:29.580 --> 00:05:34.460
still learn. I mean, it's like, you'll, you'll see it's, it's like super. I have to check it out now.

00:05:34.460 --> 00:05:40.680
Yeah. It's like worth watching for the, like the blush worthy, like, Oh,

00:05:40.820 --> 00:05:46.680
Oh, Oh, come on. Okay. Well, let's just move on now, please. But nonetheless, you do, they do,

00:05:46.680 --> 00:05:51.080
uh, demo some interesting things and whatnot. So that's probably enough on that. But if you're

00:05:51.080 --> 00:05:54.660
into MongoDB, MongoDB five has a lot of cool things to talk about there.

00:05:54.660 --> 00:05:57.300
You know what else is cool and coming up?

00:05:57.300 --> 00:05:59.260
Python 311.

00:05:59.260 --> 00:06:06.120
We don't, we don't even have Python 310 yet. So, well, I do. you, the beta is available

00:06:06.120 --> 00:06:12.860
for three 10, you can run it, but the alpha is around for three 11, which is a neat. Nice.

00:06:12.860 --> 00:06:20.520
and, what I wanted to highlight here was, highlight, was enhanced error locations

00:06:20.520 --> 00:06:26.120
in tracebacks. I'm so excited about this. This is so cool. So, I mean, Python has not been

00:06:26.120 --> 00:06:32.020
that bad for tracebacks. I've, I've dealt with worse tracebacks, but the, it points out what

00:06:32.020 --> 00:06:36.740
line that's going on, but sometimes there's like weird stuff, like none, not irrefrencible or

00:06:36.740 --> 00:06:42.820
something. And you don't know what's going on, but now it'll in three 11, it will point to exactly

00:06:42.820 --> 00:06:47.600
what part of the line has the error, with little, little carrots underneath pointing

00:06:47.600 --> 00:06:52.520
exactly where it's at. That is actually super cool. So like the example you got on the screen here on the

00:06:52.520 --> 00:07:00.500
announcement, you've got multiple objects being accessing their fields, like 0.1.x, 0.2.x. And the

00:07:00.500 --> 00:07:06.720
error is none type object has no attribute X, which is probably the most common error that you'll ever

00:07:06.720 --> 00:07:13.180
find in Python. But what I like about it that you're pointing out here is like the second object is the

00:07:13.180 --> 00:07:17.700
one that is none. And it actually highlights, no, no, not the first one, the second one, because there's

00:07:17.700 --> 00:07:21.980
nothing about the error message that would tell you which of these two things was the problem.

00:07:21.980 --> 00:07:27.320
Yeah. That's awesome. Yeah. And it's, it's deep into the, so if you have a deep stack trace,

00:07:27.360 --> 00:07:32.360
it'll show you exactly where into it. And even like there, there's another example where it shows

00:07:32.360 --> 00:07:39.780
like, deep into a dictionary, deep dictionary, D reference or something, right. And it, and it

00:07:39.780 --> 00:07:46.880
points out exactly which index is the one that's messing up. so that's pretty amazing. also even

00:07:46.880 --> 00:07:52.960
math, arithmetic expressions, like a division by zero, you've got multiple divisions, which one

00:07:52.960 --> 00:07:57.320
is the problem? And it'll show you exactly which one it is. The thing I love about this,

00:07:57.320 --> 00:08:02.320
change is this is one of those things. This is absurdly difficult. Like this is like acres

00:08:02.320 --> 00:08:06.600
of computer science and a bunch of people working together on this for, I couldn't even imagine

00:08:06.600 --> 00:08:11.400
how long it took them to do, to make something, which is just a beautiful little incremental

00:08:11.400 --> 00:08:15.880
improvement to our lives as Python developers. But if you, if you, I think the release notes

00:08:15.880 --> 00:08:19.600
actually talk about some of the internal changes they had to make that to get this to work. This

00:08:19.600 --> 00:08:24.400
is like really deep stuff and it's totally worth it for what you get out of it. But it it's, I think,

00:08:24.400 --> 00:08:28.400
I think it's easy to look at this and think, okay, that's a reasonably sensible, small change.

00:08:28.400 --> 00:08:29.400
And this was not a small change at all.

00:08:29.400 --> 00:08:35.400
And I think it's going to dramatically increase the on-ramping of new people into Python because,

00:08:35.400 --> 00:08:41.400
um, being able to like figure out what's wrong with your code, that's, you know, basics.

00:08:41.400 --> 00:08:47.400
I mean, some of us old hatters, are used to digging into like confusing tracebacks, but,

00:08:47.400 --> 00:08:51.400
um, some new people are not. So if we can make them less confusing, that'll be great.

00:08:51.400 --> 00:08:55.400
Right. When I work with new programmers, it's so common. You get it, they get a traceback and

00:08:55.400 --> 00:09:00.200
they freeze because this utter, utter meaningless junk has just shown up on their screen. And what

00:09:00.200 --> 00:09:04.120
are they supposed to do with that? And here it feels like this is just such a huge improvement because

00:09:04.120 --> 00:09:08.440
at least it's pointing to the bit in the giant blob of text that they should be paying attention to.

00:09:08.440 --> 00:09:12.760
Yeah. Lovely. Yeah. I want it in 3.10 though, but we have to wait till 3.11.

00:09:12.760 --> 00:09:20.280
From futures, import nice stack trace or trace back. Yeah. Very cool. All right. So Simon,

00:09:20.280 --> 00:09:26.680
you got the third one. Tell us all about it. Okay. So fly.io, a hosting provider who I've been,

00:09:26.680 --> 00:09:29.960
they launched about a year ago. I've been following along because they're doing some really interesting

00:09:29.960 --> 00:09:34.440
stuff around hosting Docker containers and all my stuff is in Docker containers. So I'm always looking for

00:09:34.440 --> 00:09:39.240
things where I can throw a docking container to host online. Their secret sauce is that they do

00:09:39.240 --> 00:09:46.040
geographic hosting. So you can ask them to run your container in like Tokyo and San Francisco and London,

00:09:46.040 --> 00:09:51.320
and they will do that and they will direct traffic to the closest version of that app. So it's this

00:09:51.320 --> 00:09:56.120
thing. I worked at Eventbrite for many years. And one of the things I was always trying to figure out was,

00:09:56.120 --> 00:10:01.720
okay, could we run Eventbrite close to our users? Could we have like European, a database in Europe

00:10:01.720 --> 00:10:06.520
and a database in New York and give people a faster experience that way? Incredibly difficult to do.

00:10:06.520 --> 00:10:12.600
Right. But what a lot of people do is they do CDNs. So the static content, but then there's one server

00:10:12.600 --> 00:10:17.560
somewhere that is really the one, right? That's the problem. It's the database, it's the application code

00:10:17.560 --> 00:10:23.000
and then it's the database server, especially. And so what fly.io are doing is making it so much easier

00:10:23.000 --> 00:10:27.880
to do this, that you could start a project and have it geographically distributed from day one without

00:10:27.880 --> 00:10:31.800
having to think particularly hard about it. So I like that about them. But then they wrote this,

00:10:31.800 --> 00:10:37.400
this, this article came out within the last week, I think. And it talks about their plan for multi-region

00:10:37.400 --> 00:10:43.160
databases. And in that case, they're talking about Postgres and this desire to have Postgres data,

00:10:43.160 --> 00:10:48.760
have like Postgres databases distributed around the world. And so when you're doing that, splitting up,

00:10:48.760 --> 00:10:53.320
you're having rights to multiple places remains incredibly difficult, but a very common pattern is you say,

00:10:53.320 --> 00:10:58.680
okay, we're going to have the leads database is in, I don't know, New York and that all of the rights

00:10:58.680 --> 00:11:04.280
go to that. And then any of the reads get spread out to a replica database that's running in different

00:11:04.280 --> 00:11:08.680
places around the world. And that's still a really difficult thing to set up with the geographic load

00:11:08.680 --> 00:11:14.760
balancing. So what they propose is basically run your application all the way around the world and set

00:11:14.760 --> 00:11:19.960
it up so that if anyone tries to write to the database and they're not talking to the leads database

00:11:19.960 --> 00:11:26.120
server, the error gets caught and the application server replies to fly CDN and say, it says, hey,

00:11:26.120 --> 00:11:30.840
we run this request against the leader database in New York. And so the user doesn't see anything at

00:11:30.840 --> 00:11:36.280
all. The user attempts to do something and it works. And what's actually happened is they tried to do a

00:11:36.280 --> 00:11:43.160
right against Tokyo. Tokyo said, oh, we can't handle rights fly invisibly sort of internally redirected to

00:11:43.160 --> 00:11:46.600
New York. And the right happened against New York and the result came back. And so this takes

00:11:46.600 --> 00:11:52.200
geographically distributing your database reads, which used to be, I mean, I was thinking it was

00:11:52.200 --> 00:11:56.440
going to be a team of engineers for six months to get this working. And it's just baked into their

00:11:56.440 --> 00:12:02.440
platform. It's this incredibly elegant piece of sort of systems engineering design that they've done.

00:12:02.440 --> 00:12:07.480
And I was fascinated. I've banged my head against this problem for so long and they just solved it.

00:12:07.480 --> 00:12:11.800
You know, they just said, hey, here's a way it will work. We've shipped it, try it out.

00:12:11.800 --> 00:12:16.440
I, as I, as something of a architecture nerd, this really fascinated me.

00:12:16.440 --> 00:12:21.560
This is fascinating. Yeah. And I can see just, you know, we've got like the retry

00:12:21.560 --> 00:12:26.280
decorators and stuff for various Python functions. Like I could see almost a, you know,

00:12:26.280 --> 00:12:32.360
like retry the right decorator that you put on them. And it just goes, it catches the error and it just

00:12:32.360 --> 00:12:35.960
goes, nope, we're going to send it everywhere it goes. And then, then return the result, right? Like

00:12:35.960 --> 00:12:39.800
Yeah. And it's basically put decorators anywhere you're going to ever do a right and you're good

00:12:39.800 --> 00:12:44.360
to go. Exactly. And in fact, they've even got example code for Ruby on Rails. We don't even

00:12:44.360 --> 00:12:49.240
have to do that. They catch the database error that says, you know, you tried to do a write in a read

00:12:49.240 --> 00:12:54.600
only transaction and they turn that into an HTTP header that replays it against the lead region.

00:12:54.600 --> 00:12:58.600
And that's it. It's like this it's in, on the one hand, it's kind of an awful,

00:12:58.600 --> 00:13:03.880
clergy hack, but it's also genius. Like this is taking six months of engineering work and turning

00:13:03.880 --> 00:13:08.120
it into add these five lines of code. Now your application works all the way around the world.

00:13:08.120 --> 00:13:13.240
It fascinates me. Yeah. This is pretty interesting. Yeah.

00:13:13.240 --> 00:13:17.880
They also, I've got, there's one other link in the show notes. There's a second article they put out

00:13:17.880 --> 00:13:24.840
a few days ago, which is just doing something. It's more about using Redis as a cache in your

00:13:24.840 --> 00:13:31.400
geographical data centers. So you can have a local Redis, like, because I mean, their argument is

00:13:31.400 --> 00:13:35.800
people in London tend to be interested in other things that people in London are interested. Ditto for

00:13:35.800 --> 00:13:41.400
Tokyo. So actually distributing your cache by city normally gives you really good cache hit rates.

00:13:41.400 --> 00:13:46.280
But they also pointed out that, and I didn't know that Redis could do this. Redis can be set up to

00:13:46.280 --> 00:13:52.520
allow rights to supposedly read only replicas. So you can have a local cache that you're writing to and

00:13:52.520 --> 00:13:57.800
reading from, but still have that leader Redis in your main data center that can send rights out to all

00:13:57.800 --> 00:14:03.480
of those replicas. So that gives you cache invalidation from a central point. You can, in your sort of

00:14:03.480 --> 00:14:08.920
lead Redis, you can say, "Okay, everyone delete the cache entry for whatever this thing is." And all of

00:14:08.920 --> 00:14:12.680
those replicas around the world will then delete that cache entry, even though normally they're acting

00:14:12.680 --> 00:14:18.920
independently. And yeah, it's, again, this is for, if you're a systems architecture design nerd, the stuff that

00:14:18.920 --> 00:14:22.280
they're doing is so interesting. I think it's interesting, and I'm not one of those.

00:14:22.280 --> 00:14:25.080
Maybe you are and you didn't realize.

00:14:25.080 --> 00:14:31.480
You will be next year. You will be next year. Fantastic. Yeah, this is super cool as well. And

00:14:31.480 --> 00:14:37.480
yeah, it seems really useful. You know, and it's perfectly in line with like, let's take our app and

00:14:37.480 --> 00:14:44.040
put the logic in multiple places. Because that person is unlikely to move from Tokyo to

00:14:44.040 --> 00:14:51.240
Virginia during a session. But once they start in one place, they're going to stay in that place.

00:14:51.240 --> 00:14:56.840
And so the cache would reasonably just have like their local data on that one instance, right?

00:14:56.840 --> 00:14:57.240
Yeah.

00:14:57.240 --> 00:14:57.880
Yeah.

00:14:57.880 --> 00:15:03.880
Cool. But maybe your CDN or not your CDN, your CMS is like generated a page and everybody needs that

00:15:03.880 --> 00:15:08.200
always to be in sync, right? There's that global data as well. Yeah. So very cool. I like this.

00:15:08.200 --> 00:15:09.080
Check it out.

00:15:09.080 --> 00:15:09.480
Indeed.

00:15:09.480 --> 00:15:09.960
Indeed.

00:15:09.960 --> 00:15:11.560
Well, let's talk about unicorns.

00:15:11.560 --> 00:15:16.920
I love unicorns. So unicorns, the magical creature. And Simon, I'm so glad that you're here

00:15:16.920 --> 00:15:20.680
because we can get your thoughts on this, even if you maybe haven't been like deep down in it.

00:15:21.640 --> 00:15:27.080
So not too long ago, we talked about HTMX, which I'm still a big fan of HTMX. It's a cool like

00:15:27.080 --> 00:15:33.240
sprinkling of magic onto JavaScript stuff onto your page to make it more interactive. But if you're

00:15:33.240 --> 00:15:40.600
doing Django, HTMX is very relevant, but there's also this thing called Django unicorn at Django-unicorn.com.

00:15:40.600 --> 00:15:46.680
It's a magical full stack framework for Django. So the idea is that you can create these templates,

00:15:46.680 --> 00:15:52.200
these interactive templates without going and rewriting everything in like some front end

00:15:52.200 --> 00:15:56.920
framework, like React or something like that. You can skip the JavaScript build tools because

00:15:56.920 --> 00:16:02.040
you know, you've got a lot less of that. And you can skip a bunch of serializers and just use Django

00:16:02.040 --> 00:16:07.960
for like the API bits. So you install unicorn, you create component, and then at the top of your

00:16:07.960 --> 00:16:12.360
template, you put load, you know, percent load unicorn, and then you can just give it a,

00:16:12.360 --> 00:16:18.760
one of these names. So for example, here's a little task. Task one is tell people about unicorn.

00:16:18.760 --> 00:16:24.680
I can add that as too many will tell people about unicorn. And you can see like this cool little thing

00:16:24.680 --> 00:16:30.440
is interacting and it's not a refreshing the page, right? It's like a front end framework type of thing.

00:16:30.440 --> 00:16:36.680
But the way that you write it is you just put some extra complete pieces on there, like unicorn colon

00:16:36.680 --> 00:16:42.280
prevent, submit, prevent, and we're going to do this add function instead. And if somebody hits the

00:16:42.280 --> 00:16:47.320
escape key, we're going to change the value. And you know, that's not JavaScript. Those are just

00:16:47.320 --> 00:16:53.000
HTML attributes, but they turn into JavaScript, right? Which is very cool. So, and then you just put your

00:16:53.000 --> 00:16:59.640
regular Django template business down and, and off it goes. And it turns it into basically something

00:16:59.640 --> 00:17:02.920
that's way more front end framework friendly. Simon, what do you think?

00:17:02.920 --> 00:17:08.760
So as far as I can tell, the real magic here is that they're using, they're doing the trick

00:17:08.760 --> 00:17:13.480
where you render the HTML on the server. In this case, use reusing your Django template. And then the,

00:17:13.480 --> 00:17:19.240
they send back JSON with a blob of HTML in which you then essentially write into an inner HTML to update

00:17:19.240 --> 00:17:25.640
the page. And I love this pattern. Like, this is, sort of fun. I I've always been a big fan of the

00:17:25.640 --> 00:17:30.680
progressive enhancement, method of writing JavaScript where you get the stuff to more or

00:17:30.680 --> 00:17:34.920
less work without any JavaScript at all. And then if there's JavaScript, then you get in page, page

00:17:34.920 --> 00:17:40.120
updates and all of that kind of thing. but there's also one of the problems I've seen with,

00:17:40.120 --> 00:17:44.040
all sorts of lots of engineering shops that try and do that is that you're not writing your templates

00:17:44.040 --> 00:17:48.360
twice. You have the Django templates that know how to do something, and then you have front end templates

00:17:48.360 --> 00:17:53.240
using react or handlebars or whatever that know how to do something. And you have to keep those in sync,

00:17:53.240 --> 00:17:57.720
which is an enormous waste of time for everyone involved. So what they're doing here then is

00:17:57.720 --> 00:18:03.240
they're handling that they're cleaning up that inconsistency for you. You write a, you write a

00:18:03.240 --> 00:18:08.760
Django template. They can then render, they can use that template in Python code to generate just that

00:18:08.760 --> 00:18:12.760
fragment of HTML, send that back and have that displayed on the page. So yeah, I think this is

00:18:12.760 --> 00:18:16.680
a really interesting approach. I've not spent much time with Django unicorn itself, but,

00:18:16.680 --> 00:18:22.120
it also reminds me a bit of the, I think it's called hot, hot, hot wire. The, Ruby on rails

00:18:22.120 --> 00:18:28.360
community built this, this very exciting, framework again, against these kinds of principles,

00:18:28.360 --> 00:18:33.160
just shipping blobs of HTML back and forth. I feel like it's, something like the,

00:18:33.160 --> 00:18:36.680
the mad rush towards single page applications over the past 10 years,

00:18:36.680 --> 00:18:41.560
is mostly resulted in applications that load slower and, take, take, take longer for

00:18:41.560 --> 00:18:48.360
people to build. And they're so inconsistent and they make me so crazy. For example, I'll go to

00:18:48.360 --> 00:18:52.040
like a bank or something and I'll say, all right, I'm going to run my one password,

00:18:52.040 --> 00:18:57.400
pre-fill the page and you'll see it fill out the page. And then you try to submit it. It goes,

00:18:57.400 --> 00:19:01.000
please fill out this field. And there's clearly like an email address or something in there.

00:19:01.000 --> 00:19:05.800
What do you got to do? Go put a space, delete the space. So the JavaScript event triggers because

00:19:05.800 --> 00:19:11.000
they're like, not really, not really HTML. It's all that junk. And it's just like,

00:19:11.000 --> 00:19:16.280
yeah, you know what I'm in. But it turns out what people actually want is they don't want a full page

00:19:16.280 --> 00:19:20.520
reload. Like anyone who's getting into single page apps and so on really, they just don't want that

00:19:20.520 --> 00:19:25.240
flicker when the browser reloads everything. So using this trick where if JavaScript is available,

00:19:25.240 --> 00:19:30.760
you update a section of the page using stuff that came back from an Ajax API totally works. And that,

00:19:30.760 --> 00:19:34.200
that feels like the model here and also the hotline model from Wales.

00:19:34.200 --> 00:19:40.440
Exactly. Yeah. So the HTMX, the hotwire and this, it's all about, let's not write new stuff. Let's

00:19:40.440 --> 00:19:45.160
just take the views and the templates already doing their magic. And let's just put the little pieces

00:19:45.160 --> 00:19:48.120
in there to make them dynamic, which I'm all about this. This is great.

00:19:48.120 --> 00:19:54.520
What I've missed is why is this a Django thing? Is it, is it because it uses the Django templates or is

00:19:54.520 --> 00:19:59.880
that? It looks like it. Yeah. It looks like the magic here is that it's using Django templates.

00:20:00.520 --> 00:20:03.160
It's because it has its own. And the models.

00:20:03.160 --> 00:20:07.720
It provides its own views to us because it needs to provide views that have provided

00:20:07.720 --> 00:20:12.600
JSON API where you can send it data from a form. It then renders that Django template in Python code

00:20:12.600 --> 00:20:17.160
and then sends you back the stuff. So there's two sides to this, right? There's the Python Django

00:20:17.160 --> 00:20:20.760
view functions they've written, but they've also written a sort of eight kilobytes, I think of

00:20:20.760 --> 00:20:24.520
JavaScript that, that, that, that hooks it up on the front end. Cool. Nice.

00:20:24.520 --> 00:20:30.920
Yep. Yep. Very neat. So not very much code at all to get your Django to become more dynamic,

00:20:30.920 --> 00:20:37.560
which is great. Yeah. So, our, I don't think unicorns are blue. I'm not really sure what

00:20:37.560 --> 00:20:42.840
color unicorns. I feel like they could be any color. Like they might be rainbow, but, but this, that actually,

00:20:42.840 --> 00:20:50.280
that's not a rainbow. It's not a rainbow. I want to, I want to talk about blue and I'm, I'm, I think I'm,

00:20:50.280 --> 00:20:55.240
I think I'm ready, to have tomatoes thrown at me or something for bringing this up.

00:20:55.240 --> 00:21:05.720
but so blue is, is an alternative to black. anyway. so I love black. I think black's awesome,

00:21:05.720 --> 00:21:13.960
but there are times where you can't use it. and in the, for specific reasons. And, I'm thinking

00:21:13.960 --> 00:21:20.360
here may see basically about the decision that black made to default to, not a default,

00:21:20.360 --> 00:21:27.480
but enforce, double quotes on strings instead of single quotes. There are some code bases where

00:21:27.480 --> 00:21:32.760
there's already a standard to use single quotes. And then there's also code bases where there's so

00:21:32.760 --> 00:21:39.320
many strings that actually have mixed quotes. So you've got, single quotes and then double quotes

00:21:39.320 --> 00:21:45.720
inside. And you know, mine end up mixed sometimes because if I want to put quote something in the

00:21:45.720 --> 00:21:50.280
actual string, I'll use single quotes on the outside. But if I'm going to say it's a good idea,

00:21:50.280 --> 00:21:55.000
I'll put double quotes on the outside. So I don't have to escape the single quote. You know, like if,

00:21:55.000 --> 00:21:58.840
if you're going to have one of the quotes in the string, then just go with the other one is often

00:21:58.840 --> 00:22:03.560
something I'll end up doing. Oh, but actually, black does that for you. If you've got a string

00:22:03.560 --> 00:22:07.480
with a single quote in a string with a double quote, and that's the one time that black will use single

00:22:07.480 --> 00:22:11.880
quotes, which is kind of neat. Okay. Okay. That's good. Yeah. Good to know. I do like that,

00:22:11.880 --> 00:22:17.720
but okay. So if this is this, the sticking point is really just the quotes, then maybe try blue.

00:22:17.720 --> 00:22:23.000
So blue is, is actually, I was worried that it was going to be a fork of black. It's not a fork. It's,

00:22:23.000 --> 00:22:29.720
um, it's sort of, in includes black and it like, overwrites some of the functionality

00:22:29.720 --> 00:22:35.720
and specifically just a few things. So the differences are the defaults to single quote strings,

00:22:35.720 --> 00:22:40.920
um, and except for, except for things with places where we love double quotes, like,

00:22:40.920 --> 00:22:45.720
doc strings and triple credit switch strings. For some reason, those look weird with single quotes.

00:22:45.720 --> 00:22:52.600
So, I'm on board with that. it defaults the line lengths to 79 and I don't really care.

00:22:52.600 --> 00:22:58.040
Cause I always override that to like 120 or something like that. and I like black that black allows

00:22:58.040 --> 00:23:03.000
that overriding. and then the other thing that I didn't even think about, which is kind of nice is,

00:23:03.000 --> 00:23:08.200
uh, one of the things black does is, takes the hash. like if you have, hash comments

00:23:08.200 --> 00:23:13.320
on the, on your right side of your code, you've got like a block of them. Like, like maybe you're

00:23:13.320 --> 00:23:18.920
talking about an entire block of code. So you have a block of comments, black alike, remove the

00:23:18.920 --> 00:23:24.360
white space in front of the hash, whereas blue will leave those alone. So you can have block comments

00:23:24.360 --> 00:23:30.920
on the side. that's really it. That's the only difference. and I think having this

00:23:30.920 --> 00:23:35.720
around is a neat thing. interesting quote from the doc is that they'd actually don't want to keep,

00:23:35.720 --> 00:23:40.440
uh, keep this project alive for very long. They'd really like these to just be options in black.

00:23:40.440 --> 00:23:41.560
Yeah.

00:23:41.560 --> 00:23:43.560
I don't know how viral they'll get, but.

00:23:43.560 --> 00:23:43.560
Yeah.

00:23:43.560 --> 00:23:49.560
I don't think that's going to happen. I think black is pretty hardcore guarantee.

00:23:49.560 --> 00:23:53.640
like they're very into not adding configuration where they can still avoid it.

00:23:53.640 --> 00:24:00.120
Yeah. in researching this, one of the things I, somehow missed about black,

00:24:00.120 --> 00:24:03.960
maybe I haven't read the documentation in a long time, but a couple of years ago,

00:24:03.960 --> 00:24:09.960
uh, it added, the ability to have format off and format on. So, one of the things,

00:24:09.960 --> 00:24:16.040
for instance, occasionally, not very often, occasionally I've got a large chunk of data

00:24:16.040 --> 00:24:23.320
set up in, in like a, a list or, or dictionary, something with, that I have called the,

00:24:23.320 --> 00:24:30.680
I have them aligned with comma alignment, like an old style CSV table. and black totally like

00:24:30.680 --> 00:24:32.040
a 19 80 C programmer.

00:24:32.040 --> 00:24:38.360
Yeah. Oh, sure. but black totally tears that apart, but for that you can, you can turn formatting

00:24:38.360 --> 00:24:40.280
off and, I appreciate that.

00:24:40.280 --> 00:24:42.040
Oh, that's cool. That's a good feature.

00:24:42.040 --> 00:24:47.400
Yeah. See, it does have a little bit of, a little bit of give. but yeah.

00:24:47.400 --> 00:24:50.440
Yeah. That's cool. Yeah. Very good one. Very good one.

00:24:50.440 --> 00:24:51.320
So we got next.

00:24:51.320 --> 00:24:57.800
Oh, okay. so this is, there's a link in the show notes. This, this is an article that,

00:24:57.800 --> 00:25:04.280
somebody wrote about using Tesseract OCR to build yourself a searchable index of your screenshots.

00:25:04.280 --> 00:25:10.360
and I got really excited about this because Tesseract is like, Tesseract's been around since 1995,

00:25:10.360 --> 00:25:15.480
I think it's a huge, it was started off at Hewlett Packard and it's pretty much still the leading

00:25:15.480 --> 00:25:19.560
light of OCR in the open source space, but I've never managed to get it to work. And I've always

00:25:19.560 --> 00:25:25.400
wanted OCR that I can just run. And thanks to this article, I can actually use Tesseract now. So

00:25:25.400 --> 00:25:30.440
I've got a couple of demos here. Can we see this? Yeah. So, I grabbed a screenshot just of the,

00:25:30.440 --> 00:25:36.040
a random slide from our conversation earlier and I can run, let's see, I think it's Tesseract,

00:25:36.040 --> 00:25:41.560
screenshot.png. I'll put it in a file called screenshot dash. You have to tell it the language

00:25:41.560 --> 00:25:45.560
that you're using because that affects how it does these things. And it's what's like 70 odd languages,

00:25:45.560 --> 00:25:51.240
I think. and I'm going to say, I want that as a TXT file and you run it. And now if I can't

00:25:51.240 --> 00:25:58.440
screenshot.txt, this is the launch today, MongoDB 5.0. This is the screenshot I took of our conversation

00:25:58.440 --> 00:26:04.280
earlier. A better example even would be the, I took a screenshot of Python documentation just now.

00:26:04.280 --> 00:26:11.400
So I can run that same command, except I'll do it against Python docs.png, Python docs.png. I'll call

00:26:11.400 --> 00:26:19.800
it P screenshot. There we go. Okay. And now if I cat this, this is pretty decent OCR against the screenshot

00:26:19.800 --> 00:26:25.400
of a pilot documentation. The really fun thing though, is that you can say you want it as a PDF file.

00:26:25.400 --> 00:26:29.960
And if you do that, it will give you a PDF, which is visually identical to the screenshot,

00:26:29.960 --> 00:26:36.360
but has selectable text on it. So you can copy and paste out of that PDF. So, the chap whose

00:26:36.360 --> 00:26:43.560
article is linked in the, in the notes, his trick is he has a folder on his

00:26:43.560 --> 00:26:49.000
computer that he saved screenshots to, and he has a automated script that then turns those screenshots

00:26:49.000 --> 00:26:54.360
into these annotated PDFs, which means that spotlight on his Mac can now search them. So anything that he

00:26:54.360 --> 00:26:58.920
drops into that folder, a few seconds later becomes available to global search on his computer.

00:26:58.920 --> 00:27:00.920
I think that's a really neat trick.

00:27:00.920 --> 00:27:02.360
I love it. That's great.

00:27:02.360 --> 00:27:08.200
Then the, so yeah, there's so much stuff I want to do with this. yeah, it was Alec,

00:27:08.200 --> 00:27:14.600
Alexandru Nedlesu. I don't know if I'm pronouncing that correctly. wrote all of this up. but yeah,

00:27:14.600 --> 00:27:19.240
it's, it's, it's, you can install it with homebrew. It's brew install tesseract. There's

00:27:19.240 --> 00:27:23.960
actually a Python library called PI. I think it's called PI tesseract, which I thought was doing

00:27:23.960 --> 00:27:28.120
complicated things with C modules. Actually, if you read the source, it's just shelling out to this

00:27:28.120 --> 00:27:34.520
command. So apparently that's the state of the art in, in Python, OCR is shell out to the tesseract

00:27:34.520 --> 00:27:37.160
command line tool, which I'm perfectly happy to do, you know?

00:27:37.160 --> 00:27:43.000
Yeah. I really like this. You know, it's, if you've got a bunch of image data and you want to

00:27:43.000 --> 00:27:47.880
be able to do interesting things with it, like here's a really quick and easy way to do it. Right.

00:27:47.880 --> 00:27:53.720
Right. It's super simple. The, this article also, I didn't know that you could use the Mac,

00:27:53.720 --> 00:28:00.120
launch D I think you can use, you can add a launch agent, which automatically runs a script when a file

00:28:00.120 --> 00:28:04.920
is saved in a certain folder. So in this case, he's got a launch script that runs the, the, the

00:28:04.920 --> 00:28:09.480
test rack to OCR stuff, but this is great right now. I can automate any folder on my Mac to do

00:28:09.480 --> 00:28:13.640
basically anything using this system that's built into the operating system, but I didn't know how to

00:28:13.640 --> 00:28:18.360
use. I didn't know you could do that either. That's great. That's cool. Yeah. Yeah. That's awesome.

00:28:18.360 --> 00:28:24.280
I feel like this is right up your alley, Simon, you know, with the data set, the dog sheep and like,

00:28:24.280 --> 00:28:29.640
oh, here's this data we got from this, this automation. And yet I just can't dig into it. And now you can.

00:28:29.640 --> 00:28:34.600
I'm really excited about this. Although, so Apple photos, the next version of macOS,

00:28:34.600 --> 00:28:39.800
Apple photos is going to do OCR and all of your photographs for you. So you can search for text

00:28:39.800 --> 00:28:44.280
in pictures that you've taken. And, if it's anything like the current version of,

00:28:44.280 --> 00:28:48.600
our sex photos, all of that data is going to be stored in SQLite databases on your computer.

00:28:48.600 --> 00:28:54.520
Like I've been, having a huge amount of fun building things against my Apple photos library,

00:28:54.520 --> 00:28:59.800
because they already run machine learning labeling against your photos. They know when you take a photo of

00:28:59.800 --> 00:29:04.760
a dog and they tag it with dog and the word dog is in a SQLite database on your computer.

00:29:04.760 --> 00:29:09.480
So once you've figured that out, you can run SQL queries against photos you've taken and say,

00:29:09.480 --> 00:29:17.000
say, show me every photo I've taken of a dog that was in San Francisco on like in the month of May.

00:29:17.000 --> 00:29:19.800
And you get results back, which is crazy interesting.

00:29:19.800 --> 00:29:20.280
Yeah.

00:29:20.280 --> 00:29:21.640
That's pretty cool.

00:29:21.640 --> 00:29:25.000
Yeah. That's super cool. I love the stuff that you're doing with that.

00:29:25.000 --> 00:29:30.520
Is it just local or is there, are they caching that in their own databases as well?

00:29:30.520 --> 00:29:35.320
Oh, well, so they synchronize it all. So if you're using iCloud, your photos are synchronized up to

00:29:35.320 --> 00:29:40.280
their servers that you take a photo on your phone, it shows up on your computer automatically, but all

00:29:40.280 --> 00:29:45.960
of it's the actual local data storage is all SQLite database files. Apple are really big into SQLite.

00:29:45.960 --> 00:29:50.280
So yeah, there are just these files littering your computer with your address book in there and all of

00:29:50.280 --> 00:29:56.040
your iMessages and all of your photo metadata, it's just sat there waiting for you to dig in and play

00:29:56.040 --> 00:29:56.440
with it.

00:29:56.440 --> 00:29:59.160
Nice. With dataset, probably.

00:29:59.160 --> 00:30:05.640
Right? Yep. I've got a script called, I'll add it to the show notes. I've got a script called Dog

00:30:05.640 --> 00:30:11.720
Sheep Photos, which uploads your photos to your own S3 bucket so that you can actually link to them and

00:30:11.720 --> 00:30:17.720
embed them on web pages. And it extracts all of that SQLite data into a more usable format. So yeah,

00:30:17.720 --> 00:30:23.320
I've got a online database of all of my photographs that I update every now and then with the script.

00:30:23.320 --> 00:30:25.960
And it works. It's phenomenal what you can do with it.

00:30:25.960 --> 00:30:26.600
Cool.

00:30:26.600 --> 00:30:31.960
Out in the live scene, Brandon, hey, Brandon says, this is fantastic. Definitely excited.

00:30:31.960 --> 00:30:38.200
And also taking a step back to yours, Brian, David Colton. Hey, David says, I'm using double quotes now

00:30:38.200 --> 00:30:43.640
in black, but my typing has not evolved yet to double quotes. So you just pass it through the single

00:30:43.640 --> 00:30:48.440
quote to double quote compiler process called black. And then you got it all adapted. That's nice.

00:30:48.440 --> 00:30:49.240
Yeah.

00:30:49.240 --> 00:30:56.200
I've saved like black has given me back. I estimate 5% of my program typing time used to be worrying

00:30:56.200 --> 00:31:01.240
about indentation and such like, and I got all of that back. Like, thanks to black. I never even

00:31:01.240 --> 00:31:07.960
think about how I indent or style my code at all. I just say, I, I, I'll literally write horrible run on

00:31:07.960 --> 00:31:13.400
lines that go on for ages and then run black and it formats it nicely. And I forget about it. It's,

00:31:13.400 --> 00:31:14.680
it's wonderful. It's fantastic.

00:31:14.680 --> 00:31:15.560
That's cool.

00:31:15.560 --> 00:31:16.440
Yeah. Great.

00:31:16.440 --> 00:31:18.440
got any extras for us, Michael?

00:31:18.440 --> 00:31:23.880
you know, I do. I always do. Unless I have an extra, extra, extra, you're all about it. Then I

00:31:23.880 --> 00:31:31.800
guess I still do. So, we talked about strong typing last time, which lets you do cool stuff like

00:31:31.800 --> 00:31:37.720
go and put a decorator onto a function and say, well, this one, you know, if it has type

00:31:37.720 --> 00:31:43.560
and annotations or type information, like Python itself just does, if you put at match typing the

00:31:43.560 --> 00:31:48.520
decorator on there, it'll verify it runtime that you said it took an integer and you actually pass

00:31:48.520 --> 00:31:52.120
an integer, not a list or whatever to that parameter. Right. Yeah.

00:31:52.120 --> 00:31:56.920
Well, Felix, who maintains this project reached out today that actually does a whole lot more

00:31:56.920 --> 00:31:59.720
that you should check some other things out. I just wanted to highlight a couple of things that

00:31:59.720 --> 00:32:05.080
he pointed out one. If we, you know, we're all familiar with the named tuple and you, you say

00:32:05.080 --> 00:32:12.040
the type name in a quote, and then you say the fields or the elements attributes in a list, either

00:32:12.040 --> 00:32:19.400
space or comma separated, like spell, mana, fact, and so on. So this one has a typed name tuple where

00:32:19.400 --> 00:32:23.640
you can put the type information in very similar ways to what Python would have like colon,

00:32:23.640 --> 00:32:29.400
str, colon list, and so on. And then you get actual type runtime validation that your

00:32:29.400 --> 00:32:33.880
data going into your named tuple is actually the type of data you expect in your name tuple.

00:32:33.880 --> 00:32:34.760
Oh, nice.

00:32:34.760 --> 00:32:34.760
That's good.

00:32:34.760 --> 00:32:35.560
Isn't that neat?

00:32:35.560 --> 00:32:35.800
Yeah.

00:32:35.800 --> 00:32:36.280
Yeah.

00:32:36.280 --> 00:32:41.720
Yeah. So there's that. And then also, I love this about our show. It's, it's kind of blows my

00:32:41.720 --> 00:32:46.920
mind that this, this is how the world works. And I really appreciate this. Everyone who plays along,

00:32:46.920 --> 00:32:52.360
we'll say things like, oh, I wish we could specify indexes in Beanie. And then like the next episode,

00:32:52.360 --> 00:32:59.080
we're like, Hey, look, Roman added a way to do indexes in Beanie. And I said, this is awesome that it applies to

00:32:59.080 --> 00:33:04.040
functions, but why couldn't it apply to classes? It's basically the same thing. And so now six days

00:33:04.040 --> 00:33:11.960
ago, we have a new feature. You can also apply strong typing to classes as well or something

00:33:11.960 --> 00:33:13.880
like that. So well done. Well done.

00:33:13.880 --> 00:33:19.800
Is it because you asked for it? Because I mean, I asked for single quotes in black and I didn't get

00:33:19.800 --> 00:33:20.600
that, but...

00:33:20.600 --> 00:33:27.000
Well, I mean, it also may depend on the size of the project. The more input they get, the less

00:33:27.000 --> 00:33:33.160
influence any individual statement may have on it. Right. Yeah. Anyway, I feel like thanks for

00:33:33.160 --> 00:33:35.320
working on that and the extra information there. Yeah.

00:33:35.320 --> 00:33:42.680
I actually, one other thing. Yes. I have finally, I've been working to make sure that we don't have to

00:33:42.680 --> 00:33:50.440
have one of these completely useless, dreadful talks on technology. Our site uses cookies. Here's our

00:33:50.440 --> 00:33:55.480
cookie policy. Do you accept our cookie policy or do you not accept our cookie policy? AKA, would you

00:33:55.480 --> 00:33:59.320
like our website to work or would you like to go away? Like that's kind of what the button so often

00:33:59.320 --> 00:34:05.640
means. Right. and so I thought I removed all the analytics. I removed anything else that we might

00:34:05.640 --> 00:34:10.440
doing third, be doing third party. We're good. And I went to Python bytes and I'm like, wait, there's,

00:34:10.440 --> 00:34:14.520
there's double click. There's Facebook, there's Google. There's like, what is all this stuff?

00:34:14.520 --> 00:34:20.920
And we started including the live stream YouTube in bed and it started bringing back. And I'm like,

00:34:20.920 --> 00:34:25.080
why would Google be putting in Facebook? That sucks. And there was also the discus

00:34:25.080 --> 00:34:29.880
conversation stuff that people haven't really stopped using. They all just go and chat on the

00:34:29.880 --> 00:34:33.880
YouTube streams. Now they want to have a live comment type of thing. So I'm like, well, I'll

00:34:33.880 --> 00:34:38.920
just take that out. That got rid of the Facebook one. and then, but what do you do about, about

00:34:38.920 --> 00:34:44.520
that? So I, instead of embedding the YouTube player, I said, I'm going to figure out a way to get the

00:34:44.520 --> 00:34:49.880
picture automatically from YouTube, the poster. And then when you hover over it, it just has a play

00:34:49.880 --> 00:34:54.760
icon. It says play on YouTube and it opens up a new window. And I thought I was all clever by just putting

00:34:54.760 --> 00:35:01.160
the image there, but serving it from Google. No, there's now like the YouTube image servers putting

00:35:01.160 --> 00:35:06.840
tracking cookies on our site. I'm like, well, come on. Why is this so hard? So now on the server,

00:35:06.840 --> 00:35:12.280
we use requests. We download the image anytime it has to be shown on a page, put it in MongoDB.

00:35:12.280 --> 00:35:17.720
And then if you pull it, we serve it back out so we can like strip the cookies, the tracking cookies out.

00:35:17.720 --> 00:35:23.480
Nice. And now, now when you look at the tracking content, none detected on the site,

00:35:23.480 --> 00:35:26.360
but why, why world does it have to be so hard? I just want to.

00:35:26.360 --> 00:35:31.320
Isn't it amazing how it used to be YouTube embeds were the absolute gold standard for

00:35:31.320 --> 00:35:35.480
embedding video on a webpage. Like that, why would you do anything else? And now actually I'm beginning

00:35:35.480 --> 00:35:42.280
to think, you know what? Post the video, the .mp.mod file or whatever yourself and stick on an HTML5 video

00:35:42.280 --> 00:35:47.080
embed. And that's probably a better experience for your users as well. Because you know, when they click the

00:35:47.080 --> 00:35:50.760
video on their mobile phone, it'll play full screen and they won't have to hop through to the YouTube

00:35:50.760 --> 00:35:55.720
app and all of that kind of thing. Yeah, absolutely. Yeah. So anyway, just quick shout out, like this is

00:35:55.720 --> 00:36:02.760
taking several passes, but I think it's finally 100% no tracking. I mean, we weren't putting there before,

00:36:02.760 --> 00:36:08.280
but like it was seeping in from just like what we might include on the page as content. Right. So anyway,

00:36:08.280 --> 00:36:14.440
there you have it, Brian. That was my weekend. How was it? Nice. Well, thanks. I appreciate you doing all that work for us.

00:36:14.440 --> 00:36:21.880
Yeah. David Colton has the wash hands emoji. There we go. We're all better. Yeah. Well, I've got no

00:36:21.880 --> 00:36:27.640
extras. Simon, do you have anything extra you want to share? I've got one. So Textual is the,

00:36:27.640 --> 00:36:31.800
you know, and Will McGugan, who's working on Rich has been building Textual, which I know you've talked

00:36:31.800 --> 00:36:36.920
about on the podcast before. What I would encourage people to do is pay close attention because I've never

00:36:36.920 --> 00:36:43.240
seen a piece of open source software developed this quickly. Like every day he's posting this video where he's

00:36:43.240 --> 00:36:50.440
like, oh, and here's the new feature where today he posted a video of it doing full like tree view on a file system,

00:36:50.440 --> 00:36:56.280
which you could interact with with your mouse in the terminal. And when you clicked on a file, it would open it in a separate panel with,

00:36:56.280 --> 00:37:04.600
like with, with syntax highlighting. It's, it's absolutely astonishing. It's like turning into one of the better ways of building a

00:37:04.600 --> 00:37:10.520
GUI application and it's running in, in text in the terminal. We can almost have just a section of the show

00:37:10.520 --> 00:37:17.080
called what's, what's Will up to. You really could. Absolutely. Yeah. He's, he's re implemented CSS grid,

00:37:17.080 --> 00:37:23.800
the CSS grid mechanism for terminal applications. It's brilliant. And yeah, I'm just having such a great time

00:37:23.800 --> 00:37:27.240
watching him do all of this stuff. And he seems to be live streaming it.

00:37:27.240 --> 00:37:33.160
I don't think so, but he posts like little five minute videos on Twitter every day of the stuff that

00:37:33.160 --> 00:37:39.560
he's doing. But I feel inadequate watching him work this fast, but just saying. It's such a delight

00:37:39.560 --> 00:37:44.440
though. It's like he was, he was born to build this piece of software and now he's building it and we all get

00:37:44.440 --> 00:37:50.440
to watch him do it. Yeah. That's great. Yeah. Henry Schreiner out in the live stream says textual is

00:37:50.440 --> 00:37:55.800
amazing. Indeed. It's, it's quite, quite something. Yeah. And I know, I remember when he was trying to

00:37:55.800 --> 00:38:00.840
name it and textual didn't even come up on my radar as something that might be possible, but it's,

00:38:00.840 --> 00:38:08.040
it's so obvious now like graphical and textual. Yeah. It makes sense. It's cool. So, hey, how about a joke?

00:38:08.040 --> 00:38:13.880
Maybe. Oh man, I got some jokes for us. Two jokes. The one, I'm not really sure how to convey it,

00:38:13.880 --> 00:38:20.100
but I, yes, I'll do my best. I want you to sing. No, man, this is you. This is you, bro. All right.

00:38:20.100 --> 00:38:26.100
So first one here is, I could definitely do this one. This one is, from John on Twitter,

00:38:26.100 --> 00:38:30.520
but pointed out to us by Nick Moore, who was previously on the show not too long ago. Thanks,

00:38:30.520 --> 00:38:35.960
Nick. And this one poses, I think also this is perfect for when Simon is on the show. It says,

00:38:35.960 --> 00:38:42.320
what do you get when you select star from goblins, dragons, elves, and comma unicorns,

00:38:42.320 --> 00:38:46.180
a query tale. Oh my goodness.

00:38:46.180 --> 00:38:49.000
It's a fairy tale, a query tale. It's bad.

00:38:49.000 --> 00:38:50.740
It's terrible. It's bad. Oh, wow.

00:38:50.740 --> 00:38:56.700
well, I wanted to share one that people could actually share with their, this isn't in the

00:38:56.700 --> 00:39:01.000
list, but one that people, I just read recently, people might be able to share with their kids.

00:39:01.380 --> 00:39:08.060
in the Northwest, we've got, Sasquatch, right? So, you know what they, yeah, what do they call Bigfoot in Europe?

00:39:08.060 --> 00:39:18.820
Big meter. Oh, it's pretty bad. quick tip. If you're ever near Santa Cruz in California,

00:39:18.820 --> 00:39:24.960
there is a Bigfoot museum in a log cabin in the woods outside of Santa Cruz called the Bigfoot discovery

00:39:24.960 --> 00:39:29.980
experience. And it is not a joke. It is very serious. And there is a man there who will take

00:39:29.980 --> 00:39:34.420
you through all of his evidence for big, Bigfoot. And it takes about an hour. He's got maps and

00:39:34.420 --> 00:39:40.800
plaster casts of feet, footprints and a map with pins on it. And it's fascinating. I could not recommend

00:39:40.800 --> 00:39:41.780
it more. Yeah.

00:39:42.040 --> 00:39:46.780
I wonder if the COVID pandemic has affected the Bigfoot population.

00:39:46.780 --> 00:39:51.560
Oh, you, you should, well, go, go, go, go. You can call him up and ask him while I was talking to him.

00:39:51.560 --> 00:39:57.360
He got a phone call to answer questions about Bigfoot. So he will, he will answer your calls. Yeah.

00:39:57.360 --> 00:40:01.540
All right. Hey, Brian, your joke got a grown all the way from Australia.

00:40:01.540 --> 00:40:03.720
Nice.

00:40:03.720 --> 00:40:06.960
What was it mine? I'm not sure. It could have been either. Honestly.

00:40:06.960 --> 00:40:07.660
Yeah.

00:40:07.660 --> 00:40:09.380
I think I'm going to go with the meter one.

00:40:10.560 --> 00:40:11.720
They were both pretty bad.

00:40:11.720 --> 00:40:18.620
All right. I'll see what I can do this with this next one here. So if, if you're a kid of the nineties,

00:40:18.620 --> 00:40:21.900
I guess it's probably the time there's a pinky in the brain.

00:40:21.900 --> 00:40:29.920
And apparently on one of the 10 places I have to write your name, I typed it too quickly and wrote brain.

00:40:29.920 --> 00:40:33.000
Yeah. And Brett Cannon caught it.

00:40:33.000 --> 00:40:38.980
And so, so he, he did a take on pinky in the brain and it starts out.

00:40:38.980 --> 00:40:40.740
What do you want to do today, Brian?

00:40:40.740 --> 00:40:41.600
Same thing.

00:40:41.600 --> 00:40:45.420
We do everything with every Wednesday, Michael help Python take over the world.

00:40:45.420 --> 00:40:48.720
It's Michael and the brain. Yes.

00:40:48.720 --> 00:40:49.840
Michael and the brain.

00:40:49.840 --> 00:40:52.400
One's into testing others in the GUIs.

00:40:52.400 --> 00:40:55.360
They're both into making Python seem sane.

00:40:55.360 --> 00:40:56.200
They're Michael.

00:40:56.200 --> 00:40:58.760
They're Michael and the brain brain brain.

00:40:58.760 --> 00:40:59.040
Yeah.

00:40:59.040 --> 00:40:59.640
Yeah.

00:40:59.640 --> 00:41:00.500
Fantastic.

00:41:00.500 --> 00:41:00.920
I love it.

00:41:00.920 --> 00:41:01.600
Phenomenal.

00:41:01.600 --> 00:41:07.300
We need to have somebody that's got like musical talent to actually put this together as something.

00:41:07.300 --> 00:41:08.320
So anyway,

00:41:08.320 --> 00:41:08.640
yes.

00:41:08.640 --> 00:41:10.580
Someone who is not me because it won't come out.

00:41:10.580 --> 00:41:10.820
Well,

00:41:10.820 --> 00:41:14.260
so we'll put in this with the lyrics in the show notes.

00:41:14.260 --> 00:41:14.800
Um,

00:41:14.800 --> 00:41:17.940
I think we should leave them there so that we are accepting submissions.

00:41:17.940 --> 00:41:18.360
Yes.

00:41:18.360 --> 00:41:19.400
And if they are,

00:41:19.400 --> 00:41:20.420
if they pass,

00:41:20.420 --> 00:41:23.360
we may actually play them on one of the next episodes.

00:41:23.360 --> 00:41:23.680
Oh,

00:41:23.680 --> 00:41:24.160
I'd love it.

00:41:24.160 --> 00:41:24.580
Yeah.

00:41:24.580 --> 00:41:25.700
Could be the new theme song,

00:41:25.700 --> 00:41:25.980
Brian.

00:41:25.980 --> 00:41:26.740
Yeah.

00:41:27.340 --> 00:41:30.220
I'm getting tired of the old theme song.

00:41:30.220 --> 00:41:30.740
Yeah,

00:41:30.740 --> 00:41:31.240
exactly.

00:41:31.240 --> 00:41:32.700
Which is no theme song.

00:41:32.700 --> 00:41:35.500
All right.

00:41:35.500 --> 00:41:35.700
Well,

00:41:35.700 --> 00:41:36.000
thanks.

00:41:36.000 --> 00:41:36.340
Uh,

00:41:36.340 --> 00:41:37.320
thanks a lot for,

00:41:37.320 --> 00:41:37.840
uh,

00:41:37.840 --> 00:41:39.240
showing up Michael and thanks Simon.

00:41:39.240 --> 00:41:39.800
Um,

00:41:39.800 --> 00:41:40.260
this was fun.

00:41:40.260 --> 00:41:41.180
Thanks for having me.

00:41:41.180 --> 00:41:41.660
Yep.

00:41:41.660 --> 00:41:41.980
You bet.

00:41:41.980 --> 00:41:42.460
Bye everyone.

00:41:42.460 --> 00:41:44.320
Thanks for listening to Python Bytes.

00:41:44.320 --> 00:41:47.120
Follow the show on Twitter via at Python Bytes.

00:41:47.120 --> 00:41:50.220
That's Python Bytes as in B-Y-T-E-S.

00:41:50.220 --> 00:41:53.020
Get the full show notes over at Pythonbytes.fm.

00:41:53.020 --> 00:41:55.080
If you have a news item we should cover,

00:41:55.080 --> 00:41:57.080
just visit Pythonbytes.fm and click,

00:41:57.180 --> 00:41:58.340
submit in the nav bar.

00:41:58.340 --> 00:42:00.460
We're always on the lookout for sharing something cool.

00:42:00.460 --> 00:42:02.320
If you want to join us for the live recording,

00:42:02.320 --> 00:42:07.800
just visit the website and click live stream to get notified of when our next episode goes live.

00:42:07.800 --> 00:42:12.140
That's usually happening at noon Pacific on Wednesdays over at YouTube.

00:42:12.140 --> 00:42:14.300
On behalf of myself and Brian Okken,

00:42:14.300 --> 00:42:15.500
this is Michael Kennedy.

00:42:15.500 --> 00:42:19.220
Thank you for listening and sharing this podcast with your friends and colleagues.