Live data from Hacker News

New Ways to Be Told That Your Python Code Is Bad

nickdrozd.github.io

31–40 of 262 posts

Re: New Ways to Be Told That Your Python Code Is Bad

#31
> less code is better than more code, and this block can be rewritten more concicely

Conciseness is not necessarily better.

- Does this idiom make debugging easier? no, it doesn't.

- Does this idiom make it easy to identify where a branch starts and ends? no, it doesn't. Before you could use indentation alone, now you have to read the statement.

- Is it slightly faster to type? Maybe. But that does not matter because time spent typing is a tiny tiny fraction of the time you spend as a developer. You spend much more time reading than typing.

Re: New Ways to Be Told That Your Python Code Is Bad

#32

I love linters. This is one of the first things that I add to a new project, before I write one line of code: https://github.com/realm/SwiftLint I write about it here: https://littlegreenviper.com/miscellany/swiftwater/swiftlint...

Hating linters is like hating a weight scale for telling you your weight, or hating a blood exam for telling you that you have high cholesterol.

If the linter says your function is too long then you refactor it, you don't turn off the linter. You also fix it immediately, not "later" (broken windows theory) before the next offender copies and pastes the offending code or continues making it worse.

In underdeveloped countries, governments manipulate the definition of unemploment to make themselves look better. Does that solve anything? no. It actually makes things worse because now you cannot mobilize people and resources to solve a problem you don't have. It's wrong. And so is turning off linting.

Re: New Ways to Be Told That Your Python Code Is Bad

#33
post #7

Sure, once you cherry-pick the most trivial imaginable example ternary expressions are easy enough to read. First counter-example which came to mind: print("yes") if random.choice([True, False]) else print("no") Does this do the right thing? I was pleasantly surprised to find that this is indeed lazily evaluated, but that's not at all intuitive: first because `print("yes")` comes before the conditional (note that the…

I would write it like this. Seems fine to me

  do_a_thing(now, using, five, different, parameters
      ) if some_complex_condition(using, four, different, parameters
      ) else do_another_thing(having, three, parameters)

Re: New Ways to Be Told That Your Python Code Is Bad

#36

Earlier quoted context omitted.

Exactly. I prefer this a lot more to at least avoid using else: x = 5 if condition(): x = 4

In your version, we need to check the definition of 'condition', to see whether the 'x = 5' statement has any affects on its execution. The ternary won't assign the variable until we know its value. Also, your version isn't safe to use with objects (e.g. 'myObject.x = ...'), since the initial assignment could trigger arbitrary code (properties, __setattr__, etc.). Also, your version isn't safe to use when the right-h…

Can't be used in list comprehension either

Re: New Ways to Be Told That Your Python Code Is Bad

#37

Python doesn't have a do..while loop, so when you want to do a thing at least once, the simplest replacement is starting the loop with "while 1:" and ending the loop with "if ... break". I disapprove of any linter that flags this idiom.

why "while 1:" and not "while true:"?

Re: New Ways to Be Told That Your Python Code Is Bad

#38
post #27

>most code is not complex enough to warrant while loops, scale = 5 while (scale > 0.1): do_stuff(scale) scale = scale/2 Sure, you could use exponentials with range(), but is that really clearer?

Even clearer:

    scale = 5
    # The alternative would be exponentials with range(),
    # but it's clearer to use 'while'
    # pylint: disable=[while-used]
    while (scale > 0.1):
        do_stuff(scale)
        scale = scale/2
Less sarcastically, how about:

    scales = itertools.takewhile(
      lambda n: n > 0.1,
      functools.reduce(lambda x, y: x / y, itertools.repeat(2), 5)
    )
    map(do_stuff, scales)
This would be even easier with an 'iterate(x, f)' function which generated (x, f(x), f(f(x)), ...), but I couldn't find one in Python's builtins:

    scales = takewhile(
        lambda n: n > 0.1,
        iterate(5, lambda x: x / 2)
    )
    map(do_stuff, scales)

Re: New Ways to Be Told That Your Python Code Is Bad

#39
post #30

The author mentioned this at the end, but banning while loops (and any other way for running a loop with a priori unknown number of iterations) actually decreases the expressiveness of a language - it becomes no longer Turing complete. A classic example is the Ackerman function - it cannot be computed in a primitive recursive language. (The author is on point when they say almost all code used in practice is primitiv…

I think “while loops” are orthogonal to primitive recursive functions.. for example, here’s how to compute the Ackerman function using only recursion in several languages; https://stackoverflow.com/questions/16115815/ackermann-very-...

Re: New Ways to Be Told That Your Python Code Is Bad

#40
post #4

> less code is better than more code Not when it's at the cost of readability. The example "better" code fails my readability test horribly. I'd gladly take C's ternary operator over this monstrosity: > x = 4 if condition() else 5

Yeah I don't like them as implemented, because most of my 'if' statements are in response to unforeseen things, so my mental expansion of it is 'Now, stop and check if...' I wouldn't mind it so much if I could write it as: x = 4 unless shenanigans(); then x = 5 Yes, that is a semicolon. Fight me.

That's PERL right there.

Makes way more sense to my brain to read:

print unless $x ~ /end$/;

then

print if $x !~ /end$/;

I used to get flack for using not just if expressions as ternaries, but also for using unless. Then I started teaching PERL at my company and drilled it into all the fresh new minds.

Post reply on HN