Как отслеживать url в формах Django
Есть сайт на Django для бронирования номеров в разных отелях (13 штук- 13 страниц), данные из заполненной формы записываются в БД. Ничего лучше не придумал как создать 13 одинаковых таблиц с разными названиями для каждого отеля. Но это сильно противоречит принципу DRY. Поэтому вопрос - как можно отследить url с которого передаётся форма и автоматически заполнять ячейку названием отеля в БД.

class ReceptionAlexander(models.Model):
date_first = models.DateField(verbose_name='Дата заезда')
date_second = models.DateField(verbose_name='Дата выезда')
rooms = models.IntegerField(verbose_name='Количество номеров', default=1)
adult = models.IntegerField(verbose_name='Количество взрослых гостей', default=1)
kids = models.IntegerField(verbose_name='Количество детей', default=0)
name = models.CharField(verbose_name='ФИО', max_length=40)
phone = models.CharField(verbose_name='Номер телефона', max_length=12)

class Meta:
    verbose_name_plural = 'Александр Хаус'

class ReceptionGalunov(models.Model):
date_first = models.DateField(verbose_name='Дата заезда')
date_second = models.DateField(verbose_name='Дата выезда')
rooms = models.IntegerField(verbose_name='Количество номеров', default=1)
adult = models.IntegerField(verbose_name='Количество взрослых гостей', default=1)
kids = models.IntegerField(verbose_name='Количество детей', default=0)
name = models.CharField(verbose_name='ФИО', max_length=40)
phone = models.CharField(verbose_name='Номер телефона', max_length=12)

class Meta:
    verbose_name_plural = 'Галунов Отель'

class ReceptionGelvecia(models.Model):
date_first = models.DateField(verbose_name='Дата заезда')
date_second = models.DateField(verbose_name='Дата выезда')
rooms = models.IntegerField(verbose_name='Количество номеров', default=1)
adult = models.IntegerField(verbose_name='Количество взрослых гостей', default=1)
kids = models.IntegerField(verbose_name='Количество детей', default=0)
name = models.CharField(verbose_name='ФИО', max_length=40)
phone = models.CharField(verbose_name='Номер телефона', max_length=12)

class Meta:
    verbose_name_plural = 'Отель Гельвеция'

Форма

class ReceptionFormGelvecia(forms.ModelForm):
class Meta:
    model = ReceptionGelvecia
    fields = ['date_first', 'date_second', 'rooms', 'adult', 'kids', 'name', 'phone']

И так далее к каждой таблице

Вам нужно пересмотреть архитектуру ваших модейлей. Создайте две зависимые таблицы.
Создаёте модель Hotel в которой у Вас будет хранится все отели , его название и месторасположение (для примера).

class Hotel(models.Model):
    title = models.CharField(max_length=255, blank=False, null=False)
    location = models.CharField(max_length=255, blank=False, null=False)

    def __str__(self):
        return self.title

После чего создаёте модель под бронирование.

class ReceptionAlexander(models.Model):
    hotel_name = models.ForeignKey(Hotel, related_name='h_name', blank=False, null=False)
    date_first = models.DateField(verbose_name='Дата заезда')
    date_second = models.DateField(verbose_name='Дата выезда')
    rooms = models.IntegerField(verbose_name='Количество номеров', default=1)
    adult = models.IntegerField(verbose_name='Количество взрослых гостей', default=1)
    kids = models.IntegerField(verbose_name='Количество детей', default=0)
    name = models.CharField(verbose_name='ФИО', max_length=40)
    phone = models.CharField(verbose_name='Номер телефона', max_length=12)

    def __str__(self):
        return ' | '.join([self.hotel_name, self.name])

И получится следующее, в поле hotel_name у вас будет перечень всех созданных отелей. Через Django Forms создаете выпадающий список для поля hotel_name на основе таблицы Hotel.
По итогу у Вас будет 2 model, 1 forma и 1 url.
Либо создаёте одну модель

class ReceptionAlexander(models.Model):
    hotel_name = models.CharField(max_length=255, blank=False, null=False)
    date_first = models.DateField(verbose_name='Дата заезда')
    date_second = models.DateField(verbose_name='Дата выезда')
    rooms = models.IntegerField(verbose_name='Количество номеров', default=1)
    adult = models.IntegerField(verbose_name='Количество взрослых гостей', default=1)
    kids = models.IntegerField(verbose_name='Количество детей', default=0)
    name = models.CharField(verbose_name='ФИО', max_length=40)
    phone = models.CharField(verbose_name='Номер телефона', max_length=12)

    def __str__(self):
        return ' | '.join([self.hotel_name, self.name])

И после чего в django forms создаёте под поле hotel_name  выпадающий список.

Hotels =(
    ("1", "Редисон"),
    ("2", "Хаятт"),
    ("3", "Континенталь"),
    ("4", "Четыре сизона"),
)

# creating a form
class HotelForm(forms.Form):
    hotel_name = forms.ChoiceField(choices = Hotels)


Как корректно транспонировать (развернуть) строку в столбцы?
Имею следующий
df:

qw as df rt fg gh qw fg
12 34 56 67 87 89 98 09

Данный
df получаю следующим способом, выборкой строки из общего
table_df:

df = table_df.loc[[18]]

Просьба, подсказать, как можно корректно и универсально развернуть строку, то есть привести к следующему виду:

qw 12
as 34
df 56
rt 67
fg 87
gh 89
qw 98
fg 09

Воспользуйтесь методом DataFrame.stack():

res = df.stack().reset_index(name="val").drop(columns="level_0").rename(columns={"level_1":"key"})

результат:

In [194]: res
Out[194]:
    key  val
0    qw   12
1    as   34
2    df   56
3    rt   67
4    fg   87
5    gh   89
6  qw.1   98
7  fg.1    9

если нужно получить Pandas.Series:

In [196]: df.stack().reset_index(level=0, drop=True)
Out[196]:
qw      12
as      34
df      56
rt      67
fg      87
gh      89
qw.1    98
fg.1     9
dtype: int64

или же просто транспонировать:

In [199]: df.T
Out[199]:
       0
qw    12
as    34
df    56
rt    67
fg    87
gh    89
qw.1  98
fg.1   9


При изменении переменной меняется и аргумент в lambda python [дубликат]

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

Создание списка кнопок с разными параметрами обработчика нажатия

                                (1 ответ)

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

Я получаю информацию из файла, а потом вызываю функцию
select_user.
Вот упрощённая версия кода:

from tkinter import * # Использую tkinter для графического интерфейса

a_txt = open("a.txt", encoding = "utf8").read() # Читает файл a.txt
a = {}
for i in a_txt.split("\n"): # При каждой строке файла выполняет следующее
    a_tab = a.split("\t")
    a[a_tab[0]] = a_tab[1] # Обнаруживая таб в файле, разделяет его на две части и записывает в a

tk = Tk()

def select_user(clid):
    print(clid)

for name, clid in a.items():
    b = Button(tk, text = name, command = lambda: select_user(clid)) # Создаёт кнопку
    b.place(relx = 0.034, rely = 0.08) # Размещает кнопку на экране (в оригинальном коде они помещаются на экран в разные места)

Вот файл a.txt (вместо четырёх пробелов там табы):

Название1    0
Название2    1
Название3    2

Проблема заключается в том, что аргумент
clid изменяется с каждой итерацией
for и при нажатии кнопки передаётся самый последний результат.
Вот результат нажатия на 3 разные кнопки:

2
2
2

Есть ли возможность как-нибудь по другому вызвать функцию с аргументом (и чтобы аргумент не менялся) при нажатии кнопки в
tkinter?
Надо сделать так, чтобы при нажатии на первую кнопку чтобы результатом был
0, на вторую
1, а на третью
2

Это поведение особенность лямбд при циклах. Чтобы обойти проблему нужно в лямбде значение задавать как параметр с значением, поэтому вместо
lambda: select_user(clid) нужно писать
lambda clid=clid: select_user(clid) (т.е. мы объявили лямбду с параметром
clid, у которого значение по-умолчанию берется из переменной
clid)
Пример:

b = Button(tk, text = name, command=lambda clid=clid: select_user(clid))


Как заставить пользователя вновь выбирать нужный вариант ответа?
Как "заставить" пользователя заново выбирать одну из предложенных цифр, если он решил пойти против "правил"?
<code>
print ("Добро пожаловать")
trin = input ("""Каким путём ты хочешь пойти?
1. Простым.
2. Сложным. """)
if trin == '1':
    print ("Как скажешь. ")
if trin == '2':
    prin ("Так держать!")
else:
    print ("Такого варианта нет, выбери цифру ещё раз. ")
</code>
У меня есть предположения, что это делается через циклы, но не знаю,
Как это правильно написать, чтобы всё работало?

Можно и через циклы:
<code>
print("Добро пожаловать!")

trin = None

while trin not in ['1', '2']:
    trin = input("""Каким путём ты хочешь пойти?
    1. Простым.
    2. Сложным. """)

    if trin == '1':
        print("Как скажешь.")
    elif trin == '2':
        print("Так держать!")
    else:
        print("Такого варианта нет, выбери цифру ещё раз. ")

print("Спасибо за сделанный выбор")
</code>


Нужна помощь в реализации комментариев на Django
Если быть точнее, нужно переписать рабочую функцию на класс DetailView или же предложить лучшую реализацию. И было бы здорово получить решение привязки Юзера к комментарию, так как в моем случае приходиться выбирать из всех существующих. Заранее спасибо!
Функция:

def product_detail(request, pk):
    template_name = 'main/product_detail.html'
    product = get_object_or_404(Product, pk=pk)
    comments = product.comments.filter(active=True)
    new_comment = None
    # Comment posted
    if request.method == 'POST':
        form = CommentForm(data=request.POST)
        if form.is_valid():

            # Create Comment object but don't save to database yet
            new_comment = form.save(commit=False)
            # Assign the current post to the comment
            new_comment.product = product
            # Save the comment to the database
            new_comment.save()
    else:
        form = CommentForm()

    return render(request, template_name, {'product': product,
                                           'comments': comments,
                                           'new_comment': new_comment,
                                           'form': form})

Модель:

class Comment(models.Model):
    product = models.ForeignKey(Product,on_delete=models.CASCADE,related_name='comments')
    username = models.ForeignKey(Profile, on_delete=models.CASCADE)
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=False)

    class Meta:
        ordering = ['created_on']

    def __str__(self):
        return 'Comment {} by {}'.format(self.body, self.username)

Форма:

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('username', 'body')

Шаблон:

<!-- comments -->
        <h2>{{ comments.count }} comments</h2>
              <hr>
 {% for comment in comments %}
            <p>{{ comment.body | linebreaks }}</p>
            <small class="text-muted">Posted by <b>{{ comment.username }}</b> on {{ comment.created_on }}</small><br><br>
{% endfor %}
            <hr>

        {% if new_comment %}
        <div class="alert alert-success" role="alert">
          Your comment is awaiting moderation
        </div>
        {% else %}
        <h3>Leave a comment</h3>
        <form action="." method="post" style="margin-top: 1.3em;">
          {{ form.as_p }}
          {% csrf_token %}
          <button type="submit" class="btn btn-success">Leave a Review</button>
        </form>
        {% endif %}

Если я правильно понял, то привязать юзера к модели cледует так:

class Comment(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)

А потом перед тем как будешь сохранять форму:

 form.user = request.user
 form.save()

А по поводу переписать функцию на класс можешь взять этот пример.

class Detail(DetailView):
    model = MyModel
    template_name = 'mymodel_detail.html'

    def get_context_data(self, **kwargs):
        context = super(Detail, self).get_context_data(**kwargs)
        context['form'] = DetailForm
        return context

    def post(self, request, *args, **kwargs):
        form = DetailForm(request.POST, request.FILES)
        if form.is_valid():
            # Write Your Logic here

            self.object = self.get_object()
            context = super(Detail, self).get_context_data(**kwargs)
            context['form'] = DetailForm
            return self.render_to_response(context=context)

        else:
            self.object = self.get_object()
            context = super(Detail, self).get_context_data(**kwargs)
            context['form'] = form
            return self.render_to_response( context=context)


Почему не работает timeit Python?
<code>
result = [[], [], [], []]
methods = [
    'method1(texts_array[y])',
    'method2(texts_array[y])',
    'method3(texts_array[y])',
    'method4(texts_array[y])',
]
texts_array = [
    'wergwergwreg',
    'wrggtvxfgafd',
    'hwrthwrthrtb',
    'qerdcjuiuolj',
]

def method1(text):
    print(text + '123' + text)

def method2(text):
    print(text + '123')

def method3(text):
    print(text)

def method4(text):
    print(text + text)

def method_name():
    for x in range(len(methods)):
        for y in range(len(texts_array)):
            result[x].append(timeit.timeit(methods[x], globals=globals(), number=100) / 100)

method_name()
</code>
Почему не работает timeit? Появляется ошибка: NameError: name 'y' is not defined.
По идее, я ведь написал globals=globals().
Если двойной цикл вынести из метода, тогда все будет работать, но так не подходит, нужно, чтобы он был в методе.

У вас
y - это локальная переменная. Её можно передать, объединив
globals() c
locals(). Но дальше у вашего кода будет ещё много ошибок.
Так что вот рабочий пример:

import timeit

result = []
methods = [
    'method1(text)',
    'method2(text)',
    'method3(text)',
    'method4(text)',
]
texts_array = [
    'wergwergwreg',
    'wrggtvxfgafd',
    'hwrthwrthrtb',
    'qerdcjuiuolj',
]

setup="""
def method1(text):
    print(text + '123' + text)

def method2(text):
    print(text + '123')

def method3(text):
    print(text)

def method4(text):
    print(text + text)
"""

def method_name():
    number = 100
    for method in methods:
        result.append([])
        for text in texts_array:
            result[-1].append(timeit.timeit(method, globals={**globals(), **locals()}, setup=setup, number=number) / number)

method_name()
print(result)


Как перемешать два списка?
Подскажите пожалуйста, как перемешать два списка?
Например из:

l1 = [1, 2, 3]
l2 = ['test1', 'test2', 'test3']

получить:

['test1', 1, 'test2', 2, 'test3', 3]

Если ключевым является "перемешать", воспользуйтесь random.shuffle():

import random

l1=[1, 2, 3]
l2=['test1', 'test2', 'test3']

l3 = l1 + l2
print(f'before: {l3}')

random.shuffle(l3)
print(f'after:  {l3}')

выведет:

before: [1, 2, 3, 'test1', 'test2', 'test3']
after:  ['test3', 2, 3, 'test2', 'test1', 1]


Игнорирование ключевого слова в update запросе
Приключилась досадная ситуация, имя одного из полей таблицы, которую я использую совпадает с ключевым словом pass. При попытке создать update запрос, с указанием этого поля в values выкидывает синтаксическую ошибку. Подскажите как можно обойти эту ситуацию? Поле переименовать невозможно, т.к таблица используется и другими сервисами.
<code>
engine = create_engine(config.user_base_data ,echo = False)
meta = MetaData(engine)
connector = engine.connect()

client = Table('client' , meta, autoload = True)
client_ip = Table('client_ip', meta, autoload = True, )
ip_tariff = Table('ip_tariff', meta, autoload = True)
payment = Table('payment', meta, autoload = True)

def update_password(message, password, login):
    if password == message.text:текст, выделенный жирным шрифтом
        password_update_query = update(client).where(client.c.id == login).values(pass = password)
        password_update = connector.execute(password_update_query)
        bot.send_message(message.chat.id, 'Пароль изменен')
    else:
        bot.send_message(message.chat.id, 'Пароли не совпадают')
</code>

Передавайте аргументы разворачивая kwargs:

update(client).where(client.c.id == login).values(**{'pass': password})

Эта проблема не имеет отношения к sqlalchemy или sql. В питоне нельзя использовать ключевые слова в качестве имен:

>>> def f(**kwargs):
...   print(kwargs)
...
>>> f(pass=1)
  File "<stdin>", line 1
    f(pass=1)
         ^
SyntaxError: invalid syntax
>>> f(**{'pass': 1})
{'pass': 1}


Замена значения из списка
Как заменить nan на 5 в списке
q = [nan,10,nan,nan]?

Предполагаемо, что
nan это
float('nan')

import math

q = [float('nan'), float('nan'), 10, float('nan'), 9]
[ 5 if math.isnan(i) else i for i in q]  # [5, 5, 10, 5, 9]


Алгоритмическая задача на питоне ("Тимофей ищет место для строительства своего дома")
Всем привет! Совсем недавно начал изучать алгоритмические задачи на питоне и наткнулся на одну задачу, которую никак не могу решить. Прошу вашей помощи(если несложно, можно побольше объяснений):
Улица, на которой хочет жить Тимофей, имеет длину n, то есть состоит из n одинаковых идущих подряд участков. На каждом участке либо уже построен дом, либо участок пустой. Тимофей ищет место для строительства своего дома. Он очень общителен и не хочет жить далеко от других людей, живущих на этой улице.
Чтобы оптимально выбрать место для строительства, Тимофей хочет для каждого участка знать расстояние до ближайшего пустого участка. (Для пустого участка эта величина будет равна нулю –— расстояние до самого себя).
Ваша задача –— помочь Тимофею посчитать искомые расстояния. Для этого у вас есть карта улицы. Дома в городе Тимофея нумеровались в том порядке, в котором строились, поэтому их номера на карте никак не упорядочены. Пустые участки обозначены нулями.
Формат ввода
В первой строке дана длина улицы —– n (1 ≤ n ≤ 106). В следующей строке записаны n целых неотрицательных чисел — номера домов и обозначения пустых участков на карте (нули). Гарантируется, что в последовательности есть хотя бы один ноль. Номера домов (положительные числа) уникальны и не превосходят 109.
Формат вывода
Для каждого из участков выведите расстояние до ближайшего нуля. Числа выводите в одну строку, разделяя их пробелами.
Пример 1:
Ввод:
5
0 1 4 9 0
Вывод:
0 1 2 1 0
Пример 2:
Ввод:
6
0 7 9 4 8 20
Вывод:
0 1 2 3 4 5
Python | Ограничение времени: 3 сек | Ограничение памяти: 256 мб
По моим догадкам, нам надо найти расстояние до ближайшего участка слева, потом для ближайшего участка справа, следующий этап: ближайший пустой дом - это или ближайший слева, или ближайший справа.
Код:
<code>
n = int(input())
numbers = input().split()
for i in range(n):
    if numbers[i] != '0':
        l = 10**6
        for a in range(n):
            if numbers[i - a] == '0':
                if a <= i and l > a:
                    l = a
                if a > i and l > n - a:
                    l = n - a
            numbers[i] = l
print(*numbers)
</code>

Ваш алгоритм работает за квадрат от числа участков. Вам нужен линейный алгоритм.
Вычислите расстояние до нуля слева. Это легко сделать последовательно. Если в предыдущем участке расстояние было
d, то в следующем оно будет
d + 1 или ноль. В начало последовательности до первого нуля впишем большие числа.
Расстояние до нуля справа считается также, только надо перевернуть последовательность участков и потом перевернуть результат.
От двух последовательностей берем минимум поэлементно.
Готово:

def zero_dists(start, seq):
    d = start
    for n in seq:
        if n == '0':
            d = 0
        else:
            d += 1
        yield d

input()
numbers = input().split()

to_left = zero_dists(len(numbers), numbers)
to_right = reversed(tuple(zero_dists(len(numbers), reversed(numbers))))

print(*map(min, zip(to_left, to_right)))

$ echo -e "5\n0 1 4 9 0" | python nearest_zeros_2.py
0 1 2 1 0

$ echo -e "6\n0 7 9 4 8 20" | python nearest_zeros_2.py
0 1 2 3 4 5


Как в discord.py сделать функцию которая будет выбирать один из двух вариантов?
Пытаюсь сделать discord бота на python и хочу сделать функцию,которая будет рандомно выбирать либо "орёл" ,либо "решка",но не знаю как.

Можно использовать библиотеку
random. Через нее уже куча вариантов решения, примеры:

Через выбор из списка:

import random
variants = ['орел', 'решка']
print(random.choice(variants))

Через случайное число:
Этот метод стоит использовать, когда вам нужно изменить шансы, то есть не только 50 на 50

import random
choice = random.randint(0, 100) # случайное число от 0 до 100
if choice < 30:
   print('Первый вариант (шанс выпадения 30%)')
else:
   print('Второй вариант (шанс выпадения 70%)')

Сама функция может быть оформлена примерно так:

import discord, random
from discord.ext import commands

bot = commands.Bot(command_prefix='!', intents = discord.Intents.all())

@bot.command()
async def орел_решка(ctx):
    await ctx.send(random.choice(['орел', 'решка']))

bot.run(TOKEN)

Ну или другими методами. Вызов функции в чате дискорда:
!орел_решка
Не забудьте указать ваш токен в конце!


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

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

items = set()

items.add('факел')
items.add('меч')

if 'меч' in items:
    kill_monsters()
else:
    flee()

А если одинаковых предметов может быть много, то можно использовать коллекцию "словарь":

items = dict()

items['золото'] = 100
items['бутерброды'] = 5

if health < 10:
    if items['бутерброды'] > 0:
        health += 100
        items['бутерброды'] -= 1


Python telebot не работает проверка подписки
есть вот такой код:
<code>
import telebot
from telebot import *
import requests
import json

bot = telebot.TeleBot('My_token')

@bot.message_handler(commands=['start'])
def start_command(message):
    bot.send_message(message.chat.id, "Hello")
    print(message.from_user.id)
    print('2')
    CHAT_ID = -....
    USER_ID = ....
    result = bot.get_chat_member(CHAT_ID, USER_ID)
    print(result)
    print("ok")

bot.polling(none_stop=True, interval=0)
</code>
и в result он мне возвращает данные пользователя который не разу не вступал в группу хотя должен был выдавать ошибку что пользователь не состоит в группе
Что я делаю не так?

в result есть слово "status:" и там будет написано member вступил, left вышел, creator создатель и тд.


Счетаем значения по кол-ву пропусков в ряде
Как вычислить значения
a=0,b=0,c=0 из списка h? Значения формируем путем подсчета пропусков между цифрами.

h = [nan,10,nan,nan,20,20,nan,nan,nan,5,nan,4,nan]

Сначала между 10 и 20 - это будет значение
а = 3. Затем 20 и 5 - это будет значение
b=5 (20,20 - подряд не считается, берем только первое), затем 5 и 4 - это значение
c=2.
a,b,c это три значения которые будут получены, но например для
c может не хватить значения из списка, тогда оно все еще будет 0. Также может появится дополнительная буква d к примеру, поэтому делаю на вырост так сказать.
Как можно правильно сделать такое, максимально компактно в пару строчек?

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

nan = None
h = [nan,10,nan,nan,20,20,nan,nan,nan,5,nan,4,nan]

last_num = None
res = [1]
for elem in h:
    if elem in (nan, last_num):
        res[-1] += 1
    else:
        res.append(1)
        last_num = elem

res = res[1:-1]
print(res)

Результат:

[3, 5, 2]


Код для формирования результата для
Polygon сделал по коду в вашем ответе, надеюсь, что правильно понял. Если что-то неправильно, добавьте пример результата для
Polygon в вопрос.

import ast

from collections import defaultdict
from operator import itemgetter

anno_data=[['Item1', 'Rectangle', 'label1', '018', '[276, 22]', '[18.0, 21.0]'],
           ['Item1', 'Polygon', 'label1', '018', '[[199.0, 179.0], [200.0, 179.0], [201.0, 179.0], [202.0, 179.0], [203.0, 179.0], [204.0, 179.0], [207.0, 211.0], [206.0, 211.0], [205.0, 211.0], [204.0, 211.0], [203.0, 211.0], [202.0, 211.0], [201.0, 211.0], [200.0, 211.0], [199.0, 211.0], [198.0, 211.0], [197.0, 211.0], [195.0, 210.0], [194.0, 209.0], [192.0, 207.0], [191.0, 206.0], [192.0, 206.0]]', ''],
           ['Item1', 'Point', 'label1', '018', '[380, 171]', ''],
           ['Item2', 'Rectangle', 'label1', '032', '[67, 80]', '[39.0, 46.0]']]

d = defaultdict(lambda : dict(regions=dict()))

for row in anno_data:
    file_data = d[row[3]]
    file_data['filename'] = row[3]

    regions = file_data['regions']

    if row[1] == 'Rectangle':
        # Вытаскиваем список из строки с помощью literal_eval, и сразу распаковываем в отдельные переменные
        x, y = ast.literal_eval(row[4])
        width, height = ast.literal_eval(row[5])
        shape_attributes = dict(
            name=row[1],
            x=x,
            y=y,
            width=width,
            height=height
        )
    elif row[1] == 'Point':
        x, y = ast.literal_eval(row[4])
        shape_attributes = dict(
            name=row[1],
            cx=x,
            cy=y
        )
    elif row[1] == 'Polygon':
        points = ast.literal_eval(row[4])
        # zip тут превращает большой список из маленьких списков по 2 элемента в два длинных списка
        # (один для x координат, другой для y), и дальше эти два списка распаковываем в отдельные переменные
        all_points_x, all_points_y = zip(*points)
        shape_attributes = dict(
            name=row[1],
            all_points_x=all_points_x,
            all_points_y=all_points_y
        )
    else:
        raise ValueError(f"Неизвестная фигура: {row[1]}")

    # Вычисление следующего индекса: максимальное целочисленное значение ключа + 1, или 0, если еще ничего нет
    index = max(map(int, regions.keys()), default=-1) + 1
    regions[str(index)] = dict(
        shape_attributes=shape_attributes,
        region_attributes=dict(label=row[2])
    )

# Если обязательно нужен словарь, а не defaultdict, то выполнить следующую строчку:
d = dict(d)

# json только для красивого вывода
import json
print(json.dumps(d, indent=4))

Результат:

{
    "018": {
        "regions": {
            "0": {
                "shape_attributes": {
                    "name": "Rectangle",
                    "x": 276,
                    "y": 22,
                    "width": 18.0,
                    "height": 21.0
                },
                "region_attributes": {
                    "label": "label1"
                }
            },
            "1": {
                "shape_attributes": {
                    "name": "Polygon",
                    "all_points_x": [
                        199.0,
                        200.0,
                        201.0,
                        202.0,
                        203.0,
                        204.0,
                        207.0,
                        206.0,
                        205.0,
                        204.0,
                        203.0,
                        202.0,
                        201.0,
                        200.0,
                        199.0,
                        198.0,
                        197.0,
                        195.0,
                        194.0,
                        192.0,
                        191.0,
                        192.0
                    ],
                    "all_points_y": [
                        179.0,
                        179.0,
                        179.0,
                        179.0,
                        179.0,
                        179.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        211.0,
                        210.0,
                        209.0,
                        207.0,
                        206.0,
                        206.0
                    ]
                },
                "region_attributes": {
                    "label": "label1"
                }
            },
            "2": {
                "shape_attributes": {
                    "name": "Point",
                    "cx": 380,
                    "cy": 171
                },
                "region_attributes": {
                    "label": "label1"
                }
            }
        },
        "filename": "018"
    },
    "032": {
        "regions": {
            "0": {
                "shape_attributes": {
                    "name": "Rectangle",
                    "x": 67,
                    "y": 80,
                    "width": 39.0,
                    "height": 46.0
                },
                "region_attributes": {
                    "label": "label1"
                }
            }
        },
        "filename": "032"
    }
}


Есть числа по порядку, но с пропусками. Как получить интервалы?
Есть некий интервал чисел с пропусками, например: 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20. Как получить вместо списка интервалы: 1-3, 5-7, 9-12, 15-20 ?

Функция
events выдаёт наружу события. В события включаются концы последовательности чисел и пары чисел окружающих дыры.
Функция
ranges соединяет события в пары. Эти пары и есть ответ:

def events(seq):
    it = iter(seq)
    try:
        p = next(it)
    except StopIteration:
        return
    yield p
    for v in it:
        if p < v - 1:
            yield p
            yield v
        p = v
    yield p

def ranges(seq):
    return zip(*[iter(events(seq))] * 2)

values = 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20
print(*events(values))
print(*ranges(values))

$ python ranges_in_list.py
1 3 5 7 9 12 15 20
(1, 3) (5, 7) (9, 12) (15, 20)


Проверить предыдущее значение
Как проверить что предыдущее значение в списке больше 0?

ff = [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0]

Вот так проверяем что текушее ff значение больше 0:

for u in ff:
    if u > 0:
        print(1)

а как проверить u предыдущее (ff-1)?


Django. Как отправить действие во views.py
Входные данные:
Имеется сайт на
Django. Одна из
template содержит 20 кнопок для обнуления некоторых данных в базе данных. Пользуются данной страницей не часто и то только избранные, поэтому вопроса о логичности данного решения я не ставлю. Каждая кнопка уникальна и при нажатии пересылает некоторые данные во
views.py (назовем их
регистр и
состояние).
Как работает сейчас
Каждая кнопка оборачивается в
<form action="" method="post"></form> и содержит скрытые
input, которые содержат необходимые флаги для манипуляций на стороне сервера и БД. Во
views.py смотрятся какие
регистр и
состояние пришли из
template  и по флагу направляется в одну из веток
if, и относительно этого строятся запросы к БД и логика поведения.
Что не так
При нажатии на любую кнопку во
views.py летят все
input,
csrf-токены и прочий не нужный мусор.
Вопрос
Есть ли решение, которое позволяет одназначно определить нажатие кнопки для метода
POST, чтобы не затрагивать всю информацию со страницы, а получить один токен и одну пару
регистр:
состояние? Плюс избежать загромождающую логику во
views.py, которая содержит "миллион"
if-ов
В решениях на SO примеры почти все одинаковые и реализовано как описано выше в пункте "Как работает сейчас"

Сделайте для каждой кнопки свой метод во views.py:

def action1(request):
  ...

def action2(request):
  ...

Добавьте их в urls.py:

urlpatterns = [
    url(r'^existing/path/action1', views.action1),
    url(r'^existing/path/action2', views.action2),
    ...
]

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

<form action="action1" method="post">
  ... тут только параметры для action1
</form>


Ошибка при обучении сверточной нейросети Keras
Я только начинаю изучать нейросети и у меня появился задача( предсказание временного ряда ) под которую нужно обучить сверточную нейросеть. Привожу пример кода, размерности такие же как и в моей модели, но запустить никак не получается, не пойму в чем я ошибаюсь
<code>
import random
import numpy as np
import tensorflow as tf
import pandas as pd
from tensorflow import keras
from tensorflow.keras.layers import Dense, BatchNormalization, LeakyReLU
from tensorflow.keras.layers import Activation, Input, MaxPooling1D, Dropout
from tensorflow.keras.layers import AveragePooling1D, Conv1D, Flatten
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.optimizers import Adam, RMSprop, SGD

a = np.random.uniform(1, 2, (1000, 60, 1))
c = np.random.uniform(90, 120, (1000, 60, 1))
X_train = np.concatenate([a, c], axis = 2)
y_train = np.random.randint(0, 10, (1000, 60, 1))

model = Sequential()
model.add( Conv1D( filters=32, kernel_size=5, padding="same", strides=1,
                   input_shape= X_train.shape[1:]))
model.add(MaxPooling1D(pool_size=2, strides=2))
model.add(Flatten())
model.add(   Dense(128, activation='relu'))
model.add(   Dense(60,  activation='softmax'))

model.compile(optimizer='adam',
             loss='categorical_crossentropy',
             metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=60, epochs=5, validation_split=0.2)
</code>


Как сложить числа находящиеся в строке?
<code>
numbers = "22.32 3.74 4.67 "
print(sum(numbers))
</code>
Как получить сумму чисел, находящихся в строке?

Разложите строку на числа (по пробелу), а элементы переведите во флоат:

str_num = "22.32      3.74     4.67               "
nums_sum = sum(float(x) for x in str_num.split())

>>> nums_sum
30.730000000000004

или

nums_sum = round(sum(float(x) for x in str_num.split()), 2)

чтоб округлить сразу ответ


Как проверить слово на отсутствие смешивания кириллицы и латинского алфавита?
Проверка слова на отсутствие смешивания кириллицы и латинского алфавита. Вопрос заключается в том, как можно производить проверку текста (текст из БД), чтобы в одном слове не было букв латинского и русского алфавита?
Например "o [ou], p [pi:], c [si:], a [ei]" не заменяли аналогичные буквы русского алфавита и слово "горох" не было введено "гo([ou])pox", также в обратную сторону английское слово не должно содержать русских букв.
P.S. изначально не известно перед проверкой на каком языке написано слово, т.е. необходимо проверить, если ли в слове сочетания букв из двух разных алфавитов.

Проверка на то, все ли буквы из латинского алфавита:

import string

def all_en(word):
    if all(c in string.ascii_letters for c in word):
        return True
    return False

Такая же проверка на русские буквы может быть разной, в зависимости от того, могут ли в словах быть цифры и прочие знаки (подчеркивание, например).
Можно, например, просто проверять, находится ли код символа в нужном диапазоне. Для UTF-8 можно использовать такой вариант:

def all_ru(word):
    for letter in word:
        if ord(letter) < 1040 or ord(letter) > 1103:
            return False
    return True

1040 - 1103 (0x410 - 0x44f) это диапазон кодов для русского алфавита (без "Ёё"). Для ё/Ё нужно еще добавить проверку на равенство 1025 или 1105 (0x401 / 0x451):

def all_ru(word): # немного оптимизировал еще тут
    for letter in word:
        code = ord(letter)
        if not(1040 < code < 1103) and code != 1025 and code != 1105:
            return False
    return True

Ну и то, что вам нужно, в итоге таким образом:

def contains_en_and_ru(word):
    if not all_ru(word) and not all_en(word):
        return True # есть латинские и кириллица
    return False # только латинские или только кириллица


Декомпозиция в python. Как передать параметры в функцию? [дубликат]

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

Что значит * (звёздочка) и ** двойная звёздочка в параметрах функций?

                                (2 ответа)

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

Хочу передать в функцию словарь с аргументами.
Например, в
javascript можно сделать так:

const dict = {
   a: 1,
   b: 2,
};

function test(incomingDict) {
  const {a, b} = incomingDict;
}

test(dict)

А как в
python такое повторить?
Пришло в голову так:

dict = {
    "a": 1,
    "b": 2,
}

def test(incoming_dict):
    a = incoming_dict["a"]
    b = incoming_dict["b"]

test(dict)

Есть идеи? Как "красиво" передавать множество параметров... Больше пяти, скажем.

Можно передать через "двойную звездочку", тогда словарь распакуется в параметры с соответствующими ключам именами:
<code>
d = {
    "a": 1,
    "b": 2,
}

def test(a, b):
    print(a, b)  # Выведет 1, 2

test(**d)
</code>


код на wxpython не работает
Этот код

import wx,os

class FileManager(wx.Panel):
    def __init__(self,*args, **kwargs):
        super().__init__(*args, **kwargs)
        self.l=list(os.listdir(r'C:\Windows\System32'))
        self.list=wx.ListBox(self,choices=self.l)
        self.sizer=wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.list,1,wx.EXPAND|wx.ALL)
        self.SetSizer(self.sizer)

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.top_splitter=Splitter(self)
        self.top_splitter.SetMinimumPaneSize(150)
        file_manager=FileManager(self.top_splitter)
        control=Control(self.top_splitter,wx.TE_MULTILINE)
        self.top_splitter.split_vertically(file_manager,control)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.top_splitter, 1, wx.EXPAND)
        self.SetSizer(sizer)
class Splitter(wx.SplitterWindow):
    def __init__(self,*args,**kw):
        super().__init__(*args,**kw)
    def split_vertically(self,first,second):
        self.SplitVertically(first,second)
    def split_horizontally(self,first,second):
        self.SplitHorizontally(first,second)
class Control(wx.Panel):
    def __init__(self,*args,**kw):
        super().__init__(*args,**kw)
        self.sizer=wx.BoxSizer()
        self.sizer.Add(self)
        self.SetSizer(self.sizer)
app = wx.App()
editor = Frame(None, title='wxPython')
editor.Show()

app.MainLoop()

Возвращает

Process returned 3221226525 (0xc000041d)        execution time : 4.721 s
Для продолжения нажмите любую клавишу . . .

И не открывает окно. Как исправить?

В сайзер панели
Control вы добавляете саму эту панель. Конечно же так делать нельзя.
Если убрать
self.sizer.Add(self), программа запускается.


Как правильно конвертировать binary столбец в string?
Как правильно конвертировать
binary столбец в
string?
Дело в том, что столбец, откуда тянутся данные в binary, использую методы
str,
to_string, попадают так -
b'\x80\xc6\x10K\xa8\x95\xd8\x11\xe6\r\x...
, но в самой БД 0x80C610604BA895D811E60DE464C54D74` (откуда тянется).
Если не использовать эти методы, то попадают как
\x80C610604BA895D811E60DE464C54D74.
Может кто-то сталкивался с такой проблемой ?

engine = create_engine('...')
df = pd.read_sql("""Select id_bin from table1""",engine)
local_port = str(server.local_bind_port)
df.index +=1
df['id_bin']=str(df['id_bin'])
engine1 = create_engine('..')
pd1 = engine1.execute("""Truncate table table2""")
df.to_sql('table2',con=engine1,if_exists='append',index_label='id')

Попробуйте так:
<code>
df = pd.read_sql("""select convert(varchar(1000), id_bin, 2) from table1""", engine)

</code>


Вывод изображения из массива numpy в colab
Есть .tif изображения считанные и записанные в массив numpy:

train_images = []
for directory_path in glob.glob('/content/gdrive/My Drive/Image_dataset/sandstone/images_train_128_patches_stone'):
    for img_path in glob.glob(os.path.join(directory_path, "*.tif")):
        #Считывание изображения в (RGB-1)
        img = cv2.imread(img_path, 1)
        img = cv2.resize(img, (SIZE_Y, SIZE_X))
        #img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
        train_images.append(img)

train_images = np.array(train_images)
print(train_images.shape) #(1600, 128, 128, 3)

train_masks = []
for directory_path in glob.glob('/content/gdrive/My Drive/Image_dataset/sandstone/masks_train_128_patches_stone'):
    for mask_path in glob.glob(os.path.join(directory_path, "*.tif")):
        #Считывание изображения в оттенках серого
        mask = cv2.imread(mask_path, 0)
        mask = cv2.resize(mask, (SIZE_Y, SIZE_X), interpolation = cv2.INTER_NEAREST)  #Otherwise ground truth changes due to interpolation
        #img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
        train_masks.append(mask)

train_masks = np.array(train_masks)
print(train_masks.shape) # (1600, 128, 128)

Далее кодирую метки для классов изображений масок:

from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
# Возвращает размерности массивов (уровней массивов)
number_images, height, width = train_masks.shape
print("Размерности массивов: ", train_masks.shape)
print("Class values in the dataset are ... ", np.unique(train_masks))
# Изменение представления массива (перестройка уровней)
train_masks_reshaped = train_masks.reshape(-1,1)
print("Размерности массивов: ", train_masks_reshaped.shape)
#Нормализует метки таким образом, чтобы они содержали только значения от 0 до n_classes-1
#Tакже можно использовать для преобразования нечисловых меток (если они хешируемы и сопоставимы) в числовые метки
train_masks_reshaped_encoded = labelencoder.fit_transform(train_masks_reshaped)
train_masks_encoded_original_shape = train_masks_reshaped_encoded.reshape(number_images, height, width)
print("Class values in the dataset are ... ", np.unique(train_masks_encoded_original_shape))

Добавляю в массив с масками измерение с кодом класса маски:

train_masks_input = np.expand_dims(train_masks_encoded_original_shape, axis=3)
print(train_masks_input.shape) # (1600, 128, 128, 1)

Разбиваю на наборы:

from sklearn.model_selection import train_test_split
X1, X_test, y1, y_test = train_test_split(train_images, train_masks_input, test_size = 0.10, random_state = 0)
X_train, X_do_not_use, y_train, y_do_not_use = train_test_split(X1, y1, test_size = 0.5, random_state = 0)

print(X_train.shape) # (720, 128, 128, 3)
print(y_train.shape) # (720, 128, 128, 1)

И пытаюсь просмотреть соответствия между изображением и маской:

import random
import numpy as np
image_number = random.randint(0, len(X_train))
plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.imshow(np.reshape(X_train[image_number], (128, 128)), cmap='BGR')
#plt.imshow(X_train[image_number])
plt.subplot(122)
plt.imshow(np.reshape(y_train[image_number], (128, 128)), cmap='gray')
#plt.imshow(y_train[image_number])
plt.show()

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

plt.imshow(np.reshape(y_train[image_number], (128, 128)), cmap='gray')

В этой строке ошибка:

plt.imshow(np.reshape(X_train[image_number], (128, 128)), cmap='BGR')

ValueError: cannot reshape array of size 49152 into shape (128,128)

Подскажите в чем причина? Как это можно исправить?
Мне нужно после присвоения меток классов и разбития убедится, что маска соответствует изображению и вывести это на экран.
Судя по числу в ошибке, 49152=128x128x3

Судя по ошибке
reshape нужно делать в
(128, 128, 3), это подтверждает размерность
train_images выше по коду:
(1600, 128, 128, 3)
В вашем случае скорее всего
cmap вообще не нужен, а если палитра будет неправильная, её лучше преобразовать в явном виде, как у вас в коде закомментировано
#img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) (или наоборот надо
BGR2RGB, я точно не помню, но помню, что у
OpenCV вроде своя родная палитра
BGR, из-за этого могут быть несостыковки со стандартной палитрой картинок
RGB).


Проблема с определением последовательности на Python
Вводится список чисел, найти в нем самую длинную неубывающую цепочку чисел, в которой каждый элемент не превосходит 50.
Я решил так, но не при всех вводных данных оно считает правильно (например, при последовательности 2 3 1 3 4 5 6 3 2 1 выводит верно, в остальных случаях - нет). У меня вся программа не на той логике построена или где-то незначительная ошибка?
<code>
import copy
a = []
n = int(input())
for i in range(n):
    a.append(int(input()))
max_len, current_len = 1, 1
spis1 = []
spis2 = []
for i in range(1, len(a)):
    if a[i] >= a[i - 1] and a[i] < 50:
        current_len += 1
        max_len = max(max_len, current_len)
        spis1.append(a[i - 1])
        spis2 = spis1.copy()
        c = a[i]
    else:
        current_len = 1
        spis1.clear()
if spis1 != spis2:
    spis2.append(c)
    print(spis2)
else:
    spis1.append(c)
    print(spis1)
</code>

current_len нужно назначать 1 только в случае, если элемент не превосходит 50.
Не вижу смысла хранить целый список с хорошей последовательностью - достаточно знать место  и длину.

import random
a = [random.randint(20,55) for _ in range(random.randint(5,15))]
print(a)
if a[0] <= 50:
    max_len, current_len, max_end = 1, 1, 0
else:
    max_len, current_len, max_end = 0, 0, -1

for i in range(1, len(a)):
    if (a[i] >= a[i - 1]) and (a[i] <= 50):
        current_len += 1
        if current_len > max_len:
            max_len = current_len
            max_end = i
    else:
        current_len = 1 if a[i] <= 50 else 0
        if current_len > max_len:
            max_len = current_len
            max_end = i
if max_len:
    print(max_len, a[max_end - max_len + 1: max_end+1])


Как вывести колонку ManyToManyField в admin и на сайте?
admin.py

from django.contrib import admin

from .models import Bd, Category

class AdminBd(admin.ModelAdmin):
    list_display = ('name', 'content')
    filter_horizontal = ['category', ]

admin.site.register(Bd, AdminBd)
admin.site.register(Category)

models.py

from django.db import models
from django.urls import reverse

class Category(models.Model):
    title = models.CharField(max_length=50, verbose_name='Категория')

    def __str__(self):
        return self.title

    def get_absolute_ulr(self):
        return reverse('category', kwargs={"category_id": self.pk})

    class Meta:
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'
        ordering = ['title', ]

class Bd(models.Model):
    name = models.CharField(max_length=50, verbose_name='Имя')
    content = models.TextField(max_length=1500, verbose_name='Именование')
    category = models.ManyToManyField('Category', verbose_name='Категория')
    photo = models.ImageField(upload_to='photo/%Y/%m/%d', blank=True, null=True, verbose_name='Картинка')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Дата публикации')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
    is_created = models.BooleanField(default=False, verbose_name='Создан мной')

    def __str__(self):
        return self.name

    def get_absolute_ulr(self):
        return reverse('view_news', kwargs={"news_id": self.pk})

    class Meta:
        verbose_name = 'Объявление'
        verbose_name_plural = 'Объявления'
        ordering = ['-updated_at', '-created_at']

views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Bd

def index(request):
    bd = Bd.objects.all()
    return render(request, 'news_test/index.html', {'bd': bd})

Я не давно делал такую задачу. Значит в модель нужно добавить метод:
def get_category(self):
return ",".join([str(p) for p in self.сategory.all()])
И в admin.p yказать его в list_display
list_display = ('name', 'content', 'get_category')


Как выбрать элементы в подгруппах groupby, или есть что то изящнее?
Есть два фрейма - ордера с налогами и справочник налога на каждый товар.
Нужно отобрать по каждому коду товара те ордера, в которых значение "налога" выше стандартного, взятого из "справочника".
Вот код:

import pandas as pd

def marker(g, epsilon):
    """Mark."""
    g = g.query("fee + fee_preview < -@epsilon")
    return g

df_orders = pd.DataFrame({
    "order_id": list(range(1, 14)),
    "sku": 9 * ["a", ] + 4 * ["b", ],
    "fee_amount": [-1, -1, -1, -1, -1.1, -0.8, -1.1, -2, -2, -2.1, -2.1, -2.1, -4.3],
    "quanty": 7 * [1, ] + 2 * [2, ] + 3 * [1, ] + [2, ],
})

print(df_orders)

df_fee = pd.DataFrame({
    "fee": [1, 0.8, 2.1, 4.3],
    "sku": ["a", "d", "b", "g"],
})

print(df_fee)

df_orders["fee"] = df_orders["fee_amount"] / df_orders["quanty"]

df = df_orders.join(df_fee.set_index("sku"), on="sku", rsuffix="_preview")

dd = df.groupby("sku").apply(marker, 0.005)
print(dd)

Все отрабатывает, вот результат:

        order_id sku  fee_amount  quanty
0          1   a        -1.0       1
1          2   a        -1.0       1
2          3   a        -1.0       1
3          4   a        -1.0       1
4          5   a        -1.1       1
5          6   a        -0.8       1
6          7   a        -1.1       1
7          8   a        -2.0       2
8          9   a        -2.0       2
9         10   b        -2.1       1
10        11   b        -2.1       1
11        12   b        -2.1       1
12        13   b        -4.3       2
   fee sku
0  1.0   a
1  0.8   d
2  2.1   b
3  4.3   g
        order_id sku  fee_amount  quanty   fee  fee_preview
sku
a   4          5   a        -1.1       1 -1.10          1.0
    6          7   a        -1.1       1 -1.10          1.0
b   12        13   b        -4.3       2 -2.15          2.1

Но меня смущает операция
.join(), раздувающая промежуточный фрейм.
Нет ли чего то "более SQL" подобного, или другого решения, боле экономно использующего память?

Львиная доля методов и функций в Pandas возвращают новый созданный результирующий DataFrame. Некоторые функции поддерживают параметр
inplace=True - замену DataFrame "на месте" с экономией памяти. Но сами разработчики Pandas считают эту, казалось бы, полезную фичу злом и хотят от нее избавиться в будущих версиях.
Поэтому ваше решение вполне нормальное.
В том случае если вам нужно добавить только один новый столбец, объединяя по другому столбцу, можно воспользоваться методом Series.map():

df_orders["fee_preview"] = df_orders["sku"].map(df_fee.set_index("sku")["fee"])

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


Ошибка AttributeError: 'Bot' object has no attribute 'split' discord.py[решён]
Хочу добавить калькулятор в своего discord бота,но при попытке запустить команду выдаёт ошибку

AttributeError: 'Bot' object has no attribute 'split'

Вот код:
<code>
import simpleeval
from simpleeval import simple_eval

@bot.command(pass_context=True)
async def калькулятор(ctx):
        _, math_str = message.split(' ', 1)
        result = simple_eval(math_str)
        print(result)
</code>
Как исправить?

Вы уверены, что ошибка возникает именно в указанной вами функции
калькулятор()?

AttributeError: 'Bot' object has no attribute 'split'

В тексте ошибки сказано, что вы пытаетесь разбить методом
split() не строку, а объект вашего бота -
discord.ext.commands.Bot(), но в прикрепленной вами функции такого действия нет.

Зато есть другая ошибка. В этой строке:

 _, math_str = message.split(' ', 1)

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

 _, math_str = ctx.message.content.split(' ', 1)

С объектом
Bot у вас, наверное, та же ситуация. Посмотрите внимательно, что вы делаете.


Минимальное положительное значение из списка Python
Я новичок, прошу объяснить как мне из списка
<code>
x = [-2, 0, -5, 5, 3]
</code>
вытащить минимальное положительное значение (тут это 3). Я понимаю что это можно сделать с помощью функции min() и значения key, но я пока слабо разбираюсь в лямбда функциях. Покажите как реализовать пожалуйста :)


При попытке запустить команду discord бот ничего не делает[решено]
Пишу бота для discord на python и пытался добавить таймер
<code>
@client.event
async def on_message(message):
    if message.content.startswith("таймер"):
        message.id=766947123312721930
        min=0
        sec=60
        while(sec != 0):
            sec-=1
            emb = discord.Embed(type="rich", colour=discord.Color.blurple(), description= f'До конца: {min} мин. {sec} сек.')
            await message.edit(embed = emb)
            await asyncio.sleep(0.25)
</code>
Но при попытке ввести команду #таймер выдают ошибку:

discord.ext.commands.errors.CommandNotFound: Command "таймер" is not found

Как исправить?

Вы используете объект
discord.ext.commands.Bot(), командой которого является отдельная асинхронная функция, помеченная декоратором
@bot.command(), где
bot - имя объекта вашего бота.
Вы же не создаете функцию команды, а просто пытаетесь обработать любое поступающее сообщение, путем сравнения первого слова. Если сообщение начинается с "#таймер", то обрабатываете его как команду.
Вообще, ваша текущая проблема решится, если в этой строке вы укажите "#" перед "таймер". То есть вот так:

if message.content.startswith("#таймер"):

Но в любом случае потом возникнут другие проблемы, так как код написан не совсем корректно. Ниже я немного поправил его и сделал правильное оформление команды бота :)

Вы используете объект
discord.ext.commands.Bot(), который умеет обрабатывать полноценные команды. Зачем тогда создавать такие "костыли" через проверку сообщения?
Правильнее будет заменить вашу "команду" на асинхронную функцию:

import discord, asyncio
from discord.ext import commands

bot = commands.Bot(command_prefix = '#')

@bot.command()
async def таймер(ctx):
    min=0
    sec=60
    emb = discord.Embed(type="rich", colour=discord.Color.blurple(), description= f'До конца: {min} мин. {sec} сек.')
    message = await ctx.send(embed = emb)
    while(sec != 0):
        sec-=1
        emb = discord.Embed(type="rich", colour=discord.Color.blurple(), description= f'До конца: {min} мин. {sec} сек.')
        await message.edit(embed = emb)
        await asyncio.sleep(0.25)

bot.run(TOKEN)

В конце укажите токен вашего бота!


Как напрямую читать файлы .dtl в DataFrame?
Анализирую логи, которые АСУТП сохраняет в файлы *.dtl. Чтобы импортировать их в DataFrame, сначала перевожу их в .xlsx с помощью утилиты производителя (Easy Builder).
Проблема в том, что у меня этих файлов тысячи, а конвертер за один раз больше 15 штук не принимает.
Есть ли какие-нибудь способы напрямую читать файлы .dtl?
Файл для примера прилагаю: download .dtl (31 kb).

Судя по документации утилита для конвертирования может работать из командной строки:

EasyConverter.exe /t1 /s "C:\Format.lgs" "C:\Src.dtl" "C:\Dest.xls"

Parameter Description

/c{a,8,u} Optional, specifies encoding method, only required when
exporting a .csv file.

/ca : ASCII (Default)

/c8 : UTF-8
/cu :
Unicode
/t{0,1} Optional, specifies whether or not to include
millisecond information.

EasyConverter EasyBuilder Pro V6.05.01

/t0 : Excludes millisecond information.

/t1 : Includes millisecond information. (Default)

/s Optional, specifies whether or not to import settings file. To
import settings file, specify the path of .lgs file following
/s.
For example:
/s "C:\Format.lgs"
"Src file" Specifies the source file path, and the file format should
be: .dtl, .evt, or .db
"Dest file" Specifies the destination file path, and the file format
can be: .xls or .csv. See Note.

Поэтому можно легко сгенерировать
.BAT /
.CMD файл, в котором данная утилита вызывается для каждого
.dtl файла.


Игнорирование ключевого слова pass
Приключилась досадная ситуация, имя одного из полей таблицы, к которой я обращаюсь посредствам sqlalchemy совпадает с ключевым словом pass. Поле переименовать возможности нет. Подскажите как можно обойти эту проблему?
<code>
engine = create_engine(config.user_base_data ,echo = False)
meta = MetaData(engine)
connector = engine.connect()

client = Table('client' , meta, autoload = True)
client_ip = Table('client_ip', meta, autoload = True, )
ip_tariff = Table('ip_tariff', meta, autoload = True)
payment = Table('payment', meta, autoload = True)

def check_logpass(message):
    userdata = message.text.split(' ') #Парсинг строки введенной пользователем
    login_for_check = userdata[0]
    password_for_check = userdata[1]
    logpass_query = select(client).where(and_(client.c.id == login_for_check, client.c.pass == password_for_check))
    result =  connector.execute(logpass_query)
</code>

Обращайтесь к полю через строку в таких случаях
<code>
# via string
client.c['pass']
</code>


Закрывает второе окно приложения сразу же после открытия
Открываю по нажатии кнопки второе окно, но оно сразу же закрывается.
В чем дело?
<code>
def form_settings_open(self):
        widget = QtWidgets.QMainWindow()
        widget.show()
</code>

Дело в том, что
widget это локальная переменная, которая удаляется сборщиком мусора. Продлите ей жизнь, сделайте ее атрибутом класса.

def form_settings_open(self):
    self.widget = QtWidgets.QMainWindow()
    self.widget.show()


Решение задачи на Python
Вроде бы все должно работать, но система не пропускает.
Дано четырехзначное число. Определите, является ли его десятичная запись симметричной.
Если число симметричное, то выведите 1, иначе выведите любое другое целое число.
Число может иметь меньше четырех знаков, тогда нужно считать, что его десятичная запись дополняется слева нулями. Десятичная запись числа симметрична, если при прочтении слева направо и справа налево получается одно и то же число.
При решении задачи можно пользоваться только целочисленными арифметическими операциями. Нельзя пользоваться нелинейными конструкциями: ветвлениями, циклами, функциями.
<code>
H = int(input())

f1 = (H // 1000)                                # первое число в четырехзначном
f12 = (H % 10)                                  # последнее число в четырехзначном
s1 = (H - (f1 * 1000)) // 100                   # второе слева число
w1 = (H - (f1 * 1000) - (s1 * 100)) // 10       # третье число слева
q = (f12 * 1000) + (w1 * 100) + (s1 * 10) + f1  # обираем с конца

print(H // q)
</code>
Помогите решить. Где моя ошибка?

В комментариях расписано, как и что считается.
<code>
V = int(input())
Axxx = V // 1000            # цифра на позиции тысяч
xBxx = V % 1000 // 100      # цифра на позиции сотен
xxBA = xBxx * 10 + Axxx     # зеркальное двузначное число из цифр сотен и тысяч
xxCD = V % 100              # младшая (правая) половина числа
symmetry = xxBA - xxCD      # если 0 - то исходное число симметрично
print(symmetry + 1)         # выведет 1 если symmetry = 0, иначе будет другое число
</code>


Вопрос по решению задачи про улитку на python
Нужно решить задачку на пайтон. Решить нужно используя только арифметику.
Улитка ползет по вертикальному шесту высотой H метров, поднимаясь за день на A метров, а за ночь спускаясь на B метров. На какой день улитка доползет до вершины шеста?
Программа получает на вход целые H, A, B. Гарантируется, что A > B ≥ 0.
Программа должна вывести одно натуральное число.
Придумал такое решение, но почему то не пропускает
<code>
H = int(input())
A = int(input())
B = int(input())
print(1 + (H - A) // (A - B))
</code>

Вот одно из решений.
<code>
H = int(input("Высота столба : "))
A = int(input("Пробег вверх за день : "))
B = int(input("Пробег вниз за ночь : "))

h_remain = H - A # остаток высоты столба после подъёма за день
d_day = A - B    # расстояние, на которое поднимется улитка за сутки
# классическая формула
days = (h_remain - 1) // d_day + 1 + 1  # второе +1 здесь эмулирует округление вверх
# или более сложная
# days = 1 + (h_remain // d_day) + (h_remain % d_day + d_day - 1) // d_day

print(days)
</code>


Pycharm Packaging error
Писал бота(discord.py) через repl.it все было хорошо. Но потребовалось перейти на pycharm, прописал в консоли pycharm pip install discord.py. Скопировал рабочий код и:
<code>
Traceback (most recent call last):
  File "/Users/nikita/PycharmProjects/KrBot/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 969, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 1081, in create_connection
    transport, protocol = await self._create_connection_transport(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 1111, in _create_connection_transport
    await waiter
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/sslproto.py", line 528, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/sslproto.py", line 188, in feed_ssldata
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 944, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/*/PycharmProjects/*/main.py", line 55, in <module>
    bot.run('*.*.*')
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/client.py", line 723, in run
    return future.result()
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/client.py", line 702, in runner
    await self.start(*args, **kwargs)
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/client.py", line 665, in start
    await self.login(*args, bot=bot)
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/client.py", line 511, in login
    await self.http.static_login(token.strip(), bot=bot)
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/http.py", line 300, in static_login
    data = await self.request(Route('GET', '/users/@me'))
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/discord/http.py", line 192, in request
    async with self.__session.request(method, url, **kwargs) as r:
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/client.py", line 1117, in __aenter__
    self._resp = await self._coro
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/client.py", line 520, in _request
    conn = await self._connector.connect(
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 535, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 892, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 1051, in _create_direct_connection
    raise last_exc
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 1020, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
  File "/Users/*/PycharmProjects/*/venv/lib/python3.9/site-packages/aiohttp/connector.py", line 971, in _wrap_create_connection
    raise ClientConnectorCertificateError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host discord.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)')]
</code>
Что не так?

Помогла установка версии Python 3.8 и перевод программы на файл питона 3.8


Как сделать генератор вывода запроса?

cur.execute('SELECT admin, status FROM admins')
with cur.fetchall() as admin, status:
    ...

Мне нужен словарь
{admin:status}, но боюсь что у меня все результаты собьются.

Попробуйте так:
<code>
cur.execute('SELECT admin, status FROM admins')
for admin, status in cur.fetchall():
    ...
</code>


Неправильно работает Телеграм - бот в связке с SQL
<code>
user_data = {}

class User:
     def __init__(self, first_name):
          self.first_name = first_name
          self.last_name = ''
          self.school = ''
          self.city = ''

@bot.message_handler(commands=['reg'])
def send_welcome(message):
     msg = bot.send_message(message.chat.id, 'Введите Имя')
     bot.register_next_step_handler(msg, process_first_name_step)

def process_first_name_step(message):
    try:
        user_id = message.from_user.id
        user_data[user_id] = User(message.text)
        msg = bot.send_message(message.chat.id, "Введите фамилию")
        bot.register_next_step_handler(msg, process_lastname_step)
    except Exception as e:
        bot.reply_to(message, 'oooops')

def process_lastname_step(message):
    user_id = message.from_user.id
    user = user_data[user_id]
    user.last_name = message.text

    sql = "INSERT INTO userss (first_name, last_name, user_id, school) VALUES (%s, %s, %s, %s)"
    val = (user.first_name, user.last_name, user_id, school)
    cursor.execute(sql, val)
    db.commit()
    msg = bot.send_message(message.chat.id, 'Введите номер школы')
    bot.register_next_step_handler(process_school,msg)

def process_school(message):
    user_id = message.from_user.id
    user = user_data[user_id]
    user.school = message.text

    sql = "UPDATE userss (first_name, last_name, user_id, school) VALUES (%s,%s,%s,%s)"
    val = (user.first_name, user.last_name, user_id, school)
    cursor.execute(sql,val)
    db.commit()
    bot.send_message(message.chat.id, "Вы успешно зарегистрированны!", reply_markup=kb.keyboardreg)
</code>
Помогите понять, почему не работает.

Покажите ошибку полностью.
Скорее всего у вас ошибка в
bot.register_next_step_handler(process_school, msg)
Первый параметр должен быть message, а вы передаете функцию.

bot.register_next_step_handler(msg, process_school)


телеграм бот повтор выбора кнопок
Есть бот: При запуске появляется выбор кнопок. Юзер нажимает одну из, получает выборку из базы. Как сделать чтоб после выборки данных из базы опять появлялся выбор кнопок. Без рестарта. Если не затруднит, примером. Спасибо.
<code>
@dp.message_handler(commands=['start'])
async def process_command(message: types.Message):
    await message.reply("Нажмите одну из кнопок", reply_markup=kb.inline_kb_full)

    @dp.callback_query_handler(lambda c: c.data == 'button1')
    async def process_callback_button1(callback_query: types.CallbackQuery):
        button_push = callback_query
        await bot.answer_callback_query(callback_query.id, config.switch_button.get(button_push))
        print(button_push.data)
        push = button_push.data
        button_request = config.switch_button.get(push)
        print(button_request)
        con = pymysql.connect(host='', user='', password='', database='')
        with con:
            cur = con.cursor()
            cur.execute(button_request)
            rows = cur.fetchone()
            print(rows)
            await bot.send_message(callback_query.from_user.id, rows)
</code>

В последней строчке:

await bot.send_message(callback_query.from_user.id, rows)

Заменить на

await bot.send_message(callback_query.from_user.id, rows, reply_markup=kb.inline_kb_full)


Крестики-нолики (ввод - вывод)
я новичок в python, как мне в этом примере сделать так, чтобы можно было спросить хочет ли игрок переиграть и чтобы board не сохраняла предыдущий результат игры?
<code>
from random import randint
BOARD_SIZE = 3
board = [i for i in range(9)]
is_winner = False
current_player = randint(0, 1)
markers = {0: 'O', 1: 'X'}
available_turns = (x for x in range(9))
# Отрисовка поля
# Старт игры, запрос ввода (если валидация == False, exception)
# Валидация ввода
# Переопределяем значения списка по индексу
# Проверка на победителя
# Переключаем игрока

def draw_board():
    res = ""
    for i, v in enumerate(board):
        res += str(v) + " "
        if (i+1) % BOARD_SIZE == 0:
             res += "\n"
    print(res)

def validate(value = " "):
    if not value.isdigit() and int(value) not in available_turns:
        raise ValueError ("Enter valid value and try again")
    if board[int(value)] in ('X', 'O'):
        raise ValueError ("This value has already played")
    if '.' in value:
        raise ValueError('Number must be int')

def check_winner():
    current_marker = markers[current_player]
    if board[0] == current_marker and board[4] == current_marker and board[8] == current_marker or \
            board[2] == current_marker and board[4] == current_marker and board[6] == current_marker or \
            board[0] == current_marker and board[1] == current_marker and board[2] == current_marker or \
            board[3] == current_marker and board[4] == current_marker and board[5] == current_marker or \
            board[6] == current_marker and board[7] == current_marker and board[8] == current_marker or \
            board[0] == current_marker and board[3] == current_marker and board[6] == current_marker or \
            board[1] == current_marker and board[4] == current_marker and board[7] == current_marker or \
            board[2] == current_marker and board[5] == current_marker and board[8] == current_marker:
        return True
    else:
        return False

for i in range(9):
    try:
        input_error = True
        draw_board()
        while input_error:
            choice = input(f"Pllayer {markers[current_player]} enter your number Введите число:\n")
            validate(choice)
            input_error = False
        board[int(choice)] = markers[current_player]
        #проверить победителя
        is_winner = check_winner()
        if is_winner == True:
            print(f'Player {markers[current_player]} won the game!!')
            break
        current_player = 0 if current_player == 1 else 1
        # if is_winner == True:
    except ValueError as ex:
        print(ex)

if is_winner == False:
    print('Draw')
</code>

Переместите цикл в функцию и вызывайте ее в бесконечном цикле с выходом по условию (если игрок ответит Нет)... Как-то так, например:
<code>
from random import randint

BOARD_SIZE = 3

# Отрисовка поля
# Старт игры, запрос ввода (если валидация == False, exception)
# Валидация ввода
# Переопределяем значения списка по индексу
# Проверка на победителя
# Переключаем игрока

def draw_board():
    res = ""
    for i, v in enumerate(board):
        res += str(v) + " "
        if (i+1) % BOARD_SIZE == 0:
             res += "\n"
    print(res)

def validate(value = " "):
    if not value.isdigit() and int(value) not in available_turns:
        raise ValueError ("Enter valid value and try again")
    if board[int(value)] in ('X', 'O'):
        raise ValueError ("This value has already played")
    if '.' in value:
        raise ValueError('Number must be int')

def check_winner():
    current_marker = markers[current_player]
    if board[0] == current_marker and board[4] == current_marker and board[8] == current_marker or \
            board[2] == current_marker and board[4] == current_marker and board[6] == current_marker or \
            board[0] == current_marker and board[1] == current_marker and board[2] == current_marker or \
            board[3] == current_marker and board[4] == current_marker and board[5] == current_marker or \
            board[6] == current_marker and board[7] == current_marker and board[8] == current_marker or \
            board[0] == current_marker and board[3] == current_marker and board[6] == current_marker or \
            board[1] == current_marker and board[4] == current_marker and board[7] == current_marker or \
            board[2] == current_marker and board[5] == current_marker and board[8] == current_marker:
        return True
    else:
        return False

def game(is_winner, current_player, ):
    for i in range(9):
        try:
            input_error = True
            draw_board()
            while input_error:
                choice = input(f"Player {markers[current_player]} enter your number Введите число:\n")
                validate(choice)
                input_error = False
            board[int(choice)] = markers[current_player]
            #проверить победителя
            is_winner = check_winner()
            if is_winner == True:
                print(f'Player {markers[current_player]} won the game!!')
                break
            current_player = 0 if current_player == 1 else 1
            # if is_winner == True:
        except ValueError as ex:
            print(ex)

    if is_winner == False:
        print('Draw')

new_game = True
while new_game:
    print('Новая игра')
    board = [i for i in range(9)]
    is_winner = False
    current_player = randint(0, 1)
    markers = {0: 'O', 1: 'X'}
    available_turns = (x for x in range(9))

    game(is_winner, current_player, )
    new_game = int(input('Еще игру? (1 - да, 0 - нет)'))
</code>


Pandas построчное объединение таблиц
Просьба, подсказать, возможно ли построчно объединять несколько df, например имеется 2 df с общими id
1df

   ID  QW ER TY UI IO OP
   112 11 23 45 56 76 78
   113 12 45 67 57 75 57
   114 56 75 57 57 87 90

2df

ID   NM HJ KL
112  56 67 54
113  34 45 56
114  12 41 98

объединить нужно к следующему ввиду, например при вызове ID 112

ID  QW ER TY UI IO OP
112 11 23 45 56 76 78
ID  NM HJ KL
112 56 67 54
113 12 45 67 57 75 57
114 56 75 57 57 87 90

соответсвенно при вызове других id также вставлять строки из df2 с общим id на последующие строки в df1

Я бы предложил вам лучше через
join (с параметром
left) сформировать таблицу такого вида:

ID  QW ER TY UI IO OP NM HJ KL
112 11 23 45 56 76 78 56 67 54
113 12 45 67 57 75 57
114 56 75 57 57 87 90

Так в принципе можно сделать, хотя пустые места придётся либо сначала
NA заполнить и при выводе в
html потом данные в строки преобразовать из
NA в пробелы, либо сразу все числа перевести в строки и тогда можно прямо пробелы в строках иметь.
А в том виде как вы хотите сформировать таблицу не получится - у таблицы не может быть в середине ещё одна строка с заголовками столбцов. А даже если она и могла бы быть, это всё-равно какая-то ерунда, потому что дальше то идут строки у которых заголовки от изначальной таблички и с точки зрения представления информации это что-то непонятное получается.


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

<span class="_ _179">

я хочу изменить
" " на
' '
Написал регулярное выражение

tag = re.sub(r'<span class="_ _\d{1,6}">', r'', str(tag))

что передать вторым параметром (на что меняем)?
я это вижу как то так

tag = re.sub(r'<span class="_ _\d{1,6}">', r'<span class='_ _числокотороенашлось'>', str(tag))

Но как это записать?

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

You can match a previously captured group later within the same regex
using a special metacharacter sequence called a backreference.
\<n>
Matches the contents of a previously captured group.
Within a regex in Python, the sequence \<n>, where <n> is an integer
from 1 to 99, matches the contents of the <n>th captured group.

Поэтому вся замена сводится к одной строчке:

tag = re.sub(r'(<span class=)"(_ _\d{1,6})"(>)', r"\1'\2'\3", tag)

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

tag = re.sub(r'(<\s*span\s+class\s*=\s*)"(_ _\d{1,6})"(\s*>)', r"\1'\2'\3", tag)


Цикл генерации случайного списка
имеется задача:
Анализ лотереи: напишите цикл, который проверяет, насколько сложно выиграть в смоделированной вами лотерее. Создайте список или кортеж с именем my_ticket . Напишите цикл, который продолжает генерировать комбинации до тех пор, пока не выпадет выигрышная комбинация. Выведите сообщение с информацией о том, сколько выполнений цикла понадобилось для получения выигрышной комбинации.
Я написал к ней код, но хотел бы узнать как можно его оформить покороче/полаконичнее?

from random import randint

my_ticket = [1,3,7,2,3]
count = 0
numbers = []
while my_ticket != numbers:
    count += 1
    for i in range(5):
        numbers.append(randint(1, 7))

    if my_ticket != numbers:
        numbers = []
    else:
        print(numbers)
        print(f'Количество итераций {count}')

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

   if my_ticket != numbers:
        numbers = []

Если совсем коротко, то как-то вот так:

from random import randint

my_ticket = [1,3,7,2,3]
count = 1
while my_ticket != [randint(1, 7) for _ in range(5)]:
    count += 1
print(f'Количество итераций {count}')

Или очень-очень коротко :)

from random import randint

my_ticket = [1,3,7,2,3]
print('Количество итераций', sum(1 for _ in iter(lambda: [randint(1, 7) for _ in range(5)], my_ticket)))


как сравнивать версии ПО с помощью Python?
Нужно написать класс Version. чтобы создавать экземпляры и потом иметь возможность сравнивать их между собой как версии.
Пример:
<code>
Version('1.1.3') < Version('2.2.3')
# True

Version('1.3.0') > Version('0.3.0')
# True
</code>
Насколько я понимаю, нужно переопределить методы le и т.п. но не совсем понимаю как это сделать. Провбовал импортировать from distutils.version import Version, LooseVersion, StrictVersion. но мне нужно именно написать свой класс

Берем класс, в котором всё есть и делаем из него свой:

class Version(tuple):
    def __new__(cls, text):
        return super().__new__(cls, tuple(int(x) for x in text.split('.')))

__new__ потому как tuple инициализируется до
__init__

>>> Version('1.1.3') < Version('2.2.3')
True
>>> Version('1.3.0') > Version('0.3.0')
True

Для наглядности методов сравнения реализуются функции

class Version:
    def __init__(self, text):
        self.version = tuple(int(x) for x in text.split('.'))

    def __le__(self, other):
        return self.version <= other.version

    def __ge__(self, other):
        return self.version >= other.version

    def __lt__(self, other):
        return self.version < other.version

    def __gt__(self, other):
        return self.version > other.version

    def __eq__(self, other):
        return self.version == other.version

    def __str__(self):
        return '.'.join(self.version)

Но если версии разной длинны нужно вводить функцию сравнения:

import itertools

class Version:
    def __init__(self, text):
        self.version = tuple(int(x) for x in text.split('.'))

    def __le__(self, other):
        return self.__cmp(other.version) <= 0

    def __ge__(self, other):
        return self.__cmp(other.version) >= 0

    def __lt__(self, other):
        return self.__cmp(other.version) < 0

    def __gt__(self, other):
        return self.__cmp(other.version) > 0

    def __eq__(self, other):
        return self.__cmp(other.version) == 0

    def __cmp(self, b):
        a = self.version
        for x,y in itertools.zip_longest(a, b, fillvalue=0):
            if x != y:
                return x - y
        return 0

Тогда

>>> Version('1.1') == Version('1.1.0')
True


Curselection не возвращает первый элемент listbox'a
Есть список, в который занесены станции. Также имеется два листбокса для выбора начальной и конечной станции соответственно. При выборе 1го элемента из этих листбоксов нет никакой реакции, хотя прописан бинд на событие ListboxSelect. Curselection не работает только с первым элементом, с остальными всё в порядке.
<code>
      def onselect(evt):
        w = evt.widget
        k = w.curselection()
        if k:
            p = int(k[0])
            if p:
                lbl_condition["text"] = "Выберите\nконечную станцию"
                lbl_condition.pack()
                f = open('stations.txt', 'w')
                f.write(f'{w.get(p)}\n')
                f.close()
                stations.append(w.get(p))
                sstation_listbox.bindtags("all")
                estation_listbox.config(state=tk.NORMAL)

    def onselect1(evt):
        w = evt.widget
        global buildpath
        global hidden_btn
        k = w.curselection()
        if k:
            p = int(w.curselection()[0])
            if p:
                f = open('stations.txt', 'a')
                f.write(f'{w.get(p)}\n')
                f.close()
                buildpath = tk.Button(master=frm_button, text='Построить маршрут', width=20, font=20, command=route)
                buildpath.pack(pady=(5, 290))
                hidden_btn = tk.Button(master=frm_button, text='Построить новый маршрут', width=25, command=reset_all)
                hidden_btn.pack_forget()
                estation_listbox.bindtags("all")

    j = 0
    i = 0
    frm_canvas = tk.Frame(master=master)
    frm_sstation = tk.Frame(master=frm_canvas, borderwidth=2, relief=tk.RIDGE, bg='red')
    frm_button = tk.Frame(master=frm_canvas, relief=tk.SUNKEN)
    frm_estation = tk.Frame(master=frm_canvas, borderwidth=2, relief=tk.RIDGE, bg='green')

    label_start = tk.Label(master=frm_sstation, text="Начальная станция")
    label_start.pack(padx=5, pady=5)
    scrollbar1 = tk.Scrollbar(master=frm_sstation)
    scrollbar1.pack(side=tk.RIGHT, fill=tk.Y)
    sstation_listbox = tk.Listbox(master=frm_sstation, width=35, height=35, yscrollcommand=scrollbar1.set)

    label_end = tk.Label(master=frm_estation, text="Конечная станция")
    label_end.pack(padx=5, pady=5)
    scrollbar2 = tk.Scrollbar(master=frm_estation)
    scrollbar2.pack(side=tk.RIGHT, fill=tk.Y)
    estation_listbox = tk.Listbox(master=frm_estation, yscrollcommand=scrollbar2.set, height=35, width=35)
    for i in range(3):
        window.columnconfigure(i, weight=1, minsize=75)
        window.rowconfigure(i, weight=1, minsize=50)
    for k in dict.keys():
        if '(' in k:
            sstation_listbox.insert(tk.END, k[:k.find('(')])
            estation_listbox.insert(tk.END, k[:k.find('(')])
        else:
            sstation_listbox.insert(tk.END, k)
            estation_listbox.insert(tk.END, k)
        i += 1
    lbl_condition = tk.Label(master=frm_button, text='Выберите\nначальную станцию', font=2, width=20)
    lbl_condition.pack(pady=30)
    sstation_listbox.pack()
    sstation_listbox.bind('<<ListboxSelect>>', onselect)
    estation_listbox.config(state=tk.DISABLED)
    scrollbar1.config(command=sstation_listbox.yview)
    estation_listbox.pack()
    estation_listbox.bind('<<ListboxSelect>>', onselect1)
    scrollbar2.config(command=estation_listbox.yview)
    frm_sstation.grid(padx=5, pady=1, row=0, column=0, rowspan=4)
    frm_button.grid(pady=1, row=0, column=1, padx=93)
    frm_estation.grid(row=0, column=2, padx=5, sticky=tk.W, rowspan=4)
    frm_canvas.pack()
</code>

Проблема здесь:

        p = int(w.curselection()[0])
        if p:

Первый элемент списка имеет индекс
0. И, соответственно, этот
if не сработает для нуля, ибо
0 - это
False. Во втором обработчике то же самое.


как собрать вывод в один словарь?
<code>
letters = {'а': 1, 'б': 2, 'в': 3, 'г': 4, 'д': 5, 'е': 6, 'ё': 7, 'ж': 8, 'з': 9,
       'и': 1, 'й': 2, 'к': 3, 'л': 4, 'м': 5, 'н': 6, 'о': 7, 'п': 8, 'р': 9,
       'с': 1, 'т': 2, 'у': 3, 'ф': 4, 'х': 5, 'ц': 6, 'ч': 7, 'ш': 8, 'щ': 9,
       'ъ': 1, 'ы': 2, 'ь': 3, 'э': 4, 'ю': 5, 'я': 6}

name = str.casefold(input("Введите запрос:")) # например Пётр
for i, letter in enumerate(name):
    if letter in letters.keys():
        new_letter = list()
        new_letter.append(letters[letter])
        print(new_letter, end='')
</code>


Отправка данных, введенных пользователем, в БД SQL Python

@bot.message_handler(commands=['reglearner'])
def reglearner(message):
    bot.send_message(message.chat.id, 'Введите имя')
    first_name = message.text
    firstnameSQL = """INSERT INTO users (first_name, last_name) VALUES (%s, %s, %s) """
    cursor.execute(firstnameSQL)
    db.commit()

Выводит ошибку

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s, %s, %s)' at line
1

Помогло
<code>
@bot.message_handler(commands=['reglearner'])
def reglearner(message):
    bot.send_message(message.chat.id, 'Введите имя')
    first_name = message.text
    last_name = 'chto to'
    firstnameSQL = """INSERT INTO users (first_name, last_name) VALUES (%s,%s) """
    val = (first_name,last_name)
    cursor.execute(firstnameSQL,val)
    db.commit()
</code>
Спасибо @andreymal


Почему в цикле if-elif выполняется только первый блок
<code>
n = input()
if n.isupper:
    print(n.lower())
elif n.islower:
    print(n.upper())
else:
    print("Wrong input")
</code>
При вводе буквы в нижнем регистре, должна вывестись буква в верхнем. И наоборот
Но при вводе у меня срабатывает только блок if. Поскольку при вводе "a" мне выводит "a". При вводе "A" выдает "a"
Если поменять местами условия у if elif, то будет все то же самое только наоборот. Т.е. для ввода большой буквы выводиться будет большая, так же как и для ввода маленькой
В чем проблема подскажите пожалуйста

isupper и islower это функции, так же как lower() и upper(), нужно сделать так:
<code>
n = input()
if n.isupper():
    print(n.lower())
elif n.islower():
    print(n.upper())
else:
    print("Wrong input")
</code>


python как создать декоратор для планировщика Schedule
Как возможно создать декоратор для планировщика задач : Schedule
Наподобие такого: запуск задачи каждые 20 секунд

@schedule(seconds=2)

def my_function(self):
    # -- основной код программы -- #

""" Пример реализации Планировщика
когда функция выполняется по расписанию (заускается каждый день например)
(в отдельном потоке) """

import schedule
import time
import threading
from threading import Thread
import datetime

def test():
    a = 12
    b = a + 8
    print(b)

def geeks():
    print(f"Ready and datetime_now :{datetime.datetime.now()}\n")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}\n")

def geeks_2():
    print(f"\nWoW + datetime_now : {datetime.datetime.now()}\n")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}\n")

def run():
    schedule.every(10).seconds.do(geeks)

    while True:
        schedule.run_pending()
        time.sleep(1)

def run_2():
    schedule.every(20).seconds.do(geeks_2)

    while True:
        schedule.run_pending()
        time.sleep(1)

# thread = Thread(name='worker', target=run)
# thread.start()

def run_thread():
    thread_2 = Thread(name='worker_2', target=run_2)
    thread_2.start()

run_thread()

test()

В отличие от обычных декораторов тут не нужно оборачивать функцию во wrapper, просто возвращаем ее же, но перед этим создаем объект
Job() с помощью функции
every(), и вызываем
job.do(func).

import datetime
import schedule
import time
import threading

def run_pending():
    while True:
        schedule.run_pending()
        time.sleep(0.1)

# daemon=True значит что этот поток будет работать, пока работает пока работает основной поток
threading.Thread(target=run_pending, daemon=True).start()

def scheduler(**interval_args):
    # Получаем имя и значение параметра, например unit='seconds'; interval=10
    unit, interval = list(interval_args.items())[0]  # Параметр должен быть обязательно передан, иначе будет IndexError
    job = schedule.every(interval)

    # Немного некорректно прописывать `unit` напрямую в обход свойств `.seconds`/`.minutes`/`.hour` и т.д.,
    # но работать тем не менее будет
    job.unit = unit

    def decorator(func):
        job.do(func)
        return func  # Возвращаем саму функцию, никак не заменяя

    return decorator

# ----

@scheduler(seconds=1)  # единица_измерения=интервал
def geeks():
    print("geeks")
    print(f"Ready and datetime_now :{datetime.datetime.now()}")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}")
    print()

@scheduler(seconds=2)
def geeks_2():
    print("geeks2")
    print(f"\nWoW + datetime_now : {datetime.datetime.now()}")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}")
    print()

while True:
    time.sleep(10)

Можно упростить код декоратора, если передавать в него параметром объект
Job, который возвращается функцией
every() (только не добавлять в конце
.do()), тогда синтаксис задания интервала будет "унаследован" от библиотеки
schedule:

def schedule_job(job: schedule.Job):
    def decorator(func):
        job.do(func)
        return func

    return decorator

# ----
# Для укорочения записи интервалов импортируем every
from schedule import every

@schedule_job(every().second)
def geeks():
    print("geeks")
    print(f"Ready and datetime_now :{datetime.datetime.now()}")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}")
    print()

@schedule_job(every(2).seconds)
def geeks_2():
    print("geeks2")
    print(f"\nWoW + datetime_now : {datetime.datetime.now()}")
    thread_name = threading.current_thread().name
    print(f"Thread_name: {thread_name}")
    print()

И аналогично
@schedule_job(every().week),
@schedule_job(every().wednesday.at("13:15")), и т.д.

UPD. оказалось, в библиотеке schedule уже есть свой декоратор, причем на 90% процентов совпадает с моим вторым вариантом (в отличие от моего варианта есть еще возможность передачи параметров из декоратора в декорируемую функцию):
Источник, соответствующий pull request, и пример в документации

def repeat(job, *args, **kwargs):
    """
    Decorator to schedule a new periodic job.
    Any additional arguments are passed on to the decorated function
    when the job runs.
    :param job: a :class:`Jobs <Job>`
    """

    def _schedule_decorator(decorated_function):
        job.do(decorated_function, *args, **kwargs)
        return decorated_function

    return _schedule_decorator


Как продолжить выполнение программы Python при ошибке в цикле FOR?
Нужно, чтобы при любой ошибке в любой из функций - выждать 5 сек и продолжить выполнение, не переходя на следующий цикл, с тем же ftid.
Сейчас, в случае ошибки, будет пропуск отработки функций с этим ftid.
Как сделать максимально правильно.
<code>
for ftid in range(begin_ftid, end_ftid):
        try:
           f1(ftid)
           f2(ftid)
           f3(ftid)

        except Exception:
            time.sleep(5)
            pass
</code>

Простой вариант так сказать:
<code>
for ftid in range(10):
    b = True
    while b: #Повторять пока b = True
        try:
           f1(ftid)
           f2(ftid)
           f3(ftid)
           b = False # если все хорошо прерываем цикл while
        except Exception: # иначе выполнится исключение и b останется True
            time.sleep(1)
            pass
</code>


Telegram bot с регистрацией
Пишу бота, и не знаю как реализовать регистрацию не при помощи пошагового бота, пользователь вводит Имя, Фамилию, Должность, которые сохраняются в БД.

@bot.message_handler(commands=['start'])
def start(message):
    msg = bot.send_message(message.chat.id, 'Введите Имя, Фамилию, Должность', parse_mode='Markdown')
    bot.register_next_step_handler(msg, start_2)

def start_2(message):
    first = message.text.split()[0]
    last = message.text.split()[1]
    position = message.text.split()[2]

    # print(first, last, position)
    create_user_db(message.chat.id, first, last, position)

def create_user_db(id_tlgrm, first, last, position):
    conn = sqlite3.connect(db)
    cursor = conn.cursor()
    db_data = [(id_tlgrm, first, last, position)]
    cursor.executemany('INSERT INTO users VALUES (?, ?, ?, ?)', db_data)
    conn.commit()


'NoneType' object is not subscriptable | discord.py
Сам код:
<code>
connection=sqlite3.connect('server.db')
cursor = connection.cursor()

@client.event
async def on_ready():
    print('Бот успешно подключен к серверу!')

    await client.change_presence( status = discord.Status.online, activity = discord.Game('Sublime (пишет код)') )
    cursor.execute("""CREATE TABLE IF NOT EXISTS users (
            name TEXT,
            id INT,
            cash BIGINT,
            lvl INT
        )""")

    for guild in client.guilds:
        for member in guild.members:
            if cursor.execute(f"SELECT id FROM users WHERE id = {member.id}").fetchone() is None:
                cursor.execute(f"INSERT INTO users VALUES ('{member}', {member.id}, 0, 1)")

            else:
                pass
    connection.commit()

@client.event
async def on_member_join(member):
    if cursor.execute(f"SELECT id FROM users WHERE id = {member.id}").fetchone() is None:
        cursor.execute(f"INSERT INTO users VALUES ('{member}', {member.id}, 0, 1)")
        connection.commit()

    else:
        pass

@client.command( pass_context = True)
async def balance(ctx, member: discord.Member = None):
    if member is None:
# 94 строчка,в которой вроде ошибка, строкой ниже
        await ctx.send(embed = discord.Embed(
        description = f"""баланс пользователя **{ctx.author}** составляет **{cursor.execute("SELECT cash FROM users WHERE id = {}".format(ctx.author.id)).fetchone()[0]} :leaves:**"""
        ))
    else:
        await ctx.send(embed = discord.Embed(
        description = f"""баланс пользователя **{member}** составляет **{cursor.execute("SELECT cash FROM users WHERE id = {}".format(member.id)).fetchone()[0]} :leaves:**"""
        ))
</code>
Ошибка:
Traceback (most recent call last):
File "D:\python\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "D:\python\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "D:\python\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'NoneType' object is not subscriptable

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

'NoneType' object is not subscriptable означает, что вы пробуете выполнить операцию
[] для
None.
В вашем случае запрос
SELECT cash FROM users WHERE id = {} очевидно не нашел пользователя и
.fetchone() возвращает
None.


Замена id юзера в message pyTelegramBotAPI
Хочу заменить значение message.from_user.id, получаемое при отправке юзером сообщения боту на любое другое в библиотеке pyTelegramBotAPI. Возможно ли это?
Пробовал
message['from_user.id'] = 0

В чем сложность я не до конца понимаю. Вам следовало бы почитать о классах.
message.from_user.id = 2


Вывод результата метода в другой метод
Подскажите пожалуйста, могу ли я подставить возвращаемые результаты из функций
gender() и
age_check() в функцию
show_info()?
Например я создаю экземпляр со следующими аргументами:

person1 = People('m', 20)

И я хочу получить в строке
return (f"That is {self.its_gender}, and person is {self.age}") такой вывод:

That is Man and person is Adult
Что для этого необходимо изменить?

class People:
    def __init__(self, its_gender, age):
        self.its_gender = its_gender
        self.age = age

    def show_info(self):
        return (f"That is {self.its_gender}, and person is {self.age}")

    def gender(self):
        if self.its_gender == "m":
            return ("Man")
        elif self.its_gender == 'f':
            return ("Woman")

    def age_check(self):
        if self.age > 18:
            return ("Adult")
        elif self.age <= 18:
            return ("Young")

Надо написать эту строку используя в подстановках вызовы методов, вот так:
<code>
return (f"That is {self.gender()}, and person is {self.age_check()}")
</code>


Как измерить количество используемой методом памяти Python?
Есть метод:

def method(g):
    x = []
    for i in range(g):
        x.append(i)
    return x

Нужно измерить количество потребляемой памяти.
Пытаюсь измерить с помощью
memory_profiler, но его
PyCharm почему-то не видит (from memory_profiler import memory_usage написал).
Теперь вопрос, как получить именно используемую память?
Память вычисляется с помощью memory_profiler.memory_usage(), но почему-то не работает, если писать так:

import memory_profiler

def method(g):
    x = []
    for i in range(g):
        x.append(i)
    return x

y = []
for j in range(len(10)):
    y.append(memory_profiler.memory_usage(method(10000)))

Напишу ответ, в вашем случае воспользоваться
memory_profiler в venv.
Установить (macOS):

python3 -m venv env
source env/bin/activate
pip3 install -U memory_profiler

Установить (Windows):

py -m venv env
env/Scripts/activate
pip install -U memory_profiler

Первое, необходимо функцию саму задекорировать в
@profile.
А затем вызывать ее в стандартной конструкции

if __name__ == '__main__':
    method(10000)

То есть весь код будет выглядеть вот так:

@profile
def method(g):
    x = []
    for i in range(g):
        x.append(i)
    return x

if __name__ == '__main__':
    method(10000)

Теперь запусти на исполнение и посмотрим на результат

python3 -m memory_profiler func.py

Результат:

Filename: func.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
     2   18.750 MiB   18.750 MiB           1   @profile
     3                                         def method(g):
     4   18.750 MiB    0.000 MiB           1       x = []
     5   19.203 MiB    0.266 MiB       10001       for i in range(g):
     6   19.203 MiB    0.188 MiB       10000           x.append(i)
     7   19.219 MiB    0.016 MiB           1       return x

Если же, вы хотите использовать в самом коде, то можно вот так

def method(g):
    x = []
    for i in range(g):
        x.append(i)
    return x

from memory_profiler import memory_usage
print(memory_usage((method, (10000,))))

Результат:

[19.28125, 19.296875, 19.296875]

Все примеры использования взяты из доументации