[Tutor] Is there a way to store and later use comparison operators (<, <=, =, >=, >) ?

Marc Tompkins marc.tompkins at gmail.com
Wed Apr 29 22:46:10 CEST 2015


On Wed, Apr 29, 2015 at 1:10 PM, boB Stepp <robertvstepp at gmail.com> wrote:

> Python 2.4.4, Solaris 10.
>
> I have some functions that I believe I could collapse into a single
> function if I only knew how:
>
> def choose_compare(operator, value0, value1, pass_color, fail_color):
>     """
>     Perform the comparison indicated by operator. Return pass_color if
> true, fail_color if false.
>     """
>     if operator == '<':
>             return less_than(value0, value1, pass_color, fail_color)
>     elif operator == '<=':
>         return less_than_or_equal(value0, value1, pass_color, fail_color)
>     elif operator == '=':
>         return equal(value0, value1, pass_color, fail_color)
>     elif operator == '>':
>         return greater_than(value0, value1, pass_color, fail_color)
>     elif operator == '>=':
>         return greater_than_or_equal(value0, value1, pass_color,
> fail_color)
>     else:
>         print 'WarningMessage = "Invalid comparison operator in
> function, choose_compare(). at Please contact script administrator for
> assistance.";'
>
> def less_than(value0, value1, pass_color, fail_color):
>     """
>     See if value0 is less than value1. If true, return pass_color. If
> false, return fail_color.
>     """
>     if value0 < value1:
>         return pass_color, True
>     else:
>         return fail_color, False
>
> def less_than_or_equal(value0, value1, pass_color, fail_color):
>     """
>     See if value0 is less than or equal to value1. If true, return
> pass_color. If false, return fail_color.
>     """
>     if value0 <= value1:
>         return pass_color, True
>     else:
>         return fail_color, False
>
> ... 3 more functions ...
>
> I won't give the remaining functions for the other comparison
> operators. The string variable, operator, is originally populated from
> a data file, which tells what type of comparison needs to be made. The
> last two functions I gave (and the ones I omitted giving) all follow
> the same exact pattern. I know there has to be some way to replace
> these 5 functions with 1, but what experimentation I have done to date
> has not worked.
>
> Also, what about the first function above? I could use 2 dictionaries,
> 1 for calling the 5 functions and one to pass the arguments, but is it
> worth doing this? Or, I would not be surprised if there is a much
> better way! ~(:>))
>
> Thanks!
>

Here's what I came up with:

def choose_compare(operator, value0, value1, pass_color, fail_color):
    comps = {"=":"==", "<":"<", ">":">", "<=":"<=", ">=":">="}
    if operator in comps.keys():
        operator = comps[operator]
        if eval("{} {} {}".format(value0, operator, value1)):
            return pass_color, True
        else:
            return fail_color, False
    else:
        print('WarningMessage')

I would ordinarily avoid eval() like the plague, but I think that this
sanitizes the input pretty effectively.  I had to make comps a dict instead
of a list because (in your example, anyway) you're using a single equals
sign to check for equality, which throws a Syntax Error (e.g.  "if 1 = 2"
instead of "if 1 == 2").


More information about the Tutor mailing list