Another website using Comic Sans...

Журнал Пушыстого

Журнал Пушыстого

(no subject)
[info]_winnie
Писать скрипты в расчёте на то что пользователи (дизайнеры, художники, моделлеры) - внимательные и неленивые как роботы, это всё равно что писать network-движок сетевой игры в расчёте на локальную сеть без лагов и разрывов.
То есть, "ну это проблема дизайнеров, что они сделали опечатку в 3% материалов" это всё равно что обвинить интернет в проблемах неустойчивого к потере пакетов кода.

Асинхронно, автоматически
[info]_winnie
Написал себе под cygwin клёвый скрипт. Который выключает сервер, берёт версию из svn, подготавливает ресурсы для перезапуска, включает сервер, запускает игру.
Колеги тыкают в кнопочки в Tortoise SVN, веб-морду сервера, в батник запуска игры, а у меня всё само ^_^
И оно не только само, но ещё работает быстрее чем типичный запуск руками, так как скрипт асинхронный - апдейт из svn и шатдаун серверу можно делать параллельно, запуск клиента игры и запуск сервера - тоже можно одновременно.

(no subject)
[info]_winnie
Сегодня сделал типичную опечатку, передал в функцию вместо объекта - список объектов, вместо
Kuzdra(bokrenki[i]) написал Kuzdra(bokrenki).
Ну, спустя пять секунд увидел ошибку, "У объекта "список" нет метода Budlan". С точки зрения машины, вполне нормальное сообщение. Хотя реальная ошибка в забытых квадратных скобках.
Подумал, раз браузеры, гугли, zshы и прочие научились исправлять ошибки автоматом, может когда-нибудь языки программирования научаться сообщать в листинге -
"у вас тут ошибка типов, но если добавить индексирование списка - то получится Ok". Ну как сейчас сообщают "Тут какая-то непонятная хрень, но если добавить точку с запятой то будет Ok".

struct X {} int main() {}
----
error C2628: 'X' followed by 'int' is illegal (did you forget a ';'?)


А ещё этот пост родился из моего вчерашнего скрипта, который проверяет данные ведённые дизайнером. Который должен был выдать не просто что 1+2+3+4 != 1+2+0+4, но и что вместо 0 скорее всего хотели написать 3.

(no subject)
[info]_winnie
Очень крутое видео от Джоела про упрощение интерфейсов - http://blip.tv/file/3996778/

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

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

И приводит, как пример, покупку из онлайн-магазина в один клик. Именно в один, а не "положить в корзину, перейти в корзину, подтверждаю покупку, подтверждаю доставку". Если человек кликнул по ошибке - то надо тратить клик на отмену, а не на подтверждение, которое происходит в 90% случаев.

Ещё до просмотра этого ролика я сделал генератор имён в нашей ММО, именно для того что бы пользователю надо было сделать меньше кликов для начала игры. Как оказалось, половина народа бегает с дефолтными никами :) Кстати, генератор мужских ников занимает 3 строчки, а женских - 20 строчек. Например,
Мимичоми     Нукетазд
Нуха         Сремоблух
Мястюби      Сругав
Ячучутя      Летокракр
Момока       Блолоздум
Уляся        Зоблеблел
Кикипоша     Тотоздоб
Чилюми       Тезал
Лелеша       Хеблуз
Юсямама      Блегаз

Рефакторинг регулярных выражений
[info]_winnie
Рискую быть обвинённым в капитанстве, но всё-таки. Всё-таки я часто вижу нечитабельные регулярные выражения, причем не потому, что они регулярные, а потому что автор - макака.

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

Вот есть у нас регулярка для последовательности пробелов \s+. И есть регулярка для числа, ([-+]?[\d]+). Нам надо извлекать числа из строк вроде "+123 -123 111:222:333". Легко сочинить монстра "([-+]?[\d]+)\s+([-+]?[\d]+)\s+([-+]?[\d]+):([-+]?[\d]+):([-+]?[\d]+)". Сочинить легко, прочитать и исправить сложно. А нужно для читаемости писать код так, как он в голове, а не транслировать его в копипаст. Можно такое регулярное выражение записать вот так:

"7 7 7:7:7".replace('7', r'([-+]?[\d]+)').replace(' ', r'\s+')


Тогда проще понять что имелось ввиду, исправить регулярное выражение. Как структуру первого уровня, например заменить "7 7 7:7:7" на "7:7:7:7". Так и второго, напр. матчить не только целые числа, но и дробные 123.456.

Winnie C++ Colorizer
[info]_winnie
Обновил Winnie C++ Colorizer. Генерирует лаконичный html код, делая самый часто встречающийся цвет дефолтным, так же заменяет "#000000" на "black", "#0000ff" на "blue" и тп. Так же перехал со старого dobrokot.nm.ru с рекламой на новый dobrokot.ru. К сожалению, забыл пароль от ftp, и не могу поставить редирект.

Брать здесь:
DobroKot.ru/WinnieColorizer.

Для тех кто не в курсе - это расцветка кода С++, для того что бы постить в ЖЖ. Автор заявляет, что может покрасить любой самый извращённый C/C++, включая мутантов с Obfuscated Contest. И выдаст более короткий html чем любой другой колорайзер :) Проблему с русскими буквами ещё буду решать, что бы выдавать UTF-8 в stdout и UCS-2 в clipboard.

Пример работы под катом.
Read more... )

В C++ тоже есть дао!
[info]_winnie
В порядке отражения нападок от бородатых Сишников с одной стороны и фанатов OCaml/Python/Java/... с другой.
C++ никому не нужен, есть C для быстрого и низкоуровневого кода, и мой FooBar для высокоуровневого кода!

Позволяет ли ваш любимый язык программирования, сделать свой тип данных, например 3d-вектор, struct { float x, y, z; }:

Так что динамический массив vec3 data[N]; займёт 3*sizeof(float)*N памяти. А массив из нового типа данных struct { vec3 pos; unsigned color; } длины 1000000 займёт именно 16 мегабайт памяти.

и ввести свои операторы +-*.. так что можно писать 0.5f * (A + B) и получить хотя бы 20% от производительности процессора в гигафлопсах, без ручного инлайна (0.5f*(A.x + B.x), 0.5f*(A.y + B.y), 0.5f*(A.z + B.z)).

Именно что завести свой любимый тип, а не использовать встроенный.

Позволяет ли ваш любимый язык программирования создавать типизированные структуры данных (деревья поиска, хеш-таблицы, очереди, ...) работающие так же эффективно, как написанные на C. Ну и что бы Queue тоже жрал именно sizeof(int)*N памяти, а не был обёрткой над Queue с void* или AbstractObjectBaseForAllObjects.

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

Отладка от обратного
[info]_winnie
Разрабатываем некую программу. Вроде всё правильно написано, но на выходе - явно хрень.

Два подхода к исправлению бага:

1) Путь света. Факт наличия ошибки игнорируется. Доказываем, что ошибки нет. Там где доказать не получается - там и ошибка.
Не получается в общем виде - так хотя бы на конкретных входных данных, отладочной печатью убеждаемся, что на каждом звене цепочки - везде ожидаемое значение.

2) Путь тьмы. Используем в логических переходах тот факт, что в программе есть ошибка, приводящая к наблюдаемой неправильной работе. Исходя из особенностей неправильного результата, определяем наиболее вероятное место ошибки.

Первый способ нередко находит другие ошибки в коде. Сцуко требует разбираться в том, что происходит и читать код. Трудный, требует времени. Больше уверенности в корректности исправления. Может привести к полному рефакторингу кода, просто ради того, что бы можно было надёжно исправить его.

Второй - это часто источник defensive programming в стиле if (value == NULL) return;, когда вместо того, что бы разобраться почему value - NULL, ставится заплатка, маскирующая ошибку. Часто требует меньше времени на закрытие конкретного бага в багтрекере.

(no subject)
[info]_winnie
Интересно, только я понимаю, что миллион скриптов конвертации и генерации не будут запущены, потому что они не встроены в билд сборки. А для некоторых скриптов их создатель уже на другом проекте или ушёл из компании.
Типично они перезапускаются так - тестер замечает что нет какой-то фигни в игре, и отсылает баг программистам.

Правильно работающая программа — просто частный случай Undefined Behavior.
[info]_winnie
[info]wizzard0 кинул ссылки на статью про undefined behavior C++. Там разбираются весьма интересные примеры из практики современных оптимизирующих компиляторов.

  • Может ли компилятор соптимизировать эту функцию до return 1, если вычисление INT_MAX+1 - это undefined behavior (C++ 5.5, C99 6.5)?
    int stupid (int a) {
      return (a+1) > a;
    }
  • Может ли компилятор выкинуть проверку if (!dev) и вместо падения при разыменовании NULL - молча пойти дальше?
    static void __devexit agnx_pci_remove (struct pci_dev *pdev)
    {
      struct ieee80211_hw *dev = pci_get_drvdata(pdev);
      struct agnx_priv *priv = dev->priv;
    
       if (!dev) return;
    
      ... do stuff using dev ...
    }

  • Как написать надёжную функцию bool div(int a, int b, int *result), получающую данные из ненадёжного источника? Которая возвращает false, если результат a/b нельзя представить как int.



http://blog.regehr.org/archives/232
http://blog.regehr.org/archives/226
http://blog.regehr.org/archives/213
Tags: c--, soft-dev

Home
>