Search code examples
pythonfunctional-programmingcalculus

seek a better design suggestion for a trial-and-error mechanism in python?


See below data matrix get from sensors, just INT numbers, nothing specical.

    A   B   C   D   E   F   G   H   I   J   K
1   25  0   25  66  41  47  40  12  69  76  1
2   17  23  73  97  99  39  84  26  0   44  45
3   34  15  55  4   77  2   96  92  22  18  71
4   85  4   71  99  66  42  28  41  27  39  75
5   65  27  28  95  82  56  23  44  97  42  38
…                                           
10  95  13  4   10  50  78  4   52  51  86  20
11  71  12  32  9   2   41  41  23  31  70  
12  54  31  68  78  55  19  56  99  67  34  94
13  47  68  79  66  10  23  67  42  16  11  96
14  25  12  88  45  71  87  53  21  96  34  41

The horizontal A to K is the sensor name, and vertical is the data from sensor by the timer manner.

Now I want to analysis those data with trial-and-error methods, I defined some concepts to explain what I want:

o source

source is all the raw data I get

o entry

a entry is a set of all A to K sensor, take the vertical 1st row for example: the entry is

25  0   25  66  41  47  40  12  69  76  1

o rules

a rule is a "suppose" function with assert value return, so far just "true" or "false". For example, I suppose the sensor A, E and F value will never be same in one enrty, if one entry with A=E=F, it will tigger violation and this rule function will return false.

o range:

a range is function for selecting vertical entry, for example, the first 5 entries

Then, the basic idea is:

o   source + range = subsource(s)
o   subsource + rules = valiation(s)

The finally I want to get a list may looks like this:

rangeID ruleID violation
1   1   Y
2   1   N
3   1   Y
1   2   N
2   2   N
3   2   Y
1   3   N
2   3   Y
3   3   Y

But the problem is the rule and range I defined here will getting very complicated soon if you looks deeper, they have too much possible combinations, take "A=E=F" for example, one can define "B=E=F","C=E=F","C>F" ......

So soon I need a rule/range generator which may accept those "core parameters" such as "A=E=F" as input parameter even using regex string later. That is too complicated just defeated me, leave alone I may need to persistence rules unique ID, data storage problem, rules self nest combination problem ......

So my questions are:

  1. Anyone knows if there's some module/soft fit for this kind of trial-and-error calculation or the rules defination I want?

  2. Anyone can share me a better rules/range design I described?

Thanks for any hints.

Rgs,

KC


Solution

  • If I understand what you're asking correctly, I probably wouldn't even venture down the Numbpy path as I don't think given your description that it's really required. Here's a sample implementation of how I might go about solving the specific issue that you presented:

    l = [\
            {'a':25, 'b':0, 'c':25, 'd':66, 'e':41, 'f':47, 'g':40, 'h':12, 'i':69, 'j':76, 'k':1},\
            {'a':25, 'b':0, 'c':25, 'd':66, 'e':41, 'f':47, 'g':40, 'h':12, 'i':69, 'j':76, 'k':1}\
    ]
    r = ['a=g=i', 'a=b', 'a=c']
    res = []
    
    # test all given rules
    for n in range(0, len(r)):
            # i'm assuming equality here - you'd have to change this to accept other operators if needed
            c = r[n].split('=')
            vals = []
            # build up a list of values given our current rule
            for e in c:
                    vals.append(l[0][e])
            # using len(set(v)) gives us the number of distinct values
            res.append({'rangeID': 0, 'ruleID':n, 'violation':'Y' if len(set(vals)) == 1 else 'N'})
    
    print res
    

    Output:

    [{'violation': 'N', 'ruleID': 0, 'rangeID': 0}, {'violation': 'N', 'ruleID': 1, 'rangeID': 0}, {'violation': 'Y', 'ruleID': 2, 'rangeID': 0}]

    http://ideone.com/zbTZr

    There are a few assumptions made here (such as equality being the only operator in use in your rules) and some functionality left out (such as parsing your input to the list of dicts I used, but I'm hopeful that you can figure that out on your own.

    Of course, there could be a Numpy-based solution that's simpler than this that I'm just not thinking of at the moment (it's late and I'm going to bed now ;)), but hopefully this helps you out anyway.

    Edit:

    Woops, missed something else (forgot to add it in prior to posting) - I only test the first element in l (the given range).. You'd just want to stick that in another for loop rather than using that hard-coded 0 index.