Версия для печати темы
MyDC.ru _ Готовые скрипты для PtokaX _ Бот-конвертер/калькулятор ( Ip,cidr,os.time,шара )
Автор: district 4.4.2009, 13:45
Название скрипта: Georgian Calculator
Версия скрипта: v2 rev.27.05.09
Версия API: API 1, API2
Автор: district
Описание скрипта :
Хочу поделиться вот таким ботом-конвертером (калькулятором). Лично мне наличие такого бота помогло начать лучше ориентироваться в том, что такое "os.time", "IP-адрес", "CIDR-адрес" и вообще, вспомнить что такое "двоичный" (бинарный) код. Особо помогает разбираться в запутанных whois-данных диапазонов и роутов различных провайдеров.
Очень надеюсь, что бот пригодится и технически ориентированным админам, и любознательным юзерам.
Все функции бота видно из картинки.
Изменения :
Прикреплены файлы новой ревизии от 27 мая 2009
Изменение от 02.11.09 Поддержка скрипта прекращена
Автор: Setuper 4.4.2009, 15:30
Приятно, что хоть кто-то смотрит в тему "Функции Для Разработчиков"
Автор: district 4.4.2009, 21:55
Найдена ошибка в функции NoSpareZeros (захотелось вот сделать такую, для убирания из IP нечаянно введенных нулей, просто для красоты, на вычисление они не влияют). Вроде исправил, передобавляю.
Попутно попробовали с товарищем сконвертировать под API2 - тоже вроде работает, но замечен эффект, при вводе os.time на его хабе выдается дата плюс один час, что-то связанное с летним временем. Не моем хабе прямое и обратное преобразование даты полностью бьются.
Изменения от 05.04.2009
Доработано. Покончено с мракобесием пошагового (погодового, помесячного и т.д.) подсчета секунд, прошедших от опорной даты, при вычислении os.time, использован стандартный метод os.time ([table]). Добавлено вычисление даты и вычисление os.time применительно ко Гринвичскому времени ( GMT ). Доведены наконец, вроде бы, до ума две функции "защиты от дурака" и коррекции неверного формата введенного IP-адреса.
Однако, нет гарантии, что скрипт вообще невозможно повесить каким-нибудь некорректным вводом... Тестирование продолжается.
Автор: степашка 5.4.2009, 17:48
большое спасибо. очень прикольно. у народа пользуется спросом )))
Автор: district 5.4.2009, 18:02
Вот и здорово, не ожидал даже) Однако, бьюсь над закрытием существенных дырок в счислении дат... Еще оптимизирована защита от корявого ввода IP-адреса. Как только доделаю сразу выложу. Пока что нет должной защиты от некорректного ввода даты (предельно допустимого снизу и сверху).
Автор: D'aspid 5.4.2009, 18:18
Будем ждать. Многим пользователям будет как нельзя кстати этот скрипт
Автор: степашка 5.4.2009, 19:29
в принципе можно типа этого туда добавить (прилагаю)
Автор: district 5.4.2009, 21:37
За уравнения спасибо, правда, не знаю насколько это направление актуально для так сказать нашей дц- и интернет- тематики. На свежую голову посмотрю потом.
Ну вот, доведена наконец, вроде бы, до ума функция "защиты от дурака" и коррекции неверного формата введенного IP-адреса (кто успел скачать - NoSpareZeros признана вообще неактуальной и выброшена, все оказалось намного проще, извиняюсь).
Ну и насколько оказалось возможным, сделана подстраховка от ввода некорректной даты или некорректного значения os.time при получении даты. Формат выводимой даты сделан в точности таким, какой требуется для ввода даты, - для облегчения обратного вычисления (встречной проверки).
Ниже несколько слов для админов, начинающих разработчиков, всех тех, кто как и я захочет получше понять
что такое даты в Птоке, что такое os.date и os.time.
Цитата
os.time ([table])
Возвращает текущее время при вызове без аргументов, или время и дату, указанные в передаваемой таблице. Эта таблица должна иметь поля year, month, и day, и может иметь поля hour, min, sec, и isdst (описание этих полей см. в описании функции os.date).
Возвращаемое значание – это число, значение которого зависит от системы. В POSIX, Windows, и некоторых других системах, это число соответствует количеству секунд, отсчитываемому от некоторого заданного момента времени ("эпоха"). В других системах, значение не специфицировано, и число, возвращаемое функцией time, может быть использовано только как аргумент функций date и difftime.
Примечание. "Некоторый заданный момент" в нашем случае - это дата 01.01.1970 00:00:00 Гринвича, или 01.01.1970 (00 + смещение от Гринвича ):00:00 , если считаем применительно к локальной дате/времени.
Максимально возможное для перевода в форматированную дату значение os.time составило 2147505247 (для GMT !!!). Для локального времени в том случае, если ваш комп находится к востоку от гринвича, это значение будет соответственно меньше на разницу вашего локального времени и временем Гринвича в секундах. А вот попробовать "оказаться к западу от Гринвича" и посмотреть что получится, руки пока не дошли.
На всякий случай, если не сработают все предыдущие защиты, функция вычисления os.time вернет строку "Ошибка", если ей не удастся получить os.time(tDate).
Автор: Setuper 5.4.2009, 21:51
http://mydc.ru/topic574.html
Автор: Trans 11.4.2009, 7:40
Название - Грузинский калькулятор (так написано в самом скрипте) - откуда такое название?
Просто интересно.
По теме думал, что имя автора такое - Георгий, но в скрипте русским по белому - Грузинский калькулятор.
Автор: district 11.4.2009, 7:45
Работаю над оптимизацией и расширением функций, почти готов очередной вариант. Возник вопрос : нет ли у кого под рукой стандартной функции раскодирования в строку представления больших чисел вида "2.8428972647776e+16 Байт" (результат для 25.25 Pb ). Чтобы не тратить время на изобретение велосипеда. Если уж сделан счет байты в петабайты, логично было бы и обратное преобразование иметь, пусть даже в длиннющем виде.
Trans
Попробуй заставить его посчитать, скажем, os.time для 01.01.1968_00:00:00 или допустим для 29.02.2001_00:00:00 - тогда сам увидишь почему
Автор: степашка 11.4.2009, 15:19
Цитата(Trans @ 11.4.2009, 8:40)
Название - Грузинский калькулятор (так написано в самом скрипте) - откуда такое название?
Просто интересно.
По теме думал, что имя автора такое - Георгий, но в скрипте русским по белому - Грузинский калькулятор.
=======================
почитай комментарии внутри самого скрипта и поймёшь
Автор: district 11.4.2009, 18:54
Подготовлена новая редакция бота.
Изменения и дополнения :
1.Добавлена функция расчета IP-адреса вида a.b.c.d+n и обратное преобразование.
2.Добавлен альтернативный метод счета шары : теперь можно переводить байты в Мб, Гб .. и т.д. с округлением вниз (до 3 знаков после запятой) или использовать "умный" метод ( предложен alex82 ). Разницу, как говорится, нужно просто "почувствовать"
3.При переводе больших значений шары в байты (больше 90.9494... сколько-то там ТБ) в Байты калькулятор теперь просто отказывается считать, преобразование числового формата вида, например, "1.0000058254623e+14" в длинный ряд все-таки байтов пока не реализовано, да и актуальность этого дела под вопросом.
4.Менюшку топерь можно посылать или только зареганным, или всем юзерам, в развернутом виде (как на картинке), или с подпунктами.
5.Везде для преобразований связанных с IP-адресами сделан промежуточный показ IP-адресов в бинарном виде.
6.Сделан показ введенных значений для всех исходных преобразуемых величин в результатах счета.
7.Проведена общая оптимизация кода, насколько глаз хватило, большей частью путем замены вызова глобальных ЛУА-функций на вызов локальных методов.
Под вопросом остается алгоритм проверки валидности введенного CIDR-адреса при его преобразовании в привычный IP-диапазон, и алгоритм вычисления наиболее близкого введенному валидного значения, то же самое при обратном преобразовании. Чувствую что можно улучшить, но руки пока не дошли.
Файлы передобавлены.
Автор: степашка 11.4.2009, 19:54
класс! спасибо
Автор: Setuper 12.4.2009, 22:35
Локальные методы - это конечно же оптимизация, но локальными могут быть так же и переменные. Я бы сказал, что в данном коде значительной оптимизацией будет перевод всех глобальных переменных в локальные.
Например:
Код
local Bot = "Грузинский.Калькулятор"
local bRegOnly = false -- доступ к функциям бота только для зареганных : по умолчанию отключено
local bUseFullMenu = false -- true если использовать развернутое меню, false - если с подпунктами
local iShareFormatIdx = 3 -- до скольки знаков после запятой округлять шару при "умном" округлении
local sMenuWay = "Грузинский калькулятор"
local sMove = false -- смещение от GMT в часах
local iDiff = false -- разница между локальным и Гринвичским временем в секундах
function OnStartup()
local RTime = os.time(os.date("*t"))
local GMTTime = os.time(os.date("!*t"))
iDiff = RTime - GMTTime
if iDiff >= 0 then
sMove = "+"..tostring(iDiff/3600)
else
sMove = tostring(iDiff/3600)
end
end
переменные RTime и GMTTime можно вовсе убрать. Зачем выделять лишнюю память под не используемые больше нигде переменные, когда можно написать так:
Код
iDiff = os.time(os.date"*t") - os.time(os.date"!*t")
По поводу оптимизации можно дискуссировать долго
Вот, допустим, посмотрим на код функции UserConnected.
Кошмар сколько конкатенаций
. Ведь это всё выполняется при каждом входе пользователя на хаб.
Всё это дело можно же значительно оптимизировать, если написать это всё вне функции UserConnected, тогда это всё дело выполниться только один раз - при старте скрипта. То есть написать так:
Код
if not bUseFullMenu then
bUseFullMenu = "$UserCommand ............"
else
bUseFullMenu = "$UserCommand ............"
end
function UserConnected(user)
if not bRegOnly or ( bRegOnly and RegMan.GetReg(user.sNick) ) then
Core.SendToUser(user, bUseFullMenu)
end
end
При этом можно одну переменную использовать 2 раза (а не заводить новую переменную). Переменная bUseFullMenu сначала используется для определения типа меню, а потом для хранения меню. (так как переменная фактически перестаёт иметь одну "роль", то её бы следует назвать как-то по-другому, например, просто Menu, и Венгерская нотация для такого рода переменных теряет свой смысл, поэтому спереди не пишем ни b, ни s
)
По поводу конкатенаций тут (пункт 3): http://mydc.ru/topic1018.html
Автор: district 13.4.2009, 5:22
И насчет переменных времени, и насчет выработки вида меню однократно при старте - принято к сведению, спасибо. Две переменные были оставлены чисто интуитивно (для себя чтоб получше усвоить и затвердить).
Файлы передобавлены.
ЗЫ теперь я понял, откуда брался прирост расхода памяти, как часики тикал. Это, получается, меню создавалось с каждым входом нового юзера на хаб.
Автор: Setuper 13.4.2009, 11:09
Вот это:
Код
local sMove = false -- смещение от GMT в часах
local iDiff = false -- разница между локальным и Гринвичским временем в секундах
тоже не просто так написано. Если этого не написать, то эти переменные будут глобальными, так как переменная при первом использовании становится глобальной, если она не была до этого объявлена как локальная. Тоже самое касается и переменной sMenu. Она тоже глобальная, и для того, чтобы сделать её локальной нужно объявить её вне функции:
Код
local sMenu = false
Пишу везде false только для того, чтобы в случае если переменная не будет использоваться по каким-либо причинам, то она занимала по минимому памяти.
Код
local Bot = "Грузинский.Калькулятор"
local bRegOnly = false -- доступ к функциям бота только для зареганных : по умолчанию отключено
local bUseFullMenu = false -- true если использовать развернутое меню, false - если с подпунктами
local iShareFormatIdx = 3 -- до скольки знаков после запятой округлять шару при "умном" округлении
local sMenuWay = "Грузинский калькулятор"
-- объявления локальных переменных вместо глобальных!
local sMove = false
local iDiff = false
local sMenu = false
function OnStartup()
iDiff = os.time(os.date("*t")) - os.time(os.date("!*t")) -- разница между локальным и Гринвичским временем в секундах
if iDiff >= 0 then
sMove = "+"..tostring(iDiff/3600) -- смещение от GMT в часах
else
sMove = tostring(iDiff/3600)
end
CreateMenu()
end
Далее...
Вместо
Код
local _,_,cmd = data:find("%b<>%s+%p(%S+)")
лучше писать так:
Код
local cmd = data:match"%b<>%s+%p(%S+)"
Однако, в условных операторах лучше использовать метод find:
Код
if s:find"^%d+$" then
Далее...
Посмотрим на код:
Код
Core.SendToUser(user,"<"..Bot.."> *** Ошибка ! Неверный формат числа!")
В данном коде используется переменная Bot, которая содержит имя бота, а под строки
"<" и
"> *** Ошибка ! Неверный формат числа!" выделяется память -
под каждую! Получается что выделяется 4 байта на каждую строку, то есть 8 байт (так как 2 строки). Выделенная память очиститься со временем уборщиком мусора.
Тут я объяснил чем плоха конкатенация, поэтому её надо по возможности избегать.
Поэтому в данном случае лучше написать так:
Код
Core.SendToUser(user, ("<%s> *** Ошибка ! Неверный формат числа!"):format(Bot))
Тут 4 байта выделится только под 1 строку:
"<%s> *** Ошибка ! Неверный формат числа!"Код
Core.SendToUser(user, ("<%s> *** Результат подсчета для %s Байт : %s"):format(Bot, s, GetNormalSize(s,iShareFormatIdx)))
Автор: district 26.5.2009, 23:38
Обнаружена пара ошибок, допущенных при улучшайзинге. В первый пост передобавлены файлы новой ревизии.
Автор: ((((F@UST)))) 28.3.2010, 15:50
district Так а где этот твой бот???Скинь плиз скрипт под API2
Автор: Артём 10.12.2012, 22:22
Исправлена ошибка, перезалит 10 февраля 2014 года
Georgian_Calculator_API2__v3.0_rev.10.06.10.lua ( 32.36 килобайт )
: 8
Автор: Артём 7.2.2014, 20:48
Ошибка из скрипта выше.
При попытке конвертировать "Дата в формате --> os.time // Дата GTM +2 --> os.time GTM +2" ввожу 07.02.2014_17:40:02
выбивает ошибку
Georgian Calculator[API2]_v3.0_rev.10.06.10.lua:547: attempt to index global 'iYear' (a number value)
строка
Код
if iYear:len() < 4 then value = "Генацвали, жадний, да? Или ленивий? Годь нужно четыр"..
Помогите исправить, сам не справляюсь.
Автор: Ksan 7.2.2014, 21:17
Цитата
ввожу 07.02.2014_17:40:02
Попробуй перевернуть это -
07.02.2014, то есть, год, месяц, день чтоб было, а не наоборот..
Автор: Артём 7.2.2014, 21:41
Код
s1..sMenuWay.."\\Дата в формате --> os.time\\Дата GMT"..sMove.." --> os.time GMT"..sMove..s3.." !RcalcD %[line:Введите дату GMT"..sMove..", пример: 01.01.2008_12:30:00]"..s4..
ввожу как в примере, да и скрипт выдаёт дату вот так...
[20:43:08] <Грузинский.Калькулятор> *** 07.02.2014_20:43:08
значит ввожу правильно, может автор не рассчитывал, что скрипт доживёт до 2014 года, типа конец света и всё такое.
Но всё же, ошибка сыпется, как исправить не знаю.
Автор: Ksan 7.2.2014, 23:17
Артём
Сейчас вот спешал фор Ю поставил калькулятор, ответ получил:
Цитата
[03:16:07] <Грузинский.Калькулятор> *** Результат подсчета для даты ( GMT+7 ) 08.02.2014_03:15:55 : 1391804155
Что делаю не так?
Автор: Артём 7.2.2014, 23:43
вопрос в другом, что я не так делаю, буду тогда двигать скрипт, пробовать...
P.S. может из-за версии хаба, у меня 0.5.0.0 mod 3, сейчас попробую на разных версиях PtokaX.
P.S.s испробовал на 0.4.1.0, 0.4.1.1, 0.4.1.2 и на 0.5.0.0 везде одно и то же, ошибка...
Цитата
[22:56:14] <PtokaX> Этот хаб работает под управлением PtokaX DC Hub 0.4.1.2 (Время работы: 0 дней, 0 часов, 3 минут / Юзеры: 0)
[22:56:20] <Грузинский.Калькулятор> *** 07.02.2014_22:56:20
[22:56:29] <Артём> !RcalcD 07.02.2014_22:56:20
дату показывает нормально, при попытки пересчитать в os.time ошибка на всех версиях что пробовал, скриптов нет, один калькулятор.
Автор: Alexey 9.2.2014, 23:11
- В строке 531 замени find на match.
- В строке 547 на выбор:
a. Замени iYear на sYear.
b. Замени условие на аналогичное по действию if iYear < 1000 then blah-blah-blah
Автор: Артём 10.2.2014, 1:16
Alexey, Спасибо.
P.S. Перезалил скрипт с исправлением. (старые строки закомментил после исправленных, может кому-то исправление не нужно будет и вернёт старое)
Автор: Ksan 10.2.2014, 1:22
Возможно, я уже исправлял у себя, вспомнил, что что-то правил, но не помню, что и на каком участке, давно дело было. Потому, наверно, у меня работает нормально.