10 Tips to Become REALLY Good at Python

00:27:39
https://www.youtube.com/watch?v=zml0rTMJVXg

概要

TLDRThe video presents ten vital tips for improving as a Python developer. These tips include mastering comprehensions for concise code, utilizing f-strings for efficient string formatting, and knowing built-in functions that simplify coding tasks. Generators are highlighted for their memory efficiency, while context managers ensure proper resource management. It emphasizes using libraries like Pandas and NumPy to streamline tasks and encourages implementing type annotations for better code readability. Abstraction principles and effective testing practices with PyTest are discussed for writing maintainable code. Finally, the video concludes by advising on the appropriate use of classes and functions within code architecture.

収穫

  • 🚀 Master comprehensions for concise code.
  • 💡 Use f-strings for effective string formatting.
  • 🔎 Familiarize yourself with built-in functions.
  • 📊 Implement generators for memory-efficient operations.
  • 🔧 Utilize context managers for resource management.
  • 📚 Leverage libraries like Pandas and NumPy.
  • 📜 Use type annotations for clarity.
  • 🔄 Practice abstraction for code decoupling.
  • ✅ Write tests to ensure code reliability.
  • ⚙️ Choose classes, data classes, or functions wisely.

タイムライン

  • 00:00:00 - 00:05:00

    In this video, the speaker shares 10 tips to elevate Python programming skills. The first tip emphasizes mastering comprehensions, which make code more concise and Pythonic by allowing developers to create lists, dictionaries, sets, and even generators with ease. Examples demonstrate how comprehensions can be utilized to compute squares of numbers, map keys to values in dictionaries, and filter unique items in sets.

  • 00:05:00 - 00:10:00

    The second tip promotes the use of f-strings for string formatting in Python, showcasing their power and flexibility over traditional methods. Examples include decimal precision formatting, adding thousands separators, and even debugging syntax, which prints both expressions and their results, facilitating easier code inspection. The speaker warns against using f-strings to construct SQL queries due to security risks.

  • 00:10:00 - 00:15:00

    Next, the speaker advises developers to harness Python's built-in functions, which can simplify code and save time. These include functions like min, max, zip, enumerate, and complex operations with any, all, map, and filter. The speaker also emphasizes how using built-in functions can lead to cleaner and more efficient Python code through practical examples.

  • 00:15:00 - 00:20:00

    A crucial aspect highlighted is the efficiency of using generators for iteration, allowing developers to manage memory effectively when working with large datasets. Generators only compute the required values when explicitly requested, showcasing their utility with practical examples and explaining how they can be used in scenarios involving functions yielding results on-the-fly, preserving system memory during operations.

  • 00:20:00 - 00:27:39

    The speaker then discusses the importance of using context managers to handle resource management automatically, ensuring proper cleanup, especially with files and database connections. Following this, the video introduces the rich ecosystem of Python libraries such as Pandas, NumPy, and scikit-learn, emphasizing their role in simplifying complex tasks and speeding up development processes.

もっと見る

マインドマップ

ビデオQ&A

  • What are comprehensions in Python?

    Comprehensions allow for creating lists, dictionaries, sets, and generators in a concise manner.

  • What are f-strings?

    F-strings are a powerful way to format strings that are concise, readable, and support advanced formatting.

  • What is a generator?

    Generators are functions that produce values over time using the yield keyword, allowing for memory-efficient iteration.

  • Why use context managers?

    Context managers automate resource management, ensuring resources are properly closed or cleaned up.

  • What is the importance of testing in Python?

    Testing creates a safety net that ensures your code works as intended, especially after modifications.

  • What are type annotations?

    Type annotations improve code clarity by explicitly indicating expected data types for function parameters and return values.

  • What is the difference between a class and a data class?

    Classes encapsulate data and behavior, while data classes focus on storing structured data with less boilerplate.

  • How can I improve my Python coding skills?

    Hands-on practice, utilizing resources like Brilliant, and working on real projects are effective ways to improve.

  • What libraries are recommended for Python development?

    Common libraries include Pandas for data manipulation, NumPy for numerical operations, and Matplotlib for plotting.

  • What is abstraction in Python?

    Abstraction separates code functionality from implementation details, enhancing code cleanliness and decoupling.

ビデオをもっと見る

AIを活用したYouTubeの無料動画要約に即アクセス!
字幕
en
オートスクロール:
  • 00:00:00
    Today I'll share 10 tips that can take you from a good Python developer to a great one.
  • 00:00:06
    In particular, the last tip is something that I see a lot of developers struggle with,
  • 00:00:10
    so make sure you watch this video to the end to get the most out of it.
  • 00:00:14
    This video is sponsored by Brilliant. More about them later.
  • 00:00:17
    The first tip is to master comprehensions.
  • 00:00:19
    Comprehensions in Python aren't just for lists.
  • 00:00:22
    They work for dictionaries, sets, and even generators.
  • 00:00:25
    By mastering them, you'll write more concise and more Pythonic code.
  • 00:00:29
    List comprehensions are the most common, and they allow you to create lists in a single line.
  • 00:00:34
    I have an example here of a few different types of comprehensions,
  • 00:00:37
    and I know, blasphemy, I'm using a Jupyter notebook here, but they are actually quite handy.
  • 00:00:41
    So here's an example of a list comprehension that just generates squares of even numbers.
  • 00:00:47
    So when I run this, then we get the result that you see right here.
  • 00:00:52
    So this is just a single line, and that allows us to create a list.
  • 00:00:55
    But you can do list comprehensions for other types of data structures as well.
  • 00:00:58
    For example, here I'm mapping numbers to their queues, and I'm putting that in a dictionary.
  • 00:01:04
    So that looks like this. So this is a dictionary comprehension.
  • 00:01:09
    You can also use set comprehensions.
  • 00:01:11
    These are similar to list comprehensions, except they don't contain any duplicate values.
  • 00:01:16
    So, for example, here I have a list of words,
  • 00:01:19
    and I'm going to compute the unique length using a set comprehension like so.
  • 00:01:25
    And that's going to give us a set with two values, 5 and 6.
  • 00:01:29
    So it's going to remove the duplicate values.
  • 00:01:31
    Now, similar to these comprehensions, you can also use generators.
  • 00:01:35
    These look almost the same, but they use parentheses.
  • 00:01:38
    The difference between this type of structure and the list comprehension you saw at the start right here
  • 00:01:43
    is that this is actually evaluated lazily.
  • 00:01:46
    So the value is only computed when you actually call it.
  • 00:01:51
    So you can see it just prints these values, goes through them with a for loop,
  • 00:01:55
    but these values are only computed when we actually call the function.
  • 00:01:59
    And you can even nest comprehensions if you want to do, let's say,
  • 00:02:02
    multidimensional data processing or something.
  • 00:02:04
    So let's say we have a matrix here.
  • 00:02:06
    Then you can use a list comprehension here,
  • 00:02:08
    which takes the num for the row in the matrix for each number in a row.
  • 00:02:14
    And then that's going to print a flattened list like so.
  • 00:02:18
    And that happens because of this nested comprehension that you see right here.
  • 00:02:22
    The second tip is to use f-strings for string formatting.
  • 00:02:25
    F-strings are a really powerful way to format strings in Python.
  • 00:02:28
    They're concise, they're readable, they support advanced formatting features
  • 00:02:32
    for numbers, dates, and more.
  • 00:02:34
    So let me start off easy here with a simple f-string
  • 00:02:37
    that interpolates a name and a level and then constructs a new string.
  • 00:02:41
    So when I run this, then we get this as a result.
  • 00:02:44
    Now, instead of simply referring to variables,
  • 00:02:47
    you can actually also put expressions in here.
  • 00:02:49
    So, for example, I have a variable containing an age, 30,
  • 00:02:53
    and then I construct an f-string, but in between these braces,
  • 00:02:58
    I can actually write an expression like this, age plus 10.
  • 00:03:01
    And then when I run this, it's going to compute this as you would expect.
  • 00:03:04
    Now, next to simply including these values in strings,
  • 00:03:08
    you can also format numbers with a certain precision
  • 00:03:11
    or put them in a more human-readable format.
  • 00:03:14
    For example, let's say we have a value for pi,
  • 00:03:17
    and this, of course, is not a very precise version of pi.
  • 00:03:20
    This might actually be the Doom version of pi, I'm not entirely sure.
  • 00:03:24
    But what you can do with f-strings, you can actually format them.
  • 00:03:27
    So this is going to display a floating point version of pi
  • 00:03:31
    that is rounded to two decimals.
  • 00:03:34
    So when I run this, we're going to get 3.14.
  • 00:03:37
    And you can also use formatting to make things more readable.
  • 00:03:40
    For example, if you add a comma behind a number like this,
  • 00:03:44
    then it's going to add thousands of separators to it.
  • 00:03:48
    So there you see, then we get this as a result.
  • 00:03:50
    So that makes it a lot easier to read.
  • 00:03:52
    You can also display percentage, so that's what you see right here.
  • 00:03:55
    And as you can see, it presents a percentage
  • 00:03:58
    with a precision of one decimal.
  • 00:04:01
    So if I add, let's say, more precision here,
  • 00:04:03
    then I'm going to run this again.
  • 00:04:05
    You can see it still displays this single decimal.
  • 00:04:08
    I can change this to, for example, two.
  • 00:04:10
    And then we're going to get this as a result.
  • 00:04:13
    You can also use f-strings with date-time objects.
  • 00:04:16
    So here I'm importing date-time,
  • 00:04:19
    and then I'm creating the current date and time as of recording this video.
  • 00:04:24
    And then you can use these types of formats
  • 00:04:26
    to indicate how the date or the time should be printed.
  • 00:04:29
    And then this is what you're going to get as a result.
  • 00:04:32
    As you can see, I'm recording this like a week before Christmas,
  • 00:04:35
    and you're actually only seeing this in 2025.
  • 00:04:38
    What you can also do is text alignment,
  • 00:04:40
    and that's actually also really powerful
  • 00:04:42
    if you want to format outputs
  • 00:04:44
    and display them neatly in the table or something.
  • 00:04:46
    Here you see some examples of that.
  • 00:04:48
    So this is how you left-align a particular value
  • 00:04:52
    and want this to take up minimum 10 characters.
  • 00:04:55
    And you can do the same thing for right-aligned and also for centered.
  • 00:04:58
    So this is what that looks like.
  • 00:05:00
    So left, right, centered.
  • 00:05:02
    And you can change these numbers.
  • 00:05:04
    So let's say I'm going to turn this into 20 instead.
  • 00:05:09
    So then you will see it's simply going to move all of this text to the right
  • 00:05:13
    and it's going to change the alignment like so.
  • 00:05:16
    But if I change this back to 10
  • 00:05:19
    and I'm using a longer string like so,
  • 00:05:23
    well, then actually there is no alignment that's going to happen
  • 00:05:26
    because the string is actually longer than the 10 characters
  • 00:05:29
    that I've provided here as a setting.
  • 00:05:32
    So that's how alignment works.
  • 00:05:34
    Final thing I want to show you with fStrings,
  • 00:05:36
    and that's a really cool feature that I use all the time,
  • 00:05:38
    is that it supports a debugging syntax
  • 00:05:41
    and that allows you to display both the expression and the result.
  • 00:05:45
    So in this case, I have a value of 42.
  • 00:05:48
    And if you write an equal statement behind that,
  • 00:05:51
    it's also going to print the name of the variable.
  • 00:05:54
    So before we did this,
  • 00:05:57
    and then it's simply going to display the value.
  • 00:05:59
    If you write the equal statement behind it,
  • 00:06:01
    it's going to also print the name of the variable.
  • 00:06:04
    And it even displays expression.
  • 00:06:07
    So if I do, let's say, value plus 30,
  • 00:06:10
    then it's going to display the computed value,
  • 00:06:13
    but it's also going to display the expression.
  • 00:06:15
    So this is really great for quickly debugging things,
  • 00:06:18
    even though if you're seriously debugging some piece of code,
  • 00:06:21
    you should probably use the VS Code debugger.
  • 00:06:24
    And then you can also specify watch expressions
  • 00:06:26
    that achieve the same results.
  • 00:06:28
    fStrings are great for most formatting needs in Python.
  • 00:06:32
    However, if you're formatting strings dynamically,
  • 00:06:34
    for example, building templates,
  • 00:06:36
    consider string.format or the template class
  • 00:06:40
    from the string module for more advanced use cases.
  • 00:06:43
    Also, don't use fStrings to construct SQL queries.
  • 00:06:46
    fStrings don't escape values,
  • 00:06:48
    so that's going to leave you open to SQL injection attacks.
  • 00:06:51
    Instead, use a prepared statement.
  • 00:06:53
    fString formatting takes a bit of time to get used to,
  • 00:06:56
    but in my opinion, the best way of learning is by doing.
  • 00:06:59
    For example, if you want to become better at Python,
  • 00:07:01
    don't just watch my videos,
  • 00:07:02
    but work on solving actual problems with the language,
  • 00:07:05
    like you can do with today's sponsor, Brilliant.
  • 00:07:08
    Brilliant has thousands of interactive lessons in programming,
  • 00:07:12
    including Python, but also math, data analysis,
  • 00:07:15
    programming, and AI.
  • 00:07:17
    Using Brilliant is an effective way
  • 00:07:19
    to support your skill development
  • 00:07:21
    because their first principles approach
  • 00:07:23
    helps you build understanding from the ground up.
  • 00:07:25
    Brilliant helps build your critical thinking skills
  • 00:07:28
    through hands-on problem solving, not memorizing.
  • 00:07:31
    So while you're building real knowledge on specific topics,
  • 00:07:35
    you're also becoming a better thinker.
  • 00:07:37
    Learning a little every day
  • 00:07:38
    is one of the most important things you can do,
  • 00:07:40
    both for your personal and professional growth.
  • 00:07:43
    Brilliant makes it easy to learn anywhere right on your phone
  • 00:07:46
    with fun lessons you can do whenever you have some time.
  • 00:07:49
    Myself, I've been using Brilliant
  • 00:07:51
    to learn more about data science and AI.
  • 00:07:53
    Brilliant recently launched a ton of new data science content,
  • 00:07:56
    all of which uses real-world data
  • 00:07:58
    to train you to see trends and make better informed decisions.
  • 00:08:02
    For example, here's an interesting case study
  • 00:08:04
    that analyzes Airbnb data
  • 00:08:06
    and finds the best place to buy a rental property.
  • 00:08:09
    To try everything, Brilliant has to offer for free
  • 00:08:12
    for a full 30 days.
  • 00:08:13
    Visit brilliant.org/ArjanCodes or scan the QR code on screen
  • 00:08:18
    or click the link in the description.
  • 00:08:20
    You'll also get 20% off an annual premium subscription.
  • 00:08:24
    Third tip is to know built-in functions.
  • 00:08:26
    Python's built-in functions are incredibly powerful
  • 00:08:29
    and often overlooked.
  • 00:08:30
    They can simplify your code, make it more Pythonic,
  • 00:08:33
    and save you time.
  • 00:08:34
    Spoiler alert, soon I'm going to publish a video
  • 00:08:37
    covering built-in functions in more detail.
  • 00:08:39
    Now, you probably know functions like min, max, round, and len,
  • 00:08:43
    but how about the following ones?
  • 00:08:45
    For example, you can use enumerate to loop through an iterable
  • 00:08:48
    and then also keep track of the index.
  • 00:08:50
    That's what you see here.
  • 00:08:51
    So I have a list of items,
  • 00:08:53
    and then I'm using enumerate to go through the items,
  • 00:08:56
    and I also have the index.
  • 00:08:58
    So when I run this, I can do something with the index.
  • 00:09:00
    Really helpful.
  • 00:09:01
    And then there's also zip,
  • 00:09:02
    which is going to combine two or more iterables element-wise,
  • 00:09:06
    and then it creates tuples from them.
  • 00:09:08
    So I can have a list of names and a list of scores,
  • 00:09:12
    and then I can use zip to combine them
  • 00:09:14
    and then iterate over name and score at the same time.
  • 00:09:17
    And then this is what you get.
  • 00:09:19
    Also quite useful is any and all.
  • 00:09:22
    So if I have a list of numbers like so,
  • 00:09:24
    then any of those numbers is going to output true if any of the values are truthy.
  • 00:09:30
    In Python, a value is considered truthy if it evaluates to true in a Boolean context.
  • 00:09:36
    Examples of truthy values include non-zero numbers,
  • 00:09:39
    non-empty strings, lists, and other objects.
  • 00:09:42
    Falsy values like zero,
  • 00:09:44
    none, false, and empty collections evaluate to false.
  • 00:09:48
    And that's also what you see in this particular example,
  • 00:09:51
    where if you run this, you take this list of numbers.
  • 00:09:53
    So any is going to output true because there are truthy values in this list of numbers,
  • 00:09:59
    whereas all is going to output false because there are some falsy values,
  • 00:10:04
    which is these zero values right here.
  • 00:10:07
    And there's more useful built-in functions like map, for example,
  • 00:10:10
    which transforms an iterable by applying a function to each element.
  • 00:10:14
    So if you have a list of numbers,
  • 00:10:16
    you can map the square to this particular list and then print that,
  • 00:10:20
    and then this is what you're going to get.
  • 00:10:22
    Or you can use filter to select elements based on a certain condition.
  • 00:10:26
    For example, we only want to get the numbers that are divisible by 10.
  • 00:10:30
    And then when you run this, then this is the result that you get.
  • 00:10:33
    You can also use the reversed built-in function
  • 00:10:36
    that's going to reverse an iterable without actually modifying it.
  • 00:10:39
    So if I have this list of items,
  • 00:10:41
    and then I'm going to iterate over the reverse list,
  • 00:10:45
    then it's simply going to print that,
  • 00:10:46
    but actually at the same time, items is not changed.
  • 00:10:50
    So if I print items,
  • 00:10:52
    then you see that it will still have the original order preserved.
  • 00:10:56
    And another nice tip is that min and max,
  • 00:10:59
    which is really common functions used in Python,
  • 00:11:02
    actually also work with custom keys.
  • 00:11:04
    So for example, let's say I have a list of words.
  • 00:11:07
    What I can do is I can check what the longest word is using the max function
  • 00:11:12
    by supplying the length function as the key.
  • 00:11:14
    So then it's going to apply that function to each value
  • 00:11:17
    and then use that value to determine the maximum.
  • 00:11:20
    And then this is what we get.
  • 00:11:22
    The longest word is banana.
  • 00:11:24
    The next step is to use generators for efficient iteration.
  • 00:11:27
    If you use the yield keyword in a function,
  • 00:11:30
    then that's going to turn it into a generator.
  • 00:11:32
    Yield basically pauses the function
  • 00:11:35
    and allows it to produce a series of values over time,
  • 00:11:38
    resuming from where it left off with each subsequent call.
  • 00:11:42
    Because of that, generators are a really great way to handle large datasets
  • 00:11:46
    or streams of data without consuming too much memory.
  • 00:11:49
    Here you see a couple of examples of generators.
  • 00:11:52
    So in this case, I have a square numbers function,
  • 00:11:55
    and that's going to use a for loop to go over a certain range,
  • 00:12:00
    and then it's going to yield the square of that particular value,
  • 00:12:04
    but it's only going to compute that when you actually call that function.
  • 00:12:08
    So what you can then do is use this generator function
  • 00:12:10
    to compute the actual value.
  • 00:12:12
    So I'm going to loop over square numbers five,
  • 00:12:15
    and then I'm going to print the actual value.
  • 00:12:18
    And then this is what you're going to get.
  • 00:12:19
    And it's not going to compute the square numbers
  • 00:12:22
    for every possible integer, only the ones that you actually request.
  • 00:12:26
    And that's one of the main powers of generators,
  • 00:12:28
    that they compute values lazily.
  • 00:12:29
    So they only produce the results when you explicitly request them.
  • 00:12:33
    So here you can actually see that happening,
  • 00:12:35
    where we have a generator that also computes the square of a number,
  • 00:12:39
    but with a delay.
  • 00:12:40
    So I'm using a time.sleep here.
  • 00:12:43
    And then I'm going to yield that value.
  • 00:12:45
    And then what you're going to see is that I use another built-in function
  • 00:12:49
    here, next, to go through the generator manually
  • 00:12:52
    and fetching these values on the fly.
  • 00:12:54
    So I'm computing it of 0, 1, and 2 with a time delay.
  • 00:12:58
    And you actually see that happening when you
  • 00:13:01
    run this particular piece of code.
  • 00:13:03
    Now, our next step is to use context managers, which
  • 00:13:05
    is also a really nice feature.
  • 00:13:08
    Context managers, they use the with statement.
  • 00:13:11
    They simplify and automate management of resources,
  • 00:13:14
    like files, database connections, network sockets.
  • 00:13:18
    They ensure that resources are properly closed or cleaned up,
  • 00:13:22
    even if some exception occurs during execution.
  • 00:13:25
    File operations are one of the most common uses of context managers.
  • 00:13:30
    Here you see a couple of examples.
  • 00:13:31
    So I'm using a context manager here, using the with statement
  • 00:13:35
    and opening example.txt, which is this particular file.
  • 00:13:39
    And then when I run that, well, it's simply
  • 00:13:41
    going to open that file and print the content.
  • 00:13:44
    And it's going to automatically close the file again.
  • 00:13:47
    That's exactly what context managers do.
  • 00:13:49
    And they work for lots of different scenarios.
  • 00:13:51
    For example, they can also help manage external connections,
  • 00:13:54
    like a database connection, and make sure
  • 00:13:56
    that it closes properly when you're done with the particular database.
  • 00:13:59
    So in this case, I have a SQLite example.
  • 00:14:01
    It connects to a database.
  • 00:14:03
    It's going to create a table if it doesn't exist.
  • 00:14:05
    And then it's going to insert a user and then
  • 00:14:08
    fetch the users in the database.
  • 00:14:10
    So there you see there is now one user in the database.
  • 00:14:12
    If I run this again, there's going to be two aliases.
  • 00:14:15
    You can also create your own context manager
  • 00:14:18
    with the context manager decorator.
  • 00:14:21
    And that actually allows you to use a generator.
  • 00:14:23
    So all these different concepts, they combine to produce
  • 00:14:26
    like a really cool syntax.
  • 00:14:29
    So we use this decorator.
  • 00:14:30
    And then I have a timer.
  • 00:14:31
    I'm going to start the timer and then do a yield.
  • 00:14:35
    So every time I call the context manager,
  • 00:14:37
    that's where it's going to pause.
  • 00:14:39
    And then after that, it's going to compute the end time
  • 00:14:41
    and then print the elapsed time.
  • 00:14:44
    And then the usage of this is really simple.
  • 00:14:46
    You can just do with timer.
  • 00:14:48
    And then once that's completed, it's
  • 00:14:50
    going to close the context by running this piece of code.
  • 00:14:53
    So when I run this, then this is what we get.
  • 00:14:55
    So this took us 0.13 seconds.
  • 00:14:58
    Now, if you need something more complex that
  • 00:15:00
    can't be handled with the decorator,
  • 00:15:01
    you can also implement a context manager
  • 00:15:04
    by defining the enter and exit Donder methods in a class.
  • 00:15:08
    So that's basically what you see here.
  • 00:15:10
    And then you are in a method, and you
  • 00:15:11
    can do like a bunch of things.
  • 00:15:13
    And in the exit, you also have things
  • 00:15:15
    like the traceback and exception type and value
  • 00:15:18
    that you can work with.
  • 00:15:20
    And then you can use this like so.
  • 00:15:22
    And that also is a context manager.
  • 00:15:24
    The next step is to use Python's libraries.
  • 00:15:27
    Python has an extensive ecosystem,
  • 00:15:29
    and that's one of its greatest strengths.
  • 00:15:32
    Libraries like Pandas, NumPy, HTTPS, Matplotlib,
  • 00:15:35
    they can make your work significantly easier.
  • 00:15:38
    Knowing when to use a library versus when
  • 00:15:41
    to implement something yourself makes you
  • 00:15:42
    a much more efficient developer.
  • 00:15:44
    Now, of course, there's thousands and thousands
  • 00:15:46
    of libraries.
  • 00:15:47
    I'm not going to show all of them,
  • 00:15:48
    but just a few simple ones that I regularly use.
  • 00:15:51
    So one is HTTPS.
  • 00:15:52
    So if you want to do some API requests, I always use this.
  • 00:15:56
    And it's really simple.
  • 00:15:58
    It works really great.
  • 00:15:59
    Of course, there's Pandas for data manipulation and analysis.
  • 00:16:03
    So if you can create a data frame
  • 00:16:05
    and then perform some operations on it,
  • 00:16:07
    like computing the mean of the age column,
  • 00:16:10
    this is actually pretty slow.
  • 00:16:11
    I'm guessing it's initializing something.
  • 00:16:15
    Why did that take eight seconds?
  • 00:16:17
    That's ridiculous.
  • 00:16:18
    Let's try that again.
  • 00:16:18
    OK, now it's way faster.
  • 00:16:20
    So data frames can be easily printed.
  • 00:16:22
    You can do things like compute the mean.
  • 00:16:24
    And of course, Pandas has many, many, many different features
  • 00:16:27
    that you don't have to implement from scratch yourself
  • 00:16:30
    if you use that library.
  • 00:16:31
    Of course, there's also NumPy.
  • 00:16:33
    So we can create an array, a NumPy array,
  • 00:16:36
    and then also perform these type of simple operations on it.
  • 00:16:39
    And it's all implemented in C. So NumPy is really fast.
  • 00:16:42
    We have scikit-learn, which has machine learning algorithms.
  • 00:16:45
    So you can take, let's say, some data that we have here
  • 00:16:49
    and then create a linear regression model
  • 00:16:53
    and then fit to that model and then predict the next value,
  • 00:16:57
    which is what you see here.
  • 00:16:58
    And apparently, I'm running this for the first time
  • 00:17:00
    on this machine.
  • 00:17:01
    This is now also pretty slow.
  • 00:17:02
    So in this case, 1, 2, 3, so the predictive value for 5
  • 00:17:05
    is obviously 5.
  • 00:17:07
    But if I change this to, I don't know, let's say 10,
  • 00:17:09
    and then I run this again, then you
  • 00:17:11
    see we're going to get a different value here.
  • 00:17:13
    So it's really easy.
  • 00:17:14
    Scikit-learn is a really great package.
  • 00:17:17
    matplotlib can plot graphs, charts, so that's also really easy, and also integrates directly
  • 00:17:23
    with Jupyter Notebooks, which I'm using here to show you these code examples. In short,
  • 00:17:29
    use these libraries. They really save you a lot of time. The next tip is to use type annotations
  • 00:17:33
    for better code clarity. Type annotations or type hints, they help others and future you
  • 00:17:39
    understand your code better. I've talked about type annotations many times on this channel.
  • 00:17:44
    They're really easy to add in Python and they simply make your functions look a lot cleaner
  • 00:17:49
    and clearer. Because when you look at, for example, this function's signature, you can
  • 00:17:53
    immediately see that this function expects a list of integers. If you leave out the type
  • 00:17:58
    annotation, you don't know, right? You have to check the code and figure out what is going on.
  • 00:18:02
    And we also know that it's going to return a floating point value. So that's very useful
  • 00:18:06
    information. It's like structured documentation. And then we can, of course, simply run this.
  • 00:18:12
    But what's nice about type hints is that they also help you write code that's more generic.
  • 00:18:16
    So in this case, we have the average function that takes a list of integers. But actually,
  • 00:18:21
    when you look at the body, you may realize that it doesn't have to be a list. It can also be a set,
  • 00:18:28
    for example. And in fact, as long as numbers is of type iterable, anything that's iterable,
  • 00:18:34
    a list or a set, then you can actually perform this function. So I can do average on a set,
  • 00:18:41
    in this case. And that's also going to give me that value. I might say, well, yeah, of course,
  • 00:18:46
    you could also just leave out the type annotations. Then it also works with anything, right? And you
  • 00:18:51
    would be absolutely correct. But the thing is that by being explicit about types in this way,
  • 00:18:57
    it also helps you get yourself as a developer a better understanding of what kind of data
  • 00:19:03
    a function expects. And by understanding that better, you're going to write better code,
  • 00:19:09
    because you may do some refactor to improve the efficiency or improve the structure. And
  • 00:19:13
    thinking about types the way that your data is structured is going to massively help you
  • 00:19:17
    understand your code better. The next step is to use abstraction to decouple your code.
  • 00:19:22
    Abstraction is a key concept in software design that allows you to separate what a piece of code
  • 00:19:28
    does from how it does it. In Python, you can use ABCs, abstract base classes, and protocols. These
  • 00:19:36
    provide the tools to create clean and decoupled code. ABCs, abstract base classes, they define
  • 00:19:42
    a sort of blueprint for concrete classes. They specify what methods or properties a subclass
  • 00:19:48
    must implement. I've shown ABCs many times in videos on the channel. So if you want to learn
  • 00:19:54
    more about that, watch some of my older videos. But this is basically what it looks like. So
  • 00:19:58
    we can create a, in this case, payment processor, which is an abstract base class. We do that by
  • 00:20:03
    inheriting from the ABC class. And you can define methods, like so. So process payment
  • 00:20:09
    doesn't have implementation, so it's an abstract method. And then you can create subclasses of
  • 00:20:14
    this, like a PayPal processor and a Stripe processor. And then we have another function
  • 00:20:20
    that has a processor as an argument. And this function now doesn't need to know anything about
  • 00:20:26
    what specific type of payment processor it uses. And that's exactly the abstraction that we're
  • 00:20:32
    looking for. So when I run this, then, well, this is the result that we're going to get. And
  • 00:20:37
    process order knows nothing about specific payment processors that it uses. Now, next to abstract
  • 00:20:44
    base classes, you can also use the protocol class, which relies more on Python's duck typing
  • 00:20:50
    mechanism. And this works a bit differently in that we can have a logger. In this case,
  • 00:20:56
    that's another example, but that's a protocol. So it doesn't inherit from ABC, it inherits from
  • 00:21:01
    protocol, and that has a log method. But then we can create classes that implement or that follow
  • 00:21:08
    this protocol. But as you can see, there's no inheritance relationship here. The class simply
  • 00:21:13
    has the same methods. And there's also a file logger that does the same thing, but it logs to
  • 00:21:19
    the file. And then, similar to what we had in the ABC example, I can then perform a task and provide
  • 00:21:24
    a logger, an abstract logger, as an argument. And here, this uses duck typing. So Python is simply
  • 00:21:32
    going to check, hey, what we pass here, does it actually follow this protocol? And then it's going
  • 00:21:36
    to use that object in some way. So when I run this, then it's going to log these things here. And
  • 00:21:43
    actually, it now also has created the log file right here. Now, personally, I do like protocols
  • 00:21:48
    quite a bit. They're more closely related to the actual typing system of Python, whereas abstract
  • 00:21:53
    base classes are, in my opinion, a bit different. But, you know, they both do the job. So use whichever
  • 00:21:59
    one of these options you prefer. You can only apply abstraction well if you thought about the design
  • 00:22:04
    of your software. If you want to learn how to design a piece of software from scratch and avoid the main
  • 00:22:09
    pitfalls, check out my free design guide at arjan.codes/designguide. This describes the seven steps
  • 00:22:15
    you need to take, and it's going to help you avoid some of the mistakes that I made in the past.
  • 00:22:19
    The next step is to write tests. You need to test your code early and often. You can use PyTest
  • 00:22:25
    for that. This doesn't come out of the box with Python, so you need to install it separately,
  • 00:22:29
    with UV, for example, or with any dependency manager that you use. But what writing tests is
  • 00:22:34
    going to do for you is that it will create a safety net. Basically, things that you know
  • 00:22:39
    they're guaranteed to work, because when you run those tests, you add some code, you run the test
  • 00:22:44
    again, you can verify that actually it's not broken. And that's what tests are really helpful
  • 00:22:48
    with. And they are scalable, in a sense, because you can just add more, and you're not going to
  • 00:22:52
    forget to manually test some edge case. Writing these tests in Python is actually not that hard.
  • 00:22:58
    So here I can show you a quick example where this is from a recent code roast video that I did,
  • 00:23:05
    data CLI. And there you see I have a test folder that basically tests different things. So I simply
  • 00:23:12
    write these functions that do some tests. And you can write different files here containing
  • 00:23:18
    all sorts of different tests, like here's a test to show files. And you can even do mocking, like
  • 00:23:25
    I create a mock data dictionary here, which just contains a bunch of data frames. And then I'm
  • 00:23:31
    going to check that calling this show files function and prints the correct message. And
  • 00:23:36
    if you followed the previous tip related to abstractions, then actually you can use abstractions
  • 00:23:40
    to mock things as well in your test. For example, this is another code example I did a while back
  • 00:23:46
    about the repository pattern. But here I want to test the repository. And what I did in this case
  • 00:23:52
    is that I have a mock repository that is a subclass of repository. Now repository itself
  • 00:24:00
    is an abstract base class, so that's, you know, no implementation. And then I have here a specific
  • 00:24:05
    implementation of that for blog posts. But then I also have a mock version that just does some
  • 00:24:11
    very basic simple things. And then you can write tests that use this mock repository. Now these
  • 00:24:16
    specific tests here are not that useful, but by having this abstract version we don't have to
  • 00:24:21
    create an actual repository which may connect to a database, etc. So abstractions are really helpful
  • 00:24:26
    for that. My final tip is to use classes and functions wisely. And this is something that
  • 00:24:32
    lots of developers struggle with. Understanding when to use a class, a data class, or a plain
  • 00:24:37
    function can help you write cleaner, more maintainable Python code. So here's a breakdown.
  • 00:24:42
    First, use a class when you need to encapsulate behavior and data together. Classes are ideal
  • 00:24:48
    for creating objects that have both state attributes and behavior methods. Here you can
  • 00:24:54
    see a clear example of that. So I have a class Shopping Cart, which has a bunch of items. And
  • 00:24:58
    it also has behavior. So you can add an item and you can also compute the total. That's what you
  • 00:25:04
    see right here. And then we can run this code like so and print some information about it. So we have
  • 00:25:09
    three dollars and fifty cents in our Shopping Cart. A data class is a bit different. It's a
  • 00:25:14
    lightweight alternative to a class that's more focused on representing some sort of structured
  • 00:25:20
    data. So when you need to do that and you don't need that much behavior, a data class is actually
  • 00:25:25
    really nice and it allows you to avoid some of the boilerplate that's involved with writing a
  • 00:25:30
    regular class, such as an initializer like you see here. So here you see an example where we have a
  • 00:25:35
    data class of a class Item, which has a name and a price. And the class is very simple. It's really
  • 00:25:41
    easy. And then I can simply use that and also add some other things like easily printing an instance
  • 00:25:47
    of the class and things like that. So as you can see, if I print the item, then it's going to give
  • 00:25:52
    me some useful information. And I can still access, of course, the instance variables like so. If you
  • 00:25:58
    have a stateless operation that you need to perform, then a function is a much better fit.
  • 00:26:04
    In other words, a task that doesn't really require you to maintain a state and that you
  • 00:26:08
    can perform independently. And then you can also introduce abstraction again,
  • 00:26:11
    what I talked about in one of the previous tips.
  • 00:26:13
    So here's an example of that, where I have a function to calculate a discounted price so that it gets a price and a discount.
  • 00:26:20
    So this is like a really independent function, it doesn't need to maintain any state.
  • 00:26:24
    And then I can simply call that function and then this is what we get.
  • 00:26:28
    And then of course you will often use these things in various combinations to get a complete solution to your problem.
  • 00:26:35
    So here, for example, I have a data class which is an item.
  • 00:26:38
    I have a shopping cart which is a regular class that has behavior, but it also maintains a list of items.
  • 00:26:45
    And then I have this calculateDiscount function that expects a shopping cart.
  • 00:26:50
    You could even introduce some abstraction here by allowing any type of object that has a total method.
  • 00:26:57
    And then it's going to calculate the discount and then, well, we simply use it in this way.
  • 00:27:02
    And we have the basic setup of a simple webshop, apart from the website and actual payments and all the other things you need for a webshop.
  • 00:27:10
    So these were my tips, but now I'd like to hear from you.
  • 00:27:14
    Did you find these tips helpful? Did I miss any important ones?
  • 00:27:18
    Let me know your thoughts in the comments.
  • 00:27:20
    Next to writing Python code, you also need to think about the ideal way of managing your Python project.
  • 00:27:26
    In what environment you're going to run your code, managing your dependencies, and so on.
  • 00:27:30
    Watch this video next to learn how to do that the easiest way possible.
  • 00:27:35
    Thanks for watching and see you next time.
タグ
  • Python
  • Programming
  • Developer Tips
  • Comprehensions
  • f-strings
  • Generators
  • Type Annotations
  • Abstraction
  • Testing
  • Libraries