I recently read the questions that recommend against using switch-case statements in languages that do support it. As far as Python goes, I've seen a number of switch case replacements, such as:
- Using a dictionary (Many variants)
- Using a Tuple
- Using a function decorator (http://code.activestate.com/recipes/440499/)
- Using Polymorphism (Recommended method instead of type checking objects)
- Using an if-elif-else ladder
- Someone even recommended the Visitor pattern (Possibly Extrinsic)
Given the wide variety of options, I am having a bit of difficulty deciding what to do for a particular piece of code. I would like to learn the criteria for selecting one of these methods over the other in general. In addition, I would appreciate advice on what to do in the specific cases where I am having trouble deciding (with an explanation of the choice).
Here is the specific problem:
(1)
def _setCurrentCurve(self, curve):
if curve == "sine":
self.currentCurve = SineCurve(startAngle = 0, endAngle = 14,
lineColor = (0.0, 0.0, 0.0), expansionFactor = 1,
centerPos = (0.0, 0.0))
elif curve == "quadratic":
self.currentCurve = QuadraticCurve(lineColor = (0.0, 0.0, 0.0))
This method is called by a qt-slot in response to choosing to draw a curve from a menu. The above method will contain a total of 4-7 curves once the application is complete. Is it justified to use a throw away dictionary in this case? Since the most obvious way to do this is if-elif-else, should I stick with that? I have also consider using **kargs here (with a friends help) since all the curve classes use **kargs...
(2)
This second piece of code is a qt-slot that is called when the user changes a property of a curve. Basically the slot takes the data from the gui (spinBox) and puts it in an instance variable of the appropriate curve class. In this case, I again have the same question - should I use a dict?
Here is the aforementioned slot-
def propertyChanged(self, name, value):
"""A Qt slot, to react to changes of SineCurve's properties."""
if name == "amplitude":
self.amplitude = value
elif name == "expansionFactor":
self.expansionFactor = value
elif name == "startAngle":
self.startAngle = value
elif name == "endAngle":
self.endAngle = value
For reference, here is the code for connecting to the above slot -
def _connectToPage(self, page):
for connectionData in page.getConnectibles():
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
lambda value, name = connectionData["property"]:\
self.currentCurve.propertyChanged(name, value))
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
self.hackedDisplayArea.update)
Note - The self.endAngle etc. are initialized in the constructor.
As far as I know, the reasons for choosing a dict is for fast lookup. When is that warranted? when I have 100 cases or more? Is it a good idea to keep building and throwing away a dictionary each time the function is called? If I build a dict for this purpose outside a function, should I check If it is needed elswhere? What happens if it is not needed elsewhere?
My question is what is the best-practice if there is one? What is the best/most elegant way to go about things? Put in yet another way, when to use if-elif-else, when to use each of the other options?