How To Write Better Functions In Python

Поділитися
Вставка
  • Опубліковано 24 лис 2024

КОМЕНТАРІ • 85

  • @Titouan_Jaussan
    @Titouan_Jaussan 2 місяці тому +102

    I was wondering, Could you make some sort of code review type videos ? I know it probably takes more time but at the same time you could also explain a lot of other stuff, like how to handle big sized projects, how to make code more professional on a larger scale ... This could really be cool I think

  • @JeffreyLiss0
    @JeffreyLiss0 2 місяці тому +55

    Eschewing long function names simply makes naming much harder. You end up having to make important distinctions with fewer words, so grammar comes into play. This function, for example, should be named get_discounted_total or get_discounted_price, because that's what it's returning -- not the sum of all discounts to be applied to a product. Playing grammar nazi with code is nobody's idea of a good time, and it's particularly difficult on teams where people have different native languages. Better to make your peace with longer names, especially since any IDE worth the name will offer to autocomplete it for you.

    • @kellymoses8566
      @kellymoses8566 2 місяці тому +4

      I agree. With modern IDEs there isn't a lot of drawback for long function names.

    • @Just.Be.Kind.please
      @Just.Be.Kind.please Місяць тому +1

      While I’m opining from a position of extreme novice in coding, I have absolutely noticed myself using more detail/length in my function names when needed. This helps me and my neurodivergence keep things understandable when going back to review or continue working on a project.
      I imagine it would be just as helpful, if not more, for a group/team.

  • @drew.esbssy
    @drew.esbssy 2 місяці тому +21

    I like how I came to watch the video thinking it would just be normal stuff i would already know and ended up learning how to create function documentations

    • @olivergrim7634
      @olivergrim7634 2 місяці тому

      i was disappointed the way i expected to, i knew all of this :c

  • @Marc-ElianBegin
    @Marc-ElianBegin 22 дні тому +1

    Thanks for the video. There are several standards for documentation. Making a review of those with its pros and cons would be nice.

  • @spreadneck2063
    @spreadneck2063 4 дні тому +1

    So you can use : instead of = when defining a variable?

  • @marcof1430
    @marcof1430 2 місяці тому +5

    I think documentation has a double side: useful but terrible if it's not updated. And it's easy to forget to update, even in the video the documentation needed to be updated. I prefer comments in the hard parts so I understand what the programmer wanted to achieve or do..

    • @nuynobi
      @nuynobi Місяць тому +2

      Valid point about documentation needing to be maintained. That's an argument for keeping docstrings simple and concise (unlike in this video), _not_ and argument for not using them at all. Comments and documentation have different purposes. Both are useful and should be employed where appropriate. The convention is that docstrings explain the _what_ while comments explain the _how._

  • @Heavy_Lvy
    @Heavy_Lvy 2 місяці тому +3

    3:23 this is commonly referred to as Dependency Injection (DI)

  • @frozendude707
    @frozendude707 Місяць тому +1

    7:23 I'm gonna do a sad frikkin "errm, actually" here, so technically it should drop an exception or segfault if the locale is missing or corrupt, in which case you could return a generic time format like %H:%M:%S (there seems to be no built-in support for standard ISO 8601 formats).

  • @amitshogun
    @amitshogun 2 місяці тому +5

    This function has two responsibilities. Sum and percentage discount. Better to split / extract to 2 simple generic functions and create another one that combines both. Better code reuse.
    And what about validating percentage value?
    Thank you

    • @ziul123
      @ziul123 2 місяці тому

      there is already a generic function for sum: the sum function. It is also faster, because it's implemented in C. The function he wrote already combines both functionalities. There is no need to write a separate one liner function to apply a percentage, it is literally just a multiplication

    • @nuynobi
      @nuynobi Місяць тому

      ​@@ziul123 True, but his point still stands. Why pass in a list of prices when you could simply pass in the total already summed? And it should be called something like apply_discount(price, rate).

  • @baptisteb8910
    @baptisteb8910 2 місяці тому +1

    For the function name I would say:
    1. As short as possible, but as long as needed.
    And if the name is too long, then the function might need to be divided.
    Otherwise LGTM !

  • @DuncanBooth
    @DuncanBooth 2 місяці тому +11

    I don't like it when people duplicate the parameter types in the docstring. You have the type clearly specified in the function signature so no need to repeat it. (And if you're using tools to process the docstring that don't use the function signature types get better tools.)

    • @nuynobi
      @nuynobi Місяць тому +1

      Amen. It's redundant. And then you need to remember to update it in both places if something changes. DRY.

  • @Desafecto
    @Desafecto Місяць тому

    I would suggest adding one last step: a test for the function. 😊

  • @Greenbay-bn3yk
    @Greenbay-bn3yk 2 місяці тому +2

    I learnt a lot of Python techniques from this channel. Thanks Mr. Indently 🙂

  • @nerdl4bs
    @nerdl4bs 2 місяці тому +2

    I don't like get methods in Python but I like everything else in the video

    • @MrMaxtng
      @MrMaxtng 2 місяці тому +1

      Its a convention, not a real getter as per Java or similar. You could call a function that calculates coefficients for a neural network get_coefficients. Why do you care?

  • @bismarkosei9656
    @bismarkosei9656 2 місяці тому

    I would also recommend that you make the validation as function.

  • @capnmark4
    @capnmark4 2 місяці тому

    Good tips for any programming language!

  • @danielrhouck
    @danielrhouck Місяць тому +2

    I think you took the short function names too far. Based on the name `get_time`, I expect the *time* and not a string. I’d do `get_time_locale` or something, even with the return type.

  • @divyakumar8147
    @divyakumar8147 23 дні тому

    thanks

  • @angelou8633
    @angelou8633 26 днів тому

    can you do some tutorial in dart/flutter?

  • @DrDeuteron
    @DrDeuteron 2 місяці тому

    also and/or emphasis on what you did:
    1) one point of return (if you must have branches)
    2) don't have branches (except for guard clauses)
    3) Use guard clauses: raise exceptions early.
    Most important:
    Be pure:
    No side-effects. Don't modify arguments! e.g.:
    >>>sorted(list_)
    returns a sorted list w/o modifying the argument. Modify objects only in their one methods:
    >>>list_.sort()
    and don't have a state: same arguments means same result (rand and date time notwithstanding).

  • @martinmaher8129
    @martinmaher8129 2 місяці тому

    Beautiful!

  • @ArtyomKatsap
    @ArtyomKatsap 2 місяці тому +3

    Why do you need to specify the type of the "now" variable? Even in static type language lile c++ you can write "auto" and let the compiler figure out the variable type. Here - almost any IDE will know that the returned value is "datetime" and will give you same intellisense support without the surplus verbosity.

    • @gJonii
      @gJonii 2 місяці тому

      Compiler wouldn't warn you if the function would start, after some modification, returning strings. If you write it explicitly, then you get proper warning if you modify something and the return type is wrong.

    • @ArtyomKatsap
      @ArtyomKatsap 2 місяці тому

      In this case, either the rest of the code will be compatible with the new type which means the new type has the same protocol or is a subclass of datetyme type, or the intellisense will alert me of incorrect/incompatible usage.

    • @gJonii
      @gJonii 2 місяці тому +2

      ​@@ArtyomKatsapActually, yeah, you're right. I thought you talked about function signatures somehow, but yeah, the variable typing is imo kinda pointless there, the datetime.now() is already a typed function.
      If you were to reassign "now", it would make more sense to type it, but here, it seems purely fluff.

    • @Jason-b9t
      @Jason-b9t 2 місяці тому

      @@gJonii In most cases you do not need to type the variable type. (I wouldn't do it either.)
      But typing variable type is sometimes helpful, like the following code:
      from datetime import datetime
      now = datetime.now()
      today = datetime.date(now) # Get today's date
      if today == now:
      print('today is now')
      else:
      print('today is not now') # Print this line because the type of "now" is different from the type of "today".
      If you type variable type it is easier to understand the type of the variable.

    • @Jason-b9t
      @Jason-b9t 2 місяці тому

      ​@@gJonii If you type variable type it is easier to understand the type of the variable.
      now = datetime.now()
      isoNow = datetime.isoformat(now)
      print(f'{now=}, {isoNow=}')
      if isoNow == now:
      print('isoNow is now')
      else:
      print('isoNow is not now') # Print this line because the type of "isoNow" is different from the type of "now".
      But I usually don't type variable type because it's very troublesome.

  • @uruloki
    @uruloki 2 місяці тому +5

    Shouldn’t the discount function be renamed to totalAfterDiscount?

    • @michaelhoffmann2891
      @michaelhoffmann2891 2 місяці тому +1

      totalAfterCalculatedDiscountWithLocalisationAndRebates(), which is overridden in DiscountAndRebateCalculationInstantiationFactory.
      Java.............. 🙄
      But in case, you were serious: Java uses camel case, Python uses snake case. If one of my peers uses the former format in the latter language, I will not approve their PR. I see that a lot among more junior, fresh-out-of-uni coders.

    • @uruloki
      @uruloki 2 місяці тому +1

      @@michaelhoffmann2891 Case is usually shop specific. Good on you for enforcing your standard!

    • @michaelhoffmann2891
      @michaelhoffmann2891 2 місяці тому +1

      @@uruloki True, but I would look *very* askance at a shop that dictated camel case for Python in defiance of PEP.

  • @popovanatoliy4736
    @popovanatoliy4736 Місяць тому

    05:46 i'm not sure it's pep but probably you write dosrctring in a wrong way. it starts with a verb. like "get current time" instead of "a function that returns you a current time".

  • @ferroalloys594
    @ferroalloys594 Місяць тому

    Only ever abstract over an EXPRESSION, whatever it's arguments...! Simples (:-)

  • @markdillon9588
    @markdillon9588 2 місяці тому

    Brilliant:)

  • @TellyT-i5e
    @TellyT-i5e 2 місяці тому +1

    Redundant docs just clutter up the code unless you are making a library api

  • @smanzoli
    @smanzoli 2 місяці тому +1

    The first example was not a good choice (ok, it's an example only), because as a rule, we should NEVER write a function which only purpose is call another function.
    get_time() is completelly useless since we can simply use directly datetime.now()
    Also, inside the useless function, we create a useless variable now, where we could return datetime.now() directly.
    Second example is very good.
    Great video!

  • @TheBlueboyRuhan
    @TheBlueboyRuhan 2 місяці тому +4

    my money don't jiggle jiggle, it folds

  • @farzadmf
    @farzadmf 2 місяці тому

    Seems like :type ...: doc is not reflected in the popup (I mean it doesn't mention anything about the type of the params)

  • @cerealport2726
    @cerealport2726 2 місяці тому

    If i put all my functions in 1 file, and the "executable" code in another, is there some general guideline for where I should put fixed variables? like, if i call them in the "executable" file, then put them there, otherwise, put in the function file...?

    • @samagraarohan2513
      @samagraarohan2513 2 місяці тому +4

      put them where they are gonna be used most, and where it makes sense for them to exist

    • @ffggvfg4323
      @ffggvfg4323 2 місяці тому +1

      Putting all your functions in one file makes your code hard to read and makes debugging a pain. If your code is clogged up with util functions then putting those in a file can be ok as far as variables please on behalf of everyone that will read your code define them in the main file

    • @DrDeuteron
      @DrDeuteron 2 місяці тому +1

      but the point of dunder name == dunder main is that you don't need to separate the code like that, unless another script also needs the function--but then you're writing a package.
      "fixed variables" is just not pythonic..."module constants" go after imports, before def's.

    • @gJonii
      @gJonii 2 місяці тому +1

      I'd put all the code in one file, until you identify some island of functionality that you can separate into its own file with a smaller API.

  • @curtisharwood6626
    @curtisharwood6626 29 днів тому +1

    your first tip of not naming things thoroughly is definitely just an opinion, and arguably a bad one.

  • @xXherbal1stXx
    @xXherbal1stXx 2 місяці тому

    about the type annotations;
    i think they're use- and surely helpful BUT, for me as a not very experienced coder who's still figuring out how to do stuff the best way and which techniques are available, and whilst discovering new modules and their functionalities, it can be somewhat distracting to already start using type annotations as much as possible, so my take at it is to use them as long as it stays simple, so to at least get used to them for now and to have a base to build up on later, specially once my scripts start to become bigger. same for docstrings btw..

  • @vadimkorniychuk665
    @vadimkorniychuk665 2 місяці тому

    Error handling is ok basically, but your example so overloaded

  • @BouncingCow
    @BouncingCow 2 місяці тому

    how would I handle a function if I return several value? would I do that as a list and - - > list[Str, into, df. Dataframe()] for example?

    • @michaelhoffmann2891
      @michaelhoffmann2891 2 місяці тому

      tuples! Or a dict.

    • @tw11tube
      @tw11tube 10 днів тому +1

      Especially if it's part of a library API, use a NamedTuple or dataclass, so the callers can access members by name.

  • @GreyHatGenX
    @GreyHatGenX Місяць тому

    comment

  • @jervinevangelista7615
    @jervinevangelista7615 2 місяці тому

    what vs code extensions are you using? thanks

  • @JohnUrbanic-m3q
    @JohnUrbanic-m3q 2 місяці тому +6

    Use Python because it it quick and pithy. Once you start adding in this pseudo-typing, error handling and extensive documentation you lose that, and it is a sign that you should be choosing a different language. Right tool for the job.

    • @michealakinkuotu8637
      @michealakinkuotu8637 2 місяці тому +18

      This is not true. Documentation and error handling is a crucial part of any software, whether it's statically typed or dynamically typed.

    • @DrDeuteron
      @DrDeuteron 2 місяці тому +1

      @@michealakinkuotu8637 but LBYL type checking?

    • @michealakinkuotu8637
      @michealakinkuotu8637 2 місяці тому

      @@DrDeuteron Look before you leap is not left out of the discussion in terms of error handling. While LBYL can be redundant or expensive in terms of performance, it doesn't nullify the fact that if done correctly, it gives you a "safer code" and in some cases, a much cleaner or clearer error handling through provision of meaningful feedback.

    • @DrDeuteron
      @DrDeuteron 2 місяці тому

      @@michealakinkuotu8637 I get the POV, but that gets back to OP's point: this is python: Lighten up!
      The only place I allow branchy code is in error handling. When everything is working, I want minimal cyclomatic complexity.

    • @DrDeuteron
      @DrDeuteron 2 місяці тому +2

      I do find the excessive hints annoying, the worst is type hinting strongly typed magic methods, like:
      init(self) -> None:
      str(self) -> str:
      I just can't....

  • @smanzoli
    @smanzoli 2 місяці тому

    The G you pronounce at the end of words (due to accent) is easy to fix... it's silent, simply do not say it! And bingo, your pronounce will get even better!

    • @creed404yt9
      @creed404yt9 Місяць тому

      I can't hear the G you talked about?

  • @dadogwitdabignose
    @dadogwitdabignose 2 місяці тому

    Which IDE are you using?

  • @gregd1218
    @gregd1218 2 місяці тому

    If your functions is simple enough and had a proper name, a documentation is not needed. Besides keeping documentation up to date double your work load (rewrite the doc, update the example,... every time you refactor) Most IDE can infer input and output so that's a complete waste of time. Documentation is only useful in a library and only for exposed methods.

  • @baptisteb8910
    @baptisteb8910 2 місяці тому +10

    For the function name I would say:
    1. As short as possible, but as long as needed.
    And if the name is too long, then the function might need to be divided.
    Otherwise LGTM !

    • @michaelhoffmann2891
      @michaelhoffmann2891 2 місяці тому +1

      I agree. If my func/method is getting to be more than a screen (and I use a big screen) or around 50 lines (incl copious whitespace), I refactor. Even if it's a helper method used once, with a leading '_' ( to make it "Python Private(tm)").