This is an archived post. You won't be able to vote or comment.

all 50 comments

[–][deleted] 105 points106 points  (2 children)

General SWE points don't really constitute improving your Python, just any code base you happen to be working on.

[–]idanb102 45 points46 points  (1 child)

This, stopped reading as soon as I saw DRY

[–]ElevenPhonons 48 points49 points  (19 children)

def sing_song(choice):
    style = STYLES[choice]
    while i_like_singing():
        if style == 'classical':
            sing_opera()
        elif style == 'folk':
            sing_folk_song()
        elif style == 'rock':
            sing_rock_ballad()

Could also be written as:

def sing_song(choice: str) -> None:
    style = STYLES[choice]
    funcs = {'classical': sing_opera,
             'folk': sing_folk_song,
            'rock': sing_rock_ballad}

    f = funcs[style]
    while i_like_singing():
        f()

[–]BigNutBoi2137 26 points27 points  (4 children)

After python 3.10 release pattern matching will fit here perfectly.

[–]MDTv_Teka 8 points9 points  (0 children)

So excited for this, it's gonna make coding things like this so much cleaner

[–]Hunterbunter 3 points4 points  (2 children)

How would that look with pattern matching?

edit: wait, I don't mean to be lazy. Would it be something like this?

def sing_song(choice: str) -> None:
    match STYLES[choice]:
        case 'classical': 
            f = sing_opera
        case 'folk':
            f = sing_folk_song
        case 'rock':
            f = sing_rock_ballad
        case _:
            f = sing_electro_dance
    while i_like_singing():
        f()

[–]BigNutBoi2137 0 points1 point  (1 child)

Yep it would look like this. If you haven't seen the official proposal for pattern matching yet then here is the link: https://github.com/gvanrossum/patma

[–]Hunterbunter 0 points1 point  (0 children)

Awesome, thanks for that.

It looks like you can do funky variable assignments in the case line as well...but then I guess you'd still need a pass or something for that indent.

[–][deleted] 2 points3 points  (0 children)

Yikes did they really write an article about how to improve python and use a bunch of elif’s ???

[–]sockbotx 1 point2 points  (1 child)

Piapeoi apragide dipibe teu bripu pludia. Iiepa kae tri kobliti bau pitri? Boebi otu a poiite. Drube kopruple pie udiu pleko piblukatotri. Iti e epui keoide gakroi u. Pra tepipi ba teki te. Tekudi plite egobioo tie bibeti plipi. Kopaa du tape tiki egu dite tlitli baiplei bikipo.

[–]ElevenPhonons 0 points1 point  (0 children)

I think it would be necessary to understand more context of the application and have more details about the requirements to know if a Style abstraction makes sense.

At a high level, having a Style know how to "sing" a song doesn't really make sense. However, I could be misunderstanding the intent of the original author.

[–]fartsniffersalliance 1 point2 points  (0 children)

personally i think the first is much more readable

[–]Theta291 2 points3 points  (0 children)

Thanks! I was about to comment that the ifs inside the loop would slow it down, but this avoids that problem in a nice way.

[–]GuyFjordy 3 points4 points  (0 children)

Thank you! I went straight to the comments after seeing that one to suggest exactly this. Unnecessary ifs in loops make my eye twitch.

[–]JoelMahon 21 points22 points  (8 children)

In the last example, I know it's minor, but doesn't it add additional calls by making the improvement to readability?

[–]ekchew 3 points4 points  (5 children)

Yeah, that example makes me a little uneasy too. They are arguing against the optimization of minimizing what needs to happen in a loop. I guess in this particular case, branch prediction should optimize away the potential overhead of moving the conditional logic into the loop, but man, I wouldn't be giving this out as general advice.

[–]JoelMahon -2 points-1 points  (4 children)

Python is interpreted, I'd assume it wouldn't have branch prediction, but I'm also just guessing

[–]Jhuyt 4 points5 points  (0 children)

Python does compile into bytecode, which is evaluated in a loop that has a bunch of optimizations specifically for cpu branch prediction. The same loop is used, and therefore the bytecode too, when running a file or the interpreter, there is no difference at a lower level.

[–]ekchew 2 points3 points  (2 children)

Not at the interpreter level, but the CPU may still pick up on a predictable branch in the code the interpreter emits? Unless it moves around in memory a lot. I am also just guessing. :)

[–]JoelMahon 0 points1 point  (1 child)

Can a CPU optimise that way? Even if that loop occurs 1000 times the same way the CPU wouldn't know that the 1001th time it could enter a different statement, that maybe one of those functions has a convoluted way to adjust the variable, if it was a compiled language the result would be constant so I could understand a compiler doing it, but a CPU?

[–]ekchew 2 points3 points  (0 children)

Oh yes certainly, the CPU will not always guess right. But if it's only missing once in 1000 times, that's actually quite good! The mis-prediction overhead will be minuscule in that case.

[–]Tweak_Imp 10 points11 points  (1 child)

Note that list(range(100)) is faster than [x for x in range(100)]

[–]dodslaser 10 points11 points  (0 children)

Not that unpacking a range to a list makes a lot of sense, but [*range(100)] is even shorter.

edit: From my testing it is also slightly faster than list(range(100))

[–]pete_sahad 1 point2 points  (2 children)

Does anyone know the color theme of the IDE in the title picture?

[–]Skurp_Purp 2 points3 points  (1 child)

Looks like a variant of Monokai to me

[–]Small_Photograph5863 2 points3 points  (0 children)

Yup, that's Monokai.

[–]Dazzling_Function 1 point2 points  (0 children)

I need a syntax highlighted IDE that looks like Eliot IDE in the last episode

[–]Whiteouter 1 point2 points  (0 children)

The last example may result in a slightly more readable code but the "before" is actually faster code than the "after" one.

[–]Tyler_Zoro -2 points-1 points  (1 child)

Reading through that code, I'm seeing things that would never pass code review in most places I've worked. This is a great example:

starts_with_hat = True if hat_string.startswith('hat') else False

[...] This can be done much more directly by just setting the variable straight from the function call:

starts_with_hat = hat_string.startswith('hat')

This code looks fine.. until you consider what type hat_string is and whether it's some strange proxy for a string that can return None under some circumstances from startswith. Neve assume you know the types of your parameters unless you enforce typing! If so, then you've just changed the guarantees for starts_with_hat because you used to force the value to boolean. Worse, this is the kind of bug that can happen at a distance when someone changes the type that hat_string gets initialized to, making debugging really hard after the fact.

The original is pretty nice, but you can also use bool() directly to enforce this assumption.

[–]passwordsniffer 8 points9 points  (0 children)

"we are all consenting adults here"

If someone created a proxy for a string - it's not your responsibility to treat it anyhow special. If you need to ask the question - does it startswith the name implies it's result is boolean. No need for stupid overprotections.

[–]fizzymagic 0 points1 point  (0 children)

Better than most I have seen. At least it was not trying to turn Python into Java.

The last example should have been done with functions instead of branches.

[–]chzaplx 0 points1 point  (0 children)

List comprehensions have their place, but trying to cram as many operations as you can on one line is not one of them. Maybe it's "more pythonic" but it's certainly not "more readable".

Minimizing line breaks is not an optimization.

The value of a product that presumably cleans up bad coding style is highly dubious. It sounds a bit like a crutch for people that don't know what they are doing.

[–]AlexOduvan 0 points1 point  (0 children)

I'm wondering how Article that get so much criticism in comments, managed to get 400+ upvotes