WEBVTT

00:00:00.001 --> 00:00:02.620
Have you heard of ASTs or abstract syntax trees?

00:00:02.620 --> 00:00:06.720
If you have, it was probably in the context of a compiler or some kind of parser.

00:00:06.720 --> 00:00:10.060
They're a really powerful data structure, but we often only use them

00:00:10.060 --> 00:00:12.640
really indirectly by using those types of tools.

00:00:12.640 --> 00:00:16.060
They're just such a, well, you know, abstract idea to most of us.

00:00:16.060 --> 00:00:20.340
This week, you'll meet Emily Morehouse. She's here to make this abstract concept

00:00:20.340 --> 00:00:24.920
much more concrete and discuss the places where the AST can help us write and maintain

00:00:24.920 --> 00:00:31.640
better code. This is Talk Python To Me, episode 152, recorded February 5th, 2018.

00:00:31.640 --> 00:00:50.500
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries,

00:00:50.500 --> 00:00:54.360
the ecosystem, and the personalities. This is your host, Michael Kennedy.

00:00:54.360 --> 00:00:58.700
Follow me on Twitter, where I'm @mkennedy. Keep up with the show and listen to past episodes

00:00:58.700 --> 00:01:02.760
at talkpython.fm and follow the show on Twitter via at Talk Python.

00:01:02.760 --> 00:01:07.820
This episode is brought to you by ParkMyCloud and Rollbar. Please check out what they're

00:01:07.820 --> 00:01:10.200
offering during their segments. It really helps support the show.

00:01:10.200 --> 00:01:12.040
Emily, welcome to Talk Python.

00:01:12.040 --> 00:01:13.080
Hello, how are you doing?

00:01:13.080 --> 00:01:18.440
I'm doing really well. It was so nice to meet you in Vancouver, and I really enjoyed the talk

00:01:18.440 --> 00:01:23.220
that you gave about the abstract syntax tree. You made this abstract idea kind of concrete.

00:01:23.220 --> 00:01:23.620
It was nice.

00:01:23.620 --> 00:01:28.120
Thank you. Yeah, I've gotten some really, really positive feedback from it. So I was very happy

00:01:28.120 --> 00:01:28.740
to be a part of it.

00:01:28.740 --> 00:01:33.180
Yeah, it was really cool. And we're going to talk all about the AST and what it means in

00:01:33.180 --> 00:01:37.020
Python, where it comes in, how you can actually leverage it to do all sorts of cool stuff.

00:01:37.020 --> 00:01:39.920
But before we get to all those things, let's start with your story. How did you get into

00:01:39.920 --> 00:01:40.900
programming in Python?

00:01:40.900 --> 00:01:46.540
So I kind of stumbled into it. I was a student at Florida State University. I was actually studying

00:01:46.540 --> 00:01:50.220
theater and biochemistry. And I did an internship.

00:01:50.460 --> 00:01:51.200
That's quite the mix.

00:01:51.200 --> 00:01:57.840
Yeah. Yeah. But I did an internship at a lab and realized that I could not see myself doing

00:01:57.840 --> 00:02:01.460
biochemistry for the rest of my life. I also knew that I wasn't going to make a whole lot

00:02:01.460 --> 00:02:07.620
of money doing theater. So I was really interested in forensics. So I figured if I couldn't do the

00:02:07.620 --> 00:02:10.340
biochem side, that I would go to the criminology side.

00:02:10.600 --> 00:02:16.640
So I started in criminology. And it turned out that FSU had just launched a computer criminology

00:02:16.640 --> 00:02:22.380
program. And so this was, I think, my junior year, like summer of my junior year of college.

00:02:22.380 --> 00:02:26.460
And they were like, hey, you have really great math scores. Like, why don't you go take a programming

00:02:26.460 --> 00:02:32.760
class? And I did. And I absolutely fell in love with it. It was like an intro to programming C++ class.

00:02:32.760 --> 00:02:35.320
And I built an Enigma machine simulator.

00:02:35.320 --> 00:02:36.320
Oh, wow. That's cool.

00:02:36.320 --> 00:02:37.700
The rest is history. Yeah.

00:02:37.700 --> 00:02:43.000
Yeah. That's really awesome. So this like sort of data driven criminology, is this like

00:02:43.000 --> 00:02:49.120
a little bit like CSI, like forensic type stuff? Or what kind of things would you have done there?

00:02:49.120 --> 00:02:55.360
Yeah. It was a lot of focus on security, a lot of focus on digital forensics. So taking like a dead

00:02:55.360 --> 00:03:00.400
hard drive and trying to reformulate a lot of the data that you can get off of it,

00:03:00.500 --> 00:03:05.760
that kind of stuff. That sounds pretty interesting. And I guess, you know, you were thrown right into

00:03:05.760 --> 00:03:11.120
like the deep end with C++. So if you like that, then, you know, this whole thing must be for you,

00:03:11.120 --> 00:03:16.300
right? Exactly. Yeah. And I think that looking at my history and how I got into programming and

00:03:16.300 --> 00:03:21.700
coming from a CS background, that was very, very focused on theory and compilers and all that.

00:03:21.700 --> 00:03:27.120
That's definitely where a lot of this stems from. Yeah, yeah, I'm sure. So how'd you go from

00:03:27.120 --> 00:03:34.620
C++ to Python? That's a bit of a complicated answer. So part of it was that I started building

00:03:34.620 --> 00:03:39.300
a lot of like side projects with friends. And so we would go through and like figure out how to build

00:03:39.300 --> 00:03:44.720
a web scraper and stuff like that. And then we started building APIs. And then my university

00:03:44.720 --> 00:03:50.540
actually offered Python courses. So I was able to take Python and like an advanced Python course.

00:03:50.540 --> 00:03:54.660
And then I wound up using it for a lot of the research programs that I was working on,

00:03:54.660 --> 00:03:58.100
because it's really great with data processing and building graphs and all that.

00:03:58.100 --> 00:04:00.640
Right. It's a lot quicker than trying to do that in C++.

00:04:00.640 --> 00:04:01.420
Yeah.

00:04:01.420 --> 00:04:04.180
I don't know what. OpenGL, who knows? Something crazy.

00:04:04.180 --> 00:04:09.100
Yeah. I had to do a little bit of R at one point as well. And I much prefer Python over R.

00:04:09.100 --> 00:04:12.900
Yeah, yeah, that's cool. All right. Well, that's a really cool origin story,

00:04:12.900 --> 00:04:17.040
how you got started. How about now? Are you still working in criminology?

00:04:17.220 --> 00:04:23.600
Not quite. I almost did. But I kind of had another interesting turn and wound up starting a company.

00:04:23.600 --> 00:04:28.280
So I actually am the co-founder and director of engineering of a company called Cuddlesoft.

00:04:28.280 --> 00:04:35.060
And so we are a digital product development company. So we work with a lot of different types of clients,

00:04:35.060 --> 00:04:42.600
anywhere from nonprofits to other tech companies. And we build anything from web and mobile applications

00:04:42.600 --> 00:04:46.740
to cloud migrations and embedded systems. And yeah.

00:04:46.740 --> 00:04:50.700
Yeah. That sounds like a lot of stuff, but it sounds like a really cool company. I looked around your website.

00:04:50.700 --> 00:04:58.160
It looks really, really slick and friendly. And I like it a lot. So it sounds like you must have a ton of technologies at play, right?

00:04:58.160 --> 00:05:03.760
Like as soon as you say mobile, there's probably some Java and some Swift or at least a lot of JavaScript somewhere in there.

00:05:03.760 --> 00:05:05.660
But yeah, what's it like?

00:05:05.660 --> 00:05:12.680
It's really fun. I think I consider myself lucky to be able to really hone my sort of polyglot skills.

00:05:12.680 --> 00:05:21.320
I really enjoy knowing a lot of different languages and being able to see how building a product in one language is different than using another.

00:05:21.800 --> 00:05:28.120
Even like different type systems between Swift and Java. And like, yeah, those are all debates that I love getting into.

00:05:28.120 --> 00:05:35.980
Yeah, those are cool. And I think knowing those languages gives you a richer perspective on any one of them, right?

00:05:35.980 --> 00:05:38.980
Being able to think about it and look at these things from different perspectives.

00:05:38.980 --> 00:05:39.840
I absolutely agree.

00:05:39.840 --> 00:05:41.400
I think it's cool. Yeah, nice.

00:05:41.400 --> 00:05:47.560
So you guys also run a podcast, right? I just learned. Tell me a little bit about your podcast.

00:05:47.560 --> 00:05:51.940
Yeah. So our podcast is called Startup Capital. It's a little bit of a play on words.

00:05:51.940 --> 00:05:56.160
So our original office started in Tallahassee, Florida.

00:05:56.160 --> 00:06:04.980
And there was a huge movement of entrepreneurs and like there's a business incubator and just a huge focus on entrepreneurship.

00:06:05.560 --> 00:06:20.660
And so we started a podcast to kind of highlight each of those stories and how everybody's businesses were going, how they relate to the community, how everything is kind of giving back to Tallahassee and really taking a look at what Tallahassee's ecosystem for entrepreneurs looks like.

00:06:20.660 --> 00:06:22.260
That's cool. That sounds really interesting.

00:06:22.260 --> 00:06:26.400
There's definitely seems to be a lot of entrepreneurship in Florida for some reason.

00:06:26.400 --> 00:06:29.160
I don't know why that is, but it definitely seems like it.

00:06:29.160 --> 00:06:30.740
Yeah. I mean, we got started there.

00:06:30.740 --> 00:06:35.600
Yeah. Well, there's exactly one cool example.

00:06:35.600 --> 00:06:39.900
So let's talk a little bit about the conference and then we'll get into your talk.

00:06:39.900 --> 00:06:49.240
So I learned about your presentation and stuff just by going to PyCascades, which was a new conference in Vancouver this year.

00:06:49.240 --> 00:06:52.760
I thought it went really well, your talk, but also the whole conference.

00:06:52.760 --> 00:06:53.800
What do you think of the experience?

00:06:53.960 --> 00:06:58.120
I absolutely agree. So this was actually my first regional conference that I had attended.

00:06:58.120 --> 00:07:06.660
I attended PyCon previously, but for me, regional conferences are a lot more digestible, a lot less intimidating, a lot less exhausting.

00:07:06.660 --> 00:07:11.280
So for me, like the two day conference experience is like the perfect length.

00:07:11.280 --> 00:07:14.980
Yeah. I feel like when you go to PyCon, it's kind of like the paradox of choice, right?

00:07:14.980 --> 00:07:22.180
It's like, oh, there's 10 tracks and there's open spaces and I can even skip all that and hang out with these people and cruise around the expo hall.

00:07:22.180 --> 00:07:24.040
And there's just like, you know, so much to do, right?

00:07:24.040 --> 00:07:29.920
It was pretty clear, like you either do this, the main track and you're in there with everybody or not.

00:07:29.920 --> 00:07:31.860
And that's definitely a different experience.

00:07:31.860 --> 00:07:34.260
Yeah. But I think the whole thing was really great.

00:07:34.360 --> 00:07:39.780
I know that I felt very welcomed and very supported as a first time conference speaker.

00:07:39.780 --> 00:07:50.720
And I was very, very happy to be invited into the PyCascades community, even as somebody who ventured all the way from Colorado.

00:07:50.720 --> 00:07:52.740
Yeah, that's cool. It was really nice.

00:07:52.740 --> 00:08:00.220
Yeah, there was there were a lot of Americans for a Canadian conference, but it was still nice to meet everybody from from all over the place.

00:08:00.640 --> 00:08:02.880
I got to say, your presentation was really well done.

00:08:02.880 --> 00:08:15.800
And I think it was from a sort of slides visual perspective, one of the most interesting ones there, like it had a animated gifs, little puppies, and it had all sorts of stuff to keep it interesting.

00:08:15.800 --> 00:08:22.840
You know, people so often just go present like a wall of text and you're just like, I'm sure what you're saying is super interesting, but this isn't convincing me of it, right?

00:08:22.840 --> 00:08:30.220
I had to be very conscious about how I presented a lot of this information because it can be very dense and a little bit confusing.

00:08:30.220 --> 00:08:34.520
So I knew that I had to make it interesting for one, cue puppy gifs.

00:08:34.520 --> 00:08:46.260
And I also knew that I had to relay a lot of the information in a very visual fashion so that people could see the trees and understand what they looked like instead of trying to put words together to describe it.

00:08:46.260 --> 00:08:49.100
Yeah, absolutely. There's definitely a lot of visual stuff in there.

00:08:49.100 --> 00:08:56.380
So let's start by maybe asking the question, like, should you care about Python internals?

00:08:56.380 --> 00:09:00.880
I mean, we're going to dive pretty deep into the internal of how Python works and stuff.

00:09:00.880 --> 00:09:08.040
And on one hand, you could kind of blissfully ignore that, you know, pip install requests in beautiful soup, screen scrape, you're done.

00:09:08.520 --> 00:09:11.940
So maybe why do you think people should look a little deeper?

00:09:11.940 --> 00:09:19.940
By understanding how your code works under the hood, it can give you insights into the approaches that you're using to write your code.

00:09:20.480 --> 00:09:37.720
I also think that it's really interesting to learn about how Python works as a language and then how you can leverage that to build different tools, whether you're using the actual Python AST that gets generated or just knowledge of ASTs to build other really neat tools.

00:09:37.720 --> 00:09:46.200
Just to know that you can leverage these ASTs to do more or even change how things execute is, it's pretty cool to know.

00:09:46.200 --> 00:09:48.340
And it's not at all obvious that that's possible, right?

00:09:48.340 --> 00:09:48.840
Absolutely.

00:09:48.840 --> 00:09:49.560
Yeah, yeah.

00:09:49.560 --> 00:09:59.340
So what we're going to focus on mostly is around taking Python source code, getting it to abstract syntax trees and into bytecode.

00:09:59.340 --> 00:10:03.860
Like once the bytecode runs and that sort of is a whole nother area.

00:10:03.980 --> 00:10:10.200
So I just want to give a shout out for people who are interested in this to Philip Wo's 10-hour CPython code walk.

00:10:10.200 --> 00:10:16.840
And I did an episode on that with him, like looking inside the CPython implementation at that sort of disassembly part.

00:10:16.840 --> 00:10:19.580
A whole bunch way back on episode 22.

00:10:19.580 --> 00:10:21.960
So that's kind of a good compliment to this.

00:10:21.960 --> 00:10:30.100
But let's maybe start by talking about how do we go from source code to machine instructions executing, right?

00:10:30.100 --> 00:10:31.480
Like actual stuff happening.

00:10:31.620 --> 00:10:36.280
And you posed a really interesting question of asking whether Python is interpreted or compiled.

00:10:36.280 --> 00:10:37.840
What's the answer?

00:10:37.840 --> 00:10:39.000
The answer is both.

00:10:39.000 --> 00:10:43.820
Usually there's somebody in the audience who actually gets that one right, which I really appreciate.

00:10:43.820 --> 00:10:45.860
But yes, Python is actually both.

00:10:45.860 --> 00:10:50.460
It seems, you know, like you hear that Python is interpreted, so there must be no compile step.

00:10:50.460 --> 00:10:54.980
But the thing that actually gets interpreted is a bunch of compiled bytecode.

00:10:55.160 --> 00:10:57.580
It doesn't get down to machine instructions.

00:10:57.580 --> 00:11:00.940
It just stays these sort of higher level bytecode things, right?

00:11:00.940 --> 00:11:02.860
So maybe talk a little bit about that process.

00:11:02.860 --> 00:11:03.200
Exactly.

00:11:03.200 --> 00:11:08.500
So the compiler generates your bytecode, and then the interpreter actually executes your bytecode.

00:11:09.360 --> 00:11:14.800
So essentially what you do is you take your source code that gets parsed into what's called a parse tree.

00:11:14.800 --> 00:11:22.300
And then for various reasons, your parse tree gets to be a little bit too detailed and is a little bit harder to work with.

00:11:22.300 --> 00:11:25.800
So you actually transform that into an abstract syntax tree.

00:11:25.800 --> 00:11:33.940
Is the parse tree like basically almost exactly what you typed, whereas the abstract syntax tree is like the meaning, like the essence of what you typed?

00:11:33.940 --> 00:11:34.780
Yes, exactly.

00:11:34.780 --> 00:11:38.900
So one of my favorite examples to use is a math expression.

00:11:38.900 --> 00:11:44.260
And so all of us are taught from a very young age the order of operations, right?

00:11:44.260 --> 00:11:56.520
So you know that if you have one plus two in parentheses times three, you know, based on the order of operations, that you execute the parentheses first and then you multiply.

00:11:56.960 --> 00:12:12.680
And so that's one of my favorite examples to use from parse tree to AST, because when you have your AST, you can actually automatically know the order in which you have to perform your operations just based on how the tree itself is laid out.

00:12:12.680 --> 00:12:17.960
Instead of having to know, oh, well, I have parentheses, so I have to worry about that too.

00:12:17.960 --> 00:12:18.800
Right, right.

00:12:18.800 --> 00:12:22.240
And we don't have your great pictures to help here because this is audio.

00:12:22.240 --> 00:12:29.760
But, you know, imagine a tree where the top operation is multiply and then like each branch, one is like the three and the other is one plus two.

00:12:29.760 --> 00:12:31.520
You just you just go down it and evaluate it.

00:12:31.520 --> 00:12:31.640
Right.

00:12:31.640 --> 00:12:33.640
It's pretty, pretty straightforward once it's in that mode.

00:12:33.640 --> 00:12:34.260
Yeah, that's cool.

00:12:34.260 --> 00:12:36.820
OK, so we were we're talking.

00:12:36.820 --> 00:12:37.760
So we have source code.

00:12:37.760 --> 00:12:42.660
It gets parsed into a parse tree and then into an abstract syntax tree.

00:12:42.660 --> 00:12:43.460
And then what?

00:12:43.460 --> 00:12:48.800
And then you take your abstract syntax tree that gets transformed into what's called a control flow graph.

00:12:49.100 --> 00:13:02.680
So if you think about it, an AST is still represented in a very hierarchical fashion, whereas your CFG, you can actually have cycles or loops that can mimic the actual control flow of your program in a better way.

00:13:02.680 --> 00:13:07.420
And then from there, you can actually emit your byte code that winds up being executed.

00:13:07.420 --> 00:13:08.060
Right.

00:13:08.060 --> 00:13:09.160
And can we find this byte code?

00:13:09.160 --> 00:13:11.780
Like, does it land on disk somewhere when we run our code?

00:13:11.780 --> 00:13:12.500
Yeah, absolutely.

00:13:12.700 --> 00:13:17.700
So most of the time, all of your byte code is actually stored in PyC files.

00:13:17.700 --> 00:13:23.680
It used to also get stored in PyO files back Python 2, if you're still using that.

00:13:23.680 --> 00:13:24.040
Yeah.

00:13:24.040 --> 00:13:28.020
And it's in that dunder PyCache that you sometimes see hanging around, right?

00:13:28.020 --> 00:13:28.480
Yeah.

00:13:28.480 --> 00:13:35.760
So Python 3, they were very kind to organize all those PyC files into your PyCache directory to kind of get them out of the way.

00:13:35.760 --> 00:13:36.160
Yeah.

00:13:36.280 --> 00:13:38.720
The one thing is, here's junk, you can throw it away.

00:13:38.720 --> 00:13:39.980
Yeah.

00:13:39.980 --> 00:13:45.420
So let's start talking about working with this, maybe just by focusing on the tools.

00:13:45.420 --> 00:13:52.740
So there's a couple of modules built into Python directly that lets you work with this byte code and these trees and stuff, right?

00:13:52.940 --> 00:13:53.140
Yeah.

00:13:53.140 --> 00:13:56.780
So there are two modules that are built in that I use a lot.

00:13:56.780 --> 00:13:58.900
One of them is the AST module.

00:13:58.900 --> 00:14:05.060
So this is made to assist you in actually interacting with the AST that Python generates.

00:14:05.060 --> 00:14:19.120
And it also has a bunch of helpers that you can use to support translations from your source code into an AST, AST into code objects, and then actually executing the code from those code objects.

00:14:19.120 --> 00:14:20.560
Yeah, that sounds really interesting.

00:14:20.820 --> 00:14:27.020
So let's see, you could take the AST module and you could like parse just source text, right?

00:14:27.020 --> 00:14:32.020
And I guess you could either get that from a file by reading the text of the file, or you literally could just give it text, right?

00:14:32.020 --> 00:14:33.060
That's pretty interesting.

00:14:33.060 --> 00:14:37.360
And if you want to look at it, though, you can't, you know, it's just like an object in memory.

00:14:37.360 --> 00:14:43.000
It's like underscore AST dot, I don't know, node or expression or something at some address, right?

00:14:43.000 --> 00:14:44.660
It's completely hard to make any sense of.

00:14:44.720 --> 00:14:52.200
But there's a nice dump thing, which will dump it sort of back to, what is that, like a text version of a tree or something?

00:14:52.200 --> 00:14:53.080
I'm not entirely sure.

00:14:53.080 --> 00:14:56.860
It's this huge glob of tree data.

00:14:56.860 --> 00:15:15.960
So the easiest way to actually interact with it is to do like a traversal and actually walk over your AST, which is actually, I have a few like third party libraries that make that a little bit easier that abstract away actually interacting with the tree and it handles, you know, what is your next step?

00:15:15.960 --> 00:15:16.600
Right. Okay.

00:15:16.600 --> 00:15:24.600
Yeah. And then there's actually some really neat visualizations that have been built that you can actually just give it your source code that you want to visualize.

00:15:24.600 --> 00:15:28.760
And then it'll print out of an actual tree representation.

00:15:28.760 --> 00:15:30.400
It has like an SVG.

00:15:30.400 --> 00:15:40.380
So you can visualize that you can even take these nodes, these abstract syntax trees and say compile them and then look at their underlying bytecode, right?

00:15:40.380 --> 00:15:41.380
Just all in memory.

00:15:41.380 --> 00:15:42.260
Yeah, exactly.

00:15:42.260 --> 00:15:52.780
So what I kind of did was I approached it as trying to kind of step through as much of the compilation process as I could just by looking at the AST.

00:15:52.780 --> 00:16:01.660
So actually going from your source code, kind of skipping the parse tree, going to the AST and then being able to see your bytecode and interact with it.

00:16:01.860 --> 00:16:05.160
And so everybody always says that everything in Python is an object.

00:16:05.160 --> 00:16:13.620
And that actually is true down to the smallest, most integral parts of the actual implementation of the language.

00:16:13.620 --> 00:16:18.680
So your source code gets compiled into what's called code objects.

00:16:18.680 --> 00:16:24.760
And then those code objects store things like disassembled bytecode or sorry, the assembled bytecode.

00:16:25.260 --> 00:16:27.300
Just the straight numbers, right?

00:16:27.300 --> 00:16:30.020
Like three, 102, seven.

00:16:30.020 --> 00:16:30.940
Yeah.

00:16:30.940 --> 00:16:33.480
And it's actually stored as bytes.

00:16:33.480 --> 00:16:35.000
So they're not even like human readable.

00:16:35.000 --> 00:16:44.060
So you can actually, you have to go in there and poke at it a little bit and to get everything translated into integers so that you can actually read it as a human.

00:16:44.060 --> 00:16:44.420
Right.

00:16:44.520 --> 00:16:54.800
So once you compile it here or if you use the disassembly module, you can just go to the code objects and they have like a .co underscore code, which is, that's the bytes you're talking about.

00:16:54.800 --> 00:16:57.200
And then you can do a couple of things.

00:16:57.200 --> 00:17:01.780
You could actually just re-execute it in case you're messing with it here or you could disassemble it.

00:17:01.780 --> 00:17:04.820
So I kind of sidetracked you when you're talking about the tool.

00:17:04.820 --> 00:17:08.060
So there's the AST module, which does all the stuff that we're talking about, right?

00:17:08.080 --> 00:17:14.580
It'll take source code and you can actually turn it into an AST, but you are also talking about the disassembly module?

00:17:14.580 --> 00:17:15.040
Yes.

00:17:15.040 --> 00:17:25.320
So the disassembly module allows you to take your code objects and actually shows you sort of the machine instructions as they get executed.

00:17:25.320 --> 00:17:38.260
And it also shows you like the registers that they use and a bunch of information, but it makes it a lot easier to actually just look at the disassembly bytecode because it goes through a lot of the lookup processes for you.

00:17:38.260 --> 00:17:52.280
So I'm not going to remember what these are off the top of my head, but if you see like instruction 101, there's actually a giant switch statement in the CPython interpreter that goes through and says, okay, instruction 101.

00:17:52.280 --> 00:17:54.880
I know that that is supposed to be, I don't know, a load.

00:17:54.880 --> 00:18:00.480
Load function or like add a variable to the call stack or something like that.

00:18:00.480 --> 00:18:01.020
Yeah.

00:18:01.020 --> 00:18:07.900
There's literally like this huge switch statement that is like 3000 lines in C eval.c and CPython.

00:18:07.900 --> 00:18:10.220
That's like just every one of those codes.

00:18:10.220 --> 00:18:10.520
Okay.

00:18:10.520 --> 00:18:11.820
It's code 101.

00:18:11.820 --> 00:18:12.540
What does that mean?

00:18:12.540 --> 00:18:13.300
What do I do with that?

00:18:13.300 --> 00:18:13.500
Right.

00:18:13.500 --> 00:18:28.940
And so the disassembly module basically take this bytecode, whether you got it just from running and directly some bit of code or, or from messing with the AST and it'll show you that and kind of the raw steps, almost the assembly language of Python.

00:18:28.940 --> 00:18:29.460
Right.

00:18:29.460 --> 00:18:30.720
As close as you're going to get anyway.

00:18:30.720 --> 00:18:31.960
Yeah.

00:18:31.960 --> 00:18:32.440
Right.

00:18:34.220 --> 00:18:37.560
This portion of talk Python to me is brought to you by park my cloud.

00:18:37.560 --> 00:18:40.740
The last time you parked your car, did you leave it running?

00:18:40.740 --> 00:18:41.420
No.

00:18:41.420 --> 00:18:44.400
Well, then why are you leaving your cloud resources running?

00:18:44.400 --> 00:18:50.060
Every year, $13 billion are wasted on cloud instances that no one is using.

00:18:50.060 --> 00:18:52.380
Don't let any of those be yours.

00:18:52.380 --> 00:19:00.300
Park my cloud automatically identifies and eliminates wasted cloud spend, saving you 65% on AWS, Azure,

00:19:00.400 --> 00:19:01.400
and Google's cloud.

00:19:01.400 --> 00:19:05.380
You're up and running quickly with a 10 minute setup and no scripting required.

00:19:05.380 --> 00:19:09.840
Plus govern users and easily integrate into your DevOps process.

00:19:09.840 --> 00:19:14.420
See why park my cloud was chosen by McDonald's, Unilever, Fox, and more.

00:19:14.420 --> 00:19:19.520
Start a free trial today at parkmycloud.com slash talk Python.

00:19:19.520 --> 00:19:21.820
So those are the two built-in ones.

00:19:21.820 --> 00:19:24.860
And then there's a couple of others that let you dig around.

00:19:24.860 --> 00:19:28.280
There's AST or AST or how do you say it?

00:19:28.280 --> 00:19:28.960
How do you think?

00:19:29.120 --> 00:19:30.500
I've pronounced it as Aster.

00:19:30.500 --> 00:19:31.060
Aster.

00:19:31.060 --> 00:19:31.880
That sounds more fun.

00:19:31.880 --> 00:19:32.020
Yeah.

00:19:32.020 --> 00:19:32.640
Tell us about that.

00:19:32.640 --> 00:19:37.100
And it's a derivative of CodeGen, which comes from Armin Roeneker of Flask fame as well.

00:19:37.100 --> 00:19:37.560
Indeed.

00:19:37.560 --> 00:19:38.000
Yeah.

00:19:38.000 --> 00:19:44.540
So he started out by writing some CodeGen and there were a few little holes that it had.

00:19:44.540 --> 00:19:48.180
So other people in the community kind of picked it up and patched it together.

00:19:48.180 --> 00:19:51.460
And so both Aster and there's another package called Meta.

00:19:52.400 --> 00:20:01.040
They're kind of focused on taking bytecode or an AST and generating the code from it, like your original source code from it.

00:20:01.040 --> 00:20:05.940
And so it's kind of focused on this like reverse engineering of bytecode and ASTs.

00:20:05.940 --> 00:20:10.880
And then Aster also provides some really cool like pretty printing and ways to manipulate the AST.

00:20:10.880 --> 00:20:16.380
So if you want to like inject code in certain parts of the AST, it provides helpers to do that.

00:20:16.380 --> 00:20:16.740
Right.

00:20:16.740 --> 00:20:20.920
Every time you see this type of pattern, like wrap it in whatever, right?

00:20:20.920 --> 00:20:22.100
Something to that effect, right?

00:20:22.100 --> 00:20:22.600
Mm-hmm.

00:20:22.600 --> 00:20:23.020
Yeah.

00:20:23.020 --> 00:20:23.360
Yeah.

00:20:23.360 --> 00:20:23.680
Cool.

00:20:23.680 --> 00:20:28.600
With the straight AST module, can you modify the ASTs as well?

00:20:28.600 --> 00:20:36.760
I don't know if there are any helpers that kind of make that process easier, but you can go in and actually like edit the data structure.

00:20:36.760 --> 00:20:42.220
So there is an actual like underscore AST data structure that you can interact with.

00:20:42.220 --> 00:20:44.640
If you want to just do it at the lowest level, I guess.

00:20:44.640 --> 00:20:45.380
Yeah.

00:20:45.460 --> 00:20:45.680
Yeah.

00:20:45.680 --> 00:20:51.360
So there's a couple of interesting things that the Aster and Kojen did.

00:20:51.360 --> 00:20:52.680
You talked about the pretty printing.

00:20:52.680 --> 00:20:59.060
They let you kind of traverse the tree in a less heavyweight way, I guess, is one thing it does.

00:20:59.060 --> 00:21:01.960
But it also does this concept of round tripping.

00:21:01.960 --> 00:21:04.080
Tell us about this idea of round tripping.

00:21:04.080 --> 00:21:07.240
I am really interested in round tripping for a few different reasons.

00:21:07.240 --> 00:21:14.540
But basically what you can do is you can take your source code, translate it into an AST, and then translate it back into Python

00:21:14.540 --> 00:21:16.700
and see how much your code has changed.

00:21:16.700 --> 00:21:24.940
So the idea of round tripping can actually be used in sort of refactoring or going through and linting code.

00:21:24.940 --> 00:21:34.160
So there are certain changes that you can make to your code that doesn't change the underlying semantic meaning that you can see through the AST.

00:21:34.540 --> 00:21:43.420
So it's a way to kind of guarantee that you've made changes to the syntax of your code, but you haven't actually changed how your code is working or what it's doing.

00:21:43.420 --> 00:21:43.740
Right.

00:21:43.740 --> 00:21:48.780
It's like the linter says, you really should format this way or you should tweak it around that way.

00:21:48.780 --> 00:21:49.020
Right.

00:21:49.020 --> 00:21:51.340
But it really should have exactly the same meaning.

00:21:51.340 --> 00:21:54.840
If the AST changes, well, it doesn't have the same meaning.

00:21:54.840 --> 00:21:55.100
Right.

00:21:55.100 --> 00:21:58.580
So this is kind of a byte level check almost.

00:21:59.620 --> 00:22:09.360
Yeah, I could see a unit test that kind of like snapshots the AST, saves it as like a pretty printed text, and then, you know, just compares again.

00:22:09.360 --> 00:22:10.520
Does that change?

00:22:10.520 --> 00:22:11.280
Did that change?

00:22:11.280 --> 00:22:11.580
All right.

00:22:11.580 --> 00:22:13.100
And if it ever changed, it kind of failed.

00:22:13.100 --> 00:22:14.040
That's pretty interesting.

00:22:14.900 --> 00:22:24.560
Another one that I ran across recently that kind of falls into this general realm of like digging inside the bytecode, it's not technically to do with ASTs, I don't think.

00:22:24.560 --> 00:22:27.120
It's more about the disassemblies, this thing called Python Hunter.

00:22:27.120 --> 00:22:28.200
You've seen that, right?

00:22:28.200 --> 00:22:30.480
Yeah, I recently looked into it.

00:22:30.480 --> 00:22:39.340
They do some really cool things with code tracing, and it'll actually kind of show you at a very low level each step that your code is taking under the hood.

00:22:39.480 --> 00:22:44.540
Yeah, so it's kind of like logging the disassembly as your code executes.

00:22:44.540 --> 00:22:46.100
It's pretty funky, that thing.

00:22:46.100 --> 00:22:48.220
But yeah, it's definitely just another library.

00:22:48.220 --> 00:22:52.460
There's probably, you know, 10 others that we're forgetting or we don't even know exist, right?

00:22:52.460 --> 00:22:56.740
Out of the 125,000 PyPI packages, there's got to be some more in there.

00:22:56.740 --> 00:22:57.680
Nice.

00:22:57.680 --> 00:22:59.160
Okay, so let's see.

00:22:59.160 --> 00:23:07.960
One thing that you talked about in your talk that I thought was interesting is that we can use the disassembly module to check out our code,

00:23:08.080 --> 00:23:12.020
like take the bytecode and sort of look at it in these lower level operations.

00:23:12.020 --> 00:23:15.680
But the bytecode and the source code, they don't always line up, right?

00:23:15.680 --> 00:23:17.400
Sometimes the bytecode is more verbose.

00:23:17.400 --> 00:23:19.420
Sometimes it's less verbose than our source code.

00:23:19.420 --> 00:23:21.920
And maybe tell people about that mismatch there.

00:23:21.920 --> 00:23:28.800
One of the things that you always kind of assume is that there's some sort of optimization that happens under the hood.

00:23:29.260 --> 00:23:35.820
And so you can actually see how a lot of those optimizations happen by looking at your bytecode.

00:23:35.820 --> 00:23:39.520
The two I remember are the peephole optimization and the constant folding.

00:23:39.520 --> 00:23:40.040
Yeah.

00:23:40.040 --> 00:23:42.280
So I guess I can describe them first.

00:23:42.880 --> 00:23:48.460
The two most common ways that Python is optimized under the hood is the peephole optimizer.

00:23:48.460 --> 00:23:53.460
So the way I like to think about that is looking around without moving your head.

00:23:53.460 --> 00:24:01.500
So kind of using your peripheral vision to see your direct surroundings and then being able to make intelligent choices based on those surroundings.

00:24:01.500 --> 00:24:15.340
So as humans, we have learned that if you have x equals 1 and then y equals x plus 2, we automatically know since x equals 1 that we can kind of substitute those values in.

00:24:15.340 --> 00:24:19.540
And that's one of the things that the peephole optimizer does.

00:24:19.540 --> 00:24:23.980
And the other optimization is called constant folding.

00:24:23.980 --> 00:24:30.220
And so basically you can evaluate constant expressions at compile time instead of at runtime.

00:24:30.220 --> 00:24:30.880
Right.

00:24:30.880 --> 00:24:39.760
So for example, if you had like what I have all the time in my web apps is there's usually some part that says, how long do you want to cache this for?

00:24:39.760 --> 00:24:42.640
And it's sometimes in milliseconds and it's sometimes in seconds.

00:24:42.640 --> 00:24:47.920
And I don't want to write, you know, 236,414 seconds.

00:24:47.920 --> 00:24:48.320
All right.

00:24:48.320 --> 00:24:53.140
Like 60 times, 60 times, 24 times, 31, a month's worth of seconds.

00:24:53.140 --> 00:24:54.140
Do the math for me.

00:24:54.140 --> 00:25:00.560
And what you're saying is that Python will actually do the constant folding and go, well, that's the, you know, whatever actual number that is.

00:25:00.760 --> 00:25:02.340
Just before it ever runs.

00:25:02.340 --> 00:25:02.600
Right.

00:25:02.600 --> 00:25:03.320
Yeah, exactly.

00:25:03.320 --> 00:25:06.260
And it tries to look out for you a little bit.

00:25:06.260 --> 00:25:12.100
So one of my other favorite examples is if you have like a double negative in your logic.

00:25:12.640 --> 00:25:19.400
So if you have something like not A, not in B, the compiler actually goes, oh, no, no, no, no.

00:25:19.400 --> 00:25:20.520
I know what you're trying to say here.

00:25:20.520 --> 00:25:22.800
This is simply just A and B.

00:25:22.800 --> 00:25:25.180
Like, let me simplify that for you.

00:25:25.180 --> 00:25:25.200
Right, right.

00:25:25.740 --> 00:25:27.720
I don't need to do three tests for you.

00:25:27.720 --> 00:25:29.400
I'll just do the one or two.

00:25:29.400 --> 00:25:31.380
However, however you count not in.

00:25:31.380 --> 00:25:34.800
Yeah, that's totally a good idea.

00:25:34.800 --> 00:25:37.240
And that's one of the people optimizations as well.

00:25:37.240 --> 00:25:39.000
It's like there's a whole class there.

00:25:39.460 --> 00:25:48.620
So things that I don't think happen are things like what C++ might do where you might like inline non-virtual function calls and stuff like that.

00:25:48.620 --> 00:25:50.040
So I don't know.

00:25:50.040 --> 00:25:55.540
There's I think it's pretty interesting that one of the big focuses recently on Python is around its performance.

00:25:56.040 --> 00:25:58.580
I think that was the 3.6 work.

00:25:58.580 --> 00:25:59.200
I can't remember.

00:25:59.200 --> 00:26:06.680
But like Victor Stinner and some of those guys are like, we're going to make a bunch of improvements on like function call speed and stuff.

00:26:06.680 --> 00:26:09.820
And so they're getting better at the optimizations for sure.

00:26:09.820 --> 00:26:11.820
But yeah, it's not too advanced, right?

00:26:11.820 --> 00:26:12.160
Correct.

00:26:12.160 --> 00:26:12.480
Yeah.

00:26:12.480 --> 00:26:20.080
I think one of the things that happened with Python 3 is that when Python 3 was first released, it was actually a little bit slower than Python 2.

00:26:20.460 --> 00:26:28.860
And so I think they realized that they really needed to put a lot of focus into at least making it as fast, if not faster, than Python 2.

00:26:28.860 --> 00:26:36.440
Yeah, we've had this big challenge for quite a while, which I feel like we're on the verge of sort of putting that behind us.

00:26:36.440 --> 00:26:46.160
But the sort of Python 3, Python 2 wars, it is hard to say you should choose Python 3 when it actually slows down everything you do, right?

00:26:46.160 --> 00:26:46.680
Exactly.

00:26:46.680 --> 00:26:49.700
Yeah, that definitely is not what you want on your side of the argument.

00:26:49.700 --> 00:26:52.540
So it's good that they're making it faster and using less memory.

00:26:52.540 --> 00:26:57.320
Like there was that whole presentation at PyCon 2017 from Instagram.

00:26:57.320 --> 00:26:57.840
I don't know.

00:26:57.840 --> 00:26:58.580
Did you see that one?

00:26:58.580 --> 00:26:59.220
I might have.

00:26:59.220 --> 00:26:59.540
Yeah.

00:26:59.540 --> 00:27:05.020
So they've talked about upgrading from Python 2 to Python 3 from Django, some old version to like modern Django.

00:27:05.020 --> 00:27:11.860
And they basically save like 12% on their memory usage and something similar around performance just by upgrading.

00:27:11.860 --> 00:27:17.140
So, you know, it's finally getting to the point where it's better to upgrade, not worse.

00:27:17.140 --> 00:27:18.480
So that's pretty awesome.

00:27:18.480 --> 00:27:19.240
All right.

00:27:19.340 --> 00:27:23.980
So these abstract syntax trees, it's interesting to know that they work.

00:27:24.520 --> 00:27:25.660
It's kind of cool.

00:27:25.660 --> 00:27:25.700
It's kind of cool.

00:27:25.700 --> 00:27:28.140
It gives you some insight into your code like we talked about.

00:27:28.140 --> 00:27:37.760
But, you know, let's talk about some of the applications because, you know, it's sort of an abstract idea until you can do something constructive with it.

00:27:37.960 --> 00:27:41.020
So you had a bunch of different applications that you talked about.

00:27:41.020 --> 00:27:45.760
I think it's kind of a lot of things that you're going to do something like 100% of the code coverage for your tests.

00:27:45.760 --> 00:27:49.380
So you're going to do something like 100% of the compiler does.

00:27:49.380 --> 00:27:57.340
There's also a few like very random cases where if you're trying to get like 100% code coverage for your tests.

00:27:57.560 --> 00:28:07.980
There's actually certain cases that if you have an if else statement, for example, that your else, the actual line for the else doesn't actually get executed.

00:28:07.980 --> 00:28:14.480
So there are certain like weird things where you're like, I don't know, I can't get my else to execute, but I know that it executes.

00:28:14.980 --> 00:28:15.580
Yeah.

00:28:15.580 --> 00:28:15.940
Yeah.

00:28:15.940 --> 00:28:21.620
So there are certain ways that you can use this knowledge to sort of debug different errors that you're encountering.

00:28:21.620 --> 00:28:21.940
Right.

00:28:21.940 --> 00:28:25.120
Or if you're super obsessed about getting 100% code coverage.

00:28:25.120 --> 00:28:25.460
Yeah.

00:28:25.460 --> 00:28:27.920
You just want to force that to happen.

00:28:27.920 --> 00:28:28.240
Yeah.

00:28:28.240 --> 00:28:37.160
Another thing is if you wanted to create your own sort of domain specific language derived from Python, right, if you want to change the grammar a little bit.

00:28:37.160 --> 00:28:43.920
So that's kind of one of the fun things about Python is that anybody can sort of propose a PEP and propose a change to the language.

00:28:44.640 --> 00:28:50.340
So if you did want to actually get in there and change Python's grammar, you can do that fairly easily.

00:28:50.340 --> 00:28:54.000
There's a lot of blog posts out there about how to actually get in there and do it.

00:28:54.000 --> 00:28:54.340
Yeah.

00:28:54.340 --> 00:29:01.020
It's probably a pretty tough sell to get them to accept like a new concept, right?

00:29:01.020 --> 00:29:01.420
Usually.

00:29:01.420 --> 00:29:01.920
Yeah.

00:29:01.920 --> 00:29:02.240
Yeah.

00:29:02.240 --> 00:29:07.900
I mean, that's one of the things where like once it's in there, you have to live with it no matter what.

00:29:07.900 --> 00:29:08.160
Right.

00:29:08.160 --> 00:29:13.820
If it's in the language, unless you're doing a major break and change like Python 2 to 3, like generally,

00:29:14.300 --> 00:29:16.920
you know, it's kind of like the gift of a puppy, right?

00:29:16.920 --> 00:29:19.000
You have it once you've received it.

00:29:19.000 --> 00:29:19.540
Nice.

00:29:19.540 --> 00:29:21.680
And then we talked about round tripping already.

00:29:21.680 --> 00:29:34.040
That's another interesting application to sort of verify that changes based on linting or automatic linting actually don't make any significant, you know, any meaningful change to the underlying bytecode.

00:29:34.040 --> 00:29:35.300
That's pretty interesting.

00:29:36.000 --> 00:29:40.360
Maybe one of the ones where people see the most is around this idea of code generation.

00:29:40.360 --> 00:29:40.800
Yeah.

00:29:40.800 --> 00:29:42.260
So code generators are really cool.

00:29:42.260 --> 00:29:52.220
And it's actually one of the things that I learned in this process is that there's actually some decent chunks of Python itself and Python's compiler that are actually generated.

00:29:52.220 --> 00:29:53.120
Oh, that's pretty cool.

00:29:53.380 --> 00:29:53.500
Yeah.

00:29:53.500 --> 00:29:57.640
But you can use code generators for a lot of really neat things.

00:29:57.640 --> 00:29:59.780
So one of them is called Pythoscope.

00:29:59.780 --> 00:30:00.820
Now, what's that?

00:30:00.820 --> 00:30:05.120
It will actually essentially generate unit tests for you.

00:30:05.380 --> 00:30:11.840
So if you have a project that you haven't actually written any tests for, you can use Pythoscope to kind of kickstart that process.

00:30:11.840 --> 00:30:12.460
That's cool.

00:30:12.460 --> 00:30:18.960
So the logo they have is like this doctor checking out like a sick snake.

00:30:18.960 --> 00:30:21.240
It's a pretty good logo, actually.

00:30:21.240 --> 00:30:22.520
It's funny.

00:30:23.140 --> 00:30:24.440
So look at this.

00:30:24.440 --> 00:30:29.220
It says you take the old code and sort of run this thing across it.

00:30:29.220 --> 00:30:35.920
It will write what it thinks are the unit tests for you in comments for all the various things.

00:30:35.920 --> 00:30:37.280
And it just fails all the tests.

00:30:37.280 --> 00:30:41.920
But you can sort of uncomment them and make them real, which is pretty cool.

00:30:41.920 --> 00:30:47.160
And it apparently uses the abstract syntax tree to go understand the various pieces, right?

00:30:47.160 --> 00:30:47.580
Yeah.

00:30:47.700 --> 00:30:54.200
So it uses the AST to kind of figure out what tests that it can actually generate and what needs to be tested and all that.

00:30:54.200 --> 00:30:54.540
Oh, yeah.

00:30:54.540 --> 00:30:54.920
That's cool.

00:30:54.920 --> 00:30:56.160
That's a really nice way to do it.

00:30:56.160 --> 00:31:00.360
So another thing that's pretty interesting is this thing called Transcript.

00:31:00.360 --> 00:31:02.420
And I've never heard of Transcript.

00:31:02.420 --> 00:31:13.100
It's apparently a Python in the browser, sort of a JavaScript to, sorry, a Python to JavaScript compiler type thing like Babel.

00:31:13.100 --> 00:31:14.520
Have you played with this?

00:31:14.520 --> 00:31:15.000
Have you seen it?

00:31:15.000 --> 00:31:17.580
I haven't played with it before, but it's really interesting.

00:31:18.000 --> 00:31:23.900
So I think that that's one of the things that a lot of people are trying to do is they're trying to make Python a lot more portable.

00:31:23.900 --> 00:31:28.600
And one of the things I have also learned, I'm just a fountain of knowledge over here.

00:31:28.600 --> 00:31:33.980
Python was almost the JavaScript of browser languages.

00:31:33.980 --> 00:31:34.920
Oh, really?

00:31:34.920 --> 00:31:35.360
Yes.

00:31:35.360 --> 00:31:37.820
That would have been nice.

00:31:37.820 --> 00:31:38.560
Yeah.

00:31:38.560 --> 00:31:46.220
Way back in the day, I think there was like an old Netscape browser that was actually built using Python as it's like in browser language.

00:31:46.220 --> 00:31:47.220
Wow, that's cool.

00:31:47.220 --> 00:31:47.480
Yeah.

00:31:47.480 --> 00:31:54.260
So, you know, Netscape back in the day, that's when they came up with JavaScript just for Netscape, right?

00:31:54.260 --> 00:31:56.220
So, too bad.

00:31:56.220 --> 00:31:57.860
But yeah, there are a couple options.

00:31:58.440 --> 00:32:00.200
There's Sculpt and there's a couple of others.

00:32:00.200 --> 00:32:02.120
But I don't know how the others work.

00:32:02.120 --> 00:32:02.900
Maybe similarly.

00:32:02.900 --> 00:32:15.140
But at least this transcript one, which I didn't know was an option until now, that one uses AST to sort of generate the JavaScript equivalent from Python, which seems like a pretty good way to do it.

00:32:15.140 --> 00:32:20.060
Yeah, I think that transpiling languages is fairly common.

00:32:20.060 --> 00:32:31.740
So, like you mentioned, there's definitely a lot of transcription in the JavaScript world just going from newer, you know, ES7, ES6 syntax to original ES5.

00:32:31.740 --> 00:32:40.260
That's a pretty interesting thing to just say, we're going to solve the version problem by recompiling it down to a different version of source code for you.

00:32:40.380 --> 00:32:40.860
Yeah.

00:32:40.860 --> 00:32:44.380
I'm not sure it's a good way, but it's an interesting way.

00:32:44.380 --> 00:32:49.520
As somebody who has to work with a lot of JavaScript, I definitely prefer the newer syntax.

00:32:49.520 --> 00:32:53.060
And I definitely appreciate being to use, you know, arrow functions and all that.

00:32:53.060 --> 00:32:58.420
Yeah, the new JavaScript is a lot better, although it feels much more engineered.

00:32:58.420 --> 00:33:06.680
Like you almost need a CS degree to properly work with modern JavaScript, where it used to be just this few jQuery selectors and go with it.

00:33:06.680 --> 00:33:08.440
Real simple type thing, right?

00:33:08.440 --> 00:33:18.700
Yeah, but I definitely think that that's also sort of reflected in the amount of weight that we're making JavaScript carry in, you know, modern web applications.

00:33:18.700 --> 00:33:19.980
Yeah, that's true.

00:33:19.980 --> 00:33:21.040
They are doing a lot, aren't they?

00:33:21.040 --> 00:33:21.300
Yeah.

00:33:21.300 --> 00:33:24.620
So another thing that you talked about was reformatting code.

00:33:24.620 --> 00:33:26.080
How does that work?

00:33:26.140 --> 00:33:35.840
So I think there are these ideas using things like AutoPep 8, where you can kind of translate your code and impose certain restrictions.

00:33:35.840 --> 00:33:43.820
And so one of my favorite ones is, I think it's just yet another Python formatter.

00:33:43.820 --> 00:33:46.200
Yep, of course.

00:33:46.200 --> 00:33:46.700
Yeah.

00:33:47.180 --> 00:33:48.400
And so that one's really neat.

00:33:48.400 --> 00:34:09.180
It takes a very intelligent approach to actually looking at your code and seeing at a more underlying level what your AST is actually doing and being able to make certain choices based on this advanced knowledge that it has of your code and how it can actually transform it and almost refactor it in a way.

00:34:09.280 --> 00:34:10.040
It's pretty cool.

00:34:10.040 --> 00:34:12.120
They have a little online demo that you can play with.

00:34:12.120 --> 00:34:15.300
And I think this comes from Google, right?

00:34:15.300 --> 00:34:15.680
Yes.

00:34:15.680 --> 00:34:19.240
And it lets you pick different formatting guidelines.

00:34:19.240 --> 00:34:25.140
You can format via Pep 8 or Google or Facebook, like whatever their rules for how Python code should look.

00:34:25.140 --> 00:34:26.920
You can just make it look like that.

00:34:26.920 --> 00:34:27.820
That's pretty cool.

00:34:27.820 --> 00:34:29.460
I would guess you could extend it.

00:34:29.460 --> 00:34:29.920
Oh, yeah.

00:34:29.920 --> 00:34:31.380
I think you definitely can.

00:34:31.460 --> 00:34:33.680
I'm a huge fan of code formatting.

00:34:33.680 --> 00:34:38.720
It seems like a pretty nice sort of right before you check in type of feature.

00:34:38.720 --> 00:34:46.500
Just make sure you run that against your code always because there's always those weird like, why did this file change?

00:34:46.500 --> 00:34:48.900
Oh, it's just their formatting indented.

00:34:48.900 --> 00:34:53.200
My formatting unindents like war in the version control, right?

00:34:53.200 --> 00:34:56.980
And so having like something sort of stabilizing that, that's kind of cool.

00:34:56.980 --> 00:34:57.260
Yeah.

00:34:57.260 --> 00:35:00.320
And I think it helps normalize the look of code.

00:35:00.320 --> 00:35:03.140
So code is there for people to read, right?

00:35:03.140 --> 00:35:05.620
Like humans have to understand what your code is doing.

00:35:05.620 --> 00:35:15.260
And if you always know that certain line breaks are in certain places or stuff like that, I think it makes it a lot easier for people to actually interact with it.

00:35:15.260 --> 00:35:19.480
So I actually have, for most of my projects, I'll set up get hooks.

00:35:19.480 --> 00:35:27.200
So it's like a pre-commit hook that'll run the formatting and then also run any tests or anything like that to make sure that it didn't break anything.

00:35:27.200 --> 00:35:28.720
Yeah, that's a really cool idea.

00:35:28.720 --> 00:35:29.320
I like it.

00:35:29.320 --> 00:35:29.520
Yeah.

00:35:29.520 --> 00:35:35.820
Most of the stuff we've talked about so far really has to do with CPython, you know, the disassembly and the interpreter and stuff.

00:35:35.820 --> 00:35:38.560
But there's alternate interpreters as well, right?

00:35:38.560 --> 00:35:41.840
And that, of course, involves abstracts, syntax, trees as well.

00:35:41.840 --> 00:35:44.920
We talked a little bit about Python's speed.

00:35:44.920 --> 00:35:51.700
And so the best way to speed up CPython is actually to just completely switch out your interpreter.

00:35:51.700 --> 00:36:00.580
And so that's why there are a lot of interpreters like PyPy, Jython, Cython, the list goes on.

00:36:00.580 --> 00:36:07.680
And so you can actually use these other interpreters to run almost exactly the same syntax.

00:36:07.920 --> 00:36:08.920
So that is one of the downsides.

00:36:08.920 --> 00:36:18.300
So that is one of the downsides is that in order to make some of these optimizations, you have to have certain sacrifices in the way that your language is represented.

00:36:18.740 --> 00:36:29.420
So your AST is going to look a bit different in these different interpreters because a lot of them will try to make different optimizations and translations of that AST.

00:36:29.420 --> 00:36:29.840
Right.

00:36:29.840 --> 00:36:33.880
And so, like, for example, Cython would be totally different probably.

00:36:34.540 --> 00:36:37.420
But maybe PyPy is actually really similar.

00:36:37.420 --> 00:36:45.940
I think PyPy starts out the same as an interpreted CPython, but eventually if it finds a hotspot, it will replace it with a JIT compiled version.

00:36:45.940 --> 00:36:47.760
So maybe it starts out the same.

00:36:47.760 --> 00:36:48.480
I don't actually know.

00:36:48.480 --> 00:36:51.740
Yeah, I'm definitely not an expert on all the different interpreters.

00:36:51.740 --> 00:36:53.640
It's interesting, though.

00:36:53.640 --> 00:37:00.920
There's all these different tradeoffs and there's all these different interpreters trying to explore the advantages or disadvantages of something, right?

00:37:00.920 --> 00:37:01.480
Yeah.

00:37:01.480 --> 00:37:04.100
Another one you talked about was the Beware project.

00:37:04.100 --> 00:37:04.800
Is it PyB?

00:37:04.800 --> 00:37:06.360
Is that also from the Beware project?

00:37:06.360 --> 00:37:09.960
I know PyB is, like, their GitHub account, I believe.

00:37:09.960 --> 00:37:10.760
Yeah, yeah.

00:37:10.760 --> 00:37:12.560
There's a ton of projects under there, yeah.

00:37:12.560 --> 00:37:13.040
Yeah.

00:37:13.040 --> 00:37:20.280
PyB is doing some really, really awesome work in trying to use Python for, like, native mobile development.

00:37:20.280 --> 00:37:33.840
And so whether that is in the form of transpiling code in order to interact with native mobile components or actually they have a project called Batavia.

00:37:33.840 --> 00:37:35.820
I probably am butchering that.

00:37:35.820 --> 00:37:36.240
Yeah, yeah.

00:37:36.240 --> 00:37:36.720
That's right.

00:37:36.720 --> 00:37:38.220
That is their transpiler one.

00:37:38.220 --> 00:37:38.620
That's right.

00:37:38.620 --> 00:37:38.900
Yeah.

00:37:38.900 --> 00:37:43.440
So they're actually, they'll transpile Python into JavaScript as well.

00:37:43.440 --> 00:37:44.260
How interesting.

00:37:44.260 --> 00:37:44.700
Yeah.

00:37:44.700 --> 00:37:47.480
They definitely have some interesting stuff going on over there.

00:37:47.540 --> 00:37:49.860
I would love for that to become a thing.

00:37:49.860 --> 00:37:53.420
You know, like, proper native mobile apps in Python.

00:37:53.420 --> 00:37:57.660
Because right now, you know, I don't think there's a lot of great options.

00:37:57.660 --> 00:38:03.460
I know you can do some stuff with Pythonista, but it's kind of stuck within, like, that app, right?

00:38:03.500 --> 00:38:05.720
You can't just ship your own app to the app store.

00:38:05.720 --> 00:38:13.160
And I've been playing with Ionic framework and Electron.js and Cordova and all those things.

00:38:13.160 --> 00:38:14.900
And I would rather just not, you know.

00:38:14.900 --> 00:38:17.280
But right now, there's not a super awesome option.

00:38:17.280 --> 00:38:19.020
So it'd be cool if they were successful.

00:38:21.280 --> 00:38:24.400
This portion of Talk Python To Me has been brought to you by Rollbar.

00:38:24.400 --> 00:38:28.100
One of the frustrating things about being a developer is dealing with errors.

00:38:28.100 --> 00:38:33.140
Relying on users to report errors, digging through log files, trying to debug issues,

00:38:33.140 --> 00:38:37.120
or getting millions of alerts just flooding your inbox and ruining your day.

00:38:37.120 --> 00:38:43.860
With Rollbar's full stack error monitoring, you get the context, insight, and control you need to find and fix bugs faster.

00:38:43.860 --> 00:38:47.860
Adding Rollbar to your Python app is as easy as pip install Rollbar.

00:38:48.100 --> 00:38:52.080
You can start tracking production errors and deployments in eight minutes or less.

00:38:52.080 --> 00:38:56.260
Are you considering self-hosting tools for security or compliance reasons?

00:38:56.260 --> 00:38:59.840
Then you should really check out Rollbar's compliant SaaS option.

00:38:59.840 --> 00:39:04.360
Get advanced security features and meet compliance without the hassle of self-hosting,

00:39:04.360 --> 00:39:09.220
including HIPAA, ISO 27001, Privacy Shield, and more.

00:39:09.220 --> 00:39:10.600
They'd love to give you a demo.

00:39:10.600 --> 00:39:12.300
Give Rollbar a try today.

00:39:12.300 --> 00:39:16.000
Go to talkpython.fm/Rollbar and check them out.

00:39:17.220 --> 00:39:22.200
I think that being able to actually transpile into native code.

00:39:22.200 --> 00:39:27.720
So a lot of other platforms like Ionic, etc. will use WebViews.

00:39:27.720 --> 00:39:31.940
So you're still running a JavaScript app in your native application.

00:39:31.940 --> 00:39:32.580
Right.

00:39:32.580 --> 00:39:34.140
And you have all these performance issues.

00:39:34.140 --> 00:39:40.000
Like large lists are super weird unless you choose like virtual scrolling add-ons and all kinds of stuff, right?

00:39:40.100 --> 00:39:40.280
Yeah.

00:39:40.280 --> 00:39:42.000
And like animations are a lot harder.

00:39:42.000 --> 00:39:47.840
You just, you have that separation between your app and the bare metal.

00:39:47.840 --> 00:39:50.460
So you can't do a lot of like GPU optimizations.

00:39:50.820 --> 00:39:50.940
Yeah.

00:39:50.940 --> 00:39:54.820
So fingers crossed for a little bit more from the Beware folks.

00:39:54.820 --> 00:39:55.480
That'd be awesome.

00:39:55.480 --> 00:40:01.220
Another one that a lot of people likely interact with, especially from the Flask world, is Jinja2.

00:40:01.380 --> 00:40:01.500
Yeah.

00:40:01.500 --> 00:40:11.700
So that's one of the things like the more you start looking around at the tools that you're using, the more you realize that a lot of them are using ASTs under the hood to accomplish some really cool things.

00:40:12.440 --> 00:40:17.560
So, but it makes sense because, I mean, HTML in itself can be thought of in a tree structure.

00:40:17.560 --> 00:40:21.700
And so it's really easy to parse HTML into a tree.

00:40:21.700 --> 00:40:34.720
And then if you have variables in your Jinja template that need to be filled in, it's really easy to kind of pop those values in and then transpile everything back into an AST or into the HTML from the AST.

00:40:34.720 --> 00:40:39.840
The template languages are pretty impressive the way they work for all the different web frameworks.

00:40:39.840 --> 00:40:41.520
It's kind of cool to see them go.

00:40:41.520 --> 00:40:41.800
Yeah.

00:40:41.800 --> 00:40:48.280
And if you think about it, you can have little bits and pieces of Python code in your Jinja templates.

00:40:48.280 --> 00:41:00.040
And so you can kind of see how all this comes together where you've got an AST that you can then edit and kind of piece additional bits of code into the AST and then transpile it all back.

00:41:00.040 --> 00:41:00.680
Yeah.

00:41:00.680 --> 00:41:01.440
Yeah.

00:41:01.440 --> 00:41:02.500
It's definitely a cool example.

00:41:02.500 --> 00:41:05.120
So all those are kind of within the realm of Python.

00:41:05.120 --> 00:41:06.520
How about outside Python?

00:41:06.520 --> 00:41:10.220
There's a lot of different code analysis that you can do.

00:41:10.220 --> 00:41:13.880
Any sort of linting is usually going to use an AST under the hood.

00:41:13.880 --> 00:41:17.840
And then we already talked about Babel in the JavaScript world.

00:41:17.840 --> 00:41:21.500
There's also some really cool stuff that they're doing with CSS.

00:41:21.660 --> 00:41:32.260
So especially with the advent of all these newer JavaScript frameworks, there's a huge debate over how you actually handle your CSS and your styling now.

00:41:32.420 --> 00:41:43.660
So you can use an AST to do CSS transformations and really optimize the use of mixins and different media queries.

00:41:43.660 --> 00:41:47.080
And you can kind of automate a bit more than what you used to be able to.

00:41:47.200 --> 00:41:50.400
There's definitely a ton of that stuff over in the JavaScript web world.

00:41:50.400 --> 00:41:51.720
It's quite interesting.

00:41:51.720 --> 00:41:59.060
And all the minification and all types of stuff that happens before your code actually goes out to the web.

00:41:59.060 --> 00:41:59.640
Yeah.

00:41:59.640 --> 00:42:00.460
It's pretty cool.

00:42:00.460 --> 00:42:06.400
So what else would you like to sort of let people know about why you got some time to speak with them?

00:42:06.400 --> 00:42:14.200
One of the things that I have definitely been sort of reflecting on a lot recently is just going through my first time speaking at a conference.

00:42:14.200 --> 00:42:17.960
And so I think I mentioned I wrote a blog post on it.

00:42:17.960 --> 00:42:22.820
But I think that I want to kind of shed some light on what that process looks like.

00:42:22.880 --> 00:42:30.260
And for a lot of people, it's like, it's really intimidating to actually go out there and especially to start off with a technical talk.

00:42:30.260 --> 00:42:35.120
I think one of the really scary parts is I think a lot of people are afraid that when you get up in front of them,

00:42:35.120 --> 00:42:42.200
the audience is just going to find that little one thing you don't know and just tear into you because you didn't know.

00:42:42.200 --> 00:42:45.460
Well, actually, there's this one aspect of ASTs that does one thing.

00:42:45.640 --> 00:42:51.800
And I think one of the things I've learned about the Python community is that people are generally really supportive.

00:42:51.800 --> 00:42:59.460
And those types of things are not likely to happen unless you just have like really an unprepared presentation, I think.

00:42:59.460 --> 00:43:00.760
I've gotten some really great feedback.

00:43:00.760 --> 00:43:04.880
And I did have these little like, oh, well, you missed this little thing.

00:43:04.880 --> 00:43:07.560
But I really liked this, this, this, and this, you know.

00:43:07.560 --> 00:43:14.020
But I think I really urge people if you have a desire to speak at a conference to just do it and submit that proposal.

00:43:14.380 --> 00:43:16.840
And you might get accepted and you might not.

00:43:16.840 --> 00:43:19.800
But you also might get some really great feedback on your proposal.

00:43:19.800 --> 00:43:25.500
I think it can absolutely change your position within the community, right?

00:43:25.500 --> 00:43:28.660
Like once you've done one of these talks, like your talk is now on YouTube.

00:43:28.660 --> 00:43:34.820
If for some reason you ever wanted to apply for a job, it sounds like you're being super successful not having a boss.

00:43:34.820 --> 00:43:39.800
But if for some reason you wanted to, having that up there would be a really great resume item, right?

00:43:39.800 --> 00:43:42.060
You could say, do you want to know if I know about it?

00:43:42.080 --> 00:43:46.680
Look, here's me speaking for half an hour in front of hundreds of people doing it, right?

00:43:46.680 --> 00:43:47.040
Yeah.

00:43:47.040 --> 00:43:51.620
And it's also a really great way to like get accepted for other conferences too.

00:43:51.620 --> 00:44:03.160
So like as soon as you have that first conference talk, you can kind of point to that and be like, yeah, I can actually hold my own in front of a crowd and stand up on stage and not completely forget how to speak.

00:44:03.640 --> 00:44:12.760
I'm sure that's a concern for conference organizers and, you know, seeing someone who's obviously good at it is really, really opens doors, I would think.

00:44:12.760 --> 00:44:16.860
And it doesn't have to just be like the main PyCon, right?

00:44:16.860 --> 00:44:19.880
For example, PyCascades is a regional one.

00:44:19.880 --> 00:44:20.960
They're all over the world.

00:44:21.200 --> 00:44:30.240
But there's also meetups and user groups and smaller things, maybe even like a brown bag lunch talk at your company for the first type thing, right?

00:44:30.240 --> 00:44:32.400
Like here, I'm going to tell you guys all about like web scraping.

00:44:32.400 --> 00:44:33.480
Nobody knows about it here.

00:44:33.480 --> 00:44:34.420
So let's talk about it.

00:44:34.480 --> 00:44:34.620
Yeah.

00:44:34.620 --> 00:44:37.600
And I always kind of remind myself to go back to that.

00:44:37.600 --> 00:44:52.800
It's like a very, very well-known Venn diagram of like what you think everybody else knows and what you think you know and how there's really a lot less overlap in those spaces than you'd think and how much value you can really add.

00:44:52.800 --> 00:44:56.620
Even though you just kind of assume, oh, everybody else probably already knows this.

00:44:56.620 --> 00:44:57.320
Yeah, that's right.

00:44:57.320 --> 00:45:01.540
It's easy to assume that, but I find it's actually rarely the case.

00:45:01.780 --> 00:45:10.900
I used to do a lot of like in-person professional training and I would get on the phone to like set up some kind of event with the company I was going to.

00:45:10.900 --> 00:45:14.540
And the managers would also say, our developers are super advanced.

00:45:14.540 --> 00:45:15.440
They're really advanced.

00:45:15.440 --> 00:45:16.980
Like just no beginner stuff.

00:45:16.980 --> 00:45:19.400
We only want advanced stuff for them because they're the best.

00:45:19.400 --> 00:45:20.140
All right, great.

00:45:20.140 --> 00:45:22.720
You know, then we show up like, all right, we're just doing advanced stuff.

00:45:22.720 --> 00:45:23.640
But hold on.

00:45:23.640 --> 00:45:26.880
Can we talk about this not advanced stuff for like a day or two?

00:45:26.880 --> 00:45:28.020
Because nobody knows it.

00:45:28.020 --> 00:45:29.320
Like, what do you mean nobody knows it?

00:45:29.320 --> 00:45:32.000
Like your manager just told me that, all right, great.

00:45:32.000 --> 00:45:33.700
That's what I actually believe was the case.

00:45:33.700 --> 00:45:36.280
But, you know, you don't want to tell that to people, right?

00:45:36.280 --> 00:45:39.720
But I think there's a lot of value in sort of some of the foundational stuff for sure.

00:45:39.720 --> 00:45:40.560
Yeah, absolutely.

00:45:40.560 --> 00:45:40.880
Yeah.

00:45:40.880 --> 00:45:42.920
So I think there's a bunch of opportunities for people to speak.

00:45:42.920 --> 00:45:44.600
And it's also, you can kind of level up, right?

00:45:44.600 --> 00:45:49.960
Like you do a talk at a user group and then that gives you the confidence to do a talk at like a regional conference.

00:45:49.960 --> 00:45:52.500
And then you can do, you know, whatever else you want to do.

00:45:52.500 --> 00:46:09.820
I was very pleasantly surprised at how rewarding it was and how validating it was that like me going from somebody who has like a very technical theoretical background and being kind of mildly obsessed with ASTs and learning about CPython's compiler and interpreter.

00:46:10.180 --> 00:46:19.140
And then being like, oh, yeah, I'm going to give a talk on this and having people be interested in it and want to talk about, you know, their perspectives and interests.

00:46:19.540 --> 00:46:31.660
So one of the things that I gained from doing this talk is seeing all the dozens of different interpretations and interests that people had that this talk sparked for them, which was really interesting.

00:46:31.660 --> 00:46:32.120
Yeah.

00:46:32.120 --> 00:46:32.620
Yeah.

00:46:32.620 --> 00:46:33.600
That's really rewarding.

00:46:33.600 --> 00:46:41.940
I guess last thought on this one is how much time did it take you to prepare this whole half hour presentation with all the research and everything?

00:46:41.940 --> 00:46:43.300
Like what kind of commitment was it?

00:46:43.300 --> 00:46:43.580
Yeah.

00:46:43.580 --> 00:46:47.320
I put 30 plus hours easy.

00:46:47.500 --> 00:46:50.760
So that's like more than 10 times.

00:46:50.760 --> 00:46:51.920
It was 30 minute talk.

00:46:51.920 --> 00:46:53.480
So 60 times.

00:46:53.480 --> 00:46:53.900
Yeah.

00:46:53.900 --> 00:46:59.960
That's it still seems about right because it's a lot of research and your talk was really well put together.

00:46:59.960 --> 00:47:00.580
So, yeah.

00:47:00.580 --> 00:47:04.420
And that's just so that's just the talk preparation itself.

00:47:04.420 --> 00:47:10.100
So I've been kind of iterating on my own like side research into CPython for.

00:47:10.100 --> 00:47:11.880
Oh, geez.

00:47:11.880 --> 00:47:13.480
Probably almost a year now.

00:47:13.480 --> 00:47:15.200
Maybe over a year.

00:47:16.640 --> 00:47:20.060
So there's definitely a lot of a lot of research that's gone into it.

00:47:20.060 --> 00:47:22.880
A lot of, you know, shower thoughts and all that stuff.

00:47:22.880 --> 00:47:23.160
Yeah.

00:47:23.160 --> 00:47:23.420
Yeah.

00:47:23.420 --> 00:47:23.660
Sure.

00:47:23.660 --> 00:47:25.860
Well, like I said, it was really good talk.

00:47:25.860 --> 00:47:28.200
We'll link to it from the show notes.

00:47:28.200 --> 00:47:29.240
People can go watch it.

00:47:29.240 --> 00:47:32.360
I think they just have like two whole days of video.

00:47:32.360 --> 00:47:34.480
So I have a timestamp in the link.

00:47:34.560 --> 00:47:35.880
So hopefully it starts playing.

00:47:35.880 --> 00:47:42.140
But if for some reason it doesn't, it's like two hours and 45 minutes into day two or something like that.

00:47:42.140 --> 00:47:44.660
But yeah, it was a really, really good talk.

00:47:44.660 --> 00:47:46.400
And I'm glad you gave it there.

00:47:46.400 --> 00:47:46.780
Thank you.

00:47:46.780 --> 00:47:47.860
I'm glad to have given it.

00:47:47.860 --> 00:47:48.360
Yeah.

00:47:48.780 --> 00:47:53.100
So let me hit with the final two questions before I let you out of here.

00:47:53.100 --> 00:47:56.660
First, if you're going to write some Python code, what editor do you use?

00:47:56.660 --> 00:48:01.520
I always use Sublime on a daily basis.

00:48:01.520 --> 00:48:07.880
I'm also really comfortable in VI and Vim just because I did a lot of sort of server management.

00:48:07.880 --> 00:48:09.940
So I can get around there.

00:48:09.940 --> 00:48:14.040
But I am a huge fan of Sublime's Anaconda package.

00:48:14.040 --> 00:48:15.200
Oh, that is really nice.

00:48:15.200 --> 00:48:15.460
Yeah.

00:48:15.460 --> 00:48:15.780
Yeah.

00:48:15.780 --> 00:48:16.880
That's not the regular.

00:48:16.880 --> 00:48:20.080
That's not Anaconda as in the NumPy scientific world.

00:48:20.080 --> 00:48:21.100
It's a totally different thing.

00:48:21.100 --> 00:48:22.160
Maybe tell people about it.

00:48:22.160 --> 00:48:29.560
It kind of brings a little bit of like the IDE experience to Sublime and allows you to

00:48:29.560 --> 00:48:33.380
highlight, you know, where a function is defined and that kind of stuff.

00:48:33.380 --> 00:48:33.620
Yeah.

00:48:33.620 --> 00:48:35.160
It's really a really nice add on for it.

00:48:35.160 --> 00:48:35.520
That's cool.

00:48:35.520 --> 00:48:38.380
And notable PyPI package.

00:48:38.380 --> 00:48:39.400
We talked about a bunch.

00:48:39.400 --> 00:48:41.180
Let's grab one of those or another one.

00:48:41.180 --> 00:48:41.520
Yeah.

00:48:41.520 --> 00:48:47.120
I think the one that I always have to talk about when people ask me this is the request library.

00:48:48.260 --> 00:48:56.380
So I think that was the first Python code that I saw that I was like, wow, this like it felt Pythonic to me.

00:48:56.380 --> 00:49:00.920
Like I was like, this is how interacting with a package should feel.

00:49:00.920 --> 00:49:08.340
And I think that Kenneth Reed always does a really excellent job of thinking about your package's API.

00:49:08.340 --> 00:49:12.940
All of your code and your classes and all that have an API that humans have to interact with.

00:49:12.940 --> 00:49:15.360
I love that that's a theme for all of his work.

00:49:15.360 --> 00:49:15.600
Yeah.

00:49:15.600 --> 00:49:17.860
The tagline, all of his stuff is for humans.

00:49:17.860 --> 00:49:19.800
Requests is for humans.

00:49:19.800 --> 00:49:22.980
And then records is like SQL for humans and all sorts of stuff.

00:49:22.980 --> 00:49:23.160
Yeah.

00:49:23.160 --> 00:49:23.660
Yeah.

00:49:23.660 --> 00:49:24.540
Definitely good stuff.

00:49:24.540 --> 00:49:25.820
He's doing really, really good work.

00:49:25.820 --> 00:49:26.880
All right.

00:49:26.880 --> 00:49:28.680
So final call to action.

00:49:28.680 --> 00:49:29.960
People are excited about the stuff.

00:49:29.960 --> 00:49:30.780
They want to learn more.

00:49:30.780 --> 00:49:34.300
I mean, obviously they should check out your talk, but what else can they do to get started?

00:49:34.300 --> 00:49:36.100
That is a great question.

00:49:36.100 --> 00:49:43.200
I would encourage people to find the way that they want to apply ASTs.

00:49:43.200 --> 00:49:59.400
So whether that's in linting or code highlighting or actually like getting in there and messing around with ASTs and find something that is like a really small thing that you can tweak and have fun with and see how you can actually improve your current workflow.

00:49:59.600 --> 00:49:59.760
Yeah.

00:49:59.760 --> 00:50:00.460
That sounds awesome.

00:50:00.460 --> 00:50:00.860
All right.

00:50:00.860 --> 00:50:03.180
Well, Emily, thank you so much for being on the show.

00:50:03.180 --> 00:50:07.000
It was great to chat with you and thanks for sharing your AST project with us.

00:50:07.000 --> 00:50:07.460
Thank you.

00:50:07.460 --> 00:50:07.900
Yep.

00:50:07.900 --> 00:50:08.100
Bye.

00:50:09.780 --> 00:50:12.500
This has been another episode of Talk Python To Me.

00:50:12.500 --> 00:50:15.180
Today's guest was Emily Morehouse.

00:50:15.180 --> 00:50:18.480
And this episode has been brought to you by ParkMyCloud and Rollbar.

00:50:18.480 --> 00:50:20.980
Do you hear that sucking noise?

00:50:20.980 --> 00:50:24.500
That's your cloud provider making you pay for your idle instances.

00:50:24.500 --> 00:50:27.840
Turn on ParkMyCloud, plug the leaks and save money.

00:50:27.840 --> 00:50:30.940
Visit talkpython.fm/park to get started.

00:50:30.940 --> 00:50:33.880
Rollbar takes the pain out of errors.

00:50:33.980 --> 00:50:41.580
They give you the context and insight you need to quickly locate and fix errors that might have gone unnoticed until your users complain, of course.

00:50:41.580 --> 00:50:48.660
As Talk Python To Me listeners, track a ridiculous number of errors for free at rollbar.com slash talkpythontome.

00:50:48.660 --> 00:50:51.420
Are you or a colleague trying to learn Python?

00:50:51.420 --> 00:50:56.080
Have you tried books and videos that just left you bored by covering topics point by point?

00:50:56.480 --> 00:51:04.680
Well, check out my online course, Python Jumpstart, by building 10 apps at talkpython.fm/course to experience a more engaging way to learn Python.

00:51:04.680 --> 00:51:12.040
And if you're looking for something a little more advanced, try my Write Pythonic Code course at talkpython.fm/pythonic.

00:51:13.040 --> 00:51:14.760
Be sure to subscribe to the show.

00:51:14.760 --> 00:51:16.960
Open your favorite podcatcher and search for Python.

00:51:16.960 --> 00:51:18.200
We should be right at the top.

00:51:18.200 --> 00:51:27.520
You can also find the iTunes feed at /itunes, Google Play feed at /play, and direct RSS feed at /rss on talkpython.fm.

00:51:27.520 --> 00:51:29.380
This is your host, Michael Kennedy.

00:51:29.380 --> 00:51:30.740
Thanks so much for listening.

00:51:30.740 --> 00:51:31.820
I really appreciate it.

00:51:31.820 --> 00:51:33.760
Now get out there and write some Python code.

00:51:33.760 --> 00:51:54.480
I really appreciate it.