Live data from Hacker News

New Ways to Be Told That Your Python Code Is Bad

nickdrozd.github.io

191–200 of 262 posts

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

#191
post #122

> Python programmers in general have an irrational aversion to if-expressions, a.k.a. the “ternary” operator. Because the Python ternary operator is fucking backwards! Why on earth would you put the condition in the middle !? x = 4 if condition() else 5 vs.: condition() ? 4 : 5 vs. the author's own lisp example: (setq x (if (condition) 4 5)) I love ternary operators, and Lisp/ML-style if else blocks that return thing…

If you don't like awkward ugly clunky syntax, you probably shouldn't program in Python. And, for that matter, if you like correctness checking, you also shouldn't program in Python...

Serious question, what alternative(s) to Python would you recommend with nicer syntax?

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

#192

Ah, leave people alone. I stopped using ternary expressions because someone told me not to. I could start using them again, whatever. I use while loops when the burden of describing the loop as an iteration is too high (too much of a stretch), or when I'm writing something that really isn't a composition of forEach/map/filter/reduce (gasp). For me, it's whatever I need to do to get through code review without arguing…

> For me, it's whatever I need to do to get through code review without arguing too much. The language quibblers of the programming industry have installed a set of opinions, not knowledge. They proceed to waste time and energy with their assertions.

> The language quibblers of the programming industry have installed a set of opinions

Pray they don't install another one.

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

#193
post #122

> Python programmers in general have an irrational aversion to if-expressions, a.k.a. the “ternary” operator. Because the Python ternary operator is fucking backwards! Why on earth would you put the condition in the middle !? x = 4 if condition() else 5 vs.: condition() ? 4 : 5 vs. the author's own lisp example: (setq x (if (condition) 4 5)) I love ternary operators, and Lisp/ML-style if else blocks that return thing…

I love Python but my personal hate goes for this when used in list comprehensions. a = [1,2,3] # list comprehension with if [ x for x in a if x > 1] [2, 3] # list comprehension with if/else [ x if x > 1 else x*2 for x in a] [2, 2, 3] When it's just "if" it goes after the "for", when it's "if/else" it goes, all of it, before. I still don't understand why it's this way, it doesn't even make sense even reading it in nat…

The "before" is what value is returned, the "after" is whether it should be returned.

In your case you were conditionally choosing a manipulated return value for x and didn't care at all about filtering the list. Here's one with both:

  [x if x > y else x*2 for x in a if x % 2 == 0]
   ^^^^^^^^^^^^^^^^^^^            ^^^^^^^^^^^^^
   return x as...                 filter down to only...
   x or x*2                       even 'x's
There's not really a semantically logical place for an "else" in the latter half because it's only looking for a true statement so it can return x (or not).

For example this makes sense:

  ... if x % 2 == 0 or x == 3
(filter the list to even values of x or the value 3)

but this does not:

  ... if x % 2 == 0 else x == 3
(filter the list to even values, otherwise wait, otherwise?)

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

#194
post #155

Earlier quoted context omitted.

In C, I always put the ternary clauses on their own lines prefixed with the operator. This always makes things readable. int result = condition ? value * 12 : something_else(); and in the case where the condition is sufficiently complex: int result = ( some_condition() && another_condition() && yet_another_condition() ) ? value * 12 : something_else(); For me, at least, this is entirely readable. The unfortunate bit…

> The unfortunate bit is that there is no formatter in existence (yet) that can handle this for C, or really any other language with similar syntax. Prettier does it fine for JS, which uses C-style ternary syntax. > Python's "Black" formatter actually does the best job here, yet the python ternary syntax is still very verbose and strange IMO. To me, its quite natural when used sensibly, since if you drop everything a…

Prettier does okay, it has some weird edge cases though that make certain code entirely unreadable. But they're rare. I still prefer how Black does things, e.g. splitting complex expressions into multiple lines using parenthesis.

> Though I would slightly prefer if the ternary form was:

Agreed, I do like that much better too.

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

#195

Earlier quoted context omitted.

If you don't like awkward ugly clunky syntax, you probably shouldn't program in Python. And, for that matter, if you like correctness checking, you also shouldn't program in Python...

Serious question, what alternative(s) to Python would you recommend with nicer syntax?

Scheme or Go.

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

#196
post #157

Some (including me) would argue that writing any loop yourself is considered harmful and you should be better of using higher order functions. In Haskell there is a higher order function for basically every usecase and (most of the time) the compiler is smart enough to merge chained higher order functions into a single loop. Python is at least trying with its `itertools` package, but it's still a far cry from the gen…

Okay, so how should the following loop be rewritten:

    while self.keep_going:
        s = input('> ').lstrip()

        if s == '':
            continue

        cmd = self.parse_cmd(s)
        
        # The "quit" commands sets self.keep_going to False, oh the horrors
        # of the global mutable state
        cmd()
? Should it be:

    for cmd in self.stream_of_commands():
        cmd()
But stream_of_commands() will still have a loop inside it, wouldn't it? Because that's how you write generators?

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

#197
post #122

> Python programmers in general have an irrational aversion to if-expressions, a.k.a. the “ternary” operator. Because the Python ternary operator is fucking backwards! Why on earth would you put the condition in the middle !? x = 4 if condition() else 5 vs.: condition() ? 4 : 5 vs. the author's own lisp example: (setq x (if (condition) 4 5)) I love ternary operators, and Lisp/ML-style if else blocks that return thing…

I love Python but my personal hate goes for this when used in list comprehensions. a = [1,2,3] # list comprehension with if [ x for x in a if x > 1] [2, 3] # list comprehension with if/else [ x if x > 1 else x*2 for x in a] [2, 2, 3] When it's just "if" it goes after the "for", when it's "if/else" it goes, all of it, before. I still don't understand why it's this way, it doesn't even make sense even reading it in nat…

The first is a transform of the values (with only that, the list stays the same length, the IF says whether the transform happens or doesn't for each value), the second is a WHERE filter picking or dropping some values (list might shrink), you can have both (list shrinks and the selected values are transformed):

    >>> list([ x if x > 1 else x*2 for x in a if x 

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

#198

Earlier quoted context omitted.

If you don't like awkward ugly clunky syntax, you probably shouldn't program in Python. And, for that matter, if you like correctness checking, you also shouldn't program in Python...

Serious question, what alternative(s) to Python would you recommend with nicer syntax?

Well, to be fair, sometimes, especially for short scripts, you're stuck with Python because you know it's going to be available.

Personally, from a syntax point of view, as opposed to an easy availability point of view, I prefer Haskell, or Lisp if you can live with the parentheses. Haskell has some syntactic oddities, and the support for infix operators has encouraged the ecosystem to define way too many obscure -looking things, but the syntax mostly just gets out of your way and is relatively regular.

I do admit that if you're going to be infixy anyway, a C-like "?:" ternary is nice. C got its expressions right.

It is, of course, objectively true that one of the things Python does get right about syntax is the significant whitespace, and Haskell has that too (without the stupid colons). Curly braces are the work of the Devil, and "BEGIN" and "END" are just unmentionable.

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

#200

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.

> Python doesn't have a do..while loop Python doesn't have an “[repeat...]until” loop, which C misspells as “do...while”, which fails to express what is going on. > 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". “while True:” is more idiomatic Python (“while 1:” works since 1 is truthy, but using a literal 1 for “Tru…

Actually the most idiomatic way to write this is `while "False":`
Post reply on HN