Let’s start transitioning away from inherited
interactmethods, making them abstract as originally intended. I’ll try to devise a sensible way of proceeding,
I think the first thing is to do one at a time. Here’s what I have that isn’t abstract in InvadersFlyer now:
class InvadersFlyer(Flyer): # Inherited for convenience def interact_with_invaderexplosion(self, explosion, fleets): pass def interact_with_shotcontroller(self, controller, fleets): pass # @abstractmethod def interact_with_shotexplosion(self, bumper, fleets): pass def interact_with_topbumper(self, top_bumper, fleets): pass
I am of course immediately tempted to do them all at once, “because it will be more efficient”. Let’s try doing just one at least once, to see what we see.
@abstractmethod def interact_with_invaderexplosion(self, explosion, fleets): pass
33 tests fail. What is a good way to find all the problem areas? I’ll try Code / Insect Code. That will find a lot of things, but probably will find all the classes missing the new abstract method.
I do that, find the heading for must implement method, then double click to open a class, find the place where I want to method to go, Control+I and select OK. It goes where it should:
def interact_with_bumper(self, bumper, fleets): pass def interact_with_invaderexplosion(self, explosion, fleets): pass def interact_with_invaderfleet(self, invader, fleets): pass
But I will have to do this eight more times. And each time, I should practice asking myself whether this class should interact with the explosion. Of course the answer is always “no” because this one doesn’t interact with anything.
Tedious to repeat but if I just set PyCharm free, it won’t place the method where I want it, in an alphabetical list of the interaction methods.
I find a quicker way. PyCharm has a window that opens when you select an inspection and you can do the Control+I there.
InvaderPlayer class had another method out of order so I took the moment to fix that one.
InvaderFleet was messy. I took the time to clean it up. Similarly with PlayerShot. I’ve been a bit careless. Pretty quickly I’ve done the one. Commit: make method abstract.
Quick enough but it did commit ten files, which is huge for me.
I guess I can do it again, make another one abstract.
The next time through, ShotController, goes faster. I am not thinking hard about each case. Of course I “know” that
pass is the right answer for these ones. But thinking would be better. It’d hard to pause to think when doing a sort of rote boring task. And it’s an important time to think.
A better way
I learn a new trick. You can run a specific inspection, so I run the abstract method checking one and get a shorter list of things to look at. Still the same ones but no other noise around them.
I learn that I don’t have to open each heading, I can click the heading and the class opens in the editing window and i scroll to the right place and to my Control+I. Getting more efficient. Commit again.
PyCharm remembers the last inspection by name that I did. If I could remember command shift control I I could get there with that and a couple of returns. One more batch to do.
Done. Not bad at all and I feel very righteous. All the methods that should be abstract now are, or at least all the ones that I did lazily recently. Possibly there are others that should be as well but none in InvadersFlyer.
Well, I say “Done”. There are inherited methods in AsteroidFlyer as well. I should schedule those for similar work but I’m on the Invaders project right now. But apparently I’ve been sinning more frequently than I remembered.
I do think making all the
interact_with_doodah methods abstract is the right thing, by a narrow margin, even though it is a pain to do. It’s safer than silently ignoring them.
I would like to have a better way but I still don’t know one. I’ll keep thinking and listening to folks with ideas.
Anyway, the code is happier today, and so am I.
See you next time!