Reputation: 107
I trying to see if there is a more efficient way to write if elif statement. Writing an API to generate a url based on the number of parameters the class is called.
For Ex:
def Cars(self, model=null, color=null, miles=null)
if model == null and color == null and miles ==null:
url = cars/
elif model != null and color == null and miles ==null:
url = cars/model=%s)% model
elif model != null and color != null and miles ==null:
url = cars/model=%s/color=%s)% model, color
else url = someting
return url
I have more than 10 parameters and don't want to write that many elif statements with all the combinations..
Upvotes: 0
Views: 1036
Reputation: 3803
Like chepner's answer (and others in the comments), my thought was to use
keyword arguments. However, rather than using url += ...
each time through the loop, my approach is generally to append the parameters to a list, and then use .join()
to create the final string once the parameter list has been created. That way I don't have to worry about whether I'm formatting the string correctly; I can let Python take care of that headache.
I only post this to demonstrate an alternate method using the same starting point.
def cars(**kwargs): # If using as part of a class, would be cars(self, **kwargs)
params = []
for key in kwargs.keys():
# Append `key=value` to `params`.
if kwargs.get(key):
params.append('{!s}={!s}'.format(key, kwargs[key]))
url = '/cars?{!s}'.format('&'.join(params))
return url
print(cars(make='Ford', model='Taurus', year=2000, colors='white'))
Upvotes: 0
Reputation: 11831
If you are simply patterning your url, where each parameter gives a substring to the url, you can do something like this:
url = 'http://foo.com/'
if model is not None:
url += 'model={}'.format(model)
if color is not None:
url += 'color={}'.format(model)
if miles is not None:
url += 'miles={0:.1f}'.format(model)
If you don't need any custom formatting per parameter, you can collapse all of that to this:
url = 'http://foo.com/'
for parameter in ['model', 'color', 'miles']:
url += '{}={}'.format(parameter, locals()[parameter])
Upvotes: 0
Reputation: 412
Ignoring all your mistakes in the code... what about:
url = "cars"
if model:
url += "/model={}".format(model)
if color:
url += "/color={}".format(color)
if ...
Upvotes: 0
Reputation: 1713
You could perhaps do something like this:
def Cars(self, model=null, color=null, miles=null)
url = "cars/"
if ( model ) :
url += "/models=%s" % model
if ( color ) :
url += "/color=%s" % color
if ( miles ) :
url += "/miles=%s" % miles
return url
In writing it this way, you'll avoid having to use combinatorics. In your code, you'll have 9 if..else statements, here we have only three.
Upvotes: 0
Reputation: 531420
The attributes don't appear to be dependent on each other; handle each one separately:
def cars(self, model=None, color=None, miles=None)
url = "cars"
if model is not None:
url += "/model=%s" % (model,)
if color is not None:
url += "/color=%s" % (color,)
if miles is not None:
url += "/miles=%s" % (miles,)
return url
This leads to the realization that you probably want to accept arbitrary keyword arguments, and check for the existence of a specific set:
def cars(self, **kwargs):
url = "cars"
for kw in ["model", "color", "miles"]:
if kwargs.get(kw) is not None:
url += "/%s=%s" % (kw, kwargs[kw])
return url
This ignores the issue of whether or not the string you are building is, in fact, a valid URL.
Upvotes: 9