• Почему телеграм бот (aiogram) не работает во время команды?

    drygdryg
    @drygdryg
    Python-разработчик
    Вы вызываете системную команду grep с помощью синхронной функции os.popen, из-за чего на время выполнения команды блокируется цикл событий asyncio, и ваш бот как бы зависает. Поэтому вам следует вызывать системные команды с помощью неблокирующей функции-корутины asyncio.create_subprocess_shell.
    https://stackoverflow.com/questions/63782892/using...
    Ответ написан
  • Почему телеграм бот на aiogram работает неправильно?

    drygdryg
    @drygdryg
    Python-разработчик
    Функция setRand() в вашем коде не изменяет глобальную переменную NUMBER, а лишь создаёт локальную переменную с таким же именем, перекрывающую глобальную переменную. Добавьте следующее в функцию, чтобы она изменяла значение глобальной переменной NUMBER:
    def setRand():
        global NUMBER
        NUMBER = random.randrange(10)
        print(NUMBER)


    Советую познакомиться с тем, как устроены области видимости в Python.
    Но, как упомянули в комментарии к вопросу, лучше не использовать механизм с глобальными переменными в этом коде, а найти более надёжное решение задачи. Думаю, что можно применить конечный автомат (FSM), который реализован в aiogram.
    Ответ написан
    Комментировать
  • Как реализовать команду вида /get2367 в aiogram?

    drygdryg
    @drygdryg
    Python-разработчик
    Используйте регулярные выражения и filters.RegexpCommandsFIlter. Например:
    from aiogram.dispatcher import filters
    
    
    @dp.message_handler(filters.RegexpCommandsFilter(regexp_commands=['get([0-9]+)']))
    async def send_welcome(message: types.Message, regexp_command):
        identifier = regexp_command.group(1)
        ...

    Этот обработчик будет реагировать на команды вида: /get1, /get319, /get25 и др.

    https://docs.aiogram.dev/en/latest/dispatcher/inde...
    https://github.com/aiogram/aiogram/blob/dev-2.x/ex...
    Ответ написан
    Комментировать
  • Чем ошибки отличаться от исключений?

    drygdryg
    @drygdryg
    Python-разработчик
    Объяснение из книги "Python 3 и PyQt 5. Разработка приложений":
    Исключения — это извещения интерпретатора, возбуждаемые в случае возникновения ошибки в программном коде или при наступлении какого-либо события. Если в коде не предусмотрена обработка исключения, выполнение программы прерывается, и выводится сообщение об ошибке. Существует три типа ошибок в программе:
    - синтаксические — это ошибки в имени оператора или функции, отсутствие закрывающей или открывающей кавычек и т.д. — т.е. ошибки в синтаксисе языка. Как правило, интерпретатор предупредит о наличии ошибки, а программа не будет выполняться совсем. Пример синтаксической ошибки:
    >>> print("Нет закрывающей кавычки!)
    SyntaxError: EOL while scanning string literal

    - логические — это ошибки в логике программы, которые можно выявить только по результатам её работы. Как правило, интерпретатор не предупреждает о наличии такой ошибки, и программы будет успешно выполняться, но результат её выполнения окажется не тем, на который мы рассчитывали. Выявить и исправить такие ошибки весьма трудно;
    - ошибки времени выполнения — это ошибки, которые возникают во время работы программы. Причиной являются события, не предусмотренные программистом. Классическим примером служит деление на ноль:
    >>> def test(x, y): return x / y
    >>> test(4, 2)  # Нормально
    2.0
    >>> test(4, 0)  # Ошибка
    Traceback (most recent call last):
      File "<pyshell#4>", line 1, in <module>
        test(4, 0)
      File "<pyshell#2>", line 1 in test
        def test(x, y): return x / y
    ZeroDivisionError: division by zero

    Необходимо заметить, что в Python исключения возбуждаются не только при возникновении ошибки, но и как уведомление о наступлении каких-либо событий. Например, метод index() возбуждает исключение ValueError, если искомый фрагмент не входит в строку:
    >>> "Строка".index("текст")
    Traceback (most recent call last):
      File "<pyshell#5>", line 1 , in <module>
        "Строка".index("текст")
    ValueError: substring not found

    Ответ написан
  • TKinter При нажатии на кнопку ничего не происходит. Как это исправить?

    drygdryg
    @drygdryg
    Python-разработчик
    Когда вы нажимаете на одну из трёх кнопок, вызывается соответствующая функция, которая изменяет глобальную переменную choice. Если вы хотите, чтобы после нажатия кнопки оглашался результат, вынесите логику определения исхода игры в отдельную функцию и вызывайте её в обработчиках кнопок. Простейшее решение проблемы может выглядеть так:
    spoiler

    import random
    from tkinter import *  
    
    
    window = Tk()
    
    textgame = "Давай играть! Выбирай:\nКамень,\nНожницы,\nБумага.\n"
    choiceC = random.choice(['Камень', 'Ножницы', 'Бумага'])
    choice = "none"
    
    
    lblr = Label(window, text="test", font=("Arial Bold", 15))
    lblr.grid(column=1, row=2)
    
    
    def win():
      global choiceC
      lblr.configure(text=choiceC + "." + " Вы победили!")
    
    
    def lose():
      global choiceC
      lblr.configure(text=choiceC + "." + " Вы проиграли!")
    
    
    def announce_outcome():
      """Определяет исход игры"""
      if choice =="Камень" and choiceC =="Ножницы":
        win()
      elif choice =="Ножницы" and choiceC =="Бумага":
        win()
      elif choice =="Бумага" and choiceC =="Камень":
        win()
      elif choice =="Камень" and choiceC =="Бумага":
        lose()
      elif choice =="Ножницы" and choiceC =="Камень":
        lose()
      elif choice =="Бумага" and choiceC =="Ножницы":
        lose()
      elif choice == choiceC:
        print("\n",choiceC + "." + " Ничья!")
    
    
    def clickedRock():
      global choice
      choice = "Камень"
      announce_outcome()
    
    
    def clickedScissors():
      global choice
      choice = "Ножницы"
      announce_outcome()
    
    
    def clickedPaper():
      global choice
      choice = "Бумага"
      announce_outcome()
    
    
    window.title("Rock, scissors, paper with graphics")
    window.geometry('400x250')
    
    lbl = Label(window, text=textgame, font=("Arial Bold", 15))
    lbl.grid(column=1, row=0)
    
    btnr = Button(window, text="Камень", command=clickedRock)
    btnr.grid(column=0, row=1)
    
    btns = Button(window, text="Ножницы", command=clickedScissors)
    btns.grid(column=1, row=1)
    
    btnp = Button(window, text="Бумага", command=clickedPaper)
    btnp.grid(column=2, row=1)
    
    window.mainloop()

    Ответ написан
    Комментировать
  • Atom -- Произошла ошибка при создании дочернего процесса.?

    drygdryg
    @drygdryg
    Python-разработчик
    Сначала попробуйте переустановить пакет python-is-python3:
    sudo apt update
    sudo apt upgrade
    sudo apt install --reinstall python-is-python3

    Если это не поможет, то просто вручную создайте ссылку на /usr/bin/python3:
    cd /usr/bin
    sudo ln -s python3 python
    Ответ написан
    Комментировать
  • Как aiogram боту взять даные из pyrogram юзербота?

    drygdryg
    @drygdryg
    Python-разработчик
    ConnectionError: Client has not been started yet

    Вы получаете ошибку (очевидно, внутри функции get_chat_name), которая говорит о том, что клиент Pyrogram не запущен. Вы должны запустить клиент, прежде чем вызывать методы Telegram API, после чего его можно остановить. Это можно сделать с помощью менеджера контекста async with:
    app = Client("creehk24", parse_mode=ParseMode.HTML)
    
    def get_chat_name(chat_id)
        async with app:
            chat = await app.get_chat(chat_id)
        if chat.type == ChatType.PRIVATE:
            return f'{chat.first_name} {chat.last_name}'
        else:
            return chat.title

    или с помощью Client.start() и Client.stop():
    app = Client("creehk24", parse_mode=ParseMode.HTML)
    
    def get_chat_name(chat_id)
        await app.start()
        chat = await app.get_chat(chat_id)
        await app.stop()
        if chat.type == ChatType.PRIVATE:
            return f'{chat.first_name} {chat.last_name}'
        else:
            return chat.title
    Ответ написан
  • Как подключится к WiFi в debian без графической оболочки?

    drygdryg
    @drygdryg
    Python-разработчик
    Убедитесь, что iwd установлен (iwctl — это его часть):
    $ apt show iwd
    Для Linux на данный момент существует два актуальных универсальных сервиса Wi-Fi: wpa_supplicant и iwd. Они взаимозаменяемы.
    Если в системе нет iwd, и его проблематично установить, то попробуйте настроить Wi-Fi соединение через wpa_supplicant.
    Ответ написан
    2 комментария
  • Как сделать аргумент с пробелами в Aiogram?

    drygdryg
    @drygdryg
    Python-разработчик
    Используйте метод str.split() с параметром maxsplit=1:
    @dp.message_handler(commands=['r'])
    async def r(message: types.Message):
        args = message.get_args().split(maxsplit=1)
        if len(args == 2):
            user_id, msg = int(args[0]), args[1]
            await dp.bot.send_message(user_id, msg)
    Ответ написан
    8 комментариев
  • Как передать часть массива в переменную?

    drygdryg
    @drygdryg
    Python-разработчик
    y — это строка, у неё нет атрибута parts.
    Но если вы имели в виду список parts, то можете.
    Также в качестве альтернативного варианта можно создать сразу несколько переменных для каждого элемента списка parts, используя т.н. распаковку, переменная parts в таком случае не понадобится:
    def get_next_hostname(hostname):
        for vm in asl_vms:
            hostname = vm['name']
            service, x, name = hostname.split('-')
            number = int(name.split('.')[0])
            y = '{}-{}-{}.node.eu.consul'.format(service, x, number + 6)
        return y, service

    Но обратите внимание, что такой вариант распаковки hostname.split('-') вы можете использовать только в том случае, если уверенны, что в результате разбиения строки получается список именно из трёх элементов — не больше и не меньше.
    Ответ написан
    Комментировать
  • JS в Python или как сделать простейшее API?

    drygdryg
    @drygdryg
    Python-разработчик
    Можно попробовать исполнить скрипт во встраиваемом интерпретаторе JavaScript Duktape. Для него есть Python-биндинги:
    https://github.com/amol-/dukpy
    https://github.com/stefano/pyduktape
    Ответ написан
    1 комментарий
  • Почему видает ошибку с ChatJoinRequest?

    drygdryg
    @drygdryg
    Python-разработчик
    Тип ChatJoinRequest появился в версии Telegram Bot API 5.4. Вам нужно обновить aiogram, как минимум, до версии 2.16 для поддержки Bot API v5.4:
    pip install --upgrade aiogram
    Ответ написан
  • Как преобразовать значение при использовании dataclass?

    drygdryg
    @drygdryg
    Python-разработчик
    Возможно, вам стоит использовать Pydantic вместо dataclasses для этого: он позволяет создавать пользовательские валидаторы как отдельного поля, так и всех полей. Валидаторы можно использовать для преобразования типов данных. Что важно, он позволяет создавать пре-валидаторы, то есть те, которые будут применяться к полю перед стандартными валидаторами Pydantic. Например, вашу задачу можно решить так:
    from datetime import date, datetime
    
    from pydantic import BaseModel, validator
    
    
    class Person(BaseModel):
        first_name: str
        last_name: str
        bdate: date
    
        @validator('bdate', pre=True)
        def bdate_from_string(cls, v):
            if isinstance(v, str):
                return datetime.strptime(v, '%Y%m%d').date()
            return v
    
    
    data = {
        'first_name': 'Adam',
        'last_name': 'Smith',
        'bdate': '20220617'
    }
    
    person = Person(**data)
    print(person)


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

    drygdryg
    @drygdryg
    Python-разработчик
    Для гибкого управления запускаемым процессом ffmpeg можно использовать модуль subprocess.
    Также можно использовать pythonic-обёртку для ffmpeg — ffmpeg-python.

    Если вы захотите использовать subprocess, то вывод ffmpeg (stderr, stdout по отдельности либо вместе взятые) можно отключить, например, так, либо передав аргумент -loglevel quiet в ffmpeg.
    Ответ написан
  • Сильно ютуб грузит процессор и почему?

    drygdryg
    @drygdryg
    Python-разработчик
    Для решения проблемы можно использовать сторонний видеоплеер для воспроизведения видео вне браузера — на устаревших машинах это обычно позволяет смотреть потоковое видео в разрешении 720p, в то время, когда в браузере такое разрешение воспроизводится с "заиканиями".
    Можно использовать как и "голый" mpv в связке с yt-dlp/youtube-dl, так и полноценные GUI-приложения: SMPlayer + SMTube либо Minitube, а также GTK YouTube viewer (использует YouTube API в отличие от предыдущих).
    Ответ написан
    2 комментария
  • Как отменить экранирование в python?

    drygdryg
    @drygdryg
    Python-разработчик
    Просто добавьте ещё один обратный слэш:
    if '/' not in msg.text or '\\' not in msg.text or '|' not in msg.text:

    или используйте "сырую" строку (raw string) — интерпретатор не будет обрабатывать экранирующие символы внутри неё:
    if '/' not in msg.text or r'\' not in msg.text or '|' not in msg.text:
    Ответ написан
    Комментировать
  • Как получить JSON в FLASK?

    drygdryg
    @drygdryg
    Python-разработчик
    Создайте маршрут, который будет принимать POST-запросы и ожидать тело запроса в формате JSON. Например, так:
    from flask import Flask, request
    
    app = Flask(__name__)
    
    ...
    
    @app.route('/res', methods=['POST'])
    def res():
        form_data = request.get_json()
        ...
        return {'status': 'ok', 'error': False}
    Ответ написан
  • Как данные с одного столбца вставить/раскидать в нужное мне количество столбцов в новом файле?

    drygdryg
    @drygdryg
    Python-разработчик
    Если столбец представлен в виде списка, то есть несколько способов — смотрите https://datagy.io/python-split-list-into-chunks/
    Ответ написан
    Комментировать
  • Как сделать, чтобы каждый раз, через заданное мной число операций цикла for выполнялся другой код?

    drygdryg
    @drygdryg
    Python-разработчик
    Можно использовать оператор деления с взятием остатка (%), чтобы определить, является ли номер текущей итерации цикла кратным девяти:
    for i in range(30):
        print(i)
        if i % 9 == 0:
            print('Какая-нибудь надпись')

    Если i делится на 9 без остатка, то i кратна девяти.
    Ответ написан
    Комментировать
  • Откуда берется html код на сайте при парсинге python3?

    drygdryg
    @drygdryg
    Python-разработчик
    Скорее всего, вы столкнулись с динамическим сайтом.
    Отдельные части HTML-страницы могут формироваться на стороне клиента (браузера) с использованием скриптов на языке JavaScript. Такие страницы и сайты называются динамическими. На динамическом сайте после загрузки страницы браузером содержимое в ней может изменяться посредством AJAX-запросов и изменением дерева HTML средствами JavaScript (см. DOM) — то есть на таких сайтах содержимое частично или полностью генерируется на стороне клиента.
    Чтобы скрапить динамические страницы (что вы, вероятно, ошибочно называете парсингом) с использованием Python, вам потребуется полноценный браузер с JavaScript-движком, управляемый из вашей программы. В Python для автоматизации использования браузеров можно применить один из этих инструментов: Selenium, Pypeteer или Playwright.
    Очень часто можно применить другой подход, не прибегая к использованию браузера с JavaScript-движком. Заключается он в том, чтобы, используя вкладку "Network" в DevTools (инструменты разработчика, открываются по нажатию F12), найти нужные AJAX-запросы, которые генерируются странцей, и воспроизвести их в вашем Python-коде, и таким образом получить необходимые данные с сайта, вообще не прибегая к разбору HTML. Нередко в качестве формата сериализации AJAX-запросов используется JSON, с ним не составит труда работать из Python.
    Ответ написан