Скрипты для Demagog
Модератор: flegont
- flegont
- V.I.P.
Скрипты для Demagog
Да. WAudio - это просто вызов подпрограммы Демагога записи аудио, а она использует подключенные словари. Хорошей практикой, думаю, будет полное отключение всех словарей, если мы работаем со скриптами словарных замен и/или скриптами записи аудио.
Скрипты для того (в основном) и предназначены, чтобы делать словарные замены и запись аудио не так, как велят "врожденные инстинкты" Демагога, а как задумал опытный пользователь. Т.е. скриптами вызываются нужные словари, скриптами делаются словарные замены, скриптами пишется аудио. Следовательно, все словари в Панели словарей надо заранее отключить (лишив тем самым Демагога собственной воли ).
Скрипты для того (в основном) и предназначены, чтобы делать словарные замены и запись аудио не так, как велят "врожденные инстинкты" Демагога, а как задумал опытный пользователь. Т.е. скриптами вызываются нужные словари, скриптами делаются словарные замены, скриптами пишется аудио. Следовательно, все словари в Панели словарей надо заранее отключить (лишив тем самым Демагога собственной воли ).
- tonio_k
- V.I.P.
Скрипты для Demagog
Тода напрашивается команда для скрипта - отключить(а лучше игнорировать) все активные словари.
- flegont
- V.I.P.
Скрипты для Demagog
Я уже думал об этом. Может, попробую в следующей версии добавить команду для скрипта - игнор всех подключенных словарей...
- tonio_k
- V.I.P.
Скрипты для Demagog
Функция WSeries(i, folder, fragsize, parag, header, ender, startnum)
Пример:
WSeries(ind, homedir, 6000, true, 'Сериал ', 'Конец серии',21)
1) header
В настройках Демагог "Сериалы"- "Добавлять в начале и конце сериала"
указываю: Сериал %2. Моя книга на выходе дает: Сериал N. Моя книга
Как это реализовать в WSeries?
2) ender
... , 'Конец серии',21)
21 - начало нумерации вставляется внутри файла, но начало нумерации самих txt файлов не меняется
3) header без ender
WSeries(ind, homedir, 6000, true, 'Сериал ', 21) - по смыслу хочу что бы вставлял только "Сериал" и нумерация началась с 20. При этом, ender (Конец серии) в текст не вставлялся.
Вместо этого, 21 воспринимается как ender вставляется в текст и к нему автоматом добавляется нумерация startnum
4)
x, y = FilterToAll(homedir, '0*.txt', diclist)
- смущает 0*.txt
Теоретически номер файла может быть: ... 1023.txt, 1024.txt ... 1023.txt ... 3217.txt Хотя лично у меня на практике было максимум 0987.txt, но как то все равно очень близко
Отправлено спустя 16 минут 43 секунды:
Есть сериал, а что дальше?
Допустим, обработали все файлы словарями.
Теперь в папке homedir - куча обработанных файлов 0001.txt, 0002.txt ... 0331.txt
Как скриптом дать команду WAudio записать все файлы в папке homedir в аудио?
Отправлено спустя 17 минут 9 секунд:
Содержимое файла Demagog\work\mylib.lua
Выходит сообщение об ошибке:
Если содержимое mylib.lua вставляю в calculator.lua (строку require "work/mylib" - удаляю) тогда всё прекрасно отрабатывает.
В чем ошибка вызова функций из "work/mylib" ?
Отправлено спустя 2 часа 7 минут 8 секунд:
Дальше либо удовлетвориться наименованием 0001+.mp3, 0002+.mp3 ... 0331+.mp3, либо создать функцию по переименованию файлов (удаление "+").
Пример:
WSeries(ind, homedir, 6000, true, 'Сериал ', 'Конец серии',21)
1) header
В настройках Демагог "Сериалы"- "Добавлять в начале и конце сериала"
указываю: Сериал %2. Моя книга на выходе дает: Сериал N. Моя книга
Как это реализовать в WSeries?
2) ender
... , 'Конец серии',21)
21 - начало нумерации вставляется внутри файла, но начало нумерации самих txt файлов не меняется
3) header без ender
WSeries(ind, homedir, 6000, true, 'Сериал ', 21) - по смыслу хочу что бы вставлял только "Сериал" и нумерация началась с 20. При этом, ender (Конец серии) в текст не вставлялся.
Вместо этого, 21 воспринимается как ender вставляется в текст и к нему автоматом добавляется нумерация startnum
4)
► Показать
- смущает 0*.txt
Теоретически номер файла может быть: ... 1023.txt, 1024.txt ... 1023.txt ... 3217.txt Хотя лично у меня на практике было максимум 0987.txt, но как то все равно очень близко
Отправлено спустя 16 минут 43 секунды:
Есть сериал, а что дальше?
Допустим, обработали все файлы словарями.
Теперь в папке homedir - куча обработанных файлов 0001.txt, 0002.txt ... 0331.txt
Как скриптом дать команду WAudio записать все файлы в папке homedir в аудио?
Отправлено спустя 17 минут 9 секунд:
► Показать
► Показать
► Показать
В чем ошибка вызова функций из "work/mylib" ?
Отправлено спустя 2 часа 7 минут 8 секунд:
Такой вариант придумал:
► Показать
- flegont
- V.I.P.
Скрипты для Demagog
1) Перевод сообщения об ошибке:
Ошибка загрузки модуля work\mylib
из файла 'D:\YandexDisk\?????\Balabolka\Demagog\work\mylob.lua' в строке 1
неожиданный символ рядом с символом 255
Символ 255 в кодировке ANSI - это русская буква я
Пока это всё, что могу сказать. Впечатление, что в текст затесался какой-то левый символ...
Скопировал ваш текст mylib.lua с Форума, сделал тестовую копию Демагога в папке, вложенной в папку с русским именем, запустил ваш пример - работает, библиотека подключилась
2) Ваш пример записи аудио прекрасно работает
Но, лучше написать не WAudio(0,homedir,true) а WAudio(0,homedir,false) чтобы не проверялась каждый раз возможность делить очередной файл на серии. Ведь он сам по себе - уже серия.
Ошибка загрузки модуля work\mylib
из файла 'D:\YandexDisk\?????\Balabolka\Demagog\work\mylob.lua' в строке 1
неожиданный символ рядом с символом 255
Символ 255 в кодировке ANSI - это русская буква я
Пока это всё, что могу сказать. Впечатление, что в текст затесался какой-то левый символ...
Скопировал ваш текст mylib.lua с Форума, сделал тестовую копию Демагога в папке, вложенной в папку с русским именем, запустил ваш пример - работает, библиотека подключилась
2) Ваш пример записи аудио прекрасно работает
Но, лучше написать не WAudio(0,homedir,true) а WAudio(0,homedir,false) чтобы не проверялась каждый раз возможность делить очередной файл на серии. Ведь он сам по себе - уже серия.
- flegont
- V.I.P.
Скрипты для Demagog
P.S. Маску с нулем '0*.txt' я указывал просто для примера, правильней было бы *.txt
- flegont
- V.I.P.
Скрипты для Demagog
Работаю над этим.В настройках Демагог "Сериалы"- "Добавлять в начале и конце сериала"
указываю: Сериал %2. Моя книга на выходе дает: Сериал N. Моя книга
Как это реализовать в WSeries?
- flegont
- V.I.P.
Скрипты для Demagog
Вот, чуть короче:
Мне, однако, не нравится, как ведет себя WAudio. Она должна сама создавать новое имя аудиофайла, по образцу имени, открытого в окне. Вместо этого вынуждает заниматься этим переименованием пользователя. Непорядок. Буду смотреть, чего с ней не так...
Код: Выделить всё
local a = AllFiles(homedir,'0*.txt')
for i = 1,#a do
WOpen(0,homedir..a[i])
name_p = SplitFileName(a[i])[2]
WAudio(0,homedir,false)
os.rename (homedir..'0001.mp3', homedir..name_p..'+.mp3')-- переименовываем 0001.mp3 на имя открытой в окне серии
os.remove(homedir..a[i])
end
WNew(0)
- tonio_k
- V.I.P.
Скрипты для Demagog
да, но тогда результат она будет кидать в D:\MP3\0001.audio\0001.mp3 т.е. каждый файл сериала он воспринимает как отдельную книгу и будет создавать для каждой подкаталог 0001.audio
- flegont
- V.I.P.
Скрипты для Demagog
Вообще-то в программе задумано так:
1. Если книга не делится на сериал, то никаких "книжных" подкаталогов для аудио не создается. Не делится на сериалы может оттого, что: запрещено в настройках или в параметрах WAudio().
2. Если задано деление на сериал, и оно прошло успешно, то создается подкаталог ИмяКниги.audio
3. "Папка назначения" - это совсем другое. Это - папка, куда надо положить готовую аудиокнигу.
Аудиокнига - это либо один файл ИмяТекста.mp3, либо папка ИмяТекста.аudio
4. Если указано, например: WAudio(0, homedir, false) то никакого деления текста в окне 0 на серии не будет, оно запрещено параметром false
1. Если книга не делится на сериал, то никаких "книжных" подкаталогов для аудио не создается. Не делится на сериалы может оттого, что: запрещено в настройках или в параметрах WAudio().
2. Если задано деление на сериал, и оно прошло успешно, то создается подкаталог ИмяКниги.audio
3. "Папка назначения" - это совсем другое. Это - папка, куда надо положить готовую аудиокнигу.
Аудиокнига - это либо один файл ИмяТекста.mp3, либо папка ИмяТекста.аudio
4. Если указано, например: WAudio(0, homedir, false) то никакого деления текста в окне 0 на серии не будет, оно запрещено параметром false
- tonio_k
- V.I.P.
Скрипты для Demagog
может еще сделать Функцию:
AudioToAll(folder, mask, mode) к файлам в папке folder, имена которых отвечают маске mask применяется запись в аудио с mode = false/true (удалять/не удалять) текстовый файл из сериала, к которому уже создан аудиофайл
- flegont
- V.I.P.
- tonio_k
- V.I.P.
Скрипты для Demagog
Такое пожелание, что бы еще была еще одна функция "симбиоз":
Т.е. после
Код: Выделить всё
WSave(0,folder..a[i]) -- сохранение файла после обработки словарей,
Код: Выделить всё
WAudio(0,folder,false)
os.remove(folder..a[i])
1)открывается текстовый файл,
2)прогоняется через словари,
3)записывается аудио,
4) удаляется текстовый файл
Это все для защиты от "сбоев". Что бы при внештатной остановке Демагога или выключения ПК, было с чего продолжить запись - просто открыв тот же файл и запустив повторно этот же скрипт - указать папку назначения
- flegont
- V.I.P.
Скрипты для Demagog
В моем представлении, это должен быть скрипт, максимально автоматизирующий изготовление аудиокниги. Что-то вроде: Audiobook maker.lua
0. Проверка существования "временного контрольного файла". если его нет, то п.1, иначе сообщение пользователю о переходе к п.4
1. Выбор файла книги через Диалог открытия файлов
2. Выбор папки назначения через Диалог выбора папки
3. Выбор плей-листа со списком словарей из меню
4. Далее, автоматом:
- создание/обновление "временного контрольного файла"
-- создание папки сериала в папке назначения
-- проход в цикле по каждой текстовой серии:
---- обработка словарями
---- запись аудио
---- удаление текста серии
5. Если все серии преобразованы в аудио, то сообщение об успешном завершении; и удаление "временного контрольного файла"
Примечание. "Временный контрольный файл" содержит имена ранее выбранных: файла книги, папки назначения и плей-листа. Если он существует, значит предыдущий запуск скрипта завершился досрочно, и надо продолжить прерванную работу.
0. Проверка существования "временного контрольного файла". если его нет, то п.1, иначе сообщение пользователю о переходе к п.4
1. Выбор файла книги через Диалог открытия файлов
2. Выбор папки назначения через Диалог выбора папки
3. Выбор плей-листа со списком словарей из меню
4. Далее, автоматом:
- создание/обновление "временного контрольного файла"
-- создание папки сериала в папке назначения
-- проход в цикле по каждой текстовой серии:
---- обработка словарями
---- запись аудио
---- удаление текста серии
5. Если все серии преобразованы в аудио, то сообщение об успешном завершении; и удаление "временного контрольного файла"
Примечание. "Временный контрольный файл" содержит имена ранее выбранных: файла книги, папки назначения и плей-листа. Если он существует, значит предыдущий запуск скрипта завершился досрочно, и надо продолжить прерванную работу.
- tonio_k
- V.I.P.
Скрипты для Demagog
предлагаю именно этот пункт сделать автоматом. Но при первом запуске при отсутствии плейлиста, пусть выходит окно, в котором пользователь может выбрать последовательность словарей и присвоить алгоритм работы словаря, после чего сохраняет плей лист и при повторном запуске п.3 уже работает автоматом. Если пользователь использует несколько вариантов схем применения словарей, то пользователь сам создаст варианты скрипта и вручную укажет путь к нужному варианту файла с плей листом.
И сразу вопрос, а как со словарями, находящимися в другой папке (dic2)?
И еще один момент, во время работы скрипта, а именно во время записи аудио, попробуйте по-нажимать другие окна кроме статистики например на открытой книге- и текст с анимацией обработки может уже в новом окне оказаться. Вроде бы явных проблем это не вызывало, но мало ли что. Поэтому может на время работы скрипта полостью заблокировать все окна на предмет их смены? Пусть показывает только окно, в котором идет работа и все.
Можно добавить:
3.1. Выбор Выключить ПК? (Да/нет)
6. Если в 3.1. выбрали да - Выключить ПК
Отправлено спустя 26 минут 32 секунды:
Такая мысль, а может в calculator создать функцию использующую WSeries в которой "
После отработки WSeries в каждый файл в конец самой первой строки будет добавляться ". Моя книга" аналогично: Конец сериала N. Моя книга
- flegont
- V.I.P.
Скрипты для Demagog
Будет вот как. Пример:После отработки WSeries в каждый файл в конец самой первой строки будет добавляться ". Моя книга" аналогично: Конец сериала N. Моя книга
WSeries(11, [[d:/MP3]], 6000, true, 'Серия %d. Нахалка', 'Конец серии %d. Нахалка')
Т.е. параметры header и ender - это любые фразы, включающие в себя (в любом удобном пользователю месте) маркер %d для вставки номера серии
Отправлено спустя 5 часов 4 минуты 26 секунд:
Согласен.Выбор плей-листа со списком словарей из меню
предлагаю именно этот пункт сделать автоматом
Ну, может, не совсем автоматом, при запуске меню из 2 пунктов: Работа|Настройкиа как со словарями, находящимися в другой папке (dic2)?
А в настройках можно табличку завести: полное имя словаря | тип применения
Если указывать полные имена, то словари вообще могут быть в любых местах на компьютере
Если проблемы будут, то что-нибудь придумаю. Пока останется, как есть. "Принцип минимализма".по-нажимать другие окна кроме статистики например на открытой книге ... Вроде бы явных проблем это не вызывало, но мало ли что.
Согласен.Можно добавить:
3.1. Выбор Выключить ПК? (Да/нет)
P.S. Скрипт будет опубликован после выхода версии 359. Сперва пусть обкатается версия.
- tonio_k
- V.I.P.
Скрипты для Demagog
Может кому пригодится:
Если в нескольких ваших рабочих скриптах есть одни и те же одинаковые (стандартные) участки кода, например список словарей применяемых к текущему окну, то можно этот участок кода переместить в отдельный файл например slovar_osnov.lua
Допустим файл slovar_osnov.lua находится в папке с программой Demagog.exe в подкаталоге profiles
Тогда "Вызываться" этот стандартный участок кода будет через команду:
где:
HomeFolder - автоматически получаемый путь к папке, в которой находится программа Demagog.exe
profiles - подкаталог (...\Demagog\profiles)
Отправлено спустя 14 минут 11 секунд:
*Примечание!. На время выполнения dofile (HomeFolder('profiles')..'slovar_osnov.lua') основной скрипт приостанавливает свою работу. Т.е. вызов dofile в скрипте - это последовательная, а не параллельная операция.
Отправлено спустя 58 минут 22 секунды:
Еще момент, не стоит "прятать" в другой файл команды, отправляющие работу скрипта в другой его участок goto. Например:
Будет сообщение об ошибке, так как не найден ::HALT::
но если сделать так:
dofile (HomeFolder('profiles')..'shutdown_on.lua')
if a == 0 then goto HALT end
содержимое файла shutdown_on.luaто должно сработать, так как ссылка на HALT и сам ::HALT:: находится в основном скрипте
Если в нескольких ваших рабочих скриптах есть одни и те же одинаковые (стандартные) участки кода, например список словарей применяемых к текущему окну, то можно этот участок кода переместить в отдельный файл например slovar_osnov.lua
Допустим файл slovar_osnov.lua находится в папке с программой Demagog.exe в подкаталоге profiles
Тогда "Вызываться" этот стандартный участок кода будет через команду:
Код: Выделить всё
dofile (HomeFolder('profiles')..'slovar_osnov.lua')
HomeFolder - автоматически получаемый путь к папке, в которой находится программа Demagog.exe
profiles - подкаталог (...\Demagog\profiles)
Отправлено спустя 14 минут 11 секунд:
*Примечание!. На время выполнения dofile (HomeFolder('profiles')..'slovar_osnov.lua') основной скрипт приостанавливает свою работу. Т.е. вызов dofile в скрипте - это последовательная, а не параллельная операция.
Отправлено спустя 58 минут 22 секунды:
Еще момент, не стоит "прятать" в другой файл команды, отправляющие работу скрипта в другой его участок goto. Например:
► Показать
но если сделать так:
dofile (HomeFolder('profiles')..'shutdown_on.lua')
if a == 0 then goto HALT end
содержимое файла shutdown_on.lua
► Показать
- flegont
- V.I.P.
Скрипты для Demagog
Да, таким способом можно из скрипта вызывать другие скрипты.
Основной скрипт будет как бы сценарием, запускающим последовательно другие скрипты
Надо, в таких случаях, конечно быть внимательным. Скажем, в данном примере надо помнить, что переменная a определена не в основном скрипте. а в вызванном.
Но я бы кусок кода с вопросом о выключении компьютера оформил бы функцией:
Использование:
Основной скрипт будет как бы сценарием, запускающим последовательно другие скрипты
Надо, в таких случаях, конечно быть внимательным. Скажем, в данном примере надо помнить, что переменная a определена не в основном скрипте. а в вызванном.
Но я бы кусок кода с вопросом о выключении компьютера оформил бы функцией:
Код: Выделить всё
function ShutdownDialog()
local cap, itms, warn, a
if CurrentLang() == 'Russian' then
cap = 'Выключить компьютер после записи аудио?'
itms = {' ДА',' НЕТ'}
warn = 'После записи аудио, компьютер будет выключен!'
else
cap = 'Shut down computer after recording audio?'
itms = {' YES',' NO'}
warn = 'After recording audio, the computer will be turned off!'
end
a = Menu(cap,itms)
if a == 0 or a == 2 then return false end
if a == 1 then
ShowMessage(warn)
return true
end
end
-- Замечание: if a == 0 or a == 2 then return false end реагирует на 2 варианта
-- отказа пользователя: 0 - нажата клавиша Esc; 2 - выбран в меню ответ НЕТ
Код: Выделить всё
a = ShutdownDialog()
...
if a then
os.execute('shutdown /s') -- выключить компьютер
end
- tonio_k
- V.I.P.
Скрипты для Demagog
► Показать
Хотел использовать окно статистики как статус бар для украшательства - что бы в процессе работы скрипта обновлялось окно статистики с выводом текущих переменных
Отправлено спустя 19 минут 37 секунд:
сам нашел.
вместо:
print ('\nИдет первичная обработка... ')
использовать:
WAdd(0,-1,'\nИдет первичная обработка... ')
- flegont
- V.I.P.
Скрипты для Demagog
Именно так
А через print не получится, потому что результаты работы всех команд print в скрипте - выводятся в окно Статистики одновременно по окончании работы скрипта. До этого они просто накапливаются в памяти. Если в скрипте много команд печати, или хотя бы одна внутри цикла, то такая система накопления результатов в памяти и потом сброса в Статистику - экономит время выполния в разы.
А через print не получится, потому что результаты работы всех команд print в скрипте - выводятся в окно Статистики одновременно по окончании работы скрипта. До этого они просто накапливаются в памяти. Если в скрипте много команд печати, или хотя бы одна внутри цикла, то такая система накопления результатов в памяти и потом сброса в Статистику - экономит время выполния в разы.
- tonio_k
- V.I.P.
Скрипты для Demagog
flegont, пожелания по поводу скриптов Добавить такие возможности:
1) Как альтернатива вызова диалога открытия файлов - Вызов Библиотекаря с параметрами:
(Папка поиска файлов, Маска файлов, Искать так же во вложенных(true/false)) Что бы в скрипте в результате запуска сразу выходил список найденных файлов.
2) Пакетный конвертер PLS->DIC - так же выполнение через скрипт. Параметры:
Путь к файлу PLS, Папка куда сохранить, Учитывать регистр(true/false).
1) Как альтернатива вызова диалога открытия файлов - Вызов Библиотекаря с параметрами:
(Папка поиска файлов, Маска файлов, Искать так же во вложенных(true/false)) Что бы в скрипте в результате запуска сразу выходил список найденных файлов.
2) Пакетный конвертер PLS->DIC - так же выполнение через скрипт. Параметры:
Путь к файлу PLS, Папка куда сохранить, Учитывать регистр(true/false).
- flegont
- V.I.P.
Скрипты для Demagog
1) Я такую идею уже проверял. Интерпретатор категорически отказывается выполнять рекурсивные функции Демагога. Отрабатывает первый уровень и всё. Как только функция внутри себя вызывает опять же саму себя, то интерпретатор молча это дело игнорирует. Поэтому поиск во вложенных папках не срабатывает.
Поэтому особого толку от оформления Библиотекаря в виде функции интерпретатора - нет.
Можно ли написать чисто на интерпретаторе функцию, моделирующую основные особенности Библиотекаря? Наверное, да. И вложенные папки можно сканировать только силами интерпретатора.
Для такой функции будет одно ограничение: без поддержки юникода. Т.е. кроме русских и/или английских символов, никаких других при поиске по условиям - указывать будет нельзя.
2) Конвертер PLS очень сильно завязан на юникод. Иначе бы он не мог работать с транскрипцией IPA (МФА). Lua все файлы читает, как ansi-файлы, строго побайтно. Любой юникод таким образом превращается в абракадабру.
Заставить Демагога читать файлы словарей с транскрипцией МФА? Но, когда Демагог отдаст прочитанный файл интерпретатору, то весь юникод превратится в кучу знаков вопроса.
Так что здесь ответ однозначно - нет.
P.S. Почему разработчики Lua отказались от поддержки юникода? Ради компактности языка - не зря его называют "встраиваемый" язык Lua. Достаточно посмотреть в дистрибутиве Демагога на мизерный размер файла lua.dll А ведь это - полностью весь язык, со всеми его возможностями, довольно немалыми И, ради скорости. Это, наверное, самый быстрый интерпретируемый язык.
Поэтому особого толку от оформления Библиотекаря в виде функции интерпретатора - нет.
Можно ли написать чисто на интерпретаторе функцию, моделирующую основные особенности Библиотекаря? Наверное, да. И вложенные папки можно сканировать только силами интерпретатора.
Для такой функции будет одно ограничение: без поддержки юникода. Т.е. кроме русских и/или английских символов, никаких других при поиске по условиям - указывать будет нельзя.
2) Конвертер PLS очень сильно завязан на юникод. Иначе бы он не мог работать с транскрипцией IPA (МФА). Lua все файлы читает, как ansi-файлы, строго побайтно. Любой юникод таким образом превращается в абракадабру.
Заставить Демагога читать файлы словарей с транскрипцией МФА? Но, когда Демагог отдаст прочитанный файл интерпретатору, то весь юникод превратится в кучу знаков вопроса.
Так что здесь ответ однозначно - нет.
P.S. Почему разработчики Lua отказались от поддержки юникода? Ради компактности языка - не зря его называют "встраиваемый" язык Lua. Достаточно посмотреть в дистрибутиве Демагога на мизерный размер файла lua.dll А ведь это - полностью весь язык, со всеми его возможностями, довольно немалыми И, ради скорости. Это, наверное, самый быстрый интерпретируемый язык.
- tonio_k
- V.I.P.
Скрипты для Demagog
Библиограф - не горит на самом деле. Конвертер PLS нужен мне только потому, что постоянно сбиваются папки при открыти и папки для сохранения - стоит только что то в Демагоге открыть или сохранить. Тогда может возможен консольный через bat вариант решения этого вопроса? Или как то "заморозить" в настройках папки открытия и сохранения по умолчанию?
Отправлено спустя 1 минуту 36 секунд:
Или скомпилировать отдельный консольный exe только под конвертор?
Отправлено спустя 1 минуту 36 секунд:
Или скомпилировать отдельный консольный exe только под конвертор?
- balaamster
- Обыватель
Скрипты для Demagog
Я по незнанию был удивлён длительностью появления результата, когда при тестах решил вывести список из более 6000 строк с путями к файлам, через print при итерации.
Попробовал, для удобства, обернуть WAdd(0,-1,string) в функцию:
Код: Выделить всё
function WLog(s)
WAdd(0,-1,tostring(s)..'\n')
end
В учебных материалах по Python неоднократно встречал информацию, что конкатенация получается более затратна, чем string.format
По Lua не нашёл подобного, при беглом просмотре выдачи в гугле, по запросу concatenation versus string.format
Решил попробовать такой пример:
► Показать
► Показать
- flegont
- V.I.P.
Скрипты для Demagog
1) О "заморозке" папок открытия /сохранения всерьез как-то не думал... Как операционная система их запоминает, так оно и есть. В общем, надо выбрать время, разобраться
2) WLog - красиво, спасибо А по поводу вывода на печать, тут такое дело. Связь Delphi с Lua обеспечивает библиотека VerySimpleLua. В ней предусмотрено переопределение стандартной команды print() для нужд той программы, в которую интерпретатор встроен. Я решил это так. Результаты всех команд print конкатенируются в строку, объявленную в основной программе, в самом Демагоге. Строка потом отображается компонентом Richedit, тоже на уровне Демагога. Так что все тормоза от конкатенации - это дельфийские, т.с. тормоза.
На уровне Lua это не ускорить.
"Эмбаркадеровцы" - нынешние владельцы Delphi, утверждают, что массовые конкатенации они оптимизировали на уровне компилятора, так что (если это правда), и на уровне Дельфи мало что можно сделать.
Отправлено спустя 9 часов 15 минут 45 секунд:
Хм... провел эксперимент на своем компьютере.
Проверка скорости выполнения команды print:
Результат:
Начало: 11/03/18 09:02:55
строка 1
...
строка 1000000
Окончание: 11/03/18 09:02:56
Один миллион строк за 1 сек.
2) WLog - красиво, спасибо А по поводу вывода на печать, тут такое дело. Связь Delphi с Lua обеспечивает библиотека VerySimpleLua. В ней предусмотрено переопределение стандартной команды print() для нужд той программы, в которую интерпретатор встроен. Я решил это так. Результаты всех команд print конкатенируются в строку, объявленную в основной программе, в самом Демагоге. Строка потом отображается компонентом Richedit, тоже на уровне Демагога. Так что все тормоза от конкатенации - это дельфийские, т.с. тормоза.
На уровне Lua это не ускорить.
"Эмбаркадеровцы" - нынешние владельцы Delphi, утверждают, что массовые конкатенации они оптимизировали на уровне компилятора, так что (если это правда), и на уровне Дельфи мало что можно сделать.
Отправлено спустя 9 часов 15 минут 45 секунд:
Хм... провел эксперимент на своем компьютере.
Проверка скорости выполнения команды print:
Код: Выделить всё
print('Начало: '..os.date("%c"))
for i = 1,1000000 do
print('строка '..i)
end
print('Окончание: '..os.date("%c"))
Начало: 11/03/18 09:02:55
строка 1
...
строка 1000000
Окончание: 11/03/18 09:02:56
Один миллион строк за 1 сек.
- balaamster
- Обыватель
Скрипты для Demagog
Попробовал на своём ПК - аналогично, 1,7 сек.
В моём примере долгий вывод print был из-за длительного завершения скрипта в целом - обход каталогов в глубину, медленная работа диска.
По AllFolders и WLog есть предложения:
Из выдачи AllFolders убирать первый и второй элементы списка - ссылки на текущий (.) и вышележащий (..) каталоги.
► Показать
Возможно, поменять как-то так:
► Показать
- flegont
- V.I.P.
Скрипты для Demagog
1) Насчет служебных папок . и .. я размышлял еще когда сочинял функцию AllFolders. Решил, что пусть будут в списке. Всё по-честному: функция называется ВсеПапки, в переводе на великий и могучий.
Если пользователю они не нужны, то цикл по списку папок он может начинать не с 1, а с 3. Зато их присутствие в списке позволит отобразить меню со ссылками "на верхние уровни".
Эдак можно написать функцию - файловый менеджер
2) Да, недоглядел с проверкой типа s поправлю.
Если пользователю они не нужны, то цикл по списку папок он может начинать не с 1, а с 3. Зато их присутствие в списке позволит отобразить меню со ссылками "на верхние уровни".
Эдак можно написать функцию - файловый менеджер
2) Да, недоглядел с проверкой типа s поправлю.
- flegont
- V.I.P.
Скрипты для Demagog
Поправил так (и обновил дистрибутив):
Пример:
x = WLog(sin(1)^2+cos(1)^2-2)
WLog(x)
В окно Статистики добавятся строки:
-1.0
4
Код: Выделить всё
function WLog(s)
if not s then
s = ''
else
if type(s) ~= 'string' then s = tostring(s) end
end
WAdd(0,-1,s..'\r')
return #s
end
x = WLog(sin(1)^2+cos(1)^2-2)
WLog(x)
В окно Статистики добавятся строки:
-1.0
4
- balaamster
- Обыватель
Скрипты для Demagog
И правда, недальновидное предложение у меня было. В сторону урезания функционала.
Решил поиграться с этой идеей, черновик файл-менеджера:
upd.: поправил ошибку в скрипте.
► Показать
Отлично, я проверку типа упустил из виду
Тогда, преобразование в строку здесь уже не потребуется, по идее: WAdd(0,-1,tostring(s)..'\r')
- flegont
- V.I.P.
Скрипты для Demagog
1) Точно, лишнее преобразование tostring не нужно. Убрал.
2) Черновик ф.мен. красиво работает
2) Черновик ф.мен. красиво работает
- tonio_k
- V.I.P.
Скрипты для Demagog
Вариант функции Одновременного применения словарей и записи аудио к сериалу.
Преимущество - в случае внештатного прерывания процесса записи в аудио достаточно повторно прогнать эту функцию
flegont, думаю в function FilterToAll(folder, mask, diclist) в дистрибьюторе нужно по умолчанию добавить IgnoreDicPan()
Отправлено спустя 30 минут 18 секунд:
в демагоге F2 нажимаю - пусто дает. Не понял как получить ind для срабатывания:
if (ind == 1) then
os.execute('shutdown /s') -- выключить компьютер
end
Преимущество - в случае внештатного прерывания процесса записи в аудио достаточно повторно прогнать эту функцию
► Показать
Отправлено спустя 30 минут 18 секунд:
Код: Выделить всё
ShutdownDialog(ind)
ShowMessage(ind)
if (ind == 1) then
os.execute('shutdown /s') -- выключить компьютер
end
- flegont
- V.I.P.
Скрипты для Demagog
Пример 1:
Пример 2:
Отправлено спустя 24 минуты 50 секунд:
Я потестирую WFilter, проверю - так ли это на самом деле?
UPDATE.Проверил. WFilter полностью независима от Панели словарей. Она грузит словарь непосредственно из указанного ей файла, и работает только с ним.
А вот WAudio - завязана на настройки Панели словарей. С одной стороны - это хорошо, используется набор словарей, настроенный заранее. Но, если текст уже обработан словарями!? Тогда либо отключать все словари в Панели словарей перед запуском скрипта с функцией WAudio, либо IgnoreDicPan в начале скрипта.
Отправлено спустя 6 минут 31 секунду:
Если, например, ее нечаянно применить к папке, где хранилась коллекция любимых книг
Какая-то нужна защита от ошибок пользователя...
Код: Выделить всё
confirm = ShutdownDialog(1) -- меню покажет выделенной по умолчанию строку 1 ("ДА")
if confirm then -- если была нажата строка "ДА" то confirm - истинно
os.execute('shutdown /s') -- выключить компьютер
end
Код: Выделить всё
confirm = ShutdownDialog(2) -- меню покажет выделенной по умолчанию строку 2 ("НЕТ")
if confirm then -- если была нажата строка "ДА" то confirm - истинно
os.execute('shutdown /s') -- выключить компьютер
end
Отправлено спустя 24 минуты 50 секунд:
У меня такое сложилось убеждение, что я в свое время предусматривал изначальное игнорирование Панели словарей функцией WFilter(), спрятанной внутри FilterToAll, тогда IgnoreDicPan там уже не нужно.в function FilterToAll(folder, mask, diclist) в дистрибьюторе нужно по умолчанию добавить IgnoreDicPan()
Я потестирую WFilter, проверю - так ли это на самом деле?
UPDATE.Проверил. WFilter полностью независима от Панели словарей. Она грузит словарь непосредственно из указанного ей файла, и работает только с ним.
А вот WAudio - завязана на настройки Панели словарей. С одной стороны - это хорошо, используется набор словарей, настроенный заранее. Но, если текст уже обработан словарями!? Тогда либо отключать все словари в Панели словарей перед запуском скрипта с функцией WAudio, либо IgnoreDicPan в начале скрипта.
Отправлено спустя 6 минут 31 секунду:
Хорошая мысль. Но, как я понял, эта функция последовательно удаляет уже обработанные в папке текстовые файлы.FilterToAll(folder, mask, diclist)
Если, например, ее нечаянно применить к папке, где хранилась коллекция любимых книг
Какая-то нужна защита от ошибок пользователя...
- tonio_k
- V.I.P.
Скрипты для Demagog
FilterAudioToAll можно в функцию добавить диалог предупреждение: Удалять все файлы по маске к которым будут применены словари? Да/Нет
Отправлено спустя 7 минут 12 секунд:
Этот диалог заставит экспериментатора засомневаться в правильности указания путей к книгам в работе скрипта.
А слишком много защиты это уже не "продвинутый пользователь"
Отправлено спустя 7 минут :
Такой вопрос. Как будут работать конфликтные функции?
Например одинаковые названия функции но с разными кодами. Одна в work/mylib, другая в calculate?
А Если эти одноименные но разные по коду ф-ции в одном файле lua?
- flegont
- V.I.P.
Скрипты для Demagog
Да, согласен. Короткого предупреждения будет достаточно.добавить диалог предупреждение
В обоих случаях самое последнее объявление функции перекроет все предыдущие.Как будут работать конфликтные функции? А Если эти одноименные но разные по коду ф-ции в одном файле lua?
1) Библиотека calculator.lua автоматически присоединяется к любому скрипту, перед его выполнением. Если в скрипте присоединяется библиотека mylib, то совпадающие в ней объявления функций перекроют те, что указаны в calculator.lua.
Это - логично. Таким способом пользователь сможет переопределять "стандартные" функции калькулятора. Конечно, это требует большой осторожности, и знания Lua. В calculator.lua многие функции используют другие функции из calculator.lua. Переопределив какую-то одну из них, можно очень удачно развалить всё
2) Если в одном скрипте одна и та же функция определена несколько раз, действовать будет самое последнее определение. (Точнее: каждое определение действует до тех пор, пока не встретится следующее)
Пример:
► Показать
- tonio_k
- V.I.P.
Скрипты для Demagog
Код: Выделить всё
homedir = Folders("ВЫБЕРИТЕ ПАПКУ с книгами \nПапка по умолчанию: ", 'D:\\MP3', true)
ind = WActive() -- получить номер активного окна
WOpen(ind,homedir..'Книга1.txt')
a = WName(ind) -- получить Путь+Имя+расширени файла
ShowMessage(a)
- tonio_k
- V.I.P.
Скрипты для Demagog
в цикле WAudio(0,folder,false) после каждого созданного аудио файла выдает звуковое оповещение о завершении.
Рассмотрите, пожалуйста, возможность "убрать" из WAudio звуковой сигнал. Как вариант перенести его в отдельную функцию. Кому надо, тот в конце скрипта ее пропишет что бы срабатывал при завершении работы скрипта
- flegont
- V.I.P.
Скрипты для Demagog
Подумаю над этим. Наверное, лучше звуковой сигнал оставить только для штатной записи аудио Демагогом. А в интерпретаторе пусть WAudio работает молча. Не шарманка ведь
- tonio_k
- V.I.P.
Скрипты для Demagog
Иногда нужно прервать работу Демагога в процессе работы словарей или записи в аудио. Раньше запускал Диспетчер задач, находил в процессах Demagog.exe - и завершал процесс.
Сейчас такое простое решение:
создать скрипт например ВЫКЛЮЧИТЬ Демагог.lua с единственной строкой: Во время работы Демагога активируем любое окно, в котором не проводится работа,и запускаем скрипт ВЫКЛЮЧИТЬ Демагог.lua - Демагог закрывается на любом этапе своей работы.
Как вариант, можно os.exit() написать в любом пустом окне Демагога и нажать F2
Сейчас такое простое решение:
создать скрипт например ВЫКЛЮЧИТЬ Демагог.lua с единственной строкой:
Код: Выделить всё
os.exit()
Как вариант, можно os.exit() написать в любом пустом окне Демагога и нажать F2
- flegont
- V.I.P.
Скрипты для Demagog
Хорошо придумано
Мне даже в голову не приходило... пора начинать изучать свою собственную программу
Мне даже в голову не приходило... пора начинать изучать свою собственную программу
- tonio_k
- V.I.P.
Скрипты для Demagog
flegont, может os.exit() - сделать "штатной" функцией завершения работы Демагога? Нажал на крестик и программа закрылась несмотря на запущенные процессы. Ну хочет пользователь закрыть программу пусть она закроется. Можно дополнительное окно "Закрыть программу?" - если нужно для подстраховки.
- flegont
- V.I.P.
Скрипты для Demagog
Лучше это сделать дополнительной опцией, что-нибудь вроде "Экстренный выход" с комментарием в строке состояния: "Выход из программы с прерыванием всех незавешенных операций". И какую-нибудь комбинацию клавиш, не слишком простую, типа Ctrl+Alt+Q
Отправлено спустя 2 часа 32 минуты 20 секунд:
А вообще-то игра не стоит свеч. В общем случае нет никакого универсального способа насильственно прервать выполнение программы из самой программы.
Пример.
В любом свободном окне пишем:
и нажимаем F2.
Всё. 2-й закон роботехники в действии Программа изо всех сил выполняет невыполнимое задание и не реагирует больше ни на что.
За одним исключением. Не помню, как в Win 7, давно в ней не работаю, а в 10-ке единственное живое место - это крестик закрытия окна программы. Нажатие более 1 раза вызывает сообщение: "Программа не отвечает. Подождать отклика | Завершить".
Выбираю завершить, и все дела.
Отправлено спустя 2 часа 32 минуты 20 секунд:
А вообще-то игра не стоит свеч. В общем случае нет никакого универсального способа насильственно прервать выполнение программы из самой программы.
Пример.
В любом свободном окне пишем:
Код: Выделить всё
while true do end -- бесконечный цикл
Всё. 2-й закон роботехники в действии Программа изо всех сил выполняет невыполнимое задание и не реагирует больше ни на что.
За одним исключением. Не помню, как в Win 7, давно в ней не работаю, а в 10-ке единственное живое место - это крестик закрытия окна программы. Нажатие более 1 раза вызывает сообщение: "Программа не отвечает. Подождать отклика | Завершить".
Выбираю завершить, и все дела.
- balaamster
- Обыватель
Скрипты для Demagog
Проверил, в семёрке также.
Пример с "while true do end" навёл меня на мысль об эксперименте:
Код: Выделить всё
local st = os.clock()
i = 1
while os.clock() - st < 1 do
i = i + 1
end
WLog(i)
В мануалах по Lua говорилось, что к переменным, объявленным локально, обращение происходит быстрее, чем к глобальным.
Если в вышеприведённом примере объявлять "i = 1", то получаем вот такое количество итераций за секунду (три отдельных запуска): 4617750, 4613107, 4632709
При объявлении "local i = 1": 6583886, 6246269, 6456704
Получается ощутимо быстрее.
- tonio_k
- V.I.P.
Скрипты для Demagog
А переменные объявленные локально как работают с функциями? Смею предположить что скорость "расчетов" внутри скрипта может и будет быстрее, но основное время будет работать сам Демагог. И особого прироста в общей скорости не прибавится?
- flegont
- V.I.P.
Скрипты для Demagog
Думаю, да. Вполне показательный тест, спасибо. (И за пробу с мертвым циклом на 7-ке )такой пример можно считать "бенчмарком"?
Код: Выделить всё
переменные объявленные локально
А в скриптах - кому как нравится. Но, опять же, если я написал скрипт, вызывающий другие скрипы, а в них есть переменные с такими же именами, но выполнящие другие роли... это ж какая каша может получиться?
- tonio_k
- V.I.P.
Скрипты для Demagog
вот вы напомнили о вопросе, который давно хотел задать. Что касается переменных в функциях в калькуляторе. Есть вероятность накладки переменных объявленных в основном скрипте и одноименными переменными в функции?
- flegont
- V.I.P.
Скрипты для Demagog
Если в функции все переменные объявлены локальными, то всё в порядке. Локальные переменные будут действовать только внутри функции. В вызывающем блоке они не видны. А ни одна из глобальных переменных внутри функции не использована. И никаких накладок в таком случае не будет.
Отправлено спустя 11 минут 54 секунды:
Следует также помнить, что переменная-счетчик цикла - всегда локальная (автоматически, без объявления) и видна только внутри цикла.
Типичная ошибка думвть, что переменная i существует после окончания этого цикла и якобы равна 10
Отправлено спустя 11 минут 54 секунды:
Следует также помнить, что переменная-счетчик цикла - всегда локальная (автоматически, без объявления) и видна только внутри цикла.
Код: Выделить всё
for i = 1,10 do end
- flegont
- V.I.P.
Скрипты для Demagog
Дистрибутив вер. 359 обновлен до 360.
Очень небольшое изменение/дополнение в составе функций интерпретатора.
Очень небольшое изменение/дополнение в составе функций интерпретатора.
► Показать
- tonio_k
- V.I.P.