3 ms·
The all pairs loop is unnecessarily low level, and it would be hard to spot a mistake there. It would be great if there was a way to say for i < j <= N as
by rmtech 6y ago
The all pairs loop is unnecessarily low level, and it would be hard to spot a mistake there. It would be great if there was a way to say
for i < j <= N
as this is super clear.
- mattkrause 6y agoI guess so. I don't think it's atrocious: it looks like iterating over the upper/lower triangular part of a matrix to me, which is fairly common (in some domains, I guess). Plus, I like that the double for-loop indicates slowness. However, Python has itertools.combinations(X,2) and Julia has IterTools.subsets(X,2) if that's what you want.
- klyrs 6y agoI think you mean # see __magic_numbers.py itertools.combinations(X, number_of_things_in_a_pair)
- deleted 6y ago[deleted]
- mattkrause 6y agoHa! You’re clearly taking the mickey but... Some things only/obviously make sense over pairs of items. For those, go with a literal 2 for x,y in itertools.combinations(obj, 2): if is_overlapping(x,y): raise OverlapError(x,y) However, sometimes the subset’s size just happens to be two (but you might change it), maybe a constant would be good. Ditto if you’re doing some math where there are “real” 2s that are part of a formula and incidental ones that are due to the subset size. For example: subset_size = 2 for subset in itertools.combinations(X, subset_size): mse.append(sum((subset - target)**2)/subset_size) is a bit more flexible and more clear than using all 2s, IMO, and at very little cost (YAGNI blah blah, but I think that’s an argument for not making a whole configuration system that lets you set the size at runtime).
- klyrs 6y ago> Ha! You’re clearly taking the mickey but... Only in my choice of variable name. OP drew a line at 0, 1 and -1. What I did there was highlight that the implications of that rule are absurd. See how your sum of squares also contains a 2? VERBOTEN!!!! And don't you dare re-use "subset_size" ;) This is somewhat akin to Dijkstra's opinion on goto. Which is actually great advice when you're doing apps in javascript, but doesn't get you very far if you're writing or generating assembly. When such advice is promoted to a taboo, I side with Churchill: this is the type of arrant pedantry up with which I will not put. Or Emerson: foolish consistency is the hobgoblin of little minds. Yes, too many numeric literals can make code hard to read. But math is hard to read[1] because you need to really think about it -- you can't avoid the complexity; you can only rearrange it. Where you put it is a matter of taste, and absolutes have absurd consequences. As for the original notion of indexing a triangular array, I have a greater concern: for i in range(n): for j in range(i): foo(array[i][j]) this is self-documenting in the sense that I immediately know the relationship between i and j -- without reading documentation, I can't recall if itertools.combinations will give me the upper or lower triangle. In this case, I'd avoid the 2 for entirely different reasons :) [1] and I don't mean "let's go shopping!" -- I mean that reading a math paper, even for experts, can take days per page.