Transcript #305: Decorators need love too
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:04 This is episode 305, recorded October 10, 2022, and I am Brian Okken.
00:10 - I'm Michael Kennedy.
00:11 - We got a whole bunch of stuff that's great.
00:14 We also want to thank Microsoft for Startups, Founders Hub, for sponsoring this episode.
00:18 We'll hear more about them later.
00:20 But do you want to start us off with something exciting?
00:24 - Let's kick it off.
00:25 I have a theme this week, Brian.
00:26 - Okay.
00:27 - Before we get to it, If my voice sounds a little bit scratchy, I just want to apologize.
00:31 It's not that I'm sick.
00:33 It's that I was rocking out to the Scorpions last night.
00:35 They were here in Portland, and even if they're 70, they still rock.
00:38 It was amazing.
00:39 I don't know how old they are, but they probably are up there.
00:41 - I don't know, maybe being sick may have been a better excuse.
00:45 - Yeah, maybe. (laughs)
00:46 All right, I do have a theme, though, for the week, and let's kick it off with that theme.
00:51 This first one, both of these are recommendations.
00:54 The first one came to us from Matt Kramer.
00:56 Thank you for that.
00:57 And Jeff Glass, I remember last time I said, they announced PyScript, that is Python compiled to WebAssembly running on top of PyIodide and Wasm in the browser, which is amazing.
01:11 So many cool things and so much potential there.
01:14 I pointed out that that was released and there were some breaking changes and it was like last minute that I got that.
01:19 So I just threw it in as an extra, but now I had a chance to look at it.
01:23 So there's a bunch of changes and I just wanna highlight some of the things for people.
01:27 So they're using semantic versioning and I don't fully understand this.
01:33 I guess it's just like month based, right?
01:35 So it's 2022.09.1.
01:38 That doesn't mean September 1st though, it was released on September 30th.
01:41 So about 11 days ago, 10 days ago.
01:45 And they just reiterate this project is undergoing lots of changes.
01:50 It's in its super early stages.
01:52 The calendar versioning doesn't really indicate that it's like 0.1 or whatever type of level, but there's a lot of breaking changes.
01:59 So if you've worked with it before, just you wanna read through this and figure out where things are going.
02:05 It doesn't look like anything's majorly broken in like you've got to rewrite a ton of stuff, but it also, there are parts that will stop working, but they seem pretty easy to fix.
02:15 So first of all, like many Python programs, you need to express your dependencies.
02:21 You would do that through a pyproject.toml or requirements.txt, unless you're on the web running the browser, then nope, you don't do that.
02:29 Instead, what you would do is you'd use this py-env section to express, I depend on these packages, either just a URL to a wheel, a Python wheel, or something that could be pip installed using micro pip.
02:41 That's gone.
02:42 It's now deprecated and will be taken away.
02:45 So now that's folded into the py-config section, and there's a way to just say packages are a list of packages and files that we're using is a list of paths.
02:55 And it's in these kinds of places where you indicate what Python files you might write and import, because while you can write Python in HTML, just like JavaScript, you should do that very sparingly and you shouldn't just write your, you know, a thousand lines of Python like inline.
03:10 That's not a great idea.
03:12 So you would link over to a set of Python files that you can run one of them and import others from that.
03:18 All right, so pyenv going away, folded into pyconfig.
03:22 This is one of the things that's easy to fix, but like I said, will stop working.
03:25 They've also changed the syntax of some events.
03:29 So you might've seen people on HTML elements like a paragraph or a div or a button, say mouse over equals in some JavaScript function name, like a function call, either inline function or a function you've written.
03:43 In PyScript, there's a py-event.
03:47 So there's a pie dash mouse over and a pie dash click type of thing.
03:52 And in here you can just write arbitrary Python.
03:55 And unlike JavaScript, you can actually write arbitrary Python, separate multi-line Python separated by semicolons, look at that.
04:03 Semicolons, they made it to Python.
04:05 You can write arbitrary Python, it doesn't have to be a single function call.
04:09 Pretty cool, right?
04:10 - It is pretty cool.
04:11 Where Python's starting to turn into JavaScript that is changing all the time.
04:15 - Exactly, well that's why the breaking changes.
04:17 No, just kidding, that's the new project, but don't let it become JavaScript.
04:21 (laughing)
04:22 I'm very excited that maybe it could supplant JavaScript to some degree.
04:26 There's some stuff about HTML escaping, so you could do like print a string and that will show up in the browser sometimes, or you can get it to go to the console.
04:36 But if you put like one is less than two, and that shows up in the browser, you know, that might get interpreted as an opening bracket instead of just a less than symbol.
04:47 So there's some fixes there, some stuff for logging.
04:50 The ability to run multiple runtimes.
04:53 So when people usually do PyScript, they point at just a CDN version of PyScript, which points at a CDN version of Pyodide.
05:03 But you can and easily can do, you can download that, customize it, and put it in your static files and run it out of there.
05:12 You could possibly not even use Pyodide itself, you could use, say, like, MicroPython, potentially.
05:19 Or you could actually have maybe different versions of PyEdite running in different sections of your site, if you wanted, so different PyScript blocks, presumably even on the same page.
05:31 So, a lot of flexibility about managing multiple runtimes.
05:35 Let's see, a few other things.
05:36 There's also some major releases of PyEdite that's coming along, and because it's built on top of PyEdite or runs on top of PyEdite, PyScript does, obviously the changes there are super important.
05:46 So some of the changes are that they broke, it used to be kind of like one huge namespace and they broke that up into a bunch of pieces.
05:53 So you got to know about that.
05:54 But probably the most relevant for people is you used to have to do this thing where you would import from JavaScript some event and do like a proxy type thing to like hook an event, which wasn't terrible, but it was kind of like, well, he's still doing Python, I don't know.
06:11 Right, so they've written a bunch of event handlers or event sources in pyodide ffi.wrappers.
06:18 So like add event listener, remove event listener, set timeout, set interval, clear interval.
06:24 And so now you can just import, say like add event listener, have a function, Python function, and then you just say add event listener on a tag, on an event, and here's your Python function.
06:33 That's awesome, right?
06:34 - That is awesome, yeah.
06:36 - Yeah, so they've added these event handler sources that are straight Python and not interoperating with JavaScript more directly.
06:45 There's a bunch of things behind the scenes that will make it better, like that we don't necessarily as users care about, but like, and Scriptin is getting better.
06:52 They've got a whole testing scheme.
06:53 You might be interested in this, Brian, for your show.
06:56 They do integration tests with PyWrite.
06:59 They do TypeScript tests, 'cause a lot of the interaction bits are in TypeScript, and they do that with Jest.
07:06 And then Python, the Python code gets tested with pytest.
07:10 That's an interesting mix, huh?
07:11 - I guess just pointing out, we said PyRite, it's PlayRite.
07:15 - Yeah, I'm sorry, I'm too much on the Py right now.
07:18 Yes, PlayRite, thank you for keeping me honest.
07:20 - Yeah, but I'll do a famous pull request on them to try to get that pytest case all lowercase.
07:27 That'd be good.
07:28 - Yeah, I'm not even gonna use this project until that gets fixed.
07:32 So some stuff on infrastructure, there's new CI things that they're working on to make it better.
07:40 They're using type annotations and they're trying to synchronize TypeScript and PyScripts type annotations to kind of keep the end to end across JavaScript, across Python, accurate and a bunch of stuff that's coming.
07:53 In particular, a lot of the rethinking how async works because JavaScript is already like super asynchronous but it just has one loop and if you hook your async Python into that and like, is it really async?
08:05 Yeah, it's a little bit complicated.
08:07 You can check out what they said there.
08:08 But otherwise, very exciting stuff.
08:10 And if you're doing PyScript, definitely check this out 'cause it's going to affect you.
08:14 - Yeah, that's cool.
08:15 Well, let's give your voice a little bit of a break.
08:18 - Yeah, I mean, too much Rocky Like a Hurricane stuff going on.
08:23 - Yeah.
08:24 Well, I wanna talk about decorators a little bit.
08:27 So I was actually on a, I sat in on a Boston, the Python Boston Meetup group.
08:34 It's kind of neat, they're still doing online.
08:38 So it's not really Boston, it's anybody can jump in and have fun there.
08:44 But we're talking about pytest and the, and Ned Batchelder was there and talking about coverage also.
08:52 And he was showing us some of the test code, it was kind of, it was really fun.
08:55 'Cause he was showing us some of the test code within the coverage, the test code that tests coverage by that coverage.py.
09:03 And he was showing some things that, and then about using decorator shortcuts.
09:10 And then I was like, that's really cool.
09:12 I always forget to do that.
09:14 And so he wrote up this, I don't know if it's just for me, but he wrote up a blog post called decorator shortcuts.
09:21 And especially, I mean, I guess for a lot of stuff, we use decorators a lot in Python now.
09:27 And in pytest also uses a lot of decorators, things like pytest mark parameterize or pytest mark skip or X fail.
09:39 Those are all decorators built in part of pytest.
09:43 And so the thing he wanted to show us is like, as an example, he's got some tests that have to, that are either skipped or X failed on certain Python versions.
09:54 So he's got a way to test that piece of code that only works on, say, like, it doesn't work on PyPy, or it doesn't work on like Python 3.8 or before or something like that.
10:08 And so he has these fairly complex version, like XFail decorator sequences that he can take.
10:19 And instead of saying, and let's say he's actually filed, maybe there's an issue, He's actually filed an issue against PyPy, for instance.
10:29 But his tests are still failing.
10:32 He had an example where instead of just this whole big XFail blob with the environment, checking the environment version, and having a reason and a link to the defect, he just shortcutted that to just like a single variable name or single name that says XFailPyPy3749, as an example, just a single thing.
10:57 And then when you're using it, instead of this whole big blob, you can just write @xfail.
11:04 Instead of saying like pytestmark xfail, you can have this specific xfail, and then you get the reason printout and everything.
11:11 Now this is-- - That's very clever.
11:13 - Yeah, especially I like it for this, is we were talking about how we don't like to leave xfails in for a long time, but sometimes you're dependent on a different piece of software that you're not one of the maintainers, in which case, what do you do with the failing test?
11:29 One of the things you can do is you can X fail it and link it to a defect report so you can keep watch of it.
11:37 But yeah, having a way to just mark different tests with the same thing, it's pretty cool.
11:44 And then this really kind of relates to really a lot of things.
11:49 There's a lot of places where we use long, long complex decorators that you can just assign to a variable and then use it later.
11:56 >> Yeah, to put this decorator on a test function, you specify a whole bunch of conditionals around the version, and then the reason is a big long string.
12:05 If that's affecting 10 tests, you put that on 10 tests, it's all over the place.
12:10 One of the things that you hear from people sometimes like, well, I don't like unit testing because it's hard to maintain.
12:16 I find that when people say that a lot, they kind of go into this mode where, when they're writing test code, they forget about things like trying to isolate, change to one place, and you would never write the same code 10 times in a real part of your app.
12:33 Why should you write it 10 times duplicate in a test?
12:36 Well, it's hard to maintain.
12:37 Well, it'd be hard to maintain if you did that in your regular code too.
12:40 You don't do it there, so don't do it here.
12:42 This is a cool technique to accomplish that, yeah.
12:45 - Yeah, definitely.
12:46 >> This part of it, it's also great because it's consistent.
12:51 It'd be terrible if you were referencing this issue in three different places, but only sometimes including the link and having some consistencies good.
13:04 There was some concerns, Larry Hastings put up a concern about possibly not doing this for code that generates a single use object, like a iterator or something like that.
13:20 But just don't do that.
13:23 But Larry has a workaround.
13:26 You can do it a different way if you have something that acts like that.
13:31 - I see, interesting, yeah.
13:32 There's a lot of turtles all the way down, like decorators of functions that return functions.
13:37 And so what we do is wrap that in a function to alleviate the capture, the closure.
13:42 - Yeah, it's fun. - Yeah.
13:44 But anyway.
13:45 So. - Cool.
13:46 Excellent stuff, yeah.
13:49 Next up, our sponsor. - Yeah.
13:51 We have a sponsor.
13:52 Our sponsor this week is Microsoft for Startups, a founders hub.
13:57 So Microsoft for Startups founders hub provides all founders at any stage with free resources to help solve startup challenges.
14:05 The platform provides technology benefits, access to expert guidance and skilled resources, mentorship, networking connections, and a whole bunch more.
14:13 And unlike others in the industry, Microsoft for Startup Founders Hubs does not require the startup to be investor backed or third-party validated or able to relocate to San Francisco for a short time.
14:27 So Founders Hub is truly open to all.
14:29 So what do you get?
14:29 You get free access to GitHub and Microsoft Cloud with the ability to unlock credits over time.
14:35 They've also partnered with other companies like OpenAI to provide services and discounts.
14:41 And Microsoft, through the Microsoft for Startup Founders Hub, becoming a founder is no longer about who you know, you'll have access to their mentorship network, giving you access to a pool of hundreds of mentors across a range of disciplines, across areas like idea validation, fundraising, management, coaching, sales, marketing, maybe even testing, who knows?
15:03 You'll be able to book a one-on-one meeting with the mentors, many of whom are former founders themselves.
15:08 So make your ideas a reality today with the critical support you'll get from Microsoft for Startups Founders Hub.
15:15 And to join or just check it out, visit pythonbytes.fm/foundershub2022.
15:22 The link is in the show notes.
15:23 And I know you can find this stuff on your own with Google or something, but if you go through our link, it helps them know that you heard about them here.
15:33 So thanks.
15:34 - Yeah, thanks Microsoft for supporting the show.
15:37 Brian, before we move on, audience feedback from Henry Schreiner.
15:40 For that exact example, talking about pytest and decorators, I'm not fond of making the test directory importable unless I have to.
15:47 A mark might be better.
15:49 What do you think?
15:49 - A mark might be better?
15:51 I mean, they are marks.
15:52 So the marks are decorators.
15:55 - Yeah, okay, cool.
15:56 What is next?
15:59 Another continuation of my theme here.
16:02 So Mark Madsen sent over a recommendation to talk about this, unrelated to the previous announcement, only in timing or origin.
16:13 So Panel, people probably have heard of HoloViz and Panel is related to that project.
16:19 It's an open source Python library.
16:22 It lets you create custom interactive web apps and dashboards by connecting widgets, plots, images.
16:28 So people have heard of Streamlit, they've heard of H2O Wave, they've heard of Plotly Dash.
16:34 It's like in that category, right?
16:36 So you can put together a lot of interactive fun pieces.
16:39 So for example, here, if you go to the main website for panel, you can see that there's this graph.
16:45 As you hover over it, it's very interactive, but you also have widgets to let you re-evaluate how you compare all these things and just play with it live.
16:53 Kind of like it's a notebook, but it's not. That's neat, right?
16:56 >> Yeah.
16:57 >> So traditionally, this has run in Jupyter Notebooks, or you can run it on the Flask backend type of thing.
17:06 You can host it on your own server.
17:07 The news is not that.
17:09 This has been around for a while.
17:10 The news is that Hanel now comes to Wasm via Pyodide and has PyScript integration.
17:19 That's pretty awesome.
17:20 - That is pretty cool.
17:21 - So in order to host it before, you have to either have a running notebook server or you had to set up your own separate web server and maintain that thing and all that goes with.
17:29 And now you can just put a little py-config in there and boom, when they interact with your data and they run it, it just happens client side.
17:38 No servers needed.
17:39 So let's talk about some of the things here.
17:42 You can automatically convert panel applications to a Pyodide version, a couple of flavors, reasons I'll explain in a minute, or you can convert to a PyScript based app, which is pretty epic.
17:55 So like you could embed a panel inside your Sphinx documentation, just as HTML, which is pretty nuts.
18:02 So there's this convert command, panel space convert on the CLI, and you can tell it the two format from your regular panel code to convert it to a Pyodide.
18:14 This one is good if you want to have a single HTML file that you say, here's my HTML file, off it goes.
18:22 It's just no dependencies.
18:23 And then it runs there.
18:24 That's not as good as creating a Pyodide worker, which creates a JavaScript and HTML file that you got to serve over more of a server, or you can even output a PyScripts version where you can write additional PyScript code.
18:38 It's pretty epic.
18:40 And here you can see a little example.
18:42 This looks like standard XGBoost SKLearn code right here.
18:47 That does all its things.
18:48 Except for the end, you just say pn.column, and here's your output right there.
18:55 And you put your little pipeline you created and maybe a head of a data frame to show up, and there it goes.
19:02 So in order to run this, you would say panel convert the script to a Pyodide worker, output Pyodide.
19:09 Then you just run a server locally so that you can get to it and can pull in the JavaScript, open it up and you get something that looks like this.
19:16 That's super interactive.
19:17 There you have machine learning in the browser.
19:19 That simple.
19:20 - That's pretty cool.
19:21 - The browsers, JavaScript will take over the world.
19:24 It'll like get smart and then take off.
19:27 So a couple of cool tips and tricks they recommend is you can do --auto reload.
19:32 So if you make changes to the file, it'll auto reload the browser.
19:35 So just as you edit, you can also add a panel.convert --watch.
19:41 So if the source files change, it'll regenerate the script and then the script will get reloaded.
19:46 So like you can chain those together, I believe.
19:49 Then there's a section on formats that actually describes what is the point of the different outputs like PyDiver's PyDiverWorker.
19:57 So the worker one says it generates an HTML file and JavaScript that runs better.
20:01 this is the most, in a separate thread, this is the most performant option, but it has to be running out of a server instead of just a file.
20:08 Worth noting here, PyScript generates an HTML file leveraging PyScript, produces standalone HTML files containing pyenv and PyScript tags with the dependencies.
20:20 It's basically a PyScript variant of the Pyodide one.
20:23 Well, guess what?
20:24 This might need a little update, coming soon.
20:26 Py-DENV is not there anymore, so they can check that out.
20:30 I'm sure they're on top of it.
20:33 - Yeah.
20:34 - Final thing to note here that's pretty dope is progressive web apps.
20:38 So this comes with a --PWA option, which turns your, I'm pretty sure this is gonna require the PowerDyed worker variant, 'cause you need these worker things for progressive web apps.
20:51 But this means that you can install your app into say an iPad or install it like a desktop app and run it with cached offline data.
21:02 So for example, let's see if I go to YouTube here.
21:06 I signed in, no.
21:08 Good, so like in Vivaldi, I can right click on this and it'll say, install YouTube there.
21:13 So if you did that option for your panel app, you could right click and say, install panel.
21:18 And you might think, oh, well, that's silly.
21:20 Like who cares about that?
21:21 Let's see if this, this let me do it though here.
21:24 Oh, this is live.
21:25 If you go to a lot of these, just need some video, I don't really care where it is.
21:29 a lot of these you can come in and actually click download.
21:32 I guess you got to be signed in, but if, if you're like a premium account, or you can click download and that's only possible for YouTube installed as a PWA.
21:40 Cause I think a lot of people feel like, Oh, it just gives me an icon on my homepage, but like, there's actually different behaviors.
21:45 So you can get like offline videos on the PWA YouTube, whereas the web one, you can't and so on.
21:52 So anyway, that's the kind of benefits you would get if you would do your panels at PWA, which is just a command line option.
21:58 Interesting.
21:58 Cool.
21:59 Anyway, people check it out if they're interested in building dashboards, they're interested in PyScript and running in the browser using WebAssembly, here's a pretty awesome option.
22:08 Thanks, Mark, for sending this in.
22:09 - Yeah, thanks a lot.
22:10 Did you know that Python 3.11 is coming right up?
22:16 - It's gotta be soon, it's October.
22:18 There's not that much October left.
22:20 - Yeah, but it was 3.8 when we got the Walrus operator.
22:23 Do you realize it's been that long?
22:25 - It seems like the Walrus operator's still new, but that's a long time, yeah.
22:30 - Yeah, so--
22:31 - So an adolescent walrus now, not even a baby walrus.
22:35 - Yeah, exactly.
22:37 So I think it's time for people to embrace the walrus.
22:41 And so one of the things you can do is you can install Marco Garelli's AutoWalrus and it'll convert your code for you in places where you really should use the walrus operator.
22:53 So, and this is good if you're supporting 3.8 and above And golly, I hope you're already up to 3.9 or 3.10 by now.
23:02 So there's this auto walrus, I checked it out.
23:06 It's pretty simple.
23:08 It can run as a pre-commit hook too, which is nice.
23:12 But you can run it on the command line, which that's what I did when I tried it.
23:17 You pip install auto-walrus.
23:19 So it's one word, but with a dash in the middle.
23:23 And then you have this application, you can run it on a file.
23:26 And like we've said, you can run it as a pre-commit hook as well, and it'll run on everything, but you can, and it just converts stuff.
23:34 So if you have things like, here's a simple example of n equals 10, and then if n is greater than three, do something.
23:42 And that converts, the auto-while-res will convert that to the while-res operator of if, you know, n colon equal 10 is greater than three.
23:53 >> Nice.
23:55 >> I like this being separate from other tools because some people just honestly haven't came on board with this already.
24:04 Embrace the walrus sort of thing.
24:07 But it's a fun way to just try it out on your code and do a diff, get diff and see what it changed and maybe you like it.
24:14 Maybe it's a thing to do as a group code review thing to just talk to your team and find out if you want to change it this way or not.
24:23 Yeah.
24:24 And then this reminded me of something.
24:25 I'm like, we had something like this before, right?
24:28 And back in episode 82.
24:32 Wow, that was in 2018.
24:35 We talked about Anthony Sotile's PyUpgrade.
24:41 So, and that's, it's been a while.
24:44 So, that's like four years ago.
24:45 So, I went and took a look again.
24:47 And I would like people to try to check out PyUpgrade too.
24:51 Because there's a whole it's moved on. So it's not just we recommended PyUpgrade for things like upgrading to from two to three sort of thing. >> Was that back in the controversial legacy Python days? >> Yeah. So there's and there's always times to go and revisit old scripts and old applications that you're still maintaining and going, well, we don't really want to support the old Python, but our code serves looks like the old Python. So let's take a look at some of of this stuff. And it'll do things like, you know, the set literal, some of the old some of the old things of and, and doing comprehensions for you and better, the comprehensions are cleaner looking. And then but there's also like different print styles. But one of the things I wanted to point out is if you go to the readme, you got to scroll all the way down or at least halfway down, and you get things like the three six plus.
25:44 So there's these plus options. So you can say if you're running and three, six or above run that.
25:50 But you also want to do like, let's just go all the way down to like three, seven plus.
25:55 And there was a kind of a new way to run sub process for instance, but you're, I mean, and it just finds some of these things and just changes it for you.
26:04 So it's kind of cool.
26:05 And some of the things you may not have remembered the three in three, eight plus the LRU cache.
26:12 You used to have to do the LRU cache call it as a function for your decorator, but now you don't have to do the params.
26:20 Just some cleanup like that. It's just nice.
26:24 I try to run this every once in a while.
26:27 I guess public service announcement for this cool little project.
26:32 >> That is a cool project and going through this huge long read me and looking at it as it gets later and later, Python versions, it's like, here are just a bunch of examples of how Python has changed over the last few years.
26:43 Yeah, who need it has a like 604 type rewrites.
26:48 It'll rewrite Union, the Union operator to the bar operator.
26:53 That's in 310 plus.
26:55 That's nice.
26:56 Yeah.
26:56 Well, we got 311 plus coming soon.
26:59 Yeah.
27:00 Yeah, that'll be fun.
27:01 So awesome.
27:02 Well, that's our items, right?
27:04 Got any extras?
27:05 You know, I was going to have an extra but I'm going to save that for later.
27:11 So no, I don't do you have any extras?
27:13 - No extras, but I have a joke.
27:16 I do a quick follow up to this though.
27:18 This is a hint of what's coming next week.
27:20 I'm gonna talk, I think it's next week I'm gonna cover this.
27:23 Refurb, have you seen Refurb?
27:25 - I don't think so.
27:26 - Refurb is a similar one that like, we'll go through and give you recommendations of here's the most modern way to do your thing.
27:31 So like, if you said, you know, if value is in bracket XYZ, it's like, you know, it's a little less efficient than like why make a mutable list when you could make it a tuple.
27:42 It's a little more efficient just to create the tuples too.
27:45 - Nice.
27:46 - If value is in parenthesis, it'll suggest you change the parenthesis or suggest using some pathlib operations instead of with open operations.
27:55 Like instead of a context manager with open, do a bunch of stuff, you can just do path of thing dot retext.
28:01 You don't need to do the context manager, just bam, there it is.
28:04 A bunch of cool stuff like that.
28:06 So anyway, one more.
28:07 And then also Flint.
28:08 I've talked about Flint a lot.
28:10 I love Flint.
28:11 Super straightforward.
28:12 It brings one of the most beloved things you can do for upgrading your Python is convert all your variations of string formatting to f-strings just across a whole directory of Python files.
28:23 - Cool.
28:23 - A lot of different things to be running together, but are you ready for our joke?
28:27 - I am.
28:28 - You had the comment about bring back the walrus, or I feel like that could be a cool T-shirt, right?
28:35 - Yeah.
28:36 - Yeah, absolutely.
28:37 So I came across this place a little while ago.
28:39 I don't know if you have any particular one recommend here, but this place that has like funny, geeky t-shirts.
28:47 So I thought I'd just pull a couple of these up and see what you think about them.
28:51 So some of them are good.
28:53 I like the first one, the Mordor.
28:54 The Mordor fun run.
28:57 One does not simply walk into middle earth.
29:01 You have a, some for our data science friends out there.
29:04 It has a graph of two things that are very similar.
29:08 One is a shark attacks.
29:10 The other is ice cream cone sales, and it says correlation does not imply causation.
29:15 Apparently ice cream sales and shark attacks are closely correlated 'cause it's warm, you go in the water.
29:21 It probably doesn't cause shark attacks.
29:23 - It might.
29:25 - It might.
29:26 If you are more into math, you have the distance raptor divided by time raptor is the velocity raptor.
29:33 But there's some really good programming ones in here as well.
29:39 Like this one, for example, check this out.
29:41 Go outside, the graphics are amazing.
29:43 And the picture of the shirt is like a super low bit rate, like graphics.
29:47 (laughing)
29:49 Here's a good one.
29:52 Some lab person pouring like beakers of clearly poisonous green stuff.
29:57 It says, forget lab safety, I want superpowers.
29:59 Oh boy, what about the, what do you think of this one, Brian, here, the forecast for Alderaan?
30:06 So remember Alderaan is the home of Princess Leia that was blown up by the Death Star in Star Wars.
30:14 And it says five day forecast Alderaan, Monday 72 and cloudy, Tuesday 74, Wednesday 15,000 degrees, no Thursday or Friday.
30:23 It's kind of mean, but it's also kind of awesome.
30:26 Yeah.
30:27 Yeah.
30:28 This is me.
30:29 Let me see if I can find one more.
30:33 One more programming one.
30:35 Oh yeah.
30:36 Let's see. Here's some good ones.
30:40 One, it has a floppy disk.
30:41 It says, "Kids today have no idea what this is." Then this one here, Brian, this is the last one.
30:48 It's somebody holding a CD going into a drive and it just says, "Never forget the CDs." >> Yeah. CD drive.
30:57 I still love that old joke of a person calls into IT help desk and says, I need I need some help because my cup holders broken.
31:07 Yeah, just went in and spilled his drink all over me.
31:11 Come on man, you guys gotta get this.
31:13 They fix.
31:14 Yeah, so you could spend a lot of time on this page.
31:19 I'm not necessarily suggesting you get a shirt here or anything, but it's pretty.
31:23 It's pretty awesome.
31:24 What makes me miss think geek?
31:25 I think it should have never.
31:27 Yes, hold it.
31:28 But we have we have other people coming up with good humorous shirts.
31:32 So that's good.
31:33 Yeah.
31:34 Houston, we have dibs.
31:35 Putting the flag on the moon.
31:36 [LAUGHTER]
31:40 Dibs on the moon.
31:42 Got it.
31:43 So a more serious--
31:46 a couple quick follow up here.
31:48 Marco Garelli, from the project that you talked about, the auto walrus, says, yeah, I love Pi upgrade.
31:54 And Will McGugan-- hey, guys--
31:57 we could use the Pi upgrade because Rich is dropping support for 3.6.
32:02 So just clean it up.
32:03 >> Yeah. Then I want to follow up with the first thing I was talking about, about the decorators.
32:12 Henry Schreiner said, I think I got the wrong one.
32:16 But for that example, I'm not fond of making the test directory importable unless I have to, a mark might be better.
32:24 I guess I brushed that off too quickly.
32:27 I think I still not sure how I would use this.
32:30 If I were to put a bunch of these, like if I had a project wide decorators that I wanted to use.
32:37 I don't know what the best way to do that would be.
32:39 It might be a non-test file that I would import.
32:42 I'll have to play with it. Thanks for Henry for bringing that up.
32:45 I'm not quite sure how to deal with that problem.
32:47 >> Indeed.
32:49 >> All right. Well, should we call it a week?
32:51 >> Let's call it.
32:53 >> All right. Thanks everybody for showing up.
32:55 We'll talk to you next week.