Причина: реализация приводит оба аргумента к строкам (str(a) + str(b)), поэтому "добавление" даёт конкатенацию "23", а не арифметическую сумму 5.
Стратегия отладки (шаги, как я бы действовал):
Запустить тест и убедиться, что он действительно падает, посмотреть сообщение об ошибке/значение.Воспроизвести поведение в REPL: вызвать add(2,3) и посмотреть результат.Просмотреть реализацию функции — заметить str(a)+str(b).Подумать о требуемых семантиках функции: должна ли она складывать только числа или ещё и строки? Сформулировать ожидаемое поведение.Расширить тесты, чтобы покрыть граничные случаи (float, отрицательные, нечисловые аргументы), чтобы поведение было явным.Исправить реализацию и запустить тесты снова.При необходимости добавить проверки типов и явные ошибки для некорректных входных данных.
Дополнительные тесты (pytest-стиль). Эти тесты покрывают целые, дробные, отрицательные значения и некорректные входы:
def test_add_mixed_string_and_number_raises(): with pytest.raises(TypeError): add(2, "3")
def test_add_non_numeric_strings_raises(): with pytest.raises(TypeError): add("a", "b")
Если вы не хотите поддерживать строки вовсе — уберите тест test_add_numeric_strings_allowed и вместо него ожидайте TypeError при любых строках.
Исправление реализации
Вариант 1 — минимальное исправление, если предполагается просто складывать аргументы (наиболее тривиально):
def add(a, b): return a + b
Этот вариант работает для чисел, но для строк вернёт конкатенацию (если строковые аргументы допустимы — возможно, это нежелательно).
Вариант 2 — более явный и безопасный: разрешаем числа (int/float/complex/ bool) и опционально числовые строки, в остальных случаях бросаем TypeError:
from numbers import Number
def add(a, b):
Если оба — числовые типы (int, float, complex, bool)if isinstance(a, Number) and isinstance(b, Number): return a + b # Если оба — строки, попробуем преобразовать в числа (целые или с плавающей точкой) if isinstance(a, str) and isinstance(b, str): try: # пробуем целое, иначе — float if '.' in a or 'e' in a.lower() or '.' in b or 'e' in b.lower(): return float(a) + float(b) else: return int(a) + int(b) except ValueError: raise TypeError("add() expects numeric strings or numbers") raise TypeError(f"Unsupported operand types for add(): {type(a).__name__} and {type(b).__name__}")
Пояснения к варианту 2:
bool — подкласс Number в Python, поэтому True/False будут трактоваться как 1/0.Если хотите запретить bool отдельно, можно добавить условие type(a) is bool: ...Решение с преобразованием строк — опционально. Если это не нужно, проще сразу выдавать TypeError при строках.
Как запустить тесты:
Установите pytest (pip install pytest).Поместите код функции и тесты в файл(ы) и выполните: pytest -q
Итог:
Причина падения — использование str(a)+str(b), что даёт строковую конкатенацию.Исправление — использовать сложение a + b (либо более строгие проверки типов, если нужно). Добавленные тесты покрывают ожидаемое поведение и граничные случаи.
Коротко — почему падает:
Причина: реализация приводит оба аргумента к строкам (str(a) + str(b)), поэтому "добавление" даёт конкатенацию "23", а не арифметическую сумму 5.Стратегия отладки (шаги, как я бы действовал):
Запустить тест и убедиться, что он действительно падает, посмотреть сообщение об ошибке/значение.Воспроизвести поведение в REPL: вызвать add(2,3) и посмотреть результат.Просмотреть реализацию функции — заметить str(a)+str(b).Подумать о требуемых семантиках функции: должна ли она складывать только числа или ещё и строки? Сформулировать ожидаемое поведение.Расширить тесты, чтобы покрыть граничные случаи (float, отрицательные, нечисловые аргументы), чтобы поведение было явным.Исправить реализацию и запустить тесты снова.При необходимости добавить проверки типов и явные ошибки для некорректных входных данных.Дополнительные тесты (pytest-стиль). Эти тесты покрывают целые, дробные, отрицательные значения и некорректные входы:
import pytest
def test_add_integers():
assert add(2, 3) == 5
def test_add_floats():
assert add(2.5, 1.5) == 4.0
def test_add_negative():
assert add(-1, 1) == 0
def test_add_zero():
assert add(0, 0) == 0
def test_add_numeric_strings_allowed():
assert add("2", "3") == 5 # опция: разрешаем числовые строки
def test_add_mixed_string_and_number_raises():
with pytest.raises(TypeError):
add(2, "3")
def test_add_non_numeric_strings_raises():
with pytest.raises(TypeError):
add("a", "b")
Если вы не хотите поддерживать строки вовсе — уберите тест test_add_numeric_strings_allowed и вместо него ожидайте TypeError при любых строках.
Исправление реализации
Вариант 1 — минимальное исправление, если предполагается просто складывать аргументы (наиболее тривиально):
def add(a, b):
return a + b
Этот вариант работает для чисел, но для строк вернёт конкатенацию (если строковые аргументы допустимы — возможно, это нежелательно).
Вариант 2 — более явный и безопасный: разрешаем числа (int/float/complex/ bool) и опционально числовые строки, в остальных случаях бросаем TypeError:
from numbers import Number
def add(a, b):
Если оба — числовые типы (int, float, complex, bool)if isinstance(a, Number) and isinstance(b, Number):return a + b
# Если оба — строки, попробуем преобразовать в числа (целые или с плавающей точкой)
if isinstance(a, str) and isinstance(b, str):
try:
# пробуем целое, иначе — float
if '.' in a or 'e' in a.lower() or '.' in b or 'e' in b.lower():
return float(a) + float(b)
else:
return int(a) + int(b)
except ValueError:
raise TypeError("add() expects numeric strings or numbers")
raise TypeError(f"Unsupported operand types for add(): {type(a).__name__} and {type(b).__name__}")
Пояснения к варианту 2:
bool — подкласс Number в Python, поэтому True/False будут трактоваться как 1/0.Если хотите запретить bool отдельно, можно добавить условие type(a) is bool: ...Решение с преобразованием строк — опционально. Если это не нужно, проще сразу выдавать TypeError при строках.Как запустить тесты:
Установите pytest (pip install pytest).Поместите код функции и тесты в файл(ы) и выполните: pytest -qИтог:
Причина падения — использование str(a)+str(b), что даёт строковую конкатенацию.Исправление — использовать сложение a + b (либо более строгие проверки типов, если нужно). Добавленные тесты покрывают ожидаемое поведение и граничные случаи.