Ответы пользователя по тегу Python
  • Что в коде не так?

    Vindicar
    @Vindicar
    RTFM!
    k = list(input())
    input() вернёт строку.
    конструирование list() на базе строки разобьёт её на одиночные символы.
    Ты что пытаешься сделать? .split()?
    Ответ написан
    1 комментарий
  • Может ли телеграм бот читать exel файл который я ему отправил?

    Vindicar
    @Vindicar
    RTFM!
    Да, можно, если речь идет о Excel (а не exel).
    Зависит от формата файла. Новый .xlsx читается довольно легко, есть библиотеки для этого,но можно и средствами стандартной библиотеки Python - это просто zip-архив с пачкой xml-файлов внутри. Выковырять данные будет не очень трудно.

    А вот старый .xls - это бинарный, плохо документированный формат. С ним будут проблемы.
    Ответ написан
    Комментировать
  • Как написать функцию чистки пользователей, которые заблокировали бота в Телеграм?

    Vindicar
    @Vindicar
    RTFM!
    Перенеси try-except внутрь цикла for, чтобы внутри try-except был только вызов bot.send_message(), и все дела.
    И зачем ты еще раз коннектишься к базе данных внутри except, у тебя ведь уже есть подключение?
    Ответ написан
    Комментировать
  • Во время произношения ассистент говорит "текст"None, как можно исправить?

    Vindicar
    @Vindicar
    RTFM!
    Что за ерунда у тебя в коде творится? Поучи азы Питона сначала, потом уже бросайся помощников писать...

    say_message("Здравствуйте, хозяин!" and "Рад снова вас видеть!")
    Как по твоему, что вот этот and должен значить? На самом деле, у тебя ВСЕГДА будет произноситься только второе выражение. and - это логический оператор в первую очередь. Его поведение для не-логических значений весьма специфическое.

    say_message("Как пожелаете"+str(right_mouse_control()))
    Оставляя за кадром вопрос "зачем", что возвращает функция right_mouse_control()? Она должна возвращать какой-то текст для произношения? Если должна, она явно этого не делает. Если не должна, то зачем ты засовываешь её возвращаемое значение в строку? Почему просто её не вызвать, вне рамок say_message()?
    То же самое для остальных вариантов ниже.

    Ну и простыня elif как вишенка на торте, да.

    EDIT: покажу, как можно это улучшить. Код сложный, но зато легко расширяется.
    Сделаем класс, который будет рулить списком известных команд и сопоставленными им фразами.
    Чтобы не пришлось повторяться, сделаем так, чтобы для добавления новой команды достаточно было
    написать функцию и задекорировать её. Пример будет ниже.
    class VoiceCommandList: #класс управляет списком голосовых команд
      def __init__(self):
        self.actions = list() #список известных классу команд
      
      def on(self, condition): #декоратор, подписывает функцию на голосовую команду
        if 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!')
        #эта функция - декоратор, она будет помечать функции-команды.
        #она описана именно внутри метода on()!
        def decorator(command_func):
          self.actions.append( (predicate, command_func) )
          return command_func
        return decorator
      
      def run_command(self, text): #функция получает строку, определяет и вызывает соотв. её команду
        text = text.lower()
        for predicate, command in self.actions:
          if predicate(text): #текст соответствует известной команде
            try:
              response = command(text) #пытаемся выполнить команду
              if response is None: #если команда не сообщила нам, что ответить
                response = "Команда выполнена" 
            except Exception as err: #не получилось
              response = "Ошибка при выполнении команды"
              print(err)
            if response: #если есть какой-то ответ
              say_message(response) #то произносим его
            break #выполняем не более одной команды за раз
        else: #этот else относится к for, не к if! Если не нашли ни одной похожей команды
          say_message("Неизвестная команда")

    А теперь примеры использования класса. Мы можем добавлять команды, описав функции. Нет нужды править длинную простыню if-elif-else
    vcl = VoiceCommandList() #экземпляр списка команд
    
    #опишем реакцию на простую строку типа "привет".
    @vcl.on('привет') #если передаём в декоратор строку - это означает, что строка должна содержаться в тексте
    def hello(text): #функция-команда принимает аргумент - сказанный пользователем текст
      return "Доброе время суток" #она должна вернуть текст, который скажет бот
    
    @vcl.on('открой оперу')
    def start_opera(text):
      operaopen() #выполняем действие
      return "Браузер запущен" #возвращаем текст ответа
    
    @vcl.on('напиши')
    def write_message(text):
      print(text)
      #если ничего не вернём, будет отклик по умолчанию
    
    @vcl.on(lambda text: ('влево' in text) and ('вправо' in text)) #можно делать сложные условия!
    def what(text):
      return "Так влево или вправо?"

    Ну а чтобы скормить боту распознанную строку:
    vcl.run_command('привет') #сюда можно подставить выхлоп распознавателя речи
    Ответ написан
    8 комментариев
  • Как реализовать запись данных пользователя в телеграм-боте на Python?

    Vindicar
    @Vindicar
    RTFM!
    Если тебе нужно реализовать сценарий, в рамках которого пользователь отправляет несколько сообщений, разбирайся с register_next_step_handler()
    Ответ написан
    Комментировать
  • Где учится созданию ботов на python?

    Vindicar
    @Vindicar
    RTFM!
    Чтобы писать ботов, в большинстве случаев достаточно знать
    1. основы языка
    2. как ставить пакеты через pip
    Также необязательно, но весьма вероятно:
    3. что такое асинхронные программы и как они работают (для ботов, которые выполняют длительные операции)
    4. основы работы с БД (для ботов, которым требуется персистентное хранилище)
    5. что такое конечный автомат и как он работает (для ботов, которые реализуют сценарий из нескоьких шагов)

    А дальше ищешь библиотеки под нужный тебе месенджер, ищешь их документацию, смотришь Quickstart, выбираешь ту, которая выглядит удобнее. Затем постепенно наращиваешь функциональность от своего quickstart-примера - определяешь нужные события/действия, ищешь как на них подписаться или какие методы им соответствуют.
    Ответ написан
    Комментировать
  • Работа с telebot. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    > color_user = message.text.lower()
    message к чему относится, по твоему?
    Оно относится к сообщению, в котором пришла команда.
    Если тебе нужно реализовать сценарий, в рамках которого пользователь отправляет несколько сообщений, разбирайся с register_next_step_handler()
    Ответ написан
    1 комментарий
  • Какой подход для фильтрации таблиц лучше?

    Vindicar
    @Vindicar
    RTFM!
    Потому что ты для каждого фильма проходишь всю таблицу рейтингов да ещё и парсишь числа каждый раз. Ещё бы оно не тормозило.
    Не проще ли для каждого фильма хранить сумму рейтингов и их количество, а потом один раз пройти таблицу рейтингов и заполнить эти хранилища?
    from collections import defaultdict
    total = defaultdict(float)
    count = defaultdict(int)
    for line in data_rating:
        total[line[1]] += float(line[2])
        count[line[1]] += 1
    
    averages = { id: total[id]/count[id] for id in count } #средние рейтинги
    #и сортируем список фильмов по убыванию рейтинга
    data_movies.sort(key=lambda item: averages.get(item[1], 0), reverse=True)
    Ответ написан
  • Почему вызов функции вызывает ошибку?

    Vindicar
    @Vindicar
    RTFM!
    > on_press = BoxOneP()
    Ты присваиваешь параметр on_press результат вызова функции BoxOneP. Которая возвращает None.

    Может, всё-таки имелось ввиду просто "on_press=BoxOneP"?

    И да, что значит "ломает приложение"? Текст ошибки со стектрейсом с студию.
    Ответ написан
    2 комментария
  • Telegram bot, не работает постоянно и выключается после запуска со словами:"process finished with exit code 0", как пофиксить?

    Vindicar
    @Vindicar
    RTFM!
    Я что-то не пойму. Документация и примеры по aiogram говорят, что бота надо выполнять вызовом executor.start_polling(), а у тебя что?
    Ответ написан
    Комментировать
  • Как записать в sql информацию через метод WHERE?

    Vindicar
    @Vindicar
    RTFM!
    INSERT не предполагает WHERE, так как создаёт новую запись в таблице.
    Если тебе нужно обновить существующую запись, используй UPDATE.
    Ответ написан
    Комментировать
  • Можно ли сделать бесконечно работающего бота телеграм?

    Vindicar
    @Vindicar
    RTFM!
    1. Как именно не работает? Приводи минимальный проблемный пример кода и полный текст ошибки (+ traceback).
    2, 3. Зависит от используемой библиотеки для общения с телеграммом. Не зная, какую ты используешь, подсказать трудно - но наверняка можно нагуглить документацию и/или примеры использования.
    Ответ написан
  • Когда требуется использовать await при вызове async функции?

    Vindicar
    @Vindicar
    RTFM!
    Следует различать вызов асинхронной функции и её выполнение.
    В твоём случае, вызов work(p) завершится немедленно (без входа в тело функции), и вернёт объект Future.
    Этот объект описывает выполняемую асинхронную операцию (ввод-вывод, выполнение функции и т.п.).
    Затем следует запланировать выполнение этого объекта в рамках цикла реактора (loop в т ерминах asyncio).
    Для этого можно использовать два способа. Если ты находишься в синхронном коде, ты должен использовать loop.create_task() (или более старую функцию, loop.ensure_future()).
    Если ты находишься в асинхронном коде, то твоя текущая функция уже завёрнута в свой собственный Future, и уже выполняется в рамках цикла реактора. Тогда ты можешь использовать await для того, чтобы "уступить место" вызываемой функции - запланировать её выполнение в рамках того же цикла, что и вызывающая функция, а вызывающую функцию приостановить до завершения выполнения вызываемой. Либо, если тебе не требуется дожидаться результата выполнения вызываемой функции, можешь также использовать первый способ.

    Таким образом, когда ты "вызываешь асинхронную функцию через await", ты на самом деле получаешь future-объект и тут же планируешь его выполнение.
    Т.е.
    X = await foo()
    будет тем же самым что
    future_X = foo()
    #future_X можно хранить, но если он будет удалён без выполнения - это даст ошибку never awaited
    X = await future_X
    Ответ написан
    Комментировать
  • Как мне сообщить пользователю в телеграмм боте, что он должен нажать на кнопки?

    Vindicar
    @Vindicar
    RTFM!
    > if message.text == 'Технология(Мальчики)':
    Имел ввиду elif? У тебя вообще довольно много elif пропущено.

    Вообще я бы посоветовал использовать словарь.
    #код неполный! вставишь эти фрагменты в свой самостоятельно
    #все задания описаны тут
    tasks = {
      'Математика': 'Параграф 4 учить РТ 3',
      #ну и так далее.
    }
    #делаем кнопки
    buttons = [types.KeyboardButton(name) for name in tasks] #по кнопке на каждое задание
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    markup.add(*buttons) #добавить все элементы списка buttons, как если бы мы написали их по одному
    
    #Проверка полученной кнопки
    if message.chat.type == 'private':
        task = tasks.get(message.text, None) #ищем текст, соответствующий кнопке
        if task is None: #не нашли
            bot.send_message(message.chat.id, 'Пожалуйста, нажми на кнопки')
        else:
            bot.send_message(message.chat.id, task)

    И никакой лестницы if-elif
    Ответ написан
    Комментировать
  • Можете объяснить как это работает?

    Vindicar
    @Vindicar
    RTFM!
    Жесть. Развернём её снаружи внутрь:
    value_mid = sum(
        value:=value[
            :[
                i for i in range(len(value)) if value[i] < 0
            ][0]
        ]
     ) /len(value)


    Снаружи сумма какого-то ряда чисел (не введённого) деленная на количество.
    Далее идёт присваивание внутри выражения (одна из новых фишек питона, по сути value переопределяется.
    Как следствие, len(value) уже будет содержать количество элементов в новом value, а не в оригинальном.
    Далее идёт срез value[:X], то есть от начала и до указанног элемента НЕ включительно.
    X это [i for i in range(len(value)) if value[i] < 0][0], то есть нулевой элемент списка, заданного выражением
    [i for i in range(len(value)) if value[i] < 0]. Это выражение будет содержать индексы всех отрицательных элементов value, соответственно X будет содержать индекс первого отрицательного элемента value.
    Тогда сумма будет считаться от начала списка и до первого отрицательного элемента (не включая), и количество тоже будет считаться также.
    Вывод: выражение считает среднее значение элементов списка от начала и до первого отрицательного элемента, и делает это через чрезвычайно хитрозакрученную задницу.
    Ответ написан
    1 комментарий
  • Какую библиотеку использовать для выполнения большого количества задач в определенное время Python?

    Vindicar
    @Vindicar
    RTFM!
    Schedule дату не учитывает. Но прямо говоря, реализовать самостоятельно не слишком сложно.
    from typing import Dict, List, Tuple, Callable
    import datetime
    import time
    
    def time_matches_mask(now: datetime.datetime, mask: Dict[str, float], delta: datetime.timedelta) -> bool:
        'Проверяем, совпало ли текущее время с заданной маской с указанной точностью'
        target = now.replace(**mask)
        return abs(now - target) < delta
    
    jobs: List[Tuple[Dict, Callable, Tuple]] = [] #Список элементов: маска, функция, аргументы
    
    def call_pending(jobs, now: datetime.datetime, delta: datetime.timedelta):
        for mask, func, args in jobs:
            if time_matches_mask(now, mask, delta):
                func(*args)
    
    jobs.append( ({'seconds':30}, print, ('Hello world!',)) ) #когда число секунд = 30, вызвать print('Hello world!')
    
    delta = datetime.timedelta(seconds=1) #с какой точностью измерять время?
    while True:
        time.sleep(1)
        call_pending(jobs, datetime.datetime.now(), delta)


    Правда, есть и тонкости. Стоит избегать вызовов 2 раза подряд из-за большой delta, можно заменить секундный цикл на ожидание до ближайшей задачи (с прерыванием, если список задач изменился). Ну и так далее.
    Ответ написан
    Комментировать
  • Почему код бота не работает на сервере?

    Vindicar
    @Vindicar
    RTFM!
    > ImageFont.truetype('arial.ttf', size=20)
    А файл со шрифтом присутствует и доступен боту?
    > f'{path}\\user_card.png'
    os.path.join() и pathlib для кого придумали? Под линуксом разделитель каталогов не \ а /.
    Ответ написан
    5 комментариев
  • Как исправить Atribute Error?

    Vindicar
    @Vindicar
    RTFM!
    Никак. 1 - это экземпляр класса int, который не поддерживает context manager protocol, т.е. не может использоваться с оператором with.
    С этим оператором могут использоваться только классы, описывающие магические методы __enter__() и __exit__().
    Ответ написан
    Комментировать
  • Как загрузить на сервер python скрипт через консоль?

    Vindicar
    @Vindicar
    RTFM!
    Если скрипт небольшой, то можно скопировать его локально, запустить в SSH-сессии простой редактор типа nano, и вставить туда. Под виндой Putty это умеет.
    Другой вариант - выложить скрипт в сеть, и скачать по прямой ссылке через wget.
    Третий вариант, пожалуй, предпочтительный - использовать scp, или вариант этой утилиты из пакета Putty (тыц)

    В любом случае вопрос не имеет отношения к Python.
    Ответ написан
    1 комментарий
  • Почему не работает ИЛИ в re python?

    Vindicar
    @Vindicar
    RTFM!
    Ты ищешь следующее:
    WHERE, за которым следует 0 или более точек, пробельных символов (в т.ч. табуляций) или табуляций, за которыми следует либо GROUP BY, либо ;

    Что именно ты пытаешься извлечь из строки?
    Ответ написан
    2 комментария