Как создавался новогодний Мяут?
Теперь вы уже знаете про новогоднего Мяута, можно поговорить подробнее про его создание.
Идея. Она не нова, каждый год (уже 3 года подряд) я создаю новогоднего бота. Сначала это был «новогодний Лис», а потом «новогодний Мяут» (2 года подряд). Стараюсь делать так, чтобы бот не был похож на старую версию. Хочу, чтобы каждый бот имел что-то своё и был лучше.
Время. Так как этот бот достаточно быстрый в создании, то сделал я его за два-три дня. Бот начал работать 9 декабря в 0:25, 9 декабря было сделано обновление, которое вступило в силу недавно...
Разбираем код. Я не заботился о качестве кода, не придал этому значению. Когда надо сделать быстро и чтобы работало редко обращаешь внимание на «красивый» код. Тут мы будем разбирать самые интересные моменты.
Если вы очень любопытный, то код можете посмотреть тут: https://gitverse.ru/codekotik/newyear_bot/content/master/bot.py
маленький комментарий: код и файлы немного отредактированы…
Самый нелюбимый момент, который я не хотел делать и который был сделан плохо фильтр и проверка сообщений.
def chek(message):with open('words.txt', 'r', encoding='utf-8') as file:m = [line.strip().lower() for line in file]if message.lower() in m:return Falsemessage = message.replace(',', ' ')message = message.replace('.', ' ')message = message.replace('!', ' ')message = message.replace('?', ' ')w1= '***'w2= "****"ifw1in message:return False
if w2in message:return Falsemessage = message.lower().split(' ')for i in message:if i in m:return False
return True
Тут нет ничего интересного. Это простая проверка, так называемый флаг, немного нагромождённый. Мне помогли и нашли файл с 1300+ плохими словами, я его дополнил до 1330. Пока-что нарушений замечено не было, но фильтр не идеальный и его можно обойти, если очень захотеть… К сожалению фильтр это единственное бесплатное решение, которое было найдено лично мной.
Самый интересный момент, который мне понравился больше всего — открытки.
characters = ["deer", "Santa Claus", "meowt"]
i1 = ['Желаю счастья полный ворох,','Пусть жизнь играет красками.','Веселья, радости, задора!','Пусть будни станут сказками.']
i2 = ['Счастья в жизни Вам желаем,','Много добрых пожеланий','Исполненья всех мечтаний!']
i3 = ['Самых ярких впечатлений,','Самых сказочных мгновений.','Пусть Вам этот год несет','Много радостных хлопот!']
color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100))img = Image.new("RGBA", (800,800), color)
# Создаем объект для рисованияdraw = ImageDraw.Draw(img)
# Загружаем шрифтrandom_font = random.choice(['19510.otf', '20610.ttf', '2055.ttf'])font_path = random_font # замените на путь к вашему шрифтуfont_size = 55font = ImageFont.truetype(font_path, font_size)
# Определяем цвета буквcolors = ['red', 'green', 'blue', 'orange', 'magenta', "pink", "black"]phrase = '!!!С Новым Годом!!!'
x_pos = 120 # начальная позиция по горизонталиy_pos = 100 # начальная позиция по вертикали
for i, char in enumerate(phrase):color = colors[random.randint(0, 4)] # выбираем цвет из списка циклическиdraw.text((x_pos, y_pos), char, fill=color, font=font)offset = font.getlength(char) # Получаем ширину символаx_pos += offset # Обновляем позицию по горизонтали
if random.choice(characters) == 'deer':i_ = random.choice(['i1','i2','i3'])if i_ == 'i1':lines = i1elif i_ == 'i2':lines = i2elif i_ == 'i3':lines = i3if random_font == '2055.ttf':random_font = '19510.otf'font_path = random_font # замените на путь к вашему шрифтуfont_size = 45font = ImageFont.truetype(font_path, font_size)colors = ['blue', 'green', 'red', 'purple']# Вычисляем центр изображенияcenter_x = img.width // 2center_y = img.height // 2 - 40# Устанавливаем начальную позицию текстаstart_y = center_y - len(lines) * font_size // 2for i, line in enumerate(lines):text_color = colors[i % len(colors)]draw.text((center_x, start_y + i * font_size), line, fill=text_color, font=font, anchor='mm')deer_image_1 = Image.open('deer.png').resize((350, 350))# Определение местоположения оленей на изображенииdeer_position_1 = (460, 450)# Добавление изображений оленей на основной холстimg.paste(deer_image_1, deer_position_1, mask=deer_image_1)img.save("test.png", "PNG")
bot.send_photo(message.from_user.id, open('test.png', 'rb'))elif random.choice(characters) == 'Santa Claus':i_ = random.choice(['i1','i2','i3'])if i_ == 'i1':lines = i1elif i_ == 'i2':lines = i2elif i_ == 'i3':lines = i3if random_font == '2055.ttf':font_path = random_font # замените на путь к вашему шрифтуfont_size = 60font = ImageFont.truetype(font_path, font_size)# Устанавливаем начальную позицию текстаstart_x = 770 # Позиция X для начала текста (справа)start_y = 220 # Позиция Y для начала текстаcolors = ['blue', 'green', 'red', 'purple']else:font_path = random_font # замените на путь к вашему шрифтуfont_size = 45font = ImageFont.truetype(font_path, font_size)# Устанавливаем начальную позицию текстаstart_x = 770 # Позиция X для начала текста (справа)start_y = 230 # Позиция Y для начала текстаcolors = ['blue', 'green', 'red', 'purple']for i, line in enumerate(lines):text_color = random.choice(colors)draw.text((start_x, start_y + i * font_size), line, fill=text_color, font=font, anchor='ra') # Выровняли текст по правому краюimage_1 = Image.open('santa.png').resize((400, 450))position_1 = (-20, 410)img.paste(image_1, position_1, mask=image_1)img.save("test.png", "PNG")# Отправляем изображение в чатbot.send_photo(message.from_user.id, open('test.png', 'rb'))
Выглядит сложно, громостко, что-то можно было упростить. Но цель — рисовать картинки. Код рабочий и рисует картинки. Цитата одного хорошего человека: «2007?». Да, пока-что дизайн не впечатляет, но они живые. Наверное в период, когда нейросеть может нарисовать картинку и она будет интересной, хорошей, но сделана не «с душой», могут зайти и мои открытки. Тем более это всё шутки, сами понимаете, с нейросетками я тягаться не планировал…
А всё остальное чисто банально и чисто стандарт.
if chek(message.text):with open('message_txt.txt', 'r', encoding='utf-8') as file: m = [line.strip().lower() for line in file]if message.text.strip().lower() not in m:with open("message_txt.txt", 'a+', encoding='utf-8') as file:file.write(f"{message.text}\n")with open("message_txt.txt", 'r', encoding='utf-8') as file:messages = file.readlines()if len(messages) > 0:message1 = random.choice(messages).strip()
bot.reply_to(message, message1)else:
bot.reply_to(message, f"Я осуждаю твои сообщения, {message.from_user.first_name}. Если продолжишь писать гадости, то мне придётся тебя залокировать. Пожалуйста, не пиши гадости.")
Мозг новогоднего Мяута — рандом. Можно бы сделать лучше и углубиться в NLP. Но задача была не сделать говорящего кота без использования генеративно-языковых моделей. Задача сделать весёлого и новогоднего бота.
Как-то так. Новогодний бот Мяут ещё далёк от идеального новогоднего бота… Но пока-что так…