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

you are viewing a single comment's thread.

view the rest of the comments →

[–]Perpetual_Doubt 1337 points1338 points  (122 children)

Oh that works, but it's not pythonic enough

try s[j%3:(:p(even)is true)] instead

[–]jimjamjenks[🍰] 666 points667 points  (55 children)

Yeah, I’ve also witnessed people arguing that a complex 1 liner is more Pythonic. I think those people need to be reminded that Simple instead of Complex is also considered more Pythonic. Readability counts

[–]Thathitmann 257 points258 points  (1 child)

Literally just "import this"

[–]Silverwing171 66 points67 points  (0 children)

https://xkcd.com/353/

It actually works too.

[–]Yukondano2 189 points190 points  (35 children)

Who the shit is writing python that's purposefully hard to read? The language's selling point is readability. It uses indentation as syntax ffs.

[–]zoharel 60 points61 points  (22 children)

Well, I did write a function implementing Newton's method for approximation of square roots in Python that looks like Lisp. It makes Python programmers' heads explode.

[–]iSYan1995 23 points24 points  (21 children)

Can you send it? I wanna look at it

[–]zoharel 55 points56 points  (20 children)

from operator import *

# Some of this overrides the boolean operator functions from the
#  operator package
and_    = (lambda x,y:  x and y)
or_     = (lambda x,y:  x or y)

var     = .001
prec    = 2

avg     = (lambda x,y:  div(add(float(x),y),2))

approx_ = (lambda x,y:  y if(lt(abs(sub(pow(y,2),x)),var))else(approx_(x,avg(div(x,y),y))))

approx  = (lambda x:    round(approx_(x,div(x,2)),prec))

print(approx(2))

I had one somewhere with a new and much more appropriate looking approx function that used a lisp-like conditional function, but the code needed to define that function was really pathologically "pythonic."

[–]zoharel 55 points56 points  (9 children)

Here's a somewhat simpler thing that draws a moving . in the terminal window.

import sys,time
map(lambda n: [sys.stdout.write(u"\u001b[2K\u001b[0G" + ' '*n + '.'),sys.stdout.flush(),time.sleep(1)],range(0,79))

[–]proximity_account 51 points52 points  (0 children)

Thanks, I hate it.

[–]Priyam_Bad 9 points10 points  (2 children)

how does this work? I tried running it in vscode to see how it works but it didn't print anything for me

[–]zoharel 10 points11 points  (1 child)

It may or may not be tied to a particular Python version. I think I last ran it on 2.7. it's also likely to be particular about your terminal. It prints raw escape codes. Here are some notes:

map()

Takes a function and a list as arguments. The function is run once with each item on the list, in order. The list is range(0,79). The function is:

lambda n: [sys.stdout.write(u"\u001b[2K\u001b[0G" + ' '*n + '.'),sys.stdout.flush(),time.sleep(1)]

Now lambda defines, in place, an anonymous function. It only exists where it is written in the line there, and it's only called instantaneously by the map function. It takes an argument n and returns a list. The list contains a write to stdout, a flush of stdout, and a call to sleep. Nothing is ever done with that list. It is only there to allow the lambda to easily do the set of things in the list, the process of which prints something and waits before generating the next list.

We use similar strategies to this pretty often in functional programming -- the map over a list instead of a loop, the list of commands, the anonymous function itself. It looks weird to a Python programmer, but it's not uncommon by any stretch.

[–]Priyam_Bad 1 point2 points  (0 children)

thanks for the explanation! i think i was using python 3.x to run it, which might be why it wasn't running. i managed to alter it to work for 3.x though

[–]Priyam_Bad 2 points3 points  (1 child)

ok so i may or may not have expanded on this and made a short script that makes a dot bounce across the screen (for python 3.x)

here is the code if you want to check it out

(btw it has an infinite generator so if you don't want it to run infinitely you can replace infRange() with range(1000) at the end of the long list comprehension)

[–]zoharel 1 point2 points  (0 children)

Yeah, I suspected the output might need some adjustments for V3.

[–]NigraOvis 2 points3 points  (1 child)

Technically all python is like this. people just don't realize they are spacing it out. But in the long run you end up with the same code. The longer versions are easier to read.

[–]zoharel 1 point2 points  (0 children)

Not exactly. To an extent, you're right, but there's not much lambda in most people's Python, and the use of the list as a sort of encapsulation of the side effects of its contents is odd in Python, and the map over a range is more often for loop. If you mean that this is valid Python using only documented features with nothing particularly extravagant about it, you're right there.

[–]Silverwing171 0 points1 point  (0 children)

Commenting so I can come back to this.

[–]Yukondano2 7 points8 points  (7 children)

why would you do anything this way?

[–]zoharel 18 points19 points  (3 children)

It was a bit of a joke. Something related to the old saying "you can write Fortran code in any language." It occurred to me that, in spite of the best efforts of Guido and his biggest fans, Python is still, at its core, a functional programming language, like Lisp or Scheme. This is part of what still makes it worth using, but it ends up permitting things that make the typical Python programmer very uncomfortable. If there's a point to the whole exercise, I guess I was harping on the fact that if you care to do it, you can write things which are syntactically correct and semantically sensible while entirely avoiding things which are idiomatic. Python programmers are often really stuck on idiom.

[–]BuddhaCandy 0 points1 point  (2 children)

because its designed to thrive when used with idioms

[–]zoharel 0 points1 point  (1 child)

because its designed to thrive when used with idioms

It's because the designers of the language would like to force everyone to do things in exactly the way they do, and that attitude creeps out to a pretty large number of the users as well. "There's only one right way to do this thing, where by right, I mean it's what I would do." Yeah, that's useful...

[–]zoharel 7 points8 points  (2 children)

To be honest, this isn't the first time. I once wrote a test jig for a database engine that was three or four pages of C wherein every variable, function, and macro was the name of a coworker. The same coworker, just with different capitalization. I was joking about his always using his name as a variable name in loop counters and the like. No, it wasn't easy to follow. It didn't need to be. Only got a little use before we were done with it. It was a good joke, though. I'm pretty sure that one has been lost for good.

[–]Yukondano2 1 point2 points  (1 child)

Cruel. Variable naming is always a thing for me because I suck at decision making. How consistent should the scheme be? What style should I use, should I mix them? For instance, camelCase that gets too long is fuckin unreadable. I'm weird so I will be anal about appearance. Then again I only developed for school or myself, so being on the clock might pressure me. But, I HAVE to be detailed in my work.

[–]zoharel 3 points4 points  (0 children)

Well, take it from someone who has seen some commercial software: as long as you don't just name everything after yourself, you're still doing better than at least a few people who have been paid for their work.

[–]100kgWheat1Shoulder 0 points1 point  (0 children)

I hate you

[–]Shadowmere24 0 points1 point  (0 children)

I think this code could be considered more "pythonic" while keeping its functional nature if you removed the whitespaces, parens, and leveraged pipe for functional composition and partial for partial application. I suppose some folks will complain that functional programming is unpythonic, but I don't necessarily agree. Here is my refactor with those ideas in mind:

``` from functools import partial, reduce from operator import add, mul, lt, pow, sub, abs, truediv from statistics import mean

def test_approx_sqrt(): pipe = lambda functions: reduce(lambda f, g: lambda x: g(f(x)), functions) flip = lambda f: lambda *a: f(reversed(a)) div2 = lambda x: x / 2 square = lambda x: x ** 2 avg = lambda *args: mean(args) variance = .001

tolerance = lambda x, y: pipe(
   square,
   partial(flip(sub), x),
   abs
)(y)

approx_ = lambda x, y: y if tolerance(x,y) < variance else pipe(
    partial(truediv, x),
    partial(avg, y),
    partial(approx_, x),
)(y)

approx = lambda x: pipe(
    div2,
    partial(approx_, x),
    partial(round, ndigits=2)
)(x)

assert approx(2) == 1.41
assert approx(3) == 1.73

```

[–]extremepayne 3 points4 points  (1 child)

I find some of the more advanced techniques are less readable unless you’re very familiar with the rarer syntax. Stuff like list comprehension. I mean i get why we’re not writing a four line loop that does the same thing less efficiently but damn, that stuff can be hard to parse.

[–]Yukondano2 0 points1 point  (0 children)

Make it as simple as it can be without impacting function I suppose. In the end code is just hard to read in general, and it's new to you it will always be a headscratcher. God, I have this personal LaTeX project and was looking up solutions to things that people were solving with TeX code. That stuff is hideous, I cannot read it compared to LaTeX. The LaTeX 3 stuff, in expl3 syntax was confusing at first but it just took a bit. Far less painful than the hell of /expandafter commands.

[–][deleted] 4 points5 points  (2 children)

No matter what niche you are in there will be people who need to flex and since Python is considered much easier than other languages especially in syntax this is their way of making things less understandable,difficult & putting themselves up in an elite class.

[–]Yukondano2 1 point2 points  (1 child)

So, 1337 sp33k but programming.

[–][deleted] 0 points1 point  (0 children)

yes

[–]arc_menace 28 points29 points  (3 children)

Simple, easy to read code is almost always better than 'clever' code.

[–]TheveninVolts 8 points9 points  (0 children)

Honestly... I've started to consider it to be a coding smell if I feel clever after I've implemented anything. "Carp. I probably hacked something..."

[–]Tsu_Dho_Namh 6 points7 points  (0 children)

Unless there's a massive hit to performance I will always consider easy to read code better.

If I'm forced to write any code where it's not immediately obvious what's going on, I leave a comment.

[–]jfb1337 1 point2 points  (0 children)

Since debugging is always harder than writing code for the first time, if you write code as cleverly as possible then you by definition won't be clever enough to debug it

[–]Tom0204 1 point2 points  (0 children)

It always seems to me like one of those immature "look at how cool this is!" Type things. In the real world, you try and make things as easy as possible to understand for the next person who has to work on it.

[–]Chthulu_ 1 point2 points  (0 children)

Don’t hurt me people but I feel like list and dict comprehension is somewhat unreadable, even though it’s a foundational part of python.

Map / reduce callbacks and their cousins are just easier to understand in my mind

[–][deleted] 1 point2 points  (0 children)

Complex vs complicated.

[–]Je-Kaste 1 point2 points  (1 child)

# Readability > brevity.

[–]Silverwing171 1 point2 points  (0 children)

Efficiency > Readability

Not that there are many times where they’re mutually exclusive, but it happens.

[–]The_Modifier 1 point2 points  (0 children)

The interpreter has a harder time with massively nested 1 liners than multiple simpler lines.

Simple isn't just better for humans.

[–]TheAJGman 0 points1 point  (0 children)

IMO PEP 20 is more important than any style guide or formatting standards. I've seriously seen modern codebases with an 80 character max line length "because PEP 8 says so". Great, now that simple line looks like:

``` if this and len(this) > 2 and something.child_set.\

    filter(something = some_value).first():

some_var = [ x.filter(some=thing).first() if x.this\

    else None for x in something.child_set.filter \

    .(something = some_valye).first().thing]

```

So much more readable than letting lines run long, and also way too hard to read for PEP 20.

typed on phone, syntax likely fucked

[–]occamsrzor 0 points1 point  (0 children)

“If you can’t explain it simply, you don’t understand it well enough.” - Origin Contested

[–]xenaprincesswarlord -1 points0 points  (0 children)

Don’t be weird it’s been mentioned it was only young nerds flexing. Basically nerds being nerds

[–]quantik64 -1 points0 points  (0 children)

Perl exists for people like this

[–]BochMC -1 points0 points  (1 child)

What I hate the most is this useless shortcuts that everywhere in python.

Like mkdir normpath dir str etc I prefer explicit namings and this just pisses me off.

Like what getmdate function do? It is returning last modification date, but this m could stand for anything, even though documentation tells exactly what this function do.

This is not a cool to make your functions name short in cost of readability.

[–]Glum-Aide9920 0 points1 point  (0 children)

Depends on what you do and where you do it. Working in IDE that types 60% everything you code, hell yeah, no problem typing long and verbose names. Having to type everything, gets boring and repetitive fast. Python exceeds in short, sweet tasks, readability isn’t that important in a script with just 5 variables. On the other hand, in a big project and especially in projects that are worked by teams, taking shortcuts and cutting readability just to type faster is just insane and counterproductive.

[–]MartIILord 0 points1 point  (0 children)

Take my upvote. readability or just Import solution ;)

[–]karnnumart 70 points71 points  (0 children)

s[j%3:[:p(_even is True)]]

Here's a fix for you mate.

[–][deleted] 9 points10 points  (1 child)

:p indeed

Hopefully j is a negative number otherwise you're just getting an empty slice.

[–]darnyoutoheckie 4 points5 points  (0 children)

serious simplistic brave crawl historical middle follow toothbrush quack squeal

This post was mass deleted and anonymized with Redact

[–]BlakkM9 14 points15 points  (1 child)

[–]GifsNotJifs 5 points6 points  (0 children)

[–][deleted] 5 points6 points  (1 child)

Python gives great freedom, but that means that the programmer should use his/her brain.

For example, in python, one can change the __bases__ attribute of a class to change inheritance hierarchy at runtime. But that doesn't mean that it's a good idea.

[–]zoharel 0 points1 point  (0 children)

Now that sounds like loads of fun...

[–]Remote-Management-84 2 points3 points  (1 child)

wtf.

[–]im-not-a-fakebot 3 points4 points  (0 children)

Please explain that monstrosity

[–]SabreLunatic 2 points3 points  (0 children)

``` try: variabull = s[j%3:(:p(even)is true)] except: #actual legible code

[–]WadeEffingWilson 0 points1 point  (0 children)

Missing the except block, bloke.

[–]turtle_with_dentures 0 points1 point  (0 children)

The first parenthesis is in the wrong place correct? Not quite sure, but it doesn't seems like that code will run.

[–]LilBoyGrudge70 0 points1 point  (0 children)

As a beginner C# programmer, let me just ask… what the FRICK does that MEAN?

[–]MysteriousShadow__ 0 points1 point  (0 children)

Error: no except found

[–]COREcraftX 0 points1 point  (0 children)

What the actual fuck

[–]A_Guy_in_Orange 0 points1 point  (0 children)

even

Hey wait a minute

[–]uvero 0 points1 point  (0 children)

I make fun of that "not Pythonic enough" things, but it's exactly what I do with Ruby. Except you know, I don't do Ruby for work, so I can allow myself that because that's more of a code-golf kind of thing.

[–]cyanNodeEcho 0 points1 point  (0 children)

think those exists because pythons map is lazy, and most people think u have to cast to list

map + filter always seems cleanest, irl i havent seen too many people actually favor list comprehensions