Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 319, recorded January 17, 2023.
And I'm Brian Okken.
And I'm Michael Kennedy.
Well, I'm super excited to talk about whatever you have to share with us.
But before we go, before we get started, I just want to say thanks to Microsoft for Startup Founders Hub for sponsoring this episode.
Listen to their spot later in the show.
And let's see what you have to talk about, Michael.
What do I got to talk about?
I also want to remind people they can go to Python by Set FM, click on the live stream and see all the upcoming live streams and be part of that.
So it's always awesome to have them there.
And follow us on Mastodon.
We got all of our things there.
Believe it or not, we actually do a couple of things on Mastodon every now and then.
But what I want to do is actually talk about this article that Ned Batchelder wrote, which I found on Mastodon when we did our tools for readmes and other repo homepage types of things called the Secure Maintainer Workflow.
So, Brian, we got to judge the level of paranoia here.
Do you worry about people getting into like pytest check?
Do you worry about people getting on your computer and accessing SSH keys or things like that?
Don't.
I don't know if I should, but I don't.
Well, Ned does.
And I share some of his concern.
You know, like on my hard drive, I have SSH keys.
If you could figure out what computers those went to, you could remotely log into them.
There's a few layers of indirection that make that more difficult than you would imagine.
But still not that tricky.
And there's been a bunch of issues.
For example, let's see.
There's the CircleCI breach, I believe.
It's probably a fair search term.
CircleCI is super scary because they build the things that companies ship.
So if you ship a website or a mobile app or you ship a desktop app or any of those types of things, it's automated potentially through CircleCI and you send it out.
So if somebody, say, were to take over your CircleCI, that would be bad.
I believe what happened was somebody had gotten hold of someone who works on CircleCI, got into their GitHub account, right?
That could be through an SSH key or when you're on your terminal, you could just type git add, git push, all those types of things, right?
So Ned says, well, what can I do so that if someone did get access to run code on my behalf, that it maybe wouldn't be able to push directly to coverage.py and just start going out?
And that's the next thing is once that goes out, that goes to everybody's servers, many of them anyway, right?
And then you potentially have bad code running on people's servers.
So the consequence is not just, oh, Ned might get hacked, but everyone using coverage.py, which is many, many, many, many, many people might get hacked, right?
Yeah, and it's also used on developer workstations.
So it's going on developers' computers as well.
Exactly.
And then rinse and repeat, right?
Now they have SSH keys to what are they building in Onyx.
It goes sideways fast.
So he's like, well, I have this, I have terminal sessions that have implicit access to credentials, PyPI, Git, and so on.
It would be better, you know, for example, you can push to Git without asking for a password, right?
Either through a credential cache or an SSH key or something like that.
This is problematic in a couple of ways.
The less likely, less concerning, although a lot of advice sort of worries about this, I agree that it's not very concerning at all, is somebody actually gets physical access to your computer.
So I don't know what most people do, but you should be turning on full disk encryption, especially if you have a laptop, right?
If it could be stolen, or especially if you travel around with it and it could be lost somewhere or picked up and lifted off like the subway or something,
you don't want to be able just to take the disk out and read all the data off it, right?
So a super easy way to do that with low overhead is like FileVault, which is built into macOS, and I'm pretty sure Windows has something built in.
So anyway, full disk encryption.
So chances something bad happens there is really, really small.
On the other hand, though, is if you run some evil code.
Now, evil code could come from traditional places like spam or phishing or those other areas.
But for developers, especially people maintaining popular projects like coverage.py and many other things that Ned does, is somebody could try to send him malicious code through Python and through source control.
For example, what if somebody says, hey, Ned, I've got this issue with coverage.py.
Check out this repo and run it to see the bug to reproduce it.
It's like, you know what that might do?
Well, whatever Ned can do on his computer is what it might do.
And he says, look, if I get a huge repo, not a PR to coverage.py, but a huge set of code that coverage.py is applied to, you know, what is that potentially going to do?
He can't go code review every huge PR that is sent to him when it, you know, refers to someone else's repo, right?
So there's things you can do, but that's his primary concern is how do you deal with people sending him bad code?
So first thing is 1Password.
1Password is awesome.
Also, not LastPass.
Don't use LastPass.
More on that at the end.
But oh my God, don't use LastPass.
1Password or Bitwarden are really good choices.
And it says, look, I store my credentials in there.
And then you can have two shell functions that will load those variables into and out of the environment just for a moment.
So load the GitHub credential into the environment, do a git push, unload it, for example.
Something like that, right?
That's pretty cool.
Similarly, things that are very less likely to be used are like PyPI credentials, right?
How often do you really do a push?
It says, but also I have SSH, a .SSH directory, which on Mac and I think Linux as well is where the default SSH keys just live, unencrypted, hanging out there.
So that would be something you want to keep away.
Now he says, I don't know what to do with that.
The comments here are very helpful.
But the other thing is, he says, if I've got to run that PR and somebody gives me some huge bit of code, I'm running that in Docker.
So get one of the base Docker files for Python, log into their interactive shell, git clone, try it out.
So, you know, who cares if somebody hacks your Docker file, right?
Or your Docker container.
You're going to throw it away anyway, right?
So he asked, what else can I be doing to keep safe?
And luckily there are comments on his blog here.
It says, you could piggyback on the one password workflow to export extra SSH config.
And go down here.
Dirk Sean says, I use secretive, which keeps SSH keys on the Mac locked up.
Some comments for protecting Docker, although I don't really see any reason I would care about protecting a base Docker image.
But Kushal Das, another core developer, says one password can do SSH.
So one password will run an SSH agent that will serve up the keys on demand, but like prompt you for a fingerprint reading or verify on your watch or, you know, enter your one password password type thing, which is cool.
And he also suggests using Podman, which has higher security than Docker.
And I'm not sure why you need that.
But finally, Brett Cannon says one password for SSH.
Let's go.
That seems pretty awesome.
So interesting.
Anyway, these are some ideas.
I think it's only scratching the surface.
But yeah, and then Christopher, just to follow up, says BitLocker is the file vault equivalent for window.
That's right.
Thanks, Christopher.
So one of the things that I mean, OK, so yes, protecting against, you know, losing your laptop or somebody taking it or reading your whatever.
These are all kind of cool.
One of the my concern isn't really that somebody is going to try to access it is that I can't anymore.
Like like my laptop just dies and I can't use it anymore.
So things like one password, I assume they're backupable so that I can get access to it again.
Yeah.
So one password stores all that information on their servers where you control a super long encryption key that they don't have.
So if you lose it, there's no I'll get my thing back.
Part of the setup process for one password is they're like, here's your 30 character secret key that is combined with your password.
And if you don't have both of those, we can't help you.
It's encrypted with this and we don't know what it is.
So it's it's pretty good.
It's pretty good.
It's not LastPass again, which we'll touch on.
But so that syncs to all like it syncs to your phone.
It syncs to your different computers.
There's a web version.
It's it works on Windows, Mac, Linux.
It's a pretty good option, honestly.
It's paid, but it's it's not much like five bucks a month.
You don't want that Bitwarden, but Bitwarden is not quite as secure because I don't think it has the secret key.
It's just the password.
So you need a longer password.
I don't know.
We're going a bit down too far down that rabbit hole, maybe.
But yeah, it's it's pretty interesting.
Certainly it's a concern.
But so, for example, you can have file attachments in your one password.
So you can attach like your SSH folder to like a logins thing that you put in there.
So if you go to a new computer, you can just, you know, open that thing up and get your SSH keys, drop them in there and off you go.
Right.
But never, never lose that that that 30 character secret key because you're not getting back in without it.
All right.
Over to you.
What you got?
What do I have?
I've got some web scraping.
So or a tool.
Actually, a couple of tools for parsing HTML and parsing JSON that I thought were just pretty darn cool.
So I was reading this article, which is a decent article called A Year of Writing About Web Scraping in Review.
So somebody that got a got a job doing a whole bunch of blog posts about web scraping.
But one of the things when he talks about doing it in Python, it had HTTP, HTTPX.
And yeah, you and I both like that a lot.
Yeah, that's great stuff.
Pretty popular.
But I hadn't heard of Parcel or James Path or James Path is J-M-E-S path.
And so I wanted to check that out.
These are some pretty cool tools.
So what Parcel does is it's a Python library to extract and remove data from HTML and XML.
Sure, I guess.
Using XPath and CSS.
So the CSS part is the part that I'm excited about.
But so the idea is like, here's an example bit of HTML that we're showing on the live stream.
And you can just like access elements like you would CSS access.
Like, you know, H1 colon colon text.
I'm not sure why it's colon colon instead of dot.
But anyway.
I think those are what they're called.
Like special classes in CSS.
Okay.
Yeah, the text is odd.
But you can do things like H1 colon hover.
And that like only triggers when it hovers.
Yeah, colon colon text.
You're right.
Okay, I get it.
That is weird.
But anyway.
Kind of interesting.
I like the.
And then I'm used to the like the greater than.
I think that's like some child of or something.
Immediate child.
Yeah, it has to be immediate child.
Yeah.
Okay.
But it's fairly clear to read then to be able to pull out some stuff out of your HTML using these selectors.
So that's pretty cool.
Yeah, that's really nice.
I've always thought of beautiful soup for that.
But this sounds really nice.
The other the other one that I thought was great and which I probably do more often is grabbing Jason's stuff out of Jason.
And so I hadn't heard of James path.
And it's just something some pretty cool expressions to be able to pull out some stuff.
So if you've got like this example of foo and foo is a dictionary element and it has another dictionary inside with bar and the value of baz, you can just say foo dot bar and it'll return baz.
So those are pretty cool.
Just simple, simple little tools about getting Jason data.
So that's interesting because I never really thought of parsing Jason with like a search.
Yeah.
With a query CSS like search, I've always just thought of it as well, I'm just going to load it up and navigate it.
But this is I just want to go to this section and grab this array and I don't care what's in the middle.
Yeah.
Well, and actually, so I need to play with it.
So you're right.
I've never really thought about too much about doing searches or something.
I just like load it up and just navigate it.
But but if it's somewhere buried deep inside my document, I wouldn't know how to get it.
So yeah, or possibly if it changes over time.
So it's like, you know, there's a component on the site on the page, but it's it might be loaded anywhere on the page.
Yeah.
Yeah, exactly.
Yeah.
It's kind of like a CSS selector for Jason, which that is a cool discovery.
Yeah.
So anyway, that's it.
A couple of short items, but nice out there.
Well, McGuigan says pseudo classes.
And yes, pseudo classes for sure.
Absolutely.
So that's like the colon hover and stuff.
But these are all like colon read only colon valid colon, you know, these colon visited.
But I don't know about the double colon.
Maybe that's something else.
Maybe it's just a special specialization of pseudo classes.
Yeah.
But I don't know.
I have to dig into it a little bit more.
Same.
I've only been doing the web for like a few weeks.
I went to this boot camp.
I'm getting getting good at HTML.
All right.
Tell us about our sponsor.
This episode of Python Bytes is brought to you by Microsoft for Startups.
So 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, and network connections, and so much more.
Founders Hub is truly open to all, along with free access to GitHub and Microsoft Cloud,
with the ability to unlock credits over time.
Founders Hub also has partnered with other innovative companies to provide exclusive benefits and discounts.
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 mentors, many of whom are former founders themselves.
Make your idea reality today with critical support you'll get from Microsoft for Startups Founders Hub.
To join the program, please visit pythonbytes.fm/foundershub at 2022.
The link is in your show notes.
Indeed.
Thank you, Microsoft, for sponsoring the show.
Let's see.
What do I got next?
Back to Git.
But this time, not protecting Git.
Understanding your Git repository.
Brian, do you know what your largest Git repository is in size?
No.
Not either.
But I'm pretty sure that Talk Python training, the website, is just under a gig.
And that's quite a bit.
So maybe.
I haven't looked at all the others, but that one's one of the larger ones that I manage.
But is it big because it has a bunch of binary stuff that I should maybe find and remove?
Is it big because there's just a lot of files?
If you have directories named like backup one, backup two, stored in there?
No, no, no.
Version, version one, version two, version one final, version one final, final.
I zip those.
I don't just have enough directories.
Yeah, so anyway, what I want to tell you all about is a tool called Git Sizer.
So it computes various size metrics for Git repositories and pointing out aspects of your
repository that might cause problems.
So if you've got a small repo, like who cares?
Don't worry about this stuff.
But on the other hand, if you've got one where it's like, this thing is a pain to check out
or CI builds are really dragging because of this, this segment, if not necessarily this
tool, I think will be helpful for you.
So I recently did an episode on monorepos with David Vyek and we uncovered a bunch of
cool tools.
One of them is this Git Sizer because monorepos are like, I don't just have a repository for
this project.
I have a repository for the company and all hundred people put all of their projects into that
one repository, which is a bit of a mind bender.
But if you do stuff like that, you need to think way more carefully about how you work with
files and Git and so on.
So you can ask questions like, is the repo too big overall?
Ideally, it should be under one gig.
Well, actually, maybe I'm over by like a couple of bytes, but whatever.
And they start to get out of control at five gigs.
Like Git doesn't behave well sort of thing.
So you can do things like avoiding compiled output.
So if you have jar files, right, or wheels, I guess in our case, we have less compiled output.
But if you have say like wheels, you want to keep a version of every release, maybe don't
store that in Git, maybe store that somewhere else and link to it in Git.
I don't know.
You also use Git large file system instead of putting large files directly in there.
And things that's not very compressible and cannot be diffed.
They're very much hated by Git because Git does a lot of its work by doing Deltas.
Like, okay, here's the main one.
And then here's just the difference of these versions I need to keep.
Like this one line in this text file changed.
That could be what's stored, right?
But if it's just a binary thing that can't be diffed, then that's always a copy.
So you can go through here and you download it to get started.
It says you run it.
It'll tell you things like processing, you know, go through the blog, basically analyzing the system.
It says overall repository size.
Here's how many commits there are, how big the commit history is.
Here's how many trees as in folders and stuff and how overall size of them and the blobs, right?
So this one has 55 gigs of blobs with 1.65 million blobs.
That is a serious, serious bit of history there, whatever this project they ran it on.
But it'll go through and tell you, you know, what's going on.
And yeah, you can sort of look and get a better understanding of what's happening in your Git repository.
Cool.
Something else that I'm sure everybody knows this already, but especially in CI and stuff,
it's helpful to, when you're going to clone a branch, to clone it to depth one so that you're not cloning all the history.
You don't need it for...
Yeah, so I have some interesting newer version of that guidance for you, Brian.
Okay.
So I was looking, I watched some of the presentations at GitHub Universe.
And so what you're talking about is what's called a shallow copy.
So it says, we're only going to pretend that there's three commits deep in this branch,
in which case you only see like three commits worth of history and so on, right?
But it is much smaller because it doesn't keep all those files over time.
But you make the trade-off that you don't have all the history.
If you wanted to go back and read that and potentially even check out back to one of those,
you'd have to like delete the thing or check it out again and somehow in another less shallow way.
So what you can do that's real similar is you can do a partial clone.
I don't know how I ended up on this page, but there's docs for it on the GitHub documentation page.
So with a shallow clone, all that it will check out is the like depth one.
Sorry, not shallow.
Partial clone is...
All it will check out is level one of files, but all of the commit history and messages.
So like this file has 10 changes and here's the messages, but it doesn't check out those nine others.
But what's cool is if you were to like switch a branch or go back in history,
Git will on demand download that other one.
So what you end up typing is you type something like Git clone --filter,
colon blob equals none.
Or you can even say, I want all the files except for anything over a certain size that might be in history.
So anything over 100K.
But other than that, give me every file forever throughout us all history.
So this partial clone is like a similar type of thing,
but it's a little more flexible in that it's like a transparent proxy to the full history of the repo without cloning it.
Does that make sense?
Yeah.
So that might be a good workflow for like in a development environment.
Yes, exactly.
Yeah.
If you're not hoping that you're going to be able to go offline and completely disassociate yourself from GitHub, right?
If you are assuming I still have online access and I don't want this folder to be the true,
complete full history forever of the repo,
I trust that it's other places, then you'd be totally good.
The one place where the shallow clone would be really awesome is for CI.
Yeah.
That's what I was mentioning.
Yeah.
Right.
Yeah.
If you're doing it for CI, then like your CI system does not care what the history is.
It only cares what the current is.
Yeah.
Right.
So shallow clone.
And then similarly related to that is you have sparse checkouts where you can say,
I know there's a huge repo, but I just want these three directories and stuff under them.
And you can mix that with a partial clone.
So you can like combine these only with a partial clone, but of just these three directories,
even though there's thousands.
Oh, right.
And well, and some companies do the whole like mega repo thing where everything's in one.
So.
And that's where it would matter.
Cause you're like, well, I don't want to check out seven terabytes.
I don't want whatever it turns out to be.
Yeah.
So anyway, there's like a couple of interesting things.
I present to you all the get sizer to give you a little bit of advice, but then also some
of these other tools to help you deal with it more.
You know, if you were already in this realm, partial clone, shallow clones, and sparse checkouts
all might be tools you can apply.
What are just built into get that make this a lot better.
Yeah.
And also LFS is not that hard to use.
So if you really have to use LFS.
Yeah.
I have one other thing for you.
I did this on the Talk Python Training.
I did a partial clone.
Well, filter blob equals none, blob colon none.
And without, so without, I had the deltas was 71,000 deltas and 118,000 objects with 10,000
objects, 1,400 deltas, much, much faster checkout.
And like I said, it's kind of on demand.
It'll go get the older files if it needs to.
Cool.
Yeah.
Anyway, it seems like it's a pretty handy.
Lots to get.
What are we getting to next?
Oh, we've oops.
Right now we've got bad advice.
So I guess this may be under category of do not try this at home or just don't listen
to Brian, but it wasn't me.
It was this other guy, Adrian.
So this is a fun article called data classes without type annotations.
So I'm, I'm using data classes a lot now.
I like them.
And adders too.
I like both adders and data classes, but anyway.
So apparently I didn't know this, but data classes don't really care what the type is.
So you can put a type, but it's not a, it doesn't use the type.
It doesn't use the type at all.
Apparently.
So you can, you can do something like dot, dot, dot, for instance, as the type.
And you can do some crazy things.
So that doesn't even make any sense, but apparently it works fine.
And I'm like, I don't believe it.
So I tried it and they're right.
Doesn't do, doesn't do that.
So I, there's a whole bunch of discussion around types here and type hints and, and some people just kind of are, they don't want to use types and that's fine.
But, but if you want to use type class or data classes, they kind of require you to use types, but apparently you can get around it.
And, and I just really wanted to show this horrible example of code.
And there's a, and there's a data class that is called literally, and it has a variable, anything with the type is a tuple with two strings in it saying can go in, in here.
And we've got other variables with like lambdas expressions as types.
And, and also I tried, I tried this.
You have to put from future import annotations in your, in your file, but then you can put all sorts of horrible things in there.
It doesn't even have these, these symbols don't even have to be anywhere in your file.
As long as it parses, it works fine.
For example, the first type is a, a tuple.
It's not saying the type is tuple.
It just is a tuple, like parenthesis string comma string.
Yeah.
The second one is a lambda where the type value would go and so on.
Yeah.
And it's not even a valid lambda.
Well, I guess it is.
You can have a lambda.
It's a parameterless lambda.
That only returns a string.
How about not, not as an expression for a type, not even evaluate, even dot evaluate was, is it, is apparently a valid type.
And then the last one is just awful.
Just dot has, as a, two equals B as the parameter to has multiplied by syntactically bracket valid.
These are, this is a nightmare, but it parses fine.
So.
Crazy.
Yeah.
Your editor might not like it.
mypy might not like it.
Yeah.
Wow.
But, but there, there, there is some discussion of things that might be useful about this.
Like if you're really not using data type annotations, but you want to use data classes, you perhaps want to put some strings in there as the type to declare as a comment for what the thing is instead of, you know, I don't know.
This is bad advice.
Don't follow this, but it's fun.
It does break some conceptions that people might have about data classes.
Unlike say Pydantic, where this stuff matters.
You're like data classes, but apparently validated.
Yeah.
And apparently this, so this was apparently popular or enough.
This was written last year.
And if you want to try to do something similar to data classes where, or similar to adders where you have like atrib or something, apparently there's this other, you can say a typeless, a typeless data class.
And you can just say it's a field and, and get around it.
And this is a, this is available in a IPI package.
Yeah.
Okay, cool.
Cool.
Typeless data classes.
Fun.
All right.
Well, is that all of our topics, Brian?
I think it is.
I don't have any extras either.
Do you have any extras for us?
I have two.
Let's see.
What have I got going on here?
So my notes in the show, show notes, my comment is the last pass story just keeps getting worse.
What I have on the screen here, what I link to does not fully communicate the degree to which it has gotten worse.
So keep that in mind.
With last pass, it turns out that someone, guess what, broke into the GitHub repository of a developer sometime last year, like November.
They then use that access to further their access and eventually got the ability to copy every single customer's user's last pass encrypted vault, which sounds terrifying.
It shouldn't be, but it does because that's theoretically encrypted with your big, long, not reused password.
That's a big if, but it should be right.
Then it probably should have some kind of secret key type of thing like one password.
So even if my password was the letter A for one password, it's still 27 characters from the person of this perspective.
Last pass doesn't have that.
It's just the letter A.
So that's not ideal.
There's some posts like, oh, well, don't worry.
It's going to take like a hundred years to decrypt this.
If, if, big if, that would be if they had the latest settings, which are like if I just created a new account and it used like a hundred thousand iterations of folding the password and other things about how long the password has to be.
But here's the getting worse part.
The older versions didn't enforce that and they didn't use password folding instead of using a hundred thousand or a million iterations.
They used one.
So instead of taking a hundred years or whatever it is to decrypt it with a regular sort of cracking GPU system, it takes about 25 seconds to crack the password.
And those passwords are versioned and changed in this way, depending on when you last use them over time.
So if you created a password 10 years ago, but then changed the settings, I don't think it goes back.
Not a hundred percent sure, but I think it's still, you can have historical older passwords in your vault that are like that.
On top of that, it turns out that things like the URL of where that password belongs to and your email address were stored in plain text.
Not true with Bitwarden, not true with one password, but with LastPass stored in plain text.
Well, it's not plain text.
It's base 64 encoded, but we all know what that means.
It's just not readable by humans, but that's plain text.
So, and when was it last accessed?
So you can do things like, I want to go to the vault and see who has accessed some shady site, like who has accessed Tinder, but also seems to be married.
Can I blackmail that person without even figuring out what their password is?
Just say, look, that's a little shady.
I'm going to tell your wife about your Tinder account.
You know, so, I mean, there's all sorts of really bad things.
Plus, I can see that some of those passwords are going to my bank with a password folding of one or 500 or 5,000, which I can just break straight away.
So you can use the unencrypted bits to target which ones you want to go after.
It's really bad.
So just PSA, if you use LastPass, change your passwords.
Yeah.
Period.
Because this is out there and it's in plain text, except for the password.
Not ideal.
Okay.
So anyway, I figured that was bad enough.
I wanted to kind of point out, I know because a lot of people are like, don't worry.
It's super encrypted.
Like, sometimes.
Yeah.
But who would actually do it for 25 seconds?
I know.
Come on.
I mean, if it just said, you know, like bank of America account dot com slash log on.
I don't know.
That were 25 seconds.
Probably.
Yeah.
I mean, banks are like kind of a unique case because they often have like a 2FA or, you know, what's your cat's favorite toy's name or whatever you got to answer.
But like there's many places that don't have like some kind of second check like that.
And my bank even has the feature of even if I tell them to remember my device, they won't.
So I have to 2FA every single time.
I know.
It drives me nuts.
All right.
The other thing is I woke up this morning with a couple thousand dollars.
And unfortunately, by the time of the recording, I no longer have that money.
But I have a new Mac Mini coming, Brian.
I want one of these.
They just announced a new Mac Mini M2 Pro and the new MacBook Air Pros and Maxes and all that.
So we've been waiting.
It says 600 bucks.
Where are you down 2,000?
Well, let us go.
Let us go on the path.
So 600 bucks is the M2 version, which is basically the upgrade of what I have now, which is awesome.
But what I want is the M2 Pro for all the video editing, which is like 1,300 to start.
But then you're like, you know, I really could use a little more RAM.
And now it's that.
Then with all the video and podcast stuff, I need some more storage.
And all of a sudden, it's like, oh, I'll just sell my car.
I'll get a Mini.
That'll be great.
But anyway, I'm very excited about this coming.
I'll let people know what I think when I get it.
But I'm sure it'll be lovely.
Hmm.
Cooper Mini or Mac Mini.
They're about the same price.
Exactly.
One's made in Cupertino by Apple.
The other one is Cooper made by BMW in London or England somewhere.
All right.
That's it for extras, though.
I got some jokes if you want to joke.
Yeah.
Let's do something funny.
Yeah.
All right.
So this one's about debugging.
And have you ever done like, I've got a section and I need a breakpoint here, but there's
not a great way to put the breakpoint there.
Or you might say, I would say, if, you know, user equals such and such, or this value is in
the range of what I expected, then I want it to break.
So you might say, if something created just a variable, set a value and give it a breakpoint.
Well, this is kind of about the philosophical wonderings of this situation here.
So there's a variable.
It just says var a equals zero JavaScript, I guess, or it could be C#, but it has
a little squiggly, which is clearly like unused variable, right?
Yes.
And the variable asks, dear programmer, what is my purpose?
And then the programmer says, you're a dummy variable to place a breakpoint on.
Oh my God.
Isn't that crazy?
That's pretty funny.
Yeah.
The existential despair of the dummy variable.
But it's short-lived, but it can be quite helpful and loved.
So don't let it get you down dummy variable.
Yeah.
Or it could have been used once before and then somebody refactored the code and forgot
to delete the declaration.
Exactly.
Then you live a long time.
Yeah.
All right.
Well, that's it.
All right.
That was funny.
So thanks a lot.
And thanks for joining me again today.
And thanks, of course, to Microsoft Founders Hub to sponsor us.
You bet.
Thanks everyone for listening.