Паранормальное

Большинство людей как-то смешивает в одну кучу «всё паранормальное», принимая или отвергая всё сразу, скопом.

Для меня достаточно очевидно, что эту кучу нужно делить на два чётких класса: на то, что противоречит современным научным взглядам (телекинез, телепатия, гороскопы, суеверия, аура и прочее), как бы это наукообразно не звучало (структурированная вода, нуль-транспортировка и т. п.) и то, что может существовать в рамках современной науки. Последнее можно считать фантазиями или гипотезами, как угодно, но ничего мистического в этом нет.

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

Лох-несское чудовище благополучно разоблачено, насколько я знаю (на известной фотографии муляж), а вот с йети («снежным человеком», бигфутом) пока ничего не понятно. С точки зрения науки этот вид вполне может существовать, почему нет, десяток чудом выживших в горах больших белых обезьян могут тысячелетиями там прятаться, попробуй найди. Каждый год учёные открывают несколько новых видов животных, например, три года назад был найден новый вид пингвинов в Новой Зеландии. Так что удивительного в том, что в каких-то лесах или горах, которые просто так не прочесать, есть какие-то достаточно крупные животные, ещё и не особо желающие быть найденными?

Другая тема — инопланетяне. В этой теме традиционно серьёзные исследования никому не интересны, потому что не содержат ничего сенсационного, а громче всех высказываются люди далёкие от науки. Поэтому первые ассоциации у нас всех — «зелёные человечки» и «летающие тарелочки». Тем не менее, в возможном существовании разумной жизни с других планет нет ничего ненаучного. Количество звёзд во Вселенной оценивается в 1,5×10¹¹, а недавно астрономы заявили, что их может быть в три раза больше. Вокруг такого гигантского количества звёзд громадное количество планет. Что мешает зародится жизни на какой-то из них? Науке это не противоречит.

Другое дело — посещение Земли инопланетянами. Ближайшая к нам звезда находится на расстоянии 4,22 световых года. Современная физика утверждает, что добраться за приемлемое время из такого замкадья к нам невозможно. Наверное, может быть и что-то поближе, ещё не обнаруженное или (см.: паранойя) тщательно скрываемое, но более научные гипотезы такие: Землю инопланетяне не посещали или у нас в Солнечной системе есть соседи, ну или были.

Например, на Марсе могла бы быть какая-то цивилизация, почему нет? Например, их Рейган с Горбачёвым не договорились и цивилизация погибла, мы едва-едва не вляпались в ядерную войну, если бы не случайность.

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

62 комментария

«Неловкая пауза»

Неловкая пауза (24.35КиБ)

Художница Таня из ЖЖ, рисует очень забавные картинки, в основном обыгрывающие неоднозначность языка. Я про неё уже упоминал.

Несколько дней назад попросил её нарисовать неловкую паузу и вот! Спасибо, Таня!

Вопрос на засыпку — Перемотка в какую сторону изображена на картинке? А если приглядеться?

11 комментариев

Крестики-нолики на HTML CSS и прокрастинация

Крестики-нолики (38.95КиБ)

Есть такое понятие — прокрастинация, это про «никогда не откладывай на завтра то, что можно сделать послезавтра». В тяжёлых проектах есть соблазн отложить принятие трудных решений «на потом» или не делать что-то до последнего момента. Я человек и поэтому подвержен этой проблеме.

Я как-то рассказывал в интервью для «5 шотов», что у меня есть способ борьбы с прокрастинацией — я каждый день выделяю по полчаса на самое сложное, неприятное, то, чем заниматься совсем не хочется. Это помогает.

У меня с моими «Крестиками-ноликами» на HTML и CSS такое произошло — не хотелось заканчивать, искать ошибки и так далее. Вроде как проект-то уже сделан, проехали, кому-он-нужен-зачем-баги-править. Но какая-то неудовлетволённость осталась, хотелось доделать. В итоге я около недели по полчаса тщательно искал ошибку и вносил улучшения.

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

Багов быть не должно, могут быть шероховатости. Я сам знаю пару неаккуратных вещей — кнопка «Restart» работает не во всех браузерах и на ничьей следующий ход уже не сделать (хотя он и не нужен вообще-то).

11 комментариев

Картинка на чистом CSS

Картинка на чистом CSS (130.69КиБ)

Сейчас CSS позволяет делать всё более интересные вещи. Раз уж сегодня короткий день, за 20 минут из «сэкономленного» часа накидал программу, которая конвертирует любую картинку (в форматах PNG, JPEG или GIF) в чистый CSS (без использования dataURI). Каждая точка кодируется через одну конструкцию radial-gradient. Очень расточительно, сделал для иллюстрации принципа.

Если заморачиваться серьёзно, то можно выявлять в картинке области с градиентом (так делается в формате PNG для упаковки) и покрывать их целиком одной конструкцией, а так же оптимизировать наложением линейных градиентных областей с прозрачностью (через rgba или hsla). Достаточно интересная программисткая задача, кстати.

Самую очевидную оптимизацию я сделал в пробке по работе домой — выделил самый частый цвет и пустил его на фон, выиграл примерно 11,5КБ на картинке в примере.

За 20 минут я только успел сделать небольшой конвертор (результат работы можно посмотреть в разделе «Храню», только для «Хрома»). Так как синтаксис завязан на префиксы, то я в генераторе сделал указание браузера под который нужно сгенерировать код (поддерживаются: IE, Opera, Firefox и Chrome). Всё это весьма расточительно, картинка 75×75 занимает 164КБ.

У меня заработало для «Хрома» и «Файэрфокса», под «Оперой» не завелось, лень проверять что она не поддерживает, IE попробовать не могу — его не бывает на «Маках».

Код конвертора

// Конвертор картинки в чистый CSS, / ноябрь 2011 

<?
// ffccbb → fcb
// ff0000 → red
// abcdef → abcdef
function Bo_shortcolor($color) {
    static $shortnames = array(
        "#000080" => "navy",
        "#008000" => "green",
        "#008080" => "teal",
        "#4b0082" => "indigo",
        "#800000" => "maroon",
        "#800080" => "purple",
        "#808000" => "olive",
        //"#808080" => "gray",
        "#808080" => "grey",
        "#a0522d" => "sienna",
        "#a52a2a" => "brown",
        "#c0c0c0" => "silver",
        "#cd853f" => "peru",
        "#d2b48c" => "tan",
        "#da70d6" => "orchid",
        "#dda0dd" => "plum",
        "#ee82ee" => "violet",
        "#f0e68c" => "khaki",
        "#f0ffff" => "azure",
        "#f5deb3" => "wheat",
        "#f5f5dc" => "beige",
        "#fa8072" => "salmon",
        "#faf0e6" => "linen",
        "#ff0000" => "red",
        "#ff6347" => "tomato",
        "#ff7f50" => "coral",
        "#ffa500" => "orange",
        "#ffc0cb" => "pink",
        "#ffd700" => "gold",
        "#ffe4c4" => "bisque",
        "#fffafa" => "snow",
        "#fffff0" => "ivory",
    );

    $c = strtolower($color);
    if (isset($shortnames[$c])) {
        return $shortnames[$c];
    }

    if ($c[0] == $c[1] && $c[2] == $c[3] && $c[4] == $c[5]) {
        return '#' . $c[1] . $c[3] . $c[5];
    }

    return '#' . $c;
}

function Bo_convert($filename, $prefix = '') {
    if (!file_exists($filename) && !is_readable($filename)) {
        throw new Exception('File not found.');
    }

    $types = array(
        IMAGETYPE_JPG => 'jpeg',
        IMAGETYPE_PNG => 'png',
        IMAGETYPE_GIF => 'gif',
    );

    $imagedata = @getimagesize($filename);
    if (!is_array($imagedata) || !isset($imagedata[2]) || !isset($types[$imagedata[2]])) {
        throw new Exception('Unknown image format');
    }

    $im = call_user_func("imagecreatefrom" . $types[$imagedata[2]], $filename);
    $w  = imagesx($im);
    $h  = imagesy($im);

    // Самый частый цвет идёт на background-color
    $colorfreq = array();
    for ($x = 0; $x<$w; $x++) for ($y = 0; $y<$h; $y++) @$colorfreq[imagecolorat($im, $x, $y)]++;

    $bg = array_search(max($colorfreq), $colorfreq);

    for ($x = 0; $x<$w; $x++)
    for ($y = 0; $y<$h; $y++) {
        $pixel = imagecolorat($im, $x, $y);
        if ($pixel != $bg) {
            $color = Bo_shortcolor(sprintf('%06x', $pixel));

            $dots[] = "{$prefix}radial-gradient($color,$color) {$x}px {$y}px";
        }
    }

    $dots = join(',', $dots);
    $bg   = Bo_shortcolor(sprintf('%06x', $bg));

    return <<<HTML
<head>
<title>$filename converted in background by Evgeny Stepanischev //bolknote.ru</title>
<style text="text/css">
    div {
        background: $dots;
        background-repeat: no-repeat;
        {$prefix}background-size: 1px 1px;
        background-color: $bg;
        background-size: 1px 1px;
        width: {$w}; height: {$h};
    }
</style>
<body>
<div></div>
</body>
HTML;
}

if ($_SERVER['argc'] < 2) {
    echo <<<HELP
Image to background CSS convertor by Evgeny Stepanischev. //bolknote.ru Nov 2011

Usage: {$_SERVER['argv'][0]} filename [prefix]

filename  - image file name (PNG, JPEG or GIF)
prefix    - your browser name (Opera, IE, FF, Safari, Chrome)
HELP;
exit;
}

$browsers = array(
    'ie'     => '-ms-',
    'opera'  => '-o-',
    'safari' => '-webkit-',
    'chrome' => '-webkit-',
    'chromium' => '-webkit-',
    'ff' => '-moz-',
    'firefox' => '-moz-',
);

if (isset($_SERVER['argv'][2])) {
    $type = strtolower($_SERVER['argv'][2]);
    $prefix = isset($browsers[$type]) ? $browsers[$type] : '-' . $type . '-';
} else {
    $prefix = '';
}

try {
    echo Bo_convert($_SERVER['argv'][1], $prefix);
} catch (Exception $e) {
    echo "Error: ", $e->getMessage(), "\n";
};

9 комментариев

Цвета из CSS, названия которых короче их номеров

Кстати, если вдруг кому-нибудь для оптимизации CSS нужна таблица цветов, названия которых короче их номеров, то я вчера для конвертора сделал скрипт, который все такие цвета нашёл. Наверняка её кто-то составлял и раньше, но мне было быстрее программу написать. Список в виде массива есть в конверторе, а вот список их названий строкой: navy, green, teal, indigo, maroon, purple, olive, gray, grey, sienna, brown, silver, peru, tan, orchid, plum, violet, khaki, azure, wheat, beige, salmon, linen, red, tomato, coral, orange, pink, gold, bisque, snow, ivory.

Например, «silver» короче своего числового эквивалента «#c0c0c0» на один символ, а «tan» короче «#d2b48c» на четыре.

8 комментариев

Забавная книжка

Забавная книжка (125.48КиБ)

Всё забываю рассказать. Купили эту книжку, когда в Финляндии с друзьями были. Продавалась в Хельсинки, в Музее современного искусства. Мне кажется, незаменима для развлечения маленьких детей, даром, что на финском.

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

Книга называется «Täyttä laukkaa!» («Во весь опор!», английское название — «Gallop!»), автор, насколько я понимаю — Rufus Butler Seder (Руфус Батлер Сидер). На каждом развороте справа картинка, с какой-то несложной надписью, например под лошадью — «hoppoti-koppoti-kop» («цок-цок-цок»), слева — маленькое интро животного, у кошки — «vaanii hiipii ponkaisee ja loikkaa» («киса подкрадывается и прыгает»).

Уважаемые читатели, скажите пожалуйста, а на русском вы такие книги не видели?

22 комментария

Всякая мелочь одним постом-3

Немецкий физик Томас Зенкель собрал пилотируемый летательный аппарат с 16 пропеллерами от обычных игрушечных самолётов. Правда держится аппарат в воздухе всего от 10 до 30 минут, но это неплохо. В случае неполадок пилот может воспользоваться парашютом.

На «Хабре» недавно вышла статья сравнивающая лампы накаливания, люминесцентные и, появившиеся недавно, светодиодные бытовые лампы.

Подсказали два «пасхальных яйца» в Гугле, правда работают не во всех браузерах: Гугл делает «бочку» и Гугл перекосило.

Приказ Министерства связи и массовых коммуникаций Российской Федерации (Минкомсвязь России) от 3 мая 2011 г. N 92 г. Москва «Об определении видов технических средств и систем, подлежащих оснащению аппаратурой спутниковой навигации ГЛОНАСС или ГЛОНАСС/GPS» обязывает оснастить аппаратурой спутниковой навигации ГЛОНАСС или ГЛОНАСС/ГПС оборудование радиодоступа для беспроводной передачи данных. Точка доступа WiFi относится к оборудованию радиодоступа для беспроводной передачи данных. На что будет это похоже, а главное зачем это делать?

Полюбопытсвуйте на «Брачную газету», выпуск от 13 августа 1917 года. «Жениться желаетъ и ищетъ невѣсту съ большими средствами, не старше 35 лѣтъ…».

Очень хорошая статья «Почему мы верим во что попало и как с этим бороться». Мы предпочитаем «перебдеть, чем недобдеть», эволюция нас выучила тому, что безопаснее видеть закономерности даже там, где их нет, чем не увидеть там, где они есть.

Давно хотел написать на эту тему, а тут статья подвернулась — «Романтизм головного мозга», о том как искажают картину мира плохие фильмы и романы.

А это для программистов — приложение «D» стандарта Си 99 разрешает использование в качестве имён переменных и функций некоторые символы из Юникода. То есть уже 10 лет можно называть русскими (или арабскими) буквами переменные в Си. Чуть подробнее — у Анатолия Воробья в ЖЖ.

21 комментарий

Л…ениногорск и голуби

Я сейчас вспоминаю, что в моём детстве кругом были голуби. В Лениногорске, в моём родном городе их было много, было даже несколько голубятен. Потом в стране многое произошло, держать голубей стало дорого, люди думали совсем о другом, я переехал в Казань и, если голубятни попадались, то все они были заброшенными, разрисованными плохенькими тегами.

Голуби (85.70КиБ)

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

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

4 комментария

У̶д̶о̶б̶н̶о̶е̶ новое цитирование в блоге

Долго думал как упростить цитирование у себя в блоге, наконец придумал. Ещё остались кое-какие шероховатости, но в целом должно стать лучше.

Сделал две вещи.

Во-первых, когда вы вставляете какой-то кусок текста в поле для комментариев, движок пытается догадаться не вставляете ли вы цитату и, если вставляете, расставляет значки цитирования („>“) перед каждой строкой.

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

О последнем расскажу немного подробнее. Устроено всё несложно, разберём на примере выделения полужирным.

Сохранённые звёздочки

Чтобы звёздочки скопировались вместе с остальным текстом, они должны в этом тексте присутствовать. И они там есть. Вокруг слова, выделенного жирным находятся звёздочки, написанные нулевым шрифтом и прозрачным цветом. Поэтому в тексте и при выделении их не видно, но в буфер обмена они попадают. Так же устроено сохранение остальной разметки — вырезанных частей ссылок, исходных УРЛов картинок.

13 комментариев

Юзерпики на «Яндекс.Фотках»

Вчера в Татарстане был выходной, поэтому пока мы ехали на машине за город, я сделал заготовку для хранения юзерпиков на «Яндекс.Фотках», а вечером её доделал. Сейчас все юзерпики в фоне переливаются туда в порядке запроса пользователем в закрытый альбом специального пользователя, которого я завёл.

До этого юзерпики по сложным правилам (с использование адреса почты из SRE OpenID или vCard, favatar, gravatar, pavatar, юзерпиков из «Ярушки» и ЖЖ и т. д.) получались для каждого человека в комментариях и загружались каждый раз с совершенно разношёрстных ресурсов.

Это было плохо по трём причинам. Во-первых, они были все разного размера и приводились к моим 40×40 браузером, то есть пользователи грузили лишние килобайты. Во-вторых, частенько канал до сайта с каким-либо юзерпиком был плох и загружалось с него всё медленно, а то и вообще не загружалось. В-третьих, юзерпики иногда пропадают (сайты закрываются, пользователи их меняют), поэтому вместо картинок в старых заметках иногда зияли дыры.

Есть и четвёртая причина, не знаю насколько она значимая. Некоторые юзерпики (побайтно) повторяются, но так как браузер не знает, что с двух разных УРЛов грузится та же картинка, он грузит её два раза. У меня сейчас не так — я хеширую картинку и по хешу ищу совпадение. Есть вероятность совпадения хеша, но юзерпики не слишком-то важные данные, чтобы бояться коллизий.

Сейчас юзерпики грузятся только в фоне, то есть какое-то время он грузится с «настоящего» адреса и только через какое-то время — с «Яндекс.Фоток». Так как запросов в стеке пока очень много (сейчас загружено 779 картинок и их число растёт очень быстро), процесс перекладывания может растянуться на часы. В будущем, когда бо́льшая часть будет уже лежать на «Фотках», этот процесс сократится до минут.

17 комментариев

Первый снег в Казани

Первый снег выпал, то есть тот, который ляжет хорошим слоем и уже вряд ли растает до весны. Хорошее время, ещё не слишком холодно (−4˚C сейчас на улице), не гоняет никто (зимние шины есть не у всех, да и непривычно ещё), от этого тихо вокруг и очень комфортно на дороге.

6 комментариев

Хочу поменять библиотеку для OpenID на сайте

Хочется поменять библиотеку, которую я использую для OpenID на сайте. Я сейчас использую Janrain OpenID, но она давно не обновлялась, генерирует варнинг и только с костылями и патчами работает с реализацией OpenID в ЖЖ (баг-репорт я писал в обе компании, бестолку).

Посоветуйте какие-нибуль альтернативы (на PHP). Я рассматриваю сейчас LightOpenID.

Требования — библиотека должна поддерживать OpenID 1.x и 2.x, SREG, предоставлять возможность хранить данные где я укажу (мне нужно на диске, а не в БД) и не должна использовать экзотические модули.

6 комментариев

Запись в NTFS средствами Mac OS X

Как оказалось, использование этого небезопасно, используйте только если нет другого выхода.

Как известно пользователям «маков», Mac OS X умеет монтировать диски с файловой системой NTFS только на чтение. Обычно, чтобы писать скачивают сторонний драйвер NTFS — либо бесплатный NTFS-3G, либо какие-то платные драйвера (Tuxera или Парагон).

Ночью я случайно наткнулся на рецепт, позволяющий задействовать для записи на NTFS внутренний драйвер Mac OS X (рецепты немного различаются для «Снежного барса» и «Льва».

В сегодняшей утренней пробке я сделал программу, которая этот рецепт автоматизирует, листинг ниже, скачать можно с «Гитхаба» (запускать — через bash).

Плюсы следующие.

Во-первых, это высокая скорость записи (30МБ/сек). Во-вторых, с этим решением файл удаляется в корзину. В-третьих, никаких сторонних драйверов. Но надо быть аккурантым — диск обязательно нужно отмонтировать от «Винды» до отключения, иначе Mac OS смонтирует его в режиме только для чтения.

Добавлено позднее: Сергей Васильев предостерегает от использования родного драйвера для работы с NTFS: говорит, что можно разрушить файловую систему.

Листинг программы.

#!/bin/bash

ARCH=`uname -r | cut -d. -f1`
NMOUNT=/sbin/mount_ntfs
NLIBRA=/System/Library/Extensions/ntfs.kext/Contents/MacOS/ntfs

function usage {
    cat <<USAGE
NTFS writing enabler (//bolknote.ru Nov 2011)

usage: $0 <action>
  <action> - "enable" for enable NTFS write, "disable" otherwise.
USAGE
    exit
}

function ntfsdisable {
    if [ -e "${NMOUNT}_orig" ] && [[ -e "${NLIBRA}_orig" || $ARCH -eq 10 ]]; then
        sudo /bin/mv "${NMOUNT}_orig" "$NMOUNT"
        [ $ARCH -eq 11 ] && sudo mv "${NLIBRA}_orig" "$NLIBRA"

        echo Disabled
    else
        echo "Error: cannot disable NTFS. Already disabled?"
    fi
}

function ntfsenable {
    ntfsenable$ARCH
    echo Enabled
}

function ntfsenable10 {
    echo -n 'Please enter your administrator password. '

    sudo /bin/mv "$NMOUNT" "${NMOUNT}_orig"
    /bin/cat << MNT | sudo /usr/bin/tee "$NMOUNT" >/dev/null
#!/bin/sh
/sbin/mount_ntfs_orig -o rw "\$@"
MNT
    sudo /usr/sbin/chown root:wheel "$NMOUNT"
    sudo /bin/chmod 755 "$NMOUNT"
}

function ntfsenable11 {
    TEMP=`mktemp -d /tmp/ntfs$$.XXXXXX` || (
        echo 'Cannot create temporary directory.'
        exit
    )

    trap "/bin/rm -rf $TEMP" EXIT

    echo -n 'Please wait. Downloading...'

    curl -o "$TEMP/arch.zip" 'http://dl.dropbox.com/u/9349175/datahost-macdaily/NTFS_Enabler.zip' 2>&- 1>&- ||
    curl -o "$TEMP/arch.zip" 'http://ntfs_enabler.chat.ru/NTFS_Enabler.zip' 2>&- 1>&- || (
        echo 'Cannot download NTFS enabler bundle.'
        exit
    )

    echo ' done'

    unzip "$TEMP/arch.zip" -d "$TEMP" 2>&- 1>&-
    [ `md5 "$TEMP/NTFS_Enabler/ntfs"` == a88031b3257379257086af017891f229 ] || (
        echo "Error: invalid checksum NTFS enabler bundle"
        exit
    )
    ntfsenable10

    sudo /bin/mv "$NLIBRA" "${NLIBRA}_orig"
    sudo /bin/mv "$TEMP/NTFS_Enabler/ntfs" "$NLIBRA"
    sudo /usr/sbin/chown root:wheel "$NLIBRA"
    sudo /bin/chmod 755 "$NLIBRA"
}

if [[ $ARCH -lt 10 || $ARCH -gt 11 ]]; then
    echo 'Unknown Mac OS version (Snow Leopard or Lion required).'
    exit
fi

[ "$1" == "" ] && usage

case "$1" in
    enable)
        ntfsenable
        ;;
    disable)
        ntfsdisable
        ;;
esac

15 комментариев

Активность аудитории

Немного статистики.

В среднем на сайта в месяц бывает примерно 90 тысяч человек. Каждый месяц это число может быть меньше или больше. Например, в июне было 108 тысяч, а в августе — 77. Я недавно перелил большинство юзерпиков пользователей на «Яндекс.Фотки» и, делая скидку на людей с одинаковыми юзерпиками и именами (у меня для двух одинаковых имён сгенерируется один юзерпик), активная аудитория сайта порядка 1700 человек.

То есть более чем за 10 лет существования сайта (правда комментарии на сайте появились сильно позже) его посетила толпень народу, но комментрировали всего несколько тысяч. Похожая ситуация, судя по всему, у Экслера на его персональном блоге, в день его сайт посещает столько же народу, как меня за месяц, а комментариев в блоге — только несколько десятков к каждой записи.

Мне бы хотелось, чтобы читатели более активно высказывались, мне сейчас интереснее обсуждать мои мысли с читателями.

Причин низкой активности я вижу две: всё-таки мне не удалось научить читателей подписываться на комментарии через RSS (и надо думать о том, чтобы как-то корректно высылать их на почту), вторая — отсутствие древовидных комментариев (но их-то я вводить не хочу, они провоцируют уход от темы и читать их все у меня не получится и не интересно, тогда вопрос — зачем стимулировать дискуссии, в которых мне не хочется участвовать).

Надо думать в сторону почты. Проблема с почтой, что её надо как-то подтверждать. Устроить какому-нибудь ящику «сладкую жизнь» очень просто (у меня даже была программа «Shit Streamer» на Перле и ПХП для этого) — достаточно подписать ящик на комментарии на куче ресурсов, ведь сейчас мало кто озабочен подтверждением подлинности ящика.

Увы и подтверждение подлинности через письмо не очень-то хорошая идея — кого угодно можно засыпать по брови письмами с подтверждениями.

Идея, которую я сейчас обдумываю такова: пользователю для первого подтверждения адреса почты (что будет доступно только для пользователей, которые авторизовались через OpenID), предлагается нажать на ссылку, сформированную специально для него.

Что-то типа: mailto:bolknote-confirmation+dy43udsj36HdshddkjdDds@gmail.com?subject=http://someopenid.example.org

Пользователь жмёт на ссылку, отсылает пустое письмо на этот адрес, с этого момента считается, что он подтвердил свой адрес. «Гмэйл» устроен таким образом, что на часть после плюса он внимания не обращает и эти письма будут попадать на ящик «bolknote-confirmation». Мой скрипт время от времени будет заходить туда, прямо по протоколу POP3, это текстовый простой протокол, мне надо только научиться работать с ним через TSL, получать список писем, их заголовки, подверждать адреса и удалять обработанное.

Не слишком неудобно получается?

64 комментария

Картинка на чистом CSS-2

Ещё картинка на чистом CSS (82.31КиБ)

Я тут всё это время думал как дёшево улучшить свой конвертор картинок в чистый CSS и придумал.

Выкинул «radial-gradient» и стал использовать «linear-gradient». Картинка, которая в прошлой версии занимала 164КБ, сейчас занимает 89 79. Это уже неплохо, в сжатом (gzip) виде этот код занимает 19КБ, что всего в два с половиной раза больше, чем исходное изображение в PNG. Результат можно сильно улучшить, если отказаться от повтора цвета, но изображения с мелкими деталями (с текстом, например) пострадают.

Кстати говоря, логотип студии Лебедева при конвертации из PNG (6,7КБ) уменьшился до 1,6КБ 1,3КБ. Это уже реальная экономия, если бы не префиксы браузеров.

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

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

Добавлено позднее: сделал оптимизацию, теперь конвертор делает два прогона: один просматривает пиксели по горизонтали, второй по вертикали. Выбирается тот, который даёт наименьший результат.

Ключи запуска те же.

<?
// ffccbb → fcb
// ff0000 → red
// abcdef → abcdef
function Bo_shortcolor($color) {
    static $shortnames = array(
        "c0c0c0" => "silver",
        "808080" => "gray",
        "800000" => "maroon",
        "ff0000" => "red",
        "800080" => "purple",
        "008000" => "green",
        "808000" => "olive",
        "000080" => "navy",
        "008080" => "teal",
        "f0ffff" => "azure",
        "f5f5dc" => "beige",
        "ffe4c4" => "bisque",
        "a52a2a" => "brown",
        "ff7f50" => "coral",
        "ffd700" => "gold",
        "808080" => "gray",
        "008000" => "green",
        "808080" => "grey",
        "4b0082" => "indigo",
        "fffff0" => "ivory",
        "f0e68c" => "khaki",
        "faf0e6" => "linen",
        "800000" => "maroon",
        "000080" => "navy",
        "808000" => "olive",
        "ffa500" => "orange",
        "da70d6" => "orchid",
        "cd853f" => "peru",
        "ffc0cb" => "pink",
        "dda0dd" => "plum",
        "800080" => "purple",
        "ff0000" => "red",
        "fa8072" => "salmon",
        "a0522d" => "sienna",
        "c0c0c0" => "silver",
        "fffafa" => "snow",
        "d2b48c" => "tan",
        "008080" => "teal",
        "ff6347" => "tomato",
        "ee82ee" => "violet",
        "f5deb3" => "wheat",
    );

    $c = strtolower($color);
    if (isset($shortnames[$c])) {
        return $shortnames[$c];
    }

    if ($c[0] == $c[1] && $c[2] == $c[3] && $c[4] == $c[5]) {
        return '#' . $c[1] . $c[3] . $c[5];
    }

    return '#' . $c;
}

class Bo {
    public function __get($num) {
        return $num ? $num . 'px' : 0;
    }
}

function Bo_convert_helper($im, $lim1, $lim2, $getpix, $dotmask, $z) {
    $end  = $lim1 - 1;
    $dots = array();

    for ($o1 = 0; $o1<$lim2; $o1++) {
        $coll = array();
        $prev    = null;
        $start   = 0;

        for ($o2 = 0; $o2<$lim1; $o2++) {
            $pixel = $getpix($im, $o2, $o1);

            if ($prev !== null && $prev !== $pixel || $o2 == $end) {
                if ($prev !== null) {
                    $color = Bo_shortcolor(vsprintf('%02x%02x%02x', $prev));

                    $coll[] = "$color {$z->$start},$color {$z->$o2}";
                }

                if ($o2 == $end && $prev != $pixel) {
                    $color = Bo_shortcolor(vsprintf('%02x%02x%02x', $pixel));
                    $cell[] = "$color {$z->$o2}";
                }

                $start = $o2;
            }

            $prev = $pixel;
        }

        $dots[] = sprintf($dotmask, implode(',', $coll), $z->$o1);
    }

    return $dots;
}


function Bo_convert($filename, $prefix = '') {
    $z = new Bo();

    if (!file_exists($filename) && !is_readable($filename)) {
        throw new Exception('File not found.');
    }

    $types = array(
        IMAGETYPE_JPG => 'jpeg',
        IMAGETYPE_PNG => 'png',
        IMAGETYPE_GIF => 'gif',
    );

    $imagedata = @getimagesize($filename);
    if (!is_array($imagedata) || !isset($imagedata[2]) || !isset($types[$imagedata[2]])) {
        throw new Exception('Unknown image format');
    }

    $im = call_user_func("imagecreatefrom" . $types[$imagedata[2]], $filename);
    $sw = $w = imagesx($im);
    $sh = $h = imagesy($im);

    $hfunc = create_function('$im, $x, $y', 'return imagecolorsforindex($im, imagecolorat($im, $x, $y));');
    $hmask = "{$prefix}linear-gradient(0,%s) 0 %s";

    $hdots = join(',', Bo_convert_helper($im, $w, $h, $hfunc, $hmask, $z));

    $vfunc = create_function('$im, $y, $x', 'return imagecolorsforindex($im, imagecolorat($im, $x, $y));');
    $vmask = "{$prefix}linear-gradient(90,%s) %s 0";

    $vdots = join(',', Bo_convert_helper($im, $h, $w, $vfunc, $vmask, $z));

    if (strlen($hdots) > strlen($vdots)) {
        $dots = $vdots;
        $sw = 1;
    } else {
        $dots = $hdots;
        $sh = 1;
    }

    return <<<HTML
<head>
<title>$filename converted in background by Evgeny Stepanischev //bolknote.ru</title>
<style text="text/css">
    div {
        background: $dots;
        background-repeat: no-repeat;
        {$prefix}background-size: {$sw}px {$sh}px;
        background-size: {$sw}px {$sh}px;
        width: {$w}px; height: {$h}px;
    }
</style>
<body>
<div></div>
</body>
HTML;
}

if ($_SERVER['argc'] < 2) {
    echo <<<HELP
Image to background CSS convertor v2 by Evgeny Stepanischev. //bolknote.ru Nov 2011

Usage: {$_SERVER['argv'][0]} filename [prefix]

filename  - image file name (PNG, JPEG or GIF)
prefix    - your browser name (Opera, IE, FF, Safari, Chrome)

HELP;
exit;
}

$browsers = array(
    'ie'     => '-ms-',
    'opera'  => '-o-',
    'safari' => '-webkit-',
    'chrome' => '-webkit-',
    'chromium' => '-webkit-',
    'ff' => '-moz-',
    'firefox' => '-moz-',
);

if (isset($_SERVER['argv'][2])) {
    $type = strtolower($_SERVER['argv'][2]);
    $prefix = isset($browsers[$type]) ? $browsers[$type] : '-' . $type . '-';
} else {
    $prefix = '';
}

try {
    echo Bo_convert($_SERVER['argv'][1], $prefix);
} catch (Exception $e) {
    echo "Error: ", $e->getMessage(), "\n";
    exit(1);
};

Оставить комментарий

Будущее формата CSS image

Лого в CSS (38.79КиБ)

Мои эксперименты с картинками на чистом CSS внезапно дали следующий результат. Я взял для экспериментов логотип студии Лебедева в первом попавшемся цвете и перегнал его в CSS image при помощи своего конвертора, используя все префиксы браузеров: «webkit», «moz», «o» и «ms» («Конкерор» включать не стал, доля этого браузера исчезающе мала).

Оказалось, что если сжать получившийся файл (браузеры же понимают сжатый CSS), то получившийся файл будет размером меньше, чем та же картинка в формате PNG: 2,5КБ против 6,7. Файл с лого Студии я пропускал через онлайновый оптимизатор PNG (punypng), так что он вряд ли неоптимален.

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

Добавлено позднее: в комментариях картинку «утоптали» в 448 байт. Непонятно почему у меня такой плохой PNG получился.

23 комментария

Всякая мелочь одним постом-4

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

Всем разработчикам знакома ситуация «ладно, потом переделаем». Такая и подобные ей ситуации называются «техническим долгом». Не забывайте отдавать технические долги, аукнется, мало не покажется!

Быстро научиться разговаривать с татарским акцентом поможет смешная статья «Изучаем татарский вместе», которую я вынес из «Вконтакте».

В Живом Журнале krascat можно увидеть цветные фотографии Англии 1928 года Клиффорда Адамса. Фотографии сделаны по  методу автохрома.

Алексей Кунгуров, более 10 лет занимающийся проведением избирательных компаний, рассказывает о мифах, связанных с выборами.

Новость на английском, но важная для всех, у кого есть смартфоны: компания Adobe прекращает разработку «Флеша» под мобильные платформы.

Про месть через 17 лет пишет mercylo в своём ЖЖ. Неприятная история — сына отомстившей, а скорее мелко подгадившей женщины когда-то mercylo не приняла в университет.

4 комментария

Как поставить Кобол на Мак

Пусть здесь полежит, чтобы я потом не искал.

Как поставить Кобол на Мак (при помощи «брю»):

curl http://www.sim-basis.de/open-cobol-1.1.tar.gz
tar xvfz open-cobol-1.1.tar.gz
cd open-cobol-1.1
brew install gmp
brew install berkeley-db

./configure --prefix=/usr/local/Cellar/open-cobol/1.1
make && make install
brew link open-cobol

9 комментариев

Удаление умершей ноды в кластере «Оракла»

Небольшой видеоурок по удалению умершей ноды из кластера «Оракла». В одном месте там требуется, чтобы на машине был своп не менее 500МБ, у нас не было (на машине 96ГБ памяти, зачем ей своп), мы его просто создали на диске в файле.

2 комментария

Заказали чай из Англии

Картонная коробка с наклейкой «SMALL PACKET» и таможенной декларацией, лежащая на деревянном полу.
Открытая картонная коробка на деревянном полу, внутри — каталог «The Kent & Sussex Tea & Coffee Company» за 2017 год, оранжевая упаковка и другие товары.
На деревянном столе разложены пакетики чая и кофе от компании "Bent & Sussman", включая сорта "Lapsang Souchong" и "Cinnamon", а также оранжевый пакет и брошюра.

Решили с женой попробовать заказать чай из Англии. Заказали месяц назад восемь сортов чая и один кофе в интернет-магазине компании «The Kent & Sussex Tea & Coffee Company». Вчера забрали посылку с почты и заварили первый чайник. Чай настолько ароматный, что чувствовался через коробку и упаковку, когда я его нёс с почты. Мне пока большего из заказанного понравился «Cinnamon», чай с пряностями.

Очень рекомендую, если кто-то из читателей любит хороший чай (и расскажите что вы заказываете, например, если вы нашли магазин с хорошим китайским чаем). Цены есть на сайте, чтобы можно было грубо прикинуть, у нас получился вес 1,25 кг за £40,84 (почти 2000 рублей).

39 комментариев

Советские надписи на произодственной базе «Мелиты»

Сохранившиеся с советских времён таблички, надписи чем-то меня притягивают. Я их стараюсь фотографировать, если вижу. Буду выкладывать эти фотографии в блог.

Вот эти две — с заброшенной производственной базы фабрики «Мелита» (выпускает меховые изделия, существует с 60-х годов 19-го века), где мы в воскресенье в пейнтбол играли.

Пропуска предъявляйте в развёрнутом виде (52.50КиБ)
Вход на территорию фабрик строго запрещается с сумками узлами и чемодана (56.11КиБ)

6 комментариев

Зачем я учу языки программирования

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

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

Во-вторых, яркие, интересные языки программирования строятся вокруг какой-то парадигмы. Для проверки какой-то гипотезы или реализации интересной идеи. Эта идея в языке как бы «подсвечена», ярко сияет, хотя и не всегда объяснима. Иногда идея скучая и неинтересная (или сильно похожа на что-то знакомое), иногда непривычная и головоломная (например, Рефал мне сначала сломал мозг). В последнем случае язык я учу или смотрю, это зависит от богатства идеи. Эти новые идеи позволяют взглянуть на проблему с разных сторон, если посмотреть на одно и тоже невооружённым взглядом и через микроскоп, увидишь очень разную картину, но важны обе.

Недавно я написал, что поставил себе Кобол на Мак, у многих возник вполне закономерный вопрос — зачем?

Тут дело несколько в ином. Я хочу увидеть как всё начиналось, Кобол — один из первых языков с читаемым англоязычным синтаксисом, с революционными идеями, которые теперь кажутся очень странными. Есть и ещё причина. На Коболе до сих написано больше всего кода (по крайней мере в банковской сфере и правительственной), специалисты по Коболу стоят очень дорого (просто потому что их очень мало), и мне показалось забавным увеличить свою стоимость как программиста изучением Кобола. Это не значит, что я хотел бы программировать на этом языке профессионально. Упаси боже.

10 комментариев

Почему не следует расширять встроенные типы JavaScript

На Хабре хорошая статья — «Monkey-Patching, или Расширение Встроенных Типов: религия или осознанный выбор?».

Оставить комментарий

К выходу новой версии «Скайпа»

Скажите, а все те люди, которые установив новую версию, пишут в твиттер «вышел новый скайп, верните старый интерфейс» не догадываются, что можно скачать и поставить предыдущую или что?

35 комментариев

Канадское слоговое письмо (ᓀᐦᐃᔭᐍᐏᐣ)

Случайно наткнулся на канадское слоговое письмо, это письменность, которой пользуются коренные народы Канады.

Оно есть в Юникоде, но не знаю как оно отобразится в вашей операционной системе.

Разработано совсем недавно (1840 год) и устроено очень остроумно. Запись, в основном, идёт слогами, согласная-гласная.

Согласная буква определяется формой, а гласная — поворотом. Например, «ᑭ» — «ки», «ᑫ» — «ке», «ᒥ» — «ми», «ᒣ» — «ме» и так далее. Из знаков пунктуации присутствует только точка («᙮»). Письменность довольно широко используется и в наши дни.

Многих привычных нам букв там нехватает, так что записать мои имя и фамилию очень тяжело, разве что подобрать какие-то эквиваленты: «ᐁᐯᑫᓂ ᓭᑌᐸᓂᓭᑊ» («Епекени Сетепанисев»).

11 комментариев

Как отключить автообновление «Скайпа» пятой версии

Так как многие не могут найти как выключить в «Винде» автообновления Skype 5, вот рецепт ниже.

Надо поместить в реестр следующую информацию (сохранить в файл disableskypeupdate.reg и запустить его):

REGEDIT4 
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Skype\Phone] 
"DisableVersionCheck"=dword:00000001

Либо выполнить из командной строки вот это:

reg add HKLM\SOFTWARE\Policies\Skype\Phone /d DisableVersionCheck /t REG_DWORD /v 1

Должно помочь. В четвёртой версии «Скайпа» есть галочка в настройках для запрета автообновлений. На «Маках» она есть и в пятой версии.

5 комментариев

Как заменить табы, используя sed

Утилита командной строки sed (это потоковый редактор), как-то неочевидно работает с символом табуляции (tab). Выражения «\t», «\x09», «\011» не срабатывают даже в расширенном режиме регулярных выражений (включается флагами „-r“ или „-E“, в зависимости от системы).

Я немного поэксперементировал, оказалось, что sed вполне воспринимает этот символ как таковой, а все «магические выражения» не работают. Поскольку «таб» имеет специальное значение в командной строке, ввести его можно либо через комбинацию Ctrl+V, tab, либо Ctrl+V, Ctrl+I. Во многих шеллах (например, в bash, ksh, sh) сработает специальный синтаксис с долларом, как в примере ниже.

Например, если вам надо заменить последовательные «табы» на один, то это может выглядеть вот так:

sed $'s/\t\t*/\t/g' sample.txt # именно \t\t*, а не \t+

# или

sed -E $'s/\t+/\t/g' sample.txt # в Линуксе ключ „-r“

Если вы знаете как в sed можно работать с tab проще, расскажите, пожалуйста, в комментариях.

7 комментариев

Всякая мелочь одним постом-5

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

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

Leon_sbp67 в своём ЖЖ справедливо критикует известный пропагандистский ролик «путинские сказки».

«Гугл мапс» обновил карты и внимательные пользователи нашли на них какой-то странный объект (и даже не один) в районе Китая. Что это такое, есть идеи?

Звездой интернета, думаю, неожиданно для себя стала некая Любовь Матвеевна за оригинальный подход к воспитанию собственных детей — она спрашивает совета на сайте «Ответы мейл.ру» по очень волнительным поводам. Например: «решила продать кровать дочери, пусть спит на полу» или «хочу за проступки сына наказывать дочь, а за проступки дочери — сына» или «хочу заставить сына ходить на физкультуру не в костюме „Рибок“, а в советском трико». Очень надеюсь, что это кто-то просто развлекается.

Полезное — таблица символов Юникода, все символы в таблице (строится по мере прокрутки), заодно увидете, что поддерживает ваши система и браузер, а что нет.

34 комментария

«Здравствуй, мир» на Коболе

Я как-то проверял сколько занимает минимальная программа на «Гоу», оказалось — 232КБ. Посмотрел как дела с этим у Кобола. «ОупенКобол» скомпилировал мой helloword в девятикилобайтный запускаемый файл, что неплохо — сишный вариант у меня занял всего на килобайт меньше.

Вот так выглядит моя первая программа на Коболе:

000100*Моя первая программа на Коболе
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. hw.
000400 AUTHOR. Evgeny Stepanischev
000500 PROCEDURE DIVISION.
000600      DISPLAY "Привет, мир!".
000700      STOP RUN.

Первые шесть символов каждой строки — её номер, как легко догадаться. В современном Коболе их можно опустить (OpenCobol поддерживает этот синтаксис с ключом «-free»). Дальше идёт специальный символ, один из четырёх, насколько я знаю. Пробел — значит дальше начало новой строки кода, «звёздочка» — комментарий, минус — продолжение предыдущей строки кода (строки не должны быть длинее 80 символов) и «D» — некий «debug», для чего он, я пока не знаю.

В старом Коболе очень жёсткий порядок всего и вся. Мало того, что секции программы должны быть описано в строгом порядке, так ещё и столбец тоже имеет значение! То есть Кобол строго следит за отступами. Например, мой код с DISPLAY и STOP RUN начинается с 12-го символа. Так надо. А c 73 символа до 80-й можно писать что угодно — проигнорируется.

Язык очень многословный и имеет целую тучу зарезервированных слов, некоторые из которых весьма доставляют:

bolk@Bolk ~/Projects/Cobol  $ cobc --list-reserved | wc -l
     530

bolk@Bolk ~/Projects/Cobol  $ cobc --list-reserved | egrep '[[:digit:]]' | egrep -v 'UTF|UCS|FLOAT'
COMP-1				(Y)
COMP-2				(Y)
COMP-3				(Y)
COMP-4				(Y)
COMP-5				(Y)
COMPUTATIONAL-1			(Y)
COMPUTATIONAL-2			(Y)
COMPUTATIONAL-3			(Y)
COMPUTATIONAL-4			(Y)
COMPUTATIONAL-5			(Y)
STANDARD-1			(Y)
STANDARD-2			(Y)
SUB-QUEUE-1			(N)
SUB-QUEUE-2			(N)
SUB-QUEUE-3			(N)

Как я буду учить это всё великолепие, пока не знаю, не уверен, что интерес к языку у меня настолько глубок. Впрочем, может оказаться, что бо́льшая часть из указанных 530 зарезервированных слов нужны в жизни очень редко. А ещё, бегло пробежавшись по документации, я нашёл большое количество синонимов. За примерами далеко ходить не надо, «COMP-N» и «COMPUTATIONAL-N» из вышеприведённого листинга — синонимы.

10 комментариев

«Двести баксов»

Очень не люблю, когда люди указывают цены в долларах. «Я тут продуктов купил на 235 баксов». Сколько это вообще? Как я должен пересчитать? Я вот сейчас специально зашёл на РБК, чтобы посмотреть сколько там курс доллара, в последний раз я его смотрел около года назад, когда в Египет ездили отдыхать с женой.

Я помню времена, когда буквально всё каждый день дорожало на десятки рублей, а свой первый деловой костюм для работы я купил за сто долларов прямо в магазине, то есть в России (это конец девяностых был) брали доллары. О зарплате договаривались только в долларах, иначе через месяц можно было получить ощутимо меньше денег в плане покупательной способности.

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

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

55 комментариев

Археологи будущего о сигаретах

Ритуальное самоубийство (63.68КиБ)

В Таллине, где мы были летом, посещали экскурсию по Бастионным ходам. Там в конце экспозиции показывали каким может стать Таллин в будущем. Один из стендов по этой теме показывал фантазии на тему какие объяснения могли бы дать археологи будущего о вещах, которыми мы пользуемся в наше время.

Антитабачную тему одной из таких фантазий я, конечно же, не смог обойти вниманием и сделал кадр.

22 комментария

Игорь Растеряев

Меня тут спросили какую я музыку слушаю. Я иногда клипы сюда вставляю или слова песен. Это всё то, что мне нравится. Недавно увидел Игоря Растеряева, хорошие слова, гармошка и «клипы», снятые на сотовый телефон. Мне очень нравится, есть за этим какая-то душа, искренность.

Автор слов и музыки — сам Игорь.

12 комментариев

Какой язык программирования изучать на перспективу

Меня тут недавно спросили — какой язык программирования следует изучить на перспективу. Я ответил в том духе, что никаких формальных признаков того, что язык будет перспективен лет через пять, не существует и до сих пор думаю, что прав. В самом деле, если взять «моду» на языки за последние десять лет, видно, что их успех определяется подводными течениями, которые со стороны увидеть трудно, компании неисповедимы, могут «выстрелить» чем-то, что разрабатывали втихую много лет.

Правда потом, по пути домой я задумался над этим более глубоко и теперь считаю, что популярность должны набирать языки, в которых легко, на уровне языка, делается параллелизация. Дома у меня меня ремонт сейчас и где-то в груде вещей лежит компьютер, который я покупал пять лет назад, там стоит чётвёртый «Пентиум» с тремя гигагерцами, а через шесть лет максимальная частота процессоров «Интел» находится на уровне 3,8 гигагерца (может чуть больше, не принципиально).

Над цифрами выше трудятся уже только оверклокеры, заливая штаны жидким азотом. Гонка частот уже, кажется, остановлена, началась гонка за количество ядер. Недавно был выпущен первый смартфон с четырьмя процессорами, а рабочая станция «Мак Про» поставляется в топовой конфигурацией с 12 процессорами. Сегодня на «Хабре» появилась новость о процессоре GA144, который будет продаваться за шестьсот рублей. У него 144 ядра.

Не говоря уже о GPU, у которых количество ядер приближается к тысячам.

Если взять какой-то язык, который легко умеет параллелиться, имеет более-менее привычный большинству (читай «си-подобный») синтаксис, компилятор или интерпретатор которого умеет использовать GPU в нужных местах (сортировки, поиск и прочее), то он может иметь успех со временем.

Причём «легко» не обязательно даже так, как это сделано в «Гоу» (хотя и желательно) — отдельной конструкцией языка (go), нет нужды сводить к этому всю идеологию языка, как в «Эрланге», просто чтобы это делалось, в тривиальных случаях, в одну-две строки, но было гибко управляемым в случае такой потребности. Нужно понижать порог вхождения в многозадачность, к чёрту подробности, в простейших случаях это должно делаться легко и просто, пусть и не особо эффективно.

Например, на «Пайтоне» как-то так:

@fork
def sort(arr):
    arr.sort()
    return arr

 # тут функция начала фоном работать
result = sort(somearray)

… много кода …

# а тут уже доступны результаты, если недоступны, то будем ждать
print([el for el in result if el])

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

Пока, наверное, верится с трудом. Но мой первый Айбиэм-совместимый компьютер имел жёсткий диск на 42 мегабайта, процессор там работал на частоте в пару десятков мегагерц, а памяти было около мегабайта, тогда я бы не поверил, если бы мне кто-то рассказал про терабайты, гигабайты и гигагерцы. Не успеете оглянуться, будем меряться гигаядрами.

9 комментариев

Многозадачность в «Гоу»

В прошлой своей записи я упомянул многозадачность в «Гоу», а сейчас вспомнил, что я ни разу не показывал как же она там выглядит с точки зрения простого программиста. Покажу на примере.

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

package main

import (
    "io"
    "os"
    "crypto/sha512"
    "encoding/hex"
    "runtime"
    "strconv"
)

func main () {
    ch := make(chan string)

    N := 3

    runtime.GOMAXPROCS(N)

    for i := 0; i<N; i++ {
        go func (name string, num int, ch chan string) {
            if f, err := os.OpenFile(name, os.O_RDONLY, 0666); err == nil {
                defer f.Close()
                h := sha512.New()

                io.Copy(h, f)

                ch <- strconv.Itoa(num) + ". " + hex.EncodeToString(h.Sum())
            } else {
                panic("Cannot open file")
            }
        }(os.Args[0], i, ch)
    }

    for ; N > 0; N-- {
        print(<-ch, "\n")
    }
}

Что здесь происходит.

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

Дальше, очевидно, подключаются модули, в языке базовых функций почти нет, поэтому даже для такой небольшой программы мне понадобилось шесть модулей: «io» для копирования данных из одного потока в другой, «os» для работы с файлом, «crypto/sha512» для хеширования, «encoding/hex» для кодирования получившейся хеш-суммы в шестнадцатеричное представление, «runtime» чтобы выставить сколько го-программ будет выполняться параллельно и «strconv» чтобы сконвертировать число в строку.

Функция main — входная точка основного модуля программы, именно она (как в «Си») вызывается в самом начале.

Далее я создаю (make) небуферизированный «канал» и объявляю, что по нему будут идти строки, конструкция «:=» многим напоминает Паскаль, но отношения к нему не имеет, это синтаксический сахар для создания локальной переменной. «Канал» — это хорошее, говорящее название, хорошо отображающее суть, это действительно канал общения го-программы с чем-то извне.

В цикле создаются и сразу запускаются в фоне (конструкцией «go») на выполнение N го-программ, которым передаётся имя файла от которого надо считать хеш, номер функции в цикле и переменная «канала» для общения.

Внутри го-программы открывается файл, он копируется во входной поток хеширующей функции, считается хеш, конвертируется в шестнадцатеричное значение и отправляется (конструкцией «ch <- smth») в «канал».

Цикл не ждёт выполнения го-программы, а просто запускает их в фоне.

Дальше идёт второй цикл, где N раз запускается команда на чтение из канала („… <- ch»).

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

У такой лёгкости использования есть свои ограничения, но об этом как-нибудь в другой раз.

15 комментариев

Первый язык программирования высокого уровня — Планкалкюль ★

Планкалкюль (Plankalkül) — первый в мире язык программирования высокого уровня, разработанный немецким инженером Конрадом Цузе между 1942 и 1946 годами для его компьютера «Z4».

Экспонат в музее: деревянный пульт управления с клавиатурой и панелью приборов, застеклённый, рядом — высокие шкафы с электронными компонентами.
Компьютер «Z4», фото взято из «Википедии»

Шла Вторая Мировая Война, Цузе работал в отрыве от учёных других стран, совершенно самостоятельно. За это время он создал не только язык программирования, но и написал на нём 49 страниц программ для оценки шахматных позиций. Полностью его работа была опубликована много позже, в 1972.

Только в 1957 году (работы были начаты в 1954) появился Фортран — язык, который большинство считает первым языком высокого уровня.

«Z4» был электро-механическим, поэтому компилятора или интерпретатора Планкалкюля не существовало, но в 2000 году в Свободном универсистете Берлина (Freie Universität Berlin) был создан интерпретатор его диалекта (запускается в виде Ява-аплета в браузере).

Диалект, который реализуется, назван Plankalkül-2000 и отличается упрощённой формой записи программ. Например, упрощена форма записи, Цузе использовал двухмерную запись — первой строкой записывалось само выражение, а ниже некоторые его аргументы (тип переменной, индексы и так далее). Кроме того, были упрощены и значки самих операций, приведены к более привычному нам с вами виду.

Язык довольно богатый, на мой взгляд, для сороковых годов-то: есть условные конструкции, два вида циклов (аналог while и for), есть массивы и кортежи, можно описывать и вызывать подпрограммы (но рекурсии нет).

Все переменные делятся на четыре вида.

  • Variablen (Входные переменные) — это входные переменные подпрограмм, доступны только для чтения начинаются с буквы V и номера;
  • Zwischenwert (Значения промежуточные), доступны для чтения и записи, предназначены для хранения промежуточных вычисляемых значения, начинаются с Z и номера;
  • Resultatwerte (Результат) — в этих переменных возвращается результат вычисления, начинаются с R и номера;
  • Indizes (Индексы) — переменные цикла (аналога for), начинаются с i, дальше может быть номер, номер необходим для организации вложенных циклов.

Доступны три типа переменных. Несмотря на то, что «Z4» умел оперировать числами с плавающей точкой, интерпретатор этого не умеет.

Для целого неотрицательного указывается размерность в битах. Есть две формы записи 0 — один бит, n.0 — «n» бит, например, 8.0 — один байт (8 бит). Кортеж указывается в скобках, например (3.0, 4.0) — это две переменные в три и четыре бита, кортеж должен иметь более одного элемента. Массив записывается через точку, к примеру: 4.5.0 — массив из четырёх элементов по пять бит в каждом, 32.(0, 8.0, 16.0) — 32 кортежа, в каждом из которых три переменных: один бит, восемь и шестнадцать.

«Планкалкюль» явно можно сильно упростить по синтаксису, но современный диалект почти в точности копирует ту запись, которую использовал Цузе, я полагаю, что такой синтаксис родился из-за необходимости «отлаживать» программу на бумаге. Впрочем, язык настолько прост, что я его выучил целиком минут за 15 и даже написал на нём парочку программ в нескольких вариантах.

Одна из них вычисляет указанное (по порядку) число Фибоначчи:

P0 FactEvgenyStepanischev (V0[:4.0]) => (R0[:10.0])
(0, 1) => (Z0[:10.0], Z1[:10.0])

W1 (V0[:4.0]) [
    i > 0 -> (Z0[:10.0] + Z1[:10.0], Z1[:10.0] - Z0[:10.0]) => (Z1[:10.0], Z0[:10.0])
]

Z1[:10.0] => R0[:10.0]

END

Запускать следует так: открываете страницу с интерпретатором, копируете в окно мою программу, нажимаете «Compile», открывается отдельное окно с Ява-аплетом (требует, чтобы на компьютере была установлена Ява), в открывшемся окне мышкой побитно набираете начальное значение V0 (нажимать надо на зелёные кружки́), потом в окне браузера нажимаете «Run», в красной строчке (R0) увидите получившееся значение.

Скриншот интерфейса «Plan P0» с рядами зелёных, синих и красных фигур (круги, ромбы) и цифрами 13, 253, 233.
Запущенная программа на Планкалкюле

Подпрограммы в языке начинаются с символа P и уникального номера, дальше идёт имя, по которому её можно будет вызвать, у меня подпрограмма называется FactEvgenyStepanischev, заканчивается подпрограмма ключевым словом END (в оригинальном Планкалкюле его не было).

У подпрограммы описываются принимаемые и возвращаемые значения, у меня используется одна переменная на вход, размерностью 4 бита и одна на выход, размерность в 10. Первой строкой присваиваются значения «ноль» и «один» промежуточным переменным Z0 и Z1. Тип переменных приходится указывать при каждом их использовании, преобразовать переменную в другой тип нельзя.

Ниже идёт цикл for (W1), поскольку номер переменной цикла я не указал (указывается в первых квадратных скобках, которые тут опущены), используется переменная цикла i, без номера. В круглых скобках указывается количество повторений, а в последующих квадратных — тело цикла. Подробности можно найти в описании.

Операция «стрелка» (->) — условная конструкция, часть справа будет выполнена, если выражение слева истинно. В диалекте работают только самые простые выражения, например цикл туда подставить можно, но кнопка «Run» в аплете у меня не появилась, поэтому я ограничился присваиванием внутри цикла.

Я тут использовал комплексное присваивание, которое хорошо знакомо тем, кто использует Перл, Пайтон или ПХП, но работает оно иначе — присваивания выполняются последовательно, слева направо, поэтому я не могу ограничиться,

(Z0[:10.0] + Z1[:10.0], Z1[:10.0]) => (Z1[:10.0], Z0[:10.0])

результат будет не тот, который ожидается.

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

Кроме этого в языке почти ничего и нет. Обращение к элементам массива, вызов функции и цикл while описывать отдельно смысла не имеет, они выглядят достаточно естественно в рамках этого синтаксиса. Все операции, поддерживаемые языком (их немного — логические операции, битовые операции и четыре арифметические действия) выглядят привычно.

3 комментария

Всякая мелочь одним постом-6

Интересное видео — что будет с пиявкой если её поместить в воду, оставшуюся от кальяна. Задумайтесь, чем дышат курящие кальян.

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

Другое видео — диктор «РенТВ», читая текст про Барака Обаму, показывает в эфире средний палец. Что это было?

Для желающих понастальгировать девятого декабря выходит ремейк знаменитой игры для «Спектрума», главным героем которой является Диззи. Это ремейк шестой части, которая называется «Dizzy. Prince of The YolkFolk», игра будет выпущена под «Андроид», «Айпад» и «Айфон». Я куплю.

«Старое радио» — уникальный проект по оцифровке старых передач, аудиоплёнок и пластинок. В ЖЖ «Оттенки серого» великолепный рассказ об авторе этого проекта.

Будущее (а может уже и прошлое, кто знает) шпионажа — использование датчиков смартфона, лежащего рядом с ноутбуком или клавиатурой компьютера, для угадывания что печатает пользователь. Для английских фраз вероятность правильного распознавания с использованием только гироскопа и акселерометра (без микрофона, который может улучшить картину) — 80%.

52 комментария

С Днём рождения, жена!

Подарок (44.34КиБ)

Любимая жена, поздравляю тебя с Днём рождения! Главное — вот этот замечательный букет, который я сфотографировал, а под ним лежит незначительный, небольшой подарок, но надеюсь он тебе понравится!

5 комментариев

Инте̲рне̲т

Сегодня впервые на встрече услышал как слово «интернет» произнесли через два «е». Насколько я знаю, считается, что из слов исчезает «э» (там где в написании стоит «е»), когда слово уже прочно вошло в язык. Возможно, человек, использовавший там «е» произностит «интернет» нарочито так, чтобы продемонстрировать — он считает, что слово уже «обрусело».

Я не знаю, существует ли в реальности такая тенденция (с буквами «э» и «е»), но если и существует, то, мне кажется, она исчезает. Я нередко сталкивался с тем, что слова «тест», «секс», «энергия», «бактерия» и прочие некоторые люди старшего поколения произносят через «е», тогда как в моём поколении и младше я вообще не наблюдаю использование такого произношения, там исключительно «э».

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

19 комментариев

← сюда туда →