LINUX.ORG.RU

Учился делать Telegram-бота

 ,


1

1

Привет, ЛОР!
Есть один...

В общем, пытался в Python и Telegram API, не уверен в правильности кода и/или некоторых решений, хочу, чтобы Python-гуру оценили код и подсказали что и где неплохо бы исправить.

Бот ещё не допилен, но желающие могут его себе, т.к. все известные мне с похожим функционалом — closed-source, а значит скорее всего сливают логи из ваших чатов доброму создателю.

Из возможностей — разного рода рулеточки, статистика (WIP), запись логов и что-то ещё.
Можно легко добавлять свои собственные команды, если хоть немного знакомы с удавом.
А, ну и я осилил интерфейс конфигурирования бота с собстенными конфигами для каждой конфы — этого вообще нет нигде (ибо ограничения Telegram API) и реализовывать пришлось через одно место.

Зачем тред? Всё вышеописанное, да и просто так, чтобы, так скзть, добро не пропадало даром.
Спасибо за внимание.

NB! Если зашли в тред напомнить, что Телеграм не нужен — все и так это знают, не нужно на это тратить байты!

★★★★☆

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

Ответ на: комментарий от annerleen

Третий, конечно кое-где просел, но не настолько, чтобы сливать руби: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/ruby.html

Вообще, они одинаково медленные. Если уж ты заговорил о производительности в контексте задач питона на серверах, то говорить следует про Go.

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

добро пожаловать в стан ссаных быдлокодеров.

Как же хорошо, что я не программист.
Ещё соглашения какие-то там, стили.

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

Третий, конечно кое-где просел, но не настолько, чтобы сливать руби:

Принимаю ваши анусы в качестве ставок.

annerleen ★★★★☆
() автор топика
Ответ на: комментарий от annerleen
import psycopg2
import psycopg2.extras

conn = psycopg2.connect(dbname='', user='', password='', host='localhost')

cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
for i in range(23480):
    cur.execute( "select users.*, %s as testarr from users where users.id=%s", ([1,2,3],0) )
    for row in cur:
        assert row["login"] == 'root'
        assert isinstance(row['testarr'], list)

conn.close()


# time python3 python.py 

real	0m4.350s
user	0m1.572s
sys	0m0.444s

#!/usr/bin/ruby

require 'pg'

begin

    con = PG.connect :dbname => '', :user => '', :password => ''
    arr_dec = PG::TextDecoder::Array.new()
    23480.times do
        rs = con.exec_params "select users.*, $1 as testarr from users where users.id=$2", [[1,2,3], 0]
        rs.each do |row| 
            raise "assert failed 1" unless row["login"] == 'root' 
            raise "assert failed 2" unless arr_dec.decode(row["testarr"]).kind_of?(Array) 
        end
    end

rescue PG::Error => e

    puts e.message 
    
ensure

    con.close if con
    
end

# time ruby ruby.rb 

real	0m3.193s
user	0m0.528s
sys	0m0.188s


И это ещё используем prepared statements в Ruby. Без них ещё быстрее.

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

Даже не знаю, по-моему оно того не стоит. Ты даже докуметацию не удосужился почитать.

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

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

простите за мой русский, забываю.
исправьте на более корректный вариант, пожалуйста.

Функциональность, функциональные возможности, набор функций.

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

А, ну вот ещё —

# cat tnt.lua 
local sql = require 'pg_tarantool'
db = sql.connect({ host = '127.0.0.1', port = 5432, user='', dbname='', password='', connections=1 })
for i=1,23480 do
	local r = db:prepare("select users.*, $1 as testarr from users where users.id=$2")({1,2,3},0)
	assert(r[1].login == 'root')
end


# time tarantool tnt.lua 

real	0m5.275s
user	0m1.364s
sys	0m1.868s


Либу переписал практически полностью, но за скоростью не гонялся — в приоритете маппинг типов постгреса в луашные.

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

Ты — дурачок? Кто же так бенчит. Если опустить идиотизм такого подхода, то ты бенчишь библиотеки, а не языки, не говоря муже о том, что ты не используешь асинхронные возможности питона.

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

Сам дурак.
Пойти и посмотреть, что psycopg2 и pg/ruby это биндинги к libpq — это тебе не на ЛОР под себя бзднуть, ага.

что ты не используешь асинхронные возможности питона.

Асинхронные возможности Ruby и Lua тоже не использовал. Всё честно.

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

Здравия желаю! Вам выписан штраф в размере 1000 (одной тысячи) рублей по статье 20.1 КоАП РФ за нецензурную брань в общественном месте. Оплатить штраф вы можете в любом отделении «Сбербанка» с восьми утра до девяти утра по чётным четвергам.

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

Ты скозал?

P.S. надеюсь, ты не всерьёз сейчас рассуждал о «бенчах» с 24к простых запросов в БД и разницей в секунду, правда?
если серьёзно, то иди отдохни от этого айти, ну его.

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

Ну а если серьёзно — то Python ужасен при работе с Постгресом.
Во-первых, он не поддерживает Prepared Statements.
Это не они:

cur.execute( «select users.*, %s as testarr from users where users.id=%s», ([1,2,3],0) )

Во-вторых, нельзя просто так записать результат запроса в переменную.
Это же питон, в котором всё через жопу —

cur.execute( «select users.*, %s as testarr from users where users.id=%s», ([1,2,3],0) )
for row in cur:

DictCursor с примерами из документации ВНЕЗАПНО не работает.
А, ну да, Python, свой путь, вот это вот всё.

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

это биндинги к libpq

И что с того?

Асинхронные возможности Ruby и Lua тоже не использовал. Всё честно

Так и хочется вручить тебе медальку «бенчмаркер года».

Попозже я подключусь к твоей специальной олимпиаде, очень люблю такое, выжму из питона побольше. Запакуй мне дамп бд, если она фейковая, плиз.

Ты, кстати, assert в питоне некорректно используешь, он в проде вообще не будет отрабатывать.

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

И так всегда — в самой обычной ситуации нужно использовать некую анальную питонью магию.

  File "python.py", line 8
    rows = [*map(_prepare, cur.execute("select users.*, ARRAY[1,2,3] as testarr from users where users.id=0"), ]


Попытался угадать, куда воткнуть скобочку —

NameError: name '_prepare' is not defined

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

Функцию ты должен сам определить или лямбду вставить. Кто ж кроме тебя знает, как надо каждую строку обрабатывать.

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

Так и хочется вручить тебе медальку «бенчмаркер года».

Ты же понимаешь, что просто заспамить сокет запросами Асинхронно™ — это тупо, и нужно как минимум реализовывать очередь соединений?
А если есть пул соединений и асинхронные запросы, то «бенчи» уткнуться в ресурсы тестовой VPS с ограниченным max_connections..

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

Конечно понимаю.
Поэтому в продакшене у нас не Ruby и не Python.

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

Для меня это естественно.
Но смотреть, как меня пытаются разубедить с пеной у рта — забавно ☺

Тебя вообще не смущает то, что время старта интерпретаторов отличается раз в 5, и бенчить надо хотя бы после подключения к БД, и явно не time?
Как и то, что в Ruby используется prepared statements, которые ещё и компилируются на каждой итерации, что замедляет выполнение раза эдак в два..

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

А, да, моё любимое для time'филов

void main() {
	int i = 1;
	int k = 0;
	while(i<10000000) {
		k = i+i/10;
		++i;
	}
}



-- for.lua
i = 1
k = 0
while i < 10000000 do
  k = i + i / 10
  i = i + 1
end



root@fs-ptr1:~# time ./a.out 

real	0m0.070s
user	0m0.068s
sys	0m0.000s
root@fs-ptr1:~# time luajit for.lua # УУУ ЧТО ПРОИСХОДИТ! ЫНТЫРПРИТАТОР БЫСТРЕЕ НЯШНОЙ!

real	0m0.042s
user	0m0.040s
sys	0m0.000s


кто поймёт, тому печенька.

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

Тебя вообще не смущает то, что время старта интерпретаторов отличается раз в 5, и бенчить надо хотя бы после подключения к БД, и явно не time?

Не я же так замеряю. И нет, меня это смущает сильно меньше чем бенчинг с помощью i/o. Для скриптоты это вполне валидно, смотря как условия поставить.

Не юзал psycopg2, но что-то мне подсказывает, что там не просто форматирование.

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

Не юзал psycopg2, но что-то мне подсказывает, что там не просто форматирование.

Вроде как замена ' на ".
Так можно, но не нужно, надеюсь, не надо объяснять почему?

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

Всё в том же — глупо смотреть на замеры time.

Ты вот начал убеждать, что IO-фаллометрия — плохо, а на самом деле интерпретатор питона запускается тупо на секунду медленнее руби, остальное на самом деле +- одинаково.

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

Всё в том же — глупо смотреть на замеры time

Это ежу понятно.

на самом деле интерпретатор питона запускается тупо на секунду медленнее руби

Ты бредишь. На телефоне:

time python -c 'import sys; sys.exit(0)'

real    0m0.103s
user    0m0.070s
sys     0m0.020s

И, опять же, не учитывать разницу вполне валидно. Завит от целей теста.

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

Тогда к чему это всё?

К тому, что зачем есть ползучий кактус, если есть Ruby, которая ничем не хуже, а то и лучше?

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

Эскобар, я абсолютно согласен. Но индустрия сделала выбор в пользу питона.

Я как бы отъявленный хейтер питона, если что, на ЛОРе, масаа тому свидетельств. Но руби мне нравится ещё меньше, ибо поделия на ней люто жирные и зачастую абсолютно нерабочие. Ну и синтаксис там блевотный.

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

Индустрия чего и какая?
Там вон ещё всякие ангуляры и электроны в мейнстриме, это же не повод их есть?

Ну и синтаксис там блевотный.

Какой из трёх (или больше?) вариантов блевотный?
Про method args и прочие отсутствие return, пожалуй, соглашусь, но можно не выделываться и использовать стандартный def method() return 1 end, от питуна это отличается только возможностью не уронить всё и вся, промахнувшись пробелом.

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

ибо поделия на ней люто жирные

Жир на мониторе у меня от твоих постов :3.
Вот оно какбэ обслуживает сколько угодно клиентов, делает это быстро и ест чуть меньше 200 МБ из 2ГБ памяти, не увеличиваясь с аптаймом.

12072 Passenger watchdog
19032 Passenger core
164364 Passenger AppPreloader: /var/www (forking...)


root@vps369451:~# du -sh /var/www --exclude=/var/www/public #public=downloads
1.7M	/var/www


А если уж очень хочется, то можно и так, но чуть медленнее. (приложение одно и то же, да)

 6168 nginx: worker process                           
 6336 nginx: worker process                           
 6416 nginx: worker process                           
 6424 nginx: worker process                           
30944 thin server (0.0.0.0:3000)    


Жаль, что Ruby почти у всех ассоциируется только с Rails, а это то ещё говнище, да.

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

Это несерьёзные бенчи в контексте многих языков, которые там есть. На лоре это обсуждалось. Лучше самому замерять.

anonymous
()
Ответ на: комментарий от annerleen

Софтварная.

Там вон ещё всякие ангуляры и электроны в мейнстриме, это же не повод их есть?

Не знаю как ты связан с разработкой ПО, но явно чего-то не догоняешь. Очень даже повод. Могу объяснить почему.

Впрочем, насчёт ангуляра ты ошибаешься. Он скоро отъедет на помойку истории.

Какой из трёх

У языка не может быть несколько «синтаксисов».

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

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

Но управляющих конструкций — несколько видов.
И в самом стандартном варианте — мало чем отличается от того же питона.

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

На лоре это обсуждалось

Не могу найти.

Претензии по неравнозначности реализаций я слышал, конечно, но чем дальше от хеллоуворда, тем больше разница в реализациях, всё в порядке. Более серьёзных бенчмарков всё равно нет.

WitcherGeralt ★★
()

Телеграм не нужен все и так это знают, не нужно на это тратить байты!

У меня много байтов, я зашел напомнить, что телеграмм не нужен.

Alve ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.