Задать вопрос
  • Как из класса из функции, перетащить значение в другой класс в функцию?

    Vindicar
    @Vindicar
    RTFM!
    Проще всего вынести переменные из локальных в экземпляр класса. А потом дописать второму классу конструктор, и передавать ссылку на первый класс. Но чтобы избежать состояний гонки (когда два потока лезут в одну переменную, и хотя бы один из них - на запись), нужно спрятать переменные dej1 и dej2 под мьютекс(в терминах питона - Lock).
    class search_time(Thread):
      def __init__(self):
        super().__init__()
        self.dej = ""
        self.dej2 = ""
        self.dej_mutex = threading.Lock()
      def run(self):
        #в коде run запись в self.dej1 или self.dej2 делается строго так
        if self.dej_mutex.acquire(): #если Lock уже занят вторым потоком, первый подождёт освобождения
          self.dej1 = "Вася Пупкин"
          self.dej2 = "Жора Золотарёв"
          self.dej_mutex.release() #а теперь сами освободим Lock, чтобы второй поток мог обратиться к переменным

    Во втором потоке создаёшь конструктор, и передаёшь ему ссылку на первый поток.
    class runbot(Thread):
      def __init__(self, st):
        super().__init__()
        self.st = st
      def run(self):
        #в коде обращение к dej1 или dej2 делается строго так
        if self.st.dej_mutex.acquire(): #если Lock сейчас занят первым потоком, ждём освобождения
          print(self.st.dej1, self.st.dej2) #используем переменные
          self.st.dej_mutex.release() #а теперь сами освободим Lock, чтобы первый поток мог обратиться к переменным


    Тогда при создании потоков сделаешь так:
    w1 = search_time()
    w1.start()
    w2 = runbot(w1)
    w2.start()
    Ответ написан
    2 комментария
  • Задача на pyhton. Как разобрать формулу?

    Vindicar
    @Vindicar
    RTFM!
    nihi1ist, это знак суммы. Читай, эта запись эквивалентна такому:
    sum = 0
    for n in range(0, X): #X - то что над знаком суммы
        V = ... #выражение, зависящее от n - то что справа от знака суммы
        sum += v

    Ну разумеется, до бесконечности цикл прокрутить не получится, и тут в дело вступает точность.
    Тебе нужно вычислить очередное слагаемое в сумме, и если оно по модулю меньше точности, то цикл нужно прервать. Иначе добавить слагаемое к сумме, увеличить n и продолжить цикл.
    Ответ написан
    Комментировать
  • Почему PostdgreSQL постоянно выдает ошибку AttributeError: 'NoneType' object has no attribute 'fetchall'?

    Vindicar
    @Vindicar
    RTFM!
    Я полагаю, есть два способа сигнализации о пустом ответе, и разные движки используют разные подходы.
    Либо БД может вернуть объект-курсор, который не содержит ни одной строки.
    Либо БД может вернуть None.

    Для понятности такая аналогия: пусть нам возвращают список. Если нам всегда возвращают список, то можем писать код так:
    for line in db.query("..."):
        do_something(line)

    Сработает даже еслди в ответе нет ни одной строки, т.е. на пустом списке.
    А вот если нам при пустом ответе возвращают None, то код выше вылетит с ошибкой NoneType is not iterable, и надо будет переписать так:
    result = db.query("...")
    if result is not None:
        for line in result:
            do_something(line)
    Ответ написан
    1 комментарий
  • Как исправить ошибку IndexError: list index out of range?

    Vindicar
    @Vindicar
    RTFM!
    У тебя в списке ничего нет, я полагаю. Такое будет, если файл существует, но он пуст.
    Ответ написан
  • Можно ли вызвать из потока асинхронный метод или передать в поток асинхронный метод?

    Vindicar
    @Vindicar
    RTFM!
    Сделай свою программу асинхронной. Асинхронным методам для выполнения требуется работающий цикл-реактор (loop в терминологии asyncio). Этот цикл занимает поток, и все асинхронные корутины выполняются в этом потоке. Без него ничего не выйдет.
    Гипотетически можно запустить такой цикл в отдельном потоке и держать асинхронный код там. Но честно, лучше попробовать сделать свою программу асинхронной, если это возможно (т.е. если нет конфликтующих вечных циклов, как в GUI).
    Ответ написан
    Комментировать
  • Как отфильтровать список по заданному условию?

    Vindicar
    @Vindicar
    RTFM!
    langs = ['en-us', 'en-mc', 'en-gb', 'en-im', 'en-je', 'en-vg', 'en-ie', 'en-lu', 'sv-se', 'en-by', 'en-md', 'en-al', 'en-xk', 'en-me', 'fr-fr', 'fr-bl', 'fr-ch', 'es-es', 'it-it', 'it-sm', 'pt-pt', 'de-de', 'de-at', 'de-li', 'de-ch', 'nl-nl', 'nl-be', 'en-no', 'en-sj', 'en-fi', 'en-ax', 'en-dk', 'en-gl', 'en-is', 'ru-ru', 'pl-pl', 'bg-bg', 'cs-cz', 'el-gr', 'hu-hu', 'lt-lt', 'ro-ro', 'sk-sk', 'uk-ua', 'en-lv', 'en-rs', 'en-si', 'en-ba', 'en-cy', 'en-ee', 'en-hr', 'en-mk', 'en-mt', 'en-ph', 'en-mm', 'en-kh', 'en-mn', 'en-kz', 'en-la', 'en-za', 'en-ck', 'fr-ca', 'en-au', 'en-nz', 'es-ar', 'es-gt', 'es-do', 'es-hn', 'es-ni', 'es-pa', 'es-ec', 'es-py', 'es-ve', 'en-ae', 'en-lb', 'en-il', 'en-pk', 'id-id', 'tr-tr', 'ko-kr', 'th-th', 'en-ca', 'es-co', 'en-sg', 'zh-hk', 'zh-cn', 'en-in', 'en-bd', 'en-lk', 'en-np', 'en-mv', 'pt-br', 'es-pe', 'en-hk', 'ar', 'es-mx', 'ja-jp', 'en-my', 'vi-vn', 'zh-tw', 'en-se']
    
    lang_pairs = { l.partition('-')[0]:l for l in langs }

    Такой код оставит последнее вхождение основного языка в langs. Если нужно иначе, сортируй список langs, или переопределяй нужные вхождения отдельно.
    Ответ написан
  • Python. Как сделать интерфейс для программы без сторонних модулей и библиотек?

    Vindicar
    @Vindicar
    RTFM!
    Разве что использовать оконные функции WinAPI, но
    1. для доступа к winapi из питона потребуется сторонний пакет типа pywin32, что противоречит условию.
    2. это утомительно - гораздо утомительнее того же tkinter.
    Лезть на уровень оконного api имеет смысл только если ты хочешь сотворить что-то, что нельзя сделать стандартными фреймворками или доступными библиотеками (типа окна произвольной формы, или хитрых манипуляций чужими окнами).
    Ответ написан
    Комментировать
  • Нажатие кнопок в сообщении от Телеграм бота с помощью Python и Telethon?

    Vindicar
    @Vindicar
    RTFM!
    Быстрый гуглёж вывел на такой код:
    await messages[0].click(0)
    если messages - это коллекция сообщений (а название типа TotalList на это намекает!), то и впрямь нужно убедиться, что там есть хоть одно сообщение, и выбрать его.
    А также указать номер кнопки, которую кликаем.
    Ответ написан
    2 комментария
  • Как заставить двигаться черепаху?

    Vindicar
    @Vindicar
    RTFM!
    #подготавливаем таблицу замены символов
    transform_table = str.maketrans( { 'X': 'Z', 'Z': 'X' } )
    #функция, производящая один проход преобразования строки
    #input[::-1] - это строка, развернутая наоборот
    #метод translate() заменяет символы согласно указанной таблице замен
    def transform_once(input: str) -> str:
      return input + 'X' + input[::-1].translate(transform_table)
    #функция, производящая несколько проходов преобразования строки
    def transform_multiple(input: str, t: int) -> str:
      for _ in range(t):
        input = transform_once(input)
      return input
    Ответ написан
    Комментировать
  • Как запускать крон задачи из python virtual env?

    Vindicar
    @Vindicar
    RTFM!
    shell_guy, лучше указывать полные пути до всех файлов.
    У меня вот так примерно работает, во всяком случае.
    cd /opt/my_python_project && sudo -u username /opt/my_python_project/bin/python3 /opt/my_python_project/main.py

    где /opt/my_python_project - путь, где ты развернул venv
    /opt/my_python_project/main.py - запускаемый файл проекта
    username - имя пользователя, под которым хочешь запускать проект. Если запуск под определённой учёткой не требуется, sudo можно и опустить, но я бы не стал запускать свой скрипт от рута без реальной необходимости. Мало ли что.
    Ответ написан
    1 комментарий
  • Как сделать проверку где писал user?

    Vindicar
    @Vindicar
    RTFM!
    В официальном FAQ есть же.
    How can I distinguish a User and a GroupChat in message.chat?
    Telegram Bot API support new type Chat for message.chat.
    Check the type attribute in Chat object:

    if message.chat.type == "private":
    	# private chat message
    
    if message.chat.type == "group":
    	# group chat message
    
    if message.chat.type == "supergroup":
    	# supergroup chat message
    
    if message.chat.type == "channel":
    	# channel message
    Ответ написан
  • Как разобраться с этим шифром?

    Vindicar
    @Vindicar
    RTFM!
    Ну насколько мне видно, тебе интересует только два куска кода.
    Инициализация (сокращено):
    this.d = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    this.e = new SecretKeySpec(this.b, "DESede");
    this.f = "pUJeQ3Tr".getBytes();
    this.g = new IvParameterSpec(this.f);
    this.d.init(2, this.e, this.g);

    Дешифровка:
    str2 = new String(this.d.doFinal(Base64.decode(URLDecoder.decode(str, "UTF-8"), 0)), "UTF-8");

    Если убрать BASE64 и url-кодирование (нужно чтобы засунуть бинарную последовательность в вебстраницу), получаем просто обращение к this.d.doFinal().
    Cipher.getInstance("DESede/CBC/PKCS5Padding") - это явно обращение к библиотечному классу, так что выясняешь, что за класс используется, откуда он, ищешь доки, ищешь допустимые коды шифров.
    Когда поймешь, что за шифр "DESede/CBC/PKCS5Padding" - можешь начинать искать аналоги на Питоне.
    Также поищи, откуда в инициализацию приходит секретный ключ this.b.
    Ответ написан
    6 комментариев
  • Как написать распознавание капчи на python?

    Vindicar
    @Vindicar
    RTFM!
    1. Вырежи каждую цифру отдельно (содержащий прямоугольник).
    2. Нормализуй - переведи в оттенки серого (так проще сравнивать), приведи к какому-то фиксированному размеру.
    3. Сравнивай каждую цифру с эталонными изображениями цифр, прошедших такую же номрализацию. В качестве метрики возьми хотя бы расстояние L1 - т.е. вычитаешь значения попиксельно, берёшь модуль разностей (они могут быть меньше 0), и суммируешь.
    4. Эталон, который дал наименьшее значение метрики, наиболее похож.

    Для примитивной капчи, которая не содержит посторонних элементов и искажений, должно сработать.
    Ответ написан
    Комментировать
  • Как решить проблему с видимостью переменной root?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def get_command(message):
        if message.text == "Start":
          root = tk.Tk()
          img = ImageTk.PhotoImage(Image.open('lol.png'))
          createNewWindow(root, img)
          root.mainloop()
        elif message.text == "Stop":
          root.destroy()

    Ух как всё запущено.
    Во-первых, если ты ввёл Start, то get_command() создаёт локальную root, настраивает её, и уходит в бесконечный цикл внутри root.mainloop(). Я не знаю как pytelegrambotapi разруливает это, но бот после такого должен просто встать колом, пока все окна не будут закрыты. Подозреваю что обработчик вызывается в отдельном потоке, но фз. В любом случае, не надо так делать. Лучше иметь один root, который крутится внутри mainloop() в отдельном потоке всё время работы скрипта, а окна создавать и удалять по мере надобности, не создавая и не убивая root.
    Вообще подружить бота с оконным интерфейсом - задача нетривиальная.
    Во-вторых, переменная root - локальная. Она существует только внутри того экземпляра get_command(), который был вызван с командой старт. Если ты вызываешь его с командой Stop, у тебя запускается отдельный экземпляр, где выполняется только ветка Stop - а в этой ветке root объявлен не был, он был объявлен только в ветке Start, в другом экземпляре.
    В-третьих, окна будут спамиться только на той машине где запущен бот. Это так, на всякий случай.
    Ответ написан
    Комментировать
  • Как правильно реализовать систему непрочитанных сообщений в групповом чате?

    Vindicar
    @Vindicar
    RTFM!
    Ну например, для каждой пары пользователь-чат хранить метку времени отключения от чата (или эквивалентного события). Тогда все сообщения, которые были добавлены в чат после этой метки, будут считаться непрочитанными.
    Ответ написан
  • TypeError: descriptor 'append' for 'list' objects doesn't apply to a 'RetailItem' object?

    Vindicar
    @Vindicar
    RTFM!
    def purchase_item(self, self.__lst, obj): #приобрести товар

    1. Откуда вы вообще взяли такой синтаксис?
    2. У вас есть ссылка на self, по ней вы можете обратиться к любому атрибуту/методу self.
    Ответ написан
    3 комментария
  • Python cv2 как перести многомерный массив в картинку?

    Vindicar
    @Vindicar
    RTFM!
    src = [['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78']]
    
    int_src = [ list(map(int, row)) for row in src ]
    red = [ row[0::3] for row in src ] #подразумеваю, что у тебя составляющие идут в порядке RGB
    green = [ row[1::3] for row in src ]
    blue = [ row[2::3] for row in src ]
    image = cv2.merge((blue, green, red)) #opencv по умолчанию хранит изображения в BGR, а не RGB
    Ответ написан
    Комментировать
  • Как выполняются декораторы в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Функции(как и методы) в питоне - это объекты первого рода, их можно сохранять в переменные, передавать как параметры и так далее. Соответственно, декоратор - это тоже функция, и тогда
    @decorator("params")
    def myfunc(func_params):
        pass

    это тоже, что и
    def myfunc(func_params):
        pass
    wrapper = decorator("params")
    myfunc = wrapper(myfunc)


    Никто не мешает decorator() и wrapper() в примере сохранять адрес оборачиваемой функции в какую-то структуру данных, используемую затем ботом для диспетчеризации поступающих событий. Пример без класса:
    registered_funcs = []
    
    def decorator(param):
      #вложенная функция - фактический декоратор
      def wrapper(func):
        global registered_funcs
        #запоминаем декорируемую функцию
        registered_funcs.append( (param, func) )
        return func #не забываем её вернуть
      #возвращаем wrapper, чтобы им можно было продекорировать целевую функцию
      return wrapper
    
    #пример использования декоратора
    @decorator("foo")
    def myfunc(x):
      print("Hello from myfunc(), ", x)
    
    print(registered_funcs)
    #>>> [ ("foo", <function myfunc at 0xdeadf00d>) ]
    #и мы можем этим списком пользоваться, например:
    for arg, func in registered_funcs:
      func(arg)
    Ответ написан
    1 комментарий
  • Как получить список игр со всех пользователей?

    Vindicar
    @Vindicar
    RTFM!
    Если не знаете, какие атрибуты есть у объекта, dir() и документация в помощь.
    activities = sum([], (member.activities for member in ctx.guild.members))
    game_names = [item.name for item in activities if instanceof(item, discord.Game)]
    #если нужно только уникальные:
    game_names = set(game_names)
    Ответ написан
    Комментировать