Python неконстантные атрибуты класса

class A:
    atr_1 = '1'
    atr_2 = atr_1 + '2'

my_dict = {'prefix.1': 1,
          'prefix.2': 2}

class B:
    atr_1 = 'prefix'
    atr_2 = [el.removeprefix(atr_1 + '.') for el in my_dict.keys()]

Вопрос по коду выше. В классе A успешно создаётся атрибут класса atr_1, а в классе B - нет, т.к. ошибка "
NameError: name 'atr_1' is not defined", но почему в первом случае этой ошибки нет? И как делать подобные неконстантные атрибуты класса, которые общие для всех экземпляров? Или в Python это делается где-то в другом месте?

Получилось через такой костыль:
<code>
class B:
    atr_1 = 'prefix'
    atr_2 = (lambda atr_1: [el.removeprefix(atr_1 + '.') for el in my_dict.keys()])(atr_1)

print(B.atr_2)
# ['1', '2']
</code>


Как проверить в полноэкранном ли режиме окно в PyQt5
В программе, которую я пишу, нужна проверка на полноэкранный режим. Как осуществить это?

isMaximized() возвращает True если окно на максимум, False если
<code>
import sys
from PyQt5.QtWidgets import QVBoxLayout, QApplication, QWidget, QPushButton, QLabel

class Main(QWidget):
    def __init__(self):
        super(Main, self).__init__()
        self.resize(400, 400)
        self.setStyleSheet('background-color: #bdd3de;')
        self.label = QLabel()
        self.btn_test = QPushButton('Проверка окна')

        self.btn_test.clicked.connect(self.window_check)

        self.main_box = QVBoxLayout()
        self.main_box.addWidget(self.label)
        self.main_box.addWidget(self.btn_test)
        self.setLayout(self.main_box)

    def window_check(self):
        if self.isMaximized():
            self.label.setText('Окно на максимум')
        else:
            self.label.setText('Окно не максимум')

if __name__ == "__main__":
    app = QApplication(sys.argv)

    main = Main()
    main.show()
    sys.exit(app.exec_())
</code>


Подсчет количества строк в *.py файлах во всей директории проекта
Доброго времени суток,
Для ДЗ понадобилось подсчитать количество строк в *.py файлах в директории проекта
Получился следующий код:
<code>
import os
from collections.abc import Iterable

def gen_files_dir(path: str, depth=1) -> Iterable[str]:
    depth -= 1
    with os.scandir(path) as p:
        for entry in p:
            yield entry.path
            if entry.is_dir() and depth > 0:
                yield from gen_files_dir(entry.path, depth)

if __name__ == '__main__':
    directory = 'C:\\Users\\Nikita.Uvaliyev.KPI\\PycharmProjects\\python-ds\\'
    files_list = list(gen_files_dir(directory))
    line_count = 0

    for file_dir in files_list:
        if not os.path.isfile(file_dir):
            continue

        skip_File = True
        files_filtered = [x for x in files_list if x.endswith('.py')]

        if not skip_File:
            try:
                file = open(file_dir, "r")
                local_count = 0
                for line in file.read().split('\n'):
                    if (not line.strip() == '') and (not line.strip().startswith("#")) and (
                            not line.strip().startswith('"')):
                        local_count += 1
                print('{} - {} ст'.format(file_dir, local_count))
                line_count += local_count
                file.close()
            except FileNotFoundError:
                continue

    print("=====================================")
    print("Всего строк  - ", line_count)
</code>
Код собран из частей найденных в интернете :)
Пробовал "играться" с путями, но резульат всегда один:

=====================================
Всего строк  -  0
Process finished with exit code 0

Так же, PyCharm жалуется на отсутствие некоторых методов в "init", но их добавление ни к чему не приводит
Направьте пожалуйста на путь истинный :)

Из-за проверки с
skip_File код подсчета не выполняется

        skip_File = True
        files_filtered = [x for x in files_list if x.endswith('.py')]

        if not skip_File:
            ...

Да и код перегруженный, есть возможность сократить его в разы. Кроме того, мне показалось, что он неправильно работает
Сделал решение через
pathlib и рекурсивный
.rglob (для поиска текущей папки просто использовать
.glob):

from pathlib import Path

directory = Path(r'C:\Users\Nikita.Uvaliyev.KPI\PycharmProjects\python-ds')
line_count = 0

for f in directory.rglob('*.py'):
    if not f.is_file() or not f.exists():
        continue

    local_count = 0
    for line in f.read_text().splitlines():
        line = line.strip()
        if not line or line.startswith(('#', '"', "'")):
            continue
        local_count += 1

    print(f'{f} - {local_count} ст')
    line_count += local_count

print("=====================================")
print(f"Всего строк - {line_count}")


Как реализовать скачивание CSV-файла клиенту с сервера?
Использую
WebApp2. Клиент зашел на Web-страницу - там сформировался в памяти
csv-файл. Теперь я хочу, чтобы клиент его получил (скачал себе) автоматом.
Дополнение:
Реализовал скачивание файла:

def get(self):
    allRows = dbUser.query()
    DataForCSV_File = [['name', 'email']]
    for rows in allRows:
            DataForCSV_File.append([rows.name, rows.email])
    file_name = 'dbUser.csv'
    self.response.headers['Content-Disposition'] = 'attachment; filename="{0}"'.format(file_name)
    self.response.headers['File-Name'] = file_name
    self.response.headers['Content-Type'] = 'text/csv'
    self.response.write(DataForCSV_File)

В итоге после скачивания - открывается таблица
Excel и в 1ой ячейке текстом записан список.
Пробовал
DataForCSV преобразовывать:

f = StringIO()
csv.writer(f).writerows(DataForCSV_File)

В итоге при открытии в 1ой ячейке лежит:

<StringIO.StringIO instance at 0x3e10a6ff44d0>

Вопрос что я не так  делаю? Почему у меня не открывается нормальная CSV-таблица?

Благодаря @insolor, был найден конечный пазл! Может кто столкнется с такой проблемой вот полное решение в WebApp2:
<code>
def get(self):
    # Выборка всех пользователей из таблицы "dbUser"
    allRows = dbUser.query()

    # Подготовка данных для CSV-таблицы. 1 список в списке - название колонок
    DataForCSV_File = [['name', 'email']]

    # заполнение данных из выборки
    for rows in allRows:
        DataForCSV_File.append([rows.name, rows.email, rows.account_type])

    # Сохраняем данные будущего CSV-файла в памяти
    f = StringIO()
    csv.writer(f).writerows(DataForCSV_File)

    file_name = 'dbUser.csv'

    # Даем понимание браузеру, что ответ - это CSV-файл
    self.response.headers['Content-Disposition'] = 'attachment; filename="{0}"'.format(file_name)
    self.response.headers['File-Name'] = file_name
    self.response.headers['Content-Type'] = 'text/csv'

    # Извлекаем данные из памяти и отправляем пользователю.
    self.response.write(f.getvalue())
</code>
В итоге если этот метод указать для класса, то скачается CSV-файл!


Ошибка в Python 3.7.9 (Thonny 3.3.13) - ValueError: too many values to unpack (expected 2)
Написал код на питоне, складывающий и умножающий числа из одного файла и записывающий результат в другой.
<code>
fin = open('input.txt', 'r')
p = fin.read().split()
a, b = map(int, p)
fout = open('output.txt', 'w')
fout.write(str(a + b)+'\n')
fout.write(str(a * b))
fin.close()
fout.close()
</code>
При компиляции выдаёт ошибку:

ValueError: too many values to unpack (expected 2).

Ваша программа будет верно работать только в том случае, если Вы подаёте на вход ровно два числа — в противном случае будет оставаться либо лишняя переменная, либо лишняя строка и файла.
Я предлагаю сначала все числа занести в список, а потом из этого списка вычислять сумму и произведение (первое — через
sum(), второе — через циклы либо другие методы).

fin = open('input.txt', 'r')
p = fin.read().split()
numbers = list(map(int, p)) # заносим все введённые числа в список
fout = open('output.txt', 'w')
fout.write(str(sum(numbers))+'\n') # сумма чисел списка
prod = 1
for number in numbers:
    prod *= number
fout.write(str(prod)) # произведение чисел списка
fin.close()
fout.close()


Как в реализации шифра двойной перестановки сделать порядок столбцов и строк постоянным?
Как в данном коде сделать так, чтобы количество и порядок столбцов и строк всегда был постоянным, или чтобы количество и порядок можно было задавать с клавиатуры? Например, есть всего 4 строки в порядке (3, 1, 4, 2) и 4 столбца в порядке (4, 1, 3, 2). И чтобы, если в таблице останутся пустые ячейки, то чтобы они тоже выводились (или вставить в них какой-то специальный символ, например, "-").
Я знаю python только на базовом уровне.
Про шифр двойной перестановки хорошо описано в википедии.
Код программы:
<code>
from math import ceil
from random import shuffle
s = list('двойная перестановка')
s1 = round(len(s)**0.5)
s2 = ceil(len(s)**0.5)
a = [[s.pop(0) if s else ' ' for _ in range(s1)] for _ in range(s2)]
shuffle(a)
a = list(map(list,zip(*a)))
shuffle(a)
print(''.join([i for j in a for i in j]))
</code>

Можно попробовать так:
<code>
s = list('двойная перестановка'.replace(' ', ''))
col = [3, 1, 4, 2]
row = [3, 2, 4, 1, 5]

a = [ s[i*len(col):(i+1)*len(col)] for i in range(len(row)) ]

if len(a[-1]) < len(col):
    a[-1].extend(list(' '*(len(col)-len(a[-1]))))

for i in a:
    print(*i)

a = [[a[i][col.index(j+1)] for j in range(len(col))] for i in range(len(row))]

a = [a[row.index(i+1)] for i in range(len(row))]

print('-'*7)
for i in a:
    print(*i)
</code>


Не работает фильтр DataFrame по дате
Мне нужно отфильтровать
dataframe по диапазону дат, введенному в графическом интерфейсе.
При попытке реализовать это через метод
dataframe.loc я получаю ошибку:

TypeError: '<' not supported between instances of 'int' and 'Timestamp'

Гугл показывает только варианты ошибки между 'int' и 'str' \ 'timestamp' и 'str'
Переменные
BeginLogDate и
EndLogDate относятся к типу
string формата
'yyyy-MM-dd'
Что тут реализовано не так?

# Чтение файла с преобразованием в массив Pandas
dt = pd.read_csv(filepath_or_buffer=r'{}'.format(input_file),
                 sep=separator,
                 header=0,
                 index_col=['Index'],
                 names=['Index', 'Type', 'Date/Time', 'Unit', 'Scenario',
                        'Sensor Type', 'Limit', 'Axes', 'DSP', 'Limit Type',
                        'Limit Value', 'Max', 'HP (Hz)', 'LP (Hz)', 'Alarm', 'Stop'],
                 parse_dates=['Date/Time'],
                 na_values='---',
                 encoding=encoding
                 )

# По умолчанию, датчик записывает моменты обрыва и включения питания. В этих строках нет полезной информации.
# Удаление строк, в которых Limit Value = None (Включение и выключение системы)
dt = dt.dropna(subset=['Limit Value'])

# Фильтр значений по диапазону дат, введенному в gui
begin = pd.to_datetime(BeginLogDate+' '+'00:00:00')
end = pd.to_datetime(EndLogDate+' '+'23:59:59')
dt = dt.loc[begin:end]

df.loc[slice] - фильтрует записи по значениям индекса, которые у вас, судя по ошибке, целые значения. Поэтому вы получаете ошибку
'<' not supported between instances of 'int' and 'Timestamp'.
Отфильтровать данные можно так:

res = df.query("@begin <= `Date/Time` <= @end")

Пример:

In [196]: df
Out[196]:
   Date/Time
0 2022-01-01
1 2022-01-20
2 2021-10-10

In [197]: BeginLogDate = "2022-01-01"
     ...: EndLogDate = "2022-01-20"
     ...:
     ...: begin = pd.to_datetime(BeginLogDate)
     ...: end = pd.to_datetime(EndLogDate) + pd.offsets.Day(1) - pd.offsets.Micro(1)
     ...:
     ...: res = df.query("@begin <= `Date/Time` <= @end")

In [198]: res
Out[198]:
   Date/Time
0 2022-01-01
1 2022-01-20

PS вариант предложенный @SergFSM тоже правильно отрабатывает:

In [199]: df[df['Date/Time'].between(begin, end)]
Out[199]:
   Date/Time
0 2022-01-01
1 2022-01-20


Не срабатывает одна из команд в aiogram
Может кто сталкивался с такой проблемой: не срабатывает одна команда(new_book), хотя все остальные работают, кто в курсе в чем может быть причина?
Команды

async def set_default_commands(dp):
    await dp.bot.set_my_commands([
        types.BotCommand("start", "Запустить бота 💻"),
        types.BotCommand("help", "Помощь 📣"),
        types.BotCommand("find_book", "Поиск книги по автору или названию 🔍"),
        types.BotCommand("new_book", "Поиск новых книг")
    ])

К примеру команда find_book отрабатывает без проблем, код там идентичный:
find_book

@dp.message_handler(Command("find_book"))
async def choose_book(message: types.Message):
    await message.answer('Введите автора или название книги')
    await FindBook.book.set()

new_book

@dp.message_handler(Command("new_book"))
async def looking_new_book(message: types.Message):
    await message.answer('Приступаю к поиску новых книг')
    await FindNewBook.book.set()

start

@dp.message_handler(CommandStart())
async def bot_start(message: types.Message):
    text = 'Приветствую! 👋 \nЧтобы узнать функционал бота, пропишите комманду /help'
    await message.answer(text)

help

@dp.message_handler(CommandHelp())
async def bot_help(message: types.Message):
    text = [
        'Список комманд',
        '/start - запустить бота',
        '/help - получить справку',
        '/find_book - поиск книги по названию',
        '/new_book - поиск новых книг'
    ]

    await message.answer('\n'.join(text))

В итоге проверил у себя твой код, но урезал до минимума.

from aiogram import executor, types
from aiogram.dispatcher.filters import Command
from aiogram.dispatcher.filters.state import StatesGroup, State

from loader import dp

class FindBook(StatesGroup):
    book = State()

class FindNewBook(StatesGroup):
    book = State()

@dp.message_handler(Command("find_book"))
async def choose_book(message: types.Message):
    await message.answer('Введите автора или название книги')
    await FindBook.book.set()

@dp.message_handler(Command("new_book"))
async def looking_new_book(message: types.Message):
    await message.answer('Приступаю к поиску новых книг')
    await FindNewBook.book.set()

@dp.message_handler()
async def echo(message: types.Message):
    await message.answer(message.text)

if __name__ == '__main__':
    executor.start_polling(dp)

Он тоже после ввода new_book или find_book перестал реагировать на другие команды. Причина та о которой я писал в комментарии - запускается машина состояний и проверка в хендлере не проходит.
Исправить эту ситуацию можно двумя способами, в зависимости от того что вам нужно.
Первый это сделать хендлер с
state="*", Command('cancel'), которая будет сбрасывать ЛЮБОЙ стейт
state.finish() #внутри функции и потом команды будут снова работать.
Второй похож на первый, но только вместо того чтобы создавать новый хендлер ты добавишь к остальным хендлерам тот самый
state="*" и тогда они будут срабатывать.


Валидация формы django
Моя форма возвращает правильные данные
<QueryDict: {'Id_Incidents': ['50'], 'Type_Participation': ['p'], 'Id_People': ['1'], 'Competencies': ['рн']}>
Но форма при этом не является валидной, ошибка status=400. Правильный ли я возвращаю формат данных от QueryDict? Я пробовал удалять все дополнительные поля из модели, создавая/применяя миграции, но это не дало положительных результатов.
Views.py

def add_person(request):
        id_incidents = request.session.get('Id_Incidents', 'ничего не передано')
        if request.method == "POST":
            if request.user:
                form = AkpGroupForm(request.POST)  # форма, созданная в forms.py чтобы добавить участника
                print(request.POST)
                if form.is_valid():
                    # group_created = form['Group'].save(commit=False)
                    # group_created.Id_Incidents = get_object_or_404(AkpIncidents, Id_Incidents=id_incidents)
                    # group_created.save()
                    Id_Incidents = form.cleaned_data['Id_Incidents']
                    Id_People = form.cleaned_data['Id_People']
                    Competencies = form.cleaned_data['Competencies']
                    Type_Participation = form.cleaned_data['Type_Participation']
                    new_person = AkpGroup(
                        Id_Incidents=Id_Incidents,
                        Id_People=Id_People,
                        Competencies=Competencies,
                        Type_Participation=Type_Participation,
                    )
                    new_person.save()
                    return HttpResponse(status=201)
                else:
                    return HttpResponse(status=400)

Models.py

class AkpGroup(models.Model):
Id_Group = models.AutoField(primary_key=True, verbose_name='Идентификатор участника группы АКП')
Id_Incidents = models.ForeignKey('AkpIncidents', models.DO_NOTHING, verbose_name='Идентификатор инцидента')
# stage 3 fields
Id_People = models.ManyToManyField('AkpPeople', verbose_name='Ф.И.О. участника')
Competencies = models.CharField(max_length=256, verbose_name='Компетенции')

LOAN_TYPE_PARTICIPATION = (
    ('d', 'Руководитель группы'),
    ('p', 'Член группы')
)
Type_Participation = models.CharField(max_length=1, choices=LOAN_TYPE_PARTICIPATION, default='p',
                                      verbose_name='Тип участия')
# Вспомогательные
Change_Time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name='Время изменения')
Change_User = models.CharField(max_length=256, blank=True, null=True, verbose_name='Пользователь, внесший изменения')
Del_Date = models.DateTimeField(auto_now=False, blank=True, null=True, verbose_name='Дата удаления')
Del_User = models.CharField(max_length=256, blank=True, null=True, verbose_name='Пользователь, удаливший данные')

Is_Delete = models.BooleanField(default=False, verbose_name='Удален')
Is_Posted = models.BooleanField(default=False, verbose_name='Опублековано')

objects = models.Manager()

def display_id_people(self):
    """
    Creates a string for the Genre. This is required to display genre in Admin.
    """
    return ', '.join([Id_People.Name for Id_People in self.Id_People.all()[:10]])
display_id_people.short_description = 'AkpGroup'

def __str__(self):
    return self.Competencies

class Meta:
    db_table = 'Akp_Group'
    verbose_name = 'Группа АКП'
    verbose_name_plural = 'Группы АКП'

html

<tfoot>
        <form id="form_person_add" method="POST">
            {% csrf_token %}
            <tr>
                <th scope="row"></th>
                <th scope="row"></th>
                <th scope="col">{{form.Group.Id_Incidents}}</th>
                <th scope="col">{{form.Group.Type_Participation}}</th>
                <th scope="col">{{form.Group.Id_People}}</th>
                <th scope="col">{{form.Group.Competencies}}</th>
                <td>
                    <button type="submit">Добавить</button>
                </td>
            </tr>
        </form>
    </tfoot>
</table>

Scripts

function add_person(e) {
        const dataToBackEnd = new FormData();

        let idIncidents = $("#id_Group-Id_Incidents").val();
        let idParticipation = $("#id_Group-Type_Participation").val();
        let idPeople = $("#id_Group-Id_People").val();
        let competencies = $("#id_Group-Competencies").val();

        dataToBackEnd.append("Id_Incidents", idIncidents);
        dataToBackEnd.append("Type_Participation", idParticipation);
        dataToBackEnd.append("Id_People", idPeople);
        dataToBackEnd.append("Competencies", competencies);

        $.ajax({
            method: "POST",
            url: "/main/url_to_django/add_person/",
            headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value },
            data: dataToBackEnd,
            processData: false,
            contentType: false,
            dataType: "json",
        }).done(function(data) {
            loadDataForTable();
        });

    }

    $formAdd.on('submit', function(e) {
        e.preventDefault();
        add_person(e);
    });

    // execution
    loadDataForTable();
})();

Urls.py

app_name = "main"

urlpatterns = [
    path('', views.start, name="start"),
    path('group', views.Groups.as_view(), name='group'),

    path(
        'url_to_django/add_person/',
        views.add_person,
        name='add_person'),

Причиной моих долгих и мучительных бед было использование связи ManyToManyField, при замене на ForeignKey все успешно работает. Проанализировав, пришел к выводу, что связь многие ко многим здесь пожалуй не требуется.


Как проверить ссылку по шаблону?
Есть список ссылок:

a = ['abc.ru/v2', 'abc.com/er.tyre.6/title/86348', 'abc.com/test/ertg.yeg/title/86348', 'bcd.ru/467', 'abc.com/feed?app_id=57655'

Как из этого списка с помощью регулярного выражения вытянуть только эти ссылки:

['abc.com/er.tyre.6/title/86348', 'abc.com/test/ertg.yeg/title/86348']

Пока что есть только часть регулярки, может ее можно как-то дополнить:

r'''(?:abc\.com\/)(title/\d{5})'''

Например, с таким шаблоном
abc\.com/.+/title/\d{5} (если цифр в числах не 5:
abc\.com/.+/title/\d+)

urls = ['abc.ru/v2', 'abc.com/er.tyre.6/title/86348', 'abc.com/test/ertg.yeg/title/86348', 'bcd.ru/467', 'abc.com/feed?app_id=77625']
urls = [url for url in urls if re.search(r'abc\.com/.+/title/\d{5}', url)]
print(urls)
# ['abc.com/er.tyre.6/title/86348', 'abc.com/test/ertg.yeg/title/86348']


python: Ошибка IndexError: index out of range: 0
Помогите разобраться из-за чего возникает ошибка:
File "", line 22, in
IndexError: index out of range: 0
На небольших списках скрипт отрабатывает корректно. Но на списке более 200 элементов возникает подобная ошибка. Читал, что скорее всего элемент списка вышел за груницы массива, но так и не могу понять почему.

import json

from org.apache.spark.sql import RowFactory
from org.apache.spark.sql.types import StructType, DataTypes

from java.lang import Long

struct_def = StructType().add('partyRole', DataTypes.StringType).add('MSISDN', DataTypes.LongType)

rows = []

for i in range(len(source)):

    msisdn = source[i]['MSISDN']
    partyRole = ''

    dictData = json.loads(source[i]['body'])
    print(i)

    for each in dictData[0]["PartyRole"]: #как я понял, ошибка тут
        if each["Characteristic"][0]["value"] == msisdn:
            partyRole = each["id"]
            rows.append(RowFactory.create(partyRole, Long(int(float(msisdn)))))
            break

ds_result = sqlContext.createDataFrame(rows, struct_def)

Пример json-a

[{
        "sid": [],
        "@baseType": "Party",
        "@type": "Individual",
        "fid": "a422978d-1ffe-423d-9746-34614a43e2dc",
        "PartyRole": [{
                "EntityRef": {
                    "id": "ce2abb93-1c20-4735-a461-610104e01b58"
                },
                "MarketingSegment": "aaa",
                "id": "3139275a-77e1-4fc3-b3f5-3521dd7dbc61",
                "status": "active",
                "name": "Customer",
                "Characteristic": [{
                        "name": "phoneNumber",
                        "valueType": "string",
                        "value": "999999999"
                    }
                ]
            }
        ]
    }, {
        "fid": "ce2abb93-1c20-4735-a461-610104e01b58",
        "sid": [{
                "service": "CAM",
                "key": "customerId",
                "id": "704493404"
            }
        ],
        "@type": "Individual",
        "@baseType": "Party",
        "PartyRole": [{
                "MarketingSegment": "Mobile",
                "id": "d497f005-ecd1-4f84-9b5f-37c31b2a51a0",
                "status": "active",
                "Characteristic": [{
                        "valueType": "string",
                        "name": "phoneNumber",
                        "value": "3333333"
                    }, {
                        "name": "Tech_assigned",
                        "valueType": "string",
                        "value": "99999999"
                    }
                ],
                "name": "Technology"
            }
        ]
    }

Здесь дело абсолютно не в количестве данных, а в содержании. У вас вылетает ошибка когда длина списка под ключом
"Characteristic" равна нулю. То есть там пустой список. Чтобы исключить, просто добавьте проверку на пустоту. Что то такое:

    if dictData:
        for each in dictData[0]["PartyRole"]: #как я понял, ошибка тут
            if each["Characteristic"]:
                if each["Characteristic"][0]["value"] == msisdn:

То есть первая ветка
if провереят пустой ли список. Если не пусто, то нулевой элемент будет существовать, и вы спокойно можете к нему обратиться, зная, что ошибки не будет


Привести тип данных к типу время
Считываю данные из ексель, они там находятся в ячейках с типом время. Как в питоне привести к этому типу данных, если в экселе будет другой тип

# Наподобие такого
t = time(ws.cell(row=1, column=1).value)

UDP: Имеется эксель файл со столбцами типа текст:

1:20:00
40:00
24:00

В питоне я считываю эти данные так

t = ws.cell(row=1, column=1).value
print(type(t)) # получаю <class 'str'>
# как получить на выводе <class 'datetime.time'>

Вот такой костыль. лучше придумать не смог.
<code>
import datetime
a = '20:00'
ltime = list(map(int, a.split(':')))
if len(ltime) == 3:
    time = datetime.time(hour=ltime[0], minute=ltime[1], second=ltime[2])
else:
    time = datetime.time(minute=ltime[0], second=ltime[1])
print(type(time), time)
# <class 'datetime.time'> 00:20:00
</code>


Цикл для классов
Доброй ночи, у меня есть класс User, не могу понять как верно использовать цикл для классов. Хотел создать цикл, чтобы инкремент увеличивался только до определенного числа вне класса. Но мне выдала такую ошибку TypeError: '<' not supported between instances of 'NoneType' and 'int'. Я так понимаю что он мой метод должен что-то возвращать чтобы работать с циклом или же нет? Заранее благодарю вас за помощь
<code>
class User():

    def __init__(self,first_name,last_name,age,city):
        """Инициализация атрибутов"""
        self.first_name = first_name
        self.last_name  = last_name
        self.age = age
        self.city = city
        self.login_attempts = 0

    def describe_user(self):
        """Вывод некоторой информации о пользователе"""
        print("Имя пользователя: " + self.first_name)
        print("Фамилия пользователя: " + self.last_name)
        print("Возраст: " + self.age)
        print("Родной город: " + self.city)

    def greet_user(self):
        print("\n Hello " + self.first_name.title())

    def increment_login_attempts(self):
        self.login_attempts += 1

log = User('Иван','Иванович','21','Иваново')
while log.increment_login_attempts() < 5:
    log.increment_login_attempts()
print(log.login_attempts)
</code>

Вы сами и ответили на свой вопрос. Вы должны что-то возвращать (иначе вернётся
None). Можете возвращать количество попыток:

def increment_login_attempts(self):
    self.login_attempts += 1
    return self.login_attempts

Но более предпочтительно, на мой взгляд, изменить цикл:

while log.login_attempts < 5:
    log.increment_login_attempts()


Как совместить asyncio и aiogram
пишу телеграм бота на языке Python и библиотеке aiogram, у меня возникла необходимость при перезапуске файла выполнять функцию, покопавшись немного в интернете нашёл вот такое решение

bot = Bot(config.bot_token)
dp = Dispatcher(bot)

async def hello():
    await bot.send_message(my_id, 'Bot started!')

loop = asyncio.get_event_loop()
if __name__ == '__main__':
    loop.run_until_complete(hi())
    loop.close()
    executor.start_polling(dp, on_startup=hi())

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

RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'Executor._startup_polling' was never awaited
sys:1: RuntimeWarning: coroutine 'Executor._shutdown_polling' was never awaited

Подскажите пожалуйста в чём тут проблема?

Так погодите ка. Вам же просто нужно чтобы при запуске бота запускалась определенная функция? Вам не нужен asynio для этого. Сделайте вот так
<code>
bot = Bot(config.bot_token)
dp = Dispatcher(bot)

async def on_startup(dispatcher):
    await bot.send_message(my_id, 'Bot started!')

if __name__ == '__main__':
    executor.start_polling(dp, on_startup=on_startup)
</code>


Как удалить Inline клавиатуру Aiogram
Подскажите как мне удалить(или скрыть) клавиатуру после нажатия на нее?

Можно вот так. В колбеке который ловит нажатие этой кнопки, обратитесь к объекту message через callbackQuery и вызовите метод для изменения reply_markup (короче клавиатуры) никакие аргументы не передавайте.
<code>
@dp.callback_query_handler(text="asd")
async def asd(call:types.CallbackQuery):
    await call.message.edit_reply_markup()
</code>


Получить один столбец из данных pandas
Я беру DataFrame и разбиваю столбец на два
datetime = data['tr_datetime'].str.split(' ')
Получаю данные следующего вида:

0          [0, 10:23:26]
1          [1, 10:19:29]
2          [1, 10:20:56]
3          [1, 10:39:54]
4          [2, 15:33:42]
              ...
99995    [152, 04:43:53]
99996    [152, 04:45:24]
99997    [153, 00:00:00]
99998    [153, 00:00:00]
99999    [155, 00:00:00]
Name: tr_datetime, Length: 100000, dtype: object

Как достать только первое значение из скобок? То есть 0,1,2,3 и тд.

наверняка способов много, например, такой тоже работает:
<code>
datetime = data['tr_datetime'].apply(lambda x: x.split(' ')[0])
</code>


Удалить все вхождения элементов в списке
Есть список:

a = ['1', '2', '3', '2', '2', '3', '4', '5', '1', '5', '4']

И есть другой список:

b = ['1', '3', '2']

Как из списка a удалить все элементы списка b?
Пробовала так, но удаляется только первый элемент:

for i in b:
    a.remove(i)

P.S.удалять надо не дубликаты, а только все вхождения элементов списка b в список а. то есть должен в итоге получиться список

['4', '5', '5', '4']

Элементарное списковое включение вполне работает, непонятно, в чём у вас сложность:
<code>
a = ['1', '2', '3', '2', '2', '3', '4', '5', '1', '5', '4']
b = ['1', '3', '2']
c = [x for x in a if x not in b]
print(c)
# ['4', '5', '5', '4']
</code>


Метод .sort() выдаёт ошибку [закрыт]

Закрыт. Этот вопрос не по теме. Ответы на него в данный момент не принимаются.

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

Закрыт 1 год назад.

                        Улучшить вопрос

Имеется программа, которая суммирует все значения array
Код:

import itertools
import collections
import ast

dict1 = input("")
dict2 = input("")
d1 = ast.literal_eval(dict1)
d2 = ast.literal_eval(dict2)

new_dict = collections.defaultdict(int)

for k, v in itertools.chain(d1.items(), d2.items()):
    new_dict[k] += v

print(*new_dict.values())

У когда ещёдолжно быть действие, отсортировать полученные числа в убывающем порядке.
К примеру если дан array:

{'a': 100, 'b': 200, 'c':300} {'a': 300, 'b': 200, 'd':400}
В итоге код выведет
400 400 300 400
Но надо чтобы выдавало
400 400 400 300 (так как убывающий порядок)
Я воспользовался такой строчкой кода:
new_dict.sort(reverse = True)
Но выдало ошибку:
AttributeError: 'collections.defaultdict' object has no attribute 'sort'
Может быть есть ещё вариатны как это решить?

И опять можно применить Counter.
<code>
from collections import Counter

d1 = {'a': 100, 'b': 200, 'c':300}
d2 = {'a': 300, 'b': 200, 'd':400}

res = sorted((Counter(d1) + Counter(d2)).values(), reverse=True)
</code>


Как правильно прочитать данные. из Тега таблицы Python
Мне нужно прочитать все строки из таблицы (их может быть миллион, а может и не быть вовсе) и записать в одну переменную типа String.
Пример таблицы ниже, помогите пожалуйста разобраться!

Добрый день.

Меня зовут Андрей.

Более 6 лет я специализируюсь на красивых не стандартных слайд-шоу.

Творческие люди оценят.)))

Буду рад  выполнить Ваш заказ.

Не стесняйтесь, обращайтесь.

from bs4 import BeautifulSoup as Soup

html = """<table width="100%"><tbody><tr><td>Добрый день.<br>
Меня зовут Андрей.<br>
Более 6 лет я специализируюсь на красивых не стандартных слайд-шоу. <br>
Творческие люди оценят.)))<br>
Буду рад  выполнить Ваш заказ.<br>
Не стесняйтесь, обращайтесь.<br><br></td></tr></tbody></table>"""

soup = Soup(html, 'html.parser')
table = soup.find('table')

common_string = ''.join(table.strings)

print(common_string)

Вывод:

Добрый день.
Меня зовут Андрей.
Более 6 лет я специализируюсь на красивых не стандартных слайд-шоу.
Творческие люди оценят.)))
Буду рад  выполнить Ваш заказ.
Не стесняйтесь, обращайтесь.


Не работают inline кнопки
Совсем недавно начал изучать Python и решил написать телеграм бота. Столкнулся с такой проблемой. Кнопки "Да" и "Нет" работают, но кнопки  "Давай" и "Нет" почему то абсолютно не реагируют на нажатия. Почему такое может быть?
<code>
import telebot
from telebot import types

bot = telebot.TeleBot("мой токен")

@bot.message_handler(commands=['/start'])
def welcome(message):
    markup = types.InlineKeyboardMarkup()
    item5 = types.InlineKeyboardButton("Да",callback_data="yes")
    item6 = types.InlineKeyboardButton("Нет",callback_data="no")
    markup.add(item5, item6)
    bot.send_message(message.chat.id, text='Хорошее настроение сегодня?', reply_markup=markup)

@bot.callback_query_handler(func=lambda call:True)
def callback_inline(call):
    if call.message:
        if call.data == "yes":
            markup2 = types.InlineKeyboardMarkup()
            item7 = types.InlineKeyboardButton("Давай",callback_data="ye")
            item8 = types.InlineKeyboardButton("Нет",callback_data="ne")
            markup2.add(item7, item8)
            bot.send_message(call.message.chat.id, text='Это хорошо. Давай дружить?', reply_markup=markup2)
        if call.data == "no":
            bot.send_message(call.message.chat.id,text = "Это грустно(")

@bot.callback_query_handler(func=lambda call:True)
def callback_inline(call):
    if call.message:
        if call.data == "ye":
            bot.send_message(call.message.chat.id,text = "Теперь мы друзья!")
        if call.data == "ne":
            bot.send_message(call.message.chat.id,text = "Ты меня расстраиваешь(")
bot.polling(none_stop = True)
</code>

Я не очень шарю в телеботе, но точно вижу что у вас два колбек хендлера с одинаковым условием/фильтром, поэтому срабатывает только один, который был обьявлен раньше.
Вам нужно поменять в скобках для колбек хендлеров ваши
func=lambda call:True на
func=lambda c: c.data == 'yes' or c.data == 'no'
И почти то же самое провернуть со вторым колбеком.

func=lambda c: c.data == 'ye' or c.data == 'ne'
Правда я рекомендую в колбекдата отправить не простое yes-no, а к примеру вот так:

item5 = types.InlineKeyboardButton("Да", callback_data="asq:yes")
item6 = types.InlineKeyboardButton("Нет", callback_data="asq:no")
# и потом в колбек хендлере который должен ловить эти кнопки будет следующее
func=lambda c: c.data.split(":")[0] == 'asq'

Ну и просто для примера здесь есть разные способы задать условие для колбек хендлеров. ссылка тут


Удалить повторяющиеся значение из списка вместе с ним
Всем добрый день
Надо чтобы в input вводился какой-то список, и выводились только уникальные values из него(тоесть не повторяющиеся)
Имеется следующий код:

import ast

dict1 = input("")
d = ast.literal_eval(dict1)

temp =[]
res = dict()
for key, val in d.items():
    if val not in temp:
        temp.append(val)
        res[key] = val

print(*list(res.values()))

К примеру ввод может быть вот таким:
{"2":1,"5":1,"55":1,"34":2,"0":3}
Тогда output должен быть вот таким:
2 3
Но пока ответ получается только
1 3 2

Посчитать количество повторений каждого из значений в словаре. Для этого отлично подойдёт класс
Counter. Затем оставить только те значения, у которых получившийся счётчик равен единице.

from collections import Counter

d = {"2":1,"5":1,"55":1,"34":2,"0":3}

res = [k for k,v in Counter(d.values()).items() if v == 1]
print(*res)


Как из параметров url выделить еще один url?
Есть url:
<code>
a = 'vk.com/share.php?url=ystav.net/article/o-sozdanii-vakciny&amp'
</code>
Здесь в параметрах содержится еще одна ссылка, как ее можно достать?

Для разбора ссылок есть стандартная библиотека urllib.
<code>
import urllib.parse
url = urllib.parse.parse_qs(urllib.parse.urlparse(a).query)["url"][0]
</code>


Как отправить сообщение в aiogram после обработки callback?
Пишу диалог с ботом с помощью FSM.
В процессе диалога, после обработки нажатия inlain кнопки, нужно отправить сообщение. Но метод answer отправляет уведомление, а не сообщение.

await call.answer("спрашиваю вопрос ?:")

я знаю, что можно отправить сообщение
await bot.send_message("спрашиваю вопрос ?:") но мне это не очень подходит, так как объект bot формируется в главном скрипте в функции main. что бы было понятней прикрепляю код:
скрипт main

async def main():
    # Объявление и инициализация объектов бота и диспетчера
    bot = Bot(token=settings.API_TOKEN)
    storage = RedisStorage2('localhost', 6379, db=5, pool_size=10, prefix='my_fsm_key')
    dp = Dispatcher(bot, storage=storage)

    # Регистрация хэндлеров
    register_handlers_common(dp)
    register_handlers_lowprice(dp)

    # Установка команд бота
    await set_commands(bot)

    # Запуск поллинга
    await dp.skip_updates()  # пропуск накопившихся апдейтов (необязательно)
    await dp.start_polling()

скрипт lowprice с проблемой.

class HotelOrder(StatesGroup):
    waiting_for_city_name_l = State()
    waiting_for_city_answer_l = State()
    waiting_for_hotel_number_l = State()
    waiting_for_photo_number_l = State()
    waiting_for_history_saving_l = State()

async def hotels_start(message: types.Message):
    message_text = f'введите название города'
    await message.answer(message_text)
    await HotelOrder.waiting_for_city_name_l.set()

async def hotels_buttons(message: types.Message, state: FSMContext):
    тут формируется инлайн клавиатура

async def city_name_chosen(call: types.CallbackQuery, state: FSMContext):
    if call.data[4:] =='red':
        await call.answer("давай по новой миша.")
        return
    await state.update_data(city_id=call.data[4:])
    await call.answer("Cпрашиваю вопрос ?:") # код выводит уведомление, а не сообщение.
    await HotelOrder.next()
    await HotelOrder.waiting_for_hotel_number_l.set()

async def hotel_count_chosen(message: types.Message, state: FSMContext):
    код опущен для краткости

async def photo_count_chosen(message: types.Message, state: FSMContext):
    код опущен для краткости

async def history_chosen(message: types.Message, state: FSMContext):
    код опущен для краткости

def register_handlers_lowprice(dp: Dispatcher):
    dp.register_message_handler(hotels_start, commands="lowprice", state="*")
    dp.register_message_handler(hotels_buttons, state=HotelOrder.waiting_for_city_name_l)
    dp.register_callback_query_handler(city_name_chosen, state=HotelOrder.waiting_for_city_answer_l)
    dp.register_message_handler(hotel_count_chosen, state=HotelOrder.waiting_for_hotel_number_l)
    dp.register_message_handler(photo_count_chosen, state=HotelOrder.waiting_for_photo_number_l)
    dp.register_message_handler(history_chosen, state=HotelOrder.waiting_for_history_saving_l)

Это не сложно просто нужно обратится к объекту measage который находится в call.
<code>
await call.message.answer("text")
</code>


Как можно ускорить этот код Python?
Решаю задачу, но она не проходит все тесты по времени. Как я могу ускорить код?
В детском саду готовятся к новому году, и воспитательница решила организовать детей, чтобы они подготовили украшения и отправили их Санте Клаусу для украшения своих оленей.
Дети с интересом восприняли идею и вырезали из бумаги a звездочек и b снежинок. Теперь они планируют отправить их Санте Клаусу по почте. Им так понравились вырезанные ими украшения, что они, возможно, решат оставить себе часть. Таким образом, дети могут отправить Санте x звездочек и y снежинок, где 0≤x≤a и 0≤y≤b. Чтобы Санта не расстроился, дети должны отправить ему хотя бы одно украшение. То есть должно выполняться также условие x+y>0.
Чтобы все олени выглядели красиво, на каждом должно оказаться одинаковое количество украшений. Известно, что у Санты n оленей, поэтому если будут отправлены x звездочек и y снежинок, величина x+y должна делиться на n.
Воспитательница заинтересовалась: а сколько есть всего различных способов составить посылку Санте Клаусу. Два способа считаются различными, если в них отличается количество звездочек или количество снежинок.

Входные данные

В одном наборе входных данных содержатся несколько тестов. Каждый тест следует решить независимо.
Первая строка входных данных содержит целое число t — количество тестов (1≤t≤105).
Следующие строки описывают тесты, по одному на строке. Описание теста состоит из трех целых чисел n, a и b — количество оленей у Санты, количество звездочек и количество снежинок, вырезанных детьми (4≤n≤109; 0≤a,b≤109).

Выходные данные

Выведите t чисел. Для каждого теста выведите одно число: количество способов составить посылку для Санты Клауса.*
<code>
amount_of_tests = int(input())
for i in range(amount_of_tests):
    test = input().split()
    deers = int(test[0])
    stars = int(test[1])
    snows = int(test[2])
    x = deers
    result = 0
    all_deers = [deers]
    while True:
        if deers + x <= (stars + snows):
            deers+=x
            all_deers.append(deers)
        else:
            break
    for item in all_deers:
        num1 = item
        num2 = 0
        for i in range(item+1):
            if num1 <= stars and num2 <= snows:
                result +=1
            num1-=1
            num2+=1
    print(result)
</code>

Давайте подумаем... Итак,

x+y = n*k

при этом  k > 0 (условие x+y>0). Итак, к лежит в диапазоне

1..(a+b)//n

В цикле по этому диапазону (не забыть +1 из-за того, что верхняя граница в
range не включается), прикинем, сколько же вариантов может быть...
x может быть от 0 до
min(kn,a), y — 0 до
min(mn,b). C учетом того, что
x+y == nk, получается, что
kn украшений можно получить
min(kn,a) +min(kn,b)-nk+1 способом.
Осталось просуммировать эти значения для всех
k из указанного выше диапазона.
Поскольку писал со скоростью набора текста, добавлю-ка своё
"По-моему, так" (с) Пух


Для чего стоит указывать @pyqtSlot() перед методами? (PyQt5)
Изучаю PyQt5 по книге Прохоренка. В ней написано, что
@pyqtSlot() ускоряет выполнение метода.
Решил проверить, правда ли это. Создал функцию, в нее запихнул сначала мелкий цикл - до 10.000, затем побольше - до 200.000, и в конечном итоге - до 2 млн.
Каждый раз проводил замеры с использованием
@pyqtSlot() и без него. Все 3 замера выиграл вариант, в котором не используется
pyqtSlot(). Для сравнения - при 2 млн метод с
pyqtSlot() показал результат в 66 секунд, когда без его использования выдало 60.5 секунд.
Так почему же стоит использовать этот декоратор, если без него код выполняется быстрее? Или его стоит использовать только в том случае, если функция будет работать куда дольше 60 секунд?

from PyQt5.Qt import *
import sys
import time

class MainWindow(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.start = time.time()
        self.fun()
    @pyqtSlot()
    def fun(self):
        for i in range(2000000):
            print(i)
        end = time.time()
        print(end - self.start)

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

Там где вы читаете, речь видимо идет о сигналах и слотах.
Декоратор
pyqtSlot() является частью синтаксиса сигналов и слотов.
Ваш пример никакого отношения к сигналам и слотам не имеет.
Вот вам пример, попробуйте

import sys
import time
from PyQt5.Qt import *

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.button = QPushButton('Button', self)
        self.button.clicked.connect(self.on_clicked)

        self.start = time.time()

#        self.fun()
        QTimer.singleShot(1000, self.fun)           # +++

    def fun(self):
        for i in range(2_000_000):
            self.button.click()                     # - print(i)
        end = time.time()
        print(end - self.start)

    @pyqtSlot()                                     # +++ <----
    def on_clicked(self):
        pass

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


Бот не реагирует на нажатие inline кнопки Aiogram
Пишу бота с помощью библиотеки aiogram.  Диалог формируется с помощью FSM.
суть такова: бот спрашивает пользователя название города, он вводит, я обращаюсь к API,  и так как в результатах чаще всего несколько вариантов, я формирую инлайн кнопки с названиями. Пользователь нажимает нужную кнопку, опрос продолжается.
Но всё спотыкается на нажатии инлайн кнопки. (я так подозреваю что неправильно регистрировал хендлеры)
код
<code>
class HotelOrder(StatesGroup):
    waiting_for_city_name_h = State()
    waiting_for_city_answer_h = State()
    waiting_for_hotel_number_h = State()
    waiting_for_photo_number_h = State()
    waiting_for_history_saving_h = State()

async def hotels_start(message: types.Message):
    message_text = f'введите название города'
    await message.answer(message_text)
    await HotelOrder.waiting_for_city_name_h.set()
    logger.info('старт прошёл')

async def hotels_buttons(message: types.Message, state: FSMContext):
    logger.info('hotels_buttons вызвано')
    loc = make_locations_list(message=message)
    if not loc or len(loc) <1:
        await message.answer("Ничего не найдено, повторите запрос.")
        return
    elif loc.get('bad_request'):
        await message.answer('сервер недоступен')
        return
    else:

        city_keyboard = types.InlineKeyboardMarkup()
        for loc_name, loc_id in loc.items():
            city_keyboard.add(types.InlineKeyboardButton(
                text = loc_name,
                callback_data=f'code{loc_id}'
            ))
        await message.answer('жми кнопка', reply_markup=city_keyboard)
        await HotelOrder.waiting_for_city_answer_h.set()

async def city_name_chosen(call: types.CallbackQuery, state: FSMContext):
    await state.update_data(city_id=call.data[4:])
    await HotelOrder.next()
    await call.answer("сколько отелей выводить ?:")
    await HotelOrder.waiting_for_hotel_number_h.set()

async def hotel_count_chosen(message: types.Message, state: FSMContext):
    код опущен для краткости

async def photo_count_chosen(message: types.Message, state: FSMContext)
    код опущен для краткости
async def history_chosen(message: types.Message, state: FSMContext):
    код опущен для краткости
    await state.finish()

async def cancel(message: types.Message, state:FSMContext):
    await state.finish()
    await message.answer('Действие отменено', reply_markup=types.ReplyKeyboardRemove())

def register_handlers_highprice(dp: Dispatcher):
    dp.register_message_handler(hotels_start, commands="highprice", state="*")
    dp.register_message_handler(hotels_buttons, state=HotelOrder.waiting_for_city_name_h)
    dp.callback_query_handler(city_name_chosen, state=HotelOrder.waiting_for_city_answer_h)
    dp.register_message_handler(hotel_count_chosen, state=HotelOrder.waiting_for_hotel_number_h)
    dp.register_message_handler(photo_count_chosen, state=HotelOrder.waiting_for_photo_number_h)
    dp.register_message_handler(history_chosen, state=HotelOrder.waiting_for_history_saving_h)
</code>

Потому что в конце не

callback_query_handler

а

register_callback_query_handler


Как сделать универсальный mock для проверки получаемых парамеров?
Мне нужно протестировать ряд функций func1, func2 и т.д., которые немного схожи по структуре и все взывают в конце функцию execute.
Я хочу проверить, что эти функции возвращают верный результат и что они формируют верные параметры передаваемые в execute.
Путём мока функции execute я возвращаю нужный результат, и там же в моке получаю параметры.
Как мне сделать универсальный мок, может быть в виде фикстуры, чтобы не дублировать его код во всех тестируемых функциях?
Основной вопрос - как получить фактические тестируемые параметры.
Пример я очень упростил - в реальности в фунциях бывают ветвления и поэтому тесты отличаются.
Здесь из-за упрощения, тесты 1 и 2 отличаются только этим: func1 и func2, 'param1' и 'param2'

def func1():
    return execute('param1')

def func2():
    return execute('param2')

def test_1(monkeypatch):
    actual_param = ''

    def mock_(param):
        nonlocal actual_param
        actual_param = param
        return True

    monkeypatch.setattr('execute', mock_)

    assert func1() == True
    assert actual_param == 'param1'

def test_2(monkeypatch):
    actual_param = ''

    def mock_(param):
        nonlocal actual_param
        actual_param = param
        return True

    monkeypatch.setattr('execute', mock_)

    assert func2() == True
    assert actual_param == 'param2'

Вижу такой вариант решения - переделать функции func, чтобы была еще функция возвращаемая параметры.
И тестировать отдельно func1_param и отдельно func1. Но это не совсем то, и можно ли проще?

def func1():
    param = func1_param()
    return execute_command(param)

def func1_param():
    return 'param1'

Вам нужна параметризация теста. Вот вариант без
monckeypatch, а с использованием стандартного модуля
unittest.mock, так проще и идет из коробки:

# файл f.py
def execute(p):
    print(f'in execute with param={p}')
    return True

def func1():
    return execute('param1')

def func2():
    return execute('param2')

# файл test_f.py
import pytest
from f import func1, func2
from unittest.mock import patch

@pytest.mark.parametrize(
    "func_to_test,param_value",
    [(func1, 'param1'), (func2, 'param2')]
)
def test_1(func_to_test, param_value):
    SOME_RETURN_VALUE = 'some-vaue'

    with patch('f.execute') as mocked_execute:
        mocked_execute.return_value = SOME_RETURN_VALUE
        assert func_to_test() == SOME_RETURN_VALUE
        mocked_execute.assert_called_with(param_value)

Можно вынести и в фикстуру:

SOME_RETURN_VALUE = 'some-vaue'

@pytest.fixture
def mocked_execute():
    with patch('f.execute') as mocked_execute:
        mocked_execute.return_value = SOME_RETURN_VALUE
        yield mocked_execute

@pytest.mark.parametrize(
    "func_to_test,param_value",
    [(func1, 'param1'), (func2, 'param2')]
)
def test_1(func_to_test, param_value, mocked_execute):
    assert func_to_test() == SOME_RETURN_VALUE
    mocked_execute.assert_called_with(param_value)


Помогите пожалуйста реализовать функцию
Пожалуйста помогите реализовать данную функцию.

 def reverse_subword(s: str, subword: str) -> str:
"""
If subword exists in s, reverse the first occurrence of s and return the modified string.
Otherwise return original s.
reverse_subword("abcde", "bc") => "acbde"
reverse_subword("abcabc", "bc") => "acbabc"
reverse_subword("abcabc", "ac") => "abcabc"
:param s: original string
:param subword: len(subword) > 0
:return:
"""
pass

**У меня не проходит 3 тестер **

assert reverse_subword("tere", "ab") == "tere"
assert reverse_subword("tere", "te") == "etre"
assert reverse_subword("teretere", "te") == "etretere"

Мой код

if subword in s:
    reversed = subword[-1::-1]
    return s.replace(subword, reversed)
else:
    return s

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


Как правильно отображать прогресс в консоли?
В моей программе имеются различные числовые значения, которые постоянно изменяются, мне требуется выводить их в консоль (
без использования GUI). Самое простое - это выводить каждую отдельную строку на каждой итерации, но тогда она засоряет консоль, и читать не удобно. Пробовал очищать консоль через
cls||clear - тоже не самый лучший вариант, потому что выводится все очень быстро, а задержки выставлять не хочется. Последнее, что я придумал - использовать
progressbar, и тут тоже возникли проблемы (1
progressbar работает корректно, а если я пробую сделать их несколько, то они друг друга перекрывают, как я понял, это происходит из-за возврата каретки, может быть и нет). У меня есть значения, которые не имеют пределов (то есть нет границы, и они могут бесконечно увеличиваться или уменьшаться), я посчитал, что для этого подойдет
Counter. Но также есть значения, у которых есть границы, например 0/100 - там я уже решил использовать обычный
progressbar. В идеале, хотелось бы, чтобы все эти строки были поочередно расположены в консоли и работали параллельно. Вот то, что я пробовал сделать (далеко от истины):

import time
from progress.counter import Counter
from progress.bar import Bar

my_list = []
for x in range(1, 101):
    my_list.append(x)
val = 0

counter_ = Counter('Counter: ')

for item in range(0, 100, 5):
    counter_.next(item-val)
    val = item
    time.sleep(0.5)

counter_.finish()

bar = Bar('Gens', max=len(my_list))

for item in my_list:
    bar.next()
    time.sleep(0.2)

bar.finish()

PS Даже в отдельных потоках пытался сделать, но потом осознал, что это не самый умный ход)

Попробуйте воспользоваться модулем tqdm:
<code>
from tqdm import tqdm
for i in tqdm(range(10000)):
    ...
</code>


Не происходит переход в другой хэндлер после нажатия inline клавиатуры aiogram
После нажатия на одну из кнопок инлайн клавиатуры никакого действия не происходит, на этой кнопке внизу справа появляются часики, которые стоят секунд 5, потом исчезают и все.
Вот мой код:

@dp.message_handler(state=FindBook.book)
async def looking_book(message: types.Message, state: FSMContext):
    answer = message.text
    if len(answer) > 200:
        await message.answer('Максимально допустимое количество символов - 200. Попробуйте снова')
        await FindBook.book.set()
    else:
        await state.update_data(book=answer)
        await message.answer('Приступаю к поиску')
        data = await state.get_data()
        result = await find_book(answer=data["book"], message=message, bot=bot)
        if result:
            await state.update_data(next_page_url=result)
            await message.answer('Какое действие совершим?', reply_markup=choice)
        else:
            await message.answer('Книг больше нет')
            await state.reset_state()

@dp.callback_query_handler(text="next_page", state=FindBook.next_page)
async def new_page(message: types.Message, state: FSMContext):
    await message.answer('Приступаю к поиску')
    data = await state.get_data()
    result = await next_page(url=data["next_page_url"], message=message, bot=bot)
    if result:
        await state.update_data(next_page_url=result)
        await message.answer('Какое действие совершим?', reply_markup=choice)
    else:
        await message.answer('Книг больше нет')
        await state.reset_state()

@dp.callback_query_handler(text="cancel", state=FindBook.cancel)
async def cancel(call: CallbackQuery, message: types.Message, state: FSMContext):
    await call.answer("Вы отменили текущую комманду")
    await call.message.edit_reply_markup()
    await state.reset_state()
    await message.answer('Для просмотра всего функционала, воспользуйтесь коммандой /help')

Клавиатура:

choice = InlineKeyboardMarkup(
                              inline_keyboard=[
                                  [
                                      InlineKeyboardButton(
                                          text="Следующая страница",
                                          callback_data="next_page"
                                      )
                                  ],
                                  [
                                      InlineKeyboardButton(
                                          text="Отмена",
                                          callback_data="cancel"
                                      )
                                  ]
                              ])

В чем может быть проблема?

Судя по коду, ни разу не увидел чтобы было изменение текущего стейта на FindBook.cancel или FindBook.next_page.
Получается вы на кнопку жмёте а Стейт все ещё остаётся на FindBook.book.
Чтобы ваш код заработал просто в колбеках хендлеров оставьте state=FindBook без уточнения какое именно состояние.


Как правильно читать json python
изучая Python, а именно библиотеку json, столкнулся с непониманием как правильно мне извлечь только те данные, которые нужны?
Пример кусочка json файла ниже. как мне извлечь только id и name?
<code>
{
    "state": 0,
    "version": 2,
    "data": {
        "products": [
            {
                "id": 30030535,
                "root": 22125105,
                "kindId": 1,
                "subjectId": 105,
                "name": "Кроссовки",
                "brand": "Reebok",
                "brandId": 777,
                "siteBrandId": 748,
                "sale": 35,
                "priceU": 539900,
                "salePriceU": 350900,
                "pics": 4,
                "rating": 5,
                "feedbacks": 19,
                "colors": [
                    {
                        "name": "белый",
                        "id": 16777215
                    }
                },
                {

                "id": 30304723,
                "root": 22425063,
                "kindId": 1,
                "subjectId": 105,
                "name": "Кроссовки",
                "brand": "adidas",
                "brandId": 21,
                "siteBrandId": 561,
                "sale": 36,
                "priceU": 799900,
                "salePriceU": 511900,
                "pics": 10,
                "rating": 5,
                "feedbacks": 9,
                "colors": [
                    {
                        "name": "серый",
                        "id": 8421504
                    }
</code>

Для начала Вам нужно распарсить его, то есть преобразовать из строки в объект одного из стандартных типов Python. Для этого Вы можете воспользоваться библиотекой
json, а точнее методом
json.loads.
Данный метод вернёт Вам словарь. Извлекайте из него значения по ключу, пока не доберётесь до нужного.
Пример:

import json

s = '{"data":{"products":[{"colors":[{"name":"белый","id":16777215}]}]}}'
d = json.loads(s)

for product in d['data']['products']:
    for color in product['colors']:
        print(color['name'])
        print(color['id'])

stdout:

белый
16777215


«Кусок» и отношение
На нижегородской олимпиаде 2019 года предлагалась следующая задача:
Существуют ли такие натуральные числа a и b, в десятичной записи каждого из которых есть кусок подряд стоящих цифр 2019 и при этом отношение a:b=2019?
Найти какую-нибудь такую пару нетрудно. Например, 201900001 и 407636102019. Однако меня заинтересовала наименьшая такая пара. И если верить Питону (а как можно ему не верить?), это числа 10002019 и 20194076361.
Одна лишь загвоздка: код работает ну из рук вон медленно.
<code>
# К задаче "«Кусок» и отношение"

kusok=int(input())
otn=int(input())
k=1
while (str(k).find(str(kusok))==-1
    or str(otn*k).find(str(kusok))==-1):
        k+=1
print(k, otn*k)
</code>
Можно ли изменить этот код так, чтобы программа работала быстрее?
P. S. Кстати, Если в условии задачи заменить 2019 на номер текущего года (2022), то ответ будет аналогичным: 10002022 и 20224088484. А вот для следующего года уже не так: не 10002023 и 20234092529, а 9492023 и 19202362529. Любопытно, имеются ли там какие-то закономерности?

Очевидная оптимизация - работать с числами, а не со строками, и перебирать не все числа, а генерировать только меньшие числа, содержащие 2019
Пример для демонстрации подхода, он не выполняет правильный обход по возрастанию (что по уму следует сделать, как и отменить ограничение длины), однако работает мгновенно:
<code>
year = 2023
smallest = 999999999
for leftlen in range(5):
    leftmax = 10**leftlen
    for rightlen in range(5 - leftlen):
        rightmax = 10**rightlen
        for left in range(leftmax):
            l = left * 10**(4+rightlen) + year * 10**rightlen
            for right in range(rightmax):
                small = l  + right
                large = small * year
                while large >= year:
                    if large % 10000 == year:
                        smallest = min(small, smallest)
                        break
                    large //= 10
print(smallest, smallest * year)

>>9492023 19202362529
</code>


Исключение - StopIteration [закрыт]

Закрыт. Этот вопрос не по теме. Ответы на него в данный момент не принимаются.

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

Закрыт 1 год назад.

                        Улучшить вопрос

Подскажите пожалуйста, как поместить StopIteration в исключение.
Например: Эмуляция for через while
Мой код следующий:
<code>
n = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

iterator = n.__iter__()

while True:
    try:
        print(next(iterator))
    except SropIteration:
        print('Итератор опустошен')
</code>
Но при запуске сначала выходит следующая ошибка:

Traceback (most recent call last):   File
"C:\Users\Nikita.Uvaliyev.KPI\PycharmProjects\python-ds\27_Iterators_and_generators\practice\while_like_for.py",
line 8, in
print(next(iterator)) StopIteration
During handling of the above exception, another exception occurred:
Traceback (most recent call last):   File
"C:\Users\Nikita.Uvaliyev.KPI\PycharmProjects\python-ds\27_Iterators_and_generators\practice\while_like_for.py",
line 9, in
except SropIteration: NameError: name 'SropIteration' is not defined

После ошибки уже выводятся объекты итератора
Заранее спасибо :)

Исправьте
SropIteration на
StopIteration...

n = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

iterator = iter(n)

while True:
    try:
        print(next(iterator))
    except StopIteration:
        print('Итератор опустошен')
        break


Как получить название ряда в QTableWidget по его индексу?
Есть таблица, в которой 6 рядов. Каждый ряд имеет своё название.
Есть ли метод получить это название по индексу?
<code>
self.table = QTableWidget(self)
self.table. ...                    # метод для получение 4 ряда
</code>

Вывести имя ряда можно с помощью метода
.verticalHeaderItem(i).text()
Пример использования :

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(270, 270)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(10, 10, 250, 250))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(0)
        self.tableWidget.setRowCount(0)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

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

        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(2)
        item = QtWidgets.QTableWidgetItem()
        item.setText('имя')
        self.tableWidget.setVerticalHeaderItem(1, item)

        print(self.tableWidget.verticalHeaderItem(1).text()) # < --- выводит имя ряда

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


Как добавить категориальный столбец по какому-то условию с помощью метода assing() и pandas
Я хочу добавить столбец
company с помощью метода
assing, где будет условие
sales >= 45000, то добавить название компании
Вот датафрейм:

       name     region  sales   expenses
0      William  East    50000   42000
1      Emma     North   52000   43000
2      Sofia    East    90000   50000
3      Markus   South   34000   44000
4      Edward   West    42000   38000
5      Thomas   West    72000   39000
6      Ethan    South   49000   42000
7      Olivia   West    55000   60000
8      Arun     West    67000   39000
9      Anika    East    65000   44000
10     Paulo    South   67000   45000

Вот мой код:

df.assing(
    company = df.sales.apply(lambda x: x > 45000)
)

    name    region  sales   expenses company
0   William East    50000   42000   True
1   Emma    North   52000   43000   True
2   Sofia   East    90000   50000   True
3   Markus  South   34000   44000   False
4   Edward  West    42000   38000   False
5   Thomas  West    72000   39000   True
6   Ethan   South   49000   42000   True
7   Olivia  West    55000   60000   True
8   Arun    West    67000   39000   True
9   Anika   East    65000   44000   True
10  Paulo   South   67000   45000   True

Я хочу, чтобы вместо
True было
PatnaCompany

Воспользуйтесь функцией np.where():
<code>
In [105]: df.assign(company=np.where(df["sales"] >= 45000, "PatnaCompany", ""))
Out[105]:
       name region  sales  expenses       company
0   William   East  50000     42000  PatnaCompany
1      Emma  North  52000     43000  PatnaCompany
2     Sofia   East  90000     50000  PatnaCompany
3    Markus  South  34000     44000
4    Edward   West  42000     38000
5    Thomas   West  72000     39000  PatnaCompany
6     Ethan  South  49000     42000  PatnaCompany
7    Olivia   West  55000     60000  PatnaCompany
8      Arun   West  67000     39000  PatnaCompany
9     Anika   East  65000     44000  PatnaCompany
10    Paulo  South  67000     45000  PatnaCompany
</code>


Механизм поворота змейки на Python Pygame
Я решил сделать змейку на pygame. Всё смог написать, кроме поворота. В голове выглядит у меня это так: запоминается координата головы в момент нажатия кнопки, далее голова уходит в другую сторону, а тело поочередно вставая на место головы в момент нажатия, тоже поворачивает. Но что-то никак не получается это реализовать.
<code>
import pygame
from pygame import key
import random
import time

def motion(screen):
    global snake_body,snake_head,case
    snake_head[0] += snake_head[2]
    snake_head[1] += snake_head[3]
    for n in range(len(snake_body)):
        snake_body[n][0] += snake_body[n][2]
        snake_body[n][1] += snake_body[n][3]
        pygame.draw.circle(screen, 'yellow', (snake_body[n][0],snake_body[n][1]), 10)
    pygame.draw.circle(screen, 'yellow', (snake_head[0],snake_head[1]), 10)
    food()
    eating(adding)

def food():
    global snake_body,snake_head,case
    nose = random.choice([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15])
    if nose == 1:
        x = random.randrange(44,458)
        y = random.randrange(44,458)
        if len(case) != 3:
            case.append([x, y])

def eating(thg):
    global snake_body,snake_head,case
    xl = snake_body[-1][0]
    yl = snake_body[-1][1]
    xf = snake_head[0]
    yf = snake_head[1]
    delete = []
    for i in range(len(case)):
        if xf > case[i][0] - 7 and xf < case[i][0] + 7 and yf > case[i][1] - 7 and yf < case[i][1] + 7:
            if thg == 'down':
                snake_body.append([xl,yl + 10,0,-1])
                delete.append(i)
            if thg == 'up':
                snake_body.append([xl,yl - 10,0,1])
                delete.append(i)
            if thg == 'left':
                snake_body.append([xl - 10,yl,1,0])
                delete.append(i)
            if thg == 'right':
                snake_body.append([xl + 10,yl,-1,0])
                delete.append(i)
    for i in delete:
        del case[i]

def lose(screen):
    global snake_body,snake_head,case
    case = []
    font = pygame.font.Font(None,50)
    textwon1 = font.render('YOU LOSED!',True,(100,255,100))
    screen.blit(textwon1,(155,220))
    textnewgame1 = font.render('NEW GAME',True,(100,255,100))
    screen.blit(textnewgame1,(165,270))
    pygame.draw.rect(screen,(100,255,100), (155,260,215,50),1)
    if event.type == pygame.MOUSEBUTTONDOWN:
        print(event.pos[0],event.pos[1])
        if 380 > event.pos[0] > 155 and 290 > event.pos[1] > 260:
            snake_head = [250,250,1,0]
            snake_body = [[240,250,1,0],[230,250,1,0]]
            adding = 'left'

if __name__ == '__main__':
    pygame.init()
    size = width,height = 500,500
    screen = pygame.display.set_mode(size)
    running = True
    clock = pygame.time.Clock()
    snake_head = [250,250,1,0]
    snake_body = [[240,250,1,0],[230,250,1,0]]
    case = []
    adding = 'left'

    #задаем цикл, который выступает в качестве обработчика
    while running:
        #создаем эвент на закрытие программы
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP and adding != 'up':
                    adding = 'down'
                    snake_head[2] = 0
                    snake_head[3] = -1
                elif event.key == pygame.K_DOWN and adding != 'down':
                    adding = 'up'
                    snake_head[2] = 0
                    snake_head[3] = 1
                elif event.key == pygame.K_RIGHT and adding != 'right':
                    adding = 'left'
                    snake_head[2] = 1
                    snake_head[3] = 0
                elif event.key == pygame.K_LEFT and adding != 'left':
                    adding = 'right'
                    snake_head[2] = -1
                    snake_head[3] = 0

        pygame.draw.rect(screen, 'white', (10,10,480,480),1)

        for n in case:
            pygame.draw.circle(screen, 'yellow', (n[0],n[1]), 7)

        if snake_head[0] > 478 or snake_head[0] < 22 or snake_head[1] > 478 or snake_head[1] < 22:
            lose(screen)
        else:
            motion(screen)

        clock.tick(100)
        pygame.display.flip()
        screen.fill('black')

pygame.quit()
</code>

Поигрался с вашим кодом. Вот, что у меня получилось.
<code>
import pygame
from pygame import key
import random
import time

config = {
    "head_size" : 10,
    "head_color": "blue",
    "body_space": 10,
    "body_size" : 8,
    "body_color": "yellow",
    "body_start_length": 2,
    "case_size" : 7,
    "case_color": "green",
    "case_max"  : 3
}

def motion(screen):
    global snake_add
    if snake_add: snake_add -= 1      # extending snake
    else        : snake_body.pop(0)   # delete tail
    snake_body.append(tuple(map(sum, zip(snake_body[-1], movement))))  # add head
    #for xy in snake_body[:-1:config["body_space"]]: # alt variant
    for xy in snake_body[::-1][config["body_space"]::config["body_space"]]:
        pygame.draw.circle(screen, config["body_color"], xy, config["body_size"])
    pygame.draw.circle(screen, config["head_color"], snake_body[-1], config["head_size"])
    food()
    eating()

def self_inersect():
    xh,yh = snake_body[-1] # head coords
    distance = (config["head_size"] + config["case_size"]) ** 2  # touch distance
    for x,y in snake_body[:-int((config["head_size"] + config["case_size"]+1)*1.5-2)]:
        if (xh - x)**2 + (yh - y)**2 < distance:
            return True
    return False

def food():
    if not case or len(case) < config["case_max"]:
        nose = random.choice([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15]) if case else 1
        if nose == 1:
            x = random.randrange(44,458)
            y = random.randrange(44,458)
            case.append((x, y))

def eating():
    global snake_add
    xh,yh = snake_body[-1] # head coords
    distance = (config["head_size"] + config["case_size"]) ** 2  # touch distance
    for i,(x,y) in enumerate(case):
        if (xh - x)**2 + (yh - y)**2 < distance:
            snake_add += config["body_space"]
            case.pop(i)

def lose(screen):
    global case
    case = []
    font = pygame.font.Font(None,50)
    textwon1 = font.render('YOU LOSE!',True,(110,255,100))
    screen.blit(textwon1,(168,220))
    textnewgame1 = font.render('NEW GAME',True,(100,255,100))
    screen.blit(textnewgame1,(165,270))
    pygame.draw.rect(screen,(100,255,100), (155,260,215,50),1)
    if event.type == pygame.MOUSEBUTTONDOWN:
        print(event.pos[0],event.pos[1])
        if 380 > event.pos[0] > 155 and 290 > event.pos[1] > 260:
            new_game()

def new_game():
    global snake_body, case, movement, snake_add
    # snake head is the last element of list
    snake_body = [(250-i, 250) for i in range(config["body_start_length"]*config["body_space"]+1)][::-1]
    movement = (1, 0)
    case = []
    snake_add = 0

if __name__ == '__main__':
    pygame.init()
    size = width,height = 500,500
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()
    new_game()

    #задаем цикл, который выступает в качестве обработчика
    running = True
    while running:
        #создаем эвент на закрытие программы
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP and not movement[1]:
                    movement = (0, -1)
                elif event.key == pygame.K_DOWN and not movement[1]:
                    movement = (0, 1)
                elif event.key == pygame.K_RIGHT and not movement[0]:
                    movement = (1, 0)
                elif event.key == pygame.K_LEFT  and not movement[0]:
                    movement = (-1, 0)

        pygame.draw.rect(screen, 'white', (10,10,480,480),1)

        for xy in case:
            pygame.draw.circle(screen, config["case_color"], xy, config["case_size"])

        x, y = snake_body[-1]
        if 22 <= x <= 478 and 22 <= y <= 478 and not self_inersect():
            motion(screen)
        else:
            lose(screen)

        clock.tick(100)
        pygame.display.flip()
        screen.fill('black')

pygame.quit()
</code>


Как создать копию поля в Tkinter, но с другими координатами?
<code>
import copy
import tkinter
from tkinter import *
from tkinter import ttk
from gtts import gTTS
import sys

CHN_cordX = 130
CHN_cordY = 5

Ru_CordX = 265
Ru_CordY = 5

def app_Run():

    Win = Tk()
    Win.geometry('500x450')
    Convert_Btn = Button(Win,
                         text='Convert',
                         width=10,
                         height=2,
                         bg='gray',
                         fg='black',
                         font='arail 10')
    Convert_Btn.place(x=0, y=3)

    Sort_Btn = Button(Win,
                      text='Sorting',
                      width=10,
                      height=2,
                      bg='gray',
                      fg='black',
                      font='bold 9')
    Sort_Btn.place(x=0, y=50)

    Quantity_Btn_plus = Button(Win,
                               text='十',
                               width=10,
                               height=2,
                               bg='green',
                               fg='white',
                               font='bold 8'
                               )
    Quantity_Btn_plus.place(x=0, y=100)

    Chn_entr = Entry(Win)
    Chn_entr.place(x=CHN_cordX, y=CHN_cordY)

    Ru_Entr = Entry(Win)
    Ru_Entr.place(x=Ru_CordX, y=Ru_CordY)
    LST = {0: Chn_entr,
           1: Ru_Entr}
#Вот тут должна создаваться копия Двух полей ввода, и помещаться ниже на определенное количество пикселей. Как это реализовать ?
    LST2 = LST.copy

    Quantity_Btn_minus = Button(Win,
                                text='一',
                                width=10,
                                height=2,
                                bg='red',
                                fg='black',
                                font='bold 8',
                                command= LST2 )
    Quantity_Btn_minus.place(x=0, y=150)
    Win.mainloop()
###############################################################################

if __name__ =='__main__':
    app_Run()

</code>

Что ж так все любят этот
place() и пиксели считать? :) Когда оно может само всё размещать.

from tkinter import *
from tkinter import ttk

def app_run():
    entries = []

    def add_line(parent):
        frame = Frame(parent)
        frame.pack(fill=X)

        chn_entr = Entry(frame)
        chn_entr.pack(side=LEFT, padx=4, pady=4)

        ru_entr = Entry(frame)
        ru_entr.pack(side=LEFT, padx=4, pady=4)

        entries.append((frame, chn_entr, ru_entr))

    def remove_line():
        if entries:
            frame, *_ = entries.pop()
            frame.destroy()

    win = Tk()
    win.geometry('500x450')

    frame_btn = Frame(win)
    frame_btn.pack(side=LEFT, fill=Y, padx=2)
    frame_entries = Frame(win)
    frame_entries.pack(side=LEFT, fill=BOTH, expand=True, padx=2)

    convert_btn = Button(frame_btn,
                         text='Convert',
                         padx=10, pady=10,
                         bg='gray',
                         fg='black',
                         font='arail 10')
    convert_btn.pack(pady=2, fill=X)

    sort_btn = Button(frame_btn,
                      text='Sorting',
                      padx=10, pady=10,
                      bg='gray',
                      fg='black',
                      font='bold 9')
    sort_btn.pack(pady=2, fill=X)

    quantity_btn_plus = Button(frame_btn,
                               text='十',
                               padx=10, pady=10,
                               bg='green',
                               fg='white',
                               font='bold 8',
                               command=lambda: add_line(frame_entries))
    quantity_btn_plus.pack(pady=2, fill=X)

    quantity_btn_minus = Button(frame_btn,
                                text='一',
                                padx=10, pady=10,
                                bg='red',
                                fg='black',
                                font='bold 8',
                                command=remove_line)
    quantity_btn_minus.pack(pady=2, fill=X)

    add_line(frame_entries)
    win.mainloop()

if __name__ =='__main__':
    app_run()


Как сравнить элементы в списке?
Доброго времени суток, друзья,
У меня вопрос. Вот есть список:
<code>
a = [('германия', ), ('германия', ), ('япония', )]
</code>
Как сравнить список так, что если попадаются две одинаковые страны, то удалять одну из них?
И еще желательно как убрать лишние символы, но это другое)
list.set(a) почему-то не работает

list.set(a) почему-то не работает

Потому что у типа
list не существует метода
set(). Вместо этого предлагаю просто обернуть
set(a) в
list() — программа самостоятельно превратит множество (без повторяющихся элементов) в список:

a = [('германия', ), ('германия', ), ('япония', )]
print(list(set(a)))

-----

[('япония',), ('германия',)]


Как исправить ошибку чтоб корректно выводилось наименование возраста, по введенной цифре возраста?
<code>
age = int(input())

agesMapping = {
    'Младенец': range(0, 1),
    'Малыш': range(2, 3),
    'Ребенок': range(4, 11),
    'Подросток': range(12, 18),
    'Взрослый человек': range(19, 64),
    'Пожилой человек': range(65, 100),
}

print(agesMapping[age-1])
</code>

К примеру такой вариант
<code>
age = int(input())

agesMapping = {
    'Младенец': range(0, 2),
    'Малыш': range(2, 4),
    'Ребенок': range(4, 12),
    'Подросток': range(12, 19),
    'Взрослый человек': range(19, 65),
    'Пожилой человек': range(65, 101),
}

for k, v in agesMapping.items():
    if age in v:
        print(k)
</code>
Вам необходимо проитерироваться по словарю и провести сравнение. Так же рекомендую сдвинуть range на 1 вправо, как привел я, тогда вы будете попадать в диапазон.


Как можно ускорить поиск данных в словаре Python?
У меня есть лист строк и словарь. Например:

a = ["a", "b", "c", "d"]
d = {
    "1":
        {
            "ids": ["7612029690", "7612018248"],
            "words": ["d", "o", "m"]
        },
    "2":
        {
            "ids": ["7612018249", "7612029691"],
            "words": ["a", "b", "c"]
        },
    ....
}

Мне надо найти такой элемент словаря
d, в котором в ключе
"words" наибольшее количество элементов из листа
a. Ниже метод, в котором это вычисляется.

def find_best(a, d):
    result = {"words": [], "intersactions": 0}
    for v in d.values():
        i = len(list(set(a) & set(v["words"])))
        if i > result["intersactions"]:
            result = {"words": v, "intersactions": i}
    return result

Как можно ускорить поиск? Поможет ли в этом построение индекса данных? И будет ли работать код быстрее, если использовать базу данных и sqlite3?

Во-первых можно один раз сделать список множеством в начале функции.
Во-вторых можно не преобразовывать в список результат пересечения множеств.
Хотя прирост будет очень мал даже на больших объемах данных.

def find_best(a, d):
    result = {"words": [], "intersactions": 0}
    a = set(a) # <---
    for v in d.values():
        i = len(a & set(v["words"])) # <---
        if i > result["intersactions"]:
            result = {"words": v, "intersactions": i}
    return result

Вероятно (проверить не на чем), будет небольшой прирост от замены сохранения в переменную и сравнения на функцию
max:

def find_best(a, d):
    result = {"words": [], "intersactions": 0}
    a = set(a) # <---
    for v in d.values():
        result = {"words": v, "intersactions": max(len(a & set(v["words"])), result['intersactions'])}
    return result


Как красить пиксели в python?
Хочу сделать нейросеть на python которая будет генерировать картинки, можете подсказать какую - нибудь библиотеку в которой можно красить пиксели по цветовой модели RGB?

Могу посоветовать, например, библиотеку Pillow (форк PIL). На всякий случай вот пример вопроса касательно прорисовки пикселей: тык


Нашел для себя такой вариант:
задал фильтр на наличие ключа "C" и одновременно отсутствие ключа "P"
array[?(@.C && [email protected])]
{
"C": 1.76,
"G": 1,
"T": 1
},
{
"C": 1.995,
"G": 1,
"T": 3
}
Если есть другие варианты, напишите :)


Как считать отдельные столбцы при помощи pandas?
Нужно считать файл, состоящий из двух столбцов, и прозвести арифметическую операцию. При попытке дать имя столбцу и считать его программа загоняет в это имя весь файл. Второй столбец просто остается пустым (Nan).

table = pd.read_table('phases.dat', sep='\t', names = ['files', 'phases'])

files = table['files']
phases = table['phases'].to_numpy()
phases = phases+0.25

f = open('phases', 'w')
for i in range(len(phases)):
    f.write(str(phases[i])+"  "+files[i]+"\n")
f.close()

Я подозреваю, что дело в разделителях в самом txt файле - выставлял нужное количество пробелов, перемещал имена столбцов в разные места, но не помогло.
Сам файл имеет вот такой вид:

                 files         phases
S18421304bctneftxt.txt         0.000000
S18421305bctneftxt.txt         0.057520
S18421306bctneftxt.txt         0.114714
S18421307bctneftxt.txt         0.171091
S18421308bctneftxt.txt         0.227468
S18421309bctneftxt.txt         0.284662
S18421310bctneftxt.txt         0.341038
S18421311bctneftxt.txt         0.397415
S18421404bctneftxt.txt         0.537295
S18421405bctneftxt.txt         0.596450
S18421406bctneftxt.txt         0.652663
S18421407bctneftxt.txt         0.709040
S18421408bctneftxt.txt         0.766234
S18421409bctneftxt.txt         0.822448
S18421410bctneftxt.txt         0.878824
S18421411bctneftxt.txt         0.936672
S18421412bctneftxt.txt         0.993049
S18421413bctneftxt.txt         1.049262
S18421414bctneftxt.txt         1.107273
S18421415bctneftxt.txt         1.163650
S18421416bctneftxt.txt         1.219863
S18421417bctneftxt.txt         1.277057
S18421418bctneftxt.txt         1.334414
S18421419bctneftxt.txt         1.390954

В чем может быть проблема при считывании?

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

df = pd.read_csv("phases.dat", sep="\s+")

или так:

df = pd.read_csv("phases.dat", delim_whitespace=True)


Не могу составить код который будет вычислять четное/нечетное число на python
Суть кода в том что - 'Пользователь вводит число (a). Найти количество всех нечетных чисел, на диапазоне
Я настрогал пару строчек кода, но все равно не выходит в ответе. Когда ввожу даже 1 число просто ничего не выводиться, и даже причину не могу понять.
<code>
a= input('Введите первое число:')
def sum():
     if a / 2 == 0:
           print ('четное число')
     else:
          print ('Нечетное число')
</code>

Я так понимаю, тебе нужно найти количество чётных чисел в определенном вводимом диапазоне.
<code>
num1 = int(input('Введи первое число: ')) // Пользователь вводит первое число
num2 = int(input ('Введите второе число: ')) // Пользователь вводит второе число
k = 0 // Добавляем переменную куда будем плюсовать количество чётных чисел

for i in range(num1,num2+1): // Создаём цикл в диапазоне введённых цифр (+1 во втором аргументе, потому что в range доходит ДО числа, а не ДО ВКЛЮЧИТЕЛЬНО этого числа)
    if i % 2 == 0: // Проверяем на чётность (если чётное делаем:)
        k +=1 // Если число чётное +1
print (k)
</code>


Как вытаскивать строки из базы данных исключая некоторые из них?
Есть вот такая функция:
<code>
def funciton():
    list = [1, 3, 5]
    with sq.connect(database_path) as con:
        cur = con.cursor()
        id = cur.execute(f"select row from table where id != {list} order by random() limit 1").fetchone()
        print(id)
</code>
Мне нужно чтобы она вытащила из базы данных 1 случайную запись, но при этом если id этом записи будет в списке list то пропустить эту запись и выбрать ту где id не равно тем которые записанные в список list
Подскажите возможно ли такое сделать, и как?

Можно попробовать связать список ID для пропуска напрямую с запросом, не забыв при этом обработать его до приемлемого состояния:
<code>
def funciton():
    lst = [1, 3, 5]
    with sq.connect(database_path) as con:
        cur = con.cursor()
        format_strings = ','.join(['%s'] * len(lst))
        id = cur.execute("select * from table where id not in (%s) order by random() limit 1")
             % format_strings, tuple(lst)).fetchone()
        print(id)
</code>
Я опирался на этот ответ из англоязычной SO, т.к., по сути говоря, идея там схожа с текущей — правда, там нужно было стереть все данные с ID, имеющимися в таблице, а здесь — выбрать те, которые НЕ имебтся в таблице.


Как обрезать распакованный список списков до определенной длины? [дубликат]

На этот вопрос уже даны ответы здесь:

вывести часть последовательности 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 на python 3

                                (7 ответов)

Закрыт 1 год назад.

<code>
n = int(input())
lst = []

for i in range(1, n):
    p = [i]*i
    lst.append(p)
for i in lst:
    print(*i, end=" ")
</code>
В данной программе выводится последовательность чисел, которые повторяются столько раз сколько равны. Нужно обрезать ее до числа n.
Пример, если n = 6, то последовательность должна выводиться: 1 2 2 3 3 3
Но у меня никак не выходит обрезать до этого числа

n = int(input())
lst = []
i = 1 # для создания группы из i элементов, равных i

while len(lst) < n:
    lst.extend([i] * i)
    i += 1

print(lst[:n])


Возможно ли сортировать массив сразу при добавлении
Есть пустой массив:

array = []

Возможно ли сортировать его элементы сразу при добавлении, чтобы не вызывать sorted? То есть:

array.append(3)
array.append(2)
array.append(6)

# Массив, который ожидается
print(array)  # -> [2, 3, 6]

Можно написать функцию которая делает это

def sorted_append(l, x):
    if not l:
        return [x]
    for i in range(len(l)):
        if x <= l[i]:
            l.insert(i, x)
            return l
    return l + [x]

l = []
l = sorted_append(l, 3)
l = sorted_append(l, 2)
l = sorted_append(l, 6)
print(l) # [2, 3, 6]

Или класс

class sorted_list(list):
    def sorted_append(self, x):
        if not self:
            return self.append(x)
        for i in range(len(self)):
            if x <= self[i]:
                return self.insert(i, x)
        return self.append(x)

l = sorted_list()
l.sorted_append(3)
l.sorted_append(2)
l.sorted_append(6)
print(l) # [2, 3, 6]


Можно ли переформатировать файл .numbers в .csv-файл при помощи Python?
Для дальнейшей работы с файлом мне было бы удобнее, если бы он был в .csv-формате а не в .numbers. Есть ли способ который мог бы конвертировать .numbers-файл в csv-формат  без потери или изменений в данных?

Судя по всему, можно воспользоваться библиотеками numbers-parser и
Pandas. Там даже пример есть по ссылке:

# python3 -m pip install numbers-parser
from numbers_parser import Document
import pandas as pd

doc = Document("simple.numbers")
sheets = doc.sheets()
tables = sheets[0].tables()
data = tables[0].rows(values_only=True)
df = pd.DataFrame(data, columns=["A", "B", "C"])

Ну и дальше экспортировать в
csv:

df.to_csv('filename.csv')


Django как называть изображения pk пользователя
У меня есть форма, на основе класса UpdateView:

class UserUpdateView(UpdateView):
    model = User
    fields = ['name', 'text', 'tel', 'adress', 'img', 'name_link_1',
        'link_1','name_link_2', 'link_2','name_link_3', 'link_3',
        'name_link_4', 'link_4','name_link_5', 'link_5',]
    template_name_suffix = '_update_form'

    def get_context_data(self, **kwargs):
        context = super(UserUpdateView, self).get_context_data(**kwargs)
        if not self.request.user.pk == self.object.pk:
            return redirect('login')
        return context

В форме всего одно изображение, которое связанно с одним конкретным пользователем. Я хочу вместо названия загружаемого изображения давать ему название по pk пользователя. Вопрос в том, как мне это сделать?
models.py:

img = models.ImageField('Ваша аватарка', upload_to='images/', blank=True)

Полагаю это может помочь:

def upload_as_pk(instance, filename: str):
    """Загружает файл в новую директрорию
    """
    instance_folder = type(instance).__name__.lower()  # Папка, где хранить изображения
    filename_format = filename.split('.')[-1]  # Формат файла, извлекаете любым удобным способом
    return f'{instance_folder}/{instance.pk}.{filename_format}'

В модели указываете эту функцию в
upload_to

img = models.ImageField('Ваша аватарка', upload_to=upload_as_pk, blank=True)

PS: Ответ не проверял, но должен работать


Django как средиректить в методе get_context_data?
Подскажите, как я могу редиректить в функции
get_context_data? Класса
UpdateView
Листинг:

class UserUpdateView(UpdateView):
    model = User
    fields = [...]
    template_name_suffix = '_update_form'

    def get_context_data(self, **kwargs):
        context = super(UserUpdateView, self).get_context_data(**kwargs)
        if not self.request.user.pk == self.object.pk:
            return redirect('login')
        return context

Никак?

get_context_data возвращает контекст для использования в шаблоне.
Лучше переопределить
get/post, учитывая, что все необходимые данные там будут. Ниже код исходников
Django

class BaseUpdateView(ModelFormMixin, ProcessFormView):
    """
    Base view for updating an existing object.

    Using this base class requires subclassing to provide a response mixin.
    """
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super().post(request, *args, **kwargs)

Как видите, можно написать

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        if not request.user.pk == self.object.pk:
            return redirect('login')

        return super().get(request, *args, **kwargs)

И все будет работать


Python. Регулярные выражения. Обрезать строку
Есть код:

#Это типа pars.txt
93.180.71.3 - - [17/May/2015:08:05:32 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.16~exp12ubuntu10.21)"
93.180.71.3 - - [17/May/2015:08:05:23 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.16~exp12ubuntu10.21)"
80.91.33.133 - - [17/May/2015:08:05:24 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.16~exp12ubuntu10.17)"
217.168.17.5 - - [17/May/2015:08:05:34 +0000] "GET /downloads/product_1 HTTP/1.1" 200 490 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"
217.168.17.5 - - [17/May/2015:08:05:09 +0000] "GET /downloads/product_2 HTTP/1.1" 200 490 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"

import re

with open('pars.txt', 'r') as f:
    lines = f.readlines()
    for line in lines:
        pars_line = re.match(r'[0-9.]{0,}', line)
        pars_line_2 = re.match(r'\[#Проблема тут\]', line)
        print(pars_line.group())
        print(pars_line_2.group())

Необходимо сохранить в pars_line_2 то, что находится в квадратных скобках и вывести на экран.

Если правильно все понял, в pars_line_2 можно сохранить то что находится в квадратных скобках, например [17/May/2015:08:05:32 +0000] следующей регуляркой:
<code>
pars_line_2=re.match(r'(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})(\s-\s-\s)\[(.*)\]', line)
print(pars_line_2.group(3))
</code>


Проверить совпадение слова в строке с процентной вероятностью
Задача найти/проверить слово в строке, ситуация когда слово/строка может быть искажена при парсинге пример: "1232_words&1231" или "word$",нужно найти "words". Достаточно найти 75% совпадения.
line_1 - слово которое ищешь. line_2 - где ищешь. 100 - это вероятное совпадения.
<code>
def find_word_per(line_1, line_2, percent=100):
    max_found = 0

    for item_1 in range(len(line_1)):

        for item_2 in range(len(line_2)):
            index_found = 0

            if line_1[item_1] == line_2[item_2]:

                for index in range(len(line_2) - item_2):
                    if item_1 + index >= len(line_1):
                        break
                    elif line_1[item_1 + index] == line_2[item_2 + index]:
                        index_found += 1
            if max_found < index_found:
                max_found = index_found

    result_per = (100 / len(line_1)) * max_found

    return result_per >= percent
</code>
Это мой вариант, он рабочий: ссылка
Есть ли готовые решения в библиотеке python3?

Конечно, такое есть - библиотека TheFuzz, ранее она называлась FuzzyWuzzy.


Не создается файл для записи данных в него
Есть скрипт, которые собирает с коммутаторов определенные данные и выводит их в файл в csv формате.
Задача передо мной стоит такая: при выполнении скрипта нужно, чтобы файл создавался c названием=текущей дате и времени, в в него все записывалось. Но по какой-то неведомой для меня причине возникает ошибка. Текст ее ниже.
Если меняю имя файла, например, на test.txt, то все работает. test.txt создается автоматом и в нем все нужные мне данные.
<code>
    tz_Moscow = pytz.timezone('Europe/Moscow')
    datetime_Moscow = datetime.now(tz_Moscow)
    filename = datetime_Moscow.strftime("%d/%m/%Y")

    int_descriptions_dict = get_interface_descriptions(device)
    output = send_command(device, command)
    match = regex.finditer(output)
    data = [['interface', 'description', 'mac-address']]
    for row in match:
        data.append([row.group('intf'), int_descriptions_dict.get(row.group('intf')), row.group('mac')])
    with open(f'mac-add-{filename}.csv', 'w') as f:
        writer = csv.writer(f)
        for row in data:
            writer.writerow(row)

Traceback (most recent call last):
  File "/home/vsfomin/python-scripts/mac-address-collector.py", line 170, in <module>
    with open(f'mac-add-{filename}.csv', 'w') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'mac-add-13/01/2022.csv'
</code>

Все просто, слэши в названии файла думаются для
python как полный путь к файлу. Следуя вашей ошибке, то имя файла будет
2022.csv и файл будет лежать в директории
mac-add-13/01/. Поскольку у вас такой директории не существует, вы и получаете данную ошибку
измените здесь

filename = datetime_Moscow.strftime("%d-%m-%Y")

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


Создать все комбинации списка
Имеется список:

l = [1, 2, 3, 4, 5]

Как пересобрать массив, что бы элементы стояли во всех возможных комбинациях?

print(l) # [1, 2, 3, 4, 5]
print(l) # [1, 2, 3, 5, 4]
print(l) # [1, 2, 5, 3, 4]

итд

Используйте itertools.permutations.
<code>
import itertools

l = [1,2,3,4,5]
for x in itertools.permutations(l):
    print(x)
</code>


pywinauto определение полей foxpro
есть программа на foxpro с бд которую нет возможности выгрузить в файл
необходимо перенести все данные из программы в веб приложение
проблема в том что при открытии карточки количество полей в разных карточках не одинаково
т.е. в одной карточке имеется поле "автор" а в другой её нет. и при переносе данные можно перепутать а через коннект необходимые поля не определяются
пример
карточка1
поле1 автор пупкин и.и.
поле2 издание питер
поле3 инвентарный номер 111111
карточка 2
поле1 издание питер
поле2 инвентарный номер 111112
поле3 код 1
в итоге в веб приложении карточка 2 перенесется неверно
т.е. поле 1 где должен быть автор будет издание
есть ли возможность как то распознать поля?

открыл исполняемый файл при помощи среды разработки foxpro, подключился при помощи pywinauto, прочитал структуру, вывел необходимые значения value