1

Is it possible to parse a string in a if statement as a string? Something like

if "1 > 2":
    print "1 is greater than 2"

But is parsed as

if 1 > 2:
    print "1 is greater than 2"

Is this possible? Is the a program out there that does this?

baranskistad
  • 2,176
  • 1
  • 21
  • 42
  • You could certainly build such a thing. You'd need to describe the full syntax of strings you want to handle, though. You could even evaluate arbitrary Python expressions, but that's generally not a secure way to handle such a thing. – user94559 Aug 15 '16 at 02:23
  • Theoretically yes you could write some code to do this. Why would you need to do this though? Are you getting a lot of input as strings? – Harrison Aug 15 '16 at 02:24
  • @Harrison I'm writing a language based off basic, and instead of writing a script to parse the string, I was wondering if I could just pass a string and convert it somehow. – baranskistad Aug 15 '16 at 02:27
  • @bjskistad That can be done. I'll write up an answer. – Harrison Aug 15 '16 at 02:27
  • The expression `"1 > 2"` also returns `True` in your case. To be noted: as long as it is not `None`, the evaluation returns `True`. To get the intended effect, you must parse and convert them to `int`s/get inputs as `ints`. – Abhishek Balaji R Aug 15 '16 at 02:27
  • @AbhishekBalajiR I want this to be possible with any boolean, not just integers, so that the string would be able to contain strings. Like `if "'string' == 'string'":` – baranskistad Aug 15 '16 at 02:29

2 Answers2

3

That's what eval is for.

if eval("1 > 2"):
    print "1 is greater than 2"

Be careful with eval, though. It will call any function supplied to it. Like os.system('rm -rf /') :/

0x60
  • 3,104
  • 1
  • 15
  • 18
  • 5
    If you use `eval` prepared to take the blame for a catastrophe. – OregonTrail Aug 15 '16 at 02:33
  • Take careful note of [this wonderful article](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html). `eval` is basically impossible to make secure. – Luke Taylor Aug 15 '16 at 02:49
  • @LukeTaylor I understand that parsing user-generated data as python code is very dangerous. But that's exactly what OP asked about. – 0x60 Aug 15 '16 at 02:53
  • Yeah. I was mostly posting that for the benefit of the author, not for you. I'm glad you recognize the fact, though – Luke Taylor Aug 15 '16 at 02:58
  • 1
    perhaps use `ast.literal_eval` instead : http://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval – juanpa.arrivillaga Aug 15 '16 at 03:23
0

If you are only comparing numerical values this approach would be safer in general.

This could also be made to work for non-numerical values.

from operator import gt, ge, lt, le, eq, ne

def compare(expression):
    parts = expression.split()
    if len(parts) != 3:
        raise Exception("Can only call this with 'A comparator B', like 1 > 2")
    a, comp, b = parts
    try:
        a, b = float(a), float(b)
    except:
        raise Exception("Comparison only works for numerical values")
    ops = {">": gt, '<': lt, '>=': ge, '<=': le, '==': eq, '!=': ne}
    if comp not in ops:
        raise Exception("Can only compare with %s" % (", ".join(ops)))
    return ops.get(comp)(a, b)


def run_comp(expression):
    try:
        print("{} -> {}".format(expression, compare(expression)))
    except Exception as e:
        print str(e)

if __name__ == "__main__":
    run_comp("1.0 > 2")
    run_comp("2.0 > 2")
    run_comp("2 >= 2")
    run_comp("2 <= 1")
    run_comp("5 == 5.0")
    run_comp("5 <= 5.0")
    run_comp("5 != 5.0")
    run_comp("7 != 5.0")
    run_comp("pig > orange")
    run_comp("1 ! 2")
    run_comp("1 >")

OUTPUT

1.0 > 2 -> False
2.0 > 2 -> False
2 >= 2 -> True
2 <= 1 -> False
5 == 5.0 -> True
5 <= 5.0 -> True
5 != 5.0 -> False
7 != 5.0 -> True
Comparison only works for numerical values
Can only compare with >=, ==, <=, !=, <, >
Can only call this with 'A comparator B', like 1 > 2
sberry
  • 128,281
  • 18
  • 138
  • 165