Проблема с добавлением горячих клавиш keyboard
Делаю приложение на PyQt, пытаюсь сделать установку горячих клавиш.
Клавиши подгружаются из базы данных при запуске.
Проблема:
При запуске приложения сразу выполняются действия горячих клавиш, а при последующем их нажатии
вылезает ошибка.

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Users\ashig\AppData\Local\Programs\Python\Python39\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\Users\ashig\AppData\Local\Programs\Python\Python39\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\ashig\Documents\project\venv\lib\site-packages\keyboard\_generic.py", line 58, in process
    if self.pre_process_event(event):
  File "C:\Users\ashig\Documents\project\venv\lib\site-packages\keyboard\__init__.py", line 218, in pre_process_event
    callback(event)
  File "C:\Users\ashig\Documents\project\venv\lib\site-packages\keyboard\__init__.py", line 649, in <lambda>
    handler = lambda e: (event_type == KEY_DOWN and e.event_type == KEY_UP and e.scan_code in _logically_pressed_keys) or (event_type == e.event_type and callback())
TypeError: 'NoneType' object is not callable

Код:

import keyboard
import sqlite3
import os
import sys

from PyQt5.QtWidgets import (QApplication,
                             QMainWindow)
from design.py.macros import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.initUI()

    def initUI(self):
        self.add_combination()

    def add_combination(self):
        con = sqlite3.connect('macros_db.sqlite')
        cur = con.cursor()

        data = cur.execute("""SELECT combination, url_file FROM macros""").fetchall()
        for hotkey, url in data:
            keyboard.add_hotkey(hotkey, os.startfile(url))

        con.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

Могу предположить, что тут
lambda поможет сделать отложенное выполнение, которое вы хотели:

keyboard.add_hotkey(hotkey, lambda x=url: os.startfile(x))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Не могу закрепить сообщение пользователя, Aiogram
<code>
@dp.message_handler(commands=['pin'])
async def piim(message: types.Message):
    await message.reply(f"{bot.pin_chat_message}")
</code>

Я так понимаю, вы хотите закрепить сообщение, на которое пользователь ответил командой: /pin, если да, то вот решение:
<code>
@dp.message_handler(commands=["pin"])
async def pinHandler(message: types.Message):
    await bot.pin_chat_message(message.chat.id, message.reply_to_message.message_id)
    await message.answer("Прикрепил")
</code>


Как взять из БД дату и сравнить ее с текущей датой
Есть база данных, условно
data_date, в ней есть таблица
users в которой есть столбец
close_date в данной БД значения
date в формате
2022-10-10.
Мне нужно взять данную дату из БД и сравнить ее с текущей, если текущая меньше, то разрешить дальнейшие действия
пробовал вот так, но возвращает None

current_date = datetime.now().date()
ends_date = cursor.execute(f"SELECT close_date FROM users WHERE close_date = ?", [chat_id]).fetchone()
if current_date <= close_date:
    pass

exists = cursor.execute(f"SELECT user_id, close_date FROM id_api WHERE user_id = ? and close_date >= current_date", [chat_id]).fetchone()
if exists:
    pass


Не получается вывести комментарии в django
models.py

class Post(models.Model):
    text = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) # auth_user_model - это кастомная модель пользователя, она наследуется от AbstractUser, в ней добавлено поле возраста, но оно здесь не используется

class Comment(models.Model):
    text = models.TextField(max_length=5000)
    date = models.DateTimeField(default=timezone.now, null=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True)

views.py

@login_required(login_url="login")
def add_comment(request, comment_id):
    form = CommentForm()
    post = get_object_or_404(Post, pk=comment_id)
    author = request.user

    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.author = author
            comment.post = post
            comment.save()
            return redirect("post_detail", post.id)

    context = {"form": form, "post": post}

    return render(request, "ion/comment_form.html", context)

post_detail.html

{% extends 'base.html' %}
{% block content %}
    <div>
        {% if not post.comments.all %}
            # инструкция, если к этому посту нет комментариев
        {% else %}
            {% for comment in post.comments.all %}
                <b>{{ comment.author }}</b> - <span>{{ comment.date }}</span>
                <p>{{ comment.text }}</p>
            {% endfor %}
            # если комментарии есть, должны выводиться их автор, дата публикации и текст
        {% endif %}
    </div>
{% endblock content %}

Я не могу вывести данные о комментариях в шаблонизаторе django. У меня есть модели поста и комментария. Прикрепляю код. Форма добавления комментов работает, они видны в админке, но если перейти на detail поста, то данные комментов не выводятся.
В модели есть поля текста комментария, даты публикации, автора и поста, к которому он прикреплен. Во вьюхе задается форма отправки комментария, пост, которому он отправляется (если его нет - 404) и автор ставится автоматически. Если используется метод post, обозначаем использующаюся форму и если она валидна под переменной "comment" сохраняем введенную форму, назначаем автора и пост, для которого создавался коммент и все сохраняем. Эти данные отправляем на страницу detail поста (post_detail). В контекстном словаре передаем переменные "post" и "form". Рендерим это на страницу добавления поста(comment_form, она работает, по ней вопросов нет).
На странице detail поста проверяем, если комментариев нет, выводим сообщение, если есть под переменной comment перебираем их в цикле и выводим автора, дату и текст каждого.
Возможно проблема в том, что pk постов у меня начинаются с пяти, т.к. я удалял некоторые, а pk комментов с другого числа? (Строчки post = get_object_or_404(Post, pk=comment_id); comment.post = post.) Заранее спасибо!

class Comment(models.Model):
    text = models.TextField(max_length=5000)
    date = models.DateTimeField(default=timezone.now, null=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    post = models.ForeignKey(Post,related_name="comments" on_delete=models.CASCADE, null=True)

Добавляем
related_name="comments" для обратной связи таблиц


Как что-бы дискорд бот ставил реакции под сообщения конкретного пользователя?
Крч, мне в голову взбрело написать собственного бота в дискорд чтобы смешно и всё-такое. Но главная идея заклчсалась в том, что-бы ставить одну кастомную реакцию под сообщением конкретного пользователя (постоянно. не зависимо от содержания, времени и т.п.) Просмотрев тыщю гайдов и туторов выяснил что можно вычленить айди юзера через режим разработчика, и от этого плясать, но т.к. в питоне я как в орфографии поэтому требуется помощь. Вот как сделать чтобы бот понимал айди и ставил реакт вот это вопрос.
вот код:
<code>
    async def on_ready(self):
        print('Система успешно взломана АЗАЗАЗАЗАЗАЗА')

    async def on_message(self, message):
        if message.author == self.user:
            return

        if message.content == 'бот помоги':
            await message.channel.send('нет')

        if message.content == 'пися':
            await message.channel.send('попа')

        if message.content == 'да':
            await message.channel.send('филипкиркоров')

        if message.content == 'бот прив':
            await message.channel.send('пцвпаол')

        if message.content ==  ('бум'):
            await message.channel.send('123')

    async def on_message(self, message):
        if message.author == self.user:
            return

        if message.content == '123':
            emoji = ':1hihihiha:1037993089593262091'
            await message.add_reaction(emoji)

intents = discord.Intents.default()
intents.message_content = True
client = MyClient(intents=intents)
client.run('токен')

</code>

Можно двумя способами - через уник. id пользователя -
message.author.id или же его имя -
message.author.name
Далее фильтровать можно через бд или же простым if-ом

if message.author.id == '1234554321':
    ...
elif message.author.name == 'username':
    ...


Отредактировать значения записей DataFrame содержащие * и () и разделить колонку
Есть список персон с пометками

Person

Jake Myers

C.J. Coles   (M)

Kyle Willington  *

Matthew Smith

Peter Potter (J) *

на выходе нужны имена отдельно, опции отдельно (примерно так)

Person
Status
Online

Jake Myers

C.J. Coles
M

Kyle Willington

yes

Matthew Smith

Peter Potter
J
yes

Формат известен без всяких Nan и 0

Опция 1: J,M или K
Опция 2: есть * или нет
Могут сочетаться.

Пробовал начать разбирать со звездочек через
np where -

df['Status'] = np.where(df.Person.str[2:] != " *", 1,0)

по кондициям не совсем пролезает, на соседних столбцах работает...
Опция 1 прихватывает все заглавные буквы из-за скобок. Опция 2 вообще все. Заход через
iloc тоже помог не сильно.
Иногда спасал
split в несколько проходов (на известном формате данных), но не в этом случае.
Решается ли без
import re и как правильно составить условия, если нет?

Используйте

import pandas as pd
import numpy as np

df = pd.DataFrame({'Person':['Jake Myers', 'C.J. Coles (M)', 'Kyle Willington *', 'Matthew Smith', 'Peter Potter (J) *']})

rx = r'^(.*?)(?:\s*\(([^()]+)\)|)\s*(\*?)$'
df[['Person','Status','Online']] = df['Person'].str.extract(rx)
df['Status'] = df['Status'].fillna("")
df["Online"] = df["Online"].replace({"*": "yes"})

Результат:

>>> df
            Person Status Online
0       Jake Myers
1       C.J. Coles      M
2  Kyle Willington           yes
3    Matthew Smith
4     Peter Potter      J    yes

См. пример работы регулярного выражения:

^ - начало строки

(.*?) - Подмаска 1: ноль и более символов, отличных от символов перевода строки, как можно меньше

(?:\s*\(([^()]+)\)|) - незахватывающая подмаска, находит ноль и более пробельных символов,
(, один и более отличных от
( и
) символов (захватываемые в подмаску 2),
)

\s* - ноль и более пробельных символов

(\*?) - Подмаска 3: необязательный символ
*

$ - конец строки.

df['Status'].fillna("") заменяет все
NaN в столбце
Status на пустую строку, а
df["Online"].replace({"*": "yes"}) заменяет все
* в столбце
Online на значение
yes.


Как передать информацию из данных FSM машины состояний в Callback inline кнопки в python aiogram telegram bot?
Пишу бота для принятия заявок на работу. Мне нужно чтобы при нажатии кнопки 'accept' отправлялось определённое сообщение изначальному пользователю, который запустил заполнение анкеты. Я всё перепробовал, но так и не понял как правильно получить message.from_user.id в колбэке кнопки, чтобы после её нажатия ему отправилось какое-либо сообщение.
Код отвечающий за это:

class FormState(StatesGroup):
    exp = State()
    wh = State()
    formlog = State()
    user_id = State()

markup = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
remove = ReplyKeyboardRemove()
imarkup = InlineKeyboardMarkup()

@dp.message_handler(commands=['start'])
async def process_start_command(message: Message):
    if message.chat.type == 'private':
        sbtn = KeyboardButton('Начать')
        markup.add(sbtn)
        await message.answer('👋 Добро пожаловать на форму подачи заявки в нашу команду! Для начала заполните анкету и ответьте на несколько вопросов.', reply_markup=markup)
        await FormState.exp.set()

@dp.message_handler(state=FormState.exp, text=['Начать'])
async def get_exp(message: Message, state: FSMContext):
    await message.answer('Был ли у вас до этого опыт? Если да, то какой?', reply_markup=remove)
    await FormState.next()

@dp.message_handler(state=FormState.wh)
async def get_wh(message: Message, state: FSMContext):
    await state.update_data(exp=message.text)
    await message.answer('Сколько часов в день вы готовы уделять работе?')
    await FormState.next()

@dp.message_handler(state=FormState.formlog)
async def form_finish(message: Message, state: FSMContext):
    await state.update_data(wh=message.text, user_id=message.from_user.id)
    data = await state.get_data()
    abutton = InlineKeyboardButton(text='✅', callback_data='accept')
    dbutton = InlineKeyboardButton(text='❌', callback_data='butt_id')
    msg = InlineKeyboardButton(text='✉', callback_data='butt_id')
    imarkup.add(abutton, dbutton, msg)
    await bot.send_message(config.adminid,  f'📩 Новая заявка на вступление!\n\n👤 Пользователь: {message.from_user.mention}\n'
                                            f'🎓 Опыт: {data["exp"]}\n'
                                            f'🕗 Часы работы в день: {data["wh"]}', reply_markup=imarkup)
    await message.answer('⏳ Ваша заявка успешно подана на рассмотрение')

@dp.callback_query_handler(text='accept')
async def accept_query(call: types.CallbackQuery):
    await call.message.edit_text(call.message.text+'\n\n✅ Вы одобрили эту заявку')
    await call.bot.send_message(user_id='???', '✅ Ваша заявка была одобрена!')

Примерно так
<code>
abutton = InlineKeyboardButton(text='✅', callback_data=f'accept:{message.from_user.id}')
dbutton = InlineKeyboardButton(text='❌', callback_data=f'butt_id:{message.from_user.id}')

@dp.callback_query_handler(text_startswith='accept')
async def accept_query(call: types.CallbackQuery):
    user_id = call.data.split(":")[1]
</code>


Замена значений в dataframe
Всем привет,
У меня следующая проблема, есть последовательность

90359   0
90360   0
90361   0
90362   0
90363   0
90364   0
90365   2
90366   2
90367   2
90368   2
90369   2
90370   2
90371   2
90372   0
90373   0
90374   0
90375   0
90376   0

Мне нужно оставить первые три двойки, а остальные заменить на 0. Т.е. получить вот это:

90359   0
90360   0
90361   0
90362   0
90363   0
90364   0
90365   2
90366   2
90367   2
90368   0
90369   0
90370   0
90371   0
90372   0
90373   0
90374   0
90375   0
90376   0

При этом встречаются последовательности этих двоек разной длины, может 5 подряд, может 10.
И все их нужно привести к длине 3.
Доп. вопрос. Также встречаются одинокие двойки в этом же dataframe, возможно ли их заменить на 0?
Помогите, плиз.

В
loc[] отбираем строки по двум условиям (булевым массивам) - а) для групп двоек больше 3-х штук подряд и б) для "одиноких" двоек.
Условие а):
df.col1.eq(2) & df.groupby(df.col1.diff().ne(0).cumsum()).cumcount().gt(2) - истинно если в колонке
col1 двойка и порядковый номер двойки в группе больше 2х (нумерация с 0). В конструкции
df.groupby(df.col1.diff().ne(0).cumsum()).cumcount().gt(2) сначала сформированы номера групп с одинаковыми числами (
.diff().ne(0).cumsum()) вида 000111222333, затем они сгруппированы и числа в каждой группе пронумерованы (
.cumcount()) от 0 до n, после чего порядковым номерам от 0 до 2 поставлен в соответствие (
.gt(2)) false, а номерам от 3 до n - true.
Условие б):
(df.col1.eq(2) & df.col1.shift(-1).ne(2) & df.col1.shift(1).ne(2)) - истинно, когда ни снизу (
.shift(1).ne(2)) ни сверху (
.shift(-1).ne(2)) от двойки (
.eq(2)) нет двоек.
Условия а и б (булевы массивы) объединены оператором ИЛИ, поэтому при истинности любого из них соответствующим строкам в колонке
col1 присваивается 0:

df.loc[<условие (булев массив)>, 'col1'] = 0

df = pd.read_csv(r'c:\test\df.csv') # ваш файл с датасетом
df.loc[(df.col1.eq(2) & df.groupby(df.col1.diff().ne(0).cumsum()).cumcount().gt(2)) | (df.col1.eq(2) & df.col1.shift(-1).ne(2) & df.col1.shift(1).ne(2)), 'col1'] = 0
print(df[df.col1.eq(2)].head(20))

Вывод (отфильтровал только двойки, первые 20 строк)

      id  col1
38    38     2
39    39     2
44    44     2
45    45     2
61    61     2
62    62     2
63    63     2
92    92     2
93    93     2
127  127     2
128  128     2
129  129     2
172  172     2
173  173     2
174  174     2
195  195     2
196  196     2
197  197     2
211  211     2
212  212     2

Двойки остаются
Групп двоек больше 3-х  и "одиноких" нет


Вызванный ключ не обращён к одноименной переменной
Скорее всего я бездарно сформулировал вопрос, но вот проблема:

a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
dict = {'a':a,'b':b}
b1 = max(dict, key=dict.get)
a1 = min(dict, key=dict.get)
print(b1,a1)
result = list(filter(lambda elem: elem in b1, a1))
print(result)

Задача в том, чтобы вернуть список, который состоит из элементов, общих для этих двух списков.
Да, можно было на глаз определить более длинный список и сразу вписать вместо b1 и a1 b и a:

a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
result = list(filter(lambda elem: elem in b, a))

Но что делать, когда список из тысяч значений? Как вернуть ключ из алфавита с большей длиной?

не совсем понятно, вам нужны общие для двух списков элементы?
вариант 1:

res = list(set(a) & set(b))

вариант 2:

res = [v for v in a if v in b]

но тут будет две
1, потому что они присутствуют в
a
вариант 3:

res = [v for i, v in enumerate(a) if v in b and v not in a[:i]]

исправляет особенность варианта 2 и выдает такой же результат как вариант 1
вариант 4 (если списки отсортированы):

i = 0
j = 0

res = []

while i < len(a) and j < len(b):
    v1 = a[i]
    v2 = b[j]
    if v1 == v2:
        res.append(v1)
        i += 1
        j += 1
    elif v1 < v2:
        i += 1
    else:
        j += 1

вариант 5:

i = 0
j = 0

res = []

while i < len(a) and j < len(b):
    v1 = a[i]
    v2 = b[j]
    if v1 == v2:
        res.append(v1)
        while i < len(a) and j < len(b) and a[i] == b[j]:
            i += 1
            j += 1
    elif v1 < v2:
        while a[i] == v1 and i < len(a):
            i += 1
    else:
        while b[j] == v2 and j < len(b):
            j += 1

в отличии от варианта 4 не допускает дубликатов


Код, который убирает все цифры из начала строки Python
Пользователь вводит строку. Если первый один или несколько символов - цифры, то их нужно убрать и вывести строку без них. Если строка изначально была без символов, то вывести ее без изменений. Кроме того, нельзя использовать "сложные" конструкции вроде regex.
Вот как выглядит мой код:
<code>
    text = input('Please insert a string: ')
    for i in text:
        if text[0].isdigit:
            new_text = text[1:]
            print(new_text)
        else:
            print(text)
</code>
он при любых вводных просто убирает первый знак строки и выводит его столько раз, сколько составляет длина строки. Чувствую, что проблема в for i in text, но не могу понять, что именно не так.

У вас несколько ошибок:

всё время проверяете 0-й элемент исходной строки, которая не меняется
проверяете значение функции без её вызова, это всегда будет
True
печатаете результат на каждой итерации цикла

И одна погрешность (не ошибка, но небрежность):

вы не используете переменную цикла

Исправленный код:

text = input('Please insert a string: ')
new_text = text
for i in text:
    if i.isdigit():
        new_text = new_text[1:]
    else:
        break
print(new_text)


Как сделать так, чтобы калькулятор диcкриминанта выводил и целые, и округленные числа?
Я решил сделать калькулятор дискриминанта, но он не выводит округлённые значения. Как это можно исправить?
<code>
import math
a = int(input('Введите a '))
b = int(input('Введите b '))
c = int(input('Введите c '))
D = (b ** 2) - (4 * a * c)
if D > 0 and D == round(D):
    x1 = (-b + math.sqrt(D)) / (2 * a)
    x2 = (-b - math.sqrt(D)) / (2 * a)
    print('Корни:', "\nx1(+) = " + str(x1), '\nx2(-) = ' + str(x2))
if D > 0 and not D == round(D):
    x1 = (-b + math.sqrt(D)) / (2 * a)
    x2 = (-b - math.sqrt(D)) / (2 * a)
    print('Корни:', "\nx1(+) ≈ " + str(round(x1)), '\nx2(-) ≈ ' + str(round(x2)))
if D < 0:
    print('Корней нет')
if D == 0:
    x = -(b / (2 * a))
    print('x = ' + str(round(x)))
</code>

мне кажется вы зашли не с того конца :)
есть 2 случая дискриминанта (D >= 0) - полный квадрат или нет
и возможно в связи с этим 3 вида решения: целое, рациональное и иррациональное
проверить дискриминант на полный квадрат можно так:

int(D**.5)**2 == D

дальше я бы воспользовался библиотекой
Fraction чтобы работать с дробями в случае дискриминанта как полного квадрата, что позволило бы решить вопрос сокращения дробей
и лишь для иррациональных дискриминантов использовал бы
float и округление (а его можно уже делать как вам удобнее)


Как ускорить метод в asyncio и что он делает в python?

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1848   11.927    0.006   11.927    0.006 {built-in method _overlapped.GetQueuedCompletionStatus}

Я вывел сколько у меня по времени занимает скрипт это самая наибольшая.
Я использую asyncio aiohttp, и я хотел бы спросить, что это и можно ли это ускорить.
Вызываю функцию через
asyncio.get_event_loop().run_until_complete(main())

asyncio - метод асинхронного воспроизведения программы. Данный метод хорош тем, что если в программу поступает сразу несколько запросов, то он их анализирует и выполняет одновременно. Это увеличивает скорость выполнение программы. Если сравнивать с синхронным выполнением программы на один запрос, то асинхронный уступает, так как выполняется медленнее. Не буду говорить почему именно так происходит, не интересовался так глубоко. Но если поступает на сервер сразу несколько запросов, то в сумме асинхронный код выполнит их быстрее, так как обрабатывает сразу все запросы. Синхронный же в данном случае будет по очереди их выполнять. Поэтому если код не должен принимать сразу несколько запросов, то асинхронный метод ни к чему, так как он медленнее.
Ускорить думаю можно, но это надо видеть сам код, так как скорость зависит больше от того, как код написан.


Оптимизация кода. Оптимизация обновления экрана. Игра в Жизнь Python. PyGame. Как оптимизировать алгоритмы в коде?
Я пытался оптимизировать код различными способами, на одном из сайтов вычитал про двойную буферизацию экрана, но особого результата не заметил. Я осознаю что проблема именно в алгоритмах, которые я использую (функция get_next_generation, get_neigbours). Возможно стоит обновлять экран только при изменении клетки, но я не понимаю как это реализовать(функция update и pg.display.update). Так вот вопрос, как нужно переписать функции, в каком месте стоит обновлять экран для получения наибольшей производительности?
<code>
import pygame as pg
import pygame.time
import random

#Константы основного алгоритма
rules = {'born': [3], 'survive': [2, 3]}
cell_size = 20

#Экран
size = w, h = 1600, 800
flags = pg.FULLSCREEN | pg.DOUBLEBUF
screen = pg.display.set_mode(size, flags, 24)
pg.display.set_caption('Cell Machine')

#Цвета
black = pg.Color(0, 0, 0)
white = pg.Color(255, 255, 255)
dead = pg.Color(224, 255, 255)
alive = pg.Color(0, 139, 139)

#Шрифт
font = 'monospace'
font_size = 50

# Класс клеточки
class Cell:
    def __init__(self, x: int, y: int, life: bool = False) -> None:
        self.x = x
        self.y = y
        self.rect = x, y, cell_size, cell_size
        self.life = life

    # Использовал этот метод для обработки нажатия ЛКМ
    def is_pressed(self, pos) -> bool:
        x, y = pos
        if self.x < x < self.x + cell_size and self.y < y < self.y + cell_size:
            return True

    def change(self) -> None:   #Меняет статус жизни клетки жива/мертва
        self.life = not self.life

    def render(self) -> None:   #Рисуем клетки
        if self.life:
            pg.draw.rect(screen, alive, self.rect)
        else:
            pg.draw.rect(screen, dead, self.rect)

    def clear(self):    # Метод убивающий клетку
        self.life = 0

class Buttons:  #Класс кнопки
    def __init__(self, x, y, background_color):
        self.x = x
        self.y = y
        self.color = background_color

    def create_panel(self, width, height):  #Создание заднего фона для кнопки
        panel = pygame.Surface((width, height))
        panel.set_alpha(128)
        panel.fill(black)
        return panel

    def set_title(self, title):    #Получаем надпись которая будет на кнопке
        my_font = pygame.font.SysFont(font, font_size)
        text_surface = my_font.render(title, True, white)
        return text_surface

    def render(self, title_or_panel):   # Добавляем на экран полученную кнопку
        screen.blit(title_or_panel, (self.x, self.y))

# Функция подсчёта живых соседей НУЖНА ОПТИМИЗАЦИЯ
def get_neighbours(tar: Cell, cells: list) -> int:
    count = 0
    for cell in cells:
        if cell.life:
            x_sym = abs(tar.x - cell.x)
            y_sym = abs(tar.y - cell.y)
            # Горизонтальное, вертикальное или диагональное соседство
            h_nei = x_sym == cell_size and tar.y == cell.y and cell.life
            v_nei = y_sym == cell_size and tar.x == cell.x and cell.life
            d_nei = x_sym == cell_size and y_sym == cell_size and cell.life
            if h_nei or v_nei or d_nei:
                count += 1
        else:
            continue
    return count

# Просто рендер живых клеток
def update(cells: list) -> None:
    for cell in cells:
        cell.render()

# Обновление игрового поля НУЖНА ОПТИМИЗАЦИЯ
def get_next_generation(cells: list) -> None:
    created = []
    deleted = []
    for cell in cells:      #Здесь перебор все клеток, не уверен что это эффективно
        neighbours = get_neighbours(cell, cells)
        if cell.life:
            if neighbours not in rules['survive']:
                created.append(cell)
        else:
            if neighbours in rules['born']:
                deleted.append(cell)
    for new_cell in created:    #Этот блок нужен для того чтобы изменения клеток не влияли для дальнейшего перебора
        new_cell.change()
    for old_cell in deleted:
        old_cell.change()

def get_cells():        #Получаем список всех клеток
    cells = []
    for x in range(0, w, cell_size):
        for y in range(0, h, cell_size):
            cells.append(Cell(x, y))
    return cells

def randomize_cells(cells):     #рандомное заполнение игрового поля
    for cell in cells:
        chance = random.choices(['0', '1'], weights=[50, 10])
        if chance == ['1']:
            cell.change()

def delete_all(cells):  # Делаем все клетки мертвыми
    for cell in cells:
        cell.clear()

# Главная функция
def main() -> None:
    pg.init()
    pygame.font.init()
    # Создание отображения состояние pause play
    button = Buttons(0, 0, black)
    panel = button.create_panel(1600, 60)
    pause_title = button.set_title('Pause')
    play_title = button.set_title('Play')

    cells = get_cells()
    pause = True
    running = 1
    pg.event.set_allowed([pg.QUIT, pg.KEYDOWN, pg.MOUSEBUTTONDOWN])
    while running:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = 0
            # По нажанию на ЛКМ клетка должна менять своё состояние
            # Живая / мёртвая
            if event.type == pg.MOUSEBUTTONDOWN:
                for cell in cells:
                    if cell.is_pressed(pg.mouse.get_pos()):
                        cell.change()

            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:    #Закрываем игровое окно
                    running = 0
                if event.key == pg.K_SPACE:     #Пауза по пробелу
                    pause = not pause
                if event.key == pg.K_r:         #Рандомное заполнение по R
                    randomize_cells(cells)
                if event.key == pg.K_d:         #Очищаем поле по D
                    delete_all(cells)

        # Попытка реализоваться паузу
        if pause:
            update(cells)
            button.render(panel)
            button.render(pause_title)
        else:
            get_next_generation(cells)
            update(cells)
            button.render(panel)
            button.render(play_title)
        pg.display.update()

    pg.quit()

if __name__ == '__main__':
    main()
</code>

Решение проблемы с оптимизацией следующее: заменить класс клетки на класс игрового поля.
<code>
import pygame as pg
import numpy as np
import pygame.time

# Константы основного алгоритма
cell_size = 15

# Экран
size = w, h = 1600, 800
flags = pg.FULLSCREEN | pg.DOUBLEBUF
screen = pg.display.set_mode(size, flags, 24)
pg.display.set_caption('Cell Machine')

# Цвета
black = pg.Color(0, 0, 0)
white = pg.Color(255, 255, 255)
dead = pg.Color(224, 255, 255)
alive = pg.Color(0, 139, 139)

# Шрифт
font = 'monospace'
font_size = 50

class GameOfLife:
    def __init__(self):
        self.surface = screen
        self.width = w
        self.height = h
        self.scale = cell_size
        self.alive = alive
        self.dead = dead
        self.columns = int(h / cell_size)
        self.rows = int(w / cell_size)
        self.grid = np.random.randint(0, 2, size=(self.rows, self.columns), dtype=bool)

    def run(self):
        # Обновляем и рендерим поле
        self.draw_grid()
        self.update_grid()

    def draw_grid(self):
        # Рисуем клетку
        for row in range(self.rows):
            for col in range(self.columns):
                if self.grid[row, col]:  # Если статус 1 - рисуем живую
                    pygame.draw.rect(self.surface, self.alive,
                                     [row * self.scale, col * self.scale, self.scale,
                                      self.scale])
                else:  # Если статус 0 - рисуем мертвую
                    pygame.draw.rect(self.surface, self.dead,
                                     [row * self.scale, col * self.scale, self.scale,
                                      self.scale])

    def update_cell(self, x, y):
        # Получаем следующее поколение клеток(поля)
        current_state = self.grid[x, y]
        alive_neighbors = 0

        # Get to how many alive neighbors
        for i in range(-1, 2):
            for j in range(-1, 2):
                try:
                    if i == 0 and j == 0:
                        continue
                    elif self.grid[x + i, y + j]:
                        alive_neighbors += 1
                except:
                    continue

        # Updating the cell's state
        if current_state and alive_neighbors < 2:  # dies as if by underpopulation
            return False
        elif current_state and (alive_neighbors == 2 or alive_neighbors == 3):  # lives to the next generation
            return True
        elif current_state and alive_neighbors > 3:  # dies as if by overpopulation
            return False
        elif ~current_state and alive_neighbors == 3:  # becomes alive as if by reproduction
            return True
        else:
            return current_state

    def update_grid(self):
        # обновляем поле
        updated_grid = self.grid.copy()
        for row in range(updated_grid.shape[0]):  # shape() выводит колличество клеток  в строках/столбцах
            for col in range(updated_grid.shape[1]):
                updated_grid[row, col] = self.update_cell(row, col)

        self.grid = updated_grid

class Buttons:  # Класс кнопки
    def __init__(self, x, y, background_color):
        self.x = x
        self.y = y
        self.color = background_color

    def create_panel(self, width, height):  # Создание заднего фона для кнопки
        panel = pygame.Surface((width, height))
        panel.set_alpha(128)
        panel.fill(black)
        return panel

    def set_title(self, title):  # Получаем надпись которая будет на кнопке
        my_font = pygame.font.SysFont(font, font_size)
        text_surface = my_font.render(title, True, white)
        return text_surface

    def render(self, title_or_panel):  # Добавляем на экран полученную кнопку
        screen.blit(title_or_panel, (self.x, self.y))

# Главная функция
def main() -> None:
    pg.init()
    pygame.font.init()
    clock = pg.time.Clock()
    # Создание отображения состояние pause play
    button = Buttons(0, 0, black)
    panel = button.create_panel(1600, 60)
    pause_title = button.set_title('Pause')
    play_title = button.set_title('Play')

    game = GameOfLife()
    game.draw_grid()
    pg.display.update()
    pause = True
    running = True
    pg.event.set_allowed([pg.QUIT, pg.KEYDOWN, pg.MOUSEBUTTONDOWN])
    while running:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:  # Закрытие игрового окна на esc
                    running = False
                if event.key == pg.K_SPACE:  # Пауза/отжатие паузы на пробел
                    pause = not pause

        if pause:
            button.render(panel)
            button.render(pause_title)
        else:
            game.run()
            button.render(panel)
            button.render(play_title)
        clock.tick(10)
        pg.display.update()

        # Попытка реализоваться паузу

    pg.quit()

if __name__ == '__main__':
    main()

</code>


Почему перечисление строк CSV файла невозможно без предварительного указания файла и создания объекта reader, даже если ранее они были созданы
Мой код не отображает перечисление строк из CSV-файла без повторного указания на файл и создания объекта reader.

import csv
CSV_file = open('01.example.csv')
print(type(CSV_file))        #<class '_io.TextIOWrapper'>

CSV_file_reader = csv.reader(CSV_file)
print(type(CSV_file_reader)) #<class '_csv.reader'>

CSV_file_data = list(CSV_file_reader)
print(type(CSV_file_data))   #<class 'list'>
print(CSV_file_data)         #список списков

###CSV_file = open('01.example.csv')
###CSV_file_reader = csv.reader(CSV_file)
for row in CSV_file_reader:
    print(row)

не раскомментировав - работать не будет, хотя подобные строчки есть выше.
Полагаю, причина в строке
CSV_file_data = list(CSV_file_reader), но она не меняет переменную, а лишь интерпретирует её как список, так ведь?

Полагаю, причина в строке
CSV_file_data = list(CSV_file_reader), но она не меняет переменную, а лишь интерпретирует её как список, так ведь?

Нет, эта строка итерирует объект
CSV_file_reader, после чего его уже нельзя итерировать ещё раз в цикле
for.


Нет изображения python matplotlib
Подскажите, где можно посмотреть на изображение, которое выдаёт matplotlib?
Запускаю следующий код, но терминал пустой (без ошибок). Сохранять каждый раз - не вариант (но работает)
<code>
dataFile = open('./data_test_10.csv', 'r')
dataList = dataFile.readlines()
dataFile.close()

all_values = dataList[0].split(',')

image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))

plt.imshow(image_array, cmap='Greys', interpolation=None)

plt.savefig('123.jpg')
</code>

plt.imshow(image_array, cmap='Greys', interpolation=None)
plt.show()


Как вывести натуральные числа подряд и определить цифру на определенной позиции в Python?
У меня есть задача - нужно выписать натуральные числа от 1 до бесконечности подряд и определить, какая цифра будет на позиции 206787.

P.S Мне заблокировали вопросы и попросили их улучшить!

ну если не важно время и память, то можно сделать так:

text = ''
value = 1
while len(text) < 206787:
    text += str(value)
    value += 1

print(text[206787])

если же важны (а в задачах они важны) :), то придется делать так:
сначала идут 1циферные числа (9 штук), затем 2циферные числа (90 штук), затем 3циферные числа (900 штук), затем... вы заметили зависимость?
таким образом у вас получается задача состоящая из трех подзадач:

определение каким xциферным числом будет число на 206787 позиции

для этого надо в том же вольфрам альфа посмотреть формулу для суммы ряда

9 + 90 + 900 + ... = 9 * (10^0 + 10^1 + 10^2 + ... + 10^n)

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

дальше зная на каком знаке начинаются xциферные числа вычисляем какое по порядку xциферное число находится на 206787 позиции (вернее его цифра на этой позиции)

(206787 - позиция xциферного числа) / x

ну и дальше зная число легко получить и цифру на его позиции

(206787 - позиция xциферного числа) % x


Отправитель на кириллице
Как можно корректно передать имя отправителя на кириллице, данный код:

def send(self) -> None:
    if not self.checkParams():
        return

try:
    msg = MIMEMultipart('alternative')
    msg['Subject'] = self.__subject
    msg['From'] = self.__sender + ' <' + self.__emailAddress + '>'
    msg['To'] = ', '.join(self.__recipients)
    msg['Reply-To'] = self.__emailAddress
    msg['Return-Path'] = self.__emailAddress

    part_html = MIMEText(self.__massage, 'html')

    for file in self.__filePathList:
        if os.path.isfile(file):
            filepath = file
            basename = os.path.basename(filepath)
            filesize = os.path.getsize(filepath)
            part_file = MIMEBase('application', 'octet-stream; name="{}"'.format(basename))
            part_file.set_payload(open(filepath, "rb").read())
            part_file.add_header('Content-Description', basename)
            part_file.add_header('Content-Disposition', 'attachment; filename="{}"; size={}'.format(basename, filesize))
            encoders.encode_base64(part_file)
            msg.attach(part_file)

    msg.attach(part_html)

    mail = smtplib.SMTP_SSL(self.__server)
    mail.login(self.__emailAddress, self.__password)
    mail.sendmail(self.__emailAddress, self.__recipients, msg.as_string())
    mail.quit()

except Exception as e:
    print(e)

отлично отправляет письмо с кириллицей в теме или в теле сообщения, но стоит только указать кириллицу в отправителе, получается каша:

(550, b'your mailer sends invalid headers')

self.__sender + ' <' + self.__emailAddress + '>

собственно если я
self.__sender
принудительно переведу в кодировку utf-8, то нечего не измениться. Как только я не пробовал изворачиваться, с переменной
self.__sender, в итоге:

mail.sendmail(self.__emailAddress, self.__recipients, msg.as_string())

переменная
msg.as_string() выдаст белеберду. Может нужно как то прогнать через
MIMEText кириллицу?

Ответ был на поверхности - необходимо скопировать
msg.as_string() в строку и добавить в эту строку, в поле отправителя, то что желаете нужным на кириллице + почта отправителя, иначе будет 505 ошибка в запросе. Далее полученную строку, принудительно форматнуть в
utf-8 и ее же отформатированную отправить в

mail.sendmail(self.__emailAddress, self.__recipients, newFormatString)


Как оповестить юзера что он заблокирован Aiogram
Мне нужно чтобы мой бот блокировал юзера, но когда юзер пишет, бот отвечает "Вы были заблокированы администратором, если вы считаете что блокировка случайная и т.п. пишите сюда: @svelllll".
Обыскал весь интернет, не нашел, находит только как заблокировать пользователя что тоже самое что и черный список.

Ну так кидайте ID забаненого в список и пусть бот проверяет каждого кто пишет:
<code>
ban_list = [iD_for_ban]
async def send_help(message: types.Message):
    if message.from_user.id in ban_list:
        await message.reply('Вы забанены пишите сюда @svelllll')
</code>


Как реализовать алгоритм заполнения списка длиной N из чисел, не кратных 3
Нужна последовательность из N чисел, которые не делятся нацело на 3. Например, при

N = 10: [1, 2, 4, 5, 7, 8, 10, 11, 13, 14] (исключаем
3, 6, 9, 12 и т.д.).

1<=N<=10^6

N = int(input())
c = [x for x in range(1, N+1) if x % 3 != 0]

Изначально я просто попытался создать и заполнить список значениями, которые удовлетворяют условию, но столкнулся с проблемой, что при этом я потерял некоторые числа. При N = 10, вместо c[1, 2, 4, 5, 7, 8, 10, 11, 13, 14], я получил c[1, 2, 4, 5, 7, 8, 10]
Вопрос: Как реализовать алгоритм, который создает список длиной N и заполняет его значениями n, удовлетворяющими условию n % 3 != 0, без потери промежуточных чисел?

как я понимаю вам нужно
N чисел, которые не делятся на 3, поэтому тут помог бы бесконечный цикл
while, который бы шел до тех пор, пока нужное кол-во не будет достигнуто

res = []
value = 0

while True:
    if value % 3 != 0:
        res.append(value)
        if len(res) == N:
            break;
    value += 1

по идее можно сделать всё и за 1 цикл
for:

res = [v for v in range(M) if v % 3 != 0]

но тогда нужно вычислить
M, при котором будет набрано строго
N не делящихся на 3 чисел, типа:

M = N * 4 // 3 # Приближённая формула, точная учитывает делимость N на 3


Как ссылаться из класса на другой класс?
Бинарное дерево:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Tree:
    def insert():
        pass

Есть класс Node с параметрами и класс Tree. Как с Tree ссылаться на класс Node чтобы функция insert() принимало параметры с класса Node?
Правка:
Сделал ссылку через наследование:

class Tree(Node):
    def addItem(self, data):
        if data < self.data:
            if self.left is None:
                self.left = Tree(data)
            else:
                self.left.addItem(data)
        elif data > self.data:
            if self.right is None:
                self.right = Tree(data)
            else:
                self.right.addItem(data)

есть класс, есть экземпляр класса
в первом случае - это чертеж дома, во втором - построенный дом
в первом случае вам будет нужно наследование:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Tree(Node):
    def insert():
        pass

, во втором - передача экземпляра в качестве параметра метода:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Tree:
    def insert(node_element: Node):
        pass

Что конкретно вам нужно то?


Ошибка NameError: free variable 'li' referenced before assignment in enclosing scope
пытаюсь написать функцию с помощью генераторов списков для удаления дубликатов во входящем списке.
вместо результата выскакивает ошибка

NameError: free variable 'li' referenced before assignment in enclosing scope

Почему так происходит и как это исправить?

def del_dublicates(arr):
    li=[x for x in arr if x not in li]
    return li

    print(del_dublicates([5,9,102,5,6,78,9]))

у вас переменная
li будет инициализирована только после завершения формирования списка через цикл, а вы уже обращаетесь к ней в цикле, когда переменная еще не существует - поэтому и ошибка
можно модернизировать и работать с проверкой по старому списку формируя новый:

def del_dublicates(arr):
    li=[x for i, x in enumerate(arr) if arr[:i].count(x) == 0]
    return li

ну или вашим способом делайте в лоб тогда:

def del_dublicates(arr):
    li = []
    for x in arr:
        if x not in li:
            li.append(x)
    return li


Создание TUI на Python
Всех приветствую. Имеется 4 самостоятельных модуля на питоне, первые два выводят ликвидации, вторые два рыночные сделки с крипто биржи. Все 4 модуля работают по вебсокету.
Задача, реализовать их одновременную работу(С этим проблем нет) с одновременным выводом в приделах одного терминала, каждый модуль должен выводить свои данные в своей блок(Визуально).
Я пересмотрел множество либ для создания tui от curses до pytermui но везде одна проблема, виджеты, панели, окна, круто рисуются и выводят статический текст или список из заранее готовых переменных или словарей, но вебсокет льет данные постоянно. И мне не удалось(Возможно руки кривые =D ) заставить в рисуемые мной оконные модели засунуть вывод из вебсокета. А задача стоит, заставить это все работать именно из под терминала, без GUI.
Возможно я что-то еще не попробовал, а возможно, можно самим питоном как то в приделах одного терминала выводить данные в разные блоки? Любым наставлениям, ссылкам, "пинкам" буду рад!

Два окна, два потока сообщений:
<code>
import curses
import threading
import time

def make_log(lock, window, message, interval):

    def run():
        i = 0
        while True:
            lock.acquire()
            window.addstr(f'{i}: {message}\n')
            window.scrollok(1)
            window.refresh()
            lock.release()
            time.sleep(interval)
            i += 1

    return threading.Thread(target=run)

def main(stdscr):
    stdscr.clear()

    lock = threading.Lock()

    half_cols = curses.COLS // 2
    left_thread = make_log(
        lock,
        curses.newwin(curses.LINES, half_cols, 0, 0),
        'left message',
        0.1
    )
    right_thread = make_log(
        lock,
        curses.newwin(curses.LINES, curses.COLS - half_cols, 0, half_cols),
        'right message',
        0.2
    )

    left_thread.start()
    right_thread.start()

    left_thread.join()
    right_thread.join()

curses.wrapper(main)
</code>


Как принять несколько фото от пользователя в одном сообщении?
У меня есть бот который принимает одно фото от пользователя. Как принять от пользователя несколько фото? То есть в одном сообщение может быть n фотографий и после этого переслать это сообщение в закрытую группу. Можна ли такое вобще сделать? Как узнать что пользователь прислал больше одного фото? И можна ли принимать несколько документов в одном сообщении(pdf, doc, и тд)?

@rate_limit(0.5)
@dp.message_handler(IsPrivate(), content_types=['any'])
async def get_message(message: types.Message, album: List[types.Message]):
    if bool(album):
        media_group = types.MediaGroup()
        for obj in album:
            if obj.photo:
                file_id = obj.photo[-1].file_id
            else:
                file_id = obj[obj.content_type].file_id
            try:
                media_group.attach({"media": file_id, "type": obj.content_type})
            except ValueError:
                return await message.answer("This type of album is not supported by aiogram.")
        await bot.send_media_group(private_group, media_group)
    elif message.photo:
        information_the_user = ''
        caption = ''
        if message.caption is not None:
            caption += f'{message.caption}\n\n'
        if message.from_user.last_name is not None:
            information_the_user += f'Last_name: {message.from_user.last_name}\n'
        if message.from_user.username is not None:
            information_the_user += f'Username: @{message.from_user.username}\n'
        await bot.send_photo(private_group, photo=message.photo[-1].file_id,
                             caption=f'{caption}'
                                     f'First_name: {message.from_user.first_name}\n'
                                     f'{information_the_user}'
                                     f'id: {message.from_user.id}')
        data_id.add_message_id(message.chat.id, message.message_id)

Пробуйте

import asyncio

from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import StatesGroup, State
from aiogram.dispatcher.handler import CancelHandler
from aiogram.dispatcher.middlewares import BaseMiddleware
from aiogram.types import InputMedia

import config

bot = Bot(token=config.BOT_TOKEN)
dp = Dispatcher(bot, storage=MemoryStorage())

class AlbumMiddleware(BaseMiddleware):
    """This middleware is for capturing media groups."""

    album_data: dict = {}

    def __init__(self, latency: int | float = 0.01):
        """
        You can provide custom latency to make sure
        albums are handled properly in highload.
        """
        self.latency = latency
        super().__init__()

    async def on_process_message(self, message: types.Message, data: dict):
        if not message.media_group_id:
            return

        try:
            self.album_data[message.media_group_id].append(message)
            raise CancelHandler()  # Tell aiogram to cancel handler for this group element
        except KeyError:
            self.album_data[message.media_group_id] = [message]
            await asyncio.sleep(self.latency)

            message.conf["is_last"] = True
            data["album"] = self.album_data[message.media_group_id]

    async def on_post_process_message(self, message: types.Message, result: dict, data: dict):
        """Clean up after handling our album."""
        if message.media_group_id and message.conf.get("is_last"):
            del self.album_data[message.media_group_id]

@dp.message_handler(content_types=['photo', 'audio', 'video', 'document'])
async def get_message(message: types.Message, album: list[types.Message] = None):
    if not album:
        album = [message]

    media_group = types.MediaGroup()
    for obj in album:
        if obj.photo:
            file_id = obj.photo[-1].file_id
        else:
            file_id = obj[obj.content_type].file_id
        try:
            if obj == album[-1]:
                media_group.attach(InputMedia(media=file_id,
                                              type=obj.content_type,
                                              caption=f'{album[0].caption}'
                                                      f'First_name: {message.from_user.first_name}\n'
                                                      # f'{information_the_user}'
                                                      f'id: {message.from_user.id}',
                                              parse_mode="html"))
            else:
                media_group.attach(InputMedia(media=file_id, type=obj.content_type))
        except ValueError:
            return await message.answer("This type of album is not supported by aiogram.")

    await bot.send_media_group(message.chat.id, media_group)

if __name__ == '__main__':
    dp.middleware.setup(AlbumMiddleware())
    executor.start_polling(dp, skip_updates=True)


В зависимости от введенного числа, программа должна корректно подставлять окончание для слов python
<code>
n = int(input('enter n: '))
if n%10== 1:
    print(n,"компьютер")
elif (n%10==2 or n%10==3 or n%10==4):
    print(n,"компьютера")
else:
    print(n,'компьютеров')
</code>
при n=12/13/14 должно быть компьютеров

ну так словами запишите алгоритм
3 формы - 1) компьютер 2) компьютера 3) компьютеров

если последние 2 цифры в диапазоне от 10 до 19 - 3 форма
если последняя цифра от 5 до 9 или 0 - 3 форма
если последняя цифра от 2 до 4 - 2 форма
если последняя цифра 1 - 1 форма

т.е.

if n % 100 >= 10 and n % 100 < 20 or n % 10 > 4 or n % 10 == 0:
    print('ов')
elif n % 10 == 1:
    print('')
else:
    print('a')

можно покомпактнее

if (n % 100) % 10 == 1 or n % 10 > 4 or n % 10 == 0:
    print('ов')
elif n % 10 == 1:
    print('')
else:
    print('a')


Как получить остаток в Питоне?

Напиши программу, которая принимает два целых числа: количество коллег и задач.
Программа должна вывести два целых числа:
• количество задач, которые достанутся каждому коллеге;
• остаток задач, которые перейдут главному в команде.
Пример 1: Пользователь ввёл:
3
6
Программа должна вывести:
2
0

<code>
s1 = int(input())
s2 = int(input())
s3 = s2//s1
s4 = s3//s2
print(s3)   #сдесь ошибка может тут нужен %, или, как то по-другому.
print(s4)
</code>
что нужно добавить, что вывести остаток.

Вот ответ:
<code>
s1 = int(input())
s2 = int(input())
s3 = s2 // s1
s4 = s2 % s1 # поменяла // на %
print(s3)
print(s4)
</code>
a % b - таким образом можно получить остаток от деления а на b
В s3 просто делим нацело
В s4 получаем остаток


Как передать данные из мобильного приложения в Telegram Bot / Django сайт?
Помогите, пожалуйста, начинающему разобраться)
Есть программа, написанная под Android, которая генерирует текстовые данные.
Меня интересует, каким образом можно реализовать передачу этих данных в телеграм бота на другом мобильном устройстве?
Я не могу разобраться какую БД для этого использовать? И возможно ли вообще это сделать, так как в сети, о связке Kivy App-БД-Telegram Bot, ничего нету.
Может лучше использовать Django REST, для такой цели, тогда пользователь сможет просмотреть данные на сайте?
Извините за глупые вопросы, спасибо за ответы!

В данном случае мобильное приложение выступает в роли клиента и хранить в нём ничего нельзя. Это приложение должно взаимодействовать с сервером (бэкэндом), например, на том же Django. Далее, эти данные уже можно различными способами запрашивать на стороне телеграм-бота.
Первый вариант такой - бэкэнд приложение, написанное на Django для обслуживания мобильного приложения будет совмещено с телеграм-ботом, то есть, иметь одну базу данных и запускаться в разных потоках. Это более простой и прямой путь. Будет использована одна база данных для обоих приложений, более подойдёт для маленьких или учебных проектов.
Второй вариант - разделить приложения, веб-сервер отдельно, а телеграм-бот отдельно, тогда на стороне бота нужно будет запрашивать данные у сервера мобильного приложения. Это более сложный подход, будут использоваться разные базы данных и разные приложения, нужно писать дополнительный API для взаимодействия между сервисами. Он более правильным будет для больших проектов.


Помогите составить уравнение на python
Напиши программу, которая вычисляет значение функции
f(a, b) = 7(a + b)3 – 5a2 + 3b – 1
по введённым целым значениям a и b.
Пример 1: Пользователь ввёл:
1
2
программа выводит 189
<code>
a = int(input())
b = int(input())
c = 7*(a+b)**3
x = (-5*a)**2
z = 3*b
v = -1
print(с-x+z+v)
</code>
У меня постоянно 169, не могу понять как это сделать.

У вас три ошибки:

в квадрат нужно возводить только
a, а не
-5*a
все слагаемые нужно складывать, а вы второе вычитаете, думаю, это вы пытались так компенсировать первую ошибку
у вас в итоговой формуле буква
c русская, при исполнении кода будет ошибка

Итого, исправленный код, дающий правильный ответ:

a = int(input())
b = int(input())
c = 7*(a+b)**3
x = -5*a**2    # <-- эта строка исправлена
z = 3*b
v = -1
print(c+x+z+v) # <-- и эта исправлена


Как передать данные основному процессу, чтобы GUI не зависало?
У меня есть код, который циклически обновляет окно (таймер), также каждую секунду происходит длинное действие, которое замораживает графический интерфейс. Мне нужно передавать информацию из процесса/потока в основной процесс/поток так, чтобы интерфейс не зависал.
Я пробовал
threading,
multiprocessing.Pipe,
multiprocessing.Queue,
multiprocessing.managers.SharedMemoryManager, но всё это вызывало зависание интерфейса.
Есть ли способы это исправить?
Код:

import time
import sys
# from multiprocessing import Process
# from multiprocessing.managers import SharedMemoryManager
import random
from PyQt6.QtCore import QTimer, Qt
from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout

sec = 0

class Timer(QWidget):

    def __init__(self):
        super().__init__()

        self.time_ = 0
        self.timer = QLabel(str(time))
        self.timer.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.timer)
        QTimer.singleShot(1, self.timer_fun)
        QTimer.singleShot(1, long_action)

    def timer_fun(self):
        self.time_ += 1
        self.timer.setText(f'{self.time_}, long action: {sec}')
        QTimer.singleShot(1000, self.timer_fun)

def long_action():
    global sec
    # Какое-то долгое действие:
    sec = random.randint(1, 50) / 10
    time.sleep(sec)

    long_action()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Timer()
    window.show()
    app.exec()

Сделаем ход конём: создадим функцию в потоке, которая будет запускать процессы с долгими вычислениями:
<code>
import time
import sys
import random
from PyQt6.QtCore import QTimer
from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout
from threading import Thread
from multiprocessing import Process
from multiprocessing.managers import SharedMemoryManager
sec = 0

class Timer(QWidget):

    def __init__(self):
        super().__init__()

        self.time_ = 0
        self.timer = QLabel(str(time))

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.timer)
        QTimer.singleShot(1, self.timer_fun)
        # QTimer.singleShot(1, long_action)

    def timer_fun(self):
        self.time_ += 1
        self.timer.setText(f'{self.time_}, long_action: {sec}')
        QTimer.singleShot(1000, self.timer_fun)

def long_action(shared):
    # Какое-то долгое действие:
    shared[0] = random.randint(1, 10) / 10
    time.sleep(shared[0])

def long_action_caller():
    global sec
    with SharedMemoryManager() as smm:
        # Создаём большое значение, которое не должно быть меньше чем sec, т. к. память создаётся фиксированного размера
        shared = smm.ShareableList([200 * 100])
        while True:
            p = Process(target=long_action, args=(shared,))
            p.start()   # Запускаем процесс
            p.join()    # Ждём его завершения
            sec = shared[0]  # Присваиваем значение переменной

if __name__ == '__main__':
    Thread(target=long_action_caller, daemon=True).start()  # Демон для того, чтобы не было бесконечного AttributeError
    app = QApplication(sys.argv)
    window = Timer()
    window.show()
    app.exec()

</code>


Как получить значения ключа json?
У меня есть json файл:

"123": {"Имя": "Абоба", "фамилия": "Биба"}

Мне нужно получить значение ключа "фамилия" через python.
Ну то есть я понимаю это:

with open("test.json", "r", encoding='utf-8') as file:
    data = json.load(file)

Что сделать с data, чтобы получить значение "фамилия"?

для начала json должен выглядеть так:

{"123": {"Имя": "Абоба", "фамилия": "Биба"}}

напрямую можно получить так:

value = data["123"]["фамилия"]

если же вам надо получить значения для всех ключей:

for value in data.values():
    print(value["фамилия"])


Почему передается неправильное значение аргументов в поток?
Уважаемые!
Пишу для себя, начал немного разбираться в потоках.
возникла ошибка неправильного количества передаваемых аргументов.
На мой взгляд, всё выглядит логично, но как решить данную проблему, не очень могу понять а именно:
есть функция сканирования СОМ портов.

def scan_ttyusb():
    ports = list(serial.tools.list_ports.comports())
    result = ""
    for text in ports:
        if 'Pcui' in text[1]:
            txt = text[0]
            result = result + txt + ','
            device_port = result

    return device_port.split(",")

Она возвращает мне строку примерно такого вида:

[/dev/ttyUSB7],[/dev/ttyUSB2]

далее, я объявляю поток и передаю ему нужные аргументы

if __name__ == '__main__':
    plate1 = scan_ttyusb()[0]
    print(plate1 + " Это первая плата")
    plate2 = scan_ttyusb()[1]
    print(plate2 + " Это вторая плата")
    thread1 = Thread(target=runing_scan, args=plate1)
    thread2 = Thread(target=runing_scan, args=plate2)

    start = time.time()
    thread1.start()
    thread2.start()
    thread1.join()
    end = time.time()
    print("Время работы потока 1: " + time.strftime("%M:%S", time.gmtime(end - start)))
    thread2.join()
    end2 = time.time()
    print("Время работы потока 2: " + time.strftime("%M:%S", time.gmtime(end2 - start)))

на что получаю ошибку в виде:

Traceback (most recent call last):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 953, in run
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
TypeError: runing_scan() takes 1 positional argument but 12 were given
    self._target(*self._args, **self._kwargs)
TypeError: runing_scan() takes 1 positional argument but 12 were given

то есть логически я понимаю, что

/dev/ttyUSB2 - 12 символов
и

/dev/ttyUSB7 - 12 символов.
отсюда возникает вопрос, как правильно передать значение.
Если вызывать функцию ручками:

runing_scan(plate1)

то всё отлично работает
Вопрос конечно легкий и тупой, но я не знаю как его решить.
Буду очень признателен, за разъяснение моей ошибки или хотя бы подсказки в какую сторону рыть.

Скорее всего поможет передача аргументов в виде списка из одного элемента:
<code>
    thread1 = Thread(target=runing_scan, args=[plate1])
    thread2 = Thread(target=runing_scan, args=[plate2])
</code>
Просто тут на вход ожидается кортеж или список аргументов и когда вы передаёте строку, то она итерируется и передаётся список символов этой строки в качестве аргументов. А если передать список или кортеж, то всё будет нормально - аргументы возьмутся из этого списка.


Не работает второй/третий/... хендлер, а только первый
Почему срабатывает только первый хендлер?
<code>
@dp.message_handler()
async def get_messages(message: types.Message):
    # some code 1

@dp.message_handler(content_types="text")
async def get_messages2(message: types.Message):
    # some code 2

@dp.message_handler(text="some-text")
async def get_messages3(message: types.Message):
    # some code 3
</code>

Ответ подходит как для
aiogram так и для
pytelegrambotapi(telebot).
Итак. Этот хендлер

@dp.message_handler()

имеет фильтры по-умолчанию
content_types="text" и
state=None(только Aiogram). Потому любые сообщения типа текст, будут в нём, и любой другой хендлер ниже не будет даже проверяться, так как происходит следующее.
Юзер отправляет сообщение или нажимает на инлайн кнопку, сообщение попадает в бот и проходит по всем хендлерам в порядке регистрации (то бишь первый регистрированный первым и провериться), и если фильтры подходят и выдают
True то хендлер срабатывает и дальнейшие хендлеры игнорируются.
Чтобы не было таких казусов нужно хендлеры с пустыми фильтрами (или же таким же как и по-умолчанию) ставить в самый низ регистрации. По факту просто вырезать и вставить в конце кода.
К примеру чтобы код в вопросе работал нужно два первых хендлера слить в один и поставить ниже третьего.

@dp.message_handler(text="some-text")
async def get_messages3(message: types.Message):
    # some code 3

@dp.message_handler()
async def get_messages(message: types.Message):
    # some code 1/2

Полностью аналогичная ситуация и для колбек хендлеров.


Помогите пожалуйста с поиском в матрице на python
Поиск из массива
Вам дана матрица n * m, проверьте, что эта матрица содержит s строк слов, образованных путем объединения последовательных букв по оси x или оси y.
Входные данные:
В первой строке n и m(1≤n,m≤100)) вводятся натуральные числа.
В следующих n строках вводятся m букв, разделенных пробелами. В следующей строке записано количество тестов k ( 1001≤k≤100). Для каждого теста вводится отдельная строка.
Выходные данные:
Для каждого теста выведите «да», если это слово можно найти в матрице, иначе «нет» (в отдельных строках). Проверить можно только по вертикали и горизонтали по прямой.
<code>
Примеры
#   ввод.txt    вывод.txt
1               да
5 6             нет
absdef          нет
pruhpg          да
pliyqt          да
lkgrfk
epqtgo
5
apple
bar
ari
def
el
</code>

берете очередное слово (подстроку),
сначала в каждой строке матрицы ищите подстроку и так для каждого слова. Потом транспонируете матрицу и выполните то же самое(теперь вы фактически ищите в столбцах).
Это самый быстрый способ, с точки зрения реализации, на моей взгляд.
Также вам следует уточнить, считается ли слово найденным, если оно записано справа налево


Фиксация изменяющейся переменной класса для цикла python
Возникла проблема при создании класса: все экземпляры класса должны работать с одним аттрибутом класса:

class xpos:
    position = 0
    def __init__(self, posi):
        xpos.position = posi

    def __getitem__(self, index):
        return range(xpos.position)[index]

    def goleft(self, x0=1):
        xpos.position -= x0

Также есть два метода класса, изменяющих эту глобальную переменную, и индексирование:
Но если использовать этот массив в цикле, изменяя глобальную переменную, необходимо зафиксировать последнее значение позиции, чтобы пробежаться по всем значениям и не завершить его раньше времени, тем самым при

xx = xpos(15)
yy = xpos(5)  #xpos.position = 5

for i in xx:
    yy.goleft()

Ожидаем получить
xpos.position = 0
Как этого возможно добиться?

А, кажется, понял. Так реализуйте метод
__iter__, и тогда
for не будет обращаться к индексации, а возьмёт итератор один раз и ничего не сломается в процессе итерирования:

    def __iter__(self):
        return iter(range(xpos.position))

Я так понимаю, индексация - это запасной метод, если итератор нельзя у объекта взять, тогда для итерирования используется индексация. А в нормальной ситуации берётся итератор и дальше объект уже не дёргается лишний раз, а это как-раз то, что вам нужно.


При удалении элемента из списка удаляется следующий
Список не изменял. Принт выводит правильную индексацию, но при попытках удалить элемент, индекс перескакивает на 1 вперёд.

n=int(input())
jos=list(range(1,n+1))
print (jos[0],jos[1],jos[2],jos[3])
jos.pop(jos[1])
print(jos)

вывод:

10
1 2 3 4
[1, 2, 4, 5, 6, 7, 8, 9, 10]

Пользуйтесь на здоровье, рекомендую вам хотя бы гуглить метод перед тем как задавать вопрос.
<code>
num = int(input())
l = list(range(1, num+1))

print(l[0], l[1], l[2], l[3])
l.pop(1)
print(l)
</code>


Пытаюсь улучшить обработчик ошибок
Код реагирования на возникшие ошибки у меня выглядит так:
<code>
@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.BadArgument):
        await ctx.message.delete()
        await ctx.send(embed = TYPE_ERROR, delete_after = C)
    if isinstance(error, commands.MissingPermissions):
        await ctx.message.delete()
        await ctx.send(embed = PERM_ERROR, delete_after = C)
    if isinstance(error, commands.CommandNotFound):
        await ctx.message.delete()
        await ctx.send(embed = NOFD_ERROR, delete_after = C)
    if isinstance(error, commands.MissingRequiredArgument):
        await ctx.message.delete()
        await ctx.send(embed = REQA_ERROR, delete_after = C)
</code>
И мне он кажется крайне неуклюжим. Хотелось бы узнать каким образом можно это улучшить.

Соберите пары в таблицу соответствия и переберите её:
<code>
com_err = [
    (commands.BadArgument, TYPE_ERROR),
    (commands.MissingPermissions, PERM_ERROR),
    (commands.CommandNotFound, NOFD_ERROR),
    (commands.MissingRequiredArgument, REQA_ERROR)
]

@bot.event
async def on_command_error(ctx, error):
    for com, err in com_err:
        if isinstance(error, com):
            await ctx.message.delete()
            await ctx.send(embed = err, delete_after = C)
</code>


Сортировка списка словорей по ключу python
Есть список словарей:

[
    {
        "object": "apple", <<<
        "count": 10
    },
    {
        "object": "banana",
        "count": 11
    },
    {
        "object": "apple", <<<
        "count": 5
    }
]

Теперь мы хотим изменить последовательность списка так, чтобы рядом стояли словари, в которых значение ключа
"object" совпадает:

[
    {
        "object": "apple", <<<
        "count": 10
    },
    {
        "object": "apple", <<<
        "count": 5
    },
    {
        "object": "banana",
        "count": 11
    },
]

sort с соответствующим ключом:

lst = [
    {
        "object": "apple",
        "count": 10
    },
    {
        "object": "banana",
        "count": 11
    },
    {
        "object": "apple",
        "count": 5
    }
]

lst.sort(key=lambda x: x['object'])
print(lst)

Вывод:

[{'object': 'apple', 'count': 10},
 {'object': 'apple', 'count': 5},
 {'object': 'banana', 'count': 11}]


Как найти произведение столбца в двумерном массиве на Python
Предположил что делается так, но оказался не прав, вообще суть задания - найти найменьшее проивзедение столбцов.
<code>
n=int(input('Введите кол-во строк матрицы: '))
matrix=[]
for i in range(n):
    matrix.append(list(map(int,input('Введите матрицу, содержащую только положительные числа:').split())))
print(matrix)
minimum=1000000000
for i in matrix:
    for j in i:
        if matrix[i][j]*matrix[i+1][j]<minimum :
            minimum=matrix[i][j]*matrix[i+1][j]
print(minimum)
</code>

Упрощаем, пишем функцию для поиска произведения членов списка, конкретно для данной задачи для одного столбца

import math

def column_mul(matrix, number):
    """Возвращает произведение членов столбца с номером number"""
    column = [row[number] for row in matrix] # столбец с номером number
    return math.prod(column)

Далее используем данную функцию для количества столбцов и храним результат в переменной
mul_all_columns, а затем используем метод
min

mul_all_columns = []
for i in range(len(matrix)):
    mul_all_columns.append(column_mul(matrix, i))

minimum = min(mul_all_columns)

либо можно сократить до одной строки

minimum = min(column_mul(matrix, i) for i in range(len(matrix)))

также можно и максимум найти

maximum = max(column_mul(matrix, i) for i in range(len(matrix)))


Задача используя цикл for
Решаю задачу можно где можно использовать только цикл for.
При вводе большого числа  в d(сколько драконов было всего), код долго считает и сайт с проверкой решения выводит ошибку, не понимаю как это можно исправить.
«Раз дракон. Два дракон. Три дракон», — считала принцесса. У нее была бессонница, а считать барашков ей надоело еще в девять лет.
Впрочем, считать драконов просто так тоже было скучно, поэтому она развлекалась как могла. Этой ночью она представляла, что все посчитанные драконы явились сюда, чтобы ее украсть, а она отбивается от них, как может. Каждого k-ого дракона она била сковородкой по морде. Каждому l-ому — прищемляла хвост балконной дверью. Каждому m-ому — наступала на лапу острым каблучком. Наконец, каждому n-ому она грозила позвать мамочку, и он в ужасе ретировался.
Скольким воображаемым драконам успела нанести моральный или физический ущерб принцесса, если всего она насчитала d драконов?
Входные данные
Входные данные содержат целые числа k, l, m, n и d, каждое число в отдельной строке (1 ≤ k, l, m, n ≤ 10, 1 ≤ d ≤ 105).
Выходные данные
Выведите количество пострадавших драконов.
<code>
k=int(input())
l=int(input())
m=int(input())
n=int(input())
d=int(input())
spis=list()
if k==1 or l==1 or m==1 or n==1 or d==1:
    print(d)
elif k>d or l>d or m>d or n>d:
    print(0)
else:
    for i in range(1, d+1):
        spis.append(i)
    for i in range(1, d+1, k):
        if i in spis:
            spis.remove(i)
    for i in range(1, d+1, l):
        if i in spis:
            spis.remove(i)
    for i in range(1, d+1, m):
        if i in spis:
            spis.remove(i)
    for i in range(1, d+1, n):
        if i in spis:
            spis.remove(i)
    print(d-len(spis))
</code>

можно ли считать это решением решением через
for?

res = len([1 for i in range(1, d + 1) if any(i % j == 0 for j in (k, l, m, n))])

вот только
for:

res = len([1 for i in range(1, d + 1) if sum(i % j == 0 for j in (k, l, m, n)) > 0])

или только с 1
for:

res = sum(i % k == 0 or i % l == 0 or i % m == 0 or i % n == 0 for i in range(1, d + 1))


Как передать в функцию call: types.CallbackQuery и message: types.Message?
<code>
@dp.callback_query_handler()
async def send_random_value(message: types.Message, call: types.CallbackQuery):
    arr=["C:\парсинг\disss\Капча верефикация\captcha.png", "C:\парсинг\disss\Капча верефикация\captcha1.png", "C:\парсинг\disss\Капча верефикация\captcha2.png", "C:\парсинг\disss\Капча верефикация\captcha3.png", "C:\парсинг\disss\Капча верефикация\captcha4.png", "C:\парсинг\disss\Капча верефикация\captcha5.png", "C:\парсинг\disss\Капча верефикация\captcha6.png", "C:\парсинг\disss\Капча верефикация\captcha7.png", "C:\парсинг\disss\Капча верефикация\captcha8.png", "C:\парсинг\disss\Капча верефикация\captcha9.png", "C:\парсинг\disss\Капча верефикация\captcha10.png" ] # or imagefileid
    photo=open(random.choice(arr), "rb")
    await bot.send_photo(message.from_user.id, photo)
    if message.text  == 12:
        await bot.send_message(message.from_user.id, 'Правильно, вот ваша ссылка: ')
    else:
        await bot.send_message(messsage.from_user.id, 'Неправильно, попробуйте снова')
</code>
Вот мой код, и он должен проверять кол-во символом в капче.
Я почти уверен, что у меня многое неправильно, но начало есть.
Проблема в том, что я не могу получить текст пользователя без message: types.Message, а без call нельзя получить message.text
Подскажите как решить проблему

Ваш ответ на вопрос: никак.

Вы здесь используете обработчик коллбэков, и декоратор dp.callback_query_handler() используется именно для этого вопроса, то есть, допустим, обработка callback для какой-либо кнопки.

Советую Вам сначала принять текст от пользователи декоратором dp.message_handler() либо использовать состояния, если у нас четкие шаги.

После принятия сообщения обработать его.

Если Вы обрабатываете здесь кнопку, то вы даже не указали данные коллбэков.
Приведенный ниже код по сообщению "капча" от пользователя выполняет вашу задачу:
<code>
@dp.message_handler(lambda message: message.text and message.text == "капча")
async def text_handler(message: types.Message):
    arr=["C:\парсинг\disss\Капча верефикация\captcha.png", ...]
    photo=open(random.choice(arr), "rb")
    await bot.send_photo(message.from_user.id, photo)
    if message.text  == 12:
        await bot.send_message(message.from_user.id, 'Правильно, вот ваша ссылка: ')
    else:
        await bot.send_message(messsage.from_user.id, 'Неправильно, попробуйте снова')
</code>


Как изменить сообщение disnake
Мне нужно отредактировать сообщение через
disnake. Уверен что это крайне легко но у меня не получается.

message = await inter.response.send_message(embed = k, delete_after = 5)
await asyncio.sleep(1)
await disnake.message.edit(embed = n)
await asyncio.sleep(1)
await disnake.message.edit(embed = res)

Можно сделать так:
<code>
await inter.edit_original_response(embed = n) #изменяет сообщение.
await asyncio.sleep(1) #ждём
await inter.edit_original_response(embed = res) #изменяем ещё раз.
</code>


Какой метод открытия картинок практичнее в aiogram?

photo = open("files\screen.png", "rb")

Или

with open("files\screen.png", "rb") as file:
    photo = file.read()

Возможно даже есть лучше и правильнее вариант открытия картинок?

Этот
<code>
from aiogram.types import InputFile
photo = InputFile("pathtoimg.ext")
</code>


Подключение функции к боту
Я пытаюсь сделать в своем боте функцию поиска айди по юзернейму в тг. Код я уже написал и он работает:

from telethon.sync import TelegramClient
def get_user(username):
    API_ID = айди
    API_HASH = "хеш"
    client = TelegramClient('назв приложения', API_ID, API_HASH)
    client.connect()
    user = client.get_peer_id(username)
    return user

ids = get_user("@айди")
print(ids)

Работает это через мое приложение, и токен моего бота. Однако при подключении к боту при абсолютно аналогичном коде получаю ошибку

File "C:\Users\Alex\PycharmProjects\osint\venv\lib\site-packages\telethon\client\telegrambaseclient.py", line 473, in loop
  return asyncio.get_event_loop()
File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\asyncio\events.py", line 642, in get_event_loop
  raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'WorkerThread2'.

Сам код внутри бота выглядит так(использую библиотеку telebot):

@bot.message_handler(content_types=["text"])
def text_message(message2):
    if (message2.text)[0] == "@":
        bot.send_message(message2.chat.id, f"Начинаем поиск по тг {message2}")
        from telethon.sync import TelegramClient

        def get_user(username):
            API_ID = айди
            API_HASH = "хеш"
            client = TelegramClient('название приложения', API_ID, API_HASH)
            client.connect()
            user = client.get_peer_id(username)
            return user

        ids = get_user(message2.text)
        print(ids)

Я подозреваю, что Вы просто не в том потоке. Смотрите тут написано что аннотация
@bot.message_handler позволяет функции обрабатывать сообщения. Но в ошибке Вам пишут

There is no current event loop in thread 'WorkerThread2'

Что явно намекает на то, что Вы просто работаете не в том потоке, в котором есть цикл обработки сообщений. Ведь что бы Ваше сообщение пришло в функцию, помеченную аннотацией, в потоке должен быть цикл обработки сообщений.


Что означают параметры relax и timeout в методе start_pooling из библиотеки aiogram?
Бот выдавал такую ошибку
cannot connect to host api.telegram.org:443 ssl:default [network is unreachable] и при изменении параметров увидел, что если timeout=250, relax=0.5, то перестает выдавать такую ошибку. Не нашел в документации информации о сути этих параметров.
Как я понял timeout - это время ожидания от сервера, а про relax догадок нет.
Так же находил в интернете способы исправить данную ошибку через изменение в библиотеке - данный способ не привел к изменению

Вот в одном иссью на гитхабе нашёл:

dispatcher.start_polling() has a
relax parameter, which regulates frequency of polling requests.

Судя и по названию, и по описанию, этот параметр задаёт задержку между запросами. Там ещё дальше упоминается, что она в секундах:

However, there is no way to set it to something other then default 0.1 s.

Потом там было сделано изменение в коде, которое даёт доступ к этому параметру.
Ну а
timeout везде одно и тоже означает - сколько максимум ждать ответа, чтобы ожидание не оказалось вечным.


Нужна помощь с кортежами и словарями Python
Вводится список названий городов в одну строку через пробел. Перебрать все эти названия с помощью цикла for и определить, начинается ли название следующего города на последнюю букву предыдущего города в список. Если последними встречаются буквы 'ь', 'и', то берется следующая с конца буква слова. Вывести на экран ДА, если последовательность удовлетворяет правилу, и НЕТ – иначе. Вот такая задача, не понимаю как ее сделать. Помогите

<code>
cities_string = "Харків Воронеж"
cities = (c.strip("ь").strip('і') for c in cities_string.split())
letter = next(cities)[-1]

for c in cities:
    if c[0].lower() != letter:
        print("НЕТ")
        break
    letter = c[-1]
else:
    print("ДА")
</code>
П.С. В этом решении нет кортежей.


Не работает функция с циклом for в Python
Я новичок. Очень прошу Вашей помощи.
Есть цикл:

for dictionary in formattedData:
    if "stock_id" in dictionary:
        stock_id.append(dictionary["stock_id"])

Все работает. Список stock_id выводится корректно, со всеми нужными элементами. Заранее объявил переменную stock_id = [] .
Пытаюсь его оформить в функцию:

def values(keyname, data):
    for i in data:
        if str(keyname) in i:
            keyname.append(i[str(keyname)])
    return keyname

После
values(stock_id, formattedData)
вывожу stock_id - он пустой.
Укажите, пожалуйста, где ошибка, чтобы я понимал. Бьюсь уже целый день. Заранее спасибо.

Нет, так не получится. Объекты не знают, как называется переменная, которой присвоили ссылку на них. И
str делает не то, что вы пытаетесь сделать, это не
nameof из
C#:

stock_id = []
print(str(stock_id))

Вывод:

[]

Вам придётся в явном виде указывать и объект и название ключа словаря, хотя вам и кажется, что они по виду одинаковые и должно быть легко получить одно из другого:

def values(lst, keyname, data):
    for i in data:
        if keyname in i:
            lst.append(i[keyname])
    return keyname

Вызывать, соответственно, так:

result = values(stock_id, "stock_id", formattedData)

Но вообще если вы тут "с нуля" формируете этот список, то вам его и не нужно вообще передавать в функцию, просто сформируйте списковое сокращение и присвойте в нужную переменную:

def values(keyname, data):
    return [i[keyname] for i in data if keyname in i]

stock_id = values("stock_id", formattedData)

P.S. Вернее, в питоне всё же есть способы узнать имя переменной во время выполнения кода, но они не такие уж тривиальные.
P.P.S. Вы можете сделать словарь с результатами и работать в нём со списками по вашему ключу, никто не заставляет вас использовать отдельные переменные:

from collections import defaultdict

def values(result, keyname, data):
    for i in data:
        if keyname in i:
            result[keyname].append(i[keyname])

result = defaultdict(list)
values(result, "stock_id", formattedData)
values(result, "что-то_ещё", formattedData)
print(result)


Как спускаться вглубь словаря python с неизвестным количеством веток?
Нужно создать словарь: {'дом': {'окно': None}, 'озеро': None}.
Имея строки с "путями": ['дом/окно', 'озеро'].
Но мы не знаем сколько ветвей "спуска", чтобы указать ключи ['дом']['окно'].
Как можно создать/читать словарь python имея лишь строку с путём?

Сделайте рекурсию и используйте метод
update:

paths = ['дом/окно/стекло', 'озеро/вода', "42"]

def nested(a:str, sep:str):
    if sep not in a:
        return {a: None}
    key, val = a.split(sep, 1)
    return {key: nested(val, sep)}

res = {}
[res.update(nested(x, "/")) for x in paths]
print(res)

{'дом': {'окно': {'стекло': None}}, 'озеро': {'вода': None}, '42': None}


Здравствуйте, помогите решить задачу бинарным поиском на python
Наткнулся на задачу:
Программа судей задумывает число N(1 ≤ N ≤ 109). Ваша программа должна будет найти число, которое задуманное программой судей за максимум 100 запросов. В каждом запросе ваша программа входит в программу жюри “? X“(где X(1 ≤ X ≤ 109) - целое число), в ответ на это программа жюри выведет значение (
X mod N) в вашу программу.
При завершении ваша программа должна вывести число, которое задумали судьи в формате "! X"
Входные данные:
В ответ на каждый ваш запрос сделанный с помощью знака ? программа судей для данного вами числа X возвращает значение
X mod N  соответственно.
Выходные данные:
Воспользовавшись максимум ста запросами найдите число, задуманное судьями.
Напоминание: Для того чтобы судьи могли принимать ваши ответы от интерактивной задачи в конце каждого запросы вы должны

Если используете язык ПАСКАЛЬ: `flush(output)`
Если используете язык C/C++: `fflush(stdout) или cout.flush()`
Если используете язык JAVA: `System.out.flush()`
Если используете язык PYTHON: `sys.stdout.flush()`
Если используете язык С#: `Console.Out.Flush()`

Использовать одну из вышеперечисленных команд!
Примеры

input.txt   output.txt
1           ? 10
2           ? 8
0           ? 4
0           ! 4

я пробовал решить вот так:

import sys
maxnumber = 10000000000
l = -1
k = maxnumber

print("? "+str(maxnumber))
sys.stdout.flush()
first = int(input())

while l+1<k:
    mid = int((l+k)/2)
    print("? "+str(mid))
    sys.stdout.flush()
    b = int(input())
    if b == 0:
        if (maxnumber-first)%mid == 0:
            print("!" + str(mid))
    else:
        k = mid

но получаю timelimit
Значит программа где-то не может пройти?

Экспоненциальный поиск с удвоением шага (n- загаданное число)
<code>
maxnumber = 10000000000
k = 1
n = 348

while True:   #while k < maxnumber:
    mod = k % n   #здесь запрос проверяльщикам должен быть
    print(k, mod)
    if mod < k:
        print('! ', k - mod)
        break
    else:
        k *= 2
</code>


Вернуть ошибку из асинхронной функции с декораторм python
Декоратор:

def timeout(func):
    async def _wrap(*args, **kwargs):
        try:
            return await asyncio.wait_for(func(*args, **kwargs), timeout=0.25)
        except Exception:
            print('error!') <<< Печатается
            raise Exception <<< Теряется
    return _wrap

Код:

class Worker():
    def __init__(self) -> None:

        self.sem = asyncio.BoundedSemaphore(10)

        loop = asyncio.new_event_loop()
        loop.run_until_complete(self.main())

    async def main(self):
        tasks = []

        for i in range(100):
            task = asyncio.ensure_future(self.work(i))
            tasks.append(task)

        await asyncio.gather(*tasks, return_exceptions=True)

    @timeout <<< Декоратор, добавляющий таймаут
    async def work(self, i):
        await self.sem.acquire()
        print('work...')
        await asyncio.sleep(random.random())
        await self.sem.release()

Проблема: декоратор приведенный выше не возвращает ошибок, хотя код написанный в блоке
except выполняется.
Дополнение: Кажется проблема в возвращении любых ошибок из
asyncio.gather().

А доку почитать?

If
return_exceptions is
False (default), the first raised exception is immediately propagated to the task that awaits on
gather(). Other awaitables in the aws sequence won’t be cancelled and will continue to run.

If
return_exceptions is
True, exceptions are treated the same as successful results, and aggregated in the result list.

Вы задали параметр
return_exceptions=True, в этом случае исключения считаются успешным результатом и возвращаются в списке результатов. Вы же результат, возвращаемый
asyncio.gather, вообще не смотрите.
Проверим это утверждение из документации:

        result = await asyncio.gather(*tasks, return_exceptions=True)
        print(result)

Вывод:

[TimeoutError(), TimeoutError(), TimeoutError(), TimeoutError(), TypeError("object NoneType can't be used in 'await' expression"), TimeoutError(), TimeoutError(), ...

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

        try:
            result = await asyncio.gather(*tasks, return_exceptions=False)
            print(result)
        except Exception as ex:
            print(ex)


Как пробежать циклом FOR каждый элемент в матрице (двумерном массиве) PYTHON
Пытался разобраться как это сделать, представление есть, но написать не получается, как только не пробовал и все равно неправильно работает, суть в том, что нужно найти кол-во отриц., положит., и нулевых элементов в матрице.
Не пользовался nump и хочу сделать без него, размер матрицы формируется пользователем,и заполняется случайными числами из диапазона который вводит пользователь, это прекрасно работает, а вот как дальше пробегать по каждому элементу и сделать какое-либо условие не понял.
!Поправка! понял как пройтись по элементам проверив на print('dsad') и когда вводил матрицу 2х2 то есть 4 элемента 4 раза выводило dsad, но не пойму как все таки найти положительные или отрицательные, сделал тестовый код, в условии что-то не так, не пойму что именно сравнивать с нулём. Заранее спасибо!
<code>
import random
l,r=map(int,input('Введите диапазон чисел для заполнения матрицы: ').split())
def matrix(x, y):
    return [[random.randint(l,r) for i in range(x)] for j in range(y)]
n,k=map(int,input('Введите кол-во строк и столбцов матрицы: ').split())
for i in range(len(matrix(k,n))):
    for j in range(len(matrix(k,n)[i])):
        print(matrix(k,n)[i][j], end = ' ')
    print()
pos=0
neg=0
zero=0
for i in range(len(matrix(k,n))):
    for j in range(len(matrix())):
        if j>0:
            pos+=1
        elif j<0:
            neg+=1
        else:
            zero+=1
if pos>0:
    print('Кол-во положительных элементов матрицы: ',pos)
if neg>0:
    print('Кол-во отрицательных элементов матрицы: ',neg)
if zero>0:
    print('Кол-во нулевых элементов матрицы:',zero)
</code>

В лоб

matrix  = [[-1,2,3],[0,5,6], [-7,8,9]]

negative = 0
zeros = 0
positive = 0

for i in matrix:
    for j in i:
        if j == 0:
            zeros += 1
        elif j > 0:
            positive += 1
        else:
            negative += 1

Перебирать по индексам строк и столбцов в данном случае нет смысла, все равно нужно пробежаться по всем элементам
Устал я с вами в комментариях бороться. Ваши ошибки

Не надо каждый раз вызывать функцию
matrix(k, n), поскольку вы плодите совершенно не связанные друг с другом объекты, которые вам по сути не нужны, кроме того, что вы забираете оттуда длины. Вызовите один раз, результат работы поместите в переменную, и вот с ней и работайте

matrix_variable = matrix(k,n)

Вам не нужны
range и
len поскольку вы перебираете все члены матрицы. Для того чтобы перебрать каждый элемент вам нужен только
for и итерируемый объект

В итоге ваш код

# здесь ваш ввод, определение функции для matrix и проч
matrix_variable  = matrix(k, n)

negative = 0
zeros = 0
positive = 0

for i in matrix_variable:
    for j in i:
        if j == 0:
            zeros += 1
        elif j > 0:
            positive += 1
        else:
            negative += 1


Как записать в переменную канал или роль?
Идея:

Я хочу сделать 1 команду что бы она закрывала 3-ом(существующим) разным ролям право на общение в 3-ох разных каналах(текстовых, существующих).

Вот к примеру тут я создаю канал и записываю его в переменную, а потом меняю права:
<code>
channel = await integration.guild.create_voice_channel(f"{integration.user.name}'s voice ", category=category)
await channel.set_permissions(integration.user, overwrite=overwrite)
</code>
А как записать в переменную существующий канал или роль что бы потом у него изменять права и тд?
Подскажите как это сделать?

Можете просто заново получить объект канала

channel = bot.get_channel(channel.id)

Хотя, я не уверен, что это требуется. На всякий случай проверьте меняется ли значение свойства у текущего объекта канала после выполнения метода

await channel.set_permissions()


Почему не получается отправить сообщение telethon?

from telethon import TelegramClient

client = TelegramClient(session,
                    api_id,
                    api_hash
                    )
async def main():
    await client.send_message('username', 'Hello to myself!')

with client:
    client.loop.run_until_complete(main())

Простенький код, по идее должен работать и отправлять сообщение, но это не так.
на выходе выводит:

Server sent a very new message with ID 7161122737890074629, ignoring
Server sent a very new message with ID 7161122738048177153, ignoring

Что я не так делаю?

Чтобы отправить сообщение самому себе нужно в username вписать 'me'

username = 'me'
await client.send_message(username, 'Hello to myself!')

Чтобы отправить сообщение пользователю нужно его номер или @юзернейм также вписать в username

username = '@юзернейм взятый из профиля цели (друга/папы итд)'
    await client.send_message(username, 'Hello to myself!')


Объединить 2 хендлера pyTelegramBotApi
<code>
@bot.message_handler()
def send_docs(message):
if message.text in ['1','2','3','4','5','6','7','8','9','10','v']:
    file_source=open(f"D:\Proyekt\domstroy_{message.text}.csv")
    bot.send_document(message.chat.id, file_source)

elif:
    @bot.message_handler()
    def send_query(message):
        db=sqlite3.connect("ostatki.db",check_same_thread=False)
        cur=db.cursor()
        cur.execute("DROP table IF EXISTS tovarniye_ostatki")
        cur.execute("CREATE virtual table IF NOT EXISTS tovarniye_ostatki USING FTS5
        (nazvaniye_tovara,ostatki_tovara)")
        with open ("domstroy.csv",'r', encoding="utf8",) as file:
            for row in file:
                cur.execute("INSERT OR IGNORE INTO tovarniye_ostatki VALUES
        (?,?)",row.split(";"),)
            db.commit()
        result_query = cur.execute("SELECT ostatki_tovara, nazvaniye_tovara  FROM
                                   tovarniye_ostatki
                                   WHERE tovar_nomi MATCH (?)",(message.text,))
        result = result_query.fetchall()
        for i in result:
            bot.send_message(message.chat.id, (f"{i[1]} == {i[0]}"))
        db.close()
</code>
Мне надо объединить эти 2 хендлера.
1-Хендлер должен отправить файл, если юзер отправить цифры от 1 до 10 и букву v.
2-Хендлер должен сработать, если юзер отправит например, запрос "travertin" то есть название товара из БД.
Сейчас работает только 1-хендлер.
Подскажите, пожалуйста где ошибка.
Спасибо.

Для начала скажу, что второй хендлер не факт, что будет работать. Но как мысль о том как примерно можно реализовать вам поможет.

@bot.message_handler(content_types=['text'])
def send_docs(message):
    l = []
    with open('test.csv', encoding='utf8') as file:
        reader = csv.reader(file)
        for i in reader:
            a = i[0]
            a = a.split(';')[0]
            l.append(a)

    if message.text in ['1','2','3','4','5','6','7','8','9','10','v']:
        file_source=open(f"D:\Proyekt\domstroy_{message.text}.csv")
        bot.send_document(message.chat.id, file_source)

    elif message.text in l:
        db=sqlite3.connect("ostatki.db",check_same_thread=False)
        cur=db.cursor()
        cur.execute("DROP table IF EXISTS tovarniye_ostatki")
        cur.execute("CREATE virtual table IF NOT EXISTS tovarniye_ostatki USING FTS5
        (nazvaniye_tovara,ostatki_tovara)")
        with open ("domstroy.csv",'r', encoding="utf8",) as file:
            for row in file:
                cur.execute("INSERT OR IGNORE INTO tovarniye_ostatki VALUES
        (?,?)",row.split(";"),)
            db.commit()
        result_query = cur.execute("SELECT ostatki_tovara, nazvaniye_tovara  FROM
                                   tovarniye_ostatki
                                   WHERE tovar_nomi MATCH (?)",(message.text,))
        result = result_query.fetchall()
        for i in result:
            bot.send_message(message.chat.id, (f"{i[1]} == {i[0]}"))
        db.close()

Вам стоит в хендлере открыть БД, и считать вам нужные названия, а потом циклом вставить в список. И уже данный список проверять на схожесть с
message.text
Так же хочу, чтобы вы обратили внимание на ваш код. Вы вставили хендлер в условие, что делать нельзя, просто работать не будет. Можно лишь попробовать вызвать функцию, что стоит под хендлером, но лично я так не делал, так что не могу сказать точно.


Получение айди telegram
Я пытаюсь сделать так чтобы мой бот по нику мог определить айди. Создал приложение получил токен и хеш дальше начались проблеммы:

from telethon import TelegramClient
from telethon.tl.functions.users import GetFullUserRequest
def get_user(username):
   API_ID = айди
   API_HASH = "хеш"
   with TelegramClient('имя приложения', API_ID, API_HASH) as client:
       user = client(GetFullUserRequest(username))
   return user
id = get_user("юзер нейм корторый ищу")

При запуске данного кода и использовании токена моего бота, получаю ошибку

sys:1: RuntimeWarning: coroutine 'UserMethods.__call__' was never awaited

Помогите пожалуйста

Telethon является асинхронной библиотекой, поэтому ругается на отсутствие async.
Попробуйте так:
<code>
from telethon import TelegramClient
from telethon.tl.functions.users import GetFullUserRequest

API_ID = айди
API_HASH = "хеш"
client = TelegramClient('имя приложения', API_ID, API_HASH)

async def get_user(username: str):
    return client.GetFullUserRequest(username)

async def main():
    id_ = await get_user("юзер нейм корторый ищу")
    print(id_)

with client:
    client.loop.run_until_complete(main())
</code>
Надеюсь, что мой ответ Вам поможет.


Как написать регулярное выражение для такой строки?
Всем привет и хорошого дня. Хочу написать регулярное выражение для адреса места жительства. Мне нужен шаблон, который можно использовать и по адресу с номером квартиры и без.

tex = 'Иванов В.В.  адрес Володимирська 7 ТЕЛЕФОН 0963412678   1000
адр. Схудна 8 телефон 0667835467  Гоц Маша 560
Кот Женя      АДРЕС Леваневського 3 кв 6      тел. 0673426450 270
АДР. Гризодубово 45 кв 102   Бондар Ю.С.  ТЕЛ. 0971524366 15000000'

Я пыталась сделать это таким способом

import re
adress2 = r'((адр.|АДР.|адрес|АДРЕС)\s[А-Яа-я]+\s\d+\sкв\s\d+)'
res2 = re.findall(adress2, tex)
print(res2)

вывод такой

[('АДРЕС Леваневського 3 кв 6', 'АДРЕС'), ('АДР. Гризодубово 45 кв 102', 'АДР.')]

возможно ли сделать вывод таким?

[('адрес Володимирська 7', 'адрес'), ('адр.Схудна 8', 'адр.'),('АДРЕС Леваневського 3 кв 6', 'АДРЕС'), ('АДР. Гризодубово 45 кв 102', 'АДР.')]

Вообще не уверен, что подобный поиск по зубам регуляркам, но можно попробовать как-то так:

res = [x[0] for x in re.findall(r"адр.+?\s(.*?\d+(\sкв \d+)?)\s", tex, flags=re.IGNORECASE)]

res:

['Володимирська 7',
 'Схудна 8',
 'Леваневського 3 кв 6',
 'Гризодубово 45 кв 102']


Проблема с циклом for при резервной копии файлов (модули zipfile, os)
Знатоки, помогите, пожалуйста)
Пишу элементарную программу для резервного копирования файлов на python, использую модули zipfile, os.
Не могу дать ума как написать последний блок кода (цикл for) так, чтобы он сразу прогонял оба элемента (каталога) из списка source, добавляя их в архив? Пришлось продублировать блок, указав второй элемент списка. Работает конечно, но если список будет значительно больше, уже не так удобно.
Вот мой код:
<code>
import os
import zipfile

# 1. Файлы и каталоги, которые необходимо скопировать, собираются в список.
source = ['/Users/ozzy/Documents/filestobackup', '/Users/ozzy/Documents/filesback']

# 2. Резервные копии будут храниться в следующем каталоге:
target_dir = '/Users/ozzy/Desktop/BACKUP'

# 3. Имя zip-архива
target = 'Backup.zip'

# 4. Создаем архив
zip = zipfile.ZipFile(target, 'w')

# 5.1 Помещаем первый каталог в архив
for root, dirs, files in os.walk(source[0]):
    for file in files:
        zip.write(os.path.join(root, file))

# 5.2 Помещаем второй каталог в архив
for root, dirs, files in os.walk(source[1]):
    for file in files:
        zip.write(os.path.join(root, file))

print('Резервное копирование завершено')
</code>
Кстати, цикл for у меня вызывает сомнения (хотя и работает), поскольку такой код нашел в интернете. Если есть замечания по этому поводу - буду рад!
Заранее большое спасибо)

Как вариант:

for src in source:
    for root, dirs, files in os.walk(src):
        for file in files:
            zip.write(os.path.join(root, file))

Так к тому же можно будет помещать неограниченное кол-во путей в
source


Вывести буквы, которые встречаются только в одном слове. Выполнить операцию над списком множеств сразу
Нужно вывести те буквы, которые встречается только в одном слове.
<code>
s = 'Привет, клак у Аллы дела'
st = set()
s = s.lower()
s = s.split()
ls = []
for i in s:
    a = "".join(c for c in i if c.isalpha()) # оставляю в строке только буквы
    ls.append(set(a))
m = set()
for i in ls:
    m ^= i # симметричная разность множеств
print(m, len(m))
</code>
из - за того что я выполняю операцию последовательно, то ответ неверный.
{'л', 'и', 'д', 'п', 'у', 'в', 'к', 'т', 'р', 'а', 'ы'} 11
например, буква А не должна выводиться, т.к. оно есть в трех словах.

вариант 1:
можно сделать в лоб:

text = 'Привет клак у Аллы дела'
words = text.lower().split()

res = []
for w in words:
    for l in w:
        if text.count(l) == w.count(l):
            res.append(l)

print(res)

вариант 2:
ну или для любителей одной строки:

res = [l for w in words for l in w if text.count(l) == w.count(l)]

вариант 3:
через множества поизвратнее:

text = 'Привет клак у Аллы дела'
words = list(map(set, text.lower().split()))

res = set()

for i in range(len(words)):
    res |= words[i].difference(*set.union(*[words[j] for j in range(len(words)) if i != j]))

print(res)

вариант 4:
и однострочный вариант:

res = set.union(*[words[i].difference(*set.union(*[words[j] for j in range(len(words)) if i != j])) for i in range(len(words))])