WEBVTT

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

00:00:05.260 --> 00:00:10.460
This is episode 175, recorded March 26, 2020.

00:00:10.460 --> 00:00:11.440
I'm Michael Kennedy.

00:00:11.440 --> 00:00:12.460
And I'm Brian Okken.

00:00:12.460 --> 00:00:13.640
Brian, we have a special guest.

00:00:13.640 --> 00:00:16.880
Welcome, Matt Harrison. How are you doing, man? Glad to have you here.

00:00:16.880 --> 00:00:19.540
Good. Good. Thanks for coming. Come on.

00:00:19.540 --> 00:00:22.140
Yeah. It's always nice to have you on the show.

00:00:22.140 --> 00:00:25.840
Before we get into it, let me just tell you this episode is sponsored by Datadog.

00:00:25.840 --> 00:00:27.800
Check them out at pythonbytes.fm.

00:00:28.460 --> 00:00:30.480
Datadog. I'll tell you more stuff about them later.

00:00:30.480 --> 00:00:33.200
First, I want to just throw this out to both of you guys.

00:00:33.200 --> 00:00:39.380
The world is, I don't know, is it turned upside down or is it locked down or what has gone on with the world? It's crazy.

00:00:39.380 --> 00:00:43.500
We're kind of software people, and I know we're all kind of in different boats.

00:00:43.500 --> 00:00:46.520
I am definitely grateful that I'm a software person.

00:00:46.520 --> 00:00:56.600
I have a lot of friends that are not, that are in the retail industry or the selling stuff to people sort of industry or self-employed.

00:00:56.740 --> 00:00:58.680
And those people, they're really hurting.

00:00:58.680 --> 00:01:05.820
I've got a lot of people I know that if they're self-employed, you don't qualify for unemployment insurance and stuff.

00:01:05.820 --> 00:01:07.180
So there's a lot of people hurting.

00:01:07.180 --> 00:01:08.500
How are you guys?

00:01:08.500 --> 00:01:09.000
It's crazy.

00:01:09.000 --> 00:01:09.600
Yeah.

00:01:09.600 --> 00:01:10.300
Matt, how about you?

00:01:10.480 --> 00:01:15.980
I just found out this morning that my largest client just dropped all my trainings for the rest of the year.

00:01:15.980 --> 00:01:19.520
That's not your favorite phone call or email to receive, is it?

00:01:19.520 --> 00:01:26.720
Not the best news, but the thought that I have on that is like past couple of years have been very good, right?

00:01:26.800 --> 00:01:29.760
And people have said like the bubble will burst.

00:01:29.760 --> 00:01:36.600
And I don't know that we thought that a virus would do this, but I mean, it looks like winter came for better, for worse.

00:01:36.600 --> 00:01:38.860
And so people are going to have to adapt.

00:01:39.480 --> 00:01:43.440
And now if you can weather the storm, it's going to be tough though.

00:01:43.440 --> 00:01:50.100
I mean, I was even talking with some friends who are in the medical industry and they're like, we're worried about our jobs, right?

00:01:50.100 --> 00:01:53.260
And these are like doctors and people who work at the hospital.

00:01:53.260 --> 00:01:56.880
So it's interesting to see what's going on.

00:01:57.100 --> 00:02:01.240
And I've worked from home for the good portion of the last 15 years.

00:02:01.240 --> 00:02:07.500
And right now it's scary to see that there's a lot of upheaval and we'll see what happens.

00:02:07.500 --> 00:02:08.960
How are things going for you, Michael?

00:02:08.960 --> 00:02:10.320
Well, you know what?

00:02:10.320 --> 00:02:12.020
It's really interesting.

00:02:12.020 --> 00:02:23.040
If you'd asked me this question like six years ago when I was doing mostly in-person training, it would have been like somebody just cut the light switch off and said, you know, we're all leaving.

00:02:23.040 --> 00:02:23.600
Yeah.

00:02:23.600 --> 00:02:24.960
Lock the door on your way out, right?

00:02:25.000 --> 00:02:27.840
It would have been purely traumatic.

00:02:27.840 --> 00:02:31.760
Luckily now, like online courses are great still.

00:02:31.760 --> 00:02:33.540
Podcasting is great.

00:02:33.540 --> 00:02:39.680
Like what's ironic is my work life is literally unchanged, but the rest of my life is scrambled, right?

00:02:39.680 --> 00:02:42.540
Like my daughter is home from school because they closed school.

00:02:42.540 --> 00:02:44.240
Like Oregon's now on full lockdown.

00:02:44.240 --> 00:02:46.280
Like it's hard to go out to dinner.

00:02:46.280 --> 00:02:50.720
So everything is changed in some ways, but ironically, not my work life really.

00:02:50.720 --> 00:02:53.280
I'm sure it'll have some effect eventually, but nothing immediate.

00:02:53.800 --> 00:02:55.520
I guess one more thing before we move off.

00:02:55.520 --> 00:02:56.100
I'm just curious.

00:02:56.100 --> 00:02:57.660
Like what are your plans around training?

00:02:57.660 --> 00:03:01.980
Like are you going to be teaching over Zoom or is it just focus on other stuff until it comes back?

00:03:01.980 --> 00:03:03.720
Yeah, I think both of that.

00:03:03.720 --> 00:03:09.760
I do have some clients who are moving to virtual training and I already do a bunch of virtual training anyway.

00:03:09.760 --> 00:03:23.840
So, I mean, it's sad that some of them aren't able to or can't due to circumstances or whatnot, but try and see if other people want virtual training and just work on other products that people are interested in as well.

00:03:23.840 --> 00:03:24.940
Yeah, absolutely.

00:03:24.940 --> 00:03:26.640
Well, hang tough.

00:03:26.640 --> 00:03:33.960
You guys and everyone out there, it's going to be a wild ride and hopefully the software side of the world is a little bit less bumpy, but it's still, it's crazy.

00:03:34.600 --> 00:03:38.360
All right, well, let's talk a little bit about the future, Brian.

00:03:38.360 --> 00:03:44.020
Like we can't predict when the COVID stuff is going to be better, but you could probably predict some stuff about the Python in the future.

00:03:44.260 --> 00:03:48.920
I'm just still getting excited, used to being able to have Python 3.8 everywhere.

00:03:48.920 --> 00:03:55.160
And, but we've got Python 3.9 right around the corner and in October is the scheduled release.

00:03:55.160 --> 00:04:00.480
I don't know if that'll change due to the virus or not, but that's where it is.

00:04:00.480 --> 00:04:09.080
And one of the cool things that I noticed from a blog article is that there's union operators coming for dictionaries in Python 3.9.

00:04:09.080 --> 00:04:11.740
And this is a PEP 584.

00:04:11.740 --> 00:04:19.520
And there's a article called a dictionary merging and updating in Python 3.9 by not, I think young qui.

00:04:20.140 --> 00:04:22.560
And there's a couple new operators.

00:04:22.560 --> 00:04:28.540
One of them, it's just the bar or the bar equals or the pipe operator, whatever.

00:04:28.540 --> 00:04:32.680
It looks normal for if you're used to, I guess that's the math or operator.

00:04:32.680 --> 00:04:36.200
It's like a bitwise or, yeah.

00:04:36.200 --> 00:04:37.680
I'm kind of excited about it.

00:04:37.680 --> 00:04:45.460
So you can combine two dictionaries by just doing like a dictionary one or dictionary two or something like that.

00:04:45.660 --> 00:04:51.860
And then the equivalent assignment operator as well, which is really an update operator and a merge.

00:04:51.860 --> 00:04:59.160
The article spent a little bit of time talking about the other older methods that you can use to combine dictionaries now.

00:04:59.160 --> 00:05:02.320
And I know people have covered those in a lot of places.

00:05:02.320 --> 00:05:05.360
The one thing, the article actually spent a lot of time on it.

00:05:05.360 --> 00:05:10.940
And I just think it's something to watch out for and be aware of is when you're combining dictionaries, usually the,

00:05:11.500 --> 00:05:17.840
if there's overlapping values, like if there's a value with the same key in both dictionaries,

00:05:17.840 --> 00:05:20.380
you'll get the second one will take precedence.

00:05:20.380 --> 00:05:22.420
It's just something to be aware of.

00:05:22.420 --> 00:05:22.740
Yeah.

00:05:22.740 --> 00:05:22.980
Yeah.

00:05:22.980 --> 00:05:26.160
And that's the way it works in the, like the current operators as well, right?

00:05:26.160 --> 00:05:29.180
The star star sort of combine stuff and whatnot.

00:05:29.180 --> 00:05:29.600
Yeah.

00:05:29.600 --> 00:05:32.460
As long as you're aware of it, it's good to know, but this is clean.

00:05:32.460 --> 00:05:36.760
It's actually something that now that I see it, I'm surprised that we don't already have a,

00:05:36.760 --> 00:05:41.820
an operator already in to combine dictionaries because it's something I kind of do a lot of.

00:05:41.820 --> 00:05:42.100
So.

00:05:42.100 --> 00:05:42.400
Yeah.

00:05:42.400 --> 00:05:47.120
And if you look at the syntax there for the pipe, I mean, the pipe is already in the set operator.

00:05:47.120 --> 00:05:53.960
And prior to sets existing, when people used to use dictionaries to emulate sets, I mean,

00:05:53.960 --> 00:05:57.780
they wouldn't do the or operator, but, but it's, it's interesting that it's sort of coming around

00:05:57.780 --> 00:05:59.960
circle now that we originally had dictionaries.

00:05:59.960 --> 00:06:04.080
People started using dictionaries as a simple replacement for sets.

00:06:04.180 --> 00:06:08.540
And we got sets, which had the pipe operator and now the pipe is coming back to the dictionary.

00:06:08.540 --> 00:06:09.340
Interesting.

00:06:09.340 --> 00:06:11.660
So why do you guys think they didn't use plus?

00:06:11.660 --> 00:06:15.660
Like you want to combine two things like two lists.

00:06:15.660 --> 00:06:17.440
You don't use a pipe to put them together.

00:06:17.440 --> 00:06:18.780
You use a plus for strings.

00:06:18.780 --> 00:06:19.640
Use a plus.

00:06:19.640 --> 00:06:20.940
Plus already existed.

00:06:20.940 --> 00:06:25.060
I think it's because of the union operator already being used for sets.

00:06:25.060 --> 00:06:25.440
Yeah.

00:06:25.440 --> 00:06:26.000
You think so?

00:06:26.000 --> 00:06:26.680
Yeah.

00:06:26.680 --> 00:06:26.940
All right.

00:06:26.940 --> 00:06:27.140
Cool.

00:06:27.140 --> 00:06:32.780
Well, yeah, it's good to see some nice shorthands coming there, but if we can have a pipe equals

00:06:32.780 --> 00:06:35.000
operator, give me the plus plus.

00:06:35.000 --> 00:06:35.360
Come on.

00:06:35.360 --> 00:06:36.320
I just want the plus plus.

00:06:36.320 --> 00:06:39.180
I want the double pipe.

00:06:39.180 --> 00:06:40.660
Yeah.

00:06:40.660 --> 00:06:41.280
Double pipe.

00:06:41.280 --> 00:06:42.360
What does that mean?

00:06:42.360 --> 00:06:44.360
All right, Matt, you got the next one.

00:06:44.360 --> 00:06:48.620
This one is short and sweet, but it looks pretty cool if you got the use case for it.

00:06:48.620 --> 00:06:49.220
Yeah.

00:06:49.220 --> 00:06:49.620
Yeah.

00:06:49.620 --> 00:06:59.280
So there is this super string library, which is a new library that's a replacement of, well,

00:06:59.280 --> 00:07:02.560
not a replacement, but it's a new string library for holding sequences of characters.

00:07:02.560 --> 00:07:07.700
It's built on this rope data structure, and apparently it's pretty optimized.

00:07:07.960 --> 00:07:15.740
It uses a 20th the amount of memory and a fifth the speed, so operates five times faster for

00:07:15.740 --> 00:07:16.740
a lot of operations.

00:07:16.740 --> 00:07:23.160
I think this could be super useful for people who are manipulating data.

00:07:23.520 --> 00:07:28.860
So it'd be interesting to look at if the people who are doing NLP could take advantage of this.

00:07:28.860 --> 00:07:36.440
Definitely the memory constraints, using a 20th the amount of memory would be awesome, even

00:07:36.440 --> 00:07:41.100
in places like Pandas, NLP as well, natural language processing.

00:07:41.600 --> 00:07:44.280
The API is pretty basic right now.

00:07:44.280 --> 00:07:49.560
It's got concatenation, getting to the length, doing some indexing and slicing and stripping

00:07:49.560 --> 00:07:50.920
and uppercasing and lowercasing.

00:07:50.920 --> 00:07:56.320
So that could be a good, with the speed and memory performance they're showing, that could

00:07:56.320 --> 00:08:00.040
be a good enough limited set of capabilities.

00:08:00.040 --> 00:08:04.020
Sort of for me, the elephant in the room is the F string.

00:08:04.020 --> 00:08:06.840
For me, that's the best feature of Python 3.

00:08:06.840 --> 00:08:08.100
I know.

00:08:09.140 --> 00:08:11.960
Implement that, and let's use it.

00:08:11.960 --> 00:08:17.240
Yeah, the other thing that's missing is negative indexes, but that can't be hard to add, honestly.

00:08:17.240 --> 00:08:21.120
Maybe it's hard to add quickly, but it can't be hard to add negative indexing.

00:08:21.120 --> 00:08:22.500
That's a good point.

00:08:22.500 --> 00:08:25.720
I mean, they don't make any reference to whether they support Unicode.

00:08:25.720 --> 00:08:28.420
So that's, I guess, another question, right?

00:08:28.420 --> 00:08:34.300
If they do support the Unicode capabilities, the Python supporting, I mean, Unicode can make

00:08:34.300 --> 00:08:38.920
indexing a little bit more complicated, but that might be what's going on there.

00:08:38.920 --> 00:08:43.360
But this will be interesting to watch, interesting library to watch.

00:08:43.360 --> 00:08:44.080
What do you think, Brian?

00:08:44.080 --> 00:08:50.660
I'm just not in a place where the strings are the memory or the bottleneck in any of my applications.

00:08:50.660 --> 00:08:52.280
Yeah.

00:08:52.280 --> 00:08:55.780
Yeah, but to give you an example, like a real world example, like I've been playing with

00:08:55.780 --> 00:09:00.720
some Markdown stuff for like the sort of CMS side of things that I'm writing in Markdown.

00:09:00.720 --> 00:09:07.020
And if you've got something that's maybe 10, 20 pages of Markdown, it takes half a second

00:09:07.020 --> 00:09:10.340
to convert that from Markdown to HTML.

00:09:10.340 --> 00:09:15.080
I don't know how much of that is like the actual string juggling and how much of that is just

00:09:15.080 --> 00:09:16.840
converting it to Markdown is slow.

00:09:16.980 --> 00:09:22.080
But that's a non-trivial amount of processing that's like sort of around the corner.

00:09:22.080 --> 00:09:23.380
I mean, you would never do it manually.

00:09:23.380 --> 00:09:24.620
You would use a library, right?

00:09:24.620 --> 00:09:26.940
But still, you can benefit from that.

00:09:26.940 --> 00:09:30.520
On that, you can think of all the people who are using static libraries, right?

00:09:30.520 --> 00:09:35.080
For web pages who, you know, once you get, they all complain about once you get X number

00:09:35.080 --> 00:09:37.000
of pages in there, they start getting slow.

00:09:37.000 --> 00:09:41.520
And the rebuild takes five seconds instead of a half a second or whatever, right?

00:09:41.620 --> 00:09:44.680
And so something like this could help there as well.

00:09:44.680 --> 00:09:45.180
Right.

00:09:45.180 --> 00:09:45.700
Theoretically.

00:09:45.700 --> 00:09:49.980
So this is not a super popular library, but I'm glad you put it on here because I think

00:09:49.980 --> 00:09:50.520
it's pretty cool.

00:09:50.520 --> 00:09:51.880
I guess two thoughts.

00:09:51.880 --> 00:09:58.480
One, it'd be interesting to look at what they're doing and if there's any easy low-hanging fruit

00:09:58.480 --> 00:10:02.000
to bring back to CPython because it would be better if just Python strings were faster.

00:10:02.000 --> 00:10:03.140
And they're like, why would you make this?

00:10:03.140 --> 00:10:03.900
It's the same speed.

00:10:03.900 --> 00:10:04.740
You know what I mean?

00:10:04.740 --> 00:10:08.180
Then the other, Brian, you may have noticed, there's no tests.

00:10:08.180 --> 00:10:10.640
Yeah, it looks like it's recent.

00:10:10.980 --> 00:10:14.520
It's like, I don't know if it's even been around for more than a week.

00:10:14.520 --> 00:10:16.200
Yeah, I think it's pretty new.

00:10:16.200 --> 00:10:18.540
So if somebody's like, oh, this is cool, let me try it out.

00:10:18.540 --> 00:10:22.660
Like maybe a way you could participate is like write some tests just to verify things, right?

00:10:22.660 --> 00:10:23.840
But yeah, pretty cool.

00:10:23.840 --> 00:10:24.820
It's just imaginary.

00:10:24.820 --> 00:10:27.860
If there's no test, it's like no picture, no proof, man.

00:10:27.860 --> 00:10:33.680
If it continuously deployed in the woods and there were no tests to hear it, did it actually

00:10:33.680 --> 00:10:33.940
happen?

00:10:33.940 --> 00:10:34.400
Something like that?

00:10:34.400 --> 00:10:35.720
Yeah, yeah, exactly.

00:10:35.720 --> 00:10:36.480
Sure.

00:10:36.480 --> 00:10:39.000
That's the saying, I think, the historical version.

00:10:39.740 --> 00:10:45.760
I thought your new testing strategy is if it doesn't have tests and you don't commit

00:10:45.760 --> 00:10:46.000
it.

00:10:46.000 --> 00:10:47.620
Didn't you say you're using something like that?

00:10:47.620 --> 00:10:50.400
Yeah, that's good.

00:10:50.400 --> 00:10:52.060
Yeah, that's a good way for sure.

00:10:52.060 --> 00:10:52.760
All right.

00:10:52.760 --> 00:10:56.260
So this next one is going to affect everybody who works with Python.

00:10:56.260 --> 00:10:57.500
This is a big deal.

00:10:58.200 --> 00:11:00.840
Hopefully it's not a bumpy deal, but it's a big deal.

00:11:00.840 --> 00:11:08.480
So the Python Packaging Authority folks, the PSF subgroup, they recently got funding to

00:11:08.480 --> 00:11:10.980
hire some developers to make pip better.

00:11:10.980 --> 00:11:12.840
So pip is awesome.

00:11:12.840 --> 00:11:14.020
We all pip things.

00:11:14.020 --> 00:11:18.680
And even if you don't pip things, if you pip them or you poetry them, you really pip them

00:11:18.680 --> 00:11:19.480
down below, right?

00:11:19.480 --> 00:11:22.520
So they got a bunch of funding to make that better.

00:11:22.520 --> 00:11:27.340
And one of the challenges, one of the first challenges that they're tackling is that pip

00:11:27.340 --> 00:11:32.140
will, it's not, it doesn't take into account all the stuff you're trying to do.

00:11:32.140 --> 00:11:34.840
It just says, I see a requirements file.

00:11:34.840 --> 00:11:37.520
Let me just go from top to bottom, just start hitting it, right?

00:11:37.520 --> 00:11:38.880
Install the first one.

00:11:38.880 --> 00:11:39.560
Install the second one.

00:11:39.660 --> 00:11:43.900
So they're rolling out a new pip resolver at the end of the year.

00:11:43.900 --> 00:11:45.080
That's pretty cool, huh?

00:11:45.080 --> 00:11:45.420
Yeah.

00:11:45.420 --> 00:11:46.460
This is neat.

00:11:46.460 --> 00:11:46.700
Yeah.

00:11:46.700 --> 00:11:51.680
So the idea is basically, it's going to go and it's going to look at the dependencies of

00:11:51.680 --> 00:11:56.480
the various packages and try to install something that is consistent across all of them.

00:11:56.480 --> 00:12:02.380
Like maybe the first package in your requirements files requires, I don't know, docutils 16.

00:12:02.380 --> 00:12:05.680
And the second one requires docutils 15.

00:12:05.680 --> 00:12:09.020
Or maybe the first one doesn't even specify and 16 is just the latest.

00:12:09.020 --> 00:12:13.200
If you pip install -r that you're going to get 16 and then it's going to complain that

00:12:13.200 --> 00:12:14.580
you have 16 and not 15.

00:12:14.580 --> 00:12:15.180
You know what I mean?

00:12:15.180 --> 00:12:20.180
It's like, it just doesn't even factor in the larger system that these two things have

00:12:20.180 --> 00:12:20.620
to coexist.

00:12:20.620 --> 00:12:22.540
So that's one of the things they're working on.

00:12:22.540 --> 00:12:27.840
So to reduce inconsistency, it'll no longer install a combination of packages that's mutually

00:12:27.840 --> 00:12:30.720
inconsistent and it will be no pushover.

00:12:30.720 --> 00:12:31.920
It can be strict.

00:12:31.920 --> 00:12:38.820
If you ask it to install two packages with incompatible requirements, it will say no.

00:12:38.820 --> 00:12:39.900
It will not do it.

00:12:39.900 --> 00:12:40.120
Yeah.

00:12:40.120 --> 00:12:41.900
And then it just doesn't install anything, I think.

00:12:41.900 --> 00:12:42.240
Yeah.

00:12:42.240 --> 00:12:42.580
Yeah.

00:12:42.580 --> 00:12:43.940
It just says, no, I can't install it.

00:12:43.940 --> 00:12:46.540
That might cause some problems, right?

00:12:46.540 --> 00:12:47.600
Yeah, it might.

00:12:47.600 --> 00:12:52.420
Or make people's processes work differently.

00:12:53.000 --> 00:13:00.500
Because I mean, right now I know there's a bunch of library top of each other and I can sort

00:13:00.500 --> 00:13:02.680
of just install them over on top of it.

00:13:02.680 --> 00:13:07.860
I have my libraries and some of them sort of work and some of it doesn't refuse to install

00:13:07.860 --> 00:13:08.080
them.

00:13:08.080 --> 00:13:12.460
So this might be a speed bump in the road for a lot of people.

00:13:12.940 --> 00:13:18.940
And maybe in the end it works out better, but might cause some consternation in the short

00:13:18.940 --> 00:13:19.240
term.

00:13:19.240 --> 00:13:21.300
Yeah, that was my first thought exactly.

00:13:21.300 --> 00:13:24.580
It's like, oh, there's going to be a bunch of stuff that just won't install anymore.

00:13:24.580 --> 00:13:25.340
Yeah.

00:13:25.340 --> 00:13:29.960
Maybe a library itself can't install because two of its base libraries dependencies like

00:13:29.960 --> 00:13:31.160
themselves are inconsistent.

00:13:31.160 --> 00:13:32.620
Well, how are they working now then?

00:13:32.620 --> 00:13:34.300
You just get a warning and it just still works.

00:13:34.300 --> 00:13:37.700
It's not that they're necessarily truly inconsistent.

00:13:38.020 --> 00:13:41.480
One says, I require library less than equal to this version.

00:13:41.480 --> 00:13:44.340
Another one says, I require library greater than equal to that version.

00:13:44.340 --> 00:13:49.600
That doesn't necessarily mean the one that requires the lower one wouldn't work with the

00:13:49.600 --> 00:13:50.040
newer one.

00:13:50.040 --> 00:13:52.060
It's just that's what the requirements state.

00:13:52.060 --> 00:13:52.840
You know what I mean?

00:13:52.840 --> 00:13:59.300
Like, for example, Boto3, which is the Python 3 library if we're talking to AWS and its underlying

00:13:59.300 --> 00:14:06.340
library, BotoCore, at one point we're having different dependency, like inconsistent dependency

00:14:06.340 --> 00:14:10.580
statements or something weird like that that I was running into.

00:14:10.580 --> 00:14:11.980
But it didn't matter.

00:14:11.980 --> 00:14:12.520
It still ran.

00:14:12.520 --> 00:14:14.300
I'm just like, oh, I better run the unit test.

00:14:14.300 --> 00:14:15.620
It says these aren't going to work together.

00:14:15.620 --> 00:14:19.500
Let's see if they, you know, like maybe there's some corner of that thing that doesn't work,

00:14:19.500 --> 00:14:20.440
but I don't use that corner.

00:14:20.440 --> 00:14:21.500
So like, I don't care.

00:14:21.500 --> 00:14:22.140
Yeah.

00:14:22.140 --> 00:14:27.320
Or you have like in the machine learning side, you have like this library depends on some

00:14:27.320 --> 00:14:29.980
old version of TensorFlow, but it doesn't.

00:14:29.980 --> 00:14:31.340
You're not using TensorFlow.

00:14:31.580 --> 00:14:36.700
You're using some utility library in it, but it also has support for TensorFlow, but you're

00:14:36.700 --> 00:14:37.320
not using it.

00:14:37.320 --> 00:14:42.060
So if you had a different version of TensorFlow on it, it wouldn't really affect you because

00:14:42.060 --> 00:14:43.720
you weren't using that portion of it.

00:14:43.720 --> 00:14:44.640
Right.

00:14:44.640 --> 00:14:47.140
But it sounds like pip will say, no, I can't install these things.

00:14:47.140 --> 00:14:50.980
They make statements about two things that they can't coexist.

00:14:50.980 --> 00:14:52.980
But you're like, I don't really care that they're working.

00:14:52.980 --> 00:14:53.620
You know what I mean?

00:14:53.620 --> 00:14:55.340
So I think this is good.

00:14:55.340 --> 00:14:56.720
I think it makes things more predictable.

00:14:56.720 --> 00:14:58.220
But you're right, Matt.

00:14:58.220 --> 00:15:01.040
It's definitely going to cause some challenges.

00:15:01.040 --> 00:15:06.340
And maybe it'll get people to update things like the base library statements that they

00:15:06.340 --> 00:15:08.120
depend upon more carefully.

00:15:08.120 --> 00:15:09.100
Yeah.

00:15:09.100 --> 00:15:14.500
One of the things I'd like to see for talking about pip is that I'd really like to see Python

00:15:14.500 --> 00:15:22.500
come out with dot releases that if there's a new version of pip that all the latest versions

00:15:22.500 --> 00:15:24.940
of Python have the latest version of Pip.

00:15:24.940 --> 00:15:30.140
I'm just really tired of installing Python places and immediately having pip out of date.

00:15:30.140 --> 00:15:30.380
Yeah.

00:15:30.380 --> 00:15:35.140
I actually have an alias that when I create a virtual environment, then immediately does

00:15:35.140 --> 00:15:39.040
a pip dash install --upgrade pip and set up tools.

00:15:39.040 --> 00:15:40.940
Because why doesn't it just do that for me?

00:15:40.940 --> 00:15:41.160
Yeah.

00:15:41.160 --> 00:15:41.680
Anyway.

00:15:41.680 --> 00:15:46.280
Can I just update the top level one so that all my new virtual environments get the newest

00:15:46.280 --> 00:15:46.580
one?

00:15:46.580 --> 00:15:46.960
Yeah.

00:15:46.960 --> 00:15:47.440
Anyway.

00:15:47.440 --> 00:15:48.080
This is coming.

00:15:48.080 --> 00:15:49.000
They blogged about it.

00:15:49.000 --> 00:15:50.860
I linked to the blog post from the PSF.

00:15:50.860 --> 00:15:55.860
They said there's a couple of things you can do to help first and most fundamentally help

00:15:55.860 --> 00:15:58.020
them understand how you're using Pip.

00:15:58.160 --> 00:16:00.360
They have some user experience research going on.

00:16:00.360 --> 00:16:01.920
There's a link to go do part of that.

00:16:01.920 --> 00:16:05.420
You can check right now if this is going to be a problem for you.

00:16:05.420 --> 00:16:09.040
Go to your project, your virtual environment, activate it and type pip check.

00:16:09.040 --> 00:16:11.940
And it will tell you if you are in this inconsistent state.

00:16:11.940 --> 00:16:14.840
I had one website that was, a couple that weren't.

00:16:14.840 --> 00:16:17.960
I hacked around until I fixed them up and everything was good.

00:16:17.960 --> 00:16:19.900
Make sure you test the new version of Pip.

00:16:19.900 --> 00:16:21.260
It'll probably be out in May.

00:16:21.260 --> 00:16:22.220
Help spread the word.

00:16:22.220 --> 00:16:23.680
All three of us are doing that.

00:16:23.680 --> 00:16:23.980
Ta-da.

00:16:24.460 --> 00:16:24.760
Awesome.

00:16:24.760 --> 00:16:29.960
And if you develop a tool like Poetry or something that lives on top of this, make

00:16:29.960 --> 00:16:33.620
sure that you test integration with the thing coming out in beta in May.

00:16:33.620 --> 00:16:34.680
All right.

00:16:34.680 --> 00:16:38.700
Really quickly before we move on, let me tell you all about Datadog.

00:16:38.700 --> 00:16:41.880
This episode is brought to them, brought to you by them.

00:16:41.880 --> 00:16:43.480
So let me ask you a question.

00:16:43.480 --> 00:16:46.120
Do you have an app in production that's slower than you'd like?

00:16:46.360 --> 00:16:47.920
Is its performance all over the place?

00:16:47.920 --> 00:16:49.660
Maybe fast, sometimes slow, others?

00:16:49.660 --> 00:16:51.340
Here's the important question.

00:16:51.340 --> 00:16:54.220
Do you know why it's slow or inconsistent?

00:16:54.220 --> 00:16:55.860
With Datadog, you will.

00:16:55.860 --> 00:16:59.220
You can troubleshoot your app's performance with Datadog's end-to-end tracing.

00:16:59.220 --> 00:17:04.240
Use the detailed frame graphs to identify bottlenecks and latency in that finicky app of yours.

00:17:04.240 --> 00:17:07.480
Be the hero that got the app back on track at your company.

00:17:07.480 --> 00:17:11.140
Get started with a free trial today at pythonbytes.fm/Datadog.

00:17:11.140 --> 00:17:12.520
Use a cool product.

00:17:12.520 --> 00:17:13.680
Help support the show.

00:17:14.180 --> 00:17:19.940
Matt, I think this next topic you got here, this pretty much is on everyone's mind right now.

00:17:19.940 --> 00:17:23.120
And maybe you're trying to not think about it, but there's some useful stuff going on here.

00:17:23.120 --> 00:17:24.080
Yeah.

00:17:24.080 --> 00:17:31.460
Just with the whole coronavirus, COVID-19, I've been thinking, you know, what can I do as an

00:17:31.460 --> 00:17:32.520
individual to help?

00:17:32.520 --> 00:17:37.080
And I think a lot of people are trying to flatten the curve or limit the growth.

00:17:37.080 --> 00:17:41.760
And I think a lot of people, at least in our community, understand the importance of that,

00:17:41.860 --> 00:17:45.000
but maybe not the general populace as well.

00:17:45.000 --> 00:17:50.480
So one of the things that I thought that I could do is just, you know, spread among my local community

00:17:50.480 --> 00:17:52.480
through my local social media.

00:17:52.480 --> 00:17:54.900
Like, what is the growth locally here where I'm based?

00:17:54.900 --> 00:17:57.140
I'm based out of Salt Lake in Utah.

00:17:57.720 --> 00:18:01.400
And so I had a problem actually getting the data.

00:18:01.400 --> 00:18:06.000
I mean, there aren't any repositories that have local Utah data.

00:18:06.000 --> 00:18:13.380
The local Department of Health is reporting on it, but their data, there's not a source of data that you can cleanly pull.

00:18:13.380 --> 00:18:17.020
So I've been pulling, making my own data source.

00:18:17.020 --> 00:18:27.060
And then I've been just posting those on Twitter and LinkedIn just with my local data to sort of track what that growth looks like and sort of put that in people's minds to sort of,

00:18:27.060 --> 00:18:31.020
hey, think about what's going on locally and see what changes you can make.

00:18:31.420 --> 00:18:37.960
And I did some basic modeling to sort of predict what's going on because I've been reading other people's models about, you know,

00:18:37.960 --> 00:18:42.180
this is an exponential growth weight, blah, blah, blah, what that looks like.

00:18:42.240 --> 00:18:45.040
And so I did some basic models using machine learning.

00:18:45.040 --> 00:18:53.780
But it's also in the Twittersphere and elsewhere, people are saying all these data scientists are coming and just throwing machine learning at this,

00:18:53.780 --> 00:18:54.960
and that's not the right thing to do.

00:18:54.960 --> 00:19:00.280
The right thing to do is read the literature and see, you know, what epidemiologists and others have done.

00:19:00.280 --> 00:19:05.380
And so I just want to point to some things that might be interesting.

00:19:05.380 --> 00:19:10.520
I've got a link to a Kaggle project that shows making some basic machine learning models,

00:19:10.620 --> 00:19:17.140
but it also points to a library that's found in SciPy that probably a lot of people don't know about.

00:19:17.140 --> 00:19:18.780
I know about it because I teach about it.

00:19:18.780 --> 00:19:26.020
And that's in SciPy, there's an ODEINT function, which is a solver for what's called ordinary differential equations.

00:19:26.020 --> 00:19:30.720
And so this is probably a math class that you may have taken in college.

00:19:30.720 --> 00:19:36.940
I took one in college, and it was purely theoretical, and I've basically forgot everything since then.

00:19:37.140 --> 00:19:40.220
But there's what's called an SIR model.

00:19:40.220 --> 00:19:50.100
And that stands for you have people who are susceptible to being sick, you have people who are infected, and you have people who are recovered.

00:19:50.100 --> 00:19:56.160
And so typically, these flatten the curves are looking at the infected part, the infected growth of that.

00:19:56.160 --> 00:20:00.540
But there's a relationship between all these three different groups, and they're more complex models.

00:20:00.540 --> 00:20:11.860
But if you use ordinary differential equations, that is the tool that epidemiologists and statisticians use to plot these and determine what's going on here,

00:20:11.860 --> 00:20:18.380
rather than just throwing it at linear regression or trying to do a machine learning model that way.

00:20:18.380 --> 00:20:24.440
So I just want to point people at this Kaggle project has got an example of doing this SIR model.

00:20:24.440 --> 00:20:27.620
It's also got some basic machine learning models as well.

00:20:27.620 --> 00:20:35.120
But be aware that, you know, a lot of these things that we learn about, that in theory, you think, oh, that doesn't make sense.

00:20:35.120 --> 00:20:44.260
This is actually a case where ordinary differential equations are the right or one of the right tools to look at this data and understand what's going on there.

00:20:44.780 --> 00:20:45.680
Yeah, this is a cool project.

00:20:45.680 --> 00:20:47.260
Yeah, definitely a cool project.

00:20:47.260 --> 00:20:51.980
I'm sure there's a ton of data science going on around all of this.

00:20:51.980 --> 00:20:53.920
There's a lot of data.

00:20:53.920 --> 00:20:57.180
It's coming from different places, like live dashboards and stuff.

00:20:57.180 --> 00:20:59.160
And I think this is really cool.

00:20:59.160 --> 00:21:00.560
I didn't know about the SIR model.

00:21:00.560 --> 00:21:01.080
That's cool.

00:21:01.080 --> 00:21:08.580
There are a bunch of other Python libraries as well that epidemiologists have created and whatnot that implement these SIR models.

00:21:08.580 --> 00:21:10.660
And there's another one, S-I-E-R.

00:21:11.300 --> 00:21:14.800
And so check those out if you're interested in sort of digging with the data.

00:21:14.800 --> 00:21:18.540
But a plea to people to think about what you can do for your local community.

00:21:18.540 --> 00:21:24.180
You know, if you've got skills to help out, what can you do locally to help out and help others?

00:21:24.180 --> 00:21:25.600
Yeah, absolutely.

00:21:26.180 --> 00:21:34.920
Also, random side point here, looking through this code on Kaggle, I'd never realized that you could unpack a tuple in a nested way.

00:21:34.920 --> 00:21:39.480
Like thing, comma, tuple unpacking thing, right?

00:21:39.480 --> 00:21:41.900
So where you can layer these in deeper and deeper.

00:21:41.900 --> 00:21:43.080
That's pretty awesome, actually.

00:21:43.080 --> 00:21:43.740
Yeah.

00:21:43.740 --> 00:21:45.560
Your data structure is nested, right?

00:21:45.960 --> 00:21:50.060
Not necessarily going to make your code easy to read, but you can have fun there.

00:21:50.060 --> 00:21:52.720
It can definitely make it shorter.

00:21:52.720 --> 00:21:54.000
All right, cool.

00:21:54.000 --> 00:21:54.920
That's a nice one.

00:21:54.920 --> 00:21:58.020
Brian, you're getting all philosophical on this with this next one.

00:21:58.020 --> 00:21:58.360
What's up?

00:21:58.360 --> 00:22:03.500
Okay, so this is totally, we're going from serious to definitely not serious.

00:22:04.160 --> 00:22:05.980
So I noticed this also.

00:22:05.980 --> 00:22:14.020
So there's a Reddit thread that's now, or I don't know if it was Reddit or Stack Overflow, but it got taken down.

00:22:14.020 --> 00:22:19.920
But essentially the question was, why does all return true if the iterable is empty?

00:22:19.920 --> 00:22:25.160
So there's an all keyword in Python that I guess actually a lot of people don't know about.

00:22:25.160 --> 00:22:32.320
That takes an iterable and it returns true if all of the elements of the iterable are true.

00:22:32.880 --> 00:22:35.080
Or evaluate to true in a Boolean context.

00:22:35.080 --> 00:22:37.640
That's really helpful for a lot of things.

00:22:37.640 --> 00:22:43.480
The interesting aspect is, what should it do if the iterable is empty?

00:22:43.480 --> 00:22:50.800
And because, you know, actually the person asking the question said, shouldn't it be false?

00:22:50.800 --> 00:22:55.620
Just like, you know, you can say if list, and if it's an empty list, it's false.

00:22:55.620 --> 00:22:58.420
Why would all be true if it's empty?

00:22:58.420 --> 00:23:00.960
And I enjoyed the conversation.

00:23:00.960 --> 00:23:05.460
And somebody wrote an article called, about this, why is, why does all return true?

00:23:05.460 --> 00:23:11.440
The end lesson is, it doesn't matter why, because the core team decided it, and you just need to know it.

00:23:11.440 --> 00:23:12.380
And work around it.

00:23:12.380 --> 00:23:15.500
It's been thusly decreed to be true, so therefore it is true.

00:23:15.660 --> 00:23:21.320
Yeah, and then one of the things I wanted to point out from this discussion is the statement, all unicorns are blue.

00:23:21.320 --> 00:23:22.720
I just love that.

00:23:22.720 --> 00:23:27.180
You can't tell me, it is definitely true, because there are no unicorns.

00:23:27.180 --> 00:23:30.440
So therefore it's true for me to say all unicorns are blue.

00:23:30.440 --> 00:23:30.740
Yeah.

00:23:30.740 --> 00:23:33.040
And so I like that.

00:23:33.040 --> 00:23:38.440
And I guess I'm glad that my daughter doesn't listen to this to hear me say that there are no unicorns.

00:23:38.440 --> 00:23:39.720
Sorry, honey.

00:23:39.720 --> 00:23:40.720
Don't break her heart.

00:23:40.720 --> 00:23:43.740
Next, you can talk about no Santa or what's going on here.

00:23:43.740 --> 00:23:46.000
Like the tooth fairy is not real?

00:23:46.000 --> 00:23:46.500
Come on.

00:23:46.700 --> 00:23:51.600
But the person writing this article, Carl Johnson, is actually also a philosopher and a programmer.

00:23:51.600 --> 00:24:00.380
So he talks about this 2,500-year-old debate in philosophy about whether or not all unicorns are blue, should be true or false.

00:24:00.380 --> 00:24:08.820
And also we get talk about predicate logic and Socrates and Aristotle and syllogisms and things like that.

00:24:08.820 --> 00:24:14.980
Actually, we never, at the end, I still don't know why the core team chose that that is true.

00:24:15.100 --> 00:24:16.840
But it's a fun thing to look into.

00:24:16.840 --> 00:24:17.960
That's fun.

00:24:17.960 --> 00:24:22.440
So looking at it from the outside, I envision it working like this.

00:24:22.440 --> 00:24:30.060
The way all works to be efficient is it says for thing in collection, if not thing, return false.

00:24:30.060 --> 00:24:32.220
Go all the way in, return true.

00:24:32.220 --> 00:24:34.840
And it just never goes into that loop, so return true.

00:24:34.840 --> 00:24:35.760
Probably, yeah.

00:24:35.760 --> 00:24:40.020
But I probably got to go and open up the CPython source code to find out.

00:24:40.020 --> 00:24:41.520
Matt, what do you think?

00:24:41.520 --> 00:24:42.460
I don't know.

00:24:42.540 --> 00:24:49.460
I'm looking at the Unicode symbol, the Unicode emoji in my Python REPL right now.

00:24:49.460 --> 00:24:53.760
And that's hex code point 1F984.

00:24:53.760 --> 00:24:55.000
And it doesn't look blue.

00:24:55.000 --> 00:24:55.740
It looks pink.

00:24:55.740 --> 00:24:57.540
So something's got a pile of...

00:24:57.540 --> 00:25:02.680
We definitely got to put...

00:25:02.680 --> 00:25:04.980
Somebody's going to have to put a comment on that blog post.

00:25:04.980 --> 00:25:05.640
Yeah.

00:25:05.640 --> 00:25:06.840
Yeah, that's not true.

00:25:06.840 --> 00:25:07.860
All unicorns are pink.

00:25:07.860 --> 00:25:12.000
It's interesting that they did make it true to your point, like in a Boolean context, right?

00:25:12.000 --> 00:25:14.400
Anything empty in Python is false.

00:25:14.400 --> 00:25:15.160
So...

00:25:15.160 --> 00:25:15.520
Yeah, yeah.

00:25:15.520 --> 00:25:20.260
I mean, another option would have been to raise an exception so you can't ask for the truthiness of nothing.

00:25:20.260 --> 00:25:29.140
The main reason why I wanted to bring it up and the main reason I enjoy reading this article is now I will never forget that all of nothing is true.

00:25:30.860 --> 00:25:35.180
I'm also thinking, have I ever used all in an if statement?

00:25:35.180 --> 00:25:38.140
I don't know that I have used all in an if statement.

00:25:38.140 --> 00:25:39.560
Where do you use it?

00:25:39.560 --> 00:25:41.500
Hey, yeah, I guess I have.

00:25:41.500 --> 00:25:42.780
Yeah, I've used it.

00:25:42.780 --> 00:25:44.620
Usually I'll put like a set...

00:25:44.620 --> 00:25:45.300
Not a set...

00:25:45.300 --> 00:25:47.780
Some kind of generator expression in there.

00:25:47.780 --> 00:25:51.180
Because I don't usually want to test all the things are actually true.

00:25:51.180 --> 00:25:55.640
I want to test like the dates are greater than today for all of them or something, right?

00:25:55.640 --> 00:25:58.720
So put a little comprehension in there and then ask all of that.

00:25:58.720 --> 00:26:02.900
Yeah, I guess it returns a Boolean, so you would put it in an if statement.

00:26:02.900 --> 00:26:04.880
I guess so.

00:26:04.880 --> 00:26:08.200
I don't use it a ton either, but every now and then I'm happy with it.

00:26:08.200 --> 00:26:13.000
If I put it in an if statement, am I going to loop over the contents of all, right?

00:26:13.000 --> 00:26:16.020
I don't know that I have it in an if statement.

00:26:16.020 --> 00:26:17.240
I loop over...

00:26:17.240 --> 00:26:17.460
No, no.

00:26:17.460 --> 00:26:19.240
It would be to avoid a loop, right?

00:26:19.240 --> 00:26:21.060
It would be like one line of loop, basically.

00:26:21.060 --> 00:26:21.820
Yeah.

00:26:21.820 --> 00:26:22.140
Cool.

00:26:22.140 --> 00:26:23.660
Yeah, I won't forget either now.

00:26:23.660 --> 00:26:26.720
I didn't realize it was so philosophical, but apparently here it is.

00:26:26.720 --> 00:26:28.980
All right, last one.

00:26:28.980 --> 00:26:29.820
This was really quick.

00:26:29.820 --> 00:26:33.420
This is a project written by Jean-Sebastien Douai.

00:26:33.420 --> 00:26:34.860
Did I close it right?

00:26:34.860 --> 00:26:36.840
Called pytest Monitor.

00:26:36.840 --> 00:26:38.880
And the idea of pytest Monitor...

00:26:38.880 --> 00:26:40.020
Brian, are you familiar with this one already?

00:26:40.020 --> 00:26:41.520
I looked it up quickly, yeah.

00:26:41.520 --> 00:26:42.960
But I haven't used it before.

00:26:42.960 --> 00:26:43.800
Yeah, but okay, cool.

00:26:43.800 --> 00:26:49.320
Basically, you pip install this and then anytime you run a pytest test,

00:26:49.320 --> 00:26:52.720
it's going to automatically collect some data for you.

00:26:52.720 --> 00:26:57.800
It'll analyze memory consumption, timing, CPU usage, stuff like that.

00:26:57.800 --> 00:27:00.760
And it'll put it into a little local SQLite database file,

00:27:00.760 --> 00:27:03.300
and you can look at it over time and whatnot.

00:27:03.300 --> 00:27:05.020
So it's pretty cool, right?

00:27:05.020 --> 00:27:10.300
If you want to say, well, how long does this code take to run on the production machine

00:27:10.300 --> 00:27:12.920
versus on our laptops, right?

00:27:12.920 --> 00:27:15.720
You actually get tracking and whatnot from that.

00:27:15.840 --> 00:27:18.820
So not a huge addition, but it's kind of cool.

00:27:18.820 --> 00:27:20.500
It's built on a couple of libraries.

00:27:20.500 --> 00:27:28.320
PSutil and memory profiler, which let it basically go and ask all these questions on a per test basis.

00:27:28.320 --> 00:27:29.060
It's cool.

00:27:29.240 --> 00:27:31.080
And then obviously it just runs in pytest.

00:27:31.080 --> 00:27:31.520
That's cool.

00:27:31.520 --> 00:27:36.440
I could see where you might want to have a report where you just want to run,

00:27:36.440 --> 00:27:38.960
limit what that's running on.

00:27:38.960 --> 00:27:41.240
I don't know that I would want that necessarily on everything,

00:27:41.240 --> 00:27:47.340
but you might have some hotspots or whatever where you want to monitor that and report on that.

00:27:47.340 --> 00:27:49.440
Having it on everything seems like...

00:27:50.440 --> 00:27:55.380
I don't know what the performance implications are of all that monitoring.

00:27:55.380 --> 00:27:58.140
I think it'd be cool to see...

00:27:58.140 --> 00:28:01.940
This is one of the parts where I'd like to actually see the reporting of this project

00:28:01.940 --> 00:28:05.400
have some reporting that's nicer around it,

00:28:05.400 --> 00:28:07.340
because that's some really cool information,

00:28:07.340 --> 00:28:09.560
but I think some reporting would help it.

00:28:09.560 --> 00:28:10.380
Yeah, it doesn't look...

00:28:10.380 --> 00:28:11.480
It's not beautiful, is it?

00:28:11.480 --> 00:28:13.040
It is in the SQLite database.

00:28:13.040 --> 00:28:14.380
You could grab it and do what you want,

00:28:14.380 --> 00:28:15.780
but then you've got to write that.

00:28:15.780 --> 00:28:17.000
It's like coverage.

00:28:17.000 --> 00:28:20.700
One of the wonderful things about coverage is the reporting part of it.

00:28:20.700 --> 00:28:21.600
Yeah, absolutely.

00:28:21.600 --> 00:28:22.420
All right.

00:28:22.420 --> 00:28:24.480
Well, if that's something you guys care about,

00:28:24.480 --> 00:28:27.260
go install that and check it out.

00:28:27.260 --> 00:28:27.680
All right.

00:28:27.680 --> 00:28:29.260
Well, that's it for all of our major items.

00:28:29.260 --> 00:28:33.520
Brian, Matt, you guys got anything you want to throw out there extra before we get to our joke?

00:28:33.520 --> 00:28:34.500
Stay safe.

00:28:34.500 --> 00:28:35.740
Yeah, absolutely.

00:28:35.740 --> 00:28:36.840
I've got nothing extra.

00:28:36.840 --> 00:28:37.480
How about you, Michael?

00:28:37.480 --> 00:28:40.780
Well, I took two of my projects that I've been kind of fiddling with for

00:28:40.780 --> 00:28:42.920
either a short time or a long time,

00:28:42.920 --> 00:28:43.780
depending on which one,

00:28:43.880 --> 00:28:47.940
and put them both up on PyPI as things you can now pip install.

00:28:47.940 --> 00:28:49.020
So that's kind of cool.

00:28:49.020 --> 00:28:50.900
So the switch laying,

00:28:50.900 --> 00:28:53.020
my little extension to add switch to the Python language,

00:28:53.020 --> 00:28:54.580
you can pip install that now.

00:28:54.580 --> 00:28:55.520
I still love that thing.

00:28:55.520 --> 00:28:56.240
I use it all the time.

00:28:56.240 --> 00:28:58.820
And then my markdown subtemplates.

00:28:58.820 --> 00:28:59.500
Oh, what's that, Matt?

00:28:59.500 --> 00:29:00.960
You use that in production.

00:29:00.960 --> 00:29:02.220
Oh, yeah.

00:29:02.220 --> 00:29:02.840
All the time.

00:29:02.840 --> 00:29:03.940
Awesome.

00:29:04.740 --> 00:29:09.740
Yeah, there's like a couple of places where it would be like this huge if statement or some other weird lookup.

00:29:09.740 --> 00:29:11.340
And it does cool stuff to say like,

00:29:11.340 --> 00:29:12.900
oh, you already tested for this case.

00:29:12.900 --> 00:29:13.580
Or you're like,

00:29:13.580 --> 00:29:15.840
have the same case in two places.

00:29:15.840 --> 00:29:16.680
And you would miss one,

00:29:16.680 --> 00:29:17.380
the second one,

00:29:17.380 --> 00:29:19.100
because it'd be caught by the first and so on.

00:29:19.100 --> 00:29:19.640
Cool.

00:29:19.640 --> 00:29:20.320
Yep.

00:29:20.320 --> 00:29:21.240
And then the second one,

00:29:21.240 --> 00:29:22.520
the markdown subtemplate thing,

00:29:22.520 --> 00:29:23.680
which we talked about before,

00:29:23.680 --> 00:29:26.140
but it was not then pip installable.

00:29:26.140 --> 00:29:27.180
So now it is.

00:29:27.180 --> 00:29:28.120
People can check those out.

00:29:28.120 --> 00:29:29.320
Do you have tests on these, man?

00:29:29.320 --> 00:29:30.700
Of course we got tests on those.

00:29:30.700 --> 00:29:31.060
Okay.

00:29:31.220 --> 00:29:33.360
I don't have pytest monitor on it,

00:29:33.360 --> 00:29:34.080
but we got tests going.

00:29:34.080 --> 00:29:36.140
I have tests in there.

00:29:36.140 --> 00:29:37.200
So they do exist.

00:29:37.200 --> 00:29:38.560
The code does exist as tests.

00:29:38.560 --> 00:29:38.820
It does.

00:29:38.820 --> 00:29:41.360
Yes, we can speak of it.

00:29:41.360 --> 00:29:41.720
Yes.

00:29:41.720 --> 00:29:43.280
Are you all ready for a joke?

00:29:43.280 --> 00:29:43.740
Yes.

00:29:43.740 --> 00:29:44.520
This one is,

00:29:44.520 --> 00:29:45.880
it's not really that funny.

00:29:45.880 --> 00:29:47.600
It's more like...

00:29:47.600 --> 00:29:49.040
As opposed to the rest of our jokes.

00:29:49.040 --> 00:29:50.340
Dude, I think I've done that.

00:29:50.340 --> 00:29:54.580
Well, some of them are like meant to be straight out funny.

00:29:54.580 --> 00:29:56.160
This one's like funny,

00:29:56.160 --> 00:29:56.820
ironic,

00:29:56.820 --> 00:29:57.480
because yeah,

00:29:57.480 --> 00:29:59.640
I did that too at one point or something like that,

00:29:59.640 --> 00:29:59.820
right?

00:30:00.140 --> 00:30:02.800
So this guy on Twitter sent a message,

00:30:02.800 --> 00:30:05.040
sarcastic pharmacist,

00:30:05.040 --> 00:30:06.260
sent it over and said,

00:30:06.260 --> 00:30:09.160
I was listening to a discussion on TalkByThon

00:30:09.160 --> 00:30:11.600
about rebooting a server instead of chasing bugs

00:30:11.600 --> 00:30:16.120
and thought you should check out xkcd.com 1495.

00:30:16.120 --> 00:30:19.920
And there's just a picture

00:30:19.920 --> 00:30:21.880
and it has like a trade office.

00:30:21.880 --> 00:30:22.060
It says,

00:30:22.060 --> 00:30:22.380
okay,

00:30:22.380 --> 00:30:24.320
why is everything broken in my life?

00:30:24.320 --> 00:30:25.180
Here's the deal.

00:30:25.180 --> 00:30:32.400
like I could spend one to 10 hours figuring out why my server keeps running out of swap space and crashing.

00:30:32.400 --> 00:30:37.740
Or I could spend five minutes plugging it into a light timer that reboots it every 24 hours.

00:30:37.740 --> 00:30:38.880
That takes five minutes.

00:30:38.880 --> 00:30:39.460
Let's do that.

00:30:39.460 --> 00:30:40.240
Yeah.

00:30:40.240 --> 00:30:41.820
So true.

00:30:41.820 --> 00:30:43.000
Yeah.

00:30:43.000 --> 00:30:45.960
That's actually an interesting thing.

00:30:45.960 --> 00:30:50.440
We just ordered a bunch of web programmable power strips.

00:30:51.440 --> 00:30:51.920
Yeah.

00:30:51.920 --> 00:30:57.380
Because one of the things you do when working with electronics is sometimes power cycle the things.

00:30:57.380 --> 00:31:00.560
Ain't no way to go and do that when I'm working from home.

00:31:00.560 --> 00:31:00.840
So.

00:31:00.840 --> 00:31:01.600
How interesting.

00:31:01.760 --> 00:31:04.500
So you built that into like the CI, CD,

00:31:04.500 --> 00:31:05.320
hey,

00:31:05.320 --> 00:31:06.620
with the tests,

00:31:06.620 --> 00:31:08.300
like let's do that.

00:31:08.300 --> 00:31:08.600
Sleep.

00:31:08.600 --> 00:31:09.320
Most of the time,

00:31:09.320 --> 00:31:10.460
these aren't problematic,

00:31:10.460 --> 00:31:14.240
but there is the occasional in development instrument where,

00:31:14.240 --> 00:31:18.260
or in development operating system portions or something like that,

00:31:18.260 --> 00:31:21.820
where it gets into flaky situations and rebooting is a good,

00:31:21.820 --> 00:31:23.600
is a good thing to do from the start.

00:31:23.600 --> 00:31:25.400
Because as a software developer,

00:31:25.400 --> 00:31:27.440
I can get things into really wacky states.

00:31:27.440 --> 00:31:28.920
It doesn't happen a lot,

00:31:29.100 --> 00:31:32.640
but it happens enough to where it's good to know that,

00:31:32.640 --> 00:31:32.960
yeah,

00:31:32.960 --> 00:31:34.480
that you can buy these web power switches.

00:31:34.480 --> 00:31:36.560
We're getting industrial ones,

00:31:36.560 --> 00:31:40.000
which are kind of expensive because you can stick them in instrument racks,

00:31:40.000 --> 00:31:42.180
but they're just a normal power strip,

00:31:42.180 --> 00:31:42.740
but you've,

00:31:42.740 --> 00:31:47.900
they've got a web address and a rest or on a rest like API that you can put them in strips.

00:31:47.900 --> 00:31:48.260
And if you,

00:31:48.260 --> 00:31:48.440
yeah,

00:31:48.440 --> 00:31:50.360
if you want to use them in a CI,

00:31:50.360 --> 00:31:51.080
CD pipeline,

00:31:51.080 --> 00:31:52.720
you can call them that way too,

00:31:52.720 --> 00:31:53.180
if you want.

00:31:53.180 --> 00:31:56.100
But normally we just have them as a backup so that we,

00:31:56.200 --> 00:31:59.380
we can log in and reboot them if we need to.

00:31:59.380 --> 00:32:00.980
You don't have them connected to Alexa.

00:32:00.980 --> 00:32:02.980
Alexa,

00:32:02.980 --> 00:32:04.220
reboot my computer.

00:32:04.220 --> 00:32:05.040
No.

00:32:05.040 --> 00:32:05.580
Yeah.

00:32:05.580 --> 00:32:07.700
My test won't pass.

00:32:07.700 --> 00:32:08.000
Help.

00:32:08.000 --> 00:32:09.740
Shall I reboot again?

00:32:09.740 --> 00:32:10.160
Yes,

00:32:10.160 --> 00:32:10.480
please.

00:32:10.480 --> 00:32:13.180
Awesome.

00:32:13.180 --> 00:32:13.500
All right.

00:32:13.500 --> 00:32:13.800
Well,

00:32:13.800 --> 00:32:15.040
Brian,

00:32:15.040 --> 00:32:15.740
thank you as always.

00:32:15.740 --> 00:32:16.140
And Matt,

00:32:16.140 --> 00:32:16.960
thanks for being here today.

00:32:16.960 --> 00:32:17.740
It's fun to chat with you.

00:32:17.740 --> 00:32:17.960
Yeah.

00:32:17.960 --> 00:32:18.340
Thank you.

00:32:18.340 --> 00:32:18.580
Yeah.

00:32:18.580 --> 00:32:20.880
Thank you for listening to Python Bytes.

00:32:20.880 --> 00:32:23.420
Follow the show on Twitter via at Python Bytes.

00:32:23.420 --> 00:32:26.280
That's Python Bytes as in B-Y-T-E-S.

00:32:26.280 --> 00:32:29.500
And get the full show notes at pythonbytes.fm.

00:32:29.500 --> 00:32:31.180
If you have a news item you want featured,

00:32:31.180 --> 00:32:33.720
just visit pythonbytes.fm and send it our way.

00:32:33.720 --> 00:32:36.420
We're always on the lookout for sharing something cool.

00:32:36.420 --> 00:32:38.320
On behalf of myself and Brian Okken,

00:32:38.320 --> 00:32:39.520
this is Michael Kennedy.

00:32:39.520 --> 00:32:42.960
Thank you for listening and sharing this podcast with your friends and colleagues.