👉 To try everything Brilliant has to offer for free for a full 30 days, visit brilliant.org/TechWithTim . You'll also get a 20% discount on a premium subscription.
1. Simplify longer conditions into one variable. 2. Simplify nesting by reversing the direction of the condition. 3. Avoid ladder statements (several if-else) by: a) Creating a dictionary. Map the different values via key-value pairs. b) Alternatively, create an array and each value in the array corresponds to an index. 4. The Mega function. Split it up into logical smaller units of code 5. Remember to check for Edge Cases. Check for all possible things that can go wrong a) Raise custom errors that tells the user exactly what exactly went wrong and how to fix it.
You're trying to bring us all back to the dark ages, where people could read texts? Are texts still in use in 2024 anyway? The modern way seems to be a 20 minute 4K video which is way easier to store, and transmit with modern broadband data links, and easier to comprehend. =)
I would argue that the following code is a much better solution for Mistake #2. It showcases the use of the *range* function, the *filter* function, and *lambda* functions. def process_numbers(numbers): # store range once instead of repeatedly # recreating it while iterating over list proper_range = range(2, 100, 2); return filter(lambda n: n in proper_range, numbers); However, if the range is large, for example between 2 and 1000000, then we would want to avoid storing such a large list in memory, and instead manually apply the evenness and range checks, as shown in the code below. def process_numbers(numbers): return filter(lambda n: n % 2 == 0 && 0 < n < 1000000, numbers); Additionally, we could use *inner functions* to make the code perhaps even more readable, as shown below. def process_numbers(numbers): def is_even(num): return num % 2 == 0; def is_within_range(num): return 0 < num < 1000000; return filter(lambda n: is_even(n) && is_within_range(n), numbers);
I think Tim's video was targeted at beginners and so the showcased solutions on their level... but I must say that I love those intermediate/advanced level solution examples of yours. Wish to see that in day-to-day life :p
As in a conversation I had with a manager of some years ago said: Supervisor. "I'm not going to tell you how to do it..." Managed. "Yeah, but you'll be the first to let me know if I'm doing it wrong." We worked well together....
While the first example fix is fine for a general case, it has a different problem. It uses an if statement to just return true/false. In this simple case, just return the boolean expression.
I am also a fan of writing that sort of thing in reverse with early exits too. Writing if (! user.is_authenticated) return false; if (user.account_status != "active") return false; Just helps you keep less things in mind, eventually you wind up with a situation where multiple conditions combine and actually this page needs you to either allow anonymous submission or be logged in with permission or be an admin and if you do need to be logged in your account needs all the active stuff. Writing if (config.allow_anonymous_posting) return true; if (user.account_status != "active") return false; if (user.is_admin) return true; Etc just becomes a much nicer way to handle it than a single big boolean expression.
It's nice to see these coding advices/tutorials again. Got a bit more used to that content format rather than to the "How to become ____" videos through all the years I've been learning from your channel.
Hi Tim, I just found this interesting new topic of research on Machine Learning talking about how the new way of doing it in the future might likely be with liquid neural networks rather than static traditional ones. There were things like energy efficiency and learning new information during run-time (like how the human brain's neuroplasticity enables it to adjust to changes on the fly) that are supposed to make it mimic the human brain way more than traditional networks. So I thought you might be interested in this topic and potentially make a video about it if you think the topic's worth exploring! Also, love your videos :)
Tim, I love your approach in solving problem. Separating different components of program into functions. I gained alot with this your approach in one of your content. "Learn Python with one Project" ❤
In 4-fixed file, should we write necessary functions for process in a separate file, and then import into the main file?Is it a conventional way to write code like this?I am beginner to this ?Really appreciate and love your work bro ❤
Yes, write modular codes is good, only if you think it is, it'syour choice to decide. And yes, it is conventional to write like that, it is literally how it work in C.
16:55 Lines 5, 6 are redundant, huh? (lines 8..11 do the job) ;-) As for mistake #5 I have doubts. You will never prepare for all the possible cases, or it might be just overkill for the use case. When I was a toddler I read in some book that you should decide your trust strategy before you begin to implement the code. Say, your code should trust to the caller, or it should trust to the called subs, or there must be no trust at all, and everyone checks everything. Making a piece of code 'bullet-proof' is not always a good idea. Maybe if you write for some spaceship, then the more checks the better. I've seen code like `while (a != 0) a = 0;` and it was not a redundancy. But it looks stupid if inside a single lib two piece of code calling each other don't trust to each other. It also kills memory and CPU time. Btw, if I try to send a set or tuple with numbers into this 'better' version of calculate_average() I'll be surprised. Why it needs list and descendants if it actually can handle any kind of iterable? It's kind of stupid self-limiting design which is impossible to explain.
Good solution for the second example. But if you don't care about performance, there can be short clear alternatives. In this case using "if number in range(2, 100, 2):" is much clearer. Just make sure you never do this in code that might be called a lot.
I completely agree with the much shorter and clearer solution of using “in range(2, 100, 2)”. However, when needing to repeatedly make this check (in a loop), as in the video, you can easily avoid the performance hit by storing the return value of the “range” function call in a variable (for example named “result”), and then repeatedly executing “in result” (instead of “in range(2, 100, 2)”). Furthermore, the “filter” function can be used to iterate over the list of numbers and apply the range check, using a lambda function, to each number in the list. Applying the suggestions above result in much leaner and clearer code, as shown directly below. This solution is easier to read and understand, and also less error prone when making changes. def process_numbers(numbers): proper_range = range(2, 100, 2); return filter(lambda n: n in proper_range, numbers); However, if the range is much larger, say between 2 and 1,000,000, then of course it wouldn’t be appropriate to store such a large list in memory. Rather, the better solution would be to manually check for evenness, and for the range, as shown below. def process_numbers(numbers): return filter(lambda n: n % 2 == 0 && 0 < n < 1000000, numbers); You could even use inner functions to make the code perhaps more readable, as shown below. def process_numbers(numbers): def is_even(num): return num % 2 == 0; def is_within_range(num): return 0 < num < 1000000; return filter(lambda n: is_even(n) && is_within_range(n), numbers);
@@johnanderson290 some interesting points. But here are some things to consider. The range function returns an iter. If you want to pre-compute the reference, you need to convert it to a list. Comparing against all the values is expensive. That is why I pointed out that it was slow. My code will correctly return false on a non-numeric value. Several of your versions will blow up.
Are functions within functions considered bad? In trying to avoid error 5, I frequently create a number of input validating/sanitizing steps which can border or fall into error 4, a large function that is difficult to quickly grok. Is creating subfunctions within a function to do the input sanity checking considered maintainable or should all the sanity checking be peer level functions? Some of the sanity checking functions are nearly universal and for those it makes sense to be peer level, but a good chunk end up relating only to one specific function.
@@TechWithTim Thanks. I try to restrict it to one layer, so with code folding I can tell what the sanity checking steps are by the names before getting to the meat of the function itself.
I have seen some really bad code in my professional career Even comments that say We now call our recursive private constructor Neeto “gag” It was creating a n-ary tree from a list
"If numbers" will return False if the "numbers" list is empty AND if the "numbers" is None. In the given example, we specifically want to have different behavior for those two conditions - None raises TypeError, empty list returns 0 as average result without raising any error. Even tho we already covered the "is None" condition with "isInstance" function (first line of the "fixed #5") (only this way replacement you proposed works correctly for a given scenario), I think we should stick to len(numbers)==0 for the sake of code clarity :D
@@Ursus_major37 The “if numbers” check evaluates if the numbers list is empty. You can have either numbers = [] OR numbers = None it can’t be both. Using “if numbers” will evaluate to false in both scenarios which is a desired outcome, but it’s not an AND check.
So what does continue actually continue? Because its use here is the opposite of my intuition. Like in this example, if it's true that it's not a number, the use of continue seems to me to mean that that was the desired result so the program should continue on to the next test. If it's out of range or is odd the program should continue on to appending the number. Does continue mean leave the function without appending, because that is the exact opposite of what I would expect that command to do.
mr tim make me uderstand on how to apply coursesCareers and the payments plan after that is it guarantee that I will get the job immediately after completing the course and are u the one who will give me the job I need your response plz
No, no legitimate course can guarantee you a job. Of course we will do out best to prepare you and help you along the way but we cannot promise you will land a job.
👉 To try everything Brilliant has to offer for free for a full 30 days, visit brilliant.org/TechWithTim . You'll also get a 20% discount on a premium subscription.
Love from Pakistan ❤❤❤
1. Simplify longer conditions into one variable.
2. Simplify nesting by reversing the direction of the condition.
3. Avoid ladder statements (several if-else) by:
a) Creating a dictionary. Map the different values via key-value pairs.
b) Alternatively, create an array and each value in the array corresponds to an index.
4. The Mega function. Split it up into logical smaller units of code
5. Remember to check for Edge Cases. Check for all possible things that can go wrong
a) Raise custom errors that tells the user exactly what exactly went wrong and how to fix it.
Many thanks
Thanks Man. I found it helpful
You're trying to bring us all back to the dark ages, where people could read texts? Are texts still in use in 2024 anyway?
The modern way seems to be a 20 minute 4K video which is way easier to store, and transmit with modern broadband data links, and easier to comprehend. =)
6:40 An alternative that you can leverage: match and case. It generates a look up table during run-time so it matches instead of checks.
this guys really make me wanna keep learning no matter how unmotivated I am, thanks a lot Tim!
That’s great .Me too😅
I would argue that the following code is a much better solution for Mistake #2. It showcases the use of the *range* function, the *filter* function, and *lambda* functions.
def process_numbers(numbers):
# store range once instead of repeatedly
# recreating it while iterating over list
proper_range = range(2, 100, 2);
return filter(lambda n: n in proper_range, numbers);
However, if the range is large, for example between 2 and 1000000, then we would want to avoid storing such a large list in memory, and instead manually apply the evenness and range checks, as shown in the code below.
def process_numbers(numbers):
return filter(lambda n: n % 2 == 0 && 0 < n < 1000000, numbers);
Additionally, we could use *inner functions* to make the code perhaps even more readable, as shown below.
def process_numbers(numbers):
def is_even(num):
return num % 2 == 0;
def is_within_range(num):
return 0 < num < 1000000;
return filter(lambda n: is_even(n) && is_within_range(n), numbers);
I think Tim's video was targeted at beginners and so the showcased solutions on their level... but I must say that I love those intermediate/advanced level solution examples of yours. Wish to see that in day-to-day life :p
As in a conversation I had with a manager of some years ago said:
Supervisor. "I'm not going to tell you how to do it..."
Managed. "Yeah, but you'll be the first to let me know if I'm doing it wrong."
We worked well together....
"Do 1,000 things right and no one will remember. Do one thing wrong and no one will let you forget." - Drill Sergeant Phillips
While the first example fix is fine for a general case, it has a different problem. It uses an if statement to just return true/false. In this simple case, just return the boolean expression.
I am also a fan of writing that sort of thing in reverse with early exits too.
Writing
if (! user.is_authenticated) return false;
if (user.account_status != "active") return false;
Just helps you keep less things in mind, eventually you wind up with a situation where multiple conditions combine and actually this page needs you to either allow anonymous submission or be logged in with permission or be an admin and if you do need to be logged in your account needs all the active stuff.
Writing
if (config.allow_anonymous_posting) return true;
if (user.account_status != "active") return false;
if (user.is_admin) return true;
Etc just becomes a much nicer way to handle it than a single big boolean expression.
It's nice to see these coding advices/tutorials again. Got a bit more used to that content format rather than to the "How to become ____" videos through all the years I've been learning from your channel.
Great straightforward content
I always learn something
Thanks Tim!
Thanks, Tim for the advice... as always... you are my hero!
Best practices is what I need, how the syntax works is what the docs are for, this video here is added value to go pro.
Nicely presented. Thank you!
Hey Tim can you do a video discussing Devops roadmap
Hi Tim, I just found this interesting new topic of research on Machine Learning talking about how the new way of doing it in the future might likely be with liquid neural networks rather than static traditional ones. There were things like energy efficiency and learning new information during run-time (like how the human brain's neuroplasticity enables it to adjust to changes on the fly) that are supposed to make it mimic the human brain way more than traditional networks. So I thought you might be interested in this topic and potentially make a video about it if you think the topic's worth exploring! Also, love your videos :)
Tim, I love your approach in solving problem. Separating different components of program into functions. I gained alot with this your approach in one of your content. "Learn Python with one Project" ❤
In 4-fixed file, should we write necessary functions for process in a separate file, and then import into the main file?Is it a conventional way to write code like this?I am beginner to this ?Really appreciate and love your work bro ❤
Yes, write modular codes is good, only if you think it is, it'syour choice to decide. And yes, it is conventional to write like that, it is literally how it work in C.
Thank you for this.
16:55 Lines 5, 6 are redundant, huh? (lines 8..11 do the job) ;-)
As for mistake #5 I have doubts. You will never prepare for all the possible cases, or it might be just overkill for the use case. When I was a toddler I read in some book that you should decide your trust strategy before you begin to implement the code. Say, your code should trust to the caller, or it should trust to the called subs, or there must be no trust at all, and everyone checks everything. Making a piece of code 'bullet-proof' is not always a good idea. Maybe if you write for some spaceship, then the more checks the better. I've seen code like `while (a != 0) a = 0;` and it was not a redundancy.
But it looks stupid if inside a single lib two piece of code calling each other don't trust to each other. It also kills memory and CPU time.
Btw, if I try to send a set or tuple with numbers into this 'better' version of calculate_average() I'll be surprised. Why it needs list and descendants if it actually can handle any kind of iterable? It's kind of stupid self-limiting design which is impossible to explain.
Good solution for the second example. But if you don't care about performance, there can be short clear alternatives. In this case using "if number in range(2, 100, 2):" is much clearer. Just make sure you never do this in code that might be called a lot.
I completely agree with the much shorter and clearer solution of using “in range(2, 100, 2)”. However, when needing to repeatedly make this check (in a loop), as in the video, you can easily avoid the performance hit by storing the return value of the “range” function call in a variable (for example named “result”), and then repeatedly executing “in result” (instead of “in range(2, 100, 2)”).
Furthermore, the “filter” function can be used to iterate over the list of numbers and apply the range check, using a lambda function, to each number in the list.
Applying the suggestions above result in much leaner and clearer code, as shown directly below. This solution is easier to read and understand, and also less error prone when making changes.
def process_numbers(numbers):
proper_range = range(2, 100, 2);
return filter(lambda n: n in proper_range, numbers);
However, if the range is much larger, say between 2 and 1,000,000, then of course it wouldn’t be appropriate to store such a large list in memory. Rather, the better solution would be to manually check for evenness, and for the range, as shown below.
def process_numbers(numbers):
return filter(lambda n: n % 2 == 0 && 0 < n < 1000000, numbers);
You could even use inner functions to make the code perhaps more readable, as shown below.
def process_numbers(numbers):
def is_even(num):
return num % 2 == 0;
def is_within_range(num):
return 0 < num < 1000000;
return filter(lambda n: is_even(n) && is_within_range(n), numbers);
@@johnanderson290 some interesting points. But here are some things to consider.
The range function returns an iter. If you want to pre-compute the reference, you need to convert it to a list.
Comparing against all the values is expensive. That is why I pointed out that it was slow.
My code will correctly return false on a non-numeric value. Several of your versions will blow up.
Are functions within functions considered bad? In trying to avoid error 5, I frequently create a number of input validating/sanitizing steps which can border or fall into error 4, a large function that is difficult to quickly grok. Is creating subfunctions within a function to do the input sanity checking considered maintainable or should all the sanity checking be peer level functions? Some of the sanity checking functions are nearly universal and for those it makes sense to be peer level, but a good chunk end up relating only to one specific function.
Nested functions are “okay” but you want to avoid doing it too often as it’s just harder to read the more nesting you have going on
@@TechWithTim Thanks. I try to restrict it to one layer, so with code folding I can tell what the sanity checking steps are by the names before getting to the meat of the function itself.
I have seen some really bad code in my professional career
Even comments that say
We now call our recursive private constructor
Neeto “gag”
It was creating a n-ary tree from a list
In the first mistake, you can also use all() Python function. It tests if all conditions (inside an iterable) are true. Else, return false
YES, it looks clean. But naming variables and functions is hard :D
Thank you for your tips Tim! They are all so useful in daily life 💪
very useful, thx, bro.😁😁😁
In #5 you don’t need to check if the length is 0. Just put “if numbers:”
"If numbers" will return False if the "numbers" list is empty AND if the "numbers" is None.
In the given example, we specifically want to have different behavior for those two conditions - None raises TypeError, empty list returns 0 as average result without raising any error.
Even tho we already covered the "is None" condition with "isInstance" function (first line of the "fixed #5") (only this way replacement you proposed works correctly for a given scenario), I think we should stick to len(numbers)==0 for the sake of code clarity :D
@@Ursus_major37 The “if numbers” check evaluates if the numbers list is empty. You can have either numbers = [] OR numbers = None it can’t be both. Using “if numbers” will evaluate to false in both scenarios which is a desired outcome, but it’s not an AND check.
@@TN-cx4qi yes, you are right - I wasn't precise with 'AND', what I meant is it checks either it is empty list or None
Thanks 🤝
You could have also defined a function, which returns true, if the numbers is valid and else whatever you want it to say.
Nice job, I like that you readability over conciseness. Creating a dictionary is a great idea.
The first point is what my team does not understand, they like complexity hard to read code with lots of implementation details.
Where did you buy that background wall from?
Nevermind...I found it on Amazon as an acoustic sound diffuser panel.
So what does continue actually continue? Because its use here is the opposite of my intuition. Like in this example, if it's true that it's not a number, the use of continue seems to me to mean that that was the desired result so the program should continue on to the next test. If it's out of range or is odd the program should continue on to appending the number. Does continue mean leave the function without appending, because that is the exact opposite of what I would expect that command to do.
Continue means “continue with the looping process.”
It ends the current iteration and proceeds to the next iteration of the loop.
@@rootytuners Got it, thanks. Still not the best name lol
For example five, passing a non-number should raise an error.
new to coding but am eager to become a talented data scientist!! n = ALL
Who else loves coding
Moi!
Love coding but hate the fact that can land even an internship in my god damn country.
I'm love from coding
Scripting…
No one. We're just torturing ourselves by watching these boring, long videos
mr tim make me uderstand on how to apply coursesCareers and the payments plan after that is it guarantee that I will get the job immediately after completing the course and are u the one who will give me the job
I need your response plz
No, no legitimate course can guarantee you a job. Of course we will do out best to prepare you and help you along the way but we cannot promise you will land a job.
@@TechWithTim thank uh understand it but is 3 weeks enough for me to be a good programmer like pro
The mega function is just crazy. Makes me feel like my IQ is 70 😝😜😜
The 'continue' option is _really great_ in simplifying and making code even more readable 👍
🤚❤❤❤
1st comment ❤❤❤
And from Pakistan ❤❤❤😊
is there anything for the first viewers and commenters and likers
thank you tim 🫶🫶🫶🫶🫶
is there anything for the first viewers and commenters and likers
a heart
@@TechWithTim what does that mean bruh
@@BUSSINESS_REVIEWS what do u want lol
@@TechWithTim a free course for frontend and backend development?
@@BUSSINESS_REVIEWSyeah like you've survived world war by being the first viewer lmao.