import numpy as np

def backprop(W, b, z, a, a_prev, dA, activation_deriv, lr):
    """
    Обратное распространение для одного слоя (numpy-версия).
    W: (m, d)
    b: (m, 1)
    z: (m, 1)
    a: (m, 1)
    a_prev: (d, 1)
    dA: (m, 1)
    """
    # гарантируем, что всё двумерное
    z = np.atleast_2d(z).reshape(-1, 1)
    a = np.atleast_2d(a).reshape(-1, 1)
    a_prev = np.atleast_2d(a_prev).reshape(-1, 1)
    dA = np.atleast_2d(dA).reshape(-1, 1)

    # 1. delta = dA * σ'(z)
    delta = dA * activation_deriv(z,0.5)      # (m,1)

    # 2. dW = delta @ a_prev.T
    dW = delta @ a_prev.T                 # (m,d)

    # 3. db = просто delta (или сумма по batch)
    db = delta                            # (m,1)

    # 4. dA_prev = W.T @ delta
    dA_prev = W.T @ delta                 # (d,1)

    # 5. обновление параметров
    W -= lr * dW
    b -= lr * db

    return W, b, dA_prev