from dataclasses import dataclass
import random
from PIL import Image, ImageDraw, ImageFont
# from numba import prange


@dataclass
class Drawing:
    """Рисуем чернилами на листке"""
    COLOR_USE: bool
    stroka: str
    font_use: ImageFont
    list_size: int
    clear_paper: ImageDraw
    line_start: int
    offset: int
    spaser_word: int
    font_name: str
    font_color: list

    def _drawing_word(self, number: int, slovo: str):
        """Рисуем слово"""
        img_slovo = Image.new('RGBA', (self.width+number, self.height),
                              (255, random.randint(0, 150),
                               random.randint(0, 200), self.color_word))
        draw = ImageDraw.Draw(img_slovo)
        draw.text((number, 0), slovo, fill=(
            self.font_color[0],
            self.font_color[1],
            self.font_color[2]
        ), font=self.font_use)
        return img_slovo

    def _drawing_line(self):
        """Рисуем слова на строке"""
        for slovo in self.stroka.split():
            # print(self.width, self.height)
            new_size = self.font_use.getbbox(slovo)
            self.width, self.height = new_size[2], new_size[3]
            self.color_word = 200 if self.COLOR_USE else 0
            # Пишем на этой картинке шрифтом
            if self.font_name == 'Salavat':
                img_slovo = self._drawing_word(15, slovo)
            else:
                img_slovo = self._drawing_word(10, slovo)
            # поварачиваем текст
            ran_rotate = random.uniform(-2.0, 1.5)
            img_slovo = img_slovo.rotate(ran_rotate, expand=True)
            # img_slovo = img_slovo.transform(img_slovo.size, Image.AFFINE, (1, 20, 0, 0, 1, 0), resample=Image.BICUBIC)
            # Добавляем картинку со словом в масив
            self.mass_img.append(img_slovo)
        return self.mass_img

    def _paste_on_paper(self):
        """Рисуем строки на листке"""
        self.color_line = 155 if self.COLOR_USE else 0
        # Создаём картинку всей строки
        stroka_img = Image.new('RGBA', (self.list_size, 135), (255, 255, 255, self.color_line))
        line_width = 0
        for i in range(len(self.mass_img)):
            # Узнаём ширину картинки)
            width = self.mass_img[i].width
            # Наносим картинку фото на картинку строки
            ran_down_text = random.randint(-2, 2)
            stroka_img.paste(self.mass_img[i], (line_width, ran_down_text),
                             mask=self.mass_img[i])
            # Если есть это не последнее слово то добавляем после него пробел
            # рандомный отступ между слов
            ran_spase = random.randint(25, 35)  # 30/len(mass_img)
            # print(ran_spase)
            line_width += width + ran_spase  # spaser_word  # 30
            # except:
            #     len_width += width
        self.clear_paper.paste(stroka_img, (self.line_start, self.offset), mask=stroka_img)

    def draw(self):
        self.mass_img = []
        self._drawing_line()
        self._paste_on_paper()

 Public
Share a link to this review

7.59% issue ratio

R19 Bad variable name

Simple rule: read a variable name as if you were English-speaking person without a context and guess what's inside - and if you have no clue, then you should give it a better name. Exceptions: i, j, x, y etc.

R1 Missing type hints

Type hints help humans and linters (like mypy) to understand what to expect "in" and "out" for a function. Not only it serves as a documentation for others (and you after some time, when the code is wiped from your "brain cache"), but also allows using automated tools to find type errors.

Missing return type hint

L12 Redundant code / overengineering

This code is not really needed or may be simplified

Suggested change:
fill=self.font_color[:3]
R6 Copy-paste

Copy-paste lead to errors very, very often because developers forget to change value on one of copy-pasted lines . You should avoid it as much as possible. Usually a good solution is to extract the things that differ into separate variables.

Suggested change:
number = 15 if self.font_name == 'Salavat' else 10
img_slovo = self._drawing_word(number, slovo)
L22 Function with side effects

Side effects are evil: it's very hard to track what function does under the hood, because function signature does not reflect side effects. Always try to write "pure" functions, i.e. those which receive inputs, do something internally, and return output. You should be able to run such function million times and get exactly the same result with nothing changed in the environment. However, side effects are totally OK if that's the only thing the function does.

R4 Range-based iteration

Using len and range in python's for loop smells. Idiomatic python iteration looks like for element in collection. If you need element's index as well, use for i, element in enumerate(collection).

Suggested change:
for img in self.mass_img

Create new review request