Transcript #202: Jupyter is back in black!
Return to episode page view on github00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
00:05 This is episode 202, recorded September 30th, 2020.
00:10 I'm Brian Okken.
00:11 And I'm Michael Kennedy.
00:12 Yeah. And this episode is brought to you by Datadog. So thanks, Datadog.
00:16 Yeah. Thank you, Datadog. It's good to have you back, Brian.
00:19 It's good to be back.
00:19 We missed you.
00:20 Yeah. I had a little bit of a heart scare, but I'm all better now.
00:23 That's good to hear.
00:25 We're recording this September 30th, but by the time this comes out, we might have a new Python. So did you know that?
00:32 I did not know that, but I'm very excited that you're covering that first. Yeah. So usually there's about a week delay and that's about when Python 3.9 should be, right?
00:41 Yeah. So Python 3.9, there is a RC2 or Release Canada 2 was released September 17th. The final is scheduled for release October 5th.
00:50 Of course, you know, it's software, so things can come up, but we're looking forward to starting using 3.9 right away.
00:57 We're linking to the changelog. There's a lot of different lists for what is in 3.9, but I wanted to highlight a few features that I pulled out from the changelog.
01:08 The first couple I think I'm most excited about, there's a dictionary merge and update operators. So the merge operator is just the bar. So you can have two dictionaries and do a bar to merge them together. And the bar equal for the update.
01:25 The update kind of means, it doesn't mean append. It means like, if there's new stuff, add it to the other dictionary. But if there's changes, change it.
01:34 So I think this is just, when I first read about this, I thought, why don't we already have this? This just seems obvious. So I'm glad to have a merge operator.
01:42 Yeah, I thought this, there's already a way to accomplish this with the curly bracket, star, star, dictionary, star, star, dictionary, star, star, dictionary, which has the same effect. It's a little bit longer.
01:54 I think this is for consistency with other container objects like sets that have a pipe behavior.
02:00 So it's like, oh, you can just do it to dictionaries.
02:01 Yeah.
02:02 I think.
02:03 That's nice. I had to read a little bit. The next one is a remove prefix and remove suffix has been added to strings and also added to bytes, byte array and collections user string, which is cool.
02:14 I'm most excited about this one.
02:16 Are you?
02:16 Yeah.
02:16 Because this actually, when you look at like the workarounds to do something, the workarounds are ugly.
02:22 If you just want to, it's just, I have like this string that might be at the beginning of my, of another string.
02:28 I want to remove it. Like if I'm just this prepended stuff that happens all the time. So like spaces or things like that. What would you use it for?
02:36 Well, yeah, the same thing. There's a lot of times there's like, oh, there's this string that always starts at the beginning of this line and I just don't want it.
02:42 Right. But the trim, trim, start, trim, end, trim. If you give it characters, it doesn't mean remove that string. It remains remove, like take each one of those characters and remove all of them until you don't run into any more of those characters.
02:56 And so if one of the characters of your string happens to be the first character of the stuff that's left, it'll also get ripped.
03:02 Yeah. You just want a specific string to get removed. A set of strings.
03:07 Right. If I'm like, I want this substring off the front, you know, if it exists, but not if it doesn't, right? You don't do the test. And anyway, it's just, it cleans it up and makes it a little more predictable.
03:16 Okay. Yeah. Next thing is type annotations have a change that you can now use the built-in collection types, such as list and dict as generic types, instead of having to import typing or from typing import capital list or capital dict. I'm really excited about this.
03:33 Wait, I did get back. I'm more excited about this than remove prints.
03:35 Yeah. Cause I'm always annoyed when I have to like, cause I'm, I, I'm starting to use type hinting for a, you know, for interfaces and you don't need to import anything to do that.
03:46 Except for if you have a list or a dictionary or set or something like that. And now you don't have to do that anymore. And I'm very happy.
03:54 I'm still waiting for the optional operator, the question mark or something rather than capital O optional.
04:01 Yeah, that'd be good.
04:03 Yeah.
04:04 We've talked about the peg parser before, but the three, nine is where the new peg parser comes in. I don't know if it'll affect anybody, but it's neat.
04:12 Yeah. It's supposed to make extending the language with more complicated behaviors and more nuanced syntax easier, but it won't affect you or me probably writing code day to day. I'm not going to touch that thing.
04:24 Yeah, I'm not. I was intrigued by this. Any valid expression can now be used as a decorator. This is PEP 614. I haven't quite wrapped my head around it, but I think this will change the way we use decorators, but I think we need a few tutorials to be written to people to figure out how to use this.
04:42 So maybe we should just make decorators like a lambda expression because I know you have later in the show some really cool uses of lambda expression. So we can come back to that.
04:49 Oh my gosh. A huge lambda expression could be a decorator. Yeah, that'd be cool. Or really bad. Anyway, the other thing, last thing I wanted to mention, zone info is a new module that comes in, which is cool.
05:03 Python has IANA time zone databases support. That's part of the standard library now. And there's a whole bunch of other stuff too. So we're going to link to the change log and people should check that out.
05:14 Yeah, very cool. Exciting. We're going to have a new Python and Python comes faster now.
05:17 It does.
05:18 I think they changed the release cycle to 12 months.
05:20 Oh yeah.
05:21 So it's a year month.
05:22 310 or whatever the next thing is should be out soon.
05:26 Yeah, we'll just put it on our calendar. First week in October, we should expect a new Python.
05:29 That's right. What happens in October? Halloween and Python.
05:32 And black. Black cats.
05:34 Black. Yeah, because you want to go out into your costumes and your scary costumes at night when it's dark. It's no fun to do Halloween in the day because it looks fake.
05:44 Or maybe you just have a Jupyter notebook and you're a fan of black, but you would like to format it.
05:49 So Mary Hong sent over a cool recommendation based on some stuff we had over on Talk Python.
05:58 So in Talk Python, I did an auto racing episode with Kane Replical and his pick for a PyPI package recommendation was Black Cell Magic, which I think we covered on the show as well.
06:10 I'm pretty sure.
06:11 She said you should check out Jupyter Black.
06:13 And Jupyter Black is kind of like the same thing, but instead of having to type into the cells, you can just press.
06:21 It gives you a toolbar button. You can press and off it goes.
06:24 So that looks really cool.
06:26 It gives you a toolbar button and a couple of hotkey shortcuts, keyboard shortcuts to format single cells and format all the cells.
06:34 Okay, that was going to be my question. Can you just have it do the whole shebang at once?
06:38 Exactly. And that's what was...
06:40 You can also just run...
06:42 Instead of running black in your CI, you can run J Black or as a pre-commit hook or something like that.
06:47 Okay.
06:47 So I believe with the Black Cell Magic that I talked about previously, you had to type it into the notebook and it would do it, which is cool.
06:55 But this is more of a...
06:57 And I talked about there being an extension that would kind of do it for the whole notebook, but it had a huge message.
07:02 Like, this is no longer supported.
07:03 So I'm not so sure.
07:05 So this gives you both a CLI and hotkeys for the whole notebook, which seems cool.
07:11 Yeah, it does seem neat.
07:12 Definitely need to check that out.
07:13 Yeah, absolutely.
07:14 Quick and simple.
07:15 But to me, that's one of the huge shortcomings of Jupyter on multiple levels.
07:20 I think the auto-formatting...
07:23 Like, Jupyter should format that code as I type.
07:25 I shouldn't have to, like, run command line things against it to get formatted code.
07:29 Like, you know, Visual Studio Code, PyCharm.
07:32 It gives you that support as you go.
07:34 You're not, like, spacing around, tapping around.
07:36 The other I really wish Jupyter did better was autocomplete.
07:39 Yeah.
07:40 Yes, if you hit dot, nothing happens.
07:44 But if you hit tab, it will come up.
07:45 And I think there's a lot of...
07:47 You know, compare that to the other modern editors.
07:49 There's a lot of room to make improvements on those areas.
07:51 But, you know, this, at least having a keyboard shortcut, like, reformat document, you know, command shift B or whatever, control shift B, that seems really like a good start.
08:00 Do you know if JupyterLab has any different support or is it...
08:03 I don't think so.
08:04 I think JupyterLab just has more other UI elements.
08:08 Like, you have an ability to get to the terminal and do other stuff.
08:11 It's not just the notebook.
08:12 But I don't think the fundamental editor experience changed.
08:16 I could be wrong.
08:16 I don't compare them that often, but I don't think so.
08:19 Well, we could...
08:19 I mean, if they get to that point, it wouldn't be an IDE.
08:22 It would be a JDE, right?
08:23 Jupyter development.
08:25 That's right, a JDE.
08:26 Exactly.
08:27 Good one.
08:28 All right.
08:28 Another cool thing is Datadog.
08:30 This episode of Python Bytes is brought to you by Datadog.
08:33 Let me ask you a question.
08:35 Do you have an app in production that is slower than you like?
08:38 Is its performance all over the place?
08:40 Sometimes fast, sometimes slow.
08:42 Now, here's an important question.
08:44 Do you know why?
08:45 With Datadog, you will.
08:46 You can troubleshoot your app's performance with Datadog's end-to-end tracing.
08:50 Use the detailed flame graphs to identify bottlenecks and latency in that finicky app of yours.
08:57 Be the hero that got the app back on track for your company.
09:00 Get started today with a free trial at pythonbytes.fm/Datadog.
09:05 Awesome.
09:05 Thank you, Datadog.
09:06 You know what's not awesome?
09:07 DDoS.
09:08 Denial of service against your web app.
09:11 Yeah.
09:12 So, this is the next couple of things I've got are listener suggestions.
09:15 And unfortunately, since I've kind of been out of commission for a week, I forgot who suggested this.
09:22 So, my apologies to the listener who brought this to their attention.
09:25 There's an article written by Jacob Kaplan Moss called Understanding and Preventing Denial of Service on Web Applications.
09:34 I saw it, but I kind of dismissed it right away because I thought it was just another, like, about all languages.
09:41 But this one is focused on Python and has some specifics on Django.
09:45 So, I think it starts off with a good discussion of what denial of service is and then sort of kind of what to do about it and how to prevent it from happening and fix things with your application.
09:58 But it kind of led me down a rabbit hole and I kind of enjoyed it.
10:01 Anyway, there's one example that it lists as a, I think I've heard, Bev, I don't remember if we've talked about it on the show, which is called a RedOS, which is a regular expression denial of service.
10:12 We talked about this?
10:14 Do you know?
10:14 I don't think so.
10:15 But, yeah, there's certain types of, like, computationally expensive things that are not going to match or useless or whatever you can send over to regular expressions that will cause all sorts of trouble.
10:25 And what's interesting is, so, it says RedOS bugs occur when certain types of strings can cause improperly crafted regular expressions to form extremely, perform poorly.
10:36 And I'm talking, like, really poorly.
10:38 What's interesting is they're not even complicated or regular expressions.
10:42 They're just, like, for instance, a match, a set containing, like, one or more characters or zero or more characters, followed by another zero or more characters, followed by a B.
10:54 Or something like that.
10:56 And there's, like, a little graphic on one of the links on this page that shows how slow this is.
11:02 It has to match all these different things, and it's bad.
11:06 Anyway, some languages have stuff put in place to try to thwart this sort of a thing, but Python does not.
11:13 But we have a solution.
11:15 So, this article links to another article called Finding Python Redos Bugs at Scale Using DLint, which I was like, DLint?
11:24 What's that?
11:25 So, I went and looked there.
11:27 DLint is a Flake 8 plugin.
11:30 So, you can check for denial of service vulnerabilities when you're checking everything else with Flake.
11:36 Oh, that's interesting.
11:37 I'd never heard of that one.
11:39 Yeah, so this, I was thinking, it's a security plugin, a sort of linter for Python.
11:45 I mean, I was thinking, is there a difference between that and Bandit?
11:48 And the authors of DLint were expecting that.
11:51 So, the first FAQ is, what about Bandit?
11:55 So, there's a discussion about whether or not to use Bandit.
11:57 But the TLDR is, it checks for different things than Bandit.
12:02 So, you can run both of them and they run perfectly fine on the same code base.
12:06 Yeah, super cool.
12:07 DDoS is no fun.
12:08 Distributed DDoS, a whole lot less fun.
12:11 So, having to deal with that.
12:13 I've had to deal with that before and managed to get ahead of it.
12:18 But if there's thousands of computers trying to do bad stuff to your website all at the same time from different locations, it's not easy.
12:26 You've had to do that for maybe Talk Python or something?
12:29 For Talk Python training, yeah.
12:31 Lame.
12:32 People, thousands of computers were trying to do all sorts of stuff at the same time.
12:37 So, even things like, let's just block this IP address.
12:40 Or let's put in checks that if this IP address does five bad actions, we're going to block it for an hour or a day or permanently.
12:48 None of that would work because it was so many different computers or devices or whatever.
12:53 Anyway, not fun?
12:55 It'll definitely get your attention.
12:56 Another thing that'll get your attention is pictures.
13:00 We love pictures.
13:01 So, Shomik Chowduri sent over a project that he's working on that I think is pretty cool.
13:08 So, I decided to cover it.
13:09 It reminds me of something I'd worked on a long time ago.
13:11 So, he works with computer vision.
13:14 And now, this is not just about...
13:15 I think this is useful beyond computer vision, which is why I'm covering it.
13:18 But especially for computer vision.
13:20 What he has to work with a lot is there's an image and you're trying to find all the people and maybe the bicycle or all the cars and the things the car needs to worry about if it's a self-driving car.
13:32 Right?
13:33 So, you want to put little pictures around it.
13:36 And say, the computer vision and the ML algorithm said, this is a car.
13:40 Where is that?
13:41 Duck over there.
13:42 That's not a car.
13:42 Right?
13:43 So, you want to label them visually.
13:46 So, often what they do is they put boxes around them and they put some text to say, this is a person, this is a car, this is a duck.
13:52 And drawing those boxes with the picture, with the label lined up just right or affixed to the edge of the box or sort of an arrow pointing down to it or things like that.
14:02 You know, kind of tedious.
14:03 So, he wrote a thing called bbox visualizer, which lets you just say, here's an image file like a PNG and here is the coordinates of this box and the label I want you to put on it.
14:17 And boom, it draws like a nice fancy little box around the object that you talk about and puts a well-oriented label on it.
14:24 So, if you're doing any sort of science stuff or image analysis where you want to put, like, here's what the computer thought is over here and here's what we're calling it, you know, for all sorts of analysis.
14:36 This is a handy little library.
14:38 Yeah, this is cool.
14:39 Yeah.
14:40 Not everyone's going to need it.
14:41 You don't need it for like a fancy web app or whatever.
14:44 But I think if you're trying to do this kind of work, here's a super simple like two or three lines of code.
14:49 Put a nice bunch of bounding boxes on top of things and pictures with nice labels.
14:54 That seems cool.
14:54 Yeah, I can also see like lots of different like student projects where they're using, working with images and algorithms around it to be able to highlight a particular area that they're working on or something like that.
15:07 I think uses.
15:08 For sure.
15:08 I can see a lot of science that are doing it.
15:10 Like we just, we detected this as a star here.
15:13 This is a star.
15:14 Here's the name of the star or whatever.
15:15 Yeah.
15:16 And to just sort of lump all of the drawing the box stuff into a library.
15:20 This is cool.
15:20 I like it.
15:21 Yeah, for sure.
15:22 You've got some nice fancy code examples, like taking your Pythonic code to the next level.
15:27 Tell us about it.
15:28 To the next level.
15:28 I was debating as to, I've got like a devilish streak in me, I think, as to why I'm bringing this in.
15:34 This also was another listener suggestion.
15:36 My apologies to whoever sent it.
15:38 I forget.
15:39 I think it's a gist.
15:41 GitHub gist, I'm pretty sure.
15:42 And it's how to never use lambdas.
15:45 So I'm like just chuckling even at the name.
15:50 It starts off with a brief example showing how to rewrite a power function as a lambda.
15:57 And, you know, anybody sort of familiar with lambdas, that's kind of a common use case is I've got a little like a single one or two argument function that I need to pass in as an expression instead.
16:10 And I can't pass in functions.
16:12 So I pass in a lambda as it's kind of a bound function sort of thing.
16:16 Right.
16:16 I want to do a sort on a list and I want to sort by all users.
16:20 I want to sort by their login date.
16:22 So, you know, lambda U goes to U dot login date or something super simple like that, right?
16:27 That seems good.
16:28 And anybody scared of lambdas, if you look at the initial example, that's a good simple thing.
16:32 They're not scary.
16:34 They're just basically functions without names.
16:36 But they have to be expressions.
16:38 So first one, no problem.
16:40 But then he jumps right into some crazy code.
16:42 I'm saying he.
16:43 I don't know who wrote it.
16:45 But the crazy code right away is some code with import statements.
16:49 So how do you get around import statements?
16:51 Will you somehow it's a using a dunder import and referencing the library you want to import as an expression has to as in the value of that past as an argument to another lambda.
17:04 And these are nested lambdas.
17:06 So right off the bat, first bad example is horrible.
17:09 So don't do that.
17:10 This is almost like a decorator lambda.
17:15 Thing.
17:15 It's so weird.
17:17 It starts off frightening.
17:17 And then it shows an example of a class definition.
17:21 And then how to lambify a class definition.
17:25 Yeah.
17:26 So you can have a lambda expression be an entire class definition.
17:30 Weird.
17:32 And then the last example, which is my favorite is an entire working flask application as a single lambda expression.
17:41 It's truly horrible stuff.
17:43 You should not do this, but it's amusing to read about.
17:45 Well, if your goals have fewer lines of code, like one line for an entire flask application.
17:51 That's impressive.
17:51 I think it has two.
17:53 Yeah, it has two routes, not just one.
17:55 Impressive.
17:57 Yeah.
17:57 Yeah, it's great.
17:58 Cool.
17:59 Some of the, sometimes of these, like, let's see these ideas taken to extreme are pretty interesting.
18:04 And definitely that's the lambda equivalent there.
18:06 Yeah, one good use case of this, I think, maybe I might get struck by lightning by suggesting this.
18:11 But if you're in, if you got a CS student and you're doing really good, you've got like 110% in the class, maybe turn in a homework assignment that's just entirely lambda expressions.
18:25 Or if you're just feeling really mischievous and you get some homework assignment you're super frustrated with, you're like, you know what?
18:34 You're going to ask me to do something silly.
18:36 And you said, as long as it works, it counts.
18:39 You're getting this back.
18:40 Anyway, yeah, I'll probably get.
18:43 Yeah, don't do that.
18:44 That's mean.
18:44 I'll probably get hate mail for that.
18:45 So, sorry.
18:46 What's not mean is contributing to open source, generally speaking.
18:49 Yeah, that's not mean.
18:50 That's nice.
18:50 Yeah, so Alexander, one of the listeners, sent over an article or blog post by Vincent Wanderman.
18:56 And it's called Uncommon Contributions, Making an Impact Without Touching the Core of a Library.
19:02 I think this is one of the challenges, paradoxes that you might run into is like, you find these libraries that are very popular and you love them and you want to contribute to them.
19:13 Like, I love Django, so I want to contribute to it.
19:15 I love Flask, I want to contribute to it.
19:17 I love Request, I want to contribute to it.
19:19 Well, guess what?
19:20 Although those things are highly polished and they have a lot of different use cases, it's very hard to make changes to them because any little change will have a potentially huge effect on a lot of software, right?
19:30 Yeah, and it's also just intimidating to touch the code for a large project, too.
19:34 Yeah, exactly.
19:36 So, here are a bunch of ideas of things that are low danger, low stress.
19:41 Probably a lot of people haven't taken advantage of them.
19:44 I'll just go through a couple that Vincent works through.
19:48 One of them is just providing better information.
19:50 So, he contributed to this project called Rasa.
19:53 And I don't know what Rasa does.
19:55 I forgot to check out.
19:56 So, it has a CLI.
19:58 You say Rasa.
19:59 You can say Rasa --version.
20:02 And what it would say would be like 1.2.7.
20:04 Okay.
20:06 That seems totally legit.
20:07 Like, that feature is implemented, right?
20:09 But then, and by the way, if you look at this article, if you open up the actual article, Brian, you'll see like each one of these has like a beautiful like XKCD style picture talking about the story.
20:22 So, for like the info one, it says to debug this, like somebody says, hey, Rasa's not working.
20:26 Like, all right.
20:27 Well, in order for me to debug this, you got to give me your Python version, your operating system, all the versions of the packages that you have.
20:33 Like, are you running out of a virtual environment, et cetera, et cetera.
20:37 So, what he did was said, all right, when you say --version, now you're going to get the version of Python, the path to your virtual environment, the version of related packages that Rasa depends upon, things like that.
20:48 Nice.
20:48 That's easy to do.
20:49 That's not a challenging, you know, too difficult sort of implementation there.
20:54 The next one is to set up a cron job to run tests checking the dependencies haven't affected a package.
21:05 So, I know you know about continuous integration, right?
21:08 Check in, changes come, going to rerun your unit tests.
21:13 That's great, right?
21:14 But what happens if an underlying package has an underlying dependency?
21:21 So, the dependency of the dependency, is that a grand dependency?
21:25 I don't know.
21:25 Underlying dependency has a change that potentially makes something operate differently.
21:32 What is going to trigger your CI if you don't make any changes to your code there?
21:36 Yeah.
21:36 Right?
21:38 So, he actually ran into this.
21:40 scikit-lego is a package that Vincent works on.
21:44 And he discovered that it wasn't working for some reason because scikit-learn introduced a minor but breaking change.
21:51 So, what he set up was a cron job with GitHub Actions to just run that once a day to say, hey, just in case something which we don't know about directly affects our repo, we still want to run those tests again just to make sure, like, yeah, things are still good.
22:06 Yeah.
22:07 What do you think about that?
22:08 That's good.
22:08 And I also wonder if the breaking change was that they changed what the version output produced.
22:15 Yeah, I did think about that, actually.
22:18 If somewhere in there, there's, like, a test, you know, someone has something that's just test that, calling that on the command line.
22:24 All right.
22:25 Spell check.
22:25 Spell check is easy.
22:27 Oh, yeah.
22:27 There's always spelling errors in code.
22:30 Always, yeah.
22:31 Because a lot of times the symbols we use are not proper words.
22:34 But I do really appreciate things like PyCharm that will find misspellings inside of various things.
22:43 Right?
22:44 Like, if you've got a function, check login and I and inner switch, it'll say login is misspelled.
22:49 But, you know, it's still.
22:51 Or grammar checks.
22:52 Grammar checking people's doc strings or comments in code and stuff like that.
22:57 Exactly.
22:57 So, there's a nice example in there about looking for a country, I think, where it was Spain, but Spain was misspelled, you know, as a doc string example.
23:06 So, that's definitely something easy to do.
23:09 Just run a spell checker on the doc string.
23:11 One that I'm a real big proponent of is having better error messages.
23:15 Oh, yeah.
23:15 So, it's so frustrating.
23:18 Like, just today.
23:19 Yesterday?
23:20 I don't know.
23:21 I was asleep.
23:21 I was not sure exactly when I got this.
23:23 But I got a message from a student taking the Excel course.
23:28 It says, hey, I tried to run cookie cutter.
23:31 Because during the Excel course, we talk about setting up, like, a cookie cutter template that gets everyone started.
23:36 It says, I tried to run cookie cutter and it didn't work.
23:39 Here's the message.
23:41 And it just says something about the Git clone that cookie cutter internally tries to use failed.
23:46 And it doesn't say anything about, you know, is Git not installed?
23:50 Did Git, what was the error from Git?
23:52 Like, it just, nope.
23:53 It failed, right?
23:56 You know, just like a random, like, this command failed.
23:58 Like, great.
23:58 So, if there was a better error message, like, we tried to do that, but you don't have permission to write where you tried to clone this thing to.
24:05 Or Git is not installed.
24:06 Or something like that.
24:07 They could have gone, oh, I need to install Git.
24:09 Right?
24:10 They would have been much better off.
24:11 So, error messages.
24:12 So, they work on, Vincent works on something called Whatley's.
24:16 And it allows for optional dependencies.
24:19 Like, it has some of its functionality, but you might have to pip install Whatley's bracket something else.
24:25 Like, here's tfhub.
24:26 Right?
24:27 And in order to use a certain part of that that depends on that optional dependency, you have to have that installed.
24:33 But you don't have to install it to use the library.
24:35 Right?
24:35 So, you could run into this problem where you try to use a feature that doesn't have a dependency.
24:39 Yeah.
24:39 So, instead of just going, none object has no attribute whatever, right?
24:44 Or whatever's going to happen there.
24:45 Or no library such and such.
24:48 It's a, now the error is, in order to use convert, convert language, you'll need to install, pip install Whatley's bracket tfhub.
24:57 See installation guide here.
24:59 And there's the URL.
25:00 Like, that is a proper error message.
25:01 Yeah, that's great.
25:02 Telling people how to fix the error.
25:04 Yeah.
25:04 And, you know, it's just, it's not that much work, but just finding these problems.
25:08 Like, how many times does it appear on Stack Overflow?
25:10 Rather than just, like, let him go find it on Stack Overflow and give the message.
25:14 So, I recently added something like this to FluentCheck.
25:17 Remember when we talked, I think you brought this up, talked about using raise from on an exception.
25:23 So, you could say raise an exception, but if you do that in a catch block, you get weird other issues, right?
25:31 So, by default, it would say something like, during the handling of the above exception, another exception occurred.
25:38 And that sounds like one thing broke another.
25:40 But, like, in this library, it's supposed to find errors and then report them to you.
25:47 So, if you use raise from, it'll say the above exception was a direct cause of the following exception.
25:53 Which makes it sound like, okay, this is the source of the error, right?
25:57 So, just simple changes like that are really nice.
26:00 Get better error messages.
26:01 Failing unit tests.
26:03 And I'm not talking about going around and finding projects that have failing unit tests.
26:07 But rather, if you want to make a contribution, or rather you find a bug, rather than just submitting a bug on a GitHub issue tracker saying,
26:15 this doesn't work, I tried it, and then having a long conversation about it,
26:19 submit along with it a failing, create a PR that has a failing unit test for that issue.
26:25 Oh, that's awesome.
26:26 Yeah, right?
26:26 Just go, look, it's supposed to do this.
26:29 This fails.
26:29 If you make this pass, I'm happy, right?
26:31 And then they can fold that into the unit test suite and so on.
26:34 And then also, finally, there are some packages that might have names that result in import statements that are very confusing.
26:42 So, for example, if you've got a package, and in the package there's a file.py, lowercase f,
26:48 and within file.py, there's a capital file class.
26:52 Those would be totally reasonable.
26:54 What you can call the files, file.py.
26:55 Create a class in it.
26:56 Depending on how the package is set up, you could end up with something like from package import lowercase file and from package import uppercase file would both work,
27:06 but obviously don't mean the same thing.
27:08 So, in that case, they recommend renaming certain files that are really meant to be used internally as an option.
27:14 Yeah.
27:15 Like in the example, I don't even get what's different.
27:19 I know, I just stared at it for a while as well.
27:21 Okay.
27:22 That's it for all those recommendations.
27:23 But I think there's definitely some good ones in there.
27:25 I like the error messages a lot.
27:26 I like the failing unit tests as well.
27:29 Those are my two faves.
27:30 Yeah.
27:31 I was just even thinking about all this stuff.
27:33 Did it talk about documentation?
27:35 Not about creating documentation.
27:36 Just about the spell checking within documentation.
27:39 Okay.
27:40 Well, I would probably...
27:41 Well, I guess that's doc strings.
27:43 It's pretty limited.
27:44 I'd add documentation to this because projects always are lacking.
27:48 Or sometimes behind.
27:49 So, the documentation might be great.
27:51 Somebody was really gung-ho about it for a while.
27:54 And then there's been improvements.
27:55 But the new features just haven't made it into the documentation all over the place yet.
28:00 Yeah.
28:00 Or tutorials.
28:01 There's no good tutorials showing this part of code.
28:04 There's maybe a quick start.
28:06 But then the advanced hard stuff, there's no examples.
28:09 Yeah.
28:09 Yeah, definitely.
28:10 These are good.
28:12 Cool.
28:12 What extra you got for us?
28:14 Well, I just learned about this morning.
28:15 So, I was going to just not give a whole big thing, but just let people know.
28:20 I saw somebody on Twitter.
28:22 Of course, I'm obviously being really bad about referencing people.
28:26 But sorry.
28:26 A new thing.
28:28 There's a...
28:28 As of September, early in September, there was a collaboration between the people who do
28:34 Wonder Woman and the Smithsonian Learning Lab and NASA and Microsoft.
28:39 Nice.
28:40 So, we're linking to an article that's Learn to Code with Wonder Woman, Smithsonian, and NASA.
28:45 And so, there's a whole bunch of...
28:48 The idea is that there's...
28:49 One, there's a lot of schools that don't offer computer science education.
28:53 And also, with COVID and everything, some people have kind of...
28:57 That's kind of dropped off a little bit.
28:59 And people are focusing on core classes, which is probably fair.
29:03 But if you still want to have your kid learn programming, this might be a way to do it.
29:09 And this is pretty cool.
29:10 And it looks pretty neat.
29:12 There's some Wonder Woman adventure stuff and NASA exploration.
29:18 And there's even a little bit of Minecraft in there.
29:22 It looks really fun.
29:23 And at least some of the tutorials are in Python.
29:25 I haven't checked out to see if all of them are Python or not.
29:28 But there's a lot of Python in there.
29:30 Some of them use Blocky.
29:31 But some of them, like the Super Quiz from Wonder Woman uses Python.
29:36 And then some of the NASA ones, which Cecil actually called out the NASA Microsoft partner ones last time.
29:43 But not the Wonder Woman ones.
29:45 So, yeah.
29:45 It's a mix.
29:46 But very cool.
29:47 It's neat.
29:47 Plus, I can't wait to see 1984.
29:50 I'm looking forward to it.
29:52 Yeah, definitely.
29:54 All right.
29:55 I have a quick thing as well.
29:56 I'm going to be doing a presentation at IndiePy.
29:59 So, virtual online, obviously.
30:00 When is this?
30:02 This is coming up on October 13th.
30:06 So, there I'm going to be doing a Python memory deep dive.
30:10 Both understanding some of the internals of Python memory as well as some optimizations that you can make to go faster and use less memory.
30:17 So, you all can sign up for that and check it out if you like.
30:20 Cool.
30:20 A memory talk.
30:20 And you forgot the date.
30:21 That's funny.
30:22 Yeah.
30:23 I know.
30:24 Maybe we should just have another joke.
30:27 Yeah, let's do another joke.
30:27 Finish it off.
30:28 You know, I think we actually may have covered this a long time ago when it came out, but I'm not sure.
30:32 I don't remember covering it.
30:34 So, suggested by Tim Jacobson, Kelsey Hightower's project no code.
30:39 This is a hilarious repo, but you kind of have to go look at it.
30:43 So, the tagline is, no code is the best way to write secure and reliable applications.
30:48 Write nothing, deploy nowhere.
30:51 And you highlighted that the style guide was good, so I went and looked at that.
30:54 It says, no code style guide.
30:56 All no code programs are the same, regardless of use case.
31:00 Any code you write is a liability.
31:02 Yeah.
31:03 This is beautiful.
31:05 The style guide talks about file extensions.
31:07 It says, no code is not stored in files, but if you must, use the .no file extension.
31:14 Like, example, main.no.
31:17 There are linters built right into your POSIX-based system, your Linux systems.
31:21 So, for example, you can check by saying du-h space main.no, and if it outputs zero, then you have no code.
31:32 What is du?
31:33 Do you know?
31:34 It's like a line count.
31:35 Count the number of lines of text in this file.
31:36 And then they have code reviews.
31:40 The no code community has adopted the following conventions for reviewing code changes.
31:45 When the code changes contains no code additions or modifications, LGTM looks good to me.
31:51 When the code changes include code additions or modifications, C-I-A-L, code is a liability.
31:58 That code change should be rejected immediately.
32:02 And then the final kicker for me on this one is that there's 43,000 stars, 4,000 forks of it, which are funny.
32:10 But the thing that made me laugh is there's 368 people watching for changes in the no code repository where there's supposed to be no changes.
32:22 That's funny.
32:22 That's funny.
32:22 And there's 3.
32:23 Yeah.
32:24 Oh, it adds Docker support as well.
32:26 There's 3.2,000 issues filed against it.
32:28 Oh, my God.
32:28 There are.
32:29 What are they here for?
32:30 Oh, yeah.
32:33 Suspended Arctic code vault contributional reconstruction aviator chain generator keys.
32:39 All right.
32:39 No water in the water cooler is one of the issues.
32:42 And then the contributing at the end of the readme says contributing.
32:46 You don't.
32:47 Sweet.
32:49 All right.
32:50 Well, that's a good one, Tim and Kelsey.
32:53 Nice job on that project.
32:55 Well, thanks a lot again for a lovely podcast.
32:58 Thank you for listening to Python Bytes.
33:00 Follow the show on Twitter at Python Bytes.
33:03 That's Python Bytes as in B-Y-T-E-S.
33:06 And get the full show notes at pythonbytes.fm.
33:09 If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
33:14 We're always on the lookout for sharing something cool.
33:16 This is Brian Okken.
33:17 And on behalf of myself and Michael Kennedy, thank you for listening and sharing this podcast
33:21 with your friends and colleagues.
33:22 Thanks.