Python Bytes - #319 CSS-Style Queries for... JSON?

Episode Date: January 18, 2023

Topics 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)
Starting point is 00:00:00 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
Starting point is 00:00:34 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?
Starting point is 00:01:11 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,
Starting point is 00:01:32 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,
Starting point is 00:02:18 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
Starting point is 00:03:12 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
Starting point is 00:03:53 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.
Starting point is 00:04:39 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
Starting point is 00:05:27 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
Starting point is 00:05:49 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,
Starting point is 00:06:15 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
Starting point is 00:06:47 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.
Starting point is 00:07:17 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,
Starting point is 00:07:34 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,
Starting point is 00:07:53 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.
Starting point is 00:08:16 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.
Starting point is 00:08:35 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
Starting point is 00:08:58 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
Starting point is 00:09:35 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.
Starting point is 00:10:25 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.
Starting point is 00:11:05 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.
Starting point is 00:11:19 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
Starting point is 00:11:50 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
Starting point is 00:12:05 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
Starting point is 00:12:42 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.
Starting point is 00:12:56 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.
Starting point is 00:13:15 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.
Starting point is 00:13:34 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,
Starting point is 00:14:08 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,
Starting point is 00:14:25 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,
Starting point is 00:14:56 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.
Starting point is 00:15:12 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.
Starting point is 00:15:31 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,
Starting point is 00:15:56 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?
Starting point is 00:16:18 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
Starting point is 00:16:38 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
Starting point is 00:17:12 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,
Starting point is 00:17:44 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,
Starting point is 00:18:02 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,
Starting point is 00:18:31 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
Starting point is 00:18:48 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.
Starting point is 00:19:09 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
Starting point is 00:19:47 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.
Starting point is 00:20:02 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,
Starting point is 00:20:17 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.
Starting point is 00:20:33 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.
Starting point is 00:20:55 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,
Starting point is 00:21:14 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.
Starting point is 00:21:31 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,
Starting point is 00:21:46 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.
Starting point is 00:21:53 Cool. Yeah. Anyway, it seems like it's a pretty handy. Lots to get. What are we getting to next? Oh, we've oops.
Starting point is 00:22:00 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,
Starting point is 00:22:27 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
Starting point is 00:23:03 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
Starting point is 00:23:29 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.
Starting point is 00:24:01 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.
Starting point is 00:24:17 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.
Starting point is 00:24:48 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.
Starting point is 00:25:22 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,
Starting point is 00:25:45 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.
Starting point is 00:26:02 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,
Starting point is 00:26:47 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
Starting point is 00:27:26 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
Starting point is 00:27:43 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
Starting point is 00:28:35 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,
Starting point is 00:29:06 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,
Starting point is 00:29:16 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
Starting point is 00:29:45 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.
Starting point is 00:30:22 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
Starting point is 00:30:59 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.
Starting point is 00:31:47 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,
Starting point is 00:32:02 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.
Starting point is 00:32:34 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.

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