Python Bytes - #321 A Memorial To Apps Past
Episode Date: January 30, 2023Topics 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)
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.
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.
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.
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.
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
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?
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
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
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.
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,
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.
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.
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
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,
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
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,
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.
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.
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,
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.
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.
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.
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,
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.
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
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.
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,
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
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.
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?
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,
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.
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.
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.
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,
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.
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-
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,
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
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
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.
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.
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.
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,
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.
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
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.
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?
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.
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
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
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
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.
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
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.
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.
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.
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
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.
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
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.
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
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?
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
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.
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.
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.
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.
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
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
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
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.
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.
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.
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
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
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
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.
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.
It's the future.
Well, thanks everybody for joining. And
thanks Michael. And, um, talk to everybody next week.
Bye everyone.