24.12.2020Странные увлечения
Когда я смотрю на свои увлечения со стороны, мне и самому они кажутся очень странными. Я попадаю в какие-то крайне маргинальные сферы. Причём иногда с каким-то совершенно космическим опозданием. Отчего они ощущаются ещё более маргинальными. Вместо того, чтобы прогуливать пары с любителями MTG в универе, я внезапно подсел на неё через десять лет, когда найти партнёров в своём кругу уже не так-то просто. Вообще найти людей, сходящих с ума сходным со мною образом, довольно трудно. К тому же я почти не умею поддерживать социальные связи. Я знаю нескольких человек, которые это как-то умеют и делают в мою сторону, но сам я не особо стремлюсь инициировать контакты без повода. При этом, конечно, друзья мне дороги, и контакты с ними нужны, но по пустякам их как-то беспокоить не хочется. В связи с этим, кстати, и пандемия на моей повседневной жизни не особо сказалась.
В итоге кажется, что всеми моими странными хобби мне не с кем поделиться. А это вообще-то интересно :).
Как-то нашёл я на Ютюбе Бена Итера (Ben Eater), который собирал на макетной плате четырёхбитный компьютер. Смотрел весь плейлист просто запоем. И вот на прошлое Рождество он начал новый проект — компьютер на базе процессора 6502 всё на тех же макетных платах. И не просто так, а на американский манер ещё и наборы продавать решил. Получил я на почте этот набор, а у Бена под Рождество, да ещё и с таким количеством заказов, в видео образовалась пауза. А в Берлине на праздники делать особо нечего. Пить я почти не пью, по гостям ходить — смотри выше, погода — не очень, да ещё и магазины закрыты. И вот я сам без видео сел, прочитал все спецификации от производителей компонентов и компьютер собрал. Потом заказал на Амазоне другой дисплей, кнопок ещё, потом ещё микросхем, потом схему соединения доработал, и так Бен меня уже в своих тьюториалах за год и не догнал.
Ещё на работе у нас был товарищ, который увлекался механическими клавиатурами. И вот, казалось бы, можно в хобби уже не одному, а с кем-то. Но дружба у нас не задалась. А клавиатур я тем не менее себе собрал две. Причём одну я даже — отчасти поневоле — модифицировал. Подсветку мне было интересно припаять, а вот обычный диодик у меня отлетел, потому что корпус в него упирался в месте крепления. Пришлось припаять такой, который при сборке не мешается. Но хобби интересное. Можно спустить все деньги при желании. Спасает только то, что красивых кнопок с кириллицей очень мало.
И тут внезапно возник у двух последних хобби микро-фьюжн. Я сделал клавиатуру для своего ретро-компьютера. Причём я помню, как раньше было сложно делать печатные платы. В детстве хотел собрать радиоуправляемую машинку, а отец зажилил мне хлорного железа. Он хранил его для своего несбыточного проекта светомузыки. Тогда я вычитал в технике молодёжи, что можно платы травить электричеством. И вытравил плату с помощью китайского блока питания, большой разогнутой канцелярской скрепки и ватки с раствором столовой соли. Моя машинка в итоге, как и отцовская светомузыка, упёрлась в отсутствие нужных деталей в магазинах. Но сегодня это просто какое-то чудо. Печатные платы стоят смешных денег, любые детали можно заказать по почте, даже припаять за тебя могут, даже, наверное, и играться потом за тебя с удовольствием будут, если опцию выберешь на сайте.
В общем, немножко паяльника, немножко ассемблера и вуаля — ретро-компьютер понимает нажатия 16 клавиш в любых сочетаниях. Задача минимум, чтобы уже по-настоящему называть его компьютером, — это дописать такую ОС для него, чтобы можно было на этой клавиатуре его программировать. Пусть и самым простым придуманным языком.
09.07.2018Счастливый коммит 2.0
В далёком 2010 году писал скрипт для того, чтобы определить, счастливый ли последний сделанный коммит. Это когда у хэша коммита, как и у номера билетика, сумма цифр первой половины равна сумме цифр второй. Долгое время он у меня работал. Событие не только случайное, но и редкое — от этого ещё более приятное. Потом Илья сделал нам телеграм-бота, который постил все сделанные коммиты в проектах «нек4» в телеграм-чат. В том числе и поздравлял со счастливыми.
В текущей команде сначала пришлось, конечно, объяснить смешное понятие счастливого билетика. Если пересказывать кому-то из другой культуры, становится очевидно, насколько в нашей культуре сильны суеверия. Фактически, человек доверяет себя совпавшим цифрам. Полученная исполнением ритуала удача должна не только отвести контролёра от маршрута, но и помочь где-то дальше.
Для популяризации этой нелепой традиции я переписал скрипт на баше. Руби всё-таки неспешный. Можно почувствовать, как он спотыкается об эту проверку, особенно если ты стремительный инженер. Это не самое элегантное решение, но отдельную гордость вызывает то, что проверка работает на Маке и Убунте из коробки. Самые болезненные при переносе скриптов обычно как раз sed’ы и grep’ы. Скрипт нужно положить в .git/hooks/post-commit и сделать запускаемым.
#!/bin/bash
SHA=$(git log -1 --format=format:"%H" | tr /a-f/ /A-F/)
EQL=$(echo ${SHA:0:20}==${SHA:20:20} | sed 's/\([0-9A-F]\)/\1+/g' | sed 's/+$//' | sed 's/+=/=/' | awk '{print "obase=16; " $0}' | bc)
if [ "$EQL" == "1" ]; then
echo
echo ' ******************************'
echo ' * Yay! Lucky commit! *'
echo ' ******************************'
echo
fi
Но что делать дальше, после того, как его закоммитил, я пока не придумал. Как его съесть..? :-Е
12.02.2018Лось квайн
Давненько я не писал чисто программерского! Есть такая прекрасная маргинальная область: бесполезная дурня. Для меня — это совершенно точно искусство, как оно есть, только для очень узкого круга людей. Более ли менее известный пример — это Simone Giertz – Королева говёных роботов. Я сам бесконечно уважаю бесполезную дурню. О некоторых штуках я даже писал ранее. Например, про лося в терминале или про JSFuck. Сегодня хочу рассказать про моё свежее улечение — квайны. И похвастаться, конечно.
Про программы, которые выводят собственный текст, я слышал уже давно. Это казалось чем-то очень навороченным и неприступным. Если нет специальной функции для этого и нельзя читать файл, то не совсем понятно, с какого бока начинать. Но тут как раз перед выходными мне прислали статью, которая подводит под это дело теоретическую базу. В силу не совсем профильного образования, мне не довелось серьёзно заниматься теорией вычислений, а это оказалась довольно прикольная область.
И вот, наступил викенд, и меня сильно это дело вштырило. Вооружившись теоретическим доказательством того, что на любом языке программирования можно написать квайн, я приступил к составлению своего корявого решения. К концу выходных я написал двухступенчатый квайн, который при каждом запуске выводит следующий шаг моего лося из репортера.
В силу личного склада, это походило на зависимость. Чуть голова не разболелась. Главное в это деле — вовремя остановиться. Сейчас в репозитории есть усовершенствованная версия с гифки выше, версия, которая анимирует пробег лося по парамтерам, а так же версия в технике аски-графики. Примечательно, что не смотря на отсутсвие примеров, я пришёл к оптимальному варианту, который многие используют, когда хотят чтобы квайн, кроме своей непосредственной функции делал ещё что-то такое же бесполезное и прекрасное.
eval a = <<-'a'
# Мой код
puts "eval a = <<-'a'\n#{a}a"
a
После пошёл читать код такого же любителя странного — Юсуке Эндо (Yusuke Endoh). Он, среди прочего, написал квайн-реле, которое выводит на каждом шагу код на другом языке. И если его запустить на 128 языках 128 раз, то оно выведет обратно исходный код на первом языке. Чувак тоже относится к программированию как к искусству. Странному, гиковскому, маргинальному, нердическому, но при этом Великому и Бессмысленному Искусству. Например, он написал книгу, которая называется «The World of Obfuscated, Esoteric, Artistic Programming». Конечно же, на японском. И врядли её переведут ( ≧Д≦) Или у него есть «Квайн, устойчивый к радиации», из которого можно удалить одну любую букву и он при запуске выведет восстановленный исходный код. Ещё и в аски-графике.
Вот вам видео последней версии квайна, вдохновленное товарищем Эндо. Отлично провёл время, в общем. А у вас как дела?
Материалы для самостоятельного изучения
10.03.2016Эзотерический джаваскрипт
Конечно, это уже не новая история, но меня настолько впечатлило, что я решил написать внеочередную статью. Тем более, что и ребята из ибэя тоже пропустили известие о том, что можно писать валидный джаваскрипт, не используя букв и цифр. Поскольку статья внеурочная, то и иллюстрации сегодня не будет. К тому же фиг проиллюстрируешь эти эзотерические языки программирования.
Что случилось?
Началось всё, я так понимаю, ещё в 2009 году с обсуждений на форумах sla.ckers.org потенциальных возможностей межсайтового скриптинга. Но там ещё был другой синтаксис. Впечатливший же меня пример написания джаваскрипта обнаруживается только в 2012 году. Были и раньше другие заходы. Например, джаваскрипт из японских смайликов. Я же узнал об этом от товарища, который прислал мне ссылку на the daily wtf.
Позволю себе немного пересказать, а дорогому читателю предлагаю прямо открыть консоль и попробовать. Вся эта штука основана на конвертации типов в джаваскрипте при сложении или приведении к булевым значениям. Программировать на джаваскрипте можно всего лишь с помощью восьми символов: [, ], (, ), {, }, ! и +. Вот, что выдаёт мне консоль в ответ на ввод:
> +[]
0
> !+[]
true
> !!+[]
false
> +![]
0
> +!![]
1
> +!![]+!![]
2
> +!![]+!![]+!![]
3
И вот у нас уже есть числа и булевы константы. Теперь нам нужны буквы:
> !![]
true
> !![]+[]
"true"
> ![]
false
> ![]+[]
"false"
> +!![]+!![]
2
> +!![]+!![]+[]
"2"
> ({})
Object {}
> []+{}
"[object Object]"
> ({}[+[]])
undefined
> ({}[+[]])+[]
"undefined"
> +{}
NaN
> +{}+[]
"NaN"
Далее все строковые значения можно получить, комбинируя вышеизложенное, но я буду писать строки в виде строк, чтобы облегчить (сделать возможным) прочтение кода. Используя уже имеющиеся буквы и цифры, можно ещё получить:
> +"1e1000"
Infinity
> +"1e1000"+[]
"Infinity"
> +"1e100"
1e+100
> +"1e100"+[]
"1e+100"
Все буквы (a, b, c, d, e, f, i, j, l, n, o, r, s, t, u, I, O, [, ], <пробел>, +) можно доставать из строк, с помощью квадратных скобок и чисел. Но мы уже давно можем сделать eval — исполнить произвольный код из строки:
> (![]+[])[3]
"s"
> (![]+[])[3]+([]+{})[1]
"so"
...
> []['sort']['constructor']
function Function() { [native code] }
> []['sort']['constructor']('return alert')()
function alert() { [native code] }
> []['sort']['constructor']('return alert')()(1)
/* должен выскочить алерт */
Дело остаётся за малым — получить все остальные символы, с помощью которых можно написать программу. Чтобы уже совсем не чувствовать стеснения. И тут нам на помощь должна прийти функция unescape, которая из знака «%» и аски-кода делает символ. Но у нас пока нет для этого символов «%» и «p». Где же их взять?
> []['sort']['constructor']('return location')()
Location {hash: "", search: "", pathname: "/blog/posts/48", port: "", hostname: "lonelyelk.ru"…}
> []['sort']['constructor']('return location')()+[]
"http://lonelyelk.ru/blog/posts/48"
> ([]['sort']['constructor']('return location')()+[])[3]
"p"
> ({}+[])[0]
"["
> []['sort']['constructor']('return escape')()('[')
"%5D"
> []['sort']['constructor']('return escape')()('[')[0]
"%"
> []['sort']['constructor']('return unescape')()('%'+'7a')
"z"
Не знаю, как ты, дорогой читатель, а я нахожу такое использование джаваскрипта совершенно волшебным. Настолько волшебным, что даже несмотря на уже не первую свежесть темы, мне очень захотелось об этом написать, да ещё и в неурочное время. Все материалы для самостоятельного изучения доступны по ссылкам выше.
02.03.2016Лось
Сейчас меня уже почти не спрашивают: «Почему лось?» Отчасти потому, что я не очень продвигаю этого персонажа, а отчасти потому, что люди думают, что мне просто нравятся лоси, или я их коллекционирую. Второе приводит, например, к тому, что мне дарят разных игрушечных лосей. Это забавный результат, поэтому я считаю, что репутацию местного сумасшедшего нужно поддерживать. Как следствие я начал использовать лосей в повседневной работе.
Терминал
Первым делом нужно, чтобы лось приветствовал меня при каждом открытии терминала или новой его вкладки. Примерно так:
При этом хотелось бы, чтобы у него было разное случайное выражение лица. Для этого нужно в ~/.bash_profile (или какой у вас файл для создания окружения) написать следующее:
eye=(o O @ . - \* \~ °)
let left=${RANDOM}%${#eye[*]}
let right=${RANDOM}%${#eye[*]}
cat << EOF
_ _ _ _ _
| || | ____ | || || |
\ |/ \| /
\____ ${eye[$left]} ${eye[$right]} ______/
| |________
| }=
| __ ____ _ |
|| || || ||
|| || || ||
"" "" "" ""
EOF
Базовая работа с массивами. Встроенная в баш функция случайного числа. Обязательно предварять косой чертой «*» и «~», чтобы они не стали списком файлов и домашней директорией. По-моему — красота!
Spec runner
И, конечно же, для любителей разработки через тестирование нужен правильный репортер:
Здесь нужно пользоваться эскейп кодами для управления положением каретки, то есть курсора. Мало кто помнит, но курсор можно двигать во все стороны на любое количество позиций. Данный пример я собрал для раннера тестов на жасмине. Да, да, я разрабатываю в том числе на node.js и тестирую с помощью jasmine. Ключевая функция для рисования лося вот:
function printElk() {
if (specCount > 1) {
print('\x1b[5A');
}
if (specCount % 2 === 0) {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '~( _ /\n');
print(Array(specCount + 1).join(' ') + ' || ||\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
} else {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '`( _ /\n');
print(Array(specCount + 1).join(' ') + ' // \\\\\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
}
}
Здесь specTrail и eyes следят за историей вопроса, а вся функция вместо того, чтобы как раньше, ставить точку или F, поднимается на пять строчек вверх и переписывает их полностью.
Бонус
Это не про лося, но тем не менее. Вообще, я считаю, что всегда лучше потратить немного времени, чтобы сделать всё удобно и интересно. Мелочи решают!
Эту вещь придумал не я. Скорее всего, до меня её придумали неоднократно, и я не могу найти первоисточник. Тем не менее, считаю, что это очень полезная вещь, и нужно ей поделиться. Речь идёт о том, чтобы показывать статус завершения предыдущей команды в строке запроса баша.
export PS1="\[\e]0;\u@\h: \W\a\`if [ \$? = 0 ];then echo \[\e[32m\]^_^\[\e[0m\];else echo \[\e[31m\]o_O\[\e[0m\];fi\`[\u@\h: \w][\$(rvm-prompt v)][\$(nvm_version)]\$(parse_git_branch)\$ "
Это моя строка запроса. В её начале мы видим или зелёный довольный смайлик, или красный удивлённый. Благодаря вот этой части:
\`if [ \$? = 0 ];then echo \[\e[32m\]^_^\[\e[0m\];else echo \[\e[31m\]o_O\[\e[0m\];fi\`
Когда сделал себе и привык, то теперь просто не понимаю, как другие без этого обходятся.
Материалы для самостоятельного изучения
28.05.2010Dog's dream
Плавно в течение суток мой бложек перетёк на новый хостинговый план. Со скоростью распространения информации по DNS. Кто-то, возможно, в дальних уголках интернет-пространства видит всё ещё старую копию. Хотя, на глаз не отличишь :)
♯♯♯
А ещё мне не хотелось поднимать свой почтовый сервер, и я узнал, что существует Яндекс почта для домена. Это гениально!
♯♯♯
Сегодня в комментариях (а мне нечасто в блоге пишут комментарии) некто Дмитрий подкинул мне прекрасную идею про «счастливый коммит». Это коммит, у хэша которого сумма левых 20-ти шестнадцатиричных цифр равна сумме правых 20-ти. Конечно же я тоже написал скрипт (конечно же на руби), который проверяет каждый коммит. И коммичу теперь почаще:
#!/usr/bin/env ruby
if `git log -1 --format=format:%H`.chars.each_slice(20).map{ |part| part.inject(0){ |sum, ch| sum + ch.hex } }.uniq.count == 1
puts '**************************************'
puts '* Congratulations! Lucky commit! *'
puts '**************************************'
end
♯♯♯
Наконец-то добрался и посмотрел последнюю серию:
via kuteev
Обтекаемо закончили :) Не то, что старик Линч.