This guide provides a solid, systematic framework for writing clean Python code by prioritizing clarity and maintainability. It effectively bridges the gap between basic coding and professional software engineering practices.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
How to design a good function in Python
Added:How's it going everyone? In today's video, I'm going to show you how to design really nice functions in Python in only nine simple steps. Now, before we begin, I just like to thank Zed for sponsoring this video. Zed is a lightning-fast code editor written in Rust, and I've been using it to do all my coding for a while now. If you feel like trying out Zed, I've left a link in the description box down below where you can download it for free. Anyway, let's get back to the video. The first step is to determine what you want your function to do. For this example, we're going to create a function that counts the vowels of any given string and returns the result as an integer. That will be the baseline. The second step is to list the steps of your function, and this can either be written on paper, in Notepad, or even in pseudocode, and it should end up looking something like this. Starting with the first step, which is to count the vowels in any given string and return an integer. Step two checks whether the argument is of type string.
If it's not, we raise a type error that includes the type that the user passed in. The third step states which vowels will be included. We make sure to handle both uppercase and lowercase, and then we store that string in a variable called vowels for clarity. And finally, for step four, we create a comprehension to count all the vowel occurrences. This list comprehension will be wrapped by the built-in sum function, which will be returned as an integer. And now that we have a plan, we can move on to the third step, which is to think of a meaningful name for the function. For this example, we will write def count vowels. This is a good name because it's simple, concise, and straight to the point. If the user is still confused, they can consult the docstring. The fourth step is to give your parameters meaningful names and type annotations for clarity.
This function will take one string as an argument, which can be any text. So, we will name this parameter text and tell Python that it should be of type string.
This is perfect for clarity. The fifth step is to specify the return type, and this is a really good habit to get into because static type checkers and code editors will warn you if you're being silly and accidentally return the wrong type. It also self-documents the function. Other devs who look at this function will know at a single glance and what it returns. In this case, we want to return an integer. So, we will specify that in the function signature by typing arrow int. The sixth step is to actually code the function. Make sure to keep the logic as simple as you can.
If your function does more than one job, you should consider creating a class with several methods instead. For this example, we will continue by checking that the argument that the user provides is of type string. This isn't absolutely necessary since modern code editors will warn you that you're passing in the wrong type, but if this function is used somewhere else, it would be nice for the user to quickly understand why the function isn't working with their given inputs. So, if text is not an instance of string, we will raise a type error explaining what went wrong. And how stupid proof you make your function will always be up to you. There's a limit to how much you can plan for, but it's definitely nice to cover any realistic cases. In this case, I can absolutely see some users thinking that they can pass in a path or something similar instead of just a string. And in that case, it would be best to inform them that the function only accepts strings.
Then below, we can define the vowels we want to include. Creating this as a variable makes it easier for us to come back later and edit it because we will immediately be able to spot a meaningful name. And finally, as a matter of preference, I decided to perform the entire counting operation in a list comprehension to save on space since the logic is fairly simple. Well, technically this is a generator comprehension, but what matters here is that I'm using a comprehension. And all I'm doing is appending one for each letter in the text if the letter is in the vowels, and finally returning the sum of all those ones. For me, this is very easy to read and edit, but if you're not comfortable with comprehensions, feel free to use a for loop. For the majority of cases in Python, readability will be more important than cool one-liners. The seventh step is to try to break your function by testing it with all forms of input. I'd recommend using something like the pytest framework for simple testing, but the idea is simple. You want to ensure that your function works reliably. For this example, we're just going to test it directly in the same script, and I'm also going to import Path from pathlib because I want to use it as one of the inputs. Then below, I'm going to create a dictionary of inputs and what the expected results should be.
For example, this string should give us an output of six since there are six vowels in this string. An empty string should give us an output of zero. These 10 vowels should give us an output of 10. Then this string should give us an output of five. And all I want to demonstrate here is that case doesn't matter and that Y is not counted. Then I want to make sure that inserting the incorrect type ends up giving us a TypeError. Below that, we're going to loop through all of these inputs and make sure that the function is behaving the way we expect it to. So, what we're going to do is try the following code.
The first line checks that the function returns the correct result. Then we print the input and whether it passed the test. If we run into a TypeError, we're going to want to do the same thing. But this time, we want to make sure that it is the error that we are expecting. And then we can print whether this test passed. Now, when we run this, what we should get are six calls to this function with different inputs. You'll notice that each input will be present in the function call, and the result we're expecting will also be present. If the test passes, passed will return true. So, all of these tests passed. If we pass in something such as true or a path, we will end up with a type error, which is exactly what we want to happen in that case. Now, if we were to insert something such as Bob and expect an output of five, you'll notice that this test will have failed because Bob contains only one vowel, and what we expected were five vowels. So, you still have to be careful when you are creating tests because you can still make mistakes here. The goal here is to test the function with all the possible inputs just to make sure the function is working exactly as expected. And again, please use a dedicated framework for testing. What I showed you here is purely conceptual. The eighth step is to add docstrings that explain your function and include a few examples. For example, here we can include a docstring that gives a short description of the function. This function counts the number of vowels in a given string, excluding lowercase y and uppercase y.
Then we have three examples of how it works. The examples are probably my favorite part of docstrings. They show you exactly what to expect from a function without having to even run the code. Although, I'm going to be quite honest with you, I rarely write docstrings, especially if I'm creating a function for myself that I don't expect anyone else to ever see. Not to mention that a function as simple as this one doesn't really gain anything from stating what it already does. The function signature already explains everything. And in some cases, it's better not to be redundant. But that's another thing you're going to have to determine for yourself. I do absolutely love examples though. It's kind of like some kid showing you how to do a backflip by doing a backflip. You get to see the action before doing anything yourself. And finally, the ninth step, which is to pat yourself on the back because you now have a function that you never have to create again. Save it somewhere for later. Or, if you want to take it a step further, post it on Stack Overflow and get roasted. The burn might hurt a bit, but it will be worth it.
Anyway, do let me know in the comment section down below if you learned something new, or if you have some good tips of your own for creating the perfect function. I'd love to hear about it. But otherwise, with all that being said, as always, thanks for watching, and I'll see you in the next video.
Related Videos
This Machine Still Runs on Punch Cards
WaltersShortsChannel
6K views•2026-06-10
GitLab’s Manav Khurana: AI Agents, Orbit, and the Future of Coding
TechVoices-live
374 views•2026-06-10
I Made an Antivirus That Secretly Attacks Scammers
ScammerPayback
153K views•2026-06-13
Your Python loops are probably slower than they need to be. One simple decorator can instantly bo...
60SecondStack
236 views•2026-06-11
Leetcode Weekly Contest 506 | Life's boring these days
Pudeesht
2K views•2026-06-14
Partitioning vs Bucketing vs Clustering: How to Make Queries 100x Faster
thedataandaiguy
194 views•2026-06-16
Programming in English
MattGodbolt
584 views•2026-06-14
I thought this feature would be easy to deploy... I was wrong.
dreamsofcode
815 views•2026-06-10
Trending
This 80 year old corn is dangerous
NileBlue
1569K views•2026-06-10
Everyone around him is insane.
LeoinFrames-1
2406K views•2026-06-13
It does nothing, but men have worn it for 400 years. Behind the origin of the necktie
FineasJackson
1423K views•2026-06-12
Scientists Create Indestructible Medicine
DrBenMiles
628K views•2026-06-11











