📄 np_data.py
字号:
def check_eval(self, fn): vars = [] digits = [] self.filter = 0 for e in self.melist: #fn = fn.replace(e, '') exp = '%s.*?\(.*?\)' % (e) fn = re.sub(exp, '', fn) for e in self.elist: fn = fn.replace(e, '') for e in self.complist: if fn.count(e): self.filter = 1 fn = fn.replace(e, '') for c in fn: if c == 'y': self.filter = 1 if not c.isdigit(): vars.append(c) else: digits.append(c) possvars = ['a', 'b', 'c', 'm', 'n', 'x', 'y'] usevars = vars[:] for c in possvars: while c in vars: vars.remove(c) fn = fn.replace(c, '') for d in digits: fn = fn.replace(d, '') # if there's anything left it's an error if vars: return self.error('Unknown variable or constant \'%s\'' % (vars[0])) if fn: return self.error('Don\'t understand \'%s\' in function definition' % (fn)) # light up any constant entry fields and report for const in ['a', 'b', 'c', 'm', 'n']: if const in usevars: ce = self.show_const(const) if ce.get() == '': return self.error('Need value for const %s' % (const)) self.consts[const][4] = self.EVAL(ce.get(), 'Can\'t evaluate const %s' % (const), None, None, None, None, None, None, None, None) if self.consts[const][4] == None: return self.consts[const][4] else: self.hide_const(const) return 1 # success return ############################################################################## # # Build a Python list comprehension from the filter specified # def build_fn(self, fn): if not self.filter: return fn def repc(mo): #print mo.groups() return mo.group(0).replace(',', '$') # # Need to split filter specifiers on commas, but some math funs with # multiple args contain commas in arglist - find these and substitute # '$' for the moment # for f in self.marg_elist: exp = '%s.*?\(.*?(,).*?\)' % (f) fn = re.sub(exp, repc, fn) #print 'mod fn', fn # separate spec. from conditional clause i = fn.find('if') if i > 0: # both spec and conditional f1 = fn[:i] f2 = fn[i:] elif i == 0: # conditional only - add in spec f1 = 'x,y' f2 = fn else: # no conditional f1 = fn f2 = '' #print 'if split', f1, ',', f2 # replace 'x'/'y' references with data point x/y indices f1 = f1.replace('x', 'd[0]') f1 = f1.replace('y', 'd[1]') f2 = f2.replace('x', 'd[0]') f2 = f2.replace('y', 'd[1]') # what's the form of the spec ff = f1.split(',') #print 'f1 split', ff, len(ff) if len(ff) == 1: # single spec - assume applies to yvals f1 = '[d[0], %s]' % (f1) elif len(ff[0]) == 0: # no x spec f1 = '[d[0], %s]' % (ff[1]) elif len(ff[1]) == 0: # no y spec f1 = '[%s, d[1]]' % ff[0] else: # both x, y specs f1 = '[%s, %s]' % (ff[0], ff[1]) fn = '[%s for d in data %s]' % (f1, f2) # restore commas fn = fn.replace('$', ',') #print fn return fn ############################################################################## # # Trial evaluation of fn to see if parser can handle it # def EVAL(self, e, ss, x, y, a, b, c, m, n, data): try: v = eval(e) except ValueError, s: return self.error(ss + s.args[0]) except NameError, s: return self.error(s = ss + s[0]) except SyntaxError, s: return self.error(ss + '- syntax error:' + '\''+ s[1][-1] + '\'') return v ############################################################################## def fn_ok(self, fn): fn = fn[1:-1] fn = fn.replace('for d in data', '') fn = fn.replace('d[0]', 'x') fn = fn.replace('d[1]', 'y') fn = fn.replace('[', '(') fn = fn.replace(']', ')') self.inform('Apply %s ?' % (fn)) self.fn_checked = 1 ############################################################################## def ok(self, event=None): if not self.check_eval(self.fn_entry.get()): return x = 3.4785724 y = 0.394726 a = self.consts['a'][4] b = self.consts['b'][4] c = self.consts['c'][4] m = self.consts['m'][4] n = self.consts['n'][4] data = [[1,1], [2,2]] vals = [] for e, s in self.entries: #print e,s if e != self.fn_entry: val = self.EVAL(e.get(), s, x, y, a, b, c, m, n, data) else: val = self.EVAL(self.build_fn(e.get()), s, x, y, a, b, c, m, n, data) if val == None: return vals.append(val) x0, x1, inc = vals[:3] fn = self.build_fn(self.fn_entry.get()) if inc == 0: self.error('zero xinc') return if self.filter and not self.fn_checked: self.fn_ok(fn) return try: self.make_data(fn, x0, x1, inc, a, b, c, m, n) except DataError, s: self.error(s) return self.cancel() ############################################################################## def cancel(self, event=None): self.plot.canvasses[-1].canv.focus_set() self.destroy() ############################################################################## def get_path_suff(self): def sbc(sp): thing = sp.group(2) newthing = thing for c in ['a', 'b', 'c', 'm', 'n']: newthing = newthing.replace(c, c.upper()) #news = sp.group(1).replace(thing, newthing) return sp.group(1).replace(thing, newthing) s = self.fn_entry.get() #avoid PATH confusion s = s.replace('/', 'DIV') # subst const vals contslist = self.melist + self.complist clist = [e for e in contslist if 'a' in e or 'b' in e or 'c' in e or 'm' in e or 'n' in e] #print clist for e in clist: exp = '(.*?(%s).*?)' % (e) s = re.sub(exp, sbc, s) s = s.replace('a', self.constaentry.get()) s = s.replace('b', self.constbentry.get()) s = s.replace('c', self.constcentry.get()) s = s.replace('m', self.constmentry.get()) s = s.replace('n', self.constnentry.get()) s = s.replace('A', 'a') s = s.replace('B', 'b') s = s.replace('C', 'c') s = s.replace('M', 'm') s = s.replace('N', 'n') return s ############################################################################## def make_data(self, fn, x0, x1, inc, a, b, c, m, n): # print fn, x0, x1, inc sets = [] if not self.filter: newd = [] inc = fabs(inc) if x0 > x1: x0, x1 = x1, x0 x = x0 try: while x <= x1: newd.append([x, eval(fn)]) x += inc except OverflowError: self.errlabel.configure(text='Overflow during evaluation', fg='red') self.okb.configure(state=DISABLED, fg='grey56') return path_suff = self.get_path_suff() try: sets.append(DataSet(newd, DATA_TS, path_suff, None, fields=['X', 'Y'], is_filter=0)) except EmptyDataSetError: raise DataError, 'Function plots no data' else: topseti = self.plot.topset.get() for s in self.plot.sets: #if s.is_filter or s.hidden[-1]: if s.indx != topseti: continue data = s.data #print data try: newd = eval(fn) except OverflowError: self.error('Overflow during evaluation') return path_suff = self.get_path_suff() try: sets.append(DataSet(newd, DATA_TS, s.path+path_suff, None, fields=['X', 'Y'], is_filter=1)) except EmptyDataSetError: #raise DataError, 'Function plots no data' self.error('Function plots no data') return self.newdata.append((sets, (self.filter, x0, x1, inc, a, b, c, m, n, self.fn_entry.get()))) self.master.focus_set() ############################################################################################################################################################## Class to edit data point values#############################################################################################################################################################class Dedit(Toplevel): def __init__(self, master, pts, newpts): self.master = master self.pts = pts self.newpts = newpts self.entries = [] Toplevel.__init__(self, self.master) self.transient(self.master) self.title('Edit data') self.configure(bg='grey') body = Frame(self, bg='grey') self.initial_focus = self.body(body) body.pack(padx=5, pady=5) body.configure(bg='grey') self.grab_set() if not self.initial_focus: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) ypos = self.master.winfo_rooty()/2 #self.geometry("+%d+%d" % (master.winfo_rootx(),ypos)) self.initial_focus.focus_set() self.wait_window(self) ############################################################################## def body(self, master): Label(master, text='', bg='grey').grid(row=0, column=0) row = 1 for indx, ent in self.pts: Label(master, text='Index %d' % indx, bg='grey').grid(row=row, column=0, sticky=W) f = BetterEntry(master) f.configure(bg='white', width=100) f.grid(row=row, column=2) f.insert(0, ent) self.entries.append((indx, f)) row += 1 self.errlabel = Label(master, text='', bg='grey', fg='red') self.errlabel.grid(row=row, column=0, sticky=W, columnspan=2) row += 1 # OK/Cancel buttons self.okb = Button(master, text=' OK ', bg='grey', command = self.ok) self.okb.grid(row=row, column=0) self.cancb = Button(master, text='Cancel', bg='grey', command=self.cancel).grid(row=row, column=1) ############################################################################## def ok(self, event=None): for indx in range(len(self.entries)): i, f = self.entries[indx] newent = f.get() i1, ent = self.pts[indx] if i != i1 or len(newent.split()) != len(ent.split()): self.errlabel.configure(text='Data fields wrong - index %d' % (i1)) return for fld in newent.split(): try: val = float(fld) except: self.errlabel.configure(text='Can\'t evaluate value - index %d' % (i1)) return self.newpts.append((i, newent)) self.cancel() ############################################################################## def cancel(self, event=None): self.destroy() ############################################################################################################################################################class Nowt: passdef quit(): sys.exit(0)def handle_sigint(n, f): print 'SIGINT' #handle_sigint_def(n, f) sys.exit(0)def main(): # print 'main' testroot = Tk() r = Nowt() r.root = testroot r.sets = [Nowt()] r.sets[0].data = [[1,1], [1, 2]] r.sets[0].path = 'Data' r.fnspec = (0, 0.0, 10.0, 1.0, None, None, None, None, None, None) handle_sigint_def = signal(SIGINT, handle_sigint) d = [] AddFun(r, d) testroot.mainloop() for v in d[0][0]: print v.data ############################################################################### Call main when run as scriptif __name__ == '__main__': main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -