Американские логотипы в ОАЭ

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

Я, конечно, понимаю — меня куча айтишников читает, людей, которым кажется, что все вокруг знают или должны знать английский язык. Кстати, айтишники — это те же люди, 90% которых, сталкиваясь каждый день со словами «procedure», «hotkeys» и «character», не в состоянии правильно их прочитать.

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

Фасад здания Starbucks с вывеской на арабском и английском языках, зелёным логотипом и рекламным баннером справа; видны вход, окна, зонты и автомобили на переднем плане.
Заправка ADNOC Oasis с рестораном Subway, белая машина на переднем плане, скалистый склон на заднем плане.
Улица с движущимися автомобилями и зданиями, включая красное здание с арабской надписью на вывеске.
Фасад ресторана KFC с красной вывеской, на которой изображён полковник Сандерс и арабская надпись «KFC
Вход в ресторан McDonald's с вывеской на английском и арабском языках, меню на экранах и посетители у кассы

Смотрите, «Старбакс», «Сабвей», «Пицца Хат», «КФЦ», «МакДональдс» перевели свои названия на арабский и никому это странным не кажется. У нас же, после 90-х, когда на рынке была тьма-тьмущая всяких непереведённых «сникерсов» люди считают, логотипы и названия локализовывать не нужно.

Кстати, я знаю девушку, которая многие годы в магазинах спрашивала «Зуп» («7up») и её понимали.

С наступившим Новым годом вас!

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

День зависимости от интернета

С 29-го декабря по утро шестрого января, пока мы были с женой в ОАЭ, провёл без интернета. Ни одного сайта, твита, сообщения в аське или скайпе, почтового сообщения, ничего. Никакой необычайной тяги, например, проверить почту, за этот срок не ощутил. Было немного неудобно — ни погоду посмотреть, ни прочитать что-нибудь об Эмиратах, а так, в целом, никакой «зависимости от интернета» у себя не почувствовал.

Правда, по приезде ощутил неудобство: пришлось просмотреть тонну почты, пролистать кучу статей на «Хабре», прочитать накопившуюся РСС-ленту — профессия обязывает быть в курсе определённых вещей.

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

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

На сайте «Антропогенез» — разбор ошибок в лекции «Оценка теории эволюции» богослова Алексея Ильича Осипова на канале «Культура» (шла 26 апреля 2012 года). Очень интересный обзор, я прояснил для себя массу мутных моментов.

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

В ЖЖ «Планетарум» статья, показавшаяся мне несколько несвязаной, но очень интересной об ошибках соединения, персонально для меня интересно, что я ошибки в тестах из статьи не совершил, а кроме того, в статье есть хорошее объяснение парадокса Монти Холла, почитайте.

Некоторые врачи совсем офонарели — в качестве лечения назначают гомеопатию, рассказ от одного жижиста, жене и сыну которого назначили «Оциллококцинум».

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

Финализированные конструкторы под разными именами

Вчера вечером подумалось, что если в PHP сделать следующее, будет ошибка или нет:

class A {
    final public function a() {
        echo 1;
    }
}

class B extends A {
    public function b() {
        echo 2;
    }
}

$o = new B();

Интересно тут то, что не сразу видно в чём вообще загвоздка. Ну или я бы увидел не сразу, думаю, если бы сам этот пример не придумал. Кажется, все уже отвыкли в PHP от «старых» конструкторов, где конструктором считается метод, имя которого совпадает с именем класса (если нет метода «__construct»).

От осознания этого факта дополнительно отвлекают ничего незначащие имена классов и методов.

Проблема же в том, что в первом классе конструктор финализирован, его дальше переопределять нельзя. Но у второго класса имя конструктора другое. Вот и вопрос — что будет? От PHP можно чего угодно ожидать.

Тем не менее, тут язык выдаст логичную ошибку, которая, правда, способна вызвать лёгкое недоумение своей формулировкой:

Fatal error: Cannot override final A::a() with B::b() in test.php on line 12

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

Список доменов, запрещённых к регистрации в зоне «.рф»

Оказывается существует список доменов, которые запрещено регистрировать в зоне «.рф». Полюбопытствуйте, расширьте свой словарный запас! Старательные люди собирали, там более четырёх тысяч доменов. Например, «взятьзамягкоеместо.рф» или «похабник.рф».

Вот вам ругающийся однострочник на «баше», чтобы учить каждый день новое слово:

curl -so- http://flisti.ru/stop-list.txt |
iconv -f cp1251 | awk -F'[\t\.]' 'BEGIN {srand()} $3 {print rand(), $3}' |
sort -n | awk '{print $2; exit}' | tee >(cut -c1 | tr '[:lower:]' '[:upper:]') |
sed -n '1s/^.//;1h;2p;2g;2p' | tr -d '\n' ; echo '!'

Или можно так:

curl -so- http://flisti.ru/stop-list.txt | iconv -f cp1251 |
awk 'BEGIN {srand()} {print rand()"."$2}' |
sort -nt. | head -1 | cut -f2 -d. |
tee >(cut -c1 | tr '[:lower:]' '[:upper:]') | tail -r | tr -d '\n' | xargs -I? echo ?! | cut -c1,3-

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

curl -so- http://flisti.ru/stop-list.txt |
iconv -f cp1251 | awk -F'[\t\.]' 'BEGIN {srand()} $3 {print rand(), $3}' |
sort -n | awk '{print $2"!"; exit}'

Вариант для «баша», но без awk:

curl -so- http://flisti.ru/stop-list.txt |
iconv -f cp1251 | grep -Eo '\s.+рф' | cat -b |
tee >(echo $((`wc -l`*$RANDOM/32768))) | tail -r |
grep -w `head -1` | cut -f3 | cut -d. -f1 | xargs -I? echo ?!

Почему-то мне нравится программировать на «баше», остановиться не могу…

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

Алгоритм линейного счётчика: десять бит в одном бите

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

Упомянул его в разговоре знакомый математик К.Н., за что ему большое спасибо! По этому алгоритму нашлась замечательная статья «Линейный счётчик», с понятным объяснением, добавить к которому нечего, но я всё-таки приведу у себя его краткое описание.

Сначала для чего алгоритм применяется и чем он замечателен.

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

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

Но есть способ лучше! Алгоритм линейного счётчика.

Оказывается, если взять вектор в 1000 бит и 1000 раз установливать в нём в единицу случайный (с равномерным распределением) бит (некоторые биты будут установлены в единицу несколько раз), то нулей останется примерно около 370. Эта оценка получается из 1/e ≈ 0,36787944117… ≈ 0,37, подробнее есть в другой статье на том же сайте.

Таким образом, если мы встречаем битовый вектор длины n, в котором примерно 63% (100 − 0,37 × 100 = 63) единиц, то над этим вектором было произведено n операций установки бита в единицу, при условии, что биты выбирались случайно и равномерно.

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

Демо алгоритма линейного счётчика (10.68КиБ)

Хорошо это работает только на больших числах, я для наглядности сделал небольшое демо работы алгоритма линейного счётчика, там пятьдесят входных значений и вектор размером в 30 бит. Так как чисел немного, то и результаты иногда скачут сильно, но на миллионах значений погрешность выравнивается.

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

Алгоритм линейного счётчика на Google Go (golang)

Не смог отказать себе в удовольствии и попрактиковаться в «Гоу», написал и выложил на Гитхаб реализацию алгоритма линейного счётчика на Гугл Гоу. Значения, которые надо подсчитать поступают на стандартный вход, есть один параметр командной строки — «size», позволяющий задать размер вектора в битах (по-умолчанию — 10000).

Подсчёт 1 000 000 значений (8.81КиБ)

Подсчёт на моём ноуте одного миллиона уникальных значений занимает примерно 6,5 секунд. Погрешность с вектором длиной 100 тысяч бит (≈3КиБ) — 7,6%.

Чтобы скомпилировать программу новым (версии 1 и выше) компилятором «Гоу», нужно запустить следующую команду:

go build linear-counter.go

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

&^ в Google Go

Отличная иллюстрация того как важны мелочи в документации…

Читал чужой исходный код на «Гоу» и обнаружил необычную конструкцию:

v &^= 1 >> n

Почесал голову, не понял что это и пошёл читать документацию. Выяснилось, что эту конструкцию я когда-то упустил при чтении документации и означает она «bit clear (and not)», то есть является противополжностью „|=“, не ставит бит, а очищает его. Более того, есть ещё унарная операция «^», которая инвертирует все биты в числе (соблюдая размер его типа), вот как они работают:

package main

func main() {
    var test byte = 250

    println(test) // 250 (11111010)
    
    test = ^test
    println(test) // 5 (00000101)

    test &^= 4   //    (00000100)
    println(test) // 1 (00000001)
}

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

Главное, что сало не пропало!

А вы знали чем колыбельная про «серенького волчка» кончается в оригинале?

Баю-баюшки баю, Не ложися на краю — Придет серенький волчок И ухватит за бочок. И утащит во лесок. Закопает во песок. Только ноженки торчат, Волки зубочки точат. Сверху солнце печет, С (подставьте имя своего ребенка) сало течет! Люди едут, да глядят, Хлеб макают, да едят.

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

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

Мне бабушки и мама пели только первые четыре строки, за что им большое спасибо, конечно!

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

Неразборчиво в ОБД «Мемориал»

Я думал, что в ОБД «Мемориал» записаны данные только тех карточек, данные которых удалось разобрать достоверно. Случайно выяснил, что очень много данных с пропусками.

Результат запуска (24.33КиБ)

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

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

Как халляр?

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

Поэтому в разговоре часто проскакивают «автобус», «чемодан», числительные и что угодно ещё.

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

В общем, приезжие веселятся.

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

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

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

Сокращение ссылок через bit.ly из bash

На «Макрадаре» появилась статья про сокращение ссылок через bit.ly через «Автоматор», хорошая штука, иногда бывает нужно, когда кривой парсер какого-нибудь сайта не принимает какую-то ссылку, но сам скрипт (в примере «Автоматор» запускает его через «баш») мне не понравился.

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

Вот мой вариант:

TOKEN=<ваш токен, полученный по инструкции выше>
URL="$1"

[[ "$URL" =~ ^https?:// ]] || URL="http://$URL"

path="${URL#*//*/}"
host="${URL:0:${#URL}-${#path}}"
path=$(echo -n "$path" | hexdump -ve '1/1 "x%02X"' | tr x %)

curl 'https://api-ssl.bitly.com/v3/shorten' \
     --data "access_token=$TOKEN" \
     --data 'format=txt' \
     --data "longUrl=$host$path"

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

Толока

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

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

С самом деле, это же хорошо — возрождать забытые слова в обновлённых значениях.

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

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

форма деревенской взаимопомощи в России, Украине и Белоруссии. Толока является давней славянской традицией. Её организовывали в деревне для выполнения срочных работ, требующих большого количества лиц: сбор урожая, вырубка леса, сооружение домов и т. д. Иногда толоку использовали для проведения общественных работ (строительство церквей, школ, дорог и т. п.).

В толоке односельчане работали сообща, вместе, добровольно и бесплатно.

Ну что, заменим «краудсорсинг» толокой?

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

ASCII art vs. Unicode art

С приходом цветного Юникода некоторые символы могут присутствовать в системе в так называемом «стиле эмодзи», проще говоря в цвете.

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

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

Забегая вперёд, картинка того что вышло из этой затеи — ниже. Cправа — исходник картинки, слева — Юникод, то есть, каждый пиксель этой картинки — один цветной символ Юникода, написанный (или тут надо уже говорить «нарисованный») шрифтом размером 1px.

Что получилось (14.70КиБ)

Для начала я выяснил, что единственный браузер на «Маке», который показывает эти символы в цвете, это «Сафари», остальные показывают в лучшем случае в ч/б («Файрфокс», «Хром»), в худшем показывают какие-то обрывки («Опера»).

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

Карта цветов (11.91КиБ)

На «баше» (ну да, я извращенец, но так просто быстрее было) накидал небольшую программу, который из этой картинки генерирует текстовый файл, состоящий из номера символа по порядку и значения цвета в формате #rrggbb:

#!/bin/bash
FILE='color-map.png'

wh=(`file $FILE | grep -oE '\S+ x [0-9]+'`)

function ColorAt {
    convert $1[1x1+$2+$3] txt: | grep -oE '#[0-9A-F]{6}'
}

for (( y=0; y<${wh[2]}; y+=5 )); do
    for (( x=0; x<${wh[0]}; x+=5 )); do
        pos=$(( $x/5 + $y*${wh[0]}/25 ))

        echo "$pos $(ColorAt $FILE $x $y)"
    done
done

Утилита convert, которая используется в скрипте, это часть пакета ImageMagick.

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

$cached = [];

for ($y = 0; $y<$h; $y++) {
    for ($x = 0; $x<$w; $x++) {
        $cnum = imagecolorat($im, $x, $y);

        if (isset($cached[$cnum])) {
            $outchar = $cached[$cnum];
        } else {
            $mindiff = $outchar = INF;

            $c = imagecolorsforindex($im, $cnum);
            foreach ($colors as $colorandch) {
                list($ch, $r, $g, $b, $ch) = $colorandch;

                $diff = abs($r - $c['red']) + abs($g - $c['green']) + abs($b - $c['blue']);

                if ($diff < $mindiff) {
                    $mindiff = $diff;
                    $outchar = $ch;
                }
            }
            $cached[$cnum] = $outchar;
        }
        echo '<b>', $outchar, '</b>';
    }
}

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

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

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

Кутузов: смотри в оба!

Кутузов в фильме 1944 года (71.57КиБ)

Как вы себе Михаил Илларионович Кутузова представляете? Того, который полководец? Такой в мундире и с повязкой на глазу, не так ли? Я тоже примерно так себе его и представлял, пока не решил выяснить при каких обстоятельствах Кутузов потерял глаз.

Так вот оказалось, что Кутузов глаз не терял и повязку не носил:

23 июля 1774 года в сражении у деревни Шума севернее Алушты трёхтысячный русский отряд разгромил главные силы турецкого десанта. Кутузов, командовавший гренадерским батальоном Московского легиона, был тяжело ранен пулей, пробившей левый висок и вышедшей у правого глаза, который «искосило», но зрение сохранилось, вопреки расхожему мнению.

Повязка на глаз у Кутузова впервые появилась в фильме 1943 года (в цитируемом источнике год указан неверно), который так и назывался «Кутузов»:

В начале XIX в. носить повязку на глазу после заживления раны было не принято (даже если глаз совсем отсутствовал). Впервые же «одноглазый» Кутузов появился в 1944 г. в художественном фильме «Кутузов». Затем повязку на правый глаз Кутузова надели режиссеры-постановщики музыкального фильма-комедии «Гусарская баллада» (1962 г.) и одноименных спектакля (1964 г.) и балета (1979 г.).

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

С тех пор образ одноглазого Кутузова стал настолько привычен, что повязка стала его «торговой маркой», стоит увидеть изображение кого-то в мундире с наградами и повязкой на глазу, так сразу приходит мысль, что это Михаил Илларионович.

Нашлось и объяснения для чего режисёру фильма о Кутузове понадобилась повязка: после ранения глаз полководца заметно косил, но в 1943 году контактных линз не было и, чтобы приблизиться к исторической правде, глаз решили просто закрыть повязкой.

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

Алёнка Александровна Геринас

Алёнка в «Здоровье» (154.50КиБ)

Я тут пропустил смешную историю.

Приглядитесь к обложке журнала «Здоровье», это первый выпуск за 1962 год (снимок взят с «Яндекс.Фоток» у некой Наташеньки). Снимок сделал в 1960 году фотокорреспондент Александр Геринас, сфотографировал свою восьмесячную дочку Лену (кстати, Лен часто зовут Алёнами).

Снимок этот сначала напечатали в журнале «Советское фото», а позже появился на обложке журнала «Здоровье». Интересно, что платок на снимке завязан «обратным» узлом, мама Лены была левшой.

Фабрика «Красный Октябрь», выпускавшая шоколад «Алёнка», в 1966 году объявила конкурс на фотографию девочки, которая должна стать, как сейчас принято говорить, «лицом» шоколада. Победила фотография Александра Геринаса, которую художник Михаил Георгович Маслов перерисовал на обёртку шоколада, изменив цвет глаз и черты лица.

Помимо «Красного Октября», шоколад «Алёнка» выпускало в СССР ещё несколько фабрик, например, Кондитерская фабрика им. Н.К. Крупской, выпустившая свою «Алёнку» в 1964 году, на год раньше «Октября».

Рухнул Советский Союз и кто успел, тот и съел, «Красный Октябрь» первым зарегистрировал права на «Алёнку» в 1999-м, заставив фабрику Крупской выплатить штраф и переименовать свой шоколад в «Крупскую Алёнку», а потом ещё и убрать с его обёртки девочку в платке.

Далее «Октябрь» прошёлся и по другим брендам, конкурентов-то много — «Алина», «Оленка», «Алёна», «Моя Оленка», «Анёла» (sic!), «Любимая Алёнка» и прочие, где название хоть как-то похоже на «Алёнку» с рисунком девочки в платке, побеждая в суде, так как:

Этикетка сходна до степени смешения с упаковкой шоколадки «Аленка», которую производит столичная фабрика «Красный Октябрь»

Вернёмся к Елене Александровне Геринас. В 2000-м году она решила, что фабрика «Красный Октябрь» должна ей пять миллионов рублей, за использование её перерисованной фотографии. И тут… суд иск отклонил, посчитав, что это отдельное произведение, а не перерисованная фотография.

Любопытно получается. Потребители такие тупые, что девочку в платочке на шоколадке «Алина» путают с девочкой на «Алёнке», а практически идентичные фотография и рисунок (причём на рисунке сохранился тот же «обратный» узел) — разные произведения.

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

Сам себя не похвалишь…

Панасоник сам себя похвалил (53.43КиБ)

«Панасоник» сам своим батарейкам выдал бронзовую медаль. Правда, скромно как-то, всего лишь третье место.

Кстати, вы знали, что я самый крутой чувак в мире?*

*По результатам внутреннего тестирования, конечно!

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

Поиск пропусков в таблице

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

SELECT id FROM (
    SELECT id, id-@prev AS diff, @prev:=id
    FROM
        (SELECT @prev:=NULL) ``,
        sourceofdata
   ORDER BY id
) `` WHERE diff>1

Внутри есть напрасный запрос «SELECT @prev:=NULL», который там только затем, чтобы решение получилось в одну строку.

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

Может кто-то придумать проще? Не важно для какой СУБД.

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

Головоломка для верстальщика: CSS не видно, картинка спрятана

Хотите голову поломать? Вот вам тест на знание всякого странного, откройте следующий урл в «Опере»: /files/opera-mystery/ (именно в «Опере») и попробуйте догадаться как это сделано.

Ответ завтра. Кажется, во всём интернете так ещё никто не делал.

Загадка (25.18КиБ)

Выше снимок того что вы должны увидеть на экране, я испытывал под «Оперой» последней версии (12.12) для «Мака», не факт, что под другими ОС всё так же будет.

Вот что видно в консоли, если попытаться скачать этот файл:

bolk@Bolk ~$ wget -O- --user-agent="Opera/9.80 (Macintosh; Intel Mac OS X 10.8.2) Presto/2.12.388 Version/12.12" /files/opera-mystery/
--2013-01-22 00:24:09--  /files/opera-mystery/
Resolving bolknote.ru... 91.230.61.15
Connecting to bolknote.ru|91.230.61.15|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 0 [text/html]
Saving to: ‘STDOUT’

    [ <=>                                                                                                                                                   ] 0           --.-K/s   in 0s      

2013-01-22 00:24:09 (0.00 B/s) - written to stdout [0/0]

Когда догадаетесь где тело страницы, переходите на уровень два — догадайтесь откуда берётся картинка.

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

Отгадка: CSS не видно, картинка спрятана

«Уровень один» вчерашней головоломки прошли многие, этот ларчик открывается просто — есть RFC 5988, где описан способ подключать некоторые ресурсы через HTTP-заголовок. Этот RFC поддерживают «Опера» и «Файерфокс». На скриншоте, в средстве для разработчиков «Оперы» заголовок хорошо видно.

Где спряталось содержимое (20.32КиБ)

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

Теперь главное. А картинка-то откуда взялась?

Есть такой стааааренький формат графики XMB, тестовый формат и по виду явно происходит от заголовочных файлов Си. Про него и не помнит уже никто, важно же в нём то, что когда-то его поддерживали все браузеры. Я даже когда-то библиотеку Image_XBM писал для работы с ним из ПХП.

Вот начало одного из файлов, содержащих картинку в формате XBM:

#define _width 300
#define _height 225
static char _bits[] = {
0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0xde, 0x7b, 0xef,
0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0x0e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00…
}

Он тут, кстати, попроще, чем обычно используется, я выкинул название картинки, которое идёт перед подчёркиваниями. Браузеры, видимо, проще относятся к этому формату, работает и так.

У формата тяжёлая судьба, сначала его похоронил «Эксплорер», убрав в версии 6.0SP1 его поддержку из-за ошибки в кодеке, потом «Файрфокс» выбросил его за ненабодностью, а в «Хроме» его не было с рождения. Остался он только в «Сафари» и в «Опере».

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

Вот часть CSS из вчерашнего примера:

  background: 20px 20px url(bolk.css#0x5F0xBF0xFF0xDC0x530xF60x870…) no-repeat;
  width: 80px; /*_width 80px*/
  height: 80px; /*_height 80px*/
  border: 7px dashed #259;
  outline: #259 dashed 6px;
  margin: 10px; padding: 3px;
}

Читатели правильно догадались, что после хеша в свойстве «background» записана картинка, но как она оттуда попадает в HTML не догадался никто.

В гонке выкидывания лишнего из картинки в формате XBM победила «Опера», ей нужно было только оставить первую строку «#define», которую она использует в качестве «магического» значения для определения формата, где-то раскидать «_width» и «_height» (я их засунул в коментарии CSS) и оставить строку шестнадцатеричных чисел, причём, как оказалось, «Опере» и запятые не нужны!

Итак, откуда взялась картинка?

«Опера» смотрит в свойство «background» и видит там урл с картинкой, часть с хешем просто отбрасывается, в данном случае она не используется и браузер грузит картинку с адреса «bolk.css». «Опера» пытается определить в каком формате пришла картинка, тут нам помогает «магическая» строка «#define», раз она есть, стало быть это XBM.

Дальше браузер ищет в полученном файле «_width» и «_height» с цифрами и находит, считая цифры размерами картинки, после чего ищет первое вхождение «0x…» и двигается по ним, пока не находит их все, это и есть тело картинки, которую надо отобразить.

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

Получение случайного числа 0…255 в bash

Понадобилось получить случайное число в шеле из устройства /dev/urandom, написал небольшую функцию, сохраню у себя, чтобы не потерялась.

getrand() {
    head -c1 /dev/urandom | hexdump -d | sed -E '1!d;s/.+ +0+//'
}

Ещё вариант придумался (но необходим openssl):

getrand() {
    openssl rand 1 -hex | xargs -I. printf "%d" 0x.
}

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

Бу: ООП в bash

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

Долго мучался с названием, решил, что пусть пока называется «Бу» (b-oo.sh), выложил туда же пример на котором вчера тестировал:

#!/bin/bash
# Evgeny.Stepanischev Jan 2013 /

. b-oo.sh

@Class Base
    @Dim cnt

    @Dim
    __construct() {
        This[cnt]=0
    }

    @Dim
    IncCnt() {
        let 'This[cnt]++'
    }

    @Dim
    GetCnt() {
        [ "$This[cnt]" -gt 1 ] && s=s
        echo $Self said $This[cnt] time$s
    }
@End

@Class Dog Base
    @Dim
    say() {
        $This.IncCnt
        echo 'Bow-wow!'
    }
@End

@Class Car Base
    @Dim
    say() {
        $This.IncCnt
        echo 'Beep'
    }
@End

@Class Proxy
    @Dim obj

    @Dim Static
    getInstance() {
        $1.New Self[obj]
        @Ret $2 $Self[obj]
    }
@End


Proxy.getInstance Car car # создание через «фабрику», через статический метод
Proxy.getInstance Dog dog # создание через «фабрику», через статический метод

$car.say
$car.say
$car.GetCnt # 2, вызывается из родительского класса 

$dog.say
$dog.GetCnt # 1, вызывается из родительского класса

Dog.New anothedog # создание через конструктор

$anothedog.say
$anothedog.say

$anothedog.GetCnt # 2, вызывается из родительского класса

Я не стал заморачиваться с модификаторами доступа (хотя может ещё и сделаю), из реализованного: создание объектов, наследование (есть множественное), статические и динамические методы и свойства, конструктор, есть переменная This (текущий объект), Self (текущий класс) и Parent (чтобы вызывать родительские методы).

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

Во-первых, «@Dim», определящий свойства должен находиться на той же строке, что и имя свойства, а в случае метода имя метода должно быть записано на следующей строке (смотрите пример).

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

# !неправильно
obj=$(Dog.New)
obj=`Dog.New`

Чтобы выполнить Dog.New интерпретатор создаёт отдельный процесс, где всё и выполняется, после выхода из этого процесса всё моё колдунство исчезает и от переданного значения толку нет (если у вас не «баш 4», тогда есть способы).

Поэтому конструктор у меня принимает первым параметром имя переменной, куда нужно положить экземпляр класса, а облегчения жизни программисту сделана специальная команда «@Ret», посмотрите как она используется в методе getInstance.

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

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

POSTQUEL

POSTQUEL — это язык запросов, который когда-то поддерживала СУБД «Постгрес». Наверняка многие задумывались почему языков программирования так много, а языков в базах данных, кроме SQL и его диалектов, не видать; SQL оказался исключительно удачным, но у него были когда-то и соперники. «Постквел» один из них.

POSTQUEL расшифровывается как «POSTgres QUEry Language», «язык запросов Постгреса», он был разработам в 1985 году в Калифорнийском университете в Беркли под руководством Майкла Стоунбрейкера, POSTQUEL основан на языке запросов QUEL, который использовался на тот момент в БД «Ингрес».

Примеры того на что был похож POSTQUEL есть в польской Википедии:

Получить размер заработной платы сотрудника Ковальски (pracownicy — сотрудники, płace — зарплата):

retrieve (PRACOWNICY.placa) from PRACOWNICY where PRACOWNICY.nazwisko = "Kowalski"

Все сотрудники старше 40 лет (wiek — возраст, nazwisko — имя):

retrieve (P.nazwisko) from P in PRACOWNICY where P.wiek > 40

Найти все департаменты, целиком занимающие один этаж (pietro — этаж, dnazwa — сокращение от «название департамента»):

retrieve (DEPART.dnazwa)
where DEPART.pietro NOT-IN {D.pietro from D in DEPART where D.dnazwa != DEPART.dnazwa}

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

Добавлено позднее. Я обнаружил документацию 1992 года на «Постгрес», где довольно подробно упоминается и «Постквел» (ссылка есть в комментариях). Интересный язык-то был!

Например, оперировал он объектами, поддерживал наследование (все примеры из упомянутой документации):

create STUD_EMP (location = point) inherits (EMP)

Поддерживал массивы (индексы начинаются с единицы):

create SAL_EMP (name = char[], pay_by_quarter = int4[4])

append SAL_EMP (name = "bill", pay_by_quarter="{10000, 10000, 10000, 10000}")

retrieve (SAL_EMP.name) where SAL_EMP.pay_by_quarter[1] !=SAL_EMP.pay_by_quarter[2]

Поддерживал историю, вот, например, срез данных с первого января 1970 по наши дни:

retrieve (E.salary)
    from E in EMP["Jan 1 00:00:00 1970 GMT", "now"]
    where E.name = "Sam"

Была возможность создавать пользовательские типы (тут создаётся новый тип массива):

define type int_array
    (element = int4, internallength = variable,
    input = array_in, output = array_out)

Так же как и пользовательские функции:

define function eq_area_circle
    (language = "c", returntype = bool)
    arg is (circle, circle)
    as "/usr/postgres/tutorial/circle.o"

define function manager
    (language = "postquel", returntype = EMP)
    arg is (EMP)
    as "retrieve (E.all) from E in EMP
    where E.name = DEPT.manager
    and DEPT.name = $1.dept"

retrieve (EMP.name)
    where name(manager(EMP)) = "Joe"

Была даже перегрузка операторов!

define operator =
    (arg1 = circle, arg2 = circle,
    procedure = eq_area_circle)

И так далее.

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

InnoDB full-text search

Хорошие новости, оказывается, с версии 5.6.4 MySQL поддерживает полнотекстовые поиск в InnoDB (12 лет прошло с момента появления этого движка в Майэскюэле) и, кстати, в версии 5.5 и выше по-умолчанию для создания таблиц выбирается именно InnoDB.

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

Шах и мат, курильщики!

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

Начиная с 2013 года, на пачках появятся еще и картинки рака легких, ампутации, пародонтоза и других заболеваний, которые вызывает курение. Чтобы читали, смотрели и задумывались! Обновленные сигаретные пачки появятся на прилавках российских магазинов в уже мае. А через месяц сигареты вообще уберут с витрин. Останется лишь их перечень с указанием цены.

В России вводятся серьезные ограничения на курение. И в первую очередь во всех общественных местах. Например, в госучреждениях, на детских площадках, в лифтах и на лестничных клетках в подъездах домов. А с 1 июля 2014 года еще и на вокзалах, в зданиях аэропортов, в поездах дальнего следования и на кораблях, а также в больницах, гостиницах, в санаториях, в ресторанах и кафе. При этом создание «курилок» внутри помещений также запрещается, за исключением офисов и заводов, где вопрос «курить или не курить» остается на усмотрение руководителей.

С сайта Первого канала новость.

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

Как я джинсы на getwear.com заказывал

Мне давно хотелось попробовать заказать джинсы на сайте «Гетвеа», об этом бизнесе я был наслышан на конференции айтишников «404» и от Ильи Бирмана — в бюро Артёма Горбунова, где он работает, делали им сайт и он сам заказывал у них джинсы. Остался полностью доволен. Впрочем, о чём это я. Наверное, далеко не все знают о каком сайте я говорю.

Гетвейе (110.31КиБ)

«Гетвеа» (или Getwear, если вам почему-то ближе латиница) — сайт, где можно заказать джинсы, которые сошьют вам по мерке. Не можете найти джинсы на себя? Ненавидите ходить по магазинам? Хочется чтобы джинсы сидели, как влитые… Вот о последнем поподробнее и сначала.

Мои джинсы (143.48КиБ)

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

Можно ли, не трогая джинсы, не примеряя их, выбрать себе их так, чтобы потом было приятно носить? Вот в чём вопрос. Вроде как, снятые по мерке джинсы, должны сидеть идеально… Итак, у меня есть купон на три с лишним тысячи рублей и желание ответить на этот вопрос.

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

Мастер создания джинсы (63.43КиБ)

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

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

Всё понятно (64.28КиБ)

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

С остальным я справился без проблем.

Ягодицы (66.90КиБ)

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

Через пару недель я забеспокоился — статус моих джинс на сайте так и остался «в производстве». Я написал об этом в «твиттер» и примерно через неделю мои джинсы полетели ко мне «ДиЭйчЭлем». Увы («карма тестировщика», помните, да?), джинсы взяли резвый старт, попутешествовали по миру и вернулись обратно отправителю.

Кругосветка моих джинс (141.18КиБ)

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

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

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

Посылка (108.04КиБ)

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

Джинсы на талии (118.35КиБ)

Ремень тоже не помогает, стянуть им джинсы почему-то не получается, что не так, я не понял, но джинсы упорно не хотят прилегать к пояснице. Как сидит вся эта хитровымученная конструкция на мне, можно оценить на снимке:

Джинсы на мне (112.75КиБ)

Какие выводы.

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

Да, я не люблю ходить по магазинам.

Впечатление от всего процесса у меня сложилось скорее положительное, я попробую сделать ещё заказ. Кстати, мне дали многоразовый купон на скидку в 10%, разрешив делиться им с моими друзьями. Разве мои читатели мне не друзья? Делюсь: #53CZ2F3C6Z7K9, этот номер надо будет ввести где-то ближе к оплате заказа, не промахнётесь.

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

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

Напоследок надо несколько слов сказать о качестве. Оно выше всяких похвал — швы ровные, нитки не торчат, ткань прочная, заклёпки сделаны ровно. За три недели ничего не порвалось, не отвалилось, не полиняло.

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

«Магический экран» на CSS

У всех в детстве была игрушка «магический экран»? Такая прямоугольная штуковина, обычно из красного пластика с двумя крутилками, которые надо было поворачивать, чтобы что-нибудь нарисовать?

А все знают, что браузеры на основе «вебкита» («Хром», «Сафари» и им подобные) некорректно отрабатывают некоторые комбинации CSS3-селекторов? Они «забывают» их перерисовывать, если меняется состояние, зависящее от псевдо-селекторов «:hover», «:target» и другим, которые активно взаимодействуют с внешним окружением.

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

Магический экран на CSS (33.62КиБ)

Вчера ночью я про него думал и меня осенило каким образом баг можно использовать, чтобы создать кое-что интересное. Ведь чем этот баг характеризуется? «Залипанием» состояния. Отлично, это можно использовать!

На основе этого бага я наколдовал «магический экран» без использования Джаваскрипта (не забудьте, работает в «Сафари» или «Хроме»). Если вести справа налево кружки́ рисуются, если слева направо — стираются. «Крутилки» только для декора, они не работают.

Шаманство и контакт с космосом происходит вот в этом участке CSS:

.outer>i:hover+i+i {
        width: 10px;
        height: 10px;
        background: gray;
        border-radius: 50%;
        z-index: 2;

        margin: -2px 0 0 -2px;
    }

Поле для рисования состоит из кучи элементов размером 3×3, когда я наезжаю курсором на один из них, срабатывает «:hover» и меняет стиль кружка́, который находится сильно после того, на который я наехал курсором. Это нужно, чтобы «вебкит» не увидел момента, когда курсор уходит с элемента. «Вебкит» хоть и неправильно работает с селекторами, тем не менее содержит кучу «хаков», чтобы в распространённых случаях всё выглядело как надо.

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

В самых свежих «Сафари» 5.1 и «Хроме» 24 мой «магический экран» работает.

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

График Гангнам-стайла

Гангнам-стайл (3.05КиБ)

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

Я сконвертировал её в PHP, можете запустить у себя и самостоятельно убедиться. Я там ещё две функции определил: sgn — это функция знака и theta — функция Хевисайда, их в PHP нет, а они нужны по коду.

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

Бу: ООП в bash, дополнение

Дописал немного «Бу», библиотеку ООП для «Баша», о которой я рассказывал недавно. Прошлая версия не умела работать напрямую (не из методов, снаружи) со свойствами. Новая умеет.

# … пример из предыдущего поста, дополненный

Dog.New dog # создаём экземпляр «собаки»
$dog.cnt =100 # записываем в свойство «cnt» значение «100», обратите внимание на пробел перед «равно»

cnt="$($dog.cnt)" # чтение значения из свойства

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

@Destroy $dog # yничтожаем объект, в $dog теперь мусор

Dog.New dog # опять создаём «собаку»
unset dog # удаляем ссылку
@Class.gc # вызов сборщика вручную

@Class.gc.on # включаем тормоза и автоматический сборщик мусора

Dog.New dog # и снова создаём «собаку»
dog2="$dog" # ссылка на тот же экземпляр «собаки»
unset dog

echo Объект ещё существует, осталась одна ссылка

unset dog2

echo Объекта уже нет

Кстати, при уничтожении объекта любым из этих способов вызывается деструктор (метод «__destruct»), если он есть, конечно.

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

← сюда туда →