This is Python Bytes, Python headlines and news delivered directly to your earbuds.
It's episode 10, recorded Monday, January 23rd, 2016.
This is Michael Kennedy. I'm here with Brian Okken.
Hey, Brian. You ready to talk about Python for the week?
I'm very ready, yes.
Yeah, we got some really cool stuff.
And we have a pretty interesting data story to wrap things up
where people are out rescuing data with Python, I'm pretty sure.
So let's save that for the end and let's get started with time.
We had mentioned in episode 7 that Matplotlib 2.0 was coming out, and it is.
It's official now as of January 17th.
And there's an article from a website called Black Arbs called Advanced Time Series Plots in Python.
And I thought it was a nice focused tutorial.
Matplotlib does a whole bunch of stuff, and it's a little bit overwhelming if you only use it once in a while.
So this is a focused tutorial.
Tutorial looks good.
It uses pandas, numpy, Matplotlib, of course, and a library called Seaborn that I had never heard of before.
It's a statistical data visualization add-on, I think, for Matplotlib.
Looks good.
But the article starts with an empty XY chart and gets some financial data from Yahoo and does some manipulation of it to plot it out.
But then, now, the defaults aren't ever exactly what you want.
So this tutorial goes through how to add, like, shaded areas for, in this example, it was for times where there were recessions.
If there's something special about part of your data you want to highlight, there's a way to do that.
Adding chart titles and axis labels and styling the legend.
I never knew you could do this.
The different formatting for the XY tick labels.
And if, like, this chart had both positive and negative numbers.
And if you want to draw a zero line or a line anywhere that's a horizontal line, it shows how to do that.
Turning on data points.
And one of the things I didn't even know you could do, a couple things, were to put chart annotations to describe specific plot points.
And then put arrows pointing to that piece of the data.
And then adding logos and watermarks over the top.
And it's a nice, short, concise tutorial.
I like it.
Yeah, it's really nice.
And it's super approachable.
It just shows you, like, here's the code steps from here to there to there.
Get some financial data from Yahoo and do some graphs.
And, yeah, if you need to graph stuff, right, Python is getting better and better.
So very, very nice.
Yeah.
Speaking of pictures, Instagram has a lot of pictures.
Yeah.
And they actually run a significant amount of traffic through Django and through Python.
They use a pretty interesting way of configuring their servers.
It's not at all unlike the way I do for my Talk Python websites as well.
In fact, Python bytes as well.
And so let me just quote from their little article here.
And it says, how we run our web server.
Instagram's web servers run Django in a multi-process mode with a master that process that forks itself a dozens of times to create worker processes that actually handle the requests.
And they're doing that with MicroWSGI in a pre-fork mode so they can leverage shared memory across the master and the 20, 50, whatever worker processes that it controls.
Because they're all kind of running the same code for the most part.
So why do you need, you know, 20 copies of Python loaded into memory and things like that, right?
So they're thinking about how can they get their code to run faster?
How can they run more of these forked processes and basically add more concurrency per server?
And so they came up with a pretty radical idea.
They said, what if we just turn off garbage collection in Python?
That seems bad, right?
It does seem bad, yeah.
So they wrote an article called Dismissing Python Garbage Collection at Instagram.
What they did is they had a thing where they would monitor the memory of the worker processes and I believe restart them if the memory got too out of control.
I don't know why they're doing that, but for whatever reason they did.
And I think that they found that the shared memory was much, much less shared than they expected.
So they said that each worker process was like 225 megs of memory usage and they're only sharing like 140 megs, even though they're basically all doing the same thing.
So they went to look and sort of do some profiling and they thought that there was some Linux copy on write behaviors happening due to reference counting.
So they said, all right, let's turn off reference counting.
That seems like really bad because for those of you guys who don't know, Python's GC or sort of memory management works in two modes.
There's a direct reference counting deterministic thing that when the last reference to an object goes away, it's typically deleted instantly.
But the problem with reference counting for garbage collection and memory management is you can get cycles.
So there's a GC that manages cycles.
Okay.
And so what happened is they tried turning off reference counting.
That didn't help.
They said, all right, well, let's turn off GC.
And they said when they turned off garbage collection, they were still able to run about the same, you know, only like accepting sort of memory leaks from cycles, I guess.
And they said they successfully raised the shared memory from 140 megs to 225.
I guess that was a little bit the wrong number, but they dramatically increased the shared memory and they were able to drop the memory usage per server by eight gigs.
And they saved 25% RAM on their entire Jenga fleet.
And in fact, they actually got it to run 10% faster due to the way the rearranged memory done by garbage collection actually lines up with CPU caches and things.
So they wrote this really detailed article with like lots of stats and the command you can run to do these things.
And they said, actually, for us, for our weird ultra high performance, ultra heavy load servers, it makes sense to turn off Python's garbage collection and basically set up a custom shutdown thing that doesn't collect too much memory on the way out the door.
Isn't that interesting?
It's very interesting.
I didn't even know you could turn off the garbage collection.
There's apparently a way that you can do it, but it's not simple.
Yeah.
And they ran into problems like they turned it off and other libraries would ensure that it was on and turn it back on and things like that.
They're like, no, I want it off.
And so they had, I think they had to like recompile some things.
You know, it's not like a flag.
But anyway, it's pretty interesting.
It's definitely an interesting story.
Yeah, it's a thing.
It's a thing.
It questions some assumptions about how things work.
And it's sometimes, it definitely does not sound pretty.
But, you know, maybe you're optimizing that last 10, 20%.
It's not going to be pretty.
But this is a pretty interesting look at what Instagram is doing.
I just like to look at these large scale deployments and people have handling tons of requests, what they're doing.
It's always interesting.
Yeah.
And also somebody else out there might be thinking, hey, maybe we could turn it off and try to learn from Instagram.
Yeah, absolutely.
They detailed it out there.
They have a nice engineering blog.
They put interesting stuff up there frequently.
But Brett Cannon, no, I forget where Brett Cannon works, but.
Brett Cannon works with Dino Veland over at Microsoft.
I think the Azure Data Science team and their Brett Cannon is a Python core developer.
Yeah.
And he's, we've learned a lot of interesting things from Brett.
But he's got a blog called snarky.ca.
And he put up my experience with type hints in mypy.
I was attracted to this article because I have sort of been watching this type hint thing with a little skepticism.
So I'm not really sure if it's going to help, how it can help me.
So I was interested in reading this.
He took a project that he supports and then used both mypy and type hints to try to, who's hoping to improve the quality of it.
And it's kind of an interesting project.
It's a, I didn't even know what CLA was.
So it's a CLA enforcement bot for the Python Software Foundation.
And that's the contributor license agreement.
So the idea is if somebody pushes or submits a pull request into one of the Python projects,
this robot goes out and makes sure that the person that is pushing or requesting the pull request has assigned CLA.
It sounds like it's obvious why this is needed.
But it's a small enough project to run this experiment on of adding type hints.
And it's not a very long article, but he points to his pull request for this, the changes he made, and the lessons learned.
I didn't know what mypy was before.
So mypy is a static analysis tool that makes sure you're, I think it just makes sure your type hints are correct or uses the type hints for linting.
Yeah, I think so.
And, you know, the PEP that you talked about, originally, I think that was all Python 3 stuff.
I'm pretty sure that that all works on Python 2 now, at least with some of the tooling, that the type hint ideas are being backported,
with the idea being that if we can take a lot of this legacy Python code, give it some static type definitions,
and then use tooling more intelligently with more information to check the upgrade to Python 3.
So actually, it can provide some structure to the older code, actually.
So it's, you know, I always thought of type hints as being this thing that only Python 3 gets,
and it's kind of this new deal.
But, you know, it may turn out to be most important in crossing that Python 2 to Python 3 chasm, which is pretty interesting.
It'd be an interesting benefit.
You know what else is interesting?
The second largest, the second most active contributor to this mypy project, Guido Von Rossum.
Oh, really?
Yeah.
He's really doing a lot with this.
There was a couple hiccups that he ran into.
Apparently, there's some of the 3.6 isn't fully supported, but I'm sure that'll get supported fairly quickly.
What I really wanted to highlight was, I'm going to quote from his conclusion.
After this experiment, he asked himself, would he bother using typing and static typing in new Python 3 code?
And essentially, he said yes.
Once it supports f-strings, apparently, at the time, it doesn't.
I don't know if it's fixed yet.
I think it only supported Python 3.5 and f-strings, of course, 3.6, which is shiny new.
But he says, when I design an API, I already have to think about what type of objects would be acceptable.
So quickly writing down my assumptions doesn't hurt anything.
It's relatively quick, and it benefits anyone having to work with my code.
But I also wouldn't contort my code to fit within the confines of type hints.
For example, if type hints force me to write cleaner code, then that's great.
But if something is so dynamic that it can't have type hints, then that's fine, and I'll happily use typing.any as an escape hatch.
In the end, I view type hints as enhanced documentation that has tooling to help verify that the documentation about types is accurate.
And for that use case, I see type hints worth doing and not at all a burden.
And he also mentions that it didn't make his code less readable.
It only enhanced the readability.
And since I'm all for making your code more readable, this article actually gives me a more positive light on using types.
Yeah, that's cool.
I do periodically put type hints in my Python 3 code.
And I find that I usually do it when I'm looking at a function.
I'm like, you know, I don't really remember the context in which this is called and what is being passed in here.
So let me make it really explicit at the function signature level.
And then the tooling can, of course, tell me if we're doing it wrong somewhere else.
But it's kind of a reminder to me if it's not obvious what's going on.
But I don't do it, like, universally.
It's more like in those places where I'm knowing the type is going to really help.
Yeah, and I'm still spending, I guess, too much time straddling the legacy Python 3 world that I'm still having trouble with that chasm.
Yeah, sure.
Well, the mypy works on Python, too.
So there you go.
You know what else is quite pervasive throughout Python?
Underscores.
The underscore is special in Python.
Is it special?
It is special.
You know, there's a lot of things that are special or, you know, maybe a more common way to say it would be idiomatic, right?
Or Pythonic.
I think the use of the underscore is one of these symbols that shows up a lot.
And they actually have meaning.
But people coming from other languages don't necessarily know all the nuanced behavior of the underscore.
Or not behavior, meaning of the underscore.
And so there's this article called Understanding the Underscore of Python, which is kind of a cool title.
It gives you some examples.
It says if you write, if you come across some Python code, you might see something like for underscore in range 10 or dunder in itself.
Things like that.
You see it all the time.
But these underscores have meanings.
And they said, look, there's basically five cases with some sub cases thrown in about when you might have special meaning with this underscore.
The first one is if you're in the REPL.
If you're in just the, you know, just type Python, go into the REPL.
Whatever you type, the last value is always underscore.
Right.
So if you call a function and you forget to store its value, you can just say underscore.
And that's whatever that function returned, for example.
I didn't know that before reading this article.
That's pretty cool.
Yeah.
It's really handy.
If you did something that took like 20 seconds, you're like, oh, I forgot to put that in a variable.
You can just, you still have it.
It's called underscore.
That's cool.
But that's not really in code, right?
The first example I gave you, four underscore in range of 10.
That's kind of the, I don't care.
I have to put something here, but I want to explicitly make the point that I don't care about this variable.
So there's interesting places where that might come up, right?
This four underscore is an example.
Maybe I just want to do a loop 10 times.
I don't actually care about the number.
I just want to do it 10 times.
So that's one way to do it.
If you have a...
So that's just a convention, right?
So what's happening there is the underscore is just a character, which is a valid variable name?
Yes, exactly.
Okay.
Except for the linters, the linting tools know about it.
Oh, okay.
So for example, in like in PyCharm, if you have a function that takes a parameter and you're not using that parameter,
then it'll like make it gray and give it a little squiggly saying, here's an unused argument.
Examples come to mind in the dunder init in Pyramid.
There's like a sort of startup thing that passes a configuration settings thing.
And if you don't care about the configuration settings thing, well, what are you going to do?
Well, you can just put an underscore and then you don't get warnings that that variable's unused.
Now, let's see.
If you're doing tuple unpacking and you've got a tuple of five things, you want the first and the fourth or whatever.
You can put some underscores in there to make it unpack correctly all over the place.
So you have this, I don't care variable.
And the linters actually will not warn you that underscore is not used.
Okay, cool.
That's cool.
And then you have like giving meaning to variables.
Underscore variable is like a, some people say private.
I think of it more of as a protected variable.
So if I've got a class and has a field or attribute like underscore name or whatever, right?
It's hints to consumers of that class.
They should leave it alone.
But technically it's still accessible.
I think of that more as protected, right?
It still leaves it accessible to derived classes, but it does tell people stay away.
Yeah.
I also think of that as like, I don't make any promises that I might not change this behavior.
Yes.
Yeah.
Yeah, exactly.
All right.
And you can have double underscore in a class, which will actually rename it.
So it is much harder to get a hold of like name mangling.
So that's like real private.
And if you have a conflicting thing, you can have, like if you have a variable, you want to call it in,
well, there's a keyword called in, like key in dictionary.
You can just say in underscore.
SQLAlchemy has like and underscore or underscore in underscore.
So it can have things that look very similar to restricted keywords, but, you know, avoids them.
And then you have the whole Python data, data model with like dunder init, dunder new, dunder representation,
string, so on, like all the magic methods.
And then there's a few that I didn't really know about.
Well, one, I guess, in the internationalization of strings.
There's some special meaning there.
It's kind of complex.
I'm not going to go into it.
And then in Python 3.6, you can use it as like where you would have commas for separating for digit grouping.
You can have underscore.
So like one underscore zero, zero, zero, underscore zero, zero is a million in Python 3.6.
Yeah.
And this is good also just for reading other people's code to understand how they're using it.
Yeah.
Because you might just think, oh, that's a weird naming convention that that person used here.
But like they're trying to communicate something very specific by using underscore in all these circumstances.
So I think it's good to like bring it up.
People maybe come from other languages.
Yeah.
Especially people that come from Perl because Perl has a very special meaning for underscore.
So it's good to know that it isn't that.
Yeah.
You know, one of the things that I think is frustrating is if there's like a super old PyPI package.
It hasn't been updated in five years, but it's got like that perfect name.
There should be some active project that could sort of inherit its name.
There was a PEP that came out on the 12th by Donald Stuffed.
And it's in draft status currently, but I'm sure that with probably a few tweaks by people that are really in the Python core people, it'll probably go through.
But it's called package.
It's PEP 541 package index name retention.
And it's basically just like what you said is given a package name in the index, it's a flat namespace.
The unique names are a finite resource.
So as the package index is growing and growing older, we need to have a way to deal with things like old packages that aren't updated anymore.
Somebody that just like squatted on it, but hasn't done anything with it.
Or, you know, there's other various things or conflict of two people that legitimately want to use it.
How do we resolve those conflicts?
Yeah, like an example comes to mind for me is there's a cool package for kind of a crummy problem called Suds.
So consuming soap web services in Python is not pretty because they have all their namespaces.
So it's just like soap is like a big gnarly XML format for web services that's like preceded or was sometimes more popular within enterprises than JSON HTTP services.
So there's a cool package called Suds that has like a really great API for consuming those on the client side.
But it's kind of old and outdated.
It only supports Python 2.
So a guy whose username is Jerko created, no reflection on him personally, created a project called Suds-Jerko.
So if you wanted to have in the package name and code is just Suds, but it's like basically that thing upgraded for Python 3.
And he couldn't use Suds because even though it was not being maintained, it still owned it on PyPI.
Yeah, that's a tough one though.
And even if something's not updated, it's hard to know if people are using it or not.
Some of the stuff that was addressed in this proposal is things like checking out other uses of the word like on CPAN or npm or GitHub.
And so like if it's a very popular GitHub repository, maybe we should let it go through or something.
I actually wanted to put in a package name to expect in.
It was already used by somebody else.
But then I went out and looked and it was legitimate.
There's a lot of other tools that were more like that tool than what I wanted to use.
So it would have been bad for me to try to throw a hissy fit and grab that.
Yeah, it's interesting.
Yeah, it's cool that they're proposing a way to look at prior art and existing things.
I'm actually a little surprised it didn't already exist, but I'm glad it's happening.
Yep.
It's definitely a good thing.
I mean, we're about to come up on 100,000 PyPI packages.
Like the naming is starting to become something scarish, right?
All right.
So did you ever read William Gibson books like Neuromancer and some of these crazy futuristic cyberpunk type books?
No.
Yeah.
I kind of feel like we're living in this sort of sci-fi future in a weird way.
There was the craziest article that I saw I've seen in a while come out.
And I'll just read you the title.
Hackers downloaded U.S. government climate data and stored it on European servers as Trump was being inaugurated.
So here's the deal.
I'm going to try to make this as politically neutral as possible.
I just want to talk about the data side of this in a pretty interesting way.
Like who owns and controls data, right?
Does the president, does the country, does the world own this data?
Like the U.S. has an incredible amount of data about the world at the Environmental Protection Agency, at NASA, Department of Energy, and so on.
And there had been some rumors that when Trump took office, he was going to reduce, cut back, or even fire some people that worked on climate change.
People knew this a few months before, maybe a month before there, where people are looking around saying, you know, these websites, like the EPA, for example, has a bunch of data on it.
And they're like, what if that gets deleted?
There was actually a meeting of 60 programmers and scientists at the Department of Information Studies at UCLA.
And their goal was to find as many of these websites with government data on it and start to scrape it and download it and exfiltrate it from the country.
Isn't that crazy?
So what they did is they all got together and they were working like 22 hours a day for like the four or five days leading up to the inauguration.
And they were just downloading.
They had like a huge spreadsheet of hundreds of sites where they'd go in and they'd try to get the data and they would pull it off.
So examples include like web pages dedicated to Department of Energy's solar project initiatives or the Energy Information Administration stuff about fossil fuels compared to renewable energy and fuel cell research and those kinds of things.
And it turns out there's actually these sort of what they call volunteer data rescue events in Toronto and Philly and Chicago and Indianapolis and Michigan over the last weeks trying to scrape hundreds of thousands of pages off the Internet.
So you might say like people are being crazy.
Come on.
But it turned out exactly at noon has Trump was sworn in and UCLA was actively working that that group was working.
All the climate change related data on Whitehouse.gov disappeared.
But they had gotten a lot of it.
Okay.
And so there's this company called Page Freezer and I think they're a Canadian company and they basically create snapshots of web pages a little bit like Internet Archive or the Wayback Machine.
And it's actually a commercial service.
So these guys start to participate and they're storing all of this data somewhere in Europe.
The reason for storing it in Europe because there's no like there'd be not a way for the government to force it to shut down or something.
Yeah, exactly.
Exactly.
So I just I thought that was like that's the craziest headline around programming I've seen this week.
Yeah.
And I wanted to include that.
Now, I do know that there's there's so again to try to not be too political on this, but there's aren't there legacy versions of the old versions of the Whitehouse website?
There there.
There.
I mean, probably on like on the Wayback Machine and stuff, but I it could not it could be that it doesn't necessarily store the data linked in it.
You know what I mean?
Like like the 100 meg CSV file or whatever.
And that was the kind of stuff they were actually going after.
Hmm.
Well, it's good.
Good to have it saved.
It's it's good to have it saved.
So we'll we'll see where it goes.
But I just thought this was a really interesting and I'm sure Python played a pretty key role in a lot of screen scraping initiatives with beautiful soup and scrapey and things like that.
Yeah.
All right.
So I think we're going to leave it there for this week.
That's a lot of a lot of cool news for everyone, Brian.
Definitely cool.
All right.
Well, thanks for talking to me this week.
You bet.
Thanks for sharing the stories and I'll catch you next time.
Thank you for listening to Python Bytes.
Follow the show on Twitter via at Python Bytes.
That's Python Bytes as in B-Y-T-E-S.
And get the full show notes at Python Bytes dot FM.
If you have a news item you want featured, just visit Python Bytes dot FM and send it our way.
We're always on the lookout for sharing something cool.
On behalf of myself and Brian Okken, this is Michael Kennedy.
Thank you for listening and sharing this podcast with your friends and colleagues.