Data wrapper for result object
This commit is contained in:
parent
20e9beaf69
commit
6aefad8ab1
28
forms.py
28
forms.py
@ -47,7 +47,7 @@ class MainFrame (wx.Frame):
|
||||
bSizer3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.m_specs = wx.TreeCtrl(self, style = wx.TR_DEFAULT_STYLE)
|
||||
self.m_specs.SetMinSize(wx.Size(150,-1))
|
||||
self.m_specs.SetMinSize(wx.Size(200,-1))
|
||||
|
||||
bSizer3.Add(self.m_specs, 0, wx.ALL|wx.EXPAND, 1)
|
||||
|
||||
@ -56,25 +56,32 @@ class MainFrame (wx.Frame):
|
||||
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))
|
||||
self.m_user_models.SetMinSize(wx.Size(-1, 300))
|
||||
self.m_user_models.AddColumn("Model name")
|
||||
self.m_user_models.AddColumn("Status")
|
||||
self.m_user_models.AddColumn("Progress")
|
||||
self.m_user_models.AddColumn("Comment")
|
||||
|
||||
bSizer4.Add(self.m_user_models, 0, wx.ALL|wx.EXPAND, 1)
|
||||
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)
|
||||
self.m_params.AddPage('fp')
|
||||
bSizer4.Add(self.m_params, 1, wx.EXPAND |wx.ALL, 1)
|
||||
bSizer4.Add(self.m_params, 1, wx.EXPAND | wx.ALL, 1)
|
||||
|
||||
bSizer3.Add(bSizer4, 1, wx.EXPAND, 5)
|
||||
|
||||
self.m_job_list = wx.ListBox(self)#, style = wx.LC_LIST)
|
||||
self.m_job_list.SetMinSize(wx.Size(200,-1))
|
||||
bSizer5 = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
bSizer3.Add(self.m_job_list, 0, wx.ALL|wx.EXPAND, 1)
|
||||
self.m_quick_result = wxpg.PropertyGridManager(self)
|
||||
self.m_quick_result.AddPage('fp')
|
||||
self.m_quick_result.SetMinSize(wx.Size(200, -1))
|
||||
bSizer5.Add(self.m_quick_result, 1, wx.EXPAND | wx.ALL, 1)
|
||||
|
||||
self.m_plots = wx.TreeCtrl(self, style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
|
||||
bSizer5.Add(self.m_plots, 1, wx.EXPAND | wx.ALL, 1)
|
||||
|
||||
bSizer3.Add(bSizer5, 0, wx.ALL | wx.EXPAND, 1)
|
||||
|
||||
sbar = wx.StatusBar(self)
|
||||
self.SetStatusBar(sbar)
|
||||
@ -130,7 +137,8 @@ class MainFrame (wx.Frame):
|
||||
|
||||
class ResultFrame(wx.Frame):
|
||||
def __init__(self, parent, title):
|
||||
wx.Frame.__init__ (self, parent, -1, title, size = wx.Size(600, 400))
|
||||
wx.Frame.__init__ (self, parent, -1, title, size = wx.Size(500, 500),
|
||||
style = wx.DEFAULT_FRAME_STYLE)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
@ -140,8 +148,8 @@ class ResultFrame(wx.Frame):
|
||||
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)
|
||||
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()
|
||||
|
66
opal.py
66
opal.py
@ -65,6 +65,11 @@ class MainFrame(forms.MainFrame):
|
||||
self.OnParamChanging)
|
||||
self.m_params.Bind(wxpg.EVT_PG_CHANGED,
|
||||
self.OnParamChanged)
|
||||
self.m_specs.Bind(wx.EVT_TREE_ITEM_ACTIVATED,
|
||||
self.OnAddModelToSelected)
|
||||
self.m_user_models.Bind(wx.EVT_TREE_ITEM_ACTIVATED,
|
||||
self.OnModelProcess)
|
||||
|
||||
|
||||
self.Bind(wx.EVT_MENU, self.OnTest,
|
||||
id = forms.ID_TEST)
|
||||
@ -136,9 +141,15 @@ class MainFrame(forms.MainFrame):
|
||||
p = 'Unknown' if percent < 0 else '{:%}'.format(percent)
|
||||
um.SetItemText(item, p, 2)
|
||||
um.SetItemText(item, comment, 3)
|
||||
print jid, (state, percent, comment)
|
||||
print 'JID', jid, (state, percent, comment)
|
||||
# завершающие действия по окончанию выполнения работы
|
||||
if state == server.JOB_COMPLETED:
|
||||
# получаем результаты выполнения
|
||||
data.res = self.server.GetJobResult(jid)
|
||||
# если завершившаяся задача в данный момент выделена
|
||||
# то сразу же показываем этот результат
|
||||
if um.IsSelected(item):
|
||||
self.ShowQuickResult(data.res)
|
||||
|
||||
wx.MutexGuiLeave()
|
||||
time.sleep(0.1)
|
||||
@ -238,13 +249,13 @@ class MainFrame(forms.MainFrame):
|
||||
Смотри руководство пользователя для того, чтобы получить полную
|
||||
информацию о всех типах данных, используемых в Opal.
|
||||
"""
|
||||
if param_type == 'bool':
|
||||
if param_type == 'bool' or param_type == 'boolean':
|
||||
return wxpg.BoolProperty
|
||||
elif param_type == 'int':
|
||||
return wxpg.IntProperty
|
||||
elif param_type == 'float' or param_type == 'double':
|
||||
return wxpg.FloatProperty
|
||||
elif param_type == 'string':
|
||||
elif param_type == 'str' or param_type == 'string':
|
||||
return wxpg.StringProperty
|
||||
elif param_type == 'list':
|
||||
return wxpg.ArrayStringProperty
|
||||
@ -257,7 +268,7 @@ class MainFrame(forms.MainFrame):
|
||||
pg.ClearPage(0)
|
||||
for label, value in model_def.params.iteritems():
|
||||
param = model_def.DD[label]
|
||||
title = param.GetTitle() or label
|
||||
title = param.GetTitle()
|
||||
prop = SelectProperty(param.GetType())
|
||||
pid = pg.Append(prop(title, value = value))
|
||||
pg.SetPropertyClientData(pid, label)
|
||||
@ -265,6 +276,15 @@ class MainFrame(forms.MainFrame):
|
||||
|
||||
self.SetStatusText(model_def.PackParams(), 0)
|
||||
|
||||
def ShowQuickResult(self, result):
|
||||
if not result:
|
||||
return
|
||||
pg = self.m_quick_result
|
||||
pg.ClearPage(0)
|
||||
for label, param in result.data.iteritems():
|
||||
pg.Append(wxpg.StringProperty(label, value = str(param.GetValue())))
|
||||
pg.SetSplitterLeft()
|
||||
|
||||
def GetSelectedItem(self, source):
|
||||
item = source.GetSelection()
|
||||
if not item.IsOk():
|
||||
@ -291,6 +311,7 @@ class MainFrame(forms.MainFrame):
|
||||
data = self.m_user_models.GetPyData(item)
|
||||
if data:
|
||||
self.SelectUserModel(data.mdef)
|
||||
self.ShowQuickResult(data.res)
|
||||
|
||||
def OnParamChanging(self, event):
|
||||
#value = event.GetValue()
|
||||
@ -389,27 +410,26 @@ class ResultFrame(forms.ResultFrame):
|
||||
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))
|
||||
if not self.result:
|
||||
return
|
||||
|
||||
self.table.AutoSize()
|
||||
cols = len(self.result.columns)
|
||||
rows = len(self.result.rows)
|
||||
self.table.CreateGrid(rows, cols)
|
||||
#
|
||||
for i, col in enumerate(self.result.columns):
|
||||
label = "{} ({} {})".format(col.GetTitle(), col.GetType(), col.GetLabel())
|
||||
self.table.SetColLabelValue(i, label)
|
||||
#
|
||||
for i, row in enumerate(self.result.rows):
|
||||
for j, value in enumerate(row):
|
||||
self.table.SetCellValue(i, j, str(value))
|
||||
|
||||
data = self.result.get('data', {})
|
||||
pg = self.scalar
|
||||
for label, value in data.iteritems():
|
||||
pid = pg.Append(wxpg.StringProperty(label, value = str(value)))
|
||||
self.table.AutoSize()
|
||||
|
||||
pg = self.scalar
|
||||
for label, param in self.result.data.iteritems():
|
||||
pg.Append(wxpg.StringProperty(label, value = str(param.GetValue())))
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Приложение
|
||||
|
@ -246,7 +246,7 @@ class Worker(threading.Thread):
|
||||
# в ответе пришел результат вычислений
|
||||
# помещаем в секцию результата
|
||||
elif ans == 'result':
|
||||
job.result = data['result']
|
||||
job.result = task.ResultData(data['result'])
|
||||
# произошла ошибка
|
||||
elif ans == 'error':
|
||||
WriteToLog('Error! ' + msg)
|
||||
|
58
task.py
58
task.py
@ -17,14 +17,18 @@ import json
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Parameter:
|
||||
def __init__(self, data):
|
||||
def __init__(self, label, data):
|
||||
self.data = data
|
||||
self.data['label'] = label
|
||||
|
||||
def GetLabel(self):
|
||||
return self.data['label']
|
||||
|
||||
def GetType(self):
|
||||
return self.data['type']
|
||||
|
||||
def GetTitle(self):
|
||||
return self.data.get('title', '')
|
||||
return self.data.get('title', self.GetLabel())
|
||||
|
||||
def GetComment(self):
|
||||
return self.data.get('comment', '')
|
||||
@ -38,6 +42,34 @@ class Parameter:
|
||||
def Test(self, value):
|
||||
return True
|
||||
|
||||
class Value(Parameter):
|
||||
def __init__(self, label, value):
|
||||
if isinstance(value, dict):
|
||||
self.data = value
|
||||
else:
|
||||
self.data = {
|
||||
'value': value,
|
||||
'type': value.__class__.__name__
|
||||
}
|
||||
self.data['label'] = label
|
||||
|
||||
def GetType(self):
|
||||
return self.data.get('type', 'unknown')
|
||||
|
||||
def GetValue(self):
|
||||
return self.data['value']
|
||||
|
||||
class Column(Parameter):
|
||||
def __init__(self, colvalues):
|
||||
self.data = {}
|
||||
# следующие два поля должны обязательно присутствовать
|
||||
self.data['label'] = colvalues[0]
|
||||
self.data['type'] = colvalues[1]
|
||||
try:
|
||||
self.data['title'] = colvalues[2]
|
||||
except:
|
||||
pass
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class DataDescription:
|
||||
@ -51,7 +83,7 @@ class DataDescription:
|
||||
self.pdata = self.data.get('params', {})
|
||||
# заменяем текстовое описание на объект-параметр
|
||||
for label in self.pdata:
|
||||
par = Parameter(self.pdata[label])
|
||||
par = Parameter(label, self.pdata[label])
|
||||
self.pdata[label] = par
|
||||
|
||||
self.specs = []
|
||||
@ -129,7 +161,23 @@ class DataDefinition:
|
||||
|
||||
class ResultData:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.data = {}
|
||||
for key, value in data.get('data', {}).iteritems():
|
||||
self.data[key] = Value(key, value)
|
||||
|
||||
table = data.get('table', [])
|
||||
self.head = {}
|
||||
self.table = []
|
||||
if table:
|
||||
self.head = [ Column(item) for item in table[0] ]
|
||||
self.table = table[1:]
|
||||
|
||||
def GetColumns(self):
|
||||
pass
|
||||
return self.head
|
||||
|
||||
columns = property(GetColumns)
|
||||
|
||||
def GetRows(self):
|
||||
return self.table
|
||||
|
||||
rows = property(GetRows)
|
||||
|
@ -11,13 +11,13 @@
|
||||
"author": "Anton Vakhrushev",
|
||||
"date": "2012-03-08",
|
||||
|
||||
"exec": true,
|
||||
"exec": false,
|
||||
|
||||
"params": {
|
||||
|
||||
"r": {
|
||||
"type": "float",
|
||||
"default": 6.28,
|
||||
"default": 6.283185307,
|
||||
"title": "Right edge",
|
||||
"comment": "Right edge"
|
||||
},
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
# Тестовое приложение для проекта Opal
|
||||
# Вычисление значений синуса по формулам Тейлора
|
||||
# Вычисляет значения для указанного диапазона с заданной точностью
|
||||
# и нужным количеством шагов
|
||||
# Вычисляет значения для указанного диапазона
|
||||
# с заданной точностью и нужным количеством шагов
|
||||
|
||||
import sys
|
||||
import json
|
||||
@ -43,12 +43,12 @@ def result(s, t):
|
||||
return json.dumps({
|
||||
"answer": "result",
|
||||
"result": {
|
||||
"data": s,
|
||||
"data": s,
|
||||
"table": t
|
||||
}})
|
||||
|
||||
def serie(n, d, h, l = 0):
|
||||
for i in xrange(n):
|
||||
for i in xrange(n + 1):
|
||||
y = sin_taylor(l, d)
|
||||
yield (l, y)
|
||||
l += h
|
||||
@ -87,17 +87,17 @@ def main():
|
||||
[[ ['x', 'double'], [ 'y', 'double' ] ]] + res))
|
||||
|
||||
elif label == 'left':
|
||||
for x, y in serie(n-1, d, h):
|
||||
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))
|
||||
[[ ['x', 'double'], [ 'y', 'double' ], [ 's', 'double', 'Delta sum' ] ]] + res))
|
||||
|
||||
elif label == 'right':
|
||||
for x, y in serie(n-1, d, h, h):
|
||||
for x, y in serie(n - 1, d, h, h):
|
||||
s = y * h
|
||||
res.append([x, y, s])
|
||||
write(answer(x / r, label))
|
||||
@ -108,7 +108,7 @@ def main():
|
||||
|
||||
elif label == 'trapezium':
|
||||
prev = 0
|
||||
for x, y in serie(n + 1, d, h):
|
||||
for x, y in serie(n, d, h):
|
||||
s = 0.5 * (y + prev) * h
|
||||
res.append([x, y, s])
|
||||
write(answer(x / r, label))
|
||||
|
Loading…
Reference in New Issue
Block a user