~yacinechaouche/+junk/BZR

« back to all changes in this revision

Viewing changes to PROG/LECOMPTEESTBON/calculator_r3.py

  • Committer: yacinechaouche at yahoo
  • Date: 2015-01-14 22:23:03 UTC
  • Revision ID: yacinechaouche@yahoo.com-20150114222303-6gbtqqxii717vyka
Ajout de CODE et PROD. Il faudra ensuite ajouter ce qu'il y avait dan TMP

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
## Yassine chaouche
 
2
## yacinechaouche@yahoo.com
 
3
## http://ychaouche.wikispot.org
 
4
## Jun 16 2012 - 02:42
 
5
 
 
6
 
 
7
"""
 
8
This is the engine that calculates the expressions generated by the generator (generator.py).
 
9
Its main function is evaluate, which takes an expression s and returns its value.
 
10
It may return None when any part of the expression divides by 0.
 
11
Expressions must be surrounded by parenthesis because the evaluate function does only operations with
 
12
two operands. An expression surrounded by parenthesis is considered one operand.
 
13
So you may call evaluate("(5+3) + (3+((9+10)/2))") but not evaluate("(10-3)/2+(8-3)")
 
14
The function is not defensive at all, it does not check the validity of its input.
 
15
"""
 
16
 
 
17
 
 
18
def evaluate(s):
 
19
    """
 
20
    evaluate("6+(3*2)") => 12
 
21
    where : first = 6; second = + and third = (3*2).
 
22
 
 
23
    symmetrically, evaluate("(8*2) - 10") => 6
 
24
    where first = (8*2); second = -; and third = 10.
 
25
 
 
26
    first and third are either numbers or expression between parentheses
 
27
    second is always an operator, otherwise the application may crash (not tested)
 
28
    """
 
29
    first,second,third = tokenize(s)
 
30
    if is_number(first):
 
31
        #print "%s is a number -> put in var1" % first
 
32
        left = int(first)
 
33
    else:
 
34
        #print "%s is not a number -> eval" % first
 
35
        # if it's not a number, evalute it.
 
36
        left = evaluate(first[1:-1])
 
37
        # if division by zero or if the division returned a fraction,
 
38
        # consider the whole expression wrong.
 
39
        if left == None:
 
40
            return
 
41
 
 
42
    if is_operand(second):
 
43
        #print "%s is an operation -> put in operation" % second
 
44
        operation = second
 
45
        
 
46
    else:
 
47
        print "%s is not an operation, skipping (this will crash)" % second
 
48
        return
 
49
        
 
50
    if is_number(third):
 
51
        #print "%s is a number -> put in var2" % third
 
52
        right = int(third)
 
53
    else:
 
54
        #print "%s is not a number -> eval" % third
 
55
        right = evaluate(third[1:-1])
 
56
        if right == None:
 
57
            return
 
58
 
 
59
    # now that we have our two operands and our operation, we can calculate the result.
 
60
    result = do_op(left,operation,right)
 
61
    #print "we return the value of %s %s %s which is %s" % (left,operation,right,result)
 
62
    return result
 
63
 
 
64
def tokenize(s):
 
65
    #print "tokenize",s
 
66
    if s[0] not in ('(',')') :
 
67
        first  = read_number(s)        
 
68
        second = s[len(first)]
 
69
        third  = s[len(first)+1:]
 
70
    else:
 
71
        n   = 0
 
72
        pos = 0
 
73
        for x in s:
 
74
            if x == '(':
 
75
                n += 1
 
76
            if x == ')':
 
77
                n -= 1
 
78
            if n == 0:
 
79
                break
 
80
            pos += 1
 
81
        first  = s[0:pos+1]
 
82
        second = s[pos+1]
 
83
        third   = s[pos+2:]
 
84
    #print "tokenization : %s, %s , %s" % (first,second,third)
 
85
    return first,second,third
 
86
 
 
87
def read_number(s):
 
88
    c = ""
 
89
    while s[0].isdigit():
 
90
        c += s[0]
 
91
        s = s[1:]
 
92
    return c
 
93
 
 
94
def do_op(left,operation,right):
 
95
 
 
96
    # we may have None in one of those,
 
97
    # for example when dividing by 0
 
98
    
 
99
    if not (left and right) :
 
100
        return
 
101
    
 
102
    if operation == "+" :
 
103
        return left + right
 
104
    
 
105
    elif operation == "*" :
 
106
        return left * right
 
107
    
 
108
    elif operation == "/" :
 
109
        if right != 0 : 
 
110
            result =  left / right
 
111
            # we may only allow net divisions
 
112
            if not left % right :
 
113
                return result
 
114
    
 
115
    elif operation == "-" :
 
116
        return left - right
 
117
    
 
118
def is_number(s):    
 
119
    return s.isdigit()
 
120
 
 
121
def is_operand(s):
 
122
    return s in ["+","/","*","-"]
 
123
 
 
124
 
 
125
def main():
 
126
    import sys
 
127
    print evaluate(sys.argv[1])
 
128
 
 
129
if __name__ == "__main__":
 
130
    main()