Это копия, сохраненная 5 августа 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Предыдущий: >>2248924 (OP)
Литература:
https://ln2.sync.com/dl/cf2c1d070#xq4s328t-xbbjys2z-9r6j7ss7-gf4e9dv6 <-- Книжки, новое собрание
Ещё книжки: https://yadi.sk/d/HQhhsBsq3TVRUq
Тоже книжки: https://yadi.sk/d/tArKKuQu3Kejuq
Больше книжек: https://yadi.sk/d/H-00n-UG3RSQem
Анон, вместо того, чтобы без разметки постить код, лучше шарь его через специальные ресурсы:
https://ideone.com/ - возможность постить листинги кода и онлайн-запуска, не требует регистрации
https://dumpz.org/ - можно постить листинги, не требует регистрации
https://pastebin.com/ - для листингов, регистрация не обязательна
https://www.codepile.net/ - можно расшарить код в том числе на редактирование, особая полезная опция - чат при каждом листинге, где можно код обсудить
https://pyfiddle.io/ - запуск python кода онлайн, но чтобы шарить, надо регистрироваться
#######################################
ЧаВо: https://github.com/TheKnightsWhoSayNi/info/wiki/Hat Актуальность примерно 2015 года
Вопросы-ответы:
— А стоит ли читать Лутца, том номер N?
Мнения в треде разделены. Кто-то за (очень неплохая база даётся), кто-то против (слишком много воды и объём книг убивает всё рвение). В общем — решать тебе, книга вредна не будет, но ты можешь её просто не дочитать и забросить.
— Стоит ли читать %книга_нейм%, если там питон версии 2.х?
Нет, не стоит. 100% есть более актуальная книга, для пистона 3.х
— А что ещё можно читать?
Питон сам по себе очень хорошо задокументирован и для уровня начинающих, и для продвинутого. Смотри официальную документацию. Можно начать вот с этого https://docs.python.org/3/tutorial/introduction.html
— Есть у кого на примете годный курс лекций по алгоритмам? Формат лекций мне как-то ближе, нежели просто чтение книги.
МФТИшный курс, например, https://www.youtube.com/playlist?list=PLRDzFCPr95fK7tr47883DFUbm4GeOjjc0
— Что можно почитать/посмотреть по многопоточности/параллелизации в питоне, да и вообще в целом?
Очень годный ролик на американском языке про многопоточность и асинхронность https://www.youtube.com/watch?v=MCs5OvhV9S4
— А как учить джангу? Нахожу только книги по джанге 1.х
У джанги отличные доки (одни из лучших для пистоновских либ, имхо), почитай их для начала. Книгу по джанге можно читать и для версий <2, это не проблема, т.к. принципы остаются теми же. Для переката на 2.х хватит changelog`a или тех же самых доков/статей. Начни изучать с разбора учебного приложения с голосовалкой из официальной документации.
— В ньюфаг-треде написано, что нужно начинать с SICP, чтобы научиться программировать
Вот, пожалуйста, та же самая программа, но переработанная под язык Python: http://composingprograms.com/ (нужно знать ангельский или уметь пользоваться переводчиком)
— Можно ли на питоне делать мобильные приложения?
Да, смотри на фреймворк Kivy https://en.wikipedia.org/wiki/Kivy_(framework) https://kivy.readthedocs.io но народ на него жалуется
— Как можно без лишней возни ускорить программу на питоне
1) проверь сначала свой код, алгоритмы и структуры данных. Чаще проблема здесь.
2) код можно иногда феерично ускорить, используя JIT (Just-in-Time) компиляцию. Почитай обязательно про модуль numba, он ставится через pip, и альтернативный интерпретатор PyPy.
— Дайте нормальные книжки на русском! Мы, блядь, не в пиндосии живём
Брат, смотри книжки по ссылкам в шапке, там есть и русские. Но помни, без языка ангелов твоя жизнь проходит мимо и ты обречён быть на обочине знаний и технологий.
ps: анон, если ты вносишь изменения в шапку, оставляй ссылку на код с обновлённым исходником.
Исходник: https://dumpz.org/bASGKD8cCFDf
Как так?
Аргументы принт вычисляются перед вызовом, врайт отрабатыват и возвращает свой результат, потом отрабатывает принт.
Раздели их и всё. Группу делай в асинхронном режиме, а после неё синхронный. В conqurrent можно это обернуть без необходимости делать омерзительные асинхронные методы:
ex1=execute(task1, args)
ex2=execute(task2, args)
task3(args, ex1.ready())
У тебя выполняется стдаут на этапе загрузки параметров в принт и даёт какой-то результат.
Ничего удивительного тут нет
насколько я понял, он проксирует запросы к базовому классу, который определяется в порядке mro. если вызвать super() без аргументов, то это будет эквивалентно super(MyClass, self), и запросы к базовому классу буду проксироваться через self, т.е. в __init__, напиример, явно не нужно будет передавать self. На этом этапе все понятно, проблемы с пониманием у меня начинаются в тот момент, когда в качестве второго аргумента передается не объект, а тип.
Пример: если я переопределяю __new__, то в конце обычно пишут что то типо return super(MyClass, cls).__new__(cls, args, *kwargs)
Так вот, почему обязательно нужно указывать cls в качестве первого аргумента? Разве не должно произойти проксирование от лица cls, как в примере с __init__?
на пике аналогия с методом класса, и там это работает, как ожидается
получается __new__ -- не метод класса?
У меня потребности немного другие, в твоем случае таска 3 не начнется до тех пор пока не завершится первая. Распишу подробнее.
Условно, есть бесконечная таска-продюсер, которая генерирует некоторые значения и кладет их в массив до тех пор пока он не будет заполнен (в моем случае это asyncio.Queue и наполняется оно через await queue.put) и есть таски-консумеры, которые берут значения через await queue.get.
В группу тасок консумеров могут в любой момент добавится еще в любом количестве. Важно, что бы если в массиве есть значения, а консумеры еще не закончились ни в коем случае не запускать таску продюсер (только в случае, если массив опустел, а консюмеры остались), так как она работает гораздо медленнее и соответственно для этого мне и нужны были приоритеты, что бы продюсер запускался только в момент простоев и опустощения массива.
new это статический метод, который именно создает новый объект, поэтому нужен тип. А init уже настраивает этот созданный в new объект, поэтому он уже знает, что это за класс.
да, это я в курсе, просто не очевидно было, что new это статический метод
Тут приоритеты не помогут. Нужны примитивы синхронизации. Тебе нужна третья синхронная? таска, контроллер, которая будет периодически (или может после каждой таски из обеих групп, но тогда это проще декоратором сделать, а не новой таской) запускаться, проверять выполнено ли условие (первая группа тасок завершило выполнение) и менять глобальный лок. Потом в зависимости от значения глобального лока вызывать таски одной из двух групп. Можно просто на все таски кастомный декоратор, который выполняет её только при определёном значении лока, а меняет значение лока только таска контролер. Вместо лока можно кондишионал вариэйбал использовать как>>67304 этот анон посоветовал. Возможно так даже поконсистентней будет.
>>67304
Я решил еще попробовать тупо в лоб решить без всякого тюнинга просто создавая задачи через create_task внезапно оказалось, что таски выполяются в том порядке, что я и хочу, лишнего вызова генерации посреди сбора данных не происходит, все последовательно. Пошел курить статьи по работе эвентлупа.
Мехатронщик. Сам учил в пассивном режиме, т.к лет 10 так или иначе кодил что-то, алгоритмы разной степени сложности, логику плк.
На резюме просили делать простые серваки, микросервисы, генерация токенов, менедж файлов, пикч и тд.
Если до этого вообще не связывался с информатикой, то наверное лучше курсы.
Нашёл работу через месяца два примерно, т.к с вебом вообще не знаком был
Мне кажется сначала лучше понять REST, нежели и REST и асинхронность сразу. А если новичок не знает ещё чего-то, например работу с БД, ORM, то ещё больше информации новой приходится узнавать
Я понимаю, образование (буду его так называть) должно быть простым, но не в ущерб качеству будущих продуктов, REST понять можно за пару часов на всем известном сайте (https://www.restapitutorial.com/), тем более, разве не движок важнее всего? Скорость принятия и обработки запросов является чуть-ли не основополагающей проблемой при работе с большим кол-вом запросов (>10к/s к примеру), а сейчас заказчики просят чуть-ли не 80к/сек, для проектов стоимостью меньше 20к!
Пиздос, а до моды на асинхронность, которой от силы лет десять, как люди жили вообще? По домофону сайты грузили, сука.
Лет 10 назад запросы были меньше, по части скорости и кол-ву, так сказать что невидимо невооруженому взгяду - то асинхронно (Делитанское дерьмо, знаю, но звучит прикольно)
Разве не выгодней сразу сделать приложение, которое способно выдерживать большие нагрузки, чтобы не тратиться на создание инстансов на других серверах, чем создать вроде-как простое приложение, но не способное выдерживать большие нагрузки?
В разумных пределах, если это не мешает работе. Про вред преждевременной оптимизации почекай как-нибудь статейки или еще чего.
Разве автоматическое задумывание на будущее является чем то плохим? (Я понял про разумные пределы, я имею ввиду про некое злоупотребление)
>2022 год
>использовать синхронные драйверы для коннекта в БД
Вы че, пистонисты бля, совсем гавном зажрались уже?
Сейчас все асинхронные фреймворки по сути напоминают тот же фласк
Если приложение получит пользу в производительности от перехода с синхроного на асинхроный формат, то это значит, что там слишком много ио операций и оно так же получит прирост перфоманса от увелечения количества тредов. В гуникорне можно просто задать оверкомит 8 тредов процесс и по одному процессу на ядро процессора. Плюс буферизация и распределение нагрузки в энджинксе если есть долгие и быстрые запросы. И на очень долгих селари. Этого достаточно чтобы код поддерживал тысячи запросов в секунду на одном инстансе. Причём на малом количестве запросов в несколько сотен например такой код быдет быстрее асинхроного т.к. не надо на каждый чих контекст в ивентлупе менять. С большим количеством запросов этот вариант не справиться, а асинхроный переварит ценой понижения перфоманса. В этом похоже и трейдоф. Хочешь быстро приложение делай синхроно. Хочешь чтобы паралельно много юзеров на одном инстансе сервилось делай асинхроно. Это уже вопрос экономии. А на инстансах нет особого смысла экономить тогда месяц аренды одного инстанса стоит как час работы одного спеца по асинхронщине. Поэтому видимо бизнес и не спешит переходить на асинхроные фреймворки
Как же ты филигранно размотал этого маленыша...
>Причём на малом количестве запросов в несколько сотен например такой код быдет быстрее асинхроного т.к. не надо на каждый чих контекст в ивентлупе менять
Нужно всего лишь менять тред каждые 100 мс вне зависимости от того, есть ли в нем выполняемая нагрузка или нет. Соответственно, если у тебя висит 20 тредов, а задача только в половине, то процесс будет замедлен в два раза просто из-за необходимости ожидания. Треды для IO можно использовать только в языках где поддерживаются нормальные треды, а не GIL.
Чуть обосрался, не 100мс, а нс, но сути не меняет
АРЯЯЯ ДИДЫ ТАК ДЕЛАЛИ И НАМ ЗАВЕЩАЛИ! ЯСНО??
питон при работе с каждым новым питонобджект отпускает гил. А ещё при созвании сокета в входа в сишную библиотеку. Поэтому питон релизик гил достаточно часто чтобы скедулер ос за одну милисекунду успел пройтись по всем тредам несколько раз. Плюс в фласке более 90 процентов времени тред ждёт. Поэтому процесс питона почти всегда будет выполнять тред, который не ожидает ио. Тут главное не создавать лишних тредов чтобы вечное переключение контекста его не стало замедлять. 8 в процессе эмпирически выглядит хорошо. Но тут надо подгонять под каждый проект.
Хачю кейворды поменять
>Поэтому питон релизик гил достаточно часто чтобы скедулер ос за одну милисекунду успел пройтись по всем тредам несколько раз.
В любом случае, переключение треда гораздо дороже, чем таски в эвентлупе
>8 в процессе эмпирически выглядит хорошо. Но тут надо подгонять под каждый проект.
Только если у тебя нет походов на сторонние сервисы/в сеть, а сам инстанс ходит только в базу/память без тяжелых запросов. Иначе треды запнутся о 100 мс задержку на стороннее апи и приложение сдохнет без заливания дополнительными инстансами. В мелких проектах норм, но на чем-то большем начнут приходить неприятные счета за железо.
>В любом случае, переключение треда гораздо дороже, чем таски в эвентлупе
Да дороже. Но таски в ивентлупе переключаются чаще. 2 таск на 80 процентов состоящие из ио ожидания по 50 мс в двух тредах законачаться примерно через 50 мс, а в ивентлупе примерно за 60 мс. То есть выполняя простую операцию в треде тебе не нужно прерывать его каждый раз когда авэйт вызвается чтобы переключиться на другую таску. Там неявно вызывается релиз гила, но такой же релиз и в тасках с ивентлупом происходит. Так что ивентлуп помогает обслуживать больше одновременных запросов на том же железе за счёт небольшого увеличиния его времени выполнения.
>Только если у тебя нет походов на сторонние сервисы/в сеть, а сам инстанс ходит только в базу/память без тяжелых запросов.
Нет. Это неправда. Гил релизится на открытие сокета. То есть выполняя 2 запроса к внешнему апи в двух разных тредах по 100 мс они оба после открытия сокетов отпустят гил и выполнятся за 100 мс. Тут нет просадки пока не делаешь сотни запросов на один реквест. Но даже для этого есть оптимизация не требующая явного переписывания кода проекта на асинхроный мод.
> В мелких проектах норм, но на чем-то большем начнут приходить неприятные счета за железо.
Нет. В больших тоже годится. Вот возьми время ответа 40-50 мс. Это без учёта времени пинга и работы энджинкса т.к. они не влияют на работу треда. Это только время окупации треда. Если там время дольше, то таску можно перенаправить в селарии, доставаться значения из кэша вместо явного вызова каждый раз или как-нибудь ещё оптимизировать и тогда время станет снова 40-50 мс. И возьмём средний такой инстанс на 8 цп с 8 тредами на процесс за 20 центов в час. Это где-то 150 долларов на 1500 запросов в секунду. 10 запросов в секунду за каждый доллар. Для маленьких приложений это норм цена т.к. пока цена 5к доларов не привысит (зп одного разраба) можно не заморачиваться оптимизацией и скэйлить. А это 50к запросов в секунду. Потом уже можно заняться оптимизацией эндпоинтов, тюнингом параметров и править архитектуру клауда чтобы при тех же расходах держать в нескольк раз больше запросов в секунду. Так можно 100-200 тысяч запросов в секунду выдать почти не тратясь на облако при эффективности 20-40 запросов в секунду. Если прям очень надо выдать эффективности в сотню и больше запросов в секунду на доллар, то пора вводить асинхронность. И то в таком случае лучше вынести кретический функционал в микросервисы и переписать их на го ля большего выхлопа, чем поддерживать одновремено фласк и фастапи какой-нибудь. И вот тогда может и будет проект поддерживать сотни тысяч запросов в секунду на кластере ценой в пару десятков тысяч долларов. Но там вылазят проблемы другого масштаба и просто асинхроность тут не достаточно. Всякие фастапи полезны когда поднимаешь всего 3 инстанса (балансировщик, основной и резервный серверы) и хочешь как можно скорее новый код в продакшен и чтобы он справлялся с тысячами пришедших пользователей одновремено ценой скорости работы.
>В любом случае, переключение треда гораздо дороже, чем таски в эвентлупе
Да дороже. Но таски в ивентлупе переключаются чаще. 2 таск на 80 процентов состоящие из ио ожидания по 50 мс в двух тредах законачаться примерно через 50 мс, а в ивентлупе примерно за 60 мс. То есть выполняя простую операцию в треде тебе не нужно прерывать его каждый раз когда авэйт вызвается чтобы переключиться на другую таску. Там неявно вызывается релиз гила, но такой же релиз и в тасках с ивентлупом происходит. Так что ивентлуп помогает обслуживать больше одновременных запросов на том же железе за счёт небольшого увеличиния его времени выполнения.
>Только если у тебя нет походов на сторонние сервисы/в сеть, а сам инстанс ходит только в базу/память без тяжелых запросов.
Нет. Это неправда. Гил релизится на открытие сокета. То есть выполняя 2 запроса к внешнему апи в двух разных тредах по 100 мс они оба после открытия сокетов отпустят гил и выполнятся за 100 мс. Тут нет просадки пока не делаешь сотни запросов на один реквест. Но даже для этого есть оптимизация не требующая явного переписывания кода проекта на асинхроный мод.
> В мелких проектах норм, но на чем-то большем начнут приходить неприятные счета за железо.
Нет. В больших тоже годится. Вот возьми время ответа 40-50 мс. Это без учёта времени пинга и работы энджинкса т.к. они не влияют на работу треда. Это только время окупации треда. Если там время дольше, то таску можно перенаправить в селарии, доставаться значения из кэша вместо явного вызова каждый раз или как-нибудь ещё оптимизировать и тогда время станет снова 40-50 мс. И возьмём средний такой инстанс на 8 цп с 8 тредами на процесс за 20 центов в час. Это где-то 150 долларов на 1500 запросов в секунду. 10 запросов в секунду за каждый доллар. Для маленьких приложений это норм цена т.к. пока цена 5к доларов не привысит (зп одного разраба) можно не заморачиваться оптимизацией и скэйлить. А это 50к запросов в секунду. Потом уже можно заняться оптимизацией эндпоинтов, тюнингом параметров и править архитектуру клауда чтобы при тех же расходах держать в нескольк раз больше запросов в секунду. Так можно 100-200 тысяч запросов в секунду выдать почти не тратясь на облако при эффективности 20-40 запросов в секунду. Если прям очень надо выдать эффективности в сотню и больше запросов в секунду на доллар, то пора вводить асинхронность. И то в таком случае лучше вынести кретический функционал в микросервисы и переписать их на го ля большего выхлопа, чем поддерживать одновремено фласк и фастапи какой-нибудь. И вот тогда может и будет проект поддерживать сотни тысяч запросов в секунду на кластере ценой в пару десятков тысяч долларов. Но там вылазят проблемы другого масштаба и просто асинхроность тут не достаточно. Всякие фастапи полезны когда поднимаешь всего 3 инстанса (балансировщик, основной и резервный серверы) и хочешь как можно скорее новый код в продакшен и чтобы он справлялся с тысячами пришедших пользователей одновремено ценой скорости работы.
avatar.status = 'ready'
avatar.status = 'pending'
avatar.save()
То на моменте вызова save мы отправим 1 запрос (последний) или отправим несколько запросов на UPDATE поля status?
>То есть выполняя 2 запроса к внешнему апи в двух разных тредах по 100 мс они оба после открытия сокетов отпустят гил и выполнятся за 100 мс.
Это только работает только во время инициализации запроса, если при следующем переключении он будет продолжать ожидать, то там потребуется те же 100 нс без полезной нагрузки.
>то таску можно перенаправить в селарии
То есть использовать сторонний таск менеджер и получить дополнительный расход на загрузку и выгрузку задачи по которой ответ придет в течении 100-200 мс. Причем паралеллизм достигается за счет закидывания процессами, которые имеют такие же ограничения. Да и целом, речь шла о мультитрединге против асинхронности, процессы подключить и к асинхронному коду можно.
>доставаться значения из кэша вместо явного вызова каждый раз или как-нибудь ещё оптимизировать и тогда время станет снова 40-50 мс
>как-нибудь
А если никак-нибудь? Запросы не выдают один и тот же результат и поэтому их нельзя закешировать. Любая интеграция с крупным продуктом скорее всего породит такие проблемы.
>Вот возьми время ответа 40-50 мс
Нет, не возьму, даже запрос гугловой статики размазанной по куче CDN размером 1кб с главной страницы занимает 50 секунд и это без полезной нагрузки. У нас до главного поставщика данных запрос идет 300 мс, соответветственно дальнейшие расчеты можно не смотреть.
ап
Еще тоже такой вопрос. Есть вообще цмски на питоне похожие на дле где есть многое из коробки, например, шаблоны.
Отправится только один запрос UPDATE (при выполнении строки с save).
Я знаю об этой цмске, там есть шаблоны, комунити пилит шабы или нет? А то придется вручную расставлять в шаблонизаторе.
Комунити, проект то опен сорсный
Например, надо сделать запрос на другой ресурс и записать результаты в базу.
Это будут два отдельным метода, типа сделать запрос и записать в базу. Или один, который будет реализован в виде метода соответствующей модели?
Конечно, это всё для примера. В реальных ситуациях запросов и записей гораздо больше.
Независимые методы, но громоздкая бизнес логика. Или же специальные методы, но простая бизнес логика.
Какой подход обычно вы используете и какой считаете оптимальным?
Только не утопическая золотая середина.
>10 запросов в секунду за каждый доллар
Ещё трафик надо добавить, 10 запросов в секунду это 250 миллионов запросов в месяц, от 50 до 1000 гигабайт трафика. Тариф там что-то около 10 центов за гигабайт, соответственно к этому доллару надо добавить ещё 5-100. Зависит от тажеловесности запроса.
Неохота вникать, но не понимаю, в чём проблема с использованием асинхронности.
Ожидание данных в асинхронности основано на select принципе, используются аналогичные системные вызовы. Соответствующая таска получит управление только тогда, когда на сокет придут данные. Что принципиально отличает историю от сокетов.
Поэтому всё работает очень быстро. И ресурсы потребляются небольшие.
Один процесс питона спокойно может обслуживать тысячи одновременных соединений. При условии, что там данных немного, конечно, что один процесс в принципе такой объём данных может обработать.
Сейчас при работе с сетью использовать треды в питоне в принципе несерьёзно, только asyncio и всё, без вариантов.
А если задачи последовательны и каждый этап зависит от предыдущей?
Вообще любой вызов сервера это в большинстве случаев именно последовательные задачи.
Если один вызов делает кучу разных независимых задач, то может лучше их разбить на несколько, а не делать всё в один клик?
Асинхронность нужна на фронте. В беке она нахуй не упёрлась.
>А если задачи последовательны и каждый этап зависит от предыдущей?
>Вообще любой вызов сервера это в большинстве случаев именно последовательные задачи.
И что? IO там меньше не становится, суть не в том, что бы обслужить не один, а множество запросов.
Асинхронность и синхронность - это тупо разные стеки. Разные модули, функции, разная работа с ними.
Если ты умеешь в асинхронность, то будет просто работать. Если ты планируешь работать с сетями, то асинхронность надо уметь.
Сложно асинхронность с gui стыковать.
> Сложно асинхронность с gui стыковать.
С чего бы? Там изначально ивент луп, а если хочешь, чтобы оно не фризилось на тяжелых операциях, то надо хуярить треды или асинхронщину. Так что никто синхронно и не пишет.
Асинхронность в питоне это asyncio. Гуи в основном асинкио не поддерживают, они на базе тредов. И тебе придётся какой-то геморой пройти, запускать asyncio event loop в отдельном треде, потом организоыввать обмен данными между разными тредами и т.п. В общем не очевидно там всё.
В бизнес логике всё линейно. Что же вы там делаете такого, для чего чуть ли не весь код приходится делать асинхронным.
Всем привет, уважаемые заклинатели змеи, накачал книг по питону, возник вопрос, с какой стоит начать, какой продолжить? Какие-то может быть лишние?
Изучаем питон Марк Лутц ( и его же карманный справочник)
Аллен Б. Дауни Основы питона. Научитесь думать как программист
Кристиан Майер Однострочники питон
Билл Любанович Простой питон. Современный стиль программирования
На данный момент за плечами курс поколение питон для начинающих и полкурса поколение питон для продвинутых на степике
А если два запроса придет? А три? А тысяча? И везде то поход в базу, то в другой сервис, то на сторонние АПИ
Если придёт два запроса сервер сам создаст инстанс. На сторонние апи можно отправить от силы пару запросов параллельно, таких мест очень мало. Часто следующий запрос зависит от предыдущего.
Если придёт тысяча, есть celery и aws sqs.
Всё ещё не понимаю для каких задач бек нужно делать асинхронным.
>Если придёт два запроса сервер сам создаст инстанс
Это хорошо, если у тебя нагрузка ограничивается двумя запросами одновременно
>celery
Ну то есть для тебя прикрутить многопроцессорную залупу с необходимостью дополнительного брокера и расходами на передачу туда данных это заебись, а воспользоваться нативной функциональностью языка, которая для этого была создана и более оптимально расходует сетевые ресурсы это НИНУЖНА?
Это как юзать сортировку пузырьком и говорить что нахуй этот тимсорт нужен, работает же.
Для асинхронного кода надо переписывать методы и менять логику.
Для celery надо просто закинуть данные в очередь.
Я вернулся и готов продолжать.
>Это только работает только во время инициализации запроса, если при следующем переключении он будет продолжать ожидать, то там потребуется те же 100 нс без полезной нагрузки.
Нет. Обычный запрос во внешний апи это 99 процентов ожидание результата. То есть 2 треда с разнице ну может миллисекунду делает ревест во внешний апи, а потом отдновремено ждут результата. Поэтому такой кейс нормально паралелится тредами.
>То есть использовать сторонний таск менеджер
Таков путь. Ивентлуп или селари всё равно что-то придётся использовать. Без него бэкенд не полноценен.
>получить дополнительный расход на загрузку и выгрузку задачи по которой ответ придет в течении 100-200 мс
Не уверен о чём ты. Особености селари видны на очень долгих запросах. Если обычный запрос справляется за 30мс, то нет смысла ставить селари, а если там какая-нибудь долгая выгрузка объекта из с3 например, которая 200мс работает, то тогда стоит отправить запрос в селари и тред потрати время только на инициализацию таски всего 10мс и сможет следующий реквест хэндлить. Особеность асинхронщины, что этот запрос обрабатывался бы те же 200мс, но при этом несколько раз в одну мс менял бы контекст, переключался бы на другие реквесты, застревал бы в цпу баунд тасках других реквестов и общее время ответа сервера было бы не 200, а 250мс например.
>Да и целом, речь шла о мультитрединге против асинхронности, процессы подключить и к асинхронному коду можно.
Мультитрединг против асинхроности в одном процессе не совсем продакшен кейс. Если у тебя почему-то есть ограничение всего 1 процесс, то тогда для мультитредингу лучше взять джаву, а для асинхроности го и не писать такое приложение на питоне. С точки зрения инженерной эффективности такой случая можно расматривать, но с точки зрения пользы для бизнеса это какая-то крайность
>А если никак-нибудь?
Там перед как-нибудь было или. То есть перенос таски в селари точно поможет. Или могут быть другие более эффиктивные способы. Вынести например эти запросы в микросервис, хотябы с односекундным ттл может и можно кэшировать. То есть варианты оптимизации есть. Но даже если нет, то возвращаешь на такой долгий запрос 202 код и переносишь таску в селари. Это 100 процентов сократит время окупации треда до пары десятков мс.
> У нас до главного поставщика данных запрос идет 300 мс
Это ты время пинга учитываешь. Я говорю про время, котоое тред занят и не может принимать другие реквесты. Время пинга со стороны бэкенда никак не уменьшить. Тот же cdn очень быстро тебе результат отдаст. Файлик у него скорее всего в раме зэкеширован и меньше, чем за одну мс он его вернут. А всё остальное время потратится на передачу данных по сети. Вот как раз синхроность уменьшает время обработки запроса на сервере в том время как асинхроность увеличивает количество рпс. Это основной технический трейдофф. На принятие решения внедрять ли асинхроность ещё может влиять как сложно будет бизнесу переписать имеющейся код и стоит ли результат этого. Плюс если проект пишут с нуля, то могут подумать о ноде или го. Только если уже есть питоновская команда могут начать думать над новым проектом с фастапи. Ну и другие бизнесовые аспекты наверняка есть. Иммено поэтому асинхроность сейчас не такая популярная, но медленно набирает популярность в новых проектах
Я вернулся и готов продолжать.
>Это только работает только во время инициализации запроса, если при следующем переключении он будет продолжать ожидать, то там потребуется те же 100 нс без полезной нагрузки.
Нет. Обычный запрос во внешний апи это 99 процентов ожидание результата. То есть 2 треда с разнице ну может миллисекунду делает ревест во внешний апи, а потом отдновремено ждут результата. Поэтому такой кейс нормально паралелится тредами.
>То есть использовать сторонний таск менеджер
Таков путь. Ивентлуп или селари всё равно что-то придётся использовать. Без него бэкенд не полноценен.
>получить дополнительный расход на загрузку и выгрузку задачи по которой ответ придет в течении 100-200 мс
Не уверен о чём ты. Особености селари видны на очень долгих запросах. Если обычный запрос справляется за 30мс, то нет смысла ставить селари, а если там какая-нибудь долгая выгрузка объекта из с3 например, которая 200мс работает, то тогда стоит отправить запрос в селари и тред потрати время только на инициализацию таски всего 10мс и сможет следующий реквест хэндлить. Особеность асинхронщины, что этот запрос обрабатывался бы те же 200мс, но при этом несколько раз в одну мс менял бы контекст, переключался бы на другие реквесты, застревал бы в цпу баунд тасках других реквестов и общее время ответа сервера было бы не 200, а 250мс например.
>Да и целом, речь шла о мультитрединге против асинхронности, процессы подключить и к асинхронному коду можно.
Мультитрединг против асинхроности в одном процессе не совсем продакшен кейс. Если у тебя почему-то есть ограничение всего 1 процесс, то тогда для мультитредингу лучше взять джаву, а для асинхроности го и не писать такое приложение на питоне. С точки зрения инженерной эффективности такой случая можно расматривать, но с точки зрения пользы для бизнеса это какая-то крайность
>А если никак-нибудь?
Там перед как-нибудь было или. То есть перенос таски в селари точно поможет. Или могут быть другие более эффиктивные способы. Вынести например эти запросы в микросервис, хотябы с односекундным ттл может и можно кэшировать. То есть варианты оптимизации есть. Но даже если нет, то возвращаешь на такой долгий запрос 202 код и переносишь таску в селари. Это 100 процентов сократит время окупации треда до пары десятков мс.
> У нас до главного поставщика данных запрос идет 300 мс
Это ты время пинга учитываешь. Я говорю про время, котоое тред занят и не может принимать другие реквесты. Время пинга со стороны бэкенда никак не уменьшить. Тот же cdn очень быстро тебе результат отдаст. Файлик у него скорее всего в раме зэкеширован и меньше, чем за одну мс он его вернут. А всё остальное время потратится на передачу данных по сети. Вот как раз синхроность уменьшает время обработки запроса на сервере в том время как асинхроность увеличивает количество рпс. Это основной технический трейдофф. На принятие решения внедрять ли асинхроность ещё может влиять как сложно будет бизнесу переписать имеющейся код и стоит ли результат этого. Плюс если проект пишут с нуля, то могут подумать о ноде или го. Только если уже есть питоновская команда могут начать думать над новым проектом с фастапи. Ну и другие бизнесовые аспекты наверняка есть. Иммено поэтому асинхроность сейчас не такая популярная, но медленно набирает популярность в новых проектах
В обоих режимах трафик на реквест будет одинаковый. Там только количество ресурсов съедаемых реквестом будет разным. То есть если ты за 10 долларов делаешь 100 рпс, то плати ещё долар сверху за трафик, а если 200 рпс, то ещё 2 долара сверху за трафик. Это для примера, но расходы трафика растут линейно с увеличением рпс. Поэтому в метрику рпс на доллар его сложно добавить. Да не надо наверно. типа если у тебя 10к запросов в секунду и ты тратишь Х доларов на трафик, то для синхроного кода тебе нужно 5 вмок, а для асинхроного одна и тоже Х доларов на трафик.
>Неохота вникать, но не понимаю, в чём проблема с использованием асинхронности.
Нет проблемы. Другой анон жаловался, что асинхроность не повнедряли повсюду, а я говорю о низкой рентабельности её внедрения в общем случае.
>Соответствующая таска получит управление только тогда, когда на сокет придут данные.
Не правда. Таска получит контроль только тогда когда другая кооперативная таска отпустит поток выполнения и ивентлуп решит вернуть контроль таске этой таске работающей с сокетом
>И ресурсы потребляются небольшие.
Скорее не потребляются небольшие, а ютилизируются помаксимуму. Небольшое использование ресурсов это скорее про масштабируемости асинхроных сервисов
>Сейчас при работе с сетью использовать треды в питоне в принципе несерьёзно, только asyncio и всё, без вариантов.
Не обязательно. Бывают таски, где надо опрасить несколько сервисов и тогда время её выполнения это время завершения самого долгого реквеста. Асинкио ещё больше увеличит это время за счёт оверхеда если на каждый реквест ещё какой-нибудь парсинг джисона делать надо. Хотя большинству бизнесов наверно всё равно в селари запихнуть эту таску или в ивентлуп. Что проще прямо сейчас реализовать то и сделают
Еще и goвноедов вспомнили, мм
>Не правда. Таска получит контроль только тогда когда другая кооперативная таска отпустит поток выполнения и ивентлуп решит вернуть контроль таске этой таске работающей с сокетом
Переключение задачи возможно только на операции await. Это скорее плюс, тебе почти не нужно думать о race condition, которые в тредах могут возникнуть по любому поводу.
Но, если данные на сокет не пришли, event loop просто не станет переключать управление на твою задачу, а выберет другую. Поэтому ты в одном процессе можешь позволить себе держать тысячи ожидающих данные задач. Оверхед околонулевой.
Асинкио в принципе удобнее, хотя есть проблема с тем, чтобы встроить его в другие фреймворки. Если ты работаешь внутри фреймворка, вроде GUI, которые все сами по себе фреймворки, или джанго, то их стыковать с асинкио может быть тяжело. Но если делаешь что-то с нуля, то проще с асинкио сразу.
>Переключение задачи возможно только на операции await. Это скорее плюс, тебе почти не нужно думать о race condition, которые в тредах могут возникнуть по любому поводу.
Да. Про это и говорю. И рэйсы в асинио возможны.
>Но, если данные на сокет не пришли, event loop просто не станет переключать управление на твою задачу, а выберет другую. Поэтому ты в одном процессе можешь позволить себе держать тысячи ожидающих данные задач. Оверхед околонулевой.
Нет. Ивентлуп ничего не знает про то что ты там выполняешь в таске. У него был вызов авэйта при открытии сокета он и переключился, отправив твою таску с сокетом в очередь с ожидающим стейтом. Когда очередь придёт он начнёт её выполнять. Снова наткнётся на код с чтением сокета, увидет, что чтение не закончилось и снова в очередь. Так пока не закончатся данные литеть (это если тсп сокет). Тут ивентлуп не может волжебным образом узнать что там внутри тасок и когда переключаться. Поэтому он почти рандомно прыгает между авейтами пока не найдёт код, который можно выполнять.
>Асинкио в принципе удобнее, хотя есть проблема с тем, чтобы встроить его в другие фреймворки. Если ты работаешь внутри фреймворка, вроде GUI, которые все сами по себе фреймворки, или джанго, то их стыковать с асинкио может быть тяжело. Но если делаешь что-то с нуля, то проще с асинкио сразу.
Да удобно. Да просто. Но только с инженерной точки зрения и в малых масштабах. Годно оно для пета, внутренней разработке или какого-нибудь легенького скрапера/коннектора/агрегатора/тулзы для автотеста, которые в продакшен не пойдут. А для продакшена: нет инструментов, есть оверхед на частое переключение контекста, на новых проектах работает меньше людей, чем на старых и когда создают новый проект, то не только фреймворк выбирают, но и язык. Поэтому как соискателю шансов нарваться на проект, где это нужно меньше, чем на проект с тредами. А как бизнесу есть тысяча поводов подумать нужно ли что-то делать с асинкио. Отсюда и низкая скорость принятия этой технологии. И никакие рассказы программистов про то, что это волшебство доступное из коробки не помогут
>Переключение задачи возможно только на операции await. Это скорее плюс, тебе почти не нужно думать о race condition, которые в тредах могут возникнуть по любому поводу.
Да. Про это и говорю. И рэйсы в асинио возможны.
>Но, если данные на сокет не пришли, event loop просто не станет переключать управление на твою задачу, а выберет другую. Поэтому ты в одном процессе можешь позволить себе держать тысячи ожидающих данные задач. Оверхед околонулевой.
Нет. Ивентлуп ничего не знает про то что ты там выполняешь в таске. У него был вызов авэйта при открытии сокета он и переключился, отправив твою таску с сокетом в очередь с ожидающим стейтом. Когда очередь придёт он начнёт её выполнять. Снова наткнётся на код с чтением сокета, увидет, что чтение не закончилось и снова в очередь. Так пока не закончатся данные литеть (это если тсп сокет). Тут ивентлуп не может волжебным образом узнать что там внутри тасок и когда переключаться. Поэтому он почти рандомно прыгает между авейтами пока не найдёт код, который можно выполнять.
>Асинкио в принципе удобнее, хотя есть проблема с тем, чтобы встроить его в другие фреймворки. Если ты работаешь внутри фреймворка, вроде GUI, которые все сами по себе фреймворки, или джанго, то их стыковать с асинкио может быть тяжело. Но если делаешь что-то с нуля, то проще с асинкио сразу.
Да удобно. Да просто. Но только с инженерной точки зрения и в малых масштабах. Годно оно для пета, внутренней разработке или какого-нибудь легенького скрапера/коннектора/агрегатора/тулзы для автотеста, которые в продакшен не пойдут. А для продакшена: нет инструментов, есть оверхед на частое переключение контекста, на новых проектах работает меньше людей, чем на старых и когда создают новый проект, то не только фреймворк выбирают, но и язык. Поэтому как соискателю шансов нарваться на проект, где это нужно меньше, чем на проект с тредами. А как бизнесу есть тысяча поводов подумать нужно ли что-то делать с асинкио. Отсюда и низкая скорость принятия этой технологии. И никакие рассказы программистов про то, что это волшебство доступное из коробки не помогут
Не набрасывай
drogon-core
Это же старьё
>Нет. Ивентлуп ничего не знает про то что ты там выполняешь в таске. У него был вызов авэйта при открытии сокета он и переключился, отправив твою таску с сокетом в очередь с ожидающим стейтом. Когда очередь придёт он начнёт её выполнять. Снова наткнётся на код с чтением сокета, увидет, что чтение не закончилось и снова в очередь.
Ты не понимаешь как работает асинкио.
Чтение из сокета использует системный вызов kqueue в линуксе, select в винде. Это системные вызовы уведомляют систему, что пришли данные на сокет. Пока данные не придут, задача будет в idle состоянии и переключения на неё не будет вообще.
За счёт этого и достигается огромный прирост производительности по сравнению с тредами.
> системный вызов kqueue в линуксе
тьфу, kqueue это BSD решение, в линуксе epoll. Но это примерно одно и то же. Смысл именно такой.
>>68933
Это один из тех методов, которые гивент патчит чтобы автоматические понимать когда должно переключение контекста делаться. В исходниках сипайтона этого нет. Там весь ивентул это гуляние по таскам, которые до этого вызывали елд фром. Не знаю в каких местах там всё в третьем питоне пропатчено. Возможно ивентлуп и не заходит в таски не получившие ничего на ввод, по это точно часть сетевой либы питона, и на сипайтона, а значит переключение контекста на новую таску для этой проверки всё таки происходит, он быстро видит, что нотифаев нет и переключается дальше. Да оптимизация, но проблемы частой смены контекста не решает
>Возможно ивентлуп и не заходит в таски не получившие ничего на ввод, по это точно часть сетевой либы питона, и на сипайтона, а значит переключение контекста на новую таску для этой проверки всё таки происходит, он быстро видит, что нотифаев нет и переключается дальше.
Это пофикшено в uvloop, буквально две строчки добавить
Нам на стажировке сказали Мэтта Харрисона читать. Хз, насколько она норм.
Что ты несёшь?
Работа с сокетом это по-определению только 3-й питон. Без каких-либо патчей использует select-принцип получения данных.
Это есть и в исходниках, и в доках сказано, наконец просто сделай в линуксе strace работающей программы и посмотри на используемые системные вызовы.
Сотню тысяч открытых соединений асинкио держит, я проверял из праздного любопытства. С низкой активностью, конечно. Можешь сам проверить, хотя тут напрячься придётся, чтобы саму систему заставить столько соединений поддерживать на процесс.
Естественно подразумевается, что ты используешь API от asyncio, то есть или через протоколы + loop.create_server/loop.create_connection делаешь, или через asyncio.start_server/asyncio.open_connection
но только так с асинкио и работают.
>Работа с сокетом это по-определению только 3-й питон. Без каких-либо патчей использует select-принцип получения данных.
Гивент на втором питоне тоже пытается неблокающий ио делать. И у него костыльно, но получается. Точно помню, что он патчит этот самый епол и свитчит контекст на этих операциях.
Не знаю как в третьем питоне это сделано. Могу только предпологать на основе того, что знаю. Думал, что так же как и во втором с гивентом, но теперь нативно. Но видимо как-то по-другому
>>69100
И как там теперь? Просто про бегающий по таскам ивент луп это точно. Прям во внутриностях сипайтона этот алгоритм захардкожен. Что делает ивент луп когда заходит в таску, которая пока не получила ничего в ио? Или он туда по какой-то причине не заходит раньше времени? Объяснишь?
Смотрю коммитов нет нихуя, хотя по доке вызываю коммит на connection.
Погуглил, вот у чела в каменте чисто такая же хуйня
https://stackoverflow.com/questions/20199569/pyodbc-insert-into-sql
> in my case, cnxn( AKA connection) cnxn.commit() did not work, but I user the exact cursor like cursor.commit()
Благодаря ему починил, но какого хуя? Не могу понять почему так.
>Что делает ивент луп когда заходит в таску, которая пока не получила ничего в ио? Или он туда по какой-то причине не заходит раньше времени? Объяснишь?
Он не заходит, таски полностью оборачиваются в epool вызовы
>Гивент на втором питоне тоже пытается неблокающий ио делать.
Я сам когда-то это релазизовывал через модуль select, когда мне во втором питоне надо было с несколькими сокетами одновременно работать, а треды не хотелось.
Но asyncio всё поддерживает из коробки. Там другого способа и нет, по идее.
У тебя планировщик не переключит на другую задачу, пока ты явно через await какой-нибудь future ему это не разрешишь.
При этом более быстрая работа с сетью это low-level протоколы. Где ты у тебя планировщик просто вызывает синхронный метод класса-протокола (asyncio.Protocol, data_received(self, data)), когда у тебя данные приходят. Всё это обёрнуто в epoll/select.
Есть список айдишников одной модели: sections_ids
Мне в Джанго нужно обновить поле в каждой Section, айдишник которой лежит в этом списке. Вроде как очевидно можно пройтись циклом вот так:
for section_id in sections_ids:
----section = Section.objects.get(id=section_id)
----section.status = "executing"
----section.save()
Но блин, по факту тут мы будем высирать уйму sql-запросов, по одному на каждую секцию, а ведь в просто SQL я бы просто скинул batch-update и разом обновил все. Как это нормально сделать в Джанге? (сука, такой стек на проекте, ничего не поделать)
код https://ideone.com/SzTV5s
1) Шаг – 50, конец интервала – 5, точность – 0.1
2) Шаг – 100, конец интервала – 5, точность – 0.05
Никто не сталкивался с этим? Уже неделю пытаюсь понять в чём дело. В логах ничего необычного не присходит. Просто не вызывается метод. Даже со включённым ask_late брокер помечает его как выполненный
Ну и да, ещё botocore пишет dripped connection, но и на успешные таски он это пишет.
Ещё я concurencyустановил в 1, но всё равно он делает таски в обход ограничения в 1 секунду. Причём выдача настроена на стороне очереди. Хрень происходит какая-то в общем
Почему не создается архив?
Через консоль винды нормально работает, а питон шлет нахер.
Дебаггер тут if os.system(rar_command) == 0:показывает что возвращается 1 вместо 0 и собственно пиздец.
Это пример из книжки A Byte of Python, только под rar.
попробуй установить винду 11. это известный баг, вот здесь есть подробности https://www.cvedetails.com/cve/CVE-2021-028359/
Unknown CVE ID
This site only contains valid CVE entries. Rejected or reserved CVE entries are not included in our database. Please visit http://cve.mitre.org and nvd.nist.gov if you think that the CVE entry is missing in our database.
Так это из-за несовместимости ОС. Нужно установить винду 11 чтобы открыть страницу.
Судя по описанию комманды os.system(rar_command) она должна написать в консоль текст ошибки, если была ошибка. Нужно прочитать этот текст и понять в чём именно проблема.
Попробуй на дебаге посмотреть значение переменной rar_command.
Скопировать дословно и ввести в консоль винды эту команду, чтобы проверить.
Попробуй на дебаге посмотреть значение переменной rar_command.
Скопировать дословно и ввести в консоль винды эту команду, чтобы проверить.
Привет программач.
Есть одна простенькая бд
И есть модуль, который сохраняет в базу данных строки по столбцам и извлекает их по запросу. Я это реализовал с помощью одних функций (создать базу если её нет, проверить наличие записи в бд, создать запись, обновить запись, удалить запись. Ключ - уникальный id).
И задался вопросом, может это сделать классом? Но так как я туповатый самоучка и с классами пока не работал (только теоретически и на детских примерах), не очень понятно с чего начать. inb4: идти в школу/нахуй/в университет/в гугл
>То есть выполняя простую операцию в треде тебе не нужно прерывать его каждый раз когда авэйт вызвается чтобы переключиться на другую таску
Чаво блять? Если await стоит то он не спроста нахуй, нужно переключить контекст и вытащить результат определенной Future, потому что функция иначе не сможет дальше работать. Если тебе нужно что-то выполнить в бекгрануде то делается сразу несколько "хаков":
asyncio.create_task
loop.call_soon
Future.add_done_callback
asyncio.gather (для одновременного исполнения множества запросов)
>Это будут два отдельным метода, типа сделать запрос и записать в базу
Скорее всего это будет проходить в одном методе, который однако будет дергать 2 других - какие-нибудь ModelService.make_request и ModelRepositary.save_model
>Особеность асинхронщины, что этот запрос обрабатывался бы те же 200мс, но при этом несколько раз в одну мс менял бы контекст
Чел... асинхронка вообще не так работает. Контекст меняется только в момент когда асинхронная таска исполнилась и ивент луп взял ее результат
>го
>для асинхронщины
Чел ты...
https://medium.com/nuances-of-programming/конкурентность-и-параллелизм-в-golang-go-процедуры-82bae0f92e81
Model.objects.bulk_update
Типа, если в данный момент идут 10 запросов, то выполняются 6, а остальные ждут пока освободится место.
Там говнокод обыкновенный. В некоторых тасках последовательные, в некоторых через futures по максимум 5 одновременных запросов за раз, если надо сделать больше. Асинк не использую, ибо джанго, да и не умею пока. Переписывать на фастапи уже поздно.
Проблема в том, что может получится так, что у меня будут активны много запросов на один и тот же домен. Ладно, если он просто возвращал ответ о превышени лимита, так он ещё в бан отправит нахуй, если я нарушаю частоту несколько раз.
Как это может быть сделано. Проверить количество текущих активных запросов на конкретный домен, и если он выше определённого числа, то ждать, скажем, 100мс перед следующей проверкой.
Просто я не знаю как это сделать
Если тебе лень разбираться, могу предложить в качестве костыля развернуть рядом с твоей аппкой прокси, которое будет обрубать тебе количество запросов.
Это надо делать на домен. Не на все запросы. И таск должен просто подождать, а не кидать ошибку
Так для стандартной аутентификации нужен пароль же, а уменя его по факту нет. Это получается мне свой бек для аутентификации писать?
Я ньюфаг в этом деле, буквально вот-вот начал интересоваться.
Python 3.9 на команду pip instal sha256 очень ругается, не могу понять почему.
В гугле ответ на проблему не смог найти.
Буду рад, если кто пояснит почему такое происходит и как фиксить.
В общем, ratelimits позволяет такое провернуть. Осталось понять, как это привязать к домену, а не только к функции
Штуковина ratelimits подошла хорошо. Тред можно закрывать
Я просто научную работу пишу на эту тему в Берлинском технологическом университете. Никак не могу разобраться.
Контекст переключается на каждом авейте. Авейт это такой гоуту на глобальную функцию ивентлупа, которая сама решит какую тасочку потом продолжить. А внутри асинхроной либы может быть дохуя вложеных асинк функций с авейтами. и статью твою читать не буду. она на русском. я не говноет таким обмазываться
то что авейт не спроста не значит что он не несёт оверхед. внутри одной вункции стоит несколько авейтов. потом эту функцию с авейтом вызывают. и так несколько раз внутри всей асинхроной библиотеки. в итоге дохуя цпу времени тратится просто на переключение между контекстом вместо того чтобы тратить его на цпу баунд таски. в итоге с асинхронмы кодом ты не можешь на 100 процентов заюзать цпу полезными тасками. ты заюзаешь его на 90 процентов полезными и на 100 переключением контекста. а в тредах это можно сделать и там скорость выполнения простых тасок выше.
Нет же. процесы вместо тредов обычно нужны из-за гила. а асинхроность ускоряет ио баунд таски. типа если тебе надо 100 раз по урлам обратиться открыть проще это в одном треде асинхроном сделать, чем для каждого урла создавать тред и тратить ресурсы ядра на эти операции
У тебя явно написано тредпул
Переключение тредов тоже требует ресурсов, скорее больше, чем переключение задач в asyncio. Особенно если ты ещё какие-нибудь uvloop добавишь.
Альтернатива асинкио это несколько работающих ПРОЦЕССОВ, и внешний балансировщик, который раздаёт задания процессам. В принципе в большинстве случаев ты запускаешь много процессов, которые обслуживают всю нагрузку. Вместо того, чтобы держать event loop, ты можешь держать достаточно много процессов, с запасом, каждый процесс просто последовательно запросы обслуживает.
Синхронные фреймворки только так и запускают, тебе про треды ничего знать и не надо в этом случае.
>Переключение тредов тоже требует ресурсов, скорее больше, чем переключение задач в asyncio
Конечно. Но это происходит гораздо реже. То есть если у тебя асинхроная либа и ты парсишь джейсон ответ от сервера, то и персить ты будешь асинхроно т.к. иначе одна таска займёт весь поток и другие не получат время. это смысл кооперативных тасок. поэтому твой парсер джйсона будет работать дольше, чем просто в треде его синхроно запускать. это не учитывая то время когда таска не выполняется потому что исполняется другая. то есть в треде не учитываем время когда другой тред держит гил, а в асинкио не учитываем когда ивентлуп переключился на другую таску. и тогда время потраченное на вычесления в тредах меньше, чем в асинкио
И процессы это не альтернатива. Это абсолютно другой вариант распаралеливания. Он не заменит асинкие
Проблема точно в beat. Обнови его конвиг и рестартни. Ещё можешь ивенты включить и посмотреть кто куда что отправляет
Жалка.
Самое интересное, что с остальных очередей таски суются в default queue, несмотря на явное указание.
Всё решилось указанием очереди в app.task(queue=...) Остальное просто игнорировалось
Выбираю стек технологий в новый проект. Подскажите ORM, который бы при UPDATE записи базы данных, если заблокированна, сам дожидался ее разблокирования и выполнял апдейт (прозрачно для программиста).
>в итоге дохуя цпу времени тратится просто на переключение между контекстом
1 мкс?
Шизофреник, ты че несешь? Ты попробуй произвольную синхронную прогу переписать на асинк так чтобы он был исключительно оверхедом, т.к. без IO-операций - по приколу вызывай каждую функцию через await и посмотри на оверхед, он блять не превысит 3%
>Первую работу
>Выбираю стек
Пизда проекту. Не такого орм, который бы дедлок аккуратно доидался. У тебя к хуям сервис умрет
>она на русском я не говноет таким обмазываться
Прозападный пердикс косит под зумерка, спешите видеть
Вот есть у меня джанго-приложуха, я в ней меняю схемы БД на удаленном тест-серваке через миграции, затем через какое-то время на этот сервер я заливаю другой код, из более ранее ветки, и там же сцуко схемы БД будут другие из-за чего могут вылезать занятные ошибки на NOT-NULL CONSTRAINT и прочее. Как с таким справляться?
На серве? А локально че делать если я работаю на ветке провел N миграций а потом возвращаюсь к более старой ветке и миграции там не залиты. Как разрабатывать-то?
Проиграл. У тебя есть мастер ветка. В которой хранятся финальные или околофинальные изменения. Делаешь дроп таблицы? Ок. Старая ветка юзает поле, которое дропнуто? Не юзай его, переделывай таску. Если просто конфликт миграций - вливаешь масте в свою ветку, обновляешь миграцию и делаешь её последней.
Тут ситуация такая: никакие миграции не конфликтуют, однако при попытке добавить запись в таблицу вылезает NOT NULL CONSTRAINT VIOLATION потому что в новых миграциях была добавлена новая колонка, которая обазательна (а default у нее не проставлен). Очевидно что в старом коде добавление происходит без учета этой колонки. Как его тестить-то блэт?
>1 мкс?
Тут есть нюанс, если у тебя есть операции (например, парсинг/генерация жсона, которой необходимо 20 мс) для выполнения в 2 из 10 тредов, а в остальных ожидание базы/апи/етц, то их скорость снизится в 5 раз, так как каждому треду выделяется равное количество процессорного времени и в рамках 100 мс на треды с полезной нагрузкой будет выделено только 2 * 10 мс. В то время, кооперативная многозадачность позволит решить эту проблему, так как в этом случае трата гпу на неактивные таски не производится.
Пока что ни разу не изучал пайтон, впервые буду трогать его. Начну с мурзилки, всё как полагается - метанит.
Я верю в себя, пацантре! Я стану лучшим на этой стажировке!
мимо 1С-Битрикс middle
Так это чтобы попасть на стажировку, офк с вебинара почти ноль полезной инфы, плюс у них плеер плохой, когда перетаскиваешь ползунок, то не показывает какая минута видео. А на ютуб отказываются заливать, лол.
Я же сказал
>мурзилка - метанит
Потом мб книги с шапки почитаю.
Привет, Питонисты. Реквестирую объяснения на человеческом работы Channels для Джанги 3, почему какие-то вечные sync to Async , че вообще, можно как-то привычные вещи с эвент лупом написать? Как вообще мне asyncio использовать в этой либе? Мне кажется, я не понимаю ее идею именно, для каких целей она создана
Типа почему я не могу перенаправлять роутом запросы TCP/UDP на то место, где я скажем поднял на другом порте что-нибудь асинхронное в своей как бы среде, с asyncio, aiohttp и шлюхами
Тут и постепенное внедрение микросервисов, тут и гибкость, тут и как бы меньше кода, удобнее, почему нет?
Разве что на фронте могут быть проблемы какие-то, но думаю это решаемо
В ту сторону вообще воюю, господа ?
Ну добавь какое-то значение в старый код, если оно обязательно и нет дефолта. Очевидно же.
В мейне создаются сервисы асинхронные, в зависимости от параметров переданных и запускается
from aiomisc import entrypoint
with entrypoint([list, of, entrypionts] as loop:
____loop.run_forever()
Так же в мейне я хочу инициализировать пул коннектов для бд. Пул создать еще до создания сервисов, бд должна отдать данные для сервисов и из пула брать коннект до остановки сервисов. Я написал получение коннектов, но нужен работающий цикл событий. Как это сделать? Еще один евент луп создавать что ли? Но так, вроде, делать неправильно
Я запутался если честно, попробуй добавить инициализации конекторов при создании лупа или же просто как отдельную короутину запускай сначала, может быть gather-ом , я бы 2 луп не создавал, тебе охота с 2 ебаться ?
Видел ссылки на всякие python-sdk но суть нигде так и не пояснена: КАК работает платежкп? Куда там и как реквесты передаются?
У нас сервис авторизации тоже на торнадо написан.
У них изначально вообще был фласк, потом они патчили его через гевент.
Добавьте в шапку.
>Python developer trainee
>Практический опыт с Python от полугода
Шутки кончились!
Короче вот пример
from aiomisc improt entrypoint
...
if __name__ == '__main__':
__# Вот тут как сделать асинхронный вызов функции в том же цикле событий, что и внизу луп?
____service = Service()
____with entrypoint(service) as loop:
________looз.run_forever()
Ну дак это немецкая компания, плюс 40к платят, так что справедливо. Тем более это необязательно коммерческий опыт, можно и пет-проекты.
Побробуй asyncio.Run in executor
Тебе зачем вызывать инициализацию базы в эвент лупе ? Почему не сделать так
1. Запуск инициализации пул коннектов
2. Далее в эвент лупе создаешь сервисы или че там
че там aiomisc я не знаю в душе, я угарел по стандартной либе
>Тебе зачем вызывать инициализацию базы в эвент лупе ?
Конфиги там для сервисов лежат, таймеры, предельные значения, таймауты и т.д.
Ну вызови тоже самое в эвент лупе через asyncio , по сути у тебя что вызывается то ? Асинхронные функции , короутины, вот, он их и вызовет в отдельном как бы исполнителе, это не то чтоб отдельный эвент луп, если представить завод, то executor это что-то типа подрядчик с соседнего цеха , собственно , более того, у тебя 1 эвент луп будет, если ты решишь получить экземпляр лупа, то он будет как у тебя изначально в твоем коде после комментария, то бишь даже так, твои инциаилизации не будут крутится в этом лупе, но будут выполнены до начала лупа, что тебе и нужно, нет?
Бля, я в начале хотел сказать в executor , более того можешь даже в thread pool executor
>Ну вызови тоже самое в эвент лупе через asyncio
я об этой строке
У Гоши Дударя спроси, или кто там еще есть из таких, во, Аудио Хо или АудиХо, ну как-то так, что-то с Хо
Ты сначала свое что-то напиши или на опенсорсе что-то зделай, какой-нить плагин допили/обнови, который авторы забросили. Вот это будет считаться. А твоё видео это кал.
Это очень большая ошибка посылать новичка сразу в попенсорс. Туда как раз таки пишут люди с большим опытом и пониманием того что и зачем они делают. Даже просто так обновить либы нельзя, потому что это требует проверки на совместимость.
Ну ладно тогда просто зделай пет-проект, вкатись за еду в рандом-город, где мало конкуренции и учись у старших коллег писать код, а потом в опенсорс. Хотя уже не понадобится.
Аноны, что представляют собой переменные с точки зрения интерпретатора? Где они хранятся?
У Лутца (Изучаем Python, т.1, 209 стр.):
>Переменные — это записи в системной таблице, в которых предусмотрены места для связей с объектами.
Это мне ни о чем не говорит - пытался нагуглить, что за системные таблицы, ничего конкретного нет.
Ответ, что переменная - это указатель на значение в памяти, не подходит. Я понимаю, что она делает - вопрос в том, что она собой представляет.
Почему он сначала вычисляет вложенный цикл?
graph_cycles = [[node]+path for node in graph for path in dfs(graph, node, node)]
Компрехеншен разворачивается слева направо.
❤️
менеджер пакетов
Вот вы тут значит дрочите на скорость асинхроннщины. Как быть с этим, когда последующий запрос напрямую зависит от предыдущего?
Если у тебя один запрос в секунду и каждый из них выполняется раньше, чем поступает следующий то никаких преимуществ.
А вот теперь представь, что у тебя два (три, четыре, сто, etc) запроса одновременно. Во время ожидания первого запроса уже можно начинать второй, так как контекст в это время свободен.
Я так и делаю. Выделяю относительно независимые участки кода и сую их в executor. Но таких мест очень мало. Просто обидно что один запрос оьрабатывается так долго, примерно секунды две.
Приходится делать очередь с одним воркером, скорость пиздец, но по другому нельзя, иначе у меня появятся два одновременных запроса которые создадут две записи, чего быть недолжно.
Уже мысль появилась, может копить это говно по 10 штук и одновременно их обрабатывать. Апи позволяет делать пакетные запросы, но это в итоге в такой говнокод превратится, это пиздец
>примерно секунды две
У тебя там процессинг какой-то или простое ожидание?
>Приходится делать очередь с одним воркером, скорость пиздец, но по другому нельзя, иначе у меня появятся два одновременных запроса которые создадут две записи, чего быть недолжно.
То есть тебе нельзя делать одновременные запросы, но при этом ты решил делать все через асинхронность? А ты знаешь зачем она вообще нужна? Тебе даже с мультитредами/процессами пришлось бы ждать.
Однако, ты говорил про то, что ты проверяешь какую-то запись. Если это происходит по айди приходящему извне, то ты можешь сделать лочку через set().
Не, я не это имел ввиду. К примеру, мне приходит запрос, содержащий номер телефона и сообщение. Я делаю запрос, чтоб проверить наличие контакта и получить его id, если контакта нет, делаю следующий запрос на создание контакта, откуда получаю id, потом использую его на создание чата и получения id чата (храню в базе), потом проверки наличия связи этого чата с другой сущностью и создание если его нет и только потом отправка сообщения по id чата.
Вся эта процедура это один запрос на мой сервер. К примеру, мне могут прийти одновременно два таких запроса на разные параллельные инстансы сервера. Он вполне может создать два одинаковых контакта, если его нет. Как решаются такие проблемы? Очередь с одним работником? Я так и делаю сейчас, но это пиздец как медленно
Первый вариант
Делаешь внешнее хранилище, например redis, проверяешь отсутствие номера там, куда кидаешь его внутрь и после окончания удаляешь оттуда, соответственно, если номер там, то отбрасываешь реквест, желательно, что бы клиент был синхронный, что бы во время ожидания не сделать доп запрос.
Второй вариант
Делаешь дополнительно сервис-балансировщик, который принимает все запросы и каждому инстансу присваиваешь номер. Подбираешь ключ партицирования (в твоем случае это номер телефона) и функцию партицирования так, что бы запросы распределялись равномерно по сервисам. (можно просто mod). Каждый запрос кидаешь по нужному инстансу согласно результату функции. В самом сервисе уже можешь сделать внутреннее хранилище, например set/dict, которое проверяет обрабатывается ли этот ключ в данном сервисе в данный момент и откидывает его (или кладет в какую-нибудь очередь, что бы потом запроцессить, после окончания предыдущего запроса).
Первый вариант гораздо легче реализуется, второй идеалогически правильнее.
Я еще чуть подумал, в случае редиса можешь и асинхронный клиент юзать. Сам редис однопоточный и даже если ты сделаешь два запроса одновременно один гарантированно отвалится.
Выглядит неплохо, вероятность появления дублированных запросов снижается, но всё же остаётся.
Можно попробовать в мемкеш сувать какой-нибудь идентификатор запроса и удалять его при завершении. Если он присутствует - приостанавливать запрос, либо отправлять его содержимое в мемкеш, где предыдущий запрос в конце будет проверять наличие другой. Но в первом случае забьются инстансы, а во втором память.
>но всё же остаётся
Откуда она у тебя остается? Хранилище последовательно обрабатывает запросы на удаление/вставку.
fastapi
Антуаны, возможно вопрос не по теме, но не знаю где еще спросить.
Почему -4//3 дает -2?
Почему не -1?
Спасибо.
В сети нашел такое объяснение.
>Разделить целое число a на целое число b!=0 с остатком — это значит
>найти такие два целых q и r, которые удовлетворяют следующим условиям:
>1) a = b q + r;
>2) 0 <= r < |b|.
Но все равно не сходится. Предположим, что -4//3 будет -2
(-2)3+1 получается -5, а не -4
Если вкратце, // округляет вниз, ближайшее целое, меньшее -1.(3) - это -2
Если ты про аннотацию типов и тип возвращаемого значения -- я использую, мне очень нравится. У меня тоже вопрос: как пользоваться директивой todo? Есть гайды на эту тему, примеры? Я бы хотел отмечать в коде планы на будущее
Что тебе конкретно непонятно в использовании todo?
Просто без задней мысли пишешь
# todo: допилить хуйнянейм
И всё, дальше тебе IDE напомнит, если что.
Типа, туду не надо использовать в виде "планов на будущее", как ты сказал, для этого должен быть адекватный бэклог. Это просто записка о том, что код можно в этом месте улучшить/отрефакторить, но сейчас это делать некогда.
А какие у тебя вопросы по скорости к сейчас? Покажи пару тестов, замаж офк что не нужно видеть или вырежь, джанга так -то по скорости удовлетворяет большинству задач малого бизнеса
def debug(text):
print("i debug filter")
return ''
environment.filters['debug'] = debug
то работает на ура. Но если пытаюсь применить этот фильтр где то на html page , то жалуется что такого фильтра нет и падает приложение.
Как правильно добавлять фильтр правильно, че то не могу нагуглить как оно глобально работает
Я пытаюсь написать редактер с tkinter
В общем там несколько окон
Основное с холостом
И окно с инструментами делаю toplevel
Есть в итоге два файла main.py и tools.py с этим окошком.
Пытаюсь написать функцию которая ресует на canvas из main при нажатии на кнопку в побочном окне. Всё это в tools.
Только вопрос как мне получить доступ к canva из main в tools
Я хотел при создании в main передавать типа
c=Canvas()
from tools import *
tool = tools(c)
Но ошибку выдаёт что делать?
Серее уже нашел
Написал функцию, вложил в цикл. На первой итерации работает нормально, после - не обновляет количество очков. В чем может быть проблема?
https://pastebin.com/NeyyThfB
Что-то в голосину с наименования переменных. Ты в курсе, что лучше сразу приучать себя к нормальному неймингу?
ochko = input('ochko')
Тогда и на реальных проектах тебе будет скучно, завязывай, другалек.
Глобальная переменная - это тебе намек на то, что надо почитать про области видимости переменных.
virtualenv
pyenv, venv, docker
Так она и не влияет, ты пробуешь менять глобальную переменную в функции, но она недоступна, потому что перекрыта локальной. Да и это бы не получилось, потому что надо было бы пробрасывать ее в скоуп через global. В любом случае, это хуевый подход. Лучше чтобы функция возвращала на хуевертила с глобальными переменным, а возвращала результат, который уже можно использовать вменяемо.
@task_failure.connect
def my_handler(args, *kwargs):
----pass
Проблема в том что он глобально нах не нужен, его стоит вешать только на определенные типы ошибок. Как это поменять?
Cryptodome.Hash -> SHA1
Cryptodome.Signature -> pss
Перепробовал множество разных вариантов с модулем crypto (да и со сторонними) - не получается.. Есть сервер, на который эта подпись отправляется, так и узнаю о корректности данных. Через питон запрос успешно проходит, а на ноде ошибка.
Я сделал нотификацию, когда данные изменились и время взять свежие, но как их закешировать?
Анус себе закешируй
Бля, ну читни какую-то начальную книгу по фласку или джанго, или что ты там хочешь, или посмотри видяшку на ютубе от зумера зумеркова.
Это самое начало начал.
Кроме шуток, заебала эта биполярка, никак не начну даже пытаться найти работу. С утра проснусь думаю збс, много чего уже знаю, проходит три часа и уже ужасаешься, что невозможно найти РАБоту, просматривая списки требованийпоплакал
Какие подводные моего плана?
При определенном условии она должна пинговать классам разным, что состояние изменилось и надо получить новые данные.
Как это сделать? Думал через коллбек сделать, но тогда придется список классов вносить, какие методы дергать.
Через сигналы вроде можно, но тогда надо метод определить, который бы присваивался классу, да и хз как его сделать. статическим нельзя, ведь переменные класса надо менять, а класс метод - опять же надо список классов иметь.
Какую-то корутину определять не знаю как, да и выглядит так себе. Слушатель должен быть один, а если она будет, то каждый будет дергать бд и куча лишних коннектов к бд будет
На игре не планирую.
В будущем планирую, но тема с питоном это просто как разминка для мозга.
Потом планирую вкатываться в c# уже по серьёзному.
class A:
____def __init__(self, some_obj)
________self.method_a = some_obj.method_a
Могу ли я как-то сделать, чтоб при вызова some_obj.method_a()
в классе A помимо method_a выполнялись другие действия?
Что за наркомания. Почему не передать в some_obj объект класса А и уже из obj.method_a вызывать действия с классом А
Немного не то, что я имел ввиду. Мне бы что-нибудь про подробный разбор asyncio. Там ебнешься сколько методов запуска, с новыми потоками, с тасками. Вот тут я обосрался, когда пытался в существующем цикле событий вставить вызов маленькой функции
Вброс конечно, но по работе основной бек был изначально на джанге, все новое пилю на фастапи. Перегруженные тонной ебанины конвееры типа джанги и ему подобных аналогов на других языках считаю устаревшим подходом. Всегда можно ебануть элегантную и более эффективную сборку на микрофреймах и чувствовать себя хозяином в своем коде.
У Flask хорошая документация, кроме нее ничего не нужно. Я делал минимальное приложение, как здесь сказано
https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application
а потом по мере добавления функциональности изучал соотв. разделы.
Токсичная у вас атмосфера.
>При определенном условии она должна пинговать классам разным, что состояние изменилось и надо получить новые данные.
Pub-Sub
Нахуй пошел.
Как мне, допустим, написать калькулятор? Отдельным окошком, с кнопочками. Ну, на сишарпе я наверно сделать смогу, там конструктор винформс, как делфи. На андройде также.
Но как написать графическое приложение на питоне, или там базу данных например? Где все книжки на эту тему? Каюсь, ничего не искал особо, но все книги или гайды, которые я видел, это либо "для начинающих", либо что-то для уже программистов, что выше моего уровня.
Покажите путь ньюфагу, аноны
pyside(qt), kivy и т.д. посмотри это на счёт форм
Разве не так?
Оказалось в vscode нужно было выбрать интерпретатор
>Планирую планирую
>
>Нахуй нам это знать, другалек ? Планами знаешь кого насмешишь? Делай лучше. 0 токсичности
Вообще, довольно токсично. Я уже начал изучать питон.
Чем старше инструмент, тем больше в сети по нему статей. Если видишь много статей для какого-то инструмента, есть повод задуматься что он устарел. Чаще смотри на даты статей. Юзай fastapi и pydantic
мимокрокодил 250кк в секунду
https://docs.python.org/3/library/asyncio-stream.html
Задача:
Несколько клиентов1 подключается на 1001 порт, несколько клиентов2 на 2002 порт одного сервера. Требуется обработать и передать клиентам2 всё что отправит на сервер каждый из клиентов1.
Не пойму как православно реализовать такое. Держать глобально массив Writer'ов? Для каждого клиента2 создавать очередь? Или вообще использовать другую либу?
Молоток
Тебе крона достаточно будет
А тот факт, что всем по сути отправляется одно и то же никак не упрощает задачу? Может что-то на протоколах наколдовать можно?
Трудно себе представляю как сервер1 будет знать сколько клиентов у сервера2. Получается, нужна главная очередь и очереди на каждое соединение? Не много ли очередей для такой простой задачи? Без них не обойтись?
https://2ch.hk/b/res/262122227.html (М)
А у тебя клиенты как подключаются то? По какому протоколу? Тебе в любом случае нужно иметь пул соединений
asyncio.start_server() разве сам его не создаёт?
Может есть ссылка что почитать где нормальным русским языком объясняется про все эти потокобезопасности, сокеты, вебсокеты, пулы, протоколы, стримы и т.д. А то сами исходники понятней чем английские маны по ним. Везде 100500 способов сделать сервер на asyncio, но к какому способу в каком случае и зачем прибегают нигде не сказано. Везде "можно ещё вот так и вот так изъебнуться, смотри как здорово!"
Цикл:
https://ideone.com/8oczQe
Замер с помощью timeit, результат - 3.97 секунд
python3 -m timeit "from main import countdown; countdown(100)"
100000 loops, best of 5: 3.97 usec per loop
Если замерять цикл с помощью time.perf_counter(), результат - 9.8 секунд.
https://ideone.com/cS4HjQ
9.873999999999994e-06
1. Почему результаты разные? И как правильно в этом случае?
2. Почему он считает 3.97 / 9.8 секунд, если выполняется буквально секунду-две? Прикидывает среднее время выполнения одной итерации и экстраполирует на остальные итерации цикла? Использование perf_counter дает те же самые результаты, если это важно.
Это микросекунды, а не секунды.
А разница из-за способов подсчета, очевидно. Надо разбираться.
Порараз бирацца.
После возврата не принимает ничего
async def update_text(message: types.Message, action: str):
with suppress(MessageNotModified):
await Form.back.set()
directs = {"rk":"направление1","inv":"направление2","tpr":"направление3","tinv":"направление4"}
await message.edit_text("Выбранное направление: "+directs[action]+"\nВведите тему:", reply_markup=get_back())
@dp.callback_query_handler(callback_direct.filter(action="back"), state=Form.back)
async def callback_back(call: types.CallbackQuery):
await cmd_switch(call.message)
await call.answer()
@dp.message_handler(commands="w")
async def cmd_switch(message: types.Message):
#user_data["username"] = 0
await Form.name.set()
await message.answer("Куда хочешь направить:", reply_markup=get_keyboard())
@dp.callback_query_handler(callback_direct.filter(action=["rk", "inv", "tpr", "tinv"]), state=Form.name)
async def callback_directs(call: types.CallbackQuery, callback_data: dict, state: FSMContext):
action = callback_data["action"]
if action == "rk":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
# await topic_text(call.message)
elif action == "inv":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
elif action == "tpr":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
elif action == "tinv":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
await call.answer()
@dp.message_handler(state=Form.topic)
async def topic_text(message: types.Message, state: FSMContext):
with suppress(MessageNotModified):
async with state.proxy() as user_data:
user_data["Topic"]=message.text
await message.answer("Опишите проблему:")
await Form.next()
После возврата не принимает ничего
async def update_text(message: types.Message, action: str):
with suppress(MessageNotModified):
await Form.back.set()
directs = {"rk":"направление1","inv":"направление2","tpr":"направление3","tinv":"направление4"}
await message.edit_text("Выбранное направление: "+directs[action]+"\nВведите тему:", reply_markup=get_back())
@dp.callback_query_handler(callback_direct.filter(action="back"), state=Form.back)
async def callback_back(call: types.CallbackQuery):
await cmd_switch(call.message)
await call.answer()
@dp.message_handler(commands="w")
async def cmd_switch(message: types.Message):
#user_data["username"] = 0
await Form.name.set()
await message.answer("Куда хочешь направить:", reply_markup=get_keyboard())
@dp.callback_query_handler(callback_direct.filter(action=["rk", "inv", "tpr", "tinv"]), state=Form.name)
async def callback_directs(call: types.CallbackQuery, callback_data: dict, state: FSMContext):
action = callback_data["action"]
if action == "rk":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
# await topic_text(call.message)
elif action == "inv":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
elif action == "tpr":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
elif action == "tinv":
async with state.proxy() as user_data:
user_data["username"] = call.from_user.first_name
user_data["Direction"] = action
await Form.next()
await update_text(call.message, action)
await call.answer()
@dp.message_handler(state=Form.topic)
async def topic_text(message: types.Message, state: FSMContext):
with suppress(MessageNotModified):
async with state.proxy() as user_data:
user_data["Topic"]=message.text
await message.answer("Опишите проблему:")
await Form.next()
И тут они применяют вот это на пикче. Объясните что это за скрипт, потому как я не понял что это такое и откуда он взялся
Я забыл написать, откуда они взяли блядский hello
то есть тебя рпиняли, хотя ты в этом не шаришь? охуеть
Давай, старайся! Ты должен превозмочь! а что по бабкам?
ты шкет?
то есть все папки, кроме подходящих под условие, не должны попасть в конечных список?
3 день думаю, нихуя не придумаю.
перебирал с помощью glob, listdir - не понимаю, как заставить скрипт игнорировать папки, в которых их нет файлов интересующего меня расширения.
чел, ты мой герой. я бы еще долго думал до os.walk'а считая его слабее glob и listidir). ну а в цирке походу выступаю я.
class A:
__def __init__(self):
#это конечная операция, не долгая
____self.data = asyncio.get_event_loop().run_until_complete(self.get_data())
____# Тут как сделать вызов асинхронного listen который вечный цикл юзает, чтоб не блокировало программу?
__async def listen(conn):
____async with conn.cursor() as cur:
______await cur.execute("LISTEN channel")
______while True:
________try:
__________msg = await conn.notifies.get()
________except psycopg2.Error as ex:
__________print("ERROR: ", ex)
__________return
________if msg.payload == "finish":
__________return
________else:
__________print("Receive <-", msg.payload)
Я просто хз уже. Вызов слушания блокирует всё, он должен работать всегда.
Разобрался
Есть такой код https://ideone.com/W9RNzB
Там базовый класс ещё до меня был. Он много где используется. Новый класс с дополнительными фичами я сейчас делаю. Он должен делать то же самое, что и базовый, но если создали со специальным флагом, то он запускает дополнительные фичи. И эти фичи тоже конфигурируются ещё одним флагом. И внутри он использует методы этого базового класса. И всё вроде хорошо когда я подменяю в коде базовый класс на новый.
Но проблема в том, что базовый класс много где используется. И если я отправлю пулреквест на замену всех использований базового класса на свой, то этот пулреквест не пройдёт ревью т.к. мои фичи не везде нужны, но при этом должна быть возможность их везде запускать. То есть идеально было бы это сделать новый класс и от него унаследовать базовый. Но тогда я не смогу использовать методы базового класса внутри нового. Как тогда такого добиться?
Делай так, наследуешься от класса, делаешь фичи без флага. Там, где они нужны, создаешь объект от твоего класса, где нет - от базового.
В идеале даже так, Базовый класс с абстрактными методами, Делаешь два класса, которые от него наследуются. Старый класс и твой. Создаешь объект нужного класса на этапе определения есть ли флаг
>Там, где они нужны, создаешь объект от твоего класса, где нет - от базового.
Слишком много мест, где придётся заменять базовый класс на мой. Мне так не разрешат. Это должно работать во всех местах где есть базовый класс, но подэфолту выключено. Если я в каждом месте базовый клас заменю на новый и оставлю этот функционал выключены, но на меня как на дурочка будут смотреть если делать так
>Базовый класс с абстрактными методами
Эти методы отлично вписываются в базовый класс. Они не должны там быть абстрактными. Мне нужно просто их расширить.
Думал вариант над mixin. Вот так получилось https://ideone.com/3v1qm9
Но мне нужен порядок вызовов. Сейчас там порядок вызова старта A -> B. Базовый класс тоже унаследован от другого, который унаследован от ещё одного, но супер внутри старт и стопа не вызывает. Поэтому мне надо. Если вставляю mixin, то получаю A -> mixin -> B. А мне нужно A -> B -> mixin чтобы мои фичи самые последние запускались. Такое можно сделать?
Это надо склонировать одного вкатуна пару тысяч раз и проивзести статистические подсчеты.
Готов послужить подопытным для вкатологии?
Я так чисто интересуюсь, сам даже не планирую. Неужели нет хотя бы примерной инфы от состоявшихся джунов?
Я сначала написал ответ, как реализовать нормально надо. Но вижу, что ты уперся в свой флаг и мне не охото стало рассказывать
Т.е он получил набор последовательных тасков и выполняет их последовательно с большим интервалом, когда как solo и prefork делают это гораздо быстрее.
Однако у gevent производительность в параллельных тасках гораздо быстрее, для чего он мне и нужен, но если есть только одна последовательность он просто ждет по 10с блядь
Нихрена не понятно.
У меня сразу вопрос возникает, ты же не только с классом работаешь, ты скорее с объектами класса работает, а у них будет конкретный тип, вот как здесь ты всё себе представляешь не понятно.
Вот эти флаги смотрятся грязно в любом случае. Тем более, когда у тебя глобальный флаг.
Есть ещё варианты, тоже грязнованые правда, это просто переписать класс в рантайме. То есть ты можешь сделать так, чтобы просто твой Base класс реально указывал на его наследника. Это обезьяньи техники (monkey), такое при тестировании используют, для рабочего кода мне кажется это не очень.
Дополню себя >>80600
Тебе надо как-то прояснить, зачем ты это делаешь.
Есть базовые принципы SOLID, они в том, например, что функционал уже существующего кода не должен меняться при доработке классов-наследников. Если люди используют базовый класс, значит им нужен базовый класс. А ты даёшь какой-то дополнительный функционал, и, соответственно, твой класс будут использовать те, кому он нужен. Обычное ООП для этих целей работает очень хорошо.
Что за флаги не понятно. Если они тебе нужны для отладки, тестирования и каких-то подобных задач, то это другая история. Довольно обычная техника, которая применяется при этом, это создание обёрток вокруг функций, это переписывание в рантайме классов или отдельных методов.
Пример, есть библиотека, где определён класс:
===
class Base:
____def __init__(self, value='default value'):
________print("original base class __init__")
________self.value = value
____def prn(self):
________print(f"Base print, value {self.value}")
def foo():
____b = Base()
____b.prn()
===
Вот допустим, ты хочешь подменить класс, не влезая в код библиотеки, ты просто делаешь
===
import lib
class Magic(lib.Base):
____def prn(self):
________print(f"Magic-print, value: {self.value}")
lib.foo()
lib.Base = Magic
lib.foo()
===
запускаешь
>python3 magic.py
>original base class __init__
>Base print, value default value
>original base class __init__
>Magic-print, value: default value
это monkey-patching
Но для продакшен-целей так делать не надо.
Для продакшен целей делают разные декораторы, либо иные обёртки. Надо смотреть, что у тебя за задача.
Дополню себя >>80600
Тебе надо как-то прояснить, зачем ты это делаешь.
Есть базовые принципы SOLID, они в том, например, что функционал уже существующего кода не должен меняться при доработке классов-наследников. Если люди используют базовый класс, значит им нужен базовый класс. А ты даёшь какой-то дополнительный функционал, и, соответственно, твой класс будут использовать те, кому он нужен. Обычное ООП для этих целей работает очень хорошо.
Что за флаги не понятно. Если они тебе нужны для отладки, тестирования и каких-то подобных задач, то это другая история. Довольно обычная техника, которая применяется при этом, это создание обёрток вокруг функций, это переписывание в рантайме классов или отдельных методов.
Пример, есть библиотека, где определён класс:
===
class Base:
____def __init__(self, value='default value'):
________print("original base class __init__")
________self.value = value
____def prn(self):
________print(f"Base print, value {self.value}")
def foo():
____b = Base()
____b.prn()
===
Вот допустим, ты хочешь подменить класс, не влезая в код библиотеки, ты просто делаешь
===
import lib
class Magic(lib.Base):
____def prn(self):
________print(f"Magic-print, value: {self.value}")
lib.foo()
lib.Base = Magic
lib.foo()
===
запускаешь
>python3 magic.py
>original base class __init__
>Base print, value default value
>original base class __init__
>Magic-print, value: default value
это monkey-patching
Но для продакшен-целей так делать не надо.
Для продакшен целей делают разные декораторы, либо иные обёртки. Надо смотреть, что у тебя за задача.
Например, зачем мне знать про области видимости, про global и nonlocal, если функции я начну писать очень не скоро.
В общем, вопрос: это нормально или лучше читать Лутца, параллельно кодя что-то осмысленноеХочу в pygame что-нибудь сделать, как раз функции буду писать для создания игры
Так там тебя не учат этому, просто могут быть структурированные таблички. А так будет по порядку.
Но вообще лутц не лучшая первая книга, это да.
>Если позиции товаров повторяются, то в итоговый список попадает суммарное количество товара по данной позиции.
Убил 8 часов на это, еле-еле сделал, ну и сложные задачки, конечно.
Внимание! Вопрос к знатокам.
Сап двач, я собственно из другой сферы программирования, просто стала задача по вебу(батяня попросил написать ему программульку) и я так понимаю для быстрого его решения подойдет лучше питон.
Суть вопроса моего такова:
У меня есть страничка на али (ордер заказа), на ней есть комментарий продавца, который мне надо получить в мою программульку.
одним из вариантов решения я вижу для данной задачи использовать какой нить парсер по типу (Silenium, beautifulsoup )
Важное примечание, что для того чтобы получить инфу надо быть залогининым(вериф идет по почте) как это обойти? Я видел, что с помощью этих фреймов можно проходить обычную верификацию , а можно ли подставить свои куки для обхода этого? и сработает ли это ?
Потом, на сколько я понимаю в ваших вебах сама инфа на страничке генерится жабаскриптом, парсер сможет ее прочитать или он только хтмл + цсс читает ? или как это вообще работает?
Как все делать мне показывать не надо, у меня чисто вопросы по вебу, по выбору фрейма, и то что я тут обсуждаю в теории будет работать ? или какие тут подводные камни ? Просто в альтернативе тогда захерячить какой нить макрос, но мне не хочется делать его , так как это прям всемогущий костыль будет, и может повлиять на юзера(в теории). Либо есть еще альтернативы в решении этой таски? Буду благодарен если кто нить по существу ответит.
всем продуктивного вечера!
Насколько я помню, на али весьма злоебучий процесс логина, так что чистыми запросами будет сложно. Так что берешь селениум или какой-то pyppeteer, дергаешь нужные селекторы и все. И не надо парится насчет генерируемого и подругажемого контента. Просто ждешь готовую страницу и забираешь что надо.
В данном случае у питона никаких особых плюсов нет, это делается примерно одинаково везде.
Благодарю вас
Я почему то думал, что это надо попробовать через парсер как то делать , но вот вижу, что через селениум можно браузер эмулировать.
Еще раз спасибо.
Да я знаю про славри и методы, но до такого:
>items.setdefault(name, {}).setdefault(item, 0)
чтобы догадаться надо иметь IQ > 140 явно, какой-то космос tbh
Как и селери?
Что вместо очередей теперь используют?
Мне надо распределять запросы на последовательную обработку по определённому идентификатору в самом запросе.
Делаю чаты. Мне приходят сообщения с разных чатов и я отправляю их в другой сервис с чатами. В пределах одного чата нужен порядок.
Я в вебе буквально полгода, многих технологий могу не знать. Единственное что нашёл это селери и fifo очереди. Основной сервер на gunicorn с одним инстансом, который сразу отправляет данные в очередь, где они дальше распределяются.
Понимаю что под нагрузкой он не сможет работать адекватно. Запускал на uvicorn, производительность атас, но порядка нет никакого.
Я не понял причем тут селери относительно предыдущего вопроса, оно вполне себе юзается. Хотя ты упомянул селери в контексте очередей и для этого какой-нибудь кролик лучше подходит.
С брокером проблем нет. Проблемы именно в работниках, которые тупят по 10с прежде чем забрать следующий таск в случае с gevent воркерами. Prefork так не делает, а solo вообще без тормозов.
Но gevent нужен для лучшей масштабируемости
string = '1. 0.1, 0.2, тест, тест. ' \
'2. тест, тест, 0.5=0.3+0.2.'
Нужно заменить точки на запятые только в тех местах, где они отделяют дробную часть числа, чтобы было вот так:
string = '1. 0,1, 0,2, тест, тест. ' \
'2. тест, тест, 0,5=0,3+0,2.'
Как это сделать?
Только без костылей типа string = '1. ' + '0.1, 0.2, тест, тест'.replace('.', ',') + '. 2. тест, тест, ' + '0.5=0.3+0.2'.replace('.', ',') + '.'
мб \\
/\ или \\
my_list_1 = [1, 1, 1, 1, 2, 2, 2, 3, 4]
my_list_2 = [2, 1, 4, 5]
Хочу удалить из первого списка элементы, присутствующие во втором списке.
Почему код вида:
for number in my_list_1:
if number in my_list_2:
my_list_1.remove(number)
Не удаляет все единицы и двойки из списка my_list_1?
1. Потому что нужно читать документацию
>If a list contains duplicate elements, the remove() method only removes the first matching element.
2. Потому что так писать вообще не стоит. Ты на пустом месте получаешь n^2, хотя задача решается за линейное время.
[x for x in my_list_1 if x not in set(my_list_2)]
ну и в догонку - ты меняешь коллекцию в процессе итерации. Так не надо делать.
Это логарифм от размера my_list_2 (и set в лямбде тоже ленивый получится, то есть, пердон его на каждой итерации будет из листа переделывать)
Если не пограммист, то зачем тебе сравнение интеграторов?
>1. Потому что нужно читать документацию
>If a list contains duplicate elements, the remove() method only removes the first matching element.
Что интересно, итоговый my_list_1 выглядит так: [1, 1, 2, 2, 3]. То есть почему-то удаляется две единицы и две двойки. Если бы удалились по одной, то всё было бы понятно. Но почему работает так?
Ты че, на плюсах пишешь обычно? Тута у нас set через хэшмап сделан, а не кчд.
Да и даже логарифм растет медленнее линейной функции, так что в сумме все еще O(n)
>и set в лямбде тоже ленивый получится
Да господи, это же общая идея. Скасти его заранее же.
Потому что все люди разные и с разными интеллектуальными способностями.
ваш кэп-крокодил
Потому что ты меняешь коллекцию в процессе итерации же:
In [8]: my_list_1 = [1, 1, 1, 1, 2, 2, 2, 3, 4]
...: my_list_2 = [2, 1, 4, 5]
In [9]: for i, number in enumerate(my_list_1):
...: if number in my_list_2:
...: my_list_1.remove(number)
...: print(i)
...: print(my_list_1)
...:
...:
0
[1, 1, 1, 2, 2, 2, 3, 4]
1
[1, 1, 2, 2, 2, 3, 4]
2
[1, 1, 2, 2, 3, 4]
3
[1, 1, 2, 3, 4]
4
[1, 1, 2, 3]
есть русик, на гите есть код. В целом вроде все рассказали и разжевали. Остается только повторить успех.
Всё равно непонятно: почему на итерации 2 удаляется двойка из списка, а не единица?
Ты удаляешь первое вхождение и всё сдвигается назад.
PyPDF2 не имеет такого функционала.
Декораторы, асинхронность
На ютабах и гите нет моих задач. Везде хеловорлды пишут, а чего-то реального нет.
Никто не хочет делиться опытом, чтоб не было конкуренции и они были незаменимыми на рынке.
Так ты просто скрипт сделал, это хуйня из под коня.
Учил джангу на боевом сервер, ибо
КОГДА ГОТОВ? СКОЛЬКО ВРЕМЕНИ НАДО?
@
НЕДЕЛЬКИ ХВАТИТ ЧТОБ СЕРВЕР СДЕЛАТЬ?
@
ДАВАЙ ТЕСТИТЬ
@
ТЕСТЫ ДЕЛАЮТСЯ РУКАМИ, ТЫКАЮТ КНОПОЧКИ, О ЮНИТ ТЕСТАХ НЕТ И РЕЧИ
@
НУ РАБОТАЕТ, ДАВАЙ НА ПРОД
@
ОЙ А ПОЧЕМУ ЭТОГО НЕТ, НАДО ЧТОБ БЫЛО
@
ПОЧЕМУ НЕ РАБОТАЕТ ФРОНТ? ПОХУЙ ЧТО ТЫ НА БЕКЕ
Че-то всё вперемешку.
Ну показал что можешь пользоваться либой дискорда и асинки везде делать. Это как бы одна из базовых вещей. Ну и всё на этом. У тебя все происходит в либе, абсолютно всё.
Как будешь деплоить? Это ж бот, он как бы и сервер иметь должен свой наверное не?
Короче мешанина непонятная. Нет внятной точки входа. Кажется будто это просто часть какого-то другого проекта либо сделано как тестовое. С учётом нулевого опыта можно снисходительно оценить.
Как боевой проект - однозначно нет.
Для начала, разделяй бизнес логику от основной. В мейне расписывать методы НЕЛЬЗЯ, там должна быть ТОЛЬКО точка входа. В бизнес логике методы расписывать НЕЛЬЗЯ. Методы расписываются в другом месте. В твоём случае отдельным файлом типа tasks. Нет настроек, чем окружение разделять будем? Где requirements? Чем демонизировать?
Разумеется, этого всего можно не делать, если вы не собираетесь поддерживать свою хуйню уже с завтра. Но если вы позиционируете себя как ниибаца крутой, будьте любезны делать всё по стандартам.
Ой, что там расписывать, стандартная лапша.
Это как в языках с визуальной разработкой нубы накидывают на форму контролов и хуярят все в обработчиках событий.
Но гонору пиздец.
Единственное что могу сказать - делай рабочий проект. Не калькуляторы или какой-нибудь демонстрационный проект для портфолио, а то чем ты будешь пользоваться, чего тебе не хватает или другим.
У тебя будет стимул писать хорошо, поддерживать свой код, крутить-вертеть по всякому. А если ещё и получать прибыль с него это вообще стимул стимулов.
Но мне ничего не надо и я ничем не пользуюсь. Ну написал я сохранятель картинок в треде с двача, как кто-то посоветовал, но им нет смысла пользоваться, так как в любом треде обязательно будет картинка с говном или гомосеком.
Не те картинки которые 1в1, а разных размеров, например, или какой-нибудь фигней типа мелкой надписи сбоку, чтоб он считал их одинаковыми
Храни папку картинко с говном, и проверяй на вхождение, когда сохраняешь
@
КРУТО
@
ПРИ ЭТОМ ЮЗАЕТ IF SOME: PASS
@
ДА ВАЩЕ ИЗИ ТУТ ВСЁ СПРАШИВАЮТ
Чет проиграл с этого дебила
Ну и логирования нет. Куча try except pass и ни одного сообщения, даже info. Когда будут косяки будешь по полчаса искать их.
Покидайте идей чего еще интересного можно попробовать на нем сделать. Гуглил useful python scripts, но такого чтоб прям зацепило не находится.
Если таски делает один поток (из одной очереди), то он делает очень большие паузы, между ними, за каким-то хуем привязанные к wait_time_seconds.
Если таски разбирают два и более потока одновременно, то они разбирают их очень быстро, без пауз. Менял все конфиги, пробовал разные настройки - результат такой же.
Я уже просто заебался гуглить эту хуйню. Такое чувство будто никто с этим не сталкивался.
Исходник в utf-8, показывает так PyCharm. На пике длинные пробелы типа табов, U-2004 в таблице символов винды
Построчно т.к. я удалял последнюю строку, где указан год написания. Потом будет нужно разбить этот текст на отдельные слова и посмотреть, какие встречаются чаще всего, поэтому даты не должны портить статистику
Лол, только сейчас заметил, строки же иммутабельны.
Надо делать str = str.replace
Алсо, лучше переделай на имена, т.е. str.replace("\N{THREE-PER-EM SPACE}", " ") и т.д.
Генераторы и списков смотри
Неа, даже так не сработало. Странно, что раньше интерпретатор вообще не ругался на мою попытку реплейснуть строку.
Сделай через regex
Рандомайзер генерирует число. Это число записывается в некоторый список. Мне не нужно больше 30-и последних, т.е. список должен быть ограничен и при добавлении нового числа, 31-е должно удаляться. Также из этого списка я должен читать и сравнивать некоторое их N-ное количество.
Сделай свой класс
Читай доку https://docs.python.org/3/library/collections.html#collections.deque
Почти тот же список, но с дополнительными плюшками. А можешь и в список перегнать через list(q).
Орм
Если таски делает один поток (из одной очереди), то он делает очень большие паузы, между ними, за каким-то хуем привязанные к wait_time_seconds.
Если таски разбирают два и более потока одновременно, то они разбирают их очень быстро, без пауз. Менял все конфиги, пробовал разные настройки - результат такой же.
Я уже просто заебался гуглить эту хуйню. Такое чувство будто никто с этим не сталкивался.
Через PYPDF2 (вроде) можно было сам постскрипт менять, но это гемор еще тот.
Pymupdf что-то такое мог: https://github.com/pymupdf/PyMuPDF/issues/201
Это амазоновский параметр, регулирует вроде как частоту опроса или хз что вообще.
Просто суть в том что если gevent обрабатывает таски в нескольких тредах, то всё ок, но если только в одном треде - время между тасками равно этому параметру.
Просто сейчас создаётся впечатление, что воркер фризится и не знает какому треду отдать таск, из-за этого он не даёт его никому и ждёт пока селери опросит очередь.
Хотя по идее, он забирает данные сразу пачками, короче хз, какая-то залупа происходит.
pool solo работает очень быстро, prefork медленнее, а gevent вообще ждёт по 10с.
Я делаю тест, просто вывожу сообщение в лог, т.е нагрузки нет никакой
Хуйфы.
Как учиться, чему учиться, с какой целью.
На веб-дебила:
1. Язык, чтобы не спрашивать каждый раз "а что такое дикаратор" или "ой че-та библиотека не подгружается" или "пук строку не могу ревеснуть стак лох оверфлоу памахи"
Для этого нужно ботать книжки или доку. Ты конечно можешь сразу сесть и кодить, но это путь говнокодера, т.к тонкости языка пройдут мимо тебя.
2. Фреймворк. Нужно прочитать доку + сделать пару петов.
3. Основы веб: хттп, тлс, хэши, криптография, хтмл, ксс, основы сетей (базовое понимание как вообще запросы от юзера к сайту идут)
4. Инструменты: гит, гитхаб и прочая ссанина.
5. Базы данных.
Чтоб учиться нужен стимул и время.
У тебя дохуя времени, учишь тонкости-хуенкости, считаешь байтики, дорожки на платах, вычисляешь сопротивление, считаешь схемы транзисторов, как делаются процы. И всё ради того чтоб просто сервер поднять. А зачем это всё надо знать? Надо, ведь иначе ты говнокодер. Но да ладно, предположим что всем этим он будеть заниматься.
А какой у него будет стимул для этого? Ну, т.е он учит чего-то, но не видит результата, для этого нужен проект. Он не может просто писать код без задней мысли, потому что тогда станет говнокодером, ведь он ещё не знает как устроены конвейеры в проце.
Работать? Работать он не сможет.
Учить ради учебы? Т.е делать монотонные действия без стимула? Это один из диагнозов аутизма, если что, такие в принципе не достигнут вменяемого результата, ведь у него нет стимула, он напишет какую-нибудь бесполезную и неработающую хуйню, которая ее приносит прибыль. Для чего? Чтобы что? Показать что ты чего-то можешь? Кому показывать?
Чтобы учиться кодить надо кодить. Просто брать задачи и делать, остальное будет приходить в процессе. Не надо бояться говнокодить, все проходят через говнокодинг. Ты ж когда был пиздюком в 1.5 годиков и учился говорить, не начинал же с грамматики, правильно? Здесь то же самое.
>У тебя дохуя времени, учишь тонкости
До уровня транзисторов доходить не надо, но основные конструкции языка + подводные камни лучше изучить до активного кодинга.
Просто чтобы не быть как те челы выше, которые не могут из стандартной либы функцию загуглить для решения простейшей задачи(например, деку). А что он будет гуглить, если даже не знает что такое дека и что она вообще есть в питоне?
С остальным тоже самое: как ты будешь какое-нибудь веб-приложение писать, если не понимаешь хотя бы на среднем уровне как работает фреймворк? По туторам с ютуба будешь кодить? На каждую ситуацию тутора нет, а дока написана с учетом того, что человек знает язык, на котором она написана.
Дока зачастую написана уебищно, функции можно узнать по definition и то не всегда. Для этого не нужно знать чего-то сверх.
С фреймворками та же история, гуглишь базово как им пользоваться, а остальное в процессе.
Очень важно первостепенно сделать что-нибудь что работает, а оптимизацией занимайся потом. Не наоборот. С опытом придёт понимание как надо, а как не надо.
Если человек не может сам что-то делать и гуглить, значит он не умеет учиться самостоятельно, это уже проблемы совсем другого уровня. Он либо без вышки, где его учат учиться, внезапно, либо совсем без мозга.
1) сущности - это же про модели? Правильно понимаю, что надо использовать связь многие к одному? (ингредиенты к одному рецепту)
2) Про JSON REST API в душе не ебу, но речь про функции представления? (views)
3) Написано делать бэкенд - то есть и шаблоны (templates) тоже пилить надо?
Да я и не собирался неделю пилить всё это. Просто уточняю у вас моменты эти, дабы не оподливиться. По факту проект у меня есть похожий, собирался сделать ctrl c - ctrl v.
Гугли DRF
https://pastebin.com/tW1G4rp9
> сущности - это же про модели?
Ага
>Правильно понимаю, что надо использовать связь многие к одному? (ингредиенты к одному рецепту)
Хз что ты имеешь ввиду, но есть такая штука, как нормальные формы реляционных отношений. Таблиц у тебя должно получится три - ингредиенты, рецепты и таблица связей ингредиент-рецепт
> 2) Про JSON REST API в душе не ебу, но речь про функции представления? (views)
Загугли, если не ебешь - с гугления программирование и начинается.
API - скорее control, а не view, если говорить в терминах MVC.
> Написано делать бэкенд - то есть и шаблоны (templates) тоже пилить надо?
Нет. шаблоном(представлением) данных в твоем случае будет их сериализованное в json представление.
Прочитать текст ошибки.
>asyncio.run(AsyncFunc)
Ты запихиваешь в run функцию вместо корутины.
А корутина в данном случае - это то, что AsyncFunc возвращает
asyncio.run(AsyncFunc()) должно быть.
Но все равно не заработает. У тебя в __anext__ count вместо self.count.
Ну и не используй camelCase для функций.
Вот спасибо, всё понял.
Осталось ещё понять, в чём преимущество асинхронных итераторов, ведь всё равно они выполняются последовательно.
Я так предполагаю, что они нужны потому что в обычных итераторах нельзя сделать await и подождать выполнения какого-то асинхронного кода.
Но опять-таки, непонятно, почему нельзя. В джаваскрипте же, вроде, можно писать await где угодно перед промисами.
__iter__ и __next__ это синхронные функции, которые пишутся через обычный def, в них нельзя await писать
Потому что вызов асинхронной функции порождает корутину и она до закидывания в луп не исполняется, а вызов обычной какой-либо результат сразу. Можно конечно было бы забить хуй и заставить интрепретатор определять что эта за хуйня на момент создания функции по наличию ключевого слова await, но это неудобно в том числе и для программиста во время чтения кода.
А в чём разница для программиста, кроме того, что он как минимум ещё одну функцию должен объявить с async, а потом ещё и передать ей управление, вместо того, чтобы просто сделать await в обычной функции?
И принт тоже синхронный?
Я-то думал мы пишем типа
t1 = await go()
...
...
if t1:
...
и он запускается в момент await и спустя какое-то количество строк кода, когда мы вызываем результат t1 он либо ждёт результата, если не успел, либо даёт результат
Если это работает не так, то это ж пиздец. Ладно, буду дальше посмотреть
Просто обычный слип блокирует весь скрипт, вместе с лупами и залупами.
>и он запускается в момент await и спустя какое-то количество строк кода, когда мы вызываем результат t1 он либо ждёт результата, если не успел, либо даёт результат
Не. При await следующие строчки не выполнятся, пока не завершится та асинхронная функция, которая указана после await.
А вот, кстати, хрен знает, как сделать так, как ты описал. Кроме как через asyncio.gather.
>>82868
Очевидно, заменить его на httpx.
https://www.youtube.com/watch?v=m_a0fN48Alw
Жаль. В любом случае пока пользуюсь threadpoolexecutor и внимательно ищу узкие места где можно было бы сделать что-нибудь ещё помимо прочего.
Может когда-нибудь перейду на асинки. Когда сменю джангу на что-нибудь другое.
>И принт тоже синхронный?
Конечно.
А слип, видимо, слипу рознь. Наверное, этот слип отдаёт управление от питона операционной системе. А тут нужен asyncio.sleep, наверное, чтобы отдал управление эвент лупу, запущенному в asyncio.run
Создание таски автоматически закидывает корутину в луп, где начинается ее выполнение, последний await отрабатывает сразу, так как к этому моменту она уже закончена.
Вообще непонятно, что тебя тут смущает. Ожидаемый результат же.
А как ты декоратор тогда напишешь?
А как ты при наследовании будешь поступать?
А что, если я не хочу await-ить крутизну, а хочу ее через таск запустить?
Ну и нужно понимать, что корутина - это все всего лишь хитровыебаный генератор, а не какая-то магия.
например
def test(a, b = []):
b.append(a)
print(b)
test(1)
>> [1]
test(2)
>> [1, 2]
test(3, [])
>> [3]
test(4)
>> [1, 2, 4]
Как мне этого избежать, но сохранить возможность пустого списка как параметр по умолчанию?
Смотрим джангу за час, или быстро читаем доки примеры с опросами.
Далее. Находим начинатора. Я выбрал divanov11 и его репу. Он пилит сайты на джанго.
Начинаем читать чужие коды.
Как читать.
Смотрим в самом проекте на урлы и сеттинги. Тут все.
Далее в самом эппе смотрим
Модели, формы, урлы и вьюшки. Именно в таком порядке читаю. Понял вообще все.
Далее что почитать.
Чужие коды искать на гите так
туду эппы, маст хэв, понимается круд технология.
всякие блоги хуеги
можно почитать туторы от мозиллы, и сделать их задание сделать блог, но я и так нашел и чекнул на гите.
Начинаем пилить хелло ворд на джанге. Далее думаем о шаблонах. Кроме красивых шаблонов в джанге проблем я не нашел. Любой чих задокументирован, куча примеров на гите.
Улица Герцена, ты?
Вот я делаю приложуху на джанге и хочу чтоб все рендерилось на стороне сервера, то есть чтоб на клиенте js было по минимуму. И как быть со всеми этими шаблонами? Там же анрил как-то порядок держать. А ещё если из шаблона передавать данные в js скрипт, то это вообще каша получается и боль.
>А как ты декоратор тогда напишешь?
>А как ты при наследовании будешь поступать?
Не понимаю, чем await внутри обычной функции помешает сделать ей декоратор или как await внутри обычного метода помешает его переопределить.
>А что, если я не хочу await-ить крутизну, а хочу ее через таск запустить?
А что этому помешает, если await можно будет внутри обычных функций использовать?
>Ну и нужно понимать, что корутина - это все всего лишь хитровыебаный генератор, а не какая-то магия.
Всё равно не понимаю. В чём проблема дождаться завершения работы хитровыебанного генератора в обычной, а не асинхронной процедуре?
Прочитать два абзаца о том, что такое корутина и как они реализованы не можешь ты, а мудак я. Ясн.
Ты хочешь сказать, что это просто?
То есть ты не можешь на простой вопрос ответить, и вместо этого начинаешь писать оскорбления, и после этого ты не мудак? Ясн.
Про какие два абзаца ты написал - вообще непонятно. Ты хоть понимаешь, что в интернете миллиарды абзацев?
2д22 год, а программисты все еще не знают, как искать информацию в интернете. Классика.
https://lmgtfy.app/?q=python+await+outside+async+function&iie=1
Держи. И не говори потом, что я мудак, оскорбляю тебя, и не помогаю.
Мудак. Потому что мог бы либо помочь не оскорбляя, либо пройти мимо. С чего ты вообще взял, что я программист? Может, я таксист? Ты вот знаешь, где улица Есенина? Не знаешь? Шизоебанат, загуглить не можешь?
А ссылка твоя хуёвая, не работает нихуя. Она же по логике вещей должна гуглить за меня, а она не гуглит, только делает вид, что собирается погуглить. Это какое-то наебалово. И вообще, на английском непонятно. На русском два абзаца дай. А пока не дал - не пытайся умничать, что кто-то не может их прочитать.
Хуево быть тобой, за два часа не смочь найти ответ.
Ну, значит, не особо он тебе и нужен, таксист вполне себе хорошая профессия.
Я и не искал. Ты ведь сказал, что для этого нужно прочитать два абзаца, и я жду, когда ты уточнишь, которые именно. А ты юлишь жопой. Наверное, ты просто боишься, что я брошу таксовать и отберу у тебя рабочее место с зарплатой 300 к в наносек.
Есть два хтмл файла например.
home.html
blog-page.html
Простой блог. Где домашняя и там где будут статьи.
Так вот. Как сделать пагинацию чтобы все это дело множилось?
>Как сделать пагинацию чтобы все это дело множилось?
Без задней мысли. Ты делаешь запрос, в ответ тебе приходит json с какими-то там статьями, штук 30 например, ты их рендеришь в шаблоне. И делаешь ссылку на следующие 30 штук
Вот функция:
def savetofile(filename):
file = open('{filename}.csv', 'w')
...
Вот вызов:
savetofile(001)
В итоге вместо создания файла 001.csv создается файл {filename}.сsv
А если я типо сам вылаживаю статьи?
Вот метод massege принимает параметр passcode, это булевая переменная, а куда сам пасскод-то назначать? Почему у двача такая уебищная документация...
f, format, % дохуя способов.
Сразу проиграл, вспомнив, что у пистона ДОЛЖЕН БЫТЬ ОДИН СПОСОБ СДЕЛАТЬ ЭТО И ПРИ ЭТОМ -САМЫЙ ОЧЕВИДНЫЙ
Открыть исходник и посмотреть, как оно там сделано.
Ну и очевидно, что f-strings самый правильный. А остальные оставлены для обратной совместимости. Короче, нужно тонкости языка знать и понимать, впрочем, как и везде
>нужно прочитать два абзаца, и я жду, когда ты уточнишь, которые именно
>отберу у тебя рабочее место с зарплатой 300 к в наносек
О дивный манямир
>>83663
>>83680
Окей, подставлять переменную в название файла получилось:
file = open(f'{filename}.сsv', 'w')
А как быть вот с такой конструкцией?
file.write(tabulate({filename}().to_values(), headers=headers, tablefmt="tsv"))
Максимум что получается через f-string - это записать строку "tabulate(название файла().to_values(), headers=headers, tablefmt="tsv")" в файл "название файлаю.csv". В остальных вариантах {filename} вообще не распознается.
Бля, чел, не дави тупостью, если у тебя там какие-то операции над переменной - сделай новую
filename = '_'.join(filename.to_values())
file.write(f'tabulate{filename}.csv') Или что там у тебя
Т.е. если мне надо маппинг распаковать, писать f'{mapping["key1"]} ... {mapping["key2"]} ... ' вместо '{key1} ... {key2} ... '.format_map(mapping) ? Принял к сведению))
пробовал через for n in spisok но чет жидко обосрался с ошибкой <generator object <genexpr> at 0x01E14F00>
Палишь паскод
Ну так не бойся и покажи, что за абзацы такие.
Бляяя, анон, спасибо! Пиздец я долбоеб слепой, уже полчаса сижу тыкаю, не могу понять в чем проблема.
А, подсказали уже.
Конечно, макака долбоёб. Везде пасскодом называет, а в апи нет - юзеркод, блядь, а потому что на хуй пошли, вот почему.
Чтоб такие как ты ее взламывали макабу.
Я бы вообще использовал какой-нибудь md5 вместо названия поля
Чё-то типа
puk = [*pok.split(..) for pok in kok]
Только я не помню как разворачивать его, наверное ещё надо что-то сделать. Ну или вариант на две- три строки
Конечн принимай, принимай ещё что фстринги быстрее
>>84021
хуя жеские. Я не знал про itertools и map (я только учусь), и смог вывести ['1 2 3', '1 2 3'] через цикл с с записью в пустой массив с исключением пробела. Получилось
>puk = ['1', '2', '3', '1', '2', '3']
А требуется
>puk = [[1,2,3][1,2,3]]
Простым словом, я изначально сам себе неправильно поставил задачу и теперь надо как-то исправлять.
Я пока еще не дошел в курсе до itertools и map, предполагается что я решу все с помощью циклов. Думаю с помощью цикла проверить каждый элемент, в него вложить цикл с условием который будет менять символы пробелов в элементах на запятую, и потом надо будет вспомнить как поменять значение в элементе с str на int через его индекс.
Аттрибут всегда лямбда функция где ВАЖНЫЙ параметр это имя самого аттрибута (поэтому загрузка из файла что бы в лямбду передать строку)
Дальше будет сложно объяснить, но я хочу лишиться парсинга из файла
Могу ли я сделать так что бы имея одну фунцию и при написании object.blablabla я бы получал ссылку на свою функцию куда в параметр будет передан аттрибут blablabla ?
Блять пиздец я тупой даже не знаю как скачать что мне нужно
Послушаешь себя так у меня шиза вообще, но функция везде реально одинаковая, отличается только одна строка переданая в параметр
на пикче мой шизокод
Проблема в том что при обновлении api мне нужно будет обновлять файл и записывать туда новые функции и выписывать старые, а вообще похуй на самом деле чё в функцию передавать, если у api такой функции нет, он мне просто ошибку вернёт, поэтому тут уже мне нужно будет следить что я пытаюсь вызвать
Если у тебя такая вереница получается, которую нельзя свести к более простой конструкции, значит ты пишешь говнокод
Не, это говноязык
В int преобразовать не забудь
Сделай просто py файл. Зачем такие изьебства. Хранить конфиги в py это нормально
Динамические SQL-запросы с кучей параметров это у нас теперь вереница и признаки говнокода, так и запишем.
Буду тогда построчно джойны форматировать через f', а потом конкатенировать через if-elif в единый скрипт, так будет не говнокод))
В этом случае это
>'{key1} ... {key2} ... '.format_map(mapping)
ненамного лучше f-strings. Какие же двачеры дегенераты, им дают удобную фичу, а они продолжают кушать говно.
Где лучше, ебанат? Скорость себе в очко засунь, толку от твоих десятков милисекунд никакой.
С ф-стрингами мне надо явно указывать название маппинга и обращаться к ключу через ['ключ']. Если потом поменяется название маппинга, мне руками лишний раз ctrl-c + ctrl-v делать? А если набор ключей поменяется, руками лезть и заменять всю эту портянку?
С форматом мне достаточно указывать только ключи и распаковать маппинг. Если поменяется маппинг - поменять маппинг в формате, если поменяется набор ключей - через дикт компрехеншн отфильтровать. Ой забыл, это же всё говнокод, надо всё на ф-стринги переводить, ебаться с конкатенацией, чтоб сэкономить милисекунды на форматировании, но добрать их на конкатенации, зато фичу использую.>>84347
Например паттерны - структурные, порождающие и прочее.
А как быть с SOLID, это же про ООП?
И про GRASP это нужно и чем отличается?
Да, это говнокод, если тебе уж так необходимо всегда передавать длинный список параметров, то выдели его в структуру или класс, это БАЗА рефакторинга.
>Если потом поменяется название маппинга, мне руками лишний раз ctrl-c + ctrl-v делать?
Решается простейшей глобальной заменой, к тому же, навряд ли у тебя эта переменная будет в одном месте. Но если ты настолько беспомощен, что не может пользоваться ей, то что ты вообще делаешь в программировании?
>если поменяется набор ключей - через дикт компрехеншн отфильтровать
Лол. И разве это не говнокод?
Паттерны (или шаблоны) проектирования описывают типичные способы решения часто встречающихся проблем при проектировании программ.
Ты можешь вполне успешно работать, не зная ни одного паттерна. Но зная паттерны, ты получаешь ещё один инструмент в свой личный набор профессионала.
В пайтоне уже некоторые паттерны реализованы, да, типа фабрики, декоратора, итератора, но никто не мешает тебе реализовать и другие
>выдели его в структуру или класс
У меня это так и работает, распаковка сериализованных данных из MyClass.dict().
По твоей логике мне надо всё засрать 'MyClass.dict()["ключ"]'.
>решается простейшей глобальной заменой
Глобальной заменой чего, класса? У меня разный набор входящих данных сериализуется в отдельных функциях, причем тут вообще глобальная замена?
>Лол. И разве это не говнокод?
Потому что ты так скозал - да.
Добавлю к >>84393
>если поменяется набор ключей - через дикт компрехеншн отфильтровать
Вообще я могу это делать на уровне класса, но в том же пайдантике есть параметры типа exclude_unset, так что это пример для чистого дикта.
Очередная экономия на спичках, и лишь бы доебаться со своими фишечками, где они удобны только в простых случаях. Никто это переделывать и переписывать не будет, т.к. всё работает и так и никто на ревью не доёбывался.
Запиши это в комментах к коду, чтоб после тебя, когда его будут править другие люди, они видели чем ты руководствовался
element = wait.until(
EC.element_to_be_clickable((By.ID, "scroll"))
)
element.click()
После чего начинается новомодный скролл траницы с отрисвокой. Но мне нужно кликнуть на то, что отрисуется после скролла.
Проблема в том, что этот элемент "clickable" сразу, а скролл-то ещё не доехал и этого элемента не видно. Как можно без sleep() заставить движок подождать завершения скрола?
Есть ли какая-то принципиальная разница, если я напишу if - elif - elif - else или if-if-if-if?
https://ideone.com/3vhGMk линкрил.
Побежал во всех проектах переделывать формат на ф-строки и отправлять пулл реквесты с комментарием "Руководствовался советами с двача, чтоб сэкономить 20 миллисекунд"
Во-первых, страдает читабельность.
Много ифов намекает, что может быть несколько совпадающих условий для одного случая. А иф-елсиф-елс это только один вариант.
Ну и делать инвертированый вариант всех условий для елс это тупо и не всегда возможно.
>Много ифов намекает, что может быть несколько совпадающих условий для одного случая. А иф-елсиф-елс это только один вариант.
Справедливо. Оке, понял, спасибо.
Горелодупый жабий скриптовик, ты?
Был проект, предложили переписывать. Говорил, давайте на го сделаем, он быстрее, можно на микросервисы сделать, согласились. А потом звонят и говорят, ну его, давай лучше на джанге, так быстрее чем го осваивать.
А у вас было такое?
Интерпретатор код читает справа на лево
Напишите программу, на вход которой подаётся прямоугольная матрица в виде последовательности строк. После последней строки матрицы идёт строка, содержащая только строку "end" (без кавычек, см. Sample Input).
Программа должна вывести матрицу того же размера, у которой каждый элемент в позиции i, j равен сумме элементов первой матрицы на позициях (i-1, j), (i+1, j), (i, j-1), (i, j+1). У крайних символов соседний элемент находится с противоположной стороны матрицы.
В случае одной строки/столбца элемент сам себе является соседом по соответствующему направлению.
https://github.com/Testudinate/Python/blob/master/26_while_matrix.py
Если такие малочитабельные list comprehensions использовать, то почти любой достаточно большой код на Питоне можно сократить в полтора раза. "В пять строчек" твою задачу без них (ну или без itertools или numpy) решить никак нельзя.
Лично я при одинаковой алгоритмической сложности предпочту решение в 16 строк, чем в пять, но подобное.
>li, lj = len(m), len(m[0])
Бля, вроде очевидная такая хуйня, а меня на нее осенило только после того как кругами раз 20 по комнате походил, потом еще записал в отдельный текст и сохранил на рабочем столе что
>количество элементов в списке a[0] - это количество столбов, количество вложенных списков в a[] это количество строк.
вроде и интересно такое все решать, а вроде и жепу рвет.
Подскажите, как мне посчитать разницу в минутах между двумя этими датами? Никогда не работал с таким типом данных, вообще хз.
Импортируешь в datetime, а там есть функции для разницы.
Пишешь сервер, всё хорошо, всё по полочкам, на своих местах. А потом в какой-то момент это превращается в какую-то мешанину, особенно бизнес логика и условный tasks превращается в какую-то помойку из независимых классов на 2к строк по 10-20 методов, которые вроде как дублируют друг друга, сука, и в то же время нет, потому что отличаются какой-нибудь специфичной залупой.
Трясёт уже от этой херни. Чувствуешь себя конченым дебилом
Ещё самое обидное, что некому это ревьюить. Сидишь себе в этой замкнутой бочке и перевариваешься в собственном соку до состояния говна. Ни спросить ни посоветоваться, нихуя. Только на прод выкати завтра, а дальше ебстись как хочешь
У меня на ревью кода, я отправл на ревью, был косяк, в словаре закомментил строку и подсунул True для проверки что там будет выводиться при разных данных. Так на ревью апрувнули без вопросов. Сук, как это бесить, хоть блять 1/0 пиши, апрувнут не глядя
Просто редактор не подтягивает методы декоратора, как я понял.
У меня есть список кортежей: [('ask', 421), ('answer', 634), ('answer', 125), ('answer', 285), ('ask', 755), ('ask', 451), ('answer', 935), ('ask', 633)]
Мне нужно профильтровать его так, чтобы у кортежей чередовалось первое значение. Если повторяется значение 'answer', то мне надо выкинуть из списка все кортежи, кроме первого в этом повторении. Если повторяется значение 'ask' - то выкинуть все, кроме последнего в этом повторении. По итогу фильтрации должен остаться такой список:
[('ask', 421), ('answer', 634), ('ask', 451), ('answer', 935), ('ask', 633)]
Первым значением в кортеже всегда бывает либо ask, либо answer, второе значение в кортеже не играет роли (но мне надо соблюсти изначальную сортировку). ask/answer может и не повторяться, а может повторяться 2-5 раз подряд.
Олимпиадные задачки тут нарасхват вижу, а обсудить подобные проблемы нет. Такое чувство будто в треде одни вкатуны.
720x476, 4:43
Охуеть, спасибо, анончик! Только как это работает? Вообще не могу понять.
groupby нарезает последовательность на группы по ключу, первому элементу тупли в данном случае. Потом по этому же ключу выбираем, какой элемент взять из группы.
ебаный шизоид
Ты где такое взял? Это что-то на динамическое программирование. Да ещё с какой-то начальной эвристикой. Какие хоть ограничения по времени, сложности, памяти?
А ещё подпись про 64 битный ввод намекает, что предлагается решение не на питоне.
ограничение по времени 5 секунд, ограничения по памяти нет
>А ещё подпись про 64 битный ввод намекает, что предлагается решение не на питоне.
в питоне же int не ограничен или я ошибаюсь?
тогда какая проблема с 64 битным вводом? могу ведь считать все в строку а потом в инты уже
Упорядочим A по возрастанию. Теперь для заданного x_0 проверить порождает ли x_0 хорошую последовательность можно за O(n) времени, так как можно доказать, что элементы из A оптимально брать в порядке возрастания. Теперь запускаем бинарный поиск для x_0 с границами 1 и M = max(A). Сложность по времени на этом шаге составляет O(n) * O(log M). Для заданных ограничений должно уложиться.
Это копия, сохраненная 5 августа 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.