Ответы пользователя по тегу Python
  • Как запускать метод каждую минуту?

    Vindicar
    @Vindicar
    RTFM!
    Ответ зависит от целого ряда факторов.
    1. Должна ли программа делать что-то ещё? Если да, то что именно?
    2. Сколько таких периодических методов будет существовать? Строго один, или может быть более? Должны ли у них быть разные периоды?

    Если программа синхронная, и метод только один, то можно использовать простой приём:
    import time
    
    stop = False
    def proc_to_call():
      global stop
      #Это твой периодический вызов
      #когда нужен останов, делаешь stop = True
      pass
    
    while not stop:
      time.sleep(60)
      proc_to_call()
    #код после цикла выполнится только после прерывания цикла.


    Если вызовов несколько и с разной периодичностью, то лучше использовать пакет schedule. Но у тебя всё равно будет бесконечный цикл вида
    while True:
        schedule.run_pending()
        time.sleep(1)

    И пока программа крутится в этом цикле, она не будет делать ничего другого.

    Если тебе нужно делать что-то параллельно с периодическим вызовом, то дело усложняется.
    Если твоя программа синхронная, то тебе потребуется отдельный поток выполнения.
    import threading
    
    class MyJob(threading.Thread):
      def __init__(self):
        super().__init__(self)
        self.stop = threading.Event()
    
      def proc_to_call(self):
        #Это твой периодический вызов
        pass
      
      def run(self):
        while not self.stop.wait(60):
          self.proc_to_call()
    
    job = MyJob()
    job.start()
    #код основного потока продолжает выполняться после этого
    #когда нужен останов, делаешь 
    job.stop.set() #сигналим об останове
    job.join() #ждём завершения потока

    Почему использую Event вместо простой логической переменной и time.sleep()? Потому что в случае с time.sleep() тебе придётся ждать конца минуты, прежде чем поток снова проверит логический флаг и поймёт, что пора останавливаться. А при использовании Event его установка тут же прервёт ожидание - и выйдет из цикла.

    А если твоя программа асинхронная, то всё упрощается, так как корутины уже могут чередовать своё выполнение, выполняясь "как бы параллельно". Можно использовать как schedule, так и простой цикл, просто не забывай использовать await asyncio.sleep() вместо time.sleep().
    Ответ написан
    3 комментария
  • Неправильное поведение Thread с target=lambda?

    Vindicar
    @Vindicar
    RTFM!
    У тебя в первом случае тело потока (лямбда) захватывает через замыкание не значение i, а ссылку на i.
    К моменту старта в первом случае i будет иметь другое значение.
    Вот почему нужно использовать args - как во-втором случае. Тогда происходит захват значения - не через замыкание, а через параметр.
    Ответ написан
    4 комментария
  • Не работает многопоточность?

    Vindicar
    @Vindicar
    RTFM!
    Thread(target=egz_checkden(), args=())

    Когда уже погромисты научатся различать результат вызова функции (со скобками) и ссылку на функцию (без скобок).
    У тебя сейчас Питон пытается выполнить egz_checkden(), чтобы получить её возвращаемое значение и использовать его в качестве target.

    И да, у тебя в egz_checkden() бесконечная рекурсия, пусть и медленная. Вылетит с переполнением стека, хотя и не сразу. Не делай так, используй нормальный цикл.
    Ответ написан
    4 комментария
  • Не получается сделать так, чтобы когда я писал !role @nick выдавалась роль. Чтобы я не писал, она выдаётся мне. И да, я чайник :)?

    Vindicar
    @Vindicar
    RTFM!
    member = ctx.message.author
    role = discord.utils.get(member.guild.roles, name='Egg')
    await member.add_roles(role)

    Сначала получаешь автора сообщения (т.е. отправителя команды), потом выдаёшь ему роль, потом удивляешься почему так.
    (К слову, а зачем делать это командой? через интерфейс дискорда в разы быстрее).

    Ну собственно,
    async def role(ctx):
    Ты вообще параметры у команды не принимаешь.
    Сделай так:
    async def role(ctx, target: discord.Member):
    Тогда discord.py попытается распарсить переданный аргумент как пользователя.
    Ответ написан
  • Как сделать запись в бд после обращения к ней?

    Vindicar
    @Vindicar
    RTFM!
    cur.execute(f'SELECT cal FROM {usern} ')
    (cal,) = cur.fetchone()
    Ты выбрал одну строку и не закрыл курсор. Может, дело в этом?
    Ответ написан
  • Как исправить декодировку json python?

    Vindicar
    @Vindicar
    RTFM!
    Значит, в файле cookies.txt не корректный JSON. Возможно, он вообще пуст?
    Ответ написан
    1 комментарий
  • Как исправить ошибку AttributeError: module 'telebot.types' has no attribute 'User'?

    Vindicar
    @Vindicar
    RTFM!
    > C:\Users\HOME\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\telebot\types.py

    Ставил через pip install telebot? Поздравляю, ты поставил не тот пакет. Тебе вместо него нужен пакет pyTelegramBotAPI. Да, их два. Да, оба импортируются как telebot. Да, это тупо. Просто надо быть внимательнее, когда ставишь зависимости.
    Ответ написан
  • Как интерпретировать JavaScript при запросе requests?

    Vindicar
    @Vindicar
    RTFM!
    Никак. requests не для этого предназначен. Тебе нужен полноценный браузер, и код для управления им.
    Т.е. пакет selenium.

    EDIT: AlexBoss ниже правильно заметил - если сайт не слишком старается отсеивать ботов, то можно попробовать идентифицировать запросы, через которые выполняется подгрузка интересующих частей страницы, и выполнить их самому. Это позволит обойтись силами только requests, но это не всегда легко сделать.
    Ответ написан
    Комментировать
  • Какая-то проблема с кодом, поможете?

    Vindicar
    @Vindicar
    RTFM!
    Включить голову. Твой код, по сути, делает ровно то, что ты от него просишь:
    1. Если сообщение в личку, то в зависимости от слова, скинуть ту или иную фотку. Если не одно слово не подошло, то ничего не делать.
    2. Если сообщение не в личку, ответить, что на групповые сообщения не отвечает.

    Т.е. он всегда будет реагировать на не-личные сообщения по else. Не нравится? Убери этот else вместе со всем содержимым.
    Ну и да, основные алгоритмические конструкции.
    Ответ написан
    Комментировать
  • Парсинг стоимости инвентаря Steam CS:GO?

    Vindicar
    @Vindicar
    RTFM!
    Очень странный код. А зачем ты вообще используешь create_task() и gather()?
    create_task() имеет смысл, если хочешь вызвать корутину так, чтобы она выполнялась независимо от вызывающей.
    gather() имеет смысл, если у тебя НЕСКОЛЬКО корутин, и ты хочешь выполнить их параллельно, а потом дождаться, когда все выполнятся.

    А в твоём случае должно быть достаточно
    xxx = await get_inventory(steam_id)

    Далее, зачем у тебя get_quantity() вызывается асинхронно, да еще и опять через create_task()?
    Она не выполняет никакого ввода-вывода, да и ЦПУ не особо загрузит, оставь её синхронной и вызывай как обычно.

    Далее, ты используешь в куче синхроную requests и асинхронную aiohttp. Выбери что-нибудь одно? Я бы остановился на aiohttp, раз уж аснихронный код пишешь.

    В общем, проще переписать, чем исправить...
    Ответ написан
    Комментировать
  • Мой exe файл некорректно передаётся, что делать?

    Vindicar
    @Vindicar
    RTFM!
    что значит "текстовый файл передаётся нормально"? Ты первые 2048 байт при приёме выбрасываешь же.
    Ответ написан
    2 комментария
  • Библиотека threading - обратная совместимость?

    Vindicar
    @Vindicar
    RTFM!
    Как будешь параллелить выполнение CPU-bound задач?
    Ответ написан
  • Как создать базу данных sqlite3 для всех серверов на которые есть бот discord.py?

    Vindicar
    @Vindicar
    RTFM!
    Не проще ли включить id сервера в соответствующие таблицы?
    Т.е. у каждого пользователя будет составной id: свой id + id сервера. Аналогично с ссылками на этого пользователя.
    Потому что создавать отдельную БД на каждый сервер довольно муторно - и не очень ясно, какая от этого выгода.
    Ответ написан
    1 комментарий
  • Можете помочь с пониманием кода?

    Vindicar
    @Vindicar
    RTFM!
    > Я так понимаю, что должно работать как-то так:
    > @vcl.on('привет', "здравствуй")
    > def hello(text):

    Неправильно понимаешь. Это могло бы сработать, если бы ты передал
    @vcl.on(['привет', "здравствуй"]) #обрати внимание на список!
    Тогда, совместно с твоим предложением по изменению on(), сработало бы. Это один способ.

    Однако ты не обратил внимание вот на какой вариант:
    @vcl.on('привет')
    @vcl.on("здравствуй")
    def hello(text):

    Это тоже должно сработать! Список имеет смысл, если ты загружаешь этот список откуда-то, а не записываешь его как константу в коде скрипта.

    А вообще я бы посоветовал использовать регулярные выражения. Примерно так:
    import re
    #.............................................
        def on(self, condition):
            if isinstance(condition, re.Pattern):
                predicate = lambda text: condition.match(text)
            elif isinstance(condition, str):
                condition = condition.lower()
                predicate = lambda text: condition in text
            elif callable(condition):
                predicate = condition
            else:
                raise TypeError('Condition must be either string or function!')
    
            def decorator(command_func):
                self.actions.append((predicate, command_func))
                return command_func
    
            return decorator

    Для пущего удобства можно исправить метод run_command(), чтобы обработчику команды был доступен результат сопоставления.
    def run_command(self, text):
            text = text.lower()
            for predicate, command in self.actions:
                res = predicate(text) #сохраняем результат
                if res:
                    try:
                        response = command(text, res) #теперь обработчик принимает два аргумента!
                        if response is None:
                            response = "Команда выполнена"
                        else:
                            response = str(response)
                    except Exception as err:
                        response = "Ошибка при выполнении команды"
                        print(err)
                    if response:
                        m.say_message(response)
                    break
            else:
                m.say_message("Неизвестная команда")


    И пример использования будет примерно таким:
    #нужно знать синтаксис регулярных выражений
    #совпадёт с любой строкой, начинающейся строго со слов "скажи" или "произнеси"
    #всё что после этих слов попадёт в отдельную группу 1.
    @vcl.on(re.compile('^(?:скажи|произнеси) (.+)$', re.I)) 
    def hello(text, match): #все обработчики будут принимать два аргумента!
        #match будет содержать результат сопоставления входной строки с регуляркой
        #group(1) будет содержать то, что оказалось на месте (.+)
        return match.group(1) #пусть бот повторит то, что мы попросили его сказать
    Ответ написан
    Комментировать
  • Как можно ускорить код?

    Vindicar
    @Vindicar
    RTFM!
    Лобовой ответ - фоновый шум есть? Может, Recognizer его принимает за речь, и думает что ты все эти несколько минут говоришь.
    В параметрах метода listen() есть кое-что интересное, почитай.
    Ответ написан
  • Как считывать данные из базы данных в sqlite с помощью python?

    Vindicar
    @Vindicar
    RTFM!
    Потому что нужно читать документацию, там на первой же паре страниц есть примеры кода, в том числе запрос SELECT.

    Что ты вообще ожидаешь получить вызовом str(cursor.execute), если ты знаешь, что cursor.execute() - это метод?
    И почему ты игнорируешь возвращаемое им значение, когда выполняешь запрос?

    Короче, ещё раз - читай доки. Они полезные.
    for row in cursor.execute('SELECT bdname FROM user_city'):
            print(row)
    Ответ написан
    Комментировать
  • Каким модулем распознавать речь на python?

    Vindicar
    @Vindicar
    RTFM!
    Ну есть вот такой проект с открытыми исходниками, на титульной странице приведён их стек технологий.
    Ответ написан
    Комментировать
  • Почему не получается перенести текст с блока в текстовый документ?

    Vindicar
    @Vindicar
    RTFM!
    Невнимательность - мать маразма. =) Ты оба файла обозвал как f.

    f = open("skinsinfo.txt", "w")
    count = 0
    i = 0
    try:
    with open('skins.txt', 'r') as f:
    Ответ написан
  • Как сравнивать две строки, имеющий разные "шрифты"?

    Vindicar
    @Vindicar
    RTFM!
    Нормализация юникода - вещь малоприятная.
    Первый термин для гугла - гомоглиф (homoglyph), т.е. символы, которые выглядят очень похоже (типа русской и латинской о). Для питона вроде есть одноименная библиотека, но я сам с ней не работал.
    Ответ написан
    Комментировать