Истории с тегом: индийский код

Всего историй: 192

9797

У семи кодеров дитя без глазу

Не могу не поделиться чудесами интерфейса одной небезызвестной стоматологической программы.

Выхожу из истории болезни кнопкой «Отмена». Программа задаёт вопрос: «Отказаться от изменений?» Жму «Да» — и сразу второй вопрос: «Сохранить результаты?» Ага, может, передумал уже.

Сплошь и рядом отмену действия нужно подтверждать нажатием «Да». Но чтобы не терять бдительность, иногда всё же задается нормальный вопрос «Сохранить?» с ответом «Нет». При этом другая половина действий не контролируется никак.

При нажатии кнопки «Сохранить» тоже иногда задается вопрос а-ля «Может, передумаешь?»

Названия кнопки «ОК»: «Продолжить», «Сохранить», «Да», «Назначить», «Выбрать», «Печать», «Обновить».

Названия кнопки «Отмена»: «Выход», «Отказ», «Отменить», «Закрыть», «Нет».

Расположение кнопок «ОК» и «Отмена»: справа вверху, слева вверху, справа внизу, вверху посередине, в центре.

Даже галочки у «ОК» где синие, а где зелёные, где слева от надписи, а где снизу.

База данных — вообще отдельная песня. Русско-английские сочетания типа «UDERGSPRAV», «kodoper», «ordercod», длиннющие названия таблиц типа «TREATSCHGROUPSPARAMSLINKS», «GRIDLAYOUTSETTINGSBIN». Все таблицы зарплаты именованы с префиксом «SAL_», но одна названа просто «SHTATVAR» (опять языки вперемешку).

В окне «О программе» не умещается логотип.

Программа 8-й версии имеет значок с цифрой 7.

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

Про глюки уж я молчу. Наверное, я счастлив, что мне не довелось увидеть исходного кода.

9715

Бетон на языке RGB

Есть два типа программистов. Первые сначала читают, потом программируют. Вторые сразу рвутся программировать, а читают только тогда, когда у них ничего не получается, и то не всё и не до конца. Решения, которые предлагают программисты второго типа, иногда просто изумительны!

Есть бетонная плита метр на метр, покрашенная краской. Задача: определить цвет, в который она покрашена. Что делает программист второго типа? Он берёт плиту и тащит её в лабораторию. Там он устанавливает напротив неё очень яркую лампу и три фоторезистора. Фоторезисторы он закрывает светофильтрами красного, зелёного и синего цветов. Включает лампу и регистрирует показания, снятые с фоторезистров. Дальше он бежит в библиотеку, берёт каталог со всеми возможными цветами и начинает искать среди них тот, компоненты которого наиболее точно соответствуют его данным. Его абсолютно не интересует, что его метод занимает половину дня, что он работает, только если плита имеет яркий цвет и не грязная, что в каталоге может и не быть искомого цвета… Но самое главное, он не знает, что цвет можно определить мгновенно, просто посмотрев на плиту.

Работать с такими программистами мне доводится довольно часто. На днях один такой программист два часа писал функцию перемешивания массива. Не знал он, что в PHP есть такая штука, как shuffle. И самое главное — не хотел знать! Другой быстренько набросал на JS функцию, которая перебирает все элементы массива и на каждом делает только одно действие: увеличивает значение переменной на единицу… Верно, ему нужно было узнать размер массива.

Программисты, читайте перед тем, как что-нибудь делать! Этим вы сэкономите и ваше время, и чужие нервы.

9563

Синий зуб звонит бревну

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

— Отсутствует 301-й редирект. Сайт работает только с WWW.

— Работает только под «ослом». Пришлось запускать через Wine.

— Отсутствует поиск.

— Имеется русская локализация, но переведённая в стиле «Синий зуб — Позвонить бревну».

— В некоторых местах русский язык вообще отсутствует, текст написан на английском.

И как тут не вспомнить бородатый анекдот, как программисты строили дом?

9560

Жизнь, Вселенная, индусы и всё такое

Последних лет десять я занимаюсь SAP. Практически вся прикладная часть системы доступна разработчикам конечного пользователя в исходных кодах. Язык программирования ABAP/4, правда, несколько специфический. Говорят, похож на Кобол. Если сравнивать с популярными ныне языками, то у меня он более всего ассоциируется с Бейсиком.

Есть в ABAP два вида подпрограмм: формы и функции. Форма имеет локальную область видимости (хотя её можно вызвать извне, но тогда нужно указать имя главной программы, в которой размещён код формы). Функции имеют глобальную область видимости, но должны быть обязательно приписаны к какой-нибудь группе функций. SAP может поставляется в разной комплектации. Набор установленных компонент (и, соответственно, доступных групп функций) может отличаться. Из-за этого имя вызываемой функции передаётся как литерал и, если оно указано неправильно или в системе не установлен компонент, содержащий нужную группу функций, выяснится это только в процессе вызова. Разработчики различных модулей вынуждены делить между собой общее пространство имён функций, а также других объектов. Наверное, они как-то координируют имена всех создаваемых функций. Но, скажем так, у них с этим есть некоторые трудности, потому очень часто в разных модулях есть функции, выполняющие схожие действия, а имя функции содержит посторонние символы. К слову, у конечного пользователя тоже есть возможность разрабатывать свои функции. И чтобы хотя бы устранить проблемы с пересечением имён с объектами клиентов, SAP не создаёт свои объекты с именами, начинающимися на букву Z — такие имена зарезервированы для разработчиков конечного пользователя, а клиентам не рекомендует создавать объекты, начинающиеся не на букву Z.

Конкретный пример. Во многих случаях необходимо определить количество дней в данном месяце (ну или последнюю дату в данном месяце). Похоже, что для каждого модуля SAP разработчики пишут эту функцию отдельно, причём не по одному разу. Беглый поиск дал сорок два различных варианта от SAP плюс ещё, конечно, ZMONTH_LAST_DATA — вариант от разработчиков конечного пользователя. Система SAP изначально немецкая, но индусский код попадается и тут. Вот несколько примеров.

Функция CBIH_RP02_GET_END_MONTH.

Через конструкцию CASE анализирует номер месяца. Для всех месяцев, кроме февраля, присваивает своей локальной переменной end_month1 соответствующее значение 30 или 31. Для февраля вызывает форму CHECK_DATE, передаёт ей дату и анализирует возвращаемую переменную L_ERROR. В зависимости от её значения устанавливает своей переменной end_month1 значение 28 или 29. Из исходного года и месяца и вычисленного дня формирует возвращаемую дату. Форма CHECK_DATE у переданной даты меняет число на 29, эта новая дата передаётся функции DATE_CHECK_PLAUSIBILITY, по возвращении из которой форма анализирует код возврата (была ли ошибка) и возвращает эту информацию в вызвавшую функцию. Функция DATE_CHECK_PLAUSIBILITY тщательно проверяет дату на корректность по григорианскому календарю (71 строчка исходного кода) и генерирует ошибку, если дата неправильная.

Функция FIMA_END_OF_MONTH_DETERMINE.

Ничего особенного — честно проверяет для февраля високосность года по григорианскому календарю. Впечатлило использование констант. Видимо, автору кто-то сказал, что хороший стиль программирования — никогда не использовать константы напрямую, а всегда их описывать в отдельно отведённом месте. Идея, конечно, здравая, но доведена до абсурда. Все необходимые группе функций константы описаны в отдельном инклюде FIMA_CONSTANTS (135 строк исходного кода). Я ещё понимаю описание констант для номера месяца типа CON_FEBRUARY(2) TYPE N VALUE '02'. Но это скорее исключение. Типичное описание:

CON_FIRST_DAY_OF_MONTH(2) TYPE N VALUE '01',

CON_DAYS_OF_MONTH_27(2) TYPE N VALUE '27',

CON_SBERFIMA_TLRA TYPE SBEWFIMA VALUE 'TLRA',

А код для присвоения числа, соответственно, такой:

CASE I_DATE+4(2).

WHEN CON_JANUARY. E_DAYS_OF_MONTH = CON_DAYS_OF_MONTH_31.

Функции, начинающиеся на «FKK».

Две из них, FKK_DTE_DAYS_PER_MONTH и FKK_DTE_GET_LASTDAY_OF_MONTH, находятся в одной группе FKDATE, причём рядом. В группе всего семь функций — трудно не заметить существующую тому, кто писал позже. Однако детали реализации отличаются — похоже, что каждой автор писал сам, хотя концептуально алгоритмы одинаковые. За исключением того, что вторая функция для дат до 1582 года вычисляет високосность года по юлианскому календарю. В обеих честно анализируются компоненты даты. Есть отличия в формате вызова.

Для первой нужно передавать один параметр — дату. Потом функция вызывает форму, в которой выполняются все вычисления. Для второй нужно передать два параметра — год и месяц, и она ещё проверяет корректность даты и генерит исключение, если дата неправильная. Первая подразумевает, что ей всегда передают корректную дату, и может вызывать прерывание программы, если переданная дата некорректна. Интересно, столкнулись ли эти функции хотя бы раз хотя бы в какой-нибудь системе с необходимостью вычислять последний день месяца для дат до 1582 года? А если столкнулась, то в курсе ли их разработчики, что в разных странах переход на григорианский календарь происходил в разное время?

Третья функция FKK_GET_LAST_DAY_OF_MONTH находится в группе FKB3A. Вычисляет последний день месяца с использованием встроенной операции над датами — прибавления и вычитания дней. Сначала она формирует дату на 28 число того же месяца и года, потом прибавляет к ней 4, получает дату заведомо в следующем месяце, устанавливает там день в «01» и вычитает единицу из всей даты. Простенько и со вкусом. Для дат в декабре 9999 года будет ошибка из-за переполнения года по ходу вычислений. Ну да кого это сейчас волнует?

Четвёртая функция FKK_LAST_DAY_OF_MONTH находится в третьей группе FKKPERIOD. Алгоритм компромиссный. Номер следующего месяца и года вычисляется «честно», потом формируется дата на первое число этого месяца и уже от неё отнимается единица. Функция корректно обрабатывает даты в декабре 9999 года, специально анализируя этот случай и возвращая константу «31.12.9999». Но при этом все даты до 1800 года считает некорректными и генерит на них исключения, как и на даты с неправильным месяцем. Если передана дата с неправильным днём, не замечает этого.

Функция HR_RU_DAQ_GET_DAYS_IN_MONTH.

Имеет 8 входных параметров, 2 выходных и 2 одновременно входных и выходных. При этом состоит всего из 58 строк кода (из них 26 выполняемых). Алгоритм вполне аскетичный, как у FKK_GET_LAST_DAY_OF_MONTH, только прибавляет не 4 к двадцать восьмому числу, а 31 к первому. Некоторые входные параметры помечены как необязательные и никак не участвуют в алгоритме. В некоторых функциях, не вошедших в этот краткий обзор, использовались вариации — например, к первому числу прибалялось 35 или 32. Видимо, 31 побоялись прибавлять — а вдруг не хватит? 32 и 35 — надёжнее. Или, может, они так округляли? Разницы-то действительно нет, сколько конкретно прибавлять, лишь бы попало куда-нибудь в следующий месяц.

Две замечательные функции END_OF_MONTH_DETERMINE и END_OF_MONTH_DETERMINE_2.

Находятся в группах FV03 и FV02 соответственно. При этом алгоритм практически повторяется. Видно, что вторая тупо списана с первой. Но автор второй, вероятно, решил не полагаться на автора первой, а иметь такую важную функцию под собственным контролем. Обе честно вычисляют високосность года, но только по юлианскому календарю. А чего заморачиваться — на ближайшие 90 лет-то хватит, а там пусть потомки решают «проблему 2100»…

Самая аккуратная реализация оказалась у разработчика конечного пользователя. Лаконичная, эффективная и снабжённая исчерпывающими комментариями. Это и понятно — он ведь заведомо не индус.

9432

Дни Индии в Корее

Тут все ругают индийский код. Я вам скажу, корейцы не лучше.

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

Сайтов с аналогичным интерфейсом — тысячи в мировой паутине. Но только корейцам удалось написать сайт, который работает:

— только под IE и никак иначе;

— строго на одной версии Java;

— только если в системе стоит полная поддержка корейского языка, хотя сайт полностью англоязычный.

Как? Как они это сделали?!

9415

Наше Желтейшество

Устроился на работу в известную компанию младшим жёлтым программистом. Проработал уже почти год. Мой старший товарищ учился на этой базе, переходя с «семёрки» на новомодную «восьмёрку». За несколько лет его практики база из простенькой УТ 10.3 стала чудовищем, в котором документы проводятся по десять секунд, а в коде без бочонка водки не разобраться. База стала зависимой от одного человека.

Сейчас товарищ ушёл в отпуск. Я уже три дня жду, когда отгрузочные документы перестанут проводиться, и директора придут меня убивать. Чувствую себя последним героем. Помолитесь за меня жёлтому богу, ладно?

9380

Быстрее, выше, глупее

Смотрю я на эти битвы мегагерцев с ядрами и тихо офигеваю. Производители софта для смартфонов до сих пор добиваются плавности движения картинки.

Как человек, программировавший на ZX Spectrum, я помню, что при 3,5 мегагерцах частоты (в тысячу раз медленнее современных процессоров!) в играх умудрялись делать плавный скроллинг. Ну, можно сделать скидку на С, на громоздкие библиотеки, на большое разрешение экрана. Но через какую жопу нужно писать софт, чтоб ему требовался на смартфоне четырёхъядерный процессор? Где хвалёное аппаратное ускорение?

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

9245

Времени много, гигагерц полно

Сегодня ребята сдавали технологии программирования. Задают им задачу по SQL: вывести из таблицы поля «имя» и «дата рождения» только тех сотрудников, которые работают в Западном регионе. Вроде бы ничего сложного, да? Пишем:

SELECT name, birth_date FROM staff WHERE region="West"

Верно? А вот ни фига! Это задание нужно сделать двумя запросами: одним вывести имя и дату, а вторым отобрать сотрудников из заданного региона.

У меня только один вопрос: нас сознательно с универа учат писать индийский быдлокод?

9170

Падай ниц перед моим кодом!

Правлю чужой PHP-код. Самописный сайтовый движок, который умудрялся при 15000 посещений в сутки класть выделенный сервер. Причём процессор был загружен на 1–2%, а база трещала под неимоверной нагрузкой.

Выяснилось следующее. На странице в двух местах выводилось меню: полное и с текущего места. Мало того, что построение содержимого не было объединено в один процесс, то бишь каждый раз данные брались заново, так ещё и для простого составления списка статей, когда нужны заголовки и ещё пара мелочей, не мудрствуя лукаво, человек написал: «SELECT * FROM %tablename%». Всего в базе порядка 150 статей с полным и сокращённым текстом. Редкая статья меньше 4000 знаков. Ну, вы поняли…

Кривые комменты — и того лучше. Вместо простого запроса «SELECT COUNT(id) FROM %tableName%» человек получает массив всех записей из базы. Затем примерно в 30 строках описан сложнейший алгоритм подсчёта количества записей.

Но убило даже не это. После всех этих манипуляций красуется строчка:

$count_rows = $count_rows;

Ну, хоть в чём-то человек был уверен на 100%!

9139

Системные требования — китайская грамота

По правилу шести рукопожатий вышел на меня хозяин одного из известных ресторанов города. Его супруга смоталась в Поднебесную и прикупила монохромную вывеску-информер полметра на четыре, 32×384. Оба человека видят комп впервые и считают, что с помощью компа можно делать всё. Проблема в том, кто это будет делать. Схему включения у китайцев, конечно же, не взяли, поэтому вывеска валялась в кулуарах около полугода, и за неё никто не брался, услышав, что схемы нет. 20 килорублей отдавать в случае ошибки не хотелось никому.

Апофеозом была не сама система, которая была собрана и запущена на коленке буквально за пару часов. Им была программа. Простой MSI, но на выходе… На выходе была китайская грамота. Поскольку жители Китая — наши соседи на Дальнем Востоке, мне приходится знать язык хотя бы с разговорником. Интерфейс на марсианском, хелп на марсианском — у меня истерика. Вылетает программа с ошибкой ODBC от драйвера MS Access. В мануале ничего не сказано про драйвера. Попробовал четыре ноута, на одном уничтожил операционку, пока на следующий день не пришёл к себе в офис. Там прога встала без проблем.

Баннер в итоге прошил, хозяева ресторана меня пригласили на поддержку сети и т. д., но, вопрос самолюбия остался. Позвонил в краевой центр знакомым прогерам, описал проблему. Они решили вопрос за двадцать минут. Поймали ошибку ODBC, грамотно рассудили, что раз программа китайская, значит, и бороться с ней надо по-китайcки, — добавили язык в винду, и всё завелось. И кто сказал, что компьютерный язык — английский? Дома на «семёрке» не получилось, а на работе приходится общаться с китайцами, потому язык там установлен.