Ответы пользователя по тегу Python
  • Как в Python использовать инфу из переменной w_info в функции def answer(call):?

    @o5a
    Можно сделать глобальный словарь данных (в данном простом случае только для ветра, но можно и все похожие данные в таком виде записывать), в который записывать данные по городу. Затем при нажатии кнопки "Ветер" просто брать уже готовые данные из этого словаря.
    # на верхнем уровне объявляем наш словарь
    wind_info = {}
    
    ...
        elif w1 > 33:
            w_info = 'Огромные разрушения, серьезно повреждены здания, строения и дома, деревья вырваны с корнями, растительность уничтожена.'
    # после определения w_info заносим эти данные в наш словарь
        wind_info[message.text] = w_info # т.к. message.text это наш город (вообще хорошо бы его сразу в отдельную переменную выделять, так код проще читается)

    Но нам нужно в колбеке для ветра как-то указать, по какому городу хотим получить информацию о ветре. Мы можем сам город передать в колбеке
    item_wind = types.InlineKeyboardButton(text = 'Ветер', callback_data = f'wind_{message.text}')

    а затем его извлечь в самом колбеке
    вместо старого
    elif call.data == 'wind':
    обрабатываем колбек вида "wind_Москва"
    elif call.data.startswith('wind'):
            # извлекаем название города
            city = call.data.split('_',1)[1]
            # и берем нашу информацию из словаря данных по ветру
            w_info = wind_info[city]
            bot.send_message(call.message.chat.id, w_info)
    Ответ написан
    1 комментарий
  • Пишет None в рейтинге?

    @o5a
    Так функция ничего и не возвращает. Если нужен топ N, то можно просто сразу возвращать N строк со всеми данными, используя limit
    def get_top_surviveds(self, limit=3):
      with self.connection:
        return self.cursor.execute("SELECT * FROM stats ORDER BY survived desc LIMIT ?", (limit, )).fetchall()
    Ответ написан
  • Каким образом отсеивать данные массива с одинаковым первым элементом?

    @o5a
    Если данные значения всегда идут последовательно, с увеличением этого идентификатора, как в примере (т.е. 106...1021,1022,1023...), то проще при каждом занесении набора данных запоминать в переменную последний номер, а при следующем занесении пропускать все, <= этому номеру.
    # тестовые данные, 2 загрузки
    d1 = [[1016, '2', 141, 0], [1017, '2', 22341, 0], [1018, '2', 1109, 0], [1019, '2', 517, 0], [1020, '2', 443, 0], [1021, '2', 1701, 0], [1022, '2', 1604, 0], [1023, '2', 295, 0]]
    d2 = [[1021, '2', 1701, 0], [1022, '2', 1604, 0], [1023, '2', 295, 0], [1027, '2', 1933, 0], [1029, '2', 398, 0]]
    load_data = [d1, d2]
    
    all_data = []
    last_id = 0
    for data in load_data:
        for row in data:
            if row[0] > last_id:
                all_data.append(row)
        last_id = row[0]

    Если идентификаторы всегда строго увеличиваются на 1, то можно еще более оптимизировать, сразу начав выборку с нужной позиции следующих данных (зная last_id и 1-й id в новой партии данных, сразу можем вычислить, с какого элемента делать загрузку).

    Если же такой зависимости нет, то можно заносить идентификаторы в множество (set) и перед вставкой новой партии проверять на вхождение в множество.
    Ответ написан
    3 комментария
  • Вывод данных из бд в свой профиль telegram bot python?

    @o5a
    Если удобнее, то можно получать данные в виде словаря (где ключи - названия столбцов). Тогда можно напрямую обращаться к нужному полю по имени.
    class SQLighter:
      def __init__(self, database):
          self.connection = sqlite3.connect(database, check_same_thread = False)
          self.connection.row_factory = sqlite3.Row # этой строкой указываем, что результат получаем в виде словаря
          self.cursor = self.connection.cursor()
          self.cursor.execute("CREATE TABLE IF NOT EXISTS stats (user_id INT, user_name TEXT, survived INT, infected INT)")
    ...
      # и можно сделать такую функцию, возвращающую всю информацию пользователя
      def get_info(self, id):
          with self.connection:
              return self.cursor.execute("SELECT * FROM stats WHERE user_id=?", (id, )).fetchone()
    
    sql_lighter = SQLighter("database.db")
    sql_lighter.add_user(982543922, "Владимир", 1, 1)
    # затем получаем весь словарь данных и можем использовать любые нужные поля из него
    data = sql_lighter.get_info(982543922)
    print(data)
    print(data['user_name'])
    print("Информация пользователя {}: имя: {}, survived: {}, infected: {}".format(data['user_id'], data['user_name'], data['survived'], data['infected']))
    Ответ написан
    7 комментариев
  • TypeError: unhashable type: 'list' как исправить?

    @o5a
    from nltk.stem import WordNetLemmatizer
    
    lemmatizer = WordNetLemmatizer()
    words = [lemmatizer.lemmatize(word) for word in words if word not in ignore_letters]
    words = sorted(set(words))
    Ответ написан
    Комментировать
  • 'StreamReaderWriter' object is not subscriptable как исправить?

    @o5a
    Так intents определили как файл, а затем пытаетесь из него читать, как из словаря. Нужно было закончить чтение из json файла, потом уже использовать этот словарь
    with codecs.open('intents.json', encoding='utf-8') as f:
        intents = json.load(f)
    Ответ написан
  • Программа зависает?

    @o5a
    Много лишнего. Вместо numpy, pyscreenshot, cv2 можно использовать PIL. Не совсем понятно, зачем в цикле несколько раз делается скриншот, при том, что используется только 1. Если делается цикл, то объявление всяких констант лучше выносить за него.

    Например так, вместо использования промежуточных модулей с сохранением файла и вложенного цикла.
    import time
    import pytesseract
    from PIL import Image, ImageGrab
    
    pytesseract.pytesseract.tesseract_cmd = "C:\Program Files (x86)\Tesseract-OCR/tesseract.exe"
    tessdata_dir_config = r'--tessdata-dir "C:\Program Files (x86)\Tesseract-OCR\tessdata"'
    time.sleep(10)
    while True:
        try:
            time.sleep(4)
            # просто считываем с экрана и напрямую распознаем
            img = ImageGrab.grab(bbox=(713,550,1400,586))
            text = pytesseract.image_to_string(img, lang='rus', config=tessdata_dir_config)
        ...
    Ответ написан
    Комментировать
  • Pyteseract не видит русский?

    @o5a
    Ему нужно знать, где находится папка с языковыми файлами (в том числе rus.traineddata).
    Можно задать через указание переменной среды windows - TESSDATA_PREFIX (в ней указать полный путь к папке с этими файлами traineddata).
    Если этой переменной среды нет, то он пытается сам определить нахождение файлов и похоже определил неправильно.
    Другой вариант - явно указать путь этих файлов через конфиг.
    Конкретный путь к файлам может отличаться, смотрите сами, где у вас лежит rus.traineddata
    import pytesseract
    filename = 'Image.png'
    pytesseract.pytesseract.tesseract_cmd = "C:\Program Files (x86)\Tesseract-OCR/tesseract.exe"
    tessdata_dir_config = r'--tessdata-dir "C:\Program Files (x86)\Tesseract-OCR\tessdata"'
    img = Image.open(filename)
    text = pytesseract.image_to_string(img, lang= 'rus', config=tessdata_dir_config)
    Ответ написан
    1 комментарий
  • Как найти наименьшее отрицательное значение?

    @o5a
    Как найти наименьшее отрицательное значение?

    Все работает, кроме нахождения наименьшего отрицательного элемента

    Интересная формулировка ;)

    Проблема здесь:
    if a[i]<0:
        res+=[i]

    В этом цикле ведь i - это не значение (число), а индекс числа. Т.е. в список отрицательных чисел попадают не сами числа, а их индексы. Думаю, понятно, как исправить?

    И вообще, для перебора самих элементов списка не нужно прибегать к конструкциям range(len(a)), можно перебирать сами элементы:
    for n in a:
        if n<0:
        ...
    Ответ написан
    Комментировать
  • Как в таблицу SQL pypyodbc ввести данные?

    @o5a
    добавлял оценку в существующую строчку

    в SQL называется UPDATE
    mySQLQuery = (f'''update dbo.rating set `{subject}` = {appr} where id = '{your_id}')''')

    а лучше через передачу параметров
    mySQLQuery = f'''update dbo.rating set `{subject}` = %s where id = %s'''
    cursor.execute(mySQLQuery, (appr, your_id))
    Ответ написан
    Комментировать
  • Как решить задачу правильно?

    @o5a
    Подобная задача проще всего решается через стэк.
    Перебираем постепенно элементы исходного списка.
    Если последний элемент стэка равен противоположному (NORTH-SOUTH и т.п.) текущего элемента списка, то удаляем (stack.pop()) этот элемент из стэка. В противном случае добавляем к стэку. В конце цикла в стэке останется только неисключенные элементы (без пар). Для соответствия пар можно задать словарь.
    Примерно так (спрячу под спойлер, на случай если захочется реализовать самостоятельно):
    spoiler
    def dirReduc(arr):
        dirs = {"NORTH": "SOUTH", "SOUTH": "NORTH", "EAST": "WEST", "WEST": "EAST"}
        stack = []
        for d in arr:
            if stack and dirs[d] == stack[-1]:
                stack.pop()
            else:
                stack.append(d)
        return stack
    Ответ написан
    1 комментарий
  • Как в python pygame как сделать чтобы объект поворачивался до курсора мыши?

    @o5a
    Проблем 2.
    1. Вращать нужно оригинал изображения, а не уже измененную предыдущем вращением копию. Из-за этого будет забиваться память, и скорее всего поэтому он
    иногда еле-ели вертится!)

    Т.е. сменить примерно так:
    bmp_дерево_rot = pygame.transform.rotate(bmp_дерево, rotate(bmp_image))
    bmp_image = bmp_дерево_rot.get_rect(center=(150, 700))
    sc.blit(bmp_дерево_rot, bmp_image)

    2. Для расчета угла вращения нужно помимо координат мыши указывать и правильные координаты самой картинки, а не 0,0.
    def rotate(oject2):
        mouse_x, mouse_y = pygame.mouse.get_pos()
        x, y = bmp_image.center
        rel_x, rel_y = mouse_x - x, mouse_y - y
        angle = (180 / math.pi) * -math.atan2(rel_y, rel_x)
        return angle
    Ответ написан
    Комментировать
  • Возникла ошибка при работе Python и MySQL. Как исправить?

    @o5a
    , "Похудел" "Нет",

    Пропущена запятая. Из-за этого оно понимается как один элемент "ПохуделНет" и количество данных в запросе и val не сходится.
    Ответ написан
    1 комментарий
  • Как проверить JSON на обновления?

    @o5a
    Не совсем понятно, в чем собственно вопрос? Как сравнить 2 полученных результата json? Или как делать запрос с интервалом?
    Если объекты уникальный по id, то можно получить список (множество) идентификаторов одного запроса и другого, затем найти отличия id и по ним вывести нужные результаты из нового запроса.
    ids = {result['id'] for result in data['result']}
    print(ids)

    для json из примера получится
    {'8da31f62a40a2eb3973c9df3', '60831f62a40a2eb3973c9df3'}

    Допустим новый json пришел с доп. id (new_ids)
    {'8da31f62a40a2eb3973c9df3', '60831f62a40a2eb3973c9df3', '60831f62a40a2eb3973c9df5'}

    Соответственно получаем список новых id:
    diff_ids = new_ids - ids
    И по ним уже выводим данные:
    news = [result for result in new_data['result'] if result['id'] in diff_ids]

    где new_data это новый запрос json
    Ответ написан
    Комментировать
  • Почему бот выдает ошибку?

    @o5a
    IDE как тут пишут конечно хорошо, но для изучения программирования Sublime вполне подходит. Просто нужно читать свои ошибки.

    Не замечаете, что в представленном Вами коде стоит
    @bot.messege_handler(content_types=['text'])
    а в сообщении об ошибке ругается на строку
    @bot.handler_backends(content_types=['text'])
    Значит, или запускаете не тот файл, или запускаете, не сохранив изменения.
    И правильно должно быть
    @bot.message_handler(content_types=['text'])
    Ответ написан
    Комментировать
  • Почему питон ругается на аргумент?

    @o5a
    Board - сам класс. Для обращения к самому экземпляру класса (созданному объекту) нужно использовать self.
    т.е. нужно вызывать не
    Board.mark_destroyed_ship(sh)
    а
    self.mark_destroyed_ship(sh)
    Ответ написан
  • Система лайков Python?

    @o5a
    Можно так например. Таблица для хранения лайков в разрезе поста и пользователя:
    CREATE TABLE IF NOT EXISTS post_likes (
    id integer primary key,
    post_id integer, -- id поста
    user_id integer, -- id пользователя
    likes integer
    );


    Лайки можно записывать в одно поле "likes". 1 - лайк, 0 - ничего, -1 - дизлайк.
    Соответственно чтобы собрать итоги, можно использовать такой запрос:
    select sum(likes) total_score, -- общий счет
    sum(case likes when 1 then 1 end) sum_likes, -- кол-во лайков
    sum(case likes when -1 then 1 end) sum_dislikes -- кол-во дизлайков
    from post_likes where post_id = нужный_id_поста
    Ответ написан
  • Как при groupby обьединить значения в строку?

    @o5a
    address = result.groupby([‘OE’]).agg({‘Адрес’:','.join})
    Ответ написан
    2 комментария
  • Ошибка при запуске бота в Телеграм - как решить?

    @o5a
    Потому что
    parse_mode='html', ...
    должно быть частью параметров вызова send_message предыдущей строки
    Ответ написан
    Комментировать
  • Как в python сделать случайный выбор, но с определенной вероятностью?

    @o5a
    Есть еще random.choices. В параметре weights как раз указываются веса каждого значения.
    values = [q1, q2, q3]
    data = random.choices(values, weights=[0.2, 0.3, 0.5], k=1000)
    Ответ написан
    Комментировать