Python decorators are higher-order functions that take a function and return a new function with modified behavior, providing syntactic sugar for function transformation. Currying is a functional programming technique where a function that takes multiple arguments is transformed into a sequence of functions, each taking a single argument. While decorators and currying are powerful tools for creating flexible and reusable code, they can make code more complex and harder to read if overused. The speaker demonstrates practical applications of decorators for tasks like counting function calls, transforming arguments, and implementing caching strategies, while also discussing the trade-offs between using these techniques and writing more straightforward code.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Code + Coffee + Chat: Becoming an ArchmageAdded:
I guess I should also drink the coffee as ordered.
All right, I think everything's up now.
We'll see how this goes. If I drop connection a bunch of times, I apologize.
It is the um it is the hand I've been drawn. Uh dealt hand I've been dealt.
Okay. Uh let's go ahead and just close these guys. We don't need them anymore.
And away we go. Hello filthy potato. Good morning. Good morning. Yeah, I haven't been around much excitium, but I'm here.
I'm here today.
Good morning, average person. Good morning, Blackfire. Yes, happy Saturday.
No work.
No work.
That's a good thing.
All right, I'm gonna keep working on boot.dev. Yeah, no work must code. Yeah, I've actually been playing boot.dev dev probably more than is healthy over the last three days.
Uh let's see. Um I'm learning functional programming in Python is what I'm currently doing.
Uh what thought I already did this one.
I guess not. Okay.
Has anyone ever told you you look like Figma? I've never heard that. I've heard I look like coding with Lewis.
Let's look up Figma CEO.
Big Figma CEO. That's a new one. Dylan Field. Huh. Let me see.
I guess I could I guess I could see that.
I think our jawline's a little bit different and our cheekbones, but I could I could see how you get there. Yeah, I've heard coding with Lewis quite a bit, though.
You're learning assembly. Why are you learning assembly?
Just for the heck of it.
He does have some jawbreakers in those cheeks. Yeah.
What do you think is the best type of humor? Um, the shows that I find the funniest are like The Office and Parks and Recreation. So, I guess that kind of hopefully that gives you a sense of my humor. Like I really like the movie Step Brothers Bridesmaid is really funny. The Hangover.
Um, yeah. I don't know. I can appreciate most kinds of comedy, I think, but dead pan humor is pretty funny.
For fun. I always do this. So, you're learning assembly for fun. Okay, that should get you a job in and of itself.
Arch Made, Steve. I haven't reached arch mage yet, but I'm going to get my coin.
I am going. I think I now I'm at disciple is my level.
Uh, let's see. Level 43. I'm pretty sure that's a disciple.
Yeah, disciple.
So, I'm making progress slowly but surely.
I'm having to write a lot of Python, which hasn't been super fun, but I'm I'm tolerating it. You know, I have not read clean architecture. Um, I have implemented clean architecture, but I've never read the book.
The clean architecture template that I really like is from Steve Ard Dallas.
Steve Rardal or I guess his last his real name Steve Smith, but he goes by our Dallas. but he has a really nice clean architecture template that I've used two or three times in the past for projects and I've always enjoyed it. Um, even when I do like vertical slice architecture, I still kind of like to set it up a little bit with a clean architecture approach.
I I just like the separate projects. I kind of like the the the separation of code into these separate projects and sort of makes you kind of forces you to think about where to put things. Um, but some people believe it's overkill, which is totally fine.
You are still a member Born to Shine.
So, thank you for being a member, man. I appreciate it.
Just read it. Feel like I've been scammed. Lol. He never actually goes through the implementation. Ah, fair enough. Yeah. See, I've never I've never read the book. Um, my only exposure to it has been through actual code um or like um YouTube videos like presentations at conference conferences that sort of thing. That's and then using using it in code. I mean books are great. I I books haven't been a big part of my coding journey. that just hasn't been a a I think I bought two I've bought two coding books and I've probably read four coding books and most of them were free coding books. Um but yeah, it hasn't been hasn't been a big part of my learning experience, but I know some people really like books for learning. So, well, all the more power to you.
All right. What are we trying to accomplish here?
Your assignment. Define the width length function inside the width car function.
It should accept a dock. It should split the dock into lines. Use a loop. If you're feeling fancy, important. Use reduce to count the number of lines that have the given sequence in them. Return the count from the width length function. Return the width length function from the width character function. Okay. So, we're doing a little bit of little bit of curring. All right.
So, um we're returning with care here already.
So, I just need to fill in this middle section.
So, define the width length function.
And it should accept the doc, split the dock with the lines, use a loop, the given sequence.
So I guess this uh width length takes a doc, which is a string.
Uh lines equals doc.split. split.
Then I guess we need to make sure we return with length here.
And then we're going to check to see if uh sequence if sequence is in length sorry in lines.
And then we're going to do something Use a loop to count the number of lines that have the given sequence in them.
Return the count from okay.
So I guess we do for line in lines like that.
The lack of curly braces and semicolons has been a real problem.
Um, I wish there was a way I could pop the lesson out into a separate window.
So we just increase count equals zero and we'll do count + one and return the count expected three actual fix.
What am I doing wrong?
Hey, what's up? So, long time no OC.
I really like decorator annotations in Python. Way cleaner than C. Uh, I have not used decorators much in Python. Uh, but the equivalent in C# would be attributes. Attributes could be pretty helpful.
The lack the lack of curly braces is making my eyes hurt. Yeah, it's it's definitely an adjustment. Yeah, writing Python is an adjustment every time.
If it wasn't for the fact that boot.dev only teaches Python, I wouldn't be here. I I shouldn't say they only teach Python, but Python is a part of whichever track you choose on their website, so you have to do it. Um, and then they either they can they can teach you Python and Go or they teach you Python and TypeScript.
Okay, so this should be up here. Is that what they're expecting?
Let's see.
We should be able to say nonlocal count.
Okay, I've obviously misread the instructions somewhere.
It's nice to have Vim mode, too.
Hey Justin, what's up man? Good morning.
Can you implement new attributes in C#?
I don't think so, right? Oh, no you can.
Yeah, you can implement all kinds of custom attributes. Um, you can do all kinds of different functionality. You can use them as you can use them to do all kinds of crazy stuff. They're particularly helpful too with the source generator API inn net. So if you want to get into source generators, uh you can use attributes as a way to mark pieces of code and then when you do when you actually build or compile and do the source generation, you can use those attributes to locate pieces of code that you want to use in your source generation code. Yeah, you can do all kinds of crazy stuff with attributes in C. They're basically the equivalent of decorators in Python.
Okay. So, I think I'm I think I have the code right, but I think my logic must be off. Yeah, this should be in line.
There we go.
All right, we failed one time. Let's see the very last one here. Input doc is a a bb.
Input character is a blank space.
Um, interesting.
So, does that not Huh? Uh let's see print empty in what is that print?
It is true.
So I don't know why that's not working.
expected to actual zero.
So the is it's expecting this line and this line.
But I don't know why.
Oops. I think I opened that twice.
Empty strings are always considered to be a substring of any other string. So, okay, that's not what I'm looking for.
Um in keyword Python wide space doesn't make any sense to me.
If sequence in line um let's see let's look at the test cases.
Where are we? We're down here somewhere.
This one.
Hey, study for Earth. What's up? I started coding lectures last week. Can't even set up my VS Code. I'm going to kill myself. Don't Well, one, don't do that. Second off, um, setting up your development environment is just that's that's a part of the gig, you know.
It gets more fun though, like after the first time you set it up and after you start using it for a while and you do it a few more times, like it's actually turns into something you enjoy doing.
Two man army, you are always online. I respect it. I'm not always online. So, I took it like two months off. I haven't been I haven't This is only the second time I've streamed in like the last 60 days, probably. So, um I must just always show up when you're online.
I don't know, man. You should uh do whatever you want to do.
Do whatever you want to do. All right.
Uh I'm going to use some salmon and ass boots. Yo, bro, what the [ __ ] Oh, string.split with no arguments splits on any white space. Spaces tab new lines also discards empty strings. What argument should you pass to split so it splits only on new lines? Ah, [ __ ] I'm an idiot.
Hey, there we go. Man, that took a lot longer.
Also, I'm going to activate a potion.
Potion gives you more XP for like 60 minutes, I think.
There we go.
Hello, A17. Good to see you. Hope you're doing well.
How come you're learning Python, by the way? Um, well, I don't really want to write Python, but I do want to do boot.dev. And boot.dev only teaches they teach Python and TypeScript or Python and Go. So, whichever like path you want to go down, boot.dev, you have to go through Python. Um, I've written a lot of Python in the past, but I avoid it at all costs because I just don't enjoy using it.
Um, but in order to become an arch mage, I will happily I will happily put up with it, you know.
Plus, it's I mean, it's one of those things with the rise of AI, you know, and the importance of machine learning nowadays.
Uh, it's probably not a negative to at least have familiarity, more familiarity and comfort with Python. So, I'm forcing myself to do it.
Block, good to see you as well. Hope you're doing good.
Let's see. I know, but man, for first time, it's so much frustrating. I Hey, I I've been there. I'm right there with you, man. It is frustrating, but you'll figure it out. Um, you'll figure it out.
And then once you figure out how to set up your environment the way you like for your development workflow, then you can make it make it your own, right? And then it becomes much less of a thing when you ever you have to set it up again.
Um, but yeah, it's a it's a thing.
Okay. Complete the create markdown image function using curring. It takes a string. Input input alt text. Enclose the alt text in square brackets prefixed with an exclamation point.
Define an inner function that also take Okay, let's do this one step at a time.
and close the all text in square brackets prefix with an exclamation point.
All right. So say um enclosed for access to modified alt text.
Oops.
alt text our little brackets there.
Hey, greetings I think is how you say your username.
Greetings. Hope you're doing well.
Yeah, it's good to see you too, Block.
Good to see you, too. Yeah, I haven't been streaming much, but I'm I'm here this morning.
Oh, well, that's that's very kind of you to say.
That's very kind of you to say. I don't know if my streams are any good, but they are my streams.
All right. So, do an exclamation point.
Okay. So, now we need to define an inner function that also takes a string input URL. Um, the inner function should escape any parentheses in the URL by replacing them with encoded sequences.
Do the same to change any enclosing parenthesis. Okay.
enclosed URL with parenthesis.
Add the enclosed URL to the end of the enclosed alt text.
Um, so we basically have three we basically have three functions here. So let's define them. Let's do uh defaf uh create link And then let's just pass it.
And then uh death. What was the what was the thing that's the third one supposed to do? Uh it should take an optional string input for the title. So we'll say create title. And I guess this should be title something like that. pass.
And so this gu is going to return something, but this gu is going to return create link.
And then this gu is going to return create title.
I'm kind of annoyed that that I I'm having to practice so much curring because in all the time I've spent coding, I don't think I've ever actually used curring as a technique.
So, the fact that I'm I've done more than one or two lessons on it's kind of silly because it's just it's just to me it's a dumb way to write code. But, I mean, I'm sure there's very specific use cases where curring comes into comes in comes in handy, but I have not encountered them.
All right. So, the innermost function should take an optional string input for the title. So, it should be >> just become best friends.
>> Hey, thanks for the follow, man. I appreciate that. Mr. Dukeberry, nice.
Nice username, bro.
Hey, what's up, Fay 911s? Good to see you.
Jakis Jordan, good to see you as well.
Jais, hope you're doing well. It has been a minute. Good morning, Mark.
Two man army. I got a technical interview. Help me cheat. N you don't want to cheat. If you cheat, you're only cheating yourself. You know what? Have I done wrong here? Default value type is not assign.
Now you're happy.
Yeah. I mean, if you cheat, you're just cheating yourself, you know? You'll be fine. you just be fine. Inter interviews are not about trying to be anything more than than you are, right? So, show up in the interview, answer the questions honestly.
It treat it just like if you okay, imagine imagine you already have the job and you're going into the conference room with your co-workers and they pres are going to present you with a problem.
just approach the solution, approach your problem solving the same way as if you were discussing a problem or solving a problem with colleagues. Um because that's the whole point is like they want to see how you work. They want to see how you solve a problem. They want to see what you're capable of. Uh and if you if you don't have the right technical acumen for the gig that you're interviewing for, so what? You apply for other gigs. You know what I mean? So, I think people I think people carry way too much pressure into interviews because I think they desperately want to I mean, obviously they want the job because they're interviewing for it, but they also desperately want to like pass the test instead of just showing what you know and who you are and finding the right group of people who that connects with, resonates with, and is the right fit for. Um, at the end of the day, getting a job is just a numbers game. So, it's all about putting yourself in front in front of enough people that eventually you find the right one. It's just like kind of like dating in that sense. So, I I would not I would not go into a technical interview. I would not try to cheat and I would not try to fake it till you make it.
Hey, what's up, Duck Boy? Good to see you, Mark. Man, when you learn about OP, which of the pillars are are you commonly used and why? Uh, I think the one part of object-oriented programming that I tend to avoid myself is inheritance or a lot of inheritance.
Maybe like one or two levels of inheritance is fine, but beyond that, I think it get it gets a little crazy. Uh but I definitely whenever writing object-oriented code I definitely use abstraction, encapsulation.
Um what's the third one? There's a third word there. But I definitely I definitely use those.
Be yourself. It's not bad to not know.
Exactly. It's not bad to not know everything. And a lot of times, you know, problem solving is about not knowing.
And so problem solving is about how do you figure out how to know, right? How do you come up with the solution? Um if if you already know the answer, right? If you're solving problems that you already know the answers to, nine times out of 10, those problems actually aren't super useful or valuable for the person you're solving them. Then for like they're already solved problems, right? There's already a product.
There's already a solution. So a lot of times, you know, real science or real engineering is about being able to be given a lot of ambiguity, a lot of uncertainty and figure out how do you systematically approach iteratively solving the problem and making more things known and then ultimately coming up with a a true solution. So, I I think if I think if you go into a technical interview and you think the whole goal of it is to just already know the solution, like that's you kind I think you've lost the plot. Like you're not supposed to know the solution. You're supposed to be able to like systematically break problems down and systematically generate hypothesis, run tests to rule things in or out and and make progress towards an ultimate solution. And I think that's what that's what a lot of I mean I'm not going to say all interviews are like that because some people are just dicks and they want to prove that you're not as smart as them. But if they if it's a good group of people you're interviewing with they should understand that as well. Um so it's much more about trying to figure out how you solve problems and how you approach things than it is pass or fail in my opinion.
I used to overall myself which would make me start lying about myself once I started being myself. But yeah, exactly.
Yeah, I completely agree with that. I think it's it's you it feels bad to say I I don't know the first few times you do it, right?
Because you kind of feel like you you kind of feel like you're you just feel like you're not enough, right? That's how that's kind of how it makes you feel. makes you feel inadequate. But um you know I always think about Einstein is like Einstein always he his famous quote is something like it's not that I'm so smart it's just that I stick with problems longer than anyone else. And I feel like a lot of the best scientific people I've been around or engineering people I've been around are of that kind of mindset. like they just they they just very dogged in their pursuit and they have a very systematic way of going about figuring things out.
But I would not cheat. Would not cheat.
That seems like a definite way not to get the job.
All right. If title Let's see if title is passed.
Okay. So if we don't get a title, let's say title is none.
Then we'll just return.
Uh otherwise we'll say uh return.
What does it want us to do? It wants us to enclose it in double quotes.
Add the quoted title to the image syntax by first removing the closing PNS parenthesis from the end of the image syntax. Add a space and the quoted title with a closing parenthesis.
Oh, okay. Because because the other function Okay, so we need to do Okay, let's see. First thing is we'll say quoted like this.
We'll say give me that around the title.
And then this is our I guess this is ultimately going to be our image, right? So let's do let's actually call this um I don't know image link because that's ultimately what we're building. image link.
And so we need to strip this. We need to say image link dot.
Is there a way to get that in Python? Let's see.
remove the closing prints from the end of the image syntax.
So I guess we can just assume that the last character is always that. Um so let's just make that let's just I don't know if that's actually probably the best way to do this, but we'll just say image link we'll take from the end up to the last one.
Why can't I do that?
Oh, this is non-local. Uh non local midlink like this.
Or should it be the URL?
Um, great. And then We add let's see image link equals this space and then the quoted return the finished image syntax. Add a space and the quot with the closing parenthesis to the end of the should be this.
I think that's what they want there.
Yeah, we're doing Python. Digi our passion. Talk to talk to Lane Wagner over at boot.dev. See if he can switch to teaching instead of Python. See if he'll lead with C or something.
C Let's see. Actually, attributes in C are passive metadata. Uh is not equivalent to Python decorators which are executable. Huh. I I don't know about that. I kind of feel like they're similar. You can do you can use attributes to do logical things in your code as your code is executed. It's they're not they're not just passive like you can use them for data validation.
You can use them for all kinds of things. Model binding.
Yeah, you I mean I'm not sure I'm not I I wouldn't say they're passive metadata.
They can definitely be used as passive metadata, but I wouldn't say they're passive metadata.
I know it's been a long time. What happened to the text editor you're making last month? I think Oh, yeah. Uh, I haven't really >> Hassan, thanks for subbing. I really haven't actually um worked on it much.
Uh, you're talking about Zo AE. Oh, I guess I have to go to the terminal.
Yeah, I haven't I haven't done with it done much with it. Most of the coding I've been doing lately has been all kind of workrelated stuff. So, I haven't really worked on much personal projects, but it's it's still there. It's still usable. Um I just haven't just haven't done much with it.
Probably ask the interview why they're hiring. Try to solve their problem based on what you heard. Works on me. Yeah, that makes sense. I think that's completely valid. Morning, Ryan. Good to see you.
Nice haircut. Saturdays are for haircuts.
Yeah. Deaf, don't cheat if you want to get a job. Super true.
All right, let's see if we can figure out this. I've been on this lesson for like 20 minutes.
Okay. Create title. Um, so we did this, we did that, we did that, we did this.
Uh, oh, actually, hold on. This is actually not right. So we basically want to say if that is none then do all this but regardless we always want to return the image link.
Um okay then on the inner function should first escape any parentheses in the URL by replacing them with encoded sequences. So let's do uh escaped escape escape equals URL replace those with something and we also want to replace um this something.
We need percent 28 and percent 29.
Okay.
That that close URL with parenthesis. Add the enclosed URL to the end of the enclosed alt text.
So then we'll say this is such a it's just honestly this is just such a confusing way to write code. Uh so now we're going to do um image link adds a formatted string which is going to be our escaped We have to declare non local.
Okay. And I think that does it. Famous last words.
Return the innermost function.
Okay, let's give it a go.
I think they all passed. Nice. Nice.
Look at us.
Yeah. I think it honestly if I think if I if I was intro if I was introduced to a codebase and there was curring everywhere in that codebase, I would just shake my head and walk away.
I just I don't see the value in writing code this way.
All right, check the example below to see how the function is intended to be called. Define an inner function that takes two optional integers, inputs, min width, min height, both with default zero.
Okay, let's work through this systematically.
Something is screwing with my internet.
I think it may be the storm. I can't get more than half a second of the stream to load at a time and it buffers for 20 seconds after playing that half second.
Huh. Could it be me?
It looks okay on my end, but obviously I have is I have issues with my internet.
I disconnect occasionally while I'm streaming. So, it could be me, man. I don't know.
If it is me, I apologize. And if there was something I could do to make it better for you, I would most definitely do it.
Why isn't your chat GPT tab open?
Yeah, that's how everybody codes nowadays.
Coding without AI is like it's it's it's heresy. And I've been so I I honestly just been so blown away by how quickly that happened. Like everyone nowadays is like which is weird. It's it's actually weird to me because um like my in my day-to-day job and stuff like that's AI coding is not a thing, you know, uh in terms of like the people I work with and whatnot, but I but I get the sense from all the media that's pushed at me and all the media I consume that a lot of developers are very much wholesale like into AI coding. uh whether it be their choice or whether they're forced into it.
But I'm not I'm not a bit I don't enjoy it too much. So I don't I don't really I don't really do it much.
Let's do death in enter.
Does that take any arguments? Let's see.
In most that takes two integer inputs, width and height in the innermost function.
Okay.
Uh, I guess we'll just do width height. This not type height. And then we say if what? God, I really wish I could open this lesson.
Um, actually, hold on. Let me duplicate.
Can I do that?
Yeah, might be easier this way.
There we go.
That way I don't have to keep switching back and forth between the the code and the assignment.
Uh let's see. Uh if min with if men with oh actually this doesn't this does not take any arguments. If men width is more than max width or men height height.
Oh, okay.
I [ __ ] up.
Max height zero. These do not need to be default.
Okay. So if max height is great or min width is greater than max height or min height is greater than max height, we have a problem.
uh raise exception minimum size cannot exceed maximum size.
Cool.
Then we define another inner roast that takes two integer inputs with height.
Use the built-in minm max function to reduce width if it's above max height or to increase it increase it if it's below min width.
Okay. So you want new width equals something. You want new height equals something. And then you want to return the new width and the new height.
And then we need to return from here in.
And then up here we need to return innermost. Like look how confusing that is. Why would anyone write this code?
This is like cursed code in my opinion.
Do you need a diploma to get a quality coding job? I don't think so. I think I think college degrees while they're still valuable, I think they're less and less. though I I I feel like there's enough millennials now and maybe like late in or early in life Gen Xers that are in positions of like hiring and decision- making that don't necessarily put as much value on diplomas and degrees as prior generations. I mean, obviously, it's it just it makes it easier if you have a degree and have a diploma, especially if the job says it requires one. Um, but I I mean, there's just so many self-taught programmers, right, and coders that it's it's hard to say you need one, right? Because there's just so many people that don't have one.
That would it would kind of be like you're just out objectively lying if somebody said that.
This is why learning to code with Python has stifled me. Well, it's not necessarily This isn't necessarily a Python thing. This is just like currying. This is the that this this um technique that they're teaching is just kind of a curse technique in my opinion.
Um I don't know why I again I don't know why necessarily. I haven't ever come across a good scenario where using this technique in coding makes the code more usable or more understandable or more readable. But I'm sure there's some example or case out there that I'm not aware of.
Okay, I don't really know what this is asking me to do. Use the built-in min and max function to reduce width if it's above max height, above max width, or to increase it if it's below Yeah, I don't know. I don't really understand what that's asking me to do.
Um, can you help me understand this instruction?
I'm confused by it.
either I'm not very smart or it's that is written in a little bit of a let's see the line is describing clamping a value so it stays within a range Um, think of width like this. If it's too big, bring it down to max width. If it's too small, raise it to minid. Otherwise, leave it alone.
Okay.
Oh, so it just wants me to do this right here.
You just gave me the answer.
I think it just gave me the answer.
Probably not good that it did that, but so it wants me to clamp it essentially, but this one needs to be height then height.
Okay, one failed.
Uh, who failed here?
Image size.
Oh, cop. That's what copy and paste will get you.
Nice. Thank you, Boot or Boots, I think, is his name. Boots.
Yeah.
B was the hero on that one.
Okay, decorators. Here we go. Now we're finally we're finally overcurring. God damn.
All right. Remember function transformations where a higher order function takes a function and returns a function with new behavior. Python decorators offer a kind of syntactic sugar around that. Oh, wonderful.
Um the val counter line is decorating the process stock function with the val counter function. Val counter is called once when process stock is defined with the at syntax. But the wrapper function that it returns is called every time.
Process stock is called. That's why val count is preserved and printed after each time.
All right. So we have process doc decorated with vow counter. Val counter refers to this function up above and then it does stuff.
The provided file type aggregator function is intended to decorate other functions. It assumes that the function it decorates has exactly two positional arguments. Create a process doc function that's decorated by file type aggregator. It should return the following string where doc and file type are its positional arguments.
All right, let's look at the code.
Don't touch above this line.
Okay, create a process doc function that is decorated by file type. It should return the following string.
Okay. So, all you want me to do is this.
Define process doc.
And I guess we want doc, which is going to be a string. And we want file type, which I assume is going to be a string as well.
And it's going to return this guy. Let's copy and paste it.
Okay. And then you want me to decorate it with file type aggregator.
Easy enough.
Kale. Most of the degree is spent not coding anyway. Sometimes in writing reports, so could say counterintuitive.
Oh, that's an interesting way to think about it. I I mean, I think most college degrees are a lot of indirect education for the work you're going to end up going to do. Uh, which is unfortunate because I feel like there's a better model. I think there's a better, more efficient education model out there.
Like when I look at the I've always thought like nurses have it right. The way nursing degrees work, it's I feel like so much of a nursing degree is they do have like some general prerequisites that they have to take obviously, but I feel like so much of like the last two to three to the the last two years, so year three and four of a four-year nursing degree program, I feel is like largely oriented to you doing the work that you're actually going to do on the job.
um and and actually working in settings that you will eventually work in when you're employed. I've always felt like that's there's some way to bring that into other degree programs, you know, like for example, I did a biochemistry degree and I liked my degree program. I liked my professors. I liked my adviserss, but I always thought like there wasn't enough actual time on the bench being a chemist. So like obviously you have classes that have lab work, but I always thought, well, if I went and worked for an actual company employed as like a bench chemist or a bench biochemist, I feel like I wouldn't be as prepared as I would want to be. Um, and maybe maybe part of that is like there needs to be more collaboration between like the educational programs like the colleges and universities and industry, right? So, it's like some sort of hybrid model between like university and an apprenticeship I feel like would be much more useful, more practical, more valuable.
I know that's what internship like that's what internships are supposed to kind of facilitate, but obvious but honestly like why are we why are internships a separate thing from the degree program? Like they should that should be like embedded. Um that's my kind of thought on it. I don't think that's probably ever going to be a thing.
Seems like the univer at least here in the United States, the university and college and the overall education system is very slow to change.
But yeah, time could be better spent.
Yeah. Yeah. Engineering trade school vibes. I I just think it there needs to be more like it shouldn't be like college or trade school. Those two things need to come together and there needs to be more theory with more practicum and probably better if the practical side of it happens in an actual industry setting, right? So like maybe your first one to two years of college are very heavy on the theory and then your year year three and four like you spend half your time still pursuing theoretical concepts but the other half of the time you're actually working for somebody uh in whatever field or position of choice you know I think I feel I just I think that would be much more bang for your buck Tobias Uh the guy who um the guy who runs Shopify uh Tobias I think I'm saying that right. Tobias Lupke.
He talked about this in several interviews that I I listened to like the way he learned to code was he he apprenticed for a German company. Where is it? Uh there we go. Right here. He talks about this how like he kind of left school I think at like 15 or 16 or so. He was like high school age and he actually got it he was actually working or Yeah, there you go.
10th grade. So after 10th grade he was actually working as a computer programmer for a company. So I feel like that type of a model would just serve us all better if that's the way it worked.
Um obviously now with AI taking everyone's jobs, who knows? But I always I always thought that would be pretty cool way to approach things.
What do I know? I'm just a dad in Kansas.
All right. What are we learning about here? Args and ks in Python. Args and ks. Yeah. Okay. This is like um this is like the rest in in other language. Uh see positional arguments are the ones you're already familiar with.
Keyword arguments are passed in by name.
Order does not matter. Any positional arguments must come before keyword arguments. This will not work.
So KRS collects keywords arguments into a dictionary. Args collects positional arguments into a tpple.
Print each positional argument sequentially using numbers and periods as a list markers starting with one dot.
For example, args logger prints the console. Okay. Sort the keyword arguments alphabetically by key with the sorted function. Then print the sorted keyword arguments using asterisk as the list markers and with a colon between the key and value.
All right, we can do this. We can do this.
So, we have our args. So, args logger, we need to print it like this. We need to say um I guess for i in range zero length of args.
And then we need to print um what would it be? the be I I + one period and then the arcs ar and then for the other ones we need to do we're key in orgs Print F star W.
Yeah, I think that looks right. Submit.
No.
Oh, they want a space here, don't they?
No, that's not it.
Oh, they want the value. Gosh dang it, Stephen.
So, they want she and then I don't know what I'm doing wrong.
So for key and k print the key and the value.
Oh, they need to be sorted. Okay.
Oopsies.
I should have read closer. Sort keyword arguments alphabetically by key. Was there no message with that? Well, thank you, Rebecca. That's very nice of the super chat. I guess there was no message with it, but thank you very much. Super nice of you.
way more generosity than I deserve.
Let's Let's see what's this sorted function allow us to do.
So sort requires an iterable.
Um okay so what does their tip say? says uh my recommendation is use the items method to get key value pairs as a list of tpples then sort that list before printing.
Okay. So k quarks items equals quors item items.
So that gives me a tpple a list of tpple a list of stir an object and then sorted.
So let's print sorted.
Okay. And then we could then sort like that run.
There we go.
Complete the configure plug-in decorator function. and it decorates a function that expects keyword arguments, but it should return a wrapper that accepts positional arguments.
The positional arguments passed to the wrapper will be key value tpples. For example, after configure backups is decorated, this call should behave like this call to the original function.
And then the return to plug-in comp should be path duplicates prefesting.
Create a wrapper function that takes positional arguments. Convert the args into a dictionary with the dict function. Each item in args is key value tumble. return the result of calling funk with that dictionary unpacked as keyword arguments using the double star operator turns out only works with arguments but need this is what you want by using are.
Okay, let's try to see if we can figure this one out.
Also, the cup coffee cup is getting close to empty. We may need to refill it.
All right. Um, okay.
So, I need to go back.
There we go.
Death wrapper and what does wrapper do? So rapper should take positional arguments.
This is going to be an object.
Okay.
Now create a wrapper function that takes these convert the args into a dictionary with the dick function. Each item in args is key value temple. So if we do arg equals dict and pass args okay how Why?
Why are you unhappy?
No overload of bound method matches arguments.
Okay. I I don't know why that functions.
I don't know why this is not working.
Uh let's see. Um passing args to dick in python.
I mean, I know how to create a I mean, I can create a dictionary.
I guess I'll just do that. I don't know how else to um so we can do for arg and args.
So this is a tpple. So what we can do is we can say args dict equals arg0 equals arg 1 Uh, okay.
I guess I don't understand. Let's see.
I don't understand why passing args to the dict function is complaining about this air code. Let's see what's the air. Uh I'm sure it's something silly and simple, but I don't I don't know.
And I have plenty of baked salmon.
Hey Kevin, nice to see you. Hope you're doing well.
Oh, so you're so you're telling me the editor is just wrong. Is that what Okay.
So you're saying if I do this uh aric Uh, as far as what's up though, Kevin, uh, nothing. We're we're working on boot.dev. I started playing boot.dev for fun, and I'm fully intend on getting to um, getting to arch mage, which is like basically level 100, I think. Um, I'll probably end up completing the whole course though because I think I'll get to level 100 before I complete all the courses because I'm already at a level 43 and I still have like 20 more courses to go.
So, maybe the experience gets incrementally more difficult to achieve maybe as I go up. So, maybe it will take me all of them. But my plan is just to work through all these courses and have fun doing it and not talk about AI too much.
I'm kind I'm doing everything I can to try to avoid code or anything AI related to coding.
Uh where was I? I was here, wasn't I?
Yeah.
Code.
So ignore this uh I guess ignore this complaint here. Uh so what we need to do is we need to say return funk and then we pass the arcs.
No, sorry. Ar.
Okay, here we go. That was actually much simpler than I made it out to be. This threw me off though.
I still don't understand why that's complaining. No overload of bound method in it matches argument.
Go figure.
Complete the markdown to text decorator function. It can decorate a function with any number of stream just disconnected. Sorry about that.
I'm back.
Twitch always takes a long time to reconnect.
I'm out of coffee.
I'm going to go start the water for more coffee.
M Okay, there we go.
Can't figure out the right place for my mic.
Excuse me.
Convert every positional argument in cards.
Convert every value with while keeping each key unchanged. Call the decorate function with the converted positional and keyword argument.
Uh, I guess the first thing I'm going to do is I'm just going to print args. Print so I can visually see what I'm working with.
Okay.
So that means what we need to do is we need to say um I guess what I'll do is I'll do four arg in args.
Actually, we'll do it. We'll do it with the index. We'll do l range.
Let's do this. Um, converted args equals this and then inverted arms plus.
Oh, skip.
What's the name of the function? Convert MD to text. Convert MD to text and pass in.
And then let's do args.
Yeah, that looks good.
And then we'll do the same thing here.
converted quarks and this will be a big for key in quarks.
We will say um converted just the same key but the value is going to be this like that.
I don't know if that's like the most pythonista pythonic way of doing it, but I think it'll work. And then what's the last thing we needed to do? Call the decorated function with the converted positional and keyword arguments. So we have to do return funk and pass converted args in converted like that. Let's say title expected. Why are these capitalized?
Keeping the key unchanged.
I guess I don't totally understand what they're asking.
All right, here we go.
Oh my gosh, that's a big Excuse me.
Okay. Okay. So, do I have to unpack them?
Oh, my mouse my mouse just disconnected.
Now run. There we go.
Success. Success. Success.
boot.dev is offering three-month access via my GitHub student pack. Not sure if three months is enough. Well, I saw I found somebody's blog post who did it who did it in like 30 days or at least they reached Arch Mage in like 30 days.
I don't know how many courses they did.
Um, apparently there's other things you can do to earn XP other than just the courses. There's like boss battles or something. Uh but yeah, three months is probably pretty aggressive for all the course work.
There's I mean this this path this is a lot of courses. I mean there's 23 courses.
I feel though duck boy if you already know like if you already know Python or you've written P Python before and you've already like if you have a if you already have a background in programming or coding three months isn't probably unrealistic.
But if you're brand new, probably is unrealistic, you know.
So, it largely, I think, depends on where where you're starting from.
Hey, good morning, Zang. What's Coffeeman doing? Surprise stream. Uh, I haven't been streaming really at all.
It's It's good to see you, Zang. I really just haven't been streaming much.
Um, I've only been doing it when I feel like doing it, which is what is that's kind of what I've done all along, but I felt less like doing it more often, if that makes any sense. So, this is like the sec my se the second time I've streamed this week, but the second time I've streamed in like the last 60 days, I think. So, I don't know. I never really had aspirations to be like a streamer.
I just started doing it because it was fun and then AI made it not fun. So, I kind of lo lost interest in it. But boot.dev has has kind of brought back a desire to to to to stream while doing boot.dev. I don't know if I'll ever go back to streaming and working on my own projects because every time I did that, it just became a conversation about like, why aren't you using AI or AI could do this or AI could, you know, basically just people [ __ ] on the fact that I still like to write code by hand, but that's where that's where I'm at. But good to see you, Zenzang.
Stephen is becoming a super gym bro.
I've always been a super gym bro.
Yeah, I've always been a gym bro.
Quite unrealistic if you're just starting as a student and got the pack.
Yeah, that's fair. I do know a bit of Python. Quite interested to see what what they also offer. The course that I'm most excited for myself is the um it's the C course. They have a memory management course that's taught in C and I've never written any C so I'm that's the one I'm kind of the most excited about. The others kind of feel like it'll be a lot of review.
I already know how to work with Docker.
This one will be kind of interesting.
pub sub architecture. I don't think I've ever actually taken like an actual course on it, but I've definitely built things using a pub sub architecture.
So, I mean, learn learning in any amount is always a positive, right? So, any time spent with hand fingers on a keyboard is a good time in my book.
Uh, true.
Okay. Where were we doing? Uh uh LRU cache from the funk tools module is both a decorator and an example of memo memoization.
LRU stands for least recently used. It's a type of cache that stores items up to a certain size limit. When it gets full, it makes space for new items by discarding the least recently used items first. The cache can be effective because items that are used a lot are less likely to be discarded. They stay in cash.
Uh here's an example from the Python docs that perfectly illustrates how and why to use.
Okay, because the factorial function is recursive and the inputs are sequential numbers, it does get called repeatedly with the same inputs. Without caching, the function would be called 30 times in the code above. With LRU cache, the function is only called 13 times. You don't often need to compute factorials, but this example ties together how to use a decorator and minimization and recursion.
Let's see. The creator of docto is a huge fan of palinadromes for some nerdy reason. Add a feature to check if a word is a palinadrome. Import the LRU cache function from funk tools module and use it to decorate the incomplete is paladrome function. Complete the is paladrome function. It takes as input a word string and returns true if the check is a pal paladrum.
Uh pal paladrum is this the word is the same backwards and forwards. Right.
Try to use recursion. Check the outer characters first, then move inwards until you reach the base case or find that the word is not a pal in the drum.
Uh, huh. Okay.
I guess I was thinking I would just reverse the reverse the um the word and then compare it. But maybe that's too easy.
Okay. So, we do is boot.dev worth it even? Not sure.
Cost versus return. Uh, so so far I'm having a good time. Uh, the co it is costly. Um, that I won't I won't uh I won't argue with you. I paid like $20 and something dollars for 12 months. So, and I think the monthly subscription is like $50 a month. Um, I think there's some there's some discount codes out there. I think that you can find that will give you like 20% 25% off, but it is costly, right? So, if you don't have the if you don't have the money, it's probably probably not worth the investment because the the m all all that all the money does is it buys you all the gamification.
Uh you can do boat boot.dev for free, but you can't do any of like the intera interactivity of it. So, if you want to still go through the courses, you can.
Um, you'll just sort of have to do it in your own development environment.
But for me, it was u kind of an entertainment factor. I like to code.
Um, I like to learn new things. I like kind of like the RPGish gamification nature of booth.dev.
So, for me, it was just more of like um you know, instead of spending $50 a month on some other piece of entertainment, I'm just spending it on boot.dev.
Yeah, it's it's it's expensive. Yeah, I think it's $50 a month, but I'm having a good time.
Okay. So they want us to use recursion.
So I guess what we can do Um, could we get first?
Uh, okay. So, the I guess the base case would be if the length of the word if we're doing this recursively. If the rank if the length of word is one, uh, what do we do?
Yeah. So I guess what we could do is if the length of the word is one return true and then first letter equals word zero and then last letter equals word of this.
And then if these are equivalent, I guess I guess say if first uh does not equal last uh return false.
Oops, first letter.
Uh otherwise this is where we do the recursive call and we just pass in the remaining word.
So we do take from the first like this. That work.
Uh, we could special case empty, I guess. Couldn't we?
So, wait.
If the length of the word equals one, oh, I guess we could do is less than Well, that's not true.
So, let's just do a special check for actually curious to see what their solution is.
Okay, one failed.
Uh, let's see. Expected. Oh, so they do want that to be okay. Never mind.
So we could do less than.
All right. So let's see what their solution is.
So this is effectively this is effectively asking the same thing.
Hey, Minister of Defense. Good to see you.
What's happening big homie free?
Nothing's happening. We're just playing boot.dev and enjoying our Saturday morning drinking some coffee.
Hanging out on stream.
That's about it. Nothing. Nothing but that.
Okay. I think I think for the most part we basically did uh Twitch just disconnected. I'm sorry, Twitch.
I wonder if every time it disconnects it starts a new does it start a new um a new thing.
See channel. Oh, I'm already on my channel. It's going to say does it start a new video? How do I get to my videos?
Wow, I have 300 people following me on Twitch. Wow.
Maybe I should stick with this streaming thing.
I don't think I'm particularly good at it, but 300 people followed me. That's pretty cool.
Uh, I guess I can't see until I end stream maybe.
Anyho, okay, you can stack decorators and you can use curring with decorators. Okay, why do I I don't want to do that. I would never want to do this.
No way. I am the last Twitch survivor.
Yeah, you're I think you're the only one on Tw. I don't know how many people I don't I don't look at the viewer count while I stream because I think it's just distracting and it's not really the point of streaming for me. But I just can't can't believe there's that many people that follow my Twitch channel.
Complete the replacer function. It takes as input two strings old and new, returns a function replace. Replace takes an input function decorated funk, and returns a wrapper function. Wrapper takes as input a string text. It uses the replace string method to replace instances of old with new in the text.
Then it returns the result of passing the modified text to the decorated funk.
Uh use a series of calls to the replacer function to decorate tag pre. Pass the following pairs of strings to these decorator calls to encode the escape sequence.
Okay, I still I still feel like this is just me practicing writing bad code, but uh yeah.
Okay.
Return wrapper.
Define wrapper.
Uh this will have an input which we'll call spur.
then return input.
I guess we can call this text text and then we do replace old with new.
replace takes an input function decorated funk and returns a wrapper.
But I don't see a I don't >> Did we just become best friends?
>> Hey, car cars insurance. Thanks for follow on Twitch. I was just talking about I can't believe people follow me on Twitch.
Oh, it returns a replace. Replace takes an input. Okay, so that's okay. Replace. That's where I went wrong. So, this would be our decorated funk, I guess.
Then you return the wrapper. That's where I went wrong.
So replacer returns the turns wrapper and then this returns decorated like that and then this returns Replace replace takes an input function and returns a wrapper. Wrapper takes as input a text. It re uses thereplace string method to replace old new. Then returns a result of passing the modified text to the decorated funk. Then we have to go down here and we have to say um at replacer and then we pass in the old with the new like that. And then we're just going to repeat that here. So we're going to say replace this with this.
Place that that place do single quotes here. So we can do quotes.
This should be applacer.
And then we have to do this with and #x27.
Yeah. See, like to me this is just I I just don't know why you would write code this way.
I mean the the decorator I understand like a function that returns a function.
I understand it. But the currying is just something I don't I don't understand why you would do that, you know? It's like uh just seems silly to me in my opinion, but just me.
Hey, what's up, Bo Gamer Pro? Yeah, it's been forever. I I haven't streamed much lately.
Good morning, Nick Demon. Good to see you.
How would you do it differently?
I think I would just have a single function.
Honestly, like I don't understand. I mean, the whole point is they're trying they're they're just doing this to demon like they're trying to illustrate something, you know? They're trying to teach something. But I think if this was in the real world and I wanted to replace her decorator, like I would just remove the just remove the wrapper, you know, but I think I I think I have to leave it this way. I It has to work that way because of the way they're calling it.
they're expecting it to be called in a curring way. But I don't I just don't know why you would ever do that, you know.
And if if you don't know what curring is, curring just means a function has a signature like this where you'd say curried function and then you'd say something like a b c. Right? So that's that's what it looks like when you call a cur a curried function.
And again, it's like I don't know why you wouldn't just write a function that takes a, b, and c and then does the work. To me, that's much more readable.
It's easier to understand. The logic makes more sense. Um, yeah, if it if it was me, I think what I would just do is I'd just have a replacer, right, that returns this.
Like, it can still return the replace function, but it doesn't need to do all that. It should just take in just take in the text like here and then do its thing.
That's just me.
But I mean, it's good to learn about this stuff so that if you do encounter it in the wild, you sort of under you sort of like understand what the hell's going on, but I don't think I would ever author code that way myself.
Yeah. Yeah. I mean, yeah, I I'm with you, Exciting. I think I think like really simple code is often better code.
I mean, if you're a library author, that's one thing, you know. I think it a lot of a lot of the complexity in code obviously depends on like what level of abstraction you're working on. But if you're like building a very concrete thing to solve a very concrete problem, I think the simpler the code probably the better. Nine times out of 10.
What are we doing here? Remember when I said pure functions are my favorite part of functional programming? Well, sum types are a close second. A sum type is the opposite of a product type. Uh, this Python object is an example of a product type.
Um, the total number of combinations a man can have is four. The product 2 by 2 * 2. Yeah, that makes sense. If we add a third attribute, it becomes eight. Yep.
But let's pretend that we live in a world where there only there are really only three types of people that our program cares about. Datable, undatable, maybe datable.
We can reduce the number of cases uh our code needs to handle by using a subtype with only three possible types.
Okay, then we can use the is instance built-in function to check if a person is an instance of one of the subclasses.
It's a clunky way to represent some types, but hey, it's Python.
Uh, as opposed to product types which can have many often infinite combinations, some types have a fixed number of possible values. To be clear, Python doesn't really support some types. We have to use a workaround and invent our own little system and enforce it ourselves. I never heard of this term some types in all the time I've been programming. That's a new concept for me.
Uh let's do some types in C something I Oh, so that's just another word for discriminated union. Okay. I'd never I've never heard it uh said that way.
Interesting. Okay. Yes, because this is what what we're basically doing is we're recreating like pattern matching.
This is sort of the same thing you have to do in JavaScript.
Random question. Have you ever looked into Temple OS just as a novelty or interest? I have not. Um I don't really understand the fascination with um what's his name? Terry Davis and Temple OS. I believe am I'm not getting confused, am I? Temple OS is the thing Terry Davis made, right?
Yeah. So, I don't So, I don't understand the fascination with him or the operating system he made. Um, it sounded like Terry Davis led a very strange, weird, complicated life that ended in a very tragic way. And so, I don't know. I don't really I just I don't understand the fascination with him or the thing he made.
I appreciate how difficult it must have been to create an operating system himself. Like obviously it's a very difficult task but I um yeah it's never interest me but I maybe I'm just the weird one you know I don't like the developing games has never really interested me but maybe I'm just the strange one.
Yeah, I just I did it alone, I guess.
So, I mean I Yeah, I mean Yeah, I don't know. I I think there's there's the the interesting thing to me is like there seems like there's a lots of projects that were created by one person that are of equal complexity that seem difficult, you know? So, it's like I don't understand why he kind of has developed this cult following, but you know, who am I to tell people what to be interested in?
All right. What's the what is what's my assignment here?
Whenever a doc is parsed by docto, it can either succeed or fail. In functional program, we often represent errors as data rather than by raising exceptions because exceptions are side effects.
uh complete the parse. Parse represents success. It should accept a doc doc name string and a text string and save them as properties. Pared air represents failure. It should accept a doc name string and an error string and save them as properties. The test test suite uses the is instance function to see if an error occurred based on the class type.
Uh so don't touch above this line. Okay.
Okay. So, what you're just saying is I just need to do self doame equals dot name.
And you want me to do that for text, too? Yeah. Text text.
Yep. And then self.ext or sorry, error.
Wonderful.
Uh see we are we can simulate the shape of some types in Python by using classes like our maybe parse class with subasses named parsed and parsed error. That's better than nothing but it's awkward.
The type hints system in modern Python offers a more direct way of describing a value that may be one type or another.
We can just use what's called a union type. So what's the diff the way he's talking it seems like union type he's treating some type and union type as different things but Google says they're the same thing.
Not sure.
Uh, see great great great great great great great great.
Hey Artwork Studios, good to see you.
Hello not bite slayer.
Interesting Twitch name over there. Nice to see you. Hope you're doing well.
Yeah, you're welcome to hang out as long as you want, Artwork Studios.
How close am I to being done with this?
Uh what we what were we doing? Oh, we're playing boot.dev is what we're doing. Boot.dev Dev is like a it's like a gamified learning course for programming and coding.
Only have five more lessons to go.
I'm currently making a local reimplementation of boot.dev. Nice.
Well, way to go, man.
I'm impressed.
You guys are always doing things that are way more difficult than I take on.
Don't touch above this line.
Okay. So what do you want me to do here?
Parse doc accepts two strings. It should then return a parse value if content is not empty. Okay. So if content uh length of content is uh less than or equal to zero.
We're going to return a parse error.
with the doc name and no content and then otherwise we will return parse with doc name and content. Does it actually want me to parse anything? I don't think so. I think I just return the content.
Okay.
And then if the provided value is parse return parsed and in characters where n is the length of the parsed text. If the provide values parse error return fail.
So we can just do I think for now we can just do if uh result is instance result is parsed and return f it should say parsed exalt doc name and this should be result dot or sorry length result do what text otherwise we'll just return our failed And this will be all there.
Woohoo.
Cool.
Is this like a route you're going or are you going through all the courses on there? So, this is No, this is a path I guess is what they call it. The backend path is what I'm doing.
And there's two versions of this.
There's one that's Python Go and then there's one that's Python TypeScript, I think, is the two versions. And then they also have a DevOps one.
uh which I'm not currently actively going down, but maybe I will. I've got 12 months. Uh I bought twmon subscription, so I guess depending on how quickly I get done with this path, I could switch over and also do the DevOps path.
But my main goal is just my main goal is to become level 100 and get one of those arch mage coins. That's my main my main goal at the moment.
I needed tests and I'm not a fan of how the native Go testing works. So I made a testing framework that uses Lua to test Go code. Huh. I don't know. To me by Slayer that sounds like solving building a solution to something that's not a problem. But hey, whatever whatever gets you going, man.
A year is like 300 plushes. It's a lot.
I haven't decided yet if it's good for a beginner to waste that money. It's Yeah, it's completely I mean if you have I think it's well worth the investment if you have the money. Um I don't necessarily think it's necessary though.
You know there's there's uh free codeamp.org is where I always point everyone to. There's lots of free coding and programming resources.
I just wanted to do this one because it looked fun. The gamification aspect of it looked fun.
Oh, now we're learning about EDMs.
Okay. Trade enum.
We say from enum import enum and then we're going to say PDF cool as what see studios It is shameful.
What language does not support proper sum types? Python.
Why are some types use? You have to run code to see if you handled all possible cases. You can know before you run your code that you've handled all possible cases. They ensure that variables can hold. No, this one.
Let's take another look at our example enum from the previous lessons. Working with enums. Python has a map statement that tends to be a lot cleaner than a series of if else. If you have the two values to match, you can use a tpple.
Well, that's nice.
Complete the convert format function using the enum doc format. It should support three types of conversion. MD to HTML, from text to PDF, or from HTML to PDF. Okay.
Okay. So we need a match and we want to match on tupil.
How do we do that?
We can match on from format to format like that. And then we can say case and we're going to have a set of cases.
So, we're going to do How many do we have? One, two, three. We have three.
So we do MD to HTML text to PDF and HTML mark and then the default was going to be if the input is raise an exception A exception of invalid type.
You think learning from Harvard CS50 first or free co- camp better or just either or? I'm wanting to increase my skills as I do normal jobs transition after graduating. Can't find a job in my field with just the four-year. Uh, I think free code camp's great. I mean, I think the nice thing about free code camp is it has a really tight feedback loop because a lot of the courses start off with just working in the browser kind of like boot.dev does before it pulls you down into your own develop development environment. So, you get a lot quicker.
I think the quicker that feedback loop is early on when you're learning, the more likely you are to stick with it because you get that that kind of like the dopamine reward of like figuring things out with a lot of the struggle of like setting up your own development environment.
I also like Freo camp because of the uh project based learning where at some point in their coursework they basically say here's a set of requirements for a project and then you have to just go figure out how to satisfy those requirements without them like holding your hand to tell you exactly what to do which I feel like is kind of the best way to actually learn something.
Uh CS50 is good though. Uh, I feel like CS50 though a lot of times is um like more passive consumption because you're just you're watching a lot of YouTube videos. Um, granted I know like you're supposed to be following along and doing the exercises and whatnot and I know they post all that online. I've never actually done the exercises. I've just watched the lectures.
Uh, but I think I think both are fine. I think I think the more important thing is to actually do something you know to start uh like you got to you got to start and then keep keep with it you know continue every day. Programming and coding is very much a in my opinion it's very much a skill that has to be done to get better at it.
You can't just like read about it like read coding books and architecture and like you've gota you've got to read a lot of code. You got to write a lot of code I think to get better at it in my opinion.
Where did I fail?
There we go.
Oh boy. What did I Let's see. Convert. Oh, that makes sense.
Dr. Doc should be able to prepare and export a CSV file or whatever data you input. Um, CSV is ubiquitous text format that allows for information to be structured in a table. There's usually a header row followed by data rows. Within rows, items are separated by commas.
Complete the get CSV status function. It should use a match statement to select the correct response depending on the status of the export operation.
Create functions to handle each operation as follows. pending return a tupil with the string pending and the data converted from a list of lists of anything to a list of lists of strings.
Try to use nested map functions to convert the data items into strings.
Remember to convert from a map object back into a list.
Okay, this one's a little bit more involved.
Um, where's the code?
All right.
So, what we'll do is we will match against status and then let's give ourselves something to work with.
Bro, I'm about to throw my phone out the window. Someone at YouTube thought they can push 4K over a cell network and expect his work. Can't load any videos, even shorts. All settings are on data save. Huh.
Strange.
Yeah.
I guess that's still a problem we haven't quite solved.
I mean, 4K is a lot of data, though. You know, 4K files are [ __ ] enormous.
Hey Pashra Pashra, hello. Good to see you.
It's interesting that that won't auto.
There we go.
Okay. So, let's do that a couple more times and just make sure we have all our cases enumerated.
So, we have pending, we have processing and success. So pending oops pending processing success and failure.
Okay, I'm going to do these uh first.
So return a tpple with the string. So if we return a tpple that's going to be Okay, maybe we shouldn't do that one first cuz that one relies on the previous ones.
So, success looks pretty easy. We'll just return success and the data.
All right. What does pending need to do?
So pending return a tpple with the string pending and the data converted from a list of lists of anything to a list of lists of strings.
Okay, so return pending and so this would need to be uh map.
And what does map take? Map takes the data.
No map takes a lambda.
So this would be a list taking the data.
And then for each list, we want to map over it.
Sometimes I can't spell.
And take that. And I guess uh whoops.
Another lambda.
This time it's a string or it's anything. Just some piece of data.
and call the stir on that.
Is that going to work?
The return type does not match return value expected. Tuppple string with a list of lists. Found tpple pending map unknown.
Okay, I'm going to just write this so that it's simple.
Uh return uh pending.
And I guess for now just do that.
Um, actually, let's do this.
Oh, hold on. Is it because I hadn't converted it back to a list? Is that why it was complaining? Let's see.
Right, man. That's just that's the that's an ugly bit of code right there.
Not even going to lie.
Not even going to I don't even know if that's right. That's how ugly it is.
>> Just curious where can I order food using Gay.
>> Hey Rebecca. Uh I actually don't know.
Looks ugly for sure. Yeah, it looks ugly for sure.
I appreciate the super chat. You definitely don't need to super chat to ask that. I can't help you though. I don't know where I don't know where G pay is accepted. It's not my not my uh area of expertise. Hey Tyler, good to see you Tyler. Hope you're doing well. I do appreciate the super chat though, Rebecca. It's very nice of you.
Uh I've been around Tyler. I just haven't been streaming but I've been around. Been living life, you know.
just enjoying life.
Let's see. Let's run this and see what happens.
I'm just curious.
Obviously, processing isn't going to work, but I'm curious about pending. So, pending did not succeed.
All right. So, let's make pending a little simpler here. Um, so what we can do is result is this and then we're going to loop over the list in data and then we're going to loop over the item in the list.
Um, and this is going to be our new list.
And we will say new list.append stir item.
And then we will say result.append new list like that.
See, like that to me, I know this is very imperative code, right? But like that was a lot simpler to reason about than nesting map functions in my opinion.
I guess the way we actually could have fixed the earlier code would be to undo all this and then we need to convert um let's see we need to convert this to this.
I don't know, man. I don't find that I don't find this I don't find this is readable code. I know that's what they wanted me to do, but I just I don't find that as readable.
Oops.
That's just doing this.
So, I'm going to do it the way I want to do it.
Okay, now we need to work on processing.
Return a tpple with the string processing and the data converted from a list of list of strings to one string in CSV format.
Okay, so we need the same kind of idea here.
Uh but we're going to do something a little different. So the result here is going to be a string which is still our result. Uh but we got to be a little bit different here. So it's still list but this is a string now.
And so we don't need to do that here.
We don't even need to loop over.
Um let's see. So the top list so the the top level list we want to join with a new line.
I guess we still want to do that.
So, we'll call this row.
Trying to think of how I want to organize it.
So I think what I want to do is I think I just want to do rows like this.
And then down here I want to just do uh new linejoin and pass the rows which means for each row we just need to do this where we say uh rows.append the pinned um joins like that.
We don't need that anymore.
I think that's what I want. So, for each list of strings, combine the strings with join with commas in between to form a row. For each row string, combine the strings with join with new lines in between to form a table.
Okay, so that works for Yeah. Okay. So now we just need to handle failure. Um, and what does failure want us to do? return a tpple with the string unknown error retrying and the data after it's been prepared and processed into a CSV string by combining the steps for pending and processing.
Uh, so I guess we should probably separate these out into some functions.
So let's do defaf convert to list of strings, right?
And this should return a list a list of stir.
So then we can do copy all that code, put it up here.
There's no automatic formatting. That's okay. We can fix that.
Um why is this complaining any oh that's right type then we can say convert to list of strings pass the data.
Okay. And then we'll do the same thing here. And we'll say this is kind of a silly function. I don't I don't really know. Uh I mean I I uh we also need to move this.
This is kind of a silly.
So let's do defaf convert list to CSV.
And so this will take data which now this should be a list of list of stir.
Man, I just cannot stay connected to Twitch today.
Uh and this is just going to return a string.
Let's put that there.
And then don't want to return the tube.
We just want to return this guy and then down here instead of calling that we'll say convert to list of CSV. We'll pass in the data and there's no need to do that anymore.
Okay. So then for the failure, what they want me to do is they basically want me to do uh this. This is going to look like hell, but just stick with me. We're going to do unknown error retrying and we're going to do this. is we're going to convert to CSV and we're going to convert to list of strings.
We're going to pass the data.
So, three pass, one failed. Who failed?
Processing failed. Why did you fail?
So expected because we're not processing.
There we go.
Oh no.
None type object is not sub subscriptible. What?
Oh, I should have said exception unknown export status. Oopsies.
Hey, we did it. We completed the course.
13.98% of members have completed this course.
That seems like a very low number, which I guess means one of two things.
The course is new, they've had a huge influx of members, or people just don't care about doing this course, I guess.
Uh, see, let's do pretty good stuff.
But honestly, I feel like you could just not teach people about curring and the world would be a better place for it.
Uh, submit.
Hopefully that doesn't bother them.
Cool. So, what's the next thing we have to I think the next thing we're supposed to do is we're supposed to build an AI agent.
As much as I try to hide from AI, I just can't get away from it.
Can't get away from it.
Yeah, it is awesome. Duck boy, look at us. We're doing stuff.
All right, what are we doing here? Time for boot.dev to crash in on the AI hype.
We're building a toy version of cloud code using Google's Gemini API. As long as you have an LM at your disposal, it's actually surprisingly simple to build a somewhat effective custom agent. This is actually very true because at the end of the day, an agent is just it's just a for loop with prompts, right? And um maybe a set of tools that the agent can or cannot use. And then a lot of the complexity in building an agent just is around managing context and memory and retries.
Right. It's it's the it's the edges of the agent that become difficult. I actually have a whole series on my YouTube channel where I where I do this in C if you're if anybody here is curious about doing this in C. Um I have a playlist.
Where is it?
Here you go.
And we basically walk through from start to finish building out an agent. and we spilled it in a single file with C code andnet and it's pretty it's I think it's one of the better series of videos I've done. Um, if you actually want to kind of dig into the topic, obviously this is the longest of the video because this is really where like the agent takes flight because the thing that differentiates, you know, the the agent from a chatbot is the fact that the agent can perform actions, right? So, the tool is really the tools or the tools that you provide to the agent really set it apart from from your traditional chatbot stuff.
Yeah. Yeah, if you want to ever go and hear me talk about AI agents, you can do that here.
Okay.
All right. So, until recently, Google offered generous free tier limits on the Gemini API, including for Gemini 2.5 Flash, the model we recommended for this project. However, in December of 2025, Google drastically lowered the free tier rates, making it difficult to complete this project without hitting the limits often. Um, it seems Gemini API will continue to charge frequently and without notice. We recommend, if possible, setting up a paid account with Google and using Gemini 2.5 flash model.
You should acrew no more than$1 to $2 charges during this course. Otherwise, you can still use Gemini 2.5 Flash on the free tier, but you'll be subject to very few requests per day. We'll keep updating this course as the situation with free tiers and model quality evolves. It's just going to get worse.
Yeah, I mean AI coding now is pretty much even, you know, if you're using cloud code, if you're using codeex, if you're using any of those people, any of those subscription models, GitHub copilot, you can't even sign up for GitHub copilot right now. But almost all of them are it's just terribly, terribly, terribly expensive to use agents to code. If your company pays for your usage, that's great. But if you're paying out of your pocket, it's it's just not you can't get enough work done with what you can afford in my opinion.
If you try to complete this course without WSL install Windows, you're going to have a bad time.
Well, we're we're using uh we're using WSL, so we're good.
Uh I do have I already have a paid Gemini set up. So, let me go to my I use the Gemini API a lot for most things. People knock the Gemini model so much, but I like the Gemini family of models.
Um let's see. AI Studio I guess I can.
Yeah, I have a billing account set up.
So, we should be fine. We won't have any issue completing this. All right. So, the program we're building is a CLI tool that accepts a coding task. Strings aren't splitting in my my app. Please fix. Chooses from a set of predefined functions to work on the task. for example, scans the files in a directory, read a file's contents, overwrite a file's contents, execute the Python interpreter on a file, repeat step two until the task is complete, or it fails miserably, which is possible. For example, I have a buggy calculator app, so I use my agent to fix the code.
All right, Python 3.10 plus installed.
Yes, we have that. We have UV set up. we have a Unix like shell.
The goal is not to build an LLM from scratch, but instead to use a pre-trained LLM to build an agent from scratch.
Yeah, none of us can afford to build an LLM from scratch or a meaningful a meaningfully useful LM from scratch.
All right, let's do it.
Uh, let's see. Where are we here?
So, what do we want to call our agent?
Um, I don't know. Let's call it Einstein.
How about that?
Einstein.
Also, let me make this a little bit here.
Oh, actually remove Einstein.
We want to do We should just follow along with their prompts because I think they're going to have me use UV. So, I think it's going to be UV. Uh, what is it? UV.
Oops. D I'm sorry. I think there's a new project command. What is it? Uh, innit. That's what it is. Init.
Um, yeah. So, that's what they have me run for the asteroids game. Oh, yeah.
Which I did I haven't shown you guys this. I did build an asteroids uh asteroids game as part of this course, which is which was fun.
It's kind of cool, right?
You can shoot him.
This was actually deceptively hard to do. The the math part of this was the hard part.
Game programming is not for the weak.
You know what I mean? I don't know how people do it full time.
All right.
It's not what I wanted to do.
There we are.
Python setup.
So let's do UV init.
And we are going to do Einstein.
I think that's how you spell his name.
Yep.
Okay.
And then we're going to do UV create a virtual environment.
And then we are going to do we're going to activate that virtual environment.
All right. And we're going to looks like we're going to add some dependencies.
We're going to add the Google Gen AI.
And it's having me specify a particular version. So I'll just do that.
We add Python EMV. So this must be the Python package you use to load from av file.
So let's go and open NeoM.
This is a simple coding agent I built as part of the boot.
That's how you spell curriculum.
Curriculum. I think that's how you spell curriculum.
And then let's go here and let's ignore anything that has um except for example.
Okay.
And let's open up a another shell here.
So, this will be my Neovven terminal.
Neo.
This will be my terminal.
a little bigger too.
And then let's go into zen mode.
All right. Now, what else are we going to do? This tells Python. Yep. Yep. Yep.
Uh to run the project using UV virtual environment, you can use the Yes. UV run main.py.
Wonderful. In your terminal, you should see something like hello from your project name. Submit your CLI test in your original.
There we go.
Success.
All right.
They're telling us about the Gemini API.
They're telling us about tokens. They're telling us all about the AI things.
So, you're going to create an account in Google AI Studio. If you don't already have one, click the create. Yeah. Yeah.
Add ENV. Update main.
When the program starts, load the environment variables from the EMV file using then EMV library. Read the API key.
If the environment variable wasn't found, i.e. if API key is none, raise a runtime error with a helpful message.
Okay. So, we just have to do some stuff.
Yeah, do some stuffs.
So, I am going to use um Oh, this is on WSL. So, I'm actually going to create a new terminal window and I'm going to edit my EMV file and I'm going to try not to leak this API key.
Uh so I got to create a new API key and this is going to be called Einstein development.
Okay.
Add the API key.
And we're going to add uh see iuntu. Yeah. Got to go back to shell and go into Einstein. I'm just setting my ENV key here. So, uh, Gemini API key is equal that.
Now, I'm going to clear my clipboard so I don't accidentally paste that somewhere. I shouldn't.
Okay.
to get my in your initial project setup.
Wonderful.
So now we're going to import the OS module.
We're going to import from EMBB. import load and then in our main we're going to say roadb.
We're going to get the API key using the invi.
And then if the API, what does this return?
This return none.
Yeah, none. So if doesn't Python have an is keyword if API key is none.
Yeah, that to me this reads so much better than using equals.
Then we are going to raise an exception and say um let's actually do Gemini API key.
That's a terrible variable name. I just don't know what else to call it.
Uh what about API key env key?
How about that? That's a little better.
Still a little redundant. Uh let's see.
And then we'll say API key is not set.
So if we run this now this should be this should pass.
However if I remove that variable it should fail.
Just going to remove it and I'm going to rerun it. And that's what we wanted.
However, yeah, that's what we want. Exception.
Gemini is not set. Cool. Python errors are terrible.
Python stack traces are awful.
Okay.
Now, what does it want to do? So, we got our we got that done. Got this done. We got that done.
Got that done.
Oh, this this should actually be specifically should be a runtime here.
Okay.
Now it wants us to set up the Google uh import genai and then we'll say client equals genai.client and we will pass API key equals API key.
Then it says, use the client.mmodels.generate content method to get a response from the Gemini 2.5 flash model. You'll need to use two named parameters, model and the contents.
Okay.
So let's do res equals client.generate content.
Okay. Why isn't that?
Oh, models. It's one of those. It's one of those APIs.
Okay. And then we'll go ahead and specify um what do we want to specify here? We want to specify model, right? Yeah, model. And this should be Gemini 2.5 flash.
Actually, let's do let's just go big or go home. Huh. I wonder if I wonder how much more expensive 3.5 is to 2.5.
Gemini 3.5 flash versus uh 2.5 flash.
There we go.
Per 1 million tokens.$150 per. Wow. $9.
Let's look at I mean look at that. That's crazy. 3.5 $9 per million. Wow. It's inordinately more expensive.
Uh Gemini 3.5 flashlight.
So, where's 2.5?
Oh, yeah. So, what is that? Two. It's um almost three times more expensive.
Yeah. Okay. So, we will stick with 2.5 flash. I don't know how people are building profitable businesses around some of this stuff. It just seems horribly expensive.
Okay. And then content content which we have to take from here that oops.
Okay. And then it wants us to print the text property. So print like that.
All right. Let's give it a go.
Oh no.
Let's see. 404 not found. Um, models version 2.5 flash is not found for API version v1 beta or is not supported for generate content. Call model services list of Oh, yeah. I did not do that correctly.
Sorry.
Boot.dev excels as a back-end learning platform due to its highly structured, hands-on, and job oriented curriculum.
Good thing for boot.dev. Let's go.
Um, okay. I guess I'll submit. See what happens.
Huzzah.
See, when using an LM API, it's important to keep track of how many tokens you're consuming. Most APIs provide metadata about token usage and their responses, which can help you to monitor your consumption and to try to avoid hitting rate limits.
um has both prompt token count and candidates token count.
Let's make sure we can keep track of our usage, printing it along with the response if desired.
Okay.
After getting the response from the Gemini API, but before printing the response text, print the number of tokens consumed by the interaction in the following format.
All right. So, I think first and foremost, we should probably put some defensive code in here. Um, if resz Oh, I wonder if this just throws if it fails, huh?
Probably just throws an exception, doesn't it?
So I guess we'll do if reszage metadata does not equal none or equals none.
Then we should raise a runtime error message that says uh unable to get response metadata.
Request likely failed.
So, what is what is rez uh contain that would I don't think that that's true.
I think that thing's going to throw more than likely, but I'm just going to do something like that.
Then we're going to print um prompt tokens.
It's going to be equal to res do usage metadata.prompt token count.
And then this is going to be response tokens which is equal to candidates token count.
Okay.
Verify that you can see the token counts when you run your script for every response. The model will be different but it could look something like this.
So we are going to print print f uh whoops be f user prompt.
Let's say let's just go up here and we'll say user prompt equals this guy um bi.
There we go.
And then maybe vi delete that and set this to user prompt.
Then we can use that here.
And then we're going to print the response.
Okay, let's try again.
Oh, shoot. That's not I did not mean to do that.
Not what I meant to do.
Cool.
That worked.
What time is it? Oh [ __ ] it's almost 12:30. Holy moly.
I've been going for a while.
All right, I'm hungry. I'm going to take a break and go eat some lunch. Uh, yeah.
So, this was good. This is fun. I don't know how much more streaming I'm going to do on a regular basis, but if I do stream, it' probably be just me doing working on boot.dev. dev stuff. Um, I hope you guys have a lovely rest of your Saturday and I'll talk to you guys later. All right, bye y'all.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











