• При создании телеграм бота на PyDroid вылезает ошибка, что делать?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Ну вот же написано:
    ValueError: Unrecognised argument(s): Level

    Где у вас такой аргумент поищите глазами!
    А, не т не надо искать, ведь уже написно где:
    File "", line 6, in

    ...
    logging.basicConfig(Level=logging.INFO)
    ...

    А теперь читайте документацию на эту функцию, или посмотрите какие у нее аргументы в исходниках, или идите изучать питон с начала. Рано вам такое.
    Ответ написан
    3 комментария
  • Изучаю python,pygame. Почему обьект в игре перемещается по нажатию стрелок влево и вправо, но сразу возвращается в цент экрана?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Вы зачем инициализируете дисплей и грузите картинку накаждой итерации? Потому и возвращается, что вы его тоуда возвращаете.
    Проблема в том, что вы используете код, смысла которого не понимаете. Может быть стоит начаь изучения с простых алгоритмов, а потом уже поключать такие концепции, как анимация, фрейм-буфер и прочее?
    Ответ написан
  • Как зациклить пока не выполниться условие?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вам тут не нужно никакого цикла. Просто считайте, что в ответ на каждое сообщение или нажатие пользователя вы по новой заходите в эту функцию. Разделите куски алгоритма условием по содержимому входного текста. Делайте действия только в ветках.
    Ответ написан
  • Можно ли использовать open('file','r').read() в python?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Можно вот так делать:
    content = pathlib.Path('file').read_bytes()
    В таком случае всё правильно закроется.
    Вообще нужно стараться уже современные методы работы с файлами и путями использовать, а не доисторические.

    Вы, кстати, самозакрывающуюся читалку и сами сделать можете:
    def readfromfile(filename, mode='t'):
        assert mode in {'b', 't'}
        with open(filename, mode=mode) as f:
            return f.read()

    Но зачем, когда есть замечательный pathlib в третьем питоне из коробки?

    Ну и еще добавлю про незакрытие файлов.
    В продакшн коде, который планирует жить долго, конечно нужно всё правильно закрывать, но если это у вас мелкий одноразовый скрипт, который не открывает миллионов файлов, то вполне можно забить на его закрытие. По завершении процесса (интерпретатора) все его дескрипторы будут высвобождены.
    Ответ написан
    1 комментарий
  • Как к телеграм боту прикрутить веб админку?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    А в чем проблема? Пусть от хранит состояние в БД и в ту же БД ходит админка за инфой.
    Что именно вам не понятно и что не получается?
    Ответ написан
    Комментировать
  • Позволит ли OpenStreetMap реализовать данный функционал?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Выше в ответе вам уже посоветовали поднять свой инстанс OSRM.
    Это делается очень просто с помощью докера: https://hub.docker.com/r/osrm/osrm-backend/
    OSRM умеет, вроде бы (не успел попрбовать эту возможность), поддерживать дополнительную матрицу для переопределения весов ребер, учитываемых при построении маршрутов. Это обычно используется для учета пробок на дорогах. Рёбра, на которых КПП закрыты, можно опускать в рейтинге так, чтобы OSRM строил через них маршруты только в самую последнюю очередь. Если по какому-то такому ребру таки пjстроен маршрут, значит нормальных путей не нашлось.

    OSRM будет брать данные из постгреса, который стоит поднять на другjм контейнере.
    Если нужно редактировать данные, можете попробовать iD.
    Ответ написан
  • Почему не работает регулярное выражение?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Смотрите. У вас в файле абзацы по-другому устроены и при копировании они заменяются на виндовый формат.
    Ваш регексп можно чуточку упростить:
    ^(.{0,7})\r\n|^([0-9]{8})\r\n
    Для того, чтобы регексп работал на данном файле с теми абзацами что там есть, нужно использовать \n вместо \r\n.
    Ещё раз...
    В файле абзацы состоят из символа "OA". Ваш регексп в качестве абзацев ожидает пары "OD 0A". При копировании\вставке текста в редакторе в новый файл абзацы заменяются на станартные для данной ОС и данного редактора. Ваш редактор поддерживает юникс-формат абзацев, но по умолчанию использует именно виновый из двух символов. Вы можете сделать регексп универсальным поставив вопросик после символа \r.
    Ответ написан
    6 комментариев
  • Nginx send failed, из за чего ошибка?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Странно. Больше трёх лет нет отмеченного решения.
    Сожно просто прописать в /etc/hosts свои локальные домены на 127.0.0.1
    Тогда не нужно бдет ходить nginx-у ходить куда-то. чтобы зарезолвить локальные домены.
    Ответ написан
    Комментировать
  • Python - как облегчить скрипт Python?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Проблема в том, что задержка тут имеется только в do_some*, а в остальных случаях ваш скрипт с максимальной возможной скоростью скриншотит, кропает и сравнивает картинки. То есть программа написана так, что должна и будет утилизировать своим процессом всё ядро полностью. Я так понимаю проц у вас четырёхядерный, отсюда и 25 процентов.
    Добавьте задержку в основной цикл проверки и вы сильно разгрузите ваш процессор.
    Ответ написан
    3 комментария
  • Куды вы деваете б/у литературу по программированию?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Читаю в электронном виде. Осталась пачка книжек старых, но их выбрасывать жалко, память своеобразная. Новые не покупаю в бумажном виде. Смысла нет. Потом таскайся с ними при переездах.
    Ответ написан
    Комментировать
  • Как хранить схемы диалогов для чат-бота?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Нормально ORM работает с JSON, но не понятно зачем вам именно реляционная БД, если вы фактически отказались от нормализации и джойнов.
    Для вашего этого варианта подойдёт и NoSQL.
    таких ботов/диалогов может быть много.

    Много - это понятие растяжимое. Вы уже столкнулись с каким-то бутылочным горлышком и хотите уже что-то оптимизировать? Если нет, то делайте как проще и понятнее в рамках функциональных требовний.

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

    В вашем случае можно сделать всё на ORM и реляционной базе. Включая отдельные модели для вариантов ответов и прочего.
    Можно отказаться от ORM и размещать одного бота в одном документе. Тогда можно использовать монгу и десериализацию документа в собственную структуру классов. Тут писать получится больше, но и гибкость будет выше, можно будет пользовтаельские плагины какие-то прикручивать... вопрос - надо ли это и понадобится ли в будущем?

    Фактически диалог - это конечный автомат. Его можно представить в виде графа. Человечество уже давно придумало много способов сохранять и оперировать графом в любой БД, в том числе реляционной.
    Ответ написан
    2 комментария
  • Программа "Python" не работает. Возникшая проблема привела к прекращению работы программы. Краш ntdll.dll. Куда копать?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Избавляйтеь от винды и от QT. У вас там через GUI с чем-то взаимодействвать надо? Стройте процесс так, чтобы всё было максимально просто. Если куда-то ходите через браузер, есть Selenium для этого.
    Делайте всё headless, делайте стабильной простой и предсказуемой OS (linux).
    Максимально упрощайте код, избавляйтесь от лишних зависимостей, тем более бинарных. Чем меньше у вас таких вот внешних черных ящиков, тем лучше.
    Ответ написан
    Комментировать
  • Как отсортировать по ORDER BY используя ещё и rowid?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Если вам зачем-то нужен rowid, скорее всего вы делаете что-то не так. Для чего он вам нужен?
    В реляционных БД положение в таблице (не в выборке, а именно в таблице) ничего не значит. Вы не должны этим управлять и не за чем получать это положение. Уверен, есть другие способы достичь того, что вы там пытаетесь достичь. К примеру, если вам нужно узнать сколько пользователей имеют кэш меньше вашего, то так и запрашивайте:
    SELECT count(*) 
    FROM users u 
    WHERE u.cash < (SELECT cash FROM users WHERE id = :my_user_id)

    Если нужен какой-то рейтинг беднейших игроков до вас включительно, то можно использовать сортировку:
    SELECT u.id, u.cash 
    FROM users u 
    WHERE u.cash <= (SELECT cash FROM users WHERE id = :my_user_id)
    ORDER BY u.cash

    Очередность выборки по индексу одинаковых значений не гарантирована. Если нужна стабильност ьпорядка выборки, добавьте вторым параметром сортировки обычный уникальный идентификатор, тогда люди с одинаковым кэшем не будут от запроса к запросу меняться местами.
    Ответ написан
  • Какой сервис можно использовать для построения маршрута по нескольким точкам по времени?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Делал похожее на базе вот этого проекта:
    project-osrm.org
    Он опенсорс и я разворачивал инстанс сервиса у себя в докере.
    Можно настроить граф дорог под себя с помощью lua-скриптов. Источник геоданных - OSM.
    Ещё у яндекса есть сервис, но он латный, хотя, говорят, неплох и умеет учитывать пробки.
    OSRM тоже умеет учитывать пробки, но ему CSV с пробками надо как-то подсовывать извне.
    Ответ написан
    Комментировать
  • Почему данные о GPS не сохраняются при скачивании из Google Photo?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    скорее всего у фоток нет коопдинат в exif, но вы все же посмотрите повнимательнее. Гугл может делать предположение о мемте съемки по времени и по соседним кадрам со смартфона. Может быть гугл еще как-то следит за тем, где вы были и к вашему местоположению на время съемки приаязываются и фотки.

    попробуйте сами явно указать координаты у фото перед загркзкой в облако и еогда скачаете проверьте сохранились ли координаты. Если да, то скорее всего гугл отдельно хранит метаданные со своими предположениями и вы их просто так не скачаете в составе exif
    Ответ написан
    3 комментария
  • Записали на хакатон. Какой язык выбрать?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Как бы ни позиционировал себя хакатон, насколько бы готовыми ни требовались решения на выходе, на деле у всех получается всё сырое и не готовое не то что к продакшну, но и вообще к любому использованию. Хакатон - это не про попытку впихнуть полный цикл жизни продукта в два хакатоновских дня и бессонную ночь.
    На выходе хакатона хорошим результатом будет прототип или демонстрация концепции. Всё зависит от тематики, конечно, но не стоит ожидать продукта на выходе.
    Самое ценное и нужное что можно извлечь из хакатона - это знакомства, новые идеи, опыт авральной работы в команде, приятные воспоминания о классном приключении, романтика, общение, мотивация к развитию, понимание в какую сторону хочется расти и развиваться дальше, дельный совет от членов своей команды, от соперников, от членов жюри.
    Если команда подобралась достаточно цельная с более-менее опытными учатстниками, то может получиться годная, продуманная (в общих чертах) концепция, вразумительная презентация и симпатичный прототип.
    Просто обрисуйте для себя то, в чем вы более-менее разбираетесь или готовы оперативно поразбираться и ищите команду, где нужно делать то, что вы хоть как-то умеете. Если, скажем, в команде уже есть более опытный верстальщик, то можно попроситься и в эту команду, более опытный партнер сможет нарезать и делегировать вам понятных задачек, подсказать, если будут вопросы, а сам будет тем временем расти в каких-то новых для себя областях помогая бэку придумывать АПИ или сосредоточившись на фронтовой логике.

    В любом случае это не последний хакатон, в котором вам предоставится возможность поучаствовать. Было бы желание.

    К хакатону хорошо и правильно готовиться всегда. В смысле держать "тревожный чемоданчик" или рюкзачок с повербанком, зубной щеткой и запасными носками собранным. На гугл-драйве иметь подборочку заготовок, шаблонов и ассетов.

    На гитхабе имеет смысл завести несколько шаблонных проектов, где уже будет сделано основное: деплой, атворизация, бд. Посмотрите в сторону так называемых кукикаттеров (типа формочки для нарезания печенья). Идея в том, что большая часть проектов на тех или иных платформах довольно шаблонная. Есть несколько хороших проектов-агрегаторов, через которые можно в диалоговом режиме отвечая на несколько вопросов или заполняя форму сконфигурировать заготовку проекта на джанго, фласке и подобных фреймворках.
    Такие кукикаттеры есть на гитхабе, довольно разумно поставить такие проекты в избранное себе, чтобы потом легче найти и выбрать подходящий.

    Я еще раз упомяну про ассеты. Их много, много бесплатных. Это хороший способ сэкономить на дизайне, если у вас нет отдельного дизайнера в команде, а даже если и есть, но он не очень опытен и не знает что рисовать, то такой ассет может служить примером для перерисовки в ваш уникальный дизайн.
    Существуют ассеты графики, вёрстки, звуков, анимаций, моделей, иконок... Хорошо иметь подборочку в загашнике.
    Не забудьте также о шаблончике презентации для хакатона. С нуля ее рисовать гораздо дольше, а те же ассеты и клипарты из загашника позволят вам кастомизировать ваш шаблон под тему проекта более оеративно.
    В инете полно подборок вроде такой.

    Заведите себе Pocket. Удобно складывать туда полезные статьи и мануалы по созданию проектов и приложений, по настройке окружения, по конфигурированию nginx... аккуратно подходите к тегированию таких статей, ссылок и материалов. То, что может пригодиться в хакатоне, можно помечать отдельным тегом. а потом, когда приспичит, все релевантные материалы вам станоятся доступны мгновенно, да к тому же вы сможете поделиться с командой. Часто опытные разработчики надеются на свой опыт и не готовятся с такими ссылками и ассетами, а они могут сильно сэкономить время команды.

    Подберите себе провайдера, у которого можно на сутки или несколько снять бесплатную (пробную) или недорогую VDS. Попробуйте с ней поиграться, чтоб не разбираться потом в админке с нуля в цейтноте.

    Заведите себе какой-нибудь дешевый домен. Если планируете дальше карьеру разработчика или в целом айтишника, то личный ресурс в интернете вам в любом случае пригодится. Не так уж это дорого, по крайней мере до первого продления. Разберитесь как быстро поднять на нем субдомен и привязать к IP вашей тестовой VDS-ки. Это полезное умение сэкономит массу времени на хакатоне. а ваша команда получит серьёзный козырь и преимущество перед другими имея работающий прототип не где-то на вашем локальном вайфае с ноута одного из членов команды, а в интернете и этот прототип смогут потрогать все жеоающие и члены жюри. Это не так важно по сравнению с более работающим прототипом, но если у вас будут заготовки всего этого и времени это не займёт, то это только в плюс.

    Короче, просто возьмите блокнотик и карандашик с собой на первый хакатон. Ходите там с широко открытыми глазами, примерьте это дело к себе, постарайтесь найти интересное, поучаствуйте там и сям, предложите себя, подсказывайте что знаете, спрашивайте что интересно. Проект - это не только разработка, но и идея, концепция, UX. Вы же пользуетесь сайтами и приложениями, у вас есть своё какое-то видение и понимание что в них удобно, а что нет. Используйте свой бытовой опыт, применяйте его на практике.

    С первого хакатона вы увезёте блокнотик с контактами, с баззвордами (словами, обозначающими технологии, продукты, инструменты и решения, о которых вы не знали ранее, но о которых точно стоит почитать и что-то детально изучить), идеями, набросками, мыслями.
    Фотайте на презентацииях соперников и докладчиков интересные слайды (контакты, диаграммы, QR-коды). Потом может пригодиться. Можно включить диктофон в кармане и носить, потом контакты, которые вам просто продиктуют, а вы неразборчиво напишете в блокноте, можно будет восстановить. Также можно будет "вспомнить" какую-то инфу, которую вы и не собирались запоминать.

    А тут ссылок накидаю:
    Вот примеры ассетов:
    https://habrahabr.ru/company/plarium/blog/329330/
    https://habrahabr.ru/company/plarium/blog/330068/
    https://habr.com/post/421149/
    https://vectorcdr.com/skhemy-korobochek
    Еще есть чудесный и замечательный https://www.thingiverse.com/ как источник идей, есть генераторы текстур, и куча полезных ондайн редакторов всего на свете (GeoJSON, куча всего, js sandbox)

    Прикольная статья о том, почему стоит участвовать в хакатонах: https://habr.com/ru/company/ods/blog/450034/
    А вот подробная статья как готовиться к хакатонам: https://habr.com/ru/company/leadersofdigital/blog/...

    Хоршо иметь в гитхабе заготовочку идеального пакета и идеального приложения. Вот есть такого рода статеечки: https://habr.com/ru/post/483512/

    Бывают вот такие и аналогичные ресурсы, на которых можно попробовать верстку и логику: https://replit.com/
    Ответ написан
    Комментировать
  • Что не так с кодом?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Не соблюдены отступы, не сбалансированы скобки.
    Ответ написан
    Комментировать
  • Где можно найти алгоритм шахмат?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    В общем случае такие задачи решаются перебором. Для этого строится дерево возможных состояний доски начиная с текущего состояния. Потомки текущего состояния в этом дереве - это результаты всех возможных ходов очередного игрока. Это сильно ветвящееся дерево, а значит буквально через несколько ходов количество элементов в нём станет слишком большим, чтобы перебирать и оценивать их по очереди. Тут и речи не жёт о спуске по дереву до финальных (листовых) состояний, по которым можно однозначно удить о выигрыше.
    Очевидно, что дерево можно усекать и не рассматривать заведомо проигрышные или слишком затратные ходы, можно сравнивать состояния с определёнными предварительно просчитанными ситуациями. Чем их больше в БД, тем быстрее будет работать ваш алгоритм.
    В любом случае более менее эффективно играть в шахматы компьютеры научились только недавно и для этого нужны очень мощные компьютеры, большая БД и нетривиальные алгоритмы распознавания типовых паттернов на доске.
    Нельзя просто так взять и переделать готовый хороший шахматный алгоритм под себя. Вернее можно, но сложно.
    Зато попробовать написать что-то своё - это хорошее упражнение для мозгов.

    Попробуйте реализовать класс для описания состояния доски (включает положения фигур и цвет хода). Опишите класс для дерева таких состояний. В узле дерева будет состояние доски и ссылки на возможные состояния.
    Для состояния можно давать примерную оценку его выигрышности. В самом простом случае - это взвесить фигуры силе и просуммировать очки. В более сложном - это понимать под боем фигура или нет, заблокирована ли и т.д.

    На всякий случай скажу, что в шахматы я играть не умею, знаю лишь правила и могу играть только на дилетантском уровне, так что могу нести чушь. Просто рассказываю ка кподходил бы к решению здачи наивно с нуля. При серьёзном решении этой задачи наука давно перешагнула далеко за порог сложности для самого талантливого новичка.
    Ответ написан
    Комментировать
  • Sorted Object в Python. Миф или реальность?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Да, в старых версиях sorted выдавал генератор, у которого можно было запрашивать элементы по одному через next. Что нужно знать - это то, что в современном питоне сортировка возвращает материализованный список.
    Ответ написан
  • Что предпочтительнее в python - проверять значение в словаре или обработать исключение исключение?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вы можете сами произвести замеры, но ставлю на то, что быстрее окажется проверка по словарю, поскольку она делается за ~O(1) благодаря хешированию.
    Однако я бы предложил чуть более эффективню схему:
    D = dict()
    NOTFOUND = object()
    
    def f1(x):
        result = D.get(x, NOTFOUND)
        if result is NOTFOUND:
            result = D[x] = long_calculation()
        return result


    Не поленитесь (как я), сделайте замеры. Всем тут будет интересно.
    А ещё в питоне как-то не принято экономить на спичках в ущерб чтаемости и прозрачности кода.
    Но если всё как следует "посахарить"... Лучше всего такое кэширование смотрится в виде декоратора.

    UPD:
    Забавно. Я ошибся и с исключением действительно выходит быстрее. На это указал уже автор вопроса, а я на всякий случай пересчитал, причем по отдельности для прогрева, для повторного взятия и для неполучения из прогретого хеша.

    import time
    from math import tan, atan
    import timeit
    
    
    NOTFOUND = object()
    
    
    def long_calculation(x):
        return atan(tan(x) / 2)
    
    
    def f1(x):
        if x not in D:
            D[x] = long_calculation(x)
        return D[x]
    
    
    def f2(x):
        try:
            return D[x]
        except:
            D[x] = long_calculation(x)
        return D[x]
    
    
    def f3(x):
        result = D.get(x, NOTFOUND)
        if result is NOTFOUND:
            result = D[x] = long_calculation(x)
        return result
    
    
    FUNCS = (
        (f1, 'get triple'),
        (f2, 'except'),
        (f3, 'get once'),
    )
    
    
    def work(f, gap=0.1, count=1000):
        for x in range(0, count):
            f(x + gap)
    
    
    D = {}
    number = 10000
    
    for func, descr in FUNCS:
        print(f'{func.__name__} ({descr}):')
        print(f'  Cache empty:', timeit.timeit(f"work({func.__name__})", setup=f'D=dict()', globals=globals(), number=number))
        print(f'  Total reuse:', timeit.timeit(f"work({func.__name__})", setup=f'D=dict(); work({func.__name__})', globals=globals(), number=number))
        print(f'  Total miss :', timeit.timeit(f"work({func.__name__})", setup=f'D=dict(); work({func.__name__}, gap=0.2)', globals=globals(), number=number))

    И вот результат:
    f1 (get triple):
      Cache empty: 2.8940897800493985
      Total reuse: 1.7486431139986962
      Total miss : 1.6964515489526093
    f2 (except):
      Cache empty: 1.2670072519686073
      Total reuse: 1.2622331579914317
      Total miss : 1.2547212480567396
    f3 (get once):
      Cache empty: 1.6983374420087785
      Total reuse: 1.6465996010228992
      Total miss : 1.6999219709541649
    Ответ написан
    2 комментария