Руферы в Казани

Казань (93.51КиБ)

Руферы (от англ. «roof» — крыша) — это ребята забирающиеся на крыши и верхушки труднодоступных объектов. Одна из команд московских руферов побывала в Казани и выложила фотоотчёт об этом в ЖЖ. Редкая возможность посмотреть на Казань с необычного ракурса.

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

Кстати, на этом же снимке видна стройка Дворца водных видов спорта.

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

У меня большой Айпад

<AnYKEy> Заметил, в последнее время часто подписи в почте: «Отправлено с iPhone», «Отправлено с iPAD». Может тоже вставлять в подпись что-то вроде: «А у меня большой х██»?

С «Башорга» цитата.

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

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

Деньги vs. спасибо

Удивился (я ведь теперь часто езжу на «моторе») — почему казанские водители неохотно подвозят девушек, ведь четыре года назад было всё иначе? Обычная картина — стою я на дороге, впреди девушка голосует, машина проезжает мимо неё и увозит меня.

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

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

Аналог conditional comments появится в CSS

Ура, ребята из W3C одумались и в CSS появится аналог conditional comments. Первого сентября появился черновик нового модуля CSS3 — «CSS Conditional Rules Module Level 3». Самое интересное в нём — новое правило «@supports», которое позволяет проверить поддерживает ли браузер определённый функционал (жаль только нет правила «@supports-but-buggy»).

Есть поддержка «not», «or» и «and», а так же группировки скобками:

@supports (transition-property: color) or
          ((animation-name: foo)) and
           (transform: rotate(10deg))) {
  // …
}

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

@supports ( box-shadow: 2px 2px 2px black ) or
          ( -moz-box-shadow: 2px 2px 2px black ) or
          ( -webkit-box-shadow: 2px 2px 2px black ) or
          ( -o-box-shadow: 2px 2px 2px black ) {
  .outline {
    color: white;
    box-shadow: 2px 2px 2px black;
    -moz-box-shadow: 2px 2px 2px black;
    -webkit-box-shadow: 2px 2px 2px black;
    -o-box-shadow: 2px 2px 2px black;
  }
}

Я легко могу представить когда нужна будет ещё более ветвистая и страшная конструкция. Трудности я понимаю — нужно хорошо вписать конструкцию в уже существующий синтаксис CSS. Была бы моя воля, я бы сделал что-то вроде такого:

.outline {
     box-shadow: 2px 2px 2px black !fallback(no-box);
    -moz-box-shadow: 2px 2px 2px black !fallback(no-box);
    -webkit-box-shadow: 2px 2px 2px black !fallback(no-box);
    -o-box-shadow: 2px 2px 2px black !fallback(no-box);
}

@fallback no-box, no-smth-else {
    /* попадаем сюда, если все условия с таким именем внутри селектора не выполнились */
}

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

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

Айти-парк Казани

Видеопутеводитель по «Айти-парку» Казани. Там же есть небольшой рассказ о фирме, в которой я сейчас работаю, она тоже находится в «Айти-парке». Ещё обратите внимание на дата-центр и, деталь, на каждой двери есть QR-код, а так же Microsoft Tag. Можно узнать поподробнее что находится за каждой дверью.

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

«Яндекс.Пробки» в Казани

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

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

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

Исправить ситуацию можно следующим образом.

Во-первых, помните я рассказывал, что в Казани есть интерактивная карта движения транспорта? Это уже готовые датчики загруженности дороги. Там есть скорость и координаты, чтобы померить ситуацию и обозначены остановки, чтобы убрать ложные срабатывания.

Во-вторых, нужно поставить по камере в важных участках Казани. Взглянем на карту.

Казань (66.00КиБ)

Город условно делится на две части — левый берег и правый берег реки Казанки. Больша́я часть казанцев ежедневно пересекает реку в обеих направлениях, а сделать это можно строго по одному из четырёх мостов Казани (слева направо) — Кировский дамбе, Ленинской дамбе, мосту Миллениум и Третьей транспортной дамбе (сейчас последняя перекрыта, но работает её дублёр).

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

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

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

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

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

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

Казань ✈ Москва ✈ Казань

С позднего вечера субботы до вечера воскресенья — в Москве.

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

Луна не является спутником только Земли

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

…если посчитать силы, с которыми Луну притягивает Земля и Солнце обнаружится интересный факт: Солнце притягивает Луну в 2,2 раза сильнее, чем Земля! Выливается это еще и в то, что вектор результирующего ускорения тела все время имеет составляющую, направленную к Солнцу, то есть оно всегда Солнцестремительное, но не всегда Землестремительное…

Луна и впрямь вращается около Солнца (падает на Солнце!), а не около Земли, но на это движение сильно влияет Земля. Таким образом, систему Земля-Луна правильнее называть двойной планетной системой, обращающейся около Солнца.

В статье есть прекрасная картинка, иллюстрирующая как именно выглядит обращение системы Земля-Луна вокруг Солнца (зелёная линия — Земля, красная — Луна):

Земля-Луна (24.24КиБ)

В школе-то, я же помню, нам показывали модель, где все планеты с разными скоростями вращались вокруг Солнца, а Луна бешенно крутилась вокруг Земли.

Статью, кстати, рекомендую прочитать целиком, там много интересного.

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

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

«Айпад» — слепое пятно у стюардесс

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

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

Суеверные авиалинии

12, 14 (14.63КиБ)

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

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

Переход на «Льва»

Купил себе «Льва» на ноут (это новая Mac OS X), разочарован. Некоторые программы не работают, некоторые начали работать с глюками. Опытные маководы сказали мне, что надо было подождать пару версий, я же неопытный, я не знал. Со стороны казалось, что продукция «Эпла» оплот стабильности, единства и заботы о пользователи. Ничего подобного, здесь так же как везде. Более того, на «Айпаде» тоже единством и не пахнет. Я себе поставил несколько книг и читалок, у каждой свой интерфейс, свои жесты, какие-то из них блокируют поворот экрана, обычный бардак.

Вот, кстати, что подо «Львом» говорит скомпилированная ещё на прошлой версии операционки программа (это мои «уголки» на «Go»):

libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
Abort trap: 6

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

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

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

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

Горе-киберсквотер

Из аськи:

Denis_S: вас не интересует домен связанный с вашей фамилией?
Евгений Степанищев: нет, нафига он мне?
Denis_S: ну не знаю) ладно тогда извините
Евгений Степанищев: тем более, что он свободен
Denis_S: stepanishev.ru ?
Евгений Степанищев: я не Степанишев

Много, интересно, у него ещё таких доменов «связанных» с фамилиями? Simdorov.ru? Kozllow.ru?

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

Занятость каналов WiFi

Утилита, чтобы посмотреть занятость каналов (11.09КиБ)

Что делать перед днём программиста как не программировать? Я настраивал точку доступа дома и пытался выбрать более свободный канал. Быстро найти подходящую утилиту под Mac OS X я не смог, поэтому начал её писать на bash. До конца не дописал (хотел ещё обозначить сколько устройств на одном канале висит), то что есть выкладываю — не пропадать же добру!

Дальше.

#!/bin/bash
declare -a dots

TEMP=$(mktemp -t `basename "$0"`)
trap "/bin/rm -f $TEMP" EXIT

if [ -z $1 ]; then
    /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s > $TEMP
else
    /bin/cp "$1" $TEMP
fi

# Если название точки содержит пробел, у нас всё поедет, надо избавиться от названия
# для этого мы меряем с каким отступом идёт первая строка (6 — это длина слова SSID, плюс пробелы)
cutname=`awk 'NR==1 {l=length; gsub(/^ +/, ""); print l-length+6}' $TEMP`

# Название будет отрезано командой cut
while read line; do
    line=($line)

    chs=(${line[2]//,+/ })

    # Берём только каналы 2,4ГГц
    if [ ${chs[0]} -gt 13 ]; then
        continue
    fi

    # Округляем уровень сигнала
    let lvl="(100 + ${line[1]} + 9) / 10"
    # Уровень прозрачности верхней линии
    let alpha="$lvl*10 - (100 + ${line[1]})"

    # Номера каналов
    let start="${chs[0]}-2+1"
    let end="${chs[0]}+2+${chs[1]:-0}*5+1"

    # Набор точек для рисования прямоугольника wifi-точки
    for x in $(seq $start $end); do

        # Прямоугольник закрашивается сплошным…
        for y in $(seq 0 $(($lvl - 1)) ); do 
            dots[$x+$y*100]=10
        done

        # Кроме верхней границы, она закрашивается значением
        # наибольшей насыщенности
        let xy="$x+($y+1)*100"

        if  [[ -z ${dots[$xy]} || ${dots[$xy]} -lt $alpha ]]; then
            dots[$xy]=$alpha
        fi
    done
# отрезаем заголовок, отрезаем название точки, сортируем по уровню сигнала
done < <(tail -n +2 $TEMP | cut -b${cutname}- | sort -rgk2)

# Блоки по насыщенности границы
blocks=(_ ░ ░ ░ ▒ ▒ ▒ ▒ ▒ ▒ █)

# Цвета вертикальной оси
colors=(32 32 32 32 32 33 33 31 31 31 31)

# Счётчик вертикальной оси
lvl=0

declare -i alpha

# Отрисовка шкалы и данных точек
for y in {10..0}; do
    printf "\033[${colors[-$lvl/10]}m% 4d " $lvl
    let lvl="$lvl - 10"

    for x in {0..15}; do
        alpha=${dots[$x+100*$y]}

        if [ $alpha -le 0 ]; then
            echo -n '   '
        else
            b=${blocks[$alpha]}

            echo -ne "\033[37m$b$b$b"
        fi
    done

    echo
done

# Горизонтальная ось
echo -e "\033[30m     -- -- 01 02 03 04 05 06 07 08 09 10 11 12 13"

echo -e "\033[0m"

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

34

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

Отдельной строкой хочу выделить большую работу — конвертацию корпоративной «Вики» «Яндекса» в UTF-8, заодно я там детально разобрался во всех проблемах PHP с UTF-8.

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

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

Бинарные часы на bash

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

Bash Binary Clock (9.50КиБ)

Бинарные часы — популярное сейчас развлечение программистов, вроде написания игры «Жизнь». Как можно догадаться из названия, они показывают время в двоичной системе исчисления. Самое интересное в моей реализации — как подавляется ввод клавиатуры, это неочевидно. Всё дело в следующих строчках:

# Нажатие «Enter» нужно отключать отдельно
bind -r '\r'
# Сохраняем предыдущее состояние
ORIG=`stty -g`
# Отключаем остальную клавиатуру
stty -echo
# На выходе всё нужно восстановить как было
function Restore {
    stty "$ORIG"
    bind '"\r":accept-line'
}

trap 'Restore' EXIT

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

Текст программы внутри.

#!/bin/bash

declare -a xy

# Выключаем Enter
bind -r '\r'
# Выключаем остальную клавиатуру
ORIG=`stty -g`
stty -echo

function Restore {
    stty "$ORIG"
    bind '"\r":accept-line'
    echo -ne "\033[5B\033[?25h\033[m"
}

trap 'Restore' EXIT

# Цвета наших «стрелок»
colors=(30 34)

# Очистка графического массива
function Clear {
    xy=
}

# Подготовка маски одного разряда
function Print {
    mask=$(printf '%08d' `echo "obase=2; $1" | bc`)
    let pos="$2*4"

    for x in {0..1}; do
        for y in {0..3}; do
            xy[$pos+$x+$y*100]=${mask:$x*4+$y:1}
        done
    done
}

# Печать часов на экран
function PrintClock {
    echo -e "\033[?25l\033[1mBash Binary Clock by Evgeny Stepanischev\033[0m\n"

    for y in {0..3}; do
        for x in {0..9}; do
            c=${colors[${xy[$x+$y*100]:-0}]}
            echo -ne "\033[${c}m▣"
        done
        echo -e "\033[0m"
    done

    # после печати часов передвигаем курсов так,
    # чтобы следующий кадр выводился поверх предыдущего
    echo -en "\033[8A"
}

# Вывод часов
function Clock {
    Clear
    for i in {0..2}; do
        Print $1 $i
        shift
    done

    PrintClock

    echo -e "\n"
}

while true; do
    Clock `date "+%H %M %S"`
    sleep 1
done

Я писал под «Мак», так что на других системах может и не завестись.

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

Электронный документооборот

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

Мы разрабатываем электронный документооборот как компонент одной из систем электронного правительства. Электронное правительство, вопреки расхожему мнению, это не название системы и не сайт «Госуслуги», а способ взаимодействия ветвей государственной власти между собой и с гражданами. Наш документооборот существует с 2005 года и используется, в настоящее время, в Татарстане и Москве. В ближайшем будущем планируется подключать и другие регионы.

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

Электронный документооборот (47.10КиБ)

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

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

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

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

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

Bashnut Battery

Есть такая программа — coconutBattery, красиво показывает под MacOS X состояние батареи и некоторые другие характеристики. Поскольку я тут тренируюсь писать под Bash, решил сегодня повторить её функционал. Полностью не получилось, так как новая версия MacOS X выдаёт что-то странное в параметре потребляемой мощности, но остальное повторил в точности. С параметром «Age of your Mac» я смухлевал, беру данные с онлайн-сервиса (без подключения к интернету этот параметр будет выдавать NA), но зато я эти данные кеширую на сутки.

Bashnut Battery (17.12КиБ)

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

Сам код — далее.
Код ниже:

#!/bin/bash

# Хост для информации о серийнике
HOST='www.chipmunk.nl'

# Выбираем информацию о батарее, получится что-то вроде
# Amperage 18446744073709550574 Flags 4 Capacity 6632 Current 6338 Voltage 8192 CycleCount 14 и тд

BATTERY=( $(\
    ioreg -w0 -l |
    egrep '(Max|Design)Capacity|(Legacy|IO)BatteryInfo|product-name|Temperature|PlatformSerialNumber' |
    tee >(awk -F{ '/(Legacy|IO)BatteryInfo/ { gsub(/ |\}|"/, ""); gsub(/,|=/, " "); print $2 }') |
    tee >(awk -F'"' '/(Max|Design)Capacity|product-name|Temperature|PlatformSerialNumber/ { gsub(/[=<>-]/, ""); print $2 $3 $4}') |
    grep -vF '"' |
    tr '\n' ' '
))

# Достаём значение по ключу из BATTERY
function GetBatVal {
    local i

    for ((i=0; i<${#BATTERY[@]}; i+=2)); do
        if [ $1 = ${BATTERY[$i]} ]; then
            echo ${BATTERY[$i+1]}
            break
        fi
    done
}

# Получаем информацию о неделе выпуска
function GetPlatform {
    local tmpfile="$TMPDIR/battery-age-mac"

    # Файл с кешем, чтобы не дёргать сервис каждый раз
    if [ -e $tmpfile ]; then
        # проверим время создания файла
        eval $(stat -s $tmpfile)

        # Если кеш устарел, то удаляем его
        if [ $((`date +%s` - $st_mtime)) -gt 86400 ]; then
            rm -f $tmpfile
        else
            cat $tmpfile
            return
        fi
    fi

    local date=($(\
        curl --connect-timeout 3 "http://$HOST/cgi-fast/applemodel.cgi?serienummer=$1" 2>/dev/null |
        sed 's/<BR>/`/g' | awk 'BEGIN {RS="`"} /Production (year|week)/{gsub("<[^>]+>", ""); print $2 $3}' |
        sort | cut -d: -f2 | tr "\r\n" '  '
    ))

    if [ ${#date[@]} -le 1 ]; then
        echo NA
        return
    fi

    local scale
    local diff

    # Считаем количество недель
    let diff="($(date +%Y)-${date[1]})*52177 + ( $(date +%V) - ${date[0]}) * 1000"

    # Выбираем что будем отображать — недели, месяцы, годы
    if [ $diff -gt 5 ]; then
        diff=$(( $diff / 4340 ))
        scale=Month

        if [ $diff -gt 12 ]; then
            diff=$(( $diff / 12 ))
            scale=Year
        fi
    else
        diff=$(( $diff / 1000 ))
        scale=Week
    fi

    [ $diff -gt 1 ] && scale=${scale}s

    echo $diff $scale | tee $tmpfile
}

# Рисуем прогрессбар
function PrintBat {
    # Если терминал поддерживает 256 цветов, покажем красиво
    if [[ $TERM =~ 256 ]]; then
       local colors=("38;5;160" "38;5;220" "38;5;34")
    else
       # Иначе, увы, цвета попроще
       local colors=(31 33 32)
    fi

    local c=${colors[0]}

    [ $1 -ge 13 ] && c=${colors[1]}
    [ $1 -ge 20 ] && c=${colors[2]}

    local bar=$(cat)
    local prg=$(printf "%0$1s" | tr 0 ${bar:2:1})
    local rep="\033[${c}m$prg\033[30m"

    echo -e ${bar/$prg/$rep}
}

# Возраст Мака
age=$(GetPlatform `GetBatVal IOPlatformSerialNumber`)

# Всё достаточно очевидно: боксы с информацией
cur=$(GetBatVal Current)
max=$(GetBatVal Capacity)
let percent="($cur*40/$max)"

echo -e '\033[1m\n  Bashnut Battery by Evgeny Stepanischev\033[0m'

echo
echo   '  Battery charge'
echo    ┌──────────────────────────────────────────┐
printf '│ Current charge:                % 5d mAh │\n' $cur
printf '│ Maximum charge:                % 5d mAh │\n' $max
echo   '│                                          │'
echo -e '│ ████████████████████████████████████████ \033[0m│' | PrintBat $percent
echo    └──────────────────────────────────────────┘

des=$(GetBatVal DesignCapacity)
max=$(GetBatVal MaxCapacity)
let percent="($max*40/$des)"

echo   '  Battery capacity'
echo    ┌──────────────────────────────────────────┐
printf '│ Current capacity:              % 5d mAh │\n' $max
printf '│ Design capacity:               % 5d mAh │\n' $des
echo   '│                                          │'
echo -e '│ ████████████████████████████████████████ \033[0m│' | PrintBat $percent
echo    └──────────────────────────────────────────┘

echo  '  Details'
echo    ┌──────────────────────────────────────────┐
printf '│ Mac model:             % 17s │\n' $(GetBatVal productname)
printf '│ Age of your Mac:       % 17s |\n' "$age"
printf '│ Battery loadcycles:                % 5d │\n' $(GetBatVal CycleCount)
printf '│ Battery temperature:             % 5s˚С |\n' `echo "scale=1;($(GetBatVal Temperature)+5)/100" | bc`
echo    └──────────────────────────────────────────┘

echo -e "\033[0m"

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

Сетевая игра на bash: шахматы ★

Я давно хотел написать какую-нибудь сетевую игру на bash, причём желательно, чтобы управление было удобное, с клавиатуры, обычными курсорным клавишами. Вообще, тема интерактивного взаимодействия в bash глубже, чем «введите число, нажмите „Enter“» не раскопана. Мне пришлось всё изобретать и исследовать самостоятельно. Я очень старался найти что-то похожее по уровню интерактивности, но не нашёл.

Поскольку тонкости управления с клавиатурой съели очень много моего времени, я не стал заморачиваться с тонкостями совместимости, поэтому игра тестировалась только под Mac OS X, есть ненулевая вероятность, что она заработает и под Linux и уж точно её можно допилить там до рабочего состояния.

Для работы игра требует наличия nc (aka Netcat) и терминала с поддержкой 256 цветов (под Mac OS рекомендую iTerm2). При наличие интереса к игре, допилю до терминала на 16 цветов и /dev/tcp. Кстати начал выкладывать все свои шел-поделки на ГитХаб.

Два скриншота терминала с запущенной шахматной программой chess.sh на localhost:50000, показывающие начальную позицию и ход белых (e4).

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

Играть просто — в каждый момент времени активна только одна доска (на скриншоте — правая, у неё буквы и цифры вокруг доски ярче), на активной доске курсор двигается курсорными клавишами — ←, →, ↑ и ↓, взять фигуру и поставить её на доску — по клавише пробела или Enter. Как только вы поставили фигуру на доску, ход переходит к сопернику. «Съесть» фигуру соперника проще простого — достаточно поставить свою фигуру на чужую. В игре есть защита — нельзя «съесть» свою фигуру.

Ничего помимо этого в игре нет — не производится правильность контроля ходов, нет проверки на завершение игры, можно даже ходить фигурами соперника. Было очень сложно придумать как обрабатывать нажатия в shell, так что остальное сделать я просто не успел, не поместилось в формат «игрушка за вечер».

#!/bin/bash
# Network chess by Evgeny Stepanischev //bolknote.ru 2011

if [ $# -ne 2 ]; then
    echo Usage: $0 host-of-opponent port
    exit
fi

# Хост оппонента
HOST="$1"

# Общий порт
PORT="$2"

# Клавиатурные комбинации извстной длины
SEQLEN=(1b5b4. [2-7]. [cd]... [89ab].{5} f.{7})

# Фигуры
WHITE=(♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖)
BLACK=(♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟)

# Наш ход?
OURMOVE=

# Я чёрный или белый?
MYCOLOR=

# Доска
declare -a XY

# Курсор
CX=1 CY=7
TAKEN=

# Необходимые нам клавиатурные коды
KUP=1b5b41
KDOWN=1b5b42
KLEFT=1b5b44
KRIGHT=1b5b43
KSPACE=20

# Восстановление экрана
function Restore {
    echo -ne "\033[5B\033[5B\033[?25h\033[m"
    stty "$ORIG" 2>/dev/null
    (bind '"\r":accept-line' 2>/dev/null)
}

trap Restore EXIT

# Выключаем Enter
(bind -r '\r' 2>/dev/null)
# Выключаем остальную клавиатуру
ORIG=`stty -g`
stty -echo

# Убирам курсор
echo -e "\033[?25l"

# Отдаём события клавиатуры в сеть
function ToNet {
    echo $1 | nc "$HOST" "$PORT"
}

# Реакция на клавиши курсора
function React {
    case $1 in
        $KLEFT)
              if [ $CX -gt 1 ]; then
                  CX=$(($CX-1))
                  PrintBoard
              fi
           ;;

        $KRIGHT)
              if [ $CX -lt 8 ]; then
                  CX=$(($CX+1))
                  PrintBoard
              fi
            ;;

        $KUP)
              if [ $CY -gt 1 ]; then
                  CY=$(($CY-1))
                  PrintBoard
              fi
           ;;

        $KDOWN)
              if [ $CY -lt 8 ]; then
                  CY=$(($CY+1))
                  PrintBoard
              fi
    esac

    # Отдаём события клавиатуры в сеть
    [ "$OURMOVE" ] && ToNet $1
}


# Проверка совпадения с известной клавиатурной комбинацией
function CheckCons {
    local i

    for i in ${SEQLEN[@]}; do
        if [[ $1 =~ ^$i ]]; then
            return 0
        fi
    done

    return 1
}

# Функция реакции на клавиатуру, вызывает React на каждую нажатую клавишу,
# кроме KSPACE — на неё возвращается управление

function PressEvents {
    local real code action

    # Цикл обработки клавиш, здесь считываются коды клавиш,
    # по паузам между нажатиями собираются комбинации и известные
    # обрабатываются сразу
    while true; do
        # измеряем время выполнения команды read и смотрим код нажатой клавиши
        # akw NR==1||NR==4 забирает только строку №1 (там время real) и №4 (код клавиши)
        eval $( (time -p read -r -s -n1 ch; printf 'code %d\n' "'$ch") 2>&1 |
        awk 'NR==1||NR==4 {print $1 "=" $2}' | tr '\r\n' '  ')

        # read возвращает пусто для Enter и пробела, присваиваем им код 20,
        # а так же возвращаются отрицательные коды для UTF8
        if [ "$code" = 0 ]; then
            code=20
        else
             [ $code -lt 0 ] && code=$((256+$code))

             code=$(printf '%02x' $code)
        fi

        if [ $code = $KSPACE ]; then
            [ "$OURMOVE" ] && ToNet $KSPACE

            SpaceEvent && return
            continue
        fi

        # Если клавиши идут подряд (задержки по времени нет)
        if [ $real = 0.00 ]; then
            seq="$seq$code"

            if CheckCons $seq; then
                React $seq
                seq=
            fi

        # Клавиши идут с задержкой (пользователь не может печатать с нулевой задержкой),
        # значит последовательность собрана, надо начинать новую
        else
            [ "$seq" ] && React $seq
            seq=$code

            # возможно последовательность состоит из одного символа
            if CheckCons $seq; then
                React $seq
                seq=
            fi
        fi
    done
}

# Проверяем чёрная или белая фигура
function CheckColor {
     echo -n ${1:0:1}
}

# Первичное заполнение доски
function FillBoard {
     local x y ch

     for y in {1..8}; do
         for x in {1..8}; do
             ch='S '

             if [ $y -le 2 ]; then
                 ch=B${BLACK[$x+8*$y-9]}
             else
                 if [ $y -ge 7 ]; then
                     ch=W${WHITE[$x+8*$y-57]}
                 fi
             fi

             XY[$x+100*$y]=$ch
         done
    done
}

# Вывод букв по краю доски
function PrintBoardLetters {
     local letters=abcdefgh

     [ -z "$OURMOVE" ] && echo -ne "\033[30m" || echo -ne "\033[0m"

     echo -n '   '

     for x in {0..7}; do
         echo -n "${letters:$x:1} "
     done
     echo
}

# Вывод цифры по краю доски
function PrintBoardDigit {
    [ -z "$OURMOVE" ] && echo -ne "\033[30m"
    echo -en " $((9-$1))\033[0m "
}

# Вывод доски
function PrintBoard {
     local x y c ch
     local colors=('48;5;209;37;1' '48;5;94;37;1')

     PrintBoardLetters

     for y in {1..8}; do
        PrintBoardDigit $y

        for x in {1..8}; do
            c=${colors[($x+$y) & 1]}
            ch=${XY[$x+100*$y]}

            if [[ $CX == $x && $CY == $y ]]; then
                c="$c;7"
                [ "$TAKEN" ] && ch=$TAKEN
                [ $MYCOLOR == B ] && c="$c;38;5;16"
            fi

            [[ $(CheckColor "$ch") == "B" ]] && c="$c;38;5;16"

            echo -en "\033[${c}m${ch:1:1} \033[m"
        done

        PrintBoardDigit $y
        echo
     done

     PrintBoardLetters

     echo -e "\033[11A"
}

# Приём событий
function NetListen {
    nc -l $PORT
}

# Готовы слушать события сети
function NetEvents {
    local code

    while true; do
        code=$(NetListen)

        [[ "$code" == "$KSPACE" ]] && SpaceEvent && return

        React $code
    done
}

# Реакция на нажатие Space и Enter — взять или положить фигуру
function SpaceEvent {
    local xy

    # Проверяем, есть ли фигура под курсором
    let xy="$CX+$CY*100"

    # Фигуры нет
    if [ "${XY[$xy]:-S }" = "S " ]; then
        if [ -z "$TAKEN" ]; then
            echo -en "\007"
        else
            # Положили фигуру
            XY[$xy]=$TAKEN
            TAKEN=
            return 0
        fi
    # Фигура есть
    else
        # Мы не должны позволять «съесть» свою фигуру
        if [[ $(CheckColor "$TAKEN") == $(CheckColor "${XY[$xy]}") ]]; then
            echo -en "\007"
        else
			# Фигура есть «в руке», мы «съедаем» противника
			if [ "$TAKEN" ]; then
			    XY[$xy]=$TAKEN
                TAKEN=
                return 0    
			else	
                # «В руке» ничего не было, мы взяли фигуру
                TAKEN=${XY[$xy]}
                XY[$xy]="S "
            fi
        fi
    fi

    return 1
}

# Очистка клавиатурного буфера
function ClearKeyboardBuffer {
    # Быстро — через zsh
    which zsh &>/dev/null && zsh -c 'while {} {read -rstk1 || break}' && return

    # Медленно — через bash
    local delta
    while true; do
        delta=`(time -p read -rs -n1 -t1) 2>&1 | awk 'NR==1{print $2}'`
        [[ "$delta" == "0.00" ]] || break
    done
}

FillBoard

# Кто будет ходить первым
ToNet HI
[[ "$(NetListen)" == "HI" ]] && OURMOVE=1
sleep 0.2
ToNet ULOOSE

[ "$OURMOVE" ] && MYCOLOR=W || MYCOLOR=B

PrintBoard

# Основной цикл — обрабатываем события из сети или с клавиатуры
while true; do
    if [ -n "$OURMOVE" ]; then
        ClearKeyboardBuffer
        PressEvents
        OURMOVE=
    else
         NetEvents
         OURMOVE=1
    fi

    PrintBoard
done

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

Razor E300 Scooter

Человек в джинсах и кроссовках стоит на синем электрическом самокате Razor на асфальтированной дорожке в парке.
Razor E300 Scooter

Жена (спасибо, моя хорошая!) подарила на день рождения электросамокат «Скутер», вчера наличие свободного времени и хорошая погода совпали, мы решили его опробовать. Семь часов зарядки и 20 км хода, максимальная скорость — 25 км/час, защита от брызг и грязи, максимальная нагрузка — 90 кг.

С этими утренними пробками весной и летом буду доезжать до метро, а там на метро до работы, а то 40-50 минут добираться я уже устал, у меня от работы до дома пять км. Только надо привыкнуть к тому, что регулятора скорости нет (можно только включить и выключить мотор) и с заносами надо быть осторожнее.

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

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

Интерактивная игра на bash: «Арканоид» ★

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

Забегая вперёд, скажу, что проблему решить вполне удалось. Я разделил игру на два процесса, один из которых опрашивает клавиатуру и сообщает о нажатии второму при помощи сигналов — USR1, USR2 и HUP, как раз три сигнала по трём управляющим клавишам — „←“, „→“ и «пробел». Последняя нужна, чтобы пускать шарик.

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

Арканоид (49.62КиБ)

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

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

От терминала, как и в шахматах, требуется уметь отображать 256 цветов и хорошая поддержка «Юникода». Нигде, кроме как под «Мак» игру я не тестировал, по-прежнему рекомендую iTerm2 в качестве терминала.

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

Видео выложил на «Яндекс.Видео». Добавлено позднее: сервис «Яндекс.Видео» прекратил своё существование.

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

Опять столкнулся с изменившимся АПИ «Гугл Гоу»

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

Обновил компилятор до r59 и сразу пришлось менять код моего «МэйкКорнера — в модуле strings метод Split теперь называется SplitN, а Split делает то же самое, что SplitN с последним параметром „-1“, а модуль exec переписали полностью, вызовы внешних программ происходят вкорне иначе, опять пришлось читать исходный код модуля, чтобы разобраться что к чему.

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

Новое слово: «готовки», «рео»

Готовки (34.26КиБ)

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

Второе — «рео». «Рео» — это «реорганизация» (фирмы).

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

«Спасибо за сына!»

У роддома (48.08КиБ)

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

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

Изучаю ломографию

Площадь свободы (58.54КиБ)

Я пока так и не решил как я отношусь к ломографии, но попробую ей попользоваться, чтобы понять как. На снимке — площадь Свободы в Казани.

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

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

Фотки можно добавлять ещё и с picplz.com

Внёс важное изменение в движок сайта — фотографии теперь можно добавлять ещё и с сайта «Пикплз». Вообще я переделал весь механизм добавления сайтов с картинками.

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

Во-вторых, я теперь использую мультизапросы модуля «кУРЛ» — запросы на каждую картинку идут не последовательно, как раньше, а параллельно.

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

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

Добавлено позже: теперь ещё и «Фликр» работает.

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

Чудо-лампочка

Лампа на два режима (17.04КиБ)

Купили с женой в «Метро» лампочку фирмы «Осрам», насколько я разобрался в их каталоге, это «DULED Twist 21 W/827 B22d».

Лампочка, может, на чудо и не тянет, но комфорт дома чудесным образом увеличивает. Дело в том, что у этой лампы два режима.

Сразу после включения, лампочка, в режиме ночника неярко светит двумя светодиодами, потребляя всего 0,3 ватта. Если её выключить и сразу включить, то начинает работать основная энергосберегающая лампа в 21 ватт (эквивалентна лампе накаливания в 90 Вт). Очень удобно перед сном или ночью, когда спальню нужно осветить чем-нибудь неярким, не бьющим в глаза.

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

Немного Казани

Пока шёл из машины на корпоратив, сделал несколько снимков вечерней Казани.

Заброшенная Баумана (45.61КиБ)

Это заброшенный конец улицы Баумана — одной из центральных улиц города, которую должны были переделать к тысячелетию Казани. Тут много развалин казанской истории. В кадре — стена разрушенного пристроя к гостинице «Казань» (начало XIX века), летнее кафе «Вечернее», чуть вдалеке виднеется Петропавловский собор.

Петропавловский собор в Казани (68.86КиБ)

Одно из красивейших зданий Казани — Петропавловский собор, построенный в 1726 году. В хоре собора пел сам Шаляпин, его посещали А. С. Пушкин, многие российские императоры, описания собора есть у Александра Дюма и Александра Гумбольдта, он пережил пять пожаров, разграбление пугачёвцами в 1774-м, был планетарием с 1964 до 1989. Внутри храма сохранился чудом уцелевший 25-метровый семиярусный иконостас, ровесник храма.

Гостиница «Казань» (47.37КиБ)

Слева на фото — полуразрушенная гостиница «Казань», исторический памятник федерального значения, очень красивое здание 1835 года, уже много лет находятся в плачевном состоянии. Обещают восстановить в первозданном виде к Универсиаде 2013 года, очень на это надеюсь. В центре, почти не видно, современный памятник памятник Казанскому Коту. Справа (дом, покрашенный жёлтым) — торговый павильон 1796 года.

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

Китайская подделка «Летающей акулы»

Китайская подделка «Летающей акулы» (16.23КиБ)

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

Мы очень обрадовались, когда на одном из клонов «Групона» мы обнаружили предложение, позволяющее купить эту рыбу с 50% скидкой. Если судить по приведённым фотографиям и роликам, эта та самая игрушка, которую мне так хочется.

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

Жена, умница, нашла в интернетах страницу «Глобимпорта» — импортёра из Китая, где использовались всё те же завлекательные фото и ролики, но зато видно реальную упаковку поставляемого товара.

Скриншот веб-страницы компании GLOBIMPORT LLC о поставках летающих рыб AirSwimmers из Китая в Россию; видны заголовки, описание продукта и видео с демонстрацией игрушек.
Упаковка из Китая

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

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

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

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

Добавлено позднее: впрочем, у меня нашёлся аргумент посерьёзнее.

Оригинальная «Летающая акула» производится корпорацией «Вильям Марк». У них на сайте, в разделе «Вопросы и ответы» упомянуто, что существуют две модели «Летающей акулы»:

What is the difference between your Air Swimmers and the Air Swimmers sold at Toys R Us?

Toys R Us sells a radio-controlled version of Air Swimmers, which is manufactured exclusively for them under a license from our company. We sell infrared-controlled Air Swimmers to other retailers. Otherwise, the two products are very similar.

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

Упомянутый магазин продаёт модель, которой требуются четыре батарейки ААА (одна в «рыбу», остальные — в пульт), при этом в рекламе на клоне «групона» говорится о радиоуправлении. Китайская рыбка — именно радиоуправляемая и требует для питания батарейки AAA.

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

Противогаз для младенцев

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

Я не знаю учат ли в школе сейчас надевать противогаз, нас учили. Вы никогда не задумывались — вот есть противогазы для взрослых, есть для детей (в школе многие видели) и угрозами можно надеть его на самых непослушных. Но что делать, в случае опасности, с младенцами? Признаться, я не задумывался.

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

Такая камера снабжалась ремнём для переноски, а сбоку (на снимке слева) было прозрачное оконце.

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

funny refname

funny refname (20.12КиБ)

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

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

404!

Три человека сидят за столом, используя смартфоны и планшет; на столе лежат брошюры с надписью «404» и логотипом «lowkee.com».

Завтра выезжаю в Самару, на фестиваль разработчиков «404», который оставил самые хорошие впечатления с прошлого года. Это самое важное веб-событие года в России, если вы на него почему-то не попадаете, то вы многое теряете!

На фото — я и ребята из дизайн-бюро «Нок нок» на фестивале в прошлом году, фотография — Артёма Локи.

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

← сюда туда →