Python Bytes - #319 CSS-Style Queries for... JSON?
Episode Date: January 18, 2023Topics covered in this episode: Secure maintainer workflow Tools for parsing HTML and JSON git-sizer Dataclasses without type annotations Extras Joke See the full show notes for this episode on ...the website at pythonbytes.fm/319
Transcript
Discussion (0)
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 Ocken.
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 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 get into like PyTest check?
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 like just start going out.
And that's the next thing is like once that goes out, that goes to everybody's servers, many of them anyway.
Right.
And then you potentially have a bad code running on people's servers. So like 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? And on, you know, like it goes, 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 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 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, what is that potentially going to do?
He can't go code review every huge PR that is sent to him when it refers to someone else's repo.
So there's things you can do, but that's that's that's his primary concern is how do you
deal with people sending him bad code so first thing is uh one password one password is awesome
also not last pass don't use last pass more on that at the end but oh my god don't use last pass
one password or bit warden are really good choices and um 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 environment,
the environment just for a moment.
So load the GitHub credential into the environment,
do a get 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 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,
get 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
on his blog here it says you could piggyback on the one password workflow to export extra ssh
config and um go down here dirkshon 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 enter your one password type thing, which is cool.
And he also suggests using Podman, which has higher security than Docker.
Again, 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 FileVault equivalent for Windows.
That's right. Thanks, Christopher.
So one of the things that, I mean, okay, so yes,
protecting against 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's going to try to access it,
is that I can't anymore.
Like my laptop just dies and I can't use it anymore.
So things like 1Password,
I assume they're backupable
so that I can get access to it again.
Yeah, yeah.
So 1Password stores all that information on their servers
where you control a super long encryption key that they don't have.
So there's no, if you lose it, there's no, I'll get my thing back.
Part of the setup process for 1Password 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 pretty good.
It's pretty good.
It's not LastPass again, which we'll touch on.
So that syncs to your phone.
It syncs to your different computers.
There's a web version.
It works on Windows, Mac, and Linux.
It's a pretty good option, honestly.
It's paid, but it's not much, like $5 a month.
Okay.
You don't want that in Bitwarden,
but Bitwarden's 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 um
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 go to a new computer you can just you 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. But never, never lose that, uh, that, that 30 character secret key
because you're not getting back in without them. All right. Over to you. What you got?
Uh, what do I have? I've got, um, some web scraping. So, or a tool, actually a couple 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 job doing a whole bunch of blog posts about web scraping but one of the the things when
he talks about doing it in python um 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 jmes path and so i wanted to check that out um 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 um using xpath and
css so the css part is the part that i'm excited about but um so the idea is like here's a 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. are what they call like special classes in css okay yeah the text the text is up but you can do
things like h1 colon hover and that like only triggers when it hovers but yeah colon colon
text you're right that okay i get it that is weird but anyway uh kind of interesting i like the um
and then i'm used to the like the uh greater than i think that's like some child of or something. Immediate child.
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 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 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.bar
and it'll return baz
so those are
pretty cool
just simple little tools about
getting JSON data
that's interesting because I never really thought of
parsing JSONson with a
you know 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 i
you're right i've never really thought about about too much about doing searches or something.
I just like load it up and just navigate it.
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 might be loaded
anywhere on the page.
Yeah, exactly.
Yeah, it's kind of like a CSS selector for JSON, which loaded anywhere on the page. Yeah, exactly.
Yeah, it's kind of like a CSS selector for JSON,
which that is a cool discovery.
Yeah, so anyway, that's it.
A couple of short items, but... Nice.
Out there, Will McGugan 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, I don't know.
I'll 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 bootcamp.
I'm 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 a reality today
with critical support you'll get
from Microsoft for Startups Founders Hub.
To join the program,
please visit pythonbytes.fm slash 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.
I don't either, but I'm pretty sure that TalkPython 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,
and it's pretty big.
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 one, version two, version one final,
version one final, final.
I zip those.
I don't just have those 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 Viek,
and we uncovered a bunch of cool tools.
One of them is the Skitsizer,
because monorepos are like,
I don't just have a repository for this project,
I have a repository for the company,
and all 100 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 5 gigs.
Git doesn't behave well sort of thing.
So you can do things like avoiding compiled output.
So if you have jar files or wheels, I guess, in our case,
we have less compiled output.
But if you have, say, wheels and 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 can 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 say it does a lot of its work by doing delta's like okay here's the main one and then here's just
the difference of these versions i need to keep like there's 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 it's always a copy. So you can go through here
and you download it to get started. It says, if you run it, it'll tell you things like,
go through the blog, basically analyzing the system. It says overall repository size. Here's
how many commits there are, how big the commit 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 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 i have some interesting
interesting newer version of 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 level,
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,
potentially even check out back to one of those,
you'd have to 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 depth one.
Sorry, not shallow, partial clone.
All it will check out is level one of files,
but all of the commit history and messages.
So 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 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 dash dash 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 its whole 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, yeah, yeah.
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 combine these only with a partial clone, but of just these three directories, even though there's thousands.
Oh, right.
And some companies do the whole mega repo thing where everything's in one.
And that's where it would matter because you're like, well, I don't want to check out seven terabytes.
I don't know whatever it turns out to be.
So anyway, there's a couple of interesting things. I present to you all the Git Sizer
to give you a little bit of advice,
but then also some of these other tools
to help you deal with it more.
If you're already in this realm,
partial clone, shallow clones, and sparse checkouts
all might be tools you can apply
that are just built into Git that make this a lot better.
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 TalkPython training.
I did a partial clone.
Well, filter blob equals none,
blob colon none,
and without.
So without I had the deltas
with 71,000 deltas
and 118,000 objects
with 10,000 objects, 1,400 deltas was 71,000 deltas and 118,000 objects with 10,000 objects,
1,400 deltas,
much,
much faster,
uh,
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,
um,
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 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.
You can put a type, but it doesn't use the type?
It doesn't use the type at all, apparently.
So you can do something like dot, dot, dot, for instance, as the type.
And you can do some crazy things. So that instance as the type um and um 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 um uh so uh i there's a whole
bunch of uh discussion around types here and type hints and some people just kind of are they don't
want to use types and that's fine.
But if I wanted to use type class or data classes,
they kind of require you to use types,
but apparently you can get around it.
And I just really wanted to show
this horrible example of code.
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 in also i tried i tried this you have to put from future import annotations in your file,
but then you can put all sorts of horrible things in there.
It doesn't even have,
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 tuple.
It's not saying the type is tuple.
It just is a tuple, like parentheses, 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 as an expression for a type?
Not even evaluate.
Even.evaluate is apparently a valid type.
And then the last one is just awful.
Just.has, 2 equals b as the parameter to has,
multiplied by syntactically bracket valid.
This is a nightmare, but it parses fine. Um, so crazy.
Yeah. Your editor might not like it. My pie might not like it. Yeah. Um, but, uh, but there, there,
there is some discussion of, uh, things that might be useful about this. Like if you're really not
using data, uh, type annotations, um, 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.
Which are 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,
or similar to adders, where you have like atrib or something,
apparently there's this other, you can say a typeless data class, and you can just say it's similar to adders where you have like atrib or something. Apparently there's this other,
you can say a typeless data class
and you can just say it's a field
and get around it.
And this is available in a PyPI package.
Yeah.
Okay, cool.
Typeless data class is 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 LastPass story just keeps getting worse. What I have on the
screen here, what I linked to does not fully communicate the degree to which it has gotten worse so uh
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 used that access to further
their access and eventually got the ability to copy every single customer's's LastPass encrypted vault, which sounds terrifying. 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? And then it probably should have some kind of secret key type
of thing like 1Password. So even if my password was the letter A for one password, it's still 27 characters from the person of this perspective. LastPass 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. which are like if I just created a new account and it used like 100,000 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 100,000 or a million iterations,
they used one.
So instead of taking 100 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 100%
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 1Password, but with LastPass stored in plain text. Well, it's not
plain text. It's base64 encoded, but we all know what that means.
Just not readable by humans, but that's plaintext. 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, 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, 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, right? You got to answer. But like there's many places that don't have like some
kind of second check like that. And MyHandBank even has the feature of even if I tell them to
remember my device, they won't. So I have the 2FA every single time. I know. It drives me nuts.
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 people have been waiting.
It says $600.
Where are you down $2, you down 2000 well let us go let us go on on the the pass so 600 bucks is the m2 version which is basically
the 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 1300 to start but then you're like you know i really could use a little more um a little more
ram and now it's that then 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 cool but anyway i'm
very excited about this coming out i'll let people know what i think when i get it but i'm sure it'll
be lovely cooper mini or mac mini they're about the same price. Exactly. One's made in Cupertino by Apple. The
other one is a 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
break point here, but there's not a great way to put the breakpoint there?
Or you might say, I would say, if 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 sharp, 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 purpose. And then the programmer says, you're a dummy variable to place a breakpoint on. Oh my
God. That's pretty funny. Yeah. The existential despair of the dummy variable, but it short-lived,
but it can be quite helpful and loved. So don't let it, 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. Alright, well that's it.
Alright, 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. Bye.