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


Transcript #173: Your test deserves a fluent flavor

Return to episode page view on github
Recorded on Thursday, Mar 12, 2020.

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

00:05 This is episode 173 recorded March 12, 2020. I'm Michael Kennedy.

00:11 And I am Brian Okken.

00:12 And we have one of our favorite sponsors Datadog sponsoring the show. Check them out at pythonbytes.fm/datadog. Get a cool t-shirt, get some cool software. Tell you more about that later.

00:21 You know, I think people who when they're getting started, Brian, they write basic code, but they realized that Python is so easy to use because you can just do something like request.get and hey you have a website already like you've already downloaded like an something from an API or you downloaded something some html or a file and then it's easy to forget that maybe there's more to it. Yeah I actually totally forgot there was more to it and we know of requests as being both powerful and really easy to use and there's a just about a million tutorials on how to put something together quickly with requests. So I was really thrilled to come across this article by, I think it's Danny Hadovic, titled "Advanced Usage of Python Requests." He covers timeouts, retries, hooks, and more, and kind of that comment is it's easy to be immediately productive with requests, but there's some really cool things that you can do that I had no idea you could do this stuff. So some of those cool tricks that he runs down, actually all the tricks he he runs down, there's a hooks thing, you can attach a hooks to a session.

01:26 And so you can use hooks to call raise for status on every call.

01:32 So raise for status is a way you can say, well, if when I request something, if a certain status comes back, then call this other function.

01:41 But like a 404, or there's certain wildcard ones that you might wanna like all the error ones, you might wanna always call something.

01:49 So there's a way to hook that up.

01:50 That's pretty cool.

01:51 - Oh yeah, nice.

01:52 - Base URLs, I had no idea you could do this.

01:54 This is so neat.

01:55 Instead of doing like the full path to a URL, for every, if you're doing a whole bunch of them, you can use a, set up a base URL that essentially gets prepended to everything else later.

02:08 - Yeah, and this comes from request tool belt, which we covered before.

02:11 So it like wraps and adds onto requests, which is pretty awesome.

02:15 - Oh, does it?

02:16 Okay, that's cool. - Yeah, yeah, yeah.

02:17 Yeah, and this is something I do all the time when I'm writing code that talks to consumes APIs or talks to APIs or whatever is it's like, here's the base URL we set.

02:26 And there's usually an if statement, like, are you in development mode?

02:29 Do this, are you in production?

02:31 Use this other URL as the base.

02:33 And then, you know, just do a slash, whatever, get.

02:36 But for me, it's always been a--

02:37 - Well, that's a great use of base.

02:39 - Yeah, for me, it's, I've always been like, well, okay, get base URL plus whatever, then I'm like, oh yeah, does it have the slash on the end or does it not have the slash on the end?

02:48 Do I need to put the slash on the, you know what I mean?

02:51 And it's super clear here how that works.

02:53 So I really like this.

02:54 Like I could totally have made use of this and I haven't been, so I should.

02:57 - And then he covers things like retries on failure, timeouts, timeouts with retries, a little bit of testing and mocking of requests, but there's, you know, there's a lot about that.

03:07 - Yeah, I'm looking at the section here on timeouts.

03:11 I feel like, do you think people could get frustrated about this or something?

03:15 What's up with this guy in this card game, man?

03:17 - I'm not sure.

03:18 like this, like under setting default timeouts, there's like a giphy of a guy just beating a card table to death, right, because he lost.

03:25 It's playing Settlers of Catan and I'm guessing he lost.

03:29 Anyway, it's a great, great giphy to go along with it.

03:31 - I'm not sure why that is relevant to here, but it's funny.

03:36 It's a funny little video.

03:38 Why is it relevant?

03:39 This is irrelevant to the podcast, but how is this relevant?

03:43 - Well, it says it's great that stuff will just wait, but it can really frustrate you when someone's forgot to set a timeout and it halts a program in production.

03:51 So I'm guessing this is an expression of being frustrated 'cause production's lagged. - It's just frustrating.

03:55 - Yeah, yeah.

03:56 (laughing)

03:58 Anyway, the one that I also thought was interesting, the base URL is cool, is the retry on failure is pretty neat, actually.

04:04 - Yeah, and then you can even customize it to say, well, don't retry everything, but certain things you wanna make sure you retry.

04:10 - Yeah, for sure.

04:12 And how many times and whatnot.

04:13 That's a great feature.

04:14 - Yeah, and then this is kind of clever.

04:16 The last one I thought was clever was the, if you wanna mimic being different browsers by adjusting the user agent header request information, because sometimes you wanna make sure that you're, whether or not you're testing your stuff, you wanna make sure that you can deal with different user agents, or if you wanna try to, if some people have security stuff on where they only allow certain user agents 'cause they don't want bots coming in, well, you can write your bot to be a different user agent then.

04:46 - Yeah, absolutely.

04:47 You could lie to them.

04:48 Tell them you're Internet Explorer 6.

04:50 See what they think about that.

04:51 (laughing)

04:52 - Yeah.

04:53 - So this next item that I want to cover, I ran across last week and I thought it was really cool.

04:57 And I'm like, I've been looking for something like this for a while.

05:01 So have you heard of this library for testing?

05:03 It's called pytest.

05:05 Have you worked with it?

05:06 - Yeah, a little bit, yeah.

05:07 - Awesome.

05:08 So pytest is super clean and great.

05:10 And the way you express the assertions and whatnot you would you want to assert something's not none you would assert the thing is not none and like literally you write that code and that's really cool for simple stuff like is not none but if you have to test multiple aspects of a thing like it's not known none it is a number and it's greater than zero or it's between some range that can be a little bit tricky and you've kind of got to write some code it's not not as descriptive or as expressive right that That is one of the things that I was looking for, a library that has more complex tests built in.

05:47 Is this thing a subtype of that?

05:49 Or is this string parsable as an integer?

05:53 I'd like to know that beforehand.

05:55 Something like that.

05:56 I don't want to have to do the complicated, small but still somewhat complicated and non-obvious code in these assertions.

06:02 I'm also a big fan of fluent APIs.

06:04 What do you mean by fluent?

06:07 I would love to see more fluent APIs in Python, the standard library.

06:11 So what I mean is a function or property that you can call that returns the same object.

06:16 Oh, okay.

06:17 Sort of functional.

06:18 Yeah, a little bit.

06:19 So if I had, say, a list, I could say list.sort.someotherlistoperation.

06:27 If sort would return a list, the list that it was called on, right?

06:31 And maybe it had an order by, or I guess that's sort.

06:34 if it had a filter, and then you could say dot, right?

06:37 Transform or something like, right?

06:39 You could sort of chain these together without doing multiple lines.

06:42 Yeah.

06:42 Right?

06:43 So that's the fluent API.

06:44 And so this thing I want to talk about is something called fluent assertions.

06:48 And I ran across this from Dean Egan, and he was talking about it on Twitter.

06:52 And basically, the idea is it has all these checks, like tons and tons of checks built into it.

06:58 I'm not sure how many I would guess.

07:00 50 different checks.

07:03 Is that number complex? Is it not complex? Is a value between these two things? Is this set? Is it a set? Is it a non empty? Does it contain spaces? Does this string contain spaces? Is it shorter than that? Right? So you could say things like, given an object, is it a string that contains no spaces? That is all lowercase, you could do that as like one line, just like really clearly in this fluent API. And it returns throws assertion errors, which are the same thing that you would get if you failed in a assert directly. So it integrates really well into things like pytest.

07:36 That's pretty cool, right?

07:37 - Okay, cool. Yeah.

07:39 - Yeah. So there's an example in the show notes here.

07:43 And I took this from their docs. It basically says, if you wanted to test something like given two parameters, I want to check that the value is not none, that it's a float, that it's between zero and one, and you're given an object, and it's not none, and it's a type of something. All right. That's kind of complicated. Or you can go to their API and say, check n.isnotnone.isfloat.

08:03 dot isBetween, and I thought, "This idea is really cool, but I don't like it so much." There's like too many words, right?

08:10 So I've been working on a PR, and it's basically accepted.

08:13 The guys running the project said, "Sure, this looks great." They've reviewed it, and it's a simpler one, and it uses properties a lot of the time.

08:21 So it's a little more English, less function-y called.

08:25 So you can say is n dot not none dot float dot between parenthesis zero and one close parenthesis.

08:34 So the things that assert like I guess properties about it like whether it's a float or not none are just properties and the stuff that takes arguments would be still function calls.

08:43 So I think it's a really clean way to write these test assertions in nice simple ways, especially if you're testing like a couple aspects like it's not none and it's a float.

08:52 Yeah, I'm on the fence.

08:53 I know that a lot of people like this sort of a style.

08:56 I like your updates to it.

08:57 I hope that goes in, 'cause that's a lot cleaner.

09:00 It's a lot easier to read.

09:01 So good luck with that.

09:03 I'm personally a fan.

09:05 That sounded harsh.

09:06 - No, no, it's all right.

09:07 - No, I'm a fan of just the straight asserts myself.

09:11 I think they're easy to read.

09:12 But I think having a couple ways to do it, it sounds neat.

09:15 - What I like about it is it packages up some of the more complicated types of tests, like the character only has, Like the character, the string has some characters which are spaces or things like, like it's not as obvious if you've write the actual code that does the test some of the times, right?

09:32 I don't know. - Yeah.

09:32 - Anyway, that's what I like about these kinds of APIs is the sort of English telling me what you're looking for more than the code of checking for it.

09:39 - Yeah, and also you're fitting a whole bunch of stuff on one line, it's kind of nice too.

09:43 - Yeah, yeah, this is a way that you can have multiple assertions in one test without people like, say, "Hey, you're doing more than one test." Well, sort of.

09:50 Anyway, people can check that out.

09:52 It's a pretty cool library.

09:53 If that sounds useful to you, it's already working for the Check API and probably will for the Is later.

09:58 Cool, cool.

09:59 Now, before we move on to the next, I want to tell you about Datadog because they're sponsoring this episode as they have been great supporters of the show.

10:06 Let me ask you a question, dear listener.

10:08 Do you have an app in production that is slower than you like or its performance is all over the place?

10:14 Sometimes it's fast, but sometimes it's slow and you don't really know why.

10:17 That's the most important thing is Why is your app behaving this way?

10:21 Do you know what's causing it to be slow or to be kind of all over the place?

10:26 And if you have Datadog, you'll know.

10:28 You can troubleshoot your app's performance with Datadog's end-to-end tracing, use their detailed flame graphs to identify bottlenecks and latency in that finicky app of yours.

10:37 So be the hero that got your app back on track at the company and get started with a free trial at pythonbytes.fm/datadog.

10:45 - Very nice.

10:45 - Yeah, thank you Datadog.

10:46 Good stuff.

10:47 Also good stuff.

10:48 GitHub. Yeah, GitHub and GitHub Actions. I don't know how long they've been out of beta, but GitHub Actions I think are available to everyone now.

10:56 And these are different than their webhooks, right? These are more automation workflow inside GitHub. Yeah, and GitHub's sort of by part of the Azure Pipelines sort of stuff. I mean, GitHub's associated with Microsoft now. So Azure Pipelines are one way to do actions on a, when you commit something or actions at an event time within GitHub, but GitHub Actions are a way also. They're more of a lightweight pipeline thing, but for a lot of Python projects, I think they're a very good, clean way to go because a lot of our Python projects are not. If you're building a package, they're kind of perfect.

11:34 So there's an article called Python and GitHub Actions, and it's by Henik, and it's sort of really cool. He says he's currently recommending that people use GitHub Actions for Python stuff.

11:49 It's simple, easy integration. So how do you do that? And that's what this article is about. And he goes through running your tests through Tox, using coverage, testing his multiple Python versions, and shows you the YAML that you have to set up to configure GitHub Actions to do that right. And you also have to put a little bit of a, make a change to your Tox.ini file to make sure this all works. And then I think it's good he was reminding people that if you've got an open source project it's kind of nice to clean up your old stuff. So if you if you are switching from some other CI system to GitHub Actions make sure to clean up the old stuff. And then he even goes through and tells some other things like changes you want to make to make sure that you're hooked up to the CodeCov system and some other stuff. And then making sure it builds on multiple operating systems, the sort of stuff you'd want to do with continuous integration, most of it is available through Azure, or not Azure, through GitHub Actions.

12:49 So that's kind of cool.

12:50 I love that it's all part of GitHub now.

12:52 That's great.

12:53 You know, if you're already there, it can be a pain to integrate these other systems.

12:57 You can just push a few buttons or a few files and just make it run there.

13:01 Yeah.

13:02 Kind of the secret sauce is that they're really the same thing.

13:05 I think the Azure pipelines and the GitHub Actions are all running on the same system, that GitHub Actions is a little simpler interface for people that aren't.

13:13 I mean, Azure Pipelines and the Azure workflows is powerful, but it is quite overwhelming when you get into it.

13:21 - Yeah, that whole system is, pretty much all of Azure is overwhelming to me.

13:25 I go there, I'm like, why are there 400 things here?

13:27 There's so many things, like I don't care about most of these, what is this place?

13:31 - Yeah. - Yeah, yeah.

13:32 Going back to digitalization. - Definitely.

13:33 - Okay, cool.

13:34 This next one I wanna talk about touches on sort of a similar topic as the requests one that you covered.

13:40 As also the assertion one that I did.

13:42 So one of the challenges of testing your code can be when you're talking to external systems, right?

13:50 I wanna call the Stripe API and I gotta provide it all this information.

13:54 And if you call it more than once with the same token, it'll say, sorry, you can't do that, that token's used.

13:59 So you gotta go get a new token.

14:00 And there's just a lot of stuff.

14:01 And you necessarily wanna be calling real live APIs inside your tests.

14:06 that's gonna make it quite slow potentially, and so on, right?

14:09 - Yeah. - You can get charged.

14:10 Like we use a geolocation service, the training site to figure out which server to serve the video from.

14:17 And that one, it's not super expensive, but we have to pay per use.

14:20 So I don't wanna hammer it in continuous integration and pay more.

14:24 So there's this cool project called vcr.py.

14:27 Have you heard of this? - Yeah.

14:28 - Yeah, vcr.py is really cool.

14:29 I heard about this from Tim Head, who was on TalkByThon recently for the Binder project, and that's gonna be out shortly.

14:36 But the idea is that this simplifies testing things that make HTTP requests, as well as speeds it up.

14:42 So all you got to do is the first time you run it, it's you decorate the function.

14:48 And what it's going to do is going to basically instrument and record all the HTTP interaction, what gets sent out and then what comes back and it'll save that into a YAML file hanging around, which is called a cassette.

15:00 You like that?

15:01 plug the cassette to the VCR, right?

15:03 And the next, the second and third and fourth time that you run the test, if it finds that cassette file in the same inputs, it's like, well, you asked for this and here's your answer, and it just replays it back to you.

15:14 - Yeah, it's pretty clever.

15:15 - Yeah, it's super clever.

15:16 You don't have to worry about if the system is maybe slow or you've got to set things up just right to call it 'cause once it has that little cassette file, it's good to go.

15:26 So it lets you test these external service, test your integration with these external services in a semi-realistic way because you're really playing back at least snapshot in time real data that you got from it without any effort on your part.

15:41 Let's you work offline, your tests are completely deterministic, if it passes once it's always going to pass because you always get the same data back.

15:47 It'll definitely speed up the execution speed because it's just throwing back JSON that it has in a file rather than hitting an external service and all that.

15:55 And if you decide, you know what, this request is stale and out of date.

15:59 All you got to do is delete that cassette file, run your test once, it'll hit the real system and then it'll go back to playing the new cassette.

16:05 Yeah, nice.

16:06 Yeah, yeah, pretty cool.

16:07 And then for people who do like pytest, there's a cool little plugin called pytest-VCR.

16:14 And then all you got to do is for your tests that might use something like URL open or request or something, you say pytest.mark.vcr for the test and then that's it.

16:27 Magically it works.

16:28 Yeah.

16:29 - Nice. - Yeah.

16:30 - Yeah, I don't know if it's really magical.

16:32 I think it's very useful when it can be useful.

16:34 - Yeah.

16:35 - I personally don't have the experience, but I'm gonna lean on somebody that does.

16:39 On episode 102 of Testing Code, I talked with Harry Percival, and part of that, we're talking about how to set up testing an application that has external dependencies through APIs and stuff.

16:52 He does talk about both good experience with things like vcr.py and some difficulties, Like if there needs to be timestamps or different, if you call an API twice and expect to get something different back, well, this isn't going to help you.

17:07 But so I recommend if you're running down this route, then also listen to the half hour of episode 102 with Harry Percival, it'll help a lot.

17:18 - Yeah, super.

17:18 We should put a link in the show notes for that.

17:20 To me, one of the things that I really like about this is I could go pip install Stripe or pip install MailChimp or some other thing that I'm integrating with, that who knows what kind of complicated badness it's doing on the inside to make all of its stuff work.

17:35 You know, and I don't have to think about how am I going to mock out their internals, and if their internals change, how's that going to affect my tests?

17:43 And I can just say, I'm going to grab this higher level API that somewhere deep in its guts does network traffic, throw this at it, and then it'll be reproducible.

17:53 And to me, that's the big appeal.

17:55 - Yeah, and also speed.

17:56 So even if you're using a test server and not incurring all the overhead costs of the actual server, even with the test server, it's time, it's latency, and you can speed things up by caching the return values.

18:13 So it's a cool idea.

18:14 - Cool, I'm glad you like it.

18:15 I know it's probably not something you do as much in the hardware world, but yeah.

18:20 It's a cool one, what else is cool?

18:21 What else you got?

18:22 - I got eight cool things.

18:24 I'm a sucker for listicles.

18:25 if there is actually good information.

18:28 And so Jeremy Grifsky wrote the eight coolest Python programming languages features.

18:34 And I was just smiling the whole time I was reading this.

18:37 It's a quick article, but it talks about a whole bunch of features.

18:41 I was reading it thinking, man, this is why I love Python.

18:43 And I really miss all this stuff when I'm writing C++ code.

18:47 So there's code examples, of course, in this article, but we got list comprehensions.

18:54 And that's something that when you first learn about comprehensions, it's like, oh my gosh, this is so cool.

18:59 We also have dictionary comprehensions and other comprehensions.

19:04 Now you can have, there's all sorts of stuff.

19:06 Generator expressions are nice and really helpful.

19:11 Slice assignment, I sometimes forget that we can do this.

19:14 So you can take like part of a list and assign, like if you have three values or something, you want to stick in the middle of a list, you can assign those with slice assignment.

19:23 It's pretty powerful.

19:25 Iterable unpacking, so if you've got a tuple and you want to unpack that and pass that to a function but it has separate values, you can do that.

19:34 Negative indexing, I mean, you want to grab the last thing off of an array, you can say minus one or minus two.

19:39 - I love negative indexing so much.

19:41 That's a really clever feat.

19:43 It's so simple and yet it's really nice to just go, I want the thing minus one, bracket minus one.

19:50 Give me that, that's the one I want.

19:52 - I sorted it, I want minus one.

19:54 - I've tried to do this in C++, it's a bad idea.

19:57 So negative indexing's cool.

19:59 Chaining comparisons, so one is less than X is less than five to make sure X is between one and five.

20:06 That's not something you can do in most languages and it's just, it's how we talk, it's how we do math and Python has it, it's nice.

20:14 - Yeah, it's very nice.

20:15 - It finalizes it out with f-strings, which we love f-strings.

20:19 And then a whole bunch of a big list of honorable mentions.

20:23 And I was thinking as I was reading this, like this entire thing, plus his honorable mentions at the other stuff of like things I could have also talked about.

20:31 That would be a really great just like an introduction to Python course of just like here's a half an hour of why I think Python's awesome.

20:40 So it's good.

20:41 - I agree.

20:42 I think that'd be awesome.

20:43 Let's see, as I look through this, f-strings definitely stand out as something that's awesome.

20:47 Negative indexing already riffed on that.

20:49 That's cool.

20:50 Screening comparisons.

20:52 List comprehensions, and I'll throw all the expressions and other comprehensions in there.

20:57 I love them, but I wish they did a little bit more.

21:00 Like, why can't I sort a list expression, list comprehension, or something like that?

21:07 There's just a few things where it's like, oh man, if I could just, I find myself a lot of times, here's the comprehension, and then here's the little bit of things that I wish it could still support.

21:16 I gotta do afterwards.

21:17 Anyway, it would be nice.

21:19 - Interesting.

21:19 - Like for example, paging, right?

21:22 I would like to be able to skip.

21:24 So if I'm on page five of group to 20, I would like to be able to skip four times 20, take 20 with this clause sorted by that and have the sorting happen before the paging.

21:36 Like that would be so nice.

21:38 And it's just, you know, it's on the custom.

21:40 So half the time I'm like, God, I love these, but why can't I, you know, whatever, the little thing that I wish I could extend it, a little more database and memory type of behavior, but still great, great stuff.

21:49 I would totally miss them if they weren't there, that is for sure.

21:52 - Yeah. - Yeah, cool.

21:53 - Actually, so slice assignments, I didn't, never even occurred to me that you could do that with a language.

21:58 So it's neat that you can do that, but I probably wouldn't miss them if they weren't there because I wouldn't have expected them to be there.

22:05 - You shouldn't be able to do that.

22:06 Yes, exactly, exactly.

22:07 I wouldn't miss slice assignment at all, although it is neat.

22:10 You know what I definitely would not miss is bugs in my web app.

22:13 - Yeah, me either.

22:14 - Do you have bugs in your web apps?

22:16 - Well, I always think no, and then I learn yes, but not as often, not that often.

22:21 So there's this cool project called Bento that I just learned about.

22:26 Have you heard of Bento before?

22:27 - Just the lunch style?

22:28 - Yeah, exactly.

22:29 I do love a good Bento box, but this has nothing to do with that.

22:32 Maybe the name is inspired, but other than that, no.

22:34 So bento@bento.dev, this is basically an analysis system that will look at your Flask and coming soon, other languages, Django, SQLAlchemy, whatnot.

22:47 Look at your Flask app or your request calls and look for known bugs, especially in the security realm.

22:56 So you don't end up with little Bobby tables.

22:58 This is your school calling.

23:00 Did you really name your table, your son dash dash semi-colon drop whatever?

23:05 Yeah, so what the idea is you can basically pip install this thing.

23:10 You call bento init, it's going to create a Docker container with the analysis tools, and then it's gonna run those against your Flask app at the moment, like I said, Django, SQLAlchemy and stuff is coming along.

23:24 And it'll find things like if you have a missing JWT token, or you're missing a no opener, or the content set, or if you're using requests, if you're sending username and passwords over an HTTP, not an HTTPS request, it'll automatically detect that and tell you.

23:42 - Oh, very cool.

23:43 - Yeah, it's pretty nice, right?

23:44 - Yeah, it's very nice.

23:45 It even does like Jinja template checking and stuff.

23:47 - Right, exactly.

23:48 So this is open source on GitHub.

23:50 And yeah, you could check it out.

23:51 It looks pretty nice.

23:53 There's a little Giphy.

23:55 Thank you guys.

23:56 Well done on your project.

23:57 There's a Giphy showing how it works right on the page.

24:00 You can just go to the GitHub repo, scroll down a tad and just watch them find a bug, fix a bug and so on.

24:07 - Yeah, very good.

24:08 Cool. - Cool, cool.

24:09 Anyway, so yeah, if people have, For the moment, Flask apps in the future, it looks like they're coming with other things.

24:15 But yeah, you can just run this and it'll check it out.

24:17 There's also a list of all the checks that they have, which I put into the show notes.

24:21 So a bunch of stuff like, you know, some of the obvious ones are like, did you ship Flask into bug mode and stuff, but other things that are not so obvious.

24:28 That's it for our main topics, Brian.

24:30 Do you have anything you want to share with folks where we get to the laughter, the hilarity?

24:35 - No, we could use a good laugh.

24:37 But do you have anything extra?

24:39 - We haven't talked about it yet, But I feel like it's, all the tech conferences are either canceled or they're on coronavirus watch for being cut, right?

24:48 Like we've had E3, the big game one, canceled.

24:51 We have the Game Developer Conference.

24:52 We had South by Southwest canceled.

24:54 Some other ones, I think some Facebook's F8, I think was canceled.

24:59 Possibly Google I/O, I'm not sure about the one.

25:02 I don't remember exactly what they said.

25:04 But PyCon's still on for the moment.

25:05 At the time of this recording, there's gonna be an announcement tomorrow, which may change things.

25:09 but I just want to remark, what a crazy time, both for the world, but also for tech.

25:16 - Yeah, definitely crazy.

25:17 I'm curious what it's gonna do for, now this is totally self-centered, I do want everybody to be healthy, but I also wonder with less people commuting, if less people are listening to podcasts, that would be terrible.

25:30 - Oh no, they've got a lot of housework.

25:31 You all folks out there, you definitely gotta keep listening.

25:34 No, that's actually a legitimate question, whether or not that makes sense.

25:39 Maybe it does.

25:40 Here's some of the effects I think are gonna happen.

25:42 I think a lot of companies, especially larger companies, that believe you must have a meeting every Wednesday and it has to be like two hours with this group and an hour with that group, and you must commute every day into the office, even though you just work through GitHub and Slack and email anyway, they're gonna realize, you know what?

26:02 We don't actually have to have these big offices and we don't have to have our people always come in.

26:07 we were at least as well off.

26:10 And what's gonna be like the work-life change that comes from that realization?

26:15 - Yeah, we made sure, I mean, a year ago today, it was rare for anybody to be working from home in our company, even though the work is software for the most part.

26:26 But now we've made sure that everybody, I think we have out of like 80 people, something like that, we've got like only a handful of people that are not set up yet to be able to work remotely.

26:39 I think that's a good change, actually.

26:40 - I do too.

26:41 It's gonna be really interesting to see the knock-on effects.

26:43 I think there's gonna be stuff like that, like, oh wait, we actually could work in this way, or we could hire people from other places, or whatever.

26:50 It's gonna be interesting outside the just, you know, the potential chaos of people getting sick and whatnot.

26:55 - This has been like talking about the elephant in the room, but it's talking about the virus in the room.

26:59 - Yeah, well, I hope it's not in either of our rooms.

27:01 Let's just put it like that, like right now.

27:03 - Yeah, definitely not.

27:04 There's nobody else in my room.

27:05 I think I'm clean.

27:06 - So speaking of mysteries, how about I tell you a joke?

27:09 - Oh, please.

27:10 - Okay, so let me give you a definition, straight out of the dictionary.

27:14 Debugging, pronounced debugging.

27:17 It's a verb, primary definition.

27:19 Being the detective in a crime movie where you are also the murderer.

27:23 (laughing)

27:26 - Yeah.

27:26 - That's a good one, right?

27:28 - Yes, you probably get that less since you're often coding solo, But there's times where I'm like just hot under the collar, mad about some bug in the system and trying to figure out who did this.

27:42 - Dude, it's time for some version control blame, some git blame, some subversion blame.

27:47 - Yeah.

27:48 - No, it's my user, it was me.

27:52 Yeah, I've been there.

27:53 I've been there like, oh my gosh, now what do I do?

27:57 - Definitely, love that.

28:00 - It's good for your humility level though, right?

28:02 - Yeah, and then you just remember that next time you're mad at somebody else.

28:07 - Exactly.

28:08 - For doing something boneheaded.

28:10 - Awesome, well, thanks for being here.

28:11 Great to chat with you as always.

28:12 - Thank you, bye. - Yep, bye.

28:14 Thank you for listening to Python Bytes.

28:16 Follow the show on Twitter via @PythonBytes.

28:18 That's Python Bytes as in B-Y-T-E-S.

28:21 And get the full show notes at PythonBytes.fm.

28:24 If you have a news item you want featured, just visit PythonBytes.fm and send it our way.

28:28 We're always on the lookout for sharing something cool.

28:31 On behalf of myself and Brian Okken, this is Michael Kennedy.

28:34 Thank you for listening and sharing this podcast with your friends and colleagues.

Back to show page