-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmathparser.py
124 lines (102 loc) · 3.27 KB
/
mathparser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python
"""
Reads a file parsing the commands returns the result of the equation
Usage is mathparser.py [-h] file
"""
import os
import sys
import math
import getopt
class OperatorBase(object):
def load(self, value):
self.value = int(value)
def apply(self,value):
return value
class SingleOperator(OperatorBase):
def valid(self):
return True
class SquareRootOperator(SingleOperator):
def apply(self,value):
return math.sqrt(value)
class IntegerSquareRootOperator(SquareRootOperator):
#Newtons method
def apply(self,value):
x = value
y = (x + 1) // 2
while y < x:
x = y
y = (x + value // x) // 2
return x
class TwoComponentOperator(OperatorBase):
def valid(self):
return self.value is not None and isinstance(self.value, (int) )
class AddOperator(TwoComponentOperator):
def apply(self,value):
return value + self.value
class MultiplyOperator(TwoComponentOperator):
def apply(self,value):
return value * self.value
class DivisionOperator(TwoComponentOperator):
def apply(self,value):
return value // self.value
def valid(self):
return self.value != 0
class SubtractionOperator(TwoComponentOperator):
def apply(self,value):
return value - self.value
class MathOperatorFactory:
def parse(self,line):
values = line.split()
length = len(values)
#Cant you splat in python?
if length < 1:
print >>sys.stderr, "Empty row found in input file"
return None
if values[0] not in self.operators:
print >>sys.stderr, "{} is not in list of recognized commands {}".format(values[0], self.operators.keys())
return None
operator = self.operators[values[0]]()
if length >= 2 :
operator.load(values[1])
if not operator.valid():
print >>sys.stderr, "command {} value {} is not a valid combination".format(values[0],values[1])
return None
return operator
operators = {
"ADD" : AddOperator,
"MUL" : MultiplyOperator,
"DIV" : DivisionOperator,
"SUB" : SubtractionOperator,
"SQR" : IntegerSquareRootOperator
}
def readcommands(file):
with open(file, "r") as fileHandler:
factory = MathOperatorFactory();
return filter(None,(factory.parse(line) for line in fileHandler))
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
#Reading up guide lines for main according to Russo
def main(argv=None):
if argv is None:
argv = sys.argv
try:
scans = 5
delay = 0
try:
opts, args = getopt.getopt(argv[1:], "h", ["help"])
except getopt.error, msg:
raise Usage(msg)
for o, a in opts:
if o in ("-h", "--help"):
print __doc__
sys.exit(0)
commands = readcommands(args[0])
result = reduce(lambda total, current : current.apply(total), commands, 0)
print result
except Usage, err:
print >>sys.stderr, err.msg
print >>sys.stderr, "for help use --help"
return 2
if __name__ == "__main__":
sys.exit(main())