How To Write Better Functions In Python

แชร์
ฝัง
  • เผยแพร่เมื่อ 22 ธ.ค. 2024

ความคิดเห็น • 89

  • @Titouan_Jaussan
    @Titouan_Jaussan 3 หลายเดือนก่อน +110

    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

    • @sebastian_sv
      @sebastian_sv 3 หลายเดือนก่อน +7

      This would be great!

  • @JeffreyLiss0
    @JeffreyLiss0 3 หลายเดือนก่อน +56

    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 2 หลายเดือนก่อน +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 3 หลายเดือนก่อน +22

    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 3 หลายเดือนก่อน

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

  • @dingaroo2003
    @dingaroo2003 24 วันที่ผ่านมา

    Been programming with Python for 6 years, but after going through your video, I am hoping to elevate my Python skills!

  • @Marc-ElianBegin
    @Marc-ElianBegin หลายเดือนก่อน +1

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

  • @Heavy_Lvy
    @Heavy_Lvy 3 หลายเดือนก่อน +3

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

  • @frozendude707
    @frozendude707 2 หลายเดือนก่อน +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 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน

      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 2 หลายเดือนก่อน

      ​@@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).

  • @marcof1430
    @marcof1430 3 หลายเดือนก่อน +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 หลายเดือนก่อน +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._

  • @spreadneck2063
    @spreadneck2063 หลายเดือนก่อน +1

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

    • @lewie8136
      @lewie8136 21 วันที่ผ่านมา

      name: str = ‘bob’
      Variable: type = value
      : allows you to assign the type

  • @Greenbay-bn3yk
    @Greenbay-bn3yk 3 หลายเดือนก่อน +2

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

  • @uruloki
    @uruloki 3 หลายเดือนก่อน +5

    Shouldn’t the discount function be renamed to totalAfterDiscount?

    • @michaelhoffmann2891
      @michaelhoffmann2891 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน +1

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

    • @michaelhoffmann2891
      @michaelhoffmann2891 3 หลายเดือนก่อน +1

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

  • @popovanatoliy4736
    @popovanatoliy4736 2 หลายเดือนก่อน

    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".

  • @ArtyomKatsap
    @ArtyomKatsap 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน

      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 3 หลายเดือนก่อน

      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 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน

      @@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 3 หลายเดือนก่อน

      ​@@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.

  • @mattinm
    @mattinm 21 วันที่ผ่านมา

    The overall idea of this is great, but the example has issues.
    1. You use Iterable, but you iterate over it twice, which is unsafe, because an Iterator, which can only be looped once is also an Iterable.
    2. You declare float as the sub-type for prices, but check for int or float later. Just use SupportsFloat as the hint instead and explicitly cast later, e.g. via map(float, prices). This will also have the benefit of doing the type validation for you and raise if needed, instead of even needing to call isinstance.

  • @lvidarte
    @lvidarte 3 หลายเดือนก่อน +2

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

    • @MrMaxtng
      @MrMaxtng 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน

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

  • @DuncanBooth
    @DuncanBooth 3 หลายเดือนก่อน +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 2 หลายเดือนก่อน +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. 😊

  • @capnmark4
    @capnmark4 3 หลายเดือนก่อน

    Good tips for any programming language!

  • @baptisteb8910
    @baptisteb8910 3 หลายเดือนก่อน +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 !

  • @cerealport2726
    @cerealport2726 3 หลายเดือนก่อน

    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 3 หลายเดือนก่อน +4

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

    • @ffggvfg4323
      @ffggvfg4323 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน +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.

  • @angelou8633
    @angelou8633 หลายเดือนก่อน

    can you do some tutorial in dart/flutter?

  • @divyakumar8147
    @divyakumar8147 หลายเดือนก่อน

    thanks

  • @martinmaher8129
    @martinmaher8129 3 หลายเดือนก่อน

    Beautiful!

  • @TheBlueboyRuhan
    @TheBlueboyRuhan 3 หลายเดือนก่อน +4

    my money don't jiggle jiggle, it folds

  • @farzadmf
    @farzadmf 3 หลายเดือนก่อน

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

  • @BouncingCow
    @BouncingCow 3 หลายเดือนก่อน

    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 3 หลายเดือนก่อน

      tuples! Or a dict.

    • @tw11tube
      @tw11tube หลายเดือนก่อน +1

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

  • @ferroalloys594
    @ferroalloys594 2 หลายเดือนก่อน

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

  • @smanzoli
    @smanzoli 3 หลายเดือนก่อน +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!

  • @TellyT-i5e
    @TellyT-i5e 3 หลายเดือนก่อน +1

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

  • @markdillon9588
    @markdillon9588 3 หลายเดือนก่อน

    Brilliant:)

  • @danielrhouck
    @danielrhouck 2 หลายเดือนก่อน +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.

  • @DrDeuteron
    @DrDeuteron 3 หลายเดือนก่อน

    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).

  • @jervinevangelista7615
    @jervinevangelista7615 3 หลายเดือนก่อน

    what vs code extensions are you using? thanks

  • @xXherbal1stXx
    @xXherbal1stXx 3 หลายเดือนก่อน

    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..

  • @dadogwitdabignose
    @dadogwitdabignose 3 หลายเดือนก่อน

    Which IDE are you using?

  • @justliberty4072
    @justliberty4072 16 วันที่ผ่านมา

    I don't like calling fractions "percents"; that is a source of self-documenting error or ambiguity.

  • @curtisharwood6626
    @curtisharwood6626 หลายเดือนก่อน +1

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

  • @GreyHatGenX
    @GreyHatGenX 2 หลายเดือนก่อน

    comment

  • @vadimkorniychuk665
    @vadimkorniychuk665 3 หลายเดือนก่อน

    Error handling is ok basically, but your example so overloaded

  • @JohnUrbanic-m3q
    @JohnUrbanic-m3q 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน +20

      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 3 หลายเดือนก่อน +1

      @@michealakinkuotu8637 but LBYL type checking?

    • @michealakinkuotu8637
      @michealakinkuotu8637 3 หลายเดือนก่อน

      @@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 3 หลายเดือนก่อน

      @@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 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน

    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 2 หลายเดือนก่อน

      I can't hear the G you talked about?

  • @gregd1218
    @gregd1218 3 หลายเดือนก่อน

    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 3 หลายเดือนก่อน +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 3 หลายเดือนก่อน +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)").