Code refactoring
This commit is contained in:
parent
d859399249
commit
20e9beaf69
74
forms.py
74
forms.py
@ -2,18 +2,40 @@
|
||||
|
||||
import wx
|
||||
import wx.gizmos
|
||||
import wx.grid
|
||||
import wx.propgrid as wxpg
|
||||
import wx.lib.plot as wxplot
|
||||
|
||||
ID_TEST = wx.NewId()
|
||||
ID_ADD_MODEL_ROOT = wx.NewId()
|
||||
ID_ADD_MODEL_SELECTED = wx.NewId()
|
||||
ID_DUPLICATE_MODEL = wx.NewId()
|
||||
ID_DUPLICATE_TREE = wx.NewId()
|
||||
ID_DELETE_MODEL = wx.NewId()
|
||||
ID_PROCESS_MODEL = wx.NewId()
|
||||
ID_SHOW_RESULT = wx.NewId()
|
||||
ID_SHOW_PLOT = wx.NewId()
|
||||
|
||||
class TreeListCtrl(wx.gizmos.TreeListCtrl):
|
||||
|
||||
def __iter__(self):
|
||||
return TreeListCtrlIterator(self)
|
||||
|
||||
class TreeListCtrlIterator:
|
||||
def __init__(self, owner):
|
||||
self.owner = owner
|
||||
self.item = self.owner.GetRootItem()
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if not self.item.IsOk():
|
||||
raise StopIteration
|
||||
item = self.item
|
||||
self.item = self.owner.GetNext(self.item)
|
||||
return item
|
||||
|
||||
class MyTreeListCtrl(wx.gizmos.TreeListCtrl):
|
||||
def Refresh(self, erase, rect):
|
||||
wx.gizmos.TreeListCtrl.Refresh(False, rect)
|
||||
|
||||
class MainFrame (wx.Frame):
|
||||
|
||||
@ -31,9 +53,7 @@ class MainFrame (wx.Frame):
|
||||
|
||||
bSizer4 = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.m_user_models = wx.gizmos.TreeListCtrl(self,
|
||||
#self.m_user_models = MyTreeListCtrl(self,
|
||||
#self.m_user_models = wx.TreeCtrl(self,
|
||||
self.m_user_models = TreeListCtrl(self,
|
||||
style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT
|
||||
| wx.TR_EDIT_LABELS | wx.TR_ROW_LINES | wx.TR_MULTIPLE)
|
||||
self.m_user_models.SetMinSize(wx.Size(-1, 200))
|
||||
@ -45,8 +65,7 @@ class MainFrame (wx.Frame):
|
||||
bSizer4.Add(self.m_user_models, 0, wx.ALL|wx.EXPAND, 1)
|
||||
|
||||
# WARNING: wxPython code generation isn't supported for this widget yet.
|
||||
self.m_params = wxpg.PropertyGridManager(self,
|
||||
style = wxpg.PG_TOOLBAR)
|
||||
self.m_params = wxpg.PropertyGridManager(self)
|
||||
self.m_params.AddPage('fp')
|
||||
bSizer4.Add(self.m_params, 1, wx.EXPAND |wx.ALL, 1)
|
||||
|
||||
@ -80,14 +99,18 @@ class MainFrame (wx.Frame):
|
||||
menubar.Append(menu, '&File')
|
||||
|
||||
menu = wx.Menu()
|
||||
menu.Append(ID_TEST, "&Test\tCtrl+T")
|
||||
menu.Append(ID_PROCESS_MODEL, 'Process\tCtrl+R')
|
||||
menu.Append(ID_SHOW_RESULT, 'Show result\tCtrl+S')
|
||||
menu.Append(ID_SHOW_PLOT, 'Show plot\tCtrl+G')
|
||||
menu.AppendSeparator()
|
||||
menu.Append(ID_ADD_MODEL_ROOT, 'Add model to root')
|
||||
menu.Append(ID_ADD_MODEL_SELECTED, 'Append model to selected')
|
||||
#menu.AppendSeparator()
|
||||
menu.Append(ID_DUPLICATE_MODEL, "&Duplicate\tCtrl+D")
|
||||
menu.Append(ID_DELETE_MODEL, 'Delete')
|
||||
menu.AppendSeparator()
|
||||
menu.Append(ID_PROCESS_MODEL, 'Process\tCtrl+R')
|
||||
menu.Append(ID_DUPLICATE_MODEL, "&Duplicate\tCtrl+D")
|
||||
menu.Append(ID_DUPLICATE_TREE, "&Duplicate with subitems\tCtrl+Shift+D")
|
||||
menu.Append(ID_DELETE_MODEL, 'Delete\tCtrl+E')
|
||||
menu.AppendSeparator()
|
||||
menu.Append(ID_TEST, "&Test\tCtrl+T")
|
||||
menubar.Append(menu, '&Model')
|
||||
|
||||
menu = wx.Menu()
|
||||
@ -104,3 +127,28 @@ class MainFrame (wx.Frame):
|
||||
menu.Append(ID_ADD_MODEL_SELECTED, 'Add model to selected')
|
||||
self.m_specs.Bind(wx.EVT_CONTEXT_MENU,
|
||||
lambda x: self.m_specs.PopupMenu(menu))
|
||||
|
||||
class ResultFrame(wx.Frame):
|
||||
def __init__(self, parent, title):
|
||||
wx.Frame.__init__ (self, parent, -1, title, size = wx.Size(600, 400))
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.scalar = wxpg.PropertyGridManager(self)
|
||||
self.scalar.AddPage('fp')
|
||||
|
||||
self.table = wx.grid.Grid(self)
|
||||
self.table.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
|
||||
|
||||
sizer.Add(self.scalar, 0, wx.EXPAND |wx.ALL, 1)
|
||||
sizer.Add(self.table, 1, wx.EXPAND |wx.ALL, 1)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.Layout()
|
||||
self.Centre(wx.BOTH)
|
||||
|
||||
class PlotFrame(wx.Frame):
|
||||
def __init__(self, parent, title):
|
||||
wx.Frame.__init__ (self, parent, -1, title, size = wx.Size(600, 400))
|
||||
|
||||
self.plot = wxplot.PlotCanvas(self)
|
239
opal.py
239
opal.py
@ -22,6 +22,25 @@ import os
|
||||
import threading
|
||||
import re
|
||||
|
||||
class ModelData:
|
||||
def __init__(self, server, model, parent_data = None):
|
||||
# если мы создаем новый набор данных из описания модели
|
||||
if isinstance(model, task.DataDescription):
|
||||
self.mdef = task.DataDefinition(model, parent_data)
|
||||
self.jid = server.CreateJob() if model.IsExecutable() else None
|
||||
# если мы создаем набор данных из другого набора данных
|
||||
elif isinstance(model, ModelData):
|
||||
self.mdef = model.mdef.Copy()
|
||||
self.jid = server.CreateJob() if model.jid != None else None
|
||||
else:
|
||||
self.mdef = None
|
||||
self.jid = None
|
||||
|
||||
self.res = None
|
||||
|
||||
class ItemError(Exception):
|
||||
pass
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Главная форма
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -47,21 +66,28 @@ class MainFrame(forms.MainFrame):
|
||||
self.m_params.Bind(wxpg.EVT_PG_CHANGED,
|
||||
self.OnParamChanged)
|
||||
|
||||
self.Bind(wx.EVT_MENU, self.OnTest, id = forms.ID_TEST)
|
||||
self.Bind(wx.EVT_MENU, self.OnTest,
|
||||
id = forms.ID_TEST)
|
||||
self.Bind(wx.EVT_MENU, self.OnAddModelToRoot,
|
||||
id = forms.ID_ADD_MODEL_ROOT)
|
||||
self.Bind(wx.EVT_MENU, self.OnAddModelToSelected,
|
||||
id = forms.ID_ADD_MODEL_SELECTED)
|
||||
self.Bind(wx.EVT_MENU, self.OnDuplicate,
|
||||
id = forms.ID_DUPLICATE_MODEL)
|
||||
self.Bind(wx.EVT_MENU, self.OnDuplicateTree,
|
||||
id = forms.ID_DUPLICATE_TREE)
|
||||
self.Bind(wx.EVT_MENU, self.OnDeleteModel,
|
||||
id = forms.ID_DELETE_MODEL)
|
||||
self.Bind(wx.EVT_MENU, self.OnModelProcess,
|
||||
id = forms.ID_PROCESS_MODEL)
|
||||
self.Bind(wx.EVT_MENU, self.OnShowResult,
|
||||
id = forms.ID_SHOW_RESULT)
|
||||
|
||||
self.Bind(wx.EVT_CLOSE, self.OnClose)
|
||||
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
||||
|
||||
ov = threading.Thread(target = self.Overseer)
|
||||
ov.daemon = 1
|
||||
ov.daemon = True
|
||||
ov.start()
|
||||
|
||||
self.NewProject(model)
|
||||
@ -72,6 +98,12 @@ class MainFrame(forms.MainFrame):
|
||||
self.Destroy()
|
||||
|
||||
def Overseer(self):
|
||||
"""
|
||||
Функция-надсмотрщик, которая периодически проверяет состояние
|
||||
всех пользовательских моделей, в зависимости от этого изменяет
|
||||
состояние окружения, выводит информацию, подгружает результаты
|
||||
выполнения работ и др.
|
||||
"""
|
||||
|
||||
def StateToStr(state):
|
||||
if state == server.JOB_READY:
|
||||
@ -90,25 +122,26 @@ class MainFrame(forms.MainFrame):
|
||||
cycle_count = 0
|
||||
while True:
|
||||
wx.MutexGuiEnter()
|
||||
print 'cycle{:-8}'.format(cycle_count)
|
||||
#print 'cycle{:-8}'.format(cycle_count)
|
||||
cycle_count += 1
|
||||
item = um.GetRootItem()
|
||||
while item.IsOk():
|
||||
# просматриваем всю иерархию моделей
|
||||
for item in um:
|
||||
data = um.GetPyData(item)
|
||||
if data:
|
||||
jid = data[1]
|
||||
if not data:
|
||||
continue
|
||||
jid = data.jid
|
||||
if jid != None and self.server.IsJobChanged(jid):
|
||||
state = self.server.GetJobState(jid)
|
||||
um.SetItemText(item, StateToStr(state[0]), 1)
|
||||
p = state[1]
|
||||
p = 'Unknown' if p < 0 else '{:%}'.format(p)
|
||||
state, percent, comment = self.server.GetJobState(jid)
|
||||
um.SetItemText(item, StateToStr(state), 1)
|
||||
p = 'Unknown' if percent < 0 else '{:%}'.format(percent)
|
||||
um.SetItemText(item, p, 2)
|
||||
um.SetItemText(item, state[2], 3)
|
||||
print jid, state
|
||||
um.SetItemText(item, comment, 3)
|
||||
print jid, (state, percent, comment)
|
||||
if state == server.JOB_COMPLETED:
|
||||
data.res = self.server.GetJobResult(jid)
|
||||
|
||||
item = um.GetNext(item)
|
||||
wx.MutexGuiLeave()
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.1)
|
||||
except Exception, e:
|
||||
print 'Error in overseer: ', e
|
||||
|
||||
@ -118,12 +151,10 @@ class MainFrame(forms.MainFrame):
|
||||
Возвращает True, если имя уникально, иначе False.
|
||||
"""
|
||||
um = self.m_user_models
|
||||
item = um.GetRootItem()
|
||||
while item.IsOk():
|
||||
for item in um:
|
||||
item_name = um.GetItemText(item)
|
||||
if item_name == name:
|
||||
return False
|
||||
item = um.GetNext(item)
|
||||
return True
|
||||
|
||||
def GenerateName(self, name):
|
||||
@ -131,7 +162,7 @@ class MainFrame(forms.MainFrame):
|
||||
На основе переданного имени генерирует новое имя модели таким образом,
|
||||
чтобы оно осталось уникальным в рамках существующей иерархии моделей.
|
||||
"""
|
||||
m = re.match(r'(.+)\s+\d*', name)
|
||||
m = re.match(r'^(.+)\s+\d*$', name, re.UNICODE)
|
||||
basename = m.group(1) if m else name
|
||||
while True:
|
||||
name = basename + ' ' + str(self.name_id)
|
||||
@ -172,13 +203,17 @@ class MainFrame(forms.MainFrame):
|
||||
um = self.m_user_models
|
||||
item = um.GetRootItem()
|
||||
defparent = None
|
||||
for m in ms:
|
||||
root = None
|
||||
for i, m in enumerate(ms):
|
||||
name = self.GenerateName(m.GetTitle())
|
||||
item = um.AppendItem(item, name)
|
||||
data = task.DataDefinition(m, defparent)
|
||||
defparent = data
|
||||
jid = self.server.CreateJob() if m.IsExecutable() else None
|
||||
um.SetPyData(item, [data, jid])
|
||||
if not i:
|
||||
root = item
|
||||
data = ModelData(self.server, m, defparent)
|
||||
defparent = data.mdef
|
||||
um.SetPyData(item, data)
|
||||
if root:
|
||||
um.Expand(root)
|
||||
|
||||
def NewProject(self, model):
|
||||
# 1. загрузить спецификации модели
|
||||
@ -194,7 +229,7 @@ class MainFrame(forms.MainFrame):
|
||||
|
||||
return True # Project(model)
|
||||
|
||||
def SelectUserModel(self, model_def, jid):
|
||||
def SelectUserModel(self, model_def):
|
||||
|
||||
def SelectProperty(param_type):
|
||||
"""
|
||||
@ -220,23 +255,42 @@ class MainFrame(forms.MainFrame):
|
||||
msg = model_def.PackParams()
|
||||
pg = self.m_params
|
||||
pg.ClearPage(0)
|
||||
#pg.Append(wxpg.PropertyCategory('Model properties'))
|
||||
for k, v in model_def.params.iteritems():
|
||||
p = model_def.DD[k]
|
||||
title = p.GetTitle() or k
|
||||
prop = SelectProperty(p.GetType())
|
||||
pid = pg.Append(prop(title, value = v))
|
||||
pg.SetPropertyClientData(pid, k)
|
||||
pg.SetPropertyHelpString(pid, p.GetComment())
|
||||
for label, value in model_def.params.iteritems():
|
||||
param = model_def.DD[label]
|
||||
title = param.GetTitle() or label
|
||||
prop = SelectProperty(param.GetType())
|
||||
pid = pg.Append(prop(title, value = value))
|
||||
pg.SetPropertyClientData(pid, label)
|
||||
pg.SetPropertyHelpString(pid, param.GetComment())
|
||||
|
||||
self.SetStatusText(model_def.PackParams(), 0)
|
||||
|
||||
def GetSelectedItem(self, source):
|
||||
item = source.GetSelection()
|
||||
if not item.IsOk():
|
||||
raise ItemError('Invalid item')
|
||||
return item
|
||||
|
||||
def GetSelectedData(self, source):
|
||||
item = self.GetSelectedItem(source)
|
||||
data = source.GetPyData(item)
|
||||
if not data:
|
||||
raise ItemError('Empty data')
|
||||
return data
|
||||
|
||||
def GetSelectedItemData(self, source):
|
||||
item = self.GetSelectedItem(source)
|
||||
data = source.GetPyData(item)
|
||||
if not data:
|
||||
raise ItemError('Empty data')
|
||||
return (item, data)
|
||||
|
||||
pd = model_def.PackParams()
|
||||
self.SetStatusText(pd, 0)
|
||||
|
||||
def OnModelActivated(self, event):
|
||||
item = event.GetItem()
|
||||
data = self.m_user_models.GetPyData(item)
|
||||
if data:
|
||||
self.SelectUserModel(data[0], data[1])
|
||||
self.SelectUserModel(data.mdef)
|
||||
|
||||
def OnParamChanging(self, event):
|
||||
#value = event.GetValue()
|
||||
@ -251,69 +305,112 @@ class MainFrame(forms.MainFrame):
|
||||
return
|
||||
value = prop.GetValue()
|
||||
param = prop.GetClientData()
|
||||
um = self.m_user_models
|
||||
id = um.GetSelection()
|
||||
data, jid = um.GetItemPyData(id)
|
||||
data[param] = value
|
||||
data = self.GetSelectedData(self.m_user_models)
|
||||
data.mdef[param] = value
|
||||
|
||||
def OnTest(self, event):
|
||||
um = self.m_user_models
|
||||
|
||||
def OnAddModelToRoot(self, event):
|
||||
item = self.m_specs.GetSelection()
|
||||
if not item.IsOk():
|
||||
return
|
||||
print self.m_specs.GetItemText(item)
|
||||
model = self.m_specs.GetPyData(item)
|
||||
model = self.GetSelectedData(self.m_specs)
|
||||
self.AddModelToRoot(model)
|
||||
|
||||
def OnAddModelToSelected(self, event):
|
||||
"""
|
||||
Добавляет пользовательскую спецификацию к указанной модели или в уже
|
||||
существующую иерархию спецификаций.
|
||||
Добавляет пользовательскую спецификацию к указанной модели
|
||||
"""
|
||||
item = self.m_specs.GetSelection()
|
||||
if not item.IsOk():
|
||||
return
|
||||
model = self.m_specs.GetPyData(item)
|
||||
|
||||
# получаем модель, которая будет добавлена к пользовательским
|
||||
model = self.GetSelectedData(self.m_specs)
|
||||
# получаем пользовательскую модель, к которой хотим присоединить новую
|
||||
item, data = self.GetSelectedItemData(self.m_user_models)
|
||||
pmdef = data.mdef
|
||||
um = self.m_user_models
|
||||
item = um.GetSelection()
|
||||
if not item.IsOk():
|
||||
return
|
||||
|
||||
pmdef, _ = um.GetPyData(item)
|
||||
|
||||
# если новая модель может быть присоединена...
|
||||
if pmdef.DD == model.parent:
|
||||
modeldef = task.DataDefinition(model, pmdef)
|
||||
name = self.GenerateName(model.GetTitle())
|
||||
item = um.AppendItem(item, name)
|
||||
jid = self.server.CreateJob() if model.IsExecutable() else None
|
||||
um.SetPyData(item, [modeldef, jid])
|
||||
child = um.AppendItem(item, name)
|
||||
new_data = ModelData(self.server, model, pmdef)
|
||||
um.SetPyData(child, new_data)
|
||||
um.Expand(item)
|
||||
else:
|
||||
wx.MessageBox('It\'s impossible to append model', 'Error')
|
||||
|
||||
def OnDuplicate(self, event):
|
||||
um = self.m_user_models
|
||||
id = um.GetSelection()
|
||||
title = um.GetItemText(id)
|
||||
parent = um.GetItemParent(id)
|
||||
md, jid = um.GetItemPyData(id)
|
||||
"""
|
||||
Обработчик события "дублирование модели"
|
||||
|
||||
Когда модель дублируется, ее параметры копируются в новую модель,
|
||||
при неоходимости выделяется слот для работ на сервере.
|
||||
Результаты модели-оригинала не копируются.
|
||||
"""
|
||||
um = self.m_user_models
|
||||
item, data = self.GetSelectedItemData(self.m_user_models)
|
||||
title = um.GetItemText(item)
|
||||
parent = um.GetItemParent(item)
|
||||
child = um.AppendItem(parent, self.GenerateName(title))
|
||||
jid = self.server.CreateJob()
|
||||
um.SetPyData(child, [md.Copy(), jid])
|
||||
new_data = ModelData(self.server, data)
|
||||
um.SetPyData(child, new_data)
|
||||
self.SetStatusText('Copy for "{}" created'.format(title), 0)
|
||||
|
||||
def OnDuplicateTree(self, event):
|
||||
pass
|
||||
|
||||
def OnDeleteModel(self, event):
|
||||
item, data = self.GetSelectedItemData(self.m_user_models)
|
||||
self.server.DeleteJob(data.jid)
|
||||
self.m_user_models.Delete(item)
|
||||
|
||||
def OnModelProcess(self, event):
|
||||
um = self.m_user_models
|
||||
for i in um.GetSelections():
|
||||
data, jid = um.GetItemPyData(i)
|
||||
self.server.LaunchJob(jid, data)
|
||||
data = um.GetItemPyData(i)
|
||||
self.server.LaunchJob(data.jid, data.mdef)
|
||||
|
||||
def OnShowResult(self, event):
|
||||
item, data = self.GetSelectedItemData(self.m_user_models)
|
||||
title = self.m_user_models.GetItemText(item)
|
||||
title = 'Result for model "{}"'.format(title)
|
||||
rframe = ResultFrame(self, title, data.res)
|
||||
rframe.Show()
|
||||
|
||||
def OnIdle(self, event):
|
||||
pass
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Форма с результатами выполнения работы
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class ResultFrame(forms.ResultFrame):
|
||||
def __init__(self, parent, title, result):
|
||||
forms.ResultFrame.__init__(self, parent, title)
|
||||
self.result = result
|
||||
self.UpdateResults()
|
||||
|
||||
def UpdateResults(self):
|
||||
self.scalar.ClearPage(0)
|
||||
self.table.ClearGrid()
|
||||
if self.result:
|
||||
table = self.result.get('table', [])
|
||||
if table and len(table):
|
||||
cols = len(table[0])
|
||||
rows = len(table) - 1
|
||||
self.table.CreateGrid(rows, cols)
|
||||
#
|
||||
for i, col in enumerate(table[0]):
|
||||
label = "{} ({})".format(col[0], col[1])
|
||||
self.table.SetColLabelValue(i, label)
|
||||
#
|
||||
for ri, row in enumerate(table[1:]):
|
||||
for ci, value in enumerate(row):
|
||||
self.table.SetCellValue(ri, ci, str(value))
|
||||
|
||||
self.table.AutoSize()
|
||||
|
||||
data = self.result.get('data', {})
|
||||
pg = self.scalar
|
||||
for label, value in data.iteritems():
|
||||
pid = pg.Append(wxpg.StringProperty(label, value = str(value)))
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Приложение
|
||||
#-----------------------------------------------------------------------------
|
||||
|
12
server.py
12
server.py
@ -42,7 +42,7 @@ class LocalServer:
|
||||
self.workers = workers # количество потоков выполнения
|
||||
self.tasks_meta = {} # идентификаор задачи
|
||||
self.models = [] # список моделей
|
||||
self.next_job_id = 0 # очередной идентификатор работы
|
||||
self.next_job_id = 1 # очередной идентификатор работы
|
||||
self.jobs = {} # очередб работ
|
||||
self.log = None #
|
||||
self.running = False #
|
||||
@ -168,6 +168,12 @@ class LocalServer:
|
||||
if job != None:
|
||||
job.Stop()
|
||||
|
||||
def DeleteJob(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
job.Stop()
|
||||
del self.jobs[jid]
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def Start(self):
|
||||
@ -343,13 +349,13 @@ def main():
|
||||
md['d'] = 10
|
||||
md['r'] = 3.14
|
||||
|
||||
slots = [ s.CreateJob() for i in xrange(5) ]
|
||||
slots = [ s.CreateJob() for i in xrange(1) ]
|
||||
for jid in slots:
|
||||
md['n'] = random.randint(20, 30)
|
||||
print jid, md['n']
|
||||
s.LaunchJob(jid, md)
|
||||
|
||||
time.sleep(30)
|
||||
time.sleep(5)
|
||||
|
||||
for jid in slots:
|
||||
pprint(s.GetJobResult(jid))
|
||||
|
21
task.py
21
task.py
@ -32,17 +32,12 @@ class Parameter:
|
||||
def GetDefault(self):
|
||||
return self.data.get('default')
|
||||
|
||||
def GetTestExpresion(self):
|
||||
def GetTestExpression(self):
|
||||
return self.data.get('test')
|
||||
|
||||
def Test(self, value):
|
||||
return True
|
||||
|
||||
#def __repr__(self):
|
||||
# return "'{}'".format(
|
||||
# self.GetType()
|
||||
# )
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class DataDescription:
|
||||
@ -88,6 +83,9 @@ class DataDescription:
|
||||
def __getitem__(self, label):
|
||||
return self.pdata.get(label)
|
||||
|
||||
def type(self):
|
||||
return 'data-def'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class DataDefinition:
|
||||
@ -124,3 +122,14 @@ class DataDefinition:
|
||||
package.reverse()
|
||||
return json.dumps(package)
|
||||
|
||||
def type(self):
|
||||
return 'data-def'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class ResultData:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def GetColumns(self):
|
||||
pass
|
@ -7,7 +7,7 @@
|
||||
|
||||
"sintaylor": {
|
||||
|
||||
"title": "Simple model",
|
||||
"title": "Sin Taylor",
|
||||
"author": "Anton Vakhrushev",
|
||||
"date": "2012-03-08",
|
||||
|
||||
@ -40,11 +40,11 @@
|
||||
"spec": {
|
||||
|
||||
"left": {
|
||||
"title": "Left"
|
||||
"title": "Left rectangles"
|
||||
},
|
||||
|
||||
"right": {
|
||||
"title": "Right"
|
||||
"title": "Right rectangles"
|
||||
},
|
||||
|
||||
"trapezium": {
|
||||
|
@ -39,13 +39,20 @@ def error(msg):
|
||||
"comment": msg
|
||||
})
|
||||
|
||||
def result(r):
|
||||
def result(s, t):
|
||||
return json.dumps({
|
||||
"answer": "result",
|
||||
"result": {
|
||||
"table": [[ {"x": "double"}, {"y": "double"} ]] + r
|
||||
}
|
||||
})
|
||||
"data": s,
|
||||
"table": t
|
||||
}})
|
||||
|
||||
def serie(n, d, h, l = 0):
|
||||
for i in xrange(n):
|
||||
y = sin_taylor(l, d)
|
||||
yield (l, y)
|
||||
l += h
|
||||
time.sleep(0.01)
|
||||
|
||||
def main():
|
||||
|
||||
@ -62,26 +69,55 @@ def main():
|
||||
textdata = raw_input()
|
||||
data = json.loads(textdata)
|
||||
|
||||
if not len(data) or data[-1]['label'] != 'sintaylor':
|
||||
write(error('Unknown model'))
|
||||
sys.exit(1)
|
||||
|
||||
params = data[0]['params']
|
||||
l = 0 # левая граница
|
||||
r = params['r'] # правая граница
|
||||
n = params['n'] # количество шагов
|
||||
d = params['d'] # количество членов в разложении Тейлора
|
||||
h = float(r - l) / n # шаг сетки по х
|
||||
h = r / n
|
||||
res = [] # таблица резултатов
|
||||
|
||||
while l <= r:
|
||||
y = sin_taylor(l, d)
|
||||
res.append([l, y])
|
||||
write(answer(l / r, data[-1]['label']))
|
||||
l += h
|
||||
time.sleep(0.1)
|
||||
label = data[-1]['label']
|
||||
sum = 0
|
||||
|
||||
if label == 'sintaylor':
|
||||
for x, y in serie(n, d, h):
|
||||
res.append([x, y])
|
||||
write(answer(x / r, label))
|
||||
write(result({},
|
||||
[[ ['x', 'double'], [ 'y', 'double' ] ]] + res))
|
||||
|
||||
elif label == 'left':
|
||||
for x, y in serie(n-1, d, h):
|
||||
s = y * h
|
||||
res.append([x, y, s])
|
||||
write(answer(x / r, label))
|
||||
sum += s
|
||||
write(result(
|
||||
{ 'sum': sum },
|
||||
[[ ['x', 'double'], [ 'y', 'double' ], [ 's', 'double' ] ]] + res))
|
||||
|
||||
elif label == 'right':
|
||||
for x, y in serie(n-1, d, h, h):
|
||||
s = y * h
|
||||
res.append([x, y, s])
|
||||
write(answer(x / r, label))
|
||||
sum += s
|
||||
write(result(
|
||||
{ 'sum': sum },
|
||||
[[ ['x', 'double'], [ 'y', 'double' ], [ 's', 'double' ] ]] + res))
|
||||
|
||||
elif label == 'trapezium':
|
||||
prev = 0
|
||||
for x, y in serie(n + 1, d, h):
|
||||
s = 0.5 * (y + prev) * h
|
||||
res.append([x, y, s])
|
||||
write(answer(x / r, label))
|
||||
sum += s
|
||||
prev = y
|
||||
write(result(
|
||||
{ 'sum': sum },
|
||||
[[ ['x', 'double'], [ 'y', 'double' ], [ 's', 'double' ] ]] + res))
|
||||
|
||||
write(result(res))
|
||||
|
||||
except Exception, e:
|
||||
write(error('Fatal error: ' + str(e)))
|
||||
|
Loading…
Reference in New Issue
Block a user