Brought to you by Michael and Brian - take a Talk Python course or get Brian's pytest book


Transcript #286: Unreasonable f-strings

Return to episode page view on github
Recorded on Tuesday, May 31, 2022.

00:00 - Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:05 This is episode 286, recorded May 31st, 2022.

00:10 I'm Michael Kennedy.

00:12 - And I'm Brian Okken.

00:13 - And this episode is brought to you by us.

00:15 If you're looking to learn Python, check out all the courses over at Talk Python Training.

00:18 If you want to get better with testing, check out Brian's pytest book, second edition.

00:24 - Yes, yeah.

00:25 - Yes, indeed, indeed.

00:27 All right, well, let's jump right into it, Brian.

00:29 - Okay, actually-- - Tell me about the GIL.

00:32 - I do wanna talk about the GIL, but I was just realizing we're at 286.

00:35 I just started watching Big Bang Theory with my youngest kid, and there's 279 episodes of them.

00:42 So we have more than, it went on forever, and we have more episodes than them.

00:47 - That's quite the milestone.

00:48 I mean, you divide that by 52, that's a lot of years.

00:51 We've been doing this for a while.

00:52 - Yeah, so Python and the GIL.

00:56 So the GIL is a thing, right?

00:57 It's like something everybody knows about, I think.

01:00 People know about, but not too much.

01:02 So, I mean, you kind of, it means we can't do multiprocessing, but we can, but we can't.

01:07 So what is it?

01:09 And so I really like this article.

01:11 So this is an article called the Python GIL Past, Present, and Future, because we have been talking about some of the no-GIL options that are coming.

01:20 And so this is really nice.

01:22 It's, who is it?

01:23 Gary, Barry Warsaw and Pavel Polowicz, I think.

01:28 Anyway, really great article on the Backblaze blog.

01:33 And it starts out and goes through sort of what is the GIL, why we have it.

01:39 It's a lot around the way in some of the history is around reference counting.

01:45 And maybe you knew that off the top of your head, but I forgot that reference counting is something That's how we do memory management and all sorts of stuff within Python, but to make it an easy implementation, there's this global interpreter lock.

02:00 And that just basically, instead of lock like other code, you lock individual items, shared memory that you're using.

02:08 We just say the interpreter, let's just lock that and all of the variables that it uses.

02:13 It's not just reference counts, but other things too.

02:19 And this is just, it's a fairly quick read, but enough detail that you really kind of understand what's going on.

02:27 It does talk through reference counting, talks through some of the advantages, why it's really kind of handy to have it around, but then attempts to remove it, including, like, I didn't know about this one.

02:41 There was a free-threading one in '99.

02:44 - From 1999, yeah, that's, I didn't know about that one.

02:48 - Yeah, it actually was successful.

02:50 It just made your Python code really slow.

02:52 So, not good.

02:54 And then Larry Hastings' Galectomy, he's had a lot of PyCon talks, or a few PyCon talks around this.

03:01 So, that's an interesting thing to read about.

03:05 There's a little more, there's quite a few interesting bits in there, but it never really got back into main Python, but we're getting a little closer where with this no-gil stuff.

03:19 So there's no-gil stuff going on with Sam Gross.

03:24 - From Sam Gross.

03:24 - Yeah.

03:25 And then also, and then also we've got Guido and others in Microsoft now working on this problem of speeding it up and everything.

03:37 So really great discussion if you wanna catch up on all the history of the GIL and where it's going.

03:44 And then a little prediction at the end of we're going to see speedups because of these efforts.

03:50 We're going to see speedups in the next few years.

03:52 Just it's just going to get faster.

03:54 Then if we get no Gill, it might be maybe five years from now.

04:00 >> Yeah. It's pretty exciting.

04:02 There's some very neat work.

04:04 The stuff that Sam Gross is doing is quite interesting.

04:07 >> Yeah.

04:08 >> What's really cool is it's not just theory or people playing.

04:12 The Python 3.11 is a lot faster than the previous Pythons already.

04:16 It doesn't even really touch the GIL side of things.

04:19 There's actual progress being made.

04:21 >> Yeah. It's pretty exciting time to be part of Python.

04:27 It's never not been exciting.

04:30 >> It only gets more exciting. How's that?

04:32 >> Yeah.

04:34 >> Hey, let me ask you a meta question.

04:36 This is on the Backblaze blog.

04:39 Backblaze.com is one of the, I think better sort of back up my computer somewhere off site sort of things.

04:46 Yeah.

04:47 And the fact that they're blogging about the Python GIL is kind of interesting.

04:52 I wonder if they're a big Python shop and we just didn't know it.

04:54 Well, there's like, I didn't know it's on their blog, but I mean, we've got, very Warsaw is written by Barry Warsaw Powell.

05:04 Yeah.

05:04 So are they, is he, he's, he says he's currently is the senior engineer at LinkedIn.

05:10 >> Yeah.

05:11 >> I'm not sure.

05:12 >> Sometimes life's confusing.

05:14 >> Yeah. Not sure how this ended up there.

05:17 >> But it's cool to see Backblaze support in the Python world with some dives into that.

05:22 >> Yeah. Maybe somebody from Backblaze can reach out to us and tell us what's going on.

05:26 >> Yeah, that'd be great. Also great, wouldn't it be cool, Brian, if we could take our Python program, whether this is a CLI or some other app that we need to have for people to run, and instead of saying, "Well, make sure you have this version of Python at least, and make sure you've set up a virtual environment, you've installed these things, and then you've got this in the path, and then you've got this environment variable, now you can try to run our thing I gave you." >> Yeah.

05:50 >> If you could just give them a single binary that contained all of Python, contained the standard library, and you said you run this, and that's your app.

05:59 That's not bad, right?

06:01 >> Yeah.

06:01 >> So let me introduce you to PyOxi, the PyOxi Python runner.

06:05 Now, a while ago, we spoke about this thing called PyOxygen, no, PyOxidizer, that's what it was, PyOxidizer.

06:16 And this is kind of like an advanced version of Py2EXE or Py2App or PyInstaller.

06:24 But what's really nice is that it bundles the stuff up just sort of all into one thing and it runs out of memory instead of creating like a file structure of the files that you need and then sort of altering the path.

06:35 So like a copy of Python will run that and so on.

06:39 So this PyOxi attempts to make the features of PyOxidizer more accessible and simpler for people.

06:46 So here's the deal.

06:47 It is an executable program for running Python interpreters.

06:51 So you can just give somebody this one PyOxi file and they can, instead of saying Python this, they can say PyOxi some Python file, right?

07:00 You can say like run Python or run Python --and give it a file or something along those lines, right?

07:06 And it's just a thing you copy around.

07:09 You don't have to worry about installing it or configuring your system or anything like that.

07:13 So it's kind of a really easy way to pass around an executable that is Python in the standard library without all the overhead or setup of actually installing a Python runtime.

07:23 - Okay.

07:24 - Okay? - Yeah.

07:25 - Yeah, so let me go back up here.

07:27 That's pretty cool.

07:28 That's one of, it's a single file.

07:29 it's a single file that is a highly portable distribution of CPython.

07:34 So for example, on macOS and Linux, it statically links in a lot of the files that are dependencies that you might find.

07:42 So if you try to run something in Python, it might go like, oh, you have to install this other like C library in order for it to work correctly.

07:49 So all those things are also like its dependencies are statically compiled into it, which is pretty cool.

07:54 Another thing that's interesting is it gives you a lot more control over the interpreter and how it behaves.

08:00 Like you can pass it configuration files and do all sorts of crazy stuff to really tweak the behavior of the runtime, the Python runtime that it comes with.

08:09 >> Yeah.

08:09 >> It's just to make PyOxidizer apps more accessible.

08:13 Okay. So it's built with PyOxidizer, and basically it gives you its own standalone one.

08:20 Like I said, it has the whole interpreter, it has the stuff statically linked, It has the standard library, and I think you can link your own libraries into it as well, which is pretty awesome.

08:32 And you could also give it, like I said, more control.

08:34 So you can create a configuration YAML file, and when you run it, you can say, "I want you to debug allocations," or "I want you to run this command to initialize the interpreter before it starts to run any code," and things like that.

08:48 So you can give it this YAML config file and so on.

08:52 So anyway, it's a pretty new project.

08:55 This is from Gregory Sork, and he says, "It's very young, I hacked it together to try to get better exposure for PyOxidizer, for people who want to build things that they can distribute more easily and so on." For me, he's talking about, oh, there's some certain circumstances where maybe you want to have people run your script, so you can send the script and then this thing and so on.

09:17 It's supposed to be on par with Zip app, which lets you ship the zipped up thing of your app and then run it.

09:25 But the benefit is it already comes with Python.

09:28 Like a lot of these zip, shiv, pex, etc.

09:31 They all require that Python is installed on the system.

09:34 And then you can run that with its dependencies.

09:37 But this is like, no, it even comes with Python.

09:39 So all that is pretty good.

09:40 What I would love to see out of this is, could I take this and build some sort of UI framework?

09:46 Here that, I don't know, maybe with PyScript, and then get like a UI framework I can ship to people and just go, Download this, double click it, there's your app.

09:56 Who knows?

09:57 >> Yeah.

09:58 >> But anyway, if you're shipping Python to people, this might be worth checking out.

10:03 >> Yeah. Neat.

10:04 >> Yeah. Kim out in the audience asks, it looks very handy, does it make cross-platform executable?

10:11 I think you might have to run a build command or something, or ship the right binary for each platform, but it does support macOS, Windows, and Linux.

10:19 That's pretty cool.

10:20 Now, maybe you covered this and I just missed it.

10:24 What does it deal with my dependencies?

10:27 Like if I have third-party dependencies?

10:29 >> That's what I'm not 100 percent sure how to do.

10:31 When I looked through it, I was looking for that.

10:33 There's this oxidized importer, which it talks about like this embeds a copy of the Python standard library and it imports from memory using the oxidized importer.

10:43 I think that you could use that as well for your own dependencies.

10:47 I'm pretty sure that's the goal of this PyOxidizer project in the first place.

10:51 So I would think so, but nothing from this article was really clear, like, and here's how you bring in a request or HTTPX or whatever you're gonna bring along.

11:00 - Yeah.

11:01 - Yeah, so. - Okay.

11:02 Or pytest.

11:04 I was actually just thinking, if I run these tests, well, what version are you using?

11:11 Okay, just fine, here, just install this and run this test with this, and that would be great.

11:17 >> Yeah, exactly. Yeah, Alvaro, when I was talking about UI stuff, he says, "What about PyOxi plus Textual?" That'd be pretty neat as well, yeah.

11:27 >> Just around the corner.

11:28 >> Yeah. Cool. All right.

11:29 >> Nice.

11:30 >> That's PyOxi, people can check it out.

11:32 >> All right. Well, how about regular expressions?

11:39 Do you like those?

11:41 >> When they work, I love them.

11:44 When they don't, I'm like, What is this madness I've gotten myself into?

11:48 - Okay, so I was almost afraid to talk about this, but it's a really awesome article, because sometimes you need regular expressions.

11:55 And one of the things, there's lots that I like about this article.

12:01 What I'm talking about is an article called the unreasonable effectiveness of F-strings and verbose.

12:08 So regular expressions in all languages, including, I think, including Python, have a notion of verbose mode.

12:18 I've always been enticed by this.

12:20 The verbose mode idea is that you can, instead of having this weird, you still have the hard to read regular expression stuff, but you can put comment, you can put spaces and comments in it.

12:34 >> It can be multi-line, right?

12:36 >> What?

12:37 >> It can be multi-line.

12:38 >> Yeah, it can be multi-line and you can have a bunch of comments in there to say, oh, this part of the regular expression, what it's doing is this, you know, and then, so it makes it, little snippets of regular expression are easier to read.

12:51 You're like, oh yeah, I can see that it's doing that.

12:54 Great.

12:54 It's when you clog it all together, which makes it really hard to read.

12:57 So, and then, of course, you can build up strings in Python with fstrings and do string replacement.

13:06 How awesome.

13:07 So that's what this article's about, is really talking about using, taking some of the complicated bits of your regular expression or duplicated bits where it shows up several times in your regular expression and pulling that string out and even maybe commenting that and then dropping it in with f-strings to build up a complex regular expression.

13:32 It's brilliant and it also is one of the best explanations I've ever read on verbose regular expressions.

13:40 So it's pretty cool.

13:41 >> Yeah, I never really thought to refactor the pattern so that you have multiple strings.

13:46 >> Yeah. >> Be like, here's the part that's repeated, so I'll have a pattern that that's that thing, and then F string it into the other pieces.

13:52 >> Yeah.

13:53 >> But it makes perfect sense.

13:54 Of course you should do it.

13:55 >> [LAUGH] Yeah, and now, I mean, I don't use it, I mean, actually I kind of do.

14:00 I use regular expressions on a regular basis.

14:03 But not like every day, but it's always something that I, whenever I put it in there, I'm like, is anybody else gonna be able to read this?

14:13 And so I put comments around it, but I've never, I haven't ever really embraced verbose mode, and I'm definitely gonna use this now.

14:20 - Yeah, for sure.

14:22 The other thing real quick is you can have f-strings and you can have raw strings and you can have raw f-strings, apparently in Python.

14:29 So the prefix is fr, triple quote, multi-line.

14:33 Like that's some serious string action happening right there, man.

14:36 - Yeah, raw f-strings, nice.

14:39 Yeah. - Yeah.

14:42 And Neil out in the audience asks you, Brian, do you like your regular expressions, greedy or non-greedy?

14:47 - Okay, it depends on what you're trained to do.

14:52 - Yeah, I don't want mine to be greedy.

14:56 Let's share, share kindly.

14:58 All right, are we ready for the next one?

15:00 - Yes. - Cool.

15:01 All right, so this one I wanna talk about, and I'm gonna start off from a weird place, from a tweet that I gave because I can't find anywhere else to talk about it.

15:10 Like this is why this needs talking about.

15:12 So I just wanna sort of highlight some really cool stuff for people who are using PyCharm and doing open source stuff that involves pull requests.

15:21 And these could be pull requests to your private repo, like one team member gave a PR back to the repo.

15:25 It doesn't have to be open, open source.

15:28 - Okay.

15:29 - So if you're using PyCharm, check this out.

15:32 Let me pull up this screen.

15:34 Come on.

15:36 Oh, I'm not logged in.

15:37 Oh, there we go.

15:38 I thought it might not.

15:39 Let me get the image up.

15:39 Anyway, so check this out.

15:40 So people are probably familiar with the Git support in PyCharm.

15:44 You know, VS Code, PyCharm, they all have really good Git support.

15:48 You can see your changes.

15:49 A lot of times you have this sort of, this gray little overlay that says who recently edited a file or a line.

15:57 And it's really cool to go back with like get lens turned on for CPython because you'll see stuff from like 30 years ago, Guido made this commit and here was the commit message.

16:07 Like what, this is crazy, right?

16:09 But working with PRs is one of the things that doesn't normally seem to fit.

16:13 And so I don't know when this got in there, but not too recently, there's now a pull request tab.

16:19 So if you open a GitHub repository, if you're logged into GitHub and that GitHub repository has a pull request and you open up the section, it gives you a list of all the open, and I guess maybe you can toggle it closed as well, but all the lists of the open pull requests.

16:34 If you click on one of them, it'll show you all the details of the pull request, the whole conversation if you click on that, who's the reviewer, you can change that, who's it assigned to, whether there's labels, whether it's been merged.

16:47 - Wow.

16:48 - And then like on the right, you have this whole conversation, you can see sort of the flow, this person commented this and they made these few more changes, then they commented again here.

16:56 This is all really pretty neat, But the thing that is noteworthy, the reason I brought this up is there's a button that says check out.

17:03 So instead of trying to create a branch or fork their repo and checking, like you just, I don't know where this repo, or this PR came from or what branch it was against.

17:11 I just want to check it out and run it locally, run the test against it, see what it looks like, go.

17:16 Isn't that awesome?

17:17 - Yeah, that is really, really awesome.

17:20 I like it.

17:20 - Yeah, 'cause normally you're juggling a lot.

17:22 Maybe you have CI, continuous integration that tells you like the linting pass.

17:26 but other times you want to actually just get it and run it and play with it and decide did this make the code slower, did it make it faster, do I like how the result of this feature looks, especially if it's like a UI thing or something.

17:40 So I think this is super cool.

17:42 The reason I bring it up is there's nowhere in the documentations, if you go over to PyCharm here and you look for pull requests, they don't even mention this.

17:51 So I don't think people necessarily know about this.

17:53 >> It's a stealth feature.

17:56 It's a stealth feature, it seems totally worth highlighting because dealing with PRs in that way is actually kind of janky, right?

18:03 It's like it takes a little bit of understanding Git maybe more than, and GitHub more than a lot of people would off the bat.

18:09 So if you just go click, check out, play with it, nope, I don't want it, or yes, I love it, I think that's great.

18:15 I would still actually manage the PR in GitHub, but the ability to explore it super quick and easy within your project I think is super cool.

18:22 - Yeah, and quickly grab the code, because I know in GitHub you can get it, you can clone their branch.

18:29 >> Yeah, exactly. But it's hard.

18:31 It's not too easy.

18:32 >> It's several clicks at least to find it.

18:36 >> Do you actually want it cloned to your account?

18:40 Maybe not. I just want to check out the code.

18:42 So grab the right commit, hash, SHA, whatever. Also really quick, while we're on this topic, I just want to give a quick shout out to this.

18:50 If you go to just the JetBrains.com/pycharm right now across the top, there's this, oh here, there's this cool upcoming webinar, 10 Get Things You Wish You Knew in PyCharm.

19:01 Very oddly, that is me.

19:04 So anyway, I'm gonna do a webcast next week on June 7th about a whole bunch of get fun things in PyCharm and UI tools and whatnot.

19:13 So if you wanna check that out, they definitely can.

19:16 - Cool.

19:16 - Yeah, all right, so that's it for my thing.

19:18 Check out, if you're using PyCharm, check out this pull request thing.

19:21 It's even in the free version of PyCharm.

19:23 So it's worth noting.

19:25 - Nice.

19:25 - Let's see, a really, really quick real-time follow-up.

19:30 Roman Wright, hey Roman, says, "Yes, it helps me sort out PRs so much." I totally agree.

19:35 And then Wolf says, "Is it available in IntelliJ "and does it work with GitLab?" I don't know if it works with GitLab.

19:41 I'm quite sure it's available in IntelliJ 'cause PyCharm is just basically specialized IntelliJ.

19:48 So I'd be very surprised if it weren't available in IntelliJ, but I can't say for sure in GitLab.

19:53 I would check the documentation, but I also can't find that, so.

19:56 Anyway.

19:57 - So on the PyCharm side, isn't there supposed to be some UI changes that happened recently, or do you know?

20:04 Anyway.

20:05 - Possibly.

20:06 One of the things that changed recently that I actually kept stumbling into is on the Git stuff, is they have little overlays of who made changes when, kind of like that Git lens from VS Code I described.

20:16 They started adding that, and I kept clicking it by accident, trying to click on the line.

20:20 So that's like, why does it keep popping up a diff?

20:22 Oh, I see.

20:23 Okay.

20:24 (laughing)

20:25 So I kind of crashed into it, but yeah.

20:27 Anyway, if you're doing PRs, check this out.

20:29 If you're doing PRs and using PyJarm, check this out.

20:31 It's definitely useful.

20:32 - All right.

20:33 Well, so we have no guests, so that's our items for today, right?

20:37 - It is, it is.

20:39 Well, we would be remiss to not have extras, though.

20:42 - Of course.

20:43 So, yeah.

20:44 - You want to do the extras first?

20:46 Your extras first?

20:46 - Sure.

20:47 I just got one.

20:49 So it was a couple of weeks ago, I think we talked about Panda's tutor switching to Piedide, I think.

21:01 >> Mm-hm, yep.

21:02 >> So there's an article that came out on the Piedide blog that is about Panda's tutor switching to Piedide.

21:15 And so, the reason why I bring it up is because there's some cool stuff in here.

21:20 It's not just, "Hey, we did this," but it's also, "Why did we do it?" And kind of walking through some of the stuff, how they did a self-contained Pandas tutor wheel, dealing with JavaScript and imports and all that sort of stuff, and the fine-tuning and what work has to go further.

21:39 So other people that are like, "Hey, this Pyodite, actually, proof of concept, it's starting to look cool, I want to do this too.

21:46 This might be a nice thing for people to check out.

21:49 - Yeah, this is super nice.

21:50 And I definitely think the, what are the rough edges and what worked really well, those types of lessons for now are gonna be really valuable for people trying to adopt this.

22:00 - That's all my extras.

22:01 - Awesome.

22:01 All right, well, let's just make it a straight run for PyIodine, PyScript right out.

22:08 So last week I did two videos on PyScript, which is based on PyIodide as well.

22:16 So first one is a 30 minutes video.

22:20 I sort of hinted that I was working on this, but remember I said it wasn't quite released yet, Brian?

22:24 - Yeah. - Last episode.

22:25 So now it's out.

22:26 So now you can check out, I'll link to it.

22:28 You can check out my 30 minute Python, PyScript, WebAssembly, Python web apps running locally, which is super fun.

22:34 It's all about not just, you know, let's like take some Python and put it in the browser, but how can you use some like PyDash config settings to override where PyScript actually comes from.

22:46 The PyOdied, the runtime comes from, so you can put that locally in your app and then download it offline and all sorts of fun stuff there.

22:52 - Cool.

22:53 - So basically building an offline progressive web app that is like, can be almost 100% offline.

22:58 This one calls an API, so it still needs its API.

23:01 Anyway, that was really fun.

23:02 And then the next day after releasing that, it occurred to me, do you know what supports progressive web apps?

23:08 iOS and Android.

23:09 So I created a second video called Python iOS Web Apps with PyScript and Offline PWAs.

23:15 And so here is, if you look on the screen, there's a, on my iPad, there is a web app that runs PyScript talking to a Flask-based API over the internet.

23:29 And it is basically, you can go up and basically say, install this as an app on my iPad.

23:34 And when you launch it, that install process already down downloads the WebAssembly and the run the standard library and all the WebAssembly stuff that makes it large.

23:43 So you just boom and it opens up within like less than two seconds running Python client side on iOS.

23:49 That is so cool.

23:50 I'm seeing lots of uses for this.

23:53 I mean, people could do, like dashboards of, pipelines and all sorts of stuff and have them be on tablets now.

24:00 So yeah, absolutely.

24:01 Yeah.

24:01 It's, it's, I mean, once you've already made it a progressive web app, it's like a few button clicks, like this whole video about this iOS thing with like setting the stage and everything is it's three minutes.

24:11 So, I mean, it's not a hard process to make it happen, but it's just not obvious.

24:15 And it's really cool that it works that way.

24:16 Cool.

24:17 Yeah.

24:17 All right.

24:18 Well, that's it for my items.

24:21 I do have a joke.

24:22 Nice.

24:23 And I know you might have a joke as well.

24:25 Yeah.

24:26 Awesome.

24:26 Okay.

24:27 I'll go with mine first.

24:28 Cause mine's easy.

24:28 And then I have a bonus joke for you based on your topic that I didn't, didn't see coming.

24:32 Okay.

24:33 So this one comes from Brian skin.

24:35 Thanks, Brian.

24:36 I just sort of pointed out a joke from Seth, and it says, "People around here just dangerously throwing around SQL abstraction layers, and if we aren't careful, someone's gonna lose an arm." (Brian laughs)

24:47 And ORM.

24:48 It's pretty good, isn't it?

24:50 - Yeah, it's really good.

24:52 Yeah.

24:53 Actually, if you are careful, you can lose your arm for good.

24:56 - Yes, and still be all right.

24:58 - Yeah.

24:59 - All right, so here's the real-time joke follow-up that based on your reg X1.

25:05 Ask me why I'm looking like this.

25:07 - Why?

25:07 - Well, that's just my regular expression.

25:09 (laughing)

25:11 - That's terrible.

25:13 - It's really bad, all right.

25:14 - I wish I had somebody in my life I could share that with other than you.

25:18 - Okay, if other people listen to the show, we could share it with them.

25:22 - Okay, so there's like all sorts of AI and stuff going into code editors now.

25:29 They make them like do all sorts of stuff to help you out, right?

25:32 So this is Kermit the Frog looking out of a rainy window.

25:37 It's when you've barely started writing a line of code and your IDE already lets you know about three syntax errors, two runtime errors, a grammar mistake, five misdemeanors, contempt of court, and treason.

25:51 (laughing)

25:53 - Just getting started, why is it so hard?

25:56 I love it, that's really good.

25:59 - Anyway.

26:00 - Yeah, I kind of felt that way today.

26:01 I was playing around with some stuff.

26:02 I'm just like, what is--

26:03 this is over the top, this thing.

26:05 Yeah.

26:06 But no, good.

26:07 I'm glad the editors can help us out.

26:09 But sometimes I feel like an idiot.

26:11 Yes.

26:12 Indeed.

26:13 Well, great being here with you.

26:15 Good being here with you.

26:17 Indeed.

26:17 Thanks, everybody, for coming.

26:19 Bye, everyone.

26:20 Thanks for being here.

Back to show page