Transcript #323: AI search wars have begun
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 323, recorded Valentine's Day, February 14th, 2023.
00:10 And I am Brian Okken.
00:12 I'm Michael Kennedy.
00:13 Hi, I'm Pamela Fox.
00:14 So thanks, Pamela, for joining us today.
00:17 So for people that don't know who you are, can you introduce yourself?
00:20 Yeah, I'm Pamela, and I currently work at Microsoft, where I am a cloud advocate in Python,
00:26 which means that I figure out how to get stuff working on Azure while using Python
00:33 and make sure that our code samples are nice and Pythonic and that we're doing things the Python way
00:39 and just trying to streamline the experience.
00:41 And yeah, that's really fun because it just means I get to write Python all day.
00:46 And actually, it just means I deploy all day.
00:48 I'm pretty much always doing something, which I guess is appropriate.
00:53 I once had an ex-boyfriend who named our Wi-Fi network, Don't Stop Deploying.
00:59 And the password was, I like to ship it.
01:01 And I guess it's because I deployed so much back then.
01:03 So I guess I've always been a deployer.
01:05 So it works.
01:06 But yeah, that's what I do now.
01:08 Before this, I was at UC Berkeley teaching Python.
01:11 And then before that was at Khan Academy and Coursera and all sorts of places,
01:15 programming in Python and JavaScript.
01:17 Ooh, neat.
01:18 That sounds like such a fun job.
01:20 I've always thought the developer advocate would be really cool because you get to do all the cool coding tech stuff.
01:26 You don't have to run so much production software.
01:29 So you're not on pager duty.
01:31 And you get to travel and talk to a lot of people.
01:32 Like, what else could you want, you know?
01:34 Yeah.
01:34 I think for you two, it probably would be a really good job too.
01:38 It's always just a really nice combination of programming and using the other parts of your brain too.
01:44 Yeah.
01:45 Excellent.
01:45 Excellent.
01:46 Well, we're happy to have you on the show.
01:47 So thanks for being here.
01:48 And unrelated to Pamela being here and working for Microsoft, this episode is also brought to you by Microsoft for Startups.
01:55 But we'll talk more about that later.
01:57 Brian, should we kick it off?
01:58 Yeah.
01:59 While we all love to be in this tech space and we're all big fans and that's why we're here.
02:06 Sometimes you just want to get away, right?
02:07 And especially in the American West, there's a lot of places that you could get away to.
02:13 The camping sites around here are magnificent.
02:16 There's one that I really like that has free roaming peacocks that just cruise through your camp while you're camping.
02:21 It's really nuts.
02:22 And eagles flying around.
02:24 However, that and all the other places are super hard to find for this exact same reason.
02:30 Okay.
02:30 So one of our listeners, oh gosh, I don't see his name here, but Justin is the name here.
02:40 Justin Flannery from Denver, also a place with great camping, put together this cool CLI, this terminal app called Camply.
02:51 So Camply is the campsite finder.
02:54 It's a tool to find campgrounds and campsites that are typically sold out through recreation.gov and Yellowstone and other sites.
03:03 Okay.
03:03 Okay.
03:04 So, you know, it's all Python.
03:06 So the idea is basically you, it talks to all these different APIs.
03:11 You can either run it in Docker or just run it in Python, I believe.
03:13 PipX install Camply, which I love it.
03:16 PipX is exactly how CLI tools that are not part of your programming story should be installed coming from Python.
03:23 And so you would say like Camply, recreation areas, dash, you could do a search like dash, dash search, Glacier National Park.
03:31 Or have you ever wanted to stay in a fire lookout tower in California?
03:35 How cool would that be?
03:36 That'd be pretty neat.
03:38 Depends if there's a fire or not.
03:40 Yes, exactly.
03:41 Well, if there's no fire.
03:43 So maybe, maybe not September.
03:45 I don't know.
03:46 Yeah, you got a glacier and a fire.
03:48 So maybe you just use this to counter each other.
03:51 Have you ever wanted to go down a really long ladder to use the restroom?
03:55 Oh, you're so practical, Brian.
03:58 So practical.
03:59 Anyway, these things are not super easy to find potentially.
04:04 So you can say, I'm looking for campsites in some area, start date, end date, and search forever.
04:09 And it'll just sit there and just wait and hang out.
04:12 So it'll search at recreation.gov, Yellowstone, going to camp, Reserve California, some other places.
04:18 And yeah, it'll just sit there and pull that data for you.
04:23 And I think it's just a really cool app.
04:25 It's a cool use of Python.
04:26 And people, if they're interested in going camping.
04:31 The bit about this that I like is it has configurable notifications for if it finds something.
04:37 So if you're looking for a particular campground and you just got it running in the background,
04:41 you can have it hooked up to give you a Slack notification or an email or even a text message through Twilio.
04:47 And that's pretty darn cool to be able to just have it, you know, text you when you find something.
04:54 Yeah.
04:55 Just kick it off.
04:55 Let it run.
04:56 Let it keep watching.
04:57 Is it a cron job?
04:59 How does the search forever work?
05:02 I think you leave it.
05:03 I don't know for sure, but I think you just leave your terminal running.
05:06 It must have a sleep or something.
05:09 I don't know.
05:09 Yeah.
05:10 Yeah, yeah.
05:10 You would hope.
05:11 Otherwise, it's going to get banned pretty soon.
05:13 But no, I would think it just pulls every so often.
05:16 I think it's doing, I think there's some APIs in here.
05:20 If you look through, it talks about where the data is coming from.
05:24 You know, there's a recreational information database from recreation.gov.
05:30 And, you know, it's pulling some of that data.
05:32 And yeah, I do think it's really cool that it also does those different notifications.
05:37 I've just learned about push bullet and push over and realized I should probably figure out
05:41 what those are.
05:41 Those sound cool.
05:42 I know what Twilio is.
05:43 And one of the things I like about this is this could be like a SaaS app or something like
05:50 that.
05:50 Yes.
05:51 But I'm glad that somebody, but you don't have to.
05:54 If you have like a cool need that works for you and you think somebody else might have a
05:58 need for a similar thing.
05:59 So build something like this and share it.
06:01 You don't necessarily have to make money off the back of it.
06:05 There's a lot of, it's one of the things I've trained to be pushing more is software developers
06:11 have these skills that we can build things like this.
06:13 But a lot of people don't.
06:15 And being able to build things and share things is one of the great pleasures of doing what
06:20 we do.
06:20 So kudos to Justin.
06:21 Absolutely.
06:22 Yeah.
06:22 Yeah.
06:22 Well done, Justin.
06:23 Thanks for sending that in.
06:24 And one of our listeners, Kim, also been on the show before, points out that, you know,
06:30 he's from South Africa.
06:31 You should try camping in some places in South Africa.
06:33 Free roaming rhinos and elephants are slightly more concerning than peacocks.
06:37 Yeah.
06:38 I'm impressed with people that live in places that have, you know, free roaming rhinos
06:42 or pretty much all of Australia.
06:44 All of it.
06:45 Yeah.
06:46 Very impressed.
06:46 It's a lovely place, but I'm always a little nervous to be like out of the city there.
06:50 Anyway.
06:51 All of nature wants to kill you in Australia.
06:53 Exactly.
06:53 And it's good at it.
06:54 All right.
06:55 Off to you, Brian.
06:56 Okay.
06:57 Wow.
06:57 I'm not sharing anything yet.
06:58 So just one moment.
07:00 Share screen.
07:01 Sorry.
07:02 All of the people were listening and waiting for this.
07:04 Okay.
07:05 We've got fancy readmes.
07:07 So everybody loves you.
07:10 Hinnick points out that your fancy project needs a fancy PyPI readme.
07:16 Of course it does.
07:17 It's very nice.
07:18 There's lots of stuff.
07:18 So what sort of fancy stuff would you like?
07:21 So one example is the black readme.
07:25 So black is one of the ones that uses the same project that we're going to talk about.
07:30 But so what's fancy about it?
07:32 It's just got the normal standard readme stuff.
07:35 But one of the stuff that has things at the bottom is it's got a changelog listed here and
07:41 the authors and some other stuff, the highlights from different versions.
07:46 How do you do that within a readme without copy and pasting?
07:49 So that's where this comes in.
07:50 So this is a project called Hatch Fancy PyPI readme.
07:57 And Hinnick has used, apparently in the past, setup.py for generating for packaging.
08:05 And with that was the ability to do some code while you're running setup.py.
08:12 But pyproject.tomal based stuff is different, right?
08:15 So if you just have a flit thing and you point it to readme, it'll just point to a static readme.
08:21 Or you'd have generators outside of this.
08:23 But what this tool does is it has, apparently there's a hook system within Hatch that allowed this functionality.
08:32 So there's configuration that you can do things like, and there's configuration on this readme to tell you how to use it and everything.
08:40 But the things you'd want to use with it is these little fragments.
08:43 So you can add a text fragment, of course.
08:46 But, you know, that doesn't really help you much because you already have to write it down in your readme.
08:51 But this is actually what this is, is this will be part of your, in conjunction with pyproject.tomal and your readme to work together, which is cool.
09:04 So you can define some of the text fragments in your pyproject.tomal and have them show up in your readme.
09:09 You can also do files.
09:10 You can say, hey, I actually want the author's file in there also.
09:14 And the files have a start after and start before and stuff.
09:19 So some of the files that you include in there might have some boring stuff that you don't want to include in there, and you can cut that out.
09:25 So this is really exciting to be able to, because I've switched like all my project to pyproject.tomal-based projects.
09:32 But I do want some neat stuff in my readme.
09:34 So I'll start using this as well.
09:37 Okay, so you have files.
09:38 You also have pattern matching, which is neat with files.
09:42 But then down below, substitutions.
09:45 Substitutions.
09:46 So you've got like search and replace patterns that use regular expression substitutions.
09:51 And then I think that's all.
09:53 I'm not missing anything.
09:54 But some pretty neat things that you can do within your readme.
09:57 Yeah, and you've got a CLI interface.
10:00 It's lovely.
10:01 It's almost like Jinja, Chameleon, some templating language for your readme.
10:07 So here's the thing that I am always confused about is, do you, you know, there's the readme and then there's the read the docs, right?
10:15 And sometimes when I go to a package, I'm like, which one should I go?
10:19 Like, should I start in the readme and then see if there are more read the docs?
10:23 Like, so this blurs the line even more.
10:25 It's like, should it just all be in the readme?
10:28 When do you go to, you know, the external docs?
10:31 Well, okay.
10:32 So I've struggled with this on a couple of things.
10:34 And I've got one that's like on the line.
10:37 It's got a ton of functionality.
10:38 And so maybe it ought to be a read the docs thing.
10:41 But some people have really big readmes.
10:43 So which should you go to?
10:46 Well, the package.
10:47 So are you talking about the package maintainer or the person learning about the package?
10:51 Where should they go?
10:52 Well, I think you have both those questions, right?
10:55 Because one thing is I can't decide where should I link to.
10:57 Should I link to the PyPy page or should I link to their read the docs page, right?
11:01 It's just what is the canonical documentation?
11:03 And right now, I think as both a creator and a user of packages, it's not clear where to go.
11:10 Well, as a user, I always try to start at the PyPI page and whatever.
11:16 Hopefully there's either a homepage.
11:18 It's got like Black has homepage and changelog.
11:21 You can include a documentation link too.
11:23 So if it's just got a homepage, it's just probably the readme.
11:28 But the documentation, I think it's nice if people leave the homepage to go to their GitHub repo and add a documentation link if they've got a read the docs thing.
11:41 I think so.
11:42 I do like to see a lot of stuff in the readme.
11:45 Because if you're already there, you don't have to go track it down.
11:48 The time that I would see, Brian, maybe as if there's like a lot, a lot of different scenarios.
11:55 Here's this API function and here's a tutorial and here, you know, maybe there's a lot of navigation, I guess.
12:01 Maybe it makes sense for a read the docs.
12:03 Or if it fits on one file, then maybe make a copy.
12:06 I don't know.
12:07 And I've got a lot of like tiny little pytest plugins that I'm just not going to do a read the docs documentation tree.
12:14 It's just a little tool.
12:15 So small tools.
12:16 It's easy.
12:17 It's the in-between part that it's difficult.
12:20 So I don't know.
12:21 Yeah, for sure.
12:23 All right.
12:23 I love our audience.
12:24 They all have great things to add here.
12:26 Henry Schreiner says, GitHub dependency graphs now support PEP 621 as of yesterday.
12:33 So how's that for keeping on top of things?
12:35 So perfect time to switch.
12:36 If you haven't yet, nice readmes too.
12:38 And then Saro says, the docs link should always be at the top of the readme.
12:45 So excellent.
12:46 Yeah, I like that too.
12:48 Yep.
12:49 And one more piece of real-time follow-up.
12:51 Justin, author of Camply, is in the audience, says, yes.
12:55 Wait, no, wrong one.
12:57 I got out of sync there.
12:58 Thanks for featuring this.
12:59 You can leave it running in the background.
13:01 That's where the accompanying Docker image is from.
13:04 So you could just push it over to a Raspberry Pi and just let it cruise there, which is kind of cool.
13:08 So just to figure out, make sure I understand this, if you close your laptop while a Docker image is running, is it going to keep?
13:16 It's probably going to stop.
13:17 Okay.
13:18 It depends on your sleep.
13:19 So that's why you want the Raspberry Pi?
13:20 Yeah.
13:21 Yeah, something you can just leave on.
13:22 Or, you know, something, I guess you could set your laptop to still running if the clamshell
13:28 bit is closed.
13:29 But generally, it would close.
13:31 You could even put it onto one of those little tiny Adafruit things, I would imagine.
13:36 I doubt that there's anything that platform-specific.
13:39 Probably just requests and stuff.
13:41 Or you could have a Mac Mini running.
13:43 Yes, you could definitely have a Mac Mini running, like the one I'm using right now.
13:47 All right.
13:47 Before we move on, let me tell you about our sponsor this week.
13:52 So, as I said before, this episode is brought to you by Microsoft for Startups, Founders Hub.
13:58 I'm here to tell you all about a fantastic opportunity for startup founders, especially those interested in AI.
14:04 With over six figures in benefits, this program is a game changer for startups.
14:09 You'll get $150,000 in Azure credits, so you can work with Pam a lot to deploy many, many things, which is the richest credit offering from any cloud provider.
14:19 Founders Hub is offering a unique chance to access open AIs, APIs, as well as the new Azure open AI service, so you can easily infuse generative AI capabilities into your applications.
14:29 The team at Microsoft will also provide you with one-on-one technical advice to help you with architectural plans, scalability, implementation, best practices, and security.
14:38 Plus, you'll have access to the network of mentors plugged into the startup world, which we've talked about a lot.
14:44 A huge asset for building your network.
14:45 The best part is the program is open to everyone and has no funding requirements.
14:50 Whether you're in idea phase or further along, it just takes five minutes to apply and you'll get all these benefits.
14:55 So, harness the power of AI in your startup.
14:57 Sign up for Microsoft for Startups, Founders Hub.
14:59 Today at pythonbytes.fm/foundershub 2022.
15:03 Link is in your show notes.
15:04 No-brainer opportunity for startup founders, so don't miss out.
15:07 And Brian, one more thing.
15:08 Just to make the point about how awesome some of these open AI APIs and different things that they're offering here is,
15:15 I asked that same AI to write this ad for us.
15:19 So, how cool is that?
15:22 If you want to do, I don't know if you've played with these things yet, but open AI is really incredible.
15:28 And if you want all these credits to be able to work with it, access to AI, different APIs that maybe people don't all have,
15:35 sign up at our link in the show notes.
15:37 So, thanks to Microsoft for supporting the show.
15:39 Nice.
15:40 And thanks to open AI for writing a cool ad for us.
15:43 Wow.
15:44 I still don't have access to open AI and I work for Microsoft.
15:47 So, I guess I just need to apply for that program.
15:50 Exactly.
15:50 I've been waiting.
15:51 Where's your startup idea?
15:52 Get in the game.
15:53 All right.
15:54 This next one comes to us from Pamphil.
15:58 Well, wait.
15:59 Oh, go ahead.
16:00 Don't we have one from Pamela?
16:03 How did I skip that?
16:04 Yes, we absolutely have one from Pamela.
16:06 Sorry.
16:07 All right.
16:08 Sweet.
16:09 So, I'm going to talk about something new in PyDyde.
16:12 I know PyDyde has been on this show before.
16:15 PyDyde is Python for the browser based on WebAssembly, a port of CPython to WebAssembly.
16:21 Now, the really cool thing, I've been using PyDyde for various projects for a while.
16:25 But the very cool thing that happened recently is that there's now 3.11 support in the latest.
16:31 So, in mains, there's 3.11 support.
16:34 This was the PR for it.
16:36 And so, it's not in stable yet.
16:38 It's in latest.
16:39 But that means you can actually, you know, try it out in their little REPL here.
16:44 I can't pick up 3.11 code off of that.
16:47 But you can see it says 3.11.
16:50 And what they're working on right now is, let's see, they're working on some benchmarks.
16:55 So, they did some benchmarks here to show, you know, there's...
16:59 Because 3.11 has a lot of speed up improvements.
17:02 So, they did a bunch of benchmark here.
17:05 But it looks like they're also interested in other benchmarks as well.
17:09 Yeah, it looks like some are getting faster though, which is really cool.
17:12 Yeah.
17:12 And I also...
17:14 So, I did my own benchmark.
17:15 I mean, I wrote a function called benchmark.
17:17 So, it must be a benchmark, right?
17:19 So, one thing that I use PyDyde for is recursionvisualizer.com.
17:24 This is something I built when I was teaching Python at Berkeley.
17:26 And we taught a lot of recursion in Python, which I know is a weird thing to teach in Python.
17:30 But this is academia.
17:32 So, we teach recursion in Python.
17:34 So, this is a tool that uses PyDyde in order to visualize the cloud graphs.
17:40 And so, you know, when you're doing recursive functions, they can take actually a long time.
17:46 It's actually going to take a while.
17:48 Here we go.
17:49 We got it.
17:49 That wasn't that bad.
17:51 Oh, my gosh.
17:53 It's a bit long.
17:53 Here we go.
17:55 It's amazing.
17:55 So, I enabled 3.11 for this yesterday in my local branch and did my own little benchmarking.
18:08 And it's like 15% faster, which is actually relevant for recursive functions because some of the recursive functions that you run here can actually take a long time.
18:17 All you have to do is increase this parameter a little bit more.
18:19 And it really takes a while.
18:21 So, it is definitely faster for at least this use case here.
18:28 So, that's cool.
18:30 It's not yet in the stable.
18:33 So, you can see what they're working on here.
18:34 It should be in the next release of PyDyde 2.23.
18:38 They're working on that.
18:40 So, I also tried it out in my other tool that uses PyDyde.
18:44 So, this is disthis.com.
18:46 So, this is a way to disassemble Python code in the browser because I love the dis module and I want everybody else to love it too.
18:53 So, disthis.com.
18:56 And the thing that I was able to do with this because of 3.11 is that 3.11 has the specializing adaptive interpreter, which actually replaces certain opcodes with other opcodes when it sees that it's hot code.
19:11 So, some code has been run, you know, at least like eight times and it's doing some particular operation that it can optimize.
19:18 It actually replaces the bytecode.
19:20 So, we can compare this to this and you see that when we have the adaptive interpreter, it's using different opcodes than it used before.
19:31 And it's also got this cache here.
19:33 So, this is cool that now you can actually see 3.11 and see the difference in how 3.11 can work versus 3.10.
19:43 So, yeah, I thought this was really fun.
19:44 This is amazing.
19:46 And your visualizer for the recursion is really cool.
19:50 Yeah.
19:50 Yeah.
19:51 Yeah.
19:52 That's really cool.
19:53 So, this one, this disthis and, you know, props for a good naming there.
19:57 That's funny.
19:57 But, wow, you even get the adaptive interpreter in Pyodide.
20:03 Yeah.
20:04 Yeah.
20:05 So, in order to do this, so I put this together yesterday since I wanted, you know, something cool to show.
20:10 So, to do, if you want to have the, if you want to have the latest Pyodide, if you want to try it out, if you're like me and for some reason have a huge number of Pyodide projects.
20:23 I'm sure you all are.
20:24 You just have to do slash dev, right?
20:26 So, instead of a hard version number.
20:28 And, of course, you shouldn't do this if you're using Pyodide for something production.
20:31 But I don't know who's using Pyodide for something production.
20:34 Because, to me, Pyodide is all about a great way for building educational tools in the browser.
20:39 I have no desire to replace JavaScript with Python.
20:42 I think you should use JavaScript if that's, you know, just trying to make it interactive site.
20:45 But for making educational Python tools in the browser, Pyodide is not, it's so good, right?
20:51 We don't have to run a sandbox server.
20:53 So, if you want to try out 3.11, you just do slash dev instead of a hard version number.
21:00 Nice.
21:01 Yeah.
21:01 This is very exciting stuff.
21:03 What are your thoughts on PyScript?
21:04 Did you play with that, Annie?
21:06 Right.
21:06 So, I think PyScript is exactly what I don't want, which is trying to replace JavaScript, right?
21:11 As far as I understand, I haven't played with it.
21:13 Yeah.
21:13 I think it might be.
21:15 Although, I think also it may offer some interesting alternatives, right?
21:21 Like, for example, if you've got a progressive web app or you've got an Electron.js thing and you want to write Python more locally.
21:29 You know, I think some of these are kind of interesting options.
21:33 Yeah.
21:33 So, for educational tools, for dev tools, but we really need, I mean, we already, even with JavaScript, we're making websites that are not very performant, even with JavaScript.
21:42 And when you bring in these Pyodide, Pyodide is huge.
21:45 It's a big old bundle.
21:46 You shouldn't be like this YOLO downloading Python, downloading Python into your webpage, right?
21:52 It's definitely too big for that.
21:53 That's for sure.
21:54 All right.
21:54 Also, I'm super impressed.
21:56 A lot of our guests will say, I found this cool thing and it was really neat.
22:00 But you're like, oh, I wanted to create this amazing website to demonstrate some stuff of a new feature.
22:05 So, well done on Disqus and other things.
22:07 That's awesome.
22:08 Cool examples.
22:09 Yeah.
22:09 All right.
22:10 Yeah, very cool.
22:11 We'll definitely put those links in the show notes for people to go check out.
22:14 All right, Brian.
22:15 Now, should I go?
22:17 Now it's your turn.
22:18 I can't believe I almost skipped all this amazing stuff.
22:22 All right.
22:22 So, going from really fun to slightly less fun, how about we talk about European law?
22:28 Is that good?
22:29 Sure.
22:30 That sounds exciting.
22:31 Yeah.
22:32 There's this, what is it called?
22:36 Let me pull up my notes here.
22:38 There's the Cyber Resilience Act, the CRA, which is a proposal to hold, I think the most important part is to hold companies that write and ship software liable for knowingly being really negligent about shipping vulnerable software.
22:57 So, for example, you sell a router.
22:59 It's like some cheap knockoff router.
23:02 You support it with updates maybe once, maybe never.
23:06 It has some huge vulnerability that people take over your home network if they run it, you know, RCE, remote code execution, really, really bad.
23:12 You just don't bother to fix it because it's not worth it, right?
23:15 We don't want to worry about that.
23:17 And I think that's the idea of this is to say, companies that do that, no, they can't sell us a device we put in our house or we put software systems that we put into our hospitals.
23:27 And just don't care about fixing them from a security perspective, right?
23:30 Not from a not working so well perspective.
23:33 However, the concern that Pamphil Roy pointed out and sent this over, and that's why I'm talking about it, is there's a concern that that also applies to open source.
23:42 So, if I made some open source project, somebody adopted it, there was some vulnerability in it.
23:49 Am I now facing, you know, fines and punishment from the European Union because I didn't patch my silly little program?
23:57 So, there's this organization called the Open Source Initiative.
24:00 And they, let me pull up my little heights here.
24:04 It says, this Cyber Resiliency Act is an interesting and important proposal for European law that tries to drive safety and integrity for software.
24:13 The proposal includes a requirement for self-certification of suppliers of software to attest that they conform to it for security, privacy, and the lack of CVEs, critical vulnerability events.
24:25 However, the European Commission has framed an exception for open source.
24:30 But they say, we've been doing this for a long time, drawing on two decades of experience.
24:35 We can clearly see the current text will cause extensive problems for open source.
24:41 Since the goal is to avoid harming open source software, we really need to make sure that certain wording of this basically gets replaced.
24:49 So, the thing I'm linking to is the feedback from the open source initiative around this project submitted by Simon Phillips.
24:59 So, people can check it out and see what they think.
25:02 But there's a lot of things out there that are well-intentioned that have unintended consequences.
25:08 And I'd hate to see open source get squashed because, you know, people are afraid of the security liability of it basically.
25:16 Is this related to that lawsuit against the crypto open source authors where they're trying to get lots of money from them, claiming that they should be able to recover their tokens?
25:29 Interesting.
25:31 It might have been inspired.
25:32 I think it's more of a general, kind of like the GDPR, a general law proposed in the EU.
25:40 Yeah.
25:41 Pretty interesting.
25:42 There's a lot of stuff up in the air.
25:44 We've got, you know, the GitHub co-pilot lawsuit.
25:48 And we've got the stable diffusion lawsuit with Getty.
25:53 You've got this kind of stuff.
25:54 In the U.S., everyone seems bent on destroying Section 230, which is the protection.
26:00 The protection to allow people to post their own stuff.
26:03 If you moderate it, it's, we'll see where it goes.
26:06 I have no idea what's going to happen with these things, but they're kind of, a lot of stuff's up in the air.
26:09 And here's one more bit.
26:10 Yeah.
26:11 All right.
26:12 Brian, over to you.
26:15 Okay.
26:16 So, that was deep.
26:18 I know.
26:19 So, I told you we were going from a really fun thing that Pamela did, like, oh, here's some law.
26:23 Well, let's go to something really simple.
26:25 Single quotes or double quotes on your strings.
26:28 What?
26:30 So, let's do a quick poll here.
26:32 Pamela, you got a preference?
26:34 I had to figure this out a couple days ago because I've been trying to make the Azure samples more Pythonic and by running black.
26:41 But black changes all the, what does it change?
26:45 I don't even know.
26:46 I think it's single to double, right?
26:46 Single to double.
26:47 I'm not totally sure.
26:48 It changes all the single to double, but it's such a big change.
26:51 I'm like, it's so arbitrary.
26:52 It doesn't matter.
26:53 So, I undid that change.
26:54 Luckily, there's a black option that you can do, which is, like, ignore string normalization.
26:59 So, I now run it with that.
27:01 Because I don't have, I think the only reason I would tend to do single quotes is that in case I was embedding HTML, I really want double quotes in HTML.
27:09 Of course, that means I'm a bad person that's embedding HTML in my Python.
27:12 So, shh, shh.
27:13 There's other reasons, too.
27:17 Well, similar, okay, Michael, do you have a preference?
27:20 I think I prefer single quotes because it's one fewer keys to press on the keyboard.
27:26 Yeah?
27:26 Oh, yeah, you don't have to do shift.
27:28 Given that I have, excuse me, that I have RSI issues and I got to be careful of and I have my super cool Microsoft ergonomic keyboard that makes a massive difference.
27:37 But I still always am thinking about what can I do to, like, type less, do less with my hands and accomplish the same thing.
27:43 But I have an exception.
27:45 And it's similar to Pamela's but not exactly the same.
27:47 If I'm doing anything where I want to put a quote.
27:51 So, if I have to say, it's the second day of the week, then I want to put an apostrophe for the its.
27:56 And I don't want to backslash that.
27:57 So, I put double quotes for the string so that I don't have to escape the single quote.
28:02 But if I was using double quotes in the string, then I would put single quotes.
28:05 So, if I'm using one that I'll use inside the string, I'll use the other so I don't have to use escape characters.
28:11 So, that's like the argument that Black has for why they chose the double quotes, I think, is because of the apostrophes.
28:20 But I'm not really writing a lot of prose within.
28:24 If I'm writing a lot of prose, it's a triple quoted string and it doesn't matter.
28:29 Usually.
28:30 Because I'm doing a block thing.
28:31 But, so this article is a single or double quotes in Python.
28:36 And this is coming from somebody that came from R and came to Python and similarly wanted to make sure they were doing things Pythonic-like.
28:44 And they ran across people using Black and, you know, what to do about that.
28:49 So, they looked into it a little bit more.
28:51 And, like, you know, what is, what's Pep8 say?
28:54 Well, Pep8 doesn't say anything about this.
28:57 And I don't think this article goes into it, but the other thing, not just Pep8, but if you try out Python itself, the REPL, if you define a string in the REPL and then, like, X equals hi there, and then say what's the value of X, the REPL uses single quotes.
29:14 So, that seems Pythonic to me unless we're saying the REPL is non-Pythonic.
29:19 So, the real answer in this article is it's up to you.
29:25 But it kind of isn't because people use Black in their projects.
29:28 And there's a lot of people that are Black fanatics and nothing against them.
29:33 I'm kind of one of them as well.
29:35 So, me personally, I am kind of a mix.
29:39 So, I use Black on almost all projects and I use, but I just type it in as single quotes and just let Black fix it for me.
29:48 And so, the RSI is solved and Black's happy.
29:54 But mostly, it's just I don't want to make that decision on a lot of projects.
29:58 But there are some projects that there's a lot of quotes in there and it really, or the tradition, or there's a ton of code already there.
30:06 And so, I wanted to point out that this, I guess, is a public service announcement.
30:11 If you're not really into Black or just this part of it, just Black is a great idea, but I just don't want to go with double-quoted strings.
30:20 There's blue.
30:20 So, everybody, just remember there's blues around.
30:23 Blue is just like Black, but there's three primary differences.
30:27 The single quote, it defaults to single quotes instead of double quotes.
30:33 So, for projects where it really makes sense to use most of the time single quotes, and I have several that we're sending strings to other APIs, and it's just tradition to use.
30:45 There's other parameters inside that use double quotes, and they can't be single quotes inside.
30:50 So, there's projects I use blue on that for that.
30:54 The other thing is black defaults to the line length of 88 characters, I think, which is a little weird.
31:02 I know there's logic around it, but it's still a little weird.
31:06 And if you're going with Pep8s or the traditional 79, I don't think Pep8s specifies 79, but a lot of people use 79.
31:13 So, blue defaults to 79.
31:15 And the other thing that I like is it preserves white space around hash marks.
31:20 So, if you've got comments along the right side of your code, like in multi-lines, and they're lined up by the hash marks, black will strip that out and says, ah, you only need two spaces there.
31:31 And blue says, you can align over there.
31:33 That's fine.
31:34 So, those are the three differences.
31:37 So, blue is pretty cool.
31:38 I like it.
31:38 Yeah.
31:39 Pamela, use blue, black.
31:42 Yeah.
31:43 Oh, my gosh.
31:45 There's too many options.
31:45 I am waiting for rough to implement formatting, and then I will have only one tool that I need to use for everything.
31:52 Because rough now supports eyesore and pi upgrade.
31:55 So, we're just waiting.
31:57 And Charlie says he's working on formatting.
31:59 So, I'll just do whatever rough does.
32:01 Rough is awesome.
32:02 Yeah.
32:03 Rough is really cool.
32:04 Some interesting angles from the audience I think we're throwing out here.
32:10 However, if you want to fix this, if you think black should use single quotes, just do a PR.
32:14 I'm sure they'll accept it.
32:15 I hear a thing like, no, we've decided.
32:20 Kim says, if you write both C and Python, you'll learn to stick with double quotes, or you'll wonder why C doesn't work.
32:26 And, yeah.
32:28 So, basically, David Poole says the same thing.
32:31 Like, if you're working in a language that treats or doesn't support single quotes for strings, like, you might want to.
32:38 It's not the only thing.
32:39 I keep trying to write print Fs in my Python code.
32:43 You do?
32:44 Wow.
32:44 You're so old school.
32:45 I use C out less than, less than.
32:47 For my C++ style there.
32:51 All right.
32:52 Yep.
32:52 All right.
32:53 So, who we got next?
32:55 Pamela.
32:56 Pamela.
32:57 This weekend, I decided that my personal website is overengineered.
33:02 So, my personal website is PamelaFox.org.
33:05 And it's super overengineered.
33:08 So, right now, it is a Docker.
33:11 So, it's containerized.
33:12 It's a Flask app running inside a Docker container on Azure container apps with a CDN in front.
33:21 And it pulls the data from a Google spreadsheet, an authenticated Google spreadsheet.
33:27 So, all this data is actually from a Google spreadsheet.
33:30 That's cool.
33:31 So, it's a little overengineered.
33:33 And part of the reason it's overengineered is because I ported it from App Engine, Python 2.7.
33:37 So, like old school App Engine.
33:38 And I was trying to port it to Azure.
33:40 And so, I was using Memcache before.
33:42 And I was trying.
33:43 So, that's why I put a CDN in front.
33:44 So, anyway, I realized, you know, it's not that fancy of a website.
33:48 And the data only updates like once a month or something, right?
33:52 So, why do I have this whole Flask app that's just running all the time using up cloud resources?
33:57 So, I wanted to be less wasteful.
33:59 And I also wanted to try out static web apps because I feel like everybody's talking about that all the time, at least around me.
34:05 So, I was like, okay, how could I make this into a static web app?
34:08 And people have recommended various things in Python like Pelican and Lector.
34:13 But I already had this Flask app.
34:16 So, I was like, there has to be an easy way to do this for Flask.
34:18 So, I found this frozen Flask.
34:21 And it takes a Flask application and turns into a set of static files.
34:26 So, you just put in this code here.
34:29 And then you just run this.
34:30 And it'll create a folder and put the HTML files in there.
34:34 And it just does it by looking at the routes and then looking at all the URL for and then recursively following URL for until it thinks it gets it all.
34:42 And then you can deploy it.
34:44 So, you could deploy to whatever static web apps.
34:47 So, I deployed to Azure.
34:48 But you could also probably deploy to Netlify or wherever the cool kids deploy their static web apps.
34:54 GitHub Pages, Netlify.
34:55 Yeah.
34:55 So, if you do GitHub Pages, then you do have to check it in, right?
34:58 So, that's the only thing is if you did GitHub Pages, you'd have to check it in.
35:01 So, now I see one of the advantages of using something other than GitHub Pages.
35:04 Because I usually use like Recursion Visualizer, Dish This, they're all GitHub Pages.
35:08 But I wanted to see, oh, what's it like when you're actually not just using GitHub Pages for everything?
35:14 So, I thought this was cool.
35:17 And it's not a recent thing.
35:20 But the thing that's relevant is that it recently lost its maintainer.
35:26 So, in December, there was this pull request where the current maintainer, the most recent maintainer, stepped down.
35:33 So, it currently has no maintainers.
35:36 So, that makes me sad.
35:38 And maybe somebody here to maintain it.
35:42 Because to me, it was a very useful project.
35:44 Because I was able to, here's the pull request, right?
35:47 And the pull request does way more than I actually had to change.
35:50 But, you know, I was able to do this freeze and then, you know, set up some infrastructure.
35:55 And boom, I've got a static website.
35:58 And I didn't have to do a big old port to mark down and Pelican and, you know, all sorts of things.
36:04 So, I think it's a cool project.
36:06 It could use a little love today on Valentine's Day.
36:09 Some maintainer love.
36:11 So, that's what I wanted to show it.
36:14 So, I like Kim's comment saying, surely personal websites are supposed to be over-engineered.
36:21 It's how you learn what not to do in your employer's production environment.
36:25 Yeah.
36:27 No, I know.
36:28 And so, you know, I'm glad I over-engineered it.
36:30 But then I saw the bill.
36:31 I was like, I really do not need to be paying this much for my personal website.
36:35 So, I did learn.
36:37 Yeah.
36:38 Thank you, Kim.
36:38 Yeah.
36:39 So, my personal stuff's on Netlify.
36:42 It's a Hugo.
36:43 Running Hugo as a generator.
36:45 And then running on Netlify.
36:47 And it's all free.
36:49 So, I like that.
36:50 But I like the work.
36:51 It's mostly the workflow.
36:52 So, the workflow of like, I want to write something new.
36:55 What does that workflow look like?
36:57 And right now, it's write a markdown file and commit it and push it.
37:00 And that's it.
37:01 So, I like that.
37:02 Yeah.
37:03 For me, it's I update my Google spreadsheet.
37:05 I'm debating I might move it to a JSON file.
37:08 Because, you know, then I could have like a CI that just makes sure the JSON is well formatted.
37:13 Maybe something like that.
37:15 But I'm kind of a freak for spreadsheets.
37:17 So, I've been using a Google spreadsheet for 15 years.
37:20 Spreadsheets for website content?
37:21 Actually, I love it.
37:23 It's so amazing.
37:24 You've got to have overflow wrap, though, on some of those columns, I'd imagine.
37:29 In the spreadsheet, right?
37:30 Yeah.
37:32 Yeah.
37:32 I know.
37:32 This looks like a really cool offering or a cool library for people who, for whatever reason, have a website written in Flask.
37:39 And it doesn't have to just be for a blog or a personal site.
37:42 You know, it could be someone's built a Flask site for like an e-commerce type of thing or some marketing type of thing.
37:49 And they realize, you know, we don't really change this.
37:51 We haven't changed this in a year and a half.
37:53 Why do we need to maintain servers and patch things, right?
37:56 No.
37:56 And this is kind of a neat project for somebody to take on as a new maintainer.
38:02 Yeah.
38:03 Looking to level up your open source game.
38:06 How about extras?
38:07 We got all of our main stuff done.
38:09 Pamela, do you have extras?
38:11 The extra that I was going to mention was already brought up in the chat was the fact that GitHub dependency graph now supports pyproject.toml.
38:20 And I think maybe Henry brought that up.
38:22 Yeah.
38:23 Henry brought that up in the chat.
38:25 But I was going to show, wait, where's my, okay.
38:29 So I found this Python package template from Microsoft for somebody at Microsoft.
38:35 So if you're starting a new Python project, this has like everything in it that's done the proper way, including the pyproject.toml.
38:43 Or, okay, maybe not proper.
38:45 The way that they think it could be done.
38:47 So if you use this, then, you know, then the GitHub dependency graph should pick up on your dependencies.
38:58 So that was my extra thing was just to talk about the pyproject.toml with the dependency support now.
39:05 Okay.
39:06 That's big news.
39:07 Very good one.
39:07 Brian?
39:08 I'll have to go take a look at that and see what all I disagree with.
39:11 I guess.
39:12 I was just...
39:16 The hemisaur structure.
39:17 You're halfway there to liken it.
39:18 That's good.
39:20 So I just was curious what everybody thought.
39:23 I don't know if this is new, but I just saw it.
39:25 The pricing structure for GitHub.
39:27 Is this a new thing?
39:29 I don't know.
39:30 So the individual user gets extra stuff for $48 a year, essentially.
39:36 It's not per month.
39:38 It's per year.
39:39 So that doesn't seem terrible.
39:40 But what do we get?
39:41 So this is basically the free tier is just always...
39:44 You still get everything for free.
39:46 But the co-pilot is, what, $10 a month or something?
39:50 So there's some extras that you can add on to other things.
39:55 Before the transition or whatever, a couple years ago, I was paying for GitHub Pro so that I could have private repos.
40:01 Now you can have private repos with the free one.
40:05 So I switched to the free.
40:06 Is there...
40:07 What do you guys...
40:08 Michael, do you have an opinion on this?
40:11 I guess I have an opinion since I pay GitHub every month for the Talk Python organization.
40:17 Because if you have an organization and you want to have people in your organization like Talk Python authors, then you have to pay to have them, which is different than an individual having private repos and things like that.
40:30 One of the things that looks interesting from the team perspective is the code spaces, which is basically a server to run your code on, right?
40:38 Is that right, Pamela?
40:39 Yeah.
40:40 But why are they...
40:41 This is what I actually just opened it up to look at that particular point and expanded it.
40:44 Because you can...
40:45 I use GitHub Codespaces constantly on free.
40:48 And you can use it on free as well.
40:50 So I'm trying to understand what the distinction between the free and the team is for code spaces.
40:55 Because I'm also a code spaces freak.
40:57 Looks like on free you've got 15 gigabytes max.
41:00 So...
41:02 I don't know.
41:03 You can just pay for a little bit more.
41:05 I just pay.
41:05 Because I go over.
41:07 And more CICD.
41:10 I mean, I guess I'm getting to the point where a lot of these extra things like GitHub Actions and more complex GitHub Actions.
41:19 And basically, I'm doing more.
41:21 If I ever hit some of these limits, I think I'd be happy with paying.
41:24 Yeah.
41:25 $40 a year is not the worst subscription that I pay yearly.
41:29 Yeah.
41:30 There's stuff I use way less and pay more for.
41:34 Oh, yeah.
41:34 Anyway.
41:35 Okay.
41:35 That was just my extra.
41:36 I was just curious about that.
41:37 Okay.
41:38 I've got a couple as well for us.
41:39 Okay.
41:40 Our transcripts are way better over here now.
41:43 So if people are interested in using the transcripts, which we have for every episode,
41:49 not entirely unrelated to OpenAI stuff, we have way better transcripts.
41:54 Like, for example, even when Brian said PyProject.toml, it got that perfectly right, which is amazing.
42:03 And that means our search.
42:04 We have search.
42:05 That doesn't just search.
42:06 You know, some people search on their site, like for podcasts and stuff.
42:09 Just search as the show notes.
42:10 Our search is every spoken word.
42:13 Right.
42:13 So if you looked for ChatGPT and PyProject, something like that, then check it out.
42:21 We're also live streamed, by the way.
42:22 But there it is.
42:23 Right.
42:23 That one.
42:23 Which neither of those, I believe, were listed in the show notes whatsoever.
42:27 So because we're getting much better, like, tech words in our search, in our transcripts,
42:32 that means our search should be way better for people who try that out.
42:34 Anyway.
42:35 So how did you make the transcripts?
42:37 What did you use?
42:39 Some of the OpenAI API stuff over there, I got a cool Mac app that, like, plugs into that.
42:47 Oh.
42:47 Yeah.
42:48 It's pretty.
42:49 If you need something that will make your Apple Silicon Mac that normally is cold to the touch,
42:56 and you put it on your lap, you're like, oh, that thing's a cold laptop.
42:58 You want it like a heater?
42:59 You can try to generate one of these transcripts.
43:02 It'll be warm for about half an hour.
43:04 All right.
43:05 And similar, not the same thing, but somewhat related, is the AI chat wars, I think, are really
43:13 taking off.
43:13 And I watched an interview with Satya Nadella, CEO of Microsoft.
43:18 He was just relishing.
43:20 He was just completely sitting back and smiling and rubbing his hands like, oh, this is going
43:26 to be good because, you know, Microsoft and OpenAI have that partnership.
43:29 I'll leave it at that.
43:31 I guess it's probably a little more complicated with partial owners and credit anyway.
43:35 But they're working very closely together.
43:36 And so Microsoft announces that Bing is going to have chat GDP integration as part of its
43:42 results.
43:43 And you can actually talk to it.
43:44 And GDP4, I believe, not just the one that's out.
43:47 And so as a result of that, like that day, Microsoft Bing rockets to the top of the app
43:51 store after announcing chat GDP integration.
43:53 Like, when was the last time you were like, oh, my God, where is Bing?
43:56 I've got to get it.
43:57 You know, this is just not something that has been happening lately.
44:00 Right.
44:01 And like, boom, overnight it switches.
44:03 The converse is the same day.
44:06 Maybe the next day.
44:07 I think that's the same day.
44:08 Google shares drop $100 billion after the company's AI chat bot flops in the door.
44:14 So contrast those two things.
44:16 And it's going to be an interesting next year or so in the big tech space.
44:20 Yeah.
44:21 So anyway, that's just put that out there as something interesting to check out.
44:28 Also, I worked with the folks at JetBrains to get our students at Talk Python training a free
44:34 copy of PyCharm Pro.
44:36 So for folks who want that, this only works for new users.
44:39 It doesn't work for renewals.
44:40 But if you don't have a PyCharm Pro account already, then just visit the link.
44:45 And you must be a customer at Talk Python training.
44:48 That's part of the deal with JetBrains.
44:49 I can't just hand them out randomly.
44:51 Anyway, if you are, there's like a little statement of what it needs.
44:53 But for many people, they can just check that out and get a free copy of PyCharm Pro, which
44:57 is fun.
44:58 And if you're not already a member, just go ahead and purchase the pytest course.
45:03 Yeah, exactly.
45:04 I think the pytest course, this guy named Aachen wrote it.
45:07 It's pretty good.
45:07 People should check that out.
45:08 The mobile apps last time or time before last, I mentioned I was looking for someone to help
45:14 me rewrite that.
45:14 The flutterification of our mobile app story is well underway.
45:20 And that's so thanks to the audience for helping get that going.
45:24 Yeah.
45:25 And then very last thing, Brian, is I did a Talk Python episode in the behind the scenes
45:30 at the Lawrence Livermore National Laboratory with the folks.
45:33 how Python was used to do the fusion ignition breakthrough that we all heard about like a month
45:39 and a half ago.
45:40 Wow.
45:41 That was a big deal.
45:42 So Python is a super important part of that.
45:44 Turns out, and I interviewed Jay Solomonson.
45:48 He's down at the bottom because of responsiveness.
45:50 But great story.
45:52 Look inside that whole thing.
45:53 So people should check that out.
45:54 I think it's kind of a unique story that this was in the news a lot, but not this aspect of it.
45:59 Cool.
46:00 All right.
46:00 That's all my extras.
46:01 So was the, we usually do a joke, but we forgot our joke last week.
46:05 Was, was the Bing story the joke or?
46:08 No, the Bing story is real.
46:11 We have, we have a couple of good jokes, I believe.
46:13 Yeah.
46:14 Okay.
46:14 Let's for some, let me pull them up here.
46:16 I think you've got one as well, but let me put my stuff back on the screen.
46:20 I didn't know we were supposed to have jokes.
46:22 Oh no.
46:23 We normally, we just have one.
46:24 We just screwed up last time.
46:25 So we only had a, we somehow skipped it.
46:28 So this, this is one of those, you know, you go to the fast food restaurants and you'll see
46:32 they've got these digital menus up on the screen.
46:35 Yeah.
46:35 So here we've got, there's a Mook chicken, all rights reserved little circle meal.
46:41 There's a Big Mac, all rights reserved meal.
46:44 There's a chicken McNuggets, 10 piece meal.
46:47 But do you see what's in the middle there, Brian?
46:49 Yeah.
46:50 The dollar bracket title bracket.
46:53 It's 1350.
46:55 What is it?
46:57 The dollar bracket title.
46:59 It's so amazing that it's up there.
47:00 I don't know if there's just supposed to be curly braces and they missed the shift or something,
47:04 but the comments folks, the comments are nonstop.
47:07 Some of them I can't read because, because it's, you know, not necessarily safe for work,
47:14 but it's like, you know, what the blank is happening to my menu.
47:18 And oh my gosh, it's so good.
47:21 It's funny.
47:21 Yeah.
47:22 Also the pricing is really high.
47:24 I don't know who pays, you know, what is that?
47:26 $13 for a McNugget meal or $10 for a cheeseburger, but that's a pricey burger.
47:32 I guess it's a meal includes a drink, but still whatever.
47:35 That's a lot.
47:35 Yeah.
47:36 That's funny.
47:38 Okay.
47:39 Well, I have something that I was laughing like so hard at, and I'm not going to go through
47:44 all of it, but it's, it's 59 hilariously infuriating examples of user interfaces.
47:50 and, I was like, couldn't, couldn't stop laughing.
47:55 The, the, the first one right off the bat, please enter your phone number.
47:57 It's just kind of plus sign.
47:59 You just walk up.
48:02 and then the second one's actually my favorite is, you got to press it like
48:08 7 million times.
48:09 The, angry birds version of a volume control.
48:14 so you just like pull it back and then shoot the ball to what volume you want.
48:19 Oh, I love it.
48:21 I want that actually.
48:23 That would be fun.
48:24 but there's 59 of these that are just terrible.
48:27 Please enter your phone number with a dial wheel.
48:31 A digital.
48:32 That sounds kind of fun though.
48:33 It's been so long to say, I kind of want to go out and just get an old phone just to do
48:38 that.
48:38 Yeah.
48:39 I, I, a volume slider.
48:42 That's just like, you have to like, make it level.
48:45 Yeah.
48:46 It's like a level.
48:47 It slides the volume to like balance it out.
48:49 Yeah.
48:50 So, is this your phone number?
48:53 It's a phone number entry that just guesses your phone number and you have to say if it's
48:58 right or not, anyway, these are, we won't go through all 59, but, this is, these
49:05 are worth a good laugh.
49:06 don't, it's probably not safe for work unless it's okay for you to be laughing at work.
49:10 there's nothing illicit.
49:12 There is just, you know, you're not allowed to laugh at work.
49:18 Well, this is work.
49:19 This is not for fun.
49:21 You're at work.
49:21 Remember that.
49:22 I had a manager once that like was sat across a long time ago.
49:27 That sat right across from me.
49:29 And every time I glanced over, he was playing solitaire on his computer.
49:33 Like, and like, I'm like, like six hours out of the day.
49:36 Every time I looked over, it was solitaire.
49:38 Like I, I want his job.
49:40 No, but anyway.
49:43 All right.
49:44 Brian, thanks a lot.
49:45 You just ruined the next hour of productivity for me with this, this article.
49:49 Anyway, I guess that wraps up all of our items.
49:53 thanks everybody on the, live stream for watching and everybody that watches it
49:57 later.
49:57 Super.
49:58 Thanks to Pamela for showing up today.
50:00 And thanks, Michael.
50:01 Yeah.
50:01 Thank you.
50:02 Great to have you on the show, Pamela.