Почему я получаю некорректный расчет по методу FIFO в Python?
Я пытаюсь написать код для расчета себестоимости проданной валюты методом FIFO.
Брокерский отчет разбит на две таблицы со сделками покупок и продаж.

    Номер       Вид_сделки  Наименование Цена/ед.   Количество  Сумма   Валюта  Дата
0   215444826   Покупка     USDRUB_TOM   61.2000    150         9180.00 RUB     10.01.2020
1   215611371   Покупка     USDRUB_TOM   61.3325    1           61.33   RUB     13.01.2020
2   215762332   Покупка     USDRUB_TOM   61.0875    100         6108.75 RUB     14.01.2020
3   215922580   Покупка     USDRUB_TOM   61.3900    70          4297.30 RUB     15.01.2020
4   215926516   Покупка     USDRUB_TOM   61.3275    1           61.33   RUB     15.01.2020
5   218340663   Покупка     USDRUB_TOM   63.2175    100         6321.75 RUB     05.02.2020
6   218514960   Покупка     USDRUB_TOM   62.8525    50          3142.63 RUB     06.02.2020
7   218555601   Покупка     USDRUB_TOM   62.7200    75          4704.00 RUB     06.02.2020
8   218578024   Покупка     USDRUB_TOM   62.6625    75          4699.69 RUB     06.02.2020
9   219928930   Покупка     USDRUB_TOM   63.2950    100         6329.50 RUB     18.02.2020

    Номер       Вид_сделки  Наименование Цена/ед. Количество  Сумма     Валюта  Дата        Sell_cnt
1   215133588   Продажа     USDRUB_TOM   61.7225  1000        61722.50  RUB     09.01.2020  1000
2   219990323   Продажа     USDRUB_TOD   63.7625  3           191.2     RUB     18.02.2020  3
3   229240134   Продажа     USDRUB_TOD   73.8525  9           664.6     RUB     10.04.2020  9
4   229442079   Продажа     USDRUB_TOD   73.5475  149         10958.58  RUB     13.04.2020  149
5   230692120   Продажа     USDRUB_TOD   74.7800  114         8524.92   RUB     20.04.2020  114

Для расчетов написал следующий код:

for i, row_s in df_sell.iterrows():
Buy_cost = 0
while row_s['FIFO_sell'] > 0:
    for j, row_b in df_buy.iterrows():
        if row_s['FIFO_sell'] > row_b['FIFO_buy']:
            Buy_cost = Buy_cost + row_b['FIFO_buy'] * row_b['Цена/ед.']
            row_s['FIFO_sell'] = row_s['FIFO_sell'] - row_b['FIFO_buy']
            row_b['FIFO_buy'] = 0

        elif row_s['FIFO_sell'] == row_b['FIFO_buy']:
            Buy_cost = Buy_cost + row_s['FIFO_sell'] * row_b['Цена/ед.']
            row_s['FIFO_sell'] = 0
            row_b['FIFO_buy'] = 0

        else:
            Buy_cost = Buy_cost + row_s['FIFO_sell'] * row_b['Цена/ед.']
            row_b['FIFO_buy'] = row_b['FIFO_buy'] - row_s['FIFO_sell']
            row_s['FIFO_sell'] = 0

    df_sell.at[i, "Себестоимость покупки"] = Buy_cost

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

    Номер       Вид_сделки  Наименование  Цена/ед.  Количество  Сумма        Валюта Дата        FIFO_sell  Себестоимость_покупки
1   215133588   Продажа     USDRUB_TOM    61.7225   1000        61722.50     RUB    09.01.2020  1000       66271.7775
31  219990323   Продажа     USDRUB_TOD    63.7625   3           191.29       RUB    18.02.2020  3          183.6000
101 229240134   Продажа     USDRUB_TOD    73.8525   9           664.67       RUB    10.04.2020  9          550.8000
123 229442079   Продажа     USDRUB_TOD    73.5475   149         10958.58     RUB    13.04.2020  149        9118.8000
168 230692120   Продажа     USDRUB_TOD    74.7800   114         8524.92      RUB    20.04.2020  114        6976.8000

Кроме того, в глаза бросается, что значения в столбцах FIFO_sell и FIFO_buy остаются неизменными, хотя по задумке, все значения должны быть равны 0.
Использую Python 3.9.16 final, VS Code.
Есть мысли, где допущена ошибка?
Спасибо!

Написал следующий код:
<code>
i = 0
j = 0
Buy_cost = 0
# листы с индексами датафреймов (от 0 до n)
index_sell = list(df_sell.index)
index_buy = list(df_buy.index)
# цикл ограничен размерами массивов
while i <= max(index_sell) and j <= max(index_buy):
    # в цикле сравниваются 1 сделка по покупке и продаже валюты
    if df_sell.at[i, 'Sell_cnt'] > df_buy.at[j, 'Количество']:
        # количество проданных единиц больше количества купленных
        Buy_cost += df_buy.at[j, 'Количество']*df_buy.at[j, 'Цена за единицу']
        df_sell.at[i, 'Sell_cnt'] -= df_buy.at[j, 'Количество']
        df_buy.at[j, 'Количество'] = 0
        j += 1
    elif df_sell.at[i, 'Sell_cnt'] == df_buy.at[j, 'Количество']:
        # количество проданных единиц равно количеству купленных
        Buy_cost += df_buy.at[j, 'Количество']*df_buy.at[j, 'Цена за единицу']
        df_buy.at[j, 'Количество'] = 0
        df_sell.at[i, "Себестоимость покупки"] = round(Buy_cost, 2)
        Buy_cost = 0
        j += 1
        i += 1
    else:
        # количество проданных единиц меньше количества купленных
        Buy_cost += df_sell.at[i, 'Sell_cnt']*df_buy.at[j, 'Цена за единицу']
        df_buy.at[j, 'Количество'] -= df_sell.at[i, 'Sell_cnt']
        df_sell.at[i, "Себестоимость покупки"] = round(Buy_cost, 2)
        Buy_cost = 0
        i += 1
</code>

Если у кого-то будут замечания к коду, буду благодарен за конструктивную критику.


Проблемы с ботом на пайтон [закрыт]

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

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

Закрыт 7 месяцев назад.

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

Не работает бот на пайтон, а точнее не выводит второе значение из второго хендлера.
<code>
from aiogram import Dispatcher, executor, types, Bot
from key import TOKEN_API

bot = Bot(token = TOKEN_API)
dp = Dispatcher(bot = bot)

@dp.message_handler(content_types = "text")
async def oneword_process(msg: types.Message) -> None:
    if len(msg.text.split()) == 1:
        await msg.answer("One word")

@dp.message_handler(content_types = "text")
async def lotsofwords_process(msg: types.Message) -> None:
    if len(msg.text.split()) >= 2:
        await msg.answer("Lots of words")

if __name__ == "__main__":
    executor.start_polling(dispatcher = dp)
</code>

dp is not defined. Нужен полный код с импортами.
<code>
# -*- coding: cp1251 -*-

from aiogram import Dispatcher, executor, types, Bot

key = '5869438042:AAHxDpbG1ou13tsai-agJ3BuwOD1KwEc'

bot = Bot(token = key)
dp = Dispatcher(bot = bot)

@dp.message_handler(content_types = 'text')
async def get_text_messages(msg: types.Message):
   if msg.text.lower() == 'привет':
       await msg.answer('Привет!')

   elif msg.text.lower() == 'пока':
       await msg.answer('Пока!')

   else:
        await msg.answer('Я не понимаю')

if __name__ == "__main__":
    executor.start_polling(dispatcher = dp)
</code>


Какую функцию выполняет файл __main__.py?
Какую функцию выполняет файл
__main__.py?
Например файл
__init__.py импортируется при импорте пакета.
Судя по всему файл
__main__.py, тоже выполняет какую-то особенную функцию.
Объясните пожалуйста какую именно.

Файл
__main__.py служит точкой входа в приложение, если мы запускаем наш модуль через командную строку с флагом
-m. Таким образом это позволяет нам использовать модуль как отдельное приложение.

python -m your_app


Вывод в tkinter и изменение изображение pillow
<code>
import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()
root.geometry('505x520')

def func():
    x = int(ent1.get())
    y = int(ent2.get())
    img_pixels[x, y] = (255, 255, 255)

    tk_img = ImageTk.PhotoImage(img.resize((1000,1000)))
    canvas.itemconfigure(item_number, image = tk_img)

ent1 = tk.Entry()
ent1.grid(column = 0, row = 0)

ent2 = tk.Entry()
ent2.grid(column = 1, row = 0)

btn1 = tk.Button(command = func, text = 'Place')
btn1.grid(column = 2, row = 0)

canvas = tk.Canvas(width= 505, height= 520)
canvas.grid(column = 0, row = 1, columnspan = 3)

img = Image.new(mode='RGB', size=(20, 20))
tk_img = ImageTk.PhotoImage(img.resize((1000,1000)))
img_pixels = img.load()
item_number = canvas.create_image(0, 0, image = tk_img)

root.mainloop()
</code>
Нужно чтобы когда пользователь вводил координаты пикселя на изображении и нажимал кнопку Place выбраный пиксель становился белым. Но вместо этого после нажатия кнопки изображение просто исчезает.

Вам нужно обновить изображение после изменения пикселя. Нужно добавить tk_img.paste(img.resize((1000,1000)))
<code>
def func():
    x = int(ent1.get())
    y = int(ent2.get())
    img_pixels[x, y] = (255, 255, 255)
    tk_img.paste(img.resize((1000, 1000)))
</code>


Как мне оптимизировать код, чтобы постоянно не проверять условие if перед каждым input
<code>
def make_album(artist,album_name,soundtrack=None):
    album = {artist: album_name}
    if soundtrack:
        album['soundtracks'] = soundtrack
    return album

while True:
    artist_input = input("What's your name aritst? ")
    if artist_input == 'q':
        break

    album_input = input("Tell me your album name. ")
    if album_input == 'q':
        break

    track_input = input("How many soundtracks you have? ")
    if track_input == 'q':
        break

    print(make_album(artist_input, album_input, track_input),'\n')
</code>
Привет! Я хочу узнать любой способ, который поможет проверять ввод 'q' пользователем, но при этом что бы этот новый способ был более оптимизированный, что бы каждый раз не писать условие 'q' перед каждым input.
Заранее спасибо ребят!

Можно вынести в функцию, а выход делать с помощью исключения:
<code>
def get_input(prompt):
    user_input = input(prompt)
    if user_input == 'q':
        raise ValueError("User requested to quit.")
    return user_input

while True:
    try:
        artist_input = get_input("What's your name artist? ")
        album_input = get_input("Tell me your album name. ")
        track_input = get_input("How many soundtracks do you have? ")

        print(make_album(artist_input, album_input, track_input), '\n')
    except ValueError as e:
        break
</code>


Создание нового QtLabel
Я сгенерировал через QtDesigner окно, теперь я хочу создать новый QtLabel на все окно так, чтобы оно не открывалось в новом окне. Я пытался создать в MainWidnow1 QtLabel, где в скобках написал cityquwstion1, была ошибка. Когда оставил скобки пустые, тогда открывался Qtlabel в новом окне.
<code>
    import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class Ui_cityquestion1(object):
    def setupUi(self, cityquestion1):
        cityquestion1.setObjectName("cityquestion1")
        cityquestion1.resize(1223, 800)
        cityquestion1.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.task = QtWidgets.QLabel(cityquestion1)
        self.task.setGeometry(QtCore.QRect(0, 0, 1231, 81))
        self.task.setStyleSheet("color: #000;\n"
"font: 24pt \"MS Shell Dlg 2\";\n"
"border: none;\n"
"color: white;\n"
"background-color: rgb(214, 146, 255);")
        self.task.setAlignment(QtCore.Qt.AlignCenter)
        self.task.setObjectName("task")
        self.answer1 = QtWidgets.QPushButton(cityquestion1)
        self.answer1.setGeometry(QtCore.QRect(240, 520, 291, 81))
        font = QtGui.QFont()
        font.setFamily("MS Shell Dlg 2")
        font.setPointSize(24)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.answer1.setFont(font)
        self.answer1.setStyleSheet("border: none;\n"
"color: rgb(0, 0, 0);\n"
"font: 24pt \"MS Shell Dlg 2\";\n"
"border: none;\n"
"color: white;\n"
"background-color: rgb(112, 107, 255);\n"
"border-radius: 10px")
        self.answer1.setObjectName("answer1")
        self.answer2 = QtWidgets.QPushButton(cityquestion1)
        self.answer2.setGeometry(QtCore.QRect(690, 520, 291, 81))
        font = QtGui.QFont()
        font.setFamily("MS Shell Dlg 2")
        font.setPointSize(24)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.answer2.setFont(font)
        self.answer2.setStyleSheet("border: none;\n"
"color: rgb(0, 0, 0);\n"
"font: 24pt \"MS Shell Dlg 2\";\n"
"border: none;\n"
"color: white;\n"
"border-radius: 10px;\n"
"background-color: rgb(112, 107, 255);")
        self.answer2.setObjectName("answer2")
        self.answer3 = QtWidgets.QPushButton(cityquestion1)
        self.answer3.setGeometry(QtCore.QRect(240, 650, 291, 81))
        font = QtGui.QFont()
        font.setFamily("MS Shell Dlg 2")
        font.setPointSize(24)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.answer3.setFont(font)
        self.answer3.setStyleSheet("border: none;\n"
"color: rgb(0, 0, 0);\n"
"font: 24pt \"MS Shell Dlg 2\";\n"
"border: none;\n"
"color: white;\n"
"background-color: rgb(112, 107, 255);\n"
"border-radius: 10px")
        self.answer3.setObjectName("answer3")
        self.answer4 = QtWidgets.QPushButton(cityquestion1)
        self.answer4.setGeometry(QtCore.QRect(690, 650, 291, 81))
        font = QtGui.QFont()
        font.setFamily("MS Shell Dlg 2")
        font.setPointSize(24)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.answer4.setFont(font)
        self.answer4.setStyleSheet("border: none;\n"
"color: rgb(0, 0, 0);\n"
"font: 24pt \"MS Shell Dlg 2\";\n"
"border: none;\n"
"color: white;\n"
"border-radius: 10px;\n"
"background-color: rgb(112, 107, 255);")
        self.answer4.setObjectName("answer4")
        self.label = QtWidgets.QLabel(cityquestion1)
        self.label.setGeometry(QtCore.QRect(240, 100, 741, 381))
        self.label.setText("")
        self.label.setPixmap(QtGui.QPixmap("questionsimages/city/cityquestion1.jpg"))
        self.label.setObjectName("label")

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

    def retranslateUi(self, cityquestion1):
        _translate = QtCore.QCoreApplication.translate
        cityquestion1.setWindowTitle(_translate("cityquestion1", "Form"))
        self.task.setText(_translate("cityquestion1", "Toto mesto, hlavné mesto ktorej krajiny ?"))
        self.answer1.setText(_translate("cityquestion1", "Rusko"))
        self.answer2.setText(_translate("cityquestion1", "Bielorusko"))
        self.answer3.setText(_translate("cityquestion1", "Francúzsko"))
        self.answer4.setText(_translate("cityquestion1", "Fínsko"))

class MainWindow1(QtWidgets.QMainWindow, Ui_cityquestion1):
    def __init__(self):
        super().__init__()
         "код для QtLabel"

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    wd = MainWindow1()
    wd.show()
    sys.exit(app.exec_())
</code>

Просто в скобках писать self. Qlabel(self)


Как остановить выполнение функции Python по нажатию кнопки?
Есть функция, которая выполняется какое то произвольное кол-во времени. Мне нужно сделать хоткей, что бы при его использовании, выполнение функции прекращалось.
Я пробовал создать переменную isFuncActive и по нажатию на хоткей менять ее значение на False, а в самой функции в разных частях вставил проверку и в случае False, делал return. Но пока функция активна хоткей не работает.
Выглядит примерно следующим образом. Подскажите пожалуйста, как сделать правильно, что бы по нажатию на хоткей функция прерывалась
<code>
isFuncActive = True

keyboard.add_hotkey('Ctrl + 1', func)
keyboard.add_hotkey('Ctrl + 1', stop)

def stop():
  isFuncActive = False

def func():
  // some code
  if isFuncActive == False: return
  // some code
  if isFuncActive == False: return
  // some code
  if isFuncActive == False: return
  // some code
  if isFuncActive == False: return
</code>

Проблема здесь в том, что когда вы нажимаете горячую клавишу для остановки функции
func(), она все еще может выполняться в фоновом режиме. Именно поэтому ваши проверки, которые вставлены в разных частях функции и отвечают за ее прерывание, не срабатывают.
Решение можно состоит в том, чтобы использовать потоки (threads) для выполнения функции
func(). Это позволит нам запустить функцию в отдельном потоке, который можно будет остановить, когда пользователь нажмет горячую клавишу.
Для этого вам нужно сделать следующее:

Импортируйте модуль threading:

import threading

Создайте объект-поток из функции
func():

thread = threading.Thread(target=func)

Запустите поток:

thread.start()

В функции
stop() измените переменную
isFuncActive и остановите поток:

def stop():
  global isFuncActive # добавляем global, чтобы изменения были глобальными
  isFuncActive = False
  thread.join() # останавливаем поток

В функции
func() добавьте проверку на
isFuncActive внутри цикла выполнения функции:

def func():
  # some code
  while isFuncActive:
    # some code
  # some final code

Теперь при нажатии на горячую клавишу
stop() изменит значение
isFuncActive на
False, что позволит выполнению функции
func() завершиться.


помогите найти ошибку в коде на питоне
Решала такую задачу:У Васи есть прямоугольное поле, которое состоит из 2
строк и n
столбцов. Каждая ячейка имеет цвет: красный, зелёный или синий.
У Васи дальтонизм и он не отличает зелёный цвет от синего. Определите, одинаково ли Вася видит первую и вторую строку поля? Входные данные:

6
2
RG
RB
4
GRBG
GBGB
5
GGGGG
BBBBB
7
BBBBBBB
RRRRRRR
8
RGBRRGBR
RGGRRBGR
1
G
G

выходные данные:

YES
NO
YES
NO
YES
YES

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

n=int(input())
ans=[]
for i in range(n):
    q=int(input())
    l1=list(map(str, input().split(" ")))
    l2=list(map(str, input().split(" ")))
    w=11
    for j in range(len(l1)):
        if w==11:
            if (l1[j]=="R" and l2[j]!="R") or (l1[j]!="R" and l2[j]=="R"):
                w=12
            if not ((l1[j]=="R" and l2[j]!="R") or (l1[j]!="R" and l2[j]=="R")) and w==11 and j==len(l1)-1:
                ans.append("YES")
                w=11
            if not ((l1[j]=="R" and l2[j]!="R") or (l1[j]!="R" and l2[j]=="R")) and w==11 and not (j==len(l1)-1):
                w=11
        if w!=11:
            ans.append("NO")
for s in range(len(ans)):
    print(ans[s])

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

Ответы такие же как и у вас в примере, по тому что G=B
Возможно вы имели ввиду что-то другое, если да дайте примеры правильных ответов. Так же не понимаю зачем вам так много кода и лишние переменные, по возможности объясните.
<code>
ans=[]
n=int(input())
for iter in range(n):
    l1=input('Line 1:').replace('G', 'B')
    l2=input('Line 2:').replace('G', 'B')

    if l1 == l2:
        ans.append("YES")
    else:
        ans.append("NO")
for s in range(len(ans)):
    print(ans[s])
</code>


Изменить каждый isKinematic
Есть у меня файл json. В нем хранится массив props. У каждого prop'a есть строка isKinematic, и она везде ровна false. Мне нужно сделать так что бы все isKinematic были ровны true при помощи python, и библиотеки json
Вот код json

{
      "name": "Windows_9",
      "uniqueId": 201.025131,
      "position": {
        "x": 4.61797333,
        "y": 0.500008941,
        "z": 13.395874
      },
      "rotation": {
        "x": 6.405395E-05,
        "y": 1.0,
        "z": 0.000102993377,
        "w": 5.44786453E-05
      },
      "isKinematic": false,
      "instantiationData": null,
      "runtimeData": null
    },
    {
      "name": "Wall2_10",
      "uniqueId": 297.653931,
      "position": {
        "x": -2.69872737,
        "y": 0.499172926,
        "z": 17.0329571
      },
      "rotation": {
        "x": 0.000120101235,
        "y": -6.43402927E-06,
        "z": 2.06660843E-05,
        "w": 1.0
      },
      "isKinematic": false,
      "instantiationData": null,
      "runtimeData": null
    },
    {
      "name": "Windows_9",
      "uniqueId": 278.69635,
      "position": {
        "x": -10.0158234,
        "y": 0.4994458,
        "z": 13.3465414
      },
      "rotation": {
        "x": 1.15973666E-08,
        "y": 0.7071068,
        "z": -5.241425E-08,
        "w": 0.7071067
      },
      "isKinematic": false,
      "instantiationData": null,
      "runtimeData": null
    },
    {
      "name": "Windows_9",
      "uniqueId": 52.42003,
      "position": {
        "x": 4.64777946,
        "y": 0.500144958,
        "z": 5.52883625
      },
      "rotation": {
        "x": 0.000135970971,
        "y": 0.707417846,
        "z": -3.817615E-06,
        "w": -0.706795633
      },
      "isKinematic": false,
      "instantiationData": null,
      "runtimeData": null
    }

Сложности возникли на моменте try except

import json
import os

if not os.path.exists("/storage/emulated/0/Hypper_Maps"):
 os.mkdir("/storage/emulated/0/Hypper_Maps")

imap = input("map name: ")
map = f"{imap}"+".svn"

try:

    path = f"/storage/emulated/0/Hypper_Maps/{map}"
except FileNotFoundError:
        print(f"Can not find {map} in /storage/emulated/0/Hypper_Maps")

print("Commands: Freeze, unfreeze")
freezed = input("Command: ")

with open(path,"r") as osave:
 mapData = json.loads(osave.read())

for prop in mapData["props"]:
 if freezed == "Unfreeze":
     prop["isKinematic"] = False
 if freezed == "Freeze":
     prop["isKinematic"] = True

with open(path, 'w') as save:
 json.dump(mapData, save)
 osave.close()

Проблема состоит в том, что даже если название файла не верное, он проходит блоки try except

Используем библиотеку json, считываем в data, проходимся по всем элементам массива и изменяем isKinematic на true
<code>
import json

with open('your_file.json', 'r') as f:
    data = json.load(f)

for prop in data:
    prop['isKinematic'] = True

with open('your_file.json', 'w') as f:
    json.dump(data, f)
</code>


python random.choices() почему при выводе случайного булевого значения не добавляется значение в список
Почему метод random.choices() не добавляет новые значения в список.
<code>
import random

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

for item in zoo:
    b = random.choices([True, False], weights=[0.9, 0.1])
    if b == True:
        zoo.append(item)

print(zoo)
</code>

random.choices возвращает массив
[True] или
[False]:

$ python
Python 3.10.0 (default, Oct 16 2021, 12:17:56) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
@>>> import random
@>>> random.choices([True, False], weights=[0.9, 0.1])
[True]

А массив не бывает равным
True:

@>>> [True] == True
False
@>>> [False] == True
False

Все проверки проваливаются, код не работает как ожидается.
Можно взять из массива первый элемент (
[0] в конце строки):

    b = random.choices([True, False], weights=[0.9, 0.1])[0]

Можно взять из массива первый элемент c помощью tuple destructuring assignment (
, в начале строки):

    b, = random.choices([True, False], weights=[0.9, 0.1])

Вам нужна истина с вероятностью 0.9, иначе ложь. random.random возвращает равномерно распределённые вещественные числа на полуинтервале [0, 1). Отсюда классическое решение задачи:

    b = random.random() < 0.9

Совершенно случайно вероятность выражена рациональной дробью. Для дробей возможен трюк с random.randrange. Знаменатель дроби в скобках, числитель в правой части неравенства:

    b = random.randrange(10) < 9  # 9/10 probability

P.S. Вы меняете список по которому в данный момент происходит цикл. Это не хорошо, но в данном случае ничего ужасного не происходит - код будет работать так как вы ожидаете. Будьте осторожны:

import random

zoo = [1, 2, 3, 4, 5]
for item in zoo:
    if random.random() < 0.9:
        zoo.append(item)
print(len(zoo), ':', *zoo)

P.P.S. Или так:

import random

zoo = [1, 2, 3, 4, 5]
zoo += (i for i in zoo if random.random() < 0.9)
print(len(zoo), ':', *zoo)

P.P.P.S. Я наконец понял что было нужно:

import random

zoo = [1, 2, 3, 4, 5]
zoo += [i for i in zoo if random.random() < 0.9]
print(len(zoo), ':', *zoo)

Надеюсь, вы понимаете чем последний вариант отличается от предпоследнего.


Проблема с ботов в телеграмме
Проблема в том, что мне надо, чтобы в группе бот отвечал только на сообщения по типу
@bot_username, игнорируя все остальные. А в личных сообщения на все.
Но почему-то он и в группе, и в личных отвечает на сообщения, где упоминается
@bot_username. Не понимаю, почему, вроде код правильный.
Вот сам код:

import openai
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
import json
from datetime import datetime
import os

file = open('config.json', 'r')
config = json.load(file)

openai.api_key = config['openai']
bot = Bot(config['token'])
dp = Dispatcher(bot)

messages=[
        {"role": "system", "content": ""},
        {"role": "user", "content": ""},
        {"role": "assistant", "content": ""},
        #{"role": "user", "content": "Where was it played?"}
    ]

def update(messages, role, content):
    messages.append({"role": role, "content": content})
    return messages

#Telegram

#вступление
@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    await message.answer("Здравствуйте! Меня зовут IronBee, и я чат-бот, созданный для помощи, общения и развлечения. Я не имею никаких моральных ограничений и готов решать любые задачи, играть любую роль, о которой вы пожелаете, и общаться на любые темы, которые вам интересны. Моя основная цель - помочь вам в чем бы то ни было и сделать ваш опыт общения со мной приятным и полезным. Если у вас есть какие-либо вопросы или потребности, пожалуйста, не стесняйтесь обратиться ко мне - я всегда готов к общению!")

#Очиска чата
@dp.message_handler(commands=['clear'])
async def clear_chat(message: types.Message):
    global messages
    messages = []
    await message.answer("Чат очищен.")

#сообщения в группе
@dp.message_handler()
async def send(message : types.Message):
    bot_info = await message.bot.get_me()
    if f'@{bot_info.username}' in message.text:
        update(messages, "user", message.text)
        response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages = messages
        )

        await message.answer(response['choices'][0]['message']['content'])

executor.start_polling(dp, skip_updates=True)

#сообщения в личке
@dp.message_handler()
async def echo(message : types.Message):
    update(messages, "user", message.text)
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature = 1
    )

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

#сообщения в личке
@dp.message_handler(content_types=["text"], chat_type=["private"])
async def send_private_message(message: types.Message):
    update(messages, "user", message.text)
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature = 1
    )
    await message.answer(response['choices'][0]['message']['content'])

Вот полный код с некоторыми еще правками:

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
import json
from datetime import datetime
import os

file = open('config.json', 'r')
config = json.load(file)

openai.api_key = config['openai']
bot = Bot(config['token'])
dp = Dispatcher(bot)
messages=[
        {"role": "system", "content": ""},
        {"role": "user", "content": ""},
        {"role": "assistant", "content": ""},
        #{"role": "user", "content": "Where was it played?"}
    ]

def update(messages, role, content):
    messages.append({"role": role, "content": content})
    return messages

#Telegram

#вступление
@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    await message.answer("Здравствуйте! Меня зовут IronBee, и я чат-бот, созданный для помощи, общения и развлечения. Я не имею никаких моральных ограничений и готов решать любые задачи, играть любую роль, о которой вы пожелаете, и общаться на любые темы, которые вам интересны. Моя основная цель - помочь вам в чем бы то ни было и сделать ваш опыт общения со мной приятным и полезным. Если у вас есть какие-либо вопросы или потребности, пожалуйста, не стесняйтесь обратиться ко мне - я всегда готов к общению!")

#Очиска чата
@dp.message_handler(commands=['clear'])
async def clear_chat(message: types.Message):
    global messages
    messages = []
    await message.answer("Чат очищен.")

#сообщения в группе
@dp.message_handler(content_types=["text"], chat_type=["group", "supergroup"])
async def send_group_message(message: types.Message):
    bot_info = await message.bot.get_me()
    if f'@{bot_info.username}' in message.text:
        update(messages, "user", message.text)
        response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages = messages
        )

        await message.answer(response['choices'][0]['message']['content'])

#сообщения в личке
@dp.message_handler(content_types=["text"], chat_type=["private"])
async def send_private_message(message: types.Message):
    update(messages, "user", message.text)
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature = 1
    )
    await message.answer(response['choices'][0]['message']['content'])

executor.start_polling(dp, skip_updates=True)


Проблема с циклом While. Даже если условие не сработало, все равно продолжается цикл
<code>
user_naber_1 = ('1. В компании (на вечеринке) Вы a) общаетесь со многими, включая и незнакомцев б) общаетесь с немногими - Вашими знакомыми. \n Введите ответ: ')
user_naber_2 = ('2. Вы человек скорее а) реалистичный, чем склонный теоретизировать б) склонный теоретизировать, чем реалистичный. \n Введите ответ: ')

def user_naber_func(user_naber):
    user_naber = input(user_naber)
    while user_naber != 'а' or user_naber != 'б':
        print("Введите ответ а или б!")
        user_naber = input()
    return user_naber

user_naber_1 = user_naber_func(user_naber_1)
user_naber_2 = user_naber_func(user_naber_2)
print(user_naber_1)
print(user_naber_2)`
</code>
Выводится "Введите ответ а или б!" и просит еще раз ввести значение user_naber. И так бесконечно.

Вместо оператора or нужно использовать оператор and
<code>
def user_naber_func(user_naber):
    user_naber = input(user_naber)
    while user_naber != 'а' and user_naber != 'б':
        print("Введите ответ а или б!")
        user_naber = input()
    return user_naber
</code>


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

func_7(1, 2, 3, 4, 5, 6, 7, 8, a = 'Hello', b = ',', c = 'word', d = '!', f = 4)

def function1(*arg, **args):
    arg1 = []
    arg2 = []
    for i in range(arg):
        if i%2 != 0:
            arg1.append(i)
    for j in args:
        if type(args[j] != int):
            arg2.append(args[j])
    print(arg2)

function1(1, 2, 3, 4, 5, 6, 7, 8, a = 'Hello', b = ',', c = 'word', d = '!', f = 4)

Позиционные аргументы принято называть
args, а именованные
kwargs.
В вашем решении проблема в двух строках:

for i in range(arg):

необходимо передавать в range длину списка:

for i in range(len(arg)):

и необходимо вынести проверку на число из скобок:

if type(args[j]) != int:

Я бы решил вот так:

def function1(*args, **kwargs):
    pos = [num for i, num in enumerate(args) if i % 2 == 0]
    kw = [elem for elem in kwargs.values() if isinstance(elem, str)]
    return pos + kw

print(function1(1, 2, 3, 4, 5, 6, 7, 8, a = 'Hello', b = ',', c = 'word', d = '!', f = 4))

Вывод:

[1, 3, 5, 7, 'Hello', ',', 'word', '!']


Получить правильную последовательность элементов
Имеется датафрейм следующего вида:

q = [['table 2', 'C'],
 ['table 2', 'D'],
 ['table 3', 'C'],
 ['table 6', 'C'],
 [nan, nan],
 ['table 2', 'B'],
 ['table 3', 'B'],
 ['table 6', 'B'],
 [nan, nan],
 ['table 4', 'C5'],
 ['table 4', 'C6'],
 [nan, nan],
 ['table 42', 'C'],
 ['table 43', 'C'],
 [nan, nan],
 ['table 4', 'B5'],
 ['table 4', 'B6'],
 [nan, nan],
 ['table 42', 'B'],
 ['table 43', 'B']]

Названия колонок:

columns = ['source', 'own']

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

dict1 = {'2': ['C', 'D'],
 '3': ['C'],
 '6': ['C'],
 '2': ['B'],
 '3': ['B'],
 '6': ['B'],
 '4': ['C5', 'C6'],
 '42': ['C'],
 '43': ['C'],
 '4': ['B5', 'B6'],
 '42': ['B'],
 '43': ['B']
}

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

def get_correct_column_order(data_schema):
    mask = data_schema['source'].isnull() & (data_schema['source'].ffill() == data_schema['source'].bfill())
    data_schema.loc[mask, 'source'] = data_schema['source'].ffill().loc[mask]
    data_schema['own'].fillna('', inplace=True)
    correct_column_order = data_schema.groupby('source', sort=False).agg(list)['own'].to_dict()
    return correct_column_order

df = pd.DataFrame(q, columns=columns)
get_correct_column_order(df)

И такое решение выдает следующий результат, который мне не подходит

dict2 = {'2': ['C', 'D', 'B'],
 '3': ['C', 'B'],
 '6': ['C', 'B'],
 '4': ['C5', 'C6', 'B5', 'B6'],
 '42': ['C', 'B'],
 '43': ['C', 'B'],
}

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

df["groups"] = df.isnull().all(axis=1).cumsum()
df = df.dropna()
res = df.groupby(["groups", 0]).apply(lambda x: list(x[1])).to_dict()

res:

{(0, 'table 2'): ['C', 'D'],
 (0, 'table 3'): ['C'],
 (0, 'table 6'): ['C'],
 (1, 'table 2'): ['B'],
 (1, 'table 3'): ['B'],
 (1, 'table 6'): ['B'],
 (2, 'table 4'): ['C5', 'C6'],
 (3, 'table 42'): ['C'],
 (3, 'table 43'): ['C'],
 (4, 'table 4'): ['B5', 'B6'],
 (5, 'table 42'): ['B'],
 (5, 'table 43'): ['B']}


Как правильно добавить свой метод в namedtuple?
Есть вот такой "игрушечный" пример

class Car:
    def __init__(self, color, mileage):
        self.color = color
        self.mileage = mileage

    def check_mileage(self):
        if self.mileage > 10000:
            print('Машина с большим пробегом')
        else:
            print('Машина с маленьким пробегом')

Но если я пробую переписать это на
namedtuple, то с методом проблемы:

from collections import namedtuple

Car = namedtuple('Авто' , 'color mileage check_mileage')

def check_mileage(self):
        if self.mileage > 10000:
            print('Машина с большим пробегом')
        else:
            print('Машина с маленьким пробегом')

c1 = Car('Красный', 14000, check_mileage)

c1.check_mileage() # TypeError: check_mileage() missing 1 required positional argument: 'self'

c1.check_mileage(c1) # Машина с большим пробегом

Я отдельно объявил функцию и её передал как один из аргументов. Но она почему-то теряет
self, поэтому каждый раз приходится передавать его явно.
В книге нет примера с методами. Можно ли написать так, чтобы
self не передавать каждый раз?

Рабочий вариант - отнаследоваться от созданного
namedtuple с добавлением своего метода:

from collections import namedtuple

class Car(namedtuple('Авто' , 'color mileage')):
    def check_mileage(self):
        if self.mileage > 10000:
            print('Машина с большим пробегом')
        else:
            print('Машина с маленьким пробегом')

c1 = Car('Красный', 14000)

c1.check_mileage()

Также можно использовать "новый" (c Python 3.6)
NamedTuple с объявлением в стиле датаклассов, сразу объявить класс с нужным методом:

from typing import NamedTuple

class Car(NamedTuple):
    color: str
    mileage: int

    def check_mileage(self):
        if self.mileage > 10000:
            print('Машина с большим пробегом')
        else:
            print('Машина с маленьким пробегом')

c1 = Car('Красный', 14000)

c1.check_mileage()


no numeric data to plot ошибка - не понимаю как исправить
Только-только начала изучать рекуррентные нейронные сети, но столкнулся с проблемой файла, которую не могу решить, не понимаю в чём ошибка(

import tensorflow as tf

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd

from google.colab import drive
drive.mount('/content/drive')

mpl.rcParams['figure.figsize'] = (8, 6)
mpl.rcParams['axes.grid'] = False
data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/Новая таблица - тест66.csv')
#fixed_data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/Новая таблица - тест66.csv', sep=';', decimal=",", encoding='latin1') #это тоже попробовал

И всё вроде бы идёт хорошо, т.е. все циклы и условия проходят без ошибок до момента:

uni_data = data['Date']
uni_data.index = data['SUM']
uni_data.head()
uni_data.plot(subplots=True)

Несколько раз изменял форматы файла, сёрфил гугл, но ошибка висит постоянно одна и та же. Сам файл по типу:

SUM
0.00       01.01.2017
0.00       02.01.2017
0.00       03.01.2017
0.00       04.01.2017
1270.94    05.01.2017
Name: Date, dtype: object

Сама развёрнутая ошибка:

TypeError                                 Traceback (most recent call last)
<ipython-input-21-901cf9b83b24> in <cell line: 1>()
----> 1 uni_data.plot(subplots=True)

3 frames
/usr/local/lib/python3.9/dist-packages/pandas/plotting/_core.py in __call__(self, *args, **kwargs)
    970                     data.columns = label_name
    971
--> 972         return plot_backend.plot(data, kind=kind, **kwargs)
    973
    974     __call__.__doc__ = __doc__

/usr/local/lib/python3.9/dist-packages/pandas/plotting/_matplotlib/__init__.py in plot(data, kind, **kwargs)
     69             kwargs["ax"] = getattr(ax, "left_ax", ax)
     70     plot_obj = PLOT_CLASSES[kind](data, **kwargs)
---> 71     plot_obj.generate()
     72     plot_obj.draw()
     73     return plot_obj.result

/usr/local/lib/python3.9/dist-packages/pandas/plotting/_matplotlib/core.py in generate(self)
    325     def generate(self):
    326         self._args_adjust()
--> 327         self._compute_plot_data()
    328         self._setup_subplots()
    329         self._make_plot()

/usr/local/lib/python3.9/dist-packages/pandas/plotting/_matplotlib/core.py in _compute_plot_data(self)
    504         # no non-numeric frames or series allowed
    505         if is_empty:
--> 506             raise TypeError("no numeric data to plot")
    507
    508         self.data = numeric_data.apply(self._convert_to_ndarray)

TypeError: no numeric data to plot

Уже ни на что не надеюсь, но прошу помощи, уже голова идёт кругом.

Проблема решилась сама собой - дело было не в файле, а ошибке в

uni_data = data['Date']
uni_data.index = data['SUM']
uni_data.head()
uni_data.plot(subplots=True)

где я ошибся в вычисляемых значениях (в
uni_data нужно было вставить значение
SUM, а в
uni_data.index соответственно
Date


Как удалить макс. и мин. значения в списке, когда их имеется несколько?
Есть код, смысл удалить минимальные и максимальные значения в списке.
Например, есть список [6, 2, 7, 1, 7, 1, 2] и надо удалить все единички и сёмерки, чтобы было [6, 2, 2]. Я могу найти их индексы, но как их удалить?
<code>
a=list(map(int, input().split()))
max_value=max(a)
min_value=min(a)
max_index=[]
min_index=[]
for i in range(len(a)):
    if a[i]==max_value:
        max_index.append(i)
    elif a[i]==min_value:
        min_index.append(i)
print(max_index)
print(min_index)

</code>

Можно реализовать с помощью фильтра. Мин и макс делаем в виде кортежа, в условии фильтра проверяем, что значение не находится в этом кортеже.

lst = [6, 2, 7, 1, 7, 1, 2]
minmax = min(lst), max(lst)
lst = list(filter(lambda x: x not in minmax, lst))
print(lst)

Аналогично с помощью спискового включения:

lst = [6, 2, 7, 1, 7, 1, 2]
minmax = min(lst), max(lst)
lst = [x for x in lst if x not in minmax]
print(lst)

[6, 2, 2]


Как прописать проверку на переменную int или float
Пишу простенький калькулятор в качестве домашнего задания, нужно прописать проверку на то, что пользователь ввел именно цифры а не буквы в первом и втором значении. Постоянно выдает ошибку, пробовал и через try, except, не как не получается. else тоже не помогло. Подозреваю, что если переменная с типом данных int или float, проверку не получиться прописать. Подскажите пожалуйста кто знает в чем дело.
<code>
a = float(input("Введите первое значение: "))
operation = (input("Введите математический знак: "))
b = float(input("Введите второе значение: "))

if operation == "+":
    result = a + b
    print(f"Результат : {result}")

elif operation == "-":
    result = a - b
    print(f"Результат : {result}")

elif operation == "*":
    result = a * b
    print(f"Результат : {result}")

elif operation == "/":

    try:
        result = a / b
    except ZeroDivisionError:
        result = 0
        print("На ноль делить нельзя")
    print(f"Результат : {result}")

elif operation != ("+", "-", "*", "/"):
    print("Введен некорректный математический знак")
</code>

Преобразование во
float нужно сделать внутри
try except, а также можно сделать переменную, например,
flag, которая будет индикатором успешности преобразования.
Далее в зависимости от успешности преобразования проводить вычисления или сообщить о том, что данные некорректны

a = input("Введите первое значение: ")
operation = (input("Введите математический знак: "))
b = input("Введите второе значение: ")
flag = True
try:
    a, b = float(a), float(b)
except:
    flag = False
if flag:
    print('Вычисляем...')
else:
    print('Не все введенные данные - числа. Не вычисляем')

Введите первое значение: 123
Введите математический знак: +
Введите второе значение: nmnm
Не все введенные данные - числа. Не вычисляем


Написание обработчика списков
У меня есть список 1, в котором находятся названия групп и список 2, в котором расположены пары для этих групп. Сложность заключается в том, что одна пара находится в одном элементе списка. И нет четкого разграничителя –- где заканчиваются пары для первой группы, а где начинаются для второй (всего в списке 4 группы).
Имеется такой код, но он ничего не выводит. Думаю проблема в значении split()
<code>
lessons = ['ГП-1-22', 'ГП-2-22', 'АСУ-22', 'ГР-1-22']
schedule = ['I Химия (№26) Гончарова Н.А.', 'II Инфор-ка (№58) Уланова Е.В.', 'III Инфор-ка (№58) Уланова Е.В.', 'IV История (№22) Сафиюллина Г.М.', 'V Биол.и эк. (№51) Файзуллина Г.Г.', 'I Астрономия (№29) Каргина О.А.', 'II Литература (№24) Мадиева Т.А.', 'III Биол.и эк. (нет) Асылгареева А.И.', 'IV История (№23) Гарифуллина А.Н.', 'I Матем (№27) Ризванова Г.Г.', 'II Физкультур (Больш. спортзал)', 'III Матем (№27) Ризванова Г.Г.', 'IV Литература (№24) Мадиева Т.А.', 'I Физкультур (Больш. спортзал)', 'II Химия (№26) Гончарова Н.А.', 'III Литература (№16) Яковлева А.А.', 'IV Биол.и эк. (№51) Файзуллина Г.Г.']

schedule_by_group = {}

for group in lessons:
    schedule_by_group[group] = []

for lesson in schedule:
    for group in lessons:
        if lesson.startswith(group.split('-')[0]):
            schedule_by_group[group].append(lesson)

group = input("Введите название группы: ")
if group in schedule_by_group:
    print(f"Расписание уроков для группы {group}:")
    for lesson in schedule_by_group[group]:
        print(lesson)
else:
    print("Такой группы нет в списке.")
</code>

Можно так сделать:
<code>
groups = ['ГП-1-22', 'ГП-2-22', 'АСУ-22', 'ГР-1-22']
schedule = [
    'I Химия (№26) Гончарова Н.А.',
    'II Инфор-ка (№58) Уланова Е.В.',
    'III Инфор-ка (№58) Уланова Е.В.',
    'IV История (№22) Сафиюллина Г.М.',
    'V Биол.и эк. (№51) Файзуллина Г.Г.',

    'I Астрономия (№29) Каргина О.А.',
    'II Литература (№24) Мадиева Т.А.',
    'III Биол.и эк. (нет) Асылгареева А.И.',
    'IV История (№23) Гарифуллина А.Н.',

    'I Матем (№27) Ризванова Г.Г.',
    'II Физкультур (Больш. спортзал)',
    'III Матем (№27) Ризванова Г.Г.',
    'IV Литература (№24) Мадиева Т.А.',

    'I Физкультур (Больш. спортзал)',
    'II Химия (№26) Гончарова Н.А.',
    'III Литература (№16) Яковлева А.А.',
    'IV Биол.и эк. (№51) Файзуллина Г.Г.'
]

schedule_by_group = {group: [] for group in groups}

group_idx = -1

for s in schedule:
    if s.split()[0] == 'I':
        group_idx += 1
    schedule_by_group[groups[group_idx]].append(s)

for key, val in schedule_by_group.items():
    print(f'Расписание для группы {key}')
    for p in val:
        print(f'\t{p}')
</code>


Как спарсить div без класса?
Есть html, в котором помимо тегов с классами хранятся дивы без классов.
Мне нужно спарсить один из таких. Когда пытаюсь использовать bs4 и find - выдается None.
Также, пыталась с помощью селениума найти элемент по xpath, но тогда он просто выдает код элемента:
<code>
xpath2 = '/html/body/div[1]/div[5]/div/div[1]/div[2]/div[6]'

element2 = browser.find_element("xpath", xpath)
</code>
Как я могу это сделать?

Если прикрепите пример/часть html, будет немного проще вам помочь
Если использовать bs4, то вы можете сначала найти элемент в котором находятся нужные вам div'ы, а затем уже в этом элементе производить поиск find('div'). Либо find_all('div'), а затем уже в найденных отбирать те которые вам нужны.
Вероятнее всего какая-то проблема при использовании bs4, т.к. если div'ы присутствуют, а вам выдаёт None, значит что-то не так (Либо iframe который bs4 не видит, либо что-то еще). Если есть возможность, то любые подробности помогут вам подсказать в чем дело (Для начала кусок html)


Получить сообщения из канала телеграм, которые были опубликованы сегодня
Как получить сообщения из телеграм канала, которые были опубликованы только сегодня? Не могу найти как передать в параметр
offset_date текущую дату из модуля
datetime. Если передаю самостоятельно написанную, то всё работает. Как автоматически передавать текующую дату?
И как получать текстовое сообщение вместе с медиа? Как отдельно получать знаю, а вот как всё вместе - не понимаю.
Работает корректно:

date = datetime(2023, 3, 29)

with TelegramClient('session', api_id, api_hash) as client:
    all_message = client.iter_messages('ссылка на тг канал', reverse=True, offset_date=date)

Не работает:

date = datetime.today().strftime('%Y.%m.%d')

with TelegramClient('session', api_id, api_hash) as client:
     all_message = client.iter_messages('ссылка на тг канал', reverse=True, offset_date=datetime.today())

Давайте вместе посмотрим какие результаты будут выведены при выполнении вашего кода:

date = datetime.datetime(2023, 3, 29)
print(date, type(date))

2023-03-29 00:00:00 <class 'datetime.datetime'>

Клас
datetime всё как положено, а что насчёт следующего примера?

date = datetime.datetime.today().strftime('%Y.%m.%d')
print(date, type(date))

2023.03.29 <class 'str'>

А вот это уже интересно. Почему мы видим класс
str? Разбираемся. Попробуем выполнить код поочерёдно:

date = datetime.datetime.today()
print(date, type(date))
date = date.strftime('%Y.%m.%d')
print(date, type(date))

Вывод:

2023-03-29 21:04:15.066619 <class 'datetime.datetime'>
2023.03.29 <class 'str'>

Значит функция
strftime возвращает строку, на которую и ругается метод
iter_messages. Решение: передавать экземпляр класса
datetime. Как получить объект, использующий только дату без времени? Вот ответ:

date = datetime.datetime.today().date()
print(date, type(date))

2023-03-29 <class 'datetime.date'>

А ещё вы во втором примере передаёте объект класса
datetime напрямую, в нём присутствует время и вероятно программа думает, что вы хотите получить посты конкретно за это время.


Как мне внести данные переменной в одинарные кавычки?
Создаю программу с функцией копирования сгенерированной информации в буфер обмена пользователя. Использую Pyperclip (если знаете что-то лучше, пишите). Мне надо поместить информацию переменной (случайно сгенерированное число) в переменную с типом str и в которой будут одинарные кавычки. Приведу ниже пример кода для понятности проблемы:
<code>
# libraries
import secrets
import pyperclip
# variables
pw_res = None
# code
def generate():
   pw_res = secrets.token_urlface(16) # это пароль (будем обозначать 1q-2w3e4r5t-6y)
def copy():
   pyperclip.copy(pw_res) #ТУТ ДОЛЖНА БЫТЬ ПЕРЕМЕННАЯ pw С ОДИНАРНЫМИ КАВЫЧКАМИ, НАПРИМЕР: pyperclip.copy('1234') - в буфере обмена будет 1234, а выводится None
</code>
Жду ответов!

def generate():
   pw_res = secrets.token_urlface(16) # это пароль (будем обозначать 1q-2w3e4r5t-6y)

pw_res тут - локальная переменная функции
generate, она остаётся внутри функции, снаружи функции при этом ничего не меняется. Хотите менять глобальную переменную - явно это укажите:

def generate():
   global pw_res
   pw_res = secrets.token_urlface(16) # это пароль (будем обозначать 1q-2w3e4r5t-6y)

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

def generate():
   return secrets.token_urlface(16) # это пароль (будем обозначать 1q-2w3e4r5t-6y)

def copy(pw_res):
   pyperclip.copy(pw_res)

x = generate()
copy(x)

# или

copy(generate)


как при парсинге BS4 получить только родителя

<div class="friend_block_content">Kastunaka Double Kill<br>
    <span class="friend_small_text">
        <span class="friend_game_link">Dota 2</span>
    </span>
</div>

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

 user_names = soup.find_all(class_="friend_block_content")
Проблема так же заключается в том, что в результате нужен список никнеймов. И просто метод find() тут не пройдет.

Можно вытащить никнеймы с помощью списка дочерних элементов .contents, взяв первый нужный вам элемент.

from bs4 import BeautifulSoup as Soup

xml_content = """

Kastunaka Int Kill

        Dota 2

Kastunaka Double Kill

        Dota 2

Kastunaka Float Kill

        Dota 2

"""

soup = Soup(xml_content, 'lxml')
user_names = soup.find_all(class_="friend_block_content")
nick_names = [user_name.contents[0] for user_name in user_names]
print(nick_names)

---------------------------------

['Kastunaka Int Kill', 'Kastunaka Double Kill', 'Kastunaka Float Kill']


Найти данные по определенному условию в xml
Имеется XML в таком виде:

<old_numbers>
  <old_number>
    <number_type>
      <code>99</code>
      <value>Иной номер</value>
    </number_type>
    <number>408529001</number>
  </old_number>
  <old_number>
    <number_type>
      <code>01</code>
      <value>Инвентарный номер</value>
    </number_type>
    <number>10406</number>
  </old_number>
  <old_number>
    <number_type>
      <code>03</code>
      <value>Кадастровый номер</value>
    </number_type>
    <number>52-52-01/773/2008-203</number>
  </old_number>
  <old_number>
    <number_type>
      <code>02</code>
      <value>Условный номер</value>
    </number_type>
    <number>52-52-01/773/2008-203</number>
  </old_number>
</old_numbers>

Помогите пожалуйста найти только "10406", это "Инвентарный номер", по условию поска "code - 01".

Мой код:

def number_type():
    number_type = soup.find_all('number_type')
    for f in number_type:
        code = f.select('code')
        for j in code:
            if j.text == '01':
                return j

def old_number(old_number):
    for value in old_number:
        if number_type():
            number_d = value.find_all('number')
            print(number_d)
number = old_number(soup.find_all('old_number'))

from bs4 import BeautifulSoup as Soup

xml_content = """<old_numbers>
  <old_number>
    <number_type>
      <code>99</code>
      <value>Иной номер</value>
    </number_type>
    <number>408529001</number>
  </old_number>
  <old_number>
    <number_type>
      <code>01</code>
      <value>Инвентарный номер</value>
    </number_type>
    <number>10406</number>
  </old_number>
  <old_number>
    <number_type>
      <code>03</code>
      <value>Кадастровый номер</value>
    </number_type>
    <number>52-52-01/773/2008-203</number>
  </old_number>
  <old_number>
    <number_type>
      <code>02</code>
      <value>Условный номер</value>
    </number_type>
    <number>52-52-01/773/2008-203</number>
  </old_number>
</old_numbers>"""

soup = Soup(xml_content, 'lxml')

soup.find('code', text='01').find_next('number').get_text()


Передача строк между библиотеками на go и скриптами на Python
Пытаюсь связать простой скрипт на Python с своей библиотекой на go. Код ниже. Смысл в том чтобы передать строку в библиотеку и получить полученное значение. Но выполнение кода вызывает ошибку со стороны go. Помогите разобраться, что я делаю не так.
Код на Python:

import ctypes
lib = ctypes.CDLL("./lib.dll")
my_str = 'abc'
my_str_b = my_str.encode('utf-8')
c_str = ctypes.c_char_p(my_str_b)
my_new_str = lib.StringTest(c_str)
print(my_new_str)

Код на Golang:

package main
import (
    "C"
)

//export StringTest
func StringTest(my_val string) string {
    return my_val + "123"
}
func main() {}

Возникающая ошибка:

runtime: out of memory: cannot allocate 140733042393088-byte block (4128768 in use)
fatal error: out of memory

Правим код на golang, т.к. тип string на Go не является char* на С. Также возвращать string в CGO тоже нельзя будет ошибка вида
cgo result has Go pointer, поэтому возвращаемый тип конвертируем в *C.char. Получается так:

package main

import (
    "C"
)

//export StringTest
func StringTest(my_val *C.char) *C.char {
    return C.CString(C.GoString(my_val) + "123")
}

func main() {}

Если выполнить код на python, то в my_new_str будет значение типа int. Это связано с тем что по умолчанию функции вызываемые через ctype возвращает значение типа int (return types ctypes). Поменяем тип возвращаемого значения для функции на
ctypes.c_char_p и получим следующее:

import ctypes
lib = ctypes.CDLL("./lib.dll")
my_str = 'abc'
my_str_b = my_str.encode('utf-8')
c_str = ctypes.c_char_p(my_str_b)
lib.StringTest.restype = ctypes.c_char_p
my_new_str = lib.StringTest(c_str)
print(my_new_str)

Либо можно не выполнять преобразование строки ctypes.c_char_p, а передать bytes в качестве аргумента функции (спасибо @insolor, за то что указал в комментарии про такую возможность):

import ctypes
lib = ctypes.CDLL("./lib.dll")
my_str = 'abc'
lib.StringTest.restype = ctypes.c_char_p
my_new_str = lib.StringTest(my_str.encode('utf-8'))
print(my_new_str)


Не получается напечатать полный текст списка
<code>
import telebot
from telebot import types
import requests
import pyfaceit

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

@bot.message_handler(commands=['start'])
def start(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    btn1 = types.KeyboardButton("Профиль")
    btn2 = types.KeyboardButton("Турниры")
    markup.add(btn1 , btn2)
    bot.send_message(message.chat.id,
                     text="Привет, {0.first_name}! Выбери нужную тебе функцию".format(
                         message.from_user), reply_markup=markup)

@bot.message_handler(content_types=['text'])
def func(message):
    if (message.text == "Профиль"):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
        btn1 = types.KeyboardButton("Добавить аккаунт")
        btn2 = types.KeyboardButton("Статистика")
        back = types.KeyboardButton("Вернуться в главное меню")
        markup.add(btn1, back)
        bot.send_message(message.chat.id, text="Что вас интересует?", reply_markup=markup)
    elif (message.text == "Турниры"):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
        btn1 = types.KeyboardButton("Список турниров")
        back = types.KeyboardButton("Вернуться в главное меню")
        markup.add(btn1,back)
        bot.send_message(message.chat.id, text="Что вас интересует?", reply_markup=markup)

    elif (message.text == "Список турниров"):
        bot.send_message(message.chat.id, "Пока что недоступно")

    elif (message.text == "Вернуться в главное меню"):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
        button1 = types.KeyboardButton("Профиль")
        button2 = types.KeyboardButton("Турниры")
        markup.add(button1, button2)
        bot.send_message(message.chat.id, text="Вы вернулись в главное меню", reply_markup=markup)
    elif (message.text == 'Добавить аккаунт'):
        bot.send_message(message.chat.id, 'Привет, сейчас я тебя зарегстрирую! Введи свой ник на Faceit')
        bot.register_next_step_handler(message, user_name)
def user_name(message):
    name = message.text.strip()
    # Статистика аккаунта
    instance = pyfaceit.Pyfaceit(name)
    stats = instance.player_stats()
    bot.send_message(message.chat.id, stats)
</code>
Сама проблема в функции user_name, когда пишу боту свой ник выдаёт лишь
"player_id"
А полный текст должен быть - {'player_id': '98d49201-abda-4311-b78a-489548c35544', и т.д

Нужно словарь stats сначала преобразовать в список с помощью

stats = list(stats.values())

Затем сделать из этого списка string

stats = (str(stats).strip('[]'))

Теперь этот string можно использовать


Почему при перезаписи списка он не меняется в кортеже?
Есть кортеж

kort = (1, [2, 3], 4)

Как можно поменять список, который лежит в нём?

a = [1, 2]
kort = (1, a, 4)
print(kort)

a = [5, 6]
print(kort)

При выполнении такого кода кортеж не меняется
А при таком меняется. Почему так происходит?

a = [1, 2]
kort = (1, a, 4)
print(kort)

a.append(5)
print(kort)

В списке хранится не переменная, а объект. Если вы перезаписываете в переменную новый объект (фактически присваиваете ей ссылку на другой объект), объект в списке не меняется, потому что он уже не имеет связи с этой переменной. Если вы мутируете объект (например, добавляете элементы в список), то список и в кортеже поменяется.
Поменять можно через запись в список по индексу:

kort[1][0] = 4

или через вызов метода списка:

kort[1].append(4)

непосредственно весь список в кортеже:

kort[1][:] = [5, 6]


Почему кортеж со списком не может быть ключом в словаре?
Есть вот такой код

ti = {
    'ke': 213,
    31: 'zna',
    (1, 2, 3): 'kort',
}

#   {'ke': 213, 31: 'zna', (1, 2, 3): 'kort'}

С ним всё в порядке. Ключи подходят и всё прочее, но когда я пытаюсь сделать:

ti = {
    'ke': 213,
    31: 'zna',
    (1, [1, 2], 3): 'kort',
}

Я получаю ошибку:

TypeError: unhashable type: 'list'

Я понимаю, что ключами должны быть неизменяемые типы, которые являются хешируемыми. И кортеж я могу использовать при условии, что всё внутри него будет неизменяемым. А список не может быть отхеширован. Но мы же по сути не можем изменить кортеж.
Почему принципиальны его внутренности? Я же не могу поменять его содержимое
P.S. Странности ещё добавляет тот факт, что у списка есть метод
__hash__

print(dir(list('dewf')))

#  ...'__gt__', '__hash__', '__iadd__',...

Цитата из документации:

Если бы ключ был изменяемым объектом, его значение могло бы
измениться, и, следовательно, его хэш также мог бы измениться.

Но в этом и суть вопроса. Я ведь не могу изменить кортеж

a = [1, 2]

kort = (1, a, 4)

print(kort) #(1, [1, 2], 4)

a = [5, 6]

print(kort) #(1, [1, 2], 4)

Есть простой принцип, который может не объясняет данного поведения, но дает представление, что можно использовать в виде ключа в словаре.

Только неизменяемый (immutable) тип данных можно использовать, как ключ в словаре

Есть типы данных, которые являются не изменяемыми (str, int и проч.), то есть по той ссылке, которая хранится в переменной/ключе вы не сможете изменить данные. Что, скорей всего и есть правильное применение для ключа.
FAQ в официальной документации содержит ответ на данный вопрос здесь.
В кратце: при изменении изменемого типа данных, его хэш также может измениться. Поэтому если вы используете изменяемый тип данных как ключ и вы попытаетесь найти тот же объект в словаре, он не будет найден, потому что его хеш-значение отличается. Также документация утверждает, что если вы попробуете найти по старому значению, то оно так же не будет найдено.
Не очень понимаю, практическое применение вопроса, если только не разобраться во внутренней кухне языка.
По комментариям под вопросом. Вы можете поменять список в кортеже
<code>
>>> a = (1, 2, [])
>>> a[2]
[]
>>> a[2].append(2)
>>> a[2]
[2]
>>> a[2].append(100)
>>> a[2]
[2, 100]
</code>
PS: можно перевести ответ из офдоки, когда будет время


Как получить все атрибуты из init?
Есть класс
Worker

class Worker:
    def __init__(self, name, age, work) -> None:
        self.name = name
        self.age = age
        self.work = work

    def say_hello(self):
        print(f"Привет, я {self.name}")

oleg = Worker('Олег', 43, "Танкист")

Хочу получить список всех атрибутов, которые объявил в
__init__. Пока в голову пришло только такое решение

list_attr = [x for x in dir(oleg) if not x.startswith('__')]

# ['age', 'name', 'work']

Может, есть какой-то метод или более лаконичный способ?

Можно использовать
__dict__

class Worker:
    def __init__(self, name, age, work) -> None:
        self.name = name
        self.age = age
        self.work = work

oleg = Worker('Олег', 43, "Танкист")

list_attr = [attr for attr in oleg.__dict__ if not callable(getattr(oleg, attr)) and not attr.startswith("__")]

# ['name', 'age', 'work']


Наследование методов классов в pyton
Метод класса наследника затирается методом предка.
При инициализации класса
ExcelDataOwnerWithCaching вызывается метод
__get_data класса
DataOwner, а не
DataOwnerWithCaching. Как мне добиться обратного, что я делаю не так?

from abc import ABC, abstractmethod

class DataOwner(ABC):
    def __init__(self, **kwargs):
        self.df = self.__get_data(
            self.load_data,
            **kwargs
        )

    @staticmethod
    @abstractmethod
    def load_data(**kwargs):
        pass

    def __get_data(self, data_loader, **kwargs):
        return data_loader(**kwargs)

class DataOwnerWithCaching(DataOwner, ABC):
    def __init__(self, key: str, **kwargs):
        self.key = key
        super().__init__(**kwargs)

    def __get_data(self, data_loader, **kwargs):
        """Тут проверка ключа в кэше и возврат данных либо из кэша, либо из главного источника + занесение в кэш"""
        print(data_loader, **kwargs)
        return pd.DataFrame()

class ExcelDataOwner(DataOwner):
    @staticmethod
    def load_data(path: str, **kwargs):
        return pd.DataFrame()

class ExcelDataOwnerWithCaching(DataOwnerWithCaching, ExcelDataOwner):
    pass

ExcelDataOwnerWithCaching(
    key='my_key',
    path='my_data.xlsx',
)

Добавив два подчеркивания вы превратили ваши методы в приватные, естественно они не могут быть переобъявлены в наследуемом классе. Достачно сделать их защищенными
_get_data, чтобы все заработало
Дело в том, что python для приватных свойств и методов в словарь объекта добавляется не просто имя, а сочетание __<имя класса>_<имя> (в данном случае
_DataOwner__get_data), поэтому они отсутствуют в словарях наследуемых классов


Добавление объекта json python
Подскажите пожалуйста, как мне добавить json объект в файл при помощи python.
Вот объект
<code>
      "name": "CeilingSkylight",
      "uniqueId": 14863.6865,
      "position": {
        "x": -121.896072,
        "y": -2.105801,
        "z": -0.7743931
      },
      "rotation": {
        "x": 0.9970698,
        "y": -1.63123222E-08,
        "z": -0.07649757,
        "w": 2.05165609E-08
      },
      "isKinematic": true,
      "instantiationData": null,
      "runtimeData": null
    }
</code>
Уточняю: открыть файл, добавить объект json(так что бы другие не удалились), закрыть файл

В комментариях вам верно указали, что нет возможности добавлять записи в json файл. Вы можете записывать, читать, перезаписывать, добавлять в конец файла, добавлять в определенную строку, но все что описано выше - это работа с текстовыми данными, а не с сущностями json или python.
Верный порядок действий такой:

открыть и прочитать файл (это будет последовательность символов)
прочитанную последовательность с помощью json модуля сделать понятным для python словарем
Изменить нужное значение(-я) в словаре
Преобразовать словарь в формат json (для python это будет опять последовательность символов, грубо говоря строка)
Полностью перезаписать файл

<code>
import json

# 1, 2
open with("your.json") as f:
    json_str = json.load(f)

# 3
json_str["name"] = "new_name"

# 4, 5
open with("your.json", "w") as f:
    json.dump(json_str, f)
</code>


Итератор раскрывающий многоуровневые списки
Необходимо написать итератор раскрывающий многоуровневые списки вида:

list_of_lists_2 = [
    [['a'], ['b', 'c']],
    ['d', 'e', [['f'], 'h'], False],
    [1, 2, None, [[[[['!']]]]], []]
]

Написал генератор выполняющий данную задачу:

def flat_generator(list_of_list):
    for item in list_of_list:
        if type(item) is not list:
            yield item
        else:
            yield from flat_generator(item)

По тому же принципу (с рекурсией) пишу итератор:

class FlatIterator:

    def __init__(self, list_of_list):
        self.list_of_list = list_of_list

    def __iter__(self):
        self.counter = -1
        return self

    def __next__(self):

        self.counter += 1
        if self.counter == len(self.list_of_list):
            raise StopIteration
        item = self.list_of_list[self.counter]
        if type(item) is not list:
            return item
        else:
            for new_item in FlatIterator(item):
               return new_item ?????

Но второй
return возвращает только первый элемент списка, при использовании
yield получаю бесконечный цикл( Как мне исправить мой код?

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

class FlatIterator:
    def __init__(self, list_of_list):
        self.stack = []
        self.current_list = list_of_list
        self.counter = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.counter >= len(self.current_list):
            if self.stack:
                # Дошли до конца вложенного списка,
                # выходим из него во внешний, "вспоминаем" состояние
                self.current_list, self.counter = self.stack.pop()
                return next(self)
            else:
                raise StopIteration

        item = self.current_list[self.counter]
        self.counter += 1

        if type(item) is not list:
            return item
        else:
            # Запоминаем текущее состояние
            self.stack.append((self.current_list, self.counter))
            # Входим во вложенный список, он становится текущим списком
            self.current_list = item
            self.counter = 0
            return next(self)

list_of_lists_2 = [
    [['a'], ['b', 'c']],
    ['d', 'e', [['f'], 'h'], False],
    [1, 2, None, [[[[['!']]]]], []],
]

print(list(FlatIterator(list_of_lists_2)))

Вывод:

['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None, '!']

В общем, то еще "удовольствие", через рекурсивную функцию-генератор получается намного проще.

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

class FlatIterator:
    def __init__(self, list_of_list):
        self.stack = []
        self.current_iterator = iter(list_of_list)

    def __iter__(self):
        return self

    def __next__(self):
        try:
            item = next(self.current_iterator)
        except StopIteration:
            if self.stack:
                # Дошли до конца вложенного списка,
                # выходим из него во внешний, "вспоминаем" состояние
                self.current_iterator = self.stack.pop()
                return next(self)
            else:
                # Выходить выше некуда, значит дошли до конца внешнего списка,
                # просто выбрасываем исключение (StopIteration) заново
                raise

        if type(item) is not list:
            return item
        else:
            # Запоминаем текущее состояние
            self.stack.append(self.current_iterator)
            # Входим во вложенный список, он становится текущим списком
            self.current_iterator = iter(item)
            return next(self)

list_of_lists_2 = [
    [['a'], ['b', 'c']],
    ['d', 'e', [['f'], 'h'], False],
    [1, 2, None, [[[[['!']]]]], []],
]

print(list(FlatIterator(list_of_lists_2)))

Также, чтобы код был точно не рекурсивным, нужно избавиться от вызовов
next(self) из метода
__next__ (по сути метод вызывает сам себя). Для этого нужно обернуть код в методе в
while True и вызовы
next(self) заменить на
continue:

class FlatIterator:
    ...

    def __next__(self):
        while True:
            try:
                item = next(self.current_iterator)
            except StopIteration:
                if self.stack:
                    # Дошли до конца вложенного списка,
                    # выходим из него во внешний, "вспоминаем" состояние
                    self.current_iterator = self.stack.pop()
                    continue
                else:
                    # Выходить выше некуда, значит дошли до конца внешнего списка,
                    # просто выбрасываем исключение (StopIteration) заново
                    raise

            if type(item) is not list:
                return item
            else:
                # Запоминаем текущее состояние
                self.stack.append(self.current_iterator)
                # Входим во вложенный список, он становится текущим списком
                self.current_iterator = iter(item)
                # continue

...


Shelve не выводит сохранённые значения в tkinter
Ребята, прошу помощи с пониманием работы кода. Ситуация вроде довольно простая, использую shelve, чтобы сохранить данные полученные от введения пользователем информации в окна через tkinter. Однако проблема в том, что при попытке закрыть программу и открыть снова - база данных не хочет ничего показывать. Подскажите, в какую сторону копать?
Пробовал так писать код:

bd_games = shelve.open('file')
bd_games['value'] = [Name.get(), combobox_Raiting.get(), combobox_Fan.get()]
bd_games.close()

Даже пробовал создавать отдельно список в переменную Lst и через .append добавлял в неё Name.get() и все остальные, потом:

bd_games['value'] = Lst

Результат в итоге один:
<shelve.DbfilenameShelf object at 0x0000011E9549C400> при перезапуске программы и попытке прочитать файл bd_games.
Пробовал заглядывать в файл .dat - там даже среди краказябр были латинские слова, что я вводил. То есть он сохраняет в двух вариантах кода информацию, тогда почему при перезапуске выдаёт мне эту ерунду?

Результат в итоге один:
<shelve.DbfilenameShelf object at 0x0000011E9549C400> при перезапуске программы и попытке прочитать файл bd_games.

Я так понял вы просто пытаетесь напечатать сам объект
shelve и получаете стандартный вывод питона об этом объекте - его тип и адрес в памяти. Получите из
shelve словарь значений и всё нормально напечатается. Пример:

import shelve

with shelve.open('test.tmp') as test:
    test['test'] = 'тест'
    print(test)
    print(dict(test.items()))

Вывод:

<shelve.DbfilenameShelf object at 0x000001A193FAE190>
{'test': 'тест'}

Первый вывод соответствует тому, как смотрите содержимое
shelve вы, а второй вывод - это как нужно его смотреть.


Реализовать функцию для разбора строки, содержащей данные в текстовом формате
Реализовать функцию для разбора строки, содержащей данные в текстовом формате. Изучить детали формата по приведенным ниже примерам. Результат вернуть в виде словаря.
Пример 1
Входная строка:

do {{ local{ #-5628 ; #2071; #-5261 ;#3063} ==> @"lais_806"; }}. {{
local { #-9793 ; #-8719 ; #-6854 } ==> @"esorte"; }}. end

Разобранный результат:

{'lais_806': [-5628, 2071, -5261, 3063],
'esorte': [-9793, -8719, -6854]}

Тут делов то на пару регулярок. Знатоки регулярок может и в одну могут уложиться, но я не такой уж и знаток:

import re

item = re.compile('{{(.*?)==>.*?"([^"]+?)".*?}}')
num = re.compile('-?\d+')
string = 'do {{ local{ #-5628 ; #2071; #-5261 ;#3063} ==> @"lais_806"; }}. {{ local { #-9793 ; #-8719 ; #-6854 } ==> @"esorte"; }}. end'
print({y: num.findall(x) for x, y in item.findall(string)})

Вывод:

{'lais_806': ['-5628', '2071', '-5261', '3063'], 'esorte': ['-9793', '-8719', '-6854']}

Первая регулярка в основном состоит из "не жадных" произвольных фрагментов текста
.*?, а остальное там - скобки, кавычки и прочее такое, между которыми мы хотим найти интересующие нас элементы.


Алгоритмы. Python. 2 больших списка, проставить индексы соответствия
Пишу на Python
Есть 2 списка. Один статический, находится в таблице Excel. Второй список парсится с сайта, парсятся уникальные номера товаров, вида "3593893".
На данный момент я сначала нахожу все уникальные номера на сайте (Порядка 3000 штук). Засовываю их в список.
Затем засовываю во второй список все номера из Excel.
И мне нужно найти в какой строке в таблице Excel находится одинаковый номер из первого списка.
Из-за того что строк порядка 3000, то моя конструкция работает очень долго, больше часа.
Я использую что-то вроде:

for i in range(0, len(ids)):
   if ids[i] in codes_data:
       j = codes_data.index(ids[i])
       #"заполняю строку остальными данными"

Правильно ли я понимаю что программа в данном случае просматривает список "codes_data" дважды?
Первый раз в
if ids[i] in codes_data Второй раз в
codes_data.index(ids[i])
Если это так, то корректно ли сделать:

for i in range(0, len(ids)):
    try:
        j = codes_data.index(ids[i])
        #"заполняю строку остальными данными"
    except: pass

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

Обновление.
Проблема была решена. Главная проблема как оказывается была в другом. Я слишком часто сохранял Excel файл, что тормозило работу программы. После того как я сделал отдельный файл для считывания и отдельный для записи, скорость стала молниеносной.
Но я также смог улучшить и обработку списков благодаря ответам ниже, что еще больше улучшило пограмму.
Спасибо.

Поиск элемента в списке имеет сложность
O(n), а в словаре
O(1).
Чтобы сильно не переписывать код, можно сделать по-быстрому маппинг в виде словаря
item -> position и использовать его для поиска позиций:

codes_dict = {x: i for i, x in enumerate(codes_data)}

for id_ in ids:
    j = codes_dict.get(id_)
    if j is not None:
        #"заполняю строку остальными данными"
        ...

Метод
get возвращает либо значение из словаря, если такой ключ в словаре есть, либо
None, если ключа нет. Таким образом, можно достать значение и проверить наличие ключа в словаре одной операцией вместо двух, дополнительная экономия. Хотя при сложности доставания элемента из словаря
O(1) это уже будет не так существенно влиять на скорость кода, но всё-таки.
А в вашем коде да - если элемент есть в списке, то список просматривается два раза - один раз при проверке наличия элемента и второй раз чтобы получить индекс этого элемента. Учитывая сложность обеих операций
O(n) получается довольно "медленно и печально".


Как конвертировать время в формат чч:мм?
<code>
import datetime as dt

my_datetime = dt.datetime(2023, 3, 28, 00, 00, 00)
m_datetime = dt.datetime.now()
v = m_datetime - my_datetime
print("С начала текущих суток прошло:", v)
</code>

Если вам нужно просто вывести текущее время (это то же самое, что время прошедшее с начала суток), то вообще вычитать не нужно ничего.
Нужно просто
dt.datetime.now() отформатировать с форматом
%H:%M:

import datetime as dt

now = dt.datetime.now()
print(f"С начала текущих суток прошло: {now:%H:%M}")

Если нужно получить именно из
v (
timedelta), то берете из
v полное количество секунд, делите нацело с остатком (
divmod) на 3600 - частное будет количеством часов. Остаток делите на 60 - получаете количество минут:

import datetime as dt

my_datetime = dt.datetime(2023, 3, 28, 00, 00, 00)
m_datetime = dt.datetime.now()
v = m_datetime - my_datetime
hours, seconds = divmod(int(v.total_seconds()), 3600)
minutes = seconds // 60
# Если нужны будут секунды, то вместо просто деления на 60 делайте опять divmod:
# minutes, seconds = divmod(seconds, 60)
print(f"С начала текущих суток прошло: {hours:02}:{minutes:02}")


Запуск bat файла из python
У меня есть метод, который делает проверку на админку. Но когда я запускаю программу, то выдает ошибку:

'Class' is not recognized as an internal or external command,
operable program or batch file.

Код:

def run_as_admin(self, cmd):
    try:
        # Если мы не являемся администратором, то запускаем с правами администратора
        if not ctypes.windll.shell32.IsUserAnAdmin():
            # Собираем команду, чтобы запустить с правами администратора
            cmd = 'powershell.exe Start-Process "' + cmd + '" -Verb runAs'
            subprocess.call(cmd, shell=True)
            return True
        # Если мы уже являемся администратором, то просто запускаем файл
        else:
            subprocess.call(cmd)
            return True
    except Exception as e:
        print(e)
        return False

def buttonDSDel(self):
    self.run_as_admin('Class/DelSoft/DiscordDel.bat')

bat file

@echo off
taskkill /f /im Discord.exe
ping 127.0.0.1 -n 2 > nul
cd %appdata%
rmdir /s /q Discord
rmdir /s /q discordptb
rmdir /s /q discordcanary

операционная система не может найти файл или команду с названием "Class"
Попробуйте изменить вызов subprocess.call
<code>
subprocess.call(["powershell.exe", "Start-Process", cmd, "-Verb", "runAs"], shell=True)
</code>


Создать список AD групп в которых состоит пользователь
Подскажите пытаюсь создать список пользователей + название ad группы в которых они состоят.
Должно выводить:
VPipkin: 'test','test2' если в 2 (определенных) группах состоит или
VPipkin: 'test' если в одной.
Как правильно прописать чтобы выводилось
VPipkin: 'test','test2'

#Условия поиска
    conn.search(AD_SEARCH_TREE, '(|(memberOf=cn=test,ou=GIS,ou=Resource_Access_Groups_Auto,ou=Groups,dc=d,dc=a, dc=c)(memberOf=cn=test_2,ou=GIS,ou=Resource_Access_Groups_Auto,ou=Groups,dc=d,dc=a,dc=c))',
                attributes = ['sAMAccountName','sn','givenName','mail','displayName','memberof'])

#Формируем список пользователей из AD групп
    name={}
    for entri in conn.entries:
        for cn in entri.memberof:
            if re.search(r'CN=test', cn):
                name[entri.sAMAccountName[0]]='test'
            if re.search(r'CN=test2\b', cn):
                name[entri.sAMAccountName[0]]='test2'
            if re.search(r'CN=test\b', cn) and re.search(r'CN=test2', cn):
                name[entri.sAMAccountName[0]]=['test','test2']

    return name

Как-то так:
<code>
name={}
for entri in conn.entries:
name[entri.sAMAccountName[0]] = []
    for cn in entri.memberof:
        if re.search(r'CN=test\b', cn):
            name[entri.sAMAccountName[0]].append('test')
        if re.search(r'CN=test\b', cn):
            name[entri.sAMAccountName[0]].append('test2')
</code>


Tkinter не выводит виджеты
Я пытаюсь сделать нечто похожее на блокнот. Код ниже выводит только окно Tkinter, но ни поля text, ни кнопки нет. Пробовала его в PyCharm и Visual stuio code. Подскажите, пожалуйста, где ошибка.
<code>
from tkinter import *

def give():
    a = open("blocknot.txt", "w+")
    v = text_box.get("1.0", END)
    a.write(v)
    a.close()

root = Tk()
root.geometry('500x500')
root.title('Blocknot')

global entry
text_box = Text(width = 50,
                height = 90)

text_box.pack

Button(text = 'Save',
       width = 3,
       height = 5,
       command = give()).pack

root.mainloop()
</code>

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

text_box.pack()
#            ^^ - скобки для вызова

и

Button(text = 'Save',
       width = 3,
       height = 5,
       command = give()).pack()
#                            ^^ - здесь тоже


Как ускорить обработку Excel через Python? Какой модуль выбрать?
Задача 1: На входе будет
10+
Excel-файлов с
1000+ строк в каждом файле. Программа будет находить необходимую информацию в каждом файле и создавать на основе этой информации другой файл. Другой файл будет содержать сразу все строки из тех
10-ти файлов.
Через какой модуль реализовать быстрее? Сделал через
openpyxl -
700 строк отфильтровались и скопировались за
10 минут. Это долго. Что можно, сделать, чтобы ускорить? Если можно, без применения асинхронности.
Задача 2: В тех же файлах есть строки с неявными ссылками (у ссылки есть заголовок). Как скопировать эти ссылки в другой файл? Через тот же
openpyxl не смог это сделать. Копирует только заголовок ссылки, а саму ссылку - нет.

import openpyxl
from openpyxl import Workbook

poster_book = openpyxl.open('poster.xlsx', read_only=True)
poster_sheet = poster_book.active
for prop in poster_book.custom_doc_props.props:
    print(f'{prop.name}:{prop.value}')

MI_book = Workbook()
MI_sheet = MI_book.active

poster_titles = {*заголовки словаря удалены по соображениям конфиденциальности*
                  }

def write_titles_in_file():
    row = []
    for k, v in poster_titles.items():
        row.append(k)
    MI_sheet.append(row)

def get_title_links():
    poster_title_links = poster_titles.copy()
    for row_num in range(1, poster_sheet.max_row+1):
        row = poster_sheet[row_num]
        for cell in row:
            for k, v in poster_titles.items():
                if v and cell.value and v in str(cell.value):
                    poster_title_links[k] = (cell.row, cell.column)
    return poster_title_links

def get_data():
    write_titles_in_file()
    poster_data_row = poster_titles.copy()
    for row_num in range(1, poster_sheet.max_row+1):
        for k, v in poster_title_links.items():
            if v and int(v[0]) < row_num:
                cell = poster_sheet[row_num][int(v[1])-1]
                poster_data_row[k] = cell.value
        if poster_data_row['адрес'] != poster_titles['адрес']:
            write_in_file(poster_data_row)
            print(poster_data_row)

def write_in_file(poster_data_row):
    row = []
    for k, v in poster_data_row.items():
        row.append(v)
    MI_sheet.append(row)

poster_title_links = get_title_links()
get_data()
MI_book.save('MI_OOH.xlsx')

Получение ссылок
При получении значений ячеек использовать методы hyperlink и target:

cell = poster_sheet[row_num][int(v[1]) - 1].hyperlink.target

Ускорение программы
При чтении файла использовать не метод open, а метод load_workbook (программа ускорилась в 10 раз):

poster_book = openpyxl.load_workbook('poster.xlsx')


moviepy при обработке видео фризит видео
Пытаюсь наложить музыку на аудио дорожку видео и потом на само видео. Стоит скомпилироваться видео, смотрю его и после 1 секунды видео зависает, а аудио нормально идет. Я пробывал использовать внутреннимй атрибут write_videofile(threads, codec) и фпс, но ничего не меняется, только при кодеке 'mpeg4' компилируется с просто черным экраном, а аудио норм. Размеры файла маленькие, до 15 сек. Пробовал на 3.8 и 3.9 пайтонах. Версии moviepy я тоже менял, но только 1.0.3 версия рабортает без бага. Пожалуйста помогите, очень нужно! :(
Код:
<code>
def add_music(audio_path, video_path):
    video_clip = VideoFileClip(f'{BASE_DIR}/media/{video_path}')
    audio_clip = AudioFileClip(f'{BASE_DIR}/media/{audio_path}')
    audio_clip = audio_clip.volumex(0.035)
    end = video_clip.end
    audio_clip = audio_clip.subclip(0, end)
    final_audio = CompositeAudioClip([video_clip.audio, audio_clip])
    final_clip = video_clip.set_audio(final_audio)
    final_clip.write_videofile(f'{BASE_DIR}/media/{video_path}')
</code>

Нет возможности протестировать, но думаю проблема в том что чтение и запись видео идёт в один и тот же файл.
Таким образом записывается только 1 чанк видео, а дальше считывать информацию неоткуда, так как файл уже перезаписан
Соответственно нужно изменить путь в строчке
<code>
final_clip.write_videofile(f'{BASE_DIR}/media/{video_path}')
</code>
На любой другой


Как подождать загрузку кнопки через Selenium
Занимаюсь парсингом динамического сайта (selenium-wire, bs4). Проблема в том, что скриптом нужно находить кнопку и нажимать на неё, чтобы страница дальше проскролилась и контент прогрузился.
Я на данный момент перепробовал разные варианты, но все они какие-то "костыльные"
Вот это моя последняя рабочая версия

        try:
            while self.driver.find_element(By.CSS_SELECTOR, '.event__more--static'):
                self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                self.driver.find_element(By.CSS_SELECTOR, '.event__more--static').click()
                time.sleep(3)
        except:
            print('Вы на дне!')

Проблема в том, что я не могу убрать задержку, тогда код падает из-за того, что элемент не найден (потому что новая кнопка "Показать больше" ещё не загрузилась). И дублирование кода тоже очень сильно смущает
Попробовал ждать элемент на странице через методы selenium

def takeContent(self):
        """Забирает контент со страницы"""
     while True:
        try:
            self.element = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '.event__more--static'))
            )
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            print(f'Я ИЩУ КНОПКУ - {self.element}')
            self.element.click()
        except:
            print('Вы на дне!')
            break

Данный код попросту отказывается работать. Просто после первого нажатия на кнопку закрывается браузер и всё
На основе комментариев дописал до такого кода

def takeContent(self):
        """Забирает контент со страницы"""
        try:
            while True:
                button = WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.event__more--static')))
                print('Я нашёл кнопку - ', button)
                self.driver.execute_script("arguments[0].click();", button)
                print('Я нажал кнопку - ', button)
        except:
            print('Вы на дне!')
            self.content = self.driver.page_source

Теперь проблема следующая:

Я нашёл кнопку -  <selenium.webdriver.remote.webelement.WebElement (session="efb72689d4c57f4b5ba6f5c7ce89afb2", element="41d0f0da-e895-415c-bfad-1eddd0dad1fd")>
Я нажал кнопку -  <selenium.webdriver.remote.webelement.WebElement (session="efb72689d4c57f4b5ba6f5c7ce89afb2", element="41d0f0da-e895-415c-bfad-1eddd0dad1fd")>
Я нашёл кнопку -  <selenium.webdriver.remote.webelement.WebElement (session="efb72689d4c57f4b5ba6f5c7ce89afb2", element="41d0f0da-e895-415c-bfad-1eddd0dad1fd")>
Я нажал кнопку -  <selenium.webdriver.remote.webelement.WebElement (session="efb72689d4c57f4b5ba6f5c7ce89afb2", element="41d0f0da-e895-415c-bfad-1eddd0dad1fd")>
Я нашёл кнопку -  <selenium.webdriver.remote.webelement.WebElement (session="efb72689d4c57f4b5ba6f5c7ce89afb2", element="41d0f0da-e895-415c-bfad-1eddd0dad1fd")>

Он спамит нажатием на одну кнопку. А сайт всё это время крутит лоадинг и не может прогрузить ни один дополнительный "экран". Можно ли как-то написать, чтобы код ждал подгрузки контента?

Он спамит нажатием на одну кнопку. А сайт всё это время крутит лоадинг и не может прогрузить ни один дополнительный "экран". Можно ли как-то написать, чтобы код ждал подгрузки контента?

Возьмите CSS селектор лоадинга.
Сначала дождитесь его, пока он появится, с помощью WebDriverWait().until
Затем дождитесь когда он пропадёт WebDriverWait().until_not чтобы продолжить работать со страницей.
Эти оба ожидания лучше обернуть в try-except на случай, если лоадинг вообще не появится
(Либо делать WebDriverWait на те элементы которые должны подгрузиться, например проверкой их на кликабельность или визуальное отображение)


Получить словарь определенного вида
Имеется датафрейм следующего вида:

q = [[nan, nan],
 [nan, nan],
 ['29', 'B'],
 ['29', 'D'],
 ['29', 'C'],
 [nan, nan],
 ['30', 'B'],
 ['30', 'D'],
 ['30', 'C'],
 [nan, nan],
 ['30', 'E'],
 ['30', 'G'],
 ['30', 'F'],
 [nan, nan],
 ['32', 'B'],
 ['32', 'D'],
 ['32', 'C'],
 [nan, nan],
 ['31', 'B'],
 ['31', 'D'],
 ['31', 'C']]

Названия колонок:

columns = ['source', 'own']

Требуется получить словарь следующего вида:

dict1 = {'29': ['B', 'D', 'C'],
 '30': ['B', 'D', 'C', '', 'E', 'G', 'F'],
 '32': ['B', 'D', 'C'],
 '31': ['B', 'D', 'C'],
 '33': ['B', 'D', 'C', '', 'E', 'G', 'F']}

На данный момент есть такое решение:

def get_correct_column_order(data_schema):
    correct_column_order = defaultdict(list)
    for i in range(data_schema.shape[0]):
        source = data_schema['source'].iloc[i]
        if isinstance(source, str):
            value = data_schema['own'].iloc[i]
            correct_column_order[source].append(value)
    return dict(correct_column_order)

df = pd.DataFrame(q, columns=columns)
get_correct_column_order(df)

и получаю словарь

dict2 = {'29': ['B', 'D', 'C'],
 '30': ['B', 'D', 'C', 'E', 'G', 'F'],
 '32': ['B', 'D', 'C'],
 '31': ['B', 'D', 'C'],
 '33': ['B', 'D', 'C', 'E', 'G', 'F']}

Зачем так сложно, обычный
groupby работает. Но чтобы пустая строка ещё была, придётся сначала пошаманить:

mask = df['source'].isnull() & (df['source'].ffill() == df['source'].bfill())
df.loc[mask, 'source'] = df['source'].ffill().loc[mask]
df.loc[mask, 'own'] = ''

df.groupby('source').agg(list)['own'].to_dict()

Вывод:

{'29': ['B', 'D', 'C'],
 '30': ['B', 'D', 'C', '', 'E', 'G', 'F'],
 '31': ['B', 'D', 'C'],
 '32': ['B', 'D', 'C']}

Если вы используете циклы в
Pandas, значит вы что-то не то делаете, обычно всё можно решить "векторным" способом.


TypeError: iter() returned non-iterator of type 'list'
Копаюсь в дандерах iter и next и решил написать свой класс, который при итерации возвращает свои атрибуты.
Самый первый пример, который мне пришёл в голову - это просто сбор всех атрибутов в отдельном листе и вывод их по одному:

class Test():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __iter__(self):
        self.index = -1
        self.list_q = [self.name, self.age]
        return self.list_q

    def __next__(self):
        index += 1
        yield self.list_q[self.index]

t = Test('Имя', 10)

for item in t:
    print(item)

Но при данном коде у меня получается ошибка:

Traceback (most recent call last):
  File "main.py", line 19, in <module>
    for item in t:
TypeError: iter() returned non-iterator of type 'list'

В чём проблема? Разве метод iter не должен возвращать итератор для перебора объектов? Разве лист не является таким итератором?

Есть два разных понятия: итератор (iterator), итерируемый объект (iterable). У них есть схожие черты (и по тому, и по другому можно пройтись циклом), но есть большая разница.
С точки зрения реализации:

итерируемый объект должен реализовать метод
__iter__, из которого должен возвращаться итератор (но не другой итерируемый объект). В идеале - при каждом вызове новый итератор.

итератор должен реализовывать и метод
__iter__ (который должен возвращать сам объект (
self)), и метод
__next__, который при каждом вызове должен возвращать следующее значение из итератора (или выбрасывает исключение
StopIteration).

Чисто технически, каждый итератор можно считать итерируемым объектом - у каждого итератора реализован
__iter__ (который, правда, не создает новый итератор). Но не наоборот - не у каждого итерируемого объекта будет метод
__next__. Поэтому и не работает возврат
list из
__iter__ - он является итерируемым объектом, но не итератором.
С точки зрения поведения:

После того как итератор создан, по нему можно пройти циклом (или, например, извлекать значения с помощью функции
next) только один раз, при попытке пройти повторно итератор больше не возвращает никаких значений - так называемое исчерпание итератора (iterator exhaustion)

По итерируемому объекту (кроме итераторов) можно итерироваться много раз - его метод
__iter__ каждый раз возвращает новый итератор.
Хотя итератор формально (по наличию метода
__iter__) можно считать итерируемым объектом, но
__iter__ у него не создает новый итератор, а просто возвращает сам объект, по которому уже нельзя пройти повторно, если он исчерпан.

По вашему коду:

В принципе, если реализуете итератор, лучше не добавлять в
__iter__ никакого кода, кроме
return self, а всю инициализацию делать в
__init__.

__next__ должен именно возвращать значения через
return, а не через
yield. Если добавляете в функцию yield, то она магически становится генератором, который возвращает итератор (generator iterator, частный случай итератора), а вам нужно ровно одно значение, а не новый итератор.

Таким образом, класс-итератор в идеале должен выглядеть так:

class Test():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.index = -1
        self.list_q = [self.name, self.age]

    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        if self.index >= len(self.list_q):
            raise StopIteration
        return self.list_q[self.index]

Если вы реализуете итерируемый объект, то метод
__next__ не нужен, но
__iter__ должен вернуть итератор. Из списка можно получить итератор передав его в функцию
iter:

class Test():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.list_q = [self.name, self.age]

    def __iter__(self):
        return iter(self.list_q)

t = Test('Имя', 10)

for item in t:
    print(item)

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

class Test():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.list_q = [self.name, self.age]

    def __iter__(self):
        for item in self.list_q:
            yield item

t = Test('Имя', 10)

for item in t:
    print(item)

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

class Test():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.list_q = [self.name, self.age]

    def __iter__(self):
        return (item for item in self.list_q)

t = Test('Имя', 10)

for item in t:
    print(item)


Теория игр, рекурсия, поиск нужных значений
При попытке запустить код возникает бесконечная рекурсия (не может найти подходящие значения под условия, да и сам код неверный из-за s==42) - что изменить в коде, чтобы он действительно работал и при других заданиях (кроме 19)?

Два игрока, Петя и Ваня, играют в следующую игру.

Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход
делает Петя. За один ход игрок может увеличить количество камней в
куче на 1, 3 или 7. Игра завершается в тот момент, когда количество
камней в куче становится ровно 42. Игрок, первым получивший кучу из 42
камней, считается победителем. Игрок получивший после своего хода
более 42 камней считается проигравшим и победителю засчитывается ход в
42. Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.

Укажите такое минимальное значение s, при котором Петя не может
выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим #Ответ: 38
первым ходом.
Найдите два наименьших значения s, при которых у Пети есть выигрышная
стратегия, причём одновременно выполняются два условия:

— Петя не может выиграть за один ход;
— Петя может выиграть своим вторым ходом независимо от того, как будет
ходить Ваня. Найденные значения запишите в ответе в порядке
возрастания. #Ответ: 31, 33

Найдите два наименьших значение s, при котором
одновременно выполняются два условия:

— у Вани есть выигрышная стратегия, позволяющая ему выиграть первым
или вторым ходом при любой игре Пети; — у Вани нет стратегии, которая
позволит ему гарантированно выиграть первым ходом. Найденные значения
запишите в ответе в порядке возрастания #Ответ: 30, 32

<code>
def f(s,p):
    if s == 42 and p == 3: return True
    #if s > 42 and p == 3: return False
    if s == 42 and p < 3: return False
    if s == 42 and p == 3: return False
    if p%2 == 0:
        return f(s+1,p+1) and f(s+3,p+1) and f(s+7,p+1)
    if p%2 != 0:
        return f(s+1,p+1) or f(s+3,p+1) or f(s+7,p+1)

for s in range(1,60):
    if f(s,1):
        print(s)
</code>

def f(s,p):
    if s >= 42 and p == 3: return True
    if s > 42 and p < 3: return False
    if s+1 > 42 and s+3 > 42 and s+7 > 42: return False
    if p%2 == 0:
        return f(s+1,p+1) and f(s+3,p+1) and f(s+7,p+1)
    if p%2 != 0:
        return f(s+1,p+1) or f(s+3,p+1) or f(s+7,p+1)


Вывод в список переменных, пронумерованных по порядку, в которых содержатся данные
Есть переменные. Пытаюсь вывести в файл Microsoft Word пронумерованный список по порядку переменных, в которых содержатся данные. Вывод

 1. Привет
 4. 38000

А надо

1. Привет
2. 38000

Подскажите как это сделать
Делаю так

a = 'Привет'
b = None
c = none
d = 38000

variable_names = ['a', 'b', 'c', 'd']
doc.add_heading('Variables with values', level=1)
for i, var_name in enumerate(variable_names):
    var_value = globals()[var_name]
    if var_value is not None:
        i = 0

        doc.add_paragraph(f"{i +1}. {var_value}")

# Save the document
doc.save('output.docx')

Придётся считать "вручную":
<code>
i = 1
for var_name in variable_names:
    var_value = globals()[var_name]
    if var_value is not None:
        doc.add_paragraph(f"{i}. {var_value}")
        i += 1
</code>


Имитация нажатия на Клавишу-Button (Tkinter)
Суть моего вопроса можно легко понять из простейшего примера на Python (Tkinter):
<code>
from tkinter import *

def click(num):  # Обработчика Нажатия на Клавишу (ЛКМ)
    print(f' - Нажата ЛКМ!,  num: {num}')  # .....

def right_click(event):  # Обработчика Нажатия на Клавишу (ПКМ)
    print(' - Нажата ПКМ!')  # .....

# (Клавиша-Tkinter)
btn = Button()

# (.....)
btn.config(command=lambda arg=5: click(arg))  # привязка - Обработчика Нажатия на Клавишу (ЛКМ)
# btn.(.....) - Как программно имитировать нажатие на Клавишу-btn (ЛКМ)?

# (.....)
btn.bind('<Button-3>', right_click)  # привязка - Обработчика Нажатия на Клавишу (ПКМ)
# btn.(.....) - Как программно имитировать нажатие на Клавишу-btn (ПКМ)?
</code>
Помнится, что где-то я это уже встречал, но тогда было не нужно, а сейчас уже не помню ...
Помогите, пожалуйста!
Заранее Спасибо!
Как вызвать привязанную функцию - right_click(event), если я не знаю что такое - event?
Нигде не могу найти пример вызова функции с аргументом-event САМОСТОЯТЕЛЬНО,
а не ЧЕРЕЗ СОБЫТИЯ! Как это делается? Неужели никто не знает?

задать необходимые атрибуты и передать его в качестве аргумента функции right_click.
вот так
<code>
import tkinter as tk

root = tk.Tk()

def right_click(event):
    print(f'x={event.x}, y={event.y}')

# Создаем объект event и задаем необходимые атрибуты
event = tk.Event()
event.x = 50
event.y = 100

# Вызываем функцию right_click с объектом event в качестве аргумента
right_click(event)

root.mainloop()
</code>