Копипаста — это плохо.

Во-первых, если код нужно будет поменять — придётся искать все места, где он использовался и менять его везде, по всем файлам.

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

В-третьих, чем больше кода — тем труднее его читать.


Пример 1

Плохо:


import os
import requests

from urllib.parse import urljoin


def fetch_nasa_images(api_key, folder):
    ...
    images_names = ...
    for image_name in images_names:
        ...
        image_url = ...
        image_path = os.path.join(folder, image_name)
        try:
            response = requests.get(image_url)
            response.raise_for_status()
            with open(image_path, 'wb') as file:
                file.write(response.content)
        except requests.exceptions.HTTPError as e:
            logging.info(f'HTTPError: {e}')


def fetch_spacex_images(flight_id, folder):
    ...
    images_names = ...
    for image_name in images_names:
        ...
        image_url = urljoin(..., flight_id)
        image_path = os.path.join(folder, image_name)
        try:
            response = requests.get(image_url)
            response.raise_for_status()
            with open(image_path, 'wb') as file:
                file.write(response.content)
        except requests.exceptions.HTTPError as e:
            logging.info(f'HTTPError: {e}')


def main():
    ...
    fetch_nasa_images(nasa_api_key, nasa_imgs_folder)
    fetch_spacex_images(spacex_api_key, spacex_imgs_folder)

Хорошо:


import os
import requests

from urllib.parse import urljoin


def download_image(image_path, image_url):
    try:
        response = requests.get(image_url)
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        logging.info(f'HTTPError: {e}')

    with open(image_path, 'wb') as file:
        file.write(response.content)


def fetch_nasa_images(api_key, folder):
    ...
    images_names = ...
    for image_name in images_names:
        ...
        image_url = ...
        image_path = os.path.join(folder, image_name)
        download_image(image_path, image_url)


def fetch_spacex_images(flight_id, folder):
    ...
    images_names = ...
    for image_name in images_names:
        ...
        image_url = urljoin(..., flight_id)
        image_path = os.path.join(folder, image_name)
        download_image(image_path, image_url)


def main():
    ...
    fetch_nasa_images(nasa_api_key, nasa_imgs_folder)
    fetch_spacex_images(spacex_api_key, spacex_imgs_folder)


Пример 2

Плохо:


...
if mentor:
    text = (
        f'🎉 Привет, Ментор {mentor["name"]["first"]}! 🎉\n\n'
        'Это бот для отправки поздравлений ментору ❤️\n\n'
        '✨ Нажмите кнопку "ОТПРАВИТЬ ОТКРЫТКУ" чтобы отправить поздравления! ✨'
    )
    keyboard = main_keyboard
else:
    text = (
        f'🎉 Привет, Ученик {username}! 🎉\n\n'
        'Это бот для отправки поздравлений ментору ❤️\n\n'
        '✨ Нажмите кнопку "ОТПРАВИТЬ ОТКРЫТКУ" чтобы порадовать своего ментора! ✨'
    )
    keyboard = main_keyboard

await message.answer(text, reply_markup=keyboard)

Хорошо:


...
if mentor:
    recipient = f'Ментор {current_mentor["name"]["first"]}'
    action = 'отправить поздравления'
else:
    recipient = f'Ученик {message.from_user.username}'
    action = 'порадовать своего ментора'

text = (
    f'🎉 Привет, {recipient}! 🎉\n\n'
    'Это бот для отправки поздравлений ментору ❤️\n\n'
    f'✨ Нажмите кнопку "ОТПРАВИТЬ ОТКРЫТКУ" чтобы {action}! ✨'
)
keyboard = main_keyboard

await message.answer(text, reply_markup=keyboard)