3 Bad Python Habits To Avoid

Поделиться
HTML-код
  • Опубликовано: 1 июн 2024
  • Here are 3 bad Python habits I see a lot of people on the internet doing.
    ▶ Become job-ready with Python:
    www.indently.io
    ▶ Follow me on Instagram:
    / indentlyreels
    00:00 - Learning Python made simple
    00:05 - Intro
    00:12 - Bad habit #1
    02:57 - Bad habit #2
    07:01 - Bad habit #3
    10:20 - Do you have any bad habits?

Комментарии • 143

  • @Indently
    @Indently  2 месяца назад +21

    Sorry about that noise in the background! It was freezing in my room so for the first time in my life I turned on the radiator closest to my desk, and when I took off my noise cancelling headphones I realised it was pretty loud.

    • @rishiraj2548
      @rishiraj2548 2 месяца назад +2

      👍

    • @Whatthetrash
      @Whatthetrash 2 месяца назад +1

      No worries. Didn't even hear it! :)

    • @StYxXx
      @StYxXx 2 месяца назад

      Didn't hear anything. Should check my ears...

  • @Kommentierer
    @Kommentierer 2 месяца назад +143

    With a bare except block, you are also catching KeyboardInterrupt, something you definitely don't want in a console program.

    • @Indently
      @Indently  2 месяца назад +27

      Beautiful addition, I didn't even think about that.

    • @schwingedeshaehers
      @schwingedeshaehers 2 месяца назад +2

      sometimes you want, but at least you should check for it specifically, if you catch all

    • @Pacvalham
      @Pacvalham 2 месяца назад +19

      Catching/excepting KeyboardInterrupt is one step in recreating Vim in Python.

    • @uuuummm9
      @uuuummm9 2 месяца назад +1

      Are you sure? The "input" call is outside of the try catch.

    • @schwingedeshaehers
      @schwingedeshaehers 2 месяца назад +1

      @@uuuummm9 you have to time it perfectly, probably

  • @shakapaker
    @shakapaker 2 месяца назад +5

    1. Use specific exceptions instead of a bare except block. Provide meaningful error messages in exceptions
    2. Avoid mutable default arguments in function definitions. Specify function argument types for clarity
    3. Use iterators for memory efficiency. Understand the memory implications of data structures
    Write intentional and efficient code. Always aim for code that's easy to read, maintain, and efficient. Don't settle for quick fixes or lazy practices - that can lead to bugs.

  • @mudi2000a
    @mudi2000a 2 месяца назад +20

    Tell this to the developers in my company that you should not display “something went wrong”, it has become a running joke already.

  • @benjaminelo3709
    @benjaminelo3709 2 месяца назад +5

    For tip 1 I wouldn’t recommend using exceptions for control flow.
    Instead check that the input is a number first, and then ask the user to in put a valid number.
    In more complex programs it is not clear when people extend your work that your program is actually expected to throw exceptions.

  • @DuncanBooth
    @DuncanBooth 2 месяца назад +10

    Sorry but the argument `target: list[T] = None` is itself a bad habit. mypy will flag an error for this and you really should be using a tool like mypy to ensure your type annotations are correct. Either `target: list[T] | None = None` or `target: Optional[list[T]] = None` is needed for valid typing.

    • @Indently
      @Indently  2 месяца назад +5

      No need to be sorry, you absolutely caught me there. I use Mypy all the time and should have quickly run my code through it before making the video.
      Thanks for pointing it out :)

    • @mudi2000a
      @mudi2000a 2 месяца назад +4

      And then it has become an unreadable mess. I find it fascinating that if you use those type hints Python code looks worse than any statically typed language including c++.
      I do actually think they are a good idea especially for functions as they allow self documenting code but I think they are not well designed and create lots of clutter.

    • @DuncanBooth
      @DuncanBooth 2 месяца назад

      @@mudi2000a I don't think adding '| None' makes it unreadable but I used to use the implicit form before mypy started blocking it because it is shorter. Also I dislike that it permits you to actually pass None explicitly while the implicit form says the caller doesn't have to pass an argument but if they do it must be a list. Now to do it properly you have to start using `@override` with all the possible signatures which does quickly become unreadable.
      This is kind of a contrived example though, I can't think of many situations where I'd have a function with an optional list argument that modified it. If I want an optional list argument and won't be modifying it I'd use `whatever: Sequence[T] = ()` and allow them to pass list, tuple, dict, set, whatever they want. Likewise `Mapping` instead of `dict`.

    • @callbettersaul
      @callbettersaul 2 месяца назад +3

      Your beloved mypy is mistaken here. Python documentation literally says this about typing.Optional: "Note that this is not the same concept as an optional argument, which is one that has a default. An optional argument with a default does not require the Optional qualifier on its type annotation just because it is optional. On the other hand, if an explicit value of None is allowed, the use of Optional is appropriate, whether the argument is optional or not."
      Meaning that Optional is not appropriate here as None is not actually a permitted value and is immediately replaced with an actual value. I thought it was common sense.

    • @Indently
      @Indently  2 месяца назад +1

      But None is permitted, and the whole purpose of None is that it checks whether the user has inserted a list or not, that type annotation is appropriate.
      Not only is None permitted here, it's also literally the default value.
      I know you're quoting the docs, but the docs ( docs.python.org/3.12/library/typing.html#typing.Optional ) do not entirely line up with what you're trying to say.

  • @ruidian8157
    @ruidian8157 2 месяца назад +21

    I think one of the bad habits that bites me the most is not using "def main():". Not using that means every variable that you defined is in global scope. Sometimes silly mistake happens, and you end up making a function doing not what it was meant to do.

    • @VinceKully
      @VinceKully 2 месяца назад +3

      It's not the lack of a `def main()`, it's due to not having the __name__ check.

    • @ruidian8157
      @ruidian8157 2 месяца назад +4

      @@VinceKully Actually no. Even with the “__name__” check, the variable will still be global in the current file. I once wrote a function and forgot to include one of the required variable as the parameter of the function. But the code works with no error since I have a global variable which coincidentally has the same name as the variable. This causes some bugs and cost me a few days to finally found it…

    • @callbettersaul
      @callbettersaul 2 месяца назад +2

      Can't believe I never thought about the global variable part. I've never done a mistake by using them in functions, but I sure am annoyed every time pycharm suggests those variables to me, when I'm making a function. This would also remove the global variable shadowing warnings. It's decided, I'm going to start using main function as well.

    • @knut-olaihelgesen3608
      @knut-olaihelgesen3608 Месяц назад

      I often use globals - often read only constants, and I've never in my 4 years of using python had a real reason to use the main()/__name__ snippet. Globals aren't evil, but use them carefully

  • @AmitabhGhuwalewala
    @AmitabhGhuwalewala Месяц назад

    In my experience, depending on the object being returned by the iterator/generator, it might be more computationally efficient to actually force the evaluation of the whole iterator, thereby sacrificing memory for time efficiency. It would depend on the scenario though - obviously not recommended as a rule of thumb. Be very careful about this and document why you think you need to do this when you do need it.

  • @oida10000
    @oida10000 2 месяца назад +3

    The problem with many iterables is that they are one times useables and not subscriptable, range is an exception.
    Try this:
    myr=range(10)
    for m in myr:
    print(m)
    print(myr[3])
    print(myr[6])
    Try the same with map or filter, after the loop they are empty.

    • @callbettersaul
      @callbettersaul 2 месяца назад +1

      Have you ever needed to iterate map or filter twice? Usually they are needed only once and it would be a waste of memory to not discard them. Like when you do map(filter(...)), it would be a waste to keep filter results in memory after being already used by map.

    • @oida10000
      @oida10000 2 месяца назад

      @@callbettersaul You would just need to keep the filter/map function in storage, plus a refrence to the **reusable** iterable - that is not that much.

    • @joshix833
      @joshix833 2 месяца назад

      Yes, most iterators are not re-usable, but iterables that are not iterators (like range, list, tuple) are re-usable

    • @atussentinel
      @atussentinel 2 месяца назад +1

      If you want to frequently subscribe an iterable which it does not support, you are probably using a wrong data structure.
      Occasional doing something a data structure is not optimized for is considered ok.

  • @somnvm37
    @somnvm37 2 месяца назад +1

    I want to ask, is it a good practise to think of tuples as a more default way of making iterables?
    tuples are more efficient, and i've heard the idea that "by default, things should be immutable, unless you know you will change the data" a few times.
    what I mean is: is it good to write tuples every time you need a tuple/list, and only use list if it makes more sense
    or am I overthinking it

    • @edgeman1135
      @edgeman1135 2 месяца назад

      Yeah for sure, tuples are pretty great! The changes for efficiency are quite minor when you compare it to switching data structures or straight up switching languages, but overall I'd say it's a good habit to pick up.

  • @glorytoarstotzka330
    @glorytoarstotzka330 2 месяца назад

    I think when it comes to casting ranges/maps/filters to lists, it's important to note that it's still fine to do it for small scripts or low size things that you want to be able to print or have predictable behavior. sometimes you just wanna optimize for writing convenience and have no real consequences if it's something small scale

  • @DogiMetal
    @DogiMetal 2 месяца назад

    Learned something new today❤❤ thank you!

  • @SusanAmberBruce
    @SusanAmberBruce 2 месяца назад +16

    My bad habit is I don't practice writing code often enough, even though for me python is just an interesting hobby I still find some that I'm looking on Google to remember simple examples.

    • @Indently
      @Indently  2 месяца назад +19

      There's nothing wrong with googling no matter how simple it may be, I can do everything from scratch, but sometimes googling reminds me we have built-in functionality for what I'm about to do.

    • @bhai431
      @bhai431 2 месяца назад +1

      ​@@Indently *Please Make New Video On Making Telegram Bot wich work 24×7 and please must share the Script/Codes otherwise its very very difficult for us*

  • @krzysiekkrzysiek9059
    @krzysiekkrzysiek9059 2 месяца назад

    That's why I subscribe to this channel. Short, simple and very useful tips.

  • @egoragapov2033
    @egoragapov2033 2 месяца назад +2

    Thank you for the video! I believe we can use 'generators' too for memory efficient reasons?

    • @Indently
      @Indently  2 месяца назад +1

      Definitely

  • @bart5557
    @bart5557 2 месяца назад

    Great list! Curious about one thing tho. How did you add the "int()" around 1e6 so quickly? Done through a shortcut?

    • @TurkeyTray
      @TurkeyTray 24 дня назад +1

      highlighting text in PyCharm allows you to press an open parenthesis to enclose the entire thing in parenthesis. Then it's just as simple as pressing the left arrow twice and typing "int." As to how 1e6 was highlighted quickly, you can do ctrl + shift + arrow to highlight everything to the start/end of a word.

  • @ProfRoxas
    @ProfRoxas 2 месяца назад

    I like these examples, they can be quite common
    With the try-except blocks, i try to minimize the lines it has (bad habit from other languages, exceptions could use more resource than necessary) and be specific with the types, with some exception, but then I usually raise back the exception and only either print or log the exception to be verbose.
    Sometimes i even make custom exceptions to only catch what i really want to catch and let through what i didnt mean to catch like key or value errors
    The second one can be quite common, I take extra caution when i see them, because they can be simpler, but only work when the list is not modified, only checked through.
    One of my flying thought was to create a new variable and use the or operator to append to it (temp = targer or []), but then it would incorrectly append to the new object instead of target if target is an empty list
    The last example is especially useful on big data sets or even list comprehensions, because if i only need an iterable, then just by changing the [] to () makes it a memory efficient generator that won't create a temporary list (It's one of my must check thing at work, because it can be efficcient and very easy to change)

  • @phdnk
    @phdnk 2 месяца назад +2

    The Habit 2 is actually a consequence of the bad Python language design decision.

  • @DrDeuteron
    @DrDeuteron 2 месяца назад

    Catching bare exception is so bad. I worked a 7 figure NASA project that had it, and it went south on an unseen " " (space), that was caught and ignored, and the error it cause wasn't noticed for a month. They had java programmers in charge, so there there so many python violations...it was the only PJ I ever quit in disgust in 40 years. 5 years later they are following ALL my recommendations.

  • @jjggbbjunk
    @jjggbbjunk 2 месяца назад

    I barely know what I am doing, so I make all kinds of silly coding mistakes. Videos like these do help me, so thanks for this. Automating my powerflow studies has made me a much more efficient transmission engineer.

  • @ProfMonkeys
    @ProfMonkeys 2 месяца назад +1

    I have taken to using a slightly different variant of your proposed replacement for mutable defaults. I prefer to use the 1 liner of:
    target = target or []
    It is certainly not perfect, but it ends up being so concise that new and old engineers alike can wrap their head around the idiom very easily. In the case where an empty list is explicitly passed in the list that gets appended to will not be the same instance as what was passed in, but if you are running into that little hole because you aren't capturing the output to a variable, then your code usually has bigger problems that should be addressed first.

    • @schwingedeshaehers
      @schwingedeshaehers 2 месяца назад

      the problem is, that there are situations, where you get an empty list, and it expects that these 2 are the same, in the function it will use the same, but another scope may not

    • @ProfMonkeys
      @ProfMonkeys 2 месяца назад

      @schwingedeshaehers that is absolutely another weakness of the model I tend to use. In nearly all of the cases I have found, however, that distinction has not mattered.
      In the few cases I have found where I explicitly need to disambiguate between using the default value and passing in an empty object, I tend to switch to using a sentinel obnect and being verbose to make it very clear that this is a place where that distinction matters.
      My preferred model is not perfect, but the expediency and ease of parsing the resulting code has been serving me very well so far.

    • @ProfMonkeys
      @ProfMonkeys 2 месяца назад +1

      @schwingedeshaehers a big part of why I feel this is unambiguous is the fact that such a method allows a default value for a parameter means that the function does not promise that the original object passed in will be modified in place. If I wanted to make a function that made such a promise, I would not allow a default value and would require it to be passed in explicitly.
      I also generally view modifying mutable arguments in place as a practice to be avoided in most situations because it can lead to other unexpected behaviors, unless that is explicitly designed in.
      Either the function would modify the list in place and return nothing, or it would create a copy of the list with the appended elements and return the copy but mixing the two behaviors together is something to be avoided.

    • @kaltaron1284
      @kaltaron1284 Месяц назад

      @@schwingedeshaehers You would also mask any error where your funtion recieves an unintended value that equates to false like 0.

  • @rkdeshdeepak4131
    @rkdeshdeepak4131 2 месяца назад +5

    We can also use
    target = target or []

    • @emuccino
      @emuccino 2 месяца назад +8

      Note that there could be an unintended side affect when done this way. If an empty target list is passed as an argument, then this would replace it with a new empty list. While that probably is fine in most cases, there could be a scenario where a variable outside the scope of the function contains a reference to the original target list and will not be updated unless explicitly reassigned. Just something to keep in mind.

    • @maxmuster2016
      @maxmuster2016 2 месяца назад +2

      @@emuccino Thanks for pointing that out. A more safee one-liner would be target = [] if target is None else target. Why a one-liner? The excution is faster, because the processor can look ahead to predict the next lines of code.

    • @Lanxxe
      @Lanxxe 2 месяца назад

      ​​@@maxmuster2016it is also kinda confusing so I would avoid that and just go for the traditional way. Furthermore, you would need to pass in None every time right

    • @kaltaron1284
      @kaltaron1284 Месяц назад

      @@Lanxxe The ternary one-liner version of if takes a bit getting used to but IMHO is just as readable as a the normal version as long as all parts are short like in this case. If you can't get it on one line it's probably not a good idea but the same is true for if-statements.

  • @TheJaguar1983
    @TheJaguar1983 2 месяца назад

    Funny thing about "range" is I used to use "xrange" in Python 2.7 for this exact reason.

  • @Zahlenteufel1
    @Zahlenteufel1 2 месяца назад

    Is there any reason why the second one exists? Is there any situation where we would want the function to remember in that way? Because it seems like a problem that should be removed from Python instead of forcing us to do the None check every time.

  • @krzysiekkrzysiek9059
    @krzysiekkrzysiek9059 2 месяца назад

    Perfect tips 👍

  • @saitaro
    @saitaro 2 месяца назад +7

    Things like `my_list: range = range(10 ** 6)` is an overuse of typing which only clogs up the code. It doesn't provide any information, since it's clear what type the variable is.

    • @Indently
      @Indently  2 месяца назад +3

      Back then I would agree with you, but personally what is more important for me than a little bit of "clogging", is consistency. Typing 100% of my code is the approach I go for, I don't follow random rules or use special exceptions, I type everything.
      I constantly read in the comments that people all have their "special" typing rules, and that's great! But none of us will intuitively understand these "rules", so again, I type everything for consistency.
      You don't have to, but when you're teaching to millions of students, you can't always have the luxury of making up your own special case rules.

    • @saitaro
      @saitaro 2 месяца назад

      ​@@Indently I agree on consistency, though even Guido said that it is not necessary to type everything this way, nor it is theoretically possible for Python due to it's dynamic nature. The common rule is simple: type when it's not obvious right away (you suppose a list to be a list of strings) and when it will help an IDE to check and make suggestions (function signature as an example). `my_range: range = range(10)` looks redundant.

    • @Indently
      @Indently  2 месяца назад

      You're not going to like my objects then xD
      fruit: Fruit = Fruit()
      I know we're in Python, and I know I make it look like Java sometimes, but I think this consistent approach will lead to far less issues than letting people decided for themselves what's obvious and what isn't.
      This is only keeping into account that you plan to share your code with others. If you code for yourself, and don't plan to work with others or show your code to anyone else, obvious documentation and type annotations probably will not matter.

    • @thomaseb97
      @thomaseb97 2 месяца назад

      @@Indentlyyou can still be consistant while ignoring typing of certain things, i use typing alot as i feel dynamic typing was a mistake lmao, but for local variables i never use typing
      so i consistantly dont use typing on local variables, i always type my parameters and return, and always type my global variables/constants
      most modern languages also lean to this standard of typing, to not type local variables

    • @landsgevaer
      @landsgevaer 2 месяца назад +1

      The Zen of Python, L2:
      *Explicit is better than implicit*

  • @rolandovillcaarias5112
    @rolandovillcaarias5112 2 месяца назад

    About bad habit #1, what is the difference using multiple except for multiple exceptions vs only one line for one except and multiple exceptions? Are both same? it is just code readability?

    • @callbettersaul
      @callbettersaul 2 месяца назад

      Not at all, multiple except/catch lines are preferred in the situations where you want to customise the behaviour upon each different exception. Like maybe for ValueError you want to print out "please enter a number", but for IndexError this wouldn't make sense so you print out "incorrect number instead". The customisation is limitless. If you just want to log the error, then there's no reason to use multiple except clauses.

  • @auroragb
    @auroragb 2 месяца назад +1

    youtube bad habit: have chapter sections but no meaningful title.
    Clearly you weren't worried about spoiling the video as the thumbnail was a great summary. But with the chapter 1/2/3, it makes it hard for viewers interested in a particular item to jump to it

  • @rolandovillcaarias5112
    @rolandovillcaarias5112 2 месяца назад

    Hi, for bad habit number 2, is it better to validate: "if target is None" or "if not target"?

    • @dragweb7725
      @dragweb7725 2 месяца назад +2

      It depends if you want your function to accept other falsy values like {}, 0, (), False, "", or if you want it to type check whatever is given and raise an error or a warning when it is the wrong type. The thing is "if target is None" will only catch the None object, and "if not target" will catch any of the falsy values listed above

  • @timschulz9563
    @timschulz9563 2 месяца назад

    6:59 But isn't the type hint wrong then? Shouldn't it be Optional[list[T]]?

    • @Indently
      @Indently  2 месяца назад

      Yes it's wrong, and it's my fault for not running mypy before sharing the code with you guys.

  • @little8138
    @little8138 2 месяца назад

    make a video for interview practice questions, It will help to so many

  • @rezarg
    @rezarg Месяц назад

    I'm not sure if this is as bad as I think it is, but I once saw my friend coding in Python and they had "import os" in almost every function instead of just having it once at the top of the file.

    • @Indently
      @Indently  Месяц назад

      Now that's overkill xD

  • @CarlesMateu
    @CarlesMateu 2 месяца назад

    Albeit, using range and similar objects is great for memory efficiency. Sometimes I feel most of us programmers, get scared by a list using 8 million bytes of memory... but that's *only* 8 Mbytes, out of the 16000 M bytes most of us have on our machines.
    Memory availability on modern machines has grown quite a lot, laptops with 16G are common, servers with 32, 64, and upwards are not rare things. So, sometimes, we spend too much time optimizing memory usage for things, that, in perspective, don't use so much of the available memory.
    That being said, in this case, the use of range vs a list is totally justified.

  • @hikaritsumi2123
    @hikaritsumi2123 19 дней назад

    Haha I wish I could correctly handle the error from 3rd party service with no documentation
    As web dev it really get on my nerve when the team decide to return 400 to Frontend because the code CAN explode for basically any reason
    try:
    ...(everything)
    except Exception as e:
    return
    At least I return 500 to indicate that it is ME who need to correct something, and in an ideal scenario it shouldn't happen because I handle every case it could conceivebly happen in a more logical way.
    ..am I becoming Bob?

  • @nahidujjamanhridoy7129
    @nahidujjamanhridoy7129 2 месяца назад

    which ide are you using?

  • @Hernell12
    @Hernell12 2 месяца назад +1

    For tip 2:
    target = target or [] is much cleaner than the if target is None: target = []

    • @swolekhine
      @swolekhine 2 месяца назад

      Not everyone knows about the or-shortcut you used there, so that might be a reason to prefer “if target is None”. But it is definitely a cool trick!

    • @antonk1620
      @antonk1620 2 месяца назад +2

      much cleaner will be if python allowed to safe init list and dicts in func params :)

    • @callbettersaul
      @callbettersaul 2 месяца назад +4

      As mentioned in another similar comment, if someone passes in an empty list, then your approach would replace that empty list even though None wasn't given as the argument. That can easily surprise anyone if they'd expect your function to modify their list in place.

  • @leokiller123able
    @leokiller123able 2 месяца назад

    This example for exception handling is not very good because in this case there is only one possible error case: ValueError, and I think in cases like this when there is only one possible exception case it is fine to use an empty except statement.

    • @Indently
      @Indently  2 месяца назад +3

      If there's only one possible error and you know it's a ValueError, why would you catch a bare Exception instead of a ValueError?
      Using a bare "except" just says that there's potentially something that will go wrong, and that you have no idea what it is.

    • @leokiller123able
      @leokiller123able 2 месяца назад

      @@Indently for less verbose code, and because I don't want to catch an object that I won't use, anyway people who will read my code will see what type of exception it is just by looking at the error message (in my print statement for example)

    • @callbettersaul
      @callbettersaul 2 месяца назад

      @@leokiller123able You're not forced to catch an object. If you don't plan on using the exception object, you just write "except ValueError" and omit the "as e". And making people look through your code to try to figure out the potential exceptions is not a good idea. And it gets worse as your project's size increases.

    • @schwingedeshaehers
      @schwingedeshaehers 2 месяца назад

      and there is at least one, probably at least 2 other errors possible

  • @user-uc6wo1lc7t
    @user-uc6wo1lc7t 2 месяца назад

    target: list[T] = None... Meh...
    Maybe Optional[list[T]] would be better? I don't know why your type checker doesn't complain about your code example, but complains about mutable default in function signature...

  • @6_nikki_9
    @6_nikki_9 2 месяца назад

    cool video 😎

  • @barbarosteomankosoglu6602
    @barbarosteomankosoglu6602 2 месяца назад +1

    What app is this, looks really nice

    • @Indently
      @Indently  2 месяца назад

      We're in PyCharm, my friend :)

    • @barbarosteomankosoglu6602
      @barbarosteomankosoglu6602 2 месяца назад

      @@Indently Is mac and windows look different? Eventhough I have 24.1, it looks really older.

  • @andylem
    @andylem 2 месяца назад

    WHat editor is this?

  • @user-co9rc1kp7p
    @user-co9rc1kp7p 2 месяца назад +3

    I often see people using Ellipsis to define abstract method body instead of pass or NotImplemented. I guess this is weird, so use it either to show you need to code there something later or for "there could be anything" purpose. At the same time Ellipsis is ok for using inside the Protocol methods, because you're allowed to call these methods. Sry 4my Eng

  • @-wx-78-
    @-wx-78- 2 месяца назад

    Reminds me of Unix ed, which respond "huh?" to any error (without "huh" part, you know ;-).

  • @KeithKazamaFlick
    @KeithKazamaFlick 2 месяца назад

    yes sir!

  • @_dzudzu_
    @_dzudzu_ 2 месяца назад

    1:28 I have to correct you! I was paid zero dollars actually. It was made for homework

  • @AntonFrolov1
    @AntonFrolov1 2 месяца назад +1

    6:34
    target = target or []
    is not as good as
    target = [] if target is None else target
    see the comments below

  • @popel_
    @popel_ 2 месяца назад

    In my own project with 3k lines of code the biggest problem in syntax is 'except Exception' 😂
    But I think it doesn’t matter there because I catching errors from database

    • @Indently
      @Indently  2 месяца назад +1

      Fast to write, but huge pain later ahah

    • @user-vt9bp2ei1w
      @user-vt9bp2ei1w 2 месяца назад +1

      The main problem with 'except Exception' is that Exception subclasses include SyntaxError, NameError, IndentationError and TabError.
      These are exceptions that may be thrown by any line and should not be caught.

    • @callbettersaul
      @callbettersaul 2 месяца назад +1

      @@user-vt9bp2ei1w I tried to catch the errors you mentioned and I only managed to catch NameError. All other errors were still thrown despite the 'except Exception'.

    • @callbettersaul
      @callbettersaul 2 месяца назад +1

      I would assume there would be a general superclass for all those database exceptions. I would suggest catching that instead. Sweeping a critical "random" exception under the rug can be fatal in some circumstances.

    • @joshix833
      @joshix833 2 месяца назад

      ​@@squishy-tomatono bare except is like except BaseException

  • @bhai431
    @bhai431 2 месяца назад +1

    *Please Make New Video On Making Telegram Bot wich work 24×7 and please must share the Script/Codes otherwise its very very difficult for us*

    • @bhai431
      @bhai431 2 месяца назад +1

      I have need seeing your old video in this topic but unable to make from 10 days! Even the codes are not available there so I need to type all codes from your videos 😨🥲🥲🥲

  • @aspizuwastaken
    @aspizuwastaken 2 месяца назад +2

    i know your watching this mcoding

    • @Indently
      @Indently  2 месяца назад +1

      I'm a huge fan of mCoding (if you're reading this mCoding) ;)

  • @rondamon4408
    @rondamon4408 2 месяца назад +2

    When you said about bad habits with python I thought that you were going to show visual studio code

  • @Nape420
    @Nape420 2 месяца назад +6

    Few suggestions:
    1. Use the `typing.List` type annotation instead of python's `list`. It's much more flexible and linter friendly
    2. If a parameter is optional (i.e. its None by default) annotate it as such with the `typing.Optional` or use the (>= 3.10) union syntax `|` (e.g. int | None )

    • @__mrmino__
      @__mrmino__ 2 месяца назад +4

      typing.List is deprecated

    • @Indently
      @Indently  2 месяца назад +1

      I don't understand the first suggestion, in what way is it more flexible?
      For the second one I messed up, and made the video without running mypy so I accept that I will get roasted for that xD

    • @coladock
      @coladock 2 месяца назад

      Maybe he wants to express that sometimes List can be upcast to Sequence.
      My work force us pass linting and mypy. Optional is a good habits but some times return Optional may cause mypy warning make it more difficult to fix😅.

    • @callbettersaul
      @callbettersaul 2 месяца назад +3

      1. Built-in type hints were added in 3.9 and that's the exact reason they deprecated typing.List and others. So no, you should not use it.
      2. Optional is not meant to be used with default arguments, as the value None is not actually permitted there, it's merely a placeholder value. Optional is meant to be used when the explicit value of None is allowed. It even says that in the python documentation.

    • @user-co9rc1kp7p
      @user-co9rc1kp7p 2 месяца назад

      Actually, python core devs improved list to be a type annotation as well despite the fact that typing.List has already existed. So later, they did such thing with tuple. I guess there should be a good reason (imho remove useless import, i dont know). What did you mean about flexible? Sry for my Eng :)

  • @nickeldan
    @nickeldan 2 месяца назад

    if x == True:
    This one makes me want to die.

  • @chestnutmongrel
    @chestnutmongrel 2 месяца назад

    A really bad habit to avoid is create a video with that generic naming - zero new information in five minutes, thankyouverymuch...

    • @Indently
      @Indently  2 месяца назад +6

      You might not have noticed, but the thumbnail gives you a little *hint* about what will be in the video ;)
      Thank you for your constructive comment nonetheless! Have a great week :)

    • @marcellfarkas5889
      @marcellfarkas5889 2 месяца назад

      This naming convention is very common unfortunately. By the way this video was useful for me.

    • @callbettersaul
      @callbettersaul 2 месяца назад +2

      @@Indently Probably difficult to find it in a year tho ("I think I remember Indently making an awesome video about x, let me try finding it").

    • @Indently
      @Indently  2 месяца назад +2

      It's time to create an add-on that allows you to save videos to your own playlist with your own names xD