DigitableCourses

Модели на FTS

Заданий: 8

Вы пишете модель, вердикт выносит исполнение.

Что это за раздел и что означают виды заданий

Разбор, авторские примеры и свойства, приёмочные входы задания — всё считается в этой вкладке. Порядок прохождения и разбор паттернов — на /fts/practice/; здесь задания стоят по id, а не по пути.

build
Высшее свидетельство: модель компилируется и исполняется, вердикт выносит инструмент.

Где лежит ваш прогресс и чем за это заплачено

Регистрации на портале нет и не будет. Состояние живёт в вашем браузере (localStorage, ключи digitable:learn:*) и никуда не отправляется: ни один ответ не уходит на сервер, проверка целиком идёт здесь.

  • очистка данных браузера стирает всё, и восстановить нечем — кроме файла выгрузки, который вы сделали заранее;
  • синхронизации между устройствами нет: её роль исполняет тот же файл;
  • ответы и эталоны лежат на этой же странице, и увидеть их может каждый. Это решение, а не недосмотр: движок помогает учиться, а не охраняет оценку. Прятать ключ, который физически находится у читателя, — изображать защиту, которой нет.

Кредитный лимит: правила вместо ветвлений

build

Рассмотрим пример: кредитный лимит по заявке. Опишите объект «Заявка» с полями «доход» (деньги), «стаж» (число) и «риск-класс» (число) и утилиту «Рассчитать лимит», которая начинает с 0 и складывает: базовый лимит — 300 процентов дохода при доходе больше нуля; надбавку за стаж — ещё 100 процентов дохода при стаже не меньше 36; премию за низкий риск — 50 000 при риск-классе не больше 1. Ограничьте результат свойством «не больше 1 000 000» и приложите хотя бы один собственный пример.

Кейс «Рассчитать кредитный лимит» (Банкинг): вход — Доход, нагрузка и риск-класс; правило — Вычислить лимит и проверить максимум; ожидаемый результат — Детерминированный лимит.

Эталон, объяснение и разбор

Объяснение

Три правила независимы и складываются, а верхний предел вынесен в свойство, а не в четвёртое правило. Разница видна на последнем приёмочном входе: 750 000 базового плюс 250 000 за стаж плюс 50 000 премии дают 1 050 000, и модель обязана отказать, а не молча выдать округлённый ответ. Свойство — это утверждение обо всех входах сразу, поэтому оно ловит комбинацию, которой нет ни в одном примере.

Эталонная модель

категория «Кредитование»

  объект Заявка
    доход является деньгами
    стаж является числом
    «риск-класс» является числом

  утилита «Рассчитать лимит»
    принимает Заявка
    возвращает деньги
    начинает с 0

    правило «Базовый лимит»
      если доход больше 0
      то добавить 300 процентов от поля доход

    правило «Долгий стаж»
      если стаж не меньше 36
      то добавить 100 процентов от поля доход

    правило «Низкий риск»
      если «риск-класс» не больше 1
      то добавить 50000

    свойство «Лимит ограничен»
      результат не больше 1000000

    пример «Короткий стаж и высокий риск»
      дано доход равен 100000
      дано стаж равен 12
      дано «риск-класс» равен 3
      ожидается результат равен 300000

Условие целиком: /fts/practice/#step-6

Компетенции и источник задания

Компетенции: backend.middle.tests, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.banking-limit · источник: data/learning/fts.json

Итог курса: веса работ и порог посещаемости

build

Рассмотрим пример: итоговая оценка за курс. Опишите объект «Работы» с полями «теория», «практика» и «посещаемость» (числа) и утилиту «Рассчитать итог», которая начинает с 0 и складывает: 40 процентов теории, если теория больше нуля; 50 процентов практики, если практика больше нуля; 10 баллов, если посещаемость не меньше 80. Итог не может превышать 100 — запишите это свойством, а не правилом.

Кейс «Рассчитать итог курса» (Образование): вход — Работы, веса и посещаемость; правило — Вычислить результат и проверить диапазон; ожидаемый результат — Итоговый балл.

Эталон, объяснение и разбор

Объяснение

Третий вход отличает модель от арифметики «сложить проценты»: теория нулевая, поэтому её правило не срабатывает вовсе, а посещаемость ровно на пороге — «не меньше 80» включает 80, а «больше 80» его исключило бы. Граница включения — самое дешёвое место, где расчёт расходится с формулировкой на человеческом языке.

Эталонная модель

категория «Образование»

  объект Работы
    теория является числом
    практика является числом
    посещаемость является числом

  утилита «Рассчитать итог»
    принимает Работы
    возвращает число
    начинает с 0

    правило «Вес теории»
      если теория больше 0
      то добавить 40 процентов от поля теория

    правило «Вес практики»
      если практика больше 0
      то добавить 50 процентов от поля практика

    правило «Порог посещаемости»
      если посещаемость не меньше 80
      то добавить 10

    свойство «Итог не выше ста»
      результат не больше 100

    пример «Полный балл»
      дано теория равна 100
      дано практика равна 100
      дано посещаемость равна 90
      ожидается результат равен 100

Условие целиком: /fts/practice/#step-4

Компетенции и источник задания

Компетенции: backend.middle.tests, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.education-score · источник: data/learning/fts.json

Страховая премия: модель, которая обязана отказать

build

Рассмотрим пример: страховая премия по полису. Опишите объект «Полис» с полями «страховая сумма» (деньги), «возраст объекта» (число), «убытков за год» (число) и «франшиза оформлена» (признак) и утилиту «Рассчитать премию», которая начинает с 0 и складывает: 2 процента страховой суммы при страховой сумме больше нуля; ещё 1 процент при возрасте объекта не меньше 10; 15 000 при двух и более убытках за год; минус 5000 при оформленной франшизе. Тарифный комитет ограничил премию сотней тысяч — запишите это свойством. Приложите хотя бы один собственный пример.

Кейс «Рассчитать страховую премию» (Страхование): вход — Объект, риск и франшиза; правило — Сложить коэффициенты и проверить предел; ожидаемый результат — Премия полиса.

Эталон, объяснение и разбор

Объяснение

Последний приёмочный вход — вся суть языка на одном примере. 80 000 базовой ставки, 40 000 за возраст и 15 000 за убыточность дают 135 000 при разрешённых 100 000. Привычная функция вернёт 135 000 и не скажет ни слова: ограничение живёт в регламенте, а не в коде, и ни один из тестов, написанных на типичные входы, эту комбинацию не содержит. Здесь ограничение записано свойством, то есть утверждением обо всех входах сразу, — и модель отказывается считать, называя нарушенное свойство по имени. Отказ на входе, которого нет ни в одном примере, невозможно получить сверкой со строкой: его выносит исполнение.

Эталонная модель

категория «Страхование»

  объект Полис
    «страховая сумма» является деньгами
    «возраст объекта» является числом
    «убытков за год» является числом
    «франшиза оформлена» является признаком

  утилита «Рассчитать премию»
    принимает Полис
    возвращает деньги
    начинает с 0

    правило «Базовая ставка»
      если «страховая сумма» больше 0
      то добавить 2 процента от поля «страховая сумма»

    правило «Старый объект»
      если «возраст объекта» не меньше 10
      то добавить 1 процент от поля «страховая сумма»

    правило «Убыточная история»
      если «убытков за год» не меньше 2
      то добавить 15000

    правило «Франшиза»
      если «франшиза оформлена» равен да
      то добавить -5000

    свойство «Премия ограничена»
      результат не больше 100000

    пример «Новый объект без убытков»
      дано «страховая сумма» равна 1000000
      дано «возраст объекта» равен 3
      дано «убытков за год» равно 0
      дано «франшиза оформлена» равен нет
      ожидается результат равен 20000

    пример «Старый объект с франшизой и убытками»
      дано «страховая сумма» равна 1000000
      дано «возраст объекта» равен 12
      дано «убытков за год» равно 3
      дано «франшиза оформлена» равен да
      ожидается результат равен 40000

Условие целиком: /fts/practice/#step-8

Компетенции и источник задания

Компетенции: analyst.middle.nonfunctional, backend.middle.tests, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.insurance-premium · источник: data/learning/fts.json

Тариф перевозки: зоны без дыр и без нахлёстов

build

Рассмотрим пример: тариф перевозки. Опишите объект «Рейс» с полями «километров» (число), «вес» (число) и «хрупкий груз» (признак) и утилиту «Рассчитать перевозку», которая начинает с 0. Три взаимоисключающих правила задают базу по расстоянию: 500 при пробеге меньше 200; 900 при пробеге от 200 до 1000; 1600 при пробеге от 1000. Сверху добавляются надбавки: 350 при весе больше 20 и 250 за хрупкий груз. Свойством запишите, что тариф не опускается ниже 500. Приложите хотя бы один собственный пример.

Кейс «Рассчитать стоимость доставки» (Логистика): вход — Маршрут, вес и сервис; правило — Применить тарифы и надбавки; ожидаемый результат — Цена перевозки.

Эталон, объяснение и разбор

Объяснение

Правила зон не складываются между собой — они взаимоисключающие, и вместе покрывают всю числовую ось без дыр и без нахлёстов. Проверяется это приёмочными входами ровно на границах: 200, 999 и 1000. Пропущенная граница — самая частая ошибка в такой разметке: условия «меньше 1000» и «больше 1000» оставляют 1000 без правила, и рейс ровно на тысяче километров получит базовый ноль вместо тарифа. Базу вносят сами правила, а не «начинает с»: тогда нижнюю границу 500 можно записать свойством и проверять на каждом входе.

Эталонная модель

категория «Логистика»

  объект Рейс
    километров является числом
    вес является числом
    «хрупкий груз» является признаком

  утилита «Рассчитать перевозку»
    принимает Рейс
    возвращает деньги
    начинает с 0

    правило «Ближняя зона»
      если километров меньше 200
      то добавить 500

    правило «Средняя зона»
      если километров не меньше 200
      и километров меньше 1000
      то добавить 900

    правило «Дальняя зона»
      если километров не меньше 1000
      то добавить 1600

    правило «Тяжёлый груз»
      если вес больше 20
      то добавить 350

    правило «Хрупкий груз»
      если «хрупкий груз» равен да
      то добавить 250

    свойство «Тариф не ниже базового»
      результат не меньше 500

    пример «Ближний рейс»
      дано километров равно 150
      дано вес равен 5
      дано «хрупкий груз» равен нет
      ожидается результат равен 500

    пример «Ровно на границе средней зоны»
      дано километров равно 200
      дано вес равен 5
      дано «хрупкий груз» равен нет
      ожидается результат равен 900

Условие целиком: /fts/practice/#step-3

Компетенции и источник задания

Компетенции: backend.middle.feature, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.logistics-zones · источник: data/learning/fts.json

Комиссия платежа: правило-выключатель и его место в порядке

build

Рассмотрим пример: комиссия платежа. Опишите объект «Транзакция» с полями «сумма» (деньги), «карта иностранного банка» (признак) и «внутренний перевод» (признак) и утилиту «Рассчитать комиссию», которая начинает с 0 и складывает: 1 процент суммы при сумме больше нуля и 100 за карту иностранного банка. Внутренний перевод бесплатен всегда — это не вклад, а назначение результата: «то результат равен 0». Потолок комиссии 5000 запишите свойством. Приложите хотя бы один собственный пример.

Кейс «Рассчитать комиссию платежа» (Платежи): вход — Метод, валюта и сумма; правило — Применить тарифные правила по порядку; ожидаемый результат — Комиссия для checkout.

Эталон, объяснение и разбор

Объяснение

Правила применяются сверху вниз, и «то результат равен» назначает результат, а не добавляет к нему. Отсюда единственное верное место выключателя — ПОСЛЕ накопления: поставленный первым, он был бы затёрт следующими вкладами и выглядел бы сработавшим, ничего не изменив. Ловит это четвёртый приёмочный вход: внутренний перевод на 600 000. При правильном порядке — ноль; при выключателе сверху — 6100, то есть ещё и нарушение потолка. Пятый вход показывает обратную сторону: тот же платёж, но не внутренний, обязан упереться в свойство, а не выдать 6100.

Эталонная модель

категория «Платежи»

  объект Транзакция
    сумма является деньгами
    «карта иностранного банка» является признаком
    «внутренний перевод» является признаком

  утилита «Рассчитать комиссию»
    принимает Транзакция
    возвращает деньги
    начинает с 0

    правило «Комиссия за перевод»
      если сумма больше 0
      то добавить 1 процент от поля сумма

    правило «Иностранная карта»
      если «карта иностранного банка» равен да
      то добавить 100

    правило «Внутренний перевод бесплатен»
      если «внутренний перевод» равен да
      то результат равен 0

    свойство «Комиссия ограничена»
      результат не больше 5000

    пример «Обычный платёж»
      дано сумма равна 10000
      дано «карта иностранного банка» равен нет
      дано «внутренний перевод» равен нет
      ожидается результат равен 100

    пример «Свой своему не платит»
      дано сумма равна 10000
      дано «карта иностранного банка» равен да
      дано «внутренний перевод» равен да
      ожидается результат равен 0

Условие целиком: /fts/practice/#step-7

Компетенции и источник задания

Компетенции: backend.middle.feature, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.payments-fee · источник: data/learning/fts.json

Скидка корзины: три независимых вклада и потолок

build

Рассмотрим пример: скидка корзины в магазине. Опишите объект «Корзина» с полями «сумма» (деньги), «позиции» (число) и «промокод предъявлен» (признак) и утилиту «Рассчитать скидку», которая начинает с 0 и складывает: 5 процентов суммы при сумме не меньше 5000; 300 при десяти и более позициях; 200 при предъявленном промокоде. Потолок скидки — 5000; запишите его свойством, а не четвёртым правилом. Приложите хотя бы один собственный пример.

Кейс «Рассчитать скидку корзины» (Ритейл): вход — Сумма корзины, сегмент и промокод; правило — Сложить применимые проценты и проверить верхний предел; ожидаемый результат — Числовая скидка без скрытых веток.

Эталон, объяснение и разбор

Объяснение

Три правила независимы: порядок их записи на результат не влияет, и каждое можно прочитать, не держа в голове остальные. Так выглядит замена лестницы if / else if, где каждая новая ветка обязана знать про все предыдущие. Потолок вынесен в свойство: последний приёмочный вход — 10 000 процентной скидки плюс 300 плюс 200 — в модель без свойства прошёл бы молча, выдав 10 500 там, где регламент разрешает 5000. Границы проверены нарочно: 5000 — это ровно порог «не меньше 5000», а 10 позиций — ровно порог «не меньше 10».

Эталонная модель

категория «Розница»

  объект Корзина
    сумма является деньгами
    позиции является числом
    «промокод предъявлен» является признаком

  утилита «Рассчитать скидку»
    принимает Корзина
    возвращает деньги
    начинает с 0

    правило «Крупная корзина»
      если сумма не меньше 5000
      то добавить 5 процентов от поля сумма

    правило «Много позиций»
      если позиции не меньше 10
      то добавить 300

    правило «Промокод»
      если «промокод предъявлен» равен да
      то добавить 200

    свойство «Скидка ограничена»
      результат не больше 5000

    пример «Крупная корзина из трёх позиций»
      дано сумма равна 6000
      дано позиции равно 3
      дано «промокод предъявлен» равен нет
      ожидается результат равен 300

    пример «Ровно на пороге по сумме и по позициям»
      дано сумма равна 5000
      дано позиции равно 10
      дано «промокод предъявлен» равен да
      ожидается результат равен 750

Условие целиком: /fts/practice/#step-2

Компетенции и источник задания

Компетенции: backend.middle.tests, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.retail-basket · источник: data/learning/fts.json

Приоритет тикета: SLA-правила и признак

build

Рассмотрим пример: приоритет тикета в поддержке. Опишите объект «Тикет» с полями «влияние» (число), «клиентов затронуто» (число) и «платный тариф» (признак) и утилиту «Рассчитать приоритет», которая начинает с 0 и складывает: 50 при влиянии не меньше 3, 30 при более чем ста затронутых клиентах, 20 при платном тарифе. Приоритет не превышает 100.

Кейс «Рассчитать приоритет тикета» (Поддержка клиентов): вход — Клиент, влияние и срочность; правило — Применить SLA-правила; ожидаемый результат — Priority score.

Эталон, объяснение и разбор

Объяснение

Два первых входа дают одинаковое число разными путями — 50 за влияние и 30+20 за массовость с платным тарифом. Это и есть причина писать правила отдельно: приоритет читается как список причин, а не как одно число, и спор о SLA идёт про конкретное правило, а не про итог.

Эталонная модель

категория «Поддержка»

  объект Тикет
    влияние является числом
    «клиентов затронуто» является числом
    «платный тариф» является признаком

  утилита «Рассчитать приоритет»
    принимает Тикет
    возвращает число
    начинает с 0

    правило «Высокое влияние»
      если влияние не меньше 3
      то добавить 50

    правило «Массовый инцидент»
      если «клиентов затронуто» больше 100
      то добавить 30

    правило «Платный тариф»
      если «платный тариф» равен да
      то добавить 20

    свойство «Приоритет в пределах ста»
      результат не больше 100

    пример «Единичное обращение»
      дано влияние равно 1
      дано «клиентов затронуто» равно 2
      дано «платный тариф» равен нет
      ожидается результат равен 0

Условие целиком: /fts/practice/#step-5

Компетенции и источник задания

Компетенции: backend.middle.tests, analyst.middle.acceptance. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.support-priority · источник: data/learning/fts.json

Первая модель: цена билета из двух надбавок

build

Рассмотрим пример: цена билета. Это первая модель целиком — объект, утилита, правило, свойство и пример. Опишите объект «Билет» с полями «базовый тариф» (деньги), «мест багажа» (число) и «выбор места» (признак) и утилиту «Рассчитать цену», которая начинает с 0 и складывает: сам базовый тариф — 100 процентов от поля «базовый тариф», если он больше нуля; 1500 за каждый случай, когда мест багажа не меньше одного; 700 при выбранном месте. Запишите свойством, что цена не бывает отрицательной, и приложите хотя бы один собственный пример.

Кейс «Рассчитать цену билета» (Путешествия): вход — Тариф, багаж и сборы; правило — Сложить детерминированные надбавки; ожидаемый результат — Final fare.

Эталон, объяснение и разбор

Объяснение

Модель на FTS — это объект (какие данные приходят), утилита (что считаем) и три вида записей внутри неё: правило вносит вклад, свойство утверждает что-то обо всех входах сразу, пример фиксирует один конкретный расчёт. Базовый тариф вносится правилом, а не строкой «начинает с»: значение из «начинает с» видно только там, где не сработало ни одно правило, и проверить его свойством нельзя. Обратите внимание, что багаж — один вклад, а не «за каждое место»: условие «не меньше одного» срабатывает один раз независимо от числа мест.

Эталонная модель

категория «Путешествия»

  объект Билет
    «базовый тариф» является деньгами
    «мест багажа» является числом
    «выбор места» является признаком

  утилита «Рассчитать цену»
    принимает Билет
    возвращает деньги
    начинает с 0

    правило «Базовый тариф»
      если «базовый тариф» больше 0
      то добавить 100 процентов от поля «базовый тариф»

    правило «Багаж»
      если «мест багажа» не меньше 1
      то добавить 1500

    правило «Выбор места»
      если «выбор места» равен да
      то добавить 700

    свойство «Цена неотрицательна»
      результат не меньше 0

    пример «Билет без багажа»
      дано «базовый тариф» равен 8000
      дано «мест багажа» равно 0
      дано «выбор места» равен нет
      ожидается результат равен 8000

Условие целиком: /fts/practice/#step-1

Компетенции и источник задания

Компетенции: backend.junior.language, analyst.junior.types. Подтверждённое задание не переставляет отметку самооценки — оно только показывает подсказку рядом с пунктом на /career/.

id: fts.build.travel-fare · источник: data/learning/fts.json