Reputation: 4649
I made a bunch of functions that control a message-based instrument. I know how to use them but the functions should be fool-proof in case somebody else wants to code with it after I'm gone. Here is an example function:
def AutoRange(self, Function, Source, Value):
"""Enable or disable the instrument autoranging feature.\n
:Function: "source" or "measure".
:Source: "v" or "i".
:Value: 0 or 1."""
# <Something goes here to check if the inputs are valid>
self.WRITE("smua.%s.autorange%s = %s" %(Function, Source, Value))
To comply with the input requirements I initially added a RaiseException
at the start in an ugly way:
AllowedFunctions = ("source", "measure")
AllowedSources = ("v", "i")
AllowedValues = (0, 1)
if not(Function in AllowedFunctions and Source in AllowedSources and Value in AllowedValues):
raise Exception("/!\ Error in Keithley.Autorange(): Input not allowed.")
After reading about assert()
I replaced the if
with this:
MyErrorMessage = "/!\ Error in Keithley.Autorange(): Input not allowed."
assert (Function in ("source", "measure")), MyErrorMessage
assert (Source in ("v", "i")), MyErrorMessage
assert (Value in (0, 1)), MyErrorMessage
A possible neater variant would be this:
ValidInputs = ( Function in ("source", "measure")
and Source in ("v", "i")
and Value in (0, 1))
assert (ValidInputs), "/!\ Error in Keithley.Autorange(): Input not allowed."
The second option is nicer now that I think of it because then I can tell specifically which input was invalid. So my question is: is this how you should handle assertions? 1 assert()
for 1 input? If not, what is the adviced structure? Thanks in advance.
Upvotes: 1
Views: 1274
Reputation: 198476
Why not do what Python does?
Let's see an example:
open("foo", "q")
# => ValueError: invalid mode: 'q'
open
is in C, but you can see how it looks like for e.g gzip.open
:
if "t" in mode:
if "b" in mode:
raise ValueError("Invalid mode: %r" % (mode,))
Don't be scared of making the code a little longer; you can't really avoid it in Python. And also, "Error in Keithley.Autorange(): Input not allowed." doesn't tell the programmer which input is not allowed. In this case, explicit and clear is better than clever and short.
I'd do:
def auto_range(self, function, source, value):
if function not in ["source", "measure"]:
raise ValueError("Invalid function: %s" % function)
if source not in ["v", "i"]:
raise ValueError("Invalid source: %s" % source)
if value not in [0, 1]:
raise ValueError("Invalid value: %d" % value)
# ...
Not directly relevant to your questions, but it is best to stick to the language's coding style: in Python, variables are in snake_case
(lowercase with underscores).
Upvotes: 3