WEBVTT

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

00:00:04.440 --> 00:00:11.600
your earbuds. This is episode 153, recorded October 16, 2019. I'm Brian Okken. And I'm

00:00:11.600 --> 00:00:15.720
Michael Kennedy. This week's episode is sponsored by DigitalOcean. We'll talk more about them later.

00:00:15.720 --> 00:00:20.940
But first, Michael, could you extend my knowledge a bit? Yeah, by like extending

00:00:20.940 --> 00:00:26.360
the entire Python ecosystem, maybe? Yeah. Yeah. So there's actually a cool real Python

00:00:26.360 --> 00:00:33.160
article called Building a Python C Extension Module. So Brian, you know how to write C code,

00:00:33.160 --> 00:00:37.700
right? Yes. Or at least that's the theory. I used to know how. Yeah. I have this really awesome

00:00:37.700 --> 00:00:43.360
former self of mine that was super good at C++. Yeah. I kind of remember that person that I was.

00:00:43.360 --> 00:00:49.000
I used to be able to write a lot of C. That was my main job is to write C and 3D stuff and OpenGL and

00:00:49.000 --> 00:00:55.220
things like that, right? So it's definitely the main way to extend Python these days. And there's

00:00:55.220 --> 00:01:00.220
other options like there's some cool Rust options and whatnot. But, you know, primarily people know

00:01:00.220 --> 00:01:04.640
C. It runs everywhere, has like light runtime requirements. You're already running CPython

00:01:04.640 --> 00:01:10.540
probably, so you already have those requirements met, right? So extending your code with some kind

00:01:10.540 --> 00:01:17.340
of C extension gives you a couple of options. One is clearly performance. I love to talk about

00:01:17.340 --> 00:01:21.740
Python performance because one, it always surprises me. And two, like people are usually wrong about it.

00:01:21.880 --> 00:01:28.160
They say Python is slow. Like I was just reading something on Quora about why, like compare C#

00:01:28.160 --> 00:01:33.260
to Python. And somebody says, well, you can't even compare them. C# is 50 times faster.

00:01:33.260 --> 00:01:37.960
Well, that's true for certain operations, unless maybe part of that it's done in C and then probably

00:01:37.960 --> 00:01:41.780
Python is faster because like now it's down in like NumPy and doing it in C, which is actually

00:01:41.780 --> 00:01:45.480
faster, right? There's just, it gets really interesting. So one reason you might care about

00:01:45.480 --> 00:01:49.280
writing a C module is just for performance. And I think that's what most people think of,

00:01:49.280 --> 00:01:57.100
but there's also like low level operating system APIs or other C APIs, like some library you can get,

00:01:57.100 --> 00:02:03.580
you might want to use that happens to be written in C and doesn't have a Python way to talk to it,

00:02:03.580 --> 00:02:08.340
right? Yeah. There's lots of stuff with DLLs that are available with C header files,

00:02:08.340 --> 00:02:13.160
but you don't have a Python binding. Exactly. And I bet you have a lot of experience with that,

00:02:13.160 --> 00:02:18.600
with all of your devices and stuff like that. Yep. Yeah. Okay. So those are the two main reasons I can

00:02:18.600 --> 00:02:23.040
think of writing C extensions. I mean, obviously throw some Cython at it if it's a performance thing

00:02:23.040 --> 00:02:28.480
to give it a try, but there's a cool tutorial on real Python and it talks about how you can,

00:02:28.480 --> 00:02:32.140
you know, like things you'll be able to do is like import C functions within Python,

00:02:32.140 --> 00:02:38.700
pass arguments from Python to C, raise correct exceptions in your C code. So they surface bubble

00:02:38.700 --> 00:02:44.400
back into your Python code as a proper, like a value error type exception or something like that,

00:02:44.400 --> 00:02:48.540
all sorts of cool things and even how to test and distribute it. So let me just sort of talk

00:02:48.540 --> 00:02:52.460
through the process and then people really care. They can go read the big long article, right? So

00:02:52.460 --> 00:02:59.300
if you want to basically get access to some C functionality, or if you want to just like write

00:02:59.300 --> 00:03:04.200
your implementation and see for some degree, first thing you got to do is go and figure out, let's

00:03:04.200 --> 00:03:09.700
suppose you want to call like a, some C function, right? So the article uses F puts, which puts a string

00:03:10.260 --> 00:03:16.400
into a file pointer, right? Like basically writes a string to a file in C. So you have to write a

00:03:16.400 --> 00:03:23.340
function, which is pretty interesting because it returns, you have to start talking in the CPython

00:03:23.340 --> 00:03:29.180
language, not Python, right? So everything that gets passed around is a Python object pointer or the

00:03:29.180 --> 00:03:36.640
return value is like a py object pointer, right? So you pass these things around and first of all,

00:03:36.640 --> 00:03:41.900
you declare like whatever inbound arguments you're really expecting and you get basically passed a

00:03:41.900 --> 00:03:45.800
single pointer that is the arguments to your function, but that's really a tuple. So there's

00:03:45.800 --> 00:03:51.860
a pyarg parse tuple, give you the arguments, a format thing, and then you give it the address of the

00:03:51.860 --> 00:03:56.360
pointers. You pass them by reference basically. And then you just do your CPython code. In this case,

00:03:56.360 --> 00:04:02.440
the function that they're wrapping, F puts, returns the number of bytes copied when it does that.

00:04:02.560 --> 00:04:07.600
And so this function wants to return the bytes copied, but you can't just return an integer or a

00:04:07.600 --> 00:04:12.920
long. No, no, no, because everything in Python is a py object at the C level, py object star,

00:04:12.920 --> 00:04:20.600
even numbers. So you have to convert from a long to a py long from long, which is a function that you

00:04:20.600 --> 00:04:23.260
get from the Python.hc header file. Okay.

00:04:23.400 --> 00:04:28.680
It's actually pretty simple. There's like some weird non-obvious like structure at the beginning

00:04:28.680 --> 00:04:32.680
of the function. So it can be called by Python and the return value is weird, but everything else in

00:04:32.680 --> 00:04:37.880
the middle is like straight C. So you don't really have to think about what's going on. The GIL will

00:04:37.880 --> 00:04:40.460
protect you from like race conditions, all that kind of stuff.

00:04:40.460 --> 00:04:44.580
Yeah. And actually one of the things I love about this article is that it's using a fairly simple

00:04:44.580 --> 00:04:50.280
example so that you're not distracted by the example. It's just the boilerplate junk that you got to

00:04:50.280 --> 00:04:53.640
learn about. Yeah, absolutely. Which is, you know, the, probably the thing you don't know,

00:04:53.640 --> 00:04:57.760
even if you know C, right? Yeah. And it says also, there's a few other things that are necessary if

00:04:57.760 --> 00:05:02.620
you actually want to use this code and not just write it and compile it and see, because you have

00:05:02.620 --> 00:05:09.000
to write a definition for your module in C and the methods that it contains. So there's a few C

00:05:09.000 --> 00:05:13.500
functions that you call there, and then you have to build it for Python, which you basically create a

00:05:13.500 --> 00:05:20.100
setup.py file and use just utils and it will compile and create the right base library and

00:05:20.100 --> 00:05:23.980
install it for you. Okay. Pretty cool, huh? Pretty cool. Yeah. One of the issues with this is,

00:05:23.980 --> 00:05:31.720
is that people that have to, a lot of times when you need to do this, it isn't a hardcore C compiler

00:05:31.720 --> 00:05:38.040
person or a hardcore Python, CPython person that needs to do this. It's just your casual user that

00:05:38.040 --> 00:05:42.980
happens to have a use case that they need to connect Python to C. And so this is great.

00:05:42.980 --> 00:05:46.740
Yeah. And it's super approachable. And like you said, the examples are pretty straightforward.

00:05:47.380 --> 00:05:52.080
Obviously you're writing C, which puts you in a different category of hard, right? I mean,

00:05:52.080 --> 00:05:56.900
free malloc, pointers, pointers by reference, like all that kind of stuff that you learn when you learn

00:05:56.900 --> 00:06:02.000
C, but that's the world you got to live in when you go down and you don't, you know, take the blue

00:06:02.000 --> 00:06:02.940
pill or whatever it is.

00:06:05.620 --> 00:06:07.160
Is the blue one the good one? I think.

00:06:07.160 --> 00:06:11.320
No, I always forget. I know that there's a pill that's good and there's a pill that's like bad.

00:06:11.320 --> 00:06:15.320
It keeps the facade, but yeah, probably the, I don't know.

00:06:15.320 --> 00:06:17.080
Do you know what else is good?

00:06:17.080 --> 00:06:17.780
Documentation.

00:06:17.780 --> 00:06:18.500
Documentation.

00:06:18.500 --> 00:06:21.300
No, Python 3.8. Python 3.8 is good.

00:06:21.300 --> 00:06:23.400
But also Python 3.8.

00:06:23.400 --> 00:06:24.420
For even the URL, sorry.

00:06:24.420 --> 00:06:33.120
Python 3.8 dropped just this week. So it is no longer beta. It is final. And you can download it

00:06:33.120 --> 00:06:38.680
from the front page. The default is Python 3.8.0 now when you download it. So yay.

00:06:38.680 --> 00:06:39.620
Yes, that's awesome.

00:06:39.620 --> 00:06:44.560
We've talked about a lot of stuff. We've, on this podcast, we've talked about things going into 3.8.

00:06:44.560 --> 00:06:49.540
Like the walrus operator, of course, that's come up a lot of times. Those are assignment expressions,

00:06:49.540 --> 00:06:55.920
positional only parameters, and fstrings. Fstrings have the little equal signs so you can debug with

00:06:55.920 --> 00:06:56.320
them easier.

00:06:56.320 --> 00:07:00.360
Right. Fstrings have been here since 3.6, but now they have this like self-documenting

00:07:00.360 --> 00:07:02.000
short print statement thing, right?

00:07:02.220 --> 00:07:07.020
Yeah, and it takes longer to describe than to show, and it's cool. What I wanted to highlight

00:07:07.020 --> 00:07:14.340
is the what's new in Python 3.8 document that came out from, that's at docs.python.org. And it's a

00:07:14.340 --> 00:07:19.260
really great summary of all the stuff that's in 3.8. It does have all of those new things,

00:07:19.260 --> 00:07:25.520
that all those big hitters, but it also has some stuff that I was surprised by that I hadn't heard

00:07:25.520 --> 00:07:31.560
of before. One of them is, we've talked about a lot of async stuff, and now you can type

00:07:31.560 --> 00:07:37.460
python-m async.io, and it launches a async native REPL.

00:07:37.460 --> 00:07:43.300
That is so cool, and I had no idea that that was there. I guess it would have been a pain in the

00:07:43.300 --> 00:07:47.720
butt before to like work with async stuff over there in the REPL, right? So...

00:07:47.720 --> 00:07:51.920
Yeah, I guess. Now you can just, because I often drop into the REPL to try something out,

00:07:51.920 --> 00:07:54.660
now you can try out async stuff in there. So that's cool.

00:07:54.660 --> 00:07:55.500
Yeah, that's super cool.

00:07:55.680 --> 00:08:00.100
A couple other things that'll just help you while writing Python. A couple new warnings and

00:08:00.100 --> 00:08:05.980
messages for things that you might do wrong. So when you're not supposed to compare, use is or is

00:08:05.980 --> 00:08:13.540
not to compare non-objects, like strings or integers or something. It's just like, if x is 3, don't do

00:08:13.540 --> 00:08:18.640
that. But apparently the warning wasn't very good, and so now the warning is better. It tells you to use

00:08:18.640 --> 00:08:24.120
double equal or not equal. So that's cool. And then one of the things that I often get, because I do a

00:08:24.120 --> 00:08:31.920
lot of parameterized testing, is if you've got a list with tuples inside, or, you know, basically a list of

00:08:31.920 --> 00:08:37.840
lists or a tuple of tuples, and you forget the commas between some of the things, because maybe they're on a

00:08:37.840 --> 00:08:43.280
new line or something. The warning was weird before, but now it is a more helpful message.

00:08:43.280 --> 00:08:44.940
So I love things like that.

00:08:44.940 --> 00:08:49.620
Yeah, you know, it drives me crazy if those are strings. Like if you're creating like a JSON document

00:08:49.620 --> 00:08:54.240
or something like that, or a multi-line, like a list of strings, you forget a comma, it just concatenates

00:08:54.240 --> 00:08:58.360
them, even though they're on separate lines. I'm like, oh, really? That's the default behavior?

00:08:58.360 --> 00:09:00.720
But I understand where it comes from, but it drives me crazy.

00:09:00.720 --> 00:09:01.980
That probably still there.

00:09:01.980 --> 00:09:05.420
Yeah, yeah. I don't see how you would fix that without changing what that means.

00:09:05.420 --> 00:09:10.180
Yeah. This one, it took me a while to get my head around, but I didn't know that this was an issue

00:09:10.180 --> 00:09:17.460
before. Iterable unpacking, so if you like packed a bunch of stuff into a variable, you can unpack it

00:09:17.460 --> 00:09:25.660
with star variable name. You can't return that in a return statement, or you couldn't before out of a

00:09:25.660 --> 00:09:30.600
tuple. So you had to put parentheses around it before you return it. But now that's gone away,

00:09:30.600 --> 00:09:31.960
you can just return it.

00:09:31.960 --> 00:09:35.220
Yeah, there's a lot of good stuff in here, actually. And you just did an episode on it,

00:09:35.220 --> 00:09:35.480
didn't you?

00:09:35.480 --> 00:09:41.880
Yep. Episode 91 of Test and Code. I just read through the entire article, and it's still just 20 minutes.

00:09:41.880 --> 00:09:45.520
I didn't read through everything, but it highlighted all the stuff that I thought was cool.

00:09:45.520 --> 00:09:46.060
Super.

00:09:46.060 --> 00:09:48.780
You know, something else that's cool is DigitalOcean.

00:09:48.780 --> 00:09:49.660
I love DigitalOcean.

00:09:49.800 --> 00:09:55.140
This episode is sponsored by DigitalOcean, and Python Bytes infrastructure runs on DigitalOcean,

00:09:55.140 --> 00:10:00.040
thanks to Michael putting that all together. And it's quite solid, and we're super happy with it.

00:10:00.040 --> 00:10:05.360
But did you know that not all web applications and services have the same memory and CPU demands?

00:10:05.360 --> 00:10:06.400
It's shocking, isn't it?

00:10:06.400 --> 00:10:12.380
Shocking. Anyway, so DigitalOcean has embraced this diversity in their droplet structure, which is cool,

00:10:12.480 --> 00:10:19.580
with the ratio of memory to CPU powers in droplets. The general purpose droplets have a ratio of four

00:10:19.580 --> 00:10:25.340
gigabytes of memory per CPU, and you can scale those up. They added, not too long, a couple years ago,

00:10:25.340 --> 00:10:30.360
I think, CPU optimized ones. So they doubled the number of CPUs per the amount of memory,

00:10:30.820 --> 00:10:36.700
and that's great for CPU bound tasks. But there's some applications like high performance databases or

00:10:36.700 --> 00:10:43.200
in-memory caches or data processing of large sets that a lot of memory might be a really great thing.

00:10:43.200 --> 00:10:49.760
So there's now a memory optimized droplet that reverses that structure and makes it like eight

00:10:49.760 --> 00:10:52.400
gigabytes of memory per CPU. It's pretty cool.

00:10:52.400 --> 00:10:53.040
Yeah, very cool.

00:10:53.040 --> 00:10:56.340
Yeah. Use the right kind of droplet for the right service that you're using,

00:10:56.440 --> 00:11:02.740
and try it out at pythonbytes.fm/digitalocean, and they'll give you a $50 credit for new users.

00:11:02.740 --> 00:11:08.500
You and I have mentioned that folks should put legacy Python where it belongs in the past.

00:11:08.500 --> 00:11:14.160
Last time we spoke about 35 million lines of Python code at JPMorgan Chase and their

00:11:14.160 --> 00:11:21.100
journey to work on that. And that's all interesting. But we just recently got this announcement from

00:11:21.100 --> 00:11:25.720
the UK's NCSC, the National Cyber Security Center.

00:11:25.720 --> 00:11:26.320
Wow.

00:11:26.320 --> 00:11:32.160
Yeah. And they're warning developers of the risk of sticking with Python 2, particularly library writers.

00:11:32.160 --> 00:11:32.520
Okay.

00:11:32.520 --> 00:11:38.140
That's interesting, right? That they actually go so far as to call that out as a thing.

00:11:38.140 --> 00:11:44.120
So they say, look, this could be like, basically, the companies that continue to use Python 2 past its end

00:11:44.120 --> 00:11:52.000
of life could be like tempting or setting the environment for another WannaCry or even an Equifax incident.

00:11:52.000 --> 00:12:00.040
So Equifax was a horrible data breach. Basically, it's one of these companies that gathers up so much private data.

00:12:00.040 --> 00:12:04.060
Like, they know stuff about my financial past that I have forgotten and don't even know, right?

00:12:04.060 --> 00:12:08.480
They go, did you know you had this account in California? Like, I did? Oh, okay. Well, I guess I do.

00:12:08.720 --> 00:12:14.040
Right. They know all of that. And it was broken into. Why? Because there was a vulnerability in

00:12:14.040 --> 00:12:19.660
Apache Struts, which is an open source framework. People at Struts are like, guys, this is super bad.

00:12:19.660 --> 00:12:25.300
You just have to send like a special ACRP request to the server and it's owned, right? Well, the folks at

00:12:25.300 --> 00:12:30.700
Equifax got that message, but they didn't really want to get around to like upgrading it to the new

00:12:30.700 --> 00:12:34.640
version because, hey, it's kind of hard to upgrade this thing. It's like a new version, which probably was

00:12:34.640 --> 00:12:39.700
old and was slightly incompatible or something. Anyway, that's where Equifax came from is running

00:12:39.700 --> 00:12:44.520
an old version of one of these frameworks, not Java itself, but like the web framework on top of it.

00:12:44.520 --> 00:12:51.700
Anyway, there's some cool quotes in here. They say, if you're still using Python 2x, it's time to put

00:12:51.700 --> 00:12:56.840
your code to Python 3. If you continue to use unsupported modules, you are risking the security of

00:12:56.840 --> 00:13:02.360
your organization and data as vulnerabilities will sooner or later appear, which nobody's fixing.

00:13:02.640 --> 00:13:07.000
Okay, that's one. One interesting quote. Another one is, if you maintain a library that other

00:13:07.000 --> 00:13:12.540
developers depend upon, you may be preventing them from updating to 3. And by holding back other

00:13:12.540 --> 00:13:17.420
developers, you're indirectly and likely unintentionally increasing the security risk of

00:13:17.420 --> 00:13:19.460
basically all the computers in the world.

00:13:19.460 --> 00:13:19.820
Yeah.

00:13:19.820 --> 00:13:26.640
Yeah. So, I mean, we've said this before, right? You and I have said this, but if the NSA or the

00:13:26.640 --> 00:13:33.840
NCSC, they come out and publicly call out Python 2 like this, well, that maybe carries more weight

00:13:33.840 --> 00:13:36.880
than Python bytes. Not that we don't carry some weight, I'm sure.

00:13:36.880 --> 00:13:43.000
Yeah. It actually makes me think though. Let's say you have a library that now works on both Python

00:13:43.000 --> 00:13:49.400
2 and 3 and somebody else is depending on it. And they're also depending on another library that is

00:13:49.400 --> 00:13:52.440
2 only. They're going to stick with 2. Yeah.

00:13:52.440 --> 00:13:58.360
But if, like, for instance, you could push them if you, like, stopped supporting Python 3 or Python 2.

00:13:58.360 --> 00:14:04.920
It's a good question. Like, in six months, do we have a obligation to actually cut Python 2 out

00:14:04.920 --> 00:14:08.060
of our libraries? I mean, I don't have any libraries people care about, but...

00:14:08.060 --> 00:14:12.080
Maybe? To force people to upgrade? Maybe you could do some help?

00:14:12.080 --> 00:14:16.540
Yeah. Most of these changes have been more self-serving or self-centered, right? Like,

00:14:16.540 --> 00:14:21.580
NumPy and Django, all those folks dropped Python 2, not because they're like, we're going to fix the

00:14:21.580 --> 00:14:25.340
world, but, like, we don't want to maintain this stuff. We want to just move forward and use the

00:14:25.340 --> 00:14:26.860
cool features, and we can't right now.

00:14:26.860 --> 00:14:27.140
Yeah.

00:14:27.140 --> 00:14:27.920
Yeah. Pretty cool.

00:14:27.920 --> 00:14:33.200
I guess one other kind of interesting thing to call out from this report, article, whatever you call it,

00:14:33.200 --> 00:14:39.800
is that they said that Python's popularity makes updating the code imperative, which I thought was

00:14:39.800 --> 00:14:43.620
pretty interesting. It's like, Python is so successful. It's so broadly deployed. Like,

00:14:43.620 --> 00:14:48.680
we can't just ignore this. It's not like Adobe Flash. It's now running an old version. We should

00:14:48.680 --> 00:14:53.660
deal with it, right? It's like, this is one of the really important parts of the computer infrastructure

00:14:53.660 --> 00:14:58.460
that they called out. So, yeah, I mean, there's got to be other places where we get this kind of news,

00:14:58.460 --> 00:14:58.680
right?

00:14:58.880 --> 00:15:07.300
So, I got a notification from a guy called Sebastian Steins, and he put up a, it's basically

00:15:07.300 --> 00:15:14.820
a Hacker News lookalike site called news.python.sc. I don't know what sc stands for. Yeah, it looks a

00:15:14.820 --> 00:15:21.100
lot like Hacker News, but it's just got Python stuff on it, and it's pretty neat. So, I thought, oh,

00:15:21.100 --> 00:15:25.040
that's cool. We should talk about it. But one of the neat things about it is he put it all together

00:15:25.340 --> 00:15:32.900
relatively quickly in like a week or so, and it's built on Django, and all of it's open source. So,

00:15:32.900 --> 00:15:38.580
you can take it and look at how it's done and everything. Plus, it's up, and it's live, and you

00:15:38.580 --> 00:15:43.280
can post stuff. It's neat. And I thought, yeah, maybe we'll cover this. And then while I was thinking

00:15:43.280 --> 00:15:49.480
about covering it, we got like two or three other people tell us about this new news site. So,

00:15:49.620 --> 00:15:52.380
I think people are using it. It's kind of fun. What do you think?

00:15:52.380 --> 00:15:57.980
I like it. It definitely looks like Hacker News, but more Pythonic colors. And, you know,

00:15:57.980 --> 00:16:01.860
looking through this, these are all legitimately interesting things here. I'm like, yeah, oh,

00:16:01.860 --> 00:16:06.100
yeah. Well, I read about that. That was cool. And, oh, I didn't know about that, but interesting. Yeah,

00:16:06.100 --> 00:16:07.100
I feel like this is great.

00:16:07.100 --> 00:16:11.320
And even if it doesn't take off, I think it's cool to have an example of a working model

00:16:11.320 --> 00:16:18.020
of simple with like people being able to vote things up and down. And that's kind of a neat,

00:16:18.020 --> 00:16:24.220
kind of a neat model to say, there's a working website, a working user model. How can I emulate

00:16:24.220 --> 00:16:25.300
that in Python?

00:16:25.300 --> 00:16:29.660
Yeah, it's super cool. I'm definitely going to start checking it out for, as one of my news sources,

00:16:29.660 --> 00:16:31.840
in addition to Redis and Twitter and other places.

00:16:31.840 --> 00:16:33.460
Yeah, like we don't have enough to do.

00:16:33.460 --> 00:16:35.700
I know. Now you just gave me work, man. Come on, it's homework.

00:16:36.300 --> 00:16:42.560
So you've heard that most people are moving to the cloud and data science is moving to the cloud.

00:16:42.560 --> 00:16:47.620
There's all sorts of interesting stuff happening up there. But, you know, a lot of times this type

00:16:47.620 --> 00:16:51.760
of work, especially training like machine learning models and stuff is super, super intensive.

00:16:51.760 --> 00:16:58.260
So if you've got like a laptop, some of the GPU processing and other really interesting things

00:16:58.260 --> 00:17:03.940
are inaccessible to you. Like, for example, my MacBook is super killer, but it's got, you know,

00:17:03.940 --> 00:17:09.700
like 12 cores if you count the hyper threads and it's got 32 gigs of RAM, but it has a ATI, not a

00:17:09.700 --> 00:17:13.060
NVIDIA graphics card. So you can't use CUDA on it, for example, right?

00:17:13.060 --> 00:17:20.620
So what do I do? I go to the cloud. Well, if you're really into deep learning and you really want to do

00:17:20.620 --> 00:17:25.840
like data science with GPUs, there's this place called Lambda, this company called Lambda,

00:17:25.840 --> 00:17:31.920
that is creating these deep learning workstation servers and laptops. Have you heard about this?

00:17:31.920 --> 00:17:36.000
Huh? No. Just to be clear, this is like a super commercial product, right? These are like

00:17:36.000 --> 00:17:40.720
servers that you buy and we have no, this is not like a product placement. I just ran across this

00:17:40.720 --> 00:17:45.860
and thought, dang, this is interesting. So I thought I would just talk about it. So they're selling GPU

00:17:45.860 --> 00:17:53.520
accelerated TensorFlow, PyTorch, Keras, and other types of pre-configured machines. Just, they say,

00:17:53.520 --> 00:17:58.920
just plug in and start training. You're good to go. And they talk about how you can save a bunch of

00:17:58.920 --> 00:18:02.900
money, right? You don't run on the cloud. The cloud can save you money for short work,

00:18:02.900 --> 00:18:07.680
but if you got to do it over a long time, it can get expensive. So they offer a TensorBook,

00:18:07.680 --> 00:18:15.740
which is a GPU training available laptop, capable laptop for $2,900. That's a pricey laptop, right?

00:18:15.740 --> 00:18:16.100
Yeah.

00:18:16.240 --> 00:18:22.900
Actually, it's less expensive than my MacBook, but still. But if you were going to do GPU stuff,

00:18:22.900 --> 00:18:28.080
you know, this is a really cool option to be able to do it on the go or be mobile. Then they also have

00:18:28.080 --> 00:18:35.140
a workstation, which is called Lambda Quad, which has four GPUs in it. And this one is $21,000.

00:18:35.140 --> 00:18:35.960
Okay.

00:18:36.160 --> 00:18:42.620
Okay. That's a lot. But if you go and grab a second tier GPU enabled EC2 instance,

00:18:42.620 --> 00:18:51.780
specifically a P3-8X large, that's over $12 an hour, which comes out to close to $9,000 a month

00:18:51.780 --> 00:18:55.920
in cloud bills. If you were to run it all the time, I mean, obviously probably not all the time,

00:18:55.920 --> 00:19:01.840
but so, you know, like $21,000 is a lot, but a $9,000 monthly bill for AWS is also a lot.

00:19:01.840 --> 00:19:04.960
Yeah. It's something to pay attention to is just as your bill starts getting bigger,

00:19:04.960 --> 00:19:08.080
maybe a dedicated hardware makes sense.

00:19:08.080 --> 00:19:11.740
Anytime I run across something like this, if it were Alien, or if it were gaming laptops,

00:19:11.740 --> 00:19:16.280
or like the Apple MacBook Pro or whatever, it's like, all right, well, what if you're all in?

00:19:16.280 --> 00:19:21.380
What if you turn all the knobs to 11? What, like, what could you get? So they have this thing called

00:19:21.380 --> 00:19:27.720
the Lambda Hyperplane, which has eight Tesla V100 GPUs. And it starts at, it's not the final price.

00:19:27.720 --> 00:19:29.380
It starts at $114,000.

00:19:29.380 --> 00:19:32.300
Nice. That's without the pinstriping.

00:19:32.300 --> 00:19:36.940
Yeah, exactly. That's not even the leather bound keyboard or whatever. I don't know.

00:19:36.940 --> 00:19:44.720
Anyway, if you're into deep learning and you need GPUs for computational stuff, data science and whatnot,

00:19:44.720 --> 00:19:46.060
this is actually pretty cool.

00:19:46.060 --> 00:19:50.160
Yeah. Also, I'm sure there's applications where you really don't want to use the cloud. You want

00:19:50.160 --> 00:19:55.700
to use in-house computers and not go out, or the connection is bad. You're sticking some data in

00:19:55.700 --> 00:19:58.800
the middle of nowhere or something, and you can't get to the internet.

00:19:58.800 --> 00:20:02.980
Right, right. If you've got terabytes of data, like, that takes days to upload. So,

00:20:02.980 --> 00:20:05.180
maybe it's better to just run it locally. Who knows?

00:20:05.180 --> 00:20:05.380
Yep.

00:20:05.380 --> 00:20:06.480
Black has been a big hit.

00:20:06.480 --> 00:20:08.360
Yeah, I like Black.

00:20:08.360 --> 00:20:09.220
Yeah, for sure.

00:20:09.220 --> 00:20:10.560
A lot of people do.

00:20:10.560 --> 00:20:10.920
Oh, yeah.

00:20:10.920 --> 00:20:15.840
One of the things, so I ran across an article. It's not a new article, but it's all still relevant.

00:20:15.840 --> 00:20:21.560
It's auto-formatters in Python. And big shock, Black's in there. But one of the things I

00:20:21.560 --> 00:20:27.700
liked about it is they spent a little bit of time talking about why you want to use Black

00:20:27.700 --> 00:20:34.500
or something else. And I'm finding this more and more as a team lead that just, it's not great to

00:20:34.500 --> 00:20:39.720
have, like, if you're doing code reviews, you don't want to have, like, style be part of the code review.

00:20:39.720 --> 00:20:40.040
Yeah.

00:20:40.220 --> 00:20:46.420
It's way better to have a tool just dictate the style. And so, people can argue with the tool

00:20:46.420 --> 00:20:47.640
instead of arguing with each other.

00:20:47.640 --> 00:20:51.420
Yeah. It's like, if the code review, the people there, I'm sure they feel like, well, I have to

00:20:51.420 --> 00:20:57.120
make a constructive or critical comment about something. It shouldn't be, why are you indenting

00:20:57.120 --> 00:21:01.660
like that? Or why is there not a space by those commas? Like, that's the stuff machines can agree

00:21:01.660 --> 00:21:06.060
upon and just do for us, right? Like, have architectural or algorithmic conversations, right?

00:21:06.060 --> 00:21:10.760
Yeah. You should be using three double quotes there instead of one. So, get off the style

00:21:10.760 --> 00:21:16.540
police and use an auto formatter instead. I love Black. A lot of people do. But there's reasons

00:21:16.540 --> 00:21:24.260
for some people, like an established code base or other predefined style guide, that maybe it's too

00:21:24.260 --> 00:21:29.700
much. It does do things that sometimes I don't like it to do. So, there's a couple other options.

00:21:30.100 --> 00:21:38.540
And this article talks about auto PEP 8 and YAPF. Now, auto PEP 8 is essentially just, it just does

00:21:38.540 --> 00:21:45.020
PEP 8. It's, or uses PyCodeStyle, the utility, to detect PEP 8 violations and just change the code.

00:21:45.020 --> 00:21:51.720
You can do both with it. It does less than Black, but it doesn't do much more. So, if that, if really

00:21:51.720 --> 00:21:57.780
you're just trying to stick to PEP 8, maybe that's, yeah, that'd be better to use. And the other end of

00:21:57.780 --> 00:22:04.000
it is YAPF, which is a tool out of, and I don't know how to say that, YAPF? It's probably yet another

00:22:04.000 --> 00:22:09.120
Python formatter. Yeah, it probably is. It's a Google tool. I think it's Google. I think it's good if you

00:22:09.120 --> 00:22:14.140
want, it's got a lot of knobs and dials, a lot of customization. So, if Black doesn't have enough

00:22:14.140 --> 00:22:20.480
controls for you and you really want to tweak it to be your personal company's code style, this might be

00:22:20.480 --> 00:22:27.100
great for you. In the documentation, it says it takes away some of the drudgery in maintaining your code

00:22:27.100 --> 00:22:33.980
code. And what, just ultimate goal is to code, is that it produces as good a code as that a programmer

00:22:33.980 --> 00:22:37.720
would write if they were following the style guide. That sounds pretty good, honestly. One of the

00:22:37.720 --> 00:22:44.800
interesting things, I was researching this story, is I didn't know this about Black. After it's changed

00:22:44.800 --> 00:22:52.920
your code, it does a check to see if the reformatted code still produces a valid abstract syntax tree

00:22:52.920 --> 00:22:57.120
that is equivalent to the original. That's pretty cool. I didn't know it did that.

00:22:57.120 --> 00:22:59.720
Yeah, that is cool. So, run it through the Python

00:22:59.720 --> 00:23:01.900
parser and turn it into

00:23:01.900 --> 00:23:05.380
bytecode and then just see if the essence is the same, which

00:23:05.380 --> 00:23:07.680
yeah, I mean, because you don't actually want to change

00:23:07.680 --> 00:23:10.860
the meaning of the way the code actually gets interpreted. It's just formatting, right?

00:23:10.860 --> 00:23:13.460
So, the meaning change is like, well, that might be a problem.

00:23:13.460 --> 00:23:15.720
Yeah. The other thing I wanted to highlight this

00:23:15.720 --> 00:23:21.200
article for is it took a few code examples and just did the, what does Black change it into? And what does

00:23:21.200 --> 00:23:24.540
Yapf change it into? And what does Autopepate change it into?

00:23:24.540 --> 00:23:25.920
Oh, that's sweet. I like that.

00:23:25.920 --> 00:23:26.260
Yeah.

00:23:26.260 --> 00:23:30.680
Very, very cool. All right. Well, that's all of our main items. You got anything else you want to throw out there while we're here?

00:23:30.680 --> 00:23:32.260
No. You?

00:23:32.260 --> 00:23:56.640
Yes. A couple things. I'm getting excited for PyCon US. It's earlier this year, in April at some point, I'm guessing. But the announcement I want to make is that the applications for financial aid are open and they'll be accepting them through January 31st, 2020. So, 30 days into a world with only Python 3. The Python Software Foundation and PyLadies are making this financial aid possible and check it out.

00:23:56.640 --> 00:24:13.080
Yeah. So, like PSF is contributing $130,000 towards that. And yeah, it's pretty good. So, if you're thinking, hey, I would really love to go to PyCon and make some connections, kind of new to this world, use some networking and learn more about it, but I just can't justify the expense or afford it, maybe do that.

00:24:13.080 --> 00:24:26.620
Yeah. Nice. Indeed. Indeed. And I'm working on some new courses. I got one that's all done and recorded, just getting edited. Another one, I spent like six contiguous hours recording videos yesterday. That doesn't sound like a lot of time if you haven't done it, but six straight.

00:24:26.620 --> 00:24:31.180
Eight hours recording, that's a lot. So, I'm really, really excited about what's coming out. We'll share more with it when I can.

00:24:31.180 --> 00:24:32.060
Very exciting.

00:24:32.060 --> 00:24:36.940
Oh, yeah. Now, sometimes we have really short jokes. I see that you have one.

00:24:36.940 --> 00:24:47.080
We got a short joke that was contributed by Eric Nelson. Thanks, Eric. It is a math joke. The joke is, I is as complex as it gets. JK.

00:24:47.080 --> 00:24:48.500
The letter I. Yeah.

00:24:48.500 --> 00:24:55.220
I love it. I love it. I studied a bunch of complex analysis and things like that when I was doing math and yeah, I like it.

00:24:55.220 --> 00:24:57.400
Yeah. We have another one too that it's long.

00:24:57.400 --> 00:25:04.140
It's long and I'm not going to be able to do justice to it, so you have to check this out. So, you know the song American Pie, right?

00:25:04.140 --> 00:25:04.660
Yes.

00:25:04.660 --> 00:25:08.020
I drove my Chevy to the levee, but the levee was dry. That sort of song?

00:25:08.020 --> 00:25:09.140
Yeah. You can sing it.

00:25:09.140 --> 00:25:11.420
No, no, I can't sing it. I could recite it.

00:25:11.960 --> 00:25:22.340
If I sing it, it's not going to be singing. It's going to be something else. There's another one. One of our listeners, I only know his username on Reddit, I'm afraid. I can't find the tweet in time.

00:25:22.340 --> 00:25:35.340
Wait. It said, hey, you inspired me to write this song called American Pie, American P-Y, and it's basically the story of like Legacy Python done to American Pie, the song.

00:25:35.340 --> 00:25:36.680
Yeah, it's pretty awesome.

00:25:36.680 --> 00:25:41.300
It's really, really well done. I'll just like recite a little bit here one of the verses.

00:25:41.300 --> 00:26:03.400
So, bye-bye to your Legacy Pies. Made decisions about divisions, so you'll have to revise. And you decode official, it's not a bunch of bite lies. Singing, that'll be the day it dies. That'll be the day it dies. It's really good. Yeah, people should check it out. If somebody can perform this and give it to us, he's given us permission to take that and put it on the air. If it's good enough, man, we'd love it. That'd be awesome. I cannot do this.

00:26:03.400 --> 00:26:08.400
I want somebody to sing it because it includes the phrase, I was a crusty old fart coding guy.

00:26:09.400 --> 00:26:16.960
Yes, I know. You could be a YouTube sensation if you just take this chance here. Jump on it.

00:26:16.960 --> 00:26:18.820
Yes, and if you do, let us know.

00:26:18.820 --> 00:26:30.100
Yeah, for sure. Let us know. That'd be awesome. All right. Well, yeah, this really nice song and a nice job there. Well done on that. And Brian, thanks for everything. Thanks for being here.

00:26:30.100 --> 00:26:32.220
Thank you. Yep, you bet. Bye. Bye.

00:26:32.220 --> 00:26:39.800
Bye. Thank you for listening to Python Bytes. Follow the show on Twitter at Python Bytes. That's Python Bytes as in B-Y-T-E-S.

00:26:39.800 --> 00:26:47.760
And get the full show notes at pythonbytes.fm. If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

00:26:47.760 --> 00:26:52.980
We're always on the lookout for sharing something cool. This is Brian Okken, and on behalf of myself and Michael Kennedy,

00:26:52.980 --> 00:26:56.240
thank you for listening and sharing this podcast with your friends and colleagues.

