Transcript #199: Big news for a very small Python runtimeReturn to episode page view on github
00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds.
00:05 This is episode 199, almost 200 Brian.
00:10 Recorded September 9th, 2020. I'm Michael Kennedy.
00:13 And I'm Brian Okken.
00:15 And this episode is brought to you by us. We'll tell you more about the things that we're doing and what we have to offer later. But for now, I want to talk about not any huge announcement, but a very, very small announcement that is also kind of huge.
00:29 Very cool. Yeah. So micro, you might say, you might say it's microscopic, but it's a big deal.
00:34 So micro Python has just had a new release. And this is significant, because the last release from micro Python was December 19 of last year. So it's been, you know, what is that almost 10 months since the last release. So if you care about micro Python, this is like a pretty big deal.
00:51 So version 113 is out. And one of the major things is it has improved async IO, async and await support, and it has cool Bluetooth improvements.
01:02 And it even comes with the pep 526, that walrus operator.
01:08 Oh, nice.
01:09 Yeah. So there's a lot of stuff going on here. They basically, MicroPython, as you can imagine, comes with a micro async IO module, I'm guessing the U is really a mu, U async IO module, that's supposed to be more compatible with CPython's async I/O.
01:26 So the main idea is that the task object, you can use a task object for each coroutine, which allows you to have like unbounded queues of work and stuff like that.
01:36 Whereas previously, I think you had to pre-allocate it for some reason.
01:39 I never tried to do async I/O on MicroPython, but apparently it was a little bit wonky.
01:44 And so now it's more consistent.
01:47 Another thing that I thought was interesting about this release, Brian, was they went through and auto-formatted all the code in the entire repository.
01:55 And if you look at their repo, there is Python and MicroPython, but a lot like CPython, it's a lot of C as well.
02:03 Right, I think it's like 80% C or something.
02:06 And so they auto-formatted the Python code with black, and that probably won't surprise too many people, but they auto-formatted C with it's, that community's equivalent of black, and get ready for the name, Uncrustify.
02:20 They Uncrustified the C code.
02:22 - Okay. - Do you know about this?
02:23 - No, actually I'm writing it down because I'd like to check this out.
02:26 - Isn't that great?
02:27 So you can basically configure how it formats your C code.
02:29 And it's like black, it's like, you know, it just runs automatically and fixes your C code.
02:34 And boy, if you thought Python code needed some fixing, I'll bet you the C code, and there's more variety in there, right?
02:40 - Yeah, I've seen some ugly C code in my day.
02:43 - Yeah, for sure, for sure.
02:45 'Cause with the curly braces and semicolons, you have a lot more flexibility in how you format stuff.
02:50 Whereas Python forces some of that structure upon you.
02:54 All right, they also added Blue Kitchen.
02:56 Apparently Blue Kitchen is a Bluetooth stack.
02:59 And so they added a micro-MU Bluetooth module as an alternative to the Nimble stack as well.
03:07 And there's a Unix port, and you can build the Unix port with the Bluetooth support for either of these bindings.
03:14 That's pretty cool.
03:15 That comes with new events.
03:17 So if you're doing like Bluetooth discovery and things like that, you can like scan for Bluetooth stuff more easily.
03:23 It also came with a big memory leak fix for arm chips, which is big in the small space, ironically.
03:31 So apparently, there was certain memory that was not reclaimed by the garbage collector and other types of things.
03:37 So if you've, you know, and at the same time on these very small devices, you care a lot about not wasting memory, right?
03:42 It's not like you got 32 gigs like my laptop does.
03:45 So like whatever, right?
03:46 It's going to matter if you lose memory on like a little MicroPython chip.
03:50 And also they set it up so you can run parallel tests against multiple MicroPython targets.
03:58 So I'm guessing like different chips and different devices.
04:00 You can just say, go test them, run it synchronized across two or more MicroPython targets.
04:06 I don't know if that's to speed it up or to like test the whole thing on different platforms in parallel or whatever, but it sounds like a good improvement.
04:13 And it does come with a few breaking changes so people can check that out.
04:17 Anyway, if you care about MicroPython, and I'm guessing this may make its way over to CircuitPython as well at some point, knowing that those projects are really close.
04:25 So anyway, this looks really good if you're doing big stuff on small things.
04:29 Yeah, it's good to see this going forward.
04:31 And thanks to Matt Trentini for sharing this and bringing it to our attention.
04:35 I wish I was better at remembering names, but somebody I had on Testing Code brought up Respex and or Respex, I should stop.
04:44 RESPX, it's a utility for mocking out the Python HTTPX library.
04:50 So that somebody brought that up and I had never heard of it before.
04:53 So I figured we'd bring it up here.
04:55 So with requests, if you want to mock it, there's a cool library called Responses and cleverly named a bit hard to search for.
05:04 And then with HTTPX, if you want to mock it, there is Respex.
05:08 I'm going to name it responseX, but the other part, you just don't write it.
05:12 It's like the opposite of a silent E. It's not written.
05:17 Sorry, keep going.
05:19 It sounds like a great idea.
05:21 Well, interestingly enough, when you write the two imports out, they're the same number of characters.
05:26 Maybe that's part of the reason why they did that.
05:28 Anyway, that quick start shows it's really quick.
05:32 You just, it's a really just a few lines of code to mock out a request response call or response call.
05:39 You can do things like things that you would expect, like an assert that something was actually called and what the status code was and things like that.
05:48 But you can also have custom content and you can return JSON content, of course.
05:54 There's some examples.
05:55 What I like is the documentation is pretty nice.
05:58 There's some examples on how to use it with both PyTest and Unit Test, including how to set up like a mocked API fixture for PyTest so you can have multiple tests using the same mocked endpoint.
06:09 And there's a bunch of nice things about it.
06:13 Like for instance, if you wanna mock out a whole bunch of different URLs, you can use some regular expressions to set what URLs you wanna catch with that.
06:23 And then also the content that you return from your mocked object, your mocked request, is you can have a callback that can generate that on the fly based on what you pass in it.
06:35 If you have a HTTPX-based application, you definitely need to know about this for testing.
06:40 - Yeah, absolutely.
06:41 And one of the things that's challenging about testing the HTTPX is the async stuff, right?
06:47 And so this is a really cool way to get in there and just make it work, right?
06:52 - Yeah.
06:53 - Just put it decorated there, and it just mocks it out for you, like you would expect.
06:57 Looks very clean.
06:58 - Yeah, pretty easy.
06:59 And there's a lot of magic going on under the hood to make that a clean interface, but I think they did a good job.
07:05 - Yeah.
07:06 So HTTPS comes from sort of a async derivative of requests, which I think is a really fantastic library.
07:15 And I've done some cool stuff with HTTPS.
07:16 So yeah, I'm a fan of this.
07:18 It's great.
07:19 Now, before we move on, let's talk about a couple of things that we got going on that people can check out that will definitely help support the show and they might find interesting.
07:29 I know that you've got some updates for your book.
07:32 Is that right?
07:32 - Yeah, the Python testing with PyTestBook, just a minor, the book itself has a minor update.
07:38 So there's, it wasn't a big enough change to change the hardback version, but the ebook will be updated.
07:45 I don't think the hardback is gonna be updated, but it's a couple lines of code in a couple of code examples in chapter five.
07:53 So it's a very minor thing, But the big difference is the code download.
07:59 So we've updated the code download.
08:01 So even if you're working with the hardback book or using the old version, don't update the ebook, please redownload the code.
08:09 It'll make your learning experience better.
08:12 And the main change is that I've pinned the dependencies in the target project or the example project so that everything works better.
08:20 Good, there was a tinyDB is a database that I use in the project.
08:25 and it had some incompatible changes.
08:28 And instead of trying to update everything to use the new TinyDB, I just pinned it to an old version.
08:35 - Yeah, that makes sense.
08:35 I mean, it's not like you're trying to teach people TinyDB.
08:39 You're like, here's a dependency, we're trying to get around to something.
08:42 - Yeah, so that's not important to the content of teaching people how to write tests.
08:47 - Yeah, that's the problem of creating content.
08:49 The world moves on and they're not always compatible with what you did.
08:52 - How about--
08:53 Over at Talk Python, we've got a whole bunch of stuff coming.
08:58 And so what I'd like to encourage people to do is just to go to talkpython.fm or training.talkpython.fm.
09:04 And right there, you can-- at the front of the training site, you can just enter your email so you get a bunch of announcements.
09:09 Because I believe we are working on five or six courses right now or under active development.
09:14 We've got all sorts of great stuff.
09:16 And rather than going through it, just sign up to get notified when those come out.
09:19 Very cool.
09:19 Indeed, indeed.
09:20 So a while ago I went on this Twitter journey, let's say, I don't know how to really explain it.
09:27 It was like I posted a quick question that led to a ton of feedback and then wow, so many pieces of information and ideas and variations were sent around.
09:39 What I was trying to say, like I'd like a dictionary that contains objects that I can access, say with different keys.
09:45 Like I'd like to access by, put a bunch of users and access them by ID, but maybe also by email or by city.
09:52 And that would come with a bunch.
09:52 So it was like this sort of exploration there.
09:55 And one of the recommendations that came over sort of around that is like, hey, you should check out this thing called getpy.
10:02 I don't know where the name comes from, but it doesn't tell a lot about what it is, but it's a vectorized Python dictionary and set implementation.
10:11 And vectorized as in it matches up perfectly with NumPy and so pandas and all the things that are built upon NumPy to plug straight into them.
10:21 So imagine I want to have a dictionary that has data in NumPy, but lets me treat it like a regular Python dictionary or a set and things like that.
10:32 So that's what this is.
10:33 It basically brings a super high performance Python dictionary and set implementation that automatically integrates into the Python scientific ecosystem, which I think is pretty cool.
10:43 Yeah, and it's built upon this thing called parallel hash map.
10:47 So parallel hash map is apparently the current state of the art unordered map set with minimal memory overhead and super fast runtime.
10:56 So like a C binding.
10:58 And so this is just a Python wrapper on top of this C library that's a super fast dictionary and set.
11:05 So that's pretty awesome.
11:07 And here's another one for you, Brian, for your C++ adventures.
11:11 The integration between GitPy and Parallel HashMap is this thing called PyBind11.
11:18 So PyBind11 is a compatibility layer between C++11 and Python.
11:25 So if you want to write like modern C++ and then plug it in easily to Python, here you go.
11:32 - Nice. - Yeah, so that's pretty cool.
11:34 - Okay. - There's two classes, GP, so GitPy, GP.dict and GP.set, And they're designed to be basically similar to the standard dictionaries and sets from Python, but there's a few differences, so check out the docs.
11:47 And then I threw in a quick little example here that has two NumPy arrays, and you can say, here are the keys, here are the values, put them together, and then you can just access different values.
11:58 And it's also typed, which I think is kind of interesting.
12:00 Right, like it has like an unsigned eight-bit integer or something like that, much like NumPy is, but it's more like a Python array where you specify the numerical type than it is just an unbounded list.
12:17 Right, so there's some interesting stuff going on here.
12:18 - Does it solve your problem that you were looking for?
12:20 - No, not at all.
12:21 But it's very interesting.
12:23 - But it's still neat, yeah.
12:24 - Yeah, it's still neat.
12:26 Speaking of neat, we already talked about black once, but it's pretty neat.
12:29 Let's talk about it again.
12:29 - Yeah, this was sent in by John Hagen.
12:32 And he mentioned that, I mean, I'm pretty sure we've mentioned isort before.
12:36 I know we've mentioned black, but a lot of projects use both.
12:40 So, I sort will search your imports, so you don't have to.
12:45 And then just so they're consistent and they're alphabetically sorted.
12:50 And then there's some other--
12:51 Right, and there's PEP8 recommendations about that, I believe, about grouping stuff that comes from the library, from standard library versus externals and whatnot.
12:58 Yeah, and so you don't have to think about it.
13:00 You can just use I sort.
13:02 Black also is becoming more and more popular, I think, or it's just constantly very popular.
13:09 For reform, it's all of your code, but it includes the import statements as well.
13:12 So there was this issue that some projects wanted to use both Isort and Black, and there is, and they kind of fight with each other.
13:21 Right out of the box, if you run Isort, you'll have one answer, and Black will do something different in some cases.
13:29 So what do you do?
13:29 Well, there's Black had a configuration page, and we'll link to this in the show notes, that has documents, what settings you have to set for ISORT so that it's compatible with Black.
13:40 They also do that for Flake 8 and Pylint, which is nice.
13:44 But Flake 8 and Pylint are not that complicated.
13:47 It's the ISORT that's, there's like six settings you have to change.
13:51 But ISORT 5 just came out.
13:53 And ISORT 5 has what they call profiles.
13:57 And so if you run ISORT with profile Black, Black is one of the built-in profiles, it will sort the imports such that they're compatible with black.
14:09 So now if you use isort with the black profile and black also, they won't fight with each other anymore.
14:17 That's pretty cool.
14:19 Black also came out with some new changes.
14:22 So if you're interested in black, check those out.
14:24 They're not huge changes, but some minor fixes.
14:27 The profile feature is pretty cool.
14:29 And even if you don't care about black, I think you should check it out.
14:33 They do, apparently, Django, PyCharm, Google, OpenStack, Clone, Adders, and Hug are other profiles that are included.
14:42 And also, they're just good examples so that you can look at how different projects are configuring their ISORT.
14:48 You can figure yours if you want.
14:50 - Yeah, I really like it.
14:51 That's super cool.
14:52 And it is nice to have the top of your files nice and clean and organized in some certain way.
14:59 - It's interesting.
15:00 A lot of people do different linters or code reformatters, but this combination of ISORT plus black is something that's becoming more and more common in a lot of projects.
15:11 - Yeah, yeah, very cool.
15:13 So I have something interesting for you.
15:16 If you were to think of the influence of Microsoft Excel relative to the influence of all of human genetics and the genome science of the world, and they got into a fight, who would win?
15:29 Like a superhero.
15:30 - (laughs)
15:31 You seem like apples and oranges, I have no idea.
15:33 - Well, they did get into a fight in Excel 1.
15:35 So, here's the story.
15:36 There's a article that was sent over by Chris Moffat.
15:39 He's the guy who wrote the Moving from Excel to Python and Pandas course over at DocPython.
15:45 So, we did a bunch of research into like all these funny things and weird things around Excel.
15:49 So, he sent this one over and I thought I'd cover it 'cause it's fun.
15:52 So, on the Verge, there's an article that talks about scientists have renamed human genes to stop Excel from misreading them as dates.
16:02 Is that crazy?
16:05 So you think of just like formatting and stuff like that.
16:08 So there's like tens of thousands of genes in the human genome and each gene is given a name and a numerical code and then you use to talk about it.
16:17 So like this one controls like what color of hair you have or whatever, right?
16:23 So over the past year or so, 27 human genes have been renamed all because Excel kept re-reading them as symbols, they're symbols of states.
16:32 - Okay, well the examples are important.
16:34 - Yeah, so like March 1, no spaces, March 1 is a one of the genes, right?
16:42 But it gets converted to 03/01/year, or if you're in Europe, 01/03/the year, right?
16:50 Either way, that's not what you wanted.
16:52 So, March 1 actually stands for membrane-associated ring CH type finger 1, which of course is the 1st of March.
17:02 Now it sounds funny, like we're making fun of it, like ah, whatever.
17:06 There's a study in 2016 that examined the genetic data shared alongside 3,600 published papers and found that one fifth of them, which, what is that?
17:20 that's like 700 papers were affected by Excel errors.
17:24 - Oh man, yeah.
17:25 - Isn't that messed up?
17:26 So there's a scientific body in charge of naming genes called Hugo Gene Nomenclature Committee.
17:34 Who knew?
17:34 There's a committee for naming genes, but apparently.
17:36 So they published new guidelines for naming genes and they said, you have to consider what happens if you type into Excel.
17:43 If it gets reformatted, that's not okay.
17:46 Gotta pick a new name.
17:49 So they put like weird suffixes and stuff on these things to make them work.
17:52 Like March 1 is now like March 1 N1 or something like that.
17:55 Anyway, so why do I bring this up on the Python show?
17:58 You know, so much of this work that people are doing there can totally be solved by pandas and Jupyter notebook and stuff.
18:06 And so I, you know, the guy who was quoted in there was like, hey, I made these mistakes when I was in grad school because all I knew how to use was Excel.
18:15 So here's a bit of an example along with a plea to help folks who are overusing Excel to take a step forward and use something like Pandas and Jupyter.
18:28 And you're going to be able to do a lot more cool processing anyway, which I think is great.
18:34 Also one other thing, if you think the geneticists have an exclusive right to these mistakes, There's a really cool article, blog post over on Oracle's blog actually, called "The 10 Costliest Spreadsheet Boo-Boos in History." And they're really hilarious, and like, "Thank God this didn't happen to me." Well, and just like awesome stock photo that they have for this too.
18:58 Yeah, it's so bad.
19:00 Yeah, it's like perfect.
19:01 It could just come out of Excel.
19:04 So, some of them are fairly mundane, but others like MI5, the British intelligence agency, agency bugged over a thousand wrong phone numbers because the 000 in the last three digits of the number got, you know, misstated.
19:20 - Oh no.
19:21 - Yeah, or Eastman Kodak was forced to reinstate financial results for two quarters by, from, yeah, two million and 13 million respectively due to a spreadsheet mistake.
19:34 Yeah, there's just all these crazy examples of stuff just going wrong.
19:37 Like, oh, sorry, that was a billion dollar mistake we were off by some random thing.
19:42 Anyway, there's a bunch of errors like this and it's really interesting to think how you might use the Python tools to not have these errors.
19:50 I think Excel has too much influence over the world.
19:52 It does.
19:53 But if you were going to use Python and you had a Jupyter notebook, would you run it in your downloads folder?
19:59 No, definitely not.
20:01 Yeah, so this is another, just kind of an interesting and shocking, I never really think about it before, but Glyph has written an article called "Never Run Python in Your Downloads Folder." It's not just about that. Okay, so there's your advice. Don't run Python in your downloads folder.
20:18 But I think it's a good article to spread around and read because it's a nice short tutorial on how syspath works, how it's populated. So Python has this thing called syspath that is, that's where where it looks up.
20:32 So if you say import something or mostly that, where it's importing things, also the dash M or something, if you say dash M and then some module, where does it find that?
20:44 And it finds it in lots of places.
20:46 One is the normal system include directory or the system packages, but there's other places too.
20:53 And one of the places where Python uses is the location you're in when you run Python.
20:59 So a little example, he talks about a lot of people are now using, instead of running pip directly, they run Python-M pip, which I also am including that in my advice usually, because I'm tired of trying to fix people's errors when their Python and their pip are pointing to two different places.
21:21 That's frustrating.
21:22 So what happens if you run Python-M pip install something, some wheel in your downloads directory.
21:46 It's possible. I don't know if it would happen, but it's possible.
21:49 It's more likely now. Yeah, especially now.
21:52 Thanks, Cliff. But then it's going to run that instead of the pip that you expect it to run, which is bothersome.
22:00 So this is hidden, there's some extra advice in here.
22:02 I encourage everybody to read the whole article.
22:05 Understanding how the Python path variable works as well, because sometimes other applications will, and if the installer of an application can change things and change your Python path, it shouldn't, but sometimes they'll do that out of convenience.
22:22 So, occasionally look at your Python path and make sure that there's nothing weird in there.
22:27 And maybe contact application developers or if they're doing something odd.
22:32 If you are mucking with Python path, the recommendation is put absolute paths.
22:36 Don't put anything relative in there.
22:38 You want to be able to have complete control over that.
22:41 The problem with the downloads folder is not that the downloads folder has weird permissions or higher permissions or anything of that nature.
22:49 It's just that web virus maliciousness might, it's most likely to drop the payload there and the Python path plus that operation or that aspect is what is likely to lead to trouble.
23:03 - Yeah. - Right?
23:04 Like you wouldn't say don't run it in your documents folder unless you copy virus Python files in there.
23:09 - Yeah, in the example, it was real of like sometimes, like let's say you're behind a firewall or something like that and pip install just doesn't work and you haven't figured out how to do proxies yet, and you really just need some package, you might just download the wheel somewhere.
23:25 Okay, you might have that, and the wheel might be fine, but put it somewhere else.
23:29 Don't leave it in your downloads directory, put it someplace else.
23:32 And please use virtual environments.
23:34 That'll help things as well.
23:35 - Yeah, absolutely.
23:37 Good advice, and definitely another thing to be aware of.
23:40 That internet, it's a scary place.
23:44 - Yes, but we love it.
23:45 - It's also a good place.
23:46 It goes both ways, 'cause we do love it.
23:48 That's it for our main topics, but I do wanna share two quick things, and they both have to do with the internet.
23:53 Number one is we just passed 5 million downloads, Brian.
23:57 - Wow. - That's awesome.
23:59 Yeah, and we're in the top 150 or so of all tech podcasts in the world.
24:04 So I just wanna say thank you everyone that's helped to make that happen, 'cause that's kind of a milestone, so that's really cool.
24:09 - Yes, thank you. - Indeed.
24:10 Also, I recently finally broke down and got a wifi mesh router or routers.
24:18 Can you say singular router?
24:19 It's gotta be plural, right?
24:21 So one of those routers where it has a bunch of different stations and they all work together, but because of the way it works, you don't actually have to connect to different ones at different places.
24:31 It's just all one wifi.
24:33 And man, I got this Linksys wifi six mesh router, which is quite pricey, but man, it is so, so awesome.
24:42 So if people are like suffering from being home all the time that I, gosh, I gotta get better internet.
24:46 My internet was actually pretty good here, but we started getting a ton of radio interference from different sources, and it would degrade it and stuff.
24:54 So I have my recording area office above my garage, this little studio apartment thing we built, above the garage, which is a separate building across from the house.
25:05 And over here, if I go speed test, I get 400 megabit measured off my Wi-Fi now.
25:10 That is solid.
25:11 - Okay, so how far away are the mesh nodes?
25:15 - It's probably 50 feet, but it goes through like several outside walls, through like a couple inside walls, there's layers it's gotta go through.
25:23 But now with the mesh, I could put one of the nodes much closer to the wall that I'm close to that spans like that gap between houses.
25:30 - Okay, and how are they talking to each other?
25:32 - They have like their own channel, and they do some kind of like back channel Wi-Fi 6 thing.
25:38 So anyway, super good recommendation, yes.
25:41 How about you any extra stuff you want to share the world? No, just I'm sort of sick of it and fires and all that Sort of stuff. Yeah, man. It's it's looking a little smoky outside and Yeah, the whole West Coast and my sympathies go out to the folks in Northern, California I just had a meeting with someone and oh my gosh, is that smoky there?
26:00 It looked like night in the daytime in the background I could see their window and it was it was dark as if they were in it like a different time zone But they weren't not good. So hopefully hopefully that all in soon But before we end this episode I got a question Brian for you Are you a real programmer like a real one like a hardcore? I mean you do see plus-plus So I put you a little closer. Oh my god It's posture syndrome flares every time I get that question. So I don't think so Let's go to XKCD and answer it. Okay, okay So XKCD has this cartoon called Real Programmers, and it starts with two people debating about what kind of editor they're using, right?
26:42 It says there's somebody working and they're using Nano, the editor.
26:46 And the person, come on, Nano for real, real programmers use Emacs.
26:51 And then Brian walks in, Hey, real programmers use Vim.
26:55 Come on.
26:55 Oh yeah.
26:56 Well, real programmers use Ed.
26:58 No, no real programmers use cat and just stick it on the end.
27:01 Real programmers use a magnetized needle in a steady hand.
27:05 Excuse me, but real programmers use butterflies.
27:09 Everyone turns and looks at the person.
27:11 They open their hands and they let the delicate wings flap once.
27:15 The disturbance ripples outward, changing the flow of the eddy currents in the upper atmosphere, which acts as a lens that deflects incoming cosmic rays, focusing them to strike the derived platter and flip the desired bit.
27:29 Of course, there's an Emacs command to do that.
27:31 Oh yeah? Yeah. Command X, Command M, Command Butterfly.
27:40 Yeah, yeah. C-M-C-X, C-X-C-M-C-M-Butterfly. Indeed.
27:46 Damn it, Emacs, they say.
27:48 Does anybody use Emacs?
27:50 Yeah, well, I don't know, but I'm not a real programmer, because I don't use butterflies. I'm sorry.
27:54 No, I don't use butterflies.
27:56 Okay, well, we're in the joke section. I've got to share a terrible joke that my wife came up with.
28:00 came up with.
28:01 Okay, 99 bottles of beer on the wall, 99 bottles of beer, take one down, pass it around, now everybody's infected.
28:09 Hey, that sounds like college here in the US.
28:15 I think that's what they're doing.
28:16 I'm like, I can tell from all the news I'm watching.
28:18 Oh my gosh.
28:19 Geez, sorry.
28:20 Yeah, these jokes are the 2020 jokes.
28:22 Oh yeah, so this won't make sense in the future.
28:27 So in the future, when you speak to a historian and you say, "Oh, you're a historian.
28:32 What do you study?" "Oh, I actually study the year 2020." That won't be enough.
28:39 You'll have to say, "Well, which part?
28:40 Do you study the beginning?
28:44 Do you study the financial crash?
28:45 Do you study this crazy election?
28:47 Do you study the pandemic?" That year is not enough to say what your specialty is.
28:52 You got to pick one.
28:53 Pick a quarter.
28:55 Pick a quarter.
28:56 I study the fires. Oh boy.
28:59 Anyway, well, good talking with you as always.
29:02 You as well. Catch you later.
29:03 Thank you for listening to Python Bytes. Follow the show on Twitter via @PythonBytes.
29:07 That's Python Bytes as in B-Y-T-E-S. And get the full show notes at PythonBytes.fm.
29:14 If you have a news item you want featured, just visit PythonBytes.fm and send it our way.
29:18 We're always on the lookout for sharing something cool.
29:21 On behalf of myself and Brian Auken, this is Michael Kennedy.
29:24 Thank you for listening and sharing this podcast with your friends and colleagues.