5 tips for CLEAN Python code

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I've always said to people getting into coding for the first time it is much easier to get into good habits from the start than it is to break out of bad habits later on and one of the best habits you can get into is writing clean code in fact you could argue that keeping your code clean is about as important it's keeping your teeth clean if you've already picked up some bad habits it's not too late to ditch them so this video is perfect for you as well in this video I'll be showing you five tips to make your Cod cleaner and to keep it clean as well but before we get into all that let me talk to you about service called codec Crafters code Crafters is a service that provides programming challenges and it's used to you will largely depend on your skill level the challenges are tailored to your skill level meaning that if you're looking to learn a language it will give you more help if you already know the ins and outs of the language it'll be more advanced and more of a challenge for you the challenges themselves revolve around looking to build your own system so you can build your own Docker or build your own git or build your own Reddit and learn how these systems work for example recently I completed to build your own Docker one and I learned so much about sub process and I also learned about how Docker containers keep all their stuff away from the rest of the system some of their challenges are free for a limited time but if you do decide to sign up to The Full Experience you can use my link in the description below for whopping 40% off your first year again that's my link in the description below for 40% off your first year with Cod Crafters but with all out of the way let's get into some good habits so the first trick in this video is to reduce nesting wherever possible and keep keep code flat as you'll see in a bit uh so in this example here we have this function that checks if something is a vow if uh or check a character is a vow if we have just passed a single character then we check if it's a vow and if it is we return true otherwise we return false if we have more than one or less than one character pass through then we you know raise an error that we uh expected a single character and if we run this wow that terminal's why okay that was weird uh if you run this like that we can see that it works fine a is a vow B is not it works perfectly fine but it's not the cleanest you know we have uh this nesting we have this if else level here and then we have this nesting inside this uh and this is what I mean when I say nesting you want to keep things as flat as possible and when I say that I mean you want to unindent things as much as possible so the first thing we can do about this is that we can actually change the order of operations here so we can say instead of if L character equals 1 we can say if it doesn't equal one then we raise this error and then instead of having an else here we could just unindent this because if we do you know run into this condition and we'll raise the error the function will exit it won't continue on uh and so we don't need to have an else block because it's not necessary and the same thing happens here actually we can get rid of this too so now we say if uh you know character do lower in uh this string here we return true otherwise we return false we've gotten rid of more nesting and we could see it works exactly the same uh when you do something like this it's typically the case that you would um pick off all your negative cases so in this case we could do something like this we false and then sort that round it goes true and now we're saying if the length of character does not equal one that we raise if it's not a vow we return false if it and then you know if all the negative cases aren't true then it must be the positive case and we return true that is the general flow you would expect and again works the same in this particular example we can actually make this even simpler and we can get rid of this second if statement completely so we can say instead return char. lower in a aeou and because this expression will return a Boolean what we're saying here is that we just want to return the result of this so this will either return true or false so we don't actually need that if statement at all and now we can see it works you know still works exactly the same and we've reduced our function from eight lines to five and we've also flattened it an awful lot you can't get any more flat than this another advantage of working like this is that you have more real estate to work with so if you have um line length restrictions then you're less likely to meet them if you unindent more because each time you unindent it gives you four spaces if it work for Google that' be two uh but you just have more space to work with as well the second tip I want to show you is reducing code redundancy or having some reusable code in place of code that you're defining on multiple places now there are a number of ways of dealing with this one of which is decorators not going to show those off in this video because I've done a string of videos that have covered decorators in recent weeks so I'd recommend going and watching those especially the the main decorators one I did um a little while ago but I am going to be showing a concept called mixins today which are sort of the class equivalent so you'll see here we have this profile class and we have this Cube class they both you know function relatively similar in the way that they're defined at the very least you know they both you take attributes and they both set attributes I'm aware you could use a data class to do the same thing but for the sake of having an an easy simple example we're not using data classes right now and you'll notice that both have this string representation method and they both do pretty much the same thing so they have this class name you have the Open brackets and then they Define so the name and the age in this case and the width the height and the depth in this case and we have a little bit of code down here to just create some instances and then print the string representations of each if we do that we'll see that we get this format back where you know we have the format that we've defined here but it is a little bit wasteful to Define this twice in each class because if we change it in one class then we might forget to change it in another and actually adding it to each class individually especially when it comes to SS like this having to type all this out manually is just a bit annoying and a bit of a nightmare so what we can do is we can create a class that implements that functionality so I'm going to get rid of this and I'm going to get rid of this and I'm going to come up to the top here and I'm going to define a class called repper mixing I'm going to ignore that for now now mixins despite their name are just normal classes there is absolutely nothing special about them at all it is just utilizing inheritance to add attributes or methods to existing classes one thing that you could say makes a mix in a mix in is that mixins are useless on their own if you were to instantiate them it you know they probably wouldn't do anything useful otherwise it would be just a normal base class uh so we're going to define a repper here and then we're going to do self and then this is going to return a string and then we're going to say atas here so we're going to dynamically generate this list and actually we have yep that looks pretty good to me uh and then we can do that yeah that looks I think that's fine uh so we have a comma separated list where we have the key and the value and then the string representation of the value with KV in V self so V self is equivalent to self. dict so we're just getting the dictionary items from the class and we're just cycling through the items and then we're just formatting uh the string as we want so typ self. name will get the name of the class itself and then we could just format our Ates into there and if I bring reer mix in into these two like that if we run that code again we can see that it does exactly the same thing but we only Define this string representation once and now if we change it here it'll change everywhere so if we decide to separate them with a pipe for example it will change it across both classes and we won't you know potentially accidentally forget to change it in the cube class we've changed it in the profile class and it just makes it a bit more um a bit more consistent with this particular implementation if your classes had slots you'd want to do something slightly different you'd want to you know detect if it had slots or dicks and then do it like that I haven't done that here for Simplicity uh you would also or you could also do it as a meta class if you wanted to in this particular instance I have a video of meta classes I did a while ago if you want to know about those um a meta classes work actually quite similarly in terms of reducing code redundancy uh so there another method you can do I just wanted to show mixins off today uh because I haven't actually talked about mixins on the channel before and I just wanted to show them off because they're a really cool concept the third trick that I want to show you today is reducing complexity within functions so potentially splitting out codes um into more than one function if one is looking particularly complex uh so this is uh a an excerpt from the code I wrote in my o video doing o from scratch and you could potentially argue that me using my own explanatory code as an example of what not to do is a bit counterproductive uh but it is also an example of you may or may not want to split it out it depends on your exact use case it depends because you know you have your function call overheads so you may or may not want to split certain things out that would be up to your discretion but I wanted to use this as an example because I think it's quite a good example of how you could split an awful lot of code out cuz this is you know quite a long function into multiple different functions so we can Define three separate kind of sections in this so we have this section which requests our authorization we then have this section that fetches the code from the authorization server and then we have this section that actually fetches the tokens and we could split this out into three uh separate functions so if I to do doing is vowel again uh if I want to do request or oops it might no uh authorization and then we have secrets and we also want to pass in our redirect URI in here and then we want to return a DI string to string that's fine and we want to leave our redirect URI out because we want to share this across functions we could just move this in here and then put that there and then if we want to return we'll need to return the prams because we need that later we Define these prams in here again if you're unsure what's happening in this in this code accept exactly then you can go watch the o video to find out uh but we could simply say that our prams equals request oh misspelled the function I just realized request authorization there we go and now we've taken what was this 11 lines of code out and move them in here if we wanted to fetch the code create the function first uh we can do def fetch code and then we need the prams in here which is why we need to return them out and then we can simply move this out and put it into here we can then return this and say that our code equals fetch code Brams and then the same thing here so we have def fetch tokens and then that is a Secrets is the secrets the code and the redirect URI uh and then we move we can just move this out but in here we could say that we just want to return fch token Secrets redirect URI and encode and now we can see that this authorized method has been reduced from I don't know how many lines it was before actually quite a large number down to five and that's because we split it out into different sections we can now see if we were to look at this code we would see oh we're requesting authorization we're fetching the code and then we're fetching the tokens of course you could do the same thing with comments if you wanted to or a doc string um but this will just reduce complexity of individual functions and that may or may not be something you want to do it depends on the circumstance really if you have a function that is a few hundred lines long then you might want to split it out just for the sake of readability though it is a fine balance between uh introducing the performance over ahead of calling these additional functions in the case of this authorized method you're probably not going to be calling this that much so you could arguably say that splitting the function out to make it more readable is the better solution further to splitting out a function into multiple functions you can also split a file into multiple files and this is the topic of tip number four now there are some caveat to that again but I'll talk about those at the end so we could potentially in this particular instance we could if we wanted to take these two classes and move them out into their own file keep them separated and then just import them in so that's what we're going to do here so we're going to create or server.py going to go back in here we're going to get rid of these and then we're going to uh take our Imports and we're going to move them in as well we'll take that from URL li. import PA Q cell I did copy that didn't paste it what can you do and then we need to do from or uh server import server and now we have this server functionality in here but the actual definitions are in another file it does also work the other way as well in that you can split files out too far and then people are you know scrabbling around trying to look for things so if this file was significantly shorter and some people may actually believe um you know maybe we're looking at this and thinking God these these classes should be in this file or maybe they should in smaller files especially if you got a python package index which maybe exposes a function or two and maybe a class then you would want to keep it in one file just so people aren't searching through a full directory tree to find these things and the rule that I have about splitting things into multiple files and this is just my own rule uh would be that you need to promote a healthy but not excessive separation of of concerns so if you know if there is enough complex logic then you should split into files in such a way that each file has a particular purpose so a much larger example is my analytics Library I keep going back to this because it's my own project and of course I'm going to flog it wherever possible but inside this analytics folder is the actual code and there is quite a lot going on here so you have the client you have the authorization you have your errors you have your mixins you have your query uh shards utils ux but you'll notice that each of these files has a particular purpose so client.py is all the clients A.P is everything to do with authorization and this just makes things a lot easier to find so if I wanted to find the client class I could come in here and you'll notice that the client class is 892 lines long on its own so at that point yes you would definitely want to split out into multiple files what you could do though to clean something even more is utilize the init.py files and these allow you to import say the client into the init dop file and instead of having to do from analytics. client import client I can simply now do from analytics import client so it's as if it's in the same file but it is separated out into multiple files and you can bring them in using the in it and create this consistent and easy to use API for the user so it is a case of using your intuition to work out whether or not it's cleaner to keep things in one file or whether it's cleaner to keep things in a series of files but it's also down to your usage of what's available to you such as the init.py stuff um to be able to create consistent and userfriendly apis the fifth and final tip for this video is simply just use pep eight there is no excuse not to uh I said in the beginning of this video I'll say it again it is much easier to get into good habits and it is to break out of bad ones and pep eight is the best habit that you can get into early and the best thing about it is that you don't really have to think about it at all in modern day python there are plenty of tools to do it for you so if I go on the python packag IND deex and search black we'll have black there uh this is a a code formatter that formats using pep eight style there is iort which sorts all of your Imports alphabetically and in Pepe format which is really nice uh there's also linters so You' got things like rough which can actually do I sorts and black job I wouldn't necessarily use the format today I don't think it's production ready cuz it conflicts with the linter and to me that scream's not production ready but rough is there it's very quick it can find all of these things and help you make and it could do autofix as well actually so it can make your code very Pepe compliant very quickly the perfect python series which this video is a part of is literally dedicated to talking about all of these different tools that can help you do this so I'll link the series in the end cards and I'll I'll put it elsewhere as well so you can have a look at all those videos some of which dating back a very long time so you can see younger me if you really wanted to so there is literally no reason to not follow pep eight standards I would recommend just having a quick read through uh pep eight if you haven't already just to get an idea of you know what's good and what's not obviously if you code yourself using pep eight standards then that's even better but you see you you know a few times in this video even I haven't followed pep eight myself and the tools have automatically come to my rescue cuz you can just let them do that so those are five cool tips and tricks to help keep your code clean in Python let me know in the comments which ones are your favorites which ones you know already which ones you just learned today be really interesting to know as I said before if you want to know more about any of these tools or you want to keep up with how to keep your python code perfectly clean then I do have an entire series dedicated to it so recommend looking at the videos in those but I'll see you next time for whatever we do next oh tastes nice though still got some toothpaste on it
Info
Channel: Carberra
Views: 2,674
Rating: undefined out of 5
Keywords: pyfhon, pytho, pytbon, pytjon, ptyhon, pytyon, ptthon, pyyhon, pythn, pythoh, pythpn, ython, pytgon, pyhon, pytohn, phthon, oython, pthon, pyghon, pythoj, pythno, pythkn, ypthon, pytuon, lython, pyrhon, pythom, pythob, puthon, pgthon, python, pyhton, pythln, pythin, pytnon, pyton
Id: _WLq3B-h0qs
Channel Id: undefined
Length: 19min 13sec (1153 seconds)
Published: Mon Jun 17 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.