Псевдокод

Что это такое

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

Почему это важно

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

Ключевые идеи

Сначала структура, синтаксис — никогда

У псевдокода есть словарь, но нет грамматики, которой нужно удовлетворять. Пользуйтесь нумерованными шагами, if/else, while, for each и именованными процедурами, а остальное пишите словами. Если вы ловите себя на беспокойстве о точках с запятой, вы уже написали достаточно, чтобы начать программировать.

parse(line):
  fields = split(line, ",")
  if fields is empty:
    return error "пустая запись"
  record = { id: fields[0], name: fields[1], amount: number(fields[2]) }
  return record

Один уровень абстракции за раз

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

Пишите края, а не счастливый путь

Ценность упражнения — в ветках, которые вы иначе забыли бы: пустой ввод, значение не-число, файл, которого нет, две записи с одним ключом. Запишите их как обычные шаги. Если путь действительно невозможен, скажите почему одной строкой прозы. Не оставляйте читателя гадать, подумали ли вы о нём.

total = 0
rejected = 0
for each row in rows:
  amount = разобрать amount, иначе пропустить строку и rejected = rejected + 1
  total = total + amount
if rejected > 0:
  warn "пропущено строк: " + rejected
return total

Проследите его вручную

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

Практика

Проследите алгоритм, который уже знаете

Возьмите что-нибудь, чем пользуетесь не задумываясь: двоичный поиск, слияние двух отсортированных списков, цикл повторных попыток в вашем HTTP-клиенте. Напишите его псевдокодом по памяти, затем проследите ввод, заставляющий его работать больше всего. Сравните свою версию с настоящей реализацией.

Готово, когда: ваш след заканчивается ожидаемым результатом и вы записали хотя бы одну ветку, которая есть в настоящем коде, но отсутствовала в вашей версии.

Спроектируйте возможность до того, как открыть редактор

Выберите следующую небольшую возможность из своего списка. Напишите двадцать строк псевдокода, охватывающих её входы, выходы и пути отказа, прежде чем тронете файл. Передайте его человеку, который его не писал, и попросите описать, что он делает.

Готово, когда: другой человек описывает задуманное вами поведение, а написанный после этого код короче вашего первого порыва.

Частые ошибки

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

Что читать дальше

  • Алгоритмы и Big-O (01-cs-fundamentals/14-algorithms-big-o) — словарь для суждения о том, выдержит ли набросанный замысел рост входа.
  • Структуры данных (01-cs-fundamentals/02-data-structures) — большинство решений в псевдокоде на деле выбор формы данных.
  • Рефакторинг (01-cs-fundamentals/19-refactoring) — как менять работающий замысел небольшими шагами, когда след вскрыл его слабое место.