Transcript #137: Advanced Python testing and big-time diffs
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. This is episode 137 recorded June 26th 2019 I'm Michael Kennedy and I'm Brian Harkin and this episode is brought to you by roll bar I'll tell you all more about them later for now Brian I always wonder about you know, you hear that Python is an efficient and expressive language And if you write code in C++, it'll be a lot longer. But you know, how can you quantify that?
00:25 Well, you can set up a whole bunch of people to write the same thing in a whole bunch of languages.
00:30 Well, that's awesome that people did that. It seems like a lot of work, but yeah, I guess that's cool. Tell us about it. This is your first item, right?
00:38 So this is an article called "Comparing the Same Project in Rust, Haskell, C++, Python, Scala, and OCaml." Ocaml, I think, yeah.
00:49 I think, yeah.
00:50 So this was written up by Christian or Kristen Hume or Hume.
00:54 And this is about a university project, which is kind of a neat project.
00:57 Basically, they had to implement mode like a big chunk of Java.
01:03 So it's a Java to x86 compiler as part of a compiler class.
01:09 And they were basically had to set up get up teams, teams of people to do it.
01:14 And they could pick any language they wanted, which is kind of cool because, you know, people be better at different languages.
01:20 So let them use what they're good at.
01:22 - Yeah, let them use what they're good at 'cause then they'll do it properly and not just try to cram it one.
01:27 They'll be, have the most efficient use of that language for sure.
01:30 - Up to three people on a team and it was a multi-month project.
01:34 And then also tests were added.
01:35 So this is kind of a neat part of the process, which I think is an awesome way to teach people is have some published tests of like, you're gonna have to run these test cases and they have to pass.
01:45 But then also have some secret ones where people don't, they don't know what tests are gonna be tested against it, which is kind of nice because people will, they'll have to be able to make sure their implementation is robust without knowing, without the test cases.
02:01 It's kind of neat.
02:02 - Yeah, that's cool.
02:03 So I do love it that there's unknown tests, like these are the specifications.
02:08 You can kind of get close with these tests, but to pass, you actually have to just work.
02:12 - That's totally like real life, you know, you'll have to write down some specifications, And there's some specifications that are not written down.
02:20 They're just supposed to be known.
02:21 And then there's other things that people, once they see the implementation, they go, "Oh yeah, I wish it did this also." So I think that's a cool idea.
02:29 And they weren't shooting for lines of code or anything, complexity.
02:33 They were just trying to finish the project.
02:35 So this analysis was done after, was they had a Rust, a baseline implementation written by two people that were familiar with Rust.
02:43 And then they compared everything against that.
02:46 So there was another Rust team that chose different design decisions and it took, they had like three times the code.
02:54 So these are all just comparing lines of code.
02:56 The Haskell implementation was about equal, but depending on how you measure it, one to 1.6 times the code, same for the OCaml.
03:06 C++ was bigger, about 1.4 times the baseline, and Scala was a little bit less with about 70% the lines of code.
03:17 The big outlier was Python, which had a lot of standouts.
03:22 Python implementation was at half the size, approximately, plus written by one person, and had extra features past all the secret tests, plus others.
03:35 Somebody excellent at programming, of course, used some of the meta-programming techniques.
03:41 And anyway, kind of a fun article.
03:43 One of the things I forgot to mention, one of the hindrances was they were only supposed to use standard libraries, no extra parsing, and then not any parsing libraries, even if they were part of the standard library.
03:55 So even the parsing had to be kind of built up from scratch.
03:59 - Yeah, how interesting.
04:00 I wonder if that would make things like Python even better possible.
04:04 I don't know about Rust maybe as well, but like C++ doesn't have parsing libraries built in that I know of, things like that, right?
04:09 There's a lot of mini language parsing libraries around Python.
04:13 So it'd be interesting to do that with Go Wild and use whatever's available.
04:18 Right, like maybe take this project and then go, all right, well, what if we hit it with all the pip installable things?
04:25 What happens then, right?
04:26 Yeah, exactly.
04:26 Yeah, it sounds like a super intense project, though, right?
04:29 Like deep, deep into the language, right?
04:31 I mean, on one, you're writing the compiler.
04:34 You're understanding Java.
04:35 You're compiling to x86.
04:37 You're doing metaprogramming.
04:38 There's a lot of stuff going on here.
04:39 - It's a pretty cool article.
04:40 - Cool.
04:41 If that last one really connected with your deep geek outlets like go really hard into the language, this next one is going to connect with your, I just wanted to work really quick and easy.
04:51 - Yeah.
04:52 - So this one is really nice.
04:52 So if I was a data scientist, I might use Matplotlib or just any kind of person who wanted some visualization of data.
04:58 I might use Matplotlib for that and that's great, except for at least I personally can't make Matplotlib look super good, right?
05:06 Like if I used Excel, I could put the data in there and I'd highlight the stuff and I would say, okay, insert chart and I would pick the kind and then I would go and I would like right click and edit the chart and I would like maybe drag it around to size it correctly, double click on the axes to change the axes.
05:21 But in Matplotlib, you just write code and the picture comes out, right?
05:24 - Yeah, and I know you can do all this stuff, but it's not obvious and you have to look everything, every little thing up and tweak it.
05:31 - Yeah, so there's this project that we heard about from one of our listeners and I can't remember, I'm trying to remember who it was.
05:39 Oh, here it is.
05:40 I've got this is from Lee Wagner.
05:42 So thank you, Lee for sending it in, 'cause this is killer.
05:44 So there's this project called Pyllustrator for styling your matplotlib plot.
05:51 So you just do your matplotlib code, but you import Pyllustrator, and you say start at the beginning.
05:59 And what it does is it pops up when you show your plot, an interactive thing much like Excel, where you can drag and drop and arrange your different plots.
06:08 You can go to the properties and edit the axes and the colors and just all the kind of stuff that you might do.
06:15 It even has the cool design layout stuff where it'll help you equally space stuff between each other.
06:23 So put those little bars to say right there, if you drag and drop it, they'll be equally spaced or align the tops and the sides.
06:28 - Yeah, and with the start thing, you can even fill it with some of your data to begin with.
06:34 So if you kind of know the data you want to plot, because that's going to affect how you're going to design it.
06:40 So you can pre-fill it and then drag it around and design it.
06:43 It's just totally cool.
06:45 - It's totally cool.
06:46 - I'm glad they have, so the link we're going to show has a little embedded video.
06:51 And that's where, I mean, talking about it, you're like, yeah, I think this might be useful.
06:55 But you watch this video and you're like, oh my God, I need to use this right away.
06:58 - Yes, I had the exact same experience.
07:00 I'm like, ah, kind of interesting.
07:02 Oh, look at the video.
07:03 Oh my God, it's amazing.
07:04 - Yeah, so this is super cool.
07:06 And obviously, you don't save your changes to like an Excel workbook.
07:11 What you do is you save your changes and you can actually call save in PyLustrator.
07:15 And what it'll do is it'll put the configuration in Python back into the file that ran it.
07:20 So that's pretty wild, actually.
07:22 - Yeah, and then you uncomment the PyLustrator.
07:24 You don't have to import it later because it's not a dependency on your project afterwards.
07:29 - Right, it's just a little design tool.
07:30 So it's super cool if anyone's doing Matplotlib and they want to have it styled.
07:35 Especially if you're doing more than one plot and you want to put them side by side, this is super cool, so check that out.
07:40 Definitely a fan.
07:41 Another thing I'm a fan of, Brian, MongoDB.
07:43 Love it.
07:44 - Since you and I are paying attention to a lot of projects, there's a lot of different release cycles and we kind of decided early on that we weren't gonna try to track everybody's releases because that might get boring to people.
07:56 However, we covered MongoDB 4 because it came out with--
08:00 - Transactions.
08:01 - Transactions.
08:02 which was a big thing.
08:05 But 4.2 is out, and I'm kind of excited about a couple features that it came out with.
08:10 So the transactions are there, but now they're distributed transactions.
08:16 So they're transactions that cross sharded clusters and replica sets, and that's just really cool.
08:23 - Yeah, that's super cool, yeah.
08:24 I mean, you could use that cool transactional set before, but you're kind of limited, right?
08:28 And now it's like, no matter what crazy cluster with scaling and sharding and replication you have set up, you can just do a transaction and it's all good.
08:35 Pretty cool.
08:36 - They're a good idea anyway, but with testing you can set up a complex database full of stuff and then at the beginning of your test, start a transaction and then after your test, and you roll this into a fixture, you can just roll back and your next test has the same data, it saves time.
08:54 So that's cool.
08:54 - Yeah, and it's probably got isolation if for some reason they ran in parallel or whatever.
08:58 Yeah, it's really cool.
08:59 - Yeah, the other feature that's pretty amazing is the field level encryption.
09:04 And this is encryption done on a per field basis on the client side.
09:09 So the server doesn't even have, it's not doing it on the server.
09:15 So there's like system administration can be done without having to make sure everybody signs NDAs and all that stuff that you can manage your database without even being exposed to any of the secret stuff.
09:29 - Yeah, that's awesome.
09:30 Like most databases, most of what's in them is not sensitive but there's often like a little bit that is that's really, you don't want anyone to get access to.
09:39 And yeah, this is really cool because like you said, it's done in the library that talks to MongoDB.
09:45 So in PyMongo for the Python folks.
09:49 And you just set the encryption key or decryption key over there and the server cannot decrypt it.
09:55 So if somebody breaks into the server or you lose it, or it's like you set it up on the cloud for like testing and you forget that it's there, all the kind of random stuff that happens to databases, it doesn't matter in terms of this encrypted stuff because like literally the database doesn't know how to read it.
10:09 It's the drivers that on the client side that have the keys.
10:13 - So with GDPR stuff, if the customer says, "Hey, delete my stuff," that's always been an issue with databases is it might be in a whole bunch of tables, but if you destroy the customer key, the data might still be there, but it's unreadable to anybody, so it may as well be garbage.
10:31 - Absolutely, and it gets to be really tricky because even if you set up the right code to delete all the customer data out of your database, what about the backup that somebody made when an older admin was hired and they stored that in the S3 buckets so it was offsite, right?
10:50 how do you delete the data out of there?
10:53 You know what I mean?
10:54 But if it's encrypted, then you can just throw away the encryption key and then it's just gobbledygook.
10:59 - Yeah, cool. - Pretty cool.
11:01 I like it.
11:01 Speaking of cool, Rollbar, happy to have them come along and sponsor the show.
11:06 We use Rollbar on pythonbytes.fm, among other things.
11:09 So if anything goes wrong, and it's kind of fortuitous, I guess, I woke up this morning with a ton of Rollbar messages because there was a data center failure that caused some connectivity between MongoDB and Pythonbytes.fm.
11:27 How about that for a funny thing?
11:29 So some network card broke, right?
11:31 And the site couldn't talk to the database server, so it was freaking out.
11:36 How do I know?
11:37 Nobody complained to me.
11:38 They probably should.
11:39 Like, Michael, your site's down.
11:40 What's going on?
11:41 It's really messed up.
11:42 But I just opened up my email.
11:44 I'm like, whoa, there's a lot of rollbar stuff going on here.
11:46 If you want to be notified right away, even when users don't tell you, check them out.
11:51 They have a free tier.
11:52 They have some great paid tiers.
11:53 Visit pythonbytes.fm/rollbar.
11:56 Super easy to integrate into Python, into the web frameworks.
11:59 They've just got like one or two lines you enter, or maybe a little configuration, a few settings, off you go.
12:04 It's really, really nice.
12:05 So check them out, pythonbytes.fm/rollbar.
12:07 - Nice.
12:08 - So kind of like PyLustrator, that sounds kind of useful and interesting.
12:13 This next one also sounds useful and interesting, but like PyIllustrator, it's like, as you look into it, you're like, "Whoa, this thing does a lot, man.
12:20 Look at it go." So there's this project that was recommended by Francois LeBlanc.
12:25 Thank you for that, Francois.
12:27 And it's called Deep Difference.
12:30 It's just called DeepDiff.
12:31 And so it does deep differences in search of any Python object graph.
12:37 So I've got an object which holds a list.
12:39 That list points to a bunch of objects.
12:41 Those have other pointers.
12:42 I want to know is this thing somehow referenced by that?
12:46 Let me do a search on it.
12:48 Where is it?
12:49 Is this giant crazy data structure same or different than other giant crazy data structure?
12:55 And you could compare them.
12:56 So that's pretty cool.
12:57 So it has deep diff, it has deep search, and it also has deep hash.
13:01 So if I've got some giant crazy data structure, you would like to know that if the data is the same across two of those, that the hash result is identical.
13:10 And if any part of the data changes, that the hash then changes.
13:15 - Oh yeah. - Possibly, right?
13:16 So it will do that on object graphs that are not even hashable themselves.
13:20 - Really? - Yeah.
13:21 - Wow.
13:22 - So that's pretty wild.
13:24 I have just a lot of nice touches in here that kind of made me realize like, wow, this is wild.
13:29 So for example, it'll give me the differences in a list, ignoring order and duplicate, right?
13:37 Just what is the essence of this data?
13:40 Or you can say, is any data repeated in this list or in this dictionary or something like that?
13:47 You can exclude certain types.
13:50 Maybe I want to know the data is the same, but they're both using a thread object.
13:53 And the thread object is different, so of course they're going to be different.
13:56 But say, don't check on the thread object.
13:58 Just check the other stuff.
13:59 So you can explicitly opt in or out data types that you might use.
14:04 You could say, I'd like to compare these things, but only to four significant digits, because I computed them slightly differently and maybe they're, you know, I can't get them like to the decimal accuracy to be exactly the same, just the way they're done, right?
14:17 You can exclude parts of your object tree that you've got for comparing, I mean, isn't this insane?
14:22 - They've been able to do like significant digits in a deep data structure.
14:27 That's amazing, that's really cool for a lot of the stuff I work with.
14:31 - Yeah, I can imagine exactly, and you know what?
14:33 I bet this would be really good to mix in with testing.
14:35 Like you create your test data and then you deep diff it against the result.
14:39 - Yeah, exactly, 'cause there may be noise in the system and you know some of the signals are noisy, so yeah, this is awesome, cool.
14:46 - It's super simple, but yeah, it's pretty cool.
14:49 So if that sounds like problems that you're trying to solve, it sounds like you are, Brian, then I think it's definitely worth having a look at.
14:54 - Yeah, thanks.
14:55 - Yeah, you bet.
14:56 See, we just do this podcast to help each other out.
14:58 Like, people can listen in.
15:00 - Yeah.
15:01 - Speaking of testing.
15:02 - Josh Peek is somebody that we, I'm sure we met him before at a previous PyCon, He stopped by at PyCon this last year and met us and really great guy.
15:12 He wrote this great article called Advanced Python Testing.
15:15 And it's kind of incredible.
15:17 He goes through his, he got in a situation at work where he was asked to do complex tasks where he had to, he knew that testing and making sure that he was doing things properly would and do good coding practices would help the entire process and make it go smoothly.
15:34 So this is sort of a start to finish summary of it, but it's not that long of a read, but he talks about his learning journey, which he includes some great podcasts, including ours.
15:46 Also, an awesome book on testing, and I know the author for that one.
15:50 Not just plugging our own stuff, he's got some great stuff in here.
15:53 He talks about, he starts off with just a basic, for people new to testing, what a basic test function looks like and having good structure.
16:02 But then he talks about he wanted to ensure, do static analysis and code style.
16:10 So he uses black within his testing.
16:13 When he was talking about using Pylint, I don't use Pylint every day.
16:17 So I didn't know that there was, it's a very comprehensive check, but it takes some time for large codebases.
16:25 I didn't know that. But he has a cool hack that he puts in place to only for like check-in tests only lint modified files. Oh that's cool yeah because of course if they're unmodified then why would they yeah different outcome yeah right and then he uses a incorporating flake 8 to do doc string testing to make sure that people are using consistent doc string styles he covers all of his toxinny configuration changes he was trying to increases code coverage, so it includes coverage.py, but then also has a covfailunder flag that he adds for testing to make sure that if code coverage drops below a certain point, it fails the test, but he, and then just generally, gradually ratchet that up, so the increase, his target was 75%.
17:18 So it talks, even goes into fixtures and mocks and spies and stubs and then even a cool tool called pytestVCR which records your network interactions and then replays those for future test runs and he saw a 10x speedup in that.
17:35 - That's really cool.
17:35 - There's so much cool stuff in here.
17:37 - pytestVCR, that's really cool.
17:38 I think the only problem with it is like maybe a lot of folks using it have no idea what VCR means.
17:44 - Yeah, that's true.
17:46 I mean, even, yeah, so.
17:48 - Yeah, but no, it's awesome that you just record and network interactions and they don't have to depend on anything at all, I love it.
17:54 - And the recordings are done based on a per test basis.
17:57 So if you rerun a individual test, it only plays back the recording for that portion.
18:04 It doesn't have a order dependency built in, which is cool.
18:07 - Yeah, super cool, I love it.
18:10 Yeah, that's a really nice article, Josh, well done.
18:13 The last one I wanna talk about was sent over by Kevin Bukes.
18:16 Now, we've covered a few of the language, of language level learning things recently. We talked about the CPython byte compiler, either last time or the time before that, how it doesn't really optimize stuff.
18:28 And maybe there's some opportunities there, but more just to understand what's going on.
18:33 So Kevin sent in a message said, Hey, I'm basically a C, C++ guy. And I saw the del keyword in Python. And it threw me for a loop because del seems like delete in C++, which means free memory.
18:48 but it doesn't necessarily mean that in Python.
18:52 So it even seems like some of the books out there are kind of being a little misleading, at least according to Kevin's reading of them.
18:59 So I thought I'd just pull up an article that he sent over and then talk a little bit over some of the uses for Dell.
19:05 - Great, I don't use it, so this would be good.
19:07 - Yeah, so the context where I know Dell is I want to get something out of a list, or I want to get something out of a dictionary, right?
19:16 - Okay.
19:17 - And it's a little bit weird.
19:18 like in keyword, right?
19:19 A lot of times I would expect some operator to be on the object I'm modifying, right?
19:25 Like list or, you know, string.in or something and you give it the value, right?
19:31 But you say string space in space, the variable, right?
19:35 So it's a little bit funky that you apply it not on the object, but as a keyword in the language and Dell's like that, right?
19:41 So if I have a dictionary and I want to remove a key, not set it to nothing, but make it not be in the keys collection, you can say del dictionary of bracket, like as if you're accessing that value, but putting the del there takes it out.
19:53 - Oh, okay.
19:54 - Yeah, and you can also do that for lists.
19:55 So I can go in and remove it, remove something from a list if I want.
20:00 There's a remove function on the list, but somewhat confusingly potentially, it's by value, right?
20:06 So I could say remove Jeff from the list and Jeff will no longer be in that list wherever he appeared.
20:12 But if I want to say remove the third thing, there's no remove at or anything like that, right?
20:17 I can't pass two, that's not a value, right?
20:20 So Dell will let me remove that.
20:22 You can also use pop for that, I believe, on the list, but Dell's a little more general purpose, and you can also delete slices.
20:29 So I could say, go to this list and take out everything from two to five.
20:33 You know, two colon five, like that.
20:35 All right, so these are all pretty interesting.
20:38 Now, I'm linking over to the official docs that talk about it, and this article that kind of talks through some of these examples and shows you how to use it.
20:45 You can also delete a variable out of a local or a global namespace.
20:49 So if there's a variable that's been defined and you want it to not be defined, I can say del space variable name.
20:54 And now it's as if I didn't do that line that defined it, that created it.
20:58 Does it remove it from the namespace?
21:00 It removes-- yeah.
21:01 It doesn't free the memory necessarily, but it takes it out as a global variable or a local one.
21:09 So does it actually free any memory?
21:12 It depends.
21:13 So if I have it in the global names--
21:15 Let's say it's a global, right?
21:17 It has, obviously, the thing that has a value at that variable, it's taking up some memory.
21:23 If nothing else is pointing at it, it's still gonna be around 'cause that global variable's pointing at it, but if you call del that variable, you'll dereference that one reference to it, putting the reference count to zero and freeing it up.
21:35 So theoretically, you could free up memory using del.
21:38 Similarly, if it's in a list and the only place that points to it, has a reference to it, is that list itself, and you delete it out of there, out of the dictionary, it goes away, right, memory-wise.
21:46 But if something else is pointing on it, then obviously it's not going to go away.
21:50 We also talked about how the CPython bytecode compiler is dumb-- dumb as in not super optimizing, maybe on purpose.
21:57 And I think you could also, if you're really dealing with memory issues, and you're like, I really wish this thing would just go away sooner in this one little edge case, you could probably use Dell to put in some of the optimizations that you might hope that the compiler itself might do, but doesn't.
22:14 like dereference a thing as soon as it's used within a function before you can get to the end or things like this.
22:21 - Yeah, okay.
22:22 - So is it for memory?
22:23 Sort of, not really, but maybe as a side effect.
22:27 - Yeah, this has been a long time, but I do remember it tripping me up because I was like, it seems a lot like delete, which should have a matching new to it.
22:37 - Exactly, exactly.
22:38 We've both done the C++ thing, right?
22:40 Like where's the new that goes with Dell?
22:42 I've never seen a new.
22:43 Anyway, it's pretty cool.
22:44 There's a couple of links here.
22:46 There's a visual documentation.
22:47 There's the article understanding Python's Dell.
22:49 And then there's the reference to that bytecode compiler people can check out.
22:53 Yeah.
22:54 In C++, I don't think there's a way to remove a name from a namespace.
22:58 Yeah, I don't think so either, right?
22:59 Yeah.
23:00 You can make it point at null, but that's about it, right?
23:04 Yeah.
23:04 But you've got to think about it, right?
23:06 Like classes, you could delete a field out of a class, right?
23:09 Because it's just a dictionary.
23:11 So much of Python is built on dictionaries, right?
23:13 the variables are their variable names or the keys in the dictionary and their values are their value.
23:19 So you just take it out of the global dictionary effectively.
23:21 Right? - Yeah, okay, cool.
23:22 - Pretty sweet.
23:23 So those are our main items for today.
23:25 You got anything else you wanna chat about, Brian?
23:28 - I'm just, I'm glad it's summer.
23:29 It's starting to feel nice.
23:31 Feels like summer.
23:31 But other than that, not much.
23:34 How about you?
23:34 - Summer's awesome.
23:35 It makes programming hard.
23:36 'Cause programming's indoors.
23:38 Although some of my friends and I who work from home, We try to get out and program in like a coffee shop or a cafe by a lake or something.
23:45 And periodically, we have the weird experience of getting a sunburn while writing code.
23:50 And yeah, we've dubbed it a code burn and it's kind of a badge of honor.
23:55 - That's funny, cool.
23:56 - Yeah, so there's actually a couple of things I wanna throw out here.
23:59 We recently had Max Sklar from the local Maximum podcast and afterwards he had me on his podcast.
24:05 So I'll be on episode 73, which should be out not yet, but thanks to time shifting, when this episode comes out, it should already be out.
24:13 And I'll put a link to that.
24:14 Josh Thurston sent over a cool video of the popularity of languages on Stack Overflow over time as a bar chart race.
24:26 I didn't know about bar chart races, but these are basically animated bar charts over time.
24:29 And you just watch the bars grow and shrink.
24:32 And it's really cool.
24:33 Python is kind of like a little tiny consideration at the bottom.
24:36 And obviously we know that Python is crushing it on popularity and Stack Overflow and all those things.
24:41 So it's like a minute and a half video.
24:43 I think everyone will appreciate watching it if they just got a minute to kill.
24:46 - No, it's a fun video.
24:47 And one of the things I enjoy about it is early on, you see the Java bar going up and down based on the time of the year, because it was used in education a lot.
24:58 - Yes. - That totally made sense.
25:00 - Exactly, you're like, oh, there's a huge spike in September.
25:02 I wonder why. (laughing)
25:04 Maybe a bunch of people got a job.
25:06 - No, like CS 101 is now back in session.
25:09 - Yeah.
25:10 - Exactly.
25:11 Then the last one I want to throw out is this thing called PineSource.
25:15 So what this does, this comes to us from Anders Klint.
25:18 It's basically a UML diagram creation tool for Python code.
25:23 So you give it some Python files, it will generate a UML diagram that shows the relationship of all the classes in there.
25:30 - Oh, that's cool.
25:32 - Yeah, it's pretty cool.
25:32 There's a free, maybe even open source version, And then there's also a paid version.
25:38 So you can buy it.
25:40 I'm actually not a huge fan of UML.
25:43 But if you have Python code and you think a UML diagram would help describing it, this thing's pretty cool, actually.
25:49 And it's a little GUI app.
25:50 There's a bunch of screenshots.
25:51 You can check it out and see if it'll help you.
25:53 But it looks pretty neat.
25:54 And it does proper UML, not just like sort of visualization of classes.
25:59 So that's kind of nice.
26:00 -My favorite use of these kinds of diagrams is to print them out and pin them to your wall, your cubicle wall, so that other programmers think that you're smarter than they are.
26:10 - Absolutely, put some little scriptic notes on them, like as if you're marking them up, yeah, absolutely.
26:16 Love it.
26:17 Yeah, so you can do this with your project.
26:19 Yes, this huge thing is our project.
26:21 Anyway, it's pretty cool, and there's a free version, like I said, so maybe it'll help some folks out there.
26:25 All right, you ready for some jokes, Brian?
26:27 - Yes, definitely.
26:28 - All right, I have a, you've heard about the glass being half full and half empty, and like, oh, I'm a half empty sort of person, I kind of see the world as slightly negative.
26:35 Yes.
26:35 So here's the developer version.
26:37 So we have an optimist who says the glass is half full.
26:40 We have the pessimist who says the glass is half empty.
26:43 And we have the programmer who says the glass is twice as large as necessary.
26:48 Yes, definitely.
26:50 So I wanted to extend that with the pragmatist that says that I'm just allowing enough room for requirements oversight, scope creep, and schedule overrun.
26:59 That's right.
27:00 It's perfect.
27:01 I love it.
27:01 - And then you have this other one about software startups.
27:04 - Yeah, man, it's not really any startup, but I watched The Upside with Kevin Hart last night, and it was a joke that I couldn't help but sharing.
27:13 I can't remember the characters, but Kevin's character said, "Would you invest in my business idea?" And the other guy says, "That seems too niche, Kevin." What's niche mean?
27:26 Oh, it's the girl version of nephew.
27:28 (laughing)
27:30 It's terrible.
27:30 I love it. That's bad. If you got to ask, that's a pretty good answer.
27:34 Yeah. Yeah.
27:35 Cool. Cool. All right. Well, thanks for putting all the cool topics together as always and being here.
27:40 Yeah. Thank you. Bye.
27:41 Thank you for listening to Python Bytes. Follow the show on Twitter via @pythonbytes. That's Python Bytes as in B-Y-T-E-S. And get the full show notes at Python Bytes.FM. If you have a news item you want featured, just visit Python Bytes.FM and send it our way. We're always on the lookout for sharing something cool.
27:59 On behalf of myself and Brian Okken, this is Michael Kennedy.
28:02 Thank you for listening and sharing this podcast with your friends and colleagues.