Reputation: 2556
I am trying to emulate a switch-case statement from the validate_input2
function below.
def _validate_inputs2(*args):
if len(args) == 1:
stop = args
start = 1
step = 1
elif len(args) == 2:
start, stop = args
step = 1
elif len(args) == 3:
start, stop, step = args
else:
raise TypeError("xxx expected at most 3 arguments, got 4")
if 0 == step:
raise ValueError("xxx arg 3 must not be zero")
return start, stop, step
This is what I basically did but it doesn't work correctly
def _validate_inputs(*args):
start, stop, step = {
len(args) == 1: lambda x, y, z: (args, 1, 1),
len(args) == 2: lambda x, y, z: (args, 1),
len(args) == 3: args
}.get(args, lambda: TypeError("xxx expected at most 3 arguments, got 4"))()
if 0 == step:
raise ValueError("xxx arg 3 must not be zero")
return start, stop, step
Even though I find this emulation less readable I would like to better understand it in order to improve my python skills.
Can someone help me simplify this code?
Upvotes: 1
Views: 358
Reputation: 1459
Good news for you, if you are still interested in using the switch case in Python.
you can now use Match
with Python 3.10
like this:
match day:
case 1:
return "Sunday"
case 2:
return "Monday"
case 3:
return "Tuesday"
case 4:
return "Wednesday"
case 5:
return "Thursday"
case 6:
return "Friday"
case 7:
return "Saturday"
For more details read click here to read this python documentation
Upvotes: 0
Reputation: 43494
Here is a solution that builds upon what you have done:
def _validate_inputs(*args):
if len(args) > 3:
raise TypeError("xxx expected at most 3 arguments, got 4")
else:
start, stop, step = {
1: (1,) + args + (1,),
2: args + (1,),
3: args
}.get(len(args))
if 0 == step:
raise ValueError("xxx arg 3 must not be zero")
return start, stop, step
Example outputs:
>>> print _validate_inputs(40)
(1, 40, 1)
>>> print(_validate_inputs(10, 20))
(10, 20, 1)
>>> print(_validate_inputs(1, 2, 3))
(1, 2, 3)
Edit: The TypeError
wasn't working correctly in the original post. You can't return a TypeError
as the not-found value in get()
in this case, since the code is expecting 3 values to be unpacked (in python 2.x
at least AFAIK).
I've updated the code to handle the case where len(args) > 3
. One could also add a check for the case where args
is None
or empty.
>>> print(_validate_inputs(1, 2, 3, 4))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-302-c2f9c1befae1> in <module>()
----> 1 print(_validate_inputs(1,2,3,4))
<ipython-input-296-769e989711e0> in _validate_inputs(*args)
1 def _validate_inputs(*args):
2 if len(args) > 3:
----> 3 raise TypeError("xxx expected at most 3 arguments, got 4")
4 else:
5 start, stop, step = {
TypeError: xxx expected at most 3 arguments, got 4
Upvotes: 3
Reputation: 637
I would try something like this..
def _validate_inputs(*args):
start, stop, step = [0, 0, 0]
dict = {1: [args, 1, 1], 2: args.append(1), 3: args}
if len(args) in dict.keys():
start, stop, step = dict[len(args)]
else:
raise TypeError("xxx expected at most 3 arguments, got "+str(len(args))))()
if 0 == step:
raise ValueError("xxx arg 3 must not be zero")
return start, stop, step
Upvotes: 1
Reputation: 82889
(Not an answer to the question, but maybe a better approach to the actual problem.)
It seems like you are replicating part of what the Python slice
builtin does. So you could just create a slice
from the args
and get the start
, stop
, and step
from that.
>>> args = (2, 4)
>>> s = slice(*args)
>>> start, stop, step = s.start, s.stop, s.step
>>> start, stop, step
(2, 4, None)
This also takes care of handling the error cases:
>>> args = (1, 2, 3, 4)
>>> slice(*args)
TypeError: slice expected at most 3 arguments, got 4
Upvotes: 2