Здравствуйте. Эту статью я хочу сделать как разбор своих ошибок в своих прошлых статьях в целом, они актуальны, но иногда я в силу малого опыта совершал ошибки.

Функции


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)


  1. kricha
    04.01.2019 17:24
    +5

    Прочитал дважды, но так и не понял, зачем этому посвящать статью…


    1. saipr
      06.01.2019 11:13

      Нам напомнили про функции casefold() и lower(), а также пакет pymorphy2


  1. Framework
    04.01.2019 17:24
    +2

    Или

    from random import choice
    answers = ['1','2','3']
    message(choice(answers))
    


    1. DollaR84
      04.01.2019 20:57

      delete


  1. DollaR84
    04.01.2019 21:03

    В статье:
    import random
    answers = ['1','2','3']
    message(choice(answers))

    тогда:
    message(random.choice(answers))
    или choice импортировать


  1. 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)