Is it a bad practice writing long one-liner code? - coding-style

I found myself keep writing pretty long one-liner code(influenced by shell pipe), like this:
def parseranges(ranges, n):
"""
Translate ":2,4:6,9:" to "0 1 3 4 5 8 9...n-1"
== === == === ===== =========
"""
def torange(x, n):
if len(x)==1:
(x0, ) = x
s = 1 if x0=='' else int(x0)
e = n if x0=='' else s
elif len(x)==2:
(x0, x1) = x
s = 1 if x0=='' else int(x0)
e = n if x1=='' else int(x1)
else:
raise ValueError
return range(s-1, e)
return sorted(reduce(lambda x, y:x.union(set(y)), map(lambda x:torange(x, n), map(lambda x:x.split(':'), ranges.split(','))), set()))
I felt ok when I written it.
I thought long one-liner code is a functional-programming style.
But, several hours later, I felt bad about it.
I'm afraid I would be criticized by people who may maintain it.
Sadly, I've get used to writing these kind of one-liner.
I really want to know others' opinion.
Please give me some advice. Thanks

I would say that it is bad practice if you're sacrificing readability.

It is common wisdom that source code is written once but read many times by different people. Therefore it is wise to optimize source code for the common case: being read, trying to understand.
My advice: Act according to this principle. Ask yourself: Can anybody understand any piece of my code more easily? When the answer is not a 100% "No, I can't even think of a better way to express the problem/solution." then follow your gut feeling and reformat or recode that part.

Unless performance is a major consideration, readability of the code should be given high major priority. Its really important for its maintainability.
A relevant quote from the book Structure and Interpretation of Computer Programs.
"Programs should be written for people to read, and only incidentally for machines to execute."

(Update 2022-03-25: My answer refers to a previous revision of the question.)
The first and third examples are acceptable to me. They are close enough to the application domain so that I can easily see the intention of the code.
The second example is much too clever. I don't even have an idea about its purpose. Can you rewrite it in maybe five lines, giving the variables longer names?

Related

if(X){if(Y){ versus if(X&&Y). Question about efficiency

I'm sure this is a very simple question, but I'm not really sure what search parameters to use, so I'm going to ask here.
Let's say I have code I want to execute when both X and Y are true, and I want it to be as efficient as possible. There are two ways I know to go about this;
if(X)
if(Y)
//do stuff
Or there is:
if(X && Y)
//do stuff
What I'm curious to know is how this code is actually read and executed at runtime? Is it more efficient to not check Y at all if X isn't true? Or is it more efficient to execute checks for X and Y at the same time? Obviously the second is more readable for humans, but if the only goal is efficiency, which is better?
Thanks!
The 1st case is more effective than the 2nd one.
The ASM code for the 1st case will be below type.
ax = A
if ax=0 goto address
ax = B
if ax = 0 goto adress
Do something
address:
..........................
but the ASM code for the 2nd case will be below type.
ax = A
bx = B
ax = A & B
if ax=0 goto address
Do something
address:
...........................
In many (most?) languages, the two will be exactly the same.
If you care about performance, I assume you're using a good, optimizing compiler. Any optimizing compiler should realize that when you write
if(X && Y)
then if X is false, it doesn't need to waste time evaluating Y.
This so-called short circuiting behavior is part of the definition of C and C-like languages.
Also, if you care about efficiency and performance, issues like this one are probably the last thing you should be worrying about. It's very important that you pick a good language, and a good compiler for it, and choose good algorithms. Fussing with low-level coding details, like if (X) if(Y) versus if(X && Y), usually won't make much of a difference.
Also, if you really care about efficiency and performance, the only way to really answer questions like these is to perform careful measurements, using your code and your compiler and your computer, today.
And it can actually be quite difficult to perform good measurements. Often, the two options will seem to have identical performance, which is another clue that "microoptimizations" usually don't matter at all.

In a lua for loop what is a # used for?

I know how for loops work and I use them quite often but also seem to often come across a # in others' code and I want to know what it is for and how to use it. An example of this would be:
for i = 1, #npc do local v = npc[i]
I cant seem to find anything online regarding this, maybe my searches just aren't good but it would be nice if someone could explain it for me, thanks.
In Lua, # is the length operator. for i = 1, #npc essentially loops from 1 to the length of the npc array.
As was already pointed out, it gets the length of a list. However, there's another thing worth pointing out: that for loop is suboptimal and unidiomatic. It would be better written as for i, v in ipairs(npc) do. In general, using # in a for loop is almost always the wrong thing to do.

Algorithm design manual solution to 1-8

I'm currently reading through The Algorithm Design Manual by Steven S. Skiena. Some of the concepts in the book I haven't used in almost 7 years. Even while I was in college it was difficult for me to understand how some of my classmates came up with some of these proofs. Now, I'm completely stuck on one of the exercises. Please help.
Will you please answer this question and explain how you came up with what to use for your Base case and why each step proves why it is valid and correct. I know this might be asking a lot, but I really need help understanding how to do these.
Thank you in advance!
Proofs of Correctness
Question:
1-8. Proove the correctness of the following algorithm for evaluating a polynomial.
$$P(x) = a_nx_n+a_n−1x_n−1+⋯+a_1x+a_0$$
&function horner(A,x)
p=A_n
for i from n−1 to 0
p=p∗x+Ai
return p$
btw, off topic: Sorry guys, I'm not sure how to correctly add the mathematical formatting for the formula. I tried by addign '$' around each section. Not sure why that isn't working.
https://cs.stackexchange.com/ is probably better for this. Also I'm pretty sure that $$ formatting only works on some StackExchange sites. But anyways, think about what this algorithm is doing at each step.
We start with p = A_n.
Then we take p = p*x + A_{n-1}. So what is this doing? We now have p = x*A_n + A_{n-1}.
I'll try one more step. p = p*x + A_{n-2} so now p = (x^2)*A_n + x*A_{n-1} + A{n-2} (here x^2 means x to the power 2, of course).
You should be able to take it from here.

doing something in an unusual but efficient way

I watched a video today and the guy in the video just write this to understand whether a number is even or not:
number/2*2 == number ? true : false ;
i tried it when i got home and compared with
number % 2 == 0 ? true : false ;
The second one was faster then i changed the first one as:
number>>1<<1 == number ? true : false;
this time shifting the number once to the right and once to left worked faster :D
The performance difference is not huge just 0-1 second for identifying all the numbers
between 1 and 1000000000 but I liked it very much and wanted to hear such tricks from you.
so what else ? =)
and another idea from Russell Borogove =)
(number&1) == 0;
Results:
Time Elapsed With And Operation:00:00:07.0504033
Time Elapsed With Shift Operation:00:00:06.4653698
Time Elapsed With Mod Operation:00:00:06.8323908
Surprisingly shifting two times is working faster than a single and operation on my computer.
MIT actually keeps a list of such things, HAKMEM, which can be found at http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html. Most of the programming-related ones are written in assembly language, but I understand that some of them have been translated to C at http://graphics.stanford.edu/~seander/bithacks.html.
Now for a lecture: These dirty tricks might be faster, but take far too long to comprehend.
Most computing isn't so performance-critical that tricks like this are necessary. In the odd-even case, number % 2 == 0 is much clearer and more readable than number/2*2 == number or number>>1<<1 == number. That said, in normal applications you should always use the simpler and more standard option because it will make your code easier to understand and maintain.
However, there are use cases for tricks like this. Especially in large-scale mathematical or scientific computing and computer graphics, tricks like these can save your life. An excellent example of this is John Carmack's "magic inverse square root" in Quake 3.
The book Hacker's Delight is 300 pages of nothing but stuff like this. It's not cheap but it's a bit-twiddler's bible.

How to explain to a developer that adding extra if - else if conditions is not a good way to "improve" readability?

Recently I've bumped into the following C++ code:
if (a)
{
f();
}
else if (b)
{
f();
}
else if (c)
{
f();
}
Where a, b and c are all different conditions, and they are not very short.
I tried to change the code to:
if (a || b || c)
{
f();
}
But the author opposed saying that my change will decrease readability of the code. I had two arguments:
1) You should not increase readability by replacing one branching statement with three (though I really doubt that it's possible to make code more readable by using else if instead of ||).
2) It's not the fastest code, and no compiler will optimize this.
But my arguments did not convince him.
What would you tell a programmer writing such a code?
Do you think complex condition is an excuse for using else if instead of OR?
This code is redundant. It is prone to error.
If you were to replace f(); someday with something else, there is the danger you miss one out.
There may though be a motivation behind that these three condition bodies could one day become different and you sort of prepare for this situation. If there is a strong possibility it will happen, it may be okay to do something of the sort. But I'd advice to follow the YAGNI principle (You Ain't Gonna Need It). Can't say how much bloated code has been written not because of the real need but just in anticipation of it becoming needed tomorrow. Practice shows this does not bring any value during the entire lifetime of an application but heavily increases maintenance overhead.
As to how to approach explaining it to your colleague, it has been discussed numerous times. Look here:
How do you tell someone they’re writing bad code?
How to justify to your colleagues that they produce crappy code?
How do you handle poor quality code from team members?
“Mentor” a senior programmer or colleague without insulting
Replace the three complex conditions with one function, making it obvious why f() should be executed.
bool ShouldExecute; { return a||b||c};
...
if ShouldExecute {f();};
Since the conditions are long, have him do this:
if ( (aaaaaaaaaaaaaaaaaaaaaaaaaaaa)
|| (bbbbbbbbbbbbbbbbbbbbbbbbbbbb)
|| (cccccccccccccccccccccccccccc) )
{
f();
}
A good compiler might turn all of these into the same code anyway, but the above is a common construct for this type of thing. 3 calls to the same function is ugly.
In general I think you are right in that if (a || b || c) { f(); } is easier to read. He could also make good use of whitespace to help separate the three blocks.
That said, I would be interested to see what a, b, c, and f look like. If f is just a single function call and each block is large, I can sort of see his point, although I cringe at violating the DRY principle by calling f three different times.
Performance is not an issue here.
Many people wrap themselves in the flag of "readability" when it's really just a matter of individual taste.
Sometimes I do it one way, sometimes the other. What I'm thinking about is -
"Which way will make it easier to edit the kinds of changes that might have to be made in the future?"
Don't sweat the small stuff.
I think that both of your arguments (as well as Developer Art's point about maintainability) are valid, but apparently your discussion partner is not open for a discussion.
I get the feeling that you are having this discussion with someone who is ranked as more senior. If that's the case, you have a war to fight and this is just one small battle, which is not important for you to win. Instead of spending time arguing about this thing, try to make your results (which will be far better than your discussion partner's if he's writing that kind of kode) speak for themselves. Just make sure that you get credit for your work, not the whole team or someone else.
This is probably not the kind of answer you expected to the question, but I got a feeling that there's something more to it than just this small argument...
I very much doubt there will be any performance gains of this, except at least in a very specific scenario. In this scenario you change a, b, and c, and thus which of the three that triggers the code changes, but the code executes anyhow, then reducing the code to one if-statement might improve, since the CPU might have the code in the branch cache when it gets to it next time. If you triple the code, so that it occupies 3 times the space in the branch cache, there is a higher chance one or more of the paths will be pushed out, and thus you won't have the most performant execution.
This is very low-level, so again, I doubt this will make much of an impact.
As for readability, which one is easier to read:
if something, do this
if something else, do this
if yet another something else, do this
"this" is the same in all three cases
or this:
if something, or something else, or yet another something else, then do this
Place some more code in there, other than just a simple function call, and it starts getting hard to identify that this is actually three identical pieces of code.
Maintainability goes down with the 3 if-statement organization because of this.
You also have duplicated code, almost always a sign of bad structure and design.
Basically, I would tell the programmer that if he has problems reading the 1 if-statement way of writing it, maybe C++ is not what he should be doing.
Now, let's assume that the "a", "b", and "c" parts are really big, so that the OR's in there gets lost in lots of noise with parenthesis or what not.
I would still reorganize the code so that it only called the function (or executed the code in there) in one place, so perhaps this is a compromise?
bool doExecute = false;
if (a) doExecute = true;
if (b) doExecute = true;
if (c) doExecute = true;
if (doExecute)
{
f();
}
or, even better, this way to take advantage of boolean logic short circuiting to avoid evaluating things unnecessary:
bool doExecute = a;
doExecute = doExecute || b;
doExecute = doExecute || c;
if (doExecute)
{
f();
}
Performance shouldn't really even come into question
Maybe later he wont call f() in all 3 conditons
Repeating code doesn't make things clearer, your (a||b||c) is much clearer although maybe one could refactor it even more (since its C++) e.g.
x.f()

Resources