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

Руферы (от англ. «roof» — крыша) — это ребята забирающиеся на крыши и верхушки труднодоступных объектов. Одна из команд московских руферов побывала в Казани и выложила фотоотчёт об этом в ЖЖ. Редкая возможность посмотреть на Казань с необычного ракурса.
На снимке №4 видны дома, очень похожие на тот, в котором я живу (с зелёной крышей из кирпича кварцевого цвета). Я несколько подзабыл географию Казани за четыре года, возможно как раз я и живу в одном из них.
Кстати, на этом же снимке видна стройка Дворца водных видов спорта.
У меня большой Айпад
<AnYKEy> Заметил, в последнее время часто подписи в почте: «Отправлено с iPhone», «Отправлено с iPAD». Может тоже вставлять в подпись
что-то вроде: «А у меня большой х██»?
С «Башорга» цитата.
Я, кстати, тоже недоумевал. Теперь у меня есть Айпад и я знаю откуда эта надпись берётся. Её добавляет стандартный почтовый клиент, если, конечно, не залезть в настройки и не отключить, но многим лень.
Деньги vs. спасибо
Удивился (я ведь теперь часто езжу на «моторе») — почему казанские водители неохотно подвозят девушек, ведь четыре года назад было всё иначе? Обычная картина — стою я на дороге, впреди девушка голосует, машина проезжает мимо неё и увозит меня.
Расспросил водителей. Ларчик просто открывался. Девушки часто норовят доехать «за спасибо», поэтому утром, когда все хмурые и меркантильные, девушек берут реже. Вечером же ситуация, якобы, меняется на противоположную — при наличии выбора первой уедет девушка.
Семь миллиардов
Оказывается, население Земли в этом году достигло семи миллиардов.
Аналог conditional comments появится в CSS
Ура, ребята из W3C одумались и в CSS появится аналог conditional comments. Первого сентября появился черновик нового модуля CSS3 — «CSS Conditional Rules Module Level 3». Самое интересное в нём — новое правило «@supports», которое позволяет проверить поддерживает ли браузер определённый функционал (жаль только нет правила
Есть поддержка «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 {
/* попадаем сюда, если все условия с таким именем внутри селектора не выполнились */
}Менее гибко в плане условий, но более просто, коротко и не позволяет городить сложные условия (я считаю, что они сильно снижают читаемость).
Айти-парк Казани
Видеопутеводитель
«Яндекс.Пробки» в Казани
Третью неделю езжу с приложением «Яндекс.Карты» в Казани, чтобы посмотреть помогут ли мне «Яндекс.Пробки» быстрее добираться до работы. Вывод неутешительный — точность информации, как у прогноза погоды осенью — ну да, возьмёшь зонтик, вряд ли ошибёшься, но ведь и солнце
Стойкое ощущение, что в казанских «Пробках» не учитывается никаких источников данных, кроме пользовательских устройств (когда вы пользуетесь приложением для «Карт», приложение пользуется вами — передаёт «Яндексу» как быстро вы двигаетесь на этом участке).
Например, вчера я ехал по мосту «Миллениум», на котором была грандиозная пробка, прямо за моим указателем положения дорога на глазах «краснела».
Исправить ситуацию можно следующим образом.

Город условно делится на две части — левый берег и правый берег реки Казанки. Больша́я часть казанцев ежедневно пересекает реку в обеих направлениях, а сделать это можно строго по одному из четырёх мостов Казани (слева направо) — Кировский дамбе, Ленинской дамбе, мосту Миллениум и Третьей транспортной дамбе (сейчас последняя перекрыта, но работает её дублёр).
Мосты очень важная штука, там необходимо поставить по камере, причём камеры хватит одной, мост смешная вещь — с него машине в середине пробки некуда свернуть, так что если в середине затор, то и по всей протяжённости тоже затор.
Далее, к Универсиаде 2013 года Казань строит кучу двухуровневых развязок, часть важных дорог (а зачем строить развязки на неважных дорогах) перекрыта, но город, увы, не позаботился о дублёрах, поэтому автолюбители сами нашли объезды, кажется, самая болезненная ситуация перед Миллениумом — прямой выезд перекрыт и там часто пробка, но исключительно важно знать действительно ли она сейчас там есть, так как от этого зависит решение стоит ли вообще ехать через Миллениум. Напоминаю, что мосты (Миллениум — это мост) — важная штука.
В общем, вывод такой — надо работать с местными водителями и выяснять какие дороги являются основными и где заторы возникают часто, а пока информация сервиса никак не помогает ориентироваться в пробках, точность очень низкая.
Казань ✈ Москва ✈ Казань
С позднего вечера субботы до вечера воскресенья — в Москве.
Луна не является спутником только Земли
Заголовок навевает мысли об очередном исследовании «британских учёных», но, по всей видимости, так и есть, об этом убедительно рассказывается в статье «Мифы физики, как предмета преподавания». Если вкратце, то:
…если посчитать силы, с которыми Луну притягивает Земля и Солнце обнаружится интересный факт: Солнце притягивает Луну в 2,2 раза сильнее, чем Земля! Выливается это еще и в то, что вектор результирующего ускорения тела все время имеет составляющую, направленную к Солнцу, то есть оно всегда Солнцестремительное, но не всегда Землестремительное…
Луна и впрямь вращается около Солнца (падает на Солнце!), а не около Земли, но на это движение сильно влияет Земля. Таким образом, систему
Земля-Луна правильнее называть двойной планетной системой, обращающейся около Солнца.
В статье есть прекрасная картинка, иллюстрирующая как именно выглядит обращение системы

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

Снято в самолёте вчерашнего рейса «Донавии» из Казани. В первый раз такое вижу, а может не замечал раньше просто — в самолёте нет тринадцатого ряда.
Переход на «Льва»
Купил себе «Льва» на ноут (это новая Mac OS X), разочарован. Некоторые программы не работают, некоторые начали работать с глюками. Опытные маководы сказали мне, что надо было подождать пару версий, я же неопытный, я не знал. Со стороны казалось, что продукция «Эпла» оплот стабильности, единства и заботы о пользователи. Ничего подобного, здесь так же как везде. Более того, на «Айпаде» тоже единством и не пахнет. Я себе поставил несколько книг и читалок, у каждой свой интерфейс, свои жесты,
Вот, кстати, что подо «Львом» говорит скомпилированная ещё на прошлой версии операционки программа (это мои «уголки» на «Go»):
libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
Abort trap: 6Я ещё не разобрался что это, но интернет постепенно полнится сообщениями от других пользователей об аналогичных ошибках, не у меня одного возникает.
Заботу о пользователе я тоже
При всём при этом работать необъяснимо приятно, а качество сборки «Макбуков»
Горе-киберсквотер
Из аськи:
Denis_S: вас не интересует домен связанный с вашей фамилией?
Евгений Степанищев: нет, нафига он мне?
Denis_S: ну не знаю) ладно тогда извините
Евгений Степанищев: тем более, что он свободен
Denis_S: stepanishev.ru ?
Евгений Степанищев: я не СтепанишевМного, интересно, у него ещё таких доменов «связанных» с фамилиями? Simdorov.ru? Kozllow.ru?
Занятость каналов WiFi

Что делать перед днём программиста как не программировать? Я настраивал точку доступа дома и пытался выбрать более свободный канал. Быстро найти подходящую утилиту под 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"
34
Тридцать четыре года. Раз в год, в свой день рождения я подвожу своеобразные итог — что же я успел сделать с прошлого раза. За последнее время произошло традиционно немало, а именно (выпишу всё, хоть сколько значимое):
- посетил Ярославль, Самару, Тулу, Турцию (Анталью, Памуккале, гору Тахталы), Алушту, Симферополь (где я попробовал рапаны), Верхние Девлизери (Пестречинский район, Татарстан), Лениногорск, Серпухов,
Санкт-Петербург, Сергеевск, Финляндию (Хельсинки), Эстонию (Таллин), Латвию (Ригу) и Польшу (Варшаву). - помочил ноги в двух новых морях — Средиземном и Балтийском
- увидел живьём Бьёрна Страуструпа, увы, не познакомился со Стояном Стефановым
- стал «фотографом» (хорошо не свадебным)
- начал и бросил ходить на скалодром
- сменил дизайн блога (сайту исполнилось 10 лет, приурочил к этому событию)
- поверхностно изучил Perl6
- выучил новый язык программирования — Google Go, включая написание модулей с CGO
- попробовал себя в обзорах гаджетов (рассказал о телефонах Just5 CP10/11 и «МТС Глонассе 945»)
- в «Яндексе» повысили до руководителя службы
- перешёл на Mac OS X с Windows
- поменял место работы с «Яндекса» на «Системы документооборота», город с Москвы на Казань, режим с совы на жаворонка
А так же умещал игру на JavaScript в 1КБ, сконвертировал старую версию сайта, писал игру на чистом HTML, сделал эмуляцию localStorage для IE6 и 7, сделал скруглятор уголков на PHP и Google Go (а так же библиотеку для работы с графикой на Go), покатался на багги, дал интервью для «Business Class», «LookAtMe», «Пяти шотам», усовершенствовал технику совмещения JS и CSS в одном файле, написал аналоговые часы без JS, интерпретатор Brainfuck на AppleScript, преобразовал книгу «Стань стальной крысой!» в HTML, сделал утилиту для «Мака» на bash, чтобы смотреть какие каналы WiFi заняты.
Отдельной строкой хочу выделить большую работу — конвертацию корпоративной «Вики» «Яндекса»
Бинарные часы на bash
Раз пошла такая пьянка (в смысле, раз уж день программиста), я на радостях решил не останавливаться на достигнутом и написать

Бинарные часы — популярное сейчас развлечение программистов, вроде написания игры «Жизнь». Как можно догадаться из названия, они показывают время в двоичной системе исчисления. Самое интересное в моей реализации — как подавляется ввод клавиатуры, это неочевидно. Всё дело в следующих строчках:
# Нажатие «Enter» нужно отключать отдельно
bind -r '\r'
# Сохраняем предыдущее состояние
ORIG=`stty -g`
# Отключаем остальную клавиатуру
stty -echo
# На выходе всё нужно восстановить как было
function Restore {
stty "$ORIG"
bind '"\r":accept-line'
}
trap 'Restore' EXITНаверняка не раз ещё пригодится. Сама программа бинарных часов дальше, там у меня несколько сложнее, так как я ещё убираю с экрана курсор, чтобы не мешался. Выйти из программы просто — надо нажать Я писал под «Мак», так что на других системах может и не завестись.Текст программы внутри.
#!/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
Электронный документооборот
Читатели интересуются, когда же я начну
Мы разрабатываем электронный документооборот как компонент одной из систем электронного правительства. Электронное правительство, вопреки расхожему мнению, это не название системы и не сайт «Госуслуги», а способ взаимодействия ветвей государственной власти между собой и с гражданами. Наш документооборот существует с 2005 года и используется, в настоящее время, в Татарстане и Москве. В ближайшем будущем планируется подключать и другие регионы.
Система поистине огромна. Сейчас активных пользователей, которые работают каждый день, создавая колоссальную нагрузку, более 20 тысяч. Все законопроекты, распоряжения, указания и так далее теперь движутся только в недрах системы, воплощаясь в бумагу только в тех случаях, когда взаимодействовать приходится с ведомствами, не подключенными к документообороту. В Татарстане сейчас таких очень мало, даже самое отдалённое село подключено к этой системе (это не преувеличение). В Москве ситуация пока похуже, на всё требуется время, нужно учить людей, закупать сервера, доделывать систему под делопроизводство, принятое в конкретном ведомстве.

Используется три типа клиентских приложений, это
Резолюцию к документам можно добавить разными способами — напечатать на клавиатуре, надиктовать в микрофон или нарисовав
Остальное — уже неинтересные подробности, каким именно образом двигаются документы, детали различия делопроизводства в различных ведомствах и тому подобное.
Bashnut Battery
Есть такая программа — coconutBattery, красиво показывает под MacOS X состояние батареи и некоторые другие характеристики. Поскольку я тут тренируюсь писать под Bash, решил сегодня повторить её функционал. Полностью не получилось, так как новая версия MacOS X выдаёт

В этом скрипте я разучил несколько новых фокусов, рад что сел за эту задачу. И ещё новинка — я теперь проверяю тип терминала, если он содержит «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"
Сетевая игра на bash: шахматы ★
Я давно хотел написать
Поскольку тонкости управления с клавиатурой съели очень много моего времени, я не стал заморачиваться с тонкостями совместимости, поэтому игра тестировалась только под Mac OS X, есть ненулевая вероятность, что она заработает и под Linux и уж точно её можно допилить там до рабочего состояния.
Для работы игра требует наличия nc (aka Netcat) и терминала с поддержкой 256 цветов (под Mac OS рекомендую iTerm2). При наличие интереса к игре, допилю до терминала на 16 цветов и /dev/tcp. Кстати начал выкладывать все свои
Эта игра запускается посложнее, так как сетевая, у неё два параметра, о которых она расскажет, если её запустить без них. Первый — адрес машины противника, второй — порт. Порт выбирается одинаковым на обеих машинах. Игру можно запустить и на одной машине, в двух консолях (на скриншоте как раз такой случай).
Играть просто — в каждый момент времени активна только одна доска (на скриншоте — правая, у неё буквы и цифры вокруг доски ярче), на активной доске курсор двигается курсорными клавишами — ←, →, ↑ и ↓, взять фигуру и поставить её на доску — по клавише пробела или 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
Razor E300 Scooter
Жена (спасибо, моя хорошая!) подарила на день рождения электросамокат «Скутер», вчера наличие свободного времени и хорошая погода совпали, мы решили его опробовать. Семь часов зарядки и 20 км хода, максимальная скорость — 25 км/час, защита от брызг и грязи, максимальная нагрузка — 90 кг.
С этими утренними пробками весной и летом буду доезжать до метро, а там на метро до работы, а то
Замечательная штука, только от детей во дворе запаса скорости не хватает уезжать — бегут следом и просят покататься.
Интерактивная игра на bash: «Арканоид» ★
После шахмат, где я решал проблему опроса клавиатуры, мне захотелось попробовать сделать
Забегая вперёд, скажу, что проблему решить вполне удалось. Я разделил игру на два процесса, один из которых опрашивает клавиатуру и сообщает о нажатии второму при помощи сигналов — USR1, USR2 и HUP, как раз три сигнала по трём управляющим клавишам — „←“, „→“ и «пробел». Последняя нужна, чтобы пускать шарик.
Решил сделать «Арканоид», не совсем классическую версию (на неё мне ещё бы пара вечеров потребовалась), но близкую. В игре есть три типа блоков разных цветов — вишнёвый разбивается сразу, синий при первом ударе превращается в вишнёвый, а от зелёного (самое интересное!) при ударе иногда отваливается часть, поймав которую, можно получить приятный бонус — более широкую ракетку, дополнительную жизнь или липкость. Последнее означает, что шарик в этом режиме не отскакивает от ракетки, а прилипает.

Ещё одна фишка игры — звуковое оформление, которое нечасто услышишь в консоли, я думаю. Правда, только для «Мака» (сделано командой «say», я заставляю её проговаривать буквы с большой скоростью), знаю, что для Линукса тоже есть команды для синтезатора речи («espeak», например), но мне негде их попробовать.
В игре пять жизней и пять уровней, кстати второй посвящён моей любимой жене, большой любительнице кошек (этот уровень как раз на скриншоте). Я сделал щадящую скорость полёта шарика, так что игру можно пройти даже без потерь, если хорошо потренироваться. Код, как водится, выложен на «Гитхаб».
От терминала, как и в шахматах, требуется уметь отображать 256 цветов и хорошая поддержка «Юникода». Нигде, кроме как под «Мак» игру я не тестировал,
Я записал небольшое видео игрового процесса. Я попробовал две программы для записи видео с экрана — «Скрини» и «КвикТайм», к сожалению обе нагружают процессор так, что игра начинает тормозить.
Видео выложил на «Яндекс.Видео». Добавлено позднее: сервис «Яндекс.Видео» прекратил своё существование.
Опять столкнулся с изменившимся АПИ «Гугл Гоу»
Обновил компилятор до r59 и сразу пришлось менять код моего «МэйкКорнера — в модуле strings метод Split теперь называется SplitN, а Split делает то же самое, что SplitN с последним параметром
Перл «Яндекс.Переводчика»

Ах, если бы…
Новое слово: «готовки», «рео»

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

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

Я пока так и не решил как я отношусь к ломографии, но попробую ей попользоваться, чтобы понять как. На снимке — площадь Свободы в Казани.
Добавлено позднее: я тут ввёл, наверное, в заблуждение всех термином «ломография». Я имел ввиду не сам процесс съёмки специальным фотоаппаратом на плёнку всего подряд, а скорее результат, который сейчас добиваются специальными фильтрами, снимая на обычный сотовый телефон.
Фотки можно добавлять ещё и с picplz.com
Внёс важное изменение в движок сайта — фотографии теперь можно добавлять ещё и с сайта «Пикплз». Вообще я переделал весь механизм добавления сайтов с картинками.
Ничего не должно было сломаться, но если будут баги, пишите. В комментариях к предыдущему посту добавил картинку с сервиса «Пикплз»— вид на Казань из окна офиса «Яндекса» в Казани
Какие ещё сервисы картинок добавить? Два жёстких требования — они должны быть с регистрацией (чтобы мне не постили всякую порнуху) и имели АПИ для получения информации о фото (чтобы я мог выбрать подходящие размеры картинки).
Добавлено позже: теперь ещё и «Фликр» работает.
Казань → Самара → Казань
Чудо-лампочка

Купили с женой в «Метро» лампочку фирмы «Осрам», насколько я разобрался в их каталоге, это «DULED Twist 21 W/827 B22d».
Лампочка, может, на чудо и не тянет, но комфорт дома чудесным образом увеличивает. Дело в том, что у этой лампы два режима.
Сразу после включения, лампочка, в режиме ночника неярко светит двумя светодиодами, потребляя всего 0,3 ватта. Если её выключить и сразу включить, то начинает работать основная энергосберегающая лампа в 21 ватт (эквивалентна лампе накаливания в 90 Вт). Очень удобно перед сном или ночью, когда спальню нужно осветить
Немного Казани
Пока шёл из машины на корпоратив, сделал несколько снимков вечерней Казани.

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

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

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

В моём «Списке желаний» на «Ярушке» есть «Летающая акула» — забавная надувная игрушка, которой можно развлекать друзей. Акула надувается
Мы очень обрадовались, когда на одном из клонов «Групона» мы обнаружили предложение, позволяющее купить эту рыбу с 50% скидкой. Если судить по приведённым фотографиям и роликам, эта та самая игрушка, которую мне так хочется.
Напрягало только, что цена удивительно низкая —
Жена, умница, нашла в интернетах страницу «Глобимпорта» — импортёра из Китая, где использовались всё те же завлекательные фото и ролики, но зато видно реальную упаковку поставляемого товара.
Вооружившись поиском по картинкам я в пять минут нашёл китайский аналог «летающей акулы» стоимость в 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 sellinfrared-controlled Air Swimmers to other retailers. Otherwise, the two products are very similar.
Одну продаёт магазин игрушек «Тойс Ар Ас», вторую — все остальные. Пульт первой, радиоуправляемой модели, как легко выяснить, питается от одной девятивольтовой батарейки, тогда у второй модели управление происходит инфракрасным передатчиком, который питается от трёх батареек ААА, это написано на том же «Амазоне».
Упомянутый магазин продаёт модель, которой требуются четыре батарейки ААА (одна в «рыбу», остальные — в пульт), при этом в рекламе на клоне «групона» говорится о радиоуправлении. Китайская рыбка — именно радиоуправляемая и требует для питания батарейки AAA.
Противогаз для младенцев


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

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