I've been on stackoverflow looking for an alternative to the ugly if-elif-else structure shown below. The if-else structure takes three values as input and returns a pre-formatted string used for an SQL query. The code works right now, but it is difficult to explain, ugly, and I don't know a better way to do re-format it.
I need a solution that is more readable. I was thinking a dictionary object, but I can't wrap my mind how to implement one with the complex if/else structure I have below. An ideal solution will be more readable.
def _getQuery(activity,pollutant,feedstock):
if feedstock.startswith('CG') and pollutant.startswith('VOC'):
pass
if feedstock == 'FR' and activity == 'Harvest':
return 'FR'
elif feedstock == 'FR':
return 'No Activity'
elif(activity == 'Fertilizer' and pollutant != 'NOx' and pollutant != 'NH3'):
return 'No Activity'
elif(activity == 'Chemical' and pollutant != 'VOC'):
return 'No Activity'
elif( (feedstock == 'CS' or feedstock == 'WS')
and
(activity == 'Non-Harvest' or
activity == 'Chemical')):
return 'No Activity'
elif( ( ( pollutant.startswith('CO') or pollutant.startswith('SO') )
and
( activity == 'Non-Harvest' or
activity == 'Harvest' or
activity == 'Transport' )
)
or
( pollutant.startswith('VOC')
and not
( feedstock.startswith('CG') or feedstock.startswith('SG') )
)
):
rawTable = feedstock + '_raw'
return """
with
activitySum as (select distinct fips, sum(%s) as x
from %s where description ilike '%s' group by fips),
totalSum as (select distinct r.fips, sum(r.%s) as x
from %s r group by r.fips),
ratios as (select t.fips, (a.x/t.x) as x from activitySum a, totalSum t
where a.fips = t.fips),
maxRatio as (select r.fips, r.x as x from ratios r
group by r.fips, r.x order by x desc limit 1),
minRatio as (select r.fips, r.x as x from ratios r
group by r.fips, r.x order by x asc limit 1)
select mx.x, mn.x from maxRatio mx, minRatio mn;
""" % (pollutant, rawTable, '%'+activity+'%',
pollutant, rawTable)
elif( (pollutant[0:2] == 'PM')
and
(activity == 'Non-Harvest' or
activity == 'Harvest' or
activity == 'Transport')):
rawTable = feedstock + '_raw'
return """
with
activitySum as (select distinct fips, (sum(%s) + sum(fug_%s)) as x
from %s where description ilike '%s' group by fips),
totalSum as (select distinct r.fips, (sum(r.%s) + sum(r.fug_%s)) as x
from %s r group by r.fips),
ratios as (select t.fips, (a.x/t.x) as x from activitySum a, totalSum t
where a.fips = t.fips),
maxRatio as (select r.fips, r.x as x from ratios r
group by r.fips, r.x order by x desc limit 1),
minRatio as (select r.fips, r.x as x from ratios r
group by r.fips, r.x order by x asc limit 1)
select mx.x, mn.x from maxRatio mx, minRatio mn;
""" % (pollutant, pollutant, rawTable, '%'+activity+'%',
pollutant, pollutant, rawTable)
.
.
.
Lots more complex elif statements
"""with activitySum etc.
which appears twice with only minor changes. Maybe see if you can use theif/elif
structure to set values of variables with meaningful names which are then sanitised and fed into a single 'template' query string at the end. \$\endgroup\$ – Stuart Dec 19 '12 at 0:03'No Activity'
in others. \$\endgroup\$ – Gareth Rees Dec 19 '12 at 20:40