Ответы пользователя по тегу Python
  • Можно использовать sqlite3 в асинхронном боте?

    @DollaR84
    Если ваша бд сильно нагружена, то действительно лучше использовать специализированные продукты типа postgres. Но в ином случае многие sqlite сильно недооценивают.
    Эта база может и простая, но имеет много возможностей, о которых большинство и не задумываются.
    Во первых, есть несколько вариантов указания работы с многопоточностью, указывается при сборке библиотеки, по умолчанию sqlite3.dll собрана с многопоточным доступом.
    https://www.sqlite.org/threadsafe.html
    Во вторых, у sqlite есть набор интересных ключей при открытии прагмы. Советую использовать, как минимум, journal_mode='wal'. Это освободит запросы чтения от ожидания завершения запросов записи.
    Также есть прагма threads, указывающая сколько лимитов потоков можно создавать, по умолчанию стоит 0, можно увеличить данное число.
    Со всеми прагмами можно ознакомиться тут: https://www.sqlite.org/pragma.html
    В третьих, если вы работаете с базой не напрямую запросами, а через какую-то ORM, то у них тоже могут быть дополнительные опции для потокобезопасности. Например, в простой ORM peewee при открытии базы, наряду с прагмами можно также указать флаг: thread_safe=True. Не разбирал подробности как он работает, но думаю он использует в своей работе ту же прагму threads.
    Поэтому все зависит от нагрузки и роли базы в ваших ботах. В некоторых задачах sqlite оправданный выбор. Надо подбирать инструмент под задачу.
    Ответ написан
  • Пишу игру на python на windows 10, по курсу и у меня выходит ошибка, как ее исправить?

    @DollaR84
    Вот эту строку:
    player_img = pygame.image.load(os.path.join(img_folder, 'p1_jump.png')).convert()

    Надо перенести после инициализации pygame и установки экрана.
    Например сюда:
    ...
    # Создаем игру и окно
    pygame.init()
    pygame.mixer.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("My Game")
    clock = pygame.time.Clock()
    player_img = pygame.image.load(os.path.join(img_folder, 'p1_jump.png')).convert()
    ...


    UPDATE
    Код файла main.py:
    import pygame
    import random
    import os
    from player import *
    
    # настройка папки ассетов
    game_folder = os.path.dirname(__file__)
    img_folder = os.path.join(game_folder, 'img')
    
    WIDTH = 800
    HEIGHT = 650
    FPS = 30
    
    # Задаем цвета
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)
    
    
    # Создаем игру и окно
    pygame.init()
    pygame.mixer.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("My Game")
    clock = pygame.time.Clock()
    player_img = pygame.image.load(os.path.join(img_folder, 'p1_jump.png')).convert()
    player = Player(player_img, BLACK, WIDTH, HEIGHT)
    all_sprites = pygame.sprite.Group()
    all_sprites.add(player)
    
    # Цикл игры
    running = True
    while running:
        # Держим цикл на правильной скорости
        clock.tick(FPS)
        # Ввод процесса (события)
        for event in pygame.event.get():
            # check for closing window
            if event.type == pygame.QUIT:
                running = False
    
        # Обновление
        all_sprites.update()
        
        # Рендеринг
        screen.fill(BLACK)
        all_sprites.draw(screen)
        # После отрисовки всего, переворачиваем экран
        pygame.display.flip()
    
    pygame.quit()

    Код файла player.py:
    import pygame
    import random
    import os
    
    
    class Player(pygame.sprite.Sprite):
        def __init__(self, player_img, color, w, h):
            pygame.sprite.Sprite.__init__(self)
            self.image = player_img
            self.image.set_colorkey(color)
            self.rect = self.image.get_rect()
            self.w = w
            self.h = h
            self.rect.center = (self.w / 2, self.h / 2)
    
        def update(self):
            self.rect.x += 5
            if self.rect.left > self.w:
              self.rect.right = 0
    Ответ написан
  • Как заполнить фигуру в pygame?

    @DollaR84
    В pygame при рисовании различных фигур заливка определяется в зависимости от наличия параметра ширины линии.
    То есть, в вашем случае:
    py.draw.circle(sc,Black,i.pos,7)
    последний параметр 7 указывает ширину линии, поэтому заливка не происходит.
    Если этот параметр убрать, то весь круг зальется черным цветом.
    Если надо определить и заливку и цвет контура разными цветами, то необходимо нарисовать фигуру дважды, сначала с заливкой, а потом линией контура. Например так:
    py.draw.circle(sc,Green,i.pos)
    py.draw.circle(sc,Red,i.pos,7)

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

    @DollaR84
    Если я вас правильно понял, и библиотека GUI не имеет значения, то возможно вам подойдет: wx.lib.plot.plotcanvas.PlotCanvas
    Это один из компонентов библиотеки wxpython, которая, в свою очередь, является python версией кросс платформенной библиотеки WX Widgets.
    Сам я с данным компонентом еще не работал, но судя из описания:
    Создает объект PlotCanvas.
    Подкласс wx.Panel, который содержит две полосы прокрутки и фактическое графическое полотно (self.canvas). Это позволяет осуществлять простое общее построение данных с масштабированием, метками и автоматическим масштабированием оси.
    А также у него огромное количество методов по работе с ним.
    Так что, думаю должен подойти под ваш запрос.
    Ответ написан
    Комментировать
  • Как засечь время в python?

    @DollaR84
    Думаю тут хорошо подойдут методы по работе со временем самого pygame:
    pygame.time

    Для вашей задачи существуют 2 способа.
    Приведу небольшие примеры на срабатывание каждые 5 секунд, чтобы было понятнее как легко масштабировать на любое время.
    1 способ. Использовать таймер.
    # при выстреле ставим запрет на следующий выстрел
    self.timer = 0 # обнуляем начальное значение для отсчета
    pygame.time.set_timer(pygame.USEREVENT, 1000) # запускаем таймер (в милисекундах) на срабатывание каждую секунду
    затем в обработчике событий:
    for event in pygame.event.get():
        if event.type == pygame.USEREVENT:
            self.timer += 1 # считаем количество пройденных секунд
            if self.timer == 5: # если прошло 5 секунд
                pygame.time.set_timer(pygame.USEREVENT, 0) # отключаем таймер
                # даем разрешение на следующий выстрел


    2 способ. Использовать тики для отсчета времени.
    # при выстреле ставим запрет на следующий выстрел
    self.start_ticks = pygame.time.get_ticks() # запоминаем начальное значение тиков в милисекундах
    затем в обработчике событий:
    for event in pygame.event.get():
        if event.type == ...: # тут какое-то ваше событие на выстрел
            seconds= (pygame.time.get_ticks() - self.start_ticks)/1000 # вычисляем сколько прошло секунд
            if seconds > 5: # проверяем что прошло 5 секунд
                # даем разрешение на следующий выстрел
    Ответ написан
    Комментировать
  • Почему дропается база Sqlite на heroku?

    @DollaR84
    На heroku нельзя использовать файлы, так как используется виртуальная файловая система, которая минимум раз в сутки перезапускается. Об этом они сразу предупреждают в описании. На heroku предоставляется база даже в случае бесплатного доступа для обучения, правда всего 5Мб вроде в пакете hobby-dev. Остальные варианты за деньги также можно. Если же вам нужно обязательно использовать файл sqlite - то тогда надо искать другой хостинг, heroku не подойдет.
    Ответ написан
    5 комментариев
  • Как можно скомпилированный .exe запихнуть в ещё один .exe?

    @DollaR84
    На подобный вопрос, только более обобщенный, я давал вот тут:
    Как сделать так, чтобы pyinstaller взял с собой вс...
    Думаю с exe файлами можно провернуть тоже самое.
    Вам нужен ключ --add-binary для бинарных файлов.
    Ответ написан
    Комментировать
  • Как открыть дефолтный браузер из приложения на wxPython без консоли?

    @DollaR84
    Дефолтный браузер из своих програм открываю webbrowser:
    import webbrowser
    webbrowser.open('https://yandex.ru')


    P.S.: насчет опций pyinstaller. Не знаю равноценные это опции или нет, но я при сборке использую --noconsole, а не --windowed

    Итого, webbrowser и --noconsole точно дает результат открытия браузера из приложения на wx, собранного pyinstaller, без висящего на фоне окна консоли.
    Ответ написан
  • На чем писать кроссплатформенные десктопные приложения чтобы не было мучительно больно?

    @DollaR84
    Я обычно использую для десктопных программ WX Widgets на python. Для него библиотека называется wxpython. Отлично собирается в exe pyinstaller. Для создания удобных окошек своих несложных десктопных программок самое то.
    Ответ написан
    2 комментария
  • Как получить данные из JSON с помощью Python?

    @DollaR84
    import json
    with open('file.json', 'r') as f:
        c = json.load(f)['a']['c']
        print(c)
    Ответ написан
    3 комментария
  • AttributeError: module 'pygame' has no attribute 'display' Что делать?

    @DollaR84
    перед работой с какими-либо объектами pygame, сначала надо его инициализировать:

    pygame.init()
    Ответ написан
  • Как сделать так, чтобы pyinstaller взял с собой все нужные файлы?

    @DollaR84
    Для запаковки всех файлов в один exe необходимо использовать флаг -F.
    Все py файлы подхватываются pyinstaller из импортов, поэтому для их включения никаких дополнительных действий не нужно.
    Для добавления сторонних файлов используются следующие параметры:
    --add-data - для добавления текстовых файлов данных;
    --add-binary - для добавления бинарных данных.
    Правило добавления: имя-файла;имя_папки
    Например, если все дополнительные файлы лежат в папке models:
    pyinstaller -F --add-data coco-dataset.labels;models --add-data yolov3-tiny.cfg;models --add-data yolov3-tiny.weights;models pine.py

    А в в самом скрипте необходимо задать следующую функцию:
    import os
    import sys
    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        if getattr(sys, 'frozen', False):
            base_path = sys._MEIPASS
        else:
            base_path = os.getcwd()
        return os.path.join(base_path, relative_path)


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

    @DollaR84
    А зачем удалять, потом снова заполнять новыми данными.
    Используйте UPDATE в запросе SQL для обновления данных.
    То есть, сначала можно делать выборку SELECT с условием WHERE path='путь_к_файлу'.
    Если ничего не вернулось - значит такого файла в базе еще нет, и добавляете новую запись через INSERT. Если вернулась строка из БД для такого файла - используете UPDATE для обновления полей данной строки БД.
    Ответ написан
  • Как из текста сделать Excel таблицу?

    @DollaR84
    Используйте библиотеку openxl.
    Документация: OpenXL
    Создаете книгу, лист, а затем в свой парсер с сайта добавляете код заполнения ячеек.
    Ответ написан
    Комментировать
  • Как правильно упаковать .py в .exe?

    @DollaR84
    Ну судя по ошибке - telebot не может найти файл сертификата SSL.
    Дело все в том, что при запуске exe, созданного pyinstaller, сначала все содержимое распаковывается во временную папку, а затем запускается из нее, соответственно путь другой.
    Поэтому что можно сделать в вашем случае:
    файл SSL добавить в упаковку pyinstaller, с помощью опции --add-data. Пример:
    pyinstaller -F --add-data ssl;. main.py
    Где:
    ssl - файл сертификата;
    . - точка означает текущий каталог, это если файл сертификата лежит в корне со скриптом.

    Затем в самом скрипте надо добавить следующий код:
    import os
    import sys
    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        if getattr(sys, 'frozen', False):
            base_path = sys._MEIPASS
        else:
            base_path = os.getcwd()
        return os.path.join(base_path, relative_path)

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

    @DollaR84
    можно ли рамки и заливку прямоугольника сделать разными цветами, если да, то как?

    Тут все просто, конструктор прямоугольника имеет вид:
    pygame.draw.rect(surface, color, (x1, y1, size_x, size_y), width)
    То, что вас интересует, кроется в последнем параметре width.
    Если он задан то рисуется рамка прямоугольника заданной ширины, если его не задать, то рисуется прямоугольник с заливкой.
    Например, чтобы нарисовать прямоугольник, у которого рамка и заливка будут разных цветов, надо нарисовать два прямоугольника:
    pygame.draw.rect(surface, color1, (x1, y1, size_x, size_y))
    pygame.draw.rect(surface, color2, (x1, y1, size_x, size_y), width)


    С закругленными углами сложнее.
    Думаю там нужна работа с масками.
    Ответ написан
    Комментировать
  • Вопрос про requests.post, как сделать правильно data?

    @DollaR84
    Если надо в post передать словарь, можно просто использовать json в requests добавили такой функционал.
    пример:

    requests.post('url', json=your_dict)
    только словарь должен быть валидным
    Ответ написан
    Комментировать
  • Как сделать, чтобы при выполнении кода в CSV файле выводилась кириллица, а не иероглифы?

    @DollaR84
    Надо внутри python преобразовать к utf-8.
    Как я понимаю это касается new['title'] и new['content'].
    Надо в вашем цикле добавить к ним decode.
    То есть:
    for new in news:
          a_pen.writerow((new['title'].decode("utf-8"), new['href'], new['date'], new['img'], new['content'].decode('utf-8')))


    UPDATE
    совместными усилиями пришли к выводу, что я некорректно понял вопрос изначально.
    Ошибка не в самом python, а в открытии файла csv в excel.
    Для открытия csv нужно в excel его импортировать и в мастере указать кодировку utf-8.
    Но это необходимо проделывать при каждом импорте csv.
    Поэтому для получения данных для excel с нормальной кодировкой лучше писать данные не в csv, а файл полноценный xlsx при помощи модуля openxl. Он позволяет создать полноценную книгу excel и записать данные прямо туда. Сохранив файл данным модулем, кодировка в excel должна открываться сразу нормально.
    Ответ написан
  • Генератор в список?

    @DollaR84
    В случае генератора списка, он создает список со всеми значениями из словаря, удовлетворяющих условию.
    В случае же вашего развернутого цикла, вы вместо списка со всеми подходящими значениями присваиваете список с одним значением. При повторном нахождении подходящего элемента вы переприсваиваете старое значение новым, а не добавляете в список.
    Чтобы цикл был эквивалентен генератору, его надо изменить как-то так:
    when = {}
    for dest in set(fls_gen.values()):
        key_list = []
        for key, value in fls_gen.items():
            if value == dest:
                key_list.append(key)
        when[dest] = key_list
    Ответ написан
    1 комментарий
  • Я не могу понять в чем проблема в моём коде?

    @DollaR84
    У вас неправильно написаны конструкторы классов.
    У всех классов методы:
    _init_
    надо заменить на:
    __init__
    Разница в том, что там по два символа подчеркивания и спереди слова и сзади.
    И у методов __lt__ и __gt__ тоже самое.
    У всех служебных методов не один символ подчеркивания спереди и сзади, а по два символа.
    Да, кстати, и метод __lt__ правильно писать с буквой "l", а не __it__.
    Короче, просто много синтаксических ошибок от невнимательности.
    Да и еще, метод __repr__ тоже пишется по два символа подчеркивания с двух сторон. И плюс код в этом методе нерабочий, с ошибками, но то уже другой вопрос, думаю там сами разберетесь по трейсбеку.
    Ответ написан
    Комментировать