Ответы пользователя по тегу Python
  • Как из списка со строками сделать список с числами?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Варианты решения:
    1. Через цикл. Объявляете новый пустой список, итерируетесь по старому списку со строками через цикл for, в теле цикла переводите строки в числа с помощью встроенного класса int и добавляете в новый список, ну и присваиваете a новый список. Всего четыре строчки.
    2. Через генератор списков (англ. list comprehensions). Аналогично, но без объявления нового списка. Всё в одну строчку.
    Ответ написан
    1 комментарий
  • Как установить pygame_sdl2 для python3, если в системе несколько версий python?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Для начала, попробуйте следовать официальной документации:
    Ubuntu:
    sudo apt-get install build-essential python-dev libsdl2-dev \
        libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
        libjpeg-dev libpng12-dev virtualenvwrapper

    Open a new shell to ensure virtualenvwrapper is running, then run:
    mkvirtualenv pygame_sdl2
    pip install cython

    Change into a clone of this project, and run the following command to modify the virtualenv so pygame_sdl2 header files can be installed in it:
    python fix_virtualenv.py
    Finally, build and install pygame_sdl2 by running:
    python setup.py install

    Если библиотека не будет доступна для импорта в Python3, попробуйте заменить в выше процитированной инструкции вызовы python на python3 и pip на pip3. И попробуйте ещё раз.

    Так же есть подозрение, что в инструкции не хватает:
    git clone https://github.com/renpy/pygame_sdl2
    Ответ написан
  • Как в цикле выводить сообщение один раз?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    def recv():
        last_id = 0
        while True:
            file = vk.messages.getHistory(user_id=93084902, rev=0, count=1)
            for i in file['items']:
                if i['id'] > last_id:
                    last_date = i['id']
                    print(i['text'])
    
    
    variable = Thread(target=recv, args=())
    variable.start()


    Update. Заменил i['date'] на i['id']. Если сообщения пишут очень часто, так правильнее и надёжнее. Мне показалось, что id сообщений имеют случайный характер, но edward_freedom ткнул меня носом в мою невнимательность))
    Ответ написан
    3 комментария
  • Почему не устанавливается vk_api (Python 3.4.0)?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Желательно приводить в вопросе полный трэйсбэк ошибки.

    Скорее всего, проблема в версии пакета vk_api или в версиях его зависимостей (beautifulsoup4, requests, websocket-client, six), чьи разработчики могли отказаться от поддержки Python 3.4.

    Попробуйте скачать vk_api архивом с GitHub, распаковать, явно указать совместимые с Python 3.4 версии зависимостей в requirements.txt и установить пакет вручную python setup.py install.

    Как вариант, если не торопитесь, оформите issue в репозитории проекта.
    Ответ написан
  • Как проверить, встречаются ли какие-либо символы из одной строки в другой строке?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Лучше использовать регулярные выражения, см. модуль re стандартной библиотеки.

    Но если сложно, можете использовать такую функцию:
    def check_password_for_chars(password, chars):
        for char in chars:
            if char in password:
                return True
        return False

    Ну и для каждой проверки вызываете её 4 раза, указывая в качестве chars свои наборы символов.

    Если потребуется проверять, что в пароле больше 1 символа из chars. Убираете return True из тела цикла. Добавляете в функцию третий аргумент, скажем min_count (минимальный счёт), и перед циклом добавляете локальную переменную, скажем count (счёт), со значением 0. Тогда в теле цикла, при каждом обнаружении искомого символа в пароле, Вы увеличиваете count на 1. И в конце проверяете, что count больше или равно min_count, чтобы вернуть True или False.

    Но, во-первых, с регулярными выражениями решение будет короче и без цикла. Во-вторых, регулярные выражения очень гибкий инструмент. И в-третьих, они могут сильно пригодится в будущем.
    Ответ написан
    Комментировать
  • На чем писать gui-программы для debian?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Python часто называют "лучшим вторым языком для большинства задач". Написание графических приложений -- не исключение. Особенно, если нет задачи защитить исходный код приложения от изучения посторонними.

    Библиотек для создания графических приложений много.

    Из того, что более-менее на слуху:
    • GTK+ 3
      • Python GTK+ 3 (зависит от PyGObject) -- рекомендую. Во-первых, тулкит Gtk проще в освоении, чем монструозный Qt. Во-вторых, есть приличная по объёму официальная документация для Python (хотя и не полная). Приложений с большим количеством окон и виджетов пока не писал.

    • Qt5
      • PyQt5 -- несколько лет назад пробовал PyQt4 и PyQt5. Для написания чего-то сложнее "Hello world!" надо курить много документации к оригинальному Qt, а изложено там всё в контексте языка C++. Например, пару дней пытался разобраться как обойтись без Qt-шных классов для работы с СУБД (чтобы не извращаться с голым SQL) и подружить Qt-шные виджеты для таблиц с SQLAlchemy -- в итоге понял, что Qt не для меня.
      • PySide2 -- не пробовал. Лучше PyQt5 по части лицензий (есть под LGPL, что позволяет бесплатное использование и в проприентарных проектах) и, если не ошибаюсь, PySide2 лучше дружит с питоновскими типами. В остальном, тот же Qt5.

    • wxWidgets
      • wxPython -- не пробовал. Говорят проще PySide2 / PyQt5. Однако, тулкит не дотягивает по популярности до GTK+ 3, так что вероятно и инфы по нему меньше. Как я понял, стабильной версии под Python3 до сих пор нет, находится в разработке под названием Phoenix.

    • Tk
      • Tkinter -- пробовал. Собственно исходный тулкит Tk кажется морально устаревшим. Добиться более-менее приличного оформления приложений затруднительно. Для реализации сложных вещей надо писать заметно больше кода, чем в вышеупомянутых тулкитах.

    • Kivy -- фреймворк больше ориентирован на разработку мобильных приложений под Android и iOS, но можно писать приложения и под Linux системы.

    Так же, в некоторых случаях, есть смысл смотреть в сторону веб-фреймворков (Django, Flask и др.). Веб-приложение может и локально запускаться на конкретной машине, взаимодействуя с операционной системой и другими веб-приложениями в сети организации.
    Ответ написан
    7 комментариев
  • Какие модули Python лучше всего использовать для получения системной информации об устройстве и ОС?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Вопрос легко гуглиться.

    Для ОЗУ, ЦПУ и пр. железа упоминают библиотеку psutil:
    https://pypi.org/project/psutil/

    Для остального, см. модули os и sys стандартной библиотеки.
    Ответ написан
    2 комментария
  • Списковые включения, как использовать elif?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Ни в списках, ни в генераторах списков нельзя использовать elif.
    Ответ написан
    1 комментарий
  • Почему False аналогично 0?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Особенность реализации, булев тип (bool) наследуется от целочисленного (int).

    Если требуется отличать False от 0 и True от 1 -- используйте оператор is вместо !=.

    Операторы == и != проверяют равенство значений двух объектов. Но из-за особенностей реализации, у False и 0 -- одно и тоже значение, а у True и 1 -- одно и тоже другое значение.

    Оператор is проверяет равенство id двух объектов. Булевы объекты True и False -- это синглтоны, т.е. существуют в программе не более, чем в 1 экземпляре. Поэтому, у всех True -- один и тот же id, а у всех Fasle -- один и тот же другой id.
    Ответ написан
    3 комментария
  • Зачем нужен celery?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Например, очередь заданий по конвертации видео для веб-приложения на Django.

    Попытка выполнять такую задачу в Django непосредственно при обработке запросов по-умолчанию будет приводить к 504 Gateway Timeout (слишком долгий запрос) со стороны Nginx или иного HTTP-сервера.

    Попытка делать это с помощью Cron и произвольных команд Django -- немного неудобна. Допустим, Cron выполняет произвольную команду Django раз в 1 минуту:
    python3 path/manage.py convert_next_video
    , при этом первый видео файл будет конвертироваться 5 минут, после этого будет помечен в базе данных как is_converted (конвертирован) и команда на этом завершится. Через минуту cron снова запустит команду для конвертации следующего файла.

    Но за 5 минут файл ещё не будет помечен как конвертированный, поэтому cron за 5 минут создаст 4-5 процессов, которые будут конвертировать один и тот же файл.

    Ладно, тогда при начале конвертирования файл сразу будем помечать как конвертируемый, чтобы другие процессы брали другие файлы.

    Но что будет если процесс упадёт? Отмечать время начала конвертирования в базе данных и если прошло больше n часов, конвертировать повторно -- так себе решение.

    И что если пользователи загрузят 10 файлов каждый из которых будет конвертироваться 30 минут? Через 10-11 минут на сервере будут работать 10 процессов конвертирующих видео. Большая нагрузка на сервер. Можно завести в базе данных таблицу в которой отмечается сколько файлов конвертируется в данный момент.

    Решив использовать cron для долгих по выполнении задач, нам придётся решать целый ряд проблем.
    Ответ написан
    3 комментария
  • Как найти частичное совпадение строк?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Без дополнительных библиотек и с использованием расстояния Дамерау-Левенштейна можно примерно так:
    import re
    
    
    def get_substrings(string):
        """Функция разбивки на слова"""
        return re.split('\W+', string)
    
    
    def get_distance(s1, s2):
        """Расстояние Дамерау-Левенштейна"""
        d, len_s1, len_s2 = {}, len(s1), len(s2)
        for i in range(-1, len_s1 + 1):
            d[(i, -1)] = i + 1
        for j in range(-1, len_s2 + 1):
            d[(-1, j)] = j + 1
        for i in range(len_s1):
            for j in range(len_s2):
                if s1[i] == s2[j]:
                    cost = 0
                else:
                    cost = 1
                d[(i, j)] = min(
                    d[(i - 1, j)] + 1,
                    d[(i, j - 1)] + 1,
                    d[(i - 1, j - 1)] + cost)
                if i and j and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]:
                    d[(i, j)] = min(d[(i, j)], d[i - 2, j - 2] + cost)
        return(d[len_s1 - 1, len_s2 - 1])
    
    
    def check_substring(search_request, original_text, max_distance):
        """Проверка нечёткого вхождения одного набора слов в другой"""
        substring_list_1 = get_substrings(search_request)
        substring_list_2 = get_substrings(original_text)
    
        not_found_count = len(substring_list_1)
    
        for substring_1 in substring_list_1:
            for substring_2 in substring_list_2:
                if get_distance(substring_1, substring_2) <= max_distance:
                    not_found_count -= 1
    
        if not not_found_count:
            return True
    
    
    search_request = 'трубок использовали для прожигания'
    original_text = 'трубок использовали для прожигания стальковша.Замена воронки 18м 8сл. Разлита полностью'
    
    result = check_substring(search_request, original_text, max_distance=2)
    
    print(result)  # True если найдено, иначе None


    Можете доработать под свои задачи. Но учтите, нахождение расстояния Дамерау-Левенштейна в принципе ресурсоёмкая операция, тем более с реализацией на чистом Python. Например, искать вхождение подстроки в нескольких мегабайтах текста -- может быть довольно долго.

    Чтобы ускорить нахождение расстояния ДЛ, можно использовать реализацию для Python на языке Си: https://github.com/gfairchild/pyxDamerauLevenshtein

    Так же существуют менее точные, но более быстрые алгоритмы сравнения двух строк:
    https://habr.com/ru/post/114997/
    В PyPI и на GitHub должны быть библиотеки с готовыми реализациями наиболее востребованных из них.
    Ответ написан
    7 комментариев
  • Почему функция и переменная не могут одинаково называться?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Более-менее корректный ответ мог бы выглядеть так.

    Большинство "слов" в коде на Python -- это имена-ссылки на объекты Python.

    И функции, и "переменные" -- это объекты Python.

    В любом пространстве имён могут хранится имена-ссылки как на функции, так и на "переменные".

    Имена в каждом пространстве имён уникальны, поэтому нельзя одинаково назвать и функцию, и переменную. При попытке так сделать, что-то новое займёт имя-ссылку чего-то старого.

    То же самое относится к классам, к объектам классов, к полям и методам классов и пр. Все объекты Python либо занимают уникальные имена в неком пространстве имён, либо не занимают вовсе (например, числа в списке доступны не по имени, а по индексу).

    P.S. Спасибо, вопрос поднял настроение.
    Ответ написан
    Комментировать
  • Как сделать datetime.timedelta в нужном формате?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Одним выражением:
    result = ' '.join([
        pattern.format(value) for value, pattern in zip(
            (x.days, x.seconds//3600, (x.seconds//60)%60, x.seconds),
            ('{} д.', '{} час.', '{} мин.', '{} сек.'),
        )
        if value
    ])


    Падежи русского и других флективных языков (например, 1 час, но 2 часа и 8 часов) -- отдельный вопрос. Проще всего использовать сокращения: д., час., мин. и сек.
    Ответ написан
    1 комментарий
  • Что такое '-m' в командах в работе с Python?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    В последних версиях Ubuntu установленные пакеты Python не прописываются как команды оболочки. А прописывать это ручками не каждый умеет.

    Таким образом, привычное:
    pyvenv .venv
    из коробки работает не во всех операционных системах.

    И в гайдах стали писать более универсальное:
    python3 -m venv .venv

    А что это такое, можно посмотреть в справке к Python:
    python3 --help

    Где можно увидеть описание опции:
    -m mod : run library module as a script (terminates option list)


    То есть, запуск установленный библиотеки в качестве скрипта. Хотя, очевидно, не все библиотеки имеют какой-то полезный функционал, который можно так запустить.
    Ответ написан
    2 комментария
  • Как достать нужные данные?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Ознакомьтесь с основными коллекциями Python.

    Списки (тип list):
    https://pythonworld.ru/tipy-dannyx-v-python/spiski...

    Словари (тип dict):
    https://pythonworld.ru/tipy-dannyx-v-python/slovar...

    Особенно по части обращения к элементу списка/словаря по индесу.

    Тогда можно будет делать так:
    ...
    response = api.users.get(access_token = token, user_ids = id)
    first_name = response[0]['first_name']
    print(first_name)
    Ответ написан
    1 комментарий
  • Как автоматизировать создание списка?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Я чуть мозг не сломал, пытаясь понять задачу.

    Решение же простое:
    [(i+1,2,i+3,4) for i in range(1000)]
    Ответ написан
    1 комментарий
  • Почему при отправке данных в MongoDB она ругается?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Попробуйте заменить вложенные словари на объекты SON:
    from bson.son import SON
    
    pool['tags'] = [SON([(k, d[k]) for k in d]) for d in pool['tags']]
    Ответ написан
  • Как собрать с такой код для конфиг файла?

    ri_gilfanov
    @ri_gilfanov
    Web- and desktop-developer
    Roman Ratkin, для генерации кода, конфигов и разметки можно использовать шаблонизаторы.

    Например, шаблонизатор jinja2 ( jinja.pocoo.org/docs/2.10 ).

    Так поступили разработчики утилиты cookiecutter ( https://cookiecutter.readthedocs.io/en/latest/ ) для генерации кода и конфигов проектов по шаблонам. Пример такого шаблона для Django ( https://github.com/pydanny/cookiecutter-django ).

    В вашем случае, можно так же взять Jinja2, сделать файл-шаблон под конфиг, скармливать джинже нужные значения и получать готовые конфиги. Если какие-то значения конфига зависят от других значений -- можно использовать условия. Если нужно засунуть в конфиг последовательность значений и каждое завернуть в какой-то текст -- есть циклы. Нужно вставить в конфиг какую-то дату и время -- можно пробрасывать в шаблон функцию высчитывающую нужную дату и время.
    Ответ написан
    1 комментарий