Как передать часть параметров для базы данных не из формы при отправке формы
Существует модель Articles с обязательными полями title, body, create_datetime, author, tags и status.
Необходимо, чтобы часть из этих параметров бралась из формы, а другая часть из кода.
На данный момент forms.py выглядит так:

from Main.models import Articles
from django.forms import ModelForm, TextInput, Textarea, Select

class CreateArticleForm(ModelForm):
    class Meta:
        model = Articles
        fields = ["title", "body", "tags", "status"]
        widgets = {
            "title": TextInput(
                attrs={
                    'type': "text",
                    'placeholder': "Название статьи",
                    'class': "form-control"
                }
            ),
            "body": Textarea(
                attrs={
                    'placeholder': "Текст статьи",
                    'class': "form-control"
                }
            ),
            "tags": TextInput(
                attrs={
                    'type': "text",
                    'placeholder': "Теги статьи",
                    'class': "form-control"
                }
            ),
            "status": Select(choices=(
                ("published", "Публикация"),
                ("draft", "Черновик"),
            ),
                attrs={
                    'class': "form-control"
                }
            )
        }

views.py так:

from django.shortcuts import render
from html_forms.forms import CreateArticleForm

def createarticle(request):
    if request.method == 'POST':
        form = CreateArticleForm(request.POST)

        if form.is_valid():
            form.save()
    return render(request, 'html_forms/create_article_form.html',
                  {
                      'form': CreateArticleForm()
                  }
                  )

Попытки реализовать заключались в следующем:
В forms.py в списке fields вместе с текущими ключами также добавлялись "create_datetime" и "author", после чего в views.py при вызове класса CreateArticleForm помимо request.POST пытался добавить

create_datetime=datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%d"), author=request.user.get_username()

, так что получалось

form = CreateArticleForm(request.POST,
                                 create_datetime=datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%d"),
                                 author=request.user.get_username())

,разумеется при этом импортировал datetime. Django же при попытке перейти на страницу с формой ругался, что я передаю атрибуты, которые не требуются.
Так же были попытки в файле forms.py в словаре widgets дописать примерно то же самое, но Django уже при старте сервера писал
AttributeError: 'str' object has no attribute 'is_required'. Прошерстил много форумов и документаций разных версий, но нашёл только что-то похожее только с самой моделью, а не формой, и там как раз делалось то же самое, что я пытался делать в первый раз, только, разумеется, без request.POST.
Вариант с невидимыми и автоматически заполненными полями в форме небезопасный, так что он отпадает.

if form.is_valid():
    form.save(commit=False)
    form.author = request.user
    form.save()

Так и с другими полями, при этом поле
author установите необязательным.
Так же, вы можете указать
auto_now_add=True в модели
publish, таким образом, в дату публикации автоматически будет записываться дата создания записи, но при этом, поле станет не доступным для редактирования.
UPD:
models:

author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, verbose_name='Автор')
pub_date = models.DateTimeField(auto_now_add=True)

В
forms эти поля не указываете.
views:

def createarticle(request):
    if request.method == 'POST':
        form = CreateArticleForm(request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            instance.save()
    return render(request, 'html_forms/create_article_form.html',{'form': CreateArticleForm()})


Вывод определенных данных из текстового файла
Дан текстовый файл - listaudio.txt (не json). В нем находятся, для примера, такие данные (их намного больше и у всех разные наименования):

{'id': 12345, 'owner_id': 67890, 'url': '', 'artist': 'ExampleArtist', 'title': 'ExampleTitle', 'duration': 320}, {'id': 45624, 'owner_id': 67890, 'url': '', 'artist': 'ExampleArtist2', 'title': 'ExampleTitle2', 'duration': 243}

нужно вывести только данные artist и title, т. е. вывод должен выглядеть так:

ExampleArtist - ExampleTitle

ExampleArtist2 - ExampleTitle2

Подскажите, как это сделать, используя python. Думал как-то реализовать через разделитель, но толкового из этого ничего не вышло

with open('my_file.txt') as processed_file:
my_string = processed_file.read()
my_tuple = eval(my_string)
for elements in my_tuple:
    artist = elements['artist']
    title = elements['title']
    print(f"{artist} - {title}")


Как сделать проверку на наличие логина в Telegram?
я решил сделать так, чтобы люди без логина не могли пользоваться ботом(тк это ломало его), и я попробовал следующий код
<code>
@bot.message_handler(commands=['start'])
def handler_start(message):
    chat_id = message.chat.id
    login = message.from_user.username
    print(login)
    print(login == "None")
    if "None" == login:
        bot.send_message(chat_id,'Для продолжения работы с ботом, вам необходимо установить логин!')
    else:
        Что-то происходит
</code>
Как оказалось, на сравнение None и None(именно так бот определяет логин людей у которых его нет) неверным выражением(False). Почему так, и что нужно сделать?

Ты пробовал написать None без кавычек ???


Ошибка с библиотекой blockcypher
Помогите, пожалуйста, с ошибкой. Вот код:

import blockcypher

class check():
    # считываем данные из файла с текущими данными
    with open(r'current_data.txt', mode='r', encoding='utf-8') as cur_fl:
        # получим список всех строк
        cur_data_lines = cur_fl.readlines()
        # на основе списка создадим словарь ключ:значение
        cur_data_dict = {
            ln.split(';')[0]:ln.split(';')[1]  # разделение строки по ';' - левая часть в ключ, правая в значение
            for ln in cur_data_lines
        }
    # то же самое, но для файла с предыдущими значениями
    with open(r'prev_data.txt', mode='r', encoding='utf-8') as prev_fl:
        prev_data_lines = prev_fl.readlines()
        prev_data_dict = {ln.split(';')[0]:ln.split(';')[1] for ln in prev_data_lines}

    # обход по циклу всех пар ключ:значение из файла с текущими данными
    for k, v in cur_data_dict.items():
        # если ключ есть в предыдущем файле и значение не равно предыдущему
        if (k in prev_data_dict.keys()) and (v != prev_data_dict[k]):
            balance = blockcypher.get_total_balance(k)
            if k[0:2] == '0x':
                balance_in_eth = balance / 2864966.76
                # prev_balance_in_eth = blockcypher.from_satoshis(prev_balance, 'eth')
                # telegram_bot.send_message(f'Изменение количества транзакций в адресе {k}. Значение изменилось на {v}.'+"\n"+'Текущий баланс ' + balance_in_eth + ' ETH')
                print("---ETH")
                print(k)
                print(v)
                print(balance_in_btc)
            else:
                balance_in_btc = balance / 100000000
                # prev_balance_in_btc = blockcypher.from_satoshis(prev_balance, 'btc')
                # telegram_bot.send_message(f'Изменение количества транзакций в адресе {k}. Значение изменилось на {v}.'+"\n"+'Текущий баланс ' + balance_in_btc + ' BTC')
                print("---BTC")
                print(k)
                print(v)
                print(balance_in_btc)
            # переносим значения текущего файла в файл с предыдущими данными
            # открывает файл с предыдущими данными на запись
    with open(r'prev_data.txt', mode='w', encoding='utf-8') as prev_fl:
        # открываем файл с текущими данными на чтение
        with open(r'current_data.txt', mode='r', encoding='utf-8') as cur_fl:
            # записываем в файл с предыдущими файлами то, что прочли из файла с текущими
            prev_fl.write(cur_fl.read())

Вот ошибка:

Traceback (most recent call last):
  File "C:/Users/user/Desktop/task/storage.py", line 22, in <module>
    class check():
  File "C:/Users/user/Desktop/task/storage.py", line 46, in check
    balance = blockcypher.get_total_balance(k)
  File "D:\Other\pycharm\venv\lib\site-packages\blockcypher\api.py", line 310, in get_total_balance
    return get_address_overview(address=address,
  File "D:\Other\pycharm\venv\lib\site-packages\blockcypher\api.py", line 292, in get_address_overview
    assert is_valid_address_for_coinsymbol(b58_address=address,
AssertionError

Потом добавил try/except вот так:

for k, v in cur_data_dict.items():
        # если ключ есть в предыдущем файле и значение не равно предыдущему
        if (k in prev_data_dict.keys()) and (v != prev_data_dict[k]):
            try:
                balance = blockcypher.get_total_balance(k)
            except:
                print('error_in_get_total_balance')
            if k[0:2] == '0x':
                balance_in_eth = balance / 2864966.76
                try:
                    print("---ETH")
                    print(k)
                    print(v)
                    print(balance_in_eth)
                except:
                    print('error_in_print')
            else:
                balance_in_btc = balance / 100000000
                try:
                    print("---BTC")
                    print(k)
                    print(v)
                    print(balance_in_btc)
                except:
                    print('error_in_print')
            # переносим значения текущего файла в файл с предыдущими данными
            # открывает файл с предыдущими данными на запись
    with open(r'prev_data.txt', mode='w', encoding='utf-8') as prev_fl:
        # открываем файл с текущими данными на чтение
        with open(r'current_data.txt', mode='r', encoding='utf-8') as cur_fl:
            # записываем в файл с предыдущими файлами то, что прочли из файла с текущими
            prev_fl.write(cur_fl.read())

Ответ такой:

D:\Other\pycharm\venv\Scripts\python.exe C:/Users/user/Desktop/task/storage.py
---BTC
14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf
31

0.0
error_in_get_total_balance
---ETH
0xd4FD252d7D2C9479a8d616F510eAC6243B5DDdf9
8

0.0
error_in_get_total_balance
---BTC
8Hx9uDuDO98idDfCAdu9CZsbrCfyv4K7f7sf
12

0.0

Process finished with exit code 0

Посмотрел в код blockcypher-python и могу объяснить, что пошло не так в:

balance = blockcypher.get_total_balance(k)

Вот описание get_total_balance:

def get_total_balance(address, coin_symbol='btc', api_key=None):
    return get_address_overview(address=address, coin_symbol=coin_symbol)['final_balance']

Вызов get_address_overview ведет в:

def get_address_overview(address, coin_symbol='btc', api_key=None):
    assert is_valid_address_for_coinsymbol(b58_address=address, coin_symbol=coin_symbol)
    ...

А там уже происходит проверка в is_valid_address_for_coinsymbol, которую ваши данные не прошли:

def is_valid_address_for_coinsymbol(b58_address, coin_symbol):
    assert is_valid_coin_symbol(coin_symbol)

    if b58_address.startswith(COIN_SYMBOL_MAPPINGS[coin_symbol]['bech32_prefix']):
        return True

    if coin_symbol == 'eth':
        return is_valid_eth_address(b58_address)

    if b58_address[0] in COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list']:
        if is_valid_address(b58_address):
            return True
    return False

Теперь подробнее:
Первая проверка с is_valid_coin_symbol должна быть успешной, т.к. вы не передавали свой coin_symbol, а значение btc должно успешно пройти проверку, т.к. в COIN_SYMBOL_SET есть значения btc, eth, ...:

def is_valid_coin_symbol(coin_symbol):
    return coin_symbol in COIN_SYMBOL_SET

Тут видно использование словаря COIN_SYMBOL_MAPPINGS, у него ключом является coin_symbol (значения btc, eth, ...), а значением словарь из значений другого словаря COIN_SYMBOL_ODICT_LIST. Поэтому, при вызове
COIN_SYMBOL_MAPPINGS[coin_symbol]['bech32_prefix'] получится значение bc1, а
b58_address.startswith('bc1') провалит проверку, т.к. у вас в
b58_address = "14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf".
Следующая проверка is_valid_eth_address не наступит, т.к.
coin_symbol у вас всегда btc. Но если бы для
eth вы бы заполнили
coin_symbol, то проверка не прошла бы успешно.
Смотрите, у вас там значение адреса
0xd4FD252d7D2C9479a8d616F510eAC6243B5DDdf9, и оно пройдет проверку длины (без
0x как раз 40 символов), но завалит проверку
uses_only_hash_chars, т.к. в ней учитываются только символы в нижнем регистре, а в у вас есть в верхнем (по мне это чушь, нужно было сделать проверку регистронезависимой, скорее всего это бага в библиотеки, можно создать в библиотеке issue). Поэтому, я бы рекомендовал адрес для
eth приводить в нижний регистр перед тем как вызывать get_total_balance.
Код проверок:

HEX_CHARS_RE = re.compile('^[0-9a-f]*$')

def uses_only_hash_chars(string):
    return bool(HEX_CHARS_RE.match(string))

def is_valid_eth_address(addr):
    if addr.startswith('0x'):
        addr = addr[2:].strip()

    if len(addr) != 40:
        return False

    return uses_only_hash_chars(addr)

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

    if b58_address[0] in COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list']:
        if is_valid_address(b58_address):
            return True

Давайте посмотрим значения из
COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list'] для
coin_symbol:

btc:
('1', '3', '4', 'b')

eth:
('0')
У вас для
btc значение адреса
14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf, а первый символ
1, что проходит проверку (
eth при заполненном
coin_symbol тоже бы прошел проверку, т.к. начинается на
0x)

Значит проверка дойдет до is_valid_address:

def is_valid_address(b58_address):
    if b58_address.startswith('bc1') or b58_address.startswith('ltc1') or b58_address.startswith('tltc1') or b58_address.startswith('tb1'):
        return True
    try:
        return crypto_address_valid(b58_address)
    except:
        return False

Сразу видно, что адрес проверку с
.startswith( код не пройдет, значит будет проверка в crypto_address_valid:

DIGITS58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def decode_base58(bc, length):
    n = 0
    for char in bc:
        n = n * 58 + DIGITS58.index(char)
    try:
        return n.to_bytes(length, 'big')
    except AttributeError:
        return _long_to_bytes(n, length, 'big')

def crypto_address_valid(bc):
    bcbytes = decode_base58(bc, 25)
    return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]

Использовал адрес
btc с
b58_address = '14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf' с
crypto_address_valid, получил успешный результат и это логично, по вашим логам у того адреса проблем не было:

b58_address = '14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf'
bcbytes = decode_base58(b58_address, 25)
print(bcbytes)
# b'\x00#\x18\xa8z[.\xb3\x19;"T\xe3Lo\x0f.\x9fw\xda\xbf\x9e\xd9\xf7"'

print(bcbytes[-4:], sha256(sha256(bcbytes[:-4]).digest()).digest()[:4])
# b'\x9e\xd9\xf7"' b'\x9e\xd9\xf7"'

print(bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4])
# True

Теперь используем адрес, что проверку не прошел:

b58_address = '8Hx9uDuDO98idDfCAdu9CZsbrCfyv4K7f7sf'
bcbytes = decode_base58(b58_address, 25)
#  n = n * 58 + DIGITS58.index(char)
#      ValueError: substring not found

А причина в символе
O, которого нет среди DIGITS58, возможно это опечатка, т.к. в
DIGITS58 есть
o, да и в принципе, там похоже каждому латинскому символу предоставляется две формы: в верхнем регистре и нижнем. Предположительно, это бага в этой библиотеки (можно попробовать в вашем окружении зайти в файл
DIGITS58 и добавить туда
O, чтобы проверить, и если все ок, то создать issue в репозитории библиотеки).
Исключение ValueError будет поймано в is_valid_address и это сразу приведет к
return False.
Поэтому адрес
8Hx9uDuDO98idDfCAdu9CZsbrCfyv4K7f7sf не прошел проверку.

PS.
Аналогично вы сами можете проверить ошибки для других адресов.
И, конечно, для адресов
etc нужно передавать соответствующее значение в
get_total_balance:

balance = blockcypher.get_total_balance(k, coin_symbol='etc')


Объединение значений в словаре по ключу Python
Доброго времени суток!
Есть список словарей:

lst_input = [{'current_temp': 15.54,
  'time': '03:00:00',
  'date': '31-07-2020',
  'detailed_status': 'ясно',
  'feeling': 12.99,
  'humidity': 77,
  'icon': '01d',
  'max_temp': 15.54,
  'min_temp': 15.54,
  'pressure': 1010,
  'speed': 4.32,
  'status': 'Clear'},
 {'current_temp': 18.55,
  'time': '06:00:00',
  'date': '31-07-2020',
  'detailed_status': 'ясно',
  'feeling': 15.97,
  'humidity': 62,
  'icon': '01d',
  'max_temp': 18.55,
  'min_temp': 18.55,
  'pressure': 1009,
  'speed': 4.2,
  'status': 'Clear'},
 {'current_temp': 21.46,
  'time': '09:00:00',
  'date': '31-07-2020 16:00:00',
  'detailed_status': 'небольшой дождь',
  'feeling': 17.72,
  'humidity': 48,
  'icon': '10d',
  'max_temp': 21.46,
  'min_temp': 21.46,
  'pressure': 1009,
  'speed': 5.4,
  'status': 'Rain'}]

Как видно, это данные прогноза погоды. Здесь данные на каждые 3 часа.
Я хочу сделать список, который объединял бы в себе данные по ключам
date - ключ родитель,
time - ключ потомок и у
time должны собраться остальные ключи и значения, или проще говоря вот так:

 lst_output = [{'date': '31-07-2020'}: [{'time': '09:00:00'}:
 {'current_temp': 21.46,
  'detailed_status': 'небольшой дождь',
  'feeling': 17.72,
  'humidity': 48,
  'icon': '10d',
  'max_temp': 21.46,
  'min_temp': 21.46,
  'pressure': 1009,
  'speed': 5.4,
  'status': 'Rain'}],
  [{'time': '12:00:00'},
 {'current_temp': 22.15,
  'detailed_status': 'небольшой дождь',
  'feeling': 17.97,
  'humidity': 42,
  'icon': '10d',
  'max_temp': 22.15,
  'min_temp': 22.15,
  'pressure': 1009,
  'speed': 5.52,
  'status': 'Rain'}]]

Цель (Это конечный формат, для примера):

Дата: 31/07/2020
Время: 03:00
Температура: 15
Влажность: 77
Статус: Дождь
Скорость ветра: 3

Время: 06:00
Температура: 17
Влажность: 61
Статус: Облачно
Скорость ветра: 1,5

Время: 09:00
Температура: 19
Влажность: 52
Статус: Облачно с прояснениями
Скорость ветра: 1

Я новичок в Python и буду благодарен за помощь в решении.

Если данные приходят в не отсортированном виде то можно сделать

sorted_data = sorted(lst_input, key=lambda i: (i['date'][:10], i['time']))

key=lambda i: (i['date'][:10], i['time']) сортируем данные сперва по
date, а затем по
time. Так как в исходных данных ключ
date не был одного формата то я грубо обрезал его длину -
[:10]

def func(data):
    temp = set()
    for i in data:
        if i['date'][:10] not in temp:
            print(f'Дата: {i["date"][:10]}')
            temp.add(i["date"][:10])
        print(f'Время: {i["time"]}')
        print(f'Температура: {int(i["max_temp"])}')
        print(f'Влажность: {int(i["humidity"])}')
        print(f'Статус: {i["detailed_status"]}')
        print(f'Скорость ветра: {i["speed"]}\n\n')

func(sorted_data)


Работа с JSON, вывод определенных данных
Дан файл json - listaudio.json. В нем находятся примерно такие данные:

{'id': 12345, 'owner_id': 67890, 'url': '', 'artist': 'ExampleArtist', 'title': 'ExampleTitle', 'duration': 320}, {'id': 45624, 'owner_id': 67890, 'url': '', 'artist': 'ExampleArtist2', 'title': 'ExampleTitle2', 'duration': 243}
нужно вывести только данные artist и title, т.е. вывод должен выглядеть так:

ExampleArtist - ExampleTitle
ExampleArtist2 - ExampleTitle2

Подскажите, как это сделать, используя python

Всё очень просто:

import json

with open('listaudio.json') as f:
  json_object = json.load(f)

for elem in json_object:
  print('{0} - {1}'.format(elem['artist'], elem['title']))

Сперва мы открываем файл для чтения
open('listaudio.json'), далее получаем json объект из него через встроенный модуль
json.load(f).

for elem in json_object:
  print('{0} - {1}'.format(elem['artist'], elem['title']))

Через этот цикл, мы проходимся по каждому элементу данного json массива и выводим его артиста, а также название.
Только не забудьте, что в json используются двойные кавычки, так что в файле должны быть не одинарные, а двойные!


pyqrcode ошибка
При использование вот этой команды

qr = pyqrcode.create(self.entry_name_standart.get(), self.entry_mark.get(), self.entry_polych.get(), self.entry_Adress.get(), self.entry_tel.get(), self.entry_ERDPOU.get())
            qr.png('qrtest', scale = 6)

Выбивает такую ошибку

qr = pyqrcode.create(self.entry_name_standart.get(), self.entry_mark.get(), self.entry_polych.get(),

self.entry_Adress.get(), self.entry_tel.get(),
self.entry_ERDPOU.get())
TypeError: create() takes from 1 to 5 positional arguments but 6 were given

С этим можно как то бороться(сохранить количество данных) ?
Так же при уменьшение количества позиций выходит такая ошибка

TypeError: '<=' not supported between instances of 'int' and 'str'

решил вопрос таким способом , просто добавил переменную qr2 и с нее уже считывал данные для генерации qr кода
<code>
def GenerateQR():
        qr2 = (self.entry_name_standart.get() + self.entry_mark.get() + self.entry_polych.get() + self.entry_Adress.get() + self.entry_tel.get() + self.entry_ERDPOU.get())

        qr = pyqrcode.create(qr2)
        qr.png('qrtest', scale = 6)
</code>


Как из ttk.Entry достать данные в следующие окно , что бы на основе их создать qrcod
Доброго времени суток rак из ttk.Entry достать данные в следующие окно , что бы на основе их создать qrcod

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import sqlite3
import pyqrcode
import png

class Main(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.init_main()
        self.db = db
        self.view_records()

    def init_main(self):
        toolbar = tk.Frame(bg='#d7d8e0', bd=2)
        toolbar.pack(side=tk.TOP, fill=tk.X)
# Добавление кнопок управления
        self.add_img = tk.PhotoImage(file='ADD.png') #ADD
        btn_open_dialog = tk.Button(toolbar, text='Додати', command=self.open_dialog, bg='#d7d8e0', bd=0,
                                    compound=tk.TOP, image=self.add_img)
        btn_open_dialog.pack(side=tk.LEFT)

        self.update_img = tk.PhotoImage(file='ADD.png') #redach
        btn_edit_dialog = tk.Button(toolbar, text='Редукувати', bg='#d7d8e0', bd=0, image=self.update_img,
                                    compound=tk.TOP, command=self.open_update_dialog)
        btn_edit_dialog.pack(side=tk.LEFT)

        self.delete_img = tk.PhotoImage(file='ADD.png') #Delete
        btn_delete = tk.Button(toolbar, text='Видалити', bg='#d7d8e0', bd=0, image=self.delete_img,
                               compound=tk.TOP, command=self.delete_records)
        btn_delete.pack(side=tk.LEFT)

        self.search_img = tk.PhotoImage(file='ADD.png') #Shearh
        btn_search = tk.Button(toolbar, text='Пошук', bg='#d7d8e0', bd=0, image=self.search_img,
                               compound=tk.TOP, command=self.open_search_dialog)
        btn_search.pack(side=tk.LEFT)

        self.refresh_img = tk.PhotoImage(file='ADD.png') #Obnovit
        btn_refresh = tk.Button(toolbar, text='Обновити', bg='#d7d8e0', bd=0, image=self.refresh_img,
                                compound=tk.TOP, command=self.view_records)
        btn_refresh.pack(side=tk.LEFT)

        self.tree = ttk.Treeview(self, columns=('ID', 'mark', 'name', 'Kol', 'cena', 'polych',  'FIO', 'Adress', 'tel', 'ERDPOU',  'email', 'data', 'shetchik1'), height=15, show='headings')
#Расположение кнопок
        self.tree.column('ID', width=30, anchor=tk.CENTER)
        self.tree.column('mark', width=150, anchor=tk.CENTER)
        self.tree.column('name', width=150, anchor=tk.CENTER)
        self.tree.column('Kol', width=100, anchor=tk.CENTER)
        self.tree.column('cena', width=100, anchor=tk.CENTER)
        self.tree.column('polych', width=100, anchor=tk.CENTER)
        self.tree.column('FIO', width=100, anchor=tk.CENTER)
        self.tree.column('Adress', width=100, anchor=tk.CENTER)
        self.tree.column('tel', width=100, anchor=tk.CENTER)
        self.tree.column('ERDPOU', width=100, anchor=tk.CENTER)
        self.tree.column('email', width=100, anchor=tk.CENTER)
        self.tree.column('data', width=100, anchor=tk.CENTER)
        self.tree.column('shetchik1', width=100, anchor=tk.CENTER)

#Подпись кнопок
        self.tree.heading('ID', text='ID')
        self.tree.heading('mark', text='Маркування Стандарту')
        self.tree.heading('name', text='Назва Стандарту')
        self.tree.heading('Kol', text='Кількість сторінок')
        self.tree.heading('cena', text='Цена')
        self.tree.heading('polych', text='ФІО')
        self.tree.heading('FIO', text='Отримувач')
        self.tree.heading('Adress', text='Адреса')
        self.tree.heading('tel', text='Телефон')
        self.tree.heading('ERDPOU', text='ЄРДПОУ')
        self.tree.heading('email', text='Електронна адреса')
        self.tree.heading('data', text='Дата')
        self.tree.heading('shetchik1', text='shetchik1')

        self.tree.pack()
# Функции кнопок
    def records(self, mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1):  #Запись
        self.db.insert_data(mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1)
        self.view_records()

    def update_record(self, mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1): #Обновить
        self.db.c.execute('''UPDATE work SET mark=?, name_standart=?, kilkiststr=?, cena=?, FIO=?, polych=?, Adress=?, tel=?, ERDPOU=?, email=?, data=?, shetchik1=? WHERE ID=?''',
                          (mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1, self.tree.set(self.tree.selection()[0], '#1')))
        self.db.conn.commit()
        self.view_records()

    def view_records(self): #Просмотреть
        self.db.c.execute('''SELECT * FROM work''')
        [self.tree.delete(i) for i in self.tree.get_children()]
        [self.tree.insert('', 'end', values=row) for row in self.db.c.fetchall()]

    def delete_records(self): #Удалить
        for selection_item in self.tree.selection():
            self.db.c.execute('''DELETE FROM work WHERE id=?''', (self.tree.set(selection_item, '#1'),))
        self.db.conn.commit()
        self.view_records()

    def search_records(self, polych):   #Поиск
        polych = ('%' + polych + '%',)
        self.db.c.execute('''SELECT * FROM work WHERE polych LIKE ?''', polych)
        [self.tree.delete(i) for i in self.tree.get_children()]
        [self.tree.insert('', 'end', values=row) for row in self.db.c.fetchall()]

# Открытие окон
    def open_dialog(self):
        Child()

    def open_update_dialog(self):
        Update()

    def open_search_dialog(self):
        Search()

class Child(tk.Toplevel):
    def __init__(self):
        super().__init__(root)
        self.init_child()
        self.view = app

    def init_child(self):
        self.title('Додати')
        self.geometry('400x720+400+300')
        self.resizable(False, False)

        label_mark = tk.Label(self, text='Маркування Стандарту:')
        label_mark.place(x=50, y=50)
        label_name_standart = tk.Label(self, text='Назва Стандарту:')
        label_name_standart.place(x=50, y=80)
        label_kilkiststr = tk.Label(self, text='Кількість сторінок:')
        label_kilkiststr.place(x=50, y=110)
        label_cena = tk.Label(self, text='Цена:')
        label_cena.place(x=50, y=140)
        label_FIO = tk.Label(self, text='ФІО:')
        label_FIO.place(x=50, y=170)
        label_polych = tk.Label(self, text='Отримувач:')
        label_polych.place(x=50, y=200)
        label_Adress = tk.Label(self, text='Адреса:')
        label_Adress.place(x=50, y=230)
        label_tel = tk.Label(self, text='Телефон:')
        label_tel.place(x=50, y=260)
        label_ERDPOU = tk.Label(self, text='ЄРДПОУ:')
        label_ERDPOU.place(x=50, y=290)
        label_email = tk.Label(self, text='Електронна адреса:')
        label_email.place(x=50, y=320)
        label_data = tk.Label(self, text='Дата:')
        label_data.place(x=50, y=350)
        label_shetchik1 = tk.Label(self, text='shetchik1:')
        label_shetchik1.place(x=50, y=380)

        self.entry_kilkiststr = ttk.Entry(self)
        self.entry_kilkiststr.place(x=200, y=50)

        self.entry_name_standart = ttk.Entry(self)
        self.entry_name_standart.place(x=200, y=80)

        self.entry_mark = ttk.Entry(self)
        self.entry_mark.place(x=200, y=110)

        self.entry_cena = ttk.Entry(self)
        self.entry_cena.place(x=200, y=140)

        self.entry_FIO = ttk.Entry(self)
        self.entry_FIO.place(x=200, y=170)

        self.entry_polych = ttk.Entry(self)
        self.entry_polych.place(x=200, y=200)

        self.entry_Adress = ttk.Entry(self)
        self.entry_Adress.place(x=200, y=230)

        self.entry_tel = ttk.Entry(self)
        self.entry_tel.place(x=200, y=260)

        self.entry_ERDPOU = ttk.Entry(self)
        self.entry_ERDPOU.place(x=200, y=290)

        self.entry_email = ttk.Entry(self)
        self.entry_email.place(x=200, y=320)

        self.entry_data = ttk.Entry(self)
        self.entry_data.place(x=200, y=350)

        self.entry_shetchik1 = ttk.Entry(self)
        self.entry_shetchik1.place(x=200, y=380)

        btn_cancel = ttk.Button(self, text='Закрити', command=self.destroy)
        btn_cancel.place(x=300, y=480)

        self.btn_ok = ttk.Button(self, text='Додати')
        self.btn_ok.place(x=220, y=480)
        self.btn_ok.bind('<Button-1>', lambda event: self.view.records(self.entry_kilkiststr.get(),
                                                                       self.entry_name_standart.get(),
                                                                       self.entry_mark.get(),
                                                                       self.entry_cena.get(),
                                                                       self.entry_FIO.get(),
                                                                       self.entry_polych.get(),
                                                                       self.entry_Adress.get(),
                                                                       self.entry_tel.get(),
                                                                       self.entry_ERDPOU.get(),
                                                                       self.entry_email.get(),
                                                                       self.entry_data.get(),
                                                                       self.entry_shetchik1.get()))

        self.btn = ttk.Button(self, text='Создать файл', command=Generate)
        self.btn.place(x=50, y=480)

        self.grab_set()
        self.focus_set()

    def Generate(self):
        Window2()

class Generate(Child):
    def __init__(self, *arg, **kwarg):
        super().__init__(*arg, **kwarg)
        self.init_gen()
        self.view = app

    def init_gen(self):
        self.title('Создать файл')
        self.geometry('400x200+250+350')
        self.resizable(False, False)

        def get_file_name():
            file = filedialog.askopenfilename()

        def GenerateQR():
            name = entry_name_standart.get

            text = pyqrcode.create(name)
            text.png('test', scale=8)

        self.btn1 = ttk.Button(self, text='Выбрать файл', command=get_file_name)
        self.btn1.place(x=50, y=50)

        self.btn2 = ttk.Button(self, text='QRCode', command=GenerateQR)
        self.btn2.place(x=100, y=50)

class Update(Child):
    def __init__(self):
        super().__init__()
        self.init_edit()
        self.view = app
        self.db = db
        self.default_data()

    def init_edit(self):
        self.title('Редукувати')
        btn_edit = ttk.Button(self, text='Редукувати')
        btn_edit.place(x=205, y=170)
        btn_edit.bind('<Button-1>', lambda event: self.view.update_record(self.entry_kilkiststr.get(),
                                                                       self.entry_name_standart.get(),
                                                                       self.entry_mark.get(),
                                                                       self.entry_cena.get(),
                                                                       self.entry_FIO.get(),
                                                                       self.entry_polych.get(),
                                                                       self.entry_Adress.get(),
                                                                       self.entry_tel.get(),
                                                                       self.entry_ERDPOU.get(),
                                                                       self.entry_email.get(),
                                                                       self.entry_data.get(),
                                                                       self.entry_shetchik1.get()))

        self.btn_ok.destroy()

    def default_data(self):
        self.db.c.execute('''SELECT * FROM work WHERE id=?''',
                          (self.view.tree.set(self.view.tree.selection()[0], '#1'),))
        row = self.db.c.fetchone()
        self.entry_mark.insert(0, row[1])
        if row[2] != 'Доход':
            self.name_standart.current(1)
        self.entry_kilkiststr.insert(0, row[3])

class Search(tk.Toplevel):
    def __init__(self):
        super().__init__()
        self.init_search()
        self.view = app

    def init_search(self):
        self.title('Пошук')
        self.geometry('300x100+400+300')
        self.resizable(False, False)

        label_search = tk.Label(self, text='Пошук')
        label_search.place(x=50, y=20)

        self.entry_search = ttk.Entry(self)
        self.entry_search.place(x=105, y=20, width=150)

        btn_cancel = ttk.Button(self, text='Закрити', command=self.destroy)
        btn_cancel.place(x=185, y=50)

        btn_search = ttk.Button(self, text='Пошук')
        btn_search.place(x=105, y=50)
        btn_search.bind('<Button-1>', lambda event: self.view.search_records(self.entry_search.get()))
        btn_search.bind('<Button-1>', lambda event: self.destroy(), add='+')

class DB:
    def __init__(self):
        self.conn = sqlite3.connect('work.db')
        self.c = self.conn.cursor()
        self.c.execute(
            '''CREATE TABLE IF NOT EXISTS work (id integer primary key, mark text, name_standart text, kilkiststr real,cena integer, FIO text, polych text, Adress text, tel integer, ERDPOU text, email text, data text, shetchik1 integer)''')
        self.conn.commit()

    def insert_data(self, mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1):
        self.c.execute('''INSERT INTO work(mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                       (mark, name_standart, kilkiststr, cena, FIO, polych, Adress, tel, ERDPOU, email, data, shetchik1))
        self.conn.commit()

if __name__ == "__main__":
    root = tk.Tk()
    db = DB()
    app = Main(root)
    app.pack()
    root.title("Робота")
    root.geometry("1450x450+0+0")
    root.resizable(False, False)
    root.mainloop()

А именно как те данные что я ввожу сюда

self.entry_kilkiststr = ttk.Entry(self)
        self.entry_kilkiststr.place(x=200, y=50)

вытащить их для создания qrcod в следующем окне

class Generate(Child):
        def __init__(self, *arg, **kwarg):
            super().__init__(*arg, **kwarg)
            self.init_gen()
            self.view = app

        def init_gen(self):
            self.title('Создать файл')
            self.geometry('400x200+250+350')
            self.resizable(False, False)

            def get_file_name():
                file = filedialog.askopenfilename()

            def GenerateQR():
                name = entry_name_standart.get

                text = pyqrcode.create(name)
                text.png('test', scale=8)

            self.btn1 = ttk.Button(self, text='Выбрать файл', command=get_file_name)
            self.btn1.place(x=50, y=50)

            self.btn2 = ttk.Button(self, text='QRCode', command=GenerateQR)
            self.btn2.place(x=100, y=50)

Настройки окна с которого надо вытащить данные

class Child(tk.Toplevel):
def __init__(self):
    super().__init__(root)
    self.init_child()
    self.view = app

def init_child(self):
    self.title('Додати')
    self.geometry('400x720+400+300')
    self.resizable(False, False)

    label_mark = tk.Label(self, text='Маркування Стандарту:')
    label_mark.place(x=50, y=50)
    label_name_standart = tk.Label(self, text='Назва Стандарту:')
    label_name_standart.place(x=50, y=80)
    label_kilkiststr = tk.Label(self, text='Кількість сторінок:')
    label_kilkiststr.place(x=50, y=110)
    label_cena = tk.Label(self, text='Цена:')
    label_cena.place(x=50, y=140)
    label_FIO = tk.Label(self, text='ФІО:')
    label_FIO.place(x=50, y=170)
    label_polych = tk.Label(self, text='Отримувач:')
    label_polych.place(x=50, y=200)
    label_Adress = tk.Label(self, text='Адреса:')
    label_Adress.place(x=50, y=230)
    label_tel = tk.Label(self, text='Телефон:')
    label_tel.place(x=50, y=260)
    label_ERDPOU = tk.Label(self, text='ЄРДПОУ:')
    label_ERDPOU.place(x=50, y=290)
    label_email = tk.Label(self, text='Електронна адреса:')
    label_email.place(x=50, y=320)
    label_data = tk.Label(self, text='Дата:')
    label_data.place(x=50, y=350)
    label_shetchik1 = tk.Label(self, text='shetchik1:')
    label_shetchik1.place(x=50, y=380)

    self.entry_kilkiststr = ttk.Entry(self)
    self.entry_kilkiststr.place(x=200, y=50)

    self.entry_name_standart = ttk.Entry(self)
    self.entry_name_standart.place(x=200, y=80)

    self.entry_mark = ttk.Entry(self)
    self.entry_mark.place(x=200, y=110)

    self.entry_cena = ttk.Entry(self)
    self.entry_cena.place(x=200, y=140)

    self.entry_FIO = ttk.Entry(self)
    self.entry_FIO.place(x=200, y=170)

    self.entry_polych = ttk.Entry(self)
    self.entry_polych.place(x=200, y=200)

    self.entry_Adress = ttk.Entry(self)
    self.entry_Adress.place(x=200, y=230)

    self.entry_tel = ttk.Entry(self)
    self.entry_tel.place(x=200, y=260)

    self.entry_ERDPOU = ttk.Entry(self)
    self.entry_ERDPOU.place(x=200, y=290)

    self.entry_email = ttk.Entry(self)
    self.entry_email.place(x=200, y=320)

    self.entry_data = ttk.Entry(self)
    self.entry_data.place(x=200, y=350)

    self.entry_shetchik1 = ttk.Entry(self)
    self.entry_shetchik1.place(x=200, y=380)

    btn_cancel = ttk.Button(self, text='Закрити', command=self.destroy)
    btn_cancel.place(x=300, y=480)

    self.btn_ok = ttk.Button(self, text='Додати')
    self.btn_ok.place(x=220, y=480)
    self.btn_ok.bind('<Button-1>', lambda event: self.view.records(self.entry_kilkiststr.get(),
                                                                   self.entry_name_standart.get(),
                                                                   self.entry_mark.get(),
                                                                   self.entry_cena.get(),
                                                                   self.entry_FIO.get(),
                                                                   self.entry_polych.get(),
                                                                   self.entry_Adress.get(),
                                                                   self.entry_tel.get(),
                                                                   self.entry_ERDPOU.get(),
                                                                   self.entry_email.get(),
                                                                   self.entry_data.get(),
                                                                   self.entry_shetchik1.get()))

    self.btn = ttk.Button(self, text='Создать файл', command=Generate)
    self.btn.place(x=50, y=480)

    self.grab_set()
    self.focus_set()

def Generate(self):
    Window2()

Можно брать данные из текстового поля в обработчике нажатия на кнопку, потом передать как параметр в создаваемое окно.
<code>
import tkinter as tk

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        self.entry = tk.Entry(self)
        self.entry.pack()

        self.button = tk.Button(self, text='New window', command=self.new_window)
        self.button.pack()

    def new_window(self):
        ChildWindow(parent=self, text=self.entry.get())

class ChildWindow(tk.Toplevel):
    def __init__(self, parent, text):
        super().__init__(parent)
        self.label = tk.Label(self, text=text)
        self.label.pack()

if __name__=='__main__':
    main_window = MainWindow()
    main_window.mainloop()
</code>


Подскажите API для практики
Не давно начал изучать requests. Документацию прочитал, хочу закрепить практикой. Посоветуйте API какого сайта можно для этого использовать. Перефразирую: Какой API можно использовать для практики. Желательно бесплатный.

вот отличный сервис для обучения JSONPlaceholder можно сразу и в REST API разобраться.


Python JSON парсинг конкретной переменной
У меня к примеру есть такой json:
<code>
{
  "Name": Vladimir,
  "Time": "15:34",
  "Date": "12.04.1997"
}{
  "Name": Egor,
  "Time": "12:11",
  "Date": "05.02.1994"
}
и т.д
</code>
Как мне с помощью питона отпарсить только значения переменной "Name" + "Date"? С учетом что таких строк jsonов более ста, и все уникальные.

Скажите как должен выглядеть конечный результат?
Дело имеем с json или x-ndjson? Я так понимаю, что с первым, тогда формат должен быть примерно такой [{}, {}]

Если результатом должен быть кортеж вида (имя, дата), то простое решение может выглядеть так:

import json

# где response ваш json
result = [
    (i['Name'], i['Date']) for i in json.loads(response)
]
# [('Vladimir', '12.04.1997'), ('Egor', '05.02.1994')]

Для более сложных случаев можно посмотреть на библиотеку jsonpath-ng. Поиграться с путями можно здесь. Быстрый пример без разбивки по кортежам:

import json
from jsonpath_ng import parse

expression = parse('$[*][Name,Date]')
result = [
    match.value for match in expression.find(response)
]
# ['Vladimir', '12.04.1997', 'Egor', '05.02.1994']


Как преобразовать строку в число python?

l = []

s = input("Введите число: ")
l=list(s)

a = l[0:3]
b = l[3:6]

a = "123" нужно преобразовать в
a = 123

Сразу получить число:
a = int(input())


threading - передать каждому потоку свой аргумент
Я хочу выполнить авторизацию в Google с разных аккаунтов в каждом из потоков. На данный момент могу просто запустить n потоков и авторизироваться в гугле под одним аккаунтом.
Подскажите, пожалуйста, как правильно передать произвольное кол-во аргументов в thread, чтобы потом каждый поток взял по 1 уникальному аргументу (там будет связка login:password) и в будущем авторизовался в гугл с полученными значениями?
<code>
import threading

from selenium import webdriver

# Не понимаю, как воспользоваться теми аргументами,
# Что передам в args,
# Так, что бы каждый поток взял по одному из них
def main():
    print(threading.current_thread)
    options = webdriver.ChromeOptions()
    options.add_argument("--start-maximized")
    options.add_experimental_option("excludeSwitches", ['enable-automation'])
    driver = webdriver.Chrome(options=options)
    start(driver)

#--
#-- Пропуск всей логики работы программы
#-- def start(driver):
#--     pass
#--

# Запускаю потоки
if __name__ == '__main__':
    threads = []
    for i in range(n):
        # В args планируется передать login:password в N-ом кол-ве штук
        t = threading.Thread(target=main)
        threads.append(t)
        t.start()
</code>

Зачем передавать произвольное количество аргументов, когда можно каждому треду передать свой аргумент?

import argparse

def main(loginpassword):
    print(loginpassword)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Логины пароли.')
    parser.add_argument('passwords', metavar='login:password', type=str, nargs='+', help='Логины пароли списком')
    args = parser.parse_args()

    for lp in args.passwords:
        t = threading.Thread(target=main, args=(lp, ))
        ....

Но если тред должен сам выбрать один пароль из списка:

import queue

def main(q):
    lp = q.get()

q = queue.Queue()
for lp in args:
    q.put(lp)

for i in range(5):
    t = threading.Thread(target=main, args=(q,))

Положим пароли в очередь по одному и уже в треде из этой очереди их выгребаем.


Python. Как удалить фигурные скобки при выводе значения словаря?

users_data_p = Path("users_data.json")
users_data = json.loads(users_data_p.read_text(encoding='utf-8'))

users_data_list = list(users_data.items())
users_data_list.sort(key=lambda j: j[1].get('messages'))

for i in reversed(users_data_list):
    print(str(i[1]))

Выводит это:

{'messages': 145}
{'messages': 112}
{'messages': 90}
{'messages': 42}

Можно как-то убрать фигурные скобки и кавычки?
UPD:
Вот таким образом я смог убрать фигурные скобки, но кавычки остались

print(str(i[1])[1:-1].format())

попробуйте так:
<code>
users_data_list = [
    [1, {'messages': 42}],
    [2, {'messages': 90}],
    [3, {'messages': 112}],
    [4, {'messages': 145}],
]

for i in reversed(users_data_list):
    k, v = list(i[1].items())[0]
    print(f'{k}: {v:>3}')
</code>


Как вызвать метод класса для экземпляра имя которого получено с input()
<code>
class Robot:

    def __init__(self, name):
        self.name = name
        print(f'Рообот {self.name} создан')

    def jump(self):
        print(f'Робот {self.name} подпрыгнул')

robot1 = Robot('R2-D2')
robot2 = Robot('C-3PO')

jumper = input('Какой робот должен подпрыгнуть?')
jumper.jump()
</code>
Если ввести "robot1" должно вывестись "Робот R2-D2 подпрыгнул".
Но возвращается ошибка: AttributeError: 'str' object has no attribute 'jump'.
Наверное глупый вопрос: какого типа данных название атрибута класса?

class Robot:

    def __init__(self, name):
        self.name = name
        print(f'Робот {self.name} создан')

    def jump(self):
        print(f'Робот {self.name} подпрыгнул')

robot1 = Robot('R2-D2')
robot2 = Robot('C-3PO')

jumper = input('Какой робот должен подпрыгнуть?: ')

if jumper.lower() == 'r2-d2':
    robot1.jump()
if jumper.lower() == 'c-3po':
    robot2.jump()
else:
    print('Error')


заменить цифру в строке
х = ['27342837429']. заменить любую цифру в строке ниже 5 на «0», а любую цифру 5 и выше на «1».

как вариант
<code>
''.join('0' if int(i) < 5 else '1'  for i in х[0])
</code>


Запуск py файла с дополнительными опциями (аргументами)
Как сделать что бы можно было указать опцию к запуску .py файла.
Например:
python3 main.py -safemode

import sys

if sys.argv[1] == '-safemode':
    print('safe mode!')
else:
    print('no safe mode!')


определение переменной в Python
Недавно заметил в Python что определять переменную можно другим способом:

name: str = "Bob"

Так вот чем это определение отличается от такой:

name = "Bob"

По сути ничем:

Вы можете менять им значения на другие типы (что не рекомендуется):

name: str = "Bob"
name = 10

Или даже так:

name: str = "Bob"
name: int = 1 + 1

Никакой особой разницы между переменной инициализированной "по-старинке" и "модерново" нет. С ними работают одни и те же питоновские приемы.

UPD

Между прочим,
name: int = "wtf" тоже вполне работает – andreymal 4 часа назад

Единственная разница:

Хорошо для таких вещей как mypy, pylint etc.
На уровне дизассемблера (у меня version 3.8):

>>> dis("a: int = 10")
  1           0 SETUP_ANNOTATIONS
              2 LOAD_CONST               0 (10)
              4 STORE_NAME               0 (a)
              6 LOAD_NAME                1 (int)
              8 LOAD_NAME                2 (__annotations__)
             10 LOAD_CONST               1 ('a')
             12 STORE_SUBSCR
             14 LOAD_CONST               2 (None)
             16 RETURN_VALUE

vs.

>>> dis("a = 10")
  1           0 LOAD_CONST               0 (10)
              2 STORE_NAME               0 (a)
              4 LOAD_CONST               1 (None)
              6 RETURN_VALUE

Dis Explanation

SETUP_ANNOTATIONS — "настройка аннотаций" т.е. "байткод говорит: тут мы юзаем аннотация"

2 LOAD_CONST 0 (10) — подгружаем константу 10.

4 STORE_NAME 0 (a) — сохраняем в а, то что подгрузили.

А вот тут самое интересное:

6 LOAD_NAME  1 (int) — загружаем инт

8 LOAD_NAME 2 (__annotations__) — загружаем
__annotations__ это по сути словарь в котором хранятся типы переменных. На пример:
a: str = "";print(__annotations__) даст на стдауте
{'a': <class 'str'>}

10 LOAD_CONST 1 ('a') #it is clear, ain't it

12 STORE_SUBSCR:

STORE_SUBSCR
Implements TOS1[TOS] = TOS2
(docs)

14 LOAD_CONST               2 (None)
16 RETURN_VALUE

=
return None # functions return None automatically if you don't use any return in it
Эта штука ничего не возвращает т.е. None


Запись в файл всех комбинаций
Есть код для вывода комбинации пин-кода
<code>
from itertools import product
for combos in product('0123456789', repeat=4):
    S = ''.join(combos)
    if S.find('BC') == -1 and  S.find('CC') == -1:
        filee = open("pins.txt", "w")
        filee.write(S)
        filee.close()
</code>
В txt файле только одна комбинация "9999"
Как вывести все комбинации?

In [1]: from itertools import product

In [2]: combinations = []

In [3]: for combos in product("0123456789", repeat=4):
   ...:     combinations.append("".join(combos))
   ...:

In [4]: with open("data.txt", "w") as fp:
   ...:     fp.write("\n".join(combinations))


Отправка через flask-socketio python параметры и файл
Всем привет, помогите отправить файл и параметры через flask-socketio дело в том что есть программа которая может отправить id_case, id_docinf и images[].
я использую данный код:
<code>
data_file = [open(dir_file, 'rb').read(), open(dir_file, 'rb').read()]
d = MultiDict()
d.add('event', 'sendImages')
d.add('id_case', 2)
d.add('id_docinf', 4)

for image in data_file:
    d.add('images', b64encode(image))

multi  = ImmutableMultiDict(d)
socketio.emit('message', d)
</code>
при отправке socketio на стороне клиента видит только id_case и id_docinf, а images нет.
так же нет Content-Type и Content-Length: 0
в socketio должен быть Query String Parametr и FormData

b64encode(image).decode('UTF-8')
и все работает как нужно.


MX Linux установлено 2 python
Недавно установил mx linux (полный новичок) и там установлено 2 python, так и должно быть? Если нет то как удалить python-2.x? и обновить python-3.x?

там установлено 2 python, так и должно быть?

Да, это определено политикой дистрибутива Debian на базе которого собран MX Linux. Команда
python запускает версию 2.x, а команда
python3 версию 3.x.

как удалить python-2.x?

Не пытайтесь удалить python-2.x или изменить умолчания с помощью
update-alternatives - это нарушит работоспособность некоторых системных пакетов.

как обновить python-3.x?

Обновлять python-3.x рекомендуется исключительно средствами самого linux-дистрибутива, т.к. с ним в комплекте идут многочисленные бинарные модули, скомпилированные с оптимальными установками для данной системы. Не стоит стремиться установить самую последнюю версию, только потому что это "круто" - сначала спросите себя: ради какой новой функцинальности я хочу это сделать?


help me please? [закрыт]

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

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

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

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

Напишите программу, которая проверяет, что для заданного четырехзначного числа выполняется следующее соотношение: сумма первой и последней цифр равна разности второй и третьей цифр.
Формат входных данных
На вход программе подаётся одно целое положительное четырёхзначное число.
Формат выходных данных
Программа должна вывести «ДА», если соотношение выполняется, и «НЕТ» — если не выполняется.
Sample Input 1:
1614
Sample Output 1:
ДА
Sample Input 2:
1234
Sample Output 2:
НЕТ

while True:
    digit = input('Sample input: ')

    if not digit:
        break

    [a, b, c, d] = map(int, list(digit))

    if a + d == b - c:
        print('Yes')

    else:
        print('No')


Раздвоение класса python3
Есть код

class A:
    def __init__(self, a):
        self.a = a

    def b(self, n):
        self -= A(n)
        print(self)

    def __sub__(self, other):
        return A(self.a - other.a)

    def __str__(self):
        return f'class A a={self.a}'

if __name__ == '__main__':
    a = A(100)
    a.b(10)
    print(a)

Вывод

class A a=90
class A a=100

Не могу понять почему метод b вычитает 10 из какого-то дубликата класса, а сам класс остается неизменным?
Pycharm предупреждает, что
Method's parameter 'self' reassigned, то есть что self переназначается, но я не могу понять почему это происходит

Как написали в комментариях:

Потому что в методе
__sub__ Вы возвращаете новый класс, не изменяя текущий. Вот пример изменения экземпляра класса:

class A:
    def __init__(self, a):
        self.a = a

    def b(self, n):
        self -= A(n)

    def __sub__(self, other):
        self.a -= other.a
        return self

    def __str__(self):
        return f'class A a={self.a}'

if __name__ == '__main__':
    a = A(100)
    a.b(10)
    print(a)


Properties In Kivy
Сделал переменную для цвета.
Выдает ошибку.
.py

maincolor = VariableListProperty(.9,.0,.0,1)

.kv

        BoxLayout:
            size_hint: 1.0, .8
            canvas:
                Color:
                    rgba: root.maincolor
                Rectangle:
                    size: self.size
                    pos: self.pos
                    source: 'background.png'

Error

 BuilderException: Parser: File "C:\Users\sdded\Desktop\main.kv", line 54:
 ...
      52:                       canvas:
      53:                               Color:
 >>   54:                                       rgba: root.maincolor
      55:                               Rectangle:
      56:                                       size: self.size
 ...
 AttributeError: 'Game' object has no attribute 'maincolor'
   File "C:\Users\samael\AppData\Local\Programs\Python\Python38-32\lib\site-packages\kivy\lang\builder.py", line 242, in create_handler
     return eval(value, idmap), bound_list
   File "C:\Users\samael\Desktop\game\kivygame\releas\main.kv", line 54, in <module>
     rgba: set(root.maincolor)
   File "kivy\weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__

   File "C:\Users\samael\AppData\Local\Programs\Python\Python38-32\lib\site-packages\kivy\lang\builder.py", line 923, in _build_canvas
     value, _ = create_handler(
   File "C:\Users\samael\AppData\Local\Programs\Python\Python38-32\lib\site-packages\kivy\lang\builder.py", line 245, in create_handler
     raise BuilderException(rule.ctx, rule.line,

ListProperty([r, g, b, a])

А в Kivy 2.0 уже завезли

ColorProperty([r, g, b, a])


как присвоить datetime другой год? python
У меня есть объекты datetime, например datetime(1998-11-12), datetime(2020-01-31), datetime(2013-08-25) и мне нужно всем объектам, где год равен 2020, обновить это значение до единицы (не трогая остальные). Я пробовал

bdate.year = 1

так же я пробовал

DATE = datetime(1, 1, 1)
bdate.year = DATE.year

но всё это выдаёт ошибку. Как мне обновить год в datetime?

Вот так вот:
<code>
import datetime

date = datetime.date(2020, 1, 31)
print(date)

date = date.replace(year=1)
print(date)
</code>


Как ускорить расчет среднего значения на скользящем окне?

for i in range(600,len(Dts),1):
    Dts['Av sales D'][i] = Dts['Sales'][i-600:i][Dts['D']==Dts['D'][i]].mean()

Считает среднее значении продаж за текущий день месяца на скользящем окне в 600 дней.
Данных много, уходит больше 10 секунд. Пробовала через Pandarallel, но он не ставится на мою машину.
Пример данных
D - дни месяца (1-31)
Sales - сами продажи. Пример расчетов - формула в колонке
average 2:

D       Sales   average 2
1       15      na
2       1       na
3       9       na
.       .       .
.       .       .
.       .       .
1       17      na
2       28      na
3       6       na
.       .       .
.       .       .
.       .       .
1       20      (15+17)/2
2       13      (1+28)/2
3       2       (9+6)/2
.       .       .
.       .       .
.       .       .
1       1       (20+1)/2
2       0       (13+0)/2
3       7       (2+7)/2


Python вывод ошибки в except
Использую Python 3.6.8
Интересует как вывести внутри except причину ошибки.
Надеюсь объяснил понятно

Вот так вот:
<code>
try:
  0 / 0
except Exception as e:
  print(e)
</code>


Как использовать переменные в discord.py
Хочу сделать бота для мини игры в дискорде, но проблема в том как передавать переменные для команд библиотеки discord.
Например в коде ниже я хочу "заблокировать" команду start после её активации, но т.к сама функция выполняется "вне" программы я не могу сделать проверку за счёт переменной nRound.
Как вообще взаимодействовать с переменами из "вне" в функциях async, если в async функции происходит расчёт, а потом мне нужно эти расчёты сравнить.
<code>
import discord
from discord.ext import commands

TOKEN = '123'
bot = commands.Bot(command_prefix='!')
nRound = 0

@bot.command(pass_context=False)
async def start(ctx):
    if nRound == 0:
        nRound = 1
        await ctx.send("123")
    else:
        print("Игра началась. Чтобы начать новую игру завершите текущую.")
</code>

как вообще взаимодействовать с переменами из "вне" в функциях

Как обычно - с помощью ключевого слова global :
<code>
@bot.command(pass_context=False)
async def start(ctx):
    global nRound
</code>


Задача на бинарный поиск по ответу
Имеется задача. Нужно по заданной высоте, ширине и количеству дипломов повесить их в квадратную рамку минимального размера. Если нужно, вот ссылка на задачу. Я написал код, и при попутке сдать его, из 21 теста 11 тестов не проходят из-за привышения лимита памяти. Объясните, что я сделал не так.
<code>
import math
h,w,n = map(int,input().split())

# размер рамки, от рамки, для которой условие точно не
# выполниться, до рамки для который условие точно выполниться.
ans = [i for i in range(1,math.ceil(math.sqrt(n))*(max(w,h))+1)]

def bin_search(a,x,w,h):#обычний бин. поиск по ответу
    l = 0
    r = len(a)-1
    m = (l+r)//2
    while r - l >1:
        m = (l+r)//2

        if (a[m] // w) * (a[m] // h) >= n:
            r = m

        else:
            l = m

    return a[r]

print(bin_search(ans,n,w,h))

</code>

Алгоритм выглядит правильным, но на кой вам хранить последовательные целые числа большого диапазона в списке?
Работайте с
m, возвращайте
r, а
a[] вообще исключите.


Как построчно применить функцию к списку/переменной с переносами строк
<code>
import blockcypher
prev_data_lines_adr = ['14CaBzRbZDuGJCAdu9CZsbrCfyv4K7f7sf','0xd4FD252d7D2C9479a8d616F510eAC6243B5DDdf9']
for ln in prev_data_lines_adr:
    blockcypher.get_total_balance(ln)
</code>
Как изменить код, чтобы функция построчно применилась к списку или переменной с переносами строк. После выполнения функции, нужно записать выполненное назад в список либо в переменной с переносами строк

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

a = tuple(map(lambla x: x + 1, [1,2,3]))
print(a)
# (2,3,4)

А еще можно воспользоваться любым из comprehension

# генератор
a = (x + 1 for x in [1,2,3])
print(a)
# генератор
print(*a) # сработает только один раз. генератор же.
# 2 3 4

# list
a = [x + 1 for x in [1,2,3]]
print(a)
# [2,3,4]

# tuple
a = tuple(x + 1 for x in [1,2,3])
print(a)
# (2,3,4)

С генератором, что удобно это то, что генератор будет выполняться по элементно при необходиомсти. Что может быть важно при работе например с большим файлом.

# например нам нужно прочитать файл построчно и убрать из каждой строки
# переносы символов и пустые строки
with open("file.txt", "r") as source:
    lines = (x.strip() for x in source if x.strip())
# теперь у нас есть генератор lines, который еще ничего не сделал,
# а делать он будет когда мы захотим проитерировать по нему
# и делать будет по строчно.

Чаще всего включения получаются горадо понятнее чем применение map и filter

# Перепишем построчно один файл в другой без загрузки всего файла в ОЗУ.
# А также применим фильтр по длине строки

with open("source.txt", "r") as source, open("dest.txt", "w") as dest:
    _ = tuple(dest.write(x) for x in source if len(x) < 10)

# Перепишем построчно один файл в другой без загрузки всего файла в ОЗУ.
# А также применим фильтр по длине строки

with open("source.txt", "r") as source, open("dest.txt", "w") as dest:
    _ = tuple(map(dest.write, filter(lambda x: len(x) < 10, source)))

map и filter ленивые функции возвращающие генератор, который еще ничего не сделал. генератор итерируется только один раз и его нужно проитерировать для получения результатов.


Запись значения по адресу pymem
Мне нужно записать значение типа double по адресу "0EEAD0E0" программы, но я никак не могу найти как это сделать с помощью модуля pymem для python. Подскажите, пожалуйста, как это сделать.

import pymem

addr = 0x0EEAD0E0
value = 1.0

pm = pymem.Pymem("program.exe")
pm.write_double(pm.process_base + addr, value)


Как сделать регресивную нейронную сеть на Python?
как можно реализовать регресивную нейронную сеть на Python?
Недавно начал изучать нейросети, и столкнулся с проблемой. Я сделал самую простую игру Змейка на Python. Как можно сделать нейросеть, которая будет управлять змейкой? Т.е давать ей координаты змейки, координаты яблока по иксу X, и получать направление движения змейки, например 0 - налево, 1 - направо. Соответственно также для Y координаты.

Это называется нейросеть с подкреплением.Сперва то обычные черно белые картинки свои научится распозновать бы и там логические операции,потом к более сложному.Кодируете команды A-влево=0.01,В-вправо=0.02,C,D(вверх,вниз),сперва рандомно в цикле идут,потом успех 1(получение балов) и 0.Потом она должна генерировать команды,думаю архитектура типа 4 входа, 5 выходов(1 для успеха/нет).То есть по достижению минимальной ошибки,должна как то генерировать команды.Думаю так)


не могу создать объект класса tkinter.font.Font

from tkinter.font import Font
f=Font(family='Monofur',size=32)

AttributeError: 'NoneType' object has no attribute 'call'

Я не понимаю,о каком объекте NoneType может идти речь,в IDLE

>>> Font
<class 'tkinter.font.Font'>

ввод класса Font возвращает обычный подкласс tkinter.font
На сайтах с примерами кода,где я был,аналогичные куски кода работают исправно

Посмотрим ошибку детально:

>>> from tkinter.font import Font
>>> f = Font(family='Monofur', size=32)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/tkinter/font.py", line 93, in __init__
    tk.call("font", "create", self.name, *font)
AttributeError: 'NoneType' object has no attribute 'call'

tk - это объект главного окна, который берется или из глобальной переменной модуля tkinter, или передается первым параметром при создании объекта
Font (см. исходники).
Из-за того что окно еще не создано, значение этой переменной равно
None, и при вызове метода
call от
tk возникает ошибка.
Нужно сначала создать объект
Tk() (главное окно), потом уже создавать шрифт:

from tkinter import Tk
from tkinter.font import Font

root = Tk()
f = Font(family='Monofur', size=32)
# или f = Font(root, family='Monofur', size=32)


Добавление элементов в двумерный массив
Хочу добавлять числа в двумерный массив в цикле, есть вот такой код:

customers = [1,3,5,7,3,7,9,67]
n = 4
if len(customers) == 0:
    print(0)
elif n == 1:
    print (sum(customers))
elif n >= len(customers):
    print(max(customers))
else: #СОДЕРЖАТЕЛЬНАЯ ЧАСТЬ
    tills = [[]]*n
    j = 0
    for i in range(len(customers)):
        tills[j].append(customers[i])
        if j < n-1:
            j += 1
        else:
            j = 0

print(tills)

НО я не понимаю, почему вывод вот такой:

[[1, 3, 5, 7, 3, 7, 9, 67], [1, 3, 5, 7, 3, 7, 9, 67], [1, 3, 5, 7, 3, 7, 9, 67], [1, 3, 5, 7, 3, 7, 9, 67]]

По моей логике (что и нужно получить мне), должно быть вот так:

[[1,3],[3,7],[5,9],[7,67]]

Как этого добиться?

В питоне списки - это объекты, и поэтому сам язык старается максимально оптимизировать их использование через ссылки, ленивые вычисления и так далее.
Когда вы создаете список с помощью кода
array = [[]] * n, то фактически вы создаете только список
array[0], а все остальные списки становятся его копиями, записанными с помощью ссылки на этот созданный "нулевой" список.
Поэтому добавляя элементы в любой из списков, вы фактически добавляете эти элементы в
array[0], а в остальных списках они появляются потому, что все остальные списки являются ссылками на
array[0].
Для того, чтобы исправить данную ошибку, можно использовать генераторы списков:

array = [[] for _ in range(n)]


Переместить файл в корзину — Python
Как безопасно удалить файл, то есть переместить его в корзину (Recycle bin), чтобы пользователь самостоятельно смог восстановить его?

os.remove стирает игнорируя корзину

os.rmdir стирает именно директории

pip3 install send2trash

from send2trash import send2trash
send2trash("directory")

source


Оставить только строки, которые содержат определенные слова
Есть следующий датасет:

Компания    Назначение
АБ          Продажа готовой продукции
В           Оплата налогов
Г           Удаление вирусов
У           Продажа запасов

Нужно оставить только те строки с назначением "продажа". То есть на выходе получим :

Компания    Назначение
АБ          Продажа готовой продукции
У           Продажа запасов

import re

res = df[df["Назначение"].str.contains("продажа", flags=re.I)]

результат:

In [6]: res
Out[6]:
  Компания                 Назначение
0       АБ  Продажа готовой продукции
3        У            Продажа запасов


Как можно избавиться от ошибки из-за пустых ячеек Excel файла?
Код:
<code>
def find_cell_next_to_val(filename, val, **kwargs):
    df = pd.read_excel(filename, header=None, dtype=str, **kwargs)
    df = df.apply(lambda col: col.str.strip())
    rows, cols = np.where(df == str(val).strip())
    if len(rows) == 0:
        return None
    row, col = rows[0], cols[0]
    if col + 1 > df.shape[1]:
        return None
    col_idx = df.iloc[row, col+1:].first_valid_index()
    try:
        return df.iat[row, col_idx]
    except KeyError:
        return None
</code>
читает данные файлов Excel, однако если некоторая интересующая нас ячейка ссылается на пустоту то эта функция возвращает ошибку:

ValueError: iAt based indexing can only have integer indexers

Как можно избавиться от этой ошибки?
Ссылка на файл с исходными данными.

Попробуйте так:
<code>
def find_cell_next_to_val(filename, val, **kwargs):
    df = pd.read_excel(filename, header=None, dtype=str, **kwargs)
    df = df.apply(lambda col: col.str.strip())
    rows, cols = np.where(df == str(val).strip())
    if len(rows) == 0:
        return None
    row, col = rows[0], cols[0]
    if col + 1 > df.shape[1]:
        return None
    col_idx = df.iloc[row, col+1:].first_valid_index()
    try:
        return df.iat[row, col_idx]
    except (KeyError, ValueError):
        return None
</code>


Как добавлять новые задачи в async.wait по мере завершения уже запущеных задач?
Как  добавлять новые задачи в async.wait по мере завершения уже запущеных задач?
Ниже приведен кусок рабочего кода, который скачивает информацию с биржи по торговым парам за определенный период. Проблема данного скрипта в том, что если задать большое кол-во пар и период (по дням), то кол-во тасков сильно возрастает и при их обработке возникает проблемы с нехваткой памяти.
Как можно модифицировать приведенный ниже код, чтобы aio.wait обрабатывал не более 10 задач, а помере выполнения и закрытия текущей задачи, добавляли новые задачи из очереди ?
<code>
    tasks = ( FetchTrades(exchange, pair, period[0], period[1]) for pair in pairsFiltered for period in periods)
    pending = list( tasks )
    resultsList = []
    while pending:
        done, pending = await aio.wait(
                        pending,
                        #timeout=30,
                        return_when=aio.FIRST_COMPLETED
            )
        for future in done:
            result = future.result()
            pair = result[0]
            if(len(result[1]) > 0):
                for i in range(0, len(result[1]), 10000):
                    lst = result[1][i: i+10000]
                    cur.executemany(sqlInsert, lst)
</code>

Правильных вариантов может быть несколько. Можно ограничить количество задач семафором
<code>
sem = asyncio.Semaphore(value=10)

def done(future):
    result = future.result()
    pair = result[0]
    if(len(result[1]) > 0):
        for i in range(0, len(result[1]), 10000):
            lst = result[1][i: i+10000]
            cur.executemany(sqlInsert, lst)
    sem.release()

for period in periods:
    for pair in pairsFiltered:
        await sem.acquire()
        f = FetchTrades(exchange, pair, period[0], period[1])
        f.add_done_callback(done)

await asyncio.wait(asyncio.all_tasks())
</code>


UserCreationForm: текст подсказок по-русски
В UserCreationForm не полностью переводится текст подсказок. В чем может быть проблема?

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class UserOurRegistration(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

<div class="form-section">
    <form method="POST" id="reg_form">
        {% csrf_token %}
        {{ form|crispy }}
        <button type="submit" class="btn_register">Зарегистрироваться</button>
    </form>
    <hr>
</div>

Попробуйте варианты описаные здесь. Вам вероятно нужно будет переопределить список ошибок для вашей формы


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

Сделайте запись в какой-нибудь файл , к примеру в txt. Пример:
<code>
filename="save.txt"
if filename:
    print ("ТУТ ДЕЙСТВИЯ")
else :
    print ("ИДЕТ ВЫПОЛНЕНИЕ КАКОЙ-НИБУДЬ ФУНКЦИИ, ГДЕ, В КОНЦЕ БУДЕТ НАПИСАНО ТАК - ")
    with open (filename, 'w') as f:
        f.write("Теперь у нас есть что-то типа сохранения")
</code>
Что же я сделал ? Получается, если у нас есть файл, то он будет неким сохранением. Мы Проверяем, есть ли у нас файл и дальше уже решаем - продолжать действие или начать новое


Конвертация строки в дату python
Есть строка вида
'2020-07-22T16:41:35.521+0300'
Как из нее получить дату в формате dd/mm/yyyy hh:mi:ss?

from datetime import datetime

print(datetime.strptime('2020-07-22T16:41:35.521+0300', '%Y-%m-%dT%H:%M:%S.%f%z').strftime('%d/%m/%Y %H:%M:%S'))

Если кому-то прям совсем не нравится
datetime можно через
re:

import re

s = '2020-07-22T16:41:35.521+0300'
yyyy, mm, dd, h, m, ss, *_ = re.split(r'[T:.-]', s)

# или
yyyy, mm, dd, h, m, ss, *_ = re.findall(r'\d+', s)

print(f'{dd}/{mm}/{yyyy} {h}:{m}:{ss}')

# результат будет идентичный

UPD:

from dateutil.parser import parse

print(parse('2020-07-22T16:41:35.521+0300').strftime('%d/%m/%Y %H:%M:%S'))


Как отфильтровать pandas.DataFrame по столбцу, состоящему из списков в зависимости от наличия в списке тех или иных элементов?
Имеется pandas.DataFrame, в котором записана информация о школьных уроках и курсах. Среди неё имеется список классов, которые этот курс могут посещать (например, если это 9-11 класс, то будет записано [9, 10, 11] в типе int). Итак, предположим нужно получить список курсов, которые может посещать 8 класс. В Pandas это обычно делается с помощью булевского индексирования:

df = df[df['нужный_параметр'] == нужный_объект]

В результате часть
df['нужный_параметр'] == нужный_объект возвращает список из значений
True и
False, где напротив каждого индекса указано, соответствует ли строка под этим индексом в DataFrame заданному параметру. Далее
df[[bool-список]] возвращает только те значения, по индексу которых в bool-списке указано
True.
Но как я писал выше, классы для посещения курсов записаны в списке из
int, а не в
str или
int. Итак, пробуем:

df = df[8 in df['grades']]

В результате Python пожалуется с помощью
KeyError на то, что
df[] ожидал список из значений типа
bool, что справедливо, ведь часть
8 in df['grades'] возвращает лишь один
bool. Почему это происходит? Pandas образует bool-список только с мат. операторами и операторами сравнения строк? Плюс к тому же: в
df['grades'] попросту нет значения
8; в этом столбце есть только списки, в которых имеется этот элемент (
[8, ...]). Так почему же
8 in df['grades'] тогда возвращает
True? Выходит, что
df['grades'] возвращает список, в котором смешано содержимое всех списков столбца (и как в таком случае фильтровать DataFrame)?
Попробуем вручную создать этот самый bool-список и с его помощью отфильтровать DataFrame:

tf = []
for i in range(len(database['grades'])):
    if 8 in database['grades'][i]:
        tf.append(True)
    else:
        tf.append(False)
database = database[tf]

Это работает, но очевидно, что этот код громоздкий и возможно ресурсоёмкий. Как же привести всю эту обработку к удобному виду
df = df[df['нужный_параметр'] == нужный_объект]? Если нет, как это привести к максимально удобному виду? Можно ли это сделать с помощью конструктора (
tf = [i for i in ...])? Как завести этот самый список в отдельном столбце в DataFrame и как этот столбец быстро заполнить (я помню, что делал это, но сейчас забыл как)?
P. S. Понимаю, что возможно усложнил вопрос, но сделал его полным для получения полного ответа. Заранее благодарю, за то что прочитали всё и уделили вопросу внимание!

Пусть есть Dataframe:

            A
0    [3, 4, 5]
1  [9, 10, 11]

тогда:

num = 9
df["A"].apply(lambda x: num in x)

результат:

0    False
1     True
Name: A, dtype: bool


Что означает %s и % в аргументах функции в Django?
<code>
def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)
</code>

<code>
def detail(request, question_id):
return HttpResponse(f"You're looking at question {question_id}.")
</code>
Да, это такой синтаксис Python.
Приятнее и быстрее будет работать с f-строками.
И читабельнее.


Вызов диалога открытия файла при нажатии на кнопку
столкнулся с проблемой создал окно с кнопкой которое открывает следующие окно в котором есть кнопка для выбора файла, но выбор файла происходит при нажатие первой кнопки, а вторая остаётся неактивной
<code>
class Child(tk.Toplevel): #Настройка первого окна
    def __init__(self):
        super().__init__(root)
        self.init_child()
        self.view = app

    def init_child(self):
        self.title('Додати')
        self.geometry('400x720+400+300')
        self.resizable(False, False)

        self.btn = ttk.Button(self, text='Создать файл', command=Generate) #Кнопка открытия второго окна
            self.btn.place(x=50, y=480)

            self.grab_set()
            self.focus_set()

        def Generate(self):
            Window2()

class Generate(tk.Toplevel): # Настройка второго окна
    def __init__(self, *arg, **kwarg):
        super().__init__(*arg, **kwarg)
        self.init_gen()
        self.view = app

    def init_gen(self):
        self.title('Создать файл')
        self.geometry('400x720+100+300')
        self.resizable(False, False)

        file = filedialog.askopenfilename()

        self.btn1 = ttk.Button(self, text='Выбрать файл', command=file) #Кнопка выбора файла
        self.btn1.place(x=50, y=480)

</code>

filedialog.askopenfilename() сразу выполняет открытие диалога выбора файла, результатом вызова будет имя файла. Дальше вы полученное имя файла зачем-то указываете как команду для кнопки (очевидно, это не правильно). Делайте вызов диалога не в
init_gen, а в отдельной функции, и эту функцию укажите как команду для кнопки, пример:

class Generate(tk.Toplevel): # Настройка второго окна
    ...

    def init_gen(self):
        ...

        def get_file_name():
            file = filedialog.askopenfilename()
            # Дальше в этой же функции работайте с полученным именем файла, например, можно открыть этот файл

        self.btn1 = ttk.Button(self, text='Выбрать файл', command=get_file_name) #Кнопка выбора файла


guess game - index error - python [закрыт]

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

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

Вопрос закрыт, так как на Stack Overflow на русском вопросы принято задавать только на русском языке. Пожалуйста, переведите ваш вопрос на русский язык или воспользуйтесь Stack Overflow на английском.
Вопросы с просьбами помочь с отладкой («почему этот код не работает?») должны включать желаемое поведение, конкретную проблему или ошибку и минимальный код для её воспроизведения прямо в вопросе. Вопросы без явного описания проблемы бесполезны для остальных посетителей. См. Как создать минимальный, самодостаточный и воспроизводимый пример.

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

import random

def print3x3(lists):
  for i, item in enumerate(lists, 1):
    print(item, end=' ')
    if i % 3 == 0:
      print()

listx = list()
list0 = list()

for i in range(3):
  for i in range(3):
    listx.append('x')

for i in range(3):
    for i in range(3):
      r = random.randint(1, 9)
      list0.append(r)

user = int(input("Enter num:  "))

while True:
  for i, item in enumerate(list0, 1):
    if item == user:
      listx[i] = user
      print3x3(listx)

i want to hide random numbers behind these x
and let user guess them
but it gives error

Traceback (most recent call last):
  File "main.py", line 26, in <module>
    listx[i] = user
IndexError: list assignment index out of range

what can i do ?1
thanks

Не копируйте конструкции слепо. Если в первом случае использования
enumerate вам нужно, чтобы
enumerate работал начиная с 1, а не с 0, чтобы правильно отрабатывал остаток от деления, то во втором случае вам этот параметр (начинать отсчёт с 1) наоборот мешает, потому что нумерация индексов в списках идёт с 0. Правильный код будет такой:

  for i, item in enumerate(list0):
    if item == user:
      listx[i] = user


Как я могу напечатать список в гриде 3x3? 1 - Python
<code>
import random

list0 = list()

for i in range(3):
    for i in range(3):
      r = random.randint(1, 9)
      list0.append(r)

for item in list0:
  print(item, end=' ')
</code>
Я хочу написать его в сетке 3х3.
Kак я могу это сделать ?

for i, item in enumerate(list0, 1):
    print(item, end=' ')
    if i % 3 == 0:
        print()

Или, если использовать тернарный оператор:

for i, item in enumerate(list0, 1):
    print(item, end='\n' if i % 3 == 0 else ' ')


Как расширить двумерный массив в python
Я делаю игру с бесконечным миром. У меня есть двумерный массив pos_block[x][y]. Каждая ячейка массива соответствует координате в мире. Так как изначально я не могу создать массив нужного размера я хочу его расширять. Как это сделать? Создаю массив с помощью
pos_blocks=[[0 for a in range(-501,501)] for b in range(-801,801)] и хочу его увеличивать.

Да так то нет ничего проще, если немного подумать:

pos_blocks=[[0 for a in range(-1,1)] for b in range(-2,2)]
print(pos_blocks)

# добавляем ещё один список в конец основного списка
pos_blocks.append([0]*2)
print(pos_blocks)

# добавляем по одному элементу в каждый список внутри основного списка
for l in pos_blocks:
    l.append(0)
print(pos_blocks)

Исходный список списков:

[[0, 0], [0, 0], [0, 0], [0, 0]]

После добавления в него нового списка:

[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]

После добавления элемента в каждый вложенный список:

[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]


Проблема инициализации forms Django
Когда инициализирую форуму как атрибут класса, все работает, но как только переношу инициализацию в функцию, то выдает исключение, все подробности в комментариях к коду.
Спасибо за помощь!
forms.py

    class Meta:
        model = Users
        fields = ['chat_id', 'username', 'balance']
        widgets = {
            'chat_id': forms.NumberInput(attrs={'placeholder': 'Укажите токен QIWI', 'class': 'form-control'}),
            'username': forms.TextInput(attrs={'placeholder': 'Укажите токен QIWI', 'class': 'form-control'}),
            'balance': forms.NumberInput(attrs={'placeholder': 'Укажите токен QIWI', 'class': 'form-control', 'step': 0.10}),
            'referrals': forms.NumberInput(attrs={'placeholder': 'Укажите токен QIWI', 'class': 'form-control'})
        }

views.py

    login_url = '/login/login'
    # edit_user_form = EditBotUser() # Если инициализировать таким образом, то все работает

    def get(self, request, chat_id):
        user_obj = get_bot_user_by_chat_id(chat_id) # Бизнес логика, вынесена в другой файл
        if user_obj:
            edit_user_form = EditBotUser()  # Но вот так не работает :(
            print(edit_user_form.fields)  # Возвращает AttributeError: 'EditBotUser' object has no attribute 'fields'
            return render(
                request,
                'dashboard/edit_bot_user.html',
                context={'edit_user_form': edit_user_form, 'user': user_obj}
            )
        else:
            return HttpResponse('Данный пользователь не существует!')

    def post(self, request, chat_id):
        pass

urls.py

urlpatterns = [
    path('', Settings_panel.as_view(), name='settings'),
    path('qiwi/settings/', Settings_qiwi.as_view(), name='settings_qiwi'),
    path('user/edit/<int:chat_id>', EditBotUser.as_view(), name='edit_bot_user')
]

Мне кажется, или у вас форма и вьюха называются одинаково?
Если это так, то вы просто пытаетесь аттрибутом вьюхи сделать саму вьюху, а у нее действительно нет поля fields. Назовите классы согласно их функционалу, например EditBotUserForm и EditBotUserView и все станет хорошо


как отловить событие изменения размера столбца в QTableWidget?
У меня есть
QTableWidget, пользователь может менять размер столбцов при помощи мыши, и мне бы хотелось иметь возможность отловить какой-нибудь сигнал при изменении размеров какого-нибудь столбца.
Но в
QTableWidget нет никаких сигналов, которые бы делали то, что я хочу.
Где мне искать нужный сигнал?

Для отслеживания размера столбцов в заголовке таблицы, нужно обратиться к
horizontalHeader и подключиться к его сигналу
sectionResized:

QHeaderView::sectionResized(int logicalIndex, int oldSize, int newSize)

Пример:

from PyQt5.QtWidgets import QApplication, QTableWidget

def _on_section_resized(logical_index: int, old_size: int, new_size: int):
    print(logical_index, old_size, new_size)

app = QApplication([])

table = QTableWidget()
table.setColumnCount(5)
table.horizontalHeader().sectionResized.connect(_on_section_resized)
table.resize(600, 400)
table.show()

app.exec()

Если подключение сигнала будет к методу:

from PyQt5.QtWidgets import QApplication, QTableWidget, QMainWindow

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

        table = QTableWidget()
        table.setColumnCount(5)
        table.horizontalHeader().sectionResized.connect(self._on_section_resized)

        self.setCentralWidget(table)

    def _on_section_resized(self, logical_index: int, old_size: int, new_size: int):
        print(logical_index, old_size, new_size)

app = QApplication([])

mw = MainWindow()
mw.resize(600, 400)
mw.show()

app.exec()


Ошибка с TeleBot в telebot
Первый раз пишу телеграмм-бота, уже написал простейший код, пробую его запустить, но Python выдает ошибку: AttributeError: partially initialized module 'telebot' has no attribute 'TeleBot' (most likely due to a circular import). Я уже искал решения в гугле, но там говорят что нужно удалить если есть модуль telebot, и установить pytelegrambotapy. Я все так и сделал, перезапустил пк, но ошибка никуда не исчезла. Помогите пожалуйста, буду очень благодарен!
Вот код:
<code>
import telebot

bot = telebot.TeleBot("Токен")

@bot.message_handler(content_types = ["text"])
def hell_text(message):
    if message.text.upper() == "ПРИВЕТ":
        bot.send_message(message.chat.id, "Привет!")

bot.polling(none_stop = True, interval = 0)
</code>

Попробуйте, быть может, поможет.
<code>
pip uninstall telebot
pip install pytelegrambotapi
</code>


Как в файле конфигурации модуля logging указать корректный путь?
Python 3.8, для логирования используется модуль logging. Конфигурация задается в файле

[loggers]
keys=root, main

[handlers]
keys=fileErrorHandler, consoleHandler

[formatters]
keys=notificationFormatter

[logger_root]
level=INFO
handlers=consoleHandler

[logger_main]
level=INFO
handlers=fileErrorHandler
qualname=main

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=notificationFormatter
args=(sys.stdout,)

[handler_fileErrorHandler]

class=FileHandler
formatter=notificationFormatter
args=("logs/errors.log",)

[formatter_notificationFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

Но когда приложение запускается из exe после сборки в Cx_freeze автозапуском Windows, то родительской папкой для поиска "logs/errors.log" становится c:/windows/system32. Как в файле конфигурации можно определить место запускать приложения самого и определять, как запускается приложение?
В Python это решается так:

if getattr(sys, 'frozen', False):
    dir_ = os.path.dirname(sys.executable)     # frozen
else:
    dir_ = os.path.dirname(os.path.realpath(__file__))    # unfrozen

Только указав абсолютный путь.


TypeError: object of type 'NoneType' has no len(). Codewars
Код работает, но на CODEWARS Выводит ниже приписка и поэтому не получается cдать кату:

Traceback (most recent call last):
  File "main.py", line 21, in <module>
    test.assert_equals(comp(a1, a2), False)
  File "/home/codewarrior/solution.py", line 4, in comp
    if len(a) != len(b):
TypeError: object of type 'NoneType' has no len()

#Сравнивает два списка, второй должен состоять из квадратов первого, тогда True
def comp(a, b):
    if a and b is None:
        return True
    if len(a) != len(b):
        return False
    index = 0
    n = 0
    while index != len(a):
        for i in range(0, len(a)):
            if a[index]**2 == b[i]:
                n += 1
                continue
            else:
                continue
        if n != len(a):
            index += 1
    if n/2 == len(a):
        return True
    else:
        return False

Попробуйте так:

def comp(a, b):
    if a is None and b is None:
        return True
    if a is None or b is None or len(a) != len(b):
        return False
    return sorted(list(map(lambda x: x**2, a))) == sorted(b)

Тесты:

In [24]: comp([], [1,2])
Out[24]: False

In [25]: comp([], [])
Out[25]: True

In [26]: comp([4, 2, 3], [9, 16, 4])
Out[26]: True


pygame.draw.rect меняет размер, хотя тот постоянен

import pygame

FPS = 60

screen_width=800
screen_height=500
screen_size=(screen_width,screen_height)

pygame.init()
root=pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()

person=[pygame.image.load("person_right.png"),pygame.image.load("person_left.png")]

pygame.display.update()

jumpCount=15

x=0
y=0

isJump=False
side="right"

x_person=screen_width//3
y_person=screen_height-200

size_block=50
def draw_ground():
    pygame.draw.rect(root,(0,0,100),(x,y,x+size_block,y+size_block))

def draw(side):
    root.fill((0,0,0))
    if side=="right":
        root.blit(person[0],(x_person,y_person))
    else:
        root.blit(person[1],(x_person,y_person))
    draw_ground()
    pygame.display.update()

def jump():
    global y, isJump,jumpCount
    if jumpCount>=-15:
        if jumpCount>=0:
            y-=(jumpCount**2)//16
        else:
            y+=(jumpCount**2)//16
        jumpCount-=1

    else:
        isJump=False
        jumpCount=15

while True:
    clock.tick(FPS)
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()
    keys=pygame.key.get_pressed()
    if keys[pygame.K_LEFT] or keys[pygame.K_a]:
        x+=3
        side="left"
    if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
        x-=3
        side="right"
    if not isJump:
        if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]:
            isJump=True
    else:
        jump()
    draw(side)

Квадрат
pygame.draw.rect(root,(0,0,100),(x,y,x+size_block,y+size_block)) не должен по логике менять размеры, при изменении x, но он растягивается, причем проблема явно не в
pygame.display.update(), так как он растягивается когда x увеличивается и стягивается, когда x уменьшается. size_block не меняется, значит и размеры не должны меняться.

Если последние два значения тапла это координаты точки, то да, размер не должен меняться. Но я подозреваю, что это именно длина и ширина, и тогда они зависят от
x и
y. Поменяйте
x+size_block,y+size_block на
size_block,size_block.

import pygame

FPS = 60

screen_width=800
screen_height=500
screen_size=(screen_width,screen_height)

pygame.init()
root=pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()

person=[pygame.image.load("person_right.png"),pygame.image.load("person_left.png")]

pygame.display.update()

jumpCount=15

x=0
y=0

isJump=False
side="right"

x_person=screen_width//3
y_person=screen_height-200

size_block=50
def draw_ground():
    pygame.draw.rect(root,(0,0,100),(x,y,size_block,size_block))

def draw(side):
    root.fill((0,0,0))
    if side=="right":
        root.blit(person[0],(x_person,y_person))
    else:
        root.blit(person[1],(x_person,y_person))
    draw_ground()
    pygame.display.update()

def jump():
    global y, isJump,jumpCount
    if jumpCount>=-15:
        if jumpCount>=0:
            y-=(jumpCount**2)//16
        else:
            y+=(jumpCount**2)//16
        jumpCount-=1

    else:
        isJump=False
        jumpCount=15

while True:
    clock.tick(FPS)
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()
    keys=pygame.key.get_pressed()
    if keys[pygame.K_LEFT] or keys[pygame.K_a]:
        x+=3
        side="left"
    if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
        x-=3
        side="right"
    if not isJump:
        if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]:
            isJump=True
    else:
        jump()
    draw(side)


Telegram Client API
форумчане. У меня такой вопрос. Реализую сбор сообщений из чата telegram и записываю их в формате json `

for message in messages:
            all_messages.append(message.to_dict())
        first_record_number = messages[len(messages) - 1].id
        total_messages = len(all_messages)
        if total_count_limit != 0 and total_messages >= total_count_limit:
            break

    with open('channel_messages.json', 'w', encoding='utf8') as outfile:
        json.dump(all_messages, outfile, indent=2, ensure_ascii=False, cls=DateTimeEncoder)`

Как записывать лишь те сообщения, в которых присутствуют определенные слова ?
Запись в таком формате:

{
    "_": "Message",
    "id": 62,
    "to_id": {
      "_": "PeerUser",
      "user_id": 900804548
    },
    "date": "2020-07-21T08:25:59+00:00",
    "message": "ioc love belarus",
    "out": true,
    "mentioned": false,
    "media_unread": false,
    "silent": false,
    "post": false,
    "from_scheduled": false,
    "legacy": false,
    "edit_hide": false,
    "from_id": 782177156,
    "fwd_from": null,
    "via_bot_id": null,
    "reply_to_msg_id": null,
    "media": null,
    "reply_markup": null,
    "entities": [],
    "views": null,
    "edit_date": null,
    "post_author": null,
    "grouped_id": null,
    "restriction_reason": []
  },

Вы можете записать каждое сообщение, которые вам приходит. А после его обработать через модуль re.
Допустим вы определили исходный перечень слов, по которым вам нужно записать сообщение.
Однако помните, что это плохой способ. Если вы посмотрите на список ниже, слово диван некорректно указано. И в этом случае все сообщения, в которых корректно указано это слово , записаны не будут!

msg_list = ['пиво', 'диванэ', 'кофе', 'мотор']

Далее определяем получения сообщения. Для того, что бы увидеть текст сообщения пользователя используйте message.text. так же в ответе json можно записать и номер телефона и ФИО.

@bot.message_handler(content_types=['text'])
def send_text(message):

    for item in msg_list:
        if item in message.text:
            bot.send_message(message.chat.id, f'я записал слово "{message.text}"')

    user_message = message.text
    ### your logic parse tring by 're' module

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


как узнать размер окна Tkinter?
Написал программу и хочу сделать исполняемый файл с помощью
pyinstaller, но к сожалению, при запуске программы, некоторые размеры окон неверны, т.к. я задаю геометрию окна таким образом:
self.geometry('+{}+{}'.format(w, h)) В данном примере главное то, что размеры окна задаются автоматически.
При запуске программы через IDEL всё отображается правильно, но когда запускаю .exe файл, то размеры съезжают. Чтобы всё было хорошо, мне надо узнать автоматические размеры заданные окну. Как это можно реализовать?

Используйте метод
geometry() класса
tkinter.Tk(), пример:

import tkinter as tk
root = tk.Tk()
print(root.geometry())


как подтянуть сторонние модули python в exe
собрать свои самописные модули в один
exe с помощью
pyinstaller вышло, но можно ли каким то образом также и сторонние модули подтянуть в
exe и не таскать их в виртуальном окружении рядом с исполняемым файлом?

Надо вызвать
pyinstaller с опцией
--onefile в самом виртуальном окружении, а не вне его.


Как найти все совпадения в строке [закрыт]

Закрыт. Этот вопрос необходимо уточнить или дополнить подробностями. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение.

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

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

У меня в строке есть несколько слов допустим "яблоко", как мне найти все совпадение и выдать их.
Я пробовал использовать метод find()

можете использовать
findall модуля
re

import re
a = 'яблоко, яблоко, апельсин, манго'
print(re.findall('яблоко', a))


Получение пути к папке через проводник
Задача простая:
хочу выбрать в открывшемся проводнике папку и получить путь к ней
Нашёл на форуме вырвиглазный рабочий метод
<code>
import sys
from PyQt5.QtWidgets import *

class Form(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

    def get_directory(self):  # <-----
        return QFileDialog.getExistingDirectory(self, "Выбрать папку", ".")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Form()

    print(ex.get_directory())
</code>
Есть ли какое-то более простое решение? Желательно без использования такого гиганта, как PyQt5.
Интернеты мне подсказывают библиотеку easygui, документацию которой сейчас читаю, и даже нашёл метод, который делает то, что я хочу, только для файлов, а не папок (ОС Windows). Спасибо за помощь

С помощью библиотеки Tkinter:

import tkinter

foldername = tkinter.filedialog.askdirectory()

с помощью библиотеки PyQt5:

from PyQt5 import QtCore, QtWidgets, QtGui
import sys
prg = QtWidgets.QApplication(sys.argv)
dirlist = QtWidgets.QFileDialog.getExistingDirectory(None,"Выбрать папку",".")
sys.exit(prg.ecec_())


Найти ошибку в коде Python
Программа должна принимать у пользователя список чисел, и, используя контрольное значение (сумма остатков деления каждого из чисел на следующее за ним число), сравнивать полученное значение с начальным. Проблема: четвертая строка с запросом input повторяется бесконечно.
<code>
number_list = []
N = int(input('N: '))
for _ in range(N):
    number_list.append(input())
control_number = int(input())
exp_control_number = 0
for i in range(1, len(number_list)-2):
    exp_control_number += (number_list[i] % number_list[i + 1])//1
if control_number == exp_control_number:
    print('Список не изменился')
else:
    print('Список изменился')
</code>
Заранее благодарю за ответ

функция
input всегда возвращает тип
str. Потом вы делаете математические операции над строками, в связи с этим и получаете ошибку. Необходимо преобразовать данные в тип
int

    number_list = []
    N = int(input('N: '))
    for _ in range(N):
        number_list.append(int(input()))
    control_number = int(input())
    exp_control_number = 0
    for i in range(1, len(number_list)-2):
        exp_control_number += (number_list[i] % number_list[i + 1])//1
    if control_number == exp_control_number:
        print('Список не изменился')
    else:
        print('Список изменился')