4 ms·
> Why is 3 stupid? Just to be clear, I do use that pattern in practice, but I usually feel 'dirty' about it. Sometimes I also do things like this: is_admin
by pyre 11y ago
> Why is 3 stupid?
Just to be clear, I do use that pattern in practice, but I usually feel 'dirty' about it. Sometimes I also do things like this:
is_admin = (membership.type == 'master')
is_current_group = (membership.group == session.group)
if is_admin or is_current_group:
do_something()
but I find this easier to justify because I'm adding something more than just the breakup of a line. I'm adding semantic meaning to other developers reading the code. In the example I gave, saying "message=msg" doesn't add anything (as opposed to say "message=bad_shipment_msg", but maybe the definition of "bad_shipment_msg" pushes the string past 80 columns by itself).
As for the example of reusing the message, maybe it's bad practice, but I would end up with tailored messages describing the edge case (e.g.):
if not shipment_qty:
abort(400, message='Must pass a quantity')
elif shipment_qty < 0:
abort(400, message='Quantity must be > 0')
Edit: I do the boolean definition thing more then "sometimes" because I prefer to make complex boolean operations easy to understand, and to also convey the meaning of what you want to achieve.
- sago 11y agoI think it is pretty essential for boolean expressions too, yes, anything that isn't a single comparison, at least. Interesting you find aliasing in variables 'dirty'. Would you feel dirty writing something like def my_method(self): contents = self.contents ... etc ... which I use often if I'm going to use self.contents a lot in that method. It has some performance benefit in rare cases, but mostly it reduces clutter, makes lines smaller, and means I type less. But again, it is 'pointless', in one sense. From the current code open on my machine, even one character variable names!: w, h = self.width, self.height ... Dirty? Stupid? (I'm not being facetious, I'm genuinely interested in your aesthetic sense here).
- coldtea 11y agoWith autocomplete you don't get anything with "one character var names" (leave those for i, j, k etc). And no reason to pollute the local namespace with both self.contents and contents. What if you do this somewhere lower for example: contents = contents[:limit] did you mean to NOT change self.contents? Because that's what you got. Whereas: self.contents = self.contents[:limit] would propagate it.
- sago 11y ago> (leave those for i, j, k etc) Why use them then if you have autocomplete? Since character variable names are useful as very short conventions, I'd never want to see them used generally. Someone working in this code would have to know the meaning immediately from the name, as for any variable. In my application area x,y,w,h,r (radius) and c (context - which is domain specific, but is present in about 50% of LOC in my current code-base) are all as ubiquitous as i and j (I'd probably not be comfortable with k, too deep nesting). i and j are much rarer in python, either using sequences of underscore for 'don't care'. On the second point, there is reason, as I pointed out. It makes code shorter, clearer, and in some cases more performant (when contents is a property, for example). Don't get me wrong, I was following up on the specific point, I wasn't trying to recommend this style as good general practice (alias all your self variables at the top of a method - erm, no). The lack of 'const'ing in python is a risk, yes. We use immutable data structures whenever possible, including immutable classes, because we try to ensure as much code is written without side effects on data. I'd want to not alias variables that have side effects applied to them, yes. But you're right that it makes it easier for a sloppy edit to mess things up. In most cases the 'sloppy' would be adding the side effects at all, however, which either version has. Still, in pages of such code, it helps to write cos_t = math.cos(theta) sin_t = math.sin(theta) x, y = self.position.x, self.position.y return x*cos_t - y*sin_t, x*sin_t + y*cos_t rather than cos_theta = math.cos(theta) sin_theta = math.sin(theta) return self.position.x * cos_theta - self.position.y * sin_theta, self.position.x * sin_theta + self.position.y * cos_theta particularly as the number of uses of x and y increase beyond two in a functon. Ultimately code-quality and maintainability can't be mandated by a PEP or any universal rule. But like any field, you have to understand the purpose of the rule, and weigh up its risks and benefits before you break it.
- coldtea 11y agoWell, for mathematics and such cases (physics etc), yes, I agree that x vs self.position.x etc is handier. But I wouldn't ever do it for the "more performant" part, unless I have profiled the code and it indeed makes a non trivial difference (I know aliasing to a local makes a difference it itself - but I mean it should be significant when the whole program is taken into account, even if it was 1000x faster to access the aliased local, it wouldn't make sense to optimize a part of the program with it, if said part is only responsible for 1% of the total running time). For the general case, I suggested i, j, k only because they are well known conventions, so their meaning will be instantly understood (and of course, if one can avoid such indexes altogether, e.g. with a "for item in" loop, one should).
- pyre 11y ago> Interesting you find aliasing in variables 'dirty'. I don't find aliasing by itself to be dirty. It is just in this example, it would not be adding semantic meaning (as in the "named boolean expressions" example) and it would be used in only a single place (immediately on the next line) so I find it to be the least justified use of aliasing.