WEBVTT

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

00:00:04.520 --> 00:00:13.220
your earbuds. This is episode 192, recorded July 22nd, 2020. Had to look that one up.

00:00:13.220 --> 00:00:15.460
I am Brian Okken. And I'm Michael Kennedy.

00:00:15.460 --> 00:00:18.720
And I can't believe we're heading close to 200. This is crazy.

00:00:18.720 --> 00:00:21.880
Oh yeah. Been at this for a while. That's going to be like four years almost.

00:00:21.880 --> 00:00:26.420
Yeah. Again, this episode is sponsored by us and we'll tell you a little bit more about

00:00:26.420 --> 00:00:32.160
other things that we're doing a little later in the show. But first, some of the ways that people

00:00:32.160 --> 00:00:38.400
tell each other what they're up to is their personal GitHub readme on their GitHub profile,

00:00:38.400 --> 00:00:39.240
right? Yeah, that's right.

00:00:39.240 --> 00:00:45.740
So I was impressed by something that I saw recently. Simon Willison, he's the co-creator of Django.

00:00:45.740 --> 00:00:53.400
He posted something called a blog post saying how to do a building a self-updating profile readme

00:00:53.400 --> 00:00:57.380
for GitHub. So at the top of it, I'm going to quote this. It says,

00:00:57.380 --> 00:01:01.420
GitHub quietly released a new feature at some point in the past few days.

00:01:01.420 --> 00:01:03.880
Profile readmes. This is news to me.

00:01:03.880 --> 00:01:07.800
Yeah. So if you create a repository with the same name as your GitHub account.

00:01:07.800 --> 00:01:14.880
So in Simon's case, it was Simon W. So github.com/Simon W slash Simon W.

00:01:15.360 --> 00:01:22.740
So two, you go too deep and then add a readme.md or readme markdown file to it. GitHub will render

00:01:22.740 --> 00:01:29.340
the contents at the top of your personal profile page. So that's neat. In that case, it's just one

00:01:29.340 --> 00:01:34.720
up. So if you go to github.com/Simon W, you see his, but his looks really awesome. It's got a whole

00:01:34.720 --> 00:01:40.480
bunch of cool stuff in it because he took it one step further. It's not a static markdown file.

00:01:41.020 --> 00:01:46.240
He's got another article that talks about it, but this article here walks through exactly what he

00:01:46.240 --> 00:01:53.240
does. And also it's all open source. So you can see his code. He uses a GitHub actions. There's

00:01:53.240 --> 00:02:00.800
both a button that he can push to make it happen, but there's also any post to his own Simon W repo

00:02:00.800 --> 00:02:06.020
will cause this to happen. But the GitHub actions run, he contributes to a lot of open source

00:02:06.020 --> 00:02:13.100
projects. So he takes a certain set of repos that he has and pulls the latest releases and have like

00:02:13.100 --> 00:02:20.240
latest release notes using the GitHub GraphQL API. So there's an example of that. There's an example

00:02:20.240 --> 00:02:27.000
of using feed parser to pull blog entries off of his blog and an example of using a SQL query to grab,

00:02:27.480 --> 00:02:33.540
guess he's got a site called TAIL for today. I learned grabs a few links off of that. So he's

00:02:33.540 --> 00:02:39.980
got a three column setup for a read me that is kept up to date using GitHub actions. How cool is that?

00:02:39.980 --> 00:02:44.620
That is awesome. Yeah. So normally you go to your GitHub repo and you have your picture

00:02:44.620 --> 00:02:49.080
on how many followers you have and whatnot. Some other cool stuff we'll talk about later,

00:02:49.080 --> 00:02:56.080
but then has your pinned repositories and that green ish heat map of how frequently you contribute to

00:02:56.080 --> 00:03:02.140
various projects or just to get up in general. But now you can have right at the top, you know,

00:03:02.140 --> 00:03:05.960
whatever you want to write, which that's pretty awesome. I think I might have to do this.

00:03:05.960 --> 00:03:10.020
Yeah. I mean, you still get all that other stuff, but it's just that other stuff is below

00:03:10.020 --> 00:03:13.060
this read me info. That's pretty neat.

00:03:13.140 --> 00:03:17.660
Yeah. Very cool. And it's super simple, right? Anyone can write a readme.md file.

00:03:17.660 --> 00:03:21.520
Yeah. And one of the reasons why I brought this up is I think there's a lot of people trying to

00:03:21.520 --> 00:03:27.660
utilize, I mean, this day of COVID and quarantine and stuff, I'm glad I'm not looking for a job.

00:03:27.660 --> 00:03:33.280
And I think that if you are looking for a job, making your GitHub profile look professional

00:03:33.280 --> 00:03:39.180
and show the content that you want to show off and having things like, you know, blog posts on

00:03:39.180 --> 00:03:43.160
your GitHub profile, that's pretty cool. It is really cool. And just, you know, you know that people,

00:03:43.160 --> 00:03:49.400
employers say they check people's GitHub profile accounts, right? So how many people have, are going

00:03:49.400 --> 00:03:52.680
to have these unique special ones that show they care, right? Not too many.

00:03:52.680 --> 00:03:54.460
Well, the people that listen to our podcast.

00:03:54.460 --> 00:03:55.880
Exactly. Yeah.

00:03:55.880 --> 00:04:00.780
All the awesome people. Okay. So that's really cool. I definitely didn't know about that. Thanks for

00:04:00.780 --> 00:04:07.200
sharing that. It looks neat. So we got this next one from Connor Furster and he works in engineering,

00:04:07.200 --> 00:04:14.560
but also does data science-y things. And he sent over this project that he works on that is incredibly

00:04:14.560 --> 00:04:21.040
cool. So a lot of times what people want to do is they want to take symbolic math or math that you

00:04:21.040 --> 00:04:26.980
might write out by hand, turn it into Python code through pandas and numpy and whatnot, scikit learn

00:04:26.980 --> 00:04:33.440
or scikit in general, and then run it through Jupyter and get an answer. But he says he works in design

00:04:33.440 --> 00:04:39.980
engineering and you have to do a lot of calculations and those have to be kept as part of legal records

00:04:39.980 --> 00:04:47.160
to show the project design history. And one, yeah, one thing you do is do them by hand. That's kind of

00:04:47.160 --> 00:04:53.800
crazy. A lot of people use Excel. That's a nightmare. Like Excel is like unbounded go-to's you can't see,

00:04:53.900 --> 00:04:58.360
which is always tricky. So you could do it with Jupyter, but then you just got this pile of code

00:04:58.360 --> 00:05:04.740
and here's the answer and so on. Right. So you want to like the theoretical view to verify the formula

00:05:04.740 --> 00:05:12.320
you're using. Right. So he created this thing called hand calcs and C-A-L-C-S like calculus or

00:05:12.320 --> 00:05:18.680
calculations. Anyway, hand calcs. And the idea is you type in Python code into a Jupyter cell,

00:05:18.900 --> 00:05:25.440
and then you can do a percent percent render from the hand calcs project and it will turn it into

00:05:25.440 --> 00:05:30.640
symbolic math. This is beautiful. Yeah. As if you had written it out by hand. Yeah. With like,

00:05:30.640 --> 00:05:36.320
as an example in the little video demo, we've said before we like those and everybody does,

00:05:36.320 --> 00:05:41.480
but it has, has like square root symbols with a bunch of symbols underneath it and

00:05:41.480 --> 00:05:46.560
all sorts of symbols that, yeah. Yeah. Looks like, like what you would have had to show if you were

00:05:46.560 --> 00:05:51.840
in math class, right? Yep. Exactly. And it will show steps like symbolic steps from step A, step B,

00:05:51.840 --> 00:05:56.900
step C. And you can say, show it shorthand or expand it out longhand and show me all the steps you

00:05:56.900 --> 00:06:01.760
use to like solve these problems and all kinds of cool stuff. Wow. Yeah. The reason it looks so good

00:06:01.760 --> 00:06:11.240
is it basically converts symbolic Python math over to latex and latex is like the de facto math

00:06:11.240 --> 00:06:16.140
representation language for academic papers. So, you know, you want to have like integral signs,

00:06:16.140 --> 00:06:20.080
you want to have infinite summations, all that kind of stuff. No problem. Oh, this is really cool.

00:06:20.080 --> 00:06:26.340
Isn't it cool? And then you can also use the symbolic tag to get it to do other, like show more

00:06:26.340 --> 00:06:31.340
symbolic stuff. You can do longhand, shorthand, you can have it do units. They'll put units like

00:06:31.340 --> 00:06:36.560
millimeters cubed or whatever, and it'll carry the units through the calculation in symbolically.

00:06:36.560 --> 00:06:41.840
Yeah. But looking at all these formulas, it's giving me nightmares. Don't look anymore. Okay.

00:06:41.840 --> 00:06:47.620
Well, I guess the thing you would, you would want to think about the trade-off is would you rather

00:06:47.620 --> 00:06:54.400
look at them in their proper mathematical form or in like programming meaning, not, you know,

00:06:54.400 --> 00:07:01.120
where you turn it into like star star pow instead of, you know, proper exponents and stuff.

00:07:01.120 --> 00:07:05.620
No, no, I was just kidding. This is beautiful stuff. But when we got into integrals, that's

00:07:05.620 --> 00:07:10.440
where basically that's where my brain left and I never really caught integrals that way.

00:07:10.440 --> 00:07:17.380
Yeah. Yeah. Cool. All right. So if people have to take programming math, but they want to represent

00:07:17.380 --> 00:07:20.100
it more nicely, check out handcaps. Looks awesome.

00:07:20.100 --> 00:07:22.580
Yeah. Nice. Oh, I'm next.

00:07:23.400 --> 00:07:30.280
Actually, I'm not. I'd like to talk to all of us about our sponsor and our sponsor is a

00:07:30.280 --> 00:07:34.240
Talk Python Training and a testing code today.

00:07:34.240 --> 00:07:36.580
Tell me about Talk Python Training.

00:07:36.580 --> 00:07:39.380
I'll tell you about what I'm working on this week. I started writing a new course.

00:07:39.380 --> 00:07:43.280
We have a couple of new courses that are fun that are coming. And the one that I started working on

00:07:43.280 --> 00:07:46.880
is called Python memory management and tips.

00:07:46.880 --> 00:07:47.480
Tell me more.

00:07:47.620 --> 00:07:50.840
Yeah. So if you ever wondered, like, what happens, like, how does it free up memory?

00:07:50.840 --> 00:07:55.820
What algorithms make, like, work better with Python memory and what algorithms can make it

00:07:55.820 --> 00:08:00.760
more expensive or slow? What are some of the tips and tricks you can do to, like, dramatically

00:08:00.760 --> 00:08:06.280
decrease the memory consumption, like, two or three times with almost exactly the same code

00:08:06.280 --> 00:08:09.060
type of thing? Well, I'm writing a course on that.

00:08:09.140 --> 00:08:09.780
Oh, that's neat.

00:08:09.780 --> 00:08:10.640
Yeah. Thanks.

00:08:10.640 --> 00:08:15.800
Especially for people, like, talking about doing some more, we can get Python on smaller

00:08:15.800 --> 00:08:17.060
operating system.

00:08:17.060 --> 00:08:17.260
Yeah.

00:08:17.260 --> 00:08:20.240
Architectures like CircuitPython and stuff. That's important.

00:08:20.240 --> 00:08:25.060
Yeah. That's a really good point that on the small memory constraint pieces, you might care a lot

00:08:25.060 --> 00:08:25.500
for sure.

00:08:25.500 --> 00:08:25.880
Yeah.

00:08:25.960 --> 00:08:26.700
How about testing code?

00:08:26.700 --> 00:08:33.140
Well, I was interviewing somebody recently, David Lord. His actual interview will come out sometime

00:08:33.140 --> 00:08:39.640
in August. But he said, I was looking at testing code and a lot of the recent episodes really haven't

00:08:39.640 --> 00:08:45.720
been about testing. What's up with that? And I said, yeah, it's and code, test and code. But yeah,

00:08:45.720 --> 00:08:52.960
so there is a lot of testing focus because primarily because I think that software engineering doesn't

00:08:52.960 --> 00:08:58.240
talk about testing enough. But I do cover a lot of stuff. I'm going to highlight a few of the last

00:08:58.240 --> 00:09:06.240
episodes. I talked to Sebastian Ramirez on episode 120 about Fest API and Typer. Talked with Brett Cannon

00:09:06.240 --> 00:09:14.040
on episode 119 about packaging and pyproject.toml and what's going on there. 121 is a diversion. It's a

00:09:14.040 --> 00:09:20.320
completely different sort of talk. I talked to somebody about 3D printing and finite state machines

00:09:20.320 --> 00:09:25.200
and stuff. And it's just sort of a fun people doing Python and cool things.

00:09:25.200 --> 00:09:25.720
Very cool.

00:09:25.720 --> 00:09:32.540
And then again, talking, thinking about people possibly looking for jobs in episode 122, we talk about

00:09:32.540 --> 00:09:37.680
better resumes for software engineers. So there's, yeah, there is a lot of stuff for everybody. Even

00:09:37.680 --> 00:09:43.260
if you cringe when you think about testing, please check out testing code. We are still putting out

00:09:43.260 --> 00:09:46.460
episodes. If you want to hear more, I'd love to hear what people want to hear about.

00:09:46.600 --> 00:09:49.240
Yeah. It makes our job so much easier when we get suggestions.

00:09:49.240 --> 00:09:52.640
Yeah. Suggestions and questions and things that can flow into things.

00:09:52.640 --> 00:09:57.380
Yeah. Like a suggestion to return the print statement so you don't have to put the parentheses.

00:09:57.380 --> 00:10:03.620
Yeah. So this is crazy and I don't really have much of a comment here, but I saw the thing by Guido

00:10:03.620 --> 00:10:11.740
and then I saw this article by Jake Edge on LWN.net. I don't know what LWN stands for, but it doesn't matter.

00:10:11.740 --> 00:10:19.500
Anyway, the non-return of the Python print statement. So this is odd, I thought. We have talked about the new

00:10:19.500 --> 00:10:26.900
peg parser in Python that's going on. But one of the things that happened with that is, I guess, one of the reasons

00:10:26.900 --> 00:10:33.240
why Python 2 to 3, they went from a print statement to a print function was it made the parsing easier.

00:10:33.240 --> 00:10:41.560
But with the peg parser, you can do all sorts of crazy things and you can have functions that syntactically look like statements

00:10:41.560 --> 00:10:51.840
and have it work just work, sort of. So as an example, we could use a print statement instead, instead of having to be, put the

00:10:51.840 --> 00:11:02.100
parentheses in, you could avoid the parentheses. Anyway, he just put it out there as an idea and essentially people said, no, yuck. What do you think about this?

00:11:02.100 --> 00:11:09.240
It's interesting. It would be one fewer things that has to happen to move to the next stage from a 2 to 3 conversion.

00:11:09.240 --> 00:11:18.060
On the other hand, this looks like one of the easiest conversions for that step. To me, I'm not a fan of having statements and functions in the language

00:11:18.060 --> 00:11:22.720
because it looks to me like functions basically solve the same problem with a little more

00:11:22.720 --> 00:11:24.040
clarity.

00:11:24.040 --> 00:11:28.420
They're a little more functional. You can span the multi-line if the arguments are super long

00:11:28.420 --> 00:11:29.620
that you need to.

00:11:29.620 --> 00:11:34.980
Like with the print statement, you'd have to use a continuation backslash and other weirdness like that.

00:11:34.980 --> 00:11:38.460
So, you know, just because you can doesn't mean you should.

00:11:38.460 --> 00:11:40.400
I guess that's probably how I feel about it, but

00:11:40.400 --> 00:11:43.640
I wouldn't use it if it were in the language. Let me put it that way.

00:11:43.640 --> 00:11:50.200
Yeah, I'm for the no yuck camp. I think that print statement shouldn't have been a statement in the

00:11:50.200 --> 00:11:54.720
first place. And then I think Python 3 fixed it. Having it be a function is the right thing to do.

00:11:54.720 --> 00:12:01.380
I wish there were more statements that were functions instead. Also, I think I wish assert was a function

00:12:01.380 --> 00:12:06.440
instead of a statement. Because people doing, thinking that it's a function and putting a parentheses

00:12:06.440 --> 00:12:12.340
around assert causes problems. But that's not what this is about. It's interesting. I brought it up

00:12:12.340 --> 00:12:16.240
because people should know about this weird, wacky discussion.

00:12:16.240 --> 00:12:17.140
Yeah, that's funny.

00:12:17.140 --> 00:12:20.480
I'm glad that it got thumbed down. And I don't think it's going to happen.

00:12:20.480 --> 00:12:21.960
You're willing to make a statement about it?

00:12:21.960 --> 00:12:22.760
Yes.

00:12:22.760 --> 00:12:29.020
All right. Well, I'm going to make a statement about Flask. I think Flask, you just had David

00:12:29.020 --> 00:12:34.020
Lord on the show, right? That's not out yet, but pretty cool. Yeah. And he's lead maintainer of

00:12:34.020 --> 00:12:41.180
Flask these days. So Flask is, at least at the API level, got to be the most popular web framework

00:12:41.180 --> 00:12:46.840
there is. Because it's slightly more popular than Django if you look at some of the recent surveys.

00:12:46.840 --> 00:12:52.760
But if you look at the other frameworks, many of them are Flask-esque, if you will, right?

00:12:52.760 --> 00:12:52.940
Yeah.

00:12:52.940 --> 00:12:59.300
Things that are like Responder or Cynic or whatever. They have this idea of like sort of the same style,

00:12:59.300 --> 00:13:05.520
right? So there's an article called FastAPI for Flask users. And I'm actually a big fan of

00:13:05.520 --> 00:13:12.340
FastAPI. I'm hoping to have some opportunity to use it soon. Like the APIs that I've worked on,

00:13:12.340 --> 00:13:16.140
they've been around for a while, they predate FastAPI. And I don't really want to go create a whole

00:13:16.140 --> 00:13:21.760
new site just so I could use a different framework. That sounds like maintenance to me. So I haven't

00:13:21.760 --> 00:13:28.180
got a chance to use it in production yet, but FastAPI looks awesome. So there's an article called Fast

00:13:28.180 --> 00:13:33.780
FastAPI for Flask users. And it says, look, you probably know the Flask API. Here is the equivalent

00:13:33.780 --> 00:13:35.660
for FastAPI.

00:13:35.660 --> 00:13:36.220
Okay.

00:13:36.220 --> 00:13:42.880
Yeah. And so there's talk about some of the advantages and they're pretty awesome. So automatic data

00:13:42.880 --> 00:13:49.780
validation in FastAPI doesn't exist in Flask, generally speaking. Automatic documentation generation,

00:13:50.160 --> 00:13:57.200
built in best practices like type annotations and Pydantic scheme schemas and whatnot.

00:13:57.200 --> 00:14:05.780
It comes ships or recommend, I guess, as terms of like a requirement, you have to have a ASGI server.

00:14:05.780 --> 00:14:11.800
So it comes with uvicorn, which is one of the, it's like Gicorn plus uvloop for async stuff.

00:14:11.800 --> 00:14:16.500
And in a lot of ways, it's super similar. So if you want to create a view method instead of

00:14:16.500 --> 00:14:23.160
app.route, you would say app.get. And so FastAPI, would you imagine the name indicates it's

00:14:23.160 --> 00:14:24.180
mostly for building APIs?

00:14:24.180 --> 00:14:25.460
Yes.

00:14:25.460 --> 00:14:30.900
All right. So when you talk about functions and what they're going to do, you say not just

00:14:30.900 --> 00:14:39.800
here's a URL, but here's a URL and an HTTP verb. So app.get forward slash or app.put slash account

00:14:39.800 --> 00:14:44.760
or something like that, which is pretty cool. In the route, you can specify variables. So in Flask,

00:14:44.760 --> 00:14:51.000
you would, you could have a user ID and in the string route, you would say int colon user ID. If

00:14:51.000 --> 00:14:56.820
you want Flask to convert that to an integer, right? It's fine. It works. Okay. But that the rest of the

00:14:56.820 --> 00:15:01.540
tooling doesn't help you know it's an integer just because Flask knows it's going to be an integer,

00:15:01.540 --> 00:15:06.940
right? So in FastAPI, you put the variable up there as well. But then in the function,

00:15:07.420 --> 00:15:13.240
you put the variable name as a type, and then it will actually convert that to an integer using the

00:15:13.240 --> 00:15:22.060
Python language tools or specification rather than the string API thing. So that's handy. If you want a

00:15:22.060 --> 00:15:27.240
query string in Flask, you just have a URL, you can go to request.args, and you can get the value out of the

00:15:27.240 --> 00:15:34.640
query string. In FastAPI, you just put the query string values, or sorry, the keys as arguments, and they just get

00:15:34.640 --> 00:15:41.300
passed in. That's pretty cool. Yeah. If you have a API that takes a JSON post, like, you know, it's

00:15:41.300 --> 00:15:46.720
accepting a JSON document, you can just say it takes a dictionary, and that gets posted in. But you can go

00:15:46.720 --> 00:15:52.860
way, way further, which is awesome. You can define a Pydantic model, which is a class that has types

00:15:52.860 --> 00:15:58.840
and validation on the class, right? Yeah. And then you can say my view method or my API method takes,

00:15:58.840 --> 00:16:03.660
like in the example they have is a sentence that has got like various components, nouns, verbs, and

00:16:03.660 --> 00:16:09.480
whatever. You can say, here's a function, and it has an argument called sentence, and it'll take that JSON

00:16:09.480 --> 00:16:14.860
document, parse it into the Pydantic model, and pass it to you pre-validated.

00:16:14.860 --> 00:16:19.360
That's definitely one of the benefits of FastAPI is this data validation.

00:16:19.360 --> 00:16:24.080
Yeah, this data, this is like built-in data validation, because how much, how many times

00:16:24.080 --> 00:16:29.040
do you spend like effort, oh, I got a string, but I got to convert it to an integer. I got to make

00:16:29.040 --> 00:16:33.740
sure that this value is here. I got to make sure that this one is, you know, like, whatever, like it

00:16:33.740 --> 00:16:39.260
matches some, some set of sub strings or whatever. Just let, let the framework handle it. It also has

00:16:39.260 --> 00:16:43.980
the equivalent of blueprints, which it calls routers, and this automatic validation I talked about. So

00:16:43.980 --> 00:16:51.700
anyway, there's a nice article that says, you know Flask, let's teach you FastAPIs real quick by just doing a

00:16:51.700 --> 00:16:52.920
this equals that.

00:16:52.920 --> 00:17:00.240
Yeah, I love this, because there's a lot of people that have been writing APIs in Flask for a long time. And so it's

00:17:00.240 --> 00:17:06.760
just second nature to them. And having something to say, hey, I want to try FastAPI, but is the learning curves going to be

00:17:06.760 --> 00:17:12.160
a problem? Well, with something like this is decoder ring. And it is set up for, you can just sort of skim

00:17:12.160 --> 00:17:18.280
through and go, well, how do I do URLs? Oh, this is, this is how you do it. And URL variables and

00:17:18.280 --> 00:17:20.520
different things. It's set up really nice.

00:17:20.520 --> 00:17:23.040
Yeah. Yep. Definitely fun. Definitely useful.

00:17:23.040 --> 00:17:24.280
So do you use Twitter?

00:17:24.280 --> 00:17:31.680
I do use Twitter. Sometimes happily. Sometimes I get dragged into stuff. Sometimes I use it in write only

00:17:31.680 --> 00:17:35.560
mode where I want to make a statement, but I don't really want to go read it. But yeah, definitely.

00:17:35.560 --> 00:17:42.140
Yeah, well, I have a, this is probably common, sort of a love-hate relationship with Twitter. I use it a lot

00:17:42.140 --> 00:17:49.260
and like keeping track of other people. But sometimes I don't really like that it's a pain to delete old

00:17:49.260 --> 00:17:55.700
stuff. Because I think of it as a current conversation. I don't really look at what somebody wrote a year

00:17:55.700 --> 00:18:03.380
ago. And I don't really care what I wrote a year ago. So I have used Twitter deletion tools before.

00:18:03.740 --> 00:18:09.400
They seem kind of weird that I have to go out and give my credentials to some other website or

00:18:09.400 --> 00:18:10.740
something though. So, but I know.

00:18:10.740 --> 00:18:13.060
I'm sure that'll be fine. It'll be fine. Don't worry about it.

00:18:13.060 --> 00:18:20.380
Yeah. Anyway, but there's APIs. So you could use the Twitter API, but how? And so I thought it was

00:18:20.380 --> 00:18:27.680
really cool that Chris Albon is somebody that tweets about data science a lot. And he posted a little

00:18:27.680 --> 00:18:35.660
snippet that he said he uses. At least he did it first at one point. But it's a cool little example

00:18:35.660 --> 00:18:44.140
of using a library called Tweepy to interact with Twitter and to delete old tweets for your account.

00:18:44.680 --> 00:18:50.800
So it's just this really short little Python script. But it deletes tweets. There has defaults, but you

00:18:50.800 --> 00:18:55.020
can change those. Obviously, it's just a Python script. So you can change whatever you want.

00:18:55.020 --> 00:19:02.680
But it's set up to delete tweets that are older than 62 days and that have likes less than 100 people

00:19:02.680 --> 00:19:10.100
and that you haven't liked yourself. So the idea being, if you go through some of your old tweets

00:19:10.100 --> 00:19:14.460
and the ones that you're like, oh yeah, that was cool. I want to keep that around. Just like it,

00:19:14.460 --> 00:19:20.280
like your own tweets and then run this script and it'll delete some old stuff. I would definitely

00:19:20.280 --> 00:19:25.140
have to change that 100 count to something else because I don't think I've ever had a tweet liked

00:19:25.140 --> 00:19:25.940
by 100 people.

00:19:25.940 --> 00:19:30.860
That's a big number. You know, Twitter used to show how many tweets you actually had.

00:19:31.220 --> 00:19:35.220
And I don't think it shows it anymore on my profile. At least I don't see it immediately.

00:19:35.220 --> 00:19:43.320
How many tweets I had just followers and following and likes and stuff like that. But yeah, pretty cool.

00:19:43.320 --> 00:19:49.320
It's like keep the highlights, right? Just keep my highlights. I don't need every random thing of,

00:19:49.320 --> 00:19:54.600
oh, I went on, had a hamburger today. People don't need that as a piece of history.

00:19:54.600 --> 00:19:58.460
Yeah. So when, and you don't know what's going to stick and what's going to not. And I was actually

00:19:58.460 --> 00:20:04.800
reading an article recently about, about Twitter, about how that, what that says to you. If somebody

00:20:04.800 --> 00:20:09.800
like, for instance, you're trying to get a job and somebody looks at your Twitter account, having the

00:20:09.800 --> 00:20:17.000
junk in there that like nobody really related to having that automatically called out and just having

00:20:17.000 --> 00:20:20.820
the highlight reel, that's not a bad idea for some of the old stuff.

00:20:20.820 --> 00:20:25.580
Yeah. And you could turn it way down. You could say, look, if there's no likes or no retweets,

00:20:25.580 --> 00:20:30.880
just drop it. Yeah. Yeah. It might even be good for me to like, just to go back a couple of days,

00:20:30.880 --> 00:20:34.440
but if nobody's liked it in a couple of days, maybe just take it away.

00:20:34.440 --> 00:20:35.620
That didn't happen.

00:20:35.620 --> 00:20:37.220
Yeah. That didn't happen.

00:20:37.220 --> 00:20:42.620
So people could end up clinging to their old tweets, but they probably shouldn't.

00:20:42.620 --> 00:20:42.960
Right.

00:20:42.960 --> 00:20:49.980
Yeah. So I want to talk about an article by Itamar Turner-Trowing. Now we spoke about him,

00:20:50.580 --> 00:20:55.580
sort of, not by name, I don't think, but we talked about Phil, the data science memory

00:20:55.580 --> 00:20:56.980
profiler a little while ago.

00:20:56.980 --> 00:20:57.680
Okay. Yeah. Right.

00:20:57.680 --> 00:21:03.080
So he's the guy who wrote that. I actually had him on Talk Python on episode 274 as well,

00:21:03.080 --> 00:21:07.220
talking about that. So that was pretty cool. But he, independent of that, he wrote this article

00:21:07.220 --> 00:21:13.300
that I came across that I liked called Clinging to Memory, How Python Function Calls Can Increase

00:21:13.300 --> 00:21:18.440
Your Memory Usage. And this is part of my research for working on that course that I was talking about,

00:21:18.440 --> 00:21:21.080
that memory, Python memory management stuff.

00:21:21.080 --> 00:21:21.360
Okay.

00:21:21.360 --> 00:21:26.900
So he talks about like, hey, we're going to have this thing. It's going to load up some NumPy data

00:21:26.900 --> 00:21:31.060
and then it's going to pass it to a function. The function is going to make some changes,

00:21:31.060 --> 00:21:35.440
take the return value of that, pass it to another function. It's going to make some more changes.

00:21:35.440 --> 00:21:40.760
So basically three steps and said, look, we'd expect that we've loaded two gigs of memory.

00:21:40.760 --> 00:21:45.860
And yet when you run Phil against it, you end up with three gigs of maximum memory usage,

00:21:45.860 --> 00:21:51.420
which is a little bit weird. And the reason is those initial like intermediate values that you're

00:21:51.420 --> 00:21:57.500
working with on step one and step two, the way Python decides a variable goes out of scope

00:21:57.500 --> 00:22:04.560
is in this case, the function returns, not like it's never used again, but it's just the function

00:22:04.560 --> 00:22:10.020
returns. In which case it's going to hang on to all the intermediate copies all the way to the end.

00:22:10.020 --> 00:22:10.540
Interesting.

00:22:10.540 --> 00:22:16.320
Right? Like some languages, they determine that and they get rid of it. Like in C#,

00:22:16.320 --> 00:22:22.320
the JIT compiler will notice like, okay, a variable is not used after half the way. So we're going to

00:22:22.320 --> 00:22:27.300
make it eligible for GC basically, unless it's in debug mode, then keep it around in case somebody

00:22:27.300 --> 00:22:30.480
sets a break point. They want to see it. So there's a lot, a lot of the tricks that things can do.

00:22:30.480 --> 00:22:34.260
Python doesn't do them. So it's going to stick around for this

00:22:34.260 --> 00:22:39.740
length of the function. So what can you do to make it not stick around as long? Because maybe

00:22:39.740 --> 00:22:43.660
you only have two gigs and you don't want to use three gigs or whatever. Right? So he talks about

00:22:43.660 --> 00:22:48.940
three different solutions. One is to don't hold onto the intermediate variables and just chain into

00:22:48.940 --> 00:22:54.380
one massive function call, like pass the results of one to two to step two, pass the results of step

00:22:54.380 --> 00:22:59.540
two to three. And there's no variables holding on. So it'll be gone. Right? That's an option.

00:22:59.840 --> 00:23:06.560
Another one is to iteratively change the variable, say like data equals load data from first step.

00:23:06.560 --> 00:23:13.340
Data equals step two of processing of data. Data equals step three of processing of data. And that

00:23:13.340 --> 00:23:19.560
way you're dropping the reference count to the first, to the intermediate steps along the way.

00:23:20.320 --> 00:23:24.000
Right? So that's an option. And then there's a third one that's more complicated about creating

00:23:24.000 --> 00:23:29.340
like a sort of a ownership management type of thing that people can check out as well. But I just thought

00:23:29.340 --> 00:23:33.880
it was interesting to think about, you know, when, how long do these things stick around and what

00:23:33.880 --> 00:23:39.580
techniques might you use that are incredibly simple? Like just reuse the variable name, problem solved

00:23:39.580 --> 00:23:41.880
in terms of having too much memory usage.

00:23:42.040 --> 00:23:46.060
Interesting. Yeah. When I look at these, they all look kind of like the same, but having,

00:23:46.060 --> 00:23:50.800
having the answer be that they, they use different amounts of memory is not obvious.

00:23:50.800 --> 00:23:55.600
Right. It's not obvious at all, but it's, you could easily look at this one where you're iteratively

00:23:55.600 --> 00:23:59.180
changing the variable and say, Oh, you shouldn't do that. You should name it more clearly. Cause

00:23:59.180 --> 00:24:04.220
maybe the type is changing along the way and it would be weird, but you could say, yeah, but

00:24:04.220 --> 00:24:10.280
this one works cause it will fit into Ram and the other one won't. So we're willing to accept this

00:24:10.280 --> 00:24:17.160
like slightly imperfect code because it works better. Anyway, there's a lot of interesting trade-offs you

00:24:17.160 --> 00:24:21.480
can make here, but I just, it's, it's only the tip of the iceberg for things like this you could do,

00:24:21.480 --> 00:24:24.740
I think, but it's interesting to just put it on your radar.

00:24:24.740 --> 00:24:30.680
Yeah. Yeah, it is interesting. Yeah. And actually, and like we said, I think that more and more as we

00:24:30.680 --> 00:24:36.920
start using Python for other applications or non desktop kind of things, like when we're

00:24:36.920 --> 00:24:41.500
a non-server things, if we're using it for, there's a couple ends of it. If you're using

00:24:41.500 --> 00:24:47.820
small devices, like in circuit Python or something, you're going to care about this stuff. But also if

00:24:47.820 --> 00:24:53.740
you're using very large data sets, then we care about it again. And, it doesn't matter how much

00:24:53.740 --> 00:24:59.340
memory your computer has having multiple copies of gigabytes of data when you don't have to,

00:24:59.340 --> 00:25:04.960
will slow things down. Yeah, for sure. Or even if it's like an API and you just happen to be doing,

00:25:04.960 --> 00:25:09.940
it's not that extreme, but you happen to be doing a thousand of them at a time. Same story.

00:25:09.940 --> 00:25:15.460
Yeah, exactly. And as we use Python more and more and more applications, we're going to start caring

00:25:15.460 --> 00:25:21.640
about that again. Yeah, absolutely. That's the end of our six. I actually have been just so swamped

00:25:21.640 --> 00:25:25.800
with stuff. I don't have anything extra to talk about. Do you have any extra items?

00:25:25.800 --> 00:25:31.020
I do. And this is just a follow-up email we got from a listener named Adam. Thank you, Adam.

00:25:31.020 --> 00:25:36.800
And you had talked about pickling things. Apparently you're a fan of dill pickles and

00:25:36.800 --> 00:25:42.940
no wait, pickled strings, pickled lists, pickled dictionaries. No, we were talking about a pickling

00:25:42.940 --> 00:25:46.900
and how it didn't make sense most of the time, but there might be some use cases and you're like,

00:25:46.900 --> 00:25:49.500
what might be a use case that we really need? Right?

00:25:49.620 --> 00:25:55.400
So Adam said, Hey, I got a use case that worked for us. I worked on an API that spoke to a third

00:25:55.400 --> 00:26:02.740
party service that was wonky and it was over raw sockets. So you'd have to create these byte arrays

00:26:02.740 --> 00:26:09.120
and send them along. And the thing was also not available 24 seven. It would sometimes crash,

00:26:09.120 --> 00:26:13.140
things like that. So what they would do is they could set a flag in their app and it would pickle

00:26:13.140 --> 00:26:20.260
all the messages that it would, would have sent. And if the site comes back, it can like rehydrate

00:26:20.260 --> 00:26:24.680
those things and then ship them along, or you could pull them up for debugging and look at their

00:26:24.680 --> 00:26:30.140
details and whatnot. So it was like, Oh, we got to save this exactly as we would have sent it.

00:26:30.140 --> 00:26:31.020
Let's just pickle it.

00:26:31.020 --> 00:26:31.600
That's pretty cool.

00:26:31.600 --> 00:26:33.040
Yeah. That seems like a pretty good one.

00:26:33.040 --> 00:26:33.280
Yeah.

00:26:33.280 --> 00:26:36.600
And there was a feature flag they could turn on and off, which was kind of cool. Yeah.

00:26:36.600 --> 00:26:39.440
They could also do that for the messages they got from the service. Pretty cool.

00:26:39.920 --> 00:26:45.080
real quick. Python three, eight, four is out. I've already brew upgraded mine. So that's all good.

00:26:45.080 --> 00:26:49.000
And big news, big news. I can't believe it. I've been selected.

00:26:49.000 --> 00:26:49.480
For what?

00:26:49.480 --> 00:26:54.480
I, if I go to my GitHub repo, I don't have the cool read me thing that you're talking about,

00:26:54.480 --> 00:26:59.060
but under my picture, it says I have a pro account because I had to pay for some stuff,

00:26:59.060 --> 00:27:03.180
but I noticed that I'm an Arctic code vault contributor.

00:27:03.180 --> 00:27:03.740
Wow.

00:27:03.740 --> 00:27:08.720
So remember we spoke about the Arctic code vault where GitHub is taking a bunch of the popular projects

00:27:08.720 --> 00:27:16.520
and then like sticking them over in some vault in Norway or somewhere like that, Greenland,

00:27:16.520 --> 00:27:23.060
to preserve it. And if the code that you've contributed to GitHub was selected, then now

00:27:23.060 --> 00:27:27.080
you get this cool little highlight that's like a snowflake that says Arctic code vault contributor.

00:27:27.080 --> 00:27:32.060
And you can hover over it and it'll say why. So yeah, I've contributed apparently to a couple

00:27:32.060 --> 00:27:33.620
of things and you might be as well.

00:27:33.840 --> 00:27:38.160
Well, yeah, you, the listener might, but I just checked mine and I am too. So that's neat.

00:27:38.160 --> 00:27:38.880
Yeah. Awesome.

00:27:38.880 --> 00:27:39.620
Neato.

00:27:39.620 --> 00:27:40.940
Yeah. So.

00:27:41.540 --> 00:27:42.920
I think we covered that once.

00:27:42.920 --> 00:27:44.160
Yeah.

00:27:44.160 --> 00:27:48.180
Yeah. We definitely covered the code vault, but yeah, I think this, you are a contributor

00:27:48.180 --> 00:27:51.960
thing. The little badge is new and I don't know. It makes me happier than it probably should.

00:27:51.960 --> 00:27:55.880
Yes. It's so cool.

00:27:55.880 --> 00:27:59.080
It's cool.

00:27:59.080 --> 00:27:59.940
Yeah.

00:27:59.940 --> 00:28:01.300
Yeah. It's super neat.

00:28:01.300 --> 00:28:02.720
Testing is cool.

00:28:02.840 --> 00:28:05.360
I love testing and having good code coverage is cool.

00:28:05.360 --> 00:28:05.700
Yeah.

00:28:05.700 --> 00:28:08.920
So I've got a joke for you, a cartoon, if you will.

00:28:08.920 --> 00:28:09.220
Okay.

00:28:09.220 --> 00:28:11.260
From this place called geek and poke.

00:28:11.260 --> 00:28:12.800
They have all sorts of good stuff there.

00:28:12.800 --> 00:28:17.440
And, you can click on the picture and it'll take you to the actual comic.

00:28:17.440 --> 00:28:23.100
So there's a two people, a woman developer and a man developer staring at each other.

00:28:23.100 --> 00:28:25.780
And the woman is the more senior one.

00:28:25.780 --> 00:28:28.260
They're looking at each other and it says QA best practices.

00:28:29.100 --> 00:28:33.600
She's looking, looking at the guy and says, never just remove a failing test.

00:28:33.600 --> 00:28:35.980
The guy stares back blankly for a second.

00:28:35.980 --> 00:28:38.500
Says, only remove the assert statements.

00:28:38.500 --> 00:28:39.360
Yup.

00:28:39.360 --> 00:28:43.780
So how to sustain a decent code coverage.

00:28:43.780 --> 00:28:46.680
yeah, you can fix a test.

00:28:46.680 --> 00:28:49.480
You can make a test, not fail, remove the assert statements.

00:28:49.480 --> 00:28:50.000
It's good.

00:28:50.000 --> 00:28:50.360
Yeah.

00:28:50.360 --> 00:28:50.860
That's funny.

00:28:50.860 --> 00:28:54.880
You said you actually like test for failure though on yours that they potentially could

00:28:54.880 --> 00:28:55.180
fail.

00:28:55.180 --> 00:28:55.500
Yeah.

00:28:55.600 --> 00:29:00.080
Well, I think that's one of the reasons why we do code coverage on all or not code

00:29:00.080 --> 00:29:00.280
coverage.

00:29:00.280 --> 00:29:02.580
We do code coverage, but we also do a review.

00:29:02.580 --> 00:29:03.320
What's the word again?

00:29:03.320 --> 00:29:03.700
Review.

00:29:03.700 --> 00:29:04.300
Yes.

00:29:04.300 --> 00:29:04.920
Code reviews.

00:29:04.920 --> 00:29:05.560
Yes.

00:29:05.560 --> 00:29:11.540
We do code reviews on tests because we have had a test show up before that exercise.

00:29:11.540 --> 00:29:15.380
we, you know, with a test equipment, we do a lot of complicated things.

00:29:15.380 --> 00:29:21.300
You set up everything, run some stuff, and then we've often have people forget to check

00:29:21.300 --> 00:29:22.200
anything at the end.

00:29:22.200 --> 00:29:28.300
And, and the, so it is important to look at the end to see, is there any way this can

00:29:28.300 --> 00:29:29.180
actually fail?

00:29:29.180 --> 00:29:31.640
Is it, or is it just exercising things?

00:29:31.640 --> 00:29:36.760
I mean, actually exercising things isn't a bad thing because you can get a search in

00:29:36.760 --> 00:29:39.380
your code or, except, or an exception.

00:29:39.380 --> 00:29:39.980
Yeah.

00:29:39.980 --> 00:29:43.040
You still test something, but you're not testing very much.

00:29:43.040 --> 00:29:43.520
Yeah.

00:29:43.520 --> 00:29:47.760
You're testing it runs basically.

00:29:47.760 --> 00:29:48.460
Yeah.

00:29:48.460 --> 00:29:49.500
So awesome.

00:29:49.620 --> 00:29:52.160
Well, yeah, just never remove and fill in a test.

00:29:52.160 --> 00:29:53.200
Only the search statements.

00:29:53.200 --> 00:29:54.840
It's terrible.

00:29:54.840 --> 00:29:56.880
We should not give that idea to people.

00:29:56.880 --> 00:29:58.760
No, we should totally delete this joke.

00:29:58.760 --> 00:29:59.360
It didn't happen.

00:29:59.360 --> 00:29:59.980
It wasn't funny.

00:29:59.980 --> 00:30:00.840
Yeah, it wasn't funny.

00:30:00.840 --> 00:30:02.560
Thanks a lot, Michael.

00:30:02.560 --> 00:30:03.600
Yeah, you bet.

00:30:03.600 --> 00:30:04.440
Great to see you as always.

00:30:04.440 --> 00:30:06.400
Thank you for listening to Python Bytes.

00:30:06.400 --> 00:30:08.860
Follow the show on Twitter at Python Bytes.

00:30:08.860 --> 00:30:11.900
That's Python Bytes as in B-Y-T-E-S.

00:30:11.900 --> 00:30:14.780
And get the full show notes at Pythonbytes.fm.

00:30:15.020 --> 00:30:19.860
If you have a news item you want featured, just visit Pythonbytes.fm and send it our way,

00:30:19.860 --> 00:30:21.900
where I was on the lookout for sharing something cool.

00:30:21.900 --> 00:30:26.100
This is Brian Okken, and on behalf of myself and Michael Kennedy, thank you for listening

00:30:26.100 --> 00:30:28.320
and sharing this podcast with your friends and colleagues.

