WEBVTT

00:00:00.001 --> 00:00:05.980
We all love the Python language, but it's the 200,000 plus packages that actually make Python

00:00:05.980 --> 00:00:11.920
incredibly useful and productive. But installing these packages and even installing Python itself

00:00:11.920 --> 00:00:17.180
can vary across the different platforms. In particular, Windows has had a hard time.

00:00:17.180 --> 00:00:22.880
Many of the library authors don't use Windows, and so they don't test their packages on that

00:00:22.880 --> 00:00:28.600
platform. Tutorial authors often start their tutorial steps by activating a virtual environment.

00:00:28.600 --> 00:00:34.720
That's great. That's the great first step, but it is usually source venv slash bin slash activate,

00:00:34.720 --> 00:00:41.240
and that doesn't work on Windows. Yet over 50% of all developers programming in Python do so on

00:00:41.240 --> 00:00:47.100
Windows. In this episode, we'll welcome back Steve Dower. He works at Microsoft and is a Python core

00:00:47.100 --> 00:00:52.940
developer. He has a bunch of statistics around Python and Windows for us. He also has tons of

00:00:52.940 --> 00:00:58.240
good news on how Python and Windows is getting much better. This is Talk Python To Me, episode

00:00:58.240 --> 00:01:04.520
243, recorded on location at Microsoft Ignite in Orlando, Florida, November 8th, 2019.

00:01:04.520 --> 00:01:22.980
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem,

00:01:22.980 --> 00:01:27.660
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter where I'm at,

00:01:27.660 --> 00:01:32.960
mkennedy. Keep up with the show and listen to past episodes at talkpython.fm, and follow the show on

00:01:32.960 --> 00:01:38.500
Twitter via at talkpython. Hey everyone, Michael here. I'm excited to tell you about our latest course.

00:01:38.500 --> 00:01:43.780
Yes, we just released one a week or two ago, but here's another. This time, it's a nine-hour course

00:01:43.780 --> 00:01:49.440
called Python for the .NET Developer. The idea is, if you have experience with C# and .NET,

00:01:49.440 --> 00:01:54.340
would like to get better at Python, we'll take a bunch of common applications from the .NET space

00:01:54.340 --> 00:02:00.140
and recreate them in Python. For example, we'll take a data-driven web app in ASP.NET and Entity

00:02:00.140 --> 00:02:05.200
Framework and recreate that in Flask and SQLAlchemy. This means you can take all the concepts and ideas

00:02:05.200 --> 00:02:10.100
that you know if you're a .NET developer and quickly transition to being an effective Python

00:02:10.100 --> 00:02:15.980
developer. Are you the sole Python developer at a .NET shop? Maybe your team or co-workers could quickly

00:02:15.980 --> 00:02:20.780
use their .NET background to get up to speed on Python to make it an important part of your tech stack.

00:02:20.780 --> 00:02:25.040
There's even a For My Team button. Just click that and enter the number of team members you have,

00:02:25.040 --> 00:02:29.880
and you'll probably get a discount to boot. I was also just a guest on the excellent .NET

00:02:29.880 --> 00:02:34.700
Rocks podcast with Carl Franklin and Richard Campbell. If the idea of the Python for .NET

00:02:34.700 --> 00:02:42.780
developer course intrigues you, just visit .NET Rocks.com? show equals 1665 to hear us discuss this from

00:02:42.780 --> 00:02:50.140
both sides of the technology fence. So check out the course at hawkpython.fm slash .NET, D-O-T-N-E-T,

00:02:50.140 --> 00:02:55.120
and convert those C-sharp skills to Python skills. Now, let's go talk with Steve.

00:02:55.120 --> 00:02:59.520
Steve, welcome back to Talk Python To Me. Thanks for having me back. It's great to have you here.

00:02:59.520 --> 00:03:05.660
We're recording on location here at Microsoft Ignite, so a lot of fun to do that at the conference

00:03:05.660 --> 00:03:10.040
here. Yeah, is this your first time at Ignite? It is my first time at Ignite. How have you found it?

00:03:10.040 --> 00:03:16.960
I've been a couple of times. I am very surprised at this place, to be honest. So to me, big conferences

00:03:16.960 --> 00:03:24.040
are PyCon, Microsoft Build is a pretty big conference. This thing is like six times,

00:03:24.040 --> 00:03:29.780
seven times as large as those. The scale is crazy. This is 30,000 attendees, at least on the first day.

00:03:29.780 --> 00:03:34.120
I feel like it drops off. I don't think there's 30,000 today. We're on the last day. It's kind of

00:03:34.120 --> 00:03:39.160
quiet. Yeah, it's way, way more quiet. But yeah, I actually found it really nice. I've made a lot of

00:03:39.160 --> 00:03:44.140
cool connections and met a lot of people. I've met a lot of Python people even here running to some

00:03:44.140 --> 00:03:49.880
folks. So I'm finding it to be a cool event. He had an interesting person come up and ask you about

00:03:49.880 --> 00:03:54.840
your laptop. Oh, yeah, yeah. So it is the mix of the audience. It's not really a developer crowd,

00:03:54.840 --> 00:04:01.380
right? It is sometimes, it is a developer crowd, but it's also an IT crowd. It's a SharePoint crowd.

00:04:01.460 --> 00:04:04.980
It's a DevOps crowd. It's a cloud person. There's like all these different,

00:04:04.980 --> 00:04:09.320
like all the computing IT folks brought together. So I was sitting around actually getting ready for

00:04:09.320 --> 00:04:13.360
this interview to talk to you. I was taking some notes about what we're going to talk about. And

00:04:13.360 --> 00:04:17.880
this guy comes up next to me. He's like, hey, that's a cool Surface book you got there. I don't

00:04:17.880 --> 00:04:22.120
think I've seen that one before. I'm like, it's really cool, but it's a Mac book, not a Surface

00:04:22.120 --> 00:04:27.240
book or Surface laptop or whatever he called it. So yeah, it's just, it's really funny. And I think that

00:04:27.240 --> 00:04:31.300
actually is, it's an interesting angle to what we're going to talk about today.

00:04:31.300 --> 00:04:36.400
Yeah, it's such a different crowd here compared to the Python conferences where we'd normally hang

00:04:36.400 --> 00:04:39.280
out. I feel like, I feel like I've invited you into my house for this one.

00:04:39.280 --> 00:04:43.880
Yeah, I've come to visit you this time, not the other way around. That's right. So yeah, I think

00:04:43.880 --> 00:04:52.340
at PyCon, non-Windows computing or development is pretty common. And here, like, no joke,

00:04:52.340 --> 00:04:57.640
they were mistaking my Mac for a Windows machine and like, oh, well, I only do C#. I'm like,

00:04:57.640 --> 00:05:01.060
okay, that's cool. Yeah, I know C# too, but now I'm doing Python over here right now,

00:05:01.060 --> 00:05:05.100
you know, things like that. And it's cool to be part of these different communities.

00:05:05.100 --> 00:05:09.560
And it has been really exciting to see the change at Ignite over the years and Build, in fact,

00:05:09.560 --> 00:05:14.100
because they are very different communities. But the growing Python that's showing up in them,

00:05:14.100 --> 00:05:19.020
I feel like the first or second time I was at Build and Ignite, which would have been

00:05:19.020 --> 00:05:25.140
2014 or so, about five years ago, people were asking, you know, what's Python? Why are you here?

00:05:25.140 --> 00:05:28.320
Which is, you know...

00:05:28.320 --> 00:05:31.800
What are you doing at our conference? Why did you invade it with your open source weirdness?

00:05:31.800 --> 00:05:36.980
Right, exactly. It's like, what's your angle here? And they were kind of suspicious. And now it's at

00:05:36.980 --> 00:05:42.740
the point where I actually had someone come up to me yesterday and say, you know, because I was here,

00:05:42.740 --> 00:05:46.100
because I was actually here and saw everything going on, I now want to learn Python.

00:05:47.440 --> 00:05:52.620
And that, I mean, I've never heard of that happening at the Microsoft conferences before,

00:05:52.620 --> 00:05:53.460
but that's really exciting.

00:05:53.460 --> 00:05:58.340
It's super exciting. Yeah, it is exciting. You know, I don't know, maybe they saw some kind of

00:05:58.340 --> 00:06:03.060
machine learning presentation or something. They're like, wow, that I thought this was a

00:06:03.060 --> 00:06:04.340
scripting language. Look what they're doing.

00:06:04.340 --> 00:06:09.440
Yeah, we had a lot this year. I think two years ago, I was the only Python presentation at the entire

00:06:09.440 --> 00:06:11.020
conference, which was...

00:06:11.020 --> 00:06:14.560
There's a lot of presentations at this. That's like a very small percentage, right?

00:06:14.720 --> 00:06:19.740
There's like, I don't know, we have this huge screen behind us with about eight sessions

00:06:19.740 --> 00:06:24.280
running in parallel. And that's just this end of the rebroadcasting. There's probably like

00:06:24.280 --> 00:06:27.100
15 tracks or something crazy going on.

00:06:27.100 --> 00:06:27.320
Yeah.

00:06:27.740 --> 00:06:33.680
But no, this year we had like 30 or so sessions about Python. And yeah, ranging a lot of machine

00:06:33.680 --> 00:06:38.800
learning, a lot of data science, a lot of app development stuff. It's...

00:06:38.800 --> 00:06:38.900
Yeah.

00:06:38.900 --> 00:06:40.980
We're covering a lot more angles now and it's really exciting.

00:06:40.980 --> 00:06:44.440
Yeah, it's super cool. It's not exactly what we're talking about today, but we'll talk about it

00:06:44.440 --> 00:06:50.920
at some point in the future. You gave a really interesting talk on Python security and plugging

00:06:50.920 --> 00:06:53.680
that into like operating level security, right?

00:06:53.680 --> 00:06:54.280
Yeah.

00:06:54.280 --> 00:06:57.200
Maybe talk really quickly about some of the stuff that's coming there and what you talked

00:06:57.200 --> 00:06:57.420
about.

00:06:57.420 --> 00:07:01.340
I kind of like move from project to project that I'm working on. One of the biggest things

00:07:01.340 --> 00:07:07.060
I've been working on recently is getting auditing hooks, which was PEP 578 into CPython.

00:07:07.060 --> 00:07:08.340
So that released in 3.8?

00:07:08.340 --> 00:07:09.640
That released in Python 3.8.

00:07:09.640 --> 00:07:09.840
Okay.

00:07:10.160 --> 00:07:14.520
And now it's time for me to go around and teach everyone what you're meant to use them for.

00:07:14.520 --> 00:07:21.000
Because it's like they don't actually do anything on their own right now. It's just a way of raising

00:07:21.000 --> 00:07:27.160
low-level events from inside the runtime. So you'll get notifications from the socket module every

00:07:27.160 --> 00:07:32.040
time it connects to a socket or every time a file gets opened, every time Ctypes gets used,

00:07:32.040 --> 00:07:37.560
all of the stuff that you really want to know is going on, but Python doesn't really give you a

00:07:37.560 --> 00:07:42.780
way to see it. And so the security applications of that are essentially logging. You want to collect

00:07:42.780 --> 00:07:49.480
all that information. And as I said, in some variants of the talk, build a haystack of every

00:07:49.480 --> 00:07:54.280
single event so that when you figure out there's a needle in there, which is someone attacking your

00:07:54.280 --> 00:07:56.520
systems, then you've got a chance of figuring out what they were doing.

00:07:56.520 --> 00:08:01.040
At least you have a record of it. It's not just like, well, it's hacked into, nobody knows why.

00:08:01.040 --> 00:08:05.160
Right. It's like, oh, I know we got hacked because people are buying our customer database off the

00:08:05.160 --> 00:08:09.640
dark web. It's like, yeah. And honestly, I think a lot of customers find out they were hacked by

00:08:09.640 --> 00:08:15.860
saying, I only gave this email address to this, you know, they do like the plus thing,

00:08:15.860 --> 00:08:20.080
like such and such plus, right? Site name or whatever at Gmail.

00:08:20.080 --> 00:08:24.600
Or you get one of those emails. It's like, I know your password and here it is.

00:08:24.600 --> 00:08:25.980
You're like, how did they get that?

00:08:25.980 --> 00:08:29.520
Yeah. Yeah. Well, that speaks to a whole nother level of badness.

00:08:29.860 --> 00:08:34.460
You know, just, I recently had to like sign into a bunch of a bank accounts. I'm trying

00:08:34.460 --> 00:08:37.880
to consolidate just some like retirement, boring stuff. But I finally broke down and like said,

00:08:37.880 --> 00:08:42.240
I have to do this. So here I go. And I tried to log into the bank. There was some workflow

00:08:42.240 --> 00:08:47.000
where I created an account and I used a 30 character randomly generated password. And I couldn't log in

00:08:47.000 --> 00:08:52.220
again. And I kept getting like an error too long sort of thing. And they were saying, well,

00:08:52.220 --> 00:08:58.840
the password has to be 16 characters or less. And you know, the hash of a password is always the

00:08:58.840 --> 00:09:03.360
same size, no matter how large the input. So what are they doing with that password? If they care

00:09:03.360 --> 00:09:08.240
about the length of it? I'm not going to speculate on that one, but it's not, it's probably not good.

00:09:08.240 --> 00:09:10.980
That may not be where you want to consolidate all of your retirement savings.

00:09:10.980 --> 00:09:13.920
I was trying to get away from that place. So I feel all right about that. All right. So,

00:09:13.920 --> 00:09:18.220
but what you were talking about with the Python stuff is there's really interesting hooks that you can

00:09:18.220 --> 00:09:25.460
plug into for like compile or evaluate or like execute code. There's a bunch of neat stuff that

00:09:25.460 --> 00:09:29.360
you got going on, right? Yeah. And that's one of the really scary things that Python can do that,

00:09:29.360 --> 00:09:33.800
that most other tools installed on your system can't do is you can obfuscate the command line.

00:09:33.800 --> 00:09:39.740
And so you can pass in the example I showed was like a big fat base 64 string wrapped up in a little

00:09:39.740 --> 00:09:47.620
bit of decoding and eval to dynamically essentially decrypt code and run it without anyone actually being

00:09:47.620 --> 00:09:50.680
able to see what it is. And so you, you don't know what it's doing until you go through and decrypt it.

00:09:50.680 --> 00:09:55.080
The sample I showed then went off and downloaded more code off the internet and decrypted that.

00:09:55.080 --> 00:09:57.440
Yeah. Cause once it started, then, then it's trouble.

00:09:57.440 --> 00:10:02.640
Yeah. And so being able to hook the compile event, every time a bit of Python code gets exact or evaled,

00:10:02.640 --> 00:10:07.020
you, you see what's going on and it's really hard. People have tried to, you know, sandbox Python

00:10:07.020 --> 00:10:12.020
and just take those things out. And it turns out that doesn't work well firstly, because you need them

00:10:12.020 --> 00:10:16.900
for a variety of things in the, in the language and standard library. And it's, there are other

00:10:16.900 --> 00:10:23.060
ways to fight to work around that and to still compile code. So this way you don't block it hard,

00:10:23.060 --> 00:10:27.100
but you get to see everything that goes through it. And then if something bad does happen, at least

00:10:27.100 --> 00:10:27.740
you know about it.

00:10:27.740 --> 00:10:31.220
Yeah. It's, it looks really positive and you know, I don't want to talk more about it cause

00:10:31.220 --> 00:10:32.880
that's not really the topic of the show, but there was,

00:10:32.880 --> 00:10:33.620
Let's do that one later.

00:10:33.620 --> 00:10:36.840
Yeah. We'll do that as another show, but that's what you were here talking about. And the audience

00:10:36.840 --> 00:10:38.740
was full, right? Like people were really interested in this.

00:10:38.740 --> 00:10:44.760
Yeah. There's a lot more security minded people here. I did run around and do a quick survey

00:10:44.760 --> 00:10:48.060
or just a quick chat with everyone who was attending and it was a really interesting,

00:10:48.060 --> 00:10:48.840
What was the mix?

00:10:48.840 --> 00:10:55.940
Diverse crowd. It was equal parts developers, security administrator, IT management. it was

00:10:55.940 --> 00:11:01.340
a pretty good spread across all the roles that would be interested in, in managing where and how

00:11:01.340 --> 00:11:02.940
Python is used in their setup.

00:11:02.940 --> 00:11:06.080
Yeah. Yeah. The people asking questions afterwards were like, I'm not a developer,

00:11:06.080 --> 00:11:10.700
but I have to sort of oversee the execution and protection of this stuff and so on. So help me,

00:11:10.700 --> 00:11:15.940
help me understand how to do that with Python. That's pretty cool. All right. Now let's talk

00:11:15.940 --> 00:11:20.880
about Python and windows because it's okay. Actually. Yeah. It's okay. Yeah. Actually. Yeah.

00:11:20.880 --> 00:11:26.860
That's awesome. You know, when I go to a lot of conferences and like, especially I think PyCon

00:11:26.860 --> 00:11:35.260
falls under this banner, you walk in and it does feel like most people are on some kind of Mac or maybe

00:11:35.320 --> 00:11:40.220
running Linux. Like there's some windows folks there, there's, you know, some surfaces and whatnot,

00:11:40.220 --> 00:11:44.260
but it doesn't seem to be very, doesn't seem to be the majority. Does it?

00:11:44.260 --> 00:11:49.420
There are more and more surfaces, which we're very excited about, but yeah, the, there is always an

00:11:49.420 --> 00:11:53.060
army of glowing fruit staring back at you while you're speaking to that crowd.

00:11:53.300 --> 00:11:59.080
That's right. They just stand out mocking you there with a little bite. Yeah. So it feels like

00:11:59.080 --> 00:12:04.340
it can feel like to a lot of Python developers and especially, I think it's the most relevant

00:12:04.340 --> 00:12:07.020
audience is the people building Python packages, right?

00:12:07.340 --> 00:12:14.620
Yeah. Yeah. So it is certainly the most popular platform that, that and Linux for, for the people

00:12:14.620 --> 00:12:18.940
that are building the open source stuff that we know and love and rely on. And I think what's really

00:12:18.940 --> 00:12:23.980
interesting is that that's about the only data point that really looks like that. It's a bit of

00:12:23.980 --> 00:12:29.040
conference bias, I think as we see it ignite as well, it's biased in the other way. Yeah. And just

00:12:29.040 --> 00:12:35.260
through that kind of selected audience, you're going to see a certain set of people. But the problem with

00:12:35.260 --> 00:12:40.400
that and the problem with kind of all, you know, diversity type topics is if that's all you see,

00:12:40.400 --> 00:12:44.160
and that's what you believe reflects reality. Right, right. How would you know otherwise?

00:12:44.160 --> 00:12:50.600
Exactly. It's not exactly the, you know, the same thing, but Scott Hanselman also from Microsoft has

00:12:50.600 --> 00:12:54.720
a really interesting saying, he did a blog post on dark matter developers. Are you familiar with this

00:12:54.720 --> 00:12:59.420
idea? Yeah. Yeah. Yeah. It's that there's a whole bunch of folks out there who write code,

00:12:59.420 --> 00:13:03.660
they go to work, maybe they work at some big company. They're not so passionate that they're on

00:13:03.660 --> 00:13:07.560
Twitter all the time, right? They're not going to conferences or the meetups. They just, you know,

00:13:07.560 --> 00:13:11.820
they're happy programming, they do their job and they go home and they're not blogging, tweeting,

00:13:11.820 --> 00:13:17.780
podcasting about it. And that world probably looks a little bit different, right? Like what those people

00:13:17.780 --> 00:13:21.600
need, but it's still, they're a really important consumer and user of programming languages.

00:13:21.600 --> 00:13:28.120
Yeah, absolutely. And I've met quite a few of those developers in through visiting like any of the big

00:13:28.120 --> 00:13:33.280
companies or financial institutes at like in New York, I've gotten to meet some of those guys and

00:13:33.280 --> 00:13:37.000
it's like, yeah, they show up in a suit and then they go home and they stop thinking about coding

00:13:37.000 --> 00:13:42.340
completely for the night. That's fine. Right. Like if that's one of those, it sounds great. I wish I

00:13:42.340 --> 00:13:48.620
could stop thinking about coding at night. I know exactly. Exactly. So let's talk about it. So it feels like

00:13:48.620 --> 00:13:57.000
conference reality is like, I don't know, 70% Mac, 15% Linux, 15% Windows. But then in your presentation

00:13:57.000 --> 00:14:02.640
you did at PyCon, you talked about, well, that might be what the like survey around here is, but let's just

00:14:02.640 --> 00:14:08.400
look at the numbers, right? The real numbers. Yeah. So what are some of the numbers? Yeah. So I went and

00:14:08.400 --> 00:14:13.440
tracked down, there's a few data sources that everyone has access to that I went and looked at. And there's a few

00:14:13.440 --> 00:14:18.540
that I've managed to speak to some people individually and get some numbers out.

00:14:18.540 --> 00:14:24.880
PyPI is a great source of who's downloading various packages. And so I pulled that one up and

00:14:24.880 --> 00:14:30.300
checked out, checked out a few packages. There's no easy way to kind of query the whole thing. And it

00:14:30.300 --> 00:14:35.040
doesn't, it doesn't really make sense to do that. It doesn't make any sense to measure like PyWin32 or

00:14:35.040 --> 00:14:39.280
something like that, right? Right. PyWin32 is, is, doesn't get installed very often on Mac,

00:14:39.280 --> 00:14:44.880
oddly enough. If it only badly, right? So, so, you know, I tried to look at the ones that get

00:14:44.880 --> 00:14:49.760
installed everywhere in it and it turned out that it was roughly, you know, majority Linux and,

00:14:49.760 --> 00:14:53.960
and roughly equal Windows and Mac, which already is saying, okay, this is different from the PyCon

00:14:53.960 --> 00:15:00.340
crowd. Yeah. And interestingly, since then we've done some more analysis on the PyPI data and found

00:15:00.340 --> 00:15:06.360
that there's a few packages that have long lists of dependencies that may be skewing those numbers

00:15:06.360 --> 00:15:13.860
even further. Okay. In favor of Linux. So, so there's one particular package that, that I won't name,

00:15:13.860 --> 00:15:18.760
but it's, it's one of the major cloud providers tools. All right. So if you grab it and then it's

00:15:18.760 --> 00:15:22.460
going to grab 20 other things. So that counts as like 20 downloads from Linux or something like that.

00:15:22.460 --> 00:15:27.500
Yeah. That counts as, well, it's going to count as a Linux download for those. And we found that that

00:15:27.500 --> 00:15:32.640
particular package had a massive, massive spike on Linux for some reason. And I don't think anyone's dug

00:15:32.640 --> 00:15:39.240
into exactly why, but it's like in the tens of thousands of downloads a day, well beyond where

00:15:39.240 --> 00:15:43.380
any other reasonable package should be. Right. Okay. So those numbers are still skewed, but,

00:15:43.380 --> 00:15:48.240
but they are saying it's majority Linux, whereas a conference is not majority Linux. I had a chat with

00:15:48.240 --> 00:15:52.320
the, the Anaconda folks to see what they could tell me about people downloading from Condor.

00:15:52.320 --> 00:15:56.800
Yeah. I feel like they're a little more enterprise focused and that might have a different crowd.

00:15:56.800 --> 00:16:00.420
They're a little more enterprise focused as well. You see the percentage of windows

00:16:00.420 --> 00:16:04.640
downloads increasing there. So it's roughly double what it is for Mac and Linux is still

00:16:04.640 --> 00:16:07.500
about half of the overall downloads. Okay.

00:16:07.500 --> 00:16:12.900
The PSF survey. And, and we've had two of these now, and I believe that there's one going on right

00:16:12.900 --> 00:16:17.800
now. I think that's probably be over by the time we finish the time we release it. So it's a little

00:16:17.800 --> 00:16:21.940
bit, I wish I could, we could encourage people to take it, but it'll be great to look at the 2019

00:16:21.940 --> 00:16:24.760
results. I'm, I suspect we'll see some interesting trends.

00:16:24.760 --> 00:16:28.200
Yeah. So, so the interesting thing that happened with that is they changed the question slightly

00:16:28.200 --> 00:16:33.680
between the 2017 and the 2018 one. So in 2017, they didn't actually ask the question and they

00:16:33.680 --> 00:16:39.000
looked at people's huge user agents to figure out which OS they were coming from. Right. Right.

00:16:39.000 --> 00:16:45.740
And that one showed you half of all the survey respondents were on windows and fewer on Mac,

00:16:45.740 --> 00:16:50.700
fewer on Linux. And then, then there was a big gap, which some of us speculated it's probably Android

00:16:50.700 --> 00:16:55.540
in iOS phones. Yeah. Cause you can take the survey on whatever you're on, but half the people

00:16:55.540 --> 00:17:02.360
responding were on windows, which means that's kind of like a max level, I feel like, but then the

00:17:02.360 --> 00:17:06.900
following year they asked the question again and, but this time they let you choose multiple responses

00:17:06.900 --> 00:17:10.960
and they say, which ones you develop for. And so the interesting, the only thing that really changed

00:17:10.960 --> 00:17:19.800
between the two sets of data is that windows are still 50% and Linux went from about 10% up to 60%.

00:17:19.800 --> 00:17:24.760
Wow. And so people are devving on windows, but pushing to the cloud on, on Linux.

00:17:24.760 --> 00:17:27.960
My hypothesis, and we haven't checked it. And hopefully the current survey is going to

00:17:27.960 --> 00:17:35.000
help clarify this is people develop on windows and deploy on Linux and, or they work on windows.

00:17:35.000 --> 00:17:39.760
Yeah. Deploy to Linux. And so you already have a much bigger chunk of windows showing up there

00:17:39.760 --> 00:17:40.800
than you ever see at a conference.

00:17:40.800 --> 00:17:47.400
How much do you think Docker influences this? Because Docker is like, I feel like it would

00:17:47.400 --> 00:17:53.020
overcount the Linux side of things. Cause you so often recreate these images and they reinstall

00:17:53.020 --> 00:17:54.300
and reinstall, you know, like...

00:17:54.300 --> 00:17:58.320
Definitely. But virtual environments are going to be much the same thing. So I think there's,

00:17:58.320 --> 00:18:03.040
there's a lot of repetition, but, but I guess virtual environments are now cached for things

00:18:03.040 --> 00:18:06.160
like PyPI. So you're not actually going to count the download again.

00:18:06.160 --> 00:18:10.440
Yeah. Yeah. Yeah. Yeah. But a fresh, like a fresh change of like a low level part of a Docker image

00:18:10.440 --> 00:18:14.600
might as well, or CI as well, but CI is probably cached. I don't know.

00:18:14.600 --> 00:18:20.240
Ultimately the point that, that I eventually got to with all these numbers is we don't have a good

00:18:20.240 --> 00:18:24.780
answer for how many people are using this. Like you go and look at, at the editors that we also

00:18:24.780 --> 00:18:30.640
have numbers for us, a VS Code, PyCharm and their majority windows, either slim or significant

00:18:30.640 --> 00:18:36.580
majority windows and smaller Mac, very, very little Linux. And about all we can really say is that

00:18:36.580 --> 00:18:41.260
the numbers don't line up. They definitely don't line up with what we see at a conference. And when

00:18:41.260 --> 00:18:48.200
you walk around PyCon and you come away going, literally everyone is running on a Mac. Then all we

00:18:48.200 --> 00:18:50.360
can say is we know that that's not true. Right.

00:18:50.600 --> 00:18:56.440
So I feel like conservatively, probably half the Python community, half the Python user base

00:18:56.440 --> 00:19:01.440
is running on windows either for development and deployment or just for development, then deploying

00:19:01.440 --> 00:19:05.480
to another platform. Sure. And that's, so the other stat that I pulled out just for fun, because it's a

00:19:05.480 --> 00:19:11.920
big number, but is obviously biased. So the Python.org downloads, which is mostly where the,

00:19:11.920 --> 00:19:16.180
mostly where windows developers will get their Python from. And we see that in the stats that's,

00:19:16.180 --> 00:19:22.360
that is vast majority windows, but the number it's, I ran some of the analysis for one month,

00:19:22.360 --> 00:19:28.220
uh, about, about a year ago now. And there was 20 million unique downloaders in that month,

00:19:28.220 --> 00:19:34.200
which is my windows for windows. Yeah. And most estimates of the size of the Python community,

00:19:34.200 --> 00:19:41.420
like five to 6 million developers. And we got 20 million downloads for windows in that month.

00:19:41.420 --> 00:19:47.620
So how interesting. So we don't know the exact numbers, but I think we can say that it's certainly

00:19:47.620 --> 00:19:53.440
not a minority of the Python community. I would, I'd estimate it's about half, maybe more. Yeah. And

00:19:53.440 --> 00:19:58.220
it's certainly a big number. Yeah. And that's about all I'm prepared to say concretely. Yeah. Yeah.

00:19:58.220 --> 00:20:05.860
Sure. And so, I mean, maybe one of this, the takeaways from this section is we need to treat the windows

00:20:07.080 --> 00:20:12.640
dev story importantly in the Python community because a lot of people are doing that and they're either

00:20:12.640 --> 00:20:17.060
having a good experience and liking Python more or a bad experience and not feeling welcome.

00:20:17.060 --> 00:20:22.320
Right. And so the thing that concerned me out of that is where, where are, like, where are these

00:20:22.320 --> 00:20:28.080
developers at our conferences? Yeah. We have all of these Python conferences all the time and, and the

00:20:28.080 --> 00:20:33.440
numbers vary, but there's, there is nowhere near a representative number of windows devs coming to our

00:20:33.440 --> 00:20:39.820
Python conferences. And there's also not a representative amount of kind of pain and suffering

00:20:39.820 --> 00:20:44.420
that you hear online. I mean, I, this is my area. So I watched the Twitter feed for, you know,

00:20:44.420 --> 00:20:50.940
Python and windows and, and there's a lot of pain out there for a variety of reasons. and so I just

00:20:50.940 --> 00:20:58.520
wonder how much is people try and get started using Python on windows and give up or they just don't feel

00:20:58.520 --> 00:21:03.540
welcome because things are painful and it seems like they're just not, you know, no one's aware

00:21:03.540 --> 00:21:05.800
of them. No one sees them. No one knows they're there. Yeah.

00:21:05.800 --> 00:21:12.540
This portion of talk Python to me is brought to you by Linode. Whether you're working on a personal

00:21:12.540 --> 00:21:18.040
project or managing your enterprise's infrastructure, Linode has the pricing support and scale that you

00:21:18.040 --> 00:21:23.080
need to take your project to the next level with 11 data centers worldwide, including their newest

00:21:23.080 --> 00:21:29.380
data center in Sydney, Australia, enterprise grade hardware, S3 compatible storage, and the next

00:21:29.380 --> 00:21:35.180
generation network. Linode delivers the performance that you expect at a price that you don't get

00:21:35.180 --> 00:21:40.920
started on the node today with a $20 credit and you get access to native SSD storage, a 40 gigabit

00:21:40.920 --> 00:21:47.340
network industry leading processors, their revamped cloud manager at cloud.linode.com root access to your

00:21:47.340 --> 00:21:54.540
server along with their newest API and a Python CLI. Just visit talkpython.fm/Linode when creating

00:21:54.540 --> 00:21:59.680
a new Linode account and you'll automatically get $20 credit for your next project. Oh, and one last

00:21:59.680 --> 00:22:05.180
thing they're hiring. Go to linode.com slash careers to find out more. Let them know that we sent you.

00:22:07.500 --> 00:22:13.540
How many of those do you think are students? I do have some slightly more demographic data from the

00:22:13.540 --> 00:22:18.760
Python in the Windows store distribution. So that gives me a little bit more information. There's some

00:22:18.760 --> 00:22:25.760
age banding and some regional information. And that does certainly make it look like the majority of

00:22:25.760 --> 00:22:32.020
people installing Python on Windows are college students in the US and China primarily. Okay. Oh,

00:22:32.020 --> 00:22:36.840
that's pretty interesting. Yeah. Okay. Well, and it might not be that they're developing on it. They

00:22:36.840 --> 00:22:42.340
might just need it to run something as well. They may just need it to run, but given how new the

00:22:42.340 --> 00:22:46.640
Windows store distribution is, it's kind of unlikely that you'll find it unless you're looking for it.

00:22:46.640 --> 00:22:51.860
Right. Okay. Yeah. So I guess the story is here's the numbers that you're giving us.

00:22:51.860 --> 00:22:56.660
Right. We've got a lot of different sources and they all seem to point at generally the same trend.

00:22:57.440 --> 00:23:02.360
Now what? What do we do about that? Yeah. Well, and so I was giving a conference talk,

00:23:02.360 --> 00:23:08.980
right? So I had to speak to the people in the room. There's only so much value in getting up in front

00:23:08.980 --> 00:23:13.860
of a crowd of people and telling them that someone else has to do something. Yeah. I don't like doing

00:23:13.860 --> 00:23:19.820
that. So I was like, okay, what pieces can the people here help with? Because it's no one's fault,

00:23:20.040 --> 00:23:27.620
really. It's like when a conference doesn't reflect the general population for its area,

00:23:27.620 --> 00:23:35.520
it's really hard to say whose fault that is, but I think it's easier to say, knowing who you are,

00:23:35.520 --> 00:23:38.760
who's here, here are things you can do that will be net positive.

00:23:38.760 --> 00:23:39.240
Right.

00:23:39.240 --> 00:23:43.820
So PyCon, as we said, it's a lot of library developers, a lot of enthusiasts, it's people

00:23:43.820 --> 00:23:45.540
writing codes, people publishing code.

00:23:45.540 --> 00:23:50.980
People who are getting paid to do Python development already. So they're in a different demographic and

00:23:50.980 --> 00:23:52.740
whatnot to some degree as well, right?

00:23:52.740 --> 00:23:57.860
Right. And so from that, I'm like, well, okay, these are the people who are potentially writing

00:23:57.860 --> 00:24:03.340
the libraries that just grate a bit on Windows. Like for one little reason don't work well for

00:24:03.340 --> 00:24:09.280
this Windows crowd and maybe, you know, contributing to that old Python community doesn't really think

00:24:09.280 --> 00:24:14.980
about Windows. And so I built the talk around that and kind of went through some of the major

00:24:14.980 --> 00:24:21.480
kind of cross-platform mistakes or assumptions that I see people make that don't actually translate

00:24:21.480 --> 00:24:25.700
cross-platform well. Python already does a fantastic job of, you know, hiding most of that.

00:24:25.700 --> 00:24:26.020
Right.

00:24:26.020 --> 00:24:31.060
And then there's some things that bleed through that, that can, you know, if you're not aware

00:24:31.060 --> 00:24:35.680
of them, then you are going to make code that doesn't work well on other platforms.

00:24:35.680 --> 00:24:40.060
And the best part about it all is when I started going through those and find, and, you know,

00:24:40.060 --> 00:24:43.860
planning out the right way to do things, turned out they're all just best practices anyway.

00:24:43.860 --> 00:24:44.380
Right.

00:24:44.380 --> 00:24:46.320
And they make you code better on all platforms.

00:24:46.320 --> 00:24:46.760
Right.

00:24:46.760 --> 00:24:50.400
Like don't treat paths as strings, treat them as, you know.

00:24:50.400 --> 00:24:52.120
Right. Treat them as path objects.

00:24:52.120 --> 00:24:52.880
Yeah, exactly.

00:24:52.880 --> 00:24:58.320
So yeah, that's, that's one of the big ones because most people are aware, you know, Python,

00:24:58.320 --> 00:25:03.760
not Python, Windows uses backslashes to separate path segments and POSIX uses forward slashes.

00:25:03.760 --> 00:25:08.660
And so that's kind of an immediate difference where if you've written your code using the

00:25:08.660 --> 00:25:12.740
string functions and it's all, you know, string dot split forward slash, that doesn't split

00:25:12.740 --> 00:25:13.480
anything on Windows.

00:25:13.480 --> 00:25:13.920
Yeah.

00:25:13.920 --> 00:25:14.840
That's a bad time.

00:25:14.840 --> 00:25:21.260
Let's start the story of like what we can do on Windows, which you say is really is kind

00:25:21.260 --> 00:25:23.680
of like actually just best practices for Python code anyway.

00:25:24.220 --> 00:25:27.300
But, you know, we got to get started by having Python on Windows.

00:25:27.300 --> 00:25:27.640
Yeah.

00:25:27.640 --> 00:25:28.000
Right.

00:25:28.000 --> 00:25:30.020
And you've done some interesting work there.

00:25:30.020 --> 00:25:30.840
Right.

00:25:30.840 --> 00:25:35.600
And the fun thing is this, this actually happened between two of the times I gave this talk.

00:25:35.600 --> 00:25:40.060
And so I had to go back and, and, and say, you know, you assume that this is true.

00:25:40.060 --> 00:25:43.800
And yeah, and now you're right because I fixed it in between.

00:25:43.800 --> 00:25:45.300
So, so yeah.

00:25:45.300 --> 00:25:46.420
I fixed your assumption.

00:25:46.720 --> 00:25:51.000
People have, have kind of got the hang of installing Python from the Python.org installer.

00:25:51.000 --> 00:25:57.720
And one of the big differences that that has from, if you install it on Mac or Linux is it

00:25:57.720 --> 00:25:59.340
doesn't put Python on path by default.

00:25:59.340 --> 00:26:03.000
And there's a checkbox, but you got to check it and you got to know that it matters.

00:26:03.000 --> 00:26:05.580
There's a checkbox, which I really don't like.

00:26:05.580 --> 00:26:07.000
Like I put that there under protest.

00:26:07.000 --> 00:26:07.620
Okay.

00:26:07.900 --> 00:26:11.680
And I don't like it because when you put a directory on path in windows, it's not the

00:26:11.680 --> 00:26:15.140
same thing as putting a symlink in kind of an already shared directory.

00:26:15.140 --> 00:26:21.420
So you do that on, on Linux and, you know, you put it in the user's bin directory and then

00:26:21.420 --> 00:26:22.040
it just shows up.

00:26:22.040 --> 00:26:24.120
And the only thing that they get access to is Python.

00:26:24.120 --> 00:26:29.820
But on windows, when you do this, you're injecting an entire path with every single file in that

00:26:29.820 --> 00:26:30.180
directory.

00:26:30.180 --> 00:26:34.820
All the executable stuff that's hanging out with Python.exe, right?

00:26:34.820 --> 00:26:36.080
All the dynamic libraries.

00:26:36.080 --> 00:26:41.160
So if some other application tries to load the Python DLL, it might find the one that

00:26:41.160 --> 00:26:44.180
you put on path because that's how the resolution works.

00:26:44.180 --> 00:26:44.740
Right, right, right.

00:26:44.740 --> 00:26:52.280
And maybe that's like version one of, I don't know, some D library and they are actually looking

00:26:52.280 --> 00:26:53.000
for version two.

00:26:53.000 --> 00:26:55.640
And of course they're compiled against the header for version two.

00:26:55.640 --> 00:26:59.920
So they are going to like hard crash because that's not going to line up and whatnot.

00:26:59.920 --> 00:27:00.140
Right.

00:27:00.140 --> 00:27:01.080
It's a big problem.

00:27:01.080 --> 00:27:01.800
Yeah, exactly.

00:27:01.800 --> 00:27:04.820
So, so I, I'm not a fan of putting Python on path.

00:27:04.940 --> 00:27:09.700
That said, my, my fix for this, which I'll get to is I'm, I'm very happy with, but it

00:27:09.700 --> 00:27:13.140
also doesn't come as like a Python three dot XE or Python three dot seven dot XE.

00:27:13.140 --> 00:27:17.900
It would, it would just be a Python, which goes against all of the instructions that are out

00:27:17.900 --> 00:27:18.660
there on how to run it.

00:27:18.660 --> 00:27:18.820
Right.

00:27:18.820 --> 00:27:24.140
All the getting started tutorials say type Python three, this pip three, that probably sources

00:27:24.140 --> 00:27:25.200
thrown in there or dot.

00:27:25.360 --> 00:27:25.800
Oh yeah.

00:27:25.800 --> 00:27:26.400
Source activate.

00:27:26.400 --> 00:27:26.760
Yeah.

00:27:26.760 --> 00:27:29.440
There's just all these kind of little rough differences.

00:27:29.440 --> 00:27:33.320
And the first few times I gave the talk, I pointed those out.

00:27:33.320 --> 00:27:37.560
The last time I gave the talk, I got to actually say, Hey, there's a new package for this.

00:27:37.560 --> 00:27:42.300
There's a new installer for Python, which comes through the Microsoft store.

00:27:42.300 --> 00:27:45.000
It's still released by the Python software foundation.

00:27:45.000 --> 00:27:48.120
Like it's exactly the same as the one that you get from Python.org.

00:27:48.120 --> 00:27:49.720
It just comes in different packaging.

00:27:49.720 --> 00:27:54.800
And the nice thing about this is this one has a more POSIX like system for putting shortcuts

00:27:54.800 --> 00:27:55.300
on path.

00:27:55.300 --> 00:27:56.240
Okay.

00:27:56.540 --> 00:28:00.880
So it already comes with, it has a directory that's already on the user's path that only

00:28:00.880 --> 00:28:02.380
has essentially symlinks in it.

00:28:02.380 --> 00:28:02.900
I see.

00:28:02.900 --> 00:28:08.800
And so in there, I was able to put a Python three, oh, a Python, a Python three and a Python

00:28:08.800 --> 00:28:13.900
three dot seven or three dot eight shortcut that doesn't have any of the downsides of putting

00:28:13.900 --> 00:28:15.600
all the other directories on there as well.

00:28:15.600 --> 00:28:21.300
And so that now makes all of the commands available on windows as well as Mac and Linux in

00:28:21.300 --> 00:28:22.060
exactly the same way.

00:28:22.060 --> 00:28:22.260
Yeah.

00:28:22.260 --> 00:28:23.660
That's such a positive thing.

00:28:24.500 --> 00:28:29.160
So you can go there and you can now type Python three on windows and it, it means basically

00:28:29.160 --> 00:28:29.660
the same thing.

00:28:29.660 --> 00:28:32.060
You don't have to be an admin on the box to install it.

00:28:32.060 --> 00:28:32.600
Right.

00:28:32.600 --> 00:28:33.040
Yeah.

00:28:33.040 --> 00:28:35.200
As long as you can get the store, it just lives on.

00:28:35.200 --> 00:28:39.500
You probably are not even affecting other users on that window system, right?

00:28:39.500 --> 00:28:39.940
No.

00:28:39.940 --> 00:28:44.020
The only impact it may have on other users is if they install Python from the store, then

00:28:44.020 --> 00:28:46.000
windows will go, oh, I've already got this once.

00:28:46.000 --> 00:28:47.060
I'll give you the same one.

00:28:47.060 --> 00:28:47.540
Yeah.

00:28:47.540 --> 00:28:51.340
And, and it still separates everything by user, but it, it does save them the download.

00:28:51.340 --> 00:28:51.800
Right.

00:28:51.800 --> 00:28:51.980
Right.

00:28:51.980 --> 00:28:54.820
But it's not, you're not going to break one of their apps by installing.

00:28:54.820 --> 00:28:56.400
You can't install anything in their space.

00:28:56.400 --> 00:28:57.740
They can't install anything in yours.

00:28:57.740 --> 00:29:00.420
It's a good setup for multi-user Python.

00:29:00.420 --> 00:29:01.100
That's super cool.

00:29:01.100 --> 00:29:06.220
Another thing that's worth pointing out is even if you don't do that on windows 10 now, if

00:29:06.220 --> 00:29:11.920
it's properly updated to the latest and you type Python three, it doesn't say Python not

00:29:11.920 --> 00:29:13.360
found or Python three not found.

00:29:13.360 --> 00:29:13.660
Right.

00:29:13.660 --> 00:29:14.060
Right.

00:29:14.060 --> 00:29:19.220
That was one of the big benefits of putting it in the store is it made it really easy

00:29:19.220 --> 00:29:24.360
for the windows team to come around and say, well, what if we just put a shortcut in there?

00:29:24.360 --> 00:29:27.340
It's like, everyone's been asking for years, you know, can you just put Python in windows?

00:29:27.340 --> 00:29:33.360
And we figured out the best we could do without taking on a massive maintenance burden, which

00:29:33.360 --> 00:29:34.800
was, we'll just put a shortcut in there.

00:29:34.800 --> 00:29:39.800
And so you run Python, you run Python three and it'll bounce you to the store where it's

00:29:39.800 --> 00:29:42.440
then one click to actually get the Python and Python three.

00:29:42.440 --> 00:29:43.680
Then you type it again, then you're good.

00:29:43.680 --> 00:29:44.720
Type again and you're good.

00:29:44.720 --> 00:29:49.680
And we're actually seeing literally thousands of people a day installing Python through that.

00:29:49.680 --> 00:29:53.260
And they, they probably maybe didn't even know that that was what they needed to do.

00:29:53.260 --> 00:29:54.280
They just wanted to run Python.

00:29:54.280 --> 00:29:56.980
They typed it and said, you don't have it, but click this button and you'll have it.

00:29:56.980 --> 00:30:02.380
I've recommended it to a few kind of trainers and teachers and they absolutely love it because

00:30:02.380 --> 00:30:06.400
they can now go into a classroom and say, just type Python three on your machine.

00:30:06.400 --> 00:30:07.340
See what is it?

00:30:07.340 --> 00:30:07.600
What happens?

00:30:07.600 --> 00:30:11.960
And if it pops up with this, click install and now type Python three again.

00:30:11.960 --> 00:30:14.040
And everyone in the room is ready to go.

00:30:14.040 --> 00:30:14.400
Yeah.

00:30:14.400 --> 00:30:16.760
A lot of those training situations as well.

00:30:16.760 --> 00:30:22.640
Those folks don't have permission to install the wide open MSIs and all sorts of stuff that

00:30:22.640 --> 00:30:25.940
will like shut down a class.

00:30:25.940 --> 00:30:28.800
You're like, okay, the first thing we're going to do is install this.

00:30:28.800 --> 00:30:29.640
We can't install it.

00:30:29.640 --> 00:30:31.780
Well, this is going to be a real short presentation.

00:30:31.780 --> 00:30:32.260
Yeah.

00:30:32.260 --> 00:30:35.040
The next two hours are going to fly by.

00:30:35.040 --> 00:30:36.040
Exactly.

00:30:36.040 --> 00:30:37.240
Just, you just have to watch.

00:30:37.240 --> 00:30:38.700
All right.

00:30:38.700 --> 00:30:43.520
So I think we kind of started on the first thing is like, how do I run Python?

00:30:43.520 --> 00:30:44.060
Right?

00:30:44.060 --> 00:30:46.240
Not, things are not always in the path.

00:30:46.240 --> 00:30:48.300
The, the path story is, is different.

00:30:48.300 --> 00:30:55.560
Typing Python three until recently used to be a problem they would run into.

00:30:55.560 --> 00:30:58.080
People would have to Google about like, well, why does Python three not work?

00:30:58.080 --> 00:30:59.060
How do I get Python three?

00:30:59.060 --> 00:31:03.560
It says I have Python installed in like my installed apps, but I type Python three and

00:31:03.560 --> 00:31:04.100
it doesn't work.

00:31:04.100 --> 00:31:10.420
So I think people still need to be cognizant of that because even though the fix is now

00:31:10.420 --> 00:31:15.300
there, it's going to be a while before all the windows machines live in that world.

00:31:15.300 --> 00:31:15.580
Right?

00:31:15.960 --> 00:31:16.060
Yeah.

00:31:16.060 --> 00:31:20.480
It always takes time to roll out new things and hopefully over time as more and more

00:31:20.480 --> 00:31:23.640
people see it, then we'll see more instructions.

00:31:23.640 --> 00:31:27.860
I'm really looking forward to people not posting new instructions every day on how to install

00:31:27.860 --> 00:31:29.840
Python the old way.

00:31:29.840 --> 00:31:30.600
Yeah.

00:31:30.600 --> 00:31:34.740
And we start seeing some more, more people posting how to, how to install it the new way.

00:31:34.740 --> 00:31:35.220
Right.

00:31:35.220 --> 00:31:35.880
Here's the store.

00:31:35.880 --> 00:31:36.580
Click it.

00:31:36.580 --> 00:31:36.980
Yeah.

00:31:36.980 --> 00:31:42.100
And, and so in an effort to do that, we actually convinced some of the Microsoft documentation

00:31:42.100 --> 00:31:45.540
team to put our own, how to install Python on windows page up.

00:31:45.540 --> 00:31:46.200
Okay.

00:31:46.200 --> 00:31:51.380
So, so I will have to double check the URL, but I think docstopmicrosoft.com slash windows

00:31:51.380 --> 00:31:52.060
slash Python.

00:31:52.060 --> 00:31:56.820
We'll get you to some of our getting started with Python on windows page.

00:31:56.820 --> 00:31:57.780
That's pretty cool.

00:31:57.780 --> 00:32:02.040
that, you know, we invested in writing up and, and getting good steps and it'll take

00:32:02.040 --> 00:32:04.140
you all the way through to, oh, you're a student.

00:32:04.140 --> 00:32:06.140
Here's how to build your first game with Pygame.

00:32:06.140 --> 00:32:07.980
You're a system admin.

00:32:07.980 --> 00:32:11.260
Here's how to build, here's how to write a script that'll do like some file scanning.

00:32:11.260 --> 00:32:11.820
Yeah.

00:32:11.820 --> 00:32:17.680
So, you know, we're trying to, to move the entire world forward rather than leaving everyone

00:32:17.680 --> 00:32:23.020
in the, you know, here's how to install Python 3.4 instructions, which I still saw pop up

00:32:23.020 --> 00:32:23.500
recently.

00:32:23.500 --> 00:32:24.260
Oh my goodness.

00:32:24.260 --> 00:32:24.680
Yeah.

00:32:24.960 --> 00:32:30.960
I definitely looking forward to a world where there's not a bifurcation of every step until

00:32:30.960 --> 00:32:36.040
you actually get to run in your code is, is what do on Mac and Linux is what do on windows,

00:32:36.040 --> 00:32:36.260
right?

00:32:36.260 --> 00:32:39.860
Like another thing that, that varies is pip three, right?

00:32:39.860 --> 00:32:40.440
Yeah.

00:32:40.440 --> 00:32:46.760
So pip's always been a little bit better off because it would generate the versioned shortcuts.

00:32:46.760 --> 00:32:48.460
It's done that for quite a while.

00:32:48.760 --> 00:32:56.060
One of the downsides of the windows store installation is that you can't, you can only

00:32:56.060 --> 00:33:00.040
add shortcuts into that directory if you're actually the installer itself.

00:33:00.040 --> 00:33:02.080
So I have to pre-declare all of those in the package.

00:33:02.500 --> 00:33:06.880
And it means that when you pip install a package, it can't update those global shortcuts.

00:33:06.880 --> 00:33:09.160
And so they go into a directory that's not on your path.

00:33:09.160 --> 00:33:12.400
Pip these days will print a message saying you should add this to your path.

00:33:12.400 --> 00:33:13.780
And if you do that, then you'll be just fine.

00:33:13.780 --> 00:33:14.320
Okay.

00:33:14.600 --> 00:33:19.480
But, but it does mean that most kind of command line tools that you might install with pip,

00:33:19.480 --> 00:33:21.800
you won't get to through the usual name.

00:33:21.800 --> 00:33:22.160
Right.

00:33:22.160 --> 00:33:24.440
Like black or pip x or something like that.

00:33:24.440 --> 00:33:24.960
Exactly.

00:33:24.960 --> 00:33:25.440
Okay.

00:33:25.440 --> 00:33:29.280
And that's always been an issue that's always kind of run into problems here and there on

00:33:29.280 --> 00:33:29.580
Python.

00:33:29.580 --> 00:33:30.160
Yeah.

00:33:30.160 --> 00:33:34.000
And the recommendation for a long time for, for all platforms, in fact, has been to use

00:33:34.000 --> 00:33:39.800
Python three dash M and the name of that command rather than trying to use where it

00:33:39.800 --> 00:33:40.000
is.

00:33:40.000 --> 00:33:41.680
Python knows exactly where it is.

00:33:41.680 --> 00:33:41.860
Yeah.

00:33:41.860 --> 00:33:46.800
And the other advantage is if you know, like that's the Python you're working with.

00:33:46.800 --> 00:33:51.780
So we generally recommend this for pip as well, because if you pip, if you pip install

00:33:51.780 --> 00:33:56.520
something and then Python try and import it and your path is messed up and this can happen

00:33:56.520 --> 00:33:57.720
on any OS.

00:33:57.720 --> 00:34:00.120
It happens on Linux, happens on Mac, happens on Windows.

00:34:00.120 --> 00:34:02.820
Then you'll go, why can't I import that package?

00:34:02.820 --> 00:34:03.180
Right.

00:34:03.180 --> 00:34:07.100
You like, like you type pip instead of pip three and it accidentally goes into Python two

00:34:07.100 --> 00:34:09.020
because that's earlier or something like that.

00:34:09.020 --> 00:34:09.200
Right.

00:34:09.200 --> 00:34:09.600
Yeah.

00:34:09.820 --> 00:34:14.580
And so we definitely recommend, you know, Python three dash M pip, even for pip.

00:34:14.580 --> 00:34:14.920
Yeah.

00:34:14.920 --> 00:34:20.240
Brett Cannon just wrote a big article about that, talking about how we recommend Python

00:34:20.240 --> 00:34:21.100
three dash M.

00:34:21.100 --> 00:34:21.740
Yeah.

00:34:21.740 --> 00:34:23.380
And for all the different things.

00:34:24.600 --> 00:34:27.680
This portion of talk Python to me is brought to you by brilliant.org.

00:34:27.680 --> 00:34:30.380
Let me knock something off your holiday to do list.

00:34:30.380 --> 00:34:31.080
Gifts.

00:34:31.080 --> 00:34:34.640
Spread the love to your loved ones by gifting them brilliant.

00:34:34.640 --> 00:34:39.680
This really excites me because it's such a fun way to nurture curiosity, build confidence

00:34:39.680 --> 00:34:44.460
and develop problem solving skills crucial to school, job interviews or to their career.

00:34:44.460 --> 00:34:49.800
Brilliant's thought provoking content breaks up the complexities into bite size, understandable

00:34:49.800 --> 00:34:52.960
chunks that will lead them from curiosity to mastery.

00:34:52.960 --> 00:34:59.260
Go to talkpython.fm/brilliant and grab a gift subscription to help your loved ones finish

00:34:59.260 --> 00:35:01.080
their day a little smarter this season.

00:35:01.080 --> 00:35:05.000
That's talkpython.fm/brilliant or just click the link in the show notes.

00:35:05.000 --> 00:35:12.040
I'll call out some false assumptions that you had that people often make about writing code.

00:35:12.160 --> 00:35:15.760
So we touched on this first one a little bit like everyone uses forward slash for path.

00:35:15.760 --> 00:35:16.060
Yeah.

00:35:16.060 --> 00:35:22.120
I see this assumption pop up a lot and it normally looks like, you know, using the string functions.

00:35:22.120 --> 00:35:25.660
So string dot split dot partition and just passing in a forward slash.

00:35:25.660 --> 00:35:30.540
That works fine as long as, you know, every platform you're on is using forward slashes, but

00:35:30.540 --> 00:35:31.580
there's plenty that don't.

00:35:31.580 --> 00:35:39.420
I use the built-in path lib or os.path style to process that, even if I know it's only going to run on a POSIX system

00:35:39.420 --> 00:35:42.760
because I don't want to have to deal with thinking about that, right?

00:35:42.760 --> 00:35:43.200
Yeah.

00:35:43.200 --> 00:35:43.600
As a string.

00:35:43.600 --> 00:35:47.680
There's a lot of, Python has about five different ways you can do this,

00:35:47.680 --> 00:35:50.800
but certainly the os.path module is very useful.

00:35:50.800 --> 00:35:55.400
And the nice thing about that is you can also import POSIX path directly or NT path directly.

00:35:55.400 --> 00:35:59.840
If you know you need cross-platform behavior, if you like specific platform behavior.

00:35:59.840 --> 00:36:00.160
Okay.

00:36:00.420 --> 00:36:05.700
And so I've definitely written code that uses os.path for some things and POSIX path for other things

00:36:05.700 --> 00:36:09.640
because that's, you know, it's going to look more like a URL or it's going to be sent to a different system.

00:36:09.640 --> 00:36:10.860
So you have that option there.

00:36:10.860 --> 00:36:17.340
But really, we have path lib now and we've had path lib since I think Python 3.4.

00:36:17.340 --> 00:36:20.080
And that's just so much nicer.

00:36:20.080 --> 00:36:20.440
Yeah.

00:36:20.440 --> 00:36:21.500
Path lib is really nice.

00:36:21.500 --> 00:36:23.680
And yeah, but definitely not strings, right?

00:36:23.680 --> 00:36:24.760
Definitely not strings.

00:36:24.760 --> 00:36:25.240
Okay.

00:36:25.240 --> 00:36:28.320
Because I guess the tie back to Windows is right.

00:36:28.320 --> 00:36:29.900
Like it will break on Windows.

00:36:30.260 --> 00:36:34.060
You should do it anytime, but it will actually break, not just be less convenient.

00:36:34.060 --> 00:36:36.120
It will break because if you get a Windows path.

00:36:36.120 --> 00:36:41.780
And so the thing that Windows makes a little more complicated here is if you give Windows a path that has forward slashes,

00:36:41.780 --> 00:36:44.620
it will go through and correct it for you most of the time.

00:36:44.620 --> 00:36:44.820
Yeah.

00:36:45.220 --> 00:36:48.540
Not all the time, but most of the time it'll correct forward slashes to back slashes.

00:36:48.540 --> 00:36:54.060
But any path that it gives you or any path that a user gives you is going to have back slashes in it.

00:36:54.060 --> 00:36:56.500
And you can't split on forward slash then.

00:36:56.500 --> 00:36:56.920
Yeah.

00:36:56.920 --> 00:37:00.380
Because you'll always get one element back and that's probably not what you wanted.

00:37:00.380 --> 00:37:01.260
No, that's not good.

00:37:01.320 --> 00:37:04.240
Also, route paths are kind of funny, right?

00:37:04.240 --> 00:37:07.340
Like it could be weird maps or volumes or other stuff, right?

00:37:07.340 --> 00:37:07.840
Yeah.

00:37:07.840 --> 00:37:08.840
Not just C colon backslash.

00:37:08.920 --> 00:37:14.040
It gets very interesting, the kind of range of shortcuts for identifying a drive or amount point.

00:37:14.040 --> 00:37:20.880
So there's the kind of internal system representation, which for a drive often looks like a GUID.

00:37:20.880 --> 00:37:24.400
Like it's a globally unique identifier and no one's typing those.

00:37:24.520 --> 00:37:27.600
So we have a shortcut that's going to be like C colon or D colon.

00:37:27.600 --> 00:37:33.420
There's SMB shares, which are, you know, backslash, backslash, computer name, backslash to N slay.

00:37:33.420 --> 00:37:35.980
Which part of this is the root of the drive?

00:37:35.980 --> 00:37:39.980
It's like if I'm dotting up the directory, how far do I go before I have to stop?

00:37:39.980 --> 00:37:42.200
Because it varies and it's different.

00:37:42.200 --> 00:37:45.960
And the Python libraries know how to handle that.

00:37:45.960 --> 00:37:47.120
We've built that logic in.

00:37:47.120 --> 00:37:47.400
Yeah.

00:37:47.400 --> 00:37:49.880
So just don't use strings for paths.

00:37:49.880 --> 00:37:50.980
Don't use strings for path.

00:37:50.980 --> 00:37:51.240
Yeah.

00:37:51.240 --> 00:37:51.680
Thank you.

00:37:51.680 --> 00:37:52.600
Absolutely.

00:37:52.600 --> 00:37:53.360
Use pathlib.

00:37:53.680 --> 00:37:54.960
Speaking of paths, tilde.

00:37:54.960 --> 00:37:57.100
tilde slash is always good.

00:37:57.100 --> 00:37:57.860
That gets me home, right?

00:37:57.860 --> 00:37:59.900
There's no place like tilde slash.

00:37:59.900 --> 00:38:01.380
No place like tilde slash.

00:38:01.380 --> 00:38:02.820
Yeah.

00:38:02.820 --> 00:38:06.180
People love putting their configuration files in tilde slash.

00:38:06.180 --> 00:38:06.600
Yeah.

00:38:06.600 --> 00:38:09.820
And, you know, so Windows doesn't have tilde.

00:38:09.820 --> 00:38:11.280
Like tilde is just a path character.

00:38:11.280 --> 00:38:13.300
You can put that anywhere you want.

00:38:13.300 --> 00:38:15.960
And it's just another part of the name.

00:38:15.960 --> 00:38:17.060
That lives in the working directory.

00:38:17.060 --> 00:38:17.420
Right.

00:38:17.420 --> 00:38:19.200
That lives exactly where you are right now.

00:38:19.200 --> 00:38:21.280
It's where your heart is, not where you want to be.

00:38:21.680 --> 00:38:31.520
But people do make the, you know, they do very quickly figure out, oh, I should be using the user profile environment variable or figure out the home directory some other way to do that.

00:38:31.520 --> 00:38:37.400
But even that, depending on what you're planning to use it for, doesn't necessarily line up.

00:38:37.400 --> 00:38:43.560
Like you see tilde slash, you know, dot and something for a lot of configuration files on Linux.

00:38:44.840 --> 00:38:52.500
But on Windows, that just gets thrown into the root of the user's directory, which actually has a set of subdirectories for different purposes.

00:38:52.500 --> 00:38:55.800
And you start digging down, particularly for...

00:38:55.800 --> 00:38:58.440
Like app data, local app data roaming, all that kind of stuff.

00:38:58.440 --> 00:39:00.580
And they all have different reasons and different behaviors.

00:39:00.580 --> 00:39:08.320
So like app data roaming will actually propagate between different machines on a network if that's configured for that.

00:39:08.320 --> 00:39:16.160
So anything you put there is going to be copied or maybe copied onto a network share and automatically copied down if the user logs in somewhere else, which is really handy.

00:39:16.160 --> 00:39:23.880
But if you're using it for, you know, 10 gigabytes worth of log files, then everyone's going to be real upset about saturating the network and login taking so long.

00:39:23.880 --> 00:39:24.500
Yeah, exactly.

00:39:24.500 --> 00:39:26.060
The domain controller is out of disk space.

00:39:26.060 --> 00:39:27.860
We don't know why or wherever it gets stored.

00:39:27.860 --> 00:39:30.300
But the other thing is that's a very hidden directory to users.

00:39:30.300 --> 00:39:31.420
Like it isn't...

00:39:31.420 --> 00:39:33.440
It's about as hidden as, you know, a dot file.

00:39:33.440 --> 00:39:34.020
Yeah.

00:39:34.020 --> 00:39:40.920
But if you're creating something that you want the user to see and modify, then they have a documents folder for that.

00:39:40.920 --> 00:39:46.500
And you probably want a subdirectory in that documents folder anyway, just for organizational purposes.

00:39:46.500 --> 00:39:52.860
And so you start looking at a very different layout from where you would keep all of this stuff on a POSIX-based system.

00:39:52.860 --> 00:39:59.100
It makes me crazy when every program thinks it's projects folder needs to live in the root of my user directory.

00:39:59.100 --> 00:40:00.380
Like, yeah.

00:40:00.380 --> 00:40:02.000
Wouldn't need to be topmost.

00:40:02.000 --> 00:40:02.400
Come on.

00:40:02.400 --> 00:40:03.340
Doesn't need to be top.

00:40:03.340 --> 00:40:06.340
And that doesn't even help on Windows because it's such a pain to get there.

00:40:06.340 --> 00:40:06.720
Yeah.

00:40:06.720 --> 00:40:08.520
Because all of the shortcuts go deeper.

00:40:08.520 --> 00:40:09.080
Yeah.

00:40:09.080 --> 00:40:10.660
Documents is really easy to get to.

00:40:10.660 --> 00:40:11.860
Pictures is really easy to get to.

00:40:11.860 --> 00:40:12.500
Videos is really...

00:40:12.500 --> 00:40:15.880
That random folder you created is very hard to get to if you don't know how.

00:40:15.880 --> 00:40:18.440
Gotta use the address bar of the file stuff.

00:40:18.500 --> 00:40:18.620
Yeah.

00:40:18.620 --> 00:40:19.540
For sure.

00:40:19.540 --> 00:40:24.620
So the fix for all the path problems were to use some of the built-in path libraries.

00:40:24.620 --> 00:40:26.000
What's the fix for this?

00:40:26.000 --> 00:40:32.940
So this one, the recommendation I have is to use Apters, which is a module made for this purpose.

00:40:32.940 --> 00:40:34.820
It's slightly opinionated.

00:40:35.200 --> 00:40:39.600
So you will see, you know, good programs not behaving exactly like it does.

00:40:39.600 --> 00:40:41.480
But it's a very simple module.

00:40:41.480 --> 00:40:42.400
It's a single file.

00:40:42.400 --> 00:40:45.140
So you may even just copy it into your project and keep it around.

00:40:45.140 --> 00:40:49.460
But it lets you query for a specific kind of purpose.

00:40:49.460 --> 00:40:51.760
And so you can say, give me the user's data directory.

00:40:51.760 --> 00:40:53.280
Give me the user's configuration directory.

00:40:53.280 --> 00:40:54.500
Give me a cache directory.

00:40:54.500 --> 00:40:55.540
Give me the documents directory.

00:40:55.540 --> 00:40:56.300
Yeah.

00:40:56.300 --> 00:40:58.700
I believe it will give you the documents directory.

00:40:59.220 --> 00:41:01.440
I think that may be one of the ones that's missing.

00:41:01.440 --> 00:41:01.840
Okay.

00:41:01.840 --> 00:41:04.620
Well, you could obviously get the home directory and add documents.

00:41:04.620 --> 00:41:05.640
And that's exactly it.

00:41:05.640 --> 00:41:10.660
And that one's not too difficult to add in if you find yourself needing that.

00:41:10.660 --> 00:41:12.400
But it does it cross-platform.

00:41:12.400 --> 00:41:15.120
So you import the module and you query for a directory.

00:41:15.120 --> 00:41:19.660
And it will pick depending on what platform you're on and give you a sensible layout that's

00:41:19.660 --> 00:41:22.380
not going to surprise, not going to upset anyone who's using it.

00:41:22.380 --> 00:41:22.740
Yeah.

00:41:22.740 --> 00:41:23.240
That's great.

00:41:23.240 --> 00:41:23.960
Strings.

00:41:23.960 --> 00:41:25.280
Strings are also interesting.

00:41:25.280 --> 00:41:26.840
Well, yeah.

00:41:26.840 --> 00:41:28.240
Unicode.

00:41:28.240 --> 00:41:29.100
Unicode.

00:41:29.100 --> 00:41:30.380
Unicode is the interesting thing.

00:41:30.380 --> 00:41:34.700
I had this section of my talk got better and better every time I gave it because people

00:41:34.700 --> 00:41:36.680
came and gave me more context and more information.

00:41:36.680 --> 00:41:37.200
Yeah.

00:41:37.200 --> 00:41:37.440
All right.

00:41:37.440 --> 00:41:40.680
But let me pose you a trivia question here.

00:41:40.680 --> 00:41:44.200
Which was invented first or which was released first?

00:41:44.200 --> 00:41:47.020
Windows 1.0 or the Unicode standard?

00:41:47.020 --> 00:41:51.440
I would initially guess Unicode, but I'm thinking this might not be right.

00:41:51.440 --> 00:41:52.320
You'd think so.

00:41:52.320 --> 00:41:54.800
Unicode has been around for a long time.

00:41:54.800 --> 00:41:55.520
Stuff in quotes.

00:41:55.520 --> 00:41:57.340
It doesn't seem like that's totally new.

00:41:57.500 --> 00:41:59.220
It seems like that should have been right at the beginning.

00:41:59.220 --> 00:42:00.740
It should have been.

00:42:00.740 --> 00:42:01.820
Unfortunately not.

00:42:01.820 --> 00:42:03.120
Windows came out first.

00:42:03.120 --> 00:42:04.220
There were no emojis.

00:42:04.220 --> 00:42:05.140
That's the problem.

00:42:05.140 --> 00:42:05.780
Yeah.

00:42:05.780 --> 00:42:08.260
No one wanted emojis at that point yet.

00:42:08.260 --> 00:42:12.160
But because Windows came out first, they had to handle internationalization without Unicode,

00:42:12.160 --> 00:42:14.920
which is why the code page system is there.

00:42:14.960 --> 00:42:17.160
And there were previous systems that were already using it.

00:42:17.160 --> 00:42:20.640
So this well predates Unicode regardless.

00:42:20.640 --> 00:42:22.540
But it was released in Windows.

00:42:22.540 --> 00:42:25.980
And about six years before Unicode even came out, it was released in Windows.

00:42:25.980 --> 00:42:32.180
Which means that you have this very ingrained system of code pages and 8-bit character encodings

00:42:32.180 --> 00:42:35.580
that now you have a compatibility burden.

00:42:35.820 --> 00:42:40.740
And so when Unicode did come out, then it just wasn't possible to go back and say,

00:42:40.740 --> 00:42:41.920
well, forget all of that.

00:42:41.920 --> 00:42:42.940
We're going to switch to Unicode.

00:42:42.940 --> 00:42:46.280
Because so much of it was at the C level where you pass char pointers.

00:42:46.280 --> 00:42:47.140
Yeah.

00:42:47.140 --> 00:42:48.880
The char pointers are the wrong size for Unicode.

00:42:48.880 --> 00:42:50.720
And so, okay, trivia question number two.

00:42:50.720 --> 00:42:51.960
Which came first?

00:42:51.960 --> 00:42:53.720
UTF-8 or UTF-16?

00:42:53.720 --> 00:42:55.140
You start with a smaller one, right?

00:42:55.140 --> 00:42:56.320
You start with a smaller one, yeah.

00:42:56.320 --> 00:42:56.780
UTF-8?

00:42:56.780 --> 00:42:58.000
Afraid not.

00:42:58.000 --> 00:42:58.840
UTF-16.

00:42:58.840 --> 00:42:59.880
In fact, UCS-2.

00:42:59.880 --> 00:43:02.440
So the two-byte character encoding was the first one.

00:43:02.440 --> 00:43:03.160
Yeah.

00:43:03.160 --> 00:43:06.980
And turns out Windows did actually go, oh, we should adopt this because this is now the

00:43:06.980 --> 00:43:07.260
standard.

00:43:07.260 --> 00:43:12.740
And that's why the Unicode encoding is two bytes throughout Windows because that was the

00:43:12.740 --> 00:43:15.340
official standard at the time Windows said, oh, hey, let's do this.

00:43:15.340 --> 00:43:19.460
And then UTF-8 came, it was proposed like four or five years later.

00:43:19.460 --> 00:43:21.640
And eventually, and now that's the standard.

00:43:21.640 --> 00:43:24.520
And I have no doubt that if Windows kind of restarted.

00:43:24.520 --> 00:43:25.620
It would just be pure UTF-8.

00:43:25.620 --> 00:43:27.200
It would just be pure UTF-8.

00:43:27.200 --> 00:43:27.700
Absolutely.

00:43:28.840 --> 00:43:33.960
You do get some bloat on a number of languages and a number of very important languages to

00:43:33.960 --> 00:43:34.240
Windows.

00:43:34.240 --> 00:43:41.080
So arguably, there's a kind of equalization of kind of memory wastage for certain character

00:43:41.080 --> 00:43:41.400
sets.

00:43:41.400 --> 00:43:44.760
If you're in English, then yeah, UTF-8 is vastly more efficient.

00:43:44.760 --> 00:43:50.120
But as soon as you get into kind of many of the Asian languages and some of the European

00:43:50.120 --> 00:43:52.860
languages, the 16 bits...

00:43:52.860 --> 00:43:55.120
It takes more bytes to actually do the UTF-8 stuff?

00:43:55.120 --> 00:43:58.640
You end up with every single character taking four or five UTF-8 bytes.

00:43:58.800 --> 00:43:58.880
Okay.

00:43:58.880 --> 00:44:00.140
That can be a lot.

00:44:00.140 --> 00:44:04.320
Whereas it would only be one or in some cases two UTF-16 words.

00:44:04.320 --> 00:44:04.980
Yeah.

00:44:04.980 --> 00:44:06.780
Which averages out to be smaller.

00:44:06.780 --> 00:44:08.980
So maybe there's a case for either of those.

00:44:08.980 --> 00:44:15.720
But just for historical reasons, Windows has ended up with UTF-16 as kind of the default

00:44:15.720 --> 00:44:17.540
choice of Unicode.

00:44:17.540 --> 00:44:22.480
And there's no real way to go back and undo that at this point without massively disrupting

00:44:22.480 --> 00:44:23.600
the entire ecosystem.

00:44:23.600 --> 00:44:26.860
No one's rewriting Windows with breaking changes that big.

00:44:26.860 --> 00:44:27.340
Yeah.

00:44:27.340 --> 00:44:33.080
And so what that leads to, as far as Python's concerned, is a kind of fundamental difference

00:44:33.080 --> 00:44:34.860
in how paths get passed around as strings.

00:44:34.860 --> 00:44:36.940
Because on POSIX, it's bytes.

00:44:36.940 --> 00:44:38.340
In the lowest level, it's bytes.

00:44:39.160 --> 00:44:43.940
And when it comes into Python, then you can keep it as bytes and pass it back out as bytes

00:44:43.940 --> 00:44:47.080
and kind of make sure that nothing changes and gets disrupted in the way there.

00:44:47.080 --> 00:44:49.260
And Windows has the APIs for that.

00:44:49.260 --> 00:44:53.500
But it's doing a silent conversion in the background through the old legacy code page system.

00:44:53.500 --> 00:44:53.860
Okay.

00:44:53.860 --> 00:44:55.700
Which can lose data.

00:44:55.700 --> 00:44:57.100
It can absolutely lose data.

00:44:57.100 --> 00:45:00.040
And it seems semi-random.

00:45:00.040 --> 00:45:03.980
This was a big Python 2 problem, was it would do this.

00:45:03.980 --> 00:45:04.960
And so you get...

00:45:04.960 --> 00:45:07.960
This is one of the major breaking changes from 2 to 3, honestly, right?

00:45:07.960 --> 00:45:11.040
Like in terms of the effect that it had.

00:45:11.040 --> 00:45:11.900
In terms of the...

00:45:11.900 --> 00:45:12.760
Yeah, in terms of the effect.

00:45:12.760 --> 00:45:14.540
But it's also one of the most positive ones.

00:45:14.660 --> 00:45:18.600
Because I heard from many, many students in particular...

00:45:18.600 --> 00:45:18.740
Sure.

00:45:18.740 --> 00:45:22.940
...who logged into Windows with their name.

00:45:22.940 --> 00:45:26.920
And their name is Chinese characters or Korean characters.

00:45:26.920 --> 00:45:30.020
It's a language that Python 2 could not support.

00:45:30.020 --> 00:45:36.200
And sometimes they do it on machines where the code page, the legacy support for Windows, can't handle it either.

00:45:36.200 --> 00:45:38.240
I can't even say my name.

00:45:38.240 --> 00:45:39.360
Yeah.

00:45:39.360 --> 00:45:39.740
That's crazy.

00:45:39.740 --> 00:45:41.720
They couldn't even print their own...

00:45:41.720 --> 00:45:42.620
It made them feel terrible.

00:45:42.620 --> 00:45:43.020
Yeah.

00:45:43.300 --> 00:45:44.120
So I'm...

00:45:44.120 --> 00:45:47.100
You know, the break for that for Python 3 was painful.

00:45:47.100 --> 00:45:48.640
But then you have...

00:45:48.640 --> 00:45:48.840
It was needed.

00:45:48.840 --> 00:45:56.940
But then you have a handful of other libraries that still use bytes for paths because it's more performant in their context.

00:45:56.940 --> 00:46:04.140
But it's also going to break these people again, even on Python 3, if you're forcing all the file system stuff to go through this arbitrary encoding.

00:46:04.140 --> 00:46:07.240
And so the preferred one is to just use string on Windows.

00:46:07.240 --> 00:46:08.260
Right.

00:46:08.260 --> 00:46:08.880
Yes.

00:46:08.880 --> 00:46:09.540
STR.

00:46:09.540 --> 00:46:10.180
Works great.

00:46:10.180 --> 00:46:11.640
STR instead of bytes.

00:46:11.640 --> 00:46:12.240
Yeah.

00:46:12.240 --> 00:46:14.420
And in fact, it works fine on POSIX as well.

00:46:14.420 --> 00:46:19.800
We've implemented on that side the conversion for file system stuff to be perfectly round trip.

00:46:19.800 --> 00:46:29.160
So even if there's characters in paths that, you know, if you converted to text would be corrupt and it would throw exceptions, we actually preserve those and they'll pass back in.

00:46:29.160 --> 00:46:30.760
So there's a little bit of a performance impact.

00:46:30.760 --> 00:46:32.020
But...

00:46:32.020 --> 00:46:34.660
It'd be better to be slow and right than fast and wrong.

00:46:34.660 --> 00:46:35.200
Absolutely.

00:46:35.200 --> 00:46:36.340
Absolutely.

00:46:36.340 --> 00:46:36.700
Nice.

00:46:36.700 --> 00:46:38.720
And that's a super easy fix, just like use string.

00:46:38.720 --> 00:46:42.120
Well, it's never quite as easy as just use string.

00:46:42.120 --> 00:46:50.880
But where it gets real interesting is if you're doing things like reading in a list of files of the file system and writing it out to another file, because you're in control of that encoding.

00:46:51.640 --> 00:46:57.600
So Python has not and probably will not change the default encoding of a file.

00:46:58.100 --> 00:47:00.300
So, you know, you open a file to write text to it.

00:47:00.300 --> 00:47:00.940
What is the default encoding?

00:47:00.940 --> 00:47:02.920
The default on...

00:47:02.920 --> 00:47:05.080
The default is the system locale, typically.

00:47:05.080 --> 00:47:05.600
Okay.

00:47:05.600 --> 00:47:09.340
Which for most non-Windows users these days is UTF-8.

00:47:09.340 --> 00:47:09.860
Yeah.

00:47:10.100 --> 00:47:15.080
And for every Windows user is whatever the legacy encoding is.

00:47:15.080 --> 00:47:17.260
And this is a backwards compatibility thing.

00:47:17.260 --> 00:47:19.600
We would love to change it to be UTF-8 by default.

00:47:19.600 --> 00:47:24.060
But now you can't read in the file that you wrote with the previous version of Python.

00:47:24.060 --> 00:47:25.420
And that...

00:47:25.420 --> 00:47:25.900
Yeah, it's tricky.

00:47:25.900 --> 00:47:26.980
That's just seems...

00:47:26.980 --> 00:47:27.740
That's a hard sell.

00:47:27.740 --> 00:47:28.560
It's very disruptive.

00:47:28.560 --> 00:47:29.560
Very disruptive.

00:47:29.560 --> 00:47:32.020
And concerning, like, what do you mean my file is corrupted?

00:47:32.020 --> 00:47:32.800
Yeah.

00:47:32.800 --> 00:47:34.040
Yeah, that won't feel good.

00:47:34.040 --> 00:47:39.040
Yeah, and so even opening a file to write to, if you want it in UTF-8, then you should just specify that.

00:47:39.040 --> 00:47:40.360
I always put UTF-8.

00:47:40.360 --> 00:47:42.780
I wasn't sure what I'd get if I don't put that, though.

00:47:42.780 --> 00:47:43.440
Yeah.

00:47:43.440 --> 00:47:44.740
You will get...

00:47:44.740 --> 00:47:46.000
It's not entirely random.

00:47:46.000 --> 00:47:48.720
Yeah, but it's not entirely the same, always.

00:47:48.720 --> 00:47:51.360
It's not a complete encoding.

00:47:51.360 --> 00:47:51.920
Okay.

00:47:51.920 --> 00:47:54.440
So there will be characters that can't be written out in that.

00:47:54.440 --> 00:47:54.800
All right.

00:47:54.800 --> 00:47:59.140
Well, let's maybe round this out with one more false assumption here.

00:47:59.140 --> 00:48:03.500
We're sitting here looking at my very fancy Surface Book Pro.

00:48:03.500 --> 00:48:04.780
No, I mean MacBook Pro.

00:48:04.780 --> 00:48:08.080
And I'm a library developer.

00:48:08.540 --> 00:48:11.120
And maybe I can't test on Windows.

00:48:11.120 --> 00:48:12.340
Like, I'm sympathetic.

00:48:12.340 --> 00:48:12.720
Yeah.

00:48:12.720 --> 00:48:15.040
Like, half of my users are Windows developers.

00:48:15.040 --> 00:48:18.140
But I can't verify whether my library works or not.

00:48:18.140 --> 00:48:18.540
Yeah.

00:48:18.540 --> 00:48:19.460
And I get this one.

00:48:19.460 --> 00:48:21.860
Like, it's very easy to...

00:48:21.860 --> 00:48:33.760
Or it's not very easy to get a Windows setup, necessarily, that it's very hard to switch kind of the platform you're used to to another one just for the sake of being able to address all of your users.

00:48:34.660 --> 00:48:36.580
But at the same time, that's not...

00:48:36.580 --> 00:48:38.540
That's like kind of drawing the line too close.

00:48:38.780 --> 00:48:41.260
And it's like, you know, I'm aware of a problem.

00:48:41.260 --> 00:48:43.300
And I'm aware that I need to solve it.

00:48:43.300 --> 00:48:46.220
And I think of one solution and that's too hard.

00:48:46.220 --> 00:48:47.260
And so I stop thinking about it.

00:48:47.260 --> 00:48:47.580
Yeah, yeah.

00:48:47.580 --> 00:48:48.000
That's hard.

00:48:48.000 --> 00:48:48.320
So no.

00:48:48.320 --> 00:48:51.820
And that's kind of what I see happen occasionally here.

00:48:51.820 --> 00:48:59.520
And it just, you know, it makes me, you know, just choke up a little bit because I'm like, that's just bad and lazy.

00:48:59.520 --> 00:49:00.660
Yeah, and so close.

00:49:00.900 --> 00:49:02.860
And we have so many better options these days.

00:49:02.860 --> 00:49:08.320
And it's really saying, thanks, but you're not welcome here to like half the users.

00:49:08.320 --> 00:49:08.960
Absolutely.

00:49:08.960 --> 00:49:09.540
Yeah.

00:49:09.540 --> 00:49:09.880
Yeah.

00:49:09.880 --> 00:49:11.800
And I could get it 10 years ago.

00:49:11.800 --> 00:49:15.060
Because 10 years ago, we didn't have GitHub.

00:49:15.060 --> 00:49:18.780
Or if we did have GitHub, we didn't have the reach of GitHub like we do now.

00:49:18.780 --> 00:49:19.280
Right.

00:49:19.280 --> 00:49:21.520
Or Azure Pipelines or all the CI.

00:49:21.520 --> 00:49:22.520
Azure Pipelines.

00:49:22.520 --> 00:49:24.220
Like I have GitHub Actions.

00:49:24.220 --> 00:49:30.680
We didn't have all of these things where you can either set up to do it automatically and not need to own the machine yourself.

00:49:30.680 --> 00:49:34.540
And we didn't have the reach to be able to say, hey, I need help with this.

00:49:34.540 --> 00:49:36.720
Can someone come and help me test on Windows?

00:49:36.720 --> 00:49:39.640
Because that's how it always happened, essentially.

00:49:39.640 --> 00:49:44.740
Honestly, I think the hardest one to, if it's not you, the hardest one to test for is Mac.

00:49:44.740 --> 00:49:45.240
Yeah.

00:49:45.240 --> 00:49:45.720
Right?

00:49:45.720 --> 00:49:47.960
I test none of my stuff on Mac.

00:49:47.960 --> 00:49:50.840
That's not quite true.

00:49:50.840 --> 00:49:51.700
But I do it all through CI.

00:49:51.700 --> 00:49:52.520
Yeah, exactly.

00:49:52.520 --> 00:49:54.740
But it's tougher to get CI for Mac.

00:49:54.740 --> 00:49:55.580
It is.

00:49:55.580 --> 00:49:56.040
Yeah.

00:49:56.040 --> 00:49:56.320
It is.

00:49:56.320 --> 00:49:58.820
But Windows and Linux are pretty easy to get that.

00:49:58.820 --> 00:49:59.340
They're pretty easy.

00:49:59.340 --> 00:50:03.140
And Azure Pipelines and GitHub Actions both have Windows, Mac, and Linux.

00:50:03.140 --> 00:50:07.320
And I think at this point, they have multiple choices for all of those.

00:50:07.320 --> 00:50:07.640
Okay.

00:50:07.640 --> 00:50:09.980
So you can do like Mojave versus Catalina.

00:50:09.980 --> 00:50:12.340
I think Windows 7 versus 10 or something.

00:50:12.340 --> 00:50:15.100
I don't think we're offering Windows 7 as an option on any of those.

00:50:15.100 --> 00:50:15.960
You don't want to encourage that?

00:50:15.960 --> 00:50:17.480
The builds actually run on Windows Server.

00:50:17.480 --> 00:50:18.700
Not even Windows Client.

00:50:18.700 --> 00:50:22.120
So you do get a choice between Windows Server 2016 and 2019.

00:50:23.080 --> 00:50:27.460
And choice of like the Visual Studio version, which is primarily, you know, people should

00:50:27.460 --> 00:50:29.200
just be on the latest for the most part.

00:50:29.200 --> 00:50:34.780
Python stuff is not that involved in the build tool set to really need to, you know, I must

00:50:34.780 --> 00:50:36.200
stay on the old one anymore.

00:50:36.200 --> 00:50:39.080
We made sure that Python works with future builds as well.

00:50:39.080 --> 00:50:42.160
So you can build for old versions of Python with newer tools now.

00:50:42.160 --> 00:50:43.100
Yeah.

00:50:43.100 --> 00:50:43.660
So that's cool.

00:50:43.660 --> 00:50:47.180
So the options and the opportunities there is really good.

00:50:47.180 --> 00:50:47.800
And they're all free.

00:50:47.800 --> 00:50:51.400
Like it doesn't cost anything to just put on your page.

00:50:51.400 --> 00:50:53.040
I'm looking for someone to help with Windows maintenance.

00:50:53.040 --> 00:50:57.360
And it doesn't cost anything for an open source project to be on GitHub Actions.

00:50:57.360 --> 00:50:58.320
Right.

00:50:58.320 --> 00:51:01.280
And people are probably excited if they're working on Windows.

00:51:01.280 --> 00:51:04.020
Like, oh, this is a really easy way for me to contribute to this project.

00:51:04.020 --> 00:51:04.740
Yeah.

00:51:04.740 --> 00:51:05.040
Right.

00:51:05.100 --> 00:51:08.740
Like all I got to do is sort of like run the test and just try a few things out.

00:51:08.740 --> 00:51:12.420
You'll get more contributors because you're not telling them you have to switch to Linux

00:51:12.420 --> 00:51:15.900
to contribute to my project because you've got the CI running on Linux as well.

00:51:15.900 --> 00:51:16.480
Right.

00:51:16.480 --> 00:51:19.980
So it opens up your pool of contributors and it helps with releases.

00:51:19.980 --> 00:51:23.100
One of the biggest problems we see every time we release an update to Python.

00:51:23.100 --> 00:51:28.560
So Python 3.8 came out and we're seeing this happen a bit is packages don't have wheels

00:51:28.560 --> 00:51:28.820
ready.

00:51:28.820 --> 00:51:32.000
They don't have builds that like they're not actually ready for Python 3.8.

00:51:32.780 --> 00:51:36.600
And once you've got a CI setup going, which is almost automatic.

00:51:36.600 --> 00:51:36.920
Yeah.

00:51:36.920 --> 00:51:37.860
It's almost automatic.

00:51:37.860 --> 00:51:43.720
As soon as the CI service has that version of Python on there or has a way to get it sooner

00:51:43.720 --> 00:51:48.980
and, you know, we're working on making that happen faster, then it's very easy to just

00:51:48.980 --> 00:51:50.660
spin another build and release that.

00:51:50.660 --> 00:51:53.520
And all of your users are now successful at installing your package.

00:51:53.520 --> 00:51:54.400
Good advice.

00:51:54.400 --> 00:51:56.720
So that pretty much wraps it up.

00:51:56.720 --> 00:51:58.400
You want to give us the quick summary?

00:51:58.400 --> 00:51:59.280
The quick summary.

00:51:59.280 --> 00:51:59.720
The checklist.

00:51:59.720 --> 00:52:00.660
You had a checklist.

00:52:00.660 --> 00:52:02.540
You don't have to remember all this.

00:52:02.540 --> 00:52:03.800
Here's the checklist of what you got to do.

00:52:03.800 --> 00:52:04.080
Yeah.

00:52:04.080 --> 00:52:07.440
It annoys me when I see people holding their phones up at me while I'm speaking because

00:52:07.440 --> 00:52:08.680
all of my slides build up.

00:52:08.680 --> 00:52:09.160
Yeah.

00:52:09.160 --> 00:52:12.540
And so like there'll be stuff on the slide that's bad and a big red line is about to appear

00:52:12.540 --> 00:52:14.660
through it and someone's already taking a photo.

00:52:14.660 --> 00:52:15.940
They're going to share it on social media now.

00:52:15.940 --> 00:52:19.020
And I'm like, no, no, wait, wait, wait until it gets crossed out.

00:52:19.020 --> 00:52:19.400
Yeah.

00:52:19.400 --> 00:52:22.840
So I told everyone to wait for the checklist at the end of the talk because I did want to

00:52:22.840 --> 00:52:25.180
make this really actionable and really easy for people to follow up.

00:52:25.640 --> 00:52:30.540
So the things that I would recommend you check just before the next release of your project,

00:52:30.540 --> 00:52:33.820
anytime you feel like it, does the dash M option work on it?

00:52:33.820 --> 00:52:38.300
So if you've got a script entry point, can you also start your project running by typing

00:52:38.300 --> 00:52:41.500
Python 3 dash M name of your project and document it.

00:52:41.500 --> 00:52:43.260
Tell your users this is how you can use it.

00:52:43.260 --> 00:52:43.500
Yeah.

00:52:43.660 --> 00:52:45.340
Are you manipulating paths by hand anywhere?

00:52:45.340 --> 00:52:50.660
Like, do you have any dot split instead of OS dot path dot split or path lib objects?

00:52:50.660 --> 00:52:55.140
I like this recommendation because it's, it's just like you should do the thing that's easier

00:52:55.140 --> 00:52:57.500
and safer and you'll be, you'll be in good shape.

00:52:57.500 --> 00:52:58.000
Yeah.

00:52:58.000 --> 00:53:03.260
Do I put configuration in weird places, which, you know, arbitrary paths for storing stuff.

00:53:03.260 --> 00:53:07.500
It can make a mess, but it can't, you know, you can lose information and make things a

00:53:07.500 --> 00:53:08.200
little harder to find.

00:53:08.200 --> 00:53:10.660
Are you still using bytes for strings?

00:53:11.020 --> 00:53:14.660
If you've gotten out of Python 2 and into Python 3, then there's no need to do that anymore.

00:53:14.660 --> 00:53:17.160
That was the problem that we were trying to move people off.

00:53:17.160 --> 00:53:20.560
So feel free to stop, you know, just use the string type.

00:53:20.560 --> 00:53:22.860
The string type is very optimized for what it does.

00:53:22.860 --> 00:53:27.840
And do you have, you know, continuous integration tools or collaborators on your project?

00:53:27.840 --> 00:53:34.040
Like if it's just you on the project and the problem is that you are not representative

00:53:34.040 --> 00:53:35.340
of your entire audience.

00:53:35.340 --> 00:53:36.620
No one person can be.

00:53:36.620 --> 00:53:37.520
Yeah, no matter who you are or what you do.

00:53:37.520 --> 00:53:37.700
Yeah.

00:53:37.700 --> 00:53:40.980
No matter who you are, there are people out there who are using your code.

00:53:40.980 --> 00:53:42.960
Who are doing things differently from you.

00:53:42.960 --> 00:53:48.660
And with continuous integration tools, GitHub Actions, Azure Pipelines, you can kind of have

00:53:48.660 --> 00:53:52.580
automated systems that look like more of your users, but just welcoming more people in to

00:53:52.580 --> 00:53:53.620
contribute and collaborate.

00:53:53.620 --> 00:53:58.060
Even if it's just, hey, I'll email you when I'm about to do a release.

00:53:58.060 --> 00:54:00.120
Can you run, you know, your tests on it?

00:54:00.800 --> 00:54:04.060
And a lot more people are willing to do that than you think.

00:54:04.060 --> 00:54:04.360
Yeah.

00:54:04.360 --> 00:54:04.960
All right.

00:54:04.960 --> 00:54:06.840
Well, it's all good advice.

00:54:06.840 --> 00:54:10.220
And I definitely think the stats that you laid out are pretty interesting.

00:54:10.220 --> 00:54:11.220
So thanks.

00:54:11.220 --> 00:54:11.480
Yeah.

00:54:11.480 --> 00:54:15.000
Not the world we often see around us, but it's the world as it is.

00:54:15.000 --> 00:54:19.160
At least as good as the stats can measure from what we're using there.

00:54:19.160 --> 00:54:20.020
Cool.

00:54:20.020 --> 00:54:20.260
All right.

00:54:20.260 --> 00:54:22.880
Well, before we wrap up the show, let me ask you the final two questions.

00:54:22.880 --> 00:54:25.100
If you're going to write some Python code, what editor do you use?

00:54:25.180 --> 00:54:27.980
I'm bouncing between editors all the time right now.

00:54:27.980 --> 00:54:29.780
What's in the orbit that you're hitting?

00:54:29.780 --> 00:54:32.040
I use Visual Studio until it annoys me.

00:54:32.040 --> 00:54:34.000
Then I use Visual Studio code until it annoys me.

00:54:34.000 --> 00:54:36.020
Then I use Notepad 2 until it annoys me.

00:54:36.020 --> 00:54:39.060
Then I go back to Visual Studio and that's my code.

00:54:39.060 --> 00:54:41.020
That's the three-body problem, the three-editor problem?

00:54:41.020 --> 00:54:41.960
The three-editor problem.

00:54:41.960 --> 00:54:42.240
Yeah.

00:54:42.240 --> 00:54:42.400
Yeah.

00:54:42.400 --> 00:54:42.900
Indeed.

00:54:42.900 --> 00:54:44.680
And then notable PyPI package.

00:54:44.680 --> 00:54:45.740
Oh.

00:54:45.740 --> 00:54:48.520
What have you come across lately that's like, oh, this is pretty amazing?

00:54:48.520 --> 00:54:51.060
Oh, I forgot this question was going to be here, so I hadn't thought about it.

00:54:51.060 --> 00:54:51.200
Yeah.

00:54:51.200 --> 00:54:53.460
See, this is like improv too.

00:54:53.460 --> 00:54:54.240
On the spot.

00:54:54.240 --> 00:54:54.300
Yeah.

00:54:54.780 --> 00:54:55.320
What was I?

00:54:55.320 --> 00:54:58.040
I was playing with something the other day that I really enjoyed.

00:54:58.040 --> 00:55:00.700
While you're here thinking, I'll tell you about one I found recently that I thought was kind

00:55:00.700 --> 00:55:01.940
of cool is HTTPX.

00:55:01.940 --> 00:55:02.880
Oh, yes.

00:55:02.880 --> 00:55:03.140
Okay.

00:55:03.140 --> 00:55:04.240
I do like that one.

00:55:04.240 --> 00:55:09.060
I like it because it's requests compatible, but it also does HTTP2 and async.

00:55:09.060 --> 00:55:13.180
And then there's also some intermediate, simpler async parallelism built in it.

00:55:13.180 --> 00:55:13.880
It's a cool one.

00:55:13.880 --> 00:55:15.820
I've been helping promote that one.

00:55:15.820 --> 00:55:17.520
It's in its early stages.

00:55:17.520 --> 00:55:18.120
It is.

00:55:18.120 --> 00:55:22.720
They're looking for contributors who are interested in the next big HTTP project.

00:55:22.720 --> 00:55:24.220
So I'm excited about that one.

00:55:24.280 --> 00:55:25.120
I guess I can't claim it.

00:55:25.120 --> 00:55:25.780
Yeah, you claim it.

00:55:25.780 --> 00:55:25.980
Go ahead.

00:55:25.980 --> 00:55:26.500
I can claim it.

00:55:26.500 --> 00:55:26.700
Okay.

00:55:26.700 --> 00:55:28.280
We both like HTTPX.

00:55:28.280 --> 00:55:29.060
Yeah, it's a good one.

00:55:29.060 --> 00:55:29.300
Yeah.

00:55:29.300 --> 00:55:32.120
It is early days and it could use some help, but I like it as well.

00:55:32.120 --> 00:55:32.940
I think it's got promise.

00:55:32.940 --> 00:55:34.260
Cool.

00:55:34.260 --> 00:55:34.560
All right.

00:55:34.620 --> 00:55:36.580
Well, Steve, final call to action.

00:55:36.580 --> 00:55:41.460
People are working on their packages or working on their non-Windows machines.

00:55:41.460 --> 00:55:44.020
What can they do to welcome the Windows people?

00:55:44.020 --> 00:55:46.040
I think it's literally just that.

00:55:46.040 --> 00:55:48.060
Like, welcome the Windows people.

00:55:48.060 --> 00:55:52.640
You know, I gave a few simple things you can do to make them feel welcome, but it really just

00:55:52.640 --> 00:55:52.860
is.

00:55:52.860 --> 00:55:56.080
This also works on Windows, or if it doesn't, we want it to.

00:55:56.080 --> 00:55:57.780
You know, please help.

00:55:57.780 --> 00:55:58.840
Yeah, they got the checklist.

00:55:58.840 --> 00:55:59.280
Yep.

00:55:59.380 --> 00:55:59.580
All right.

00:55:59.580 --> 00:56:00.260
Well, thanks for being here.

00:56:00.260 --> 00:56:00.540
Great.

00:56:00.540 --> 00:56:00.820
Thanks.

00:56:00.820 --> 00:56:01.140
Bye.

00:56:01.140 --> 00:56:01.660
Bye.

00:56:01.660 --> 00:56:05.280
This has been another episode of Talk Python To Me.

00:56:05.280 --> 00:56:09.940
Our guest on this episode was Steve Dower, and it's been brought to you by Linode and

00:56:09.940 --> 00:56:10.760
Brilliant.org.

00:56:10.760 --> 00:56:14.780
Start your next Python project on Linode's state-of-the-art cloud service.

00:56:14.780 --> 00:56:19.280
Just visit talkpython.fm/Linode, L-I-N-O-D-E.

00:56:19.280 --> 00:56:22.500
You'll automatically get a $20 credit when you create a new account.

00:56:22.500 --> 00:56:26.980
Brilliant.org encourages you to give the gift of critical thought and knowledge.

00:56:27.520 --> 00:56:32.440
Visit talkpython.fm/brilliant and grab a gift subscription to help your loved ones

00:56:32.440 --> 00:56:34.320
finish their day a little smarter this season.

00:56:34.320 --> 00:56:36.260
Want to level up your Python?

00:56:36.260 --> 00:56:41.120
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.

00:56:41.120 --> 00:56:46.200
Or if you're looking for something more advanced, check out our new Async course that digs into

00:56:46.200 --> 00:56:49.280
all the different types of Async programming you can do in Python.

00:56:49.280 --> 00:56:53.240
And of course, if you're interested in more than one of these, be sure to check out our

00:56:53.240 --> 00:56:53.940
Everything Bundle.

00:56:53.940 --> 00:56:55.820
It's like a subscription that never expires.

00:56:56.520 --> 00:56:57.980
Be sure to subscribe to the show.

00:56:57.980 --> 00:57:00.380
Open your favorite podcatcher and search for Python.

00:57:00.380 --> 00:57:01.600
We should be right at the top.

00:57:01.600 --> 00:57:06.440
You can also find the iTunes feed at /itunes, the Google Play feed at /play,

00:57:06.440 --> 00:57:10.600
and the direct RSS feed at /rss on talkpython.fm.

00:57:10.600 --> 00:57:12.680
This is your host, Michael Kennedy.

00:57:12.680 --> 00:57:14.180
Thanks so much for listening.

00:57:14.180 --> 00:57:15.220
I really appreciate it.

00:57:15.220 --> 00:57:16.980
Now get out there and write some Python code.

00:57:16.980 --> 00:57:37.440
I'll see you next time.

