• Отличается ли мультипроцессинг от запуска нескольких программ?

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

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

    В первом случае всё придётся писать самому, что и плюс, и минус.
    Ответ написан
    Комментировать
  • Как ловить статус и от этого выводить результат?

    Vindicar
    @Vindicar
    RTFM!
    Вместо строки возвращай кортеж или словарь. Короче, структуру данных.
    from typing import NamedTuple
    
    class Result(NamedTuple):
        text: str  # текст запроса
        success: bool  # успешен ли запрос
        status: str  # статус
    
    async def check_text(text: str) -> Result:
        url = f'https://сайт.com/?query={text}'
    
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if response.status != 200:
                    return Result(text=text, success=False, status='Не удалось определить результат')
                html = await response.text()
                soup = BeautifulSoup(html, 'html.parser')
                status_element = soup.find('div', class_='table-block')
                if not status_element:
                    return Result(text=text, success=False, status='Не удалось определить результат')
                status_text = status_element.get_text().strip()
                # тебе нужно будет решить, когда запрос был успешен (True), а когда нет (False)
                if "ok" in status_text:
                    return Result(text=text, success=True, status='Можно')
                elif "no" in status_text:
                    return Result(text=text, success=False, status='Данный вариант недоступен')
                elif "no1" in status_text:
                    return Result(text=text, success=True, status='Можно под заказ')
                else:
                    return Result(text=text, success=False, status='Неизвестно')

    Тогда можно будет анализировать результат просто:
    result = await check_text(text)
    if result.success:
        ...  # реагируем на успешный запрос
        logger.info('%s: %s', result.text, result.status)
    else:
        ...  # реагируем на неудачный запрос
        logger.info('%s: %s', result.text, result.status)
    Ответ написан
  • Не могу исправить проблему, бот не может отправить сообщение по нажатии кнопки?

    Vindicar
    @Vindicar
    RTFM!
    Ну твоя проблема уже тут:
    @bot.callback_query_handler(func=lambda call: True)

    Ты говоришь боту "вызывай эту функцию всякий раз, когда пользователь нажимает кнопку"(callback_query_handler), и добавляешь "неважно, какая кнопка была нажата" (func=lambda call: True).
    Поэтому у тебя callback() будет вызываться при нажатии ЛЮБОЙ кнопки.

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

    Т.е. тебе нужно написать такие фильтры, которые смогут разделить нажатия отдельных кнопок.
    Простой способ это сделать - реализовать иерархию в callback_data, например так:
    # обрабатываем то, что начинается с 'city.'
    @bot.callback_query_handler(func=lambda call: call.data.startswith('city.'))
    def callback(call):
        city = call.data[len('city.'):]  # отрезаем префикс 'city.'
        if city == 'istanbul':
            bot.send_message(call.message.chat.id,'Вы выбрали город: Стамбул')
        elif city == 'moscow':
            bot.send_message(call.message.chat.id,'Вы выбрали город: Москва')
        else:
            bot.send_message(call.message.chat.id,'Я не знаю такого города')

    А до этого ты где-то в другом обработчике послал сообщение с клавиватурой вида
    keyboard = types.InlineKeyboardMarkup()
    # обрати внимание, callback_data всегда начинается с 'city.'
    keyboard.add(types.InlineKeyboardButton('Стамбул', callback_data='city.istanbul'))  
    keyboard.add(types.InlineKeyboardButton('Москва', callback_data='city.moscow'))

    Так ты можешь разделить обработчики для разных наборов кнопок.

    Еще советую почитать про FSM.
    Ответ написан
  • Почему происходит «Сайт XXX выполнил переадресацию слишком много раз» и как исправить ошибку «the STRING opcode argument must be quote»?

    Vindicar
    @Vindicar
    RTFM!
    ganstar565, внезапно, зависит от браузера. Например, гугл "firefox cookie storage format" даёт такой ответ:
    Cookies in Firefox are stored in an SQLite format database found in the file cookies.sqlite in the currently-active user profile directory (exact path is system-dependent).

    Иными словами, смотришь папку %APPDATA%\Mozilla\Firefox\Profiles, в ней каждый подкаталог - профиль браузера, часто один, но может быть несколько. Внутри подкаталога лежит файл cookies.sqlite.
    Путь можно сконструировать с помощью os.path.expandvars() (и модуля os.path в целом), файл открыть стандартным модулем sqlite3, а дальше смотри что внутри таблицы moz_cookies.
    Для остальных браузеров по аналогии - гугл, потом эксперименты.
    Ответ написан
    9 комментариев
  • Почему появляется ошибка «Процесс не может получить доступ к файлу»?

    Vindicar
    @Vindicar
    RTFM!
    with open(filename, 'rb') as file:
        media = MediaFileUpload(
            filename, chunksize=1024 * 1024,
            mimetype=message.document.mime_type, resumable=True)
        request = service.files().create(
            body=metadata, media_body=media)
        file.close()

    Обрати внимание, что MediaFileUpload не использует объект file.
    Поэтому абсолютно не принципиально, как и когда ты закрываешь файловый объект самостоятельно.
    Либо поищи способ отправить файл, используя уже заданный объект, либо читай как корректно закрыть MediaFileUpload. Можешь попробовать media.stream.close(), но я фз можно ли это делать, и если да то когда.
    Ответ написан
    Комментировать
  • Как передать вложенную структуру в функцию?

    Vindicar
    @Vindicar
    RTFM!
    Правильнее будет void func(const Test2& buff){} если ты не собираешься изменять структуру внутри функции. В этом случае будет передана не копия структуры, а ссылка на оригинал, что будет быстрее. Если собираешься изменять, и тебе нужно передать изменения "наружу" func(), убери const.
    Ответ написан
    1 комментарий
  • Как исправить ошибку чтения аргумента?

    Vindicar
    @Vindicar
    RTFM!
    __getattribute__() вызывается ДО проверки содержимого __dict__. В большинстве случаев нужен __getattr__().
    А вообще, что ты пытаешься сделать?
    Ответ написан
    3 комментария
  • Можно ли оптимизировать этот код?

    Vindicar
    @Vindicar
    RTFM!
    Можно, если сделать допущение, что текст кодируется посимвольно, а не группами из N символов.
    open_text = 'текст'  # открытый текст
    
    # letters - именно строка, одна позиция - один символ
    letters = ''.join(['а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф',
           'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я'])
    key = 5  # ключ к шифру - величина сдвига. Может быть >0 или <0
    # генерируем таблицы подстановки
    encrypt_table = str.maketrans(letters, letters[key:]+letters[:key])  # для шифрования
    decrypt_table = str.maketrans(letters, letters[-key:]+letters[:-key])  # для дешифрования
    
    cypher_text = open_text.translate(encrypt_table)
    restored_text = cypher_text.translate(decrypt_table)
    
    print(open_text)
    print(cypher_text)
    print(restored_text)
    Ответ написан
    Комментировать
  • Как получить url страницы и какие есть способы изменять html код через python?

    Vindicar
    @Vindicar
    RTFM!
    Ты упускаешь из виду, что современные страницы часто набиты скриптами, да и банальную необходимость авторизации на сайте. Иными словами, если ты через requests запросишь тот же URL, далеко не факт что ты получишь ту же самую страницу. Тут нужно само содержимое страницы вытаскивать. А оно может быть большое, так что лучше уж выбранный текст.
    Это проще всего сделать через браузерное расширение. Альтернатива - добавить окошко/иконку на панель задач/в трей, куда можно будет перетащить выделенный текст.
    Ответ написан
    Комментировать
  • Как нарисовать картинку имея координаты точек?

    Vindicar
    @Vindicar
    RTFM!
    Если хочется turtle, то она позволяет поднимать/опускать перо перед перемещением.
    Можно заполнить значениями массив numpy, а потом вывести с помощью matplotlib:
    import numpy
    import matplotlib.pyplot as plt
    
    with open('data.txt', 'rt') as src:
        src.readline()  # пропускаем заголовок
        points = numpy.array([
            [int(v) for v in row.split(';')] 
            for row in src
        ])
    width = points[:, 0].max()
    height = points[:, 1].max()
    image = numpy.array((height, width), dtype=numpy.uint8)
    for x, y, c in points:
        image[y, x] = c
    
    plt.imshow(image, cmap='gray')
    plt.show()

    Ну или как посоветовали выше, записать данные в SVG.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы файл python получил доступ к редактированию и созданию файлов на диске C?

    Vindicar
    @Vindicar
    RTFM!
    Не сохранять в Program Files. Для файлов с данными есть каталог пользователя, скажем, AppData/Roaming или AppData/Local.
    Ответ написан
  • Правильная и красивая замена if?

    Vindicar
    @Vindicar
    RTFM!
    В комментариях уже написали простое решение, а я его чуток разовью.

    import typing as tp
    
    Func = tp.Callable[[], None]  # функция без апарметров, возвращает None
    
    class FuncMap:
      def __init__(self):
        self.map: tp.Dict[str, Func] = dict()
    
      def register(self, key: str) -> tp.Callable[[Func], Func]:
        def decorate(f: Func) -> Func:
          self.map[key] = f
          return f
        return decorate
      
      def get(self, key: str) -> Func:
        return self.map[key]
      
      def run(self, key: str):
        return self.map[key]()
    
    # а вот так этот класс используется
    fmap = FuncMap()
    
    @fmap.register('11')
    def test():
      print('This is test()')
    
    fmap.run('11')
    Ответ написан
    2 комментария
  • Почему сайт не грузит requests, bs4?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, нет заголовка "user", есть "User-Agent".
    Во-вторых, сайт может проверять и другие заголовоки. Попробуй скопировать заголовки запроса из браузера.
    В-третьих, сайт может подтягивать контент скриптами. В этом случае может быть практичнее посмотреть, какие запросы делают скрипты, и имитировать уже их. Там с высокой вероятностью JSON, который куда удобнее загружать.
    Ответ написан
    Комментировать
  • Как создать connection_pool асинхронно, но в отдельном модуле, чтобы затем использовать его в dp.message_handler для работы с БД асинхронно?

    Vindicar
    @Vindicar
    RTFM!
    Так не получится, потому что кто кого импортировать будет? Поймаешь циклический импорт.
    Можно проще.
    # handlers.py
    def setup(dp, pool):
        # внутри setup уже объявляешь обработчики
        @dp.message_handler(content_types=['text'])
        def some_handler(message: types.message):
            ...
    
    # main.py
    connection_pool = await create_asyncpg_connection_pool()
    dp = ...
    
    import handlers
    handlers.setup(dp, connection_pool)  # вызывать строго один раз!
    Ответ написан
  • Возможно ли закрыть файл.ini на python?

    Vindicar
    @Vindicar
    RTFM!
    Откуда у тебя приходит переменная config? Где она ещё используется?
    read() будет дочитывать данные в текущее состояние конфига, не сбрасывая его в ноль перед чтением.
    Не экономь, создавай отдельный экземпляр парсера на каждый файл.

    Ну и да, база данных в ini? Лучше не надо. sqlite не настолько сложен.
    Ответ написан
    Комментировать
  • Не происходит on_connect сообщения, что делать?

    Vindicar
    @Vindicar
    RTFM!
    async def on_connect(self):
            if self.persistents_views_added:
               retrun


    retrun? Может, всё-таки return?
    Ответ написан
  • Как узнать почему не работает vpn wireguard?

    Vindicar
    @Vindicar
    RTFM!
    IP forwarding настроить не забыл?
    Без этого VPN сервер не будет пробрасывать пакеты дальше в интернет.
    Ответ написан
  • Почему он выдает interrupt exception, который не ловится?

    Vindicar
    @Vindicar
    RTFM!
    Потому что вызов thread.start() который внутри start_listen() - не блокирующий. Главный поток продолжит работу, выйдет из try-except и завершится, так что на момент возникновения KeyboardInterrupt он уже будет завершён. Твой поток не помечен как daemon, поэтому интерпретатор продолжит работу (был бы помечен - программа бы завершилась тут же).
    Если ты делаешь join() - то пока запущенный поток не закончится, главный не продолжит работу.

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

    Vindicar
    @Vindicar
    RTFM!
    Очевидно, надо в каждом словаре найти значение, которое уникально идентифицирует соединение.
    Я бы сказал, это пара IP:порт удаленного узла (с которым установлено соединение).
    Не уверен, будет ли эта информация в словаре, так как ты не озаботился привести пример, и как это будет работать с UDP (где формальных соединений нет), но попытаться можно.
    Ответ написан