Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic way to specify comparison operators?

(EDIT: I'm getting lots of answers about implementation (which I appreciate), but I am more concerned here with just the specification syntax. Users of this plugin (i.e. Python/Django developers - not website users) will need to specify conditions, in a syntax that I am inventing. So to rephrase the question...when writing a model or form class...which of the below syntaxes would the archetypal Python/Django developer prefer to specify the conditional display logic for form fields?)

I am looking for some advice for the most pythonic (readable, straightforward, etc) way to specify comparison operators for later use in comparisons (to be executed via javascript). Something like (this is just one example that comes to mind - there are lots of other possible formats):

comparisons = (('a', '>', 'b'), ('b', '==', 'c'))

which would later be evaluated in Javascript.

The context is that I am working on a Django app (ultimately for distribution as a plugin) which will require users to write comparisons in whatever syntax I choose (hence the question about making it pythonic). The comparisons will reference form fields, and will ultimately be converted to javascript conditional form display. I suppose an example is in order:

class MyModel(models.Model):
    yes_or_no = models.SomeField...choices are yes or no...
    why = models.SomeField...text, but only relevant if yes_or_no == yes...
    elaborate_even_more = models.SomeField...more text, just here so we can have multiple conditions

    #here i am inventing some syntax...open to suggestions!!
    why.show_if = ('yes_or_no','==','yes')
    elaborate_even_more.show_if = (('yes_or_no','==','yes'),('why','is not','None'))

    #(EDIT - help me choose a syntax that is Pythonic and...Djangonic...and that makes your fingers happy to type!)
    #another alternative...
    conditions = {'why': ('yes_or_no','==','yes'), 
                  'elaborate_even_more': (('yes_or_no','==','yes'),('why','is not','None'))
                  }

    #or another alternative...
    """Showe the field whiche hath the name *why* only under that circumstance 
    in whiche the field whiche hath the name *yes_or_no* hath the value *yes*, 
    in strictest equality."""
    etc...

(hand waving...convert MyModel to ModelForm using model_form_factory()...gather all "field.show_if" conditions in a dictionary and attach to ModelForm as MyModelForm.conditions or something...)

Now in a chunk of javascript in a template, each condition in MyModelForm.condtions will become a function that listens for a change in the value of a field, and shows or hides another field in response. Basically (in pseudo-Javascript/Jquery):

when yes_or_no changes...
    if (yes_or_no.value == 'yes'){
        $('#div that contains *why* field).show(); }
    else {
        $('#div that contains *why* field).hide(); }

The goal here is to let the end user specify the conditional display logic in a straightforward, pythonic way inside the model definition (there may be an option to specify the conditions on the form class instead, which I think is more "Djangonic"(??), but for my use case they need to go in the models). Then my plugin behind the scenes turns that into Javascript in a template. So you get conditional form display without having to write any Javascript. Since this will be in the hands of python/django developers, I am looking for suggestions for the most native, comfortable way to specify those conditions.

like image 604
andy Avatar asked Aug 28 '13 16:08

andy


1 Answers

Here's an idea:

import operator as op

a, b, c = 10, 7, 7

def f1():
    print 10

def f2():
    print 20

comparisons = ((a, op.gt, b, f1), (b, op.eq, c, f2))

for lhs, oper, rhs, f in comparisons:
    if oper(lhs, rhs):
        f()

=> 10
=> 20

With an appropriate representation you can dynamically specify comparison operators and their corresponding actions - implemented as functions. Take a look at the operator module to see the available operators.

like image 79
Óscar López Avatar answered Oct 01 '22 10:10

Óscar López