-
Notifications
You must be signed in to change notification settings - Fork 1
/
equation.py
199 lines (162 loc) · 5.63 KB
/
equation.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui, uic
def big(txt):
return "<font size=+3 face=Serif>%s</font>" % txt
class Eq(object):
def __init__(self, expr):
self.expr = expr
def update(self, val):
print val
def eval(self, layout):
self.formato(layout, self)
def __neg__(self):
return Eq(('-', self))
def __add__(self, other):
return Eq(('+', self, other))
def __radd__(self, other):
return Eq(('+', other, self))
def __sub__(self, other):
return Eq(('-', self, other))
def __rsub__(self, other):
return Eq(('-', other, self))
def __mul__(self, other):
return Eq(('*', self, other))
def __rmul__(self, other):
return Eq(('*', other, self))
def __div__(self, other):
return Eq(('/', self, other))
def __rdiv__(self, other):
return Eq(('/', other, self))
def __pow__(self, other):
return Eq(('^', self, other))
def __xor__(self, other):
return Eq(('^', self, other))
def __eq__(self, other):
return Eq(('=', self, other))
def __call__(self, *others):
return Eq(['func', self] + list(others) )
## ============================
@staticmethod
def frac(layout, a, b):
vboxlayout = QtGui.QVBoxLayout()
vboxlayout.setMargin(0)
vboxlayout.setSpacing(0)
num = QtGui.QHBoxLayout()
num.setMargin(0)
num.setSpacing(0)
Eq.formato(num, a)
vboxlayout.addLayout(num)
line = QtGui.QFrame()
line.setFrameShape(QtGui.QFrame.HLine)
line.setFrameShadow(QtGui.QFrame.Sunken)
vboxlayout.addWidget(line)
denom = QtGui.QHBoxLayout()
denom.setMargin(0)
denom.setSpacing(0)
Eq.formato(denom, b)
vboxlayout.addLayout(denom)
layout.addLayout(vboxlayout)
@staticmethod
def pow(layout, x, n):
Eq.formato(layout, x)
layout.addWidget(QtGui.QLabel(big("<sup>%s</sup>" % n)))
@staticmethod
def plus(layout, *expr):
op = expr[0]
for a in expr[1:-1]:
Eq.formato(layout, a)
layout.addWidget(QtGui.QLabel(big(" "+op+"")))
else:
Eq.formato(layout, expr[-1])
@staticmethod
def mult(layout, a, b):
Eq.formato(layout, a)
layout.addWidget(QtGui.QLabel(" "))
Eq.formato(layout, b)
@staticmethod
def func(layout, args):
fn = args[0].expr
layout.addWidget(QtGui.QLabel(big(fn + '(')))
for a in args[1:]:
Eq.formato(layout, a)
layout.addWidget(QtGui.QLabel(big(')')))
@staticmethod
def var(layout, expr):
if len(unicode(expr)) == 1 and unicode(expr).isalpha():
expr = '<em>%s</em>' % expr
label = QtGui.QLabel(big(expr))
label.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(label)
@staticmethod
def operacion(layout, ob):
expr = ob.expr[1]
# if len(unicode(expr)) == 1 and unicode(expr).isalpha():
## en general el valor inicial es 0
# num = eval(ob.expr[1].replace(ob.expr[2], "0"))
if not hasattr(ob, "labels"):
ob.labels = []
exprRoja = '<em style="color:red">%s</em>' % ob.expr[1]
label = QtGui.QLabel(big(exprRoja))
label.setAlignment(QtCore.Qt.AlignCenter)
layout.addWidget(label)
ob.labels.append(label)
@staticmethod
def param(layout, ob):
name = ob.expr[1]
## puede haber varias etiquetas asociadas al mismo parámetro
if not hasattr(ob, "labels"):
ob.labels = []
## en general el valor inicial es 0
## hacer esto mas general!
ob.labels.append(QtGui.QLabel(big('<em style="color:red">%s</em>' % name)))
layout.addWidget(ob.labels[-1])
def setParamValue(self, val):
valstr = "%.2f" % val
if valstr == "1.00":
valstr = "1"
elif valstr == "0.00":
valstr = "0"
if self.expr[0] == "par":
for label in self.labels:
label.setText(big('<span style="color:red">%s</span>' % valstr))
elif self.expr[0] == "operacion":
## self.expr == ("operacion", expr, val)
num = eval(self.expr[1].replace(self.expr[2], valstr))
for label in self.labels:
label.setText(big('<span style="color:red">%s</span>' % num))
@staticmethod
def formato(layout, ob):
## ob puede ser de tipo Eq, o número, o cadena
if hasattr(ob, "expr"):
expr = ob.expr
else:
expr = ob
t = type(expr)
if t == tuple or t == list:
head = expr[0]
if t == str or t == unicode or t == int or t == float:
Eq.var(layout, expr)
elif head == "func":
Eq.func(layout, expr[1:])
elif head == "+" or head == "-" or head == "=":
Eq.plus(layout, *expr)
elif head == "^":
Eq.pow(layout, expr[1], expr[2])
elif head == "/":
Eq.frac(layout, expr[1], expr[2])
elif head == "*":
Eq.mult(layout, expr[1], expr[2])
elif head == "par":
Eq.param(layout, ob)
elif head == "operacion":
Eq.operacion(layout, ob)
def defVars(*args):
## no funciona
for a in args:
exec("%s = Eq('%s')" % (a, a))
def createVars(*args):
return map(Eq, *args)
def createVarParam(name):
return Eq(('par', name))
def createOpParam(expr, var):
return Eq(('operacion', expr, var))