Помогите найти ошибки в решении задачи c декораторами

Рейтинг: 0Ответов: 1Опубликовано: 12.01.2023

Необходимо написать 3 декоратора arrow, number_filter, round_dict, такие что:

  • arrow преобразует входной словарь в список строк в виде 'key -> value'.
  • number_filter фильтрует входной список и оставляет только числовые типы
  • round_dict округляет числа во входном списке и создает словарь, где ключ это новое значение числа, а его значение - удвоенное новое значение числа.

нужно задекорируй функцию like_numbers(которая принимает список и возвращает некую строку) тремя декораторами в правильном порядке так, чтобы получить результат показанный в примере.
Пример:

# тут твои декораторы
def like_numbers(items: list):
    return f"I like to filter, rounding, doubling, "
           f"store and decorate numbers: {', '.join(items)}!"

items = ["35", 2.1, 4, 8.88, -123, "S", {"a", "b", 5}]

like_numbers(items) == "I like to filter, rounding, doubling, "
                       "store and decorate numbers: "
                       "2 -> 4, 4 -> 8, 9 -> 18, -123 -> -246!"

Мой код не работает, помогите, пожалуйста, найти ошибки:

from typing import Callable, Any


def arrow(func: Callable) -> Any:
    def inner(new_dict: dict) -> Any:
        result_list = []
        for key, value in new_dict.items():
            result_list.append(str(key) + "->" + str(value))
            return func(result_list)
    return inner


def number_filter(func: Callable) -> Any:
    def inner(items: list) -> Any:
        list_number = [item for item in items if isinstance(item, (int, float))]
        func(list_number)
    return inner


def round_dict(func: Callable) -> Any:
    def wrapper(list_number: list) -> Any:
        new_dict = {round(item): (round(item)) * 2 for item in list_number} 
        return func(new_dict) 
    return wrapper  


@arrow
@round_dict
@number_filter
def like_numbers(items: list) -> str:
    return f"I like to filter, rounding, doubling, store and decorate numbers: {','.join(items)}!"

Ответы

▲ 1

Я всё поправил:

from typing import Callable, Any

def arrow(func: Callable) -> Any:
    def inner(new_dict: dict) -> Any:
        result_list = []
        for key, value in new_dict.items():
            result_list.append(f'{key} -> {value}')
        return func(result_list)
    return inner

def number_filter(func: Callable) -> Any:
    def inner(items: list) -> Any:
        list_number = [item for item in items if isinstance(item, (int, float))]
        return func(list_number)
    return inner

def round_dict(func: Callable) -> Any:
    def wrapper(list_number: list) -> Any:
        new_dict = {round(item): (round(item)) * 2 for item in list_number} 
        return func(new_dict) 
    return wrapper  

@number_filter
@round_dict
@arrow
def like_numbers(items: list) -> str:
    return f"I like to filter, rounding, doubling, store and decorate numbers: {', '.join(items)}!"

items = ["35", 2.1, 4, 8.88, -123, "S", {"a", "b", 5}]

assert like_numbers(items) == "I like to filter, rounding, doubling, "\
                       "store and decorate numbers: "\
                       "2 -> 4, 4 -> 8, 9 -> 18, -123 -> -246!"

Ошибки:

  1. arrow - лишний отступ у return, не совсем верное форматирование строки (потеряны пробелы), я переделал форматирование на f-string, так короче
  2. number_filter - потерян return у вызова func
  3. декорирование функции like_numbers сделано в обратном порядке, нужно декорировать именно в том порядке, как нужно чтобы вызывались декораторы
  4. в самой функции like_numbers потерян пробел в строке ',' для join

Ну и проверку лучше делать через assert. Кажется, ничего не забыл.

Если не понимаете, что именно не работает - вставляйте во все функции отладочную печать, убирайте всё лишнее и запускайте код с минимальным функционалом (в данном случае - с одним декоратором для начала). Постепенно так всё можно починить.