Задать вопрос
  • Здравствуйте, есть файл с ИНН сотрудников за 1-е полугодие и за 2-е, как вывести ИНН сотрудника с наибольшей зарплатой за первое полугодие?

    Vindicar
    @Vindicar
    RTFM!
    salaries = [] # список будет содержать пары значений ИНН-зарплата
    # открываем файл так, чтобы он потом был закрыт, что бы ни случилось
    with open('salary.txt', 'rt', encoding='utf-8') as src:
        for line in src: # перебираем строки в файле
            try: # на случай, если строка неправильная
                row = line.split(',') #делим строку на части
                INN, salary = row[0], row[1] 
                # ИНН оставим строкой
                salary = int(salary) # зарплата - целое число?
                # если всё прошло как надо, добавляем пару в список
                # обратите внимание на двойные скобки
                salaries.append( (INN, salary) ) 
            except: # если была ошибка, ругаемся на строку
                print('Некорректная строка пропущена:', repr(line))
                # pass # ну или просто пишем pass чтобы ничего не делать
    # теперь все данные у нас в списке
    # могли бы и не делать список, а сканировать сразу файл,
    # если нужен только максимум, а файл большой
    # находим максимум стандартной функцией
    # функция вернёт элемент списка, т.е. пару значение ИНН-зарплата
    # key показывает, по какому критерию сравнивать элементы списка
    # в нашем случае элемент №1 (с нуля), т.е. зарплата
    max_INN, max_salary = max(salaries, key = (lambda row: row[1]))
    print(max_INN)
    Ответ написан
    Комментировать
  • AttributeError: 'int' object has no attribute 'price' как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Команда
    A=[0, 0, '']*401
    даст список вида [0, 0, '', 0, 0, '', .........]
    Т.е. число элементов списке будет 401 * 3.
    Зачем вообще выделять список заранее?
    Сделай его пустым A = [] и делай A.append(....) для каждой прочитанной строки.
    Ответ написан
  • Как исправить ошибку java.io.IOException: Cannot run program "python3": CreateProcess error=2, на Windows 10?

    Vindicar
    @Vindicar
    RTFM!
    error=2 означает что исполняемый файл не найден.
    Причин может быть несколько.
    Я подозреваю, что ява пытается запустить питон просто командой 'python3', без абсолютного пути. Тогда нужно, чтобы директория с бинарником питона была добавлена в %PATH%. Если точно прописана, то можно попробовать Монитор Ресурсов (в виндовс вроде из коробки есть), чтобы посмотреть, какие именно файлы пытается открыть java.
    Ответ написан
    1 комментарий
  • Как сделать проверку, сколько времени человек находится в голосовых каналах на сервере дискорд?

    Vindicar
    @Vindicar
    RTFM!
    1. Читаешь https://discordpy.readthedocs.io/en/latest/api.htm.... Там перечислены все события, которые можно отлавливать через discord.py. Нас интересует discord.on_voice_state_update(member, before, after), он позволяет реагировать на вход и выход пользователей на голосовых каналах. Также важно: потребуется при запуске бота указать интент Intents.voice_states, иначе события не получим.
    2. Разбираешься, как сравнивать параметры `before` и `after`, чтобы понять вошел пользователь или вышел. Оба - структура VoiceState.
    3. Описываешь структуру данных, где хранишь время последнего входа пользователя в голосовой канал. Например, словарь, где id пользователя на сервере - ключ, а время - значение. Если нужна независимая регистрация по каналам, то тогда id канала должно входить в состав ключа.
    4. На входе пользователя вносишь запись в этот словарь. На выходе пользователя - ищешь запись, находишь разность между запомненным временем входа и текущим временем, удаляешь запись. Предусмотри случай если записи нет.
    5. PROFIT. С этой разностью уже делаешь что хочешь, в БД заносишь, или ещё что.
    Ответ написан
  • Как в шаблоне django отобразить список python по столбцам в таблице?

    Vindicar
    @Vindicar
    RTFM!
    Разбей список в коде на несколько частей по 24 элемнета и вставляй каждую часть по отдельности?
    Ответ написан
    Комментировать
  • Ресурсы для изучения асинхронности в Python?

    Vindicar
    @Vindicar
    RTFM!
    По поводу ресурсов, мне очень понравилось объяснение тут (первая часть, ссылка на продолжение в конце текста):
    https://krondo.com/in-which-we-begin-at-the-beginning/
    На английском, но написано по-простому. Кроме того, автор пишет хоть и пространно, но зато последовательно показывает откуда вообще взялась концепция асинхронного программирования, в ответ на какие задачи оно было придумано, и как оно упрощает эти задачи. По сути, в ходе этой статьи мы изобретаем велосипед, чтобы потом понять как классно ездить на мотоцикле. =)
    Ответ написан
    Комментировать
  • Почему 2 раза используется команда "push ax"?

    Vindicar
    @Vindicar
    RTFM!
    Обрати внимание, что двум вызовам push ax соответствуют два вызова pop ax.
    Push сохраняет регистр на стеке, смещая вершину стека. Pop выталкивает значение с вершины стека в регистр и смещает вершину назад. Поэтому паттерн push-use-pop встречается довольно часто, если нам нужен регистр, но мы не хотим терять его предыдущее значение.
    В твоем случае этот паттерн встретился дважды, один внутри другого. Внешний сохраняет регистр при входе в подпрограмму, и восстанавливает при выходе (чтобы поменьше мешать вызывающей подпрограмме). Внутренний - сохраняет регистр AX перед пересылкой, так как мы не можем напрямую писать в ES, только через другой регистр.
    Ответ написан
    Комментировать
  • Как работает цикл for в питоне?

    Vindicar
    @Vindicar
    RTFM!
    Метод list.remove() удаляет элемент с указанным значением из списка.
    Проблема в том, что ты одновременно итерируешься по списку циклом for, и модифицируешь этот список через remove().
    Многие языки такую операцию вообще запрещают, питон, видимо, нет, но суть остаётся - когда ты удалил 1 (элемент с индексом 0), элементы списка сдвигаются к началу. И for видит, что элемент с индексом 0 удалили, а с элемента индексом 1 уже нет (из-за сдвига). Ну и решает что цикл кончился. Поэтому лучше таких ситуаций избегать!

    Решение:
    1. Если позарез нужно итерироваться и модифицировать список в одном цикле, сделай копию, например с помощью среза:
    for i in towers[:]:
    2. Если нужно просто очистить содержимое списка, не удаляя сам список, towers.clear() тебе в помощь.
    3. Если нужно оставить элементы, соответствующие условию, то подойдёт функция filter() или list comprehensions.
    Ответ написан
    Комментировать
  • Работа с переменными в sqlite3?

    Vindicar
    @Vindicar
    RTFM!
    Потому что если просто написанть название переменной в SQL запросе, sqlite не догадается магически что это именно переменная, и что её надо взять именно из этого места скрипта. И слава богу что так.

    Для решения таких задач есть placeholders, это просто и надёжно. На странице по ссылке почти в самом начале есть пример, начинается с фразы "# Do this instead". Почитай и сделай по аналогии.

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

    Vindicar
    @Vindicar
    RTFM!
    face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
    cv2.error: OpenCV(4.5.1) /tmp/pip-req-build-ms668fyv/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

    "Assertion failed" значит, не прошла впроверка входных данных.

    "!_src.empty()" подсказывает, что входное изображение должно быть не пустым - а у тебя, выходит, пустое.

    Ты делаешь frame[startY:endY, startX:endX] - вставь проверку, что startY != endY, а startX != endX.
    Кроме того, стоит проверить, что ты действительно получил кадр через frame = vs.read().
    Ответ написан
  • Как выполнить с помощью Python "js encodeURI"?

    Vindicar
    @Vindicar
    RTFM!
    %22 - это двойная кавычка "
    %27 - это одинарная кавычка '
    str(Login) даст тебе строку вида "{'User': 'Пользователь'}" с одинарными кавычками.
    Я полагаю, тебе не нужно это преобразование в строку, просто используй urllib.parse.urlencode(Login)
    Ответ написан
    Комментировать
  • Какие есть аналоги индексков списком в csv файлах, python?

    Vindicar
    @Vindicar
    RTFM!
    Тебе нужно использовать именно Panda? Тут хватит стандартных модулей. Ну и используй словарь.
    import csv
    #тут храним таблицу соответствий
    table = {}
    #удостоверься, что кодировка файла корректная
    with open(r'C:/Users/varva/Desktop/translit.csv', newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile, delimiter=',')
        for row in reader:
            #убираем пробелы из значений. Можно убрать .strip(), если они значимы
            table[row['Кириллица'].strip()] = row['Латиница'].strip()
    
    word = input()
    #по умолчанию неизвестные символы оставляем как есть. см. метод dict.get()
    result = ''.join( table.get(ch, ch) for ch in word )
    print(result)

    Работает для такого входного файла:
    Кириллица,Латиница
    Ф,F
    Д,D
    В,V
    Ы,Y
    А,A
    Ответ написан
    Комментировать
  • Как вывести два списка в python?

    Vindicar
    @Vindicar
    RTFM!
    Потому что у тебя вложенный цикл.
    Ты сначала для первого слова в russian_words прогоняешь все слова в english_words.
    Потом для второго, потом для третьего, и так далее.
    Ну, точнее, прогонял бы - если бы не break. Так прогоняешь только первое английское слово.

    Тебе вместо этого нужно брать по одному слову из каждого списка. Читай про встроенную функцию zip() в питоне (не имеет отношения к архивации).

    Код не привожу, сам осилишь.
    Ответ написан
    Комментировать
  • Как сделать такое выделение в коде?

    Vindicar
    @Vindicar
    RTFM!
    Если вопрос про markdown-разметку текста в дискорде - то вот именно так и сделать, окружить текст `обратными апострофами`. Читай справку, у них это описано.
    Ответ написан
  • Как грепать в консоле вывод от python?

    Vindicar
    @Vindicar
    RTFM!
    Питон по умолчанию буферизует вывод - не выводит в stdout сразу.
    Если подождешь подольше, то grep потом выведет сразу пачку Hello, когда буфер наполнится и будет выведен в stdout целиком.

    Можно сделать это в нужный тебе момент, вызвав sys.stdout.flush().
    Ответ написан
    Комментировать
  • Выдача ролей по реакциям discord.py?

    Vindicar
    @Vindicar
    RTFM!
    Гугли! На гитхабе discord.py есть готовый пример как это реализуется.
    Ответ написан
    Комментировать
  • Как написать такой декоратор?

    Vindicar
    @Vindicar
    RTFM!
    Именно так, как написано в ОП посте - боюсь, что нельзя.
    Но есть варианты.
    1. Передавать в декоратор параметр - словарь, куда будут складываться методы. Так сделано в комменте П. Ерошевича.
    2. Использовать пару декораторов, один для методов, другой для класса. Первый ставит некоторую метку на методы (нестандартный атрибут), второй проверяет __dict__ класса и складывает в словарь методы с этим атрибутом.
    Например:
    def methoddecorator(method):
      setattr(method, 'super_secret_attribute', True) #ставим метку на метод
      return method
    
    def classdecorator(cls):
      methods = dict()
      for name, obj in cls.__dict__.items():
        #ищем вызываемые объекты с меткой. Можно уточнить, конечно.
        if callable(obj) and getattr(obj, 'super_secret_attribute', None) is True:
          delattr(obj, 'super_secret_attribute') #удаляем метку
          methods[name] = obj #запоминаем метод
      setattr(cls, 'methods', methods) #записываем словарь меченых методов в поле класса
      return cls
    
    @classdecorator
    class Cls:
      #этот метод попадёт в Cls.methods
      @methoddecorator
      def method1(self):
        pass
    
      #этот метод НЕ попадёт в Cls.methods
      def method2(self):
        pass
    Ответ написан
    1 комментарий
  • Как мне отключить масштабируемость окна?

    Vindicar
    @Vindicar
    RTFM!
    Не используй метод show(), он исключительно отладочный и не предназначен для показа изображений в ходе нормальной работы.
    Варинты есть такие:
    1. разобраться с Tkinter - он предоставляет куда больше контроля над окном. Насчет "нельзя менять размер" - точно может, но вот "нельзя передвигать" - это уже не факт. Tkinter идет в стандартной поставке, для простых GUI подойдёт.
    2. Пишешь игру? Можешь потыкаться в pygame, он вроде для такого предназначен.
    3. Если не нужна кроссплатформенность (только под Windows), то можно попробовать создавать окно без заголовка прямо через WinAPI, но это очень гемморойно. Я бы не стал связываться.
    Ответ написан
    Комментировать
  • Вернуть переопределенный метод?

    Vindicar
    @Vindicar
    RTFM!
    Переопределить нужный метод самому? Для одного-двух методов может и подойти, при условии что вы уверены, что методы Class1 будут корректно работать с инстансами вашего класса.
    def __methodname__(self, *args, **kwargs):
        return Class1.__methodname__(self, *args, **kwargs)

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

    Vindicar
    @Vindicar
    RTFM!
    Погоди-погоди-погоди... если я правильно понимаю, ты хочешь создать класс со следующими свойствами:
    1. Экземпляры класса должны хранить в себе список пользовательских callback-функций с одинаковой сигнатурой.
    2. При вызове экземпляра этого класса (как callable object), все callback-функции должны быть вызваны поочерёдно.
    3. Добавить и удалить новый callback должно быть можно посредством операторов += и -=.
    Я верно понял? Тогда мне неясно причем тут декоратор, и что должна будет делать декорируемая функция.

    Я бы написал что-то в духе:
    class EventCaller:
        #конструктор
        def __init__(self):
            #поскольку мы не планируем позволять двойную подписку, то у нас будет множество, а не список.
            self.__callbacks = set();
        # магический метод перегрузки оператора +=
        def __iadd__(self, callback):
            #проверка, что нам вообще передали callable object
            if not callable(callback):
                raise Exception("Callback object is not callable")
            #эта проверка не позволяет подписаться дважды одним объектом
            if callback in self.__callbacks:
                raise Exception("Double event subscription")
            self.__callbacks.add(callback)
        #магический метод перегрузки оператора -=
        def __isub__(self, callback):
            if callback not in self.__callbacks:
                raise Exception("No such event handler")
            self.__callbacks.remove(callback)
        #магический метод, позволяющий вызывать экземпляр объекта как функцию
        #аргументы, переданные методу, сохраняются как есть
        #неименованные - в кортеже args, именованные - в словаре kwargs
        def __call__(self, *args, **kwargs):
            for callback in self.__callbacks:
                try:
                    callback(*args, **kwargs)
                except:
                    pass


    Вот черновик такого класса. Он, конечно, нуждается в доработке:
    а) стоит добавить потоко-безопасную работу со списком обработчиков. Возможно, заменить список на потоко-безопасное хранилище.
    б) стоит запоминать выкинутые обработчиками исключения, и сообщать о них тем или иным способом (перевыбрасывать? выбрасывать своё исключение со списком всех произошедших?)
    в) так что если один из обработчиков изменит переданные объекты, это повлияет на последующие. Если такое поведение надо избежать, возможно, стоит создавать отдельную глубокую копию (см. модуль copy) args и kwargs для каждого обработчика. Хотя там свои заморочки.

    Пример использования:
    #простой обработчик, печатающий переданные ему аргументы
    def evthandler(*args, **kwargs):
        print "Unnamed arguments are:", args
        print "Named arguments are:", kwargs
    #
    #создаем объект-событие
    evt = EventCaller()
    #подписываемся на него
    evt += evthandler
    #генерируем событие. Аргументы могут быть произвольными, они будут переданы обработчикам как есть
    evt("unnamed arg 1", "unnamed arg 2", kwarg1=True, kwarg2=42)
    #отписываемся
    evt -= evthandler
    #этот вызов не будет иметь эффекта, так как список обработчиков события пуст
    evt("unnamed arg 1", "unnamed arg 2", kwarg1=True, kwarg2=42)


    За синтаксическую правильность кода не ручаюсь, но идея должна быть ясна.
    Ответ написан