WEBVTT 00:00:00.001 --> 00:00:03.820 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to 00:00:03.820 --> 00:00:09.000 your earbuds. This is episode 181, recorded May 6, 2020. I'm Michael Kennedy. 00:00:09.000 --> 00:00:10.000 And I am Brian Okken. 00:00:10.000 --> 00:00:13.440 And this episode is brought to you by Datadog. Tell you more about them later. 00:00:13.440 --> 00:00:18.340 Brian, this first item that you picked here, I saw this going around the Twitterverse and I was 00:00:18.340 --> 00:00:20.420 like, oh, that looks really cool. Tell us about it. 00:00:20.420 --> 00:00:26.360 Yes, Interrogate. So it's a new little tool. I think it's kind of new, new to me at least. 00:00:26.580 --> 00:00:31.000 It checks your code base for missing doc strings or the presence of doc strings. 00:00:31.000 --> 00:00:36.700 So it's written and maintained by Linroot. And we were notified by Herbert Beamster, 00:00:36.700 --> 00:00:42.240 suggested it to us. I like doc strings. I don't like them. I don't have a policy of having them 00:00:42.240 --> 00:00:47.540 everywhere, but doc strings can help you understand the code quite a bit. I really love how like a 00:00:47.540 --> 00:00:54.100 function doc string is utilized by VS Code and PyCharm and other editors to do things like if you hover 00:00:54.100 --> 00:00:59.320 over a function, it just pops up a little window with like, you know, what parameters you can send 00:00:59.320 --> 00:01:04.280 to it. But it also sends the doc string, shows the doc string if there is one. There's also other tools 00:01:04.280 --> 00:01:10.460 like Sphinx or PyDoc or DocUtils that can use that amongst other things to generate documentation. 00:01:10.460 --> 00:01:16.260 I don't really use those. I know a lot of people do though. So it's a problem if you've got some 00:01:16.260 --> 00:01:19.040 missing, if you really need to have doc strings someplace and they're missing. 00:01:19.760 --> 00:01:23.700 So interrogate is a command line tool that you can use to check your code to make sure 00:01:23.700 --> 00:01:26.080 everything has a doc string that needs to. 00:01:26.080 --> 00:01:30.640 I think this is great. Yeah, it's super cool. And well done, Lin. Nice work on this one. I think 00:01:30.640 --> 00:01:37.060 this is really nice because if you have a public library, that should be documented, right? That 00:01:37.060 --> 00:01:43.020 should be covered with nice doc strings that give you all sorts of help in your editor, like you 00:01:43.020 --> 00:01:49.480 mentioned. But also if you generate the documentation, you don't want to have just some random empty, 00:01:49.480 --> 00:01:54.980 either completely missing or just the, you know, like the function name and just an empty body or 00:01:54.980 --> 00:01:59.420 whatever it gets generated there. So this is really cool. And I could see if you were doing a package 00:01:59.420 --> 00:02:06.420 that was public, having this part of your CI CD process that if somebody introduces something into, 00:02:06.640 --> 00:02:13.120 like a PR that here's a new function we wrote, like, great. It failed the CI because it doesn't 00:02:13.120 --> 00:02:17.720 have a doc string. That'd be awesome. Yeah. And then there's also some common, there's some common 00:02:17.720 --> 00:02:23.060 like caveats, like, yes, all public functions should have doc strings. But what about like private 00:02:23.060 --> 00:02:28.980 functions and stuff? There's options to be able to tell to turn off things where you, you know, 00:02:28.980 --> 00:02:32.560 might not need a doc string for just an internal helper function or something. 00:02:32.560 --> 00:02:38.240 Yeah, I totally agree. Like if it's not really meant to be included, you know, in the public API, 00:02:38.240 --> 00:02:40.960 then it shouldn't have a doc, it shouldn't necessarily have a doc string. 00:02:40.960 --> 00:02:45.640 Yeah, it can if it helps to understand it, but you don't, maybe you don't need it. So this is nice. 00:02:45.640 --> 00:02:48.240 Yeah, yeah, this is super cool. Well done, Len. 00:02:48.240 --> 00:02:54.140 Yeah, I wanted to mention also there is information on the readme about how to use the tool within talks 00:02:54.140 --> 00:02:56.940 and within CI workflows. So that's helpful. 00:02:57.140 --> 00:03:03.160 Yeah, this one seems like a super easy thing to adopt. If you already have a CI process in place, 00:03:03.160 --> 00:03:09.260 and you're working on something that's public, whether that's public to your people within your 00:03:09.260 --> 00:03:14.940 company, or you know, it's a package that is used by other projects, right? Or it's public as in 00:03:14.940 --> 00:03:19.200 on pypi.org. I still think it makes sense to just document it for whoever's consuming it, 00:03:19.200 --> 00:03:20.220 who's not writing it. 00:03:20.220 --> 00:03:20.440 Yep. 00:03:20.440 --> 00:03:25.680 Very cool. Now, this next one, I've been holding off on talking about for a long time, 00:03:25.680 --> 00:03:32.200 because it's really interesting, but I didn't feel like I was able to do it justice. So the thing I 00:03:32.200 --> 00:03:39.300 want to talk about is Streamlit. With Streamlit, the idea is it allows you to build much simpler 00:03:39.300 --> 00:03:47.760 data science applications and web apps, I guess you would say. So many people come to Python 00:03:47.760 --> 00:03:55.200 from I've got a little bit of computation that I got to do. And so I'm going to write a script that 00:03:55.200 --> 00:04:00.500 does like 10 things, maybe it doesn't even have a function, it just does do x, you know, load data, 00:04:00.500 --> 00:04:06.120 transform data, pivot data, show graph, or something like that, right? Really, really simple. They're not 00:04:06.120 --> 00:04:11.520 like, pro web developers that are like busting out view or react or something like that to build cool 00:04:11.520 --> 00:04:16.700 apps. But they've got this really cool outcome with Python, and they're happy. But at the same time, 00:04:17.320 --> 00:04:21.660 they would like to have this publicly shareable, they maybe want to put it on the internet, 00:04:21.660 --> 00:04:27.100 they want to make a web app out of it. And the gap from I've got 10 lines of code that outputs a graph 00:04:27.100 --> 00:04:35.500 to I have a fully interactive, dynamic, server backed JavaScript front end type of visual website, 00:04:35.500 --> 00:04:36.840 that's a big gap, right? 00:04:36.840 --> 00:04:37.140 Yeah. 00:04:37.140 --> 00:04:38.760 So Streamlit... 00:04:38.760 --> 00:04:39.140 Even for me. 00:04:39.140 --> 00:04:46.080 Yeah, yeah, well, yeah, for me as well. Now for Streamlit, the idea is that you write the code in the 00:04:46.080 --> 00:04:51.120 simple, straightforward style that I talked about, but then it turns it into an interactive 00:04:51.120 --> 00:04:52.700 web application. 00:04:52.700 --> 00:04:53.480 That's neat. 00:04:53.480 --> 00:04:54.260 That sounds neat, right? 00:04:54.760 --> 00:05:01.000 And it does a whole bunch of really interesting tricks to let you continue to write code in this 00:05:01.000 --> 00:05:06.920 simple, straightforward way, and yet interact with like callbacks and stuff. So you might have a 00:05:06.920 --> 00:05:11.220 function that comes along and says, okay, what I need to do is I want to show, I don't know, 00:05:11.220 --> 00:05:16.580 a drop down list in a web app, or a slider bar or something like that. And then you write your code 00:05:16.580 --> 00:05:23.280 that says, get the value from the slider bar. And you might think, okay, well, normally that's wait 00:05:23.280 --> 00:05:27.520 for the user to click on the slider bar. And when there's a change or some kind of callback, and then 00:05:27.520 --> 00:05:31.760 you have some function that runs on the callback and it updates the DOM, right? But this is like 00:05:31.760 --> 00:05:37.340 straightforward procedural code or imperative code that doesn't have any of those ideas in it. 00:05:37.340 --> 00:05:43.180 So what it does is it uses interesting caching on your functions so that if it were to rerun it with 00:05:43.180 --> 00:05:48.400 the same inputs, it gives you the same answer instantly, like LRU cache type of stuff. And then 00:05:48.400 --> 00:05:53.580 if any of those controls on the web page change, it just reruns the whole script. And when you say, 00:05:53.580 --> 00:05:58.840 get me the value from the slider, it says, well, currently the slider is set at this. And if it 00:05:58.840 --> 00:06:03.020 happens to change, it just reruns the entire thing from beginning to end. But because everything's 00:06:03.020 --> 00:06:09.040 cached, it only recomputes the parts that are needed. So you don't have to think about callbacks. 00:06:09.040 --> 00:06:12.300 You don't have to think about user interaction. You just write top to bottom code. 00:06:12.420 --> 00:06:16.480 And here you've got multiple parts of your application that can be changed dynamically 00:06:16.480 --> 00:06:22.360 that just continue to refresh. And it refreshes it by using JavaScript. So it doesn't even reload 00:06:22.360 --> 00:06:26.360 the page. It just looks like parts of the page are dynamic and coming alive. 00:06:26.360 --> 00:06:27.920 Oh, wow. This is neat. 00:06:27.920 --> 00:06:32.620 Yeah. So it's super cool. Basically, if you can write like straightforward, top to bottom 00:06:32.620 --> 00:06:39.040 code that works with like graphing or pandas or something like that, you now can create a single 00:06:39.040 --> 00:06:45.260 page, a spa app. And I don't remember what JavaScript framework it uses. It's like react or view or 00:06:45.260 --> 00:06:50.160 something like that. I think it might be react. Anyway, it's not super relevant, but it does all 00:06:50.160 --> 00:06:56.040 of that work with like hosting it and creating the server callbacks and setting up the JavaScript 00:06:56.040 --> 00:07:00.680 and the UI widgets and all that kind of stuff. And all you do is write basically procedural code. 00:07:01.040 --> 00:07:07.540 One thing that I think is a danger of these types of applications is it's easy to say if you use our 00:07:07.540 --> 00:07:14.660 magic graphing library and our magic UI widgets and our magic, you know, data processing library, 00:07:14.660 --> 00:07:19.240 not a real database, but our magic server database that we create, then it works, right? 00:07:19.240 --> 00:07:19.480 Yeah. 00:07:19.520 --> 00:07:23.760 What I like about this is it doesn't do any of those things. It just says you want to use pandas 00:07:23.760 --> 00:07:31.220 and numpy and plotly or something like that. Use those and then use them in your script. And then 00:07:31.220 --> 00:07:33.860 we just make it this single page app, which is pretty awesome. 00:07:33.860 --> 00:07:38.240 Yeah. That was my question. Is this a hosted thing or can I do it like behind a firewall or 00:07:38.240 --> 00:07:39.720 local thing or do you know? 00:07:39.800 --> 00:07:46.100 Yes. So with Streamlit, you have a couple of options. I haven't done anything myself, 00:07:46.100 --> 00:07:52.280 but you can self host it or they'll host it for you, I believe. And if you, they have this thing 00:07:52.280 --> 00:07:59.000 called four teams, which is like they automatically deploy and manage the apps and you just create them 00:07:59.000 --> 00:08:04.080 and say, here's the code and run it. It's like kind of a platform as a service for Streamlit apps type 00:08:04.080 --> 00:08:08.560 of thing. That's a paid part of what they're doing. But the stuff I described up until then, 00:08:08.980 --> 00:08:14.840 that is free and open source. So it's still pretty, pretty usable. Yeah. So you have to 00:08:14.840 --> 00:08:19.040 basically deploy them yourself, but they talk about how to do it. You know, it's not super hard. 00:08:19.040 --> 00:08:19.960 Okay. Nice. 00:08:19.960 --> 00:08:24.860 Yeah. So I had the, one of the guys Adrian on who is behind this and has also done some other 00:08:24.860 --> 00:08:30.140 interesting technical programming stuff and with self-driving cars and folding at home, 00:08:30.140 --> 00:08:34.700 those types of things on Talk Python just a couple of episodes ago. I don't remember exactly what 00:08:34.700 --> 00:08:42.800 number it was, but I guess 260 ish, something like that. So just check out that episode if people want 00:08:42.800 --> 00:08:46.960 to go much deeper, but this is really cool. If you're writing these imperative, simple little 00:08:46.960 --> 00:08:51.120 scripting apps and you're like, I would really like to share this or make it better. Streamlit's cool. 00:08:51.120 --> 00:08:52.480 Yeah. Nice. Okay. 00:08:52.660 --> 00:08:57.540 I feel like we both have themes for ours. Your theme is continuing with documenting and whatnot. And 00:08:57.540 --> 00:08:59.040 you'll see my theme develop as well. 00:08:59.040 --> 00:09:06.240 This is interesting because I ran across this interrogate second, but after I ran across this, 00:09:06.240 --> 00:09:13.780 an article by Hienic that says why you should document your tests. He makes a lot of good points. 00:09:14.480 --> 00:09:21.860 So I believe, and we have this policy where I work of tests should have doc strings on them to tell you 00:09:21.860 --> 00:09:28.020 kind of what the test is doing and why it's there. There's a lot of reasons that I have never really 00:09:28.020 --> 00:09:33.740 been able to describe clearly because you're, I mean, ideally your test name should be descriptive and 00:09:33.740 --> 00:09:38.520 the code should be clear. So why do you need a doc string? It's not, that's not something that you're 00:09:38.520 --> 00:09:40.340 going to call from an API or anything. 00:09:40.480 --> 00:09:43.860 You probably won't type help function, you know, test function, right? 00:09:43.860 --> 00:09:44.720 Right. 00:09:44.720 --> 00:09:45.620 Probably not. 00:09:45.620 --> 00:09:50.860 And you also don't call it. I mean, like test methods that you run pytest with, pytest calls 00:09:50.860 --> 00:09:55.600 it. You don't call those tests, but you can get confused in the future. And one of the explanations 00:09:55.600 --> 00:10:02.860 is Hienic has a good example where he shows some simple code with a simple test name, but the thing 00:10:02.860 --> 00:10:07.860 he's asserting on doesn't really make sense. And the reason, if you don't know what's going on under 00:10:07.860 --> 00:10:13.180 the hood. And the reason is because tests often are testing for a side effect of an action. 00:10:13.180 --> 00:10:19.860 If you're testing the output of a function, that's obvious. It's kind of obvious of the, 00:10:19.860 --> 00:10:25.680 if I pass in functional tests, if you pass in a certain parameters and you get a certain expected 00:10:25.680 --> 00:10:30.300 output, you can assert against that. But what about actions that have side effects and you need 00:10:30.300 --> 00:10:36.280 to test for those? That might need some more explanation. And he writes, this is quite common 00:10:36.280 --> 00:10:42.340 in testing. Very often you can't ask questions directly. Instead, you verify certain properties 00:10:42.340 --> 00:10:48.080 that prove that your code is achieving its goals by checking side effects and stuff like that. 00:10:48.080 --> 00:10:54.780 It's a short little article and I was just happy to have some of that expressed of why you should 00:10:54.780 --> 00:11:00.560 document. And it might be you that's confused in the future. And then it ties back into the 00:11:00.560 --> 00:11:04.640 interrogate because, so I was just thinking when I was reading about interrogate, I'm like, 00:11:04.640 --> 00:11:09.220 oh, awesome. I really want to put something in place to just make sure all my tests have doc 00:11:09.220 --> 00:11:16.540 strings. And he lists in the article, the exact command line that you need to make sure that all 00:11:16.540 --> 00:11:22.400 just text, make sure that your tests have doc strings and nothing else. So this is cool. 00:11:22.400 --> 00:11:28.300 Yeah. It looks really nice. And I can see how this would lead you down to finding a library that 00:11:28.300 --> 00:11:34.860 searches for or evaluates these. Yeah. So the test example he has here is testing that the hash, 00:11:34.860 --> 00:11:40.240 like creating the same object, the instance of a class twice and taking the hash and making sure 00:11:40.240 --> 00:11:46.380 that those are not the same because he's trying to test that adders is not implementing false on the 00:11:46.380 --> 00:11:51.280 class or something to that effect. Right. So you're like, what the heck is going on with this? Like, 00:11:51.280 --> 00:11:53.980 why would you check the hash of a thing is not equal to the hash of a thing, 00:11:53.980 --> 00:12:00.240 but it's looking like you said, for this sort of like hidden layer that's operating below it. Right. 00:12:00.240 --> 00:12:06.540 Yeah. And then also my reasoning, and I think he brings it up is that, that, often when you're 00:12:06.540 --> 00:12:11.840 looking at a test, it's because you really got to get a release out and one of the tests is failing. 00:12:12.100 --> 00:12:16.880 So you got to go look at the test and figure out what it's testing for and why it's failing. 00:12:16.880 --> 00:12:23.620 And if you don't have it clear why the test is important, you run the risk of, the person at the 00:12:23.620 --> 00:12:27.580 time going, well, I don't even understand what this test does. Maybe it's not important. 00:12:27.580 --> 00:12:28.300 Comment it out. 00:12:28.300 --> 00:12:29.460 Comment it out. 00:12:29.460 --> 00:12:30.280 Passes. 00:12:30.280 --> 00:12:30.780 You don't want that. 00:12:30.780 --> 00:12:32.120 CI is good. We're going home. 00:12:32.120 --> 00:12:37.480 I don't do that, but I've heard it done before. Of course. 00:12:37.480 --> 00:12:40.920 I would never do anything like that, but I can imagine that it has been done. 00:12:40.920 --> 00:12:45.140 Now I actually have, I have some experiences in the past where like there was some project 00:12:45.140 --> 00:12:49.760 and it had like a beautiful set of tests and then, and CI and stuff. And I wasn't working 00:12:49.760 --> 00:12:54.660 on it anymore. And whoever took it over is like, Oh, those tests were really annoying. So I turned 00:12:54.660 --> 00:13:00.080 them off. You're like, Oh my gosh, those were there for a reason. What just happened? So at least 00:13:00.080 --> 00:13:04.220 like if, if this gives you some description about what's up, that would be good. Is there anything 00:13:04.220 --> 00:13:08.820 where like pie tests will show the doc string as part of the error report? 00:13:08.820 --> 00:13:12.600 I think there was a, somebody that wrote a tool that would do, I don't remember the 00:13:12.600 --> 00:13:17.720 name of it. I remember running across the plugin that would pop out the doc string for 00:13:17.720 --> 00:13:19.760 failed tests, which would be pretty cool. 00:13:19.760 --> 00:13:20.600 Yeah. That would be pretty cool. 00:13:20.600 --> 00:13:25.800 Hopefully the person evaluating the test failures has access to the code. They can go look. 00:13:25.800 --> 00:13:30.080 Yeah. I'm thinking more of like a CI CD. Like you're not really, you don't have it like 00:13:30.080 --> 00:13:33.900 loaded up right there. Right. You're just like, Oh, I'm cruising on GitHub, checking a PR. 00:13:34.020 --> 00:13:38.080 What the heck is this? Yeah. I actually wrote a, it was an internal thing, but a quick 00:13:38.080 --> 00:13:44.600 plugin for pytest that would just before every test function, print out the test name and print 00:13:44.600 --> 00:13:49.760 out the doc string. If we can look at the logs, it's there. 00:13:49.760 --> 00:13:55.800 Yeah. That's cool. Very nice. Also cool. Data dog. So this episode is brought to you by data dog. 00:13:55.800 --> 00:13:59.560 And let me ask you a question. Do you have an app in production that's slower than you like 00:13:59.560 --> 00:14:04.020 it's performance all over the place? Maybe sometimes fast, sometimes slow. Here's the 00:14:04.020 --> 00:14:08.360 important question. Do you know why it does that with data dog? You will, you can troubleshoot 00:14:08.360 --> 00:14:13.580 your app's performance with their end to end tracing. Check out their detailed flame graphs to find 00:14:13.580 --> 00:14:19.060 bottlenecks and latency in that finicky app of yours. Be the hero that got your app back on track at your 00:14:19.060 --> 00:14:25.200 company. Get started with a free trial at pythonbytes.fm/data dog and get a cool little, 00:14:25.200 --> 00:14:29.920 t-shirt as well. All right. So your theme is so far has been pretty clear. Next one of mine, 00:14:29.920 --> 00:14:35.360 I want to talk about a project called hollow viz. Have you heard of hollow viz? I have not. I'm sure 00:14:35.360 --> 00:14:41.480 you've heard of scipy and those types of things. There's kind of a grouping of other projects, 00:14:41.480 --> 00:14:47.900 right? Under that general banner with like numpy, matplotlib and whatnot. Well, hollow viz is kind of 00:14:47.900 --> 00:14:55.620 like that for data processing and visualization. And one of its features acts very much like 00:14:55.620 --> 00:15:00.480 streamlet, but in a more general, probably a little more work to set up and like, right, 00:15:00.480 --> 00:15:05.440 you got to work more in its framework, but in a very similar way to what streamlet is doing as well. 00:15:05.440 --> 00:15:11.400 So it's a coordinated hollow viz is a coordinated effort to make browser based data visualization 00:15:11.400 --> 00:15:16.880 in Python easier to use, easier to learn and more powerful. So it's, yeah. So what does it do? 00:15:16.880 --> 00:15:22.920 So it has a bunch of tools that make it easier to apply Python plotting libraries to your data, 00:15:22.920 --> 00:15:29.900 a bunch of tutorials, conda, like meta package that when you, you know, in conda install hollow viz, 00:15:29.900 --> 00:15:33.540 it actually installs a whole bunch of things. I'll tell you about a second, even has some sample 00:15:33.540 --> 00:15:37.820 data sets. So you can like go through the tutorials and actually get the outcome. Right. 00:15:38.160 --> 00:15:43.240 So it's made up of a bunch of different things. One called panel, and that one makes creating apps 00:15:43.240 --> 00:15:48.440 and dashboards for your plots using any of the supported plotting libraries, which is pretty 00:15:48.440 --> 00:15:55.680 awesome. It has HV plot to quickly generate interactive plots as hollow views to make your 00:15:55.680 --> 00:16:02.780 data instantly visualizable. Geo views for visualizing geographic data, data shader for rendering 00:16:02.780 --> 00:16:12.080 huge data sets, param for creating a user configurable objects, like config stuff, and then color set or like 00:16:12.080 --> 00:16:18.020 color maps. So yeah, you want to have like nice colors that flow together for your plots. And panel 00:16:18.020 --> 00:16:24.120 is the main thing that I was thinking of that lets you create these single page apps around interactive 00:16:24.120 --> 00:16:30.360 sliders and dropdowns around your graphs and other, other kinds of stuff. And, yeah, very cool project 00:16:30.360 --> 00:16:35.340 as well. Yeah. I was looking at the data shader and they have like some really pretty pictures 00:16:35.340 --> 00:16:43.220 because of the examples of, overlaying data plots over the map of the U S things like that. 00:16:43.220 --> 00:16:49.200 It's cool. Yeah. Or, you know, you can plot attractors with 10 million points each. Oh, is that all? 00:16:49.200 --> 00:16:54.680 And these graphs, I mean, these, the resulting pictures are, I don't know what they're like 400 00:16:54.680 --> 00:16:59.980 by 400 pixels or smaller. It's like, yeah, that came from 10 million points or here's the United 00:16:59.980 --> 00:17:07.980 States plotting each person in the United States where they're physically located from the 2010 census. 00:17:07.980 --> 00:17:15.280 So 300 million points of data overlaid onto the United States map. Yeah. It's like, like a sun, 00:17:15.280 --> 00:17:19.900 uh, really is pretty interesting. Actually. I think I can see you over there, Brian, you're on the left. 00:17:20.960 --> 00:17:25.700 You are too. That's right. Awesome. Anyway. Yeah. So this is a cool project. There's a whole bunch, 00:17:25.700 --> 00:17:30.560 a bunch of different little libraries that are pretty neat. So if you want to try to visualize 00:17:30.560 --> 00:17:34.440 your data and we'll come back and talk some more about both of these projects towards the end of 00:17:34.440 --> 00:17:38.500 the show as well, but a bunch of cool libraries, like all brought together under this hollow of his 00:17:38.500 --> 00:17:44.280 project to make them work together. Yeah. Nice. Nice. What'd you got next? I have another command line tool. 00:17:44.400 --> 00:17:51.020 So this was by, oh gosh, Rosario. And he wrote a little blog post about it, but it's a, there's a 00:17:51.020 --> 00:17:58.720 project called a live progress and it's a progress bar for Python and it's really cool. So it is pretty 00:17:58.720 --> 00:18:05.260 cool. Command line interface, a progress bar. So often, I mean, like even like pytest has added, 00:18:05.260 --> 00:18:09.060 progress bars for, you know, watching your test finish and things like that. And it's, 00:18:09.060 --> 00:18:14.360 it's nice to have progress bars and it gives you good feedback and whatnot, but there there's limits 00:18:14.360 --> 00:18:20.020 to what you can do, except for this seems unlimited. It's, got a whole bunch of different animations 00:18:20.020 --> 00:18:25.800 and spinners and things you can combine to make a more entertaining progress bar. So it's fun. 00:18:25.800 --> 00:18:30.000 Yeah. These are really nice. And you know, these little touches, they, they probably don't seem like 00:18:30.000 --> 00:18:35.120 much, but they can definitely make your app feel more professional and more polished rather than just, 00:18:35.120 --> 00:18:37.480 you know, the answer is seven or like whatever we're done. 00:18:37.740 --> 00:18:43.620 Yeah. Some of the, like, what was it? pipenv. I don't use it, but I appreciated some of the fun 00:18:43.620 --> 00:18:48.440 command line interface stuff that they've added to it. And I think adding some fun to a tool 00:18:48.440 --> 00:18:54.580 is nice. One of the things I wanted to comment on also was just the, about the repo itself. 00:18:54.580 --> 00:19:01.040 So the code is, up on GitHub and, the readme has some nice thing features I wanted to call out. 00:19:01.040 --> 00:19:07.160 So the animated pictures of what it does is a nice touch. We've said this before. We love things 00:19:07.160 --> 00:19:13.300 like this. I liked that there was a to-do list. so it encourages having a short to-do list 00:19:13.300 --> 00:19:18.260 encourages contributions. And I think even listing things that I've gotten that I've gotten done 00:19:18.260 --> 00:19:22.360 recently so that people that might not know about those features don't try to go work on them. 00:19:22.360 --> 00:19:27.400 And then just a short list of things you'd like to have done. And then it has an interesting fact 00:19:27.400 --> 00:19:32.540 section, which is kind of cool. The code is in a functional style. It uses closures and generators. 00:19:32.860 --> 00:19:38.920 So, I mean, actually a lot of times I'll look at, code, not as an example of, of how to do 00:19:38.920 --> 00:19:43.640 something. So if somebody is proud of like their use of generators, maybe it's worth code checking out 00:19:43.640 --> 00:19:47.720 if you're trying to learn generators. And then another feature that I'm definitely going to pick 00:19:47.720 --> 00:19:53.960 up for things that I work on is change log highlights. So not the entire change log in the 00:19:53.960 --> 00:20:01.520 read me, but just one or two lines of semicolon separated features per version of change. So 00:20:01.520 --> 00:20:06.260 this is kind of a nice thing to add. Oh yeah, that is really nice. Cool. I think it's a great project. 00:20:06.260 --> 00:20:11.120 If I need a progress bar, I'm definitely going to consider this one. Like I said, like I do think 00:20:11.120 --> 00:20:15.800 they're neat and I do use them sometimes. So, yeah, that's cool. Very nice. All right. Last one's a 00:20:15.800 --> 00:20:21.060 quick one. So we talked about hollow viz, talked about streamlet and panel and how those are kind 00:20:21.060 --> 00:20:27.500 of similar. So there's this other project called awesome panel, which is kind of like an awesome 00:20:27.500 --> 00:20:35.260 list for panel that way to build interactive data science, single page apps, or not even single page 00:20:35.260 --> 00:20:42.460 apps. This is run by Mark Skalv Madsen. I got that closely, right? Mark. And yeah, it's a cool 00:20:42.460 --> 00:20:47.560 project to just show a bunch of examples and a curated list of these. So yeah, if you just open 00:20:47.560 --> 00:20:53.540 that up, you can go see, there's an app that comes up. It takes just a second come to life. And then on 00:20:53.540 --> 00:20:57.600 the left, there's like a gallery. There's all sorts of cool pictures. There's also a nice talk. I can't 00:20:57.600 --> 00:21:01.620 remember who gave the talk, but yeah, it's a, there's like a talk from one of the conferences, 00:21:01.620 --> 00:21:06.920 but if you go to the gallery, you'll see like, as you navigate around, it's kind of like this 00:21:06.920 --> 00:21:11.100 single page app. So if you click gallery, you'll see like the main part of the app sort of spin for a 00:21:11.100 --> 00:21:14.620 second and then come up and then you can go and say, Oh, there's like one of the things that's 00:21:14.620 --> 00:21:18.860 really cool that I'll point you guys at is this thing called the image classifier in there. So I 00:21:18.860 --> 00:21:25.320 went in there and it's lets you, if you just scroll down, it says upload an image and you can grab some 00:21:25.320 --> 00:21:30.140 JPEG and upload it. I grabbed some like random microphone picture that I had laying around and 00:21:30.140 --> 00:21:34.440 threw it in there. And then it ran, you can pick different neural networks to run against it. 00:21:34.440 --> 00:21:39.420 Do you want to run NAS net mobile, NAS net large, mobile net V2? Like, I don't know what these are, 00:21:39.420 --> 00:21:43.960 these glass fires, but you can pick from them and then it'll tell you in a cool little graph at the 00:21:43.960 --> 00:21:49.340 bottom, like what it thinks that is. And it thought the microphone was most likely a microphone, but it 00:21:49.340 --> 00:21:53.520 could have been a shield because it had like a big metal guard on the front of it. And it's just really 00:21:53.520 --> 00:22:00.300 cool. And so this whole website is built, if I got it right, in panel to show you how you can build a 00:22:00.300 --> 00:22:05.460 cool panel app. But then as you dive into the gallery, each one of these pieces is like an interactive 00:22:05.460 --> 00:22:09.900 sub panel or something like that. So it's kind of, it's a little bit meta in that regard, but it's 00:22:09.900 --> 00:22:10.000 pretty cool actually. 00:22:10.000 --> 00:22:12.820 Yeah. It's really, it's really cool. 00:22:12.820 --> 00:22:17.860 Yeah. And yeah, it's apparently super easy to work with. Again, I haven't built anything with it, but 00:22:17.860 --> 00:22:24.000 it seems like a much simpler way to get your interactive data science stuff on the internet 00:22:24.000 --> 00:22:30.180 than learning Vue.js, JavaScript, Flask, SQLAlchemy, et cetera, et cetera. 00:22:30.180 --> 00:22:30.540 Yeah. 00:22:30.540 --> 00:22:36.040 Yeah. So anyway, pretty cool. I recommend if you want to check this out, just go browse the gallery. That's 00:22:36.040 --> 00:22:37.820 the best way to see what this thing can do. 00:22:37.820 --> 00:22:39.240 I love pretty pictures. 00:22:39.240 --> 00:22:44.860 I know. Yeah. This one definitely passes our, our tests for you must have pretty pictures 00:22:44.860 --> 00:22:52.200 in order to talk about graphical stuff. Yeah. So Brian, really quick on this next one, click on the 00:22:52.200 --> 00:22:57.460 app for it because it's take just a second to load up. So that's it for our main items. I want to tell 00:22:57.460 --> 00:23:03.220 you about a couple of things, then we'll get to yours as well. First, one of the features that I really 00:23:03.220 --> 00:23:08.560 like about Visual Studio Code, I haven't really used because I don't use Visual Studio Code in like a 00:23:08.560 --> 00:23:13.560 meaningful way. I use it all the time for like little bits of editing, but not if I'm like doing real 00:23:13.560 --> 00:23:19.680 projects, I probably use PryCharm, but it has, it has live share, which is a pretty killer feature. 00:23:19.680 --> 00:23:25.880 So you can say, I would like to share my coding environment with someone else who's going to like 00:23:25.880 --> 00:23:30.360 look over my shoulder, do paired programming, just code review, whatever. And they can actually debug 00:23:30.360 --> 00:23:36.100 and step through and like see your code in their editor. And it could even be like a different editor. 00:23:36.100 --> 00:23:41.640 I think there's other stuff support, like proper Visual Studio versus VS Code and whatnot. So that's 00:23:41.640 --> 00:23:47.760 really cool. And I've always thought like, well, that would be awesome for PyCharm. But no. So 00:23:47.760 --> 00:23:53.160 someone on Twitter, sorry, I don't remember who sent this to me, but thank you. I sent up this link to 00:23:53.160 --> 00:24:01.240 this project called CodeTogether. So CodeTogether is a freemium product. So this is a, not an open source 00:24:01.240 --> 00:24:07.700 thing. It's like a paid project. You can go sign up, pay dollars a month for certain features, or you can 00:24:07.700 --> 00:24:12.800 just use the free version. But it has that type of experience that I just talked about, but for many 00:24:12.800 --> 00:24:17.600 different editors, right? So it comes for all the IntelliJ stuff. So like WebStorm, PyCharm, and so on. 00:24:17.600 --> 00:24:23.800 Also works with VS Code. It works with other things. I don't know exactly all the things that it covers, 00:24:23.800 --> 00:24:29.580 but certainly Eclipse, IntelliJ, and VS Code, which covers quite a bit. So if you're looking for that, 00:24:29.620 --> 00:24:33.960 and you weren't using LiveShare, because it didn't exist for what you're doing, you could check 00:24:33.960 --> 00:24:38.120 this out. I have not used it. I'm not endorsing it. I'm just saying it looks interesting and it might 00:24:38.120 --> 00:24:38.560 help people. 00:24:38.560 --> 00:24:39.480 Oh, neat. Cool. 00:24:39.480 --> 00:24:46.180 Yeah. Yeah. Cool. And then the other one that I want to just quickly mention is related to the first 00:24:46.180 --> 00:24:52.180 thing. These are totally different things. But Kevin VanderVeen sent over a message a week ago and said, 00:24:52.260 --> 00:25:00.220 hey, I built a cool data explorer to help you understand the whole COVID pandemic stuff in a 00:25:00.220 --> 00:25:05.340 local way. And he built it using Streamlit. So I thought, hey, here's an app that someone just sent 00:25:05.340 --> 00:25:11.380 over that's like a cool running on Heroku Streamlit app. That would be a nice example of what I talked 00:25:11.380 --> 00:25:16.120 about at the beginning. And it also has the GitHub repo there as well. So if you go and check out that 00:25:16.120 --> 00:25:20.900 app, like for example, Brian, you scroll down to the second, to the third graph, below the third graph, 00:25:20.900 --> 00:25:24.920 there's like a dropdown that lets you pick Oregon and you can go pick that. And wow, it looks like 00:25:24.920 --> 00:25:29.220 we're flattening the curve really well. That's pretty awesome. Although the last two days have 00:25:29.220 --> 00:25:32.700 been rough, I guess. Or you can go down a little farther and compare it against different states. 00:25:32.700 --> 00:25:37.340 You could go in there and type like it's Colorado. You could type Oregon or New York or whatever you 00:25:37.340 --> 00:25:42.380 want. And then it'll like autocomplete that out of the list and then regenerate. And this is exactly 00:25:42.380 --> 00:25:45.900 like what I was saying. Like there's some line in the Streamlit code that's just saying, 00:25:46.020 --> 00:25:52.980 get the tags from the tag selector. And then if you type in there, it just reruns the whole thing. 00:25:52.980 --> 00:25:57.900 But most of the stuff's cached and then it'll redraw the graph. It's super cool. So this is both 00:25:57.900 --> 00:26:02.460 useful, I think, for if you want to try to like understand that it's a cool data science project. 00:26:02.460 --> 00:26:07.220 The source is on GitHub. But also it's just a cool example of Streamlit if people want to see that 00:26:07.220 --> 00:26:07.460 going. 00:26:07.620 --> 00:26:12.260 And the graphs are fun too because you can do like box select and zooming and stuff like that. 00:26:12.260 --> 00:26:16.220 Yeah, these are just Plotly. So they do all the standard Plotly stuff, which is pretty cool. 00:26:16.220 --> 00:26:21.120 That's kind of what I like about the Streamlit thing, not forcing you to use their random graphing 00:26:21.120 --> 00:26:23.620 thing, but just other graphs that you might like. 00:26:23.620 --> 00:26:23.780 Yeah. 00:26:23.780 --> 00:26:26.260 Yeah. All right. Well, that's it for my extras. What else do you got? 00:26:26.260 --> 00:26:32.280 Well, I wanted to remind people that PyCon 2020 online is available and new content is still 00:26:32.280 --> 00:26:37.340 being posted through the first few weeks of May. I think that's when they're wrapping things up. 00:26:37.340 --> 00:26:39.340 Yeah, that's cool. I just saw some new videos go up there. Yeah. 00:26:39.340 --> 00:26:45.300 Yeah. One of the new videos that just came up was my talk. So multiply your testing effectiveness 00:26:45.300 --> 00:26:47.100 with parameterized testing. 00:26:47.100 --> 00:26:50.220 Oh, yeah. There it is right at the bottom with a couple of new tags on it. 00:26:50.220 --> 00:26:54.560 Yeah. So I'm excited to have people get feedback from people to see what they thought. 00:26:54.560 --> 00:26:56.700 So that looks good. I like it. Yeah. Well done. 00:26:56.700 --> 00:27:01.400 While I was there, I was looking around. There's tons of great talks. There's a bunch of tutorials 00:27:01.400 --> 00:27:04.360 there. There's charlas. Is that new this year? 00:27:04.360 --> 00:27:09.500 They did it last year, maybe the last two years, but it's the Spanish language track. 00:27:09.500 --> 00:27:14.240 Yeah. It's neat. I'm glad they're doing it. Sponsor workshops. That's kind of nice to have. 00:27:14.240 --> 00:27:18.180 And then even an online poster hall. So that's there. So it's cool. 00:27:18.180 --> 00:27:24.060 The other thing I wanted to bring up, a quick extra, if anybody's following the drama in pytest, 00:27:24.060 --> 00:27:31.160 the drama is over and I'm happy with the resolution. So hopefully there will be peace in the family. 00:27:31.280 --> 00:27:33.980 I hope so. A link to the Twitter announcement from pytest. 00:27:33.980 --> 00:27:39.460 Yeah. They got the whole public statement there. So the folks who had dropped out, 00:27:39.460 --> 00:27:43.940 are they dropping back in or what's, or is there just permanent out fallout from that? 00:27:43.940 --> 00:27:49.160 I don't know that any more details. I know at least one person is back in, 00:27:49.160 --> 00:27:54.180 but all the people I was worried about are signers of this message. So. 00:27:54.280 --> 00:27:55.020 Yeah. So probably. 00:27:55.020 --> 00:27:56.820 Kind of seems like maybe they're back in. 00:27:56.820 --> 00:28:00.360 Yeah. All right. Well, that's awesome. I'm really glad to hear that got resolved. And it sounds like 00:28:00.360 --> 00:28:08.520 exactly the outcome that I would have voted for as well. Okay. So you ready for some jokes? I don't 00:28:08.520 --> 00:28:10.700 know. These jokes. How about you? Are you ready for humor? 00:28:10.700 --> 00:28:11.940 Yes. Humor is good. 00:28:11.940 --> 00:28:19.980 Humor is definitely good. And so I found a couple of funny pictures and I'm going to put the pictures 00:28:19.980 --> 00:28:23.680 in the show notes. I don't know if they'll come up in your podcast players. Some of them do, 00:28:23.680 --> 00:28:28.880 some of them don't. Some of you guys say allow pictures in this podcast feed, just like in the 00:28:28.880 --> 00:28:32.020 player as you're looking at the show notes, but certainly on the website, they'll be there. 00:28:32.020 --> 00:28:35.320 And these are Oh really book covers. 00:28:35.320 --> 00:28:36.900 I love these. 00:28:36.900 --> 00:28:43.800 They're like O'Reilly and just if you've forgotten the O'Reilly books always have the title and then 00:28:43.800 --> 00:28:48.320 they have an animal that goes with it. Right? So if you wrote a book for O'Reilly, 00:28:48.520 --> 00:28:53.400 the thing is like, what's your animal on your book and whatnot. Yeah. So these are like, 00:28:53.400 --> 00:29:00.360 take those ideas, put an animal on it, but make it silly. Right? There's also usually like some 00:29:00.360 --> 00:29:04.500 sort of saying at the top of the book. So for these, you definitely have to read the top also. 00:29:04.500 --> 00:29:09.980 Yeah. It's right. Like sort of the subtitle. Okay. So how about this? I'll read the first one. You do 00:29:09.980 --> 00:29:15.360 the second one and so on. So this one has like a badger or something on it, on the front of it. And it's 00:29:15.360 --> 00:29:21.020 kind of like sneaky head down. And, the title is pointless meetings, the survival guide, 00:29:21.020 --> 00:29:28.760 how to survive all pointless meetings. I feel like many, many things that used to be meetings 00:29:28.760 --> 00:29:33.180 these days are now an email and people are like, Oh my gosh, they really can just be emails. Like, 00:29:33.240 --> 00:29:37.240 why have we been going to all these meetings? Right? So, all right. You want to get the next one? 00:29:37.240 --> 00:29:42.260 The next one is overriding your teammates code. My code is better than yours anyway. 00:29:45.140 --> 00:29:51.440 It's got a horse on the front. I don't know either. I really love this one. This one is the essential 00:29:51.440 --> 00:29:58.760 semicolon parenthesis. Sorry. Quote semicolon parenthesis drop table animals, semicolon dash, 00:29:58.760 --> 00:30:05.380 dash. And there's no animal because, well, this is a SQL injection that has deleted it. And it says 00:30:05.380 --> 00:30:12.560 now with user generated content. That one's that may be the best. Yes. Now with the security hole. 00:30:13.060 --> 00:30:19.700 Exactly. Related. What's next? Okay. This one has a fish on the cover. Expert hoping nobody hacks you 00:30:19.700 --> 00:30:25.340 security by optimism and prayer. I don't know what the fish has to do with it. I must be missing it. 00:30:25.340 --> 00:30:32.960 But, no, but that's good. That's most people's security solution, right? That's true. So the next one 00:30:32.960 --> 00:30:40.560 is an octopus. Obviously many legs. It can type many things. And the title is the entire book is exiting 00:30:40.560 --> 00:30:45.640 vim eventually. Just memorize the 14 contextual dependent instructions. 00:30:45.640 --> 00:30:53.560 Exiting vim eventually. Oh, I love it. I love it. Yeah. So you'll have to visit the website and 00:30:53.560 --> 00:30:58.180 check out these because they're pretty sweet. Yeah. Awesome. Speaking of sweet, it's been great to be 00:30:58.180 --> 00:31:02.000 here with you, Brian. Thanks. It has been great. Thanks. Yep. Bye. Bye.