Python Bytes - #321 A Memorial To Apps Past

Episode Date: January 30, 2023

Topics covered in this episode: git-sim Why I Like Nox I scanned every package on PyPi and found 57 live AWS keys Getting Started With Property-Based Testing in Python With Hypothesis and pytest Ex...tras Joke See the full show notes for this episode on the website at pythonbytes.fm/321

Transcript
Discussion (0)
Starting point is 00:00:00 Hello and welcome to Python Bytes, where we deliver news and headlines directly to your earbuds. This is Episode 321, recorded January 30th, almost the end of January. I am Brian Ocken. I am Michael Kennedy. Hey, Michael. Hey, hey.
Starting point is 00:00:14 Excited to be here today again. Also, before we jump too far into it, I want to thank Microsoft for Startup Founders Hub. Please listen to their spot later in the show. How are we going to start the show? What do you have for us, Michael? You may wonder, some folks have publicly expressed the bewildering thought that maybe we live in a simulation. I don't think so. Do you think we live in a simulation, Brian? Sometimes, yeah. No, I don't.
Starting point is 00:00:41 When I'm playing a game, maybe. But what if you were working on Git and you wanted to see how things were working, simulate some operations, and try to understand how Git works without actually making those changes? Because there's always the, you know, Git is full of good jokes, right? Like in case of fire, Git commit, Git push, run. Things like that, those jokes.
Starting point is 00:01:03 But the other one is, you know, you don't need to know git that well. If you mess it up, you just delete the repository and clone it again and start over, right? So, you know, ideally, you would be able to run some operations to help you understand what git is going to do without consequence.
Starting point is 00:01:20 And so I introduced you this tool called git sim. And git sim will visually simulate git operations in your repos with a single command. So what it is, is instead of saying like Git merge branch, you would say Git dash sim merge branch. Now, how best to explain what's going to happen? Like if it just says we would have merged this branch into that branch with seven changes, you're like, uh, okay, maybe that's fine for merge, but there are many other things that are more complicated. So as you, you and I are fans of this will simulate, it will show you the visual behavior
Starting point is 00:01:56 changes that are going to happen. Isn't that cool? Yeah. So by default, you get a JPEG image and the top one you see here, you can see all the commits, um, their shs, and their message. And you can see two branches. It'll see where head and main are and where dev is. And it'll show you if you do a commit or a merge, you're going to take these changes from dev, push them forward, right?
Starting point is 00:02:19 And the resulting shape or behavior of the repository. So that one's pretty straightforward. I'll show you some really cool ones in a minute. So use cases include visualizing Git commands to understand them. It's kind of what I was talking about. Also, my joke, prevent unexpected working directory and repository states by trying it out first. But there's also a whole, I'm creating blog posts, tutorials, courses, whatever. So sharing visualizations of your git commands with your team, maybe for documentation, right in our wiki, like this is our workflow, you probably don't understand what this weird git thing is that we're doing, because
Starting point is 00:02:57 it's non standard, please watch this little animation. So you know why we're doing it or something like that, right? Yeah, that's internal documentation. That's a great use for that. So yeah, absolutely. So basically, the supportive commands at the moment are log status, add, restore, commit stash branch tag, reset, revert, merge, rebase and cherry pick and then sub commands of those right. Install, it's got some some steps to install it, some some ways to run it. But then you can see, if you scroll down far enough, you'll start to see some of the examples. So there's a bunch of examples that are pictures, like a get sim dash log, it'll simulate the output showing the
Starting point is 00:03:37 most recent five commits on the active branch. Yeah. And it sort of shows you the tags and various things. You can see status and it does like a, a rich style sort of tree, not tree, a table view. Really nice there. You know, the different, uh, almost Kanban flow of your, your files going from untracked to, to attract and modify locally and staged and all that, which is actually, I think it's pretty helpful. Even with little arrows showing, it moved from here in this one of those columns to this other column.
Starting point is 00:04:11 Or I don't think I've ever used Git restore. I don't make mistakes, so it's fine. Isn't that delete and reclone? Yeah, exactly. Oh my God, don't commit that. Don't push that, please. Just delete it. Let's see, but if we go down further,
Starting point is 00:04:25 you'll get more interesting examples. The merge one is there. Let's keep going. But we get to the video ones. This is where it gets to be pretty awesome and pretty unique. We could do a get sim reset. So check this out.
Starting point is 00:04:38 So over here, you have this visual diagram showing how this stuff is changing over time. So it's like, all right, what we're going to do is we're going to reset this and you will see like the head pointer and the branch pointer move over. And what do you think, Brian? Isn't this cool? This is really neat. Yeah.
Starting point is 00:04:54 Yeah. Let's I'll just pick one, one or two more. So we got merge. That's pretty straightforward. Rebase. Let's animate a cherry pick. So you'll see it coming along here, building up the get repo status. And then what's going to happen? It's going to show us a branch and we want to take some of
Starting point is 00:05:11 those changes and cherry pick them over to the main. Yeah. Anyway, if I think I've lost on that one, but that's not a great animation, to be honest. Anyway, it shows you a bunch of examples, a bunch of cool things. I think this is really nice. Like I said, primarily documentation internally, like your internal wiki, your onboarding docs, or for, say, blog posts. You want to talk about what something looks like,
Starting point is 00:05:36 then run this. And it's not just what does a Git merge look like. It is what does the Git merge look like on this repo in this state, right? It applies to your working repo which is cool that yeah the applying to the working one that's that's really cool um what you i mean you said that mergers are pretty easy but actually i think i'll probably use this for merges the most because there's a lot of times where i have a mental model of what my repo
Starting point is 00:05:59 looks like and a merge shows a conflict or something and i'm like why why would it be a conflict because that's a good point actually and and it's probably because my mental image of what and a merge shows a conflict or something. And I'm like, why would it be a conflict? That's a good point, actually. And it's probably because my mental image of what the repo looks like right now is wrong. That like something has moved forward since I branched off of it or something. Yeah, very good point. Actually, I end up confused sometimes by,
Starting point is 00:06:19 that should have gotten a clean merge, no problem. And now I'm in some situation where it's asking me to describe the changes, and I actually don't know what they are. So let's start digging in. And then sometimes you've got to, like, manual merge? What is this, 1980? Exactly. What are we using, CVS? Come on, let's go.
Starting point is 00:06:39 Anyway, this is what I got, a Git sim. Nice. Well, so I guess we're kind of doing a tools thing, at least for now. I'd like to talk about Knox. So have you used Knox? I have not. Okay.
Starting point is 00:06:52 So there's Knox and then there's Talks. And I have used Talks a lot. So both of them, I guess, they do have like different things that you can use them for and stuff. What do I use them for? I use them primarily to run PyTest on multiple versions. So the general, one of the workflows that works on both of them is I want to create a virtual environment with like Python 3.10, 3.11, 3.9, a bunch of different Pythons, create a virtual environment,
Starting point is 00:07:20 install my package that I am trying to test, and then run that, and then all the dependencies, and then run that test suite within that environment. So, and that's kind of a standard thing. So my first thought, first when I saw Knox was, so one of the things, benefits of Knox, talks uses any files for the settings. You can also use, it supports Toml now, I think. I think you can do it in PyProject Toml also. If not, sorry. But the Nox uses just a Python file. So you have a Nox, I think it's noxfile.py or something like that.
Starting point is 00:08:02 But it just uses, I could use the example. But anyway, it does similar things. So Hynek, I'm going to get it wrong, sorry. Hynek wrote an article called Why I Like Nox. And he specifically calls out of like, I'm not bashing Tox. Tox is still awesome, a great team supporting it. And I agree. I know a lot of the people that support it.
Starting point is 00:08:25 But Nox might be for you as well. So here's a person that likes both tools, comparing them. And that's, it's refreshing. So first off, it's the file format. So any Tox uses any files, Nox uses Python. And I got to admit, even for a simple example like this, then the example I'm showing is running Python 3.10 and 3.11 and being able to pass in arguments to PyTest. Both are not terrible, but I think maybe the Knox one's a little bit more readable just because it's Python.
Starting point is 00:08:56 It's definitely more flexible because you could run arbitrary Python code in addition to some sort of setup, teardown beyond yeah so similar um and then he gets into another example which is a little bit more involved which is i i want i've got a test matrix but i also um different pythons but on i want to be able to run the oldest adders version um against um you know whatever python environment i'm'm running. And he claims that he, and I haven't tried this out, that it's actually, he doesn't know why it isn't working, but it's just, it doesn't work. And I, and I'm, you know, I can't help him out there, but then he switches to Knox and it's a,
Starting point is 00:09:39 it's a lot longer example, but it works great. And the, the longerness, longerness, I kind of like, and Hinnick points out, in terms of number of lines, it's longer than the TOX equivalent, but that's because it's more explicit. And anyone with a passing understanding of Python can deduce what's happening here, including myself a year from now. Explicit can be good, actually. So I kind of like that, that it's okay that it's longer. You're not reading it all the time, and having it more verbose might help. So I like that.
Starting point is 00:10:13 And then, of course, you brought this up, the power of the snake. You can run anything you want. It's Python code, so that's nice. And then one bonus thing is apparently it's a little easier to specify versions that nox has a dash dash python and you can pick the version you want to use like that and it just looks normal you can do that with talks too but the normal way to do it is to say
Starting point is 00:10:35 uh what like pi 310 which you just have to know the syntax it's not terrible but whatever um yeah so good good overview of nox yeah it didn't really yes i didn't realize that nox was playing python i'm sure that i knew that at one point but forgot about that looks that is an interesting advantage yeah yeah so i think i want to play with a little bit more um and i the um he points out also that he's not switching completely over to nox but he does have some projects using talksx and some using Knox. It's good there's two. Yeah, and they rhyme.
Starting point is 00:11:08 All right. How about our sponsor this week? Oh, yes. Thank you to Python. This episode of Python Bytes is brought to you by Microsoft for Startups. Microsoft for Startups has built Founders Hub to help startups be successful. Founders Hub provides founders at any stage with free resources to help solve startup challenges. The digital platform provides technology benefits,
Starting point is 00:11:30 access to expert guidance, skilling resources, mentorship, networking connections, and so much more. It is truly open to all. Along with free access to GitHub and Microsoft Cloud with the ability to unlock credits over time, Founders Hub has also partnered with other innovative companies to provide exclusive benefits and discounts, including OpenAI. And
Starting point is 00:11:50 we've heard from one of our listeners that he's taken advantage of this already and the discounts are awesome. You'll also have access to their mentorship network, giving you access to a pool of hundreds of mentors across a range of disciplines. You'll be able to book a one-on-one meeting with the mentors, many of whom are former founders themselves. Make your ideas a reality today with the critical support you'll get from Microsoft for Startups Founders Hub.
Starting point is 00:12:14 To join the program, visit pythonbytes.fm slash foundershub2022. The link is in your show notes. Ooh. Indeed. Indeed, indeed. Thank you, Microsoft. All right. Ready for the next one?
Starting point is 00:12:24 Yes. Not. Indeed. Indeed, indeed. Thank you, Microsoft. All right, ready for the next one? Yes. Not that one. So this comes from Tom's corner of the internet. Tom's got his own corner. Yeah, got a very own corner. It's, there's a lot of corners of the internet, to be honest. I don't know how many dimensions that is,
Starting point is 00:12:38 but it's, many, many corners exist in the internet. And here's one of them from Tom. And Tom says, I don't think the tools he's using here are exactly about Python, but what he is applying them to certainly is. It says, I scanned every package on PyPI and found 57 live AWS keys. Not just, oh, that looks like a string that could be an AWS key. He logged in as that person. Oh, this is not on GitHub. I want to emphasize this is on pipe.
Starting point is 00:13:08 Yeah. So pip install. Hey, look, thanks for shipping me a version of your keys. Weird, weird indeed. So it says after I inadvertently found that Infosys leaked AWS keys on pipe. Yeah. I have thought, well, if it's once, it's probably many times, right? They're probably not the only one. So after scanning, get this, all 430,000 published.
Starting point is 00:13:32 Well, no, actually, I think that's releases. There's 430,000 packages, but there's 4.1 million releases. So I think he scanned all the version history as well in case somebody found them and took them out. Anyway, after scanning those, I found 57 valid access keys from, you know, organizations. I'm sure that they're new at working with the cloud and especially AWS. It is tricky. So these organizations may not be familiar with the rules, but Amazon leaked their own AWS keys. That was the joke. The rest, not so much. But Intel, Stanford, Portland, and Louisiana universities, keeping it local.
Starting point is 00:14:13 The Australian government, thank you for that. General Atomics Fusion Development, Teradata, Data Lake. And yes, your gloves too have been leaked. Top Glove, the world's largest glove manufacturer. I love the emoji of the little glove. There's a glove emoji at the end of that title. So here, like check this out. If I click on Australian government,
Starting point is 00:14:34 it takes us to inspector.pypi.io, which I didn't really know anything about. Then it links to DataCube-OWS version 186 and pulls it down into WSGI local PyPI. Brian, what does the comment say? Do not commit. AWSQs do not commit. Not only are they committed.
Starting point is 00:14:58 You know what? Here's the thing that's interesting, okay? They may not be committed to GitHub, but they may have forgotten to take them out when they did the build step to build the wheel. And then they comment them out or somehow remove them from going to GitHub. And that's-
Starting point is 00:15:14 Oh, I could totally see how this could be easily done because you have to go through an extra step to push from GitHub to PyPI. A more natural beginner state is you publish to GitHub and you publish to PyPI. Yeah, exactly. It's very, if you haven't set up full end-to-end automation that does the publish for you,
Starting point is 00:15:34 which I think a lot of people haven't. Yeah. You know, it's easy to have this happen. All right, so let's go through this real quick here. So how do we do this? Detecting AWS keys is actually pretty simple. Did you know that there's a regular expression do this? Detecting AWS keys is actually pretty simple. Did you know that there's a regular expression that is a valid match for AWS keys? I know there's kind of random business, but no, there's a certain format that they take. So you can tell this is not
Starting point is 00:15:57 just a key, it is an AWS key ID. Oh, cool. So now I know how to search for them in other people's repos. I feel like this would be a pretty awesome pre-commit hook. And, you know, there's tools like Twine and others that people use to build their packages that get shipped to PyPI. Yeah. And PyPI itself. All of those could start applying checks for this kind of stuff, right? Because GitHub access keys have a certain pattern now. I don't remember. There's some prefix that they seem to have
Starting point is 00:16:28 that looks like it's predictable. I feel like maybe this could be put into the supply chain pipeline, as they call it. But anyway, there's a regular expression you can run against to find them. And here we go. So we can use the amazing ripgrep to search packages for this pattern. And look at that. Here we can use the amazing rip grip to search packages for this pattern.
Starting point is 00:16:45 And look at that. Here we go. You pull down this, this GZIP file, and then you rip grip it and boom, out comes the access keys. Whoopsie. Apparently Amazon pay at this point here. But just because the keys are present, are they valid? I don't know. So the next step shows you how to execute the AWS CLI command to get the caller identity to see if it's actually valid. Right? Okay, so it says, now the devil's in the details. The Z-Z flag doesn't support searching zips. So let's go and tear this up.
Starting point is 00:17:20 And it points out you can get the entire, over at github.com, or fpypi-data, you get the entire static dump of PyPI data. You know this exists. I had no idea. So I'm like, wait a minute, let's go check this out. PyPI-data, this is automatically updated PyPI API data available in bulk.
Starting point is 00:17:40 So the contents of the entire- How big is this? It's not small uh see see the shallow checkout perhaps um the contents of the entire pypi json api for all packages updated every 12 hours wow yeah so it says for example here's the json for um django anyway, I didn't know that that exists. That's pretty awesome. Then he set up a GitHub action to pull those down. Then GitHub actions, let's see,
Starting point is 00:18:13 GitHub secret scanning service will kick in and let AWS know that the keys are leaked. This will cause AWS to open a support ticket with you to notify that your keys are leaked, which is kind of an interesting chain of events that happens here. But it talks about how old the keys might be. The oldest one is from 10 years old, from 2013, and the different reasons this happens. It's hard, for example, to test against AWS.
Starting point is 00:18:42 Another reason that they say is like there's legitimate and quote uses. One of the things they talk about is why is this happening? And Python being super heavily used in data science and ML, a lot of folks come from that side of the world
Starting point is 00:18:56 without super strong software engineering practices. And so maybe, you know, coming from economy and being an economist, you're like, oh, I got this thing working. Let me publish this up to help people. Right.
Starting point is 00:19:08 It's really easy that you didn't really think about some of these things. Right. But basically, don't put your secrets in your source code. Don't put them in GitHub. And, you know, don't buy the transitive property, put them in PyPI either. Yeah. Yeah. So anyway, what do you think?
Starting point is 00:19:24 I think it's um it's a head shaker but interesting um we need we need like stickers made up for laptops do you know where your keys are exactly it's 10 p.m do you know where your keys are yes they said they're sleeping at their friend's house they're actually at a frat party. Okay. Yeah, so the article is like missing one step and that's how to set up a Bitcoin miner on all these keys that you... That's left as an exercise to the user. By the way, nice little Hugo website here.
Starting point is 00:19:58 Gotta give it a little shout out to that. I know we both like our Hugo. Okay, that's it for this one. Okay. What's your final one for us? I've got got hypothesis. So I get actually asked this a lot. I do like hypothesis, but it's a little overwhelming. I get asked, so what do you think about hypothesis? Or something like that, or do whatever? Yes, I use hypothesis. I do like it. But it is it can be overwhelming. So we're going to take a look at an article called Getting Started with Property-Based Testing in Python with Hypothesis and PyTest. And this is from Rodrigo, and I'm not going to try
Starting point is 00:20:32 the rest of the name. Rodrigo, maybe. Yeah, I'm not. Sorry. Cool name. Saro? Saro? Yeah. Anyway, it's on the Semaphore blog. And there's a lot of what I like about this article. And the well, first off, what I really like about property based testing is not that I mean, it can find some bugs in your code. And that's that's kind of what it's for. And it's good. But it also makes you think about it. So thinking about a few examples to test your code and corner cases and all that stuff is good to say, you know, how do I, how do I know if my code's working, but with property based testing, especially, and I, I think a good place to focus this on is algorithmic stuff. So
Starting point is 00:21:16 you've got like some type of some algorithm inside your, in a function, and you really want to make sure that that's just solid, no matter what you throw at it and so that's a great place for property-based testing but how what you do is you think about you have to think about what properties are true because what hypothesis is going to do is it going to throw a bunch of input at your function and you so you have to think how do i tell if i don't know what the input is if the answer is correct. Because if you know the input, you can like calculate it yourself, whether the answer is correct or not or something. But without that, you're thinking in properties. And so I love this article. The first to describe the example, it goes through two examples. The first example is a greatest common denominator in math problem
Starting point is 00:22:03 of like thinking about, I mean, you can just like have some known problems that you know the answer to and pull those out. That's great. But how would you test like for every number? And so going through a couple, thinking about what to test is great.
Starting point is 00:22:19 What did he talk about for greatest common denominator? Your answer is going to be positive. And the answer needs to divide both of the numbers, right? That's kind of the point of it. But then how do you know if it's the right one? Well, no other number larger than your answer is going to be able to divide N and M. So you're going to end up doing kind of an exhaustive search a little bit but that's okay it's it's it's source code it'll run shouldn't be too long and the other thing hypothesis do does which i i didn't know at first is it's pretty good at picking numbers that will probably break your code and by default it only picks 100 numbers it only picks up 100 test cases and the limit is important because often your sample size
Starting point is 00:23:07 that you could test is infinite. So you don't want it to just run forever. You want it to be some constraints on it. So it goes through this example coming up with how to test that, so it writes a test. And then how do you plug hypothesis into it? So you've got given and strategies is often used. And so you put a decorator on your test, say given strategy integers for both the input of n and m.
Starting point is 00:23:38 Test to make sure. And then you run your function and then test stuff around it. And the test is listed up higher in the code. And then quickly, you're going to find problems. And I like the greatest common divisor because there are test cases that don't work, which is great. Like zero. Zero, you know, by definition, we don't. If both of them are zero, it's undefined.
Starting point is 00:24:03 And if one of them is zero, it'sefined and uh if one of them zero it's defined to be the other one which i actually didn't know i'm like really is that true i looked it up and i didn't think about that either yeah so apparently if you the greatest common divisor of zero and five is five which who knew um but aside from that so uh coming up with edge cases is probably good for algorithmic type of code anyway. And then the example of 0, 0, how do you get rid of that? So in this, I guess this is one of my caveats about this article. He talks about limiting the range, which is good.
Starting point is 00:24:38 It's a good example because you're going to want to do this in a lot of your test cases is limit the range. So you can put a min and max on different things. And there's a lot more than numbers, you can do text, and you can do all sorts of stuff with hypothesis. But I think good starting with numbers is a good one. I just don't like the solution that he came up with. The solution he came up with is limit one of them to from one to 100. So that you're never going to have 00. And I'm like yeah i i personally would have used um a different mechanism so my my recommendation is a there's a strategy called so oh not strategies um making assumptions so there's a thing in hypothesis called assume and you can say um uh within a test you can say assume something assume it's just like an assert, but it doesn't
Starting point is 00:25:25 fail your test. If it fails the, it rejects the test case is how it works. So you can say for the zero zero case, you can say, assume N equals is not equal to, or assume not N equals M equals zero. It's hard to do this without code, but you can make an assumption there so that it'll kick that one out. That's how I would have done that. But other than that, it's a really great introduction to how to work with property-based testing.
Starting point is 00:25:55 So I give it a thumbs up. Then there's a second example, which is nice too. So that's cool. I didn't know about Assume, so I'm very good to know about that. The other thing that I think is a good thing to know about is example. So like the example zero zero, we specifically don't want to test that because we know it's broken or it's not
Starting point is 00:26:13 defined. But there are lots of cases where you're like, you know, somebody you're doing property based testing on something and you get a defect of like, well, if I run these numbers, it fails. And you're like, oh, well, we want to make sure we always run that. So with example, you can say hypothesis. You get to come up with the examples, except for always run this one also. And you can just kind of stack them up. That's good. Yeah.
Starting point is 00:26:36 And so for people listening, example is a decorator you put on your test. Say at example, and you put a certain set of parameters that get called there. Yeah. I just, I kind of don't like that uh so examples is a decorator that you put on the outside to say run this one always i'd like the reverse also to say this particular example don't run it because i know it's broken um and the i mean we get around it with the assume part but it would be cool if there was like a don't run this example yeah yeah it looks very helpful and i learned some things so excellent how about you what's next we got
Starting point is 00:27:09 extras extras are we done with our normal ones wow yeah time flies when you're having fun you know yeah all right when we go first you want to do yours uh i i got a short one all right go for it okay so my let's let's get rid of that we don't need that um my example my extra is just that this came in the mail and i'm really excited about it uh so it's the japanese version of python testing with pytest um it's been out for a little while in i assume japan um but uh it got translated, uh, in touch with the translator. Um, and, uh, they asked me a few questions, very respectful dude. Um, and I'm, I'm glad and I'm like, can I get a copy?
Starting point is 00:27:52 And they sent me, they sent me a few copies actually. So pretty exciting. Fantastic. Oh, that's really cool. That's it's neat to see it. It's neat to be reminded of the global reach. Yeah. And not just the cover, the insides are there too but amazing um so you're
Starting point is 00:28:08 gonna learn japanese so you can figure this out i do have a friend that speaks japanese so i'm gonna go and uh and see but they don't code but yeah it's all right i'm sure they're gonna they'll find it riveting anyway um yeah that's awesome what are your extras well a couple things so it seems like i have uh survived the very first uh python bytes on my new mac mini i just got a you know apple released the mac mini pro m2 and i got that and so far super super neat i can recommend it's a lot lots faster than the previous mini so i know i mentioned that i had i used to have money and then I had a mini on order and now I actually have a mini, a new mini. It does, it looks identical to the other, but it, it goes way faster, which is great. Maybe I'll have more to say about that later.
Starting point is 00:28:54 All right. So have you heard that Twitter is going through some turmoils? I'm not sure. I think something's going on over there. The latest turmoil is that they decided to unceremoniously, unprofessionally cancel all the third-party Twitter apps. That's just insane. It's pretty insane. Honestly, I think it's fine and within Twitter's right to say, look, we don't want to have third-party apps. We have a business model that doesn't work well. There's not third-party Facebook apps. There's not third-party Instagram apps, are there? I don't think so. Anyway, I think it's fine. But the way that it was done was, oh, we're just going to cut them off.
Starting point is 00:29:35 And then in a few days, maybe somebody will say something. What they said was the reason we cut off things like TweetBot and other ones is because they violated the terms of service. Like, wait, we've been doing this for 10 years. What do you mean? The reason they violated them is they went back and updated the terms of service to say we don't allow third-party apps. That's the one violation of it. I mean, it was just really weird.
Starting point is 00:29:57 Anyway, I want to just direct people who want to, you know, enjoy the moment technically and socially to tapbots.com slash tweetbot, where they put up a memorial to tweetbot. Brian, is this a fantastic picture? It really is. There's this little elephant, but it's all like, like 3D looking like claymation or something. It's yeah, it looks kind of, it does look a little claymation-y and, you know, the mastodon elephant is at the gravestone of TweetBot. And it has the life from April of April 2011 to January 2023 on the gravestone of TweetBot. And it's just anyway, it's pretty interesting.
Starting point is 00:30:35 The reason part that I bring this up, not just for the picture, is if you're into Mastodon, the same company decided, well, we're doubling down on Mastodon and creating Ivory, which there's been a ton of talk about Ivory being a really cool app for if you want something better than, say, the progressive web app for Mastodon. I know there are others out there as well, but a lot of people are really big fans of Tweetbot and Tapbots, the company. And so you can now, this is now publicly available. Okay. So there's that. And anyway, I started using it is now publicly available. Okay. So, so there's that. And anyway, I started using it. I like it really well. I don't use it exclusively over just using the progressive web app because the progressive
Starting point is 00:31:13 web app has the advanced view where you have multiple columns. You can create searches for hashtags and pin those as columns. And it's really nice, but this is a quite a nice, nice app if you're not kind of doing that advanced view. Oh, and by the way, Christopher Tyler has caught something incredible. nice but this is uh quite a nice nice app if you're not kind of doing that advanced view oh and by the way christopher tyler has caught something incredible yeah i have missed uh this this uh gravestone in the memorial happens to be on mars i think yeah it kind of looks like that's awesome why do you think it's on mars i don't know same thing the simulation we're not
Starting point is 00:31:42 sure about that anyway check out ivory people can try that. If you're in iOS, that's pretty good. One more quick extra. PyCon, PyCon, PyCon. Yay. I'm looking forward to this. I got my tickets, Brian. I'm going to be there for a week. I'm going to try to be cruising around the sprints. It might even take a day and try to go skiing. I haven't't decided we'll see what the weather's like out there but uh it's in salt lake city of course however i have news for you i don't even i haven't even told you this officially okay but i have gotten us an official time and place at pycon to do a live python bytes show yay awesome yeah so we've previously kind of run around the first day and looked for somewhere where we might be able to do something, but we're supposed to have an official room and a time where
Starting point is 00:32:31 we could actually live stream it. We can talk to people ahead of time if they really, they're going to be there and they want to come. So we should be able to have a cool event at PyCon. That's why I bring this up. Yeah. And it won't be on Tuesday then. No, it won't be on Tuesday because it's Thursday night, Friday, Saturday, Sunday is the conference. So it's going to be one of those days. Awesome. I'm looking forward to that. I'll be there too. Neither of us are speaking, but we'll do the live event.
Starting point is 00:32:55 And then Michael's going to probably interview absolutely everybody at the conference. Yeah, I'm trying something different this year. You know, TalkPython, primarily for the courses side of things, has had a booth on the Expo floor hall where I'll set up and meet people and show off the things we're doing. And, you know, Brian, you've come a couple of years and hung out there. We talked about Python Bytes and that booth as well, which is fantastic. This year, I'm not doing that.
Starting point is 00:33:21 I just want to try to be to be around have more interact with more people and try to maybe do some more on the spot shows and some other stuff like that right so absolutely we're going to be at pycon we're going to be doing fun stuff just not at a booth this time i'm going to try some try some variations on it this year yeah and i think i think a lot of people i think they should hit us up so So especially if you thought about maybe asking to be on one of our shows, either yours or mine or this one, but you're a little nervous, then this is a great opportunity. One, you don't have to be.
Starting point is 00:33:53 You could just contact us anyway. But at PyCon, you can hit us up and say, hey, I was curious if this would fit. And in person, sometimes it's easier to talk. And I'll be bringing stickers of course, to promote the book. Um, and, uh, I'm excited. And also, um, I'll be at Pike Cascades, um, before Pike on, uh, Pike Cascades is there is coming up, um, in March and all, and I'm speaking there too. So that's in Vancouver, right? Yep. Vancouver, BC. Lovely. That's I've been to the one in Vancouver. I think the inaugural
Starting point is 00:34:25 one was there and it's really, really nice there. So excellent, excellent commerce. I told my daughter I'm going and she's like, what's the big deal? Vancouver is like 20 minutes away. No, different Vancouver. For those of you who don't know, the people who explored, the Europeans who explored the Pacific Northwest, they didn't have a lot of creativity. There's multiple Vancouver's. There's like one just by Portland. There's one up in BC, Mount Hood, one of the most awesome mountains around here. It's just named for the friend of some guy back in England who never even was here or looked upon the mountain. It's awesome in a bad way. Okay. But yeah, the other, the Northern, the Canadian
Starting point is 00:35:07 Vancouver is a really nice place to go. All right. You ready for our joke, Brian? Yeah. So I feel like you and I can relate to this given our age here. There's a post here that says from somebody named Mark the Cat Whisperer, but reshared by Rob Isaac. Mark says, I'm a Gen Xer, so I adapt to new technology like a millennial, but I get angry about it like a boomer. I get that. I get that too. I'm definitely in the Gen X phase. And oh my gosh, I have more than one time yelled at my computer. I find personally the way, like the reason I connect to this joke so well is
Starting point is 00:35:45 I get mad at other people's technology because I'm like, I know this could be better. Why have you not put an index here? Why have you not auto-filled this? You know, like, which is like, I know you could make it better so easily. What is wrong with you? And then I guess the boomer side. But the joke is Rob says, I didn't come here to be called out like this. Funny. All right. Well, that to be called out like this. Funny. All right. Well, that's what I got for us. Nice.
Starting point is 00:36:08 Well, thanks a lot, Michael, for joining us again today. And on this 232, wait, 321st episode. Wow. Yeah. It's like the amazing countdown. We just don't know to what. Three, two, one. Contact.
Starting point is 00:36:22 It's the future. Well, thanks everybody for joining. And thanks Michael. And, um, talk to everybody next week. Bye everyone.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.