What is the most effective method for rewriting this code in a manner that is both concise and elegant?
def xy():
xset = {x for x in range(-4, 6)}
yset = {y for y in range(-3, 4)}
A = {(x, y) for x in xset for y in yset if 2*x - y == 0}
B = {(x, y) for x in xset for y in yset if 3*x + y == 0}
return A&B, A|B
print(xy())
Canât get more concise than comprehensions. Trying to figure out more concise and âelegantâ code is not effective use of resources.
A better question for you to answer: how can I write clear code that communicates intent and purpose to humans such that it results in increased maintainability.
Writing good code isnât about cramming as much functionality into as few characters as possible. It is about communication, being readable and understandable. Especially if you get into area where future developers donât necessarily have the depth of knowledge about an API youâre using just yet, they might just be starting to work on your code. One way to do that would be to use literate programming, for instance see https://jesterking.github.io/rhipy/create_pbr_material_with_textures.html , or even better read Physically Based Rendering: From Theory to Implementation for the ultimate example of best possible documentation and runnable code in one. There are of course other approaches to ensuring good communication with other developers, including future self.
As is sometimes said: writing code is communicating with readers, most likely with you yourself in the future.
I can only offer an opinion as to whether code is âconcise and elegantâ or not, after itâs been written and Iâve read it (i.e. not in advance). But some other things to consider:
Ranges are immutable sequences(*), and cannot have step=0. Therefore all the items yielded from a range are already unique, and storing them in a set (in {}s containing no :s - thatâs a dict) does not deduplicate or change of them. For testing membership, a set could be a possible optimisation for O(1) lookup. But not here. Here, firstly the two setsâre being iterated over (not used to test for membership) and thatâs O(n) each at best anyway. Secondly the implementation of a membership test for a range is probably faster than the hash algorithms of sets and dicts (not to mention the overhead of memory allocation from creating those more complex data structures on the heap).
All a range needs to test for membership of x is evaluate: start <= x < end and ((x - start) % step == 0).
tl;dr consider getting rid of the first two sets for simplicity. However in this case, I think that would actually make the A and B lines longer and less readable, so as the double for loop code is being repeated anyway, howabout:
def xy():
xy_pairs = [(x, y) for x in range(-4, 6) for y in range(-3, 4)]
A = {(x, y) for x, y in xy_pairs if 2*x - y == 0}
B = {(x, y) for x, y in xy_pairs if 3*x + y == 0}
return A&B, A|B
print(xy())
(*) In Python 3. In Python 2 range() returns a list, the equivalent type is xrange.
Although I donât completely get what youâve said, the code has improved.
def xy():
xyset = {(x, y) for x in range(-4, 6) for y in range(-3, 4)}
A = {(x, y) for x, y in xyset if 2*x - y == 0}
B = {(x, y) for x, y in xyset if 3*x + y == 0}
return A&B, A|B
print(xy())
And even then you can go even shorter by using shortest possible variable names and getting rid of whitespace.
While code golf can be fun it is not a style of programming to aspire to in production environments.
Even fewer characters:
def q():
r=range;s={(x,y) for x in r(-4, 6) for y in r(-3, 4)}
A={(x,y) for x,y in s if 2*x-y==0}
B={(x,y) for x,y in s if 3*x+y==0}
return A&B, A|B
print(q())
That is 163 against the 209 of your latest.
Anyway, I still donât see what you want with a shared root and combined roots of two hard-coded functions over hard-coded ranges.
edit: even shorter character wise, 158
def q(): r=range;s={(x,y) for x in r(-4, 6) for y in r(-3, 4)};A={(x,y) for x,y in s if 2*x-y==0};B={(x,y) for x,y in s if 3*x+y==0};return A&B,A|B
print(q())
Readable? Maintainable? Communicative? Not really.
union, intersection = set(), set()
for x in range(-4, 6):
ya = 2 * x
yb = -3 * x
if ya == yb:
intersection.add((x, ya))
if -3 <= ya < 4:
union.add((x, ya))
if -3 <= yb < 4:
union.add((x, yb))
print(union, intersection)
Do you mean your code requires less computing power or calculations?
What causes a script to run more quickly or slowly? (From line 1 to 10, for example)
Hereâs my concept:
If there are more functions in a script, such as methods() and def(), which take longer to compute. Strings are likely to require less time to compute because they are one-to-one functions.
I can understand your code, but writing it in your style takes longer because there is a mental step of âadding back to something.â If your script is faster, I will definitely modify my style for writing code. Is it true, though?
union, intersection = set(), set() # it looks professional...
My code runs for 10 values of x, creating 2 y variables and evaluating 3 if conditions per iteration.
My code only evaluates points which lie on your two lines.
your code does this:
def xy():
xset = {x for x in range(-4, 6)} # set of 10 values
yset = {y for y in range(-3, 4)} # set of 7 values
A = {(x, y) for x in xset for y in yset if 2*x - y == 0} # evaluates 70 pairs of (x, y)
B = {(x, y) for x in xset for y in yset if 3*x + y == 0} # the same 70 pairs of (x, y) again
return A&B, A|B
print(xy())
Your code evaluates every point in the 2D space you are considering - you could argue that my code is more effective because it operates on fewer irrelevant points. I would expect my code to scale better to larger spaces (if you correct the logical error where I fail to check that the intersection lies inside the allowed bounds of y values).
I think I found the most readable solution. Its a one-liner so I think this is the most convenient and elegant way. I encourage other developers to write more code like this. Makes life easier for me!
xy =lambda:eval(''.join([chr(ord(_)-0b01) for _ in \
"fwbm)czuft/gspnify)(398C39413D31413:8E3D318C39423D31433:3D31393E423D31443:3D31393E423D313E433:3D3139423D313E443:3D3139413D31413:8E3:(*/efdpef)**"]))
print(xy())