Здравствуйте. Эту статью я хочу сделать как разбор своих ошибок в своих прошлых статьях в целом, они актуальны, но иногда я в силу малого опыта совершал ошибки.
Python функциональный язык программирования и при разработке бота я этого не учёл из-за этого в статье постоянно повторяется один и тот же кусок кода:
Разумнее было сделать функцию:
И далее вызывать её
Тут подход простой. Делить строку с помощью split(). Можно оставить функцию пустой, тогда строка разделится по пробелам и знакам перевода коронки или по иному разделителю (например запятой). На выходе получим список с которым можно работать. Одним костылём меньше.
Этот тихий ужас был сделан для разнообразия фраз и борьбы с регистром.
Проблема регистра решается с помощью функции casefold(), ну или lower() в русском языке не принципиально. После этого пользователь может написать хоть: «КомАнДа», после обработки мы получим 'команда'.
Так-же неплохо привести слова в начальную/неопределённую форму. Но тут стандартными функциями не обойтись, прийдётся использовать pymorphy2.
Теперь даже если пользователь напишет: «КоМанДА», «кОманде» или «команды» на выходе будет 'команда' и ужасно длинные «or event.text ==» убрали
Не так давно ко мне обратился за помощью Norazord и спросил:
В целом мысль правильная, но вместо кучи if-ов я бы сделал вот так:
или
Спасибо Framework
Функции
Python функциональный язык программирования и при разработке бота я этого не учёл из-за этого в статье постоянно повторяется один и тот же кусок кода:
if event.from_user:
vk.messages.send( #Если написали в ЛС
user_id=event.user_id,
message='какой-то текст'
)
elif event.from_chat: #Если написали в беседе
vk.messages.send(
chat_id=event.chat_id,
message='какой-то текст'
Разумнее было сделать функцию:
def message(text,noLinks=0):
if event.from_user:
vk.messages.send(
user_id=event.user_id,
message=str(text),
dont_parse_links = noLinks
)
elif event.from_chat:
vk.messages.send(
chat_id=event.chat_id,
message=str(text),
dont_parse_links = noLinks
)
И далее вызывать её
message('какой-то текст')
Двойные циклы
Тут подход простой. Делить строку с помощью split(). Можно оставить функцию пустой, тогда строка разделится по пробелам и знакам перевода коронки или по иному разделителю (например запятой). На выходе получим список с которым можно работать. Одним костылём меньше.
if event.text == 'Википедия' or event.text == 'Вики' or event.text == <...>
Этот тихий ужас был сделан для разнообразия фраз и борьбы с регистром.
Проблема регистра решается с помощью функции casefold(), ну или lower() в русском языке не принципиально. После этого пользователь может написать хоть: «КомАнДа», после обработки мы получим 'команда'.
Так-же неплохо привести слова в начальную/неопределённую форму. Но тут стандартными функциями не обойтись, прийдётся использовать pymorphy2.
import pymorphy2
textMsg = event.text.casefold() #приводим к нижнему регистру
Msg = textMsg.split() #делим
tmp = 0
event.text = ''
for items in Msg:
p = morph.parse(str(Msg[tmp]))[0]
Msg[tmp] = p.normal_form #приводим в нормальную форму
event.text = str(event.text) +' '+ str(Msg[tmp]) #возвращаем в строку
tmp += 1
Теперь даже если пользователь напишет: «КоМанДА», «кОманде» или «команды» на выходе будет 'команда' и ужасно длинные «or event.text ==» убрали
Разные ответы
Не так давно ко мне обратился за помощью Norazord и спросил:
Извини если опять беспокою, но как сделать так чтоб бот мог отвечать разными фразами.К примеру ему пишут Hi он отвечает Hello написали еще раз Hi он уже отвечает Good afternoon (к примеру)на что я по неопытности ответил:
Ну например сделать переменную и каждый раз давать ей рандомное число (в рамках количества фраз) а потом if. Выглядеть будет как-то так
import random servis1=random.randint(1,3) if servis1==1: print('1') elif servis1==2: print('2') else: print('3')
В целом мысль правильная, но вместо кучи if-ов я бы сделал вот так:
import random
r = random.randint(1,3)
answers = ['1','2','3']
message(answers[r]) #с учётом ранее созданной функции
или
import random
answers = ['1','2','3']
message(random.choice(answers))
Спасибо Framework
Комментарии (6)
DollaR84
04.01.2019 21:03В статье:
import random
answers = ['1','2','3']
message(choice(answers))
тогда:
message(random.choice(answers))
или choice импортировать
Framework
04.01.2019 17:06Кстати, на счёт
Python функциональный язык программирования и при разработке бота я этого не учёл
То что вы под этим подразумеваете, на самом деле называется процедурным программированием.
Если говорить про функциональное программирование, то ваш пример можно было бы записать как:
from toolz import pipe from toolz.curried import map # ... event.text = pipe( event.text, str.casefold, str.split, map(morph.parse), map(lambda p: p[0].normal_form), ' '.join)
kricha
Прочитал дважды, но так и не понял, зачем этому посвящать статью…
saipr
Нам напомнили про функции casefold() и lower(), а также пакет pymorphy2