Функции Для Разработчиков, склад полезных функций |
Здравствуйте, гость ( Вход | Регистрация )
Функции Для Разработчиков, склад полезных функций |
1.4.2009, 17:20
Сообщение
#21
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Пример работы с переменным числом параметров:
Код function MyFunc1(...) local m='' for i=1,select('#',...) do m=m..tostring(select(i,...)) end Core.SendToAll(m) end Вызов функции: Код MyFunc1("qwerty", "5", 1, 0x22b==555) Результат вызова: Код qwerty51true Если параметры функции состоят только из строк и/или чисел, то функцию можно упростить, записав так: Код function MyFunc2(...) Core.SendToAll(table.concat({...})) end Вызов функции: Код MyFunc2("qwerty", "5", 1) Результат вызова: Код qwerty51
|
|
|
3.4.2009, 19:25
Сообщение
#22
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Булева алгебра.
Код x inverse 1 0 0 1 x y and 0 0 0 1 0 0 0 1 0 1 1 1 x y or 0 0 0 1 0 1 0 1 1 1 1 1 x y xor 0 0 0 1 0 1 0 1 1 1 1 0 x y xnor 0 0 1 1 0 0 0 1 0 1 1 1 x xor y = x and inverse y or inverse x and y x xnor y = x and y or inverse(x and y) x xnor y = inverse(x xor y) x xor y = inverse(x xnor y) (x xor y) and (x xnor y) = 0 (x xor y) or (x xnor y) = 1 Функции для работы с бинарным представлением чисел, хотя числа подставляются в десятичном виде Код function odd(x)
return math.floor(x / 2) * 2 ~= x end function bit_inverse(x) local c, s = 0, 1 while x > 0 do if not odd(x) then c = c + s end s = s * 2 x = math.floor(x / 2) end return c end function bit_or(x, y) local c, s = 0, 1 while x > 0 or y > 0 do if odd(x) or odd(y) then c = c + s end s = s * 2 x = math.floor(x / 2) y = math.floor(y / 2) end return c end function bit_and(x, y) local c, s = 0, 1 while x > 0 or y > 0 do if odd(x) and odd(y) then c = c + s end s = s * 2 x = math.floor(x / 2) y = math.floor(y / 2) end return c end function bit_xor(x, y) local c, s = 0, 1 while x > 0 or y > 0 do if odd(x) and not odd(y) or odd(y) and not odd(x) then c = c + s end s = s * 2 x = math.floor(x / 2) y = math.floor(y / 2) end return c end function bit_xnor(x, y) local c, s = 0, 1 while x > 0 or y > 0 do if odd(x) and odd(y) or not odd(y) and not odd(x) then c = c + s end s = s * 2 x = math.floor(x / 2) y = math.floor(y / 2) end return c end |
|
|
22.4.2009, 16:45
Сообщение
#23
|
|
Участник Группа: Пользователи Сообщений: 47 Регистрация: 20.4.2009 Пользователь №: 3 112 Спасибо сказали: 1 раз |
Функции для перевода DEC в HEX и обратно
CODE function to_hex(n) if(type(n) ~= "number") then error("non-number type passed in.") end -- checking not float if(n - math.floor(n) > 0) then error("trying to apply bitwise operation on non-integer!") end if(n < 0) then -- negative n = bit.tobits(bit.bnot(math.abs(n)) + 1) n = bit.tonumb(n) end hex_tbl = {'A','B','C','D','E','F'} hex_str = "" while(n ~= 0) do last = math.mod(n, 16) if(last < 10) then hex_str = tostring(last) .. hex_str else hex_str = hex_tbl[last-10+1] .. hex_str end n = math.floor(n/16) end if(hex_str == "") then hex_str = "0" end return hex_str end function to_dec(hex) if(type(hex) ~= "string") then error("non-string type passed in.") end head = string.sub(hex, 1, 2) if( head ~= "0x" and head ~= "0X") then error("wrong hex format, should lead by 0x or 0X.") end v = tonumber(string.sub(hex, 3), 16) return v; end -- hex lib interface hex = { to_dec = to_dec, to_hex = to_hex, } Функции для перевода BIN в HEX и обратно CODE function hex2bin(hex)
local bin_tbl = {[48]='0000',[49]='0001',[50]='0010',[51]='0011',[52]='0100',[53]='0101',[54]='0110',[55]='0111',[56]='1000',[57]='1001',[65]='1010',[66]='1011',[67]='1100',[68]='1101',[69]='1110',[70]='1111'} local r,j, b = '' for i=1,#hex do b=hex:byte(i) if (b>47 and b<58) or (b>64 and b<71) then j=bin_tbl[b] else return -1 end if i==1 then j=tonumber(j) end r=r..j end return r; end function bin2hex(bin) local hex_tbl = {['0000']='0',['0001']='1',['0010']='2',['0011']='3',['0100']='4',['0101']='5',['0110']='6',['0111']='7',['1000']='8',['1001']='9',['1010']='A',['1011']='B',['1100']='C',['1101']='D',['1110']='E',['1111']='F'} local r,b='' for i=#bin,1,-4 do b=bin:sub(i-3,i) if i<4 then b=string.rep('0',4-i)..bin:sub(1,i):sub(-1*i) end r=r..hex_tbl[b] end return r:reverse() end |
|
|
22.4.2009, 19:01
Сообщение
#24
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Во-первых, видимо math.fmod, а не math.mod.
Во-вторых, что за таблица bit? Её и функции tobits, tonumb и bnot нужно определять! В-третьих, к чему все эти проверки и вызовы функции error? Ведь если человек использует подобного рода функции, то он явно понимает, что делает, а эти проверки только делают медленнее алгоритм перевода чисел. В-четвёртых, таблица hex тоже непонятно для чего тут написана. В-пятых, переменные внутри функции надо объявлять локальными Код local hex_str = ""
|
|
|
27.4.2009, 12:07
Сообщение
#25
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Функция explode разбивает строку указанным разделителем на подстроки. Возвращает таблицу с подстроками.
Код _G.string.explode = function(self, Sep)
local ret = {} for k in (self..Sep):gmatch(("(.-)%s+"):format(Sep)) do _G.table.insert(ret, k) end return ret end |
|
|
27.4.2009, 14:48
Сообщение
#26
|
|
Местный Группа: Неактивированные Сообщений: 908 Регистрация: 26.12.2008 Пользователь №: 1 574 Спасибо сказали: 1406 раз |
Вопрос.
Код _G.string.explode Зачем использовать переменную _G, если можно просто string.explode? |
|
|
27.4.2009, 14:56
Сообщение
#27
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
|
|
|
4.5.2009, 6:50
Сообщение
#28
|
|
Постоялец Группа: Пользователи Сообщений: 454 Регистрация: 17.10.2008 Из: Новосибирск Пользователь №: 825 Спасибо сказали: 90 раз |
Рискну и я три копеечки добавить. Решал проблему разбиения на части длинных посылок (отчетов) Оператору, содержащих более 128000 символов, и вот попутно соорудил такое нехитрое форматирование. Когда нужно упихнуть длинный текст в заданные рамки ( переменная iMargin ). Не шедевр мирового программирования, но, может быть, кому-нибудь пригодится
Код function CutText(s) local txt,sReturn = s.." ","" local Len,Ln,ln,stemp = txt:len(),0,0,"" for word in string.gmatch(txt, "%S+%s+" ) do local wlen = word:len(); Ln,ln = Ln + wlen,ln+wlen if ln >= iMargin then sReturn = sReturn..stemp.."\r\n\t"; stemp = word; ln = wlen else stemp = stemp..word end if Ln == Len then sReturn = sReturn..stemp; end end return sReturn end На картинке результат форматирования Описания хаба при разном заданном значении предельной длины подстроки.
Прикрепленные файлы
|
|
|
26.5.2009, 17:44
Сообщение
#29
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Очень не стандартный, но классный метод записи мультистрок:
Код do local mt = {} function mt:__call(str) table.insert(self, str) return self end function mt:__unm() return table.concat(self, "\n") end function L(...) return setmetatable({...}, mt) end end local p = -L "line 1" "line 2" "line 3" Core.SendToAll(p) Попробуйте разобраться, что происходит в данном примере Ещё одна достаточно интересная реализация: Код function prnt(x)
if x then Core.SendToAll(x) return prnt end end prnt "one" "two" "three" |
|
|
8.6.2009, 16:17
Сообщение
#30
|
|
Самый главный активист :-D Группа: Модераторы Сообщений: 2 790 Регистрация: 29.6.2008 Из: г. Тула Пользователь №: 97 Спасибо сказали: 440 раз |
функция форматирования времени
Код function GetNormalTime(s)
s=tonumber(s) or 0 local r="" if s>=31104000 then r=math.floor(s/31104000).." г. " s=math.fmod(s,31104000) end if s>=2592000 then r=r..math.floor(s/2592000).." мес. " s=math.fmod(s,2592000) end if s>=86400 then r=r..math.floor(s/86400).." д. " s=math.fmod(s,86400) end if s>=3600 then r=r..math.floor(s/3600).." ч. " s=math.fmod(s,3600) end if s>=60 then r=r..math.floor(s/60).." мин. " s=math.fmod(s,60) end return r..s.." сек." end |
|
|
8.2.2010, 19:47
Сообщение
#31
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Функция побитового "и":
Код function bin_and(x, y)
if y <= x then local i, r, a, b = 1, 0, 0, 0 while 0 < y do x, a = math.modf(x / 2) y, b = math.modf(y / 2) if 0 < a and 0 < b then r = r + i end i = 2 * i end return r end return bin_and(y, x) end |
|
|
25.2.2010, 22:03
Сообщение
#32
|
|
Продвинутый участник Группа: Пользователи Сообщений: 153 Регистрация: 21.9.2008 Из: Челябинск Пользователь №: 574 Спасибо сказали: 54 раза |
Если у файла в названии есть кириллица, то его имя преобразовывается в какой-то код (в магнет-ссылке)
Например "мистер" в %D0%BC%D0%B8%D1%81%D1%82%D0%B5%D1%80 Нагуглил только то, что это URI Кодирование, но откуда берутся "%D0" или "%D1" не понимаю... Ну и сам вопрос: как в LUA произвести эту конвертацию? |
|
|
26.2.2010, 0:35
Сообщение
#33
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Всё достаточно просто.
Переводим текст в UTF8 и каждый "нужный" байт представляем в 16-ричном виде Функцию AnsiToUtf8 берём из первого поста. Код function URICoding(sText)
local function Check(i) if i < 33 or 126 < i then return nil end if i == 33 then return true elseif 38 < i and i < 43 then return true elseif 44 < i and i < 47 then return true elseif 47 < i and i < 58 then return true elseif 64 < i and i < 91 then return true elseif 96 < i and i < 123 then return true elseif i == 126 then return true end end local s, r = AnsiToUtf8(sText), '' for i = 1, #s do local b = s:byte(i) if Check(b) then r = r..string.char(b) else r = r..("%%%X"):format(b) end end return r end |
|
|
26.2.2010, 11:01
Сообщение
#34
|
|
Главный ра******й тут... Группа: Главные администраторы Сообщений: 1 727 Регистрация: 18.5.2008 Из: RF, 2la Пользователь №: 1 Спасибо сказали: 776 раз |
В библиотеке LuaSocket есть модуль URL в котором есть функция заменяющая URICoding:
Цитата url.escape(content) Applies the URL escaping content coding to a string Each byte is encoded as a percent character followed by the two byte hexadecimal representation of its integer value. Content is the string to be encoded. The function returns the encoded string. Код -- load url module url = require("socket.url") code = url.escape("/#?;") -- code = "%2f%23%3f%3b" Аналогично можно перевести из полученной строки в обычный текст, надо перекодировать из утф, заменить + на пробел и применить к строке функцию url.unescape |
|
|
5.5.2010, 5:27
Сообщение
#35
|
|
Белый Волк Группа: Пользователи Сообщений: 1 723 Регистрация: 11.9.2008 Из: г.Томск Пользователь №: 516 Спасибо сказали: 657 раз |
Ещё одна функция приведения к нижнему регистру (ранее нигде не встречал):
Код function StringLower(arg) os.setlocale"Russian_Russia.1251" -- (русс.локаль) arg = string.lower(arg) os.setlocale("C") -- (возврат на станд.локаль) return arg end Работает как с кириллицей, так и с латиницей. Аналогично же и для приведения к верхнему регистру: Код function StringUpper(arg) os.setlocale"Russian_Russia.1251" -- (русс.локаль) arg = string.upper(arg) os.setlocale("C") -- (возврат на станд.локаль) return arg end PS: Уж больно подозрительно простенький код получился, но работает. Если у кода есть побочные вредные эффекты, умные товарищи, надеюсь, не пропустят и подскажут. |
|
|
5.5.2010, 13:39
Сообщение
#36
|
|
Главный ра******й тут... Группа: Главные администраторы Сообщений: 1 727 Регистрация: 18.5.2008 Из: RF, 2la Пользователь №: 1 Спасибо сказали: 776 раз |
А смысл тасовать локали? При старте скрипта обозначил на русскую и пользуйся себе чисто string.lower и string.upper
|
|
|
5.5.2010, 13:40
Сообщение
#37
|
|
Белый Волк Группа: Пользователи Сообщений: 1 723 Регистрация: 11.9.2008 Из: г.Томск Пользователь №: 516 Спасибо сказали: 657 раз |
Если так, то ещё лучше. Это я и хотел услышать от старшего товарища.
|
|
|
5.5.2010, 20:14
Сообщение
#38
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Играть с локалями нужно в функциях сохранения в файл, так как в Русской локали разделителем дробной и целой части в числе является запятая, а не точка!
Я это уже объяснял на хабе и повторяю для тех, кто не видел эти разъяснения. |
|
|
5.5.2010, 22:13
Сообщение
#39
|
|
Главный ра******й тут... Группа: Главные администраторы Сообщений: 1 727 Регистрация: 18.5.2008 Из: RF, 2la Пользователь №: 1 Спасибо сказали: 776 раз |
Т.е. если локаль не русская и мы загружаем файл, который сохранялся из-под русской локали, мы получим ошибку, так? Но если обозначить локаль до загрузки файла в скрипт, будет ли ошибка при загрузке?
|
|
|
5.5.2010, 23:54
Сообщение
#40
|
|
RusHub team lead Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз |
Дело в том, что в lua разделителем дробной и целой части является точка (и этот символ не зависит от локали, а является синтаксическим правилом).
Поэтому для того чтобы загружать файл при помощи lua функции dofile нужно чтобы внутри файла был исключительно lua формат. Однако если мы сохраняем файл и при этом установлена русская локаль, то явно или неявно функция tostring преобразует разделитель из точки в запятую и после этого загрузить такой файл функцией dofile уже не удастся. Поэтому делаем так: везде используем русскую локаль, установленную один раз, но перед тем как сохранить в файл устанавливаем локаль "C", сохраняем в файл, и после сохранения опять возвращаем русскую локаль. Таким образом стандартную локаль нужно устанавливать только на время сохранения информации в файл (для того чтобы оставить в сохранности lua синтаксис в файле). |
|
|
Похожие темы
|
Сейчас: 3.12.2024, 5:36 |