Модель последнего устройства пользователя
Есть пользователи, справочник устройств и история устройств пользователя.
Для каждого пользователя, у которого есть хотя бы одна запись в истории, нужно вернуть модель его последнего устройства.
Последнее устройство определяется так:
- активная запись с
end_date IS NULLсчитается новее закрытых записей; - иначе берем максимальный
end_date; - при равном
end_dateберем максимальныйstart_date; - при полном tie берем больший
device_id.
Верните:
user_id;vendor_name;model_name.
Сортировка: user_id ASC.
Schema
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE devices (
device_id INTEGER PRIMARY KEY,
vendor_name TEXT NOT NULL,
model_name TEXT NOT NULL
);
CREATE TABLE device_history (
user_id INTEGER NOT NULL,
device_id INTEGER NOT NULL,
start_date TEXT NOT NULL,
end_date TEXT
);Решение прямо на странице
Напишите код, запустите проверки и только потом открывайте разбор.
Нажмите «Запустить проверки» или Ctrl+Enter.
Показать разбор
Идея решения
Нужно ранжировать строки истории внутри каждого пользователя. ROW_NUMBER() удобнее, чем GROUP BY MAX(end_date), потому что после выбора даты нужно вернуть связанные поля устройства и корректно обработать tie-break.
COALESCE(end_date, '9999-12-31') поднимает активное устройство наверх.Эталонный код
WITH ranked_history AS (
SELECT
h.user_id,
d.vendor_name,
d.model_name,
ROW_NUMBER() OVER (
PARTITION BY h.user_id
ORDER BY
COALESCE(h.end_date, '9999-12-31') DESC,
h.start_date DESC,
h.device_id DESC
) AS rn
FROM device_history h
JOIN devices d ON d.device_id = h.device_id
)
SELECT user_id, vendor_name, model_name
FROM ranked_history
WHERE rn = 1
ORDER BY user_id;F-score по y_true и y_pred
Даны два массива одинаковой длины:
y_true— истинные бинарные метки 0/1;y_pred— предсказанные бинарные метки 0/1.
Нужно посчитать F1-score для positive class 1.
Если precision и recall одновременно равны нулю, верните 0.0.
Сигнатура
def binary_f_score(y_true: list[int], y_pred: list[int]) -> float:Решение прямо на странице
Напишите код, запустите проверки и только потом открывайте разбор.
Нажмите «Запустить проверки» или Ctrl+Enter.
Показать разбор
Подсказки
- Positive class
Считайте TP, FP и FN только относительно класса 1.
- Нулевой знаменатель
Если модель не предсказала ни одного positive и в y_true нет positive, F-score должен быть 0.
Идея решения
Сначала считаем tp, fp и fn для positive class 1.
precision = tp / (tp + fp), recall = tp / (tp + fn), а затем F1 = 2 * precision * recall / (precision + recall). Если знаменатель F1 равен нулю, возвращаем 0.Эталонный код
def binary_f_score(y_true: list[int], y_pred: list[int]) -> float:
if len(y_true) != len(y_pred):
raise ValueError('y_true and y_pred must have the same length')
tp = fp = fn = 0
for true_label, predicted_label in zip(y_true, y_pred):
if true_label not in (0, 1) or predicted_label not in (0, 1):
raise ValueError('labels must be 0 or 1')
if predicted_label == 1 and true_label == 1:
tp += 1
elif predicted_label == 1 and true_label == 0:
fp += 1
elif predicted_label == 0 and true_label == 1:
fn += 1
precision = 0.0 if tp + fp == 0 else tp / (tp + fp)
recall = 0.0 if tp + fn == 0 else tp / (tp + fn)
if precision + recall == 0:
return 0.0
return 2 * precision * recall / (precision + recall)