5 Bad Ideas In Python

Поделиться
HTML-код
  • Опубликовано: 11 янв 2025

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

  • @420Millar
    @420Millar Месяц назад +42

    I'm not arguing that removing while iterating causes an index skip. But the reason "indently" is getting printed is because it's the current value stored in the variable "channel" during that iteration. Than the index skip happens which results in bool. It would have been more appropriate to print the list itself on each iteration not just the indexed value.

    • @jasonjarosz5897
      @jasonjarosz5897 Месяц назад +5

      Exactly. The variables "i" and "channel" have values stored in them for each iteration of the loop. The print statement on line 7 is referencing the values stored in them on line 3, it's not referencing the list. If line 7 was "print(i, channels[i])", then it would have printed "1 ArjanCodes" on the 2nd print instead.

    • @jeromemainaud
      @jeromemainaud Месяц назад +7

      The problem with removing items from the list while iterating is not that 'Indently' is printed but that 'ArjanCodes' is not (it is not processed).
      In Java, they chosen to support the fail-fast pattern and an exception would be raise in the next iteration.

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

      @@jeromemainaud Yes, its not even as if a continue can save it.
      I suppose the solution would be to build a new list.

  • @edwolt
    @edwolt Месяц назад +19

    In the recursion question, both functions are doing different things. The recursion is doing a lot of recalculations, while the iterative function calculate each number once. If you wanna say recursion hurts performance, it's better to compare two functions that are well written.

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

      How would you rewrite recursion to more efficiently calculate the nth fib number, aside from implementing caching

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

      @mikesmith4236 You could just rewrite the loop as a recursion:
      fib(a, b, n) =
      | if(n==0) return a
      | else return fib(a+b, a, n-1)
      It's not that intuitive, but this function is doing the same as the loop. So the difference of time would be more caused by recursion overhead.

  • @prok4744
    @prok4744 Месяц назад +109

    I am not convinced handling 'exception as e' is wrong. This is more like pushing one opinion as a standard or "good practice".

    • @aodhai
      @aodhai Месяц назад +37

      Especially in fields where you need the program to keep runnnig and already log all errors as they occur

    • @IonicMC
      @IonicMC Месяц назад +7

      No it is actually VERY bad as a ctrl+C (exit) is handled by exceptions so this would not be ideal

    • @mf_366
      @mf_366 Месяц назад +29

      ​@@IonicMC except Exception does not actually prevent Keyboard Interruption. If you were to use BaseException, then yes in that case I believe it would prevent Ctrl C in the terminal

    • @PhilDubach
      @PhilDubach Месяц назад +6

      Perhaps for simple try blocks, where the exception cases are clear, I agree with the video. As soon as you have a call to a library, you now need to either trust the docs or inspect the library code and also make assumptions about the exact version of the library being used. E.g. sockets, where the exception hierarchy has changed and some exceptions were deprecated.

    • @bakh554321
      @bakh554321 Месяц назад +6

      It's not bad if all you're using is normal exceptions.
      The real issue is when you start hitting the thousands of lines of code. A simple ValueError doesn't tell you much unless you know what raised it.
      When you start working with custom exceptions. You'll see why except all is poor practice.

  • @Tactical_Nerd_Clash
    @Tactical_Nerd_Clash Месяц назад +23

    You can cache the result of the recursion to make it faster

  • @tamasburghard6778
    @tamasburghard6778 Месяц назад +30

    i think the recursion part is wrong. First, you mix the dynamic programming part(nothing to do with python) with the recursion overhead. Avoiding recursion is great if you really need that, but honestly most people using python will never do anything where it really matters. If yes, a single (at)cache will solve the problem with maintaining the readability. If the recursion overhead would matter, python would already be a bad answer, tbh.
    The second example in recursion is an antipattern, a simple loop would suffice with the possibility to setup a retry number.

  • @sumedh-girish
    @sumedh-girish 4 дня назад +1

    19:43 Well this would only work soo long. If I enter the wrong stuff enough times, you will run into a snarly error for exceeding maximum recursion depth, or worse fill up memory and crash. Wouldn't it be better to use a while loop? Why recursion.

  • @kmn1794
    @kmn1794 Месяц назад +27

    So the challenge is to produce an example of code that violates as many of these rules as possible whilst being readable and performant.
    Bonus points for using descriptive names rather that type annotations.

    • @therealdebater
      @therealdebater Месяц назад +1

      "Bonus points for using descriptive names rather that type annotations" Okay, so this is a valid point, but it needs to be explained, because it will not be obvious to a lot of people. My take on this idea is that, for non-strongly typed languages, the code is intended to be type-flexible. Type annotations tend to defeat this objective.
      For example, `def neg(x: int): return -x` might be supposed to return the negative of a number. But if I try to use `neg(1.2)` it fails because I've given it a float, and the type annotation demanded an integer. If I had written `def neg(x): return -x` my float example would have worked. And so would any other numeric type, probably, including future numeric types that I have yet to invent. Also, the `def` is a bit more concise. Maybe I should write `def neg(num): return -num` to hint that the parameter is expected to be numeric.
      Having said all of this, I use TypeScript professionally instead of JavaScript and I find the TypeScript code to be immensely more maintainable in a commercial setting. So the ideal of dynamically typed programming I just illustrated may need to be taken with a pinch of salt. Possibly it is a case where the pros are outweighed by the cons.

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

      @@therealdebater Is your example not more about poorly typing, rather than not having to type at all.
      Your code would have worked with typing had you used float as the type instead. Whilst also providing linting, that highlights if your input is invalid.

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

      @@SirZyPA Yes, in a way. I could have used a broader type, or just Any. I think my example was poor. Imagine writing a function to sort an array. Its input might be an array of Any. Or perhaps an array of Comparable. Not sure. Anyway, I think it can be seen that careful choice of type (annotations) is better than no types at all, but it is always a little wordier. I find, in practice, the stronger typing is worth it most of the time.

  • @tigranav.3960
    @tigranav.3960 Месяц назад +11

    the example of a good recursion usage is actually bad. This is not a case fir recursion, rather you can use while True, and break do loop on success. the recursion approach is bad because you fill the call stack, the stack can overflow

  • @DrDeuteron
    @DrDeuteron Месяц назад +6

    5:25 another thing about try/except blocks is minimizing the code in the try block, so the 1st print statement should be before:
    try:
    user_float = float(user_input)
    except ValueError as err:
    ...
    except TypeError as err:
    ...
    else:
    print ("etc...")
    and note, the print statement is removed also, only the cast-to-float lives in try because only it is in question

  • @BizarePlayer
    @BizarePlayer Месяц назад +12

    "It's easy to debug if you know how error is produced."
    KeyError: 0

    • @smorales9492
      @smorales9492 Месяц назад +2

      That only tells that the key 0 doesn't exists in a dictionary, a very clear exception

  • @AirLight1646
    @AirLight1646 Месяц назад +6

    “We need to unindent” but I thought this was Indently!

  • @MatthewMakesAU
    @MatthewMakesAU Месяц назад +12

    For list modification, I loop through my list and append the ones I want to keep to a new list. No deletion at all. Much easier to debug

    • @martijnlerutte6118
      @martijnlerutte6118 Месяц назад +4

      Not very memory efficiënt, but certainly easier

    • @TheMaginor
      @TheMaginor Месяц назад +7

      Or you could use filter(), which is arguably even cleaner. This creates an iterable, so if you don't need to store the new list, only iterate over it, even saves the allocation of a new list in memory.

    • @davidgillies620
      @davidgillies620 Месяц назад +2

      See my comment elsewhere: use a list comprehension or filter() with a lambda. This is THE use case of filter().

    • @FreddericUnpenstein
      @FreddericUnpenstein Месяц назад +2

      This is a crappy way to do it, like, you're linearly searching the list TWICE since remove does it, too. It's also usually not a problem if you're iterating backwards. Plenty other patterns when you need to edit a list in-place like this, it's only really a problem with iterators and simple for loops (and not only in Python).

  • @dirtydevotee
    @dirtydevotee 22 дня назад

    I get you're talking about indentation, but that function at 11:16 does NOT work as expected. The problem is that a "False" nested if will trigger a return, preventing evaluation of the rest of the options. The better way is:
    def check_all(...the same parameters...):
    temp_var = True
    if not has_money:
    temp_var = False
    print ("No money...")
    ...
    if temp_var == True:
    print ("You have everything!!!")
    return temp_var
    Now it will let the user know if more than one parameter is "False".

  • @starryknight64
    @starryknight64 Месяц назад +8

    Ironic that a channel named "Indently" is recommending against excessive indentation... haha😉

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

    A good rule of thumb with guard clauses I use is " If statements that return can never have an else statement."

  • @arkazix4304
    @arkazix4304 Месяц назад +2

    Personally, the main reason I avoid using recursive algorithms in Python is the lack of tail call optimization, which unfortunately is very unlikely to ever be implemented. Some algorithms, particularly those operating on tree structures, are well-suited for recursion. However, Python is unfortunately not the best language for implementing them.

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

    The biggest issue I find with error handling is not the exception block, but handling the exception in the exception block and not passing the exception to the calling function. In an API this many times results in it returning a 200 response with no content, and the error being logged internally. So something interesting would be to cover how to do error handling in big multi-layer applications.
    On example I have is in one program someone made a DB call which could return a not found exception, but then handled the exception to log out the error message and return an empty array. All good, user get's an empty response if not found, but if the DB connection fails (DB not found exception) it was also returning 200 with empty response instead of a 500 internal error.

  • @JustThatRandomTroll
    @JustThatRandomTroll Месяц назад +2

    General exceptions are not always bad. For instance if your program is calling to a JVM instance (i.e. Databricks), Python can’t access the underlying exception types. So you have to catch it in a general except clause, check if str(e) contains the Java error you want to check snd raise again otherwise. So there are totally valid use cases

  • @Hendika
    @Hendika Месяц назад +2

    Using guard clause will make you understand your logic better

  • @therealdebater
    @therealdebater Месяц назад +2

    13:22 I think (I'm not sure) that a better term would be 'early exit' rather than 'guard clause' (which tends to be used in connection with multi-tasking and synchronisation). Early exit is often a neat way to avoid spaghetti if-then-else structures, but it can also be a liability. In a large block of code, an early exit can be easy to miss, and it can make it hard to spot certain kinds of bug. So use it with care; try to avoid it getting buried in a mass of code.

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

      In what situation would an early exit be bad?
      Youre failing early, you aren't short circuiting a success.
      Unless you aren't setting some state, but then if its that type of code, you should be returning to a piece of code to make sure thats all set.
      In C that would be an acceptable use of goto. I don't know what the python way is though.

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

      @@benholroyd5221 Obviously not OP but a problem I caught with it is that if you want to print all conditions that aren't met, you can't do it with the guard clause because you're exiting early. With the nested if...else statements, you can print all of the missing conditions and return false at the end, otherwise return true.

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

      @@Siggy or just setup a flag and return it at the end after checking all conditions

  • @ukaszzbrozek6470
    @ukaszzbrozek6470 Месяц назад +1

    I am usually working with TypeScript. This is eyeopening that knowledge about one language don’t help to avoid gotchas in a other.

  • @raz0229
    @raz0229 Месяц назад +1

    Always wondered why does the intellisense warn me about setting a default value to a mutable object... Thanks for your explanation

  • @spaniard13
    @spaniard13 23 дня назад

    Making a copy of large iterables is often something we cannot afford.
    It may not look as sleek as an enumerate, but you need to learn to use while loops and increment the index appropriately as the iterable is modified.

  • @null-0x
    @null-0x Месяц назад +1

    20:12 That last "bad idea" can sometimes also be used as Python's version of static variables.

  • @Gr3GFX
    @Gr3GFX Месяц назад +2

    You can always reverse a list to safely modify its contents in a for loop.

  • @HardlineCheats
    @HardlineCheats Месяц назад +2

    20:10 you should return the do_math() because if you would have something after the except block it will run twice because when its done with the new do_math function it will continue with the original and it will run everything that is outside the do math twice

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

      that's what try/except/else is for. do_math() should be in an else block.

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

      @@DrDeuteron wdym

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

      ​@@HardlineCheatsImagine try being an 'if error' statement. Once the user inputs the correct code, since no error occurred, the reader will read out the else statement, where the 'return' function will be executed.

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

      @@megareunion4407 basically you just need to return it even in the except it will work

  • @tubero911
    @tubero911 9 дней назад

    Mutable default arguments divides the Python community to this day. The 0.05% of people who justify it because functions are first class objects and it’s useful for caching vs. the remaining 99.95% who are astonished and frequently bitten by it.

  • @Fireman9143
    @Fireman9143 Месяц назад +1

    Thank you. I really appreciate your python teaching!

  • @duccie
    @duccie Месяц назад +2

    isnt the good recursion example potentially bad cuz if mate is too drunk and keeps hitting those exceptions wed hit a stack overflow eventually

    • @MrMoon-hy6pn
      @MrMoon-hy6pn Месяц назад

      If you reach a recursion depth of ~1000 you get a RecursionError. Ol’ mate would need to be REALLY drunk and patient to get that error. To get a stack overflow you would need to set sys.setrecursionlimit(n) to an extremely large number and not run out of heap memory before then.

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

    For the endless if-else checks, if you don’t need separate messages for every false boolean and just want to return a bool, just make a new variable (maybe call it returnBool) and set it to the first bool. Now, set it to itself and the second bool. Then, just keep doing that over and over until you reach the last bool. It should look like this:
    def exampleFunction(bool1: bool, bool2: bool, bool3: bool, bool4: bool) -> bool:
    returnBool: bool = bool1
    returnBool = returnBool and bool2
    returnBool = returnBool and bool3
    returnBool = returnBool and bool4
    return returnBool
    However, you could also use the all() function. It should look like this:
    def exampleFunction(bool1: bool, bool2: bool, bool3: bool, bool4: bool) -> bool:
    return all([bool1, bool2, bool3, bool4])

  • @synchro-dentally1965
    @synchro-dentally1965 Месяц назад +1

    Regarding the Fibonacci calculation, the readability goes down but what is your opinion on using the exact formula for the nth term?
    an = [Phi^n - (phi)^n] / Sqrt[5].
    Phi = (1 + Sqrt[5]) / 2
    phi = (1 - Sqrt[5]) / 2

    • @dragweb7725
      @dragweb7725 Месяц назад +1

      i did not know the golden ratio could be used to calculate Fibonacci 😮 this makes the function complexity O(1) instead of the O(n) function with for loop, great !

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

      The issue is that this uses floating point numbers and so it doesn't actually work for large n (because of inaccuracy).
      The absolute best way to do fibonacci on computers is using matrix representation the idea is that you have an vector f = [F(n), F(n+1)] and a matrix M such that M @ f = [F(n+1), F(n+2)].
      Then you can use matrix exponentiation to get: ((M ** n) @ [0, 1])[0] = F(n)
      You can do matrix multiplication rather quickly by repeatedly either squaring the matrix or squaring and multiplying it by M**1.
      This way you get O(log(n)) runtime and perfect precision.
      Also works for generalized fibonacci (like what if it's T(n) = T(n-1) + 52T(n-2) - 13T(n-3) instead? Well, you use the same method, just pick a corresponding matrix.)
      Also the version in the video can be fixed very easily: @functools.cached

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

    I did the first mistake. I noticed luckily that that the printed length did not match the number of printed elements from that list. After thunking myself, I asked ChatGPT and it found the bug

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

    For recursion: if recurrsion is still the simplest way to do something and you have enough memory you can cache the results to speed up the process with the decorators lru_cache or simply cache from functools.

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

    Damn, that "has money, time and cat but no girlfriend" felt kinda personal 🤣

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

    13:22 when i heard about that, it was a heaven!! Now I cant even think about nesting!
    19:39 i would use loop here too, like, return 0 and return 1 in cases if it completed without or with error, and loop accordingly

  • @rupen42
    @rupen42 Месяц назад +1

    Every time I see list.remove(value), it gives me the ick. Are you sure the list has only one element with that value? Are you sure you want to remove only the first occurrence? Etc.
    When I see things like that, I either use sets or remove them based on the index.

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

    12:10 instead of just deleting and rewriting, most editors can flip the if/else, resulting in the better code you show.

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

    Aside from the if..else section as there are use cases for the rest of the examples, what I learned from this is "Thing to not do unless you absolutely know what you're doing."

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

    19:58 i don't think that would be my GOTO strategy...
    also isn't typing deprecated?

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

      Who deprecated the guard clause?

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

    Your recursive example is O(n^2). Recursion is not the problem here. A better example for recursion is flattening a tree structure or tree search.

  • @antoineleduc7611
    @antoineleduc7611 28 дней назад

    The first one is a really good one, it’s funny, functionnal programmer had it right all along
    Modifying state can lead to some annoyance :p

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

    to be fair, couldn't you use:
    except Exception as e:
    match e:
    case _ if(isinstance(e, errortype):
    ...
    to make it even more explicit when determining what to do on an error?
    it's a bit hacky, but you could even group classes of exceptions together like:
    case _ if any([isinstance(e, errortype_1), ..., isisntance(e, errortype_n)]):
    print(f'error: {e}')
    (after working with it for like 5 min in REPL i have come to the conclusion this is more of a matter of preference and i am being nit-picky, but it was a fun thought exercise before work at least lol)

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

    03:00 is it not this the way to go: channel_filtered = [channel for channel in channels if channel != 'Idently']?

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

    25:10 it would be better to use a guard for the None value instead of an if/else with intentions - just this line instead of an if/else: ' target_list = target_list or []'

  • @fcolecumberri
    @fcolecumberri Месяц назад +1

    Default mutable that persist the function call seems more like a python design bug than a "bad idea" on the user's side. What's the intended use of that? If you want persistent data, you create a class.

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

      I'm trying to work out how they got here.
      Every language I'm aware of creates a stack frame for each function. and everything that isn't returned just gets destroyed.

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

      I've gotten some good use out of it when debugging.
      Ex. 1: Imagine a function that gets called thousands of times, that does something wrong when given 2 or 3 specific inputs in a row. The mutable default allows you to record those inputs, and inspect them when you have a breakpoint in an `except`. Especially handy when those values are large objects you can't just print.
      Ex. 2: You have a single function on a server that may get called multiple times asynchronously. You can't just put a breakpoint in there, as it'll break on every call, instead on the first call, you have `foo=[]` as a default parameter, check if it's empty, if so, `foo.append(1)` and break.
      Sure there's multiple other ways to do the same thing, but none that can be done as easily afaik.

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

      @@ultru3525 I can't get a reason why a singleton variable instanciated at the beginning can't do the same exactly as fast, but ok.

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

      @@fcolecumberri If "at the beginning" you mean outside the function/method, then yeah, sometimes it works, sometimes it doesn't without a `global` keyword which I don't fully understand and don't intend to learn when there's an easier alternative.

    • @Jason-b9t
      @Jason-b9t Месяц назад

      There's nothing complicated about this, it's just a result of python syntax. When you use default arguments, Python does not help you create an additional anonymous function that will be called every time the function is executed. Instead, it executes the expression and saves the resulting object in the function's properties. Because Python does not have a const decorator, it cannot prevent you from accessing it (and the reference semantics make it difficult to easily make a type hint containing const).

  • @icarob-eng
    @icarob-eng Месяц назад +1

    I do have good uses for `exception as e`, like when I have a complex library that calls user defined functions. Those functions can raise some exceptions and I cannot predict what they will be, and I need my system to fail gracefully oh just log and proceed to the next task

    • @tubero911
      @tubero911 9 дней назад +1

      Deeply problematic that a consumer of a function/method/interface in Python can never know the exact contract of that interface because the Python programming language does not enforce its visibility.

  • @Mustafa-Mohammed22
    @Mustafa-Mohammed22 Месяц назад

    such a cool concept of a video thank you very much

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

    These are not bad ideas that are specific to python, but just generally had programming practices, illustrated in Python. As others have said, there are also often exceptions to these rules. E.g. it’s ok to use indented ifs for two levels, if the contained blocks don’t get too long. Catch all exceptions can be useful at the top level to exit the application elegantly. Recursion is fine to get things running - don’t try to optimise too early. Etc. Etc. YMMV.

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

      That list iteration one is python specific. Or at least python could handle it better.
      Same for the mutable defaults one. I have no idea what python is doing under the hood. But I would have expected it to use a stack frame, but obviously not.

  • @HeitorYT
    @HeitorYT Месяц назад +1

    No cat... No girlfriend... No time... No money...

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

    19:39 that still isn't ideal, as we can reach the recursion limit and the program will fail

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

    many people do not know how to use async/await properly, and it leads to make asynchronize code to become synchronized again.

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

    what IDE is that?

  • @KayleLang
    @KayleLang Месяц назад +1

    The first example shows why you should be working with functional languages.
    Teasing aside, functional languages can inform better practices. I assume Python has a filter method. That would be perfect for this code.

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

      Pure functional languages are lame and gay, but elements from them in multiparadigm languages are welcome. That first example would be most easily solved with a generator or a list comprehension, calling filter map and reduce are a bit cumbersome and ugly.

  • @alexanderdelguidice4660
    @alexanderdelguidice4660 8 дней назад

    I really don't like "if not boolean" in python because not None is True. If something goes wrong before this check and you didn't catch it, you might still get the answer you are looking for.

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

    I've used 'except exception as e' a fair amount where I want to log errors but I want the program to continue even if there is an issue. I'm not convinced by this video that this is a mistake.

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

    If not gurd cases are a very elegent solution.

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

    The first one is still showing Indently because the variable channel is already set.

  • @cheesepop7175
    @cheesepop7175 Месяц назад +1

    Are you kidding me? I use nested if-statements and recursion all the time, i don't care if it makes the code bad and unreadable, the only thing that matters is that it works.

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

      A working product is better than no product in many cases. Happy you have it figured it out :)

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

    18:18 RecursionError if user wrong too many times

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

      True, you could possibly add a retry limit, or hope that the user doesn't get this wrong more than a thousand times (although that could be wishful thinking).

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

    really cool videos but as a beginner i find them pretty hard to understrand some times, can you maybe explain things a bit more so that us just starting out can understand?

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

    Very informative

  • @GeraldWaters
    @GeraldWaters 9 дней назад

    Not for the first time, I've gone to watch a video on this channel, and the first two examples in it have language elements I don't recognise but are not vital to the point being made.
    That sets up an immediate "what the?" as I have to work out whether I need to go learn that language element to get the point being made.
    If I have a single advice for makers of programming videos, it is:
    - please cut your example code back to the bare minimum!

    • @Indently
      @Indently  9 дней назад

      Nice to have you back, every video we make as teachers is a learning experience for us as well and your feedback all carries on to the next videos. Thank you!

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

    Uhm, didn't like that much the explanation to "why 'Idently' was printed" in the modifying a list section. It printed it because the channel variable had that value since channel was attributed prior to removing teh value held by channel from the list. I think making a point to notice as soon as possible that Arjan doesn't appear while Idently does is the most helpful here.
    Don't get me wrong, it is not wrong and the overall point is well made. The idea was to give contructive criticism, here. If I failed, I'm sorry!

    • @amorpaz1
      @amorpaz1 14 дней назад

      No, you’re right. That bothered me too.

  • @SantiagoRojo
    @SantiagoRojo 23 дня назад

    Please revise the recursion part. There are several errors in your explanation. It would be interesting to understand why specifically Python is not great at recursion (Guido Van Rossum's old blog posts have good context on the topic).
    Recursion is not bad in all languages. Also, the fibonacci solution is a bad usage of recursion.

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

    Not at all surprised that your take on recursion got a lot of objection. Issues with it are not limited to Python - but nor is its value for certain algorithms. De-recursifying can make the code unreadable (we all had to go through that exercise in uni, didn't we?) for little gain. Horse for courses, as we say.

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

      I appreciate when people object and present their own ideas and opinions, it allows us all to learn new ways of seeing things.

  • @111sam1
    @111sam1 Месяц назад

    Handling “exception as e” is fine as long my as you re raise the error after

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

    Thank you 😊

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

    But those are not "ideas", they are bad coding practices and should be avoided in any programming language

  • @davidmurphy563
    @davidmurphy563 Месяц назад +9

    Except Exception as e is perfectly fine 99% of the time. It's just part of this absurd typing disorder you suffer from. You can type the error response for goodness sake.
    People, don't waste time in typing nonsense, you have a job to do. Get on with it.

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

    i have not cat, girlfriend or money ☹️…at least i have my jigsaw puzzle collection

  • @TheRealZitroX
    @TheRealZitroX 26 дней назад

    Bad ideas in python
    1. Using python

  • @BotturasStudios
    @BotturasStudios Месяц назад +1

    hi

  • @amorpaz1
    @amorpaz1 14 дней назад

    I love many things about Python but the mutable default values thing is not one of them