LINUX.ORG.RU

Луа, регулярные выражения и переменные

 , , ,


0

1

имею например такой блок кода:

q3nik1 = "Лепрогнома-работника,"
if string.find (message, q3nik1:sub(1, -2)) then
    print("ТипаБорто")
end

Условие не срабатывает. Я подозреваю. что это из за тирэ в переменной… А как в этом случае быть то?

Блок кода тестовый, ник я получаю автоматически обычно и нужно это отлавливать автоматически.

Перемещено hobbit из general

★★★★★

Последнее исправление: hobbit (всего исправлений: 1)

  1. Что в message?
  2. В приведённом куске ничего критичного, но если у тебя не однобайтовая кодировка, то так можно и букву пополам порезать. Возможно, тут лучше использовать библиотеку utf8.
  3. - и другие магические символы экранируются через %: "string%-morestring".
Ceiling_QB ★★★★
()
Последнее исправление: Ceiling_QB (всего исправлений: 2)
Ответ на: комментарий от Ceiling_QB

В message строка для поиска: «Вы меряете взглядом Лепрогнома-работника.» Причем имя может быть в любой части фразы, оно не всегда в конце. И выбирается динамически.

Вот в этой строке мне надо его найти, сравнив с сохраненным в переменной, а точнее в таблице.

Я понимаю как экранировать в строке, но мне нужно искать в переменной. Как мне экранировать такое в переменной?

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Rossiks

Это и так строка.

q3nik1 = "Лепрогнома-работника,"
q3nik1 = tostring(q3nik1)

Преобразование в строку не помогло.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Уже прислали, но процитирую документацию:

string.find (s, pattern [, init [, plain]])

Looks for the first match of pattern (see §6.4.1) in the string s. If it finds a match, then find returns the indices of s where this occurrence starts and ends; otherwise, it returns fail. A third, optional numeric argument init specifies where to start the search; its default value is 1 and can be negative. A true as a fourth, optional argument plain turns off the pattern matching facilities, so the function does a plain «find substring» operation, with no characters in pattern being considered magic.

true четвёртым параметром заставляет рассматривать искомую строку (второй параметр) как подстроку, не паттерн.

Ceiling_QB ★★★★
()
Ответ на: комментарий от fluorite

Хм..неа, не работает. Но спасибо за синтаксис, запомню.

https://cdn.discordapp.com/attachments/811217303378329643/1130018324554727504/nenene.png

q3nik1 = "Лепрогнома-работника,"
q3nik1 = tostring(q3nik1)
if string.find (message, q3nik1:sub(1, -2), 1, true) then
    print("ТипаБорто")
end

if testQ[myNome]["q33q"] == "смерь" then
    print ("1")
    q3nik1 = testQ[myNome]["q33nik1"]:sub(1, -2)
    q3nik2 = testQ[myNome]["q33nik2"]:sub(1, -2)
    q3nik3 = testQ[myNome]["q33nik3"]
    if string.find (message, "Вы меряете взглядом") then
        print ("2")
        print (message .. " ник в переменной " .. q3nik1)
        if string.find (message, q3nik1, 1, true) then
        print ("3")
            SendChatMessage("Я меряю взглядом " .. q3nik1 , "OFFICER", nil, 1)
            testQ[myNome]["q33nik1"] = 1
        end
        if string.find (message, q3nik2) then
            SendChatMessage("Я меряю взглядом " .. q3nik2 , "OFFICER", nil, 1)
            testQ[myNome]["q33nik2"] = 1
        end
        if string.find (message, q3nik3) then
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik3"] , "OFFICER", nil, 1)
            testQ[myNome]["q33nik3"] = 1
        end
    end
end

Собственно вот. Первое - тестовый блок мой, второе - типа рабочий код. Оба варианта не сработали, как видно на скриншоте по принтам.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

По поводу find

А так, бей входящую квестовую строку на токены и рули =)

--разбить текущее сообщение на токены
--проверить наличие в сообщении всех нужных
--слов согласно правилу
--вернуть инфу содержит ли сообщение все нужные слова
--и в любом случае вернуть всё что совпало с правилом
function check_items(message,items)
    local found    = {};
    local notfound = {};
    for item in string.gmatch(message, '([^,^%s^.]+)') do
        for i=1,#items do
            if(items[i] == item) then
              found[#found+1] = item;
            end
        end
    end

    for i=1,#items do
        local cmp = 0;
        for k=1,#found do
            if(items[i] == found[k]) then
               cmp = 1
            end
        end
        if cmp == 0 then
            notfound[#notfound+1]=items[i];
        end
    end

    if #found == #items then
        return true, found,notfound;
    else
        return false,found,notfound;
    end

end

function print_r(...)
    io.write('\x1B[31m')
    print(...)
    io.write('\x1B[39m')
end
function print_g(...)
    io.write('\x1B[32m')
    print(...)
    io.write('\x1B[39m')
end
function print_y(...)
    io.write('\x1B[33m')
    print(">>> ".. ...)
    io.write('\x1B[39m')
end

-- принять сообщение и правило квеста
function check_quest(message,rule)
    print_y(message);
    local state,found,notfound = check_items(message,rule)
    -- всё нашлось квест выполнен в полном объёме
    -- репортуем об успехе.
    if state then
        print("### Отлично, вот твоя награда. Спасибо что принёс:");
        for i=1,#found do
            print_g('-',found[i]);
        end
    else
        print("### Я просил у тебя:");
        for k,v in ipairs(rule) do
            print_g('-',v);
        end
        if #found > 0 then
        print("### А не только:");
            for k,v in ipairs(found) do
                print_r('-',v);
            end
        end
        print("### Приснеси:");
        for k,v in ipairs(notfound) do
            print_g('-',v);
        end
    end
    print("-----------------------------------");
end


local quest_rule = {"яблоки","орехи","Лепрогнома-работника"};
local message = "Я принёс орехи, яблоки, зерно и палку Лепрогнома-работника.";

check_quest(message,quest_rule);

local message = "Я принёс орехи, зерно и палку Лепрогнома-работника.";

check_quest(message,quest_rule);

local message = "Я принёс камушек Лепрогнома-трактирщика.";

check_quest(message,quest_rule);
dron@gnu:~$ lua lalala.lua 
>>> Я принёс орехи, яблоки, зерно и палку Лепрогнома-работника.
### Отлично, вот твоя награда. Спасибо что принёс:
-	орехи
-	яблоки
-	Лепрогнома-работника
-----------------------------------
>>> Я принёс орехи, зерно и палку Лепрогнома-работника.
### Я просил у тебя:
-	яблоки
-	орехи
-	Лепрогнома-работника
### А не только:
-	орехи
-	Лепрогнома-работника
### Приснеси:
-	яблоки
-----------------------------------
>>> Я принёс камушек Лепрогнома-трактирщика.
### Я просил у тебя:
-	яблоки
-	орехи
-	Лепрогнома-работника
### Приснеси:
-	яблоки
-	орехи
-	Лепрогнома-работника
-----------------------------------
dron@gnu:~$ 

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

Так, мне тут в игре нашли решение. Вот такое:

q3nik1 = "Лепрогнома-работника,"
q3nik1 = q3nik1:sub(1, -2)
q3nik1 = "[" .. q3nik1 .. "]"
if string.find (message, q3nik1) then
    print("ТипаБорто")
end

И это работает. Тупо обнести квадратными скобками переменную.

Твой вариант как всегда…монументален. Мне чтобы прочитать его, потребуется хотя бы час вдумчивого осмотра. Но спасибо. Я сохраняю. Я вчитываюсь.

Короче, вот решение простое и быстрое:

if string.find (message,"[" .. testQ[myNome]["q33nik1"]:sub(1, -2) .. "]") then

сделать вот так и не гребсти себе мозги.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 6)
Ответ на: комментарий от LightDiver

Ладно.

Там ещё если в ответах идут разные склонения слов, яблок/яблоки,яблоко. То можно в правиле квеста писать без склонения яблок и искать вхождение этого слова в имеющиеся, а не просто точное слово.

Типа вместо

  • local quest_rule = {"яблоки","орехи","Лепрогнома-работника"};

Пишем

  • local quest_rule = {"яблок","орех","Лепрогнома-работник"};

И тогда в сообщении "Я принёс яблоки и горсть орехов Лепрогнома-работника" всё найдётся. Но эт так, мысли в слух и да это я уже не проверял.

 for i=1,#items do
-            if(items[i] == item) then
+            if(item:find(items[i],1,true));
              found[#found+1] = item;
            end
        end
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Вот про склонения я изучу. Я пока делаю просто: на однин вид склонения один код, на другой вид склонения другой код….. Не придумал быстро как универсализировать. А видимо зря. Наверное лучше сделать универсальную функцию.

Проблема что «Лепрогнома-работник» не пойдет. Ибо он «Лепрогном-работник». То есть мне нужно не просто оконания отсекать, а и середину. Чуешь беду?

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Скобками ты создал шаблон, поиска группы. Вот оно и заработало. Хотя должно работать и с find(lalal,1,true) так как тебе всё же надо просто подстроку вытащить и сравнить. Но, как удобнее так и делай конечно.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Не знаю, find(lalal,1,true) не работает. Хотя в вов апи этот вариант описан, да. Может это особенности сервера, хз. Они там пиздец чего навертели и изменили.

Интереснее что делать с именами, у которых рандомно в середине ника изменения склонений.

Изменять вручную - не вариант. Я хочу базу имен набирать автоматически от игроков, которые встречают этих персонажей.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от LightDiver

Ну прям совсем универсальную не получится наверное ибо например

Лепрогнома-работника и Лепрогному-работнику помимо разбиения входящего предложения на слова и поиска подстроки в каждом яблок в яблоки придётся ещё разбивать слова составные на подслова и в каждом искать подстроку Лепрогном + - + работник в Лепрогному-работнику. Такое надо если только ответы совсем в вольной форме.

Можно придумать игровую условность, склонение должно быть одно или два максимум орех и орехи и всё. Вот кто квест принимает тот вырос в деревне где гномы общались всего двумя склонениями и иного они не понимают :D

Не баг, а фича, на этом весь геймдев стоит :D

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Так.. косяк. Оно теперь ищет лишнее:

https://cdn.discordapp.com/attachments/811217303378329643/1130177196137398373/WoWScrnShot_071623_234017.jpg

Как видно, от одного ника сработали все три условия.

if testQ[myNome]["q33q"] == "смерь" then
    if string.find (message, "Вы меряете взглядом") then
        if string.find (message,"[" .. testQ[myNome]["q33nik1"]:sub(1, -2) .. "]") then
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik1"]:sub(1, -2) , "OFFICER", nil, 1)
            testQ[myNome]["q33nik1"] = 1
        end
        if string.find (message,"[" .. testQ[myNome]["q33nik2"]:sub(1, -2) .. "]") then
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik2"]:sub(1, -2) , "OFFICER", nil, 1)
            testQ[myNome]["q33nik2"] = 1
        end
        if string.find (message,"[" .. testQ[myNome]["q33nik3"] .. "]") then
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik3"] , "OFFICER", nil, 1)
            testQ[myNome]["q33nik3"] = 1
        end
    end
end
LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Потому что ты ищешь по шаблону, а не просто подстроку. Но мне надо бежать. Разбирася =)

Шаблоны они такие их курить надо, они упоротые вусмерть. Разберись с поиском подстроки.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Короче, мы нашли второе решение. Я не хочу доводить до третьего - писать функцию, которая будет разбивать ник на симолы и искать там тирэ. И если есть - заменять его.

/run message="Вы видите Лепрогнома-работника"; p = "Лепрогнома-работника,"; if string.find(message,p:gsub("%-", "%%-"):sub(1, -2)) then print("true") else print("false") end

Вот такой скрипт работает и выдает тру.

if testQ[myNome]["q33q"] == "смерь" then
    if string.find (message, "Вы меряете взглядом") then
        print (testQ[myNome]["q33nik1"]:gsub("%-","%%-"):sub(1, -2))
        if string.find (message,testQ[myNome]["q33nik1"]:gsub("%-", "%%-"):sub(1, -2)) then
            print (testQ[myNome]["q33nik1"])
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik1"]:sub(1, -2) , "OFFICER", nil, 1)
            testQ[myNome]["q33nik1"] = 1
        end
        if string.find (message,testQ[myNome]["q33nik2"]:gsub("%-", "%%-"):sub(1, -2)) then
            print (testQ[myNome]["q33nik2"])
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik2"]:sub(1, -2) , "OFFICER", nil, 1)
            testQ[myNome]["q33nik2"] = 1
        end
        if string.find (message,testQ[myNome]["q33nik3"]:gsub("%-", "%%-")) then
            print (testQ[myNome]["q33nik3"])
            SendChatMessage("Я меряю взглядом " .. testQ[myNome]["q33nik3"] , "OFFICER", nil, 1)
            testQ[myNome]["q33nik3"] = 1
        end
    end
end

А этот код не работает. Почему? Разницы же нету.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Мгновенно вряд ли, но там короткое время на разгадывании капчи даётся.

Хотя, может, ты у бота в базе спамеров почему-то. Можно попробовать админам чата написать, они добрые.

Ceiling_QB ★★★★
()
Ответ на: комментарий от Ceiling_QB

Аххахаха)) Так так капча была? Я зашел, увидел активное обсуждение и не стал вмешиваться - занялся очередным скриптом. Через полчаса вернулся глянуть наконец что и как, а уже забанен. Ну бывает.

Я уже разобрался в чем проблема, сейчас переписываю полностью. А то с первого раза еще и написал очень криво. Сейчас сократил код в 15 раз. И удобнее на порядок сделал.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Я просто похвастать. Смотри, переписал для некоторого удобства на питон твой вариант:

import time
import os.path
import subprocess
import shlex
import random
from sys import argv

#time.sleep(float(argv[1]))

if os.path.isfile('/tmp/signal'):
	os.remove('/tmp/signal')
	exit()
else:
	open('/tmp/signal', "w").close()

subprocess.call(shlex.split('env DISPLAY=:0 lua lo.lua'))
while True:
	if os.path.isfile('/tmp/signal'):
		subprocess.call(shlex.split('env DISPLAY=:0 sh l211.sh'))
		x = random.randint(183, 317)
		x1 = "0.1"
		x = str(x)
		x1 = str(x1)
		x = x1 + x
		x = float(x)
		print(x)
		time.sleep(x)
		subprocess.call(shlex.split('env DISPLAY=:0 sh l212.sh'))
		x = random.randint(212, 293)
		x1 = "0.1"
		x = str(x)
		x1 = str(x1)
		x = x1 + x
		x = float(x)
		time.sleep(x)
	else:
		break

Ты посмотри компактность, а? Ну питон же прекрасен. И это я ту монструозную конструкцию в конце не объединил в короткие удобные строки, ибо пока не знаю как. Но точно понимапю - можно сократить нормально.

Но тут есть косяк: пока не завершится таймер, скрипт будет висеть. Не знаешь как это решить? Или пофиг в принципе? Висит и пусть себе висит?

И размеры конечно.. или 0.2-0.3мб луа скриптик или 3мб этот.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 3)
Ответ на: комментарий от annerleen

Уже выяснил, починил и полностью переписал весь квест. Там все гораздо интереснее. Там весь и нтерфейс на луа.. весь на метатаблицах. И вот, в чат эта падла выдает один текст, в код тот же текст, а на деле там совсем другой. И да, кириллица, конечно же:

|33(Лепрогномработник)

Там какой то вот такой формат для обрастания основного слова падежами. В чат он выдает уже обросшее и коду он выдает обросшее, а вот стриг.файнду он выдает именно в таком формате. Я нашел это чисто случайно. Примерно так:

if testQ[myNome]["q33q"] == "недоуменно посмотри на персонажей: " then
    local msg = mysplit(message)
    if string.find (message, "Вы недоуменно смотрите") then
        for i=1,#msg do
            if testQ[myNome]["q33nik1"] ~= 1 then
                if string.find(msg[i],testQ[myNome]["q33nik1"]) then
                    SendChatMessage("Я недоуменно смотрю на персонажа " .. testQ[myNome]["q33nik1"] , "OFFICER", nil, 1)
                    testQ[myNome]["q33nik1"] = 1
                end
            end
        end
        for i=1,#msg do
            if testQ[myNome]["q33nik2"] ~= 1 then
                if string.find(msg[i],testQ[myNome]["q33nik2"]) then
                    SendChatMessage("Я недоуменно смотрю на персонажа " .. testQ[myNome]["q33nik2"] , "OFFICER", nil, 1)
                    testQ[myNome]["q33nik1"] = 1
                end
            end
        end
        for i=1,#msg do
            if testQ[myNome]["q33nik3"] ~= 1 then
                if string.find(msg[i],testQ[myNome]["q33nik3"]) then
                     SendChatMessage("Я недоуменно смотрю на персонажа " .. testQ[myNome]["q33nik3"] , "OFFICER", nil, 1)
                    testQ[myNome]["q33nik1"] = 1
                end
            end
        end
    end
end

То есть поделил строку на слова в таблице, и вдруг оно рассыпалось на настоящие данные.

Но теперь я не хочу на каждую эмоцию такой код писать. Сделаю уникальную функцию и подставлю в нее данные. В третий раз сейчас буду переписывать.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Ну сократить ты и на луа мог, рандом есть в луа родной, получение даты тоже, просто проверка на наличие файла тоже в одну строку, ранее же мы стату чекали по его содержимому, а не наличию. Да в питоне больше всего что тебе нужно.

Питон категорически не люблю, не знаю и знать не хочу. Но если тебе удобнее, то почему бы и нет =) Особенно когда ты просто взял и сделал с полным пониманием как оно работает. Ну вот ты уже на lua, C# и python писать научился =)

Не знаешь как это решить?

Сохранить его PID при запуске и если он активен то грохнуть его.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

То херня, не смотри то позорище. Я уже переделал. Оцени!

import time
import os.path
import subprocess
import shlex
import random
import datetime
from sys import argv

#time.sleep(float(argv[1]))

if os.path.isfile('/tmp/signal1'):
	os.remove('/tmp/signal1')
	exit()
else:
	open('/tmp/signal1', "w").close()

subprocess.call(shlex.split('env DISPLAY=:0 lua /home/diver/Скрипты/lo.lua'))
while True:
	if os.path.isfile('/tmp/signal1'):
		subprocess.call(shlex.split('env DISPLAY=:0 sh /home/diver/Скрипты/l211.sh'))
		print('1')
		print(datetime.datetime.now())
		x = random.randint(112, 216)
		x1 = "0."
		x = str(x)
		x1 = str(x1)
		x = x1 + x
		x = float(x)
		print(x)
		time.sleep(x)
		subprocess.call(shlex.split('env DISPLAY=:0 sh /home/diver/Скрипты/l212.sh'))
		print('2')
		print(datetime.datetime.now())
		x = random.randint(311, 540)
		x = int(x)
		print (x)
		i = 0
		while i < x:
			time.sleep(1)
			if i == x:
				pass
			if not os.path.isfile('/tmp/signal1'):
				break
			i = i+1
	else:
		break

оцени последние строк 10 кода. Это сложный таймер, который позволяет завершить скрипт, даже если таймер длится несколько минут, например. Только надо оформить код нормально теперь. Всю эту лапшу.

В луа нет таймера нормального. Я сначала попробовал ютаймер - он не хотел работать из под крона. Затем я написал свой таймер на питоне - вон он закомментирован в начале кода.

Потом глянул на все это, оценил баги от моих косяков и переписал все с нуля на питоне. Очень уж в нем много возможностей.

А про вызов разных таймеров я уже решил. Я просто использую два таких скрипта как выше. Один основной вон его код. Он срабатывает раз в 5-9 минут. Второй малый и вызывается кроном в определенный час в определенную минуту ровно на минуту и срабатывает раз в 100-200мс.

И все, никаких сложных управлений и айдишниковж. Тем более у меня уже есть скрипт на питоне, который работает с кроном и формирует его. Я просто добавил в него этот скрипт и все.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 3)
Ответ на: комментарий от LightDiver

Шутка

«Не люблю девчонок» и лишние else.

if os.path.isfile('/tmp/signal1'):
	os.remove('/tmp/signal1')
	exit()

open('/tmp/signal1', "w").close()

...

		print (x)
		i = 0
		while i < x:
			time.sleep(1)
			if i == x:
				pass
			if not os.path.isfile('/tmp/signal1'):
				break
			i = i+1
                continue

break

Forum0888
()
Ответ на: комментарий от LightDiver

Ну, на lua ты научился программировать, а далее ты уже выбираешь более подходящий инструмент/язык. Да, в питоне больше всего из коробки, пользуйся =) Молодец ^.^

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Ой, а логично. Если файла нет, зачем это проверять. Просто создаем. Спасибо.

А второе…мм. Я накосячил, да. Я просто сначала туда засунул второй скрипт на выполнение. И только через час до меня дошло, что это не нужно. И я его вынес оттуда. А элсе и брейк остались. Там даже континью это наверное не нужно.. А что оно значит?

По идее просто завершаем цикл и все, без брейков и прочего и идем на второй заход.

Так стоп… Это не тот брейк. Так. У нас если есть файл, то выполняем код. Если нет файла…то континью. Аааа. Континью это продолжение кода до брейка? Но как оно должно без условия работать? Я не понимать.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Ой, луа тоже прекрасен. Я на нем уже пишу просто автоматически, не задумываясь. Простой, небольшой. Никаких лишностей. Спасибо тебе за него.

Просто в нем нет такого дичайшего количества модулей на все случаи жизни. Мне питон нравится не только своей компактностью в плане кода, сколько модулями. Надо тебе прибавить к текущему времени 2,5 часа - да пожалуйста. Удалить файлы, создать, обработать одно, другое. На все случаи жизни есть компактная простая и удобная команда.

Ну и компилируется в бинарник, работает без проблем и тут и на винде. Хорошо же. Вон я обновлятор пользователям виндовым на питоне и запилил.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

В Lua не силён.
У вас if в цикле.
Если if не выполняется то break.
Правильно?
Значит на break мы можем попасть лишь в случае если if не выполнен.
Если if выполняется, то continue на продолжение цикла.

Forum0888
()
Ответ на: комментарий от LightDiver

Вообщем-то и ваш код вполне читабельный.
А вот в сложной логике с ифами, имеющими много строк да ёще
вложенными, ... бывает полезным сделать небольшой рефакторинг кода, чтобы он стал более читабельным.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Ох, тогда не стоит заглядывать на мой гитхаб. Во избежание нервного срыва. Ифы я люблю и элсы. Я обмазан ими чуть более чем полностью.

Луа, регулярные выражения и переменные (комментарий)

Ну вот, как пример. Я лично не придумаю как сделать без ифов.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Пост был о том, что вложенность ифов можно уменьшить.

if testQ[myNome]["q33q"] != "недоуменно посмотри на персонажей: " then
 return
end

local msg = mysplit(message)

 if string.find (message, "Вы недоуменно смотрите") == 0 then
  return
 end

 for i=1,#msg do

  if testQ[myNome]["q33nik1"] == 1 then
   continue
  end

  if string.find(msg[i],testQ[myNome]["q33nik1"]) == 0 then
   continue
  end

  SendChatMessage("Я недоуменно смотрю на персонажа " .. 
testQ[myNome]["q33nik1"] , "OFFICER", nil, 1)

  testQ[myNome]["q33nik1"] = 1

 end

 for i=1,#msg do

  if testQ[myNome]["q33nik2"] == 1 then
   continue
  end

  if string.find(msg[i],testQ[myNome]["q33nik2"])  == 0 then
   continue
  end

  SendChatMessage("Я недоуменно смотрю на персонажа " .. testQ[myNome]["q33nik2"] , "OFFICER", nil, 1)

  testQ[myNome]["q33nik1"] = 1

 end

 for i=1,#msg do

  if testQ[myNome]["q33nik3"] == 1 then
   continue
  end

  if string.find(msg[i],testQ[myNome]["q33nik3"]) == 0 then
   continue
  end

  SendChatMessage("Я недоуменно смотрю на персонажа " .. testQ[myNome]["q33nik3"] , "OFFICER", nil, 1)

  testQ[myNome]["q33nik1"] = 1

 end

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 2)
Ответ на: комментарий от Forum0888

Ну, суть я понял, но пока тяжко. Для меня читабельность такого снижается раз в десять. Я к такому еще не готов, да и смысла не вижу.

Так то наверное можно и не назначать единицей каждый ник отдельно, а сделать условие на котором будет переход на единое назначение. Вот это интересно. То есть проверяем выполнение и отсылаем в конец. А в конце назначение единицей. Если прошло в конец - назначили. Все остальное прерываем.. Если я правильно понял.

А так же можно избавиться от форов.. Я ведь уже разбил на слова и добился вычленения нужного из текста. Теперь конкат обратно фразу и сравниваем напрямую с ней, а не с каждым словом. Так я смогу и ники с пробелами вернуть в студию. А то вчера от них пришлось отказаться.

Спасибо!

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 4)
Ответ на: комментарий от Forum0888

Ненене, до меня доходит просто медленно. Я начал печатать и пока печатал, что «Ничего не понятно», до меня дошло и я понял как можно сделать лучше. Офигенная механика, я просто про ретерн и континью вообще до этого не слышал.

К сожалению, очень даже принциписально. Я вчера полностью переписал этот квест, сделав единую функцию на все эмоции, а не отдельную на каждую и смотри результат: 5 files changed, 95 insertions(+), 570 deletions(-)

У меня там код раз в 20-30 можно уменьшить. Особенно то, что я в первый месяц писал.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Наприер знаешь как я добывал в начале отдельные слова из фразы? Я вырезал по шаблону все, что было вне этого слова из предложения и оставлял в итоге его одного. Причем вырезал последовательно - сначала одно лишнее, потом другое… Потом узнал про таблицы и как можно проще разбить фразу.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Еще не много.

Код типа

 if testQ[myNome]["q33nik1"] == 1 then
  continue
 end

 if string.find(msg[i],testQ[myNome]["q33nik1"]) == 0 then
  continue
 end

Иногда полезно преобразовать в 

 if testQ[myNome]["q33nik1"]                     == 1 ||
    string.find(msg[i],testQ[myNome]["q33nik1"]) == 0     then

  continue

 end

Почему сказал «иногда»?.

Потому что для алгоритмов, разработанных для «big data» важна оптимизация кода и может получиться, что сложный иф приводит к выполнению «не нужных» проверок.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Слов нет. Я дебил. Сказочный дебил. Все что я делал неделю - не нужно.

Суть вот в чем. У нас есть в чате применение эмоций. В чате эмоций при этом отображается фраза. Например: «Вы кусаете Аукциониста джената. Ох!». Это если я применю на персонажа эмоцию /укус

Аддон отслеживает эту фразу, если там есть слова «Вы кусаете», то: если там есть ник, выданный тебе по квесту и он совпадает с фразой - то сделано.

Я и значально вставлял в базу ники с окончаниями типа: «Аукциониста джената».. И стринг.файн нихрена не находил. Я в непонятках возился неделю. Разбивал фразу на составляющие, вырезал из нее служебный код. Делал в цикле. Ну, там выше эти попытки описаны.

….но ведь у нас это рисованная фраза, а истинная фраза, которую видит стринг.файнд, примерно такая: «Вы кусаете |33(Аукционист дженат)|. Ох!»

Ты понимаешь насколько я дебил? Я разбивал фразу на части, отрезал от нее управляющие символы, чтобы из рисованной сделать истинную и потом сравнивал ник с каждым словом фразы. Поимел пробелмы с никами, в которых есть проблемы. Надо было еще и их разбивать. Я разбил, соединил и когда почти доделал, до меня дошло…

В истиной фразе уже есть ник в исходной форме!!! Без падежей и прочего говна. То есть мне просто надо занести в базу ники без падежей и одной строкой сравнивать.

if testQ[myNome]["q33fnd"] ~= nil then
	if string.find (message, testQ[myNome]["q33fnd"]) then
		for i=1,#testQ[myNome]["q33nik"] do
			if testQ[myNome]["q33nik"][i] ~= 1 then
				if string.find(message,testQ[myNome]["q33nik"][i]) then
					SendChatMessage(testQ[myNome]["q33ans"] .. testQ[myNome]["q33nik"][i] , "OFFICER", nil, 1)
					testQ[myNome]["q33nik"][i] = 1
				end
			end
		end
	end
end

Собственно все. Весь код. Я сейчас из 570 строк кода квеста сделал 30. 540 строк мусора сократил… Ну и кто я?

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от Forum0888

2162 строки в сервере, 3905 строк в клиенте.. Всего 6067 строк. Минус некоторые пробелы.. Допустим 6000 строк рабочего кода.

Думаю, если переписать все нормально - сократится до 600 как минимум. Уфф..

LightDiver ★★★★★
() автор топика
4 сентября 2023 г.
Ответ на: комментарий от LightDiver

import os.path
from time import sleep
from shlex import split
from subprocess import call
from random import randint
from datetime import datetime
p='/tmp/signal1'
if (Sig:=lambda:os.path.isfile(p))():os.remove(p);      exit()
open(p, "w").close()
def doSh(a=1):
    call(split(f'env DISPLAY=:0 sh /home/diver/Скрипты/l21{a}.sh'))
    print(f'{a}\n{datetime.now()}')

call(split('env DISPLAY=:0 lua /home/diver/Скрипты/lo.lua'))
while Sig():
    doSh(1);print(x:=float(f"0.{randint(112, 216)}"));   sleep(x)
    doSh(2);print(x:=randint(311, 540))
    set(sleep(1)for i in range(x)if Sig())
qulinxao3
()
Последнее исправление: qulinxao3 (всего исправлений: 1)
Ответ на: комментарий от qulinxao3

Спасибо, очень интересное, но я пока не могу расшифровать код полностью. Но за пару решений огромное спасибо.

Просто я с питоном почти не работал. Все больше с луа. Нужно больше практики.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

leetcode чисто руку набить easy -задачки - а так конечно лучше свой проект пилить тогда доходчивей

как в lua всё есть (мета)таблица так в python всё есть словарь(и чуточку (ит|ген)ератор)

qulinxao3
()
Последнее исправление: qulinxao3 (всего исправлений: 1)