I've recently been experimenting with different ways of doing this. My goals going into it were keeping the height of the answer low (previous attempts have gotten long) and explaining what exactly the code does instead of why it does it. This is antithetical to what usually makes for a good way to explain a program, but in my opinion it's more fun to read on sites like this because you get riddles like "Why did they do this here?", answered later in the program with "Oh, it lets them a neat trick to save characters here!". Those moments are my favourite thing about reading this site. A thorough, literal explanation of what the code is doing allows people who aren't familiar with the language to play along.
I recently figured out a way to explain my code and meet those goals. As an example, a recent question asked for a program or function to list every letter of the alphabet ordered by how often they show up in an input string. This was my answer:
f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1]
And this was my explanation:
range(65,91) # The numbers 65 to 90
map(chr,range(65,91)) # Convert to ASCII
s # The input string
s.upper() # Convert to uppercase
s.upper().count # Function literal for 'how many times the argument appears in the string'
sorted(map(chr,range(65,91)),key=s.upper().count) # Sort by that function
''.join(sorted(map(chr,range(65,91)),key=s.upper().count)) # Concatenate to string
''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Step through by -1 (i.e. reverse string)
lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Make it a function (`return` is implicit for lambdas)
f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Give it a name
I like this for a couple reasons:
- Simple enough to read along with if you don't know python (I think, at least. I know python so I'm not a good judge of this)
- Shows you where to start reading, which isn't always obvious in golfed code (and if there are multiple unrelated parts of the code that have to come together later, like in this answer, you can define a different entry point for each bit)
- I think it looks nice
Of course, there is one big con:
- Horizontal scrollbars make the baby Jesus cry
Overall, though, I think I'll stick with this until I find something better.
range
with the step argument, or alternatively use the step arg of the slice operation. \$\endgroup\$