Как подключить шрифты Python
Сейчас я создаю ТГ бота на aiogram, Python для себя (управление каналом). Хотелось бы узнать, как сделать нечто подобное @TextChangerBot . Мне необходимо выделять текст, отправленный пользователям перенаправлять в канал уже со шрифтом. У меня была идея циклом for проходится по всем буквам, и заменять их своими же копиями из шрифта, но получилось бы слишком громоздко, и (как я думаю) некорректно. Подскажите пожалуйста методы, которые могут мне помочь

Как меня просили, добавляю свой ответ:
Я действительно циклом прошёлся по всему слову, и заменил все буквы на их соответствующие версии в шрифте. Прикрепляю код:

def beautiful_name(string):
    for i in string:
        try:
            is_new_title = istitle(i)
            new_letter = font[i.lower()][is_new_title]
            string = string.replace(i, new_letter)
        except KeyError:
            pass
        return string

А также оставляю файл JSON в котором хранится самодельный "шрифт". Вам нужно лишь выгрузить этот файл в словарь font и дело в шляпе!
И чуть не забыл: там используется моя функция istitle(), поэтому оставлю и её код:

def istitle(letter):
    if letter == letter.title():
        return "big"
    else:
        return "small"


JsonResponse и FileResponse Django
Задача следующая: получил список id пользователей через Ajax функцию. На стороне сервера - данные пришли. Ответ вернул в JsonResponse.
Возникла необходимость генерировать шаблон таблицы и вставлять данные пользователей по id. После генерации хочу вызвать FileResponse и скачать в браузере сгенерированный файл.
Но этого у меня не получается. Пытался в теле функции вызвать другую функцию, которая в качестве ответа возвращает FileResponse - не срабатывает, файл не генерится и не скачивается.
Как можно выйти из данной ситуации?
p.s. формировать ссылку на скачаивание - не вариант.
Код:

@csrf_exempt
def multiblank_create(request, slug):
    local_storage = request.POST.get('persons')
    if local_storage:
        temp = json.loads(local_storage)
        ids = []
        for i in temp:
            ids.append(int(i))

    print('before')

    byte_io = BytesIO()
    path_to_blank = os.getcwd() + "\\main\\static\\blanks\\" + slug + "\\"
    wb = openpyxl.load_workbook(os.path.join(path_to_blank, 'create.xlsx'))
    sheet = wb['Список пользователей']
    persons = Person.objects.filter(id__in=ids)
    for item in range(1, len(persons)+1):
        sheet.insert_rows(3)
    for item in range(1, len(persons)+1):
        sheet.cell(row=item+1, column=1).value = item+1
    wb.save(byte_io)
    byte_io.seek(0)
    filename = 'Заявка '

    msg = 'ok'
    return JsonResponse(msg, safe=False)

С исправлениями:

@csrf_exempt
def multiblank_create(request, slug):
    local_storage = request.POST.get('persons')
    if local_storage:
        temp = json.loads(local_storage)
        ids = []
        for i in temp:
            ids.append(int(i))
    print('before')

    path_to_blank = os.getcwd() + "\\main\\static\\blanks\\" + slug + "\\"
    wb = openpyxl.load_workbook(os.path.join(path_to_blank, 'create.xlsx'))
    sheet = wb['Список пользователей']
    persons = Person.objects.filter(id__in=ids)
    for item in range(1, len(persons)+1):
        sheet.insert_rows(3)
    for item in range(1, len(persons)+1):
        sheet.cell(row=item+1, column=1).value = item+1
    wb.save('out_test.xlsx')
    filename = 'Заявка  '
    print('near')

    response = FileResponse(open('out_test.xlsx', 'rb'))
    response['Content-Disposition'] = 'attachment; filename='+filename+ '.xlsx'
    response['X-Sendfile'] = filename+ '.xlsx'

    return response

Если честно - у меня есть аналогичная функция, только которая генерирует файл Word и скачивается без проблем. Почему здесь такая загвоздка возникает - не могу понять.
Возможен ли вариант, что данный запрос не возможен из-за того, что данные получаю через Ajax - функцию?

Попробуйте скачать сгенерированный файл можно таким кодом во view.py:
<code>
import os
from django.http import FileResponse

def download_file(request):
    dirs = settings.TEMPLATES[0]['DIRS'][0]
    filename = 'my_file.xlsx'

    response = FileResponse(open(dirs + '/my_file.xlsx', 'rb'))
    response['Content-Disposition'] = 'attachment; filename='+filename
    response['X-Sendfile'] = filename

    return response
</code>


keyboard ввод данных при русской раскладке
Мне необходимо на выходе функции отправлять данные о нажатой кнопке только в латинице. Проблема в том, что библиотека keyboard считывает нажатие на клавиатуру при любой раскладке и выдает символы в той раскладке, которая стоит у пользователя. Можно как то, чтобы при нажатии на клавиатуру на русской раскладке, скажем на кнопку с русской буквой "И" конвертировала в латинскую букву "B" этой же кнопки.
<code>
text = keyboard.read_hotkey()
</code>

Функция возвращающая текущую раскладку
<code>
import ctypes
def get_language() -> str:
    """
    Данная функция проверяет раскладку клавиатуры
    :return: 'ru'/'en'
    """
    u = ctypes.windll.LoadLibrary("user32.dll")
    pf = getattr(u, "GetKeyboardLayout")
    if hex(pf(0)) == '0x4190419':
        return 'ru'
    if hex(pf(0)) == '0x4090409':
        return 'en'
</code>


Что вызывает ошибку?
Я попытался расширить модель User, унаследовав AbstractUser:
models.py

class Teacher(AbstractUser):
    name = models.CharField(max_length=20)
    surname = models.CharField(max_length=20)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE,
        related_name='teacher_subject')
    person = models.ForeignKey(settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE)

settings.py

AUTH_USER_MODEL = 'education.Teacher'

forms.py

class TeacherRegistrationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = Teacher
        fields = ('name','surname','subject')

class TeacherChangeForm(UserChangeForm):

    class Meta:
        model = Teacher
        fields = ('name','surname','subject')

admin.py

class TeacherUserAdmin(UserAdmin):
    add_form = TeacherRegistrationForm
    form = TeacherChangeForm
    model = Teacher
    list_display = ['name','surname','subject']

admin.site.register(Teacher, TeacherUserAdmin)

И когда я пытаюсь создать миграции, я получаю ошибку

courses.Course.owner: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
courses.Course.students: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
courses.File.owner: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
courses.Image.owner: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
courses.Text.owner: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
courses.Video.owner: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.

Что мне с этим делать?

Удаляете все миграции, базу. Копируете мой код, вставляете к себе. Делаете миграции.

# app/models.py
from django.conf import settings
from django.contrib.auth.models import User, AbstractUser
from django.db import models

class Teacher(AbstractUser):
    name = models.CharField(max_length=20)
    surname = models.CharField(max_length=20)
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from app.models import Teacher

class TeacherInline(admin.StackedInline):
    model = Teacher
    can_delete = False
    verbose_name_plural = 'teachers'

class UserTeacher(BaseUserAdmin):
    inlines = (TeacherInline,)

admin.site.register(User, UserTeacher)

settings.py у вас правильный,
forms.py к вашему вопросу не имеет отношения.
По всей видимости ошибка конкретно в предыдущих миграциях.
Пример запускал - работает. (обратите внимание, что я немного упростил (убрал) одно поле из вашего тичера)


Как отправить таблицу в сообщение почты в Питоне?
Есть необходимость вставить таблицу в почтовое сообщение в Питоне. Как это можно организовать?
Как я понимаю, нужно преобразовать текст в html код?

def order_created_shop(order_id):
    """
    Задача для отправки уведомления по электронной почте при успешном создании заказа на почту магазина.
    """
    order = Order.objects.get(id=order_id)
    subject = 'Заказ №10{}'.format(order_id)
    message = 'Добрый день, заказ №10{}. сформирован на сайте "kosmetica".'.format(order.id)
    sum_order = 0
    for item in OrderItem.objects.filter(order=order):
        sum_order += round(item.quantity*item.price, 1)
        message += '\n{}, кол-во: {} шт., сумма: {} руб.'\
            .format(item.product, item.quantity, round(item.quantity*item.price, 1))
        sum_order_coupon = round(sum_order - sum_order/100*order.discount, 1)
    message += '\n\nСтоимость заказа - {} руб.'.format(sum_order)
    if order.coupon is not None:
        message += '\n\nСкидка ("{}") - {} руб.'.format(order.coupon, round(sum_order/100*order.discount, 1))
    message += '\n\nОкончательная стоимость - {} руб.'.format(sum_order_coupon)
    message += '\n\nГород {}'.format(order.city)
    message += '<html>'
    message += '<table><tr>'
    message += '<th>Имя</th>'
    message += '<th>Фамилия</th>'
    message += '<th>Отчество</th>'
    message += '</tr></table>'
    message += '</html>'

    mail_sent = send_mail(subject,
                            message,
                            settings.EMAIL_HOST_USER,
                            ['[email protected]'])
    return mail_sent

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

def order_created_shop(order_id):
    """
    Задача для отправки уведомления по электронной почте при успешном создании заказа на почту магазина.
    """
    order = Order.objects.get(id=order_id)
    subject = 'Заказ №10{}'.format(order_id)
    message = 'Добрый день, заказ №10{}. сформирован на сайте "kosmetica".'.format(order.id)
    sum_order = 0
    for item in OrderItem.objects.filter(order=order):
        sum_order += round(item.quantity*item.price, 1)
        message += '\n{}, кол-во: {} шт., сумма: {} руб.'\
            .format(item.product, item.quantity, round(item.quantity*item.price, 1))
        sum_order_coupon = round(sum_order - sum_order/100*order.discount, 1)
    message += '\n\nСтоимость заказа - {} руб.'.format(sum_order)
    if order.coupon is not None:
        message += '\n\nСкидка ("{}") - {} руб.'.format(order.coupon, round(sum_order/100*order.discount, 1))
    message += '\n\nОкончательная стоимость - {} руб.'.format(sum_order_coupon)
    message += '\n\nЗаказчик:\n'

    data = [
        ('Имя: ', f"{order.first_name}"),
        ('Фамилия: ', f"{order.last_name}"),
        ('Телефон: ', f"{order.telefon}"),
        ('Email: ', f"{order.email}"),
        ('Город: ', f"{order.city}"),
        ('Индекс: ', f"{order.postal_code}"),
        ('Адрес: ', f"{order.address}"),
        ('Создан: ', f"{order.updated}"),
        ]

    message += tabulate(data)

    html = f'''
    <!DOCTYPE html><html><head>
    <meta charset="utf-8" /></head><body><table><tr>
    <th>{order.first_name}</th>'
    <th>Фамилия</th>
    <th>Отчество</th>
    </tr></table></body></html>
    '''

    # message += html

    # mail_sent = EmailMessage(subject,
    #                         message,
    #                         settings.EMAIL_HOST_USER,
    #                         ['[email protected]'])
    # mail_sent.content_subtype = 'html'

    mail_sent = EmailMultiAlternatives(subject,
                                message,
                                settings.EMAIL_HOST_USER,
                                ['[email protected]'])
    mail_sent.attach_alternative(html, 'text/html')
    return mail_sent

Вы можете использовать стандартный шаблонизатор.
<code>

html_mess = render_to_string('<ваш шаблон:html>',
                                         context=<ваш контекст:dict>)
em = EmailMultiAlternatives(...kwargs)
em.attach_alternative(html_message, 'text/html')
em.send()
</code>


Python. Игра змейка на pygame
Решил написать игру "Змейка" на Pygame через спрайты (наверное была глупая идея). Изначально у змейки есть только голова. И когда она съедает яблоко,то размер змейки обновляется на долю секунды, а дальше снова будет видна одна голова. Я так же могу наткнуться на "невидимый" хвост и игра заканчивается.
Вот такой код:
<code>
#!usr/bin/python3
import pygame
import random

WIDTH = 540
HEIGHT = 740
FPS = 2
SIZE_BLOCK = 20

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (224, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Ping Pong")
clock = pygame.time.Clock()

class Snake(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((SIZE_BLOCK, SIZE_BLOCK))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.center = [WIDTH/2, HEIGHT/2]
        self.speedx = 20
        self.speedy = 0

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy

    def tail(self, size_block, snake_list):
        for x in snake_list:
            pygame.draw.rect(screen, GREEN, [x[0], x[1], size_block, size_block])

class Apple(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((SIZE_BLOCK, SIZE_BLOCK))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.foodx = round(random.randrange(0, WIDTH - SIZE_BLOCK) / 20.0) * 20.0
        self.foody = round(random.randrange(0, HEIGHT - SIZE_BLOCK) / 20.0) * 20.0

    def update(self):
        self.rect.x = self.foodx
        self.rect.y = self.foody

all_sprites = pygame.sprite.Group()
apples = pygame.sprite.Group()
apple = Apple()
snake = Snake()
all_sprites.add(snake)
all_sprites.add(apple)
apples.add(apple)

snake_list = []
len_of_snake = 1
running = True
while running:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a and snake.speedy != 0:
                snake.speedx = -SIZE_BLOCK
                snake.speedy = 0
            if event.key == pygame.K_d and snake.speedy != 0:
                snake.speedx = SIZE_BLOCK
                snake.speedy = 0
            if event.key == pygame.K_w and snake.speedx != 0:
                snake.speedx = 0
                snake.speedy = -SIZE_BLOCK
            if event.key == pygame.K_s and snake.speedx != 0:
                snake.speedx = 0
                snake.speedy = SIZE_BLOCK

    screen.fill(BLACK)
    all_sprites.draw(screen)
    if snake.rect.left < -10:
        running = False
    if snake.rect.right > WIDTH + 10:
        running = False
    if snake.rect.top <= -10:
        running = False
    if snake.rect.bottom > HEIGHT + 10:
        running = False

    snake_head = [snake.rect.x, snake.rect.y]
    snake_list.append(snake_head)
    if len(snake_list) > len_of_snake:
        del snake_list[0]

    for x in snake_list[:-1]:
        if x == snake_head:
            running = False

    collide = pygame.sprite.spritecollide(snake, apples, True)
    if collide:
        snake.tail(SIZE_BLOCK, snake_list)
        apple = Apple()
        all_sprites.add(apple)
        apples.add(apple)
        len_of_snake += 1
        pygame.display.update()

    pygame.display.flip()
    snake.update()
    apple.update()

pygame.quit()

</code>
Буду премного благодарен, если подскажете, как можно исправить этот косяк.

В коде при столкновении добавляется хвост змеи:

if collide:
    snake.tail(SIZE_BLOCK, snake_list)

В классе Snake хвост змеи прописан как отрисовка блока:

class Snake(pygame.sprite.Sprite):
    def tail(self, size_block, snake_list):
        for x in snake_list:
            pygame.draw.rect(screen, GREEN, [x[0], x[1], size_block, size_block])

В цикле игры экран заливается чёрным цветом, потом происходит отрисовка спрайтов:

screen.fill(BLACK)
all_sprites.draw(screen)

Так как хвост спрайтом не является то он просто не отрисовывается. Я вижу здесь два варианта: либо добавить хвост в спрайты, либо отдельно отрисовывать хвост после заливки экрана чёрным цветом.


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

raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 90
Current browser version is 89.0.4389.90 with binary path C:\Program Files\Google\Chrome\Application\chrome.exe

или просто открывается и закрываетс резко.
А firefox  у меня тупа висит(версия драйвера 29.0 версия firefox 88.0 beta(пробывал драйвер 28 было норм, потом начал просто висеть на днях , сменил на 29 ,выдавало ошибку с 29 и 87, обновил свой 87 на 88 тож фигня осталось висит )),(устанавливал темы и пару расширений прокси и рекапча  в оригинал)
даже ie не запускается. Что делать?
п.с. скрипты рабочие, но теперь вообще не работаю.
п.п.с понял почему не подключает через оптимус у меня стоит 90 браузер а он каким-то образом считает 89 браузер для подключения.

А вы читали что у вас в исключении написано?

This version of ChromeDriver only supports Chrome version 90 Current browser version is 89.0.4389.90 with binary path

У вас ChromeDriver для Сhrome версии 90, но на пк установлен Chrome 89. Либо обновите Chrome до версии 90, либо установите ChromeDriver для версии 89.


Как можно более оптимально получить из строки все числа списком?
Написал код, выделяющий из строки все числа списком.
<code>
def numbers_in_string(n, ogr=0, l=[]):
    for i in range(len(n)):
        k = 1
        if n[i].isdigit() and i >= ogr:
            while i + k < len(n) and n[i + k].isdigit():
                k += 1
                ogr = i + k
            l.append(int(n[i:i + k]))
    return l
</code>
Вроде работает, быстро и без ошибок. Что можно улучшить?

Вариант 1 - заменяем все "нецифры" на пробелы и в конце используем метод
str.split():

res = "".join(c if c.isdigit() else " " for c in text).split()

Вариант 2 - простой RegEx:

import re

res = re.findall("(\d+)", text)

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


Питон не понятный синтаксис
Что значит ['*'] в этом коде?
<code>
for link in data:
        if link['*'] not in seeLink:
            linkToPars.append(link['*'])
            print(link['*'])
```
</code>

Это доступ к значению по ключу (в случае dict):

acronyms = dict()
acronyms['*'] = "any"
acronyms['py'] = "python"

for key in acronyms:
    print(key, type(key), acronyms[key], acronyms.__getitem__(key))

class Acr(object):
    def __getitem__(self, key):
        return getattr(self, key)

acr = Acr()
acr.py = 'python'
print(acr['py'])

Вывод:

* <class 'str'> any
py <class 'str'> python
python


Как в Tkinter сделать так, чтобы одновременно могло быть открыто лишь одно такое окно?
К примеру всплывающие окна. Как сделать, чтобы при нажатии это окно не открывалось, если уже открыта его копия?
Самый примитивный пример:
<code>
from tkinter import *
head = Tk()

head.geometry('800x500')
head.title('Лаунчер')

def new_window():
    win = Tk()
    win.geometry('300x200')
    win.title('Ошибка')
    win_frame = Frame(new_window)
    win_frame.place(relwidth=1, relheight=1)
    win.mainloop()

frame = Frame(head)
frame.place(relwidth = 1,relheight = 1)

button = Button(frame,text = 'Далее',command = new_window)
button.place(x = 350,y = 370,width = 130,height = 50)

head.mainloop()
</code>

К примеру всплывающие окна. Как сделать, чтобы при нажатии это окно не открывалось, если уже открыта его копия?

Добавляете в ваш класс булевую переменную, например:
popup_init: bool = False,
В методе, который открывает попап проверяете значение данной переменной, и не даёте открыть его повторно или деактивируете клавишу поп-апа если значение
is False.
При нажатии на клавишу открытия поп-апа или при закрытии его меняете значение переменной.


Ошибка module 'matplotlib.pyplot' has no attribute 'get_map'
При построении графика возникла ошибка, что в модуле pyplot нет get_map.
Код:

df.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,
       s=df["population"]/100, label="population",figsize=(10,7),
       c="median_house_value", cmap=plt.get_map("jet"), colorbar=True,
)
plt.legend()

Ошибка:

AttributeError: module 'matplotlib.pyplot' has no attribute 'get_map'

Вам нужно сначала имопртировать

from matplotlib import cm

а потом, вместо,

cmap=plt.get_map("jet")

использовать

cmap=plt.cm.get_cmap("jet")


Замена элемента списка с последним
Дано задание следующего типа: Задать в программе список X, состоящий из 10 целых чисел. Найти максимальный из отрицательных элементов списка и поменять его местами с последним.
Максимально отрицательное я нашел, а вот как сделать так, чтобы это число(максимально отрицательное) менялось местами с последним?
<code>
import random

s = []
maxot = -10**10

for i in range(10):
    s.append(int(input('Введите любое число: \n')))
    if s[i] < 0 and s[i] > maxot:
        maxot = s[i]
print(s)
print('Максимально отрицательное число: \n')
print(maxot)
</code>

Поменять местами элементы в списке можно зная их индексы.
Последний элемент имеет индекс -1, а max_negative_index сохраните в цикле рядом с maxot:

# import random

s = []
# maxot = -10**10
maxot = float('-inf')
max_negative_index = 0

for i in range(10):
    s.append(int(input('Введите любое числа: \n')))
    # if s[i] < 0 and s[i] > maxot:
    if maxot < s[i] < 0:
        maxot = s[i]
        max_negative_index = i

print(s)
print('Максимально отрицательное число: \n')
print(maxot)

# меняем местами последний элемент с наибольшим из отрицательных элементов
s[-1], s[max_negative_index] = s[max_negative_index], s[-1]
print(s)

Вывод:

[1, -2, 3, -4, 5, -7, 8, -9, 42, 13]
Максимально отрицательное число:
-2
[1, 13, 3, -4, 5, -7, 8, -9, 42, -2]

PS
maxot = float('-inf') лучше, чем
maxot = -10**10; и
if maxot < s[i] < 0 нагляднее, чем
if s[i] < 0 and s[i] > maxot ;)


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

if <condition>: break

if <condition>: continue

Является ли такая запись неправильной с точки зрения PEP8? Искал инфу, но не нашёл.

Flake8 считает это антишаблоном (antipattern)

PEP 8: E701 multiple statements on one line (colon)

Я бы посоветовал вам использовать IDE, например бесплатную версию Pycharm, которые автоматически проверяют код на соответствие PEP-8 и подчеркивают те участки, которые нарушают PEP-8. Если навести курсор мыши на подчеркивание, то IDE покажет какое именно правило было нарушено.
Именно так я получил сообщение:

PEP 8: E701 multiple statements on one line (colon)


Как отключить проверку сертификата в модуле requests?
Как на уровне самого модуля
requests, в его файлах отключить проверку сертификатов?
Чтобы когда какое либо приложение использующее данный модуль отправляла
get запрос не проверялся сертификат...
В каком файле этого модуля можно этого сделать?

нужно отключить эту проверку на уровне самого модуля, а не в своем
приложении, чтобы не приходилось постоянно указывать в коде
verify=False

В вашем виртуальном окружении по адресу (python3.6 может быть другим):

venv/lib/python3.6/site-packages/requests/sessions.py

можно найти
def request():

def request(self, method, url,
            params=None, data=None, headers=None, cookies=None, files=None,
            auth=None, timeout=None, allow_redirects=True, proxies=None,
            hooks=None, stream=None, verify=None, cert=None, json=None):

измените
verify=None на
verify=False... хотя затея - так себе...


Исправить несбалансированные скобки в строке
Есть ли библиотека, которая автоматически исправит несбалансированные скобки в строке? Могут быть только незакрытые скобки, неоткрытых не может быть. Везде берём максимальное количество символов в скобки.
<code>
'xxx (yyy (zzz)' -> 'xxx (yyy (zzz))'
'x(x()v' -> 'x(x()v)'
</code>

s = 'xxx (yyy (zzz)'
print(s + ")" * (s.count("(") - s.count(")")))


Преобразование массива в словарь выдаёт ошибку: dictionary update sequence element #0 has length 1; 2 is required
Я стал использовать функцию в этом тестовом коде:

f = open("keys.txt", "r")
Inkeys = f.readlines()
f.close()
for i in range(0, len(Inkeys)):
    Inkeys[i] = Inkeys[i].replace('\n', '')
    Inkeys[i] = Inkeys[i].replace('\r', '')
print(Inkeys)
keys = ***dict([x[0].strip().split('=') for x in Inkeys])***
print(keys)

В файле keys.txt:

474772B4=+78005553535
0A757481=+79005353535

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

['474772B4=+78005553535', '0A757481=+79005353535']
*Traceback (most recent call last):
  File "D:\Users\ya\Desktop\data.py", line 8, in <module>
    keys = dict([x[0].strip().split('=') for x in Inkeys])
ValueError: dictionary update sequence element #0 has length 1; 2 is required*

Не очень понятно, что вы делаете, но, возможно,
[0], т.е. взятие элемента по индексу 0, у вас лишнее. Без него получается словарь:

keys = dict([x.strip().split('=') for x in Inkeys])
print(keys)

Вывод:

{'474772B4': '+78005553535', '0A757481': '+79005353535'}


Работа со словарем [закрыт]

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

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

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

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

Необходимо реализовать добавление нового продукта и его цены пользователем в словарь. Я попытался объявить сам словарь, но как добавить в него новый продукт я не знаю. Как это сделать?
<code>
dict = {
  "Банан": 200,
  "Груша": 100,
  "Манго": 300,
  "Арбуз": 150,
  "Киви": 300,
  "Апельсин": 150,
  "Молоко": 120,
  "Колбаса": 440,
  "Хлеб": 50,
  "Вода": 90,
}

total = sum(dict.values())
print(total)
</code>

В python в словарь запись можно добавить так

dict[key] = value

Поэтому:

name = input("Название: ");
price = input("Цена: ");

dict[name] = int(price);


Отсортировать словарь по определённому значению
Мне нужно отсортировать словарь words по значению b, как это сделать не совсем понимаю.

i = 0
    words = {}
    res = txt.get()
    with open('word_search.csv', newline='') as File:
        reader = csv.reader(File)
        for row in reader:
            b = fuzz.WRatio(res, row)
            if b >= 75:
                words[i] = [b, row]
                i += 1
    sorted(words,reverse=True)
    for row in words:
        print(words[row])

Входное слово:
googl
Пример вывода:

[90, ['go']]
[90, ['l']]
[90, ['o']]
[90, ['g']]
[91, ['google']]
[90, ['oo']]
[90, ['gl']]
[90, ['og']]
[90, ['goo']]
[89, ['goog']]
[90, ['googlebot']]
[75, ['gol']]
[90, ['googling']]
[83, ['googled']]

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

for k,v in sorted(words.items(), key=lambda x: x[1][0], reverse=True):
    print(v[0], v[1])

Вывод:

91 ['google']
90 ['l']
90 ['o']
90 ['g']
90 ['oo']
90 ['gl']
90 ['og']
90 ['goo']
90 ['googlebot']
90 ['googling']
89 ['goog']
83 ['googled']
75 ['gol']

Пояснения:

итерация по словарю равнозначна итерации по его ключам
.keys(), поэтому нужно использовать
.items(), чтобы у
sorted была полная информация об элементах словаря, а не только ключ, котором только порядковый номер элемента
содержимое элементов при этом получается такое примерно:
(0, [90, ['l']]), т.е. список в кортеже, и чтобы достать оттуда рейтинг нужно взять элемент 1 из кортежа, чтобы получить список, и потом взять элемент 0 этого списка

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


Почему pandas.DataFrame ест так много памяти?
Есть файл Excel размером 37 Мб. Я хочу обработать его с помощью python, и выбрал для этого pandas как очень мощный инструмент для обработки больших объёмов данных. Возникла такая проблема: когда я открываю этот файл в pandas:

from pandas import read_excel
table = read_excel("my_table.xlsx")

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

sys.getsizeof(table) == 1238122071  # это больше гигабайта
sys.getsizeof(table.values) == 112  # 112 байт
sys.getsizeof(table.values.tolist()) == 5045384  # ~5 мегабайт

Почему такой большой разброс размеров?
Плюс ко всему когда я делаю

del table

или

table = table.values

потребление памяти скриптом в диспетчере задач не снижается - почему?
Я буду очень благодарен если кто-нибудь объяснит мне все эти вещи.
Основной вопрос: Как мне снизить потребление памяти программой?
Просто я делаю на заказ прогу, которая работает в фоновом режиме, и очень не хочется чтобы заказчик случайно заглянув в диспетчер задач увидел там такое.
Всем заранее спасибо за ответы!

Посмотрите, что выдаёт такая команда:

table.info(memory_usage='deep')

Скорее всего у вас там текстовые данные, причём сильно повторяющиеся.
xlsx - это упакованный формат данных, он может эффективно сжимать текстовые данные. А вот в
Pandas по умолчанию строки будут кушать очень много памяти.
Если у вас там действительно окажутся сильно повторяющиеся текстовые данные, то можно их перевести в категориальный формат и тогда dataframe сильно сократит свой размер, потому что вместо строк будут повторяться ссылки на строки.
Теперь насчёт
del table, я не помню подробностей, но вполне может быть, что Garbage Collector в
Python срабатывает не сразу и освобождённая память не сразу отдаётся в систему. Попробуйте вызвать GC вручную:

import gc
gc.collect()
gc.collect() # два раза подряд, для надёжности

Но бывает и такое, что некоторые виды объектов не освобождают память до конца работы программы, всякое бывает. Тогда нужно думать, как сделать так, чтобы данные сразу считывались в правильном формате.
P.S. Но первым делом нужно проверить, правильно ли распарсился файл, возможно, у вас числовые поля склеились в одну большую строку из-за неправильного разделителя полей. Может быть и такое.
P.P.S. Код для проверки ситуации и в подтверждение моих слов:

import pandas as pd
import sys

df = pd.DataFrame({'text': ['some very very long string or not very long but close to it' * 40 for _ in range(500_000)]})

print('--- ваш способ определения размера ---')
print(sys.getsizeof(df))
print(sys.getsizeof(df.values))
print(sys.getsizeof(df.values.tolist()))
print('--- правильный способ определения размера ---')
df.info(memory_usage='deep')
print('--- попробуем сжать ---')
df['text'] = df['text'].astype('category')
df.info(memory_usage='deep')

Вывод:

--- ваш способ определения размера ---
1208500160
112
4000072

--- правильный способ определения размера ---
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 500000 entries, 0 to 499999
Data columns (total 1 columns):
 #   Column  Non-Null Count   Dtype
---  ------  --------------   -----
 0   text    500000 non-null  object
dtypes: object(1)
memory usage: 1.1 GB

--- попробуем сжать ---
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 500000 entries, 0 to 499999
Data columns (total 1 columns):
 #   Column  Non-Null Count   Dtype
---  ------  --------------   -----
 0   text    500000 non-null  category
dtypes: category(1)
memory usage: 490.8 KB

У меня одна строка повторяется, поэтому так хорошо сжалось в категориальный тип. У вас будет похуже, но тоже гораздо луше всё-равно, чем если ничего не делать.
В целом я постарался подогнать цифры под ваши, получилось очень похоже. Почему цифры именно такие - это нужно лезть в глубь устройства
Pandas, просто запомните, что проверять размеры объектов
Pandas нужно именно средствами
Pandas, а так поверхностно вы смотрите размеры каких-то хитрых ссылок на объекты, а не самих объектов внутри
Pandas.DataFrame. Хотя
sys.getsizeof(df) в принципе правильно отработал, даже удивительно.


Добавление новой строки в раздел файла конфигурации без его перезаписи с помощью ConfigParser
Помогите решить проблему с новой строкой.
Как добавлять новый раздел разобрался, но с добавлением новой строки не перезаписывая раздел уперся в штангу. ConfigParser
Конфиг:

[General]
fbrightlightcolorb = 1.0000
fbrightlightcolorg = 1.0000
fbrightlightcolorr = 1.0000
istorymanagerloggingevent = -1

Код:

from tkinter import *
import configparser
import os

# Создаю файл
def get_config():
    config = configparser.ConfigParser()
    config.write(open('example.ini', 'w'))
        # Если нет файла, создаем
    if not os.path.exists('example.ini'):
        config.read('example.ini')

        with open('example.ini', "w") as configfile:
            config.write(configfile)

    config.read('example.ini')
    return config

# Набиваю файл инфой
def create_config():

    config = configparser.ConfigParser()
    config.add_section("General")
    config.set("General", "fBrightLightColorB", "1.0000")
    config.set("General", "fBrightLightColorG", "1.0000")
    config.set("General", "fBrightLightColorR", "1.0000")
    config.set("General", "iStoryManagerLoggingEvent", "-1")

    with open('example.ini', "w") as configfile:
        config.write(configfile)

# Проблема тут! Пытаюсь добавить строку, а функция просто перезаписывает содержимое раздела [General]
def abc():

    config = configparser.ConfigParser()
    config.read('example.ini') # я так понял лишнее наверное.
    config['General'] = {'abc': '1'}

    with open('example.ini', 'w') as configfile:
        config.write(configfile)

# Блок ткинтера, к делу не относится.
root = Tk()
root.title("SSEMC")
root.geometry("950x550+300+200")
root.resizable(False, False)
Button(root, text='get_config()', command=get_config).place(x=260, y=80)
Button(root, text='create_config()', command=create_config).place(x=260, y=160)
Button(root, text='abc()', command=abc).place(x=260, y=20)

root.mainloop()

Для того ,чтобы добавить данные в файл не перезаписывая его ,вы должны поменять параметр w(write) на a(append).

with open('config.cfg', 'a') as f:
     f.write('\nваши данные')

После выполнения этого кода, в файл добавиться новая строка c текстом 'ваши данные'.
Документация по
open: здесь , тут


На чем писать бота для масслайкинга? [закрыт]

Закрыт. На этот вопрос невозможно дать объективный ответ. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы на него можно было дать ответ, основанный на фактах и цитатах.

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

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

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

Ботов такого рода можно писать на любом языке. Ведь ни в одном из языков нет встроенной функции "лайкнуть пост" :-). Вам в любом случае придётся использовать внешние библиотеки, котрые позволяют эмулировать работу браузера.
Выбор стоит делать в зависимости от Вашего бэкграунда и опыта на тех или иных языках.
Главная техническая составляющая этой задачи - точная эмуляция действий пользователя при работе в браузере. Это не такая простая работа, как кажется.
Можно копать в следующих направлениях:

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

"headless" режим браузера и что то вроде selenium: у Вас запущен настоящий браузер "в песочнице", и вы его "дёргаете за ручки"

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

Только всегда возникает вопрос: а зачем их лайкать?


Django Admin изменить виджет для ForeignKey
При открытии в админке модели
CoinTransaction поле
user представляет из себя выпадающий список. Так как пользователей около 20тыс данная страница рендерится долго. К тому-же это не единственное поле
ForeignKey. Нужно заменить виджет с выпадающего списка на поле ввода, в которое можно было бы вписать
User.id
Сумел сменить виджет для ForeignKey, но данные не сохраняются. Выдает ошибку вроде этой:

Cannot assign "30784": "CoinTransaction.user" must be a "User" instance

Примечание:
30784 - это ID пользователя
User
models.py:

class User(AbstractUser):
    """Пользователь"""
    ...

    def __str__(self):
        return f'{self.last_name} {self.first_name}'

    class Meta:
        verbose_name = 'Пользователь'
        verbose_name_plural = 'Пользователи'

class CoinTransaction(models.Model):
    """Монеты пользователей"""
    ...
    user = models.ForeignKey(User, verbose_name='Пользователь', on_delete=models.CASCADE)
    ...

admin.py

class CoinTransactionAdminForm(forms.ModelForm):
    """Изменяем виджеты"""
    user = forms.IntegerField(label='Id пользователя')

    class Meta:
        model = CoinTransaction
        fields = '__all__'

@admin.register(CoinTransaction)
class CoinTransactionAdmin(admin.ModelAdmin):
    """Транзакции монет"""
    list_display = ('id', 'user', 'amount', 'operation_type', 'order')
    list_display_links = ('id', 'user',)

    def get_form(self, request, obj=None, **kwargs):
        """Я не до конца понимаю смысл этого метода"""
        if request.user.is_superuser:
            kwargs['form'] = CoinTransactionAdminForm
        return super().get_form(request, obj, **kwargs)

Меняем стандартный виджет на
ForeignKeyRawIdWidget с помощью создания своей формы
admin.py:

from django.contrib.admin.sites import site
from django.contrib.admin.widgets import ForeignKeyRawIdWidget

class CoinTransactionAdminForm(forms.ModelForm):
    """Изменяем виджет для ForeignKey"""

    class Meta:
        model = CoinTransaction
        widgets = {
            'user': ForeignKeyRawIdWidget(CoinTransaction._meta.get_field('user').remote_field, site),
        }
        fields = '__all__'

@admin.register(CoinTransaction)
class CoinTransactionAdmin(admin.ModelAdmin):
    """Транзакции монет"""
    list_display = ('id', 'user', 'amount', 'operation_type', 'order')
    list_display_links = ('id', 'user',)
    form = CoinTransactionAdminForm


декораторы python list object is not callable
при наличии декоратора я получаю ошибку  - list object is not callable , без него соответственно все работает. Почему при декорировании я получаю ошибку?
<code>
from datetime import datetime

def timeit(func):
    def wrapper(*args, **kwargs):
        start = datetime.now()
        result = func(*args)
        print(datetime.now() - start)
        return result

    return wrapper()

@timeit
def abc():
    some_list = [i for i in range(100) if i % 2 == 0]
    return some_list

print(abc())
</code>

Декоратор должен возвращать объект функции, а не её результат:
<code>
def timeit(func):
    def wrapper(*args, **kwargs):
        start = datetime.now()
        result = func(*args)
        print(datetime.now() - start)
        return result

    # return wrapper()
    return wrapper
</code>


Failed test #5 of 25. Cannot check answer. Perhaps output format is wrong

a = int(input())
b = int(input())
d = 1
while d%a!=0 or d%b!=0:
    d+=1
    if d%a==0 and d%b==0:
        print(int(d))
        break

В компиляторе код работает как надо, но stepik.ru ругается , что
Failed test #5 of 25. Cannot check answer. Perhaps output format is wrong.
Программа должна считывать размеры команд (два положительных целых числа aa и bb, каждое число вводится на отдельной строке) и выводить наименьшее число dd, которое делится на оба этих числа без остатка.

Sample Input 1:

1
2
Sample Output 1:

2
Sample Input 2:

7
5
Sample Output 2:

35
Sample Input 3:

15
15
Sample Output 3:

15

Наименьшее общее кратное
lcm можно найти быстрее, без перебора, зная наибольший общий делитель
gcd. Он есть в стандартной библиотеке
math:

import math

a = int(input())
b = int(input())

lcm = (a * b) // math.gcd(a, b)


Коснулся первый объект второго? Как узнать? Python Tkinter
Код сейчас:
<code>
from tkinter import *
import time
root=Tk()
canvas=Canvas(root, width=700, height=700)
canvas.pack()
canvas.create_polygon(50, 2, 90, 10, 10, 10,
                      fill='red',
                      outline='black')
def movetriangle(event):
    if event.keysym=='Up':
        canvas.move(1, 0, -3)
    elif event.keysym=='Down':
        canvas.move(1, 0, 3)
    elif event.keysym=='Left':
        canvas.move(1, -7, 0)
    elif event.keysym=='Right':
        canvas.move(1, 7, 0)
canvas.bind_all('<KeyPress-Up>', movetriangle)
canvas.bind_all('<KeyPress-Down>', movetriangle)
canvas.bind_all('<KeyPress-Left>', movetriangle)
canvas.bind_all('<KeyPress-Right>', movetriangle)
root.mainloop()
</code>
Сейчас есть только один объект. А если добавить второй. Как узнать коснулся ли первый объект второго? А если второй объект коснулся стены, как это узнать?

У
Canvas есть метод
find_overlapping, который находит все объекты, попадающие в заданный прямоугольник. Мы можем как первое приближение "заменить" первую фигуру на прямоугольник, найти пересекающиеся с этим прямоугольником фигуры - так мы найдем фигуры, которые возможно пересекаются с данной фигурой и отсечем фигуры, которые точно не пересекаются с ней.
В коде будет что-то вроде этого:

poly1 = canvas.create_polygon(50, 2, 90, 10, 10, 10, fill='red', outline='black')

...
# Получаем множество возможно пересекающихся фигур:
overlapping = set(canvas.find_overlapping(*canvas.bbox(poly1)))
# canvas.bbox(poly1) - получить ограничивающий прямоугольник (bounding box) указанной фигуры

# В множество пересекающихся фигур попадает сама исходная фигура, удаляем ее из множества:
overlapping.discard(poly1)

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


Запуск функции из основного файла в модуле
Допустим у меня в основном коде есть функция:

def func1(a, b):
    print(a, b)

И есть второй файл с названием
file2.py.
Как мне из файла
file2.py вызвать функцию
func1?
(Мне нужно импортировать 2 файл в основном коде, и через функцию во втором файле вызвать функцию
func1).
Надеюсь понятно объяснил)

file2.py

a = 10
b = 20

def call(fn): # Получив любую функцию в виде аргумента,
    fn(a, b)  # вызовет её с аргументами (a, b)

file1.py

import file2

def func1(x, y):
    print(x, y)

file2.call(func1) # Передаем ожидаемый аргумент (функцию).
# 10 20

В примере функции ничего не возвращают, но могли бы:
file2.py

a = 10
b = 20

def call(fn):
    return fn(a, b)

file1.py

import file2

def func1(x, y):
    return x + y

result = file2.call(func1)
print(result) # 30


Пример адаптирован под ваш формат json.
<code>
#  json_data - ваш json, n - по сколько записей разбивать
def divide_json(json_data: dict ,n: int = 5):
    kek = [json_data['data'][i:i + n] for i in range(0, len(json_data['data']), n)]
    for i in kek:
        a['data'] = i
        yield a
</code>


Django Forms ImageFileld
Не могу обновить профиль , добавить новые данные , сохраняет либо в виде кортежа либо ошибка , подскажите в чем дело
forms.py

class UpdateProfileForm(forms.Form):
    avatar = forms.ImageField(required=False)
    about= forms.CharField(widget=forms.Textarea,max_length=255)
    birthday = forms.DateField(required=False)

views.py

def updateprofile(request):
    if request.method == 'POST':
        form = UpdateProfileForm(request.POST,request.FILES)
        if form.is_valid():
            about = form.cleaned_data['about']
            birthday = form.cleaned_data['birthday']
            avatar = request.FILES.get('avatar')
            print(type(about),about)
            print(type(birthday),birthday)
            print(type(avatar),avatar)

            profile = Profile.objects.get(user=request.user)
            # profile.avatar = avatar,
            profile.about= about,
            # profile.birthday=birthday,
            profile.save()

            return HttpResponseRedirect('/')
    else:
        form = UpdateProfileForm()
    return render(request, 'updateprofile.html', {'form': form})

models

from django.db import models

class Profile(models.Model):
    avatar = forms.ImageField(required=False)
    about= forms.CharField(widget=forms.Textarea,max_length=255)
    birthday = forms.DateField(required=False)

forms

class UpdateProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = '__all__'

views

class ProfileEdit(TemplateView):
    template_name = 'profiles/profile_edit.html'

    def get(self, request, *args, **kwargs):
        context = super().get_context_data(**kwargs)
        get_profile = Profile.objects.get(user=request.user)
        formProfile = UpdateProfileForm(instance=get_profile)
        context.update({'formProfile': formProfile})
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        context = super().get_context_data(**kwargs)
        get_profile = Profile.objects.get(user=request.user)
        formProfile = UpdateProfileForm(self.request.POST,instance=get_profile)
        if formProfile.is_valid():
            formProfile.save()
            return HttpResponseRedirect(reverse_lazy('profile_home'))
        else:
            print('NotValid')
            return self.form_invalid(formProfile, **kwargs)

    def form_invalid(self, formProfile, **kwargs):
        context = self.get_context_data()
        context.update({'formProfile': formProfile})
        return self.render_to_response(context)


О подсчёте суммы по элементам списка
<code>
for h in range(0,len(a)):
    tot =0
    tot = tot+ a[h]
print (tot)
</code>
машина выдаёт 6, список - 1,2,3,4,6, явно, что-то не так. почему машина не считает верную сумму? спасибо

Вы при каждой итерации цикла обнуляете счётчик, видимо вы планировали сделать так
<code>
tot = 0
for h in range(0,len(a)):
    tot = tot + a[h]
print (tot)
</code>


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

Заведём словарь ключами в котором будут элементы списков. Под каждый ключ поместим список списков, которые этот ключ содержат:

import pprint

lists = [
    [1, 2, 3],
    [3, 4, 5],
    [5, 6, 7]
]

d = {}
for l in lists:
    for i in l:
        d.setdefault(i, []).append(l)

pprint.pprint(d)

$ python list_instersections.py
{1: [[1, 2, 3]],
 2: [[1, 2, 3]],
 3: [[1, 2, 3], [3, 4, 5]],
 4: [[3, 4, 5]],
 5: [[3, 4, 5], [5, 6, 7]],
 6: [[5, 6, 7]],
 7: [[5, 6, 7]]}


Как создать цикл от одной даты до другой с интервалом в 30 минут?
C помощью библиотеки Arrow сделал цикл через каждый час
<code>
from arrow import Arrow

start = datetime(2021, 3, 25, 0, 0)
end = datetime(2021, 3, 26, 0, 0)

for r in Arrow.range('hours', start, end):
    ...
</code>
А как сделать через каждые 30 мин?


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

import numpy as np
import cv2

# Задание изображения 640 х 480
width = 640
height = 480
img = np.array(np.vsplit(np.zeros(height*width*3).reshape(width*height,3),height))

# Задание зеленого цвета изображения
img[:,:,1] = 255

# Формирование черной полосы шириной 100 для добавления слева и справа изображения
width_nul = 100
nul = np.zeros(width_nul*height*3).reshape((width_nul*height,3))
nul = np.array(np.vsplit(nul, height))

# Добавление черных полос слева и справа
img = np.hstack((nul, img))
img = np.hstack((img, nul))
a = cv2.imshow("img", img)

Однако, когда пытаюсь добавить полосы к любой фотографии 'img.jpg', отображается белый квадрат:

import numpy as np
import cv2

# Чтение изображения 640 х 480
img = cv2.imread('img.jpg')

# Формирование черной полосы для добавления слева и справа изображения
width_nul = 100
height = 480
nul = np.zeros(width_nul*height*3).reshape((width_nul*height,3))
nul = np.array(np.vsplit(nul, height))

# Добавление черных полос слева и справа
img = np.hstack((nul, img))
img = np.hstack((img, nul))
a = cv2.imshow("img", img)

Не забудьте поделить матрицу на 255 перед вызовом
cv2.imshow

import cv2
import numpy as np

img = cv2.imread(r"image.png")
nul = np.zeros((img.shape[0], 50, 3))
img = np.hstack((nul, img))
img = np.hstack((img, nul))
cv2.imshow("img", img / 255)


Возможно ли отследить, когда пользователь удаляет или блокирует телеграм-бота?
При запуске бота сохраняется
chat_id пользователя в БД.
Есть ли способ отследить, когда пользователь удаляет или блокирует бота?

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


Как создать список списков переборов чисел от 1 до k?(без повторений)
(В моем случае k=4)
Есть список n, с 4(k) элементами, каждый из которых задается рандомно от 1 до 4(k), при этом ни одно число не должно повторяться...
Теперь есть список N, в который мы хотим вставить список n, при этом также ни один список n не должен повторяться...
Т.к. я не знаю (лень считать) итоговое кол-во списков n, то через for все прогоняем
(За 100000 прогонов, думаю, слишком маленькая вероятность пропустить хотя бы одну комбинацию)
Код:
<code>
import random
N=[]
n=[]
for i in range(0,100000):
    n.clear()
    while len(n)!=4:
        x=random.randint(1,4)
        if n.count(x)==0:
            n.append(x)
    if N.count(n)==0:
        N.append(n)
print(len(N),N)
</code>
Проблема в том, что мне выводится какой-то бред:
"1 [[любая комбинация из 1,2,3,4]]"
Если print'ов наставить в коде, то становится понятно, что список n перебирается, один раз даже добавляется в N, но дальше ни-ни... А потом каким-то чудом список N чистится, но оставляет один пустой список внутри себя...

Замените
n.clear() на
n = [].
Когда вы делаете
N.append(n) - вы добавляете объект (
n) в список. И когда делаете
n.clear() - он чистит объект
n.
По этому у вас и результат соответствующий. Проверено.


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

systems = {'Solar': ['Mercury', 'Earth', 'Mars']}

Чтобы можно было удалить
Mars, а осталось:

systems = {'Solar': ['Mercury', 'Earth']}

Мой код:

import pickle

def read_data(filename):
    ''' получаем словарь из файла
если файла нет возвращаем пустой словарь'''
    try:
        with open('data.pickle', 'rb') as f:
             return pickle.load(filename)
    except:
        return {}

def save_data(filename, data):
    ''' сохраняем словарь в файл'''
    with open(filename, 'wb') as f:
        pickle.dump(data, f)

def check():
    system = input('enter ZS:  ')
    if system not in systems:
        print('система добавлена в базу')
    return system

def planet(system):
    ''' заполняем планеты заданной системы или добавляем новые'''
    x = int(input(f' количество планет для системы {system} >>:  '))
    return [input('введите: ') for _ in range(x)]

filename = 'systems.txt'
systems = read_data(filename)

def _delS():
    d=input('enter system: ')
    del systems[d]

def _delP():
    system=input('enter system: ')
    planet=input('enter planet: ')
    systems.popitem(system,planet)

while True:
    print('1-add system/planet\n2-print systems/planets\n3-delit system with planets\n4-delit planet\n')
    key=int(input('choose menu'))
    if key==1:
        system = check()
        systems.setdefault(system, []).append(planet(system))
        save_data(filename, systems)
    elif key==2:
        read_data(filename)
        print(systems)
    elif key==3:
        _delS()
    elif key==4:
        _delP()

Удалять должна функция
_delP.

systems={'Solar':['Mercury','Earth','Mars']}
system_del = 'Solar'
planet_del = 'Mars'
systems[system_del].remove(planet_del)


Как сделать чтобы моя программа останавливалась при нажатии Escape, а при повторном нажатии продолжала работать
Хотел сделать паузу в своей небольшой игре, но столкнулся с проблемой, что все работает наоборот, да и метод у меня не особо хороший в плане кода, подскажите пожалуйста как сделать чтобы моя игра останавливалась при нажатии Escape, а при повторном нажатии продолжалась
<code>
import os
import sys
import random
from PIL import Image, ImageTk
from tkinter import Tk, Frame, Canvas, ALL, NW, Button
from keyboard import *
from time import *
import threading

class Cons:
    roadSpeed = 80

class Game(Canvas, Button):
    def __init__(self, parent = None):
        super().__init__(
            parent, width=1024, height=900, highlightthickness=0, background="black"
        )
        self.start()
        self.pack()
    def start(self):
        self.inGame = True
        self.score = 0
        self.barrierX = 128
        self.barrierY = -500
        self.loadImages()
        self.createObjects()
        self.locateBarrier()
        self.bind_all("<Key>", self.keyPressed)
        self.after(100, self.onTimer)

    def loadImages(self):
        self.icar = Image.open("ttt.png")
        self.car = ImageTk.PhotoImage(self.icar)
        self.ienemy = Image.open("enemy.png")
        self.barrier = ImageTk.PhotoImage(self.ienemy)
        self.iroad = Image.open("1396441575.png")
        self.road = ImageTk.PhotoImage(self.iroad)

    def createObjects(self):
        self.create_image(512, 502, image=self.road, tag="road")
        self.create_image(128, 650, image=self.car, tag="car")
        self.create_text(
            30, 10, text="Счет: {0}".format(self.score),
            tag="score", fill="white"
        )

    def moveLeft(self):
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        if x1 - 256 > 2:
            self.move(car[0], -256, 0)

    def moveRight(self):
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        if x1 + 256 < 1022:
            self.move(car[0], 256, 0)

    def checkBarrierCollision(self):
        barrier = self.find_withtag("barrier")
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        overlap = self.find_overlapping(x1, y1, x2, y2)
        for i in overlap:
            for j in range(0, len(barrier)):
                if barrier[j] == i:
                    self.inGame = False

    def moveRoadAndBarrier(self):
        road = self.find_withtag("road")
        cnt = 0
        for i in range(len(road)):
            x, y = self.coords(road[i])
            if y < 450:
                cnt += 1
        if cnt == 0:
            self.create_image(512, -450, image=self.road, tag="road")
            self.tag_lower("road")
        barrier = self.find_withtag("barrier")
        cnt = 0
        x, y = self.coords(barrier[0])
        if y < 1024:
            cnt += 1
        if cnt == 0:
            self.locateBarrier()
        road = self.find_withtag("road")
        z = 0
        while z < len(road):
            self.move(road[z], 0, Cons.roadSpeed)
            z += 1
        z = 0
        while z < len(barrier):
            self.move(barrier[z], 0, Cons.roadSpeed)
            z += 1

    def locateBarrier(self):
        barrier = self.find_withtag("barrier")
        for i in range(0, len(barrier)):
            self.delete(barrier[i])
        self.score += 1
        r = random.randint(1, 3)
        for i in range(r):
            r1 = random.randint(1, 4)
            r2 = r1 - 1
            self.create_image(256 * r2 + 128, -20, image=self.barrier, tag="barrier")

    def keyPressed(self, e):
        car = self.find_withtag("car")
        x, y = self.coords(car)
        key = e.keysym
        leftKey = "Left"
        if key == leftKey and x >= 128:
            self.moveLeft()
        rightKey = "Right"
        if key == rightKey and x <= 896:
            self.moveRight()

    def onTimer(self):
        road = self.find_withtag("road")
        for i in range(len(road)):
            x, y = self.coords(road[i])
            if y == 1502:
                self.delete(road[i])
        self.drawScore()
        self.checkBarrierCollision()
        if self.inGame:
            self.moveRoadAndBarrier()
            self.after(100, self.onTimer)
        else:
            self.gameOver()

    def drawScore(self):
        score = self.find_withtag("score")
        self.itemconfigure(score, text="Счет: {0}".format(self.score))
    def gameOver(self):
        self.delete(ALL)
        self.create_text(self.winfo_width() / 2, self.winfo_height() / 2,
                         text="Игра окончена со счетом {0}".format(self.score), fill="blue")
class Car(Frame):
    def __init__(self):
        super().__init__()
        self.master.title('ооаоаа')
        self.board = Game()
        self.pack()

root = Tk()
ooaoaa = Car()
root.mainloop()

</code>

Как вариант через потоки:

import keyboard
import time
import threading

stop = True # По умолчанию программа на паузе

def key_pause():
    keyboard.add_hotkey('esc', stopgame)
    keyboard.wait()

def stopgame():
    global stop
    if stop == False:
        stop = True
    else:
        stop = False

def my_pause():
    global stop
    while stop:
        time.sleep(1)

def main():
    print("Start")

    # обработка паузы
    my_pause()

    print("END")

if __name__ == "__main__":
    task1 = threading.Thread(target=key_pause, daemon=True)
    task1.start()
    main()

Из нюансов для наглядности программа стартует на паузе
esc по сути меняет состояние переменной
stop. А в местах где будет вызвана
my_pause() будет проводится проверка на паузу.
Также данную логику можно реализовать через
threading.Event()

import keyboard
import threading
import time

# Обработка нажатия esc
# По нажатия будет вызвана функция stopgame
def key_pause():
    keyboard.add_hotkey('esc', stopgame)
    keyboard.wait()

# Функция stopgame просто меняет состояние event-та
def stopgame():
    if event.is_set():
        event.clear() # False
    else:
        event.set() # True

 # функция с которой запускается ваша программа
def main():
    # Какой-то ваш код
    print("Start")

    # обработка паузы
    # Вставьте этот код в программе где хотите чтобы
    # была проверка на паузе программа или нет.
    # если да то программа зависнет пока event не изменится
    event.wait()

    # Какой-то ваш код
    print("END")

if __name__ == "__main__":
    event = threading.Event() # Создаем event

    # запускаем в отдельном потоке проверку надатия esc
    task1 = threading.Thread(target=key_pause, daemon=True)
    task1.start()

    # начальная функция Вашей игры.
    main()

Ваш код:

import os
import sys
import random
from PIL import Image, ImageTk
from tkinter import Tk, Frame, Canvas, ALL, NW, Button
from time import *
import threading
from keyboard import *
import keyboard

class Cons:
    roadSpeed = 80

class Game(Canvas, Button):
    def __init__(self, parent = None):
        super().__init__(
            parent, width=1024, height=900, highlightthickness=0, background="black"
        )
        self.start()
        self.pack()
    def start(self):
        self.inGame = True
        self.score = 0
        self.barrierX = 128
        self.barrierY = -500
        self.loadImages()
        self.createObjects()
        self.locateBarrier()
        self.bind_all("<Key>", self.keyPressed)
        self.after(100, self.onTimer)

    def loadImages(self):
        self.icar = Image.open("ttt.png")
        self.car = ImageTk.PhotoImage(self.icar)
        self.ienemy = Image.open("enemy.png")
        self.barrier = ImageTk.PhotoImage(self.ienemy)
        self.iroad = Image.open("1396441575.png")
        self.road = ImageTk.PhotoImage(self.iroad)

    def createObjects(self):
        self.create_image(512, 502, image=self.road, tag="road")
        self.create_image(128, 650, image=self.car, tag="car")
        self.create_text(
            30, 10, text="Счет: {0}".format(self.score),
            tag="score", fill="white"
        )

    def moveLeft(self):
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        if x1 - 256 > 2:
            self.move(car[0], -256, 0)

    def moveRight(self):
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        if x1 + 256 < 1022:
            self.move(car[0], 256, 0)

    def checkBarrierCollision(self):
        barrier = self.find_withtag("barrier")
        car = self.find_withtag("car")
        x1, y1, x2, y2 = self.bbox(car)
        overlap = self.find_overlapping(x1, y1, x2, y2)
        for i in overlap:
            for j in range(0, len(barrier)):
                if barrier[j] == i:
                    self.inGame = False

    def moveRoadAndBarrier(self):
        event.wait() # <<< Можно вызватиь тут
        road = self.find_withtag("road")
        cnt = 0
        for i in range(len(road)):
            x, y = self.coords(road[i])
            if y < 450:
                cnt += 1
        if cnt == 0:
            self.create_image(512, -450, image=self.road, tag="road")
            self.tag_lower("road")
        barrier = self.find_withtag("barrier")
        cnt = 0
        x, y = self.coords(barrier[0])
        if y < 1024:
            cnt += 1
        if cnt == 0:
            self.locateBarrier()
        road = self.find_withtag("road")
        z = 0
        while z < len(road):
            self.move(road[z], 0, Cons.roadSpeed)
            z += 1
        z = 0
        while z < len(barrier):
            self.move(barrier[z], 0, Cons.roadSpeed)
            z += 1

    def locateBarrier(self):
        barrier = self.find_withtag("barrier")
        for i in range(0, len(barrier)):
            self.delete(barrier[i])
        self.score += 1
        r = random.randint(1, 3)
        for i in range(r):
            r1 = random.randint(1, 4)
            r2 = r1 - 1
            self.create_image(256 * r2 + 128, -20, image=self.barrier, tag="barrier")

    def keyPressed(self, e):
        # event.wait() # <<< Можно вызватиь тут
        car = self.find_withtag("car")
        x, y = self.coords(car)
        key = e.keysym
        leftKey = "Left"
        if key == leftKey and x >= 128:
            self.moveLeft()
        rightKey = "Right"
        if key == rightKey and x <= 896:
            self.moveRight()

    def onTimer(self):
        road = self.find_withtag("road")
        for i in range(len(road)):
            x, y = self.coords(road[i])
            if y == 1502:
                self.delete(road[i])
        self.drawScore()
        self.checkBarrierCollision()
        if self.inGame:
            self.moveRoadAndBarrier()
            self.after(100, self.onTimer)
        else:
            self.gameOver()

    def drawScore(self):
        score = self.find_withtag("score")
        self.itemconfigure(score, text="Счет: {0}".format(self.score))
    def gameOver(self):
        self.delete(ALL)
        self.create_text(self.winfo_width() / 2, self.winfo_height() / 2,
                         text="Игра окончена со счетом {0}".format(self.score), fill="blue")
class Car(Frame):
    def __init__(self):
        super().__init__()
        self.master.title('ооаоаа')
        self.board = Game()
        self.pack()

def key_pause():
    add_hotkey('esc', stopgame)
    wait()

def stopgame():
    if event.is_set():
        event.clear() # False
    else:
        event.set() # True

if __name__ == "__main__":
    event = threading.Event() # Создаем event
    task1 = threading.Thread(target=key_pause, daemon=True)
    task1.start()
    root = Tk()
    ooaoaa = Car()
    root.mainloop()


Обозначение границ слова с помощью регулярных выражений в Python
Так, есть, условно, задача:
дана строка 'XABADXJSADZFNEFEXNNZFWUFNWFNXUNNINNUZAFE' (для примера, только заглавные латинские буквы).
Необходимо вывести все подпоследовательности, начинающиеся на X и заканчивающиеся Z:
XJSADZ,
XNNZ,
XUNNINNUZ,
При этом между X и Z не может быть X, т.е. строка XABADXJSADZ не должна попасть в вывод
Заранее спасибо!

В условии регулярки указываем, что ожидаем
X<любые символы кроме X>Z

import re

text = 'XABADXJSADZFNEFEXNNZFWUFNWFNXUNNINNUZAFE'

print(re.findall('X[^X]+Z', text))
# ['XJSADZ', 'XNNZ', 'XUNNINNUZ']


Как удалить объект спрайта Pygame?
Мне нужно удалять спрайт из массива, когда он выходит за границу...
Вот код:
<code>
import pygame

pygame.init()
win = pygame.display.set_mode((700, 400))
pygame.display.set_caption("Защита")
pygame.display.set_icon(pygame.image.load("images/sheald.png"))
fon = pygame.image.load("images/fon.png")

class Bullet(pygame.sprite.Sprite):
    def __init__(self, y, speed, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image).convert_alpha()
        self.rect = self.image.get_rect(center=(70, y + 20))
        self.speed = speed

    def update(self):
        self.rect.x += self.speed
        win.blit(self.image, self.rect)

playerY = 70
playerX = 20
bull = []
bulletsNumber = 10
FPS = 60

def shoot():
    global bulletsNumber
    if bulletsNumber > 0:
        bulletsNumber -= 1
        bullet = Bullet(playerY, 2, 'images/bullet.png')
        bull.append(bullet)

def window():
    win.blit(fon, (0, 0))
    pygame.draw.rect(win, (236, 218, 103), (playerX, playerY, 40, 40))
    for bul in bull:
        bul.update()
        if bul.rect.x >= 700:
            **тут нужно удалить объект**
</code>
window - это обновление экрана
shoot -  создание объекта
Как это сделать?

имя_массива.remove(нужный_фрагмент_массива)
имя_массива.pop(номер_в_массиве)

например:

 a = [1,2,3]
 a.remove(1)
 a - [2,3]
 a.pop(0)
 a - [3]


Как заменить цикл на рекурсию в python? [закрыт]

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

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

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

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

У меня возникла проблема.
Как заменить два цикла, на одну функцию которая содержит рекурсию.

for i in range(0,1):
    for j in range(1,len(A)):

Вот весь код.

import numpy as np

lest =0
def matrix(B,z):
    result = 1 in B
    return "Номер строки "+str(z)+", найдено совпадений: "+str(result)+ " строке"

A = np.array([[1, 4, 5, 0],
    [-5, 8, 9, 1],
    [1, 7, 11, 19],
    [1, 2, 4, 1]])
print("Сравнения с первой строкой:\n")
for i in range(0,1):
    for j in range(1,len(A)):
        b = list(map(lambda x, y: lest+1 if x == y  else lest+0,A[i],A[j]))
        print(matrix(b,j+1))

Спасибо за внимания.

Не совсем понимаю необходимость, можно просто убрать первый цикл, и все сравнивать с 1ым элементом, но если очень нужна рекурсия, то вот. Делает то же самое, только рекурсивно.
<code>
def matrix(B, z):
    result = 1 in B
    # не желательно форматировать строку сложением строк.
    return "Номер строки {}, найдено совпадений: {} строке".format(str(z), str(result))

A = np.array([[1, 4, 5, 0],
              [-5, 8, 9, 1],
              [1, 7, 11, 19],
              [1, 2, 4, 1]])
print("Сравнения с первой строкой:\n")

def work(mtx: np.array) -> None:
    lest = 0
    len_mtx = len(mtx)
    if len_mtx == 2:  # граничный случай
        last = mtx[-1]
        b = list(map(lambda x, y: lest + 1 if x == y else lest, mtx[0], last))
        print(matrix(b, 2))
    else:   # рекурсивный случай
        last, mtx_n = mtx[-1], mtx[:-1]
        b = list(map(lambda x, y: lest + 1 if x == y else lest, mtx[0], last))
        work(mtx_n)
        print(matrix(b, len_mtx))

work(A)
</code>


Не отправляет запрос Ajax в Django
Не отправляется запрос ajax в функцию django - в консоли выводит ошибку: 500.
Это во вьюхе:

@csrf_exempt
def resource_create_multiblank(request):
    print('ok')
    return HttpResponse('update')

url:

path('<slug:slug>/create/multiblank/', views.resource_create_multiblank, name='resource-create-multiblank'),

JS:

function generateBlank(slug) {
    if (localStorage['persons'] != "[]" && localStorage['persons'] != undefined) {

        console.log(localStorage['persons']);
        console.log(slug);

        $.ajax({
            url: "create/multiblank/",
            type: "POST",
            data: {
                'persons': localStorage['persons'],
                'service': slug,
            },
            success: function (data) {
               console.log('OK');
            },
            error: function (data) {
                console.log('Error Server');
            },
            dataType: "json",
        });
    };
};

в Шаблоне:

<a herf="#" name="{{ slug }}" class="btn btn-sm btn-outline-secondary" onclick="generateBlank(name);"></a>

Подскажите пожалуйста, в чем может быть проблема?
Есть предположение, что ошибка банальна: не передается параметр slug в адрес. Если так - как мне правильно ее передать?
пробовал так:
JS:

url: "{% url 'resource-create-multiblank' "+slug+" %}",

и так:

url: "/"+slug+"/create/multiblank/",

В этом случае выдавала 404 ошибку.
Для того, чтобы работал POST Ajax выше прописал:

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
};

const csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

Немного разобравшись в коде, получил следующий результат:
В шаблоне:

<a name="{% url 'resource-create-multiblank' slug %}" class="btn btn-sm btn-outline-secondary" onclick="generateBlank(name);"></a>

В JS:

function generateBlank(url) {
    if (localStorage['persons'] != "[]" && localStorage['persons'] != undefined) {

    $.ajax({
        url: url,
        type: "POST",
        data: {
            'persons': localStorage['persons'],
        },
        success: function (data) {
           console.log('OK');
        },
        error: function (data) {
            console.log('Error Server');
        },
        dataType: "json",
    });
};
};

view:

@csrf_exempt
def resource_create_multiblank(request, slug):
    ....
    return JsonResponse(msg, safe=False)


Не понимаю как работает код
Условие задачи:

Текстовый файл состоит не более чем из 106 символов X, Y и Z.
Определите максимальную длину цепочки вида XYZXYZXYZ... (составленной
из фрагментов XYZ, последний фрагмент может быть неполным).

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

Что делает in в цикле while?
Почему в условиях из значения длинны что-то вычитается?

Пожалуйста, помогите разобраться
<code>
s = "XYZXZZYYZXYZXYZXYZX"
k = 'XYZ'
while k in s:
  k +=  'XYZ'
l = len (k)
if k in s: print (l-1)
elif k[:l -  2] in s: print (l -  2)
else: print (l -  3)
</code>

Ниже идет описание работы алгоритма, я не считаю его оптимальным, он практически не демонстирует никаких навыков - это простой брутфорс.
На мой взгляд единичный посимвольный проход всей строки был бы куда эффективнее - O(n) и продемонстрировал больше навыков.
<code>
s = "XYZXZZYYZXYZXYZXYZX"
k = 'XYZ' # (инициализация)
'''
cтрока k приращивается каждый раз на XYZ
и проверяется находится ли такая подстрока в s
с помощью оператора in
'''
while k in s:
  print('i')
  k +=  'XYZ'

'''
так как в цикле авансом прбавляются
3 cимвола без проверки их наличия (инициализация)
то для того чтобы найти неполные строки
используется вычитание из длины
'''
l = len (k) # получаем длину заведомо болшую

'''
это условие "сработает, если k in s: False – Интик"
потому что XYZ + XYZ не содержится в XYZ
'''
if k in s: print ('a', l-1)
'''
тут мы отнимаем сразу 2 символа
k[:l - 2] эквивалентно k[:-2]
XYZXYZX.. и ищем в s
'''
elif k[:l -  2] in s: print ('b', l -  2)
'''
иначе неглядя отнимаем три символа
XYZXYZ...
'''
else: print ('c',l -  3)

'''
таким образом код работает не правильно
из-за не полноты проверки

s = "XY"
k = 'XYZ'

должно вернуть 2 но возвращает 1

s = "XYZXY"
k = 'XYZ'

должно вернуть 5 но возвращает 4

s = "XYZXYZXY"
k = 'XYZ'

должно вернуть 8 но возвращает 7
'''
</code>


Заполнение пропущенных значений для модели машинного обучения
Нужно заполнить пропущенные значения для модели машинного обучения.
С помощью функции
calculate_means (oна заранее написана в задании):

def calculate_means(numeric_data):
means = np.zeros(numeric_data.shape[1])
for j in range(numeric_data.shape[1]):
    to_sum = numeric_data.iloc[:,j]
    indices = np.nonzero(~numeric_data.iloc[:,j].isnull())[0]
    correction = np.amax(to_sum[indices])
    to_sum /= correction
    for i in indices:
        means[j] += to_sum[i]
    means[j] /= indices.size
    means[j] *= correction
return pd.Series(means, numeric_data.columns)

data = pd.read_csv('data.csv')

X = data.drop('Grant.Status', 1)
y = data['Grant.Status']

numeric_cols = ['RFCD.Percentage.1', 'RFCD.Percentage.2', 'RFCD.Percentage.3',
            'RFCD.Percentage.4', 'RFCD.Percentage.5',
            'SEO.Percentage.1', 'SEO.Percentage.2', 'SEO.Percentage.3',
            'SEO.Percentage.4', 'SEO.Percentage.5',
            'Year.of.Birth.1', 'Number.of.Successful.Grant.1', 'Number.of.Unsuccessful.Grant.1']
categorical_cols = list(set(X.columns.values.tolist()) - set(numeric_cols))

means = calculate_means(X[numeric_cols])
X_real_mean = X[numeric_cols]
for i in range(len(numeric_cols)):
    X_real_mean.iloc[:, i] = X_real_mean.iloc[:, i].fillna(means.values[i])

Но не могу понять, что делать с этой ошибкой:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-7d79cc69311f> in <module>
  2 X_real_zeros = X[numeric_cols].fillna(0)
  3
 ----> 4 means = calculate_means(X[numeric_cols])
  5 X_real_mean = X[numeric_cols]
  6 for i in range(len(numeric_cols)):

 <ipython-input-8-a1d3e6085deb> in calculate_means(numeric_data)
  3     for j in range(numeric_data.shape[1]):
  4         to_sum = numeric_data.iloc[:,j]
  ----> 5         indices = np.nonzero(~numeric_data.iloc[:,j].isnull())[0]
  6         correction = np.amax(to_sum[indices])
  7         to_sum /= correction

 <__array_function__ internals> in nonzero(*args, **kwargs)

~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in nonzero(a)
1906
1907     """
-> 1908     return _wrapfunc(a, 'nonzero')
 1909
1910

~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
 53     bound = getattr(obj, method, None)
 54     if bound is None:
 ---> 55         return _wrapit(obj, method, *args, **kwds)
 56
 57     try:

 ~\anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapit(obj, method, *args, **kwds)
 46         if not isinstance(result, mu.ndarray):
 47             result = asarray(result)
 ---> 48         result = wrap(result)
 49     return result
 50

   ~\anaconda3\lib\site-packages\pandas\core\generic.py in __array_wrap__(self, result, context)
 1788             return result
 1789         d = self._construct_axes_dict(self._AXIS_ORDERS, copy=False)
-> 1790         return self._constructor(result, **d).__finalize__(
 1791             self, method="__array_wrap__"
  1792         )

 ~\anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name,
copy, fastpath)
311                 try:
312                     if len(index) != len(data):
 --> 313                         raise ValueError(
314                             f"Length of passed values is {len(data)}, "
315                             f"index implies {len(index)}."

 ValueError: Length of passed values is 1, index implies 6000.

Если добавить в той строке на которую ругается
.values, то перестаёт ругаться и вроде работает:

indices = np.nonzero(~numeric_data.iloc[:,j].isnull().values)[0]
                                                     ^^^^^^^

Природу сего явления объяснить не могу, видимо, какое-то недопонимание между данными
Pandas.Series и функцией
Numpy.


Неверная структура запроса
Задача: Отправляем номер телефона и смс, получаем сообщение с токеном. Получаем сообщение с ошибкой Wrong request struct
Запрос:
<code>
tok_en = requests.post(url_send_token, json={"phone": number_phone, "code": cod})
token = tok_en.text
print(token)
</code>
Вот сообщение:

{"meta":{"message":"Wrong request
struct","type":"error","error":400,"date":"2021-03-2"},"data":{"date":""}}

Что не так?

Вот ответ: В переменную cod передавалось вот так ('2345',) И надо просто выбрать по индексу и получилось 2345 и выглядит так:
<code>
tok_en = requests.post(url_send_token, json={"phone": number_phone, "code": cod[0]})
token = tok_en.text
print(token)
</code>


как обратить функцию в переменную? чтобы можно было после к ней обращаться и выдергивать file_id
<code>
def save_file(message):
    try:
        chat_id = message.chat.id
        file_info = bot.get_file(message.document.file_id)
        downloaded_file = bot.download_file(file_info.file_path)

        src = 'C:/tmp/' + message.document.file_name
        with open(src, 'wb') as new_file:
            new_file.write(downloaded_file)

        bot.reply_to(message, "сохраню это")
    except Exception as e:
        bot.reply_to(message, e)
</code>

Вы можете вернуть из функции file_id:

def save_file(message):
try:
    chat_id = message.chat.id
    file_info = bot.get_file(message.document.file_id)
    downloaded_file = bot.download_file(file_info.file_path)

    src = 'C:/tmp/' + message.document.file_name
    with open(src, 'wb') as new_file:
        new_file.write(downloaded_file)

    bot.reply_to(message, "сохраню это")
except Exception as e:
    bot.reply_to(message, e)
return message.document.file_id

Тогда в основном коде вы сможете присвоить переменной file_id и одновременно выполнить функцию:

new_file = save_file(message)


Как взять из списка текст по порядку?

k = []
inp = int(input("Сколько повторов : "))

while inp != 0:
    information = input("Информация : ")
    if information == "exit":
        inp = 0

    else:
        k.append(information)
        inp -= 1

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

>>> Информация : 1
>>> Информация : 2
...
>>> Информация : 1000
print(output)
>>> python 1 python 2 [...] python 999 python 1000

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

k = []
inp = int(input("Сколько повторов : "))

while inp != 0:
    information = input("Информация : ")
    if information == "exit":
        inp = 0

    else:
        k.append(information)
        inp -= 1

for information in k:
    print(f"python {information} ", end="")
print()

также можно  переделать первый цикл

k = []
inp = int(input("Сколько повторов : "))

for _ in range(inp):
    information = input("Информация : ")
    if information == "exit":
        break
    k.append(information)

for information in k:
    print(f"python {information} ", end="")
print()


Как преобразовать датафрейм в новый и добавить новые столбцы?
Есть фрейм данных:

                            0        2        3  5
0     2021-03-23 07:06:27.758  1.19236  1.19237  6
1     2021-03-23 07:06:31.898  1.19237  1.19238  6
2     2021-03-23 07:06:33.196  1.19237  1.19240  4
3     2021-03-23 07:06:33.919  1.19237  1.19238 -4
4     2021-03-23 07:06:36.596  1.19237  1.19239  4
...                       ...      ...      ... ..
87309 2021-03-24 09:01:07.234  1.18443  1.18462  4
87310 2021-03-24 09:01:07.640  1.18443  1.18461 -4
87311 2021-03-24 09:01:07.742  1.18443  1.18460 -4
87312 2021-03-24 09:01:08.201  1.18443  1.18461  4
87313 2021-03-24 09:01:14.891  1.18444  1.18461  2

Который толком особо ничего не передает, однако появилась идея его преобразовать в новый с шагом в 1м. Идея такая: в нов.
df2 имеются колонки:

  time        znachen_one   znachen_end  srings  max_2   min_2 max_3 min_3   6  4  2  0 -2  -4  -6

где в колонке
time берется первая дата

в колонке
znachen_one первое значение

в колонке
znachen_end последнее значение

в колонке
srings кол-во строк между
znachen_one и
znachen_end, если брать шаг в 1м , то их разное кол-во

в колонках 6 4 2 0 -2 -4 -6  кол-во из колонки 5 старого
df, т.е. из примера выше "6"-2раза, "4"-4раза, "-4" - 4 раза, "2"-1 раз, если некоторых параметров нет, то просто ставится 0 (нуль)

в колонках
max и
min соответственно максимальное и минимальное значение из колонок 2 и 3

Kаким методом выставить шаг и как это вообще будет выглядеть?
Как заполнить остальные колонки ?

Вот вам удочка, рыбу, надеюсь, сами научитесь ловить.
;)
Воспользуйтесь группировкой и агрегатными функциями.
Пример:
<code>
funcs = {
    "znachen_one": ("2", "first"),
    "znachen_end": ("2", "last"),
    "srings": ("0", "size"),
    # ...
}
res = df.groupby(pd.Grouper(key="0", freq="1T")).agg(**funcs)
</code>


Здравствуйте,проблема с библиотекой Tkinter.Почему окно 'warning_port_baud' открывается в окне 'win',если я установил его открытие только по условию?
Ссылка на проект
my.py - нужный файл.
Необходимо залить на ардуино код \Arduino\prototype.ino , предварительно выбрав бодрейт (строка 407)
Код целиком:

import serial.tools.list_ports
from tkinter import *
from Arduino import Arduino
from win32api import GetSystemMetrics
import time

resx_win = str(int((GetSystemMetrics(0)/2)-(800/2)-9))          #
resy_win = str(int((GetSystemMetrics(1)/2)-(500/2)-35))         #
resx_head = str(int((GetSystemMetrics(0)/2) - (800/2)-9))       # Переменные для расположения окон посередине экрана
resy_head = str(int((GetSystemMetrics(1)/2) - (500/2)-35))      #
warningx_head = str(int((GetSystemMetrics(0)/2)-(300/2)-9))     #
warningy_head = str(int((GetSystemMetrics(1)/2) - (200/2)-35))  #

ports = serial.tools.list_ports.comports()  #
for port, desc, hwid in sorted(ports):      # Инициализация портов(разделение строки
    port                                    # состоящей из нескольких портов ещё не делал)
                                            # <Работает в тестовом режиме>

head = Tk()

head.geometry('800x500+'+resx_head+'+'+resy_head)
head.title('Лаунчер')
head.resizable(width=False, height=False)
head.wm_attributes('-alpha', 0.95)

def warning_port_baud_def():
    warning_port_baud = Tk()
    warning_port_baud.geometry('300x200+' + warningx_head + '+' + warningy_head)
    warning_port_baud.title('Ошибка')
    warning_canvas = Canvas(warning_port_baud, width=300, height=200)
    warning_canvas.pack()
    warning_port_baud_frame = Frame(warning_port_baud)
    warning_port_baud_frame.place(relwidth=1, relheight=1)

    warning_port_baud_label = Label(warning_port_baud_frame,text='Введите \nнеобходимые\n значения '    #
                                                '\nдля порта \nи скорости', font= ("message-box",16))   #
    warning_port_baud_label.place(x=120, y=20, width=180, height=150)                                   # Окно,вылезающее при
    global warning_image                                                                                # некорректном вводе
    warning_image = PhotoImage(file='y_warning.png', master=warning_port_baud_frame)                    # порта или бодрейта
    warning_ico = Label(warning_port_baud_frame, image=warning_image)                                   # Ну и картинка для
    warning_ico.place(x=15, y=43)                                                                       # этого окна
def WinSon():

    port_ch = (var_p.get())         #
    if port_ch == PortList[0]:      # Если в меню не выбран порт,
        port_ch = entry_p.get()     # читает поле ввода
        print(port_ch)              #

    baudrate = (var_bd.get())       #
    if baudrate == BaudList[0]:     # То же самое,
        baudrate = entry_bd.get()   # только уже с бодрейтом
        print(baudrate)             #

    if len(port_ch) or len(baudrate) == 0:  #
        print(len(port_ch))                 # Проверка на длину введённых данных
        print(len(baudrate))                # <Потом добавлю поиск подстроки 'COM'>
        warning_port_baud_def()             #

    board = Arduino(baudrate, port= port_ch)    # Инициализация ардуинки и её порта и скорости
    board.pinMode(13, "OUTPUT")                 # Добавил,пока,просто так
    head.withdraw()
    win = Toplevel()
    win.geometry('800x500+' + resx_win + '+' + resy_win)
    win.title('Набор')

    win.protocol("WM_DELETE_WINDOW", lambda: head.destroy())    # Закрывает окно head,при открытии этого

    canvas2 = Canvas(win,width = 800,height = 500)
    canvas2.pack()
    frame_lobby = Frame(win)
    frame_lobby.place(relwidth = 1,relheight = 1)

    win.mainloop()

canvas = Canvas(head,width = 800,height = 500)
canvas.pack()
frame = Frame(head)
frame.place(relwidth = 1,relheight = 1)

bg = PhotoImage(file = 'bg_800x500.png')    #
wallpaper = Label(frame,image = bg)         # Пикча для BG
wallpaper.pack()                            #

t_p = Label(frame, text='ПОРТ/выбери или напиши', bg='#A52A2A',font = 20)   #
t_p.place(x=20, y = 220, width = 370, height = 60)                          #
PortList = ['Выберите порт', port]                                          #
var_p = StringVar(frame)                                                    # Меню для порта
var_p.set(PortList[0])                                                      #
opt_p = OptionMenu(frame, var_p, *PortList)                                 #
opt_p.place(x=20, y=280, width=185, height=30)                              #

entry_p = Entry(frame,font = 15)                                            # Поле ввода для порта
entry_p.place(x = 205,y = 280,width = 185,height = 30)                      #

t_bd = Label(frame,text = 'БОДРЕЙТ указанный в \nскетче ардуино/выбери или напиши', #
    bg = '#A52A2A',font = 20)                                                       #
t_bd.place(x = 410,y = 220,width = 370,height = 60)                                 #
BaudList = ['Выберите скорость',9600,19200,38400,57600,115200]                      # Меню для бодрейта
var_bd = StringVar(frame)                                                           #
var_bd.set(BaudList[0])                                                             #
opt_bd = OptionMenu(frame, var_bd, *BaudList)                                       #
opt_bd.place(x = 410,y = 280,width = 185,height = 30)                               #

entry_bd = Entry(frame, font=15,bd = 3)                                             # Поле ввода для бодрейта
entry_bd.place(x=595, y=280, width=185, height=30)                                  #

further = PhotoImage(file = 'далее.png')                                            #
small_further = further.subsample(15, 15)                                           # Кнопка и картинка
further_Button = Button(frame,text = 'Далее',image = small_further,                 # выполняет команду
    compound = LEFT,font = ("lucida console", 16),bd = 5,command = WinSon)          # WinSon
further_Button.place(x = 350,y = 370,width = 130,height = 50)                       #

head.mainloop()

Само условие

    if len(port_ch) or len(baudrate) == 0:  #
        print(len(port_ch))                 # Проверка на длину введённых данных
        print(len(baudrate))                # <Потом добавлю поиск подстроки 'COM'>
        warning_port_baud_def()             #

Ошибка была в построении условия,ниже неправильный вариант

if len(port_ch) or len(baudrate) == 0:  #
    print(len(port_ch))                 # Проверка на длину введённых данных
    print(len(baudrate))                # <Потом добавлю поиск подстроки 'COM'>
    warning_port_baud_def()             #

А это уже рабочий(правильный)

if len(port_ch) == 0 or len(baudrate) == 0:  #
    print(len(port_ch))                 # Проверка на длину введённых данных
    print(len(baudrate))                # <Потом добавлю поиск подстроки 'COM'>
    warning_port_baud_def()             #

Большое спасибо Интику за помощь в обнаружении ошибки


Игра в города Python
Условие задачи: вывести все возможные последовательности городов, которые удовлетворяют условию: последняя буква текущего слова соответствует первой букве следующего.
Я использую список из N городов, записываю в файл последовательности городов через пробел. Сами последовательности разделены
\n.
Я хочу реализовать проход по всем словам в списке, которые бы инициализировали старт цикла, который бы создавал последовательности, инициализированные этим словом. Например:

[milltimber, ringwood, dundonald, londonderry, ystrad]

Выходные последовательности:

milltimber ringwood dundonald
ringwood dundonald
londonderry ystrad dundonald
ystrad dundonald

Моя реализация такова:

for city_1 in cities_list:
    создаем список cities_list_iterable и удаляем из него city_1
    for city_2 in cities_list_iterable:
        Проверяем, совпадает ли первая буква city_2 с последней буквой city_1, и если да:
            добавляем city_2 в текущую последовательность, удаляем его из cities_list_iterable
            присваиваем city_1 значение city_2

Однако при такой реализации нам необходимо вернутся в начало цикла
for city_2 in cities_list_iterable:
что бы снова начать проверять все ещё не удалённые города на соответствие условию. Я не понимаю как это сделать.
Также я не уверен в правильности этого алгоритма, а также в его оптимальности. Я раздумывал над решением через графы, но не совсем понял, как найти в данном случае все последовательности.
Оптимальность алгоритма важна, поэтому прошу подсказать также другие варианты решения задачи.

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


Как в новом файле Excel записать информацию взятую из существующего файла Excel, с использованием openpyxl?
При нажатии на кнопку должны проводиться расчеты и создаваться новый файл Excel.
На данный момент почему-то происходит превышение допустимого диапазона у кортежа в wbsheet[row][1].value = Name2
(обработка начинается со второй строки, т.к. в первой названия столбцов)
<code>
    def button_action(self):
        wb = openpyxl.Workbook()
        wb.create_sheet('Sheet1')
        wbsheet = wb['Sheet1']
        book = openpyxl.load_workbook(r'AO\Name.xlsx')
        sheet = book['Sheet1']
        col = sheet.max_row ///87
        raschety = int(self.rasch_entry.get())
        for row in range(2, col+1):
            WbId= int(sheet[row][0].value)
            Name2 = int(sheet[row][1].value)
            Name3 = int(sheet[row][3].value)
            Name4 = int(sheet[row][3].value)
            Name5 = int(sheet[row][4].value)
            Name6 = str(sheet[row][5].value)
            Name7 = int(sheet[row][6].value)
            print(WbIda)///1,2,3,4
            if raschety <= Name4:
                Name8 = Name4 / (Name2 * Name3)
                Name9 = Name4 / (Name5 * Name7)
                Name10 = Name8 * Name9
                wbsheet[row][0].value = WbIda
                wbsheet[row][1].value = Name2 ///IndexError: tuple index out of range
                wbsheet[row][2].value = Name3
                wbsheet[row][3].value = Name4
                wbsheet[row][4].value = Name5
                wbsheet[row][5].value = Name6
                wbsheet[row][6].value = Name7
                wbsheet[row][7].value = Name8
                wbsheet[row][8].value = Name9
                wbsheet[row][9].value = Name10
        wb.save('NameDone.xlsx')
</code>

Короче, перед тем как записывать информацию в excel, требуется добавить пустые "ячейки", как я понимаю это нужно именно для библиотеки, т.к. фактически ничего не добавляется.
Как пример:
<code>
sheet21.append(['', '', '', '', '', '', ''])
</code>
Тут я добавил 7 "ячеек" т.к. в документе используется 7 столбцов.


Можно ли обнулить переменную цикла?
<code>
for i in range(0, 10):
    print(i)
    i = 0
</code>
Я просмотрел этот код по шагам с помощью Visualize Python и там сначала переменная i становится равна 0, а потом, как только начинает исполняться очередная итерация цикла for, i становится равна следующему значению, будто бы её никто и не обнулял.
Можно ли как-то сделать так, чтобы после выполнения итерации цикла переменная i обнулялась? Я понимаю, что это приведёт к бесконечному циклу for, но, возможно ли такое в теории и если возможно, то как это провернуть?

for i in range(0, 10):
    print(i)
    i = 0

Так не работает. Можно заменить for на while — например так:

i = 0
while i < 10:
    print(i)
    i += 1
    i = 0 # немножко бессмысленная манипуляция, но это просто как пример ;)


Как оставить определенные символы в текстовом файле питон
Есть папка со множеством папок и файлов, среди которых есть файлы txt. В этих файлах нужно оставить только определенные символы, определенные символы заменить на слова (например @ на собака) и удалить двойные пробелы.
Вот, что написал для перебора файлов
<code>
import os
from pathlib import Path

characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя!\'\"(),-.:;? '

names = os.listdir(os.getcwd())
for name in names:
    fullname = os.path.join(os.getcwd(), name)
    if os.path.isfile(fullname) and Path(fullname).suffix == '.txt':
        with open(fullname) as f:
            s = f.read()
</code>
Собственно, после этого нужно преобразовать строку s. Полагаю, для всего этого можно использовать регулярные выражения, но не могу понять как именно.

def create_replacer():
    import re

    allowed = '''-a-z а-яё!'"(),.:;?'''
    # тире важно оставить в самом начале (или в конце),
    # т.к. посередине он воспринимается как спецсимвол для regex[...]

    replace_table = {
        '@': 'собака'
    }

    ###
    regex = r'[^' + allowed.replace(']', r'\]') + ']'

    replacer = lambda match_obj: replace_table.get(match_obj.group(0), '')

    def main_replacer(string):
        string = re.sub(r'\s\s+', '', string)
        return re.sub(regex, replacer, string, flags = re.IGNORECASE)

    return main_replacer

###
replace = create_replacer()

string = '@ и еще @?:%№;%№      \n\n\n x'

print( replace(string) ) # собака и еще собака?:;x

[^перечисленое] — такое выражение одначает «всё, кроме перечисленных символов в квадратных скобках»
Исходную строку взял в три кавычки, чтобы не париться с экранированием кавычек.

'\s\s+':
\s — любой пробельный символ (space), включая переносы строки.
+ — один или много раз подряд. Удалит всё пробельное, что встретится 2 или больше раз подряд.

main_replacer первым шагом удаляет все пробелы, вторым шагом производит удаление / замену всех лишних символов, для каждого совпадения вызывая функцию
replacer, которая в виде первого аргумента получает объект совпадения.

match_obj.group(0) — совпавшая строка используется как ключ словаря. Если для него есть подготовленная замена - вернется она, иначе -
'' по умолчанию.
P.s. комменатрий вначале кода надо бы оставить, чтобы не забыть про потенциальный источник бага. Или в начальной строке перечислить весь алфавит, а экранирование
\- предусмотреть в коде.