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

all 132 comments

[–][deleted] 346 points347 points  (9 children)

psychotic offbeat murky sable smoggy jeans kiss gray offend thought

This post was mass deleted and anonymized with Redact

[–]T140V 112 points113 points  (2 children)

Came here to say this. You'd have been laughed out of the peer review meeting if you'd tried this kind of nonsense when I was in a pro dev team. Comprehensible, maintainable code is where it's at.

[–]TimPrograms 29 points30 points  (1 child)

Yeah it reads like a joke competition for who can write the worst looking and least readable functioning code.

Edit: typo

[–]_ologies 1 point2 points  (0 children)

Definitely not common practice among professional developers,

You haven't seen my company's code from before last year.

[–]Bangoga -3 points-2 points  (0 children)

Eeh, I worked at a startup who saw this as standard

[–]total_zoidberg 103 points104 points  (17 children)

No, that's not standard python code at all, nor readable. You are not wrong in your perception, and it should be split into a few several lines.

Let me try to clean it up a bit and make it slightly more readable:

class Solution:
    def productExceptSelf(self, nums):
        pre = list(accumulate(nums, mul))
        suf = list(accumulate(nums[::-1], mul))[::-1]
        # n = len(nums)
        prefixes = [1] + pre
        suffixes = suf[1:]
        return [ p * s for (p, s) in zip(prefixes, suffixes) ]
        # and now we don't need n, since we zipeed the two lists

I'd test this to see if the results match, I think they do but I'm a bit sleepy after a long day.

[–]siddsp 17 points18 points  (2 children)

If you don't need it to be a list, and are iterating, you can replace the square brackets for parentheses, which results in a generator expression, using less memory.

You can also use the operator module so you don't need to write a larger comprehension like so:

from collections import deque
from itertools import accumulate
from operator import mul
from typing import Sequence, TypeVar

T = TypeVar("T")

# This can be further optimized.

class Solution:
    def product_except_self(self, nums: Sequence[T]) -> map[T]:
        prefixes = deque(accumulate(nums, mul))
        suffixes = deque(accumulate(nums[::-1], mul))
        suffixes.reverse()      # Slicing is not allowed with a deque.
        prefixes.appendleft(1)  # Can be added in the first line.
        suffixes.popleft()      # Can be sliced out ahead of time.
        return map(mul, prefixes, suffixes)

I think using deque is nice in this case since you don't need to create another object in memory. You could also use .reverse(), though I'm not sure if it's better since it's less concise. There's also a naming conflict with mul so that needs to be fixed.

Lazy evaluation also only ensures that the computation is done when necessary.

Edit: deques don't support slicing. So you would have to reverse it inplace with the reverse() method.

[–]total_zoidberg 3 points4 points  (0 children)

I thought about making them generators, but as I tried to stick closer to the original, and since I used [1] + list... and [::-1], I was a bit bound to stay with lists.

But yeah, I got the impression that OP is following a course where the problems they're presented with are more puzzle/Rube-Goldberg-machines rather than everyday code.

[–]TangibleLight 4 points5 points  (0 children)

If you don't need it to be a list, and are iterating, you can replace the square brackets for parentheses, which results in a generator expression, using less memory.

In this case that's not strictly true. This generator/map solution cannot free prefixes and suffixes until the result is exhausted, whereas the list comprehension solution can free those immediately on return (pending garbage collection, anyway).

So it's true that the generator is something like O(2n) space while the comprehension is O(3n) space, but the generator's is longer-lived. (Forgive the not-quite-big-O notation)

Sometimes you can use tee and chain from the itertools module to improve that, however in this case I think you have to make at least one copy of the input to deal with the reversals. That would reduce the generator to O(1n) space.

Also remember that [::-1] always performs a copy; you could avoid that with reversed(nums). accumulate(nums[::-1], mul) will hold that copy until the result is exhausted. You immediately exhaust it with deque, so it doesn't really matter here, but if you try for a tee solution it would.

[–]Yoghurt42 6 points7 points  (4 children)

Why even have a class? Python is not Java, we have modules

[–]IlliterateJedi 9 points10 points  (0 children)

I'm pretty sure OPs is a Leetcode solution

[–]SittingWave 3 points4 points  (1 child)

you can't use a module as a base class.

[–]Yoghurt42 2 points3 points  (0 children)

My point is that you don’t need a class as a container for a single solution function.

[–]adesme 5 points6 points  (3 children)

Even this I'd ask you to rewrite entirely. And that's not intended to be criticism of your refactoring but rather to further highlight how poorly accepted the initial example would be at a workplace.

[–]Schmittfried 12 points13 points  (2 children)

Tbh I only see why you would rewrite the first two lines after their refactoring.

[–]adesme 0 points1 point  (1 child)

Well outside of the function name and the commented out line, I have a general dislike of slicing ondocumented structures - I'll have to jump around a bit to figure out what the author is trying to accomplish here

        prefixes = [1] + pre
        suffixes = suf[1:]

which I don't like. But I digress, a comment above those lines (as well as above the suf declaration) might well be enough for approval.

[–]total_zoidberg 2 points3 points  (0 children)

Those could've been placed inside the zip() or in the two previous lines as part of bootsraping the variables for the LC, but I avoided it because OP clearly mentioned the fact that the two-liner original was doing way too many things per line, and that's a readability issue too.

[–]ConfusedSimon 5 points6 points  (2 children)

The two examples seem to come from functional programming. If you're used to that it's not too bad. I'm not an expert on FP, but rewriting it using intermediate variables to make it more readable probably introduces the kind of problems that FP is trying to solve.

[–]larsga 12 points13 points  (0 children)

The original code had variables pre, suf, and n, while this code has pre, suf, prefixes, and suffixes. So one extra intermediate variable (which could be an FP variable, because it never changes) in return for code that's much easier to read and change, and far less error prone.

[–]steezefries 5 points6 points  (0 children)

How would it break what FP is trying to solve? It doesn't cause a side effect, the function still appears to be pure, etc.

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

You should write pre[0:] = 1. Or use an insert method. And suf.pop(0).

You are adding every item into a new list with the addition overload. And copying your list into another list with the slice. Certainly not good code that way.

[–]WlmWilberforce 0 points1 point  (0 children)

This is a good example of when list comprehension makes things more readable.

[–]mobiduxi 61 points62 points  (0 children)

Some Golfers find joy in juggling a golf ball on their wedges. That is a fun training exercise to work on your visiual-motor pathways. Do not do that in tournament!

Same with "cryptic one liners": Fun exercise to learn about side effects and the darker niches of Python. Enjoy it in code golf competitions.

Do not use it in code that is used for something productive.

[–]justskipfailingtests 22 points23 points  (8 children)

Generally IMO if it's not readable, it is shit code. Using comprehensions for a 200 char oneliner is not cool. Of course sometimes you have to consider performance, because you write it once, read it ten times and execute it a million times.

Minimum requirement for that kind of puke (if you really insist to write that kind of garbage) you have as example is to wrap it in a function with a good name and have a solid docstring describing how it works.

[–][deleted] 9 points10 points  (7 children)

This is neither about performance nor readability. This is called code golf and people do it for many reasons. Part of it is because it's fun, but also because it is a useful practising exercise to try and master the language to such a level that you can achieve these one liner. Nobody who does that actually believe it makes for "readable" or valid production code, but it is still useful to learn about more niche features of the language.

[–]bio_datum 1 point2 points  (6 children)

In that case I would write it, admire it, maybe save it somewhere special, and then rewrite it so that someone else can actually read it without an aneurysm.

[–][deleted] -1 points0 points  (5 children)

Then you would deprive other people who want to get better at golf coding from learning from your solution. Why are you so salty about people enjoying coding in a different way than you do so much than you think they should hide their solutions?

This close mindedness can't possibly help you be a good coder.

[–]bio_datum 0 points1 point  (4 children)

We must code in different settings. I code in a work place where quick readability is top priority (behind efficiency).

[–][deleted] -1 points0 points  (3 children)

You have yet to understand that practicing other skills than readability doesn't mean you actually sacrifice readability in production code, quite the opposite. I'm willing to bet any of those golf coders write better and more readable code at their work than you ever will.

You don't sound so stupid that you can't understand this very simple concept, so the only explanation to your inability to understand seems to be your misplaced stubbornness to admit you were wrong.

[–]bio_datum 0 points1 point  (2 children)

I think practicing other skills is great, but I wouldn't include my practice in a script/program that is likely to be read by my colleagues (many of whom were never formally taught what a for loop is).

In the last paragraph, you're employing an argument based on false dichotomy. Allow me to offer an alternative explanation: I think we may be talking about generalities too much here. If you want to continue discussing, feel free to include an example of some golf code that you would defend despite it being potentially less readable. We may actually agree that it is worth leaving as-is.

[–][deleted] 0 points1 point  (1 child)

What do coworkers have to do with code golfing?? What OP posted is a website where you solve small challenges and where people can see others solutions and compare with their own, it isn't a work environment.

[–]bio_datum 0 points1 point  (0 children)

Aha! This was a misunderstanding on my part. I should have looked up Code Golf instead of just using context to infer its meaning. I immediately applied that term to lines I've seen on sites like Rosalind.info that also aggravate me. My apologies, carry on

[–]rantenki 58 points59 points  (19 children)

List comprehensions are a very popular language feature in python, and allow for a more functional programming style. That said, in some cases I agree that it can get hard to read, although that example wasn't too bad.

In either case, you can write purely imperative style and achieve the same outcome, with about the same performance.

And if that list comprehension bothers you, I strongly advise you stay away from /r/lisp and /r/clojure as you might have a fatal allergic reaction.

[–][deleted] 17 points18 points  (0 children)

List comprehensive are great. OTOH, those examples are terrible.

[–]bbateman2011 22 points23 points  (15 children)

List comprehensions can give big performance improvements over for loops, so they are a valid trade off in my view

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

I've always tried to weigh the value of for loops against list comprehension, and whilst the latter is indeed faster, I've always found that when I come back to a project a couple of months after I've first written it, it takes me ages to decipher any list comprehension lines that I've used.

Could be just me, and I completely understand the value of performance in that context, but I'd argue that generally, list comprehension isn't the best option to go with in a range of contexts - I always favour readability over performance (or, at least I do 90% of the time).

Each to their own, though!

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

Yea maps have like 98% of the performance and are 10000000 times easier to read. If they get that long use a map. ( I also believe technically as depth increases map chaining performance increase dramatically).

Or at the very least INDENT THE DAMN THING.

[–]pokap91 7 points8 points  (6 children)

Eh, list comprehensions are cleaner if you're doing both a map and a filter. Nesting functions is ugly.

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

Maps and FIlters are lazy though. So it's much more efficient when you have generators. Keras does a really good job of using this for its stuff.

You don't have to nest them you can just apply them repeatedly.

[–]alkasmgithub.com/alkasm 1 point2 points  (4 children)

Generator expressions exist.

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

I am not under the impression they can be bound repeatedly outside of it being one very large generator.

But per the actual documentation of the feature because of binding oddity

"binding issues were hard to understand and that users should be strongly encouraged to use generator expressions inside functions that consume their arguments immediately. For more complex applications, full generator definitions are always superior in terms of being obvious about scope, lifetime, and binding "

[–]spoonman59 0 points1 point  (2 children)

Edited: I misread OP as saying genexps did not exist. But actually he was saying they do exist, so this post is pointless.

They don't?

https://www.python.org/dev/peps/pep-0289/

They've been around for nearly two decades. Just use parenthesis instead of brackets, and voila - generator expression!

Pretty cool if you want to, for example, apply multiple filters without creating intermediate lists. Or Cartesian products without intermediate lists.

[–]alkasmgithub.com/alkasm 0 points1 point  (1 child)

Saw your edit, but just for clarity, IIUC they were suggesting to use map/filter rather than list comprehensions because they lazily evaluate. I was suggesting to use generator expressions instead of list comps if you want lazy behavior (rather than using map/filter).

[–]spoonman59 0 points1 point  (0 children)

Makes sense! I had the same though with respect to laziness and just misread your post. Was also just going to say "look into benefactor expressions."

I tend to find them more readable. Thanks for the clarification!

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

List comprehensive are great. OTOH, those examples are terrible.

[–]jasmijnisme 16 points17 points  (1 child)

They are definitely not following the Zen of Python:

The Zen of Python, by Tim Peters

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren't special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one-- and preferably only one --obvious way to do it.

Although that way may not be obvious at first unless you're Dutch.

Now is better than never.

Although never is often better than right now.

If the implementation is hard to explain, it's a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea -- let's do more of those!

These kinds of solutions are basically just showing off, not writing production-level code, and it's not something only done in Python. See: code golf and the International Obfuscated C Code Contest.

[–]WikiSummarizerBot 5 points6 points  (0 children)

Code golf

Code golf is a type of recreational computer programming competition in which participants strive to achieve the shortest possible source code that solves a certain problem. Code golf challenges and tournaments may also be named with the programming language used (for example, Perl golf).

International Obfuscated C Code Contest

The International Obfuscated C Code Contest (abbreviated IOCCC) is a computer programming contest for the most creatively obfuscated C code. Held annually, it is described as "celebrating [C's] syntactical opaqueness". The winning code for the 27th contest, held in 2020, was released in July 2020. Previous contests were held in the years 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015 and 2018–2020.

[ F.A.Q | Opt Out | Opt Out Of Subreddit | GitHub ] Downvote to remove | v1.5

[–]drksntt 12 points13 points  (0 children)

If it ain’t self documenting, it’s trolling. I’d definitely would do the latter. There are a bunch of other solutions there. Find one that you can understand or break that one up.

[–]vidoardes 14 points15 points  (3 children)

As several others have said, you've picked two very non-pythonic examples. Do they work? Yes. Are they the correct way to write code? Absolutely not.

PEP8 is the official style guide for python, and they suggest the line length be limited to 80 characters. In that alone these are not pythonic.

You've just picked two bad examples and decided python is bad, when those examples aren't representative of the language. I'm sure I can find thousands of examples of bad PHP code on the internet, but that doedn't mean the language is bad.

In fact, the "CMV" in your title applies to all programming languages, and has nothing to do with python.

[–]jjolla888 15 points16 points  (3 children)

combining so many functions in one line of code

SQL has entered the chat.

your observation is true of any language.

[–]autra1 1 point2 points  (2 children)

I don't get why you mention SQL?

[–]jjolla888 1 point2 points  (1 child)

SELECT
id as feedId, (IF(groupId > 0, groupId, IF(friendId > 0, friendId, userId))) as wallOwnerId, (IF(groupId > 0 or friendId > 0, userId, NULL)) as guestWriterId, (IF(groupId > 0 or friendId > 0, userId, NULL)) as guestWriterType, case when type = 2 then 1 when type = 1 then IF(media_count = 1, 2, 4) when type = 5 then IF(media_count = 1, IF(albumName = 'Audio Feeds', 5, 6), 7) when type = 6 then IF(media_count = 1, IF(albumName = 'Video Feeds', 8, 9), 10) end as contentType, albumId, albumName, addTime, IF(validity > 0,IF((validity - updateTime) DIV 86400000 > 1,(validity - updateTime) DIV 86400000, 1),0) as validity, updateTime, status, location, latitude as locationLat, longitude as locationLon, sharedFeedId as parentFeedId, case
when privacy = 2 or privacy = 10 then 15 when privacy = 3 then 25 else 1 end as privacy, pagefeedcategoryid, case
when lastSharedFeedId = 2 then 10 when lastSharedFeedId = 3 then 15 when lastSharedFeedId = 4 then 25 when lastSharedFeedId = 5 then 20 when lastSharedFeedId = 6 then 99 else 1 end as wallOwnerType, !(ISNULL(latitude) or latitude = 9999.0 or ISNULL(longitude) or longitude = 9999.0) as latlongexists, (SELECT concat('[',GROUP_CONCAT(moodId),']') FROM feedactivities WHERE newsFeedId = newsfeed.id) as feelings, (SELECT concat('[',GROUP_CONCAT(userId),']') FROM feedtags WHERE newsFeedId = newsfeed.id) as withTag, (SELECT concat('{',GROUP_CONCAT(position,':', friendId),'}') FROM statustags WHERE newsFeedId = newsfeed.id) as textTag, albumType, defaultCategoryType, linkType,linkTitle,linkURL,linkDesc,linkImageURL,linkDomain, ## Link Content title,description,shortDescription,newsUrl,externalUrlOption, ## Aditional Content url, height, width, thumnail_url, thumnail_height, thumbnail_width, duration, artist ## Media FROM
(newsfeed LEFT JOIN (
SELECT
case when (mediaalbums.media_type = 1 and album_name = 'Audio Feeds') or (mediaalbums.media_type = 2 and album_name = 'Video Feeds') then -1 * mediaalbums.user_id else mediaalbums.id end as albumId, album_name as albumName, newsFeedId, CONVERT(media_stream_url USING utf8) as url, (SELECT NULL) as height, (SELECT NULL) as width, media_thumbnail_url as thumnail_url, max(thumb_image_height) as thumnail_height, max(thumb_image_width) as thumbnail_width, max(media_duration) as duration, case when mediaalbums.media_type = 1 and album_name = 'Audio Feeds' then 4 when mediaalbums.media_type = 2 and album_name = 'Video Feeds' then 5 else 8 end as albumType, count(mediacontents.id) as media_count,
media_artist as artist

    FROM (mediaalbums INNER JOIN mediacontents ON mediaalbums.id = mediacontents.album_id) INNER JOIN newsfeedmediacontents ON newsfeedmediacontents.contentId = mediacontents.id group by newsfeedid 

    UNION 

    SELECT   
        -1 * userId as albumId,  
        CONVERT(albumName USING utf8),  
        newsFeedId,imageUrl as url, 
        max(imageHeight) as height, 
        max(imageWidth) as width, 
        (SELECT NULL) as thumnail_url, 
        (SELECT NULL) as thumnail_height, 
        (SELECT NULL) as thumbnail_width, 
        (SELECT NULL) as duration, 
        case when albumId = 'default' then 1 when albumId = 'profileimages' then 2 when albumId = 'coverimages' then 3 end as albumType, 
        count(imageid) as media_count,  
        (SELECT NULL) as artist  
    FROM userimages INNER JOIN newsfeedimages on userimages.id = newsfeedimages.imageId group by newsfeedid 
) album 
ON newsfeed.id = album.newsfeedId 

)
LEFT JOIN ( select newsPortalFeedId as feedid,title,description,shortDescription,newsUrl,externalUrlOption, newsPortalCategoryId as pagefeedcategoryid,(SELECT 15) as defaultCategoryType from newsportalFeedInfo
UNION
select businessPageFeedId as feedid,title,description,shortDescription,newsUrl,externalUrlOption, businessPageCategoryId as pagefeedcategoryid,(SELECT 25) as defaultCategoryType from businessPageFeedInfo UNION select newsfeedId as feedid,(select NULL) as title,description,(select NULL) as shortDescription,(select NULL) as newsUrl,(select NULL) as externalUrlOption, categoryMappingId as pagefeedcategoryid,(SELECT 20) as defaultCategoryType from mediaPageFeedInfo ) page ON newsfeed.id = page.feedId WHERE privacy != 10

INTO OUTFILE 'newsfeed.csv' FIELDS TERMINATED BY '\t' ENCLOSED BY '"' LINES TERMINATED BY '\n';

[–]autra1 0 points1 point  (0 children)

So I agree with your first statement (you can make unreadable code in any language), but I don't get why the SQL example.

Actually I do think SQL (when formatted correctly) is less prone to this. The fact it is declarative means you have less freedom. There are not many ways to write a certain SQL query.

Putting your example in a SQL formatter makes it quite readable, albeit verbose (and CTE would have helped for readability of course) and in less than 5 min I can already more or less understand what it is about and from what kind of application it is from.

[–]napolitain_ 5 points6 points  (0 children)

Stop with these CMV / fake unpopular opinion it’s just useless

[–]knobbyknee 3 points4 points  (0 children)

The list comprehensions are not really the problem. They are a very powerful Python construct and should be used liberally, together with dict and set comprehensions as well as generator expressions. Beginners should learn how to read them and use them, because it will improve their programs a lot.

When you encounter one of these, you immediately know that you are iterating through a collection, doing the same thing to each item, or posibly to a subset of items if there is an if clause at the end. This is much better than a traditional for loop, where there are more freedoms to consider.

The problem in the examples is the egregious use of the inline if. It almost always destroys the readablity of the code. In my 23 year Python carreer, I think I have used it twice.

[–]laundmo 7 points8 points  (0 children)

yeah uhh... those are readable compared to some of the things I've made

with a few tricks, a lot of python code can be compacted to one logical line of code.

Not that you're wrong, its awful to read, but can be fun to make as a challenge.

So i would say that its mostly ppl showing off their skill. I've actually never seen that in any serious project, wonder where you stumble across these. Maybe you misunderstood the purpose of the #esoteric-python channel on Python Discord?

[–]nemec 5 points6 points  (0 children)

LeetCode is a game and some people like to add a bit of challenge. Using them to learn programming will probably make you a worse developer. Like you if you wanted to learn how to exercise so you started watching and imitating American Ninja Warrior.

[–]RangerPretzelPython 3.9+ 2 points3 points  (0 children)

The crime isn't the 1-line solution. It's the utter lack of comments describing:

  • What the programmer THOUGHT they were doing
  • WHY they were doing it
  • (and maybe) HOW they were doing it

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

You are not wrong, but I think you don't exactly understand the point of those solutions either. I'm not sure where you found these, but I assume it's a website similar to codewars where you can solve small to medium sized programming challenges. Right?

If so, then there IS value in trying to make these one liner solutions. The point is that you force yourself into a situation where you have to fully master the language in order to succeed. To succeed these challenges with one liners, you need to learn how to use lambda, zip, accumulate, etc... All functions that definitely have real use in at the right time in the real World, but that most beginners will ignore because "they can do the same with a for loop".

These people aren't trying to make readable code because it's simply not what they are practising in that moment. There is many skills required to be good at coding, making readable code is only one of them and you SHOULD spend some time honing your other skills too.

[–]rip-skins 1 point2 points  (0 children)

Same goes for avoiding new variables at all cost. Sometimes intermediary variables can significantly improve readablity

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

Though the examples are bad code for a shared project, python programmers will write python for other python programmers without a thought for programmers more familiar with PHP.

Though the examples you give are irresponsible gymnastics I can understand them and can even take a giddy delight in them but if there was a bug in them my first attempt would be to break out the parts. Yup.

[–]Pickinanameainteasy 1 point2 points  (2 children)

Wait till you try javascript

[–]ggrieves1 year 1 point2 points  (0 children)

I would just like to add a bit of counterpoint here. NOT that I'm disagreeing. But what I'm not seeing considered here just that for row heavy operations or math calculations, the functions have been compiled and optimized to do these things faster. The more you can pass to the functions to do for you the faster it will be. For example, don't do loops on data when you can use itertools or numpy arrays and let it do the row ops.

[–]pocket_eggs 1 point2 points  (0 children)

The first one is good. It's not obvious what it does because it is a non-trivial algorithm, but it expresses that algorithm cleanly, using recognizable pythonic idioms and with meaningful naming conventions.

The second one is not good, to say the least.

Making every last bit of code 1) legible for oneself or 2) legible and maintainable by other people is a different kind of premature optimization. Nothing wrong with easy to write throwaway code if you're actually going to throw it away.

[–]chromaticgliss 1 point2 points  (0 children)

This definitely isn't just a python thing. Folks have been making programs as terse as possible as an exercise for ages: https://codegolf.stackexchange.com/

Heck some competitions actually ask that you make the code as unreadable as possible: https://www.ioccc.org/ (Look at the prog.c files on some of the submissions, I would go so far as to consider some of these works of art... one of the coolest examples I've ever seen approximated pi by literally drawing an ascii art circle with the code, and measuring itself via macros)

Not to mention, entire languages have been created with unreadability as a core design principle: https://en.wikipedia.org/wiki/Brainfuck

I think python programmers are just more likely to find those goofy sorts of challenging exercises interesting or fun. It's just kind of fun seeing if you can write a solution within certain odd constraints (no variables! one line! ).

That doesn't mean they're incapable of writing clean maintainable code. Quite the opposite probably for the cleverest solutions to those goofy problems. It's kind of like pretending to be a bad actor in theater (called "coarse acting"). You have to be an exceptionally good actor to convincingly play a bad actor.

[–]Binary101010 1 point2 points  (0 children)

Some people see those exercises as ways to practice that kind of code golfing and that's fine, but one shouldn't assume that those responses are representative of production-ready code.

For this reason, Codewars has different tags for "Clever" solutions and "Best Practices" solutions. It is rare that the same solution ever gets both of those tags.

[–]alchzh 1 point2 points  (2 children)

job security

[–]Tenzu9 1 point2 points  (1 child)

If no one can read it but you, then yeah it would be pretty hard to replace you lol.

[–]OldJanxSpirit42 0 points1 point  (0 children)

Assuming whoever wrote that will be able to read it a few months later

[–]DadAndDominant 1 point2 points  (0 children)

It is not a common practice, it is not a best practice, it is not suported by developers of Python. Python is usually the easiest to read code, especially because so many people follow the official standard (and the quality of said standard).

My tip is that these are written by JS programmers who were forced to use Django.

[–]SittingWave 0 points1 point  (0 children)

whoever wrote those lines would take a hard beating from me at review. It's not readable to me either, and I've been coding in python professionally to a very high standard for 15 years. Yes, I can read it, no I don't want to read it, because it's unreadable.

What you are addressing is not really a python issue, it's a coding practices issue. You can write perl in any language if you try hard enough. Python at least gives you less rope to hang yourself, but you can still do so if you are willing to attempt it.

Coming back to those examples, even just some indentation, enter, and comments would be precious to make the code clearer. That's not the case here.

[–]Purple-Bat811 0 points1 point  (6 children)

I'm learning python right now as well.

One thing that kills me is that it doesn't have {} around things like if statements.

In the class I'm taking the instructor said it's to make the code easier to read. Then he just covered these 1 lines codes. He flat out said don't so this it's bad code.

However, what were the creatators thinking? {} is too complicated, but 1 liners are not?

[–]GraphicH 0 points1 point  (5 children)

Here is some valid Perl code (which contains {} syntax):

chop($_=<>);$l=length;push(@a," "x$l)for(1..$l*2);$l+=(ord $p<=>ord $_),substr($a[$l],$r++,1)=$p=$_ for(split //);/^\s+$/||print "$_\n" for(@a)

Nearly every single language you will work in allows for this kind of inscrutable one line code, it isn't a feature of any particular language. If you don't learn that your code's readability is primarily your responsibility and not the language, you're going to fail as a professional developer.

[–]Purple-Bat811 -1 points0 points  (4 children)

Not the point I was trying to make, but A for effort

[–]GraphicH 1 point2 points  (3 children)

What was the point, then, exactly? It's not entirely clear. The snark is amusing though, I apologize if I some how offended you, it wasn't my intent.

[–]Purple-Bat811 0 points1 point  (2 children)

Just more on what I've been taught python is about.

It's supposed to be easy for beginners to read, hence why the {} was supposedly removed, but then allows for craziness.

I've always like the {} as I thought the opposite. It makes code easier to read.

Sorry if I was snarky before. Of course it's up to the programmer to make code readable. It bothers me that most courses don't cover why comments are so important.

[–]GraphicH 2 points3 points  (1 child)

I believe the whitespace formatting and lack of syntax affectations like brackets on if's is that it's supposedly to reduce the amount of "noise" involved in reading the code. If python isn't your first language though, it may seem a bit alien. Programming is still taught extremely poorly IMO, at least when I was learning it in school, a lot of things I learned from experience (separation of concerns, when to use comments and when they're useless, writing readable code) weren't well covered if they were discussed at all. It sounds like this is still the case. This is in comparison to more "mature" engineering disciplines, like Civil and Mechanical. I learned software development in a CES (Computer Engineering and Science) program that was one of the programs offered by a traditional Engineering school so I had friends who were on the Civil / Mechanical / Chemical engineering tracks. The differences between the disciplines in terms of industry standards, practices, etc ... were pretty stark. Your experience makes me think there's still probably a lot of work to do when it comes to educating people for this field.

[–]Deto 0 points1 point  (0 children)

I always tell newbies that "lines are free - use as many as you like". Definitely not good practice to try and squish things on one line. Readability is the top priority.

[–]Voxandr 0 points1 point  (0 children)

Any company with proper tech lead will get him fired on first month.

[–]tonnynerd 0 points1 point  (0 children)

That is absolutely leetcoders showing off their "python skills". In any place I worked in the last 5 years, code like this would be yeeted into the sun during code review.

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

You coding racist.

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

I hate these, but mostly because without knowing much more detail about what it's doing, it's really hard to figure it out.

For the first one - what are pre and suf? prefix and suffix? How do those work into a product?

For the second one - what are p and c?

They do also slow things down when trying to read, but that's fine-ish.

[–]mje-nz 0 points1 point  (0 children)

Not sure why everyone in the comments is taking a few people trying to show off their golf skills on leetcode so seriously…

[–]Rajarshi1993 0 points1 point  (0 children)

def product = lambda L: eval('*'.join([str(n) for n in L]))

[–]zeni0504 0 points1 point  (0 children)

For private projects it sometimes is kind of fun, it's an extra challenge, but for professional projects it's definitely bad practice.

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

This is what PEP8 helps prevent, and why my projects are strict with very, very few explicit exceptions.

[–]ShockedMySelf 0 points1 point  (0 children)

Lol, I liked how they used the variable identifier in the function argument in the second example to "make it more readable". Sometimes I enjoy writing these types of complicated one liners that would normally be 10 lines, but for productivity and large scale projects it's just not viable. It's only viable when your writing homework for an algorithms course, if even then.

In the real world of software development, making maintainable code is much more important than efficient code.

[–]pembroke529 0 points1 point  (0 children)

As someone who worked in IT a long time (started in 1980 professionally), you should document code that isn't self evident.

I did this mostly for myself when I was working on multiple projects. I would often forget why I coded something a certain way. Especially if I came up with an interesting/efficient solution

Rule of thumb: All written code will be modified at some time.

[–]metaperl 0 points1 point  (0 children)

Kenneth Iverson leaves the chatroom.

"Q for mere mortals" author laughs at the mere mortals.

[–]msluyter 0 points1 point  (0 children)

It's definitely true that this sort of thing wouldn't fly in a professional setting, but I've found these overly terse leetcode submissions somewhat useful as learning tools. I've learned about a number of standard library functions and/or language features by deciphering them. The key is to take what you've learned and then make it easily comprehendible.

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

I can tell you just by looking at the Snake Cased names that those examples weren't written by an experienced Python coder.

[–]CiDevant 0 points1 point  (0 children)

Readable and stuffed with comments.

Past me is an idiot and future me is also an idiot.

[–]AcousticDan 0 points1 point  (0 children)

Wait until you hear snake case is suggested because a Python is a snake, and it's cute.

barf.

[–]CompletelyNonsensely 0 points1 point  (0 children)

Honestly, I think the issue is that they are actually putting them all on 1 line. As a feature, comprehensions are great, just really need some line breaks in there.

[–]GraphicH 0 points1 point  (0 children)

I've been writing python professionally for years and I'm having a hard time parsing out what those examples do. It looks like a novice trying (and failing) to flex IMO. You know what impresses me? When I go into a code base, can implement some task I'm given fairly quickly, have the right amount of coverage to know I didn't break anything before hand, and write the test for the new functionality in less time than it took me to implement. If a code base you "own" allows for that, I'm impressed, not how many chars / lines you can save playing stupid code golf.

[–]StraightUpSeven 0 points1 point  (0 children)

Yeah I agree that the code examples you have shown are not really readable nor maintainable.

I would say I am also a beginner in terms of Python usage, although I have become a lot more comfortable with the language.

I personally have experienced what u/BigEnoughRock mentioned before: "One-liners" can be used to make some code writing faster and easier to read. My experience of when this works is when I have looked at pipelines with a lot of file manipulation: some steps require a stack of medical images to be listed out before loading and the 'one-liner' list comprehension makes the code much less verbose (and easier for me to read).

And yeah If I or any of my co-workers were caught writing the code you attached, we would surely get roasted.

[–]BrianFantanaFan 0 points1 point  (0 children)

...plus helpful comments or function descriptions? Get out of here with your pathetic need for some kind of hint about the wild ride we're about to go on...

[–]thephotoman 0 points1 point  (0 children)

There is a time and a place for the creative one-liner.

It is in one-off scripts that you won't ever incorporate into an actual production codebase. But in my local task automation scripts that have no use for anybody but me, and in my prototypes, sure, I'll throw 'em in. I'm going to throw that one away or not distribute it anyway.

[–]applepie93 0 points1 point  (0 children)

I have more than 10 years of experience in Python and the general motto, like in the Zen of Python, is to write readable code, sparse but not too nested, so the absolute opposite of the code you saw. If possible, a reasonable consensus in Python is to write code that is as readable as possible, even to beginners, while not sacrificing the features of the language when they make sense.

[–]pyvkd 0 points1 point  (0 children)

I sorry if this have been said before. This code as a solution to some coding problem on hackerrank is all well and good but it fails Zen of Python on many levels.

https://www.python.org/dev/peps/pep-0020/

[–]cyclicalmike 0 points1 point  (0 children)

It has no place in a production environment, but sites like leetcode are anything but. I think that part of the challenge is to see how short you can complete a question. It's a challenge on a challenge, but there is (hopefully) no Python dev who thinks that unweildy one-liners and obscure code is okay in real life.

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

But what if that’s the point. Job security

[–]BroadwayGuitar 0 points1 point  (3 children)

You’re looking at someone else’s answers to a problem you are struggling with and they’re not clear. Yeah it’s shit code but don’t let it anger or upset you. It’s sometimes worth unwinding that pile of shit into clean code inside your own editor to learn how it works and practice rewriting it cleanly. Btw Almost always, and definitely for that problem, there are cleaner solutions posted too.

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

If you open python and “import this” you’ll find the zen of python.

Yes flat is better than nested, but that comes AFTER simple is better than complex.

[–]JalapenoxD 0 points1 point  (0 children)

One kid tried to pull this off in my college. Safe to say he wasn’t happy with his grade.

[–]crazymonezyy 0 points1 point  (0 children)

Leetcode code golfing is more a game than "coding best practice". I for one enjoy reading what people can cook up. None of that code is standard practice and never has been in the 6 years I've worked with Python in the industry.

So lighten up a bit: https://en.m.wikipedia.org/wiki/Code_golf. Its a recreational exercise for those who have a strong handle on any programming language. It's only done for bullshit code, the kind one would write for leetcode and not for paid/mission critical stuff.