如何减少不同情况下的代码行

时间:2019-09-14 12:59:17

标签: python python-3.x

摘要如下:

@api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
    dbconnection = dbconnector.configuration('farmautomation')
    if graphType == "line" and fieldType == "weather details":
        dataframe_name = DataFrame_Conversion.weather_details_dataFrame(dbconnection)
        groupbyvalue = 'village'
        fieldstoaggregate = 'humidity'
        datamin, datamax = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
                                           field='humidity')
        return Graphs.weather(datamin, datamax)

    elif graphType == "pie" and fieldType == "total farmers":
        dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
        groupbyvalue = 'created_time'
        fieldstoaggregate = 'count'
        result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
                             field='logins')
        return Graphs.pie(result)
    elif graphType == "bar" and fieldType == "logins":
        dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
        groupbyvalue = 'created_time'
        fieldstoaggregate = 'count'
        result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
                                 field='logins')
        return Graphs.bar(result)

两个条件(elif)中的代码相同,但返回类型不同,是否有可能减少我的代码?

我不知道尝试什么,感谢您的帮助

1 个答案:

答案 0 :(得分:2)

第2个条件和第3个条件看起来基本相同,因此可以这样组合:

@api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
    dbconnection = dbconnector.configuration('farmautomation')
    if graphType == "line" and fieldType == "weather details":
        dataframe_name = DataFrame_Conversion.weather_details_dataFrame(dbconnection)
        groupbyvalue = 'village'
        fieldstoaggregate = 'humidity'
        datamin, datamax = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
                                           field='humidity')
        return Graphs.weather(datamin, datamax)

    elif graphType in ['pie','bar'] and fieldType in ['logins','total farmers']:
        dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
        groupbyvalue = 'created_time'
        fieldstoaggregate = 'count'
        result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
                             field='logins')
        if graphType == 'pie':
            return Graphs.pie(result)
        else:
            return Graphs.bar(result)

也许还有一种更好的重构方法,但这取决于您有更多(很多)要测试的案例还是只有很少的案例。

EDIT1 :固定的total farmers字符串

EDIT2 :基于有关许多路径的其他注释/问题,添加了另一个可能有效的结构。

免责声明:我是Python的新手,并且此代码尚未经过测试,但是总体思路是将问题的无限制部分合并到一个位置(在本例中为Dictionary),以便您拥有一个这部分的真理之源。

@api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
    # Open your db connection
    dbconnection = dbconnector.configuration('farmautomation')
    # Get your chart data based on selection
    chart_args = get_aggregate_data(fieldType, dbconnection)
    # Try to get a chart with that data
    chart = get_chart(graphType, chart_args)

    if chart != None:
      return chart
    else:
      # Throw an error, return None - your callable
      pass


class AggregationSettings:
  def __init__(self, df_name='', group_by='',
       fields_to_agg='', over_field=''):
    self.df_name = df_name
    self.group_by = group_by
    self.fields_to_agg = fields_to_agg
    self.over_field = over_field

# This dictionary is what will grow as you add routes
DATAFRAME_TRANSLATE = {
  "weather details":AggregationSettings("weather_details","village","humidity","humidity"),
  "logins":AggregationSettings("logins_time","created_time","count","logins"),
  "total farmers":AggregationSettings("logins_time","created_time","count","logins")
}

def get_aggregate_data(fieldType, db_connection):
  agg_setting = DATAFRAME_TRANSLATE.get(fieldType, None)
  if agg_setting == None:
    # not in the dict
    raise ValueError('The specified fieldType is not valid')

  df_val = agg_setting.df_name + '_dataFrame'
  # NOTE: I'm not familiar with pandas (which I think this is), but I 
  # suspect there is a way for you to get your return value passing the
  # name, not the class explicitly.  If not, there are ways around that too
  dataframe_name = DataFrame_Conversion.get_by_name(df_val, db_connection)
  return Groupby.groupby(dataframe_name, agg_setting.group_by,
                        agg_setting.fields_to_agg, agg_setting.over_field)

def get_chart(graphType, chart_args):
  # I expect the number of charts is small(ish) and bounded,
  # so just use if/else hex
  if graphType == 'pie':
    return Graphs.pie(chart_args)
  elif graphType == 'bar':
    return Graphs.bar(chart_args)
  else:
    # handle other cases as needed...
    pass

  raise ValueError('The specified graphType is not valid')

相关问题