-
Notifications
You must be signed in to change notification settings - Fork 30
Про отладку и внимательность (новичкам)
jack [18:02] Что же не так, кто подскажет?
$myFactorial = function($acc, $num) use (&$myFactorial) {
if ($num == 1 || $num == 0) {
return $acc;
};
return $myFactorial($acc * $num, $num - 1);
};
$myFactorial(1, $num);
kirill.mokevnin [18:03] а ошибка в чем?
kirill.mokevnin [18:03] покажите вывод запуска
jack [18:06] Ого, как оперативно)
jack [18:06] PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
FFFFFFF
Time: 204 ms, Memory: 4.75Mb
There were 7 failures:
- App\Test::testFactorial with data set #0 (1, 0) Failed asserting that null matches expected 1.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #1 (1, 1) Failed asserting that null matches expected 1.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #2 (2, 2) Failed asserting that null matches expected 2.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #3 (6, 3) Failed asserting that null matches expected 6.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #4 (24, 4) Failed asserting that null matches expected 24.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #5 (120, 5) Failed asserting that null matches expected 120.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
FAILURES! Tests: 7, Assertions: 7, Failures: 7. make: *** [test] Error 1 Run failed! Check and fix errors above!
jack [18:06] а в чате нет что-то типо спойлера?
kirill.mokevnin [18:08] нет
kirill.mokevnin [18:08] теперь будем учиться читать тесты), откройте файл который тут указан в выводе
kirill.mokevnin [18:09] и посмотрите как там запускается та функция которую вы должны определить
jack [18:31] по тесту два значения возвращается? или я вообще ничего не понимаю? (edited)
jack [18:41] а нет, дело в 14 строчке. сейчас разберусь!
kirill.mokevnin [18:49] 7) App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
kirill.mokevnin [18:49] в тестах важно учиться читать вывод
kirill.mokevnin [18:50] как вы думаете, что означает этот текст?
kirill.mokevnin [18:50] failed asserting ...
jack [19:15] failed asserting? что-то сродни неверному утверждению, когда нечто ожидается. или как?
kirill.mokevnin [19:16] так и что конкретно тут нам говорит тест?
kirill.mokevnin [19:16] что ожидал что получил
jack [19:16] вообще я вижу, что явное несовпадение на линии 14 а файле тест.
jack [19:17] ну да, неравенство в том что должно было выйти и то что вышло.
jack [19:17] но это как-то слишком абстрактно для меня.
kirill.mokevnin [19:17] почему?
kirill.mokevnin [19:17] тест ожидал что ваша функция вернет 3628800
kirill.mokevnin [19:17] но в итоге получил null
jack [19:18] $this->assertEquals($expected, factorial($number));
что-то не следует из индекса этой строке в тесте.
kirill.mokevnin [19:18] куда уж конкретнее
kirill.mokevnin [19:18] exptected это то что ожидал
kirill.mokevnin [19:18] actual это то что получил
jack [19:18] а число в десятичном?
kirill.mokevnin [19:18] конкретнее некуда я бы сказал
kirill.mokevnin [19:18] ну да
kirill.mokevnin [19:18] а какая разница какое число?)
kirill.mokevnin [19:18] для вас главное что в том вызове где ваша функция
kirill.mokevnin [19:18] получился тull
kirill.mokevnin [19:18] null
jack [19:18] я думал это что-то..ээм.. шифр или что
kirill.mokevnin [19:18] вот что для вас главное в этом сообщение
jack [19:19] хм.
jack [19:19] да, логично
kirill.mokevnin [19:19] вы смотрели наш вебинар про тесты/
kirill.mokevnin [19:19] ?
kirill.mokevnin [19:19] тесты это ваш лучший и главный друг
jack [19:19] нет, не смотрел. не знал даже о них :с
kirill.mokevnin [19:19] о, вы много пропустили)
kirill.mokevnin [19:19] сверху ссылка есть
kirill.mokevnin [19:19] на сайте
kirill.mokevnin [19:19] https://github.com/Hexlet/webinars/wiki
GitHub Hexlet/webinars Hexlet webinars
kirill.mokevnin [19:19] посмотрите обязательно
jack [19:20] спасибо большое)
kirill.mokevnin [19:20] так вот теперь вам надо выяснить почему null
kirill.mokevnin [19:20] кстати, а вы поняли с каким аргументом была вызвана функция?
kirill.mokevnin [19:20] 7) App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
kirill.mokevnin [19:20] еще раз смотрим сюда внимательно)
kirill.mokevnin [19:21] тут всего три числа 😄
kirill.mokevnin [19:21] одно из них мы знаем что означает (3628800 это exptected)
jack [19:21] там функция идет аргументом
kirill.mokevnin [19:21] data set #6 здесь видно что 6 это порядковый номер датасета
kirill.mokevnin [19:21] не функция а переменная
kirill.mokevnin [19:22] вы читали задание для задачи которую делаете?
kirill.mokevnin [19:22] там сказано что факториал принимает на вход
kirill.mokevnin [19:22] но даже без чтения задания довольно очевидно что функция факториала принимает на вход число
jack [19:22] Реализуйте рекурсивную функцию factorial используя линейно-итеративный процесс. и все(
kirill.mokevnin [19:22] таково ее математическое определение
jack [19:22] ну и на выход должно выдавать одно число
kirill.mokevnin [19:23] а да, я это не указал потому что в предыдущем упражнении где был рекурсивный процесс
kirill.mokevnin [19:23] та же функция
kirill.mokevnin [19:23] снаружи
kirill.mokevnin [19:23] тот же интерфейс
kirill.mokevnin [19:23] давайте еще раз вернемся к моему вопросу
kirill.mokevnin [19:23] так вот теперь вам надо выяснить почему null
kirill.mokevnin [12:20 PM] кстати, а вы поняли с каким аргументом была вызвана функция?
kirill.mokevnin [12:20 PM] 7) App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
kirill.mokevnin [12:20 PM] еще раз смотрим сюда внимательно)
kirill.mokevnin [12:21 PM] тут всего три числа 😄
kirill.mokevnin [12:21 PM] одно из них мы знаем что означает (3628800 это exptected)
kirill.mokevnin [19:23] так какое же число было передано на вход функции факториала так что оно вернула null?
kirill.mokevnin [19:24] мы сейчас пытаемся эвристически думать, без точного знания что там на самом деле и как работает
kirill.mokevnin [19:24] мы знаем что был вызван факториал с каким то числом, получился null, ожидался 3628800
jack [19:24] ноль же и вернуло ноль
kirill.mokevnin [19:24] еще раз копирую
kirill.mokevnin [19:24] 7) App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
kirill.mokevnin [19:24] учитесь читать вывод тестов
jack [19:24] 10!
kirill.mokevnin [19:25] наконец-то
jack [19:25] хахаха
jack [19:25] простите)
kirill.mokevnin [19:25] вы понимаете что сами себе сложности создаете тем что игнорируете вывод тестов?)
kirill.mokevnin [19:25] теперь давайте опять же эвристически попробуем понять что внутри файла тестов
jack [19:25] я не игнорирую, просто смотрю на нее и понимаю только полностью про файл и линию
kirill.mokevnin [19:26] на самом деле непонимание приводит к игнорированию, в смысле мозг не пытается даже зацепиться
jack [19:26] это да, согласен
kirill.mokevnin [19:26] называется “смотрю в книгу вижу фигу"
kirill.mokevnin [19:26] вот это важный навык, учиться понимать когда мозг так делает
jack [19:26] в самом файле, как я понимаю, каька
jack [19:26] калька
kirill.mokevnin [19:27] понятно теперь внутри самого файла что означают наборы чисел?
jack [19:27] которой должны соответствовать результаты работы основного файла?
kirill.mokevnin [19:27] одно из них ожидаемый ввывод
kirill.mokevnin [19:27] второе это то что идет на вход функции
kirill.mokevnin [19:27] теперь еще раз внимательно смотрим вывод тестов
kirill.mokevnin [19:27] весь
kirill.mokevnin [19:27] PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
FFFFFFF
Time: 204 ms, Memory: 4.75Mb
There were 7 failures:
- App\Test::testFactorial with data set #0 (1, 0) Failed asserting that null matches expected 1.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #1 (1, 1) Failed asserting that null matches expected 1.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #2 (2, 2) Failed asserting that null matches expected 2.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #3 (6, 3) Failed asserting that null matches expected 6.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #4 (24, 4) Failed asserting that null matches expected 24.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #5 (120, 5) Failed asserting that null matches expected 120.
/usr/src/app/test.php:14
- App\Test::testFactorial with data set #6 (3628800, 10) Failed asserting that null matches expected 3628800.
/usr/src/app/test.php:14
kirill.mokevnin [19:28] теперь еще раз внимательно смотрим вывод тестов
kirill.mokevnin [19:28] и уже начинаем понимать, что тест запускается для каждого набора индивидуально
jack [19:28] ага, все 7 значений вывели неверный ответ!
kirill.mokevnin [19:28] более того, вход функции не важен (судя по результатам тестов)
kirill.mokevnin [19:28] ваша функция всегда возвращает null!
jack [19:28] и все они упираются в 14 линию
kirill.mokevnin [19:28] ну так очевидно там и происходит проерка
kirill.mokevnin [19:28] это не важно что она 14
kirill.mokevnin [19:29] там вызов вашей функции
kirill.mokevnin [19:29] она возвращает null
kirill.mokevnin [19:29] теперь тест на внимательность
kirill.mokevnin [19:29] как называется функция которую вы определили?
jack [19:30] testFactorial?
kirill.mokevnin [19:30] функция которую вы опредлели
kirill.mokevnin [19:30] это ваш факториал
kirill.mokevnin [19:30] вы не определяли других функций
kirill.mokevnin [19:31] ок, давайте тогда другой важный навык прокачаем
kirill.mokevnin [19:31] я о нем говорил в самом первом уроке
kirill.mokevnin [19:31] вот у вас есть функция
kirill.mokevnin [19:31] и работает она не правильно
kirill.mokevnin [19:31] как по быстрому ее повызывать с разными аргументами посмотреть что она возвращает?
kirill.mokevnin [19:31] этакое ручное тестирование
jack [19:31] в шеле
jack [19:31] идле или как еще
kirill.mokevnin [19:31] давайте этосделаем
kirill.mokevnin [19:31] в иде внизу терминал
kirill.mokevnin [19:31] наберите там php -a
kirill.mokevnin [19:32] и дальше require ‘имя файла где определан функция факториал’;
kirill.mokevnin [19:32] после этого вызывайте echo factorial(10);
jack [19:32] ага. а то я никак не знал как терминалом вызывать
kirill.mokevnin [19:33] как набирать php -a ?
kirill.mokevnin [19:33] или require ?
jack [19:33] вызов
kirill.mokevnin [19:33] так же как и в файлах вы пишите
kirill.mokevnin [19:34] function(args);
kirill.mokevnin [19:34] echo нужен для того чтобы вывод на экран напечатать
kirill.mokevnin [19:34] это не вызов вашей функции (edited)
kirill.mokevnin [19:34] внутри шела вы как будто построчно пишите файл
jack [19:35] но ничего не происходит
kirill.mokevnin [19:35] происходит
kirill.mokevnin [19:35] вам возвращается null
jack [19:35]
root@be01d31d368b:/usr/src/app# php -a
Interactive mode enabled
require 'index.php';
echo factorial(10);
echo factorial(10);
kirill.mokevnin [19:36] наберите echo null;
kirill.mokevnin [19:36] что вам на экран будет напечатано?
kirill.mokevnin [19:36] вы не думайте что есть какая то магия
kirill.mokevnin [19:36] вы вызваете функцию (edited)
kirill.mokevnin [19:36] она вызывается (вы же не видите ошибок)
kirill.mokevnin [19:37] нет такого “ничего не происходит"
kirill.mokevnin [19:37] вопрос в том что вернула функция
kirill.mokevnin [19:37] раз ничего не печатается на экран
jack [19:37] ну я понимаю, что магии никакой нет, что все происходит "под ковром"
kirill.mokevnin [19:37] давайте еще один маленький эксперимент после которого я думаю вы многое поймете
jack [19:37] я-то не вижу отдачи
kirill.mokevnin [19:37] напишите внутри вашей функции первой строчкой вот такое
kirill.mokevnin [19:38] return “hello world”;
kirill.mokevnin [19:38] потом перезайдите в шел
kirill.mokevnin [19:38] и заново проделайте то что делали
kirill.mokevnin [19:41] что теперь показывает echo factorial(<тут любое число>); ?
jack [19:42] function factorial($num) { return “hello world”; ....
Interactive mode enabled
require 'index.php';
echo factorial(10);
^C
jack [19:42] ничего и я вышел
kirill.mokevnin [19:43] вам сначала надо было выйти
jack [19:43] да, это не пайтоновские исключения
jack [19:43] я перезагружал
kirill.mokevnin [19:44] сделайте cat index.php
kirill.mokevnin [19:44] в терминале
kirill.mokevnin [19:44] что там внутри?
kirill.mokevnin [19:44] то вы сейчас описали выше это невозможно, значит где то ошибка
kirill.mokevnin [19:44] либо файл не сохранился
kirill.mokevnin [19:44] либо не загрузилось оно в терминал
kirill.mokevnin [19:45] cat - это команда баша а не php
jack [19:46] cat отображает файл как есть в терминале
kirill.mokevnin [19:47] да
kirill.mokevnin [19:47] там есть строка ‘return ‘hello world’' ?
jack [19:47] };
$testFactorial(1, $num);
};
?>root@be01d31d368b:/usr/src/app# php -a
Interactive mode enabled
require 'index.php';
echo factorial(10);
jack [19:48] да, там порядок
jack [19:48] все как есть
kirill.mokevnin [19:48] можете скрин показать?
kirill.mokevnin [19:53] так да, у вас же там неймспейс app
kirill.mokevnin [19:54] вызывать функцию надо echo \App\factorial(10);
jack [19:54] а что это и зачем оно нужно?
kirill.mokevnin [19:54] пространства имен, чтобы не было конфликтов
kirill.mokevnin [19:54] каждый может определить свой факториал
jack [19:54] с кем?
kirill.mokevnin [19:54] они будут проходиться в более поздних уроках
jack [19:54] ааа
kirill.mokevnin [19:54] ну вдруг вы используете в программе два разных пакета и там одинаковые функции?
kirill.mokevnin [19:54] атата будет
jack [19:54] понял понял
kirill.mokevnin [19:55] папка это пространство имен
jack [19:56]
require 'index.php';
echo \App\factorial(10);
jack [19:56] вот так нужно?
kirill.mokevnin [19:56] https://www.dropbox.com/s/1lpojpkwqyxkdtm/Screenshot%202015-09-26%2012.55.55.png?dl=0
kirill.mokevnin [20:01] да беда, на самом деле почему то шел не работает
kirill.mokevnin [20:01] видите на моем скрине как он должен выглядеть?
jack [20:01] вижу конечно, но что это мне дает
jack [20:01] если он не работает)
kirill.mokevnin [20:01] это дает вам понимание
kirill.mokevnin [20:02] что вывод на самом деле есть просто проблема с отображением
jack [20:02] ну проблемы и нет, буду оффлайн средствами работать
jack [20:03] но что же не так было в функции? или лучше я посмотрю вебинар и сам разберу?
kirill.mokevnin [20:03] а не то что “в языке какая то магия"
kirill.mokevnin [20:04] блин, у меня проблемы с интернетом
jack [20:04] да я понимаю, что нет никакой магии)
kirill.mokevnin [20:04] в общем я вас подводил к очень простой вещи
kirill.mokevnin [20:04] вам просто надо построить логическую цепочку
kirill.mokevnin [20:04] ваша фукнция при любом входе возвращает null (edited)
kirill.mokevnin [20:05] такое может происходит в двух случаях
kirill.mokevnin [20:05] либо вы реально возвращаете null (и значит у вас ошибка в логике программы)
jack [20:05] неправильное тело или аргументы
kirill.mokevnin [20:05] либо вы забыли написать return
kirill.mokevnin [20:05] есть такая штука, называется “отладка"
jack [20:05] работал с ней на js
jack [20:06] php тоже имеет нечто подобное?
kirill.mokevnin [20:06] когда вы отлаживаете вашу функцию и постепенно убеждаетесь в работоспособности ее частей и в конце концов находите где ошибка
kirill.mokevnin [20:06] )
kirill.mokevnin [20:06] вы под отладкой понимаете какой то инструмент
kirill.mokevnin [20:06] а я говорю про процесс нахождения ошибок в программах
jack [20:07] ну, на пайтоне я отлаживал просто вставляя print в интересующие меня куски кода
kirill.mokevnin [20:07] это то чем занимаются программисты 90 процентов времени
kirill.mokevnin [20:07] ну так вот жеж !
kirill.mokevnin [20:07] делайте это и смотрите вывод
kirill.mokevnin [20:07] но я же вам все написал
kirill.mokevnin [20:07] либо вы реально возвращаете null (и значит у вас ошибка в логике программы)
jack [1:05 PM] неправильное тело или аргументы
kirill.mokevnin [1:05 PM] либо вы забыли написать return
kirill.mokevnin [20:07] у вас там тривиальная ошибка по невнимательности
kirill.mokevnin [20:07] первое что надо проверять когда null это “не забыл ли я сделать return"
kirill.mokevnin [20:07] посмотрите на последнюю строчку в вашей фукнции
kirill.mokevnin [20:08] и в js и в python тоже самое
kirill.mokevnin [20:08] по дефолту функция возвращает null
kirill.mokevnin [20:08] если забыть return
jack [20:08] забыл return -_\
kirill.mokevnin [20:08] в ruby не так, оно возвращает последнее вычисленное выражение
jack [20:09] с ruby не сталкивался(
kirill.mokevnin [20:09] уровень программиста определяется тем наколько быстро и качественно он отлаживает
kirill.mokevnin [20:09] по этому сразу видно
kirill.mokevnin [20:09] как он приступает к задаче
kirill.mokevnin [20:09] вот сейчас можно сказать было собеседование (оно у нас так же проходит примерно)
kirill.mokevnin [20:09] но пока вы сами даже не пытаетесь двигаться и рассуждать о коде
kirill.mokevnin [20:10] этого недостаточно даже для junior позиции
kirill.mokevnin [20:10] но зато вы увидели как это можно делать
kirill.mokevnin [20:10] надеюсь поможет
jack [20:11] спасибо большое, буду разбираться.
kirill.mokevnin [20:11] а вебинары обязательно посмотрите)
kirill.mokevnin [20:11] ну и еще, вы слышали про TDD?
jack [20:11] неа
kirill.mokevnin [20:11] вот по сути вы по нему и работаете сейчас
kirill.mokevnin [20:11] разработка через тестирование
kirill.mokevnin [20:11] сначала написаны тесты, потом пишется код который их удовлетворяет
kirill.mokevnin [20:12] многие (в том числе мы) так разрабатывают софт
kirill.mokevnin [20:12] что дает огромные возможности по быстрому и безболезненному рефакторингу
jack [20:12] а, сталкивался с chai mocha
jack [20:12] на js опять же
kirill.mokevnin [20:13] вы сейчас о другом
kirill.mokevnin [20:13] инструмент для тестирования и процесс разработки это вещи из разных категорий
kirill.mokevnin [20:13] вы можете писать тесты и не используя TDD
kirill.mokevnin [20:14] а TDD это именно разработка управляемая тестами
kirill.mokevnin [20:14] то есть вы сначала пишете тесты
kirill.mokevnin [20:14] а потом код
jack [20:14] нужно почитать про тдд
kirill.mokevnin [20:14] и не важно какой тестовый фреймворк используется и используется ли вообще
kirill.mokevnin [20:14] и заодно про экстремальное программирование
kirill.mokevnin [20:14] кстати следующий вебинар будет о нем
jack [20:14] это два вебинара?
jack [20:15] отлично
kirill.mokevnin [20:15] но там уже разговор будет идти с учетом что все смотрели вебинар про tdd
GitHub Hexlet/webinars Hexlet webinars
jack [20:16] он?
kirill.mokevnin [20:16] ага
jack [20:17] спасибо большое!) буду разбирать
kirill.mokevnin [20:17] на здоровье)