Не могу разобраться как сохранить результаты работы скрипта в файл. Нагуглил про функцию SaveTable, но она не хочет работать (или я не понимаю как ее использовать). Что-то типа t_id = AllocTable() --дальше формируем таблицу, в конце прошу скинуть в файл: SaveTable(t_id, SaveResalt) и в итоге: attempt to call a nil value (global 'SaveTable')
p.s. таблица сама на экран выводится нормально, никаких ошибок не выдает
Как-то все в одну кучу. 1. При работе в QLua надо четко различать два абсолютно разных термина "таблица": 1) Таблица как тип данных в программе Lua, т.е.
Код
а = {} -- здесь переменная a - таблица в терминах языка программирования Lua
a[1] = 5 -- так к ней можно обращаться в программе
2) Таблица как элемент визуального интерфейса, таблица, которую вы видите на экране, визуальная таблица с данными. [/CODE] a = AllocTable() -- здесь переменная a содержит в программе идентификатор визуально отображаемой таблицы в терминале QUIK -- дальше вы знаете как работать с такой таблицей, раз у вас она отображается[/CODE]
Теперь понимаете? вы в своём вопросе смешали в кучу две эти совершенно разные "концепции", называемые, к сожалению, одним термином "таблица".
Цитата
и в итоге: attempt to call a nil value (global 'SaveTable')
Потому что штатно нет в QLua функции SaveTable(t_id, SaveResalt) Вам надо найти реализацию нагугленной вами этой функции или написать ее самостоятельно. Замечу, что в данном случае будет идти речь про сохранение значений из "таблицы" в смысле 1), а никак не про визуальные!
Спасибо за ответ. Очевидно, что Ваш уровень знаний в QLUA значительно выше моего, поэтому мои формулировки могут показаться дилетанскими, не спорю. Правильно тогда мой вопрос будет звучать как: Результатом работы скрипта получается таблица как ТИП ДАННЫХ, которую нужно сохранить в файл.
Цитата
Цитата: Вам надо найти реализацию нагугленной вами этой функции или написать ее самостоятельно
в этом и вопрос как ее написать - никаких функций для этого я не нашел, даже зацепочки. Неужели такая стандартная задача до этого никем в QLUA была не востребована и не изучена?
Правильно тогда мой вопрос будет звучать как: Результатом работы скрипта получается таблица как ТИП ДАННЫХ, которую нужно сохранить в файл.
О, Господи!.. Теперь уже и таблица стала "типом данных"? А граф тоже, или ещё нет?
В какой файл, в каком формате? CSV (как самое простое и разумное)? Тупейший двойной цикл: по строкам и (внутренний) по ячейкам текущей строки. Ну и разделители полей и кортежей нужно вставлять, разумеется.
Дмитрий написал: в этом и вопрос как ее написать - никаких функций для этого я не нашел, даже зацепочки.
Сереализация и десереализация таблиц (простой вариант). <code> ----- Конвертация таблицы в строку (сереализация) ------ -- Преобразование таблицы без ее метатаблицы (ключи и значения : table, boolean, number, string) в текстовое представление -- в соответствии с синтаксисом языка lua --- ---- Можно использовать для сохранения таблиц в текстовом виде, с возможностью последующего восстановления -- со следующими ! ограничениями: -- 1) ключи и значения : table, boolean, number, string; -- 2) все элементы таблицы (ключи и значения) типа table должны быть уникальными (в пределах таблицы). ------ Параметры: 1) t - таблица (обрабатываются все вложения ); -- 2) i - начальная строка формирования отступа при выводе вложений (например, " "); если i = '', то строки таблицы выводятся без отступов -- Результат (! два): 1) строка (тремя звездочками помечены проблемные места); 2) количество записей, которые нельзя представить в текстовом виде -- с последующим восстановлением ---- --------- local function tbl_to_string(t, i) if type(t) ~= "table" then return nil end i = i or ' ' local key_tbl_stateOS= "--таблица: " local tab = "\t" if i == '' then tab ='' end local ltime_str =GetLocalTimeMls() local tbl = {} --- для результата ---- local no_unpack =0 ----------- local function dump(t, i, seen) --------- if seen then if seen[t] then return seen[t] end tbl[#tbl +1] = " { -- " .. tostring(t) .. "\n" else seen={} -- просмотренные -- tbl[#tbl +1] = "{" .. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. " -- время создания \n" end seen[t] = tostring (t) if debug.getmetatable ( t ) then no_unpack = no_unpack + 1; tbl [#tbl +1] = i .. ' --- *** У таблицы ' .. tostring(t) .. ' есть метатаблица, которая в функции tbl_to_string не обрабатывается \n' end local bracket = true -- скобка (начало) --- -- for k,v in next, t do if type(k) == "table" then if bracket then tbl [#tbl +1] = i .. " [\n"; bracket = false else tbl [#tbl +1] = i .. ", [\n" end if dump(k, i .. tab, seen) then tbl [#tbl +1] = "*** -> " .. tostring (k) .. '\n' no_unpack = no_unpack + 1 end tbl [#tbl +1] = i .. " ] = " else if bracket then tbl [#tbl +1] = i .. " [ "; bracket = false else tbl [#tbl +1] = i .. ", [ " end if type(k) == "function" or type(k) == "userdata" or type(k) == "thread" then tbl [#tbl +1] = "*** " .. type(k) no_unpack = no_unpack + 1 end if type(k) == "string" then tbl [#tbl +1] = "'".. tostring(k) .. "'" else tbl [#tbl +1] = tostring(k) end tbl [#tbl +1] = " ] = " end
if type(v) == "table" then if seen[v] then tbl [#tbl +1] = "*** -> " .. tostring(v) .. '\n' no_unpack = no_unpack + 1 else dump(v, i .. tab, seen) --- end else if type(v) == "function" or type(v) == "userdata" or type(v) == "thread" then no_unpack = no_unpack +1 tbl [#tbl +1] = "*** " .. tostring(v) .. '\n' else if type(v) == "string" then tbl [#tbl +1]= '"' .. v .. '" \n' else tbl [#tbl +1] = tostring(v) .. "\n" end end end end -- tbl[#tbl +1] = i .. " } \n" end --------------------- dump(t,i) tbl[#tbl] = i .. "}".. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. "\n" --- !!! заменяется последняя фугурная скобка --- return table.concat ( tbl), no_unpack ----- Результат: 1) строка ; 2) количество значений, не представимых в текстовом виде ---- end ----- ---- Преобразование сереализованной таблицы (строки) в таблицу Lua (десереализация) -------------------- --- Результат: таблица Lua ------ function string_to_tbl (str_tbl) -- message (" string_to_tbl ", "return " .. str_tbl ) if str_tbl:find("{") == nil then return nil end --- если в строке str_tbl нет { local tbl , err_tbl = load ("return " .. str_tbl ) ---- assert (load_OS ( "retur " .. 4)) -- $$$$ if err_tbl ~= nil then message (" string_to_tbl ", "!!! Ошибка в синтаксисе таблицы: " .. str_tbl) --- err_tbl) return nil end return tbl() end ---- <code>
----- Конвертация таблицы в строку (сереализация) ------
-- Преобразование таблицы без ее метатаблицы (ключи и значения : table, boolean, number, string) в текстовое представление
-- в соответствии с синтаксисом языка lua ---
---- Можно использовать для сохранения таблиц в текстовом виде, с возможностью последующего восстановления
-- со следующими ! ограничениями:
-- 1) ключи и значения : table, boolean, number, string;
-- 2) все элементы таблицы (ключи и значения) типа table должны быть уникальными (в пределах таблицы).
------ Параметры: 1) t - таблица (обрабатываются все вложения );
-- 2) i - начальная строка формирования отступа при выводе вложений (например, " "); если i = '', то строки таблицы выводятся без отступов
-- Результат (! два): 1) строка (тремя звездочками помечены проблемные места); 2) количество записей, которые нельзя представить в текстовом виде
-- с последующим восстановлением ----
---------
local function tbl_to_string(t, i)
if type(t) ~= "table" then
return nil
end
i = i or ' '
local key_tbl_stateOS= "--таблица: "
local tab = "\t"
if i == '' then tab ='' end
local ltime_str =GetLocalTimeMls()
local tbl = {} --- для результата ----
local no_unpack =0
-----------
local function dump(t, i, seen) ---------
if seen then
if seen[t] then
return seen[t]
end
tbl[#tbl +1] = " { -- " .. tostring(t) .. "\n"
else
seen={} -- просмотренные --
tbl[#tbl +1] = "{" .. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. " -- время создания \n"
end
seen[t] = tostring (t)
if debug.getmetatable ( t ) then no_unpack = no_unpack + 1; tbl [#tbl +1] = i .. ' --- *** У таблицы ' .. tostring(t) .. ' есть метатаблица, которая в функции tbl_to_string не обрабатывается \n' end
local bracket = true -- скобка (начало) ---
--
for k,v in next, t do
if type(k) == "table" then
if bracket then tbl [#tbl +1] = i .. " [\n"; bracket = false else tbl [#tbl +1] = i .. ", [\n" end
if dump(k, i .. tab, seen) then
tbl [#tbl +1] = "*** -> " .. tostring (k) .. '\n'
no_unpack = no_unpack + 1
end
tbl [#tbl +1] = i .. " ] = "
else
if bracket then tbl [#tbl +1] = i .. " [ "; bracket = false else tbl [#tbl +1] = i .. ", [ " end
if type(k) == "function" or type(k) == "userdata" or type(k) == "thread" then
tbl [#tbl +1] = "*** " .. type(k)
no_unpack = no_unpack + 1
end
if type(k) == "string" then
tbl [#tbl +1] = "'".. tostring(k) .. "'"
else
tbl [#tbl +1] = tostring(k)
end
tbl [#tbl +1] = " ] = "
end
if type(v) == "table" then
if seen[v] then
tbl [#tbl +1] = "*** -> " .. tostring(v) .. '\n'
no_unpack = no_unpack + 1
else
dump(v, i .. tab, seen) ---
end
else
if type(v) == "function" or type(v) == "userdata" or type(v) == "thread" then
no_unpack = no_unpack +1
tbl [#tbl +1] = "*** " .. tostring(v) .. '\n'
else
if type(v) == "string" then
tbl [#tbl +1]= '"' .. v .. '" \n'
else
tbl [#tbl +1] = tostring(v) .. "\n"
end
end
end
end
--
tbl[#tbl +1] = i .. " } \n"
end
---------------------
dump(t,i)
tbl[#tbl] = i .. "}".. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. "\n" --- !!! заменяется последняя фугурная скобка ---
return table.concat ( tbl), no_unpack ----- Результат: 1) строка ; 2) количество значений, не представимых в текстовом виде ----
end
-----
---- Преобразование сереализованной таблицы (строки) в таблицу Lua (десереализация) --------------------
--- Результат: таблица Lua ------
function string_to_tbl (str_tbl)
-- message (" string_to_tbl ", "return " .. str_tbl )
if str_tbl:find("{") == nil then return nil end --- если в строке str_tbl нет {
local tbl , err_tbl = load ("return " .. str_tbl ) ---- assert (load_OS ( "retur " .. 4)) -- $$$$
if err_tbl ~= nil then
message (" string_to_tbl ", "!!! Ошибка в синтаксисе таблицы: " .. str_tbl) --- err_tbl)
return nil
end
return tbl()
end
----
TGB, Зачем просто, когда можно сложно? На код просто смотреть страшно (и я не собираюсь этого делать). Программа пишется в 5 секунд, и она в 100500 раз проще, чем в этом "простом варианте". ЗА КАКИМ ХРЕНОМ нужна эта долбаная "конвертация таблицы в строку"? Заняться больше нечем?
Мой скрипт каждые 5 минут записывает дамп текущего состояния - так это целый граф, а не какая-то сраная таблица! Написать этот код ничуть не сложнее, чем этот пост. Вот, навскидку:
Код
for i=1,N do -- цикл по строкам таблицы
for j=1,M do -- цикл по полям текущей строки таблицы
F:write(Tab[i][j].."\t"); -- пишем значение поля с разделителем
end; -- конец цикла по полям
F:write("\n"); -- разделитель строк
end; -- конец цикла по строкам
Парсер чуть сложнее - пишется не в 5 секунд, а в 6.
Владимир написал: TGB , Зачем просто, когда можно сложно? На код просто смотреть страшно (и я не собираюсь этого делать). Программа пишется в 5 секунд, и она в 100500 раз проще, чем в этом "простом варианте". ЗА КАКИМ ХРЕНОМ нужна эта долбаная "конвертация таблицы в строку"? Заняться больше нечем?
Я предложил функции сереализации и десереализации не для вашего элементарного случая, когда массив вложен в другой массив (с индексами 1… n). Хотя и ваш случай будет обработан этими функциями. Вопрос, заданный в ветке: как сохранить, а потом восстановить таблицу, а не по работе с числовыми индексами таблицы-массива. 1. Ваш код не обработает, например, даже элементарную таблицу: t = { [‘Тикер’] = 'SBER'}. Тем более, не обработает таблицу произвольной вло-женности, в которых индексами-ключами могут быть таблицы. В вашем коде нет функции восстановления таблицы 2. Зачем элементарный код вы представляете как ваше открытие ?
TGB, Я так и сказал: "Зачем просто, когда можно сложно?" Задача организации торговли элементарна, возможности языка ничтожны, глюков предостаточно, и лично я ещё до того, как написал свою первую строчку на Lua, знал, что буду использовать в качестве имён именно числовые индексы, и много раз здесь советовал поступать так же и писал, почему.
Здесь, кстати, вообще сказано, что нужно сохранять таблицу, созданную по AllocTable, т.е. таблицу Квика, а не таблицу Lua, и потому доступ к её данным должен осуществляться чем-то вроде getItem, так что никаких "таблиц произвольной вложенности, в которых индексами-ключами могут быть таблицы" там нет по определению.
Да, мой код не обработает ИДИОТСКУЮ таблицу: t = { [‘Тикер’] = 'SBER'}. А вот НОРМАЛЬНУЮ таблицу тот же код записи дампа прекрасно обрабатывает тем же способом, причём выводит не таблицу, а именно граф. Пара фрагментов РЕАЛЬНОГО кода записи этого всего в файл:
for i=1,N do -- цикл по тикерам F:write(a[i][0][0].."\1"..a[i][0][1].."\2"..a[i][1][1].."\3"..d(a[i][1][2]).."\4"..d(a[i][1][3]).."\t");
Здесь выводится и код тикера, и код класса тикера, и код валюты тикера, и его качество (от "говна" до "отличного"), и его статус, где разные биты за что-то отвечают. Хранить эти данные в коде скрипта есть клинический маразм.
И далее (внутренний цикл): while j<a[i][1][4] do -- выводим данные по сделкам F:write(d(a[i][5][j])..":"..d(a[i][5][j+1]).."\t"); j=j+2; -- переходим к следующей ставке
Короче: структура моей сохраняемой "таблицы" в тыщу раз сложнее любой таблицы Квика и любой таблицы, с которой сумеет справиться Ваша "сереализация". Кстати, о птичках: в файл сохраняется не вся, структура данных, которая лежит в ОЗУ (там пятимерный массив данных), а лишь та её часть, которую нужно сохранить (например, я не сохраняю свечи по всем таймфреймам - они нужны для торговли, но не нужны для файла). И с этой задачей Ваша "сереализация" не справится НИКОГДА!
Владимир написал: Здесь, кстати, вообще сказано, что нужно сохранять таблицу, созданную по AllocTable, т.е. таблицу Квика, а не таблицу Lua
Читайте внимательно:
Цитата
Дмитрий написал: Правильно тогда мой вопрос будет звучать как: Результатом работы скрипта получается таблица как ТИП ДАННЫХ, которую нужно сохранить в файл.
Из контекста можно понять, что пользователя, наверное, интересует таблица Lua ---------- Вы не ответили на мой вопрос:
Цитата
TGB написал: Зачем элементарный код вы представляете как ваше открытие ?
У меня есть сильное подозрение, что ваше сообщение было написано чтобы в нем появилась фраза :
Цитата
Владимир написал: Мой скрипт каждые 5 минут записывает дамп текущего состояния - так это целый граф, а не какая-то сраная таблица!
TGB, Это Вы "читайте внимательно" - не только ТОТ пост, который процитировали, но и самый первый в ветке. И там не "из контекста можно понять", а открытым текстом сказано, что и как. К тому же "таблица как ТИП ДАННЫХ" есть идиотизм. И кто Вам сказал, что "элементарный код я представляю как ваше открытие"? Это утверждение не соответствует действительности, а потому отвечать на вопрос "зачем" относительно лживого утверждения не имеет смысла. А Ваши "сильные подозрения" меня не интересуют.
Цитата
Справится. Попробуйте.
Зачем мне "пробовать"? Любому дебилу понятно, что исходная и сохраняемая структура - это РАЗНЫЕ структуры. Или не любому?
КАКАЯ, блин, "таблица преобразовалась в КАКУЮ строку"?! Часть таблицы Lua (ЧАСТЬ, а не вся таблица!) преобразуется ВО МНОЖЕСТВО строк, файла, причём их структура РАЗНАЯ. Эти строки содержат информацию о рынке, о портфеле пользователя, о самом пользователе (код клиента, номер счёта и т.д.), о его сделках, текущей прибыли/убытку по тикерам, информацию по свечам, размер лота, ранги скоростей движения курса по таймфреймам, информацию о незакрытых заявках и прочая, и прочая, и прочая. Подавляющего большинства этих данных в файле дампа просто НЕТ, их НЕЛЬЗЯ сохранять и восстанавливать, ибо к моменту восстановления там будут ДРУГИЕ значения. Сохраняемых и восстанавливаемых данных там не более 10-20% от общего их количества, и они имеют СОВСЕМ ДРУГУЮ структуру. Мало того: туда записывается информация для самого пользователя, вроде отчёта о текущем состоянии портфеля по всем сделанным ставкам. НИКАКАЯ долбаная "сереализация" В ПРИНЦИПЕ неспособна это сделать! Хотя бы по той простой причине, что она не знает и не может знать, что и как сохранять, в каком виде, как и куда это всё восстанавливать. Она не будет работать НИКОГДА!
Владимир написал: В ПРИНЦИПЕ неспособна это сделать! Хотя бы по той простой причине, что она не знает и не может знать, что и как сохранять, в каком виде, как и куда это всё восстанавливать. Она не будет работать НИКОГДА!
Я нигде не писал, что сереализация знает что и как сохранять. Вы скопировав функции tbl_to_string(t, i) и string_to_tbl (str_tbl) смогли бы заменить весь ваш код по сохранению и при необходимости восстановления вашего графа двумя строками. У меня это работает в нескольких местах, начиная с 2019г. Так что вы неправы насчет НИКОГДА. Но, наверное, вам милее ваш код сохранения состояния выполнения вашего скрипта. Ну и пусть.
Естественно, Вы нигде не писали, что сереализация знает что и как сохранять - я бы Вас высмеял беспощадно. НА КОЙ мне эти дурацкие функции tbl_to_string и string_to_tbl, если они по определению нихрена не умеют? Тем более, что весь код моего парсера и сохранения короче кода Ваших функций, которым вне зависимости от этого место только на помойке. НЕ МОГ БЫ я "заменить весь свой код по сохранению и при необходимости восстановлению моего графа двумя строками"! НЕ МОГ! Я же русским языком сказал, что при восстановлении подавляющее большинство всех этих данных теряют актуальность и НЕ ДОЛЖНЫ восстанавливаться! И что транспортный формат данных отличается от рабочего, И ДОЛЖЕН от него отличаться. И что часть данных предназначена для человека, и это не копия какого-то куска таблицы, а, в большинстве своём, РАСЧЁТНЫЕ данные, и что при восстановлении такие данные должны игнорироваться. Могу добавить, что есть ещё часть данных, которые записываются в синтаксисе языка Lua, и при восстановлении никуда не восстанавливаются, а просто исполняются как операторы языка (через loadstring). Так на кой мне (или кому бы то ни было) Ваше беспомощное дерьмо? НИКОГДА оно не сделает из того, что требуется. НИКОГДА!
TGB, Да и я примирительно. Ну, сказали глупость - с кем не бывает? И кто Вам сказал, что я злюсь? Я всего лишь сказал, что Ваше беспомощное дерьмо НИКОГДА оно не сделает из того, что требуется. И это просто медицинский факт.
swerg, Лапуль, документацию, в которой таблица является типом данных, нужно относить на помойку, не читая. Кто эту бредятину написал? Вы, что ли? Ах, Роберто Иерусалимский? Дык я чуть ли не в первом своём комменте на этом форуме говорил, что он дебил. Когаловский Михаил Рувимович - вот этого человека стоит читать, а не всяких придурков.
swerg, Блин, и первым же предложением "The table type implements associative arrays"! Лапуль, это не просто дебил, это КЛИНИЧЕСКИЙ дебил! Как и все, кто его читает.
Владимир написал: И кто Вам сказал, что я злюсь? Я всего лишь сказал, что Ваше беспомощное дерьмо НИКОГДА оно не сделает из того, что требуется. И это просто медицинский факт.
Исходя из написанного вами выше, повторно, совершенно ясно, что вы опять не понимаете то, что я подробно объяснил в своем комментарии: https://forum.quik.ru/messages/forum10/message62929/topic7277/#message62929 В этом комментарии написано все очень просто. Прочитайте этот комментарий внимательно несколько раз и, надеюсь, что ваше мнение изменится :)
TGB, Лапуль, я и сам по себе хороший алгоритмист, и как таковой, знаю совершенно точно, что эту задачу никакая "универсальная" утилита В ПРИНЦИПЕ неспособна выполнить, какая бы хрень по этому поводу ни была где-либо написана кем бы то ни было. И я Вас уже торкал носом в этот Ваш коммент. Можем повторить(с): НИКАКАЯ долбаная "сереализация" В ПРИНЦИПЕ неспособна это сделать! Хотя бы по той простой причине, что она не знает и не может знать, что и как сохранять, в каком виде, как и куда это всё восстанавливать. Она не будет работать НИКОГДА!
Вы, похоже, сильно ошиблись форумом. Напомню, здесь, все-таки, форум по программированию, а не гей-клуб. Зачем вы подставляетесь? Ведь кто-нибуть может начать обращаться к вам по кликухе Владимир-Лапуля, с тем, чтобы не перепутать с другими Владимирами.
2.
Цитата
Владимир написал: я и сам по себе хороший алгоритмист, и как таковой, знаю совершенно точно
Алгоритмист вы посредственный, если не понимаете, что с определенными ограничениями (а я их описал в комментариях к своему коду) отдельная таблица (и вы до сих пор не поняли это) может быть сереализована. Покажите мне таблицу произвольной вложенности, в которой в качестве ключей-индексов и их значений используются : 1) ключи и значения : table, boolean, number, string; 2) все элементы таблицы (ключи и значения) типа table должны быть уникальными (в пределах таблицы). И которая не будет обработана предложенными мной кодами. А без этого все написанное вами бла-бла.
3. Что вы так убиваетесь? В конце концов, вы меня затмили по количеству выложенного вами текста, наверное, в 20 раз, с чем вас точно можно поздравить . Да и концовка дискуссии, наверное, будет за вами . И, все-таки, зацените , в моих текстах нет ни одного грубого слова, не считая ваших цитат, и почти все они по делу.
TGB, Да объяснял уже тыщу раз: "лапуля" - это термин такой, многократно доказавший за долгие годы применения свою высочайшую эффективность в вытравливании головожопых - они на него клюют, как на опарыша. И одновременно индикатор, что я уже не испытываю к собеседнику никаких чувств, кроме презрения. Вот именно, здесь форум по программированию, а не реклама маразматического софта как очередной вундервафли.
Лапуль, я уже затрахался торкать Вас носом, что сохраняется НЕ ВСЯ таблица, что сохраняемая структура в файле СОВЕРШЕННО ДРУГАЯ, нежели структура в ОЗУ, что восстанавливаются НЕ ВСЕ данные, что часть из них исполняется как операторы языка, что никакая универсальная утилита В ПРИНЦИПЕ не может этого сделать, что это не "таблица произвольной вложенности" и даже не дерево, а граф общего вида. Или, если Ваши мозги ничего кроме таблиц воспринимать не способны, это МНОЖЕСТВО таблиц, у которых ЧАСТЬ полей восстанавливается, а другая часть инициализируется значениями по умолчанию или читается из каких-то других источников. А "предложенные Вами коды можете засунуть себе в задницу - я вообще не могу представить, кому и за каким хреном это беспомощное дерьмо может понадобиться.
Господи, да насрать мне на Ваши грубые слова! Когда-то давно я воспринимал Вас как программиста, и даже примерно равного куда-то исчезнувшему Антону, с которым Вы когда-то пиписьками мерялись. Но это было давно. А сейчас я Воспринимаю Вас как надутого индюка - да, имеющего некоторые познания в программировании, но не более того. Много чести Вас в чём-то "затмить".
TGB, А у нас что, «батлз»? И я тыщу раз говорил, что я никогда не смотрю на то, КТО сказал - только на то, ЧТО сказано. Вы меня не интересуете, от слова "совсем", так что комментировать Вас я не собираюсь. Но если снова начнёте пороть чушь, ничего хорошего я Вам не гарантирую.
Владимир написал: Но если снова начнёте пороть чушь, ничего хорошего я Вам не гарантирую.
Ну, вы неугономные . Но только в написании длинных голословных текстов. Это вместо того, чтобы потестировать предложенные мною функции и найти таблицу (с довольно слабыми ограничениями, заданными в их описании), которую эти функции не смогут обработать.
TGB, Я не вижу смысла в этих функциях - зачем же мне их тестировать? У меня для тестирования великое множество других, и даже связанных с торговлей, хотя алгоритмы торговли довольно просты, и проблемы там, в основном, связаны с глюками софта самого Квика - например, та самая синхронизация. Но есть и в тыщу раз более интересные задачи.
Владимир написал: TGB , Я не вижу смысла в этих функциях - зачем же мне их тестировать?
Вам лично они, наверное, пока не нужны, так ка вы что то сделали свое. Но вы голословно, вместо того чтобы проверить, утверждаете, что эти функции не работают. У вас что, такой принцип: обгаживать все чужое, чтобы на этом фоне самому выглядеть "молодцом"? Возникает такое ощущение, что вы считаете что весь форум посвящен только вашему непревзойденному" скрипту. На форуме на самом деле есть и другие пользователи и гости. ----- Кстати, начальную проверку функций можно выполнить за 2-3 минуты (это меньше, чем написание пяти строк текста комментария) Например, для начала вы могли бы посмотреть готовый вариант: 1. Перед запуском проверок, в функции tbl_to_string заменить GetLocalTimeMls() на стандартную os.time(). 2. Код проверки простой таблицы (под кодом функций)
Код
local tbl = {
['Тикер'] = 'SBER'
, [{ 1, 2, 3}] = { 'QUIK'}
, TOBR = {6, 8, 4, {1, 2, 3 }}
, 'Сохранение таблицы'
, ok = true
}
-- Сохранение таблицы --
local str = tbl_to_string (tbl)
message ( str ) -- в str строковый образ таблицы ---
-- Восстановление таблицы ---
local tbl1 = string_to_tbl (str) --- в tbl1 восстановленная таблица
3. Далее можно, экспериментировать, меняя таблицу tbl
TGB, Пока?! Сколько можно повторять, что структура моих сохраняемых и восстанавливаемых данных НАМНОГО сложнее, и эта задача В ПРИНЦИПЕ не решаема такими функциями. Я не говорил, что эти функции не работают - я говорил, что они беспомощны в сколько-нибудь сложных случаях. Мне плевать, чужое это или своё - в любом случае такие функции практически бесполезны. И ещё больше плевать, какие там у Вас "возникают ощущения" - это Ваши комплексы, не мои. А про "мой непревзойденный скрипт" здесь знает разве что Борис, и никто более - я вообще про него практически ничего не говорил, кроме самых общих "технических" вопросов.
Да чего Вы ко мне прицепились? Не хочу я на Ваш код смотреть! Вообще не хочу, он алгоритмически убог, уже на стадии постановки задачи.
А это на что похоже (много повторений да еще крупным шрифтом самое-самое)?:
Цитата
Владимир написал: структура моих сохраняемых и восстанавливаемых данных НАМНОГО сложнее, и эта задача В ПРИНЦИПЕ не решаема такими функциями.
Да ладно вам, какие технологические сложности могут быть при построении торговых роботов? Статегия торгов это действительно проблема. Но эффективность стратегии торгов, конечно, определяется не ее сложностью. Стратегия может быть сложной, но не прибыльной, а может быть простой и прибыльной. Судя по фрагментам кодов вашего скрипта, структура данных в нем представлена в виде давно известной многомерной матрицы размерности N < 1000, с числовыми индексами, в которой вы храните свой граф. Или это не так? Что, кроме table, boolean, number, string, являются эле-ментами вашего графа? Если у вас что-то более монструозное, то было бы интересно узнать: зачем это сделано? Все-таки, надо стремиться к простоте. Но даже, если вы построили что-то монструозное, и корнем этого является таблица, то у меня есть более сложные функции сереализации (их я вам не предлагаю, понимая вашу реакцию на это ), которые, скорее всего, смогут сереализовать и десереализовать вашу монструозность. Это проверено на сохранении и восстановлении всего окружения (таблица _G) моих разных скриптов и, кстати, выполняется быстро. У меня нет цели что-то вам навязывать. Мне просто интересно: у вас что-то более сложное, чем служебная таблица окружения скрипта _G, в которой хранятся все глобаль-ные переменные работающего скрипта и многое другое?
TGB, Ну что мне, ликбез проводить? Вы же явно себя учеником не считаете. Ладно, ещё разок попробую.
1. Капс всегда был и остался способом выделения фрагментов текста. Иногда единственным (например, в Фейсбуке). Так что "это похоже" именно на выделение фрагментов текста, чем мой капс и является в действительности.
2. А при чём тут "технологические сложности"? Сам язык убог до неприличия - даже тип integer отсутствует. Я говорил про беспомощность Ваших функций, которые, как я предполагаю (в код я не заглядывал и не собираюсь) способна сохранять Lua-таблицы (которые ничего общего с таблицами не имеют) или дерево, которое эта структура может образовать. Уже в моём третьем сообщении на этом форуме... нет, вру - в четвёртом от 29.09.2020 10:31:16 я писал: Ну вот, по Вашей ссылке, первым же предложением: "Tables in Lua are not a data structure; they are the data structure. All structures that other languages offer---arrays, records, lists, queues, sets---are represented with tables in Lua". Иными словами, никаких структур данных просто НЕТ! Печально... А уж "обоснование" и вообще курам на смех: "Хотя мы МОЖЕМ (!) реализовать массивы и списки, таблицы мощнее. Многие алгоритмы упрощаются до тривиальности с использованием таблиц". И дальше вообще издевательство: "Например, вы редко пишете поиск в Lua, потому что таблицы предлагают прямой (!!!) доступ к любому типу". Ребятки, доступ по ключу - это не прямой, а как раз КРИВОЙ доступ к данным! Даже если обозвать ключи "индексами". Уши бы надрать этому "Роберто Иерусалимскому! В общем, с языком почти всё ясно: граф (точнее, дерево) объектов построить можно, а простейшую таблицу или даже массив - нельзя. Остаётся разобраться со строковыми переменными: способна ли эта loadstring интерпретировать строки как операторы языка (или, скажем, функции), то есть имеется ли здесь техническая возможность программирования данными.
3. Я вообще не говорил никогда про стратегию торгов - по крайней мере, про её сложность. Стратегии торгов достаточно простые - все до единой. По крайней мере, если для них сложность не самоцель, а задачей является эффективность стратегии. Да и откуда взяться сложности? Курс может либо расти, либо падать, либо стоять на месте, либо вообще торги по тикеру не ведутся - И ВСЁ! Больше даже вариантов никаких нет - просто безумная сложность! Я говорил про сложность СТРУКТУРЫ данных, ЛОГИЧЕСКОЙ структуры, и предельная сложность такой структуры называется "граф общего вида" (если учесть, что узлами такого графа могут быть не только атомарные элементы, но и субграфы, а его рёбра также могут быть нагружены произвольной информацией, при этом количество рёбер по разным измерениям может быть переменным, в т.ч. нулевым.
4. Разумеется, "это не так". Единственно возможная структура на Lua представляет собой дерево, а обращение к её элементом конструкциями языка выглядит именно как обращение к ячейкам многомерного куба. Так что никакой "матрицы" нет и в помине. Более того, я терпеть не могу эти матрицы, и их нет вообще ни в одной из разработанных мною программ - я чуть ли не всю свою сознательную жизнь интересовался именно СЛОЖНЫМИ данными, а не этими погремушками.
5. Сложность данных не имеет ничего общего со сложностью типов данных - атомарные элементы (а никакие не "таблицы") могут быть любых типов, а в сохранённом виде это вообще одни только строки. Это ничуть не мешает построению из таких элементов конструкций ЛЮБОЙ сложности.
6. Вот именно: "надо стремиться к простоте". Не городить уродливую и беспомощную "универсальную" конструкцию, а делать простейшими способами то, что нужно. А нужно (мне) сохранить часть переменных (просто переменных или массивов, или деревьев) в файл - и не всех, которые там вообще есть, а те, которые мне НУЖНО сохранить. Сохраняются даже те данные, которых в структуре вообще нет - они рассчитываются "на лету" перед записью. И восстановить мне нужно не все данные, а те, которые мне НУЖНО восстановить, разбросав их по разным переменным, массивам, таблицам, деревьям. Вот и вся задача! И выполняется она в main (при запуске скрипта), в OnStop (по выходу), да раз в 5 минут (по таймеру) на всякий пожарный. Хоть сто лет думайте - ничего более простого не придумаете.
7. Да, все данные по тикерам сидят именно в этой "корневой" таблице - это тоже самое простое и самое разумное решение. Переменная эта, разумеется, глобальная, так что все эти данные всегда доступны из любой функции.
8. Господи, НУ ЗА КАКИМ ХЕРОМ нужно "сохранять и восстанавливать ВСЁ окружение"? Это же ИДИОТИЗМ! Нужно делать только то, что нужно, и ничего, кроме этого.
Владимир написал: НУ ЗА КАКИМ ХЕРОМ нужно "сохранять и восстанавливать ВСЁ окружение"? Это же ИДИОТИЗМ! Нужно делать только то, что нужно, и ничего, кроме этого.
В моем комментарии не написано, что в моих боевых скриптах сохраняется все окружение. Там написано:
Цитата
TGB написал: Это проверено на сохранении и восстановлении всего окружения (таблица _G) моих разных скриптов и, кстати, выполняется быстро.
Владимир написал: просто безумная сложность! Я говорил про сложность СТРУКТУРЫ данных, ЛОГИЧЕСКОЙ структуры, и предельная сложность такой структуры называется "граф общего вида" (если учесть, что узлами такого графа могут быть не только атомарные элементы, но и субграфы, а его рёбра также могут быть нагружены произвольной информацией, при этом количество рёбер по разным измерениям может быть переменным, в т.ч. нулевым.
Особой сложности нет. Практически любая безумность, которую вы сможете написать на Lua, будет сереализована и десереализована моими сложными функциями сереализации. Но, на самом деле, для целей сохранения и восстановления состояний функций, требуемых (а всех переменных) для продолжения функционирования моего скрипта после перезапуска, я вполне обхожусь простыми функциями сереализации, выложенными здесь.
TGB, Лапуль, Вам известно слово "сарказм"? Пишется "безумная сложность", а произносится "НУ ЧТО ТУТ ВАЩЕ МОЖЕТ БЫТЬ СЛОЖНОГО"?! Когда-то здесь какой-то придурок (николз, кажется) говорил, что торговый робот сложнее шахматной программы.
И утомили Вы меня своими дурацкими "функциями сереализации". Тупейший вопрос: НУ ОТКУДА, ОТКУДА, ОТКУДА этим долбаным функциям знать, что НУЖНО сохранять, а что сохранять НЕ нужно? Мне плевать, чем там "вполне обходитесь Вы" - я всего лишь говорю, что Ваши убогие функции нафиг никому не нужны, их место на помойке.