>
Как Выжить программисту

Как Выжить программисту

Волков Михаил Мое Обучение 21 августа 2019
0 4516
Сложность: Начинающий

Как выжить, если вы начинаете первые шаги в программировании. Как не делать - не знаю как, но работает. Три секретных вопроса.

Вам что-то недоговаривают

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

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

У лектора получается постепенно построить логику кода, но у вас - нет. Код пишется, но нить его логики от вас постоянно убегает, и в конце концов у вас получается нечто вроде "не знаю как, но работает".

Как этого избежать?

Раскрываем секрет

Программирование - это легко, поверьте. Для того, чтобы научиться программировать, нужно запомнить и всегда повторять всего три вопроса. Ответив на эти вопросы, вы всегда можете получить полное представление о написанном коде и разобраться что к чему.

Что же это за волшебные вопросы?

  1. Зачем эта часть кода, что она делает?
  2. Как можно управлять ее поведением?
  3. Что эта часть возвращает?

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

Зачем эта часть кода, что она принципиально делает?

Чтобы ответить на вопрос о том, как работает код, нужно до мелочей знать весь процесс его работы? Нет, это не так, данный вопрос подразумевает кое-что другое.

Для того, чтобы ответить на него, вам не нужно вдаваться в детали, а  просто взгляните на код в целом.

Смотрим на пример:

if ($cake->isVeryBig() && $cake->isCheaper(100)) {
echo 'Супер-скидка на торт';
}

Дробим его на части:

  • Ага, это торт.
$cake
  • А это мы узнаем большой он или нет.
$cake->isVeryBig()
  • А это мы узнаем дешевле ли он ста загадочных монет.
$cake->isCheaper(100)
  • А тут у нас условие. Чтобы его пройти, необходимо чтобы выполнились обе его части.
if (... && ...)

Переводим на человеческий язык: "если торт очень больший и он дешевле чем 100, выводим текст внутри этого условия."

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

Как можно управлять ее поведением?

Переписать? Нет, это не управление поведением, но что-то мы можем здесь поменять, чтобы немного изменить поведение кода. Снова посмотрим на все его части:

  • Торт как торт, тут мы ничего не можем поменять.
$cake
  • Вряд ли метод принимает какие-то параметры, можно заглянуть внутрь него и узнать это точно, но думаю, что здесь мы тоже ничего не можем поменять. Скорее всего, когда мы делали торт, мы задавали размеры - там и поменяем при необходимости.
$cake->isVeryBig()
  • Ага, 100, метод принимает параметр, значит мы можем управлять числом: дешевле чего должен быть торт, чтобы выполнилось условие.
$cake->isCheaper(100)
  • А тут у нас условие, мы можем поменять "и" на "или".
if (... && ...)

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

Что эта часть возвращает?

Если предыдущие вопросы более-менее понятны (скорее всего, вы ими уже задавались ранее, когда первый раз увидели код), то этот вопрос особенный.

Смотрим на код:

if ($cake->isVeryBig() && $cake->isCheaper(100)) {
echo 'Супер-скидка на торт';
}

Хотя, чего на него смотреть, он ничего не возвращает, а только проверяет условие и что-то выводит.

Но на этом останавливаться нельзя, и в этом как раз заключается особый секрет. Каждая строка, да что там строка - каждое слово, каждая операция, каждый вызов метода что-то возвращают. И если вы в каждой точке кода будете понимать, что здесь возвращается, то шагнете на ступень выше в своем мастерстве программирования.

Дробим пример и отвечаем на вопрос:

  • Обращение к переменной возвращает ссылку на объект. Причем к этой переменной мы обращаемся в коде дважды.
$cake
  • Этот метод возвращает true либо false.
$cake->isVeryBig()
  • 100 - число возвращает число.
100
  • Этот метод тоже возвращает true либо false.
$cake->isCheaper(...)
  • Результат сравнения (применения оператора &&) тоже возвращает true либо false.
if (... && ...)
  • Строка возвращает строку.
'Супер-скидка на торт'
  • Оператор echo выводит строку и ничего не возвращает (null).
echo ...;

Обратили внимание, как сильно я раздробил код?  Почти до атомов!

Примеры с возвращением

Часто ответ на третий вопрос дается сложнее всего. Давайте немного попрактикуемся и применим новые знания в задачах, а заодно и исправим ошибки в этих примерах.

Пример 1

$a = (bool)rand(0, 1);
if ($a == true) {
echo 'Истина';
}

Конструкция выводит слово "истина". Когда в переменной $a хранится значение true, управлять логикой мы никак не можем без изменения кода. Разберемся, что возвращается на каждых этапах.

  • Случайное число 0 или 1.
rand(0, 1);
  • Преобразование типа дает true либо false.
(bool)rand(...);
  • Это значение помещается в переменную $a и возвращается.
$a = ...;
  • Обращение к переменной возвращает ее значение: true либо false.
$a
  • Возвращает true либо false, в зависимости от результата условия, если $a вернет true, то и выражение вернет true.
$a == true
  • Ничего не возвращается, но выполняется в зависимости от условия
if (...) {
echo 'Истина';
}

Теперь, зная каждый шаг, можно увидеть ошибку. Посмотрите на шаги 3 и 4 - они возвращают одно и то же. Значит шаг 4 можно убрать. Так же в данном случае можно избавиться от переменной $a, она используется один раз.

if ((bool)rand(0, 1)) {
echo 'Истина';
}

Пример 2

($b > 5) ? $a = $b * $b : $a = 0;

Простой тернарный оператор, если в $b число больше 5, то в $a кладется квадрат этого числа, а если меньше, то 0. Разберемся, что происходит здесь, и улучшим код. Некоторые совсем очевидные шаги я пропущу. И пойду в другую сторону, от большего к меньшему

  • Выполняется тернарное выражение и возвращается его результат.
... ? ... : ...;
  • Возвращается результат, тот же, что и внутри скобок.
(...)
  • Возвращается результат сравнения: true, либо false.
$b > 5
  • Возвращается значение переменной $b.
$b
  • В переменную $a кладется результат возведения $b в квадрат.
$a = $b * $b;
  • В переменную $a кладется ноль.
$a = 0;

Нарушен принцип работы тернарного оператора. Он возвращает либо первое, либо второе значение в зависимости от условия. Значит, его не правильно применили, т.к. возвращаемое значение никуда не присваивается.

В двух последних шагах повторяется первая часть: "В переменную $a кладется". Так почему бы не вынести это дублирование из тернарного оператора? А на шаге 2 лишние скобки.

Смотрим, что получилось после исправления:

$a = $b > 5 ? $b * $b : 0;

Сколько лишнего кода удалось убрать, досконально разобравшись в его работе!

Резюме

Всегда, в любой части кода отвечайте себе на три вопроса: что эта часть кода делает, как ей можно управлять и что она возвращает. Тогда вы будете понимать зачем нужен этот код и будете читать его так, как читают профессионалы.

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

Выживи сам - помоги другим.


Комментарии

Никто не оставлял свои комментарии