WEBVTT 00:00:00.001 --> 00:00:05.680 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. 00:00:05.680 --> 00:00:11.040 This is episode 109, recorded December 10th, 2018. I'm Michael Kennedy. 00:00:11.040 --> 00:00:11.960 And I'm Brian Okken. 00:00:11.960 --> 00:00:17.080 And this episode is brought to you by DigitalOcean. Thank you, thank you, DigitalOcean. Tell you more about them later. 00:00:17.080 --> 00:00:19.460 Right now, Brian, how is everything going? 00:00:19.460 --> 00:00:21.060 It's going really well. How about you? 00:00:21.060 --> 00:00:29.740 Oh, it's super. I'm starting to think of year in review, like what was the most amazing Python stories of the year and things like that. 00:00:29.740 --> 00:00:33.120 So looking forward to sharing those with everyone, actually. 00:00:33.120 --> 00:00:34.180 Yeah, that'd be great. 00:00:34.180 --> 00:00:46.120 Yeah. So you and I actually did an episode along with Dan Bader on Talk Python, which we'll drop here on this channel as well for the year in review in Python news, which is like this, but more stuff in more depth. 00:00:46.120 --> 00:00:49.760 So that'll be a good thing for, you know, all those people traveling for the holidays, right? 00:00:49.760 --> 00:00:51.240 Yeah. Give them something to listen to. 00:00:51.240 --> 00:00:57.000 All right. They may be stuck in an ice storm in Chicago, O'Hare, but they can listen to some good Python news. 00:00:57.000 --> 00:00:57.320 Yeah. 00:00:58.020 --> 00:01:00.720 That's right. Speaking of good Python news, what do you got to kick us off this time? 00:01:00.720 --> 00:01:02.600 I have a Python descriptor. 00:01:02.600 --> 00:01:06.760 I have Python descriptors are magical creatures. 00:01:06.760 --> 00:01:07.760 That sounds awesome. 00:01:07.760 --> 00:01:10.300 Yeah. This is actually kind of a neat approach. 00:01:10.300 --> 00:01:15.140 This article thinking, yeah, I know what descriptors are and stuff and properties. 00:01:15.140 --> 00:01:18.380 It's talking about properties of object properties in Python. 00:01:18.380 --> 00:01:20.400 But this is a really great article. 00:01:20.400 --> 00:01:23.200 So this is an article by Pablo Arias. 00:01:23.880 --> 00:01:31.180 And it talks about how you can add getters and setters to and properties to objects. 00:01:31.180 --> 00:01:41.300 So you can have like, instead of calling a function like get version, you can just have like version and, and you can use like object dot version and you can assign to that. 00:01:41.300 --> 00:01:43.640 And that'll call the setter. 00:01:43.640 --> 00:01:48.080 And if you read from it, that'll call the getter and you can have custom functions for that. 00:01:48.080 --> 00:01:50.040 It's one of the cool things about Python. 00:01:50.040 --> 00:01:58.520 And, and one that I'm glad that it's been highlighted because some people forget this is around, especially if you come from a language that doesn't have this sort of thing. 00:01:58.520 --> 00:02:00.260 See Java, that kind of stuff, right? 00:02:00.260 --> 00:02:00.680 Yeah. 00:02:00.680 --> 00:02:01.920 These are pretty neat. 00:02:01.920 --> 00:02:08.280 And they, they make it look like an attribute of the object, but it's actually a function that gets called. 00:02:08.280 --> 00:02:10.360 And it's a way you can actually migrate. 00:02:10.360 --> 00:02:14.520 You can start a system where it really is just data that's sitting there. 00:02:14.640 --> 00:02:22.540 And if you want to intercept it and say, you know, actually when somebody assigns to this, I want to do some work or I don't want to really store this data. 00:02:22.540 --> 00:02:24.100 I want to calculate it on the fly. 00:02:24.100 --> 00:02:28.920 I mean, you can turn those into getters and setters and the calling code doesn't need to know. 00:02:28.920 --> 00:02:29.100 Yeah. 00:02:29.100 --> 00:02:35.420 I really like this because often the API makes the most sense as sort of fields, just setting the attributes, right? 00:02:35.420 --> 00:02:39.220 Like user dot name, user dot first name or something like that. 00:02:39.220 --> 00:02:41.760 But what if you want validation, right? 00:02:41.760 --> 00:02:44.560 Like the name can't contain white spaces or other weird stuff. 00:02:44.580 --> 00:02:49.480 If you want to strip that off or, you know, username is always lowercase and things like that. 00:02:49.480 --> 00:02:51.260 So properties are perfect for that, right? 00:02:51.260 --> 00:02:52.220 You can validate it. 00:02:52.220 --> 00:02:56.440 You can raise an exception that says you can't have a none value here. 00:02:56.440 --> 00:02:58.600 It has to be a non-empty string, all kinds of good stuff. 00:02:58.600 --> 00:03:00.300 But the consumer doesn't care. 00:03:00.300 --> 00:03:01.060 They don't have to know. 00:03:01.060 --> 00:03:01.340 Yeah. 00:03:01.340 --> 00:03:08.840 And I personally actually have used a get and set methods before, but the getters and setters, but there's a deleter also. 00:03:08.840 --> 00:03:10.860 And I don't think I use that very much. 00:03:10.860 --> 00:03:23.360 And it's kind of probably a neat thing to stick in place if you're doing this anyway to make sure if it's invalid for somebody to try to delete an attribute, you may want to intercept that. 00:03:23.360 --> 00:03:23.880 Yeah. 00:03:23.880 --> 00:03:25.600 No, you always have a name. 00:03:25.600 --> 00:03:26.540 You can't delete it. 00:03:27.820 --> 00:03:28.260 Yeah. 00:03:28.260 --> 00:03:31.680 But this is a good general introduction to how to use these. 00:03:31.680 --> 00:03:35.460 And so people can clean up their code a little bit, make it look a little less Java-y. 00:03:35.460 --> 00:03:35.800 Yep. 00:03:35.800 --> 00:03:36.500 I totally agree. 00:03:36.500 --> 00:03:40.120 So the next one is I want to talk about a survey. 00:03:40.280 --> 00:03:46.900 So we've talked about the JetBrains Python survey and that data science featured heavily in it. 00:03:46.900 --> 00:03:53.340 But they also did a separate data science survey for just data scientists and asked data science-y questions only. 00:03:53.340 --> 00:04:00.200 So they pulled about 1,600 people who are data scientists based in the U.S., Europe, China, and Japan. 00:04:00.620 --> 00:04:08.120 And to figure out what's the story, what's the zen, and how are people feeling in the data science space right now. 00:04:08.120 --> 00:04:10.180 And so it wasn't just for Python. 00:04:10.180 --> 00:04:11.620 It was just for data scientists. 00:04:11.620 --> 00:04:17.740 But you can imagine that there are many Python things happening in the data science world, right? 00:04:17.740 --> 00:04:27.780 So one of the key takeaways was that most people assume, or currently most people use Python, and then they assume that Python will remain the primary programming language at least for five years. 00:04:27.780 --> 00:04:31.100 Yeah, and that's essentially forever in computer time. 00:04:31.100 --> 00:04:31.780 That's right. 00:04:31.780 --> 00:04:38.360 If you're planning past five years, you've got either a lot of faith in where things are going or you're doing it wrong. 00:04:38.360 --> 00:04:40.120 Those actually could be the same thing. 00:04:40.120 --> 00:04:41.020 All right. 00:04:41.020 --> 00:04:46.320 They also talked about what are the main tools people are using for machine learning stuff. 00:04:46.320 --> 00:04:50.440 And they said Keras is the main one for professional developers. 00:04:50.980 --> 00:04:59.320 Whereas if you're an amateur data scientist, you're more likely to use Microsoft Azure machine learning services rather than libraries. 00:04:59.320 --> 00:05:01.480 So you're like, just make this a model. 00:05:01.480 --> 00:05:02.160 Teach it stuff. 00:05:02.160 --> 00:05:03.220 Figure that out later. 00:05:03.220 --> 00:05:08.540 Whereas the pros, in quote, are actually doing the straight API stuff. 00:05:08.540 --> 00:05:09.920 And remind me what Keras is? 00:05:09.920 --> 00:05:11.460 Keras is a machine learning framework. 00:05:11.460 --> 00:05:11.760 Okay. 00:05:11.880 --> 00:05:12.040 Yeah. 00:05:12.040 --> 00:05:14.240 So it's sort of comparable to Azure ML. 00:05:14.240 --> 00:05:15.940 But Azure ML is a service. 00:05:15.940 --> 00:05:17.080 Like machine learning is a service. 00:05:17.080 --> 00:05:17.980 I haven't ever used it, though. 00:05:17.980 --> 00:05:18.220 Okay. 00:05:18.220 --> 00:05:18.860 So let's see. 00:05:18.860 --> 00:05:20.280 Main programming languages. 00:05:20.280 --> 00:05:22.500 Obviously, there are other languages. 00:05:23.000 --> 00:05:35.000 And if you look back just a couple years, right, R was a machine learning and data science-y language that was more popular than Python was for data science. 00:05:35.000 --> 00:05:37.040 But now Python is 57%. 00:05:37.040 --> 00:05:38.920 R is only 15%. 00:05:38.920 --> 00:05:42.280 Some people say Julia is the next big language for data scientists. 00:05:42.280 --> 00:05:45.360 So they asked about Julia of these 1,600 people. 00:05:45.360 --> 00:05:47.420 And the number of people using it was 0%. 00:05:47.420 --> 00:05:51.040 So that's not super compelling for Julia, I guess. 00:05:52.480 --> 00:05:56.560 At least amongst this data, this statistical set. 00:05:56.560 --> 00:05:57.560 Yeah, yeah, yeah. 00:05:57.560 --> 00:06:01.600 And honestly, I forgot how they found this set of people. 00:06:01.600 --> 00:06:03.440 So I'm sure they talk about it in the write-up. 00:06:03.440 --> 00:06:09.800 And then finally, when you talk about IDEs and editors, there were three standout main things people used. 00:06:09.800 --> 00:06:13.020 Obviously, Jupyter, Jupyter Notebooks, JupyterLab was 43%. 00:06:13.020 --> 00:06:15.020 PyCharm was 38%. 00:06:15.020 --> 00:06:17.920 And RStudio was 23%. 00:06:17.920 --> 00:06:19.460 So that's pretty interesting. 00:06:19.460 --> 00:06:19.860 Yeah. 00:06:19.860 --> 00:06:20.180 Yep. 00:06:20.180 --> 00:06:21.440 All right. 00:06:21.440 --> 00:06:27.340 So if you're in the data science space, maybe this will help you keep your pulse on, keep the pulse of what's going on there. 00:06:27.340 --> 00:06:28.860 I want to highlight a little tool. 00:06:28.860 --> 00:06:36.500 So like I talked about properties just as a nice technique of people should make sure they understand how those work. 00:06:36.500 --> 00:06:40.260 Another thing, I've ran across memoization. 00:06:40.780 --> 00:06:46.740 It's a technique. 00:06:46.740 --> 00:06:55.300 This is a technique to, if you've got a function or something, some work that you need to do that's dependent on input data, only dependent on the input parameters. 00:06:56.000 --> 00:07:05.960 But to get your answer, you have to, it's computationally intensive. 00:07:05.960 --> 00:07:16.380 You have to get your answer to that. 00:07:16.380 --> 00:07:26.340 If you find the, if you get past the same arguments again, just return the answer that you've already calculated. 00:07:26.340 --> 00:07:36.240 If you have some function that you're calling with relatively bounded set of inputs and it's at all computationally expensive or it goes to a service and it gets an answer back. 00:07:36.600 --> 00:07:41.380 Like you said, if the input is the only thing that drives it, it's not like, well, what's the weather at the zip code? 00:07:41.380 --> 00:07:42.320 Because that could always change. 00:07:42.320 --> 00:07:48.980 But it's like, you know, what's the limit of this integral when passing in, you know, this lower bound, you know, like discrete integral or something. 00:07:48.980 --> 00:07:49.740 Right. 00:07:49.740 --> 00:07:51.460 It's always going to give you the same answer back. 00:07:51.460 --> 00:07:53.120 So you can actually go to the function. 00:07:53.120 --> 00:07:56.500 Even with the func tools built into Python, you can say, I want this function. 00:07:56.500 --> 00:08:00.240 If it gets the same arguments to not run again, just give the answer back. 00:08:00.240 --> 00:08:01.560 It's kind of stored memory or somewhere. 00:08:01.560 --> 00:08:01.840 Right. 00:08:01.840 --> 00:08:03.860 And that, that only works in process. 00:08:03.860 --> 00:08:04.260 Yeah. 00:08:04.620 --> 00:08:12.020 One of the things I wanted to highlight is a project called cache.py that saves all this stuff off to a file. 00:08:12.020 --> 00:08:17.560 This would be helpful, especially if you've got a, like a command line tool that gets called lots of times. 00:08:17.560 --> 00:08:20.220 It isn't going to be able to store everything in memory. 00:08:20.220 --> 00:08:22.780 So being able to save it in a file might be helpful. 00:08:22.780 --> 00:08:28.040 The interface is just a decorator to say, hey, this function, you can cache the results. 00:08:28.040 --> 00:08:31.420 So you throw a decorator on it called, it's just cache.cache. 00:08:32.480 --> 00:08:33.580 Decorator onto your function. 00:08:33.580 --> 00:08:35.000 And it just works. 00:08:35.000 --> 00:08:37.680 And there's a whole bunch of customization you can do. 00:08:37.680 --> 00:08:44.340 You can say how, how long the cache is good for or, and where the, where the file should be and things like that. 00:08:44.340 --> 00:08:46.240 But the default just kind of works pretty good too. 00:08:46.240 --> 00:08:46.560 Yeah. 00:08:46.560 --> 00:08:47.360 I really like this. 00:08:47.360 --> 00:08:51.500 So the thing is the built-in stuff only works in memory. 00:08:51.500 --> 00:08:54.320 And so once the process is done, it's done. 00:08:54.320 --> 00:09:06.420 But like you said, if this is a command line tool you're stringing together and you want it to keep that data for a certain amount of time or just always keep it so that it's like, well, if you pass me seven, the answer is always going to be this. 00:09:06.420 --> 00:09:06.680 Right? 00:09:06.680 --> 00:09:06.980 Yeah. 00:09:06.980 --> 00:09:07.740 That's, yeah. 00:09:07.740 --> 00:09:09.880 It's great that that'll keep it on the file system. 00:09:09.880 --> 00:09:11.280 And it uses pickle, right? 00:09:11.280 --> 00:09:12.060 I'm not sure. 00:09:12.060 --> 00:09:12.480 Yeah. 00:09:12.480 --> 00:09:13.620 Let's see. 00:09:14.420 --> 00:09:14.580 Yeah. 00:09:14.580 --> 00:09:18.060 Currently uses pickle and inspect under the hood, making it not portable. 00:09:18.060 --> 00:09:24.800 So you can't like take your cache file and move it to windows when you ran it on Linux or something, I believe. 00:09:24.800 --> 00:09:25.180 Yeah. 00:09:25.180 --> 00:09:28.140 Because of memory structure and different versions of Python and so on. 00:09:28.140 --> 00:09:31.300 So what, remind me, what was the built-in one that works in memory? 00:09:31.300 --> 00:09:34.620 It's on functools and it's an LRU cache, I believe. 00:09:34.620 --> 00:09:35.580 Okay. 00:09:35.580 --> 00:09:37.020 Functools, LRU cache. 00:09:37.020 --> 00:09:37.300 Yeah. 00:09:37.300 --> 00:09:37.880 Yeah. 00:09:37.880 --> 00:09:38.240 Yeah. 00:09:38.240 --> 00:09:44.400 I brought this up also mostly because I know a lot of people teach them, learn on the job or teach them. 00:09:44.400 --> 00:09:52.580 I'm not bragging that I have a computer science degree, but this is one of those topics that you probably don't come up with on your own. 00:09:52.580 --> 00:09:59.700 It's a clever thing and a nice, useful tool for your toolbox, but it's not something that's obvious. 00:09:59.700 --> 00:10:01.800 It wasn't obvious to me until I learned about it. 00:10:01.800 --> 00:10:02.040 Yeah. 00:10:02.040 --> 00:10:02.460 Same here. 00:10:02.460 --> 00:10:07.020 I think the first time I learned about this was when I started studying design patterns and stuff like that. 00:10:07.020 --> 00:10:08.040 And somehow it came up in there. 00:10:08.040 --> 00:10:09.280 I'm like, oh, that's pretty clever. 00:10:09.280 --> 00:10:09.920 Yeah. 00:10:10.000 --> 00:10:10.140 Yeah. 00:10:10.140 --> 00:10:18.560 When you are working with code and it's slow, to me, it seems like there's two things that are really, really powerful that can just go, oh, well, now it's a hundred times faster. 00:10:18.560 --> 00:10:19.040 That's cool. 00:10:19.040 --> 00:10:20.720 And that was like one line of code. 00:10:21.680 --> 00:10:24.860 You know, one is using the wrong kind of data structure. 00:10:24.860 --> 00:10:31.620 Like if you're using a list, but you really should use a set because you're testing for membership on a big set, something like that or dictionaries or whatever. 00:10:31.620 --> 00:10:33.860 The other one is this kind of caching, right? 00:10:33.860 --> 00:10:43.560 Like if you're doing something and it takes a long time, even if it's going out to the internet and calling a service, like if you think that data changes once a day, it'd be totally great to put like a one minute cache on that. 00:10:43.560 --> 00:10:44.800 If you're calling it a bunch of times. 00:10:44.800 --> 00:10:45.100 Yeah. 00:10:45.100 --> 00:10:53.040 And it can, like you said, it can, it can make a massive improvement speed up and it's like sort of an obvious of, you know, after you see it, you're like, well, yeah, duh. 00:10:53.040 --> 00:10:53.960 I didn't even think of that. 00:10:53.960 --> 00:10:54.340 Absolutely. 00:10:54.340 --> 00:11:03.120 So I really think, I think this is a cool one because it takes that idea and it just makes it easy to carry it across different processes or different runs of the same process. 00:11:03.120 --> 00:11:03.780 Okay. 00:11:03.780 --> 00:11:07.380 So before we get on the next one, let me just tell you all about DigitalOcean. 00:11:07.380 --> 00:11:08.920 They're doing all sorts of cool stuff. 00:11:08.920 --> 00:11:10.160 Our infrastructure runs on it. 00:11:10.160 --> 00:11:12.180 Really, really nice and reliable. 00:11:12.620 --> 00:11:21.960 One of the things I want to highlight this time is their work with Kubernetes, Docker and coordinating Docker, orchestrating Docker stuff with Kubernetes is a big deal these days. 00:11:21.960 --> 00:11:27.500 And so they're launching a new Kubernetes cluster over at DigitalOcean. 00:11:27.500 --> 00:11:31.460 So a really nice way to manage and deploy your container workloads in the cloud. 00:11:31.460 --> 00:11:39.860 And if you go to pythonbytes.fm/DigitalOcean and you're a new user, you get $100 credit to Kubernetes all the way if you want. 00:11:40.500 --> 00:11:42.660 You can run a lot of Kubernetes for $100 in the cloud. 00:11:42.660 --> 00:11:43.960 So that's pretty awesome. 00:11:43.960 --> 00:11:45.420 That's, yeah, very cool. 00:11:45.420 --> 00:11:45.640 Yeah. 00:11:45.640 --> 00:11:48.060 So check them out, pythonbytes.fm/DigitalOcean. 00:11:48.060 --> 00:11:51.640 They're big supporters of the show and they keep us going strong each week, don't they? 00:11:51.640 --> 00:11:52.000 Yeah. 00:11:52.000 --> 00:11:53.180 I'm very grateful for them. 00:11:53.180 --> 00:11:53.480 Yep. 00:11:53.480 --> 00:11:56.360 The next one I want to tell you about is a really short video. 00:11:56.360 --> 00:11:59.720 Last week, I covered an hour and a half video about being an expert on Python. 00:11:59.720 --> 00:12:02.140 How about we cut this down to like a four minute one? 00:12:02.840 --> 00:12:09.060 So I think this one is really good for people who are getting into data science and they have a little bit of a challenge. 00:12:09.060 --> 00:12:11.680 If you're an expert, this is definitely not the video for you. 00:12:11.680 --> 00:12:14.400 But this is called Setting Up the Data Science Tools. 00:12:14.400 --> 00:12:16.800 And so it's part of a larger video series. 00:12:16.800 --> 00:12:24.240 But it basically shows you how to set up the Anaconda distribution, TensorFlow, Keras, Jupyter, all those things. 00:12:24.240 --> 00:12:31.640 And it actually talks about using Conda, Conda virtual environments, creating notebooks and switching between virtual environments. 00:12:31.640 --> 00:12:37.880 So if you've been mostly working with pip or you see examples in pip and you want to do more Anaconda stuff, this is a great video. 00:12:37.880 --> 00:12:43.080 And especially if you want to install some of these tools and get going and you're kind of new, this is a great way to get going. 00:12:43.080 --> 00:12:43.800 That's awesome. 00:12:43.800 --> 00:12:44.320 Yeah. 00:12:44.320 --> 00:12:44.780 Cool. 00:12:44.780 --> 00:12:45.260 Yeah, it's great. 00:12:45.260 --> 00:12:50.160 I was just talking to somebody who was really new to Python and super eager to get going. 00:12:50.160 --> 00:12:55.620 But he was having a problem because he was working on a computer that he didn't have admin access to. 00:12:55.620 --> 00:13:02.840 And so when he would try to pip install something, it would try to put it in the system-wide thing, which you'd have to to make that happen. 00:13:02.840 --> 00:13:03.180 You shouldn't. 00:13:03.180 --> 00:13:05.740 But if you wanted it to happen for sure, you could do sudo. 00:13:05.740 --> 00:13:09.700 But he wasn't allowed to basically run his admin to do that. 00:13:09.700 --> 00:13:10.500 Right? 00:13:10.500 --> 00:13:12.840 So I'm like, oh, you just need to use a virtual environment. 00:13:12.840 --> 00:13:14.300 Then you can do whatever you want to your machine. 00:13:14.300 --> 00:13:16.000 It's like, oh, wonderful. 00:13:16.000 --> 00:13:16.300 Right? 00:13:16.300 --> 00:13:20.980 So I think it might sound like old hat to folks that have been doing it for a long time. 00:13:20.980 --> 00:13:22.800 But when you're new to it, that's not obvious. 00:13:22.800 --> 00:13:23.120 Right? 00:13:23.120 --> 00:13:24.600 Like, my Python won't install. 00:13:24.600 --> 00:13:26.000 Well, if you had a virtual environment, it would. 00:13:26.000 --> 00:13:27.840 Or you did these other steps, it would. 00:13:27.840 --> 00:13:28.000 Right? 00:13:28.000 --> 00:13:28.360 Right. 00:13:28.360 --> 00:13:38.880 And also, somebody like me that is used to virtual environments, it's still not obvious how to do that in an Anaconda environment. 00:13:38.880 --> 00:13:39.480 Exactly. 00:13:39.480 --> 00:13:42.200 I have to look it up every time because I'm all about pip. 00:13:42.200 --> 00:13:43.240 And I was like, wait a minute. 00:13:43.240 --> 00:13:44.760 It's a different way to activate. 00:13:44.860 --> 00:13:46.140 It's like a global activate command. 00:13:46.140 --> 00:13:46.760 Where's the list? 00:13:46.760 --> 00:13:47.720 How do I know what exists? 00:13:47.720 --> 00:13:48.640 Yeah, it's different. 00:13:48.640 --> 00:13:51.000 So I'm sure I could actually use this as well. 00:13:51.000 --> 00:13:51.220 Cool. 00:13:51.220 --> 00:13:53.820 Beginner means beginner to Anaconda in data science tools. 00:13:53.820 --> 00:13:55.100 Not true beginner, right? 00:13:55.100 --> 00:13:55.380 Yeah. 00:13:55.380 --> 00:13:55.760 Awesome. 00:13:55.760 --> 00:13:56.420 All right. 00:13:56.420 --> 00:14:01.160 Speaking of data science, I bet data scientists draw a lot of graphs, right? 00:14:01.160 --> 00:14:01.580 Yeah. 00:14:01.580 --> 00:14:03.220 Well, lots of people draw a lot of graphs. 00:14:03.220 --> 00:14:05.960 Last time I tried to use Boca or Bokeh. 00:14:05.960 --> 00:14:07.440 I keep saying that wrong. 00:14:07.440 --> 00:14:09.840 You don't need to email me that I'm saying it wrong. 00:14:09.840 --> 00:14:11.000 I know it's Bokeh. 00:14:11.000 --> 00:14:12.680 It's B-O-K-E-H. 00:14:13.000 --> 00:14:15.340 It is a very powerful charting tool. 00:14:15.340 --> 00:14:21.360 I believe it's not the most simplest interface to figure out as a newbie. 00:14:21.360 --> 00:14:25.940 And it's not like Matplotlib is super easy either. 00:14:26.320 --> 00:14:28.120 But a lot of people know about it. 00:14:28.120 --> 00:14:30.480 But Bokeh, yeah, it's not bad. 00:14:30.480 --> 00:14:33.300 It's just if you're a beginner, maybe there's an easier way. 00:14:33.300 --> 00:14:35.100 And this is the easier way. 00:14:35.100 --> 00:14:41.180 One of the easier ways is a package called Chartify that simplifies a lot of the defaults. 00:14:41.180 --> 00:14:43.680 And it's built on top of Bokeh. 00:14:44.180 --> 00:14:47.480 So if you've got some data and you want to throw it into a chart, this is a nice way 00:14:47.480 --> 00:14:47.920 to do it. 00:14:47.920 --> 00:14:52.680 It fills out a whole bunch of the defaults to where it starts out fairly pretty to start 00:14:52.680 --> 00:14:52.920 with. 00:14:52.920 --> 00:14:56.760 So simplifying the API for newbies into Bokeh. 00:14:56.760 --> 00:14:57.460 Oh, that's great. 00:14:57.460 --> 00:15:00.360 I do find it a little overwhelming because you can do everything, right? 00:15:00.360 --> 00:15:01.800 You can specify so much detail. 00:15:01.800 --> 00:15:04.440 I'm like, sometimes I'm just like, you know, I could just use like a histogram. 00:15:04.440 --> 00:15:05.000 Wouldn't that? 00:15:05.000 --> 00:15:05.860 That would be awesome. 00:15:05.860 --> 00:15:06.720 Can we just do a histogram? 00:15:08.220 --> 00:15:08.580 Yeah. 00:15:08.580 --> 00:15:13.140 And if I got a bunch of different, you know, I want to be able to pick the colors fairly 00:15:13.140 --> 00:15:13.780 easily. 00:15:13.780 --> 00:15:16.160 And I don't really care, but I just want it to look nice. 00:15:16.160 --> 00:15:16.440 Yeah. 00:15:16.440 --> 00:15:21.280 They also have a bunch of nice examples, example notebooks and stuff that walk you through using 00:15:21.280 --> 00:15:21.480 it. 00:15:21.480 --> 00:15:23.180 So yeah, it's a great little resource. 00:15:23.180 --> 00:15:23.420 Yeah. 00:15:23.420 --> 00:15:27.780 Speaking of Jupyter and examples and notebooks and stuff, I want to stick with that for the 00:15:27.780 --> 00:15:28.540 last one here. 00:15:28.540 --> 00:15:32.200 And it's called the CPython Bytecode Explorer. 00:15:32.200 --> 00:15:37.700 Most people probably know this at least at some level, but I'm sure not everyone does. 00:15:37.800 --> 00:15:42.440 When you run your Python code, it loads it up and it compiles it to bytecode. 00:15:42.440 --> 00:15:43.400 And you're like, wait, what? 00:15:43.400 --> 00:15:44.920 Python's interpreted. 00:15:44.920 --> 00:15:45.620 It's not compiled. 00:15:45.620 --> 00:15:49.640 So it compiles your source code into bytecode. 00:15:49.640 --> 00:15:55.180 And those bytecodes are interpreted on top of the CPython, like a big loop that just runs 00:15:55.180 --> 00:15:56.420 goes, okay, what's the next bytecode? 00:15:56.420 --> 00:15:57.000 Let's do that. 00:15:57.000 --> 00:16:02.100 So understanding what those bytecodes are, how complex is something? 00:16:02.100 --> 00:16:05.180 Is it an atomic operation or does it take multiple steps? 00:16:05.180 --> 00:16:07.500 All of those things you might wonder about. 00:16:07.500 --> 00:16:09.660 So this was sent to us by Anton Helm. 00:16:09.660 --> 00:16:13.200 And it's created by this guy named Jeremy Tulup. 00:16:13.200 --> 00:16:19.460 And what it is, is it's a plugin for JupyterLab, not Jupyter Notebooks, but the more full-featured 00:16:19.460 --> 00:16:20.020 JupyterLab. 00:16:20.420 --> 00:16:27.380 And what it does is it lets you look at the bytecode of various things that you're, various operations 00:16:27.380 --> 00:16:28.220 that you're working on. 00:16:28.220 --> 00:16:33.680 So if you pull up that thing, Brian, the link there, you can see there's a little animated 00:16:33.680 --> 00:16:35.340 gif that shows you what's happening. 00:16:35.340 --> 00:16:38.080 So it's creating like an A, B, and a C equals A plus B. 00:16:38.340 --> 00:16:43.760 And there's just on the right as you type, it just shows you the bytecode of those. 00:16:43.760 --> 00:16:48.040 So I think this is a great way to explore working with Python. 00:16:48.040 --> 00:16:52.340 If you want to understand more of this low-level bytecode thing. 00:16:52.340 --> 00:16:52.900 Yeah. 00:16:53.080 --> 00:17:00.820 This would be awesome just in teaching, especially if you're going to talk about how names work 00:17:00.820 --> 00:17:01.540 in Python. 00:17:01.540 --> 00:17:06.280 This would be kind of fun to use to see how it all points to the same thing and whatnot. 00:17:06.280 --> 00:17:07.120 Yeah. 00:17:07.160 --> 00:17:10.360 Another example that's cool, if you go to the very bottom, there's a bunch of little 00:17:10.360 --> 00:17:11.220 animated gifs here. 00:17:11.220 --> 00:17:18.780 And the very bottom one shows the two operations looping over just the numbers 0 to 9. 00:17:18.780 --> 00:17:23.700 And you can either do this by a while loop, you create the while loop, and you have i less 00:17:23.700 --> 00:17:29.400 than 10, i plus equals 1, or you can just say 4i in range of 0 to 10. 00:17:29.400 --> 00:17:35.440 And they show it side by side comparing the disassembled bytecode of both of them. 00:17:35.800 --> 00:17:40.680 And surprise, surprise, the foreign loop is a lot fewer bytecode operations. 00:17:40.680 --> 00:17:41.940 So it's probably faster. 00:17:41.940 --> 00:17:42.720 That's cool. 00:17:42.720 --> 00:17:43.140 Cool, right? 00:17:43.140 --> 00:17:48.740 There's even a demo that shows that you can see the, have Python 3.6 and Python 3.7 running 00:17:48.740 --> 00:17:49.760 side by side. 00:17:49.760 --> 00:17:50.240 Yeah. 00:17:50.240 --> 00:17:56.620 In the same JupyterLab view, you can have different versions of Python with the same code to understand 00:17:56.620 --> 00:17:58.680 how bytecodes have evolved over time. 00:17:58.680 --> 00:17:59.540 That's trippy. 00:17:59.540 --> 00:17:59.860 Yeah. 00:17:59.860 --> 00:18:00.320 Neat. 00:18:00.320 --> 00:18:00.680 I know. 00:18:00.680 --> 00:18:04.780 So if you want to understand bytecodes, this is pretty trippy here. 00:18:04.780 --> 00:18:05.000 Yeah. 00:18:05.000 --> 00:18:09.020 Like you said, if you're teaching people about this kind of stuff, I think this would be 00:18:09.020 --> 00:18:09.760 an awesome resource. 00:18:09.760 --> 00:18:10.180 Yeah. 00:18:10.180 --> 00:18:10.860 Nice. 00:18:10.860 --> 00:18:11.280 Cool. 00:18:11.280 --> 00:18:11.500 Yeah. 00:18:11.500 --> 00:18:13.400 Really good to just dig in to understand it. 00:18:13.400 --> 00:18:16.280 That's it for our six items this week, Brian. 00:18:16.280 --> 00:18:20.260 But I was wondering, how is the internet made? 00:18:20.260 --> 00:18:22.260 Is it like factory? 00:18:22.920 --> 00:18:25.220 Is it like, are there internet trees? 00:18:25.220 --> 00:18:25.900 Yeah. 00:18:25.900 --> 00:18:29.500 I was contemplating whether or not to bring this up, but I... 00:18:29.500 --> 00:18:30.180 It's too late now. 00:18:30.180 --> 00:18:30.620 Yeah. 00:18:30.620 --> 00:18:33.880 I saw on, I'm a little addicted to Twitter. 00:18:33.880 --> 00:18:37.900 So somebody passed around this little video called How the Internet is Made. 00:18:38.300 --> 00:18:39.620 And we're going to put a link to it. 00:18:39.620 --> 00:18:45.380 And it's hard to describe, but it's just this complete silliness of these like old time 00:18:45.380 --> 00:18:48.260 videos of how things are made and stuff. 00:18:48.260 --> 00:18:53.760 It gets shipped from here to there and gets rolled across the field with barrels and stuff. 00:18:53.760 --> 00:18:55.100 And it's bizarre. 00:18:55.100 --> 00:18:57.580 But it made me laugh so hard. 00:18:57.580 --> 00:19:01.320 It's like an old timey silent movie with subtitles. 00:19:01.320 --> 00:19:04.080 It's like a documentary on how the internet is made. 00:19:04.080 --> 00:19:07.200 So it starts out, has lots of gears and cambers and things. 00:19:07.200 --> 00:19:10.380 Then eventually it's put into wheelbarrows. 00:19:10.380 --> 00:19:12.120 If I understand this correct. 00:19:12.120 --> 00:19:12.640 Yeah. 00:19:12.640 --> 00:19:14.020 And it starts in Austria, I believe. 00:19:14.020 --> 00:19:16.200 So the internet is mined in Austria. 00:19:16.200 --> 00:19:19.860 It's put into a special internet wheelbarrow, which is pretty trippy. 00:19:19.860 --> 00:19:20.820 It's like a hovercraft. 00:19:20.820 --> 00:19:25.860 It's mixed up into like a gray goo and then it's shipped off along these pipes. 00:19:25.860 --> 00:19:27.540 Anyway, it's a good joke. 00:19:27.540 --> 00:19:28.420 People can check it out. 00:19:28.420 --> 00:19:30.180 But it's much more visual. 00:19:30.180 --> 00:19:36.340 It does reference both Austria and Ireland, even though I think it's Ireland, even though 00:19:36.340 --> 00:19:38.280 the map always points to Italy. 00:19:38.280 --> 00:19:41.680 I didn't notice that. 00:19:41.680 --> 00:19:43.140 I'm like, this is so off. 00:19:43.140 --> 00:19:44.540 Pretty awesome. 00:19:44.540 --> 00:19:47.060 So people, if you need a good laugh, you know, click on that link. 00:19:47.060 --> 00:19:47.720 It's silent. 00:19:47.720 --> 00:19:50.960 So it's not going to upset folks at work, right? 00:19:50.960 --> 00:19:52.380 It's all about just the visuals. 00:19:52.380 --> 00:19:54.300 Well, I think it was a good one, Brian. 00:19:54.300 --> 00:19:56.140 And I'm glad I forced you to put it in there. 00:19:56.140 --> 00:20:02.020 So next week, we've got a kind of a year in review thing that you're putting in, right? 00:20:02.020 --> 00:20:02.580 Yeah, absolutely. 00:20:02.580 --> 00:20:08.280 So you and I had recorded a Talk Python year in review, top 10 Python stories of the year, 00:20:08.280 --> 00:20:09.200 not just of the week. 00:20:09.200 --> 00:20:11.060 And that's coming out next time. 00:20:11.060 --> 00:20:13.120 So be sure to check that out. 00:20:13.120 --> 00:20:14.280 And it'll be a lot of fun. 00:20:14.280 --> 00:20:14.560 Yeah. 00:20:14.560 --> 00:20:15.180 Nice. 00:20:15.180 --> 00:20:15.660 Okay. 00:20:15.660 --> 00:20:16.020 All right. 00:20:16.020 --> 00:20:19.040 Well, thank you for doing all of this year with me, Brian. 00:20:19.040 --> 00:20:19.320 Yeah. 00:20:19.340 --> 00:20:19.740 Thank you. 00:20:19.740 --> 00:20:20.120 You bet. 00:20:20.120 --> 00:20:20.360 Bye. 00:20:20.360 --> 00:20:20.640 Bye. 00:20:20.640 --> 00:20:22.560 Thank you for listening to Python Bytes. 00:20:22.560 --> 00:20:25.080 Follow the show on Twitter via at Python Bytes. 00:20:25.080 --> 00:20:27.980 That's Python Bytes as in B-Y-T-E-S. 00:20:27.980 --> 00:20:31.400 And get the full show notes at pythonbytes.fm. 00:20:31.400 --> 00:20:35.740 If you have a news item you want featured, just visit pythonbytes.fm and send it our way. 00:20:35.740 --> 00:20:38.440 We're always on the lookout for sharing something cool. 00:20:38.440 --> 00:20:41.820 On behalf of myself and Brian Okken, this is Michael Kennedy. 00:20:41.820 --> 00:20:45.340 Thank you for listening and sharing this podcast with your friends and colleagues.