Ответы пользователя по тегу Python
  • Ошбика при запуске ТГ бота на платном сервере pythonanywhere [Errno 101]?

    Vindicar
    @Vindicar
    RTFM!
    А ты прокси их указал, proxy.server:3128? Весь доступ в сеть только через него производится.
    Бесплатные учётки к тому же могут обращаться только вот к этим сайтам.
    И да, это реально такое имя домена, оно доступно только во внутренней сети pythonanywhere.
    Ответ написан
    1 комментарий
  • Не настраиваются разные уровни логирования в python logging?

    Vindicar
    @Vindicar
    RTFM!
    Ты задал уровень WARNING для самого логгера (не для хэндлеров), поэтому он INFO отбрасывает сходу. До хэндлеров ничего не доходит просто.
    Я бы использовал эту либу немного по-другому (пример с её гитхаба)
    t_handler = tg_logger.TgLoggerHandler(users=[...], token=TELEGRAM_TOKEN)
    t_handler.setLevel(logging.WARNING)
    logger.addHandler(t_handler)

    Так куда более похоже на обычные лог-хэндлеры, проще управлять и читать даже если с либой мало знаком.
    Ну или если очень хочется setup(), то так:
    t_handler = tg_logger.setup(logger, token=token, users=users, tg_format="<b><u>%(name)s</u> : %(levelname)s</b>\n\n<code>%(message)s</code>")
    t_handler.setLevel(logging.WARNING)


    Так что логгеру задай уровень подетальнее, INFO или даже DEBUG, а тонкую настройку делай на уровне хэндлеров.
    Ответ написан
    2 комментария
  • Почему код работает, только, если замедлять сервер до 5 кадров секунду?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, как именно не работает? Комп встаёт со стола и идёт искать Сару Коннор?
    Во-вторых,
    getData = client_socket.recv(1024).decode('utf-8').split(' ')

    А если клиент не прислал данные, то сервер будет стоять и ждать на этой строке, пока хоть что-то не придёт. Хуже, recv() в общем-то не гарантирует, что данные придут одной порцией. На это можно полагаться до килобайта, но выше может быть фрагментация.
    Ну и наконец, ты сейчас пытаешься каждый кадр передавать полную информацию о происходящем в игре. Это может и надёжно, но не быстро.
    Ответ написан
    4 комментария
  • Деление строки в список Python?

    Vindicar
    @Vindicar
    RTFM!
    Там список хранит данные о rect из pygame, это отрисовка поля

    Так передавай данные так, чтобы их удобно было парсить. Простейший вариант - используй json.
    Например, сначала генерируешь данные для отправки:
    import json
    # в словаре для отправки могут быть только числа, строки, bool, списки, словари, None.
    # и никаких других объектов. Так что переделываем список rect в список списков.
    # как из rect координаты добыть ищи сам
    rects_to_send = [ [rect.x, rect.y, rect.w, rect.h] for rect in rectangles ]
    data_to_send = {  # в словарь можно также добавить другие данные
      'rects': rects_to_send,
    }
    string_to_send = json.dumps(data_to_send, ensure_ascii=True)+'\n'
    # дальше через сокет эту строку и передаёшь

    Ну и чтение аналогично.
    import json
    
    received_string = ...  # это строка, которую ты получил из сокета
    received_data = json.loads(received_string)
    #received_data будет таким же словарём, как data_to_send выше
    for x, y, w, h in received_data['rects']:
      ...  # рисуешь эти прямоугольники у себя
    Ответ написан
    2 комментария
  • Есть ли альтернатива декораторам из Python в Java?

    Vindicar
    @Vindicar
    RTFM!
    Насколько хватает моих скромных познаний, механизма, полностью эквивалентного питоновским декораторам, нет и быть не может (если не лезть в байткод).
    Но вот каждый отдельный use case для декораторов, наверно, можно реализовать, так или иначе. Так что изволь написать, что ты пытаешься сделать с их помощью.
    Ответ написан
    Комментировать
  • Как проходить список и одновременно удалять элементы, в том числе впереди курсора?

    Vindicar
    @Vindicar
    RTFM!
    Сделай цикл while и наращивай индекс текущего элемента сам, в отдельной переменной. Если элемент не нужен - удаляешь его, если нужен - увеличиваешь индекс.
    Альтернативно, ты можешь просто проходить список с конца, тогда "съезжать" будут только те элементы, которые ты и так уже обработал. Будет простой цикл с шагом -1.
    Ответ написан
    Комментировать
  • Как запустить функцию в отдельном потоке второй раз?

    Vindicar
    @Vindicar
    RTFM!
    1.
    "RuntimeError: threads can only be started once"
    Можно ли это как-то обойти понятным для начинающего в python способом?

    Можно перестать хотеть странного и принять как данность, что завершившийся поток - завершился. С ним уже ничего не сделаешь. Это так на уровне ОС, если что. Так что создавай экземпляр Thread тогда, когда надо запустить поток.
    2.
    Может можно как-то по-другому стартовать, без доп функции?

    И как ты это себе представляешь? Tkinter должен знать, какой твой код выполнить при нажатии кнопки. Единственный способ это сделать - передать ему функцию или иной callable object. Да, можно использовать лямбду, но в лямбду много не уместишь, так что лучше функция.
    А когда придёшь к оборачиванию GUI в классы, поймёшь, что передача функции/метода - наиболее простой и практичный подход.
    Ответ написан
    1 комментарий
  • Как сделать exe файл в python?

    Vindicar
    @Vindicar
    RTFM!
    Для начала можешь переименовать питоновский файл в pyw - это означает запуск без окна консоли.
    А далее, разбираешься с pyinstaller, а лучше сразу с его обёрткой auto-yp-to-exe, там есть опция для оконных приложений.
    Файлы данных внутрь exe я бы не вносил, они всё равно будут распакованы во временный каталог при запуске, так что только запуск замедлишь. Но если очень хочется, такая опция тоже есть, читай доки на вышеупомянутое.
    Ответ написан
    Комментировать
  • Как убрать ошибку кода в exe?

    Vindicar
    @Vindicar
    RTFM!
    1. почитать внимательно про auto-py-to-exe и осознать, что он базируется на pyinstaller
    2. почитать, как указать pyinstaller модуль, импорта которого он не увидел (hidden import)
    3. найти, где в интерфейсе auto-py-to-exe можно указать дополнительные опции для pyinstaller (подсказка: секция Advanced)
    4. Вписать в нужный параметр имя comtypes (возможно, придётся указать именно comtypes.stream)
    Ответ написан
  • Как исправить код?

    Vindicar
    @Vindicar
    RTFM!
    Ну ты уже вот тут глупость сделал.
    self.layer_1 = nn.Linear(inp1, inp2)  # Почему inp2 ?!

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

    Например, в твоём случае на входе первого Linear должно быть inp1 нейронов, а на выходе - 72 - inp2 нейронов. После concatenate получится (72 - inp2) + inp2 = 72 нейрона - ровно столько, сколько на входе второго Linear.

    Код исправишь сам.
    Ответ написан
    Комментировать
  • Как сделать подсчет скорости нажатий на пробел?

    Vindicar
    @Vindicar
    RTFM!
    Одним голым питоном - трудно, потому что консольный ввод буферизуется. Условно, я зажму пробел, а программа будет видеть как я ввожу один пробел за другим. Да и интервал между нажатиями теряется.
    Тебе нужно ловить пары событий нажатие-отпускание. Ты можешь попробовать использовать tkinter (он в питоне доступен сразу), создать окно, и привязать к нему обработчики соответствующих событий. Причём нужна именно пара событий <KeyPress> и <KeyPress>, а не просто <Key>.
    А реакция на эти события... зависит от того, что тебе нужно. Например, заводишь переменную-счётчик, при отпускании клавиши наращиваешь его на 1, а раз в секунду (в ткинтере есть метод .after(), он хорошо подходит для задач вида "сделай вот это через заданное время") выводишь этот счётчик пользователю, и тут же сбрасываешь его в ноль.
    Ответ написан
    Комментировать
  • Как решать такие задачи?

    Vindicar
    @Vindicar
    RTFM!
    Размер выхода слоя равен размеру входа следующего слоя.
    Вот как узнать размер выхода последнего слоя - я фз, тут недостаточно данных.

    EDIT: ой, блин, я невнимательный. Не увидел, что слои идут не 1->2->3->4, а 4->3->4.
    Тогда ещё проще, выход 4 должен совпадать по размеру со входом 3, а вход 4 - с выходом 3.
    Ответ написан
    2 комментария
  • Что использовать в качестве workerА для отложенных задач?

    Vindicar
    @Vindicar
    RTFM!
    Я бы вообще изобрёл велосипед, если честно.
    У тебя есть список или база активных (неслучившихся) событий. Пусть это будет пара ID-метка времени, остальная инфа нам без надобности.
    При запуске бота выбираем из списка ближайшее событие, и вычисляем время ожидания (с небольшим запасом) и спим в корутине. В случае, если ожидание прервано раньше - повторяем то же самое, чтобы либо "доспать", либо переключиться на ожидание более близкого события.
    Если же ожидание закончилось успешно, обрабатываем событие и снова повторяем поиск ближайшего события.
    Если список событий изменился, прерываем текущее ожидание, чтобы корутина ожидания могла адаптироваться к изменениям.

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

    Vindicar
    @Vindicar
    RTFM!
    Если Normalize может работать нормально с uint8 - то преобразования типа не нужны.
    Если не может - то никакой другой порядок и не заработает.
    Ответ написан
    Комментировать
  • Как в openai обойти ошибку openai.PermissionDeniedError?

    Vindicar
    @Vindicar
    RTFM!
    Сделать так, чтобы openai не понял, что вы в России.
    Как хотите, но ваш туннель должен терминироваться на зарубежном хосте, и только потом идти к ним.
    Либо ставьте бота туда, либо поднимайте там прокси с авторизацией, либо городите VPN...
    Ответ написан
  • Как сжать и закодировать данные так, чтобы их можно было отправить в теле запроса на сервер?

    Vindicar
    @Vindicar
    RTFM!
    У тебя различие появляется в том, что gzip.compress() даёт не тот же результат, что был подан в gzip.decompress().
    Видимо, разные реализации алгоритма gzip. Но если данные успешно разжимаются, то не всё ли равно?

    EDIT: я посмотрел инфу о заголовке Gzip. Создать идентичный заголовок несложно, но проблема идёт дальше: сами данные непохожи. Я раскопал, как получить "голый" deflate-поток без заголовков, и попытался сравнить его с тем, что идёт после gzip-заголовка в твоих данных. В твоём случае заголовок минималистичный, поэтому занимает всего 10 байт, а дальше идёт deflate-поток. Он успешно разжимается в те же данные, которые даёт gzip, так что я вроде не ошибся.

    Но попытка перебора вариантов сжатия так, чтобы получить хоть что-то похожее, результатов не дала.
    Вот мой код, увы, он выводит Match not found.
    import binascii, gzip, zlib, sys
    
    def deflate(data, compresslevel=9, strategy=0, wbits=zlib.MAX_WBITS, memlevel=zlib.DEF_MEM_LEVEL):
        compress = zlib.compressobj(
                compresslevel,        # level: 0-9
                zlib.DEFLATED,        # method: must be DEFLATED
                -wbits,               # window size in bits:
                                      #   -15..-8: negate, suppress header
                                      #   8..15: normal
                                      #   16..30: subtract 16, gzip header
                memlevel,             # mem level: 1..8/9
                strategy              # strategy:
                                      #   0 = Z_DEFAULT_STRATEGY
                                      #   1 = Z_FILTERED
                                      #   2 = Z_HUFFMAN_ONLY
                                      #   3 = Z_RLE
                                      #   4 = Z_FIXED
        )
        deflated = compress.compress(data)
        deflated += compress.flush()
        return deflated
    
    def inflate(data):
        decompress = zlib.decompressobj(
                -zlib.MAX_WBITS  # see above
        )
        inflated = decompress.decompress(data)
        inflated += decompress.flush()
        return inflated
    
    
    input_data = b"H4sIAAAAAAAA_2SNvU7EMBAG32V7To7txMleB-JKWugsc-wllhI78k8iQLw7sgPVdauZHX0GFX5H7BHMumpnFoJzRIGw03u5muYwG4VovStIIaiT4OLE6gNDuE7GOZq1_SiEdwiZ2wf59Rjy8-vLdnm67Ref_e1t_BxrI2uTtMlp8qF2FlkxLcI1h0Au6RzpX_VStQ1X8li3iZY_IQbVDl3HWX-OOCBEmuf76ucXAAD__wEAAP__grfYVeYAAAA"
    gzipped_data = binascii.a2b_base64(input_data.replace(b"_", b"/").replace(b"-", b"+") + b"=")
    raw_data = gzip.decompress(gzipped_data)
    print('RAW', raw_data)
    
    deflate_stream = gzipped_data[10:]
    inflated = inflate(deflate_stream)
    print('DEFLATED DATA', deflate_stream)
    print('RESTORED DATA', inflated)
    print('Restored data matches original:', inflated == raw_data)
    
    for level in range(1, 10):
        for strategy in range(0, 5):
            for wbits in range(9, 16):
                for memlevel in range(1, 10):
                    test = deflate(raw_data, level, strategy, wbits, memlevel)
                    if deflate_stream.startswith(test) or test.startswith(deflate_stream):
                        print(level, strategy, wbits, memlevel)
                        sys.exit(0)
    else:
        print('No match found')
    Ответ написан
    1 комментарий
  • Задание из практикума, не могу сделать уже целую неделю. Какие есть ошибки?

    Vindicar
    @Vindicar
    RTFM!
    У тебя как минимум один косяк в expire().
    for title, batches in items.items():
        for batch in batches:
            if batch['expiration_date'] and batch['expiration_date'] < today:
                expiring_items.append({'title': title, 'expiration_date': batch['expiration_date']})
                break  # <--- ???

    Ты находишь первую "протухшую" партию для товара, и сразу же переходишь к следующему товару. А если у одного товара несколько "протухших" партий?
    Ответ написан
    Комментировать
  • Появилась проблема при запуске приложения Python в Termux?

    Vindicar
    @Vindicar
    RTFM!
    Если нужен красивый визуал в командной строке под никсами, может, стоит использовать модуль curses?
    Ответ написан
  • Где и как в Pycharm можно проанализировать код на вызовы или использование не объявленных методов\полей?

    Vindicar
    @Vindicar
    RTFM!
    Ide подсвечивает такие опечатки, но реально на них можно напороться только при исполнение кода

    Про линтеры выше написали, а я добавлю: PyCharm позволяет просмотреть список всех наденных проблем (errors, warnings) в проекте. Если он не пустой - значит, надо чинить.
    Ответ написан
  • Бот на python/telebot не приветствует новых пользователей, что не так?

    Vindicar
    @Vindicar
    RTFM!
    А почему ты вызываешь bot.polling()? Это для асинхронных ботов, а твой синхронный. Используй infinity_polling().
    Вообще, читай официальные примеры, вроде вот этого, и сравнивай со своим кодом.
    Ответ написан