вторник, 21 июня 2016 г.

Отличный образчик "индусского" PHP-кода

Работаю периодически на одном зарубежном проекте, дорабатывая функционал легаси-системы. Вчера обнаружил нечто такое, о чем хочется рассказать (заодно и сам в будущем прочитаю, вспомню и порадуюсь =)

Итак, имеется view-ка с большим объемом лапшекода, который схематически имеет следующую структуру (совпадения имен переменных случайны =):
====
...
for ($i = 0; $i < count($data); ++$i) {
     foreach ($data as $data) {
...
...
...

     }
}
====
Внутри данной конструкции  около 100 строк черт знает чего.  Логично предположить, что $data представляет собой массив. При выполнении этой конструкции я (почему-то) ожидал, что она выполнится ровно N^2 раз, где N - размерность массива $data. Но на удивление массив был обработан ровно 1 раз. И именно такое поведение и было правильным.
Я, конечно, стал искать внутри цикла какие-либо присвоения в переменную $i или выходы из цикла по инструкции break, но ни того, ни другого обнаружено не было. Стало интересно... )
И только через какое-то (весьма продолжительное =) время сообразил, почему код ведет себя именно так. Запускается внешний цикл, затем при первом запуске внутреннего цикла внешняя переменная $data перезаписывается присваиванием в нее внутреннего значения (при этом в самом foreach внешняя переменная корректно замыкается и хранит указатель на первоначальный массив $data).
По выходу из foreach() мы имеем в $data последний элемент внешнего массива, который у нас массивом не является, поэтому при проверке условия перед входом во вторую итерацию цикла внешнего for count() возвращает единицу (я так понял, что это стандартное поведение для переменных, не являющихся массивами). В итоге, вход во вторую итерацию внешнего цикла не выполняется (1 не меньше 1) и происходит выход из внешнего цикла. Просто и красиво.
Разумеется, внешний цикл был сразу мной удален и затем произведен небольшой рефакторинг по переименованию переменных для их мало-мальского различия между собой.
Ну и, конечно, остался легкий осадок в виде риторического вопроса: Зачем было писать _так_, если сразу можно было писать понятно ? )




четверг, 18 февраля 2016 г.

Задача о минимальном числе, составленном из множителей разбиения

На днях наткнулся на небольшую, но интересную задачку. Условие звучит так:
Задано целое десятичное число N такое, что 9 < N < 10^5. Требуется найти такое минимальное положительное десятичное целое число, произведение цифр которого равно числу N. Если такое число найти не удается, требуется вернуть 0.

Например, задано число 20. Его можно разбить на множители несколькими способами, которые подходят под условие задачи (исключаем множители 10 и 20, так как они не являются цифрами, плюс исключаем единицу, так как в данном случае она будет лишь способствовать увеличению числа-результата за счет дополнительного разряда):
1. цифры 4 и 5
2. цифры 2, 2 и 5
Из найденных цифр можно составить несколько чисел. Решением будет число 45, так как оно будет наименьшим среди всех возможных вариантов.

воскресенье, 24 января 2016 г.

Книга "Путь разработчика" Джона Сонмеза

В данный момент читаю книгу "Путь разработчика" Джона Сонмеза
(она же "Soft Skills: The software developer's life manual").

Книга о, так называемых, "мягких навыках" программиста: социальном взаимодействии, воспитании силы духа, воли, укреплении тела, умении правильно распоряжаться деньгами и т.д.

Книга не содержит какой бы то ни было технической начинки и читается достаточно легко.

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

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

четверг, 14 января 2016 г.

Первый опыт с PHP 7

Как уже, наверное, всем (ну или почти всем) известно, недавно вышла 7-ая версия PHP.
Установил себе ее на локальную машину для тестирования. Кое-что было добавлено нового (возможность явного указания типа данных, строгий режим, кое-какие изменения в приоритетах операций, новые операторы). Для себя пока отметил, что в генераторах стало возможным, используя конструкцию yield from <..>, выполнять рекурсивные вызовы генераторной функции, что, в общем, весьма удобно, если нужно, например, выполнять обход какой-либо древовидной структуры с генерацией промежуточных значений.
Обращаюсь к немногочисленным читателям.  Пробовал ли кто-либо из вас уже полноценно использовать PHP 7 на каких-либо проектах, и если да, то какие ее новые особенности вам наиболее запали в душу и почему ?

понедельник, 8 июня 2015 г.

Access Violation в mSysGit под Windows 7 x64 во время выполнения rebase

Буквально сегодня столкнулся с одной неприятностью при использовании mSysGit под Windows 7 x64. При выполнении "git rebase master" при наличии конфликтов в коде консольное окно закрывается с access violation.
Для воспроизведения ситуации делаем, например:
==
git init myProject
cd myProject
type NUL > file.txt
git add .
git commit -m "Initial commit"
git branch feature
echo '123' > file.txt
git commit -am "master changed"
git checkout feature
echo '222' > file.txt
git commit -am "feature changed"
git rebase master
===
То есть, создаем пустой файл file.txt, затем создаем ветку feature. В ветку master добавляем один коммит, в feature - другой. После чего пытаемся выполнить rebase ветки feature относительно master. И тут же получаем Access Violation консольного окна.
Вылетает процесс conhost.exe с кодом исключения c0000005.

Загуглив по этой теме, нашел старый топик 2011 года в google groups:

https://groups.google.com/forum/#!topic/msysgit/z1PfBWW66Jo

но решения так и не обнаружил. Что интересно, в обсуждении упоминается mSysGit версии
1.7.6, но у меня уже как бы последняя версия на сегодня 1.9.5. Непонятно.

Попытался заменить стандартную виндовую консоль на ConsoleZ, но проблема сохраняется
(вероятно, ConsoleZ использует тот же низкоуровневый процесс, который и сбоит в обоих случаях). В общем, вопрос к аудитории. Кто как борется с вышеуказанным ? Есть ли решение под Windows ?


среда, 21 января 2015 г.

Эвристический алгоритм решения задачи о минимальном количестве линий для размещения отрезков

Всем привет.  Мягко говоря, давно ничего не писал. Попробуем нарушить эту традицию )
Сегодня рассмотрим следующую интересную задачу.
Имеется некий список отрезков в одномерном пространстве. Каждый отрезок задан парой координат его левой и правой точек. Задача - найти минимальное количество линий, на которых можно разместить все эти отрезки таким образом, чтобы они не пересекались друг с другом.
В общем случае задача сводится к умному перебору.  Для разнообразия рассмотрим такую
категорию алгоритмов, как эвристические. Эти алгоритмы не гарантируют нахождение самого лучшего решения (хотя это и не исключено), но почти всегда дают вполне приемлемые результаты при сравнительно небольших временных затратах (этот показатель можно регулировать).

Давайте рассмотрим такой алгоритм. Будем действовать максимально просто.

вторник, 31 декабря 2013 г.

C наступающим 2014 новым годом )

Вот и заканчивается очередной, теперь уже 2013 год. Было в нем и хорошее, и, наверное, не очень. Как, впрочем, и всегда бывает ) На смену приходит 2014-ый год - год Лошади. Будем надеяться, что в новом году это животное поможет нам легче преодолеть все трудности.
Но, конечно, нельзя рассчитывать только на помощь лошадки. Человек сам должен также прикладывать усилия, чтобы его жизнь и жизнь окружающих его людей стала лучше. Нужно самосовершенствоваться, повышать свой уровень знаний и умений. Развиваться, одним словом. Желаю всем вам, друзья, в наступающем году выполнения всех ваших планов.  Чтобы все хорошее, что вы задумали, сбылось. С новым 2014 годом. Ура )