not stable! begin to realize save/open
This commit is contained in:
parent
8a93d853af
commit
9e29e5f9c8
4
forms.py
4
forms.py
@ -186,7 +186,7 @@ class MainFrame(wx.Frame):
|
|||||||
menubar.Append(menu, '&Run')
|
menubar.Append(menu, '&Run')
|
||||||
|
|
||||||
menu = wx.Menu()
|
menu = wx.Menu()
|
||||||
menu.Append(ID_SHOW_RESULT, 'Show numbers\tF7')
|
menu.Append(ID_SHOW_RESULT, 'Show report\tF7')
|
||||||
menu.AppendSeparator()
|
menu.AppendSeparator()
|
||||||
menu.Append(ID_SHOW_PLOT, 'Show plot\tF8')
|
menu.Append(ID_SHOW_PLOT, 'Show plot\tF8')
|
||||||
menu.Append(ID_ADD_PLOT, 'Add plot')
|
menu.Append(ID_ADD_PLOT, 'Add plot')
|
||||||
@ -228,7 +228,7 @@ class MainFrame(wx.Frame):
|
|||||||
tb1.SetToolBitmapSize(wx.Size(16, 16))
|
tb1.SetToolBitmapSize(wx.Size(16, 16))
|
||||||
|
|
||||||
tb1.AddSimpleTool(ID_ADD_MODEL_SELECTED, "model-new", wx.Bitmap('share/model-add.png'),
|
tb1.AddSimpleTool(ID_ADD_MODEL_SELECTED, "model-new", wx.Bitmap('share/model-add.png'),
|
||||||
'Add spacification to selected model')
|
'Add specification to selected model')
|
||||||
tb1.AddSimpleTool(ID_DUPLICATE_MODEL, "model-dup", wx.Bitmap('share/model-dup.png'),
|
tb1.AddSimpleTool(ID_DUPLICATE_MODEL, "model-dup", wx.Bitmap('share/model-dup.png'),
|
||||||
'Duplicate selected model')
|
'Duplicate selected model')
|
||||||
tb1.AddSimpleTool(ID_DUPLICATE_TREE, "model-dup-tree", wx.Bitmap('share/model-dup-tree.png'),
|
tb1.AddSimpleTool(ID_DUPLICATE_TREE, "model-dup-tree", wx.Bitmap('share/model-dup-tree.png'),
|
||||||
|
158
opal.py
158
opal.py
@ -13,14 +13,19 @@
|
|||||||
|
|
||||||
import server
|
import server
|
||||||
import task
|
import task
|
||||||
|
|
||||||
import wx
|
import wx
|
||||||
import wx.propgrid as wxpg
|
|
||||||
import wx.lib.plot as wxplot
|
|
||||||
import forms
|
import forms
|
||||||
|
wxpg = forms.wxpg
|
||||||
|
wxplot = forms.wxplot
|
||||||
|
from wx.lib.embeddedimage import PyEmbeddedImage
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
from wx.lib.embeddedimage import PyEmbeddedImage
|
import json
|
||||||
|
import zlib
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
class ModelData:
|
class ModelData:
|
||||||
def __init__(self, server, model, parent_data = None):
|
def __init__(self, server, model, parent_data = None):
|
||||||
@ -38,9 +43,9 @@ class ModelData:
|
|||||||
|
|
||||||
self.res = None
|
self.res = None
|
||||||
|
|
||||||
LINE_CURVE = 1
|
LINE_CURVE = 1
|
||||||
LINE_MARKER = 2
|
LINE_MARKER = 2
|
||||||
LINE_HISTOGRAM = 3
|
LINE_HISTOGRAM = 3
|
||||||
|
|
||||||
class LineData:
|
class LineData:
|
||||||
"""
|
"""
|
||||||
@ -63,6 +68,10 @@ class LineData:
|
|||||||
self.colour = colour # цвет: если не задан выбирается из списка
|
self.colour = colour # цвет: если не задан выбирается из списка
|
||||||
self.style = style # стиль: если не задан, еспользуется по умолчанию
|
self.style = style # стиль: если не задан, еспользуется по умолчанию
|
||||||
|
|
||||||
|
def GetModelTitle(self):
|
||||||
|
container, item = self.ums_ptr
|
||||||
|
return container.GetItemText(item)
|
||||||
|
|
||||||
def GetTitle(self):
|
def GetTitle(self):
|
||||||
# если есть указатель на компонент с графиками,
|
# если есть указатель на компонент с графиками,
|
||||||
# извлекаем оттуда название
|
# извлекаем оттуда название
|
||||||
@ -98,6 +107,7 @@ class MainFrame(forms.MainFrame):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
forms.MainFrame.__init__(self, None)
|
forms.MainFrame.__init__(self, None)
|
||||||
|
|
||||||
|
self.model = None
|
||||||
self.name_id = 1
|
self.name_id = 1
|
||||||
|
|
||||||
s = server.LocalServer()
|
s = server.LocalServer()
|
||||||
@ -129,6 +139,10 @@ class MainFrame(forms.MainFrame):
|
|||||||
|
|
||||||
self.Bind(wx.EVT_MENU, self.OnNewProject,
|
self.Bind(wx.EVT_MENU, self.OnNewProject,
|
||||||
id = forms.ID_NEW)
|
id = forms.ID_NEW)
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnOpenProject,
|
||||||
|
id = forms.ID_OPEN)
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnSaveProject,
|
||||||
|
id = forms.ID_SAVE)
|
||||||
|
|
||||||
self.Bind(wx.EVT_MENU, self.OnTest,
|
self.Bind(wx.EVT_MENU, self.OnTest,
|
||||||
id = forms.ID_TEST)
|
id = forms.ID_TEST)
|
||||||
@ -283,7 +297,7 @@ class MainFrame(forms.MainFrame):
|
|||||||
"""
|
"""
|
||||||
def DoItem(item, model):
|
def DoItem(item, model):
|
||||||
sp.SetPyData(item, model)
|
sp.SetPyData(item, model)
|
||||||
for spec in model.GetSpecs():
|
for label, spec in model.GetSpecs().iteritems():
|
||||||
child = sp.AppendItem(item, spec.GetTitle())
|
child = sp.AppendItem(item, spec.GetTitle())
|
||||||
DoItem(child, spec)
|
DoItem(child, spec)
|
||||||
|
|
||||||
@ -294,7 +308,7 @@ class MainFrame(forms.MainFrame):
|
|||||||
sp.ExpandAll()
|
sp.ExpandAll()
|
||||||
sp.SortChildren(root)
|
sp.SortChildren(root)
|
||||||
|
|
||||||
def NewProject(self, model):
|
def NewProject(self, model, create_default = True):
|
||||||
"""
|
"""
|
||||||
Начать новый проект:
|
Начать новый проект:
|
||||||
0. Очичтить все компоненты
|
0. Очичтить все компоненты
|
||||||
@ -307,6 +321,8 @@ class MainFrame(forms.MainFrame):
|
|||||||
self.m_params.Clear()
|
self.m_params.Clear()
|
||||||
self.m_quick_result.Clear()
|
self.m_quick_result.Clear()
|
||||||
self.m_plots.DeleteAllItems()
|
self.m_plots.DeleteAllItems()
|
||||||
|
# фиксируем выбранную модель
|
||||||
|
self.model = model
|
||||||
# Строим спецификации
|
# Строим спецификации
|
||||||
self.BuildSpecs(model)
|
self.BuildSpecs(model)
|
||||||
# Очищаем окно пользовательских моделей
|
# Очищаем окно пользовательских моделей
|
||||||
@ -314,7 +330,8 @@ class MainFrame(forms.MainFrame):
|
|||||||
um = self.m_user_models
|
um = self.m_user_models
|
||||||
um.DeleteAllItems()
|
um.DeleteAllItems()
|
||||||
um.AddRoot('root')
|
um.AddRoot('root')
|
||||||
self.AddModelToRoot(model)
|
if create_default:
|
||||||
|
self.AddModelToRoot(model)
|
||||||
# Создаем корневой элемент для окна с графиками
|
# Создаем корневой элемент для окна с графиками
|
||||||
self.m_plots.AddRoot('root')
|
self.m_plots.AddRoot('root')
|
||||||
|
|
||||||
@ -329,8 +346,123 @@ class MainFrame(forms.MainFrame):
|
|||||||
model = f.GetSelectedModel()
|
model = f.GetSelectedModel()
|
||||||
if model:
|
if model:
|
||||||
self.NewProject(model)
|
self.NewProject(model)
|
||||||
|
|
||||||
self.do_nothing = False
|
self.do_nothing = False
|
||||||
|
|
||||||
|
def OnOpenProject(self, event):
|
||||||
|
|
||||||
|
def WalkModels(source, root, models, model_def = None):
|
||||||
|
|
||||||
|
for key, value in source.iteritems():
|
||||||
|
label = value['model']
|
||||||
|
if label not in models:
|
||||||
|
raise KeyError, 'no "{}"'.format(label)
|
||||||
|
data = ModelData(self.server, models[label], model_def)
|
||||||
|
data.mdef.params = value['data']
|
||||||
|
if 'result' in value:
|
||||||
|
data.res = task.ResultData(value['result'])
|
||||||
|
# тут надо проверить все добавленные параметры
|
||||||
|
|
||||||
|
item = um.AppendItem(root, key)
|
||||||
|
um.SetPyData(item, data)
|
||||||
|
model_items[key] = item
|
||||||
|
WalkModels(value['um'], item, models[label].GetSpecs(), data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
infile = 'data.opl'
|
||||||
|
data = {}
|
||||||
|
with open(infile, 'rb') as f:
|
||||||
|
data = json.loads(zlib.decompress(f.read()))
|
||||||
|
|
||||||
|
pprint(data)
|
||||||
|
|
||||||
|
tid = data['tid']
|
||||||
|
model_label = data['model']
|
||||||
|
model = self.server.CheckModel(tid, model_label)
|
||||||
|
if not model:
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
self.NewProject(model, False)
|
||||||
|
|
||||||
|
um = self.m_user_models
|
||||||
|
model_items = {}
|
||||||
|
root = um.GetRootItem()
|
||||||
|
WalkModels(data['um'], root, {model.GetLabel(): model})
|
||||||
|
|
||||||
|
# except KeyError, e:
|
||||||
|
# wx.MessageBox("Can't parse saved file!", 'Error!')
|
||||||
|
# except ValueError, e:
|
||||||
|
# wx.MessageBox("Can't parse saved file!", 'Error!')
|
||||||
|
except Exception, e:
|
||||||
|
print 'Oops', type(e), e
|
||||||
|
|
||||||
|
|
||||||
|
def OnSaveProject(self, event):
|
||||||
|
|
||||||
|
def WalkModels(item, dest):
|
||||||
|
if item != um.GetRootItem():
|
||||||
|
data = um.GetPyData(item)
|
||||||
|
title = um.GetItemText(item)
|
||||||
|
mdef = data.mdef
|
||||||
|
dest[title] = {
|
||||||
|
'model': mdef.DD.GetLabel(),
|
||||||
|
'data': mdef.params,
|
||||||
|
'um': {}
|
||||||
|
}
|
||||||
|
if data.res:
|
||||||
|
dest[title]['result'] = data.res.DumpData()
|
||||||
|
dest = dest[title]['um']
|
||||||
|
|
||||||
|
child, _ = um.GetFirstChild(item)
|
||||||
|
while child.IsOk():
|
||||||
|
WalkModels(child, dest)
|
||||||
|
child = um.GetNextSibling(child)
|
||||||
|
|
||||||
|
def WalkPlots(root, dest):
|
||||||
|
# по всеи элементам первого уровня
|
||||||
|
item1, _ = self.m_plots.GetFirstChild(root)
|
||||||
|
while item1.IsOk():
|
||||||
|
# по всем элементам второго уровня
|
||||||
|
item2, _ = self.m_plots.GetFirstChild(item1)
|
||||||
|
lines = []
|
||||||
|
while item2.IsOk():
|
||||||
|
line = self.m_plots.GetPyData(item2)
|
||||||
|
data = {
|
||||||
|
'title': self.m_plots.GetItemText(item2),
|
||||||
|
'colx': line.columns[0],
|
||||||
|
'coly': line.columns[1],
|
||||||
|
'model': line.GetModelTitle(),
|
||||||
|
'type': line.type,
|
||||||
|
}
|
||||||
|
lines.append(data)
|
||||||
|
item2 = self.m_plots.GetNextSibling(item2)
|
||||||
|
title = self.m_plots.GetItemText(item1)
|
||||||
|
dest.append([title, lines])
|
||||||
|
item1 = self.m_plots.GetNextSibling(item1)
|
||||||
|
|
||||||
|
|
||||||
|
wx.BeginBusyCursor()
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
data['tid'] = self.model.GetTaskId()
|
||||||
|
data['model'] = self.model.GetLabel()
|
||||||
|
|
||||||
|
um = self.m_user_models
|
||||||
|
data['um'] = {}
|
||||||
|
WalkModels(um.GetRootItem(), data['um'])
|
||||||
|
|
||||||
|
data['plots'] = []
|
||||||
|
WalkPlots(self.m_plots.GetRootItem(), data['plots'])
|
||||||
|
|
||||||
|
# pprint(data)
|
||||||
|
dump = json.dumps(data, indent = 2)
|
||||||
|
with open('data.opl', 'wb') as f:
|
||||||
|
f.write(zlib.compress(dump, 9))
|
||||||
|
# f.write(dump)
|
||||||
|
|
||||||
|
wx.EndBusyCursor()
|
||||||
|
|
||||||
# Функции непосредственной работы с моделями:
|
# Функции непосредственной работы с моделями:
|
||||||
# создание, изменение, дублирование и прочее
|
# создание, изменение, дублирование и прочее
|
||||||
|
|
||||||
@ -502,7 +634,6 @@ class MainFrame(forms.MainFrame):
|
|||||||
# то все субмодели должны быть пересчитаны
|
# то все субмодели должны быть пересчитаны
|
||||||
Walk(item)
|
Walk(item)
|
||||||
|
|
||||||
|
|
||||||
def OnTest(self, event):
|
def OnTest(self, event):
|
||||||
|
|
||||||
def Walk(item):
|
def Walk(item):
|
||||||
@ -955,6 +1086,9 @@ class ThisApp(wx.App):
|
|||||||
# Запуск приложения
|
# Запуск приложения
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main():
|
||||||
app = ThisApp(redirect = False)
|
app = ThisApp(redirect = False)
|
||||||
app.MainLoop()
|
app.MainLoop()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
18
server.py
18
server.py
@ -17,6 +17,7 @@ import time
|
|||||||
import datetime
|
import datetime
|
||||||
import threading
|
import threading
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import hashlib
|
||||||
|
|
||||||
import task
|
import task
|
||||||
|
|
||||||
@ -47,8 +48,6 @@ class LocalServer:
|
|||||||
self.queue_lock = threading.Lock()
|
self.queue_lock = threading.Lock()
|
||||||
|
|
||||||
# init actions
|
# init actions
|
||||||
|
|
||||||
self.log = open('log.txt', 'w')
|
|
||||||
self.WriteToLog('local server initialized')
|
self.WriteToLog('local server initialized')
|
||||||
|
|
||||||
def Close(self):
|
def Close(self):
|
||||||
@ -61,7 +60,7 @@ class LocalServer:
|
|||||||
def WriteToLog(self, msg):
|
def WriteToLog(self, msg):
|
||||||
tm = str(datetime.datetime.now())
|
tm = str(datetime.datetime.now())
|
||||||
msg = tm + ' ' + msg
|
msg = tm + ' ' + msg
|
||||||
self.log.write(msg + '\n')
|
# self.log.write(msg + '\n')
|
||||||
print msg
|
print msg
|
||||||
|
|
||||||
def TestTaskData(self, data):
|
def TestTaskData(self, data):
|
||||||
@ -86,13 +85,14 @@ class LocalServer:
|
|||||||
self.TestTaskData(data)
|
self.TestTaskData(data)
|
||||||
|
|
||||||
# вычисляем псевдоуникальный идентификатор модели
|
# вычисляем псевдоуникальный идентификатор модели
|
||||||
tid = hash(data['meta'])
|
tid = hashlib.md5(data['meta']).hexdigest()
|
||||||
# сохраняем описание задачи
|
# сохраняем описание задачи
|
||||||
self.tasks_meta[tid] = {
|
self.tasks_meta[tid] = {
|
||||||
'title': data.get('title', ''),
|
'title': data.get('title', ''),
|
||||||
'author': data.get('author', ''),
|
'author': data.get('author', ''),
|
||||||
'meta': data['meta'],
|
'meta': data['meta'],
|
||||||
'exec': line
|
'exec': line,
|
||||||
|
'models': []
|
||||||
}
|
}
|
||||||
|
|
||||||
# выделяем описания моделей
|
# выделяем описания моделей
|
||||||
@ -101,6 +101,7 @@ class LocalServer:
|
|||||||
model_descr = task.DataDescription(None, label, data, tid)
|
model_descr = task.DataDescription(None, label, data, tid)
|
||||||
# добавляем в список описаний
|
# добавляем в список описаний
|
||||||
self.models.append(model_descr)
|
self.models.append(model_descr)
|
||||||
|
self.tasks_meta[tid]['models'].append(model_descr)
|
||||||
|
|
||||||
self.WriteToLog('Task from "{}" asked'.format(line))
|
self.WriteToLog('Task from "{}" asked'.format(line))
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
@ -116,6 +117,13 @@ class LocalServer:
|
|||||||
def GetTaskMeta(self, tid):
|
def GetTaskMeta(self, tid):
|
||||||
return self.tasks_meta.get(tid)
|
return self.tasks_meta.get(tid)
|
||||||
|
|
||||||
|
def CheckModel(self, tid, model_label):
|
||||||
|
models = self.tasks_meta[tid]['models']
|
||||||
|
for model in models:
|
||||||
|
if model_label == model.GetLabel():
|
||||||
|
return model
|
||||||
|
return None
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
def CreateJob(self):
|
def CreateJob(self):
|
||||||
|
18
setup.py
Normal file
18
setup.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from distutils.core import setup
|
||||||
|
import py2exe
|
||||||
|
|
||||||
|
|
||||||
|
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
|
||||||
|
'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
|
||||||
|
'Tkconstants', 'Tkinter']
|
||||||
|
setup(
|
||||||
|
name = 'Opal',
|
||||||
|
windows = ['opal.pyw'],
|
||||||
|
options = { "py2exe": {
|
||||||
|
"compressed": 2,
|
||||||
|
"optimize": 2,
|
||||||
|
"bundle_files": 1,
|
||||||
|
"excludes": excludes,
|
||||||
|
} },
|
||||||
|
zipfile = None,
|
||||||
|
)
|
65
task.py
65
task.py
@ -42,6 +42,17 @@ class Parameter:
|
|||||||
def Test(self, value):
|
def Test(self, value):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def DumpData(self):
|
||||||
|
"""
|
||||||
|
Возвращает данные в стандартных контейнерах
|
||||||
|
|
||||||
|
READ ONLY!!!
|
||||||
|
"""
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def LoadData(self, data):
|
||||||
|
self.data = data
|
||||||
|
|
||||||
class Value(Parameter):
|
class Value(Parameter):
|
||||||
def __init__(self, label, value):
|
def __init__(self, label, value):
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
@ -70,6 +81,13 @@ class Column(Parameter):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def DumpData(self):
|
||||||
|
return [
|
||||||
|
self.GetLabel(),
|
||||||
|
self.GetType(),
|
||||||
|
self.GetTitle(),
|
||||||
|
]
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
class DataDescription:
|
class DataDescription:
|
||||||
@ -86,10 +104,12 @@ class DataDescription:
|
|||||||
par = Parameter(label, self.pdata[label])
|
par = Parameter(label, self.pdata[label])
|
||||||
self.pdata[label] = par
|
self.pdata[label] = par
|
||||||
|
|
||||||
self.specs = []
|
|
||||||
# рекурсивное создание описаний спецификаций
|
# рекурсивное создание описаний спецификаций
|
||||||
for label, data in self.data.get('spec', {}).iteritems():
|
self.specs = { label: DataDescription(self, label, data, self.tid)
|
||||||
self.specs.append(DataDescription(self, label, data, self.tid))
|
for label, data in self.data.get('spec', {}).iteritems() }
|
||||||
|
|
||||||
|
# for label, data in self.data.get('spec', {}).iteritems():
|
||||||
|
# self.specs.append(DataDescription(self, label, data, self.tid))
|
||||||
|
|
||||||
def GetLabel(self):
|
def GetLabel(self):
|
||||||
return self.label
|
return self.label
|
||||||
@ -115,6 +135,9 @@ class DataDescription:
|
|||||||
def GetImage(self):
|
def GetImage(self):
|
||||||
return self.data.get('img')
|
return self.data.get('img')
|
||||||
|
|
||||||
|
def GetTaskId(self):
|
||||||
|
return self.tid
|
||||||
|
|
||||||
def __getitem__(self, label):
|
def __getitem__(self, label):
|
||||||
return self.pdata.get(label)
|
return self.pdata.get(label)
|
||||||
|
|
||||||
@ -158,16 +181,7 @@ class DataDefinition:
|
|||||||
|
|
||||||
class ResultData:
|
class ResultData:
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = {}
|
self.LoadData(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):
|
def GetColumns(self):
|
||||||
return self.head
|
return self.head
|
||||||
@ -187,3 +201,28 @@ class ResultData:
|
|||||||
|
|
||||||
def Zip(self, col1, col2):
|
def Zip(self, col1, col2):
|
||||||
return [ (row[col1], row[col2]) for row in self.rows ]
|
return [ (row[col1], row[col2]) for row in self.rows ]
|
||||||
|
|
||||||
|
def DumpData(self):
|
||||||
|
data = {}
|
||||||
|
if self.data:
|
||||||
|
data['data'] = { key: self.data[key].DumpData()
|
||||||
|
for key in self.data }
|
||||||
|
|
||||||
|
if self.head:
|
||||||
|
head = [ col.DumpData() for col in self.columns ]
|
||||||
|
body = self.table
|
||||||
|
data['table'] = [head] + body
|
||||||
|
return data
|
||||||
|
|
||||||
|
def LoadData(self, 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:]
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
"n": {
|
"n": {
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"default": 100,
|
"default": 10,
|
||||||
"title": "Steps",
|
"title": "Steps",
|
||||||
"comment": "Number of steps for algorithm"
|
"comment": "Number of steps for algorithm"
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ def serie(n, d, h, l = 0):
|
|||||||
y = sin_taylor(l, d)
|
y = sin_taylor(l, d)
|
||||||
yield (l, y)
|
yield (l, y)
|
||||||
l += h
|
l += h
|
||||||
time.sleep(0.01)
|
# time.sleep(0.002)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user