Generating string expression from data for filter I have a set of parameters, and I need to get the expression:

So I got this parameters:

filters = {
  "type": 'human',
  "age": [{'min': 4, 'max': 8}, {'min': 15, 'max': 30}],
  "size": [{'min': 60}],
}


And my goal is to obtain this string from it:

type == 'human' and ((age &gt;= 4 and age &lt;= 8) or (age &gt;= 15 and age &lt;= 30)) and size &gt;= 60


But when I am writing my script to do so, I keep having small details that bother me like the position of the 'or' or 'and' or the parenthesis.
And i think it really hit the readability here.
So I thought maybe there was a better way, but searching Google only shows me the inverse of what I want, that is transforming expression to expression tree.

I am trying to generate a string expression from a set of data (for a filter).

So if someone have a better idea, (or algo, or ...)

Here is my script:

#!/usr/bin/python3

# goal : type == 'human' and ((age &gt;= 4 and age &lt;= 8) or (age &gt;= 15 and age &lt;= 30)) and size &gt;= 60
filters = {
  "type": 'human',
  "age": [{'min': 4, 'max': 8}, {'min': 15, 'max': 30}],
  "size": [{'min': 60}],
}

s = ''
type_first = True
for key, value in filters.items():
  if type_first:
    type_first = False
    s += "("
  else:
    s += " and ("
  value_first = True
  if(isinstance(value, str)):
    s += "%s == %s" % (key, value)
  elif(isinstance(value, list)):
    if value_first:
      value_first = False
    else:
      s += " and"
    dict_first = True
    for dict_ in value:
      if dict_first:
        dict_first = False
        s += "("
      else:
        s += " or ("  
      if dict_.get('min', 0):
        s += "%s &gt;= %s" % (key, dict_['min'])
        if dict_.get('max', 0):
          s += " and "
      if dict_.get('max', 0):
        s += "%s &lt;= %s" % (key, dict_['max'])
      s += ")"
  s += ")"

print(s)
Please note that I am not actually reviewing your code, but guiding you towards hopefully better design, so that you can fix the issues yourself
In that same vein, the code snippets I am including do not contain a full solution, but only the hints towards it.




These kinds of transformations are very easy if you start to decompose them.

For example, you have two different rules for dealing with string data type and list data type, so let's create two different entities to deal with them.

(Here I chose functions as top-level entities, you can create classes too)

def convert_string(key, value):
    return f"{key} == '{value}'"   # I am assuming you want value in quotes


Similarly, define one for lists. (Hint: You should define one entity for dict and list function should only call and compose dict function)

How do you choose which entity to call? Simple, call another entity. 

def choose_function(key, value):
    # Your logic here
    # returns func


And finally, a composing function, which is also your main function.

def convert(params):
    str_list = []
    for key, value in params.items():
        str_list.append(choose_func(key, value)(key, value))
    return ' and '.join(str_list)}




Why it would be better than your solution?


It is much easier to test. Your problem statement is pretty much easy, but these kinds of problems could become very big with lots of complex rules in the long run, where unit testability gives you the confidence to make changes
You divide the problem statement into individual sub-pieces and another sub-problem deal with how to merge those solutions. That would eliminate lots of your _first variables. It also makes it easier in the long run.
Code readability