Избранное

«Тетрис» на Brainfuck ★

Ну разумеется я вчера не смог уснуть без того, чтобы не посмотреть что ещё мог бы написать ИИ на «Брейнфаке»! Попробовал написать «Тетрис», тем более что у меня были готовые идеи как это сделать. Правда для этого пришлось модифицировать интерпретатор. Свой собственным, разумеется, который я начал писать ещё в 2001-м году, надо бы про него рассказать тоже однажды.

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

Чтобы приступить к «Тетрису» пришлось сделать две модификации.

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

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

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

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

Скриншот игры BF TETRIS: цветные блоки заполняют поле, справа — управление (←/→ move, ↑ rotate, ↓ drop, q quit), следующий блок и счётчик линий (lines 4).

Как легко догадаться по скриншотам, нейросеть (я использовал «ГПТ-5.5») отлично справилась с задачей. Но что интересно, чтобы это сделать она реализовала ровно ту идею, про которую я писал в прошлый раз — написала генератор на ПХП, при помощи которого сгенерировала программу на «Брейнфаке». Немудрено — программа получилась монументальной — под сотню мегабайт в первой попытке.

Я даже сделал в своём интерпретаторе поддержку сжатия исходников. Наверное никому раньше не приходило в голову этим заниматься — как правило программы на «Брейнфаке» пишут люди и до таких размеров они их не доводят.

Трансляция такого огромного файла и применение оптимизаций занималось около 15—20 секунд на моём ноутбуке, так что пришлось применить ряд оптимизаций — немного переписать парсер интерпрератора, сделать кеширование и поработать над уменьшением размера кода «Тетриса».

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

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

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

ИИ: умрёт ли профессия программиста ★

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

И дело не в наивном оптимизме. Дело в механике развития технологий.

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

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

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

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

Потом пришли ассемблеры. Потом компиляторы. Потом высокоуровневые языки. Потом фреймворки. Потом облака. И всё заверте…

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

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

И что именно из этого следует?

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

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

Схема цепочки создания ИС: поиск проблематики, анализ, ТЗ, UX, разработка, тестирование, приёмка.

Нейросеть может помочь почти на каждом этапе. Но помощь и замещение — разные вещи.

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

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

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

Автоматизация всегда убирает уровень ниже. Программисты просто поднимаются выше.

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

ИИ не отменяет сложность. Он лишь сдвигает её на другой уровень абстракции.

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

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

Локальные адреса в «Веб-архиве» ★

Я тут благодаря «Виоле» обнаружил кое-что интересное в «Веб-архиве».

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

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

Я не учёл, что локальные адреса — localhost, 127.0.0.1 и прочие — не должны искаться в «Веб-архиве», ведь из интернета их не видно. Вчера случайно я запустил «Виолу» с URL http://localhost/, и вдруг у меня начал открываться какой-то сайт на японском.

Оказалось, «Веб-архив» хранит зеркала каких-то случайных сайтов, доступных по локальным адресам и портам бог знает каких сетей. Я навскидку посмотрел несколько адресов — 127.0.0.1:8080, 192.168.0.1 и так далее — и обнаружил около десятка разных сайтов. И это только вершина айсберга!

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

Попробовать что ли сканер написать, который составит список всего этого богатства…

Скриншот веб-страницы 1996 года: заголовок «熊本大学教養部», приветствие на японском, счётчик посетителей (116), дата 12-29-96, время 8:25 PM, кнопки «東光とは?」 и «ファイル倉庫».

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

«Виола»: предок VRML ★

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

Началось всё с того, что я заметил в браузере едва начатую реализацию тегов, помеченную комментариями как /* vr exp */. В исходном коде нашлась целая группа таких тегов. Назначение некоторых из них, например OVAL или LINE, было вполне очевидным, тогда как то, что в точности могли бы делать некоторые другие теги, например ACTION или BUTTON, было не вполне ясно.

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

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

Скриншот веб-страницы «Proto-VRML Graphics Demo» с примерами: жёлтые фигуры на розовом фоне, треугольник и пятиугольник, простая красная домик с солнцем.
Готовая реализация графики, которая сейчас работает в браузере

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

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

Вот, например, как на этом языке рисуется синий квадрат с тёмно-синим бордюром на светло-сером фоне в координатах x=10, y=20, повёрнутый на 45°:

<GRAPHICS WIDTH=400 HEIGHT=120>
<BGCOLOR NAME="lightgray"></BGCOLOR>
<RECT ID="rect1">
<POS X=10 Y=20></POS>
<SIZE X=70 Y=70></SIZE>
<FGCOLOR NAME="blue"></FGCOLOR>
<BDCOLOR NAME="navy"></BDCOLOR>
<ROT Z=45>
</RECT>

Особенно меня почему-то зацепил атрибут SC о роли которого я бы никогда самостоятельно не догадался. Автор описывал его так:

The SC attribute says that whenever the attributes in this object changes, relay the change to a server that broadcasts the change to all other browsers looking at this object… Have to think about this more…

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

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

Скриншот веб-страницы «ACTION Script Demo - Clickable Shapes» с цветными геометрическими фигурами и описанием их интерактивных свойств (вращение, масштабирование, смена цвета).
Активные объекты, содержащие атрибут SC рассылают свои изменения по локальной сети

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

Пришлось делать специальный таймер, который будит приложение, если ему адресованы интерактивные UDP-пакеты.

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

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

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

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

Скриншот окна браузера ViolaWWW с заголовком «Geometric Art - ViolaWWW Graphics Demo» и геометрической композицией из разноцветных фигур на сером фоне.
Пример с узорами, нарисованный при помощи реализованных графических примитивов

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

Обратная разработка GIFLITE.EXE ★

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

Когда-то давно, когда я активно верстал, формат GIF был одним из самых ходовых, для анимации так вообще альтернатив не было. И мы в то время в обязательном порядке занимались оптимизацией графики.

В случае GIF очень хорошо помогала известная утилита GIFLITE.EXE — коммерческая разработка компании «Вайт Ривер Софтвейр» (White River Software), которая, по всей видимости, давно исчезла, так как я про неё ни в какой другой связи никогда ничего не слышал.

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

Скриншот терминала: слева — справка по команде giflite (сжатие GIF), справа — результаты теста пиксельного сравнения 925 файлов (923 прошли, 2 пропущены из-за ошибок сжатия).

Она всегда меня интриговала — было интересно что она вообще такое делает, как ей удаётся уменьшить размер гифа и чем отличаются её методы сжатия, которые задаются ключом -m.

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

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

А теперь, немного подробностей.

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

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

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

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

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

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

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

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

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

В полным соответствии с принципом Парето, 20% кода отняло у меня 80% времени. Тут очень хорошо показал себя Opus 4.5, — поскольку в коде разобраться было сложно, там 40 тысяч строк на ассемблере, он ставил очень много эксприментов, сравнивая два набора файлов между собой — тот, который получался при запуске оригинального GIFLITE.EXE с нашим.

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

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

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

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

«Виола» и моя мечта: как ИИ снова мне помог ★

Вступление

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

Узнал я об этом из статей о судебной тяжбе компаний «Микрософт» и «Иолас» (Eolas), начавшейся в 1999-м году.

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

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

Скриншот ViolaWWW: заголовок «Front-Ending External Programs», описание встраивания front-end для XPlot, жёлтый каркасный самолёт на синем фоне.
Скриншот того как это выглядело в первой половине 1990-х

Что мешало

Но оказалось, что исполнению моей мечты мешало несколько обстоятельств.

Во-первых, на самом деле модель вращала утилита V-Plot, написанная Скоттом Силви, который учился вместе с автором «Виолы». Её исходники не сохранились.

Во-вторых, судя по сохранившимся исходникам веб-страницы, вращались две модели, которые назывались TomCat и x29.geom, которые ещё нужно было найти.

В-третьих, как оказалось, часть, которая должна взаимодейстовать с V-Plot не работала.

Вопрос №1: где взять V-Plot?

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

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

Оказалось, что специальный «объект» TTY «Виолы» для взаимодействия с программами, которые могут выводить графику в окно браузера, реализован только для «Линукса», а для «МакОСи» (в «Виоле» встречаются куски для очень старой версии этой операционной системы) код реализован не был.

Я как можно тщательнее, как зловредному джину, описал что именно хочу получить и опять переключился на свои дела. И вот тут, когда я без особой надежды вернулся через какое-то время посмотреть на то как нейросеть провалила задачу, меня ждало маленькое чудо: в окне, где должны выводиться модели, появилась жёлтая сетка — самодельный V-Plot делал что-то полезное!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и описанием демонстрации встраивания объекта viola для связи с процессом построения графиков XPlot.
Сетка — признак того, что взаимодействие с V-Plot работает!

Здо́рово! Но где же мои самолётики?

Настал момент узнать откуда же брались самолёты. Оказалось, что «Виола» передаёт на вход V-Plot одну из моделей, которые выберет пользователь — там на выбор несколько графиков и две модели в формате OFF (Object File Format). Моделей в комплекте с исходниками браузера не оказалось.

Ориентируясь на приметное имя x29.geom, я решил поискать эту модель, вдруг это что-то известное. А параллельно зарядил ChatGPT глубоким поиском.

Модель действительно оказалось известной — её когда-то изготовила компания «Эванс энд Сазерлэнд», а потом использовали на европейской выставке 1987 года, электронные материалы которой каким-то чудом уцелели и доступны для скачивания.

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

Дальше нейросети меня опять удивили — посмотрев на мой найденный файл, сеть для программирования «Опус 4.5», не моргнув глазом, написала мне за каких-то несколько десятков секунд код для парсинга и отображения этого формата. И вот я уже вращал свой первый самолёт!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs», описанием демонстрации встраивания объекта и желтым 3D-графиком XPlot на синем фоне.
Браузер «Виола», вращающий модель самолёта Grumman X-29 в трёх измерениях

Отлично! А что со второй моделью?

Со второй моделью так гладко не вышло — как я ни старался, ничего путного по слову TomCat на нашёл. Решил смириться и найти хоть какую-нибудь модель того же самолёта — ChatGPT определила, что на картинке нарисован Grumman F-14 Tomcat.

Тут наконец пригодился глубокий поиск — нашёлся архив внутри которого лежала модель самолёта F-14, но, вот неприятность, в формате IOB (Imagine object). Формат давно мёртвый и единственный конвертор, который я нашёл — бинарный файл под операционную систему «Амига».

Я, было загрустил, но тут решил попробовать уже совсем безумную штуку — натурально попросить нейросеть написать мне конвертор из формата IOB в OFF, причём без описания самих форматов. Самое смешное, что это сработало, причём с первого раза! Получившаяся модель сразу появилась в окне и заработала!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и демонстрацией 3D-модели самолёта XPlot в виде жёлтой проволочной сетки на синем фоне.
Модель Grumman F-14 Tomcat, сконвертированная из формата IOB

Выводы, или Что меня удивило

Лёгкость к которой нейросеть провела обратную разработку команд, написала интерпретатор команд для V-Plot и конвертор, просто поражает! Честно сказать, я на такое совсем не надеялся. Максимум, который я ожидал — полуживой прототип, который придётся отлаживать не один день.

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

Тем не менее, та работа, которую я проделал над браузером при помощи нейросетей, совершенно неподъёмна для человека в такие короткие сроки.

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

Первая BBS в Казани ★

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

Доска объявлений называлась «ORPHAN’S BBS». Модерировали её Амир Шабашвили, с которым я когда-то был знаком, и Марат Якубов. Последний и дал объявление в газету за космические 130 рублей, переплатив за срочность и пятничный номер.

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

Газета «Вечерняя Казань» от 7 августа 1992 года, пятница, № 119 (379), общественно-политическая газета с гербом и орнаментом в шапке.

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

Недавно я выделил время и сходил-таки в библиотеку. Завёл читательский билет и засел за чтение подшивок. Из найденного источника мне было известно, что объявление опубликовано в весной или летом 1992 или 1993-го года в разделе частных объявлений.

Нашёл не без труда, объявление совсем крошечное. Латинского шрифта в газете в те времена ещё не было, поэтому BBS написали как ВВС:

Владельцы модемов! Информацию о первой в Казани ФИДО-ВВС Вы можете получить по тел. 76-85-59.

Объявление: владельцам модемов в Казани — информацию о первой ФИДО-ВВС можно получить по телефону 76-85-59.
Объявление было опубликовано 7 августа 1992 года

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

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

Ненормальное программирование ★

Введение

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

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

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

«Junix» (1999—2003)

Это самый старый из сохранившихся подобных проектов. И, наверное, самый монументальный. Дело было в конце 90-х, тогда ДжаваСкрипт мало кто воспринимал всерьёз. В основном его использовали для какого-нибудь простенького интерактива или, максимум, относительно несложных игр, типа «Тетриса».

Мне же было очевидно, что ДжаваСкрипт уже можно использовать для большего. Я так был уверен в своей идее, что был готов продемонстрировать её всему миру. Проект занял несколько лет — в начальной фазе я занимался им каждый вечер на протяжении нескольких месяцев, а потом изредка реализовывал какие-то идеи. Наверное это очень долго, но с документацией тогда было негусто, кроме того в каких-то вещах я был первопроходцем.

Так у меня получилось что-то вроде эмулятора командной строки «Линукса». Это был первый такой проект в мире и о нём написали все топовые интернетные издания того времени. Я реализовал интерпретатор, похожий на tcsh, несколько утилит и аналог терминала с доступом к файловой системе.

Терминал JUnix v5.52b: вывод команд df (разделы Unix, Storage,1, Cookie,0), ls / (bin/, tmp/, dev/, usr/, etc/), cat /dev/local/storage (Storage,1) и ll /bin.

«JS-FTPd» (2001)

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

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

Используя «LiveConnect» я написал FTP-сервер — на ДжаваСкрипте, вызывая Джаву там, где ДжаваСкрипт что-то не умел. Заодно детально разобрался как устроен протокол FTP, что потом часто пригождалось.

Интерфейс JavaScript FTPD от Евгения Степанищева (2001, Казань) с логотипом Netscape, кнопками Start/Stop и инструкцией «Press "Start" to start server».

«Крестики-нолики» на HTML и CSS (2011)

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

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

Игра в крестики-нолики: три нолика в правом столбике выигрывают партию, красная линия показывает выигрышную комбинацию, под полем кнопка Restart.

«Арканоид» на bash (2011)

В рамках этой игры я хотел испытать две концепции.

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

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

Скриншот игры Space Invaders: красная пушка внизу, ряды зелёных, синих и розовых пришельцев, счёт 25, три жизни, URL bolknote.ru © 2011.

«Шахматы» на языке утилиты sed (2013)

Когда я решил написать шахматы на sed, знакомые, с которыми я поделился своей идеей, подумали, что я сошёл с ума. Ну а как иначе? sed — в их глазах не язык программирования, а текстовый редактор, который умеет менять «кота» на «собаку» в конфигах.

Но мне хотелось доказать, что даже в таком примитиве можно выжать больше, чем кажется. В итоге я провёл две недели в диалоге с регулярными выражениями: заставлял их считать, сравнивать числа в придуманном мной формате 111::11 (так в нём записывается число 302) и имитировать логику шахматного ИИ. Каждый день я порывался бросить: когда код превращался в лабиринт из меток и переходов, а функция вычитания занимала 59 строк, но упрямство перевешивало.

Как я уже сказал, большая часть логики сделана на регулярных выражениях, поверх которых я написал мета-язык, на котором уже и писал шахматы, благо в sed есть способ переиспользования кода. Было очень тяжело, но мне так нравилась идея, что я справился. Это был настолько сложный проект, что его выпуск породил волну публикаций по всему интернету. Информационный гул заметили даже «Гугле» и пригласили на собеседование, но я отказался.

Шахматная позиция: белые — король a1, ладьи d1, h1, пешки b2, f2, g4, g6; чёрные — король g8, ферзь b7, ладья a4, слон c5, пешки b4, b5, d4, f7, g7. Надпись: «Введите команду».

«Тетрис» на языке AppleScript (2017)

Встроенный в «МакОс» язык автоматизации «ЭплСкрипт», кажется, никто никогда для написания игр использовать и не пытался. По крайней мере, я таких попыток не обнаружил. И немудрено — сходу неясно чем бы он мог таким оперировать, чтобы взаимодействовать с пользователем.

Я написал «Тетрис» на нём, когда понял, что графику можно выводить, манипулируя свёрнутыми в точку окнами приложений и опрашивая клавиши регулирования громкости.

На снежном стекле нарисованы чёрными точками контур дома и несколько снежинок, на заднем плане видны ели.

«Морской бой» на клавише «Капслок» (2020)

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

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

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

Таблица с эмодзи волн, взрывов и черепов, расположенных по строкам 01–10 и столбцам А–К на чёрном фоне.

«Вампус» для наручных часов в корпусе «Касио» (2024)

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

До сих пор ношу эти часы почти каждый день, они у меня сейчас самые любимые.

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

Схема эмулятора часов Casio F-91W для игры Wumpus Hunt: экран показывает ID приложения, номер комнаты, действие и опасности (W — Вомпус, Bt — Летучая мышь, Pt — Ловушка).

«Вампус» на командах командной строки (2024)

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

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

Скриншот текстовой игры: список команд (LS, CD, RM, EXIT), вывод «I SMELL A WUMPUS, BATS NEARBY», команда «rm 12 3 2 3 4» и сообщение «AHA! YOU GOT THE WUMPUS!

«PowerShoot» игра, управляемая подключением зарядки (2024)

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

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

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

«Дум» на языке калькулятора bc (2025)

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

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

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

Скриншот игры: пиксельный персонаж стреляет из оружия по белым блокам на чёрном фоне; внизу видны числа 150 и 5.

«Throttling» игра, использующая для отображения мониторинг загрузки процессора (2025)

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

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

Три серых блока на чёрном фоне: «Start» с красным и двумя зелёными кругами, «Process» с секундомером и числом 000048, «Lost» со взрывом и числом 000064.

Заключение

Я отобрал всего несколько проектов из того «ненормального», что я делал. Надеюсь, вполне очевидно, что «ненормальное» программирование я ценю и люблю очень давно. Для меня это не просто странное баловство, а способ изучить какие-то привлекательные идеи и выразить свои чувства по отношению к ним.

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

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

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

Батарейки CR2032 ★

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

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

Горизонтальная диаграмма ранжирования брендов батареек по результатам теста: Nanfu (615.5, 100%), Фотон (595.1, 97%), Renata (588.1, 96%) и другие до Daewoo (395.8, 64%).

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

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

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

7000 и кафе ★

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

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

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

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

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

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

Прошлое: Дни Интернета в Казани ★

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

А. Х. попросил меня помочь, но сначала мне пришлось отказаться — меня ждали на встрече. Позже выяснилось, что встречу передвинули и у меня есть минут 15—20, чтобы спринтом пробежаться по памяти и чем-нибудь поделиться.

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

В конце девяностых—начале двухтысячных в Казани проводились Дни Интернета. Событие, насколько я помню, должно было стать ежегодным, но не стало. Его провели не менее двух раз и в какой-то момент оно благополучно загнулось.

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

Таблица: 15 окт — розыгрыш билета на День Интернета, 8 окт — передача, 1 окт — сюрприз, 24 сен — Степанищев о безопасности.

Я был на двух «Днях». Один из них проводил на свои деньги известный тогда в казанском интернете деятель Daddy Hab, а второй, если мне не изменяет память, провайдер «Сантел-интернет», ныне несуществующий. Но может и не он.

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

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

Как пошутил А. Х., я делился файлами через облако до того как это стало модным.

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

Скриншот письма от 25 октября 1999 года от Степанищева Евгения к теме@tema.ru с темой «День Интернета. 3-я попытка. :)» и ссылками на файлы флайера в разных форматах.

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

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

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

cmd.sh ★

Я тут случайно в спор ввязался — можно ли переписать бат-файл так, чтобы он запускался и выводил примерно одинаковый результат на трёх основных операционных системах — Виндоузе, Линуксе и МакОСи.

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

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

Что ж. Основная моя идея была в том, чтобы заменить команды батника на вызовы баш-функций, которые я спрячу в специальных конструкциях. В Виндоузе файл обработает обычный cmd.exe, на остальных операционках — bash.

То, что мне предстояло адаптировать начиналось вполне стандартно:

@ECHO off
CHCP 1251
CLS

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

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

:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }

Следующее, чему надо научиться — выводить текст в указанной в батнике кодировке. Это просто:

:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }

Если теперь сделать файл запускаемым и добавить впереди #!/bin/bash (и пренебречь тем, что cmd.exe успевает ругнуться на эту строку до очистки экрана), у нас получится следующий файл, работающий во всех трёх операционках (кодировка должна быть Windows-1251):

#!/bin/bash
:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }
@ECHO off
CHCP 1251
CLS
:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }
ECHO. Всем привет

А вот дальше сложнее. Само меню организовано в оригинале так:

SET /p opt=Введите цифру:

IF %opt%==1 GOTO dns_auto
IF %opt%==2 GOTO dnschange
IF %opt%==3 GOTO exit

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

Как быть? Во-первых, сэмулировать функцией команду SET, во-вторвых, упростить это место, чтобы меньше было писать кода на «баше»:

:; SET() { shift; ECHO. -n "${@#*=}"; read -n1 "${1%%=*}"; echo; }
:; CALL() { eval "$(sed 's/%\(.*\)%/$\1/g' <<< "$1")" 2>&-; }

SET /p opt=Введите цифру:
CALL :menu_%opt%

Первая функция парсит команду SET выводит строку после равно, ждёт ввода и записывает значение в имя переменной, указанной слева от равно.

Вторая — заменяет CALL. В ней %variable% заменяется на $variable, выполняется подстановка переменной и получившееся имя выполняется как команда или функция «баша». Конструкция 2>&- нужна, чтобы избежать вывода ошибки в ситуации, если пользователь введёт что-нибудь не то.

Теперь надо как-то научиться определять функции так, чтобы их нормально «видел» и cmd.exe, и «баш». В батнике функции — просто любое место программы, начинающееся с метки и заканчивающееся вызовом GOTO :EOF:

:function_1
ECHO это якобы функция
GOTO :EOF

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

function_1() {
    echo это функция
}

Как это объединить? Я придумал следующий подход:

:; GOTO() { :; };

GOTO ;#start
:function_1 (){
ECHO. это [якобы] функция
GOTO :EOF
:; }

:;#start

В первой строке определяется пустая функция для «баша», потому что эта часть синтаксиса бат-файла нам не нужна.

Ниже идёт строка GOTO ;#start. С точки зрения «баша» тут две конструкции — GOTO, которая вызывает определённую выше пустую функцию и #start — строка комментария, так как в«баше» с «решётки» начинаются комментарии.

В «батнике» же эта же строка будет означать переход к метке с именем ;#start. Этот переход нужен нам, чтобы «обогнуть» строки, которые определены ниже, иначе cmd.exe начнёт сразу их выполнять, а нам этого не нужно. Их нельзя «спрятать» ниже основной программы, так как в «баше» функции должны определены раньше их вызова.

Что происходит дальше? С точки зрения cmd.exe ниже расположена метка :function_1 (как показывают мои эксперименты, часть после пробела просто отбрасывается), потом тело функции, команда её завершения GOTO :EOF и метка с именем :;}.

С точки зрения «баша» там определяется функция с именем :function_1, ниже идут вызовы уже определённых мною функций ECHO. и GOTO, а ещё ниже — уже знакомая нам пустая команда : и фигурная скобка, завершающая тело функции.

Соединяем всё вместе и получается следующая программа:

#!/bin/bash
:; @ECHO() { :;}; CLS() { clear; }; CHCP() { ENC="$1"; }
@ECHO off
CHCP 1251
CLS

:; GOTO() { :; };
:; ECHO.() { echo $@ | iconv -f "CP$ENC"; }; PAUSE() { read; }; 
:; SET() { shift; ECHO. -n "${@#*=}"; read "${1%%=*}"; }
:; CALL() { eval "$(sed 's/%\(.*\)%/$\1/g' <<< "$1")" 2>&-; }

GOTO ;#start

:menu_1 (){
ECHO. Пункт первый
GOTO :EOF
:; }

:menu_2 (){
ECHO. Пункт второй
GOTO :EOF
:; }

:;#start

SET /p opt=Введите цифру:
CALL :menu_%opt%

Мой оппонент признал, что в споре я победил.

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

Пишем на «Флиппере Зеро» по-русски ★

Вкратце: в русским текстом работать можно, но сложно, код лежит на «Гитхабе».

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

Flipper Zero

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

На экране Flipper Zero отображается текст: «Привет, мир! Пишем по-русски на Флиппере Зеро. Евгений Степаницев, 2023». Устройство показано в оранжевом стиле на тёмном фоне.
Вывод русских букв (трансляция с экрана через оболочку qFlipper)

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

Внутри «Флиппера» довольно много всякого АПИ для вывода текста, от незатейливого, выводящего строку в заданные координаты, до довольно навороченного, умеющего переносить и выравнивать текст. К сожалению, с русскими буквами оно работать не умеет.

Под капотом у этого АПИ — очень известная в своей нише библиотека U∞g2, у которой по историческим, видимо, причинам есть два набора функций для работы со строками. Одни принимают только однобайтовую кодировку ASCII, другие работают в Юникоде.

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

Первый из них — canvas_set_custom_u8g2_font.

Чтобы что-то написать русскими буквами, нужен шрифт, который их содержит. Стандартный вывод canvas_set_font позволяет выбрать один из нескольких шрифтов, ни одни из которых кириллицу не поддерживает. Тут и приходит на помощь canvas_set_custom_u8g2_font. Он позволяет выбрать произвольный шрифт пакета U∞g2, — внутри их целая куча и некоторые в названии содержат слово «cyrillic».

Вот как я это делаю:

#include <u8g2/u8g2_fonts.c>
// …
canvas_set_custom_u8g2_font(canvas, u8g2_font_haxrcorp4089_t_cyrillic);

Файл u8g2/u8g2_fonts.c внутри себя содержит шрифты в особом формате, можно открыть его прямо в текстовом виде и посмотреть как всё устроено.

Шрифт мы выбрали, теперь надо что-нибудь вывести. Тут на помощь приходит canvas_draw_glyph. «Под капотом» у него лежит u8g2_DrawGlyph, которая понимает символы Юникода почти без танцев с бубном. Думаю, это чистое везение — наверняка эта функция появилась сильно позднее, поэтому у неё нет двух вариантов для работы с разными кодировками.

Плохая новость в том, что строки в коде мы обычно пишем в кодировке UTF-8, а canvas_draw_glyph ожидает их в UCS-2. Но есть и хорошая новость — в прошивке доступно АПИ для перекодирования, как обычно, великолепно документированное на языке Си.

Но canvas_draw_glyph, как можно понять из названия, выводит только один символ. Как же вывести строку? Достаточно просто — надо вывести её посимвольно, сдвигая координату на ширину символа. Звучит просто, но как это сделать?

Тут нас ждёт очередная засада. Дело в том, что canvas_glyph_width, которая должна бы это делать, принимает на вход только char, при том, что нижележащая u8g2_GetGlyphWidth преспокойно работает с Юникодом.

Поэтому я сделал просто — выдрал реализацию u8g2_GetGlyphWidth себе в исходники. В итоге мякотка моего решения выглядит вот так:

void unicode_draw_utf8_str(Canvas* canvas, uint8_t x, uint8_t y, char* str) {
    FuriStringUTF8State state = FuriStringUTF8StateStarting;
    FuriStringUnicodeValue value = 0;

    for(; *str; str++) {
        furi_string_utf8_decode(*str, &state, &value);
        if(state == FuriStringUTF8StateError) furi_crash(NULL);

        if(state == FuriStringUTF8StateStarting) {
            canvas_draw_glyph(canvas, x, y, value);
            x += unicode_GetGlyphWidth(&canvas->fb, value);
        }
    }
}

Тут unicode_GetGlyphWidth — скопированная реализация u8g2_GetGlyphWidth, а furi_string_utf8_decode используется для кодирования UTF-8-строки в последовательные символы UCS-2.

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

Надпись в «Гитхабе» ★

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

График вкладов за год: 587 правок, слово “NUMBER” из зелёных квадратов по месяцам, шкала активности от «Less» до «More».
Моя панель активности за год на «Гитхабе»

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

Скрипт переводит подготовленную картинку размером 52×7 пискелей в нужную интенсивность коммитов и распределяет их по датам. Для надписи я использовал шрифт silkscreen, русифицированный когда-то Димой Смирновым и чуть-чуть его размыл в графическом редакторе.

Если захотите себе такую же, вам понадобится так же bash, git и утилиты из набора ImageMagick. Создаёте пустой репозиторий на «Гитхабе», привязываете его к локальному, запускаете мою утилиту с картинкой и любуетесь изображением на панели активности.

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

GBox для Huwaei ★

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

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

Скриншот GBox v1.3.36: «Приложения установлены». Иконки: Google, HOHORO, Zoom, Диск, Home Connect, Шоколадница, LG ThinQ, WhatsApp, TES, Верный, Instagram, Gmail, Hommyn, hOn.
Приложение GBox, установленное на моём телефоне; приложения не знают, что они внутри Huawei

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

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

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

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

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

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

О хранении пластинок ★

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

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

Виниловая пластинка «Шаберина 1905 года» с надписью «Заказ № 9049», «Белая», «ноты, оркестр», «2-20722», «Музыка НКИ» и силуэтом фигуры с рупором на этикетке.
Отпечаток одной пластинки на другой — видно отзеркаленную надпись «RUSSIA» и след вокруг «яблока»

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

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

Вывод простой: хранение стопкой портит пластинки, так как под весом стопки одна пластинка может повредить дорожки на другой.

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

DOOGEE S98 Pro ★

В счёт годовой премии решил поменять себе смартфон — вместо служившего верой и правдой почти три года «Хуавея», купил себе тоже «Хуавей», но интереснее. Но об этом как-нибудь потом.

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

Я меняльщикам обычно даже не отвечаю — сразу закрываю диалог без лишних слов. Но сегодня в одном из предложений поменяться мелькнула какая-то незнакомая модель — DOOGEE S98 Pro и я из любопытства решил одним глазком глянуть в интернете что это такое.

Экран смартфона: 19:22, воскресенье, 8 января. Видны иконки Google, Duo, Ассистент, Play, Телефон, Сообщения, Chrome, Камера.
Только что распакованный смартфон DOOGEE S98 Pro

Оказалось, что это смартфон в «походной» комплектации — защищённый (IP68, IP69K, MIL-STD-810G), со стеклом Corning Gorilla Glass 5, с большим аккумулятором (утверждается, что заряд будет держаться до двух с половиной недель), с камерой ночного видения и тепловизором (!).

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

Тепловизионное изображение комнаты с горячими пятнами на полу и мебели; видны температуры: 34,3°C, 66,8°C, 17,7°C; логотип InfiRay в углу.
Сделал фотографию ёлки дома — сквозь неё видно батарею, а на полу — следы от труб системы отопления

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

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

Тепловизионное изображение дивана с отметками температур: 30,9°C на сиденье, 23,1°C на устройстве и 34,8°C справа; логотип InfiRay в углу.
На диване след от недавно сидящего там меня, а температура кота — около 34,8 градусов

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

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

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

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

Надо будет попробовать поснимать днём — интересно какой будет эффект.

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

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

Получил нагрудный знак ★

Перед Новым годом Республика сделала прекрасный подарок: сегодня я из рук министра цифровизации Айрата Хайруллина получил нагрудный знак «За достижения в области информатизации и связи РТ».

Красное удостоверение с золотым тиснением «УДОСТОВЕРЕНИЕ» и круглая эмблема с зелёно-красным дизайном в чёрном футляре на деревянном столе.
Нагрудный знак «За достижения в области информатизации и связи РТ» и книжечка к нему

Предупреждая вопросы: никакого особого статуса этот нагрудный знак не даёт, просто приятное признание заслуг.

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

Грека и рак ★

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

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

Ехал грека через реку,
Видит грека: в ре́ке рак,
Сунул грека руку в реку,
Рак за руку греку цап!

Сегодня веселил этим дочку и она, отсмеявшись, задала очень интересные вопросы: что за грека? через какую реку и куда он ехал? и зачем он засунул руку в реку?

Текст описывает сцену в клубе: обсуждение мировой коммуны, скороговорку про грека и рака, а также визит Зины и чаепитие у Елтышева с маковыми баранками.
Грека едет через реку в литературно-художественном и научно-публицистическом журнале «Красная Новь», №4, 1924 год

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

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

А во-вторых (и тут нас ждёт небольшое открытие), нашёлся ранний (1924 года) вариант скороговорки, в котором история несколько меняется! Он на скриншоте, в этом варианте грека «и рукою рака цап» и это совершенно другое дело.

Вообще в двадцатом веке вариантов концовки было множество: «грека за руку рак — цап!» (Георгий Никифоров, «Кимба», 1926), «рак у грека руку цап» (Бирюков, «Крылатые слова на Урале», 1960) или тот, что на скриншоте (Б. Д. Четвериков, «Атава», 1924 год).

Мне хочется верить, что самый ранний вариант, — опубликованный Борисом Дмитриевичем Четвериковым в «Красной Нови», является исходным, так как в нём больше логики. Если это так, то по меньшей мере один вопрос в истории про греку отпадает сам собой.

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

Интересная операция (18+) ★

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

Меня это сильно удивило — уж очень прогрессивно выглядит. Где 1914-й год и где тема гомосексуальности, а тем более — смены пола.

Титульный лист диссертации Николая Рафаиловича Барановского «Операция образования искусственного влагалища из прямой кишки», Санкт-Петербург, 1914 год, среди старых книг.
Операція образованія искусственаго влагалища изъ прямой кишки. С.-П., Типография В. Ѳ. Киршбаума, 1914

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

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

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

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

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

Голос Александра III? (вряд ли) ★

Портрет мужчины в красной военной форме с золотыми эполетами, синей лентой через плечо и медалями на груди, в овальной раме.
Александр III Александрович (1845—1894) — император Всероссийский, царь Польский и великий князь Финляндский. Отец последнего российского монарха Николая II

Оказывается в интернете есть аудиозапись, на которой, по одному из предположений, звучат голоса Александра Третьего и его супруги Марии Фёдоровны.

Запись была сделана на восковой цилиндр между между 1889 и 1893 годами в резиденции датского короля во Фреденсборге генеральным консулом Готфридом Рубеном, который в период 1889—1897 годов записывал известных певцов и актеров того времени, а также важных высокородных гостей членов монаршей семьи на недавно изобретенном фонографе.

В 2007-м году Университетская библиотека Дании начала оцифровку коллекции консула и выложила её в интернет на своём сайте, а в 2018 году датский журналист Йенс Корнелиус высказал предположение, что голоса на одной из записей могут принадлежать Александру III с супругой.

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

Из-за способа записи звук неважного качества, а часть записи вообще на датском, поэтому без расшифровки некоторые места не понять:

Женский голос:

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

Мужской голос:

— Вы хотите я говорил что-нибудь вам. Это не всегда так легко, когда вы хотите… И еще вы прибавили, что хотите чтобы я спел что-нибудь. Ну что же, вот, как например, это…

Поёт:

Сам Бисмарк чуть от радости
Не вырвал трёх волос,
Как телеграф известие
Такое нам принес,
Что немцы храбро заняли
Пункт важный и большой
И утверждали в Африке
Права страны родной…
С тех пор в Берлине стар и млад
Одно лишь и твердят:
Nach Afrika, nach Kamerun!
Vivat, Nach Kamerun!
Nach Afrika, nach Kamerun!
Так немцы говорят!
Nach Afrika, nach Kamerun!
Vivat, Nach Kamerun!
Nach Afrika, nach Kamerun!
Так немцы говорят!

Мужской голос:

— Закончим на этом, не могу вам читать сегодня. Если б вы заранее меня предупредили, так это другое дело. Я бы взял с собой книгу или что-нибудь в этом роде, чтобы мне прочитать. А так прямо из головы, это нелегко. Вы меня застали врасплох. И конец. До свидания, господа.

Женской голос (на датском):

— Меня очень веселит слушать голос моего мужа.

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

1 + 1 = 1 ★

Те, кто следит за недвижимостью, наверное знают, что она сейчас растёт в цене, как на дрожжах. Это связывают с очень низкими ипотечными ставками, которыми правительство надеялось поддержать народ в коронавирусное время.

Получилась уникальная ситуация, которой мы с женой решили воспользоваться. Появилась мысль продать две квартиры — пустующую однушку и ту квартиру, в которой сейчас живём, чтобы купить жильё побольше в районе получше. Выбрали ипотеку с государственной поддержкой 0,01/6,5% — то есть первый год одна сотая процента, потом — 6,5.

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

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

При этом весь год мы платим ипотеку под 0,01%, которую надеемся закрыть после продажи второй квартиры, лишь немного «въехав» в 6,5% — сдача нашей новостройки только летом, а потом ещё отделку делать и покупателей искать.

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

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

Кнопка отключения рвотного рефлекса ★

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

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

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

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

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

Осечек пока не было.

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

Три месяца с Huawei (лонгрид) ★

TL;DR: всё круто, мне нравится

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

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

Часы живут больше недели на одной зарядке

Сначала про часы. Я купил «Watch GT 2» — это последнее, что есть сейчас у «Хуавэя» из этого класса устройств. В отличие от «Самсунга» (у меня были «Gear S3 Frontier»), это не смарт-часы, то есть в них нельзя устанавливать приложения. Не знаю минус ли это, так как на все смарт-часы, которые у меня были, я так ничего путного и не установил.

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

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

Наушники всем хороши, но мне особо не с чем сравнить

Теперь наушники. У меня, опять же, последняя модель — «FreeBuds 3». Мне не с чем сравнить, это мои первые беспроводные наушники-вкладыши с чехлом-зарядкой, таких у меня ещё не было. Звук достойный, хотя мне не хватает хороших басов, честно сказать, я не уверен бывают ли вообще «вкладыши» с нормальными басами.

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

Не хватает «Гугла», но это поправимо, долго держит заряд, крутая камера

Теперь, самое главное — смартфон. У меня «P40 Pro+», как вы наверное уже догадались, самое лучшее, что было у «Хуавэя» на момент покупки, и тут самый спорный опыт.

Начну с минусов.

Во-первых, нет сервисов «Гугла». Из всех только без двух по-настоящему тяжко: без магазина приложений и программы для платежей. В собственном магазине приложений «Хуавэя» шаром покати. Для примера, когда я просил совета что поставить на хуавэевский планшет дочки, в местном магазине (если взять список из всего, что посоветовали в комментариях и соцсетях) нашлось только одно (sic!) наименование.

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

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

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

Теперь плюсы.

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

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

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

Планшет появился недавно, пока без выводов

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

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

Расшифровка печати ★

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

Судя по прочитанному, печать принадлежала контролёру кантфинотдела Cпасского кантона. Правда прочтение «СПАССКОГО» спорное, буквы там почти не читаются, но об этом дальше.

Схема с красными стрелками указывает на фрагменты текста на круглом штампе: «РСФСР», «ТАТАРСК», «АПАС КАНТФИ...», «ТАТАР...», «...БАНКА», «КАНТФИНОТДЕЛА», «КОНТРОЛЕР», «СПАССКОГО?
РСФСР; Татарск… банка; Контролёр Спасского Кантфинотдела; 1922—27 гг.

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

Как бы то ни было, в момент своего создания в 1920 году, советский Татарстан делился на десять кантонов: Арский, Бугульминский, Буинский, Лаишевский, Мамадышский, Мензелинский, Свияжский, Спасский, Тетюшский и Чистопольский. На следующий год к ним добавились Агрызский, Елабужский и Челнинский. В последующие года кантоны упраздняли и делили на районы, пока 23 июля 1930 от такого деления не отказались вовсе.

Теперь вернёмся к прочтению прилагательного между словами «КОНТРОЛЕР» и «КАНТФИНОТДЕЛА». Крайние слова читаются достаточно уверенно, в середине видно только «…ОГО» и ещё шесть каких-то букв. Заметим так же, что в надписи по-татарски (арабской вязью) в этом месте есть слово «Апас», — какое-то название.

Чёрно-белое фото: у берега реки стоят деревянные дома, дети и взрослые моют бельё у воды, на заднем плане — лодка и склон.
Город Спасск, он же Спасск-Татарский, он же Куйбышев, он же (если верить «Википедии») Великий Булгар, до затопления

Слово «кантфинотделы» тут тоже малопонятное. Это — местный аналог райфинотделов, финансовых отделов райисполкомов, то есть районных органов исполнительной власти. Поскольку в республике тогда были кантоны, то и отдел не районный, а кантонный.

Далее логика такая, — раз мы имеем дело с кантфинотделом, скорее всего нужное нам слово следует искать среди названий кантонов. По количеству букв подходят только два — «СПАССКОГО» и «БУИНСКОГО». Центром первого был затопленный ныне город Спасск, центром второго — Буинск.

Буинск не подходит по двум причинам. Во-первых, по месту обнаружения находки, во-вторых, Буинск по-татарски называется «Буа», а не «Апас». Из-за схожести звучания, можно предположить, что «Апас» — татарское название Спасска, но нагуглить какое-то подтверждение мне не удалось.

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

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

Кинопроектор инженера Гарина ★

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

Старый кинопроектор с ремнями и мотором, установленный на металлической стойке у кирпичной стены.
Киноаппарат, стоящий в углу ресторана «Максимилианс», что в Казани

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

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

Мужчина в тёмной одежде и с усами стоит рядом с мотоциклом в ночной сцене, освещённой фонарём; на заднем плане видны силуэты скал.
Кадр из фильма «Гиперболоид инженера Гарина» (1965): Евстигнеев, игравший Гарина, нацеливает свой «гиперболоид»

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

Правда на то, что стоит в ресторане не похоже даже отдалённо. А жаль.

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

Бип-бип ★

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

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

Первая страница газеты «Комсомольская правда» от 6 октября 1957 года с заголовком «ПЕРВЫЙ В МИРЕ — НАШ, СОВЕТСКИЙ!» о запуске первого искусственного спутника Земли.

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

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

Но оказывается (и это я узнал из детской книжки), у них была и практическая роль — с их помощью изучали верхние слои ионосферы. Причём сигнал был не один, передача шла на двух разных частотах — 20,005 и 40,002 МГц, один сигнал подавался в паузах второго.

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

И чуть не забыл. Вот вам астрономическая загадка от моей четырёхлетней дочери: «сколько звёзд видно на небе утром?».

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

Кто по национальности Аладдин? ★

Прошлая тема про национальность Ленина неплохо всем зашла и даже в подкаст попала, попробую повторить успех.

В моём советском детстве по телевизору часто крутили фильм «Волшебная лампа Аладдина» 1966 года, многие его помнят по фразе «в Багдаде всё спокойно!», которая потом стала крылатой. Не уверен, что в нём называлась национальность Аладдина, но было вполне очевидно, что это что-то арабско-персидское, из тех краёв.

Гораздо позже появился диснеевский мультик, где царевна Будур сменилась Жасмин, но национальность Аладдина как будто была та же, что и в советской версии.

Два рисунка в стиле гравюры: слева старец с посохом и юноша у надгробия, справа юноша зажигает лампаду перед алтарём с мандариновым деревом и цветами.
Иллюстрация из книги «Story of Aladdin and The Wonderful Lamp», Charles E. Graham & Co., New York, начало 20-го века

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

Где он взял «Аладдина» — дело тёмное, сам он в своих дневниках пояснял, что услышал эту сказку от некого маронитского учёного по имени Ханна Диаб, привезённого в Париж из сирийского города Алеппо прославленным путешественником по странам Востока Полом Лукасом. Но эта версия, вроде как, противоречит некоторым фактам.

Начало сказки «История об Аладдине, или Чудесная лампа»: в столице богатого китайского королевства жил бедный портной Мустафа с женой и сыном.
«Les mille et une nuits», Montreal: Beauchemin, дата издания неизвестна, стр. 274

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

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

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

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

«Магический шар» ★

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

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

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

Использование его в те годы могло бы выглядеть как-то так:

<A HREF=/cgi-bin/action.pl><IMG SRC=/i/pict.gif WIDTH=200 HEIGHT=100 ISMAP></A>

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

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

На тёмном фоне фиолетовый круг с надписью «My sources say no» (Мои источники говорят «нет»).
«Магический шар» из прекрасного фильма «Трасса 60»; с отрисовкой деталей я не стал заморачиваться

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

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

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

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

HTML с таким подходом становится довольно жирным — у меня получился 1,2 мегабайта, но по нынешним временам это не объём.

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

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

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

JUnix ★

Вкратце: выложил на гитхаб свой старый проект «эмулятора» Линукса, который я писал в 90-е и начале 2000-х

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

Мне тогда этот язык невероятно нравился, я был в бешеном восторге и такое вот несерьёзное к нему отношение меня очень задевало. Как-то я фантазировал на тему того, что можно было бы такого интересного сделать в браузере, чтобы показать значимость ДжаваСкрипта, и как-то мало-помалу в голову пришла идея запрограммировать эмулятор «Линукса» — я как раз активно изучал эту ОС в те годы.

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

Скриншот терминала Unix-эмулятора JUnix v5.52b с командами whoami (root), df и mount, показывающими файловые системы и их параметры.
Старый, пыльный JUnix в современном браузере. Пришлось немного повозиться, чтобы запустить

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

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

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

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

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

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

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

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

Кстати, если вам нравится в таком копаться, можете посмотреть сколько костылей в то время приходилось городить и как беден был раньше этот ДжаваСкрипт.

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

Репозиторий проекта: https://github.com/bolknote/junix.
Сайт проекта, где можно посмотреть всё в действии: https://bolknote.github.io/junix.

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

День Радио ★

Сегодня, 7 мая в России отмечают День радио — в этот день, 125 лет назад российский физик Александр Степанович Попов на заседании Русского физико-химического общества продемонстрировал «прибор, предназначенный для показывания быстрых колебаний в атмосферном электричестве».

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

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

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

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

Обёртка и некоторые функции (мигание светодиодом, опрос «Шифта» и функция задержки) написаны на Си, остальная часть — на языке «Лу́а» (Lua). Давно хотелось изучить этот странноватый язык поглубже, а тут ещё удалось поучиться встраивать его в Си.

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

Код на C с вставками Lua: создание состояния Lua, загрузка скрипта battleship.lua или строки PROGRAM, обработка ошибок загрузки.
Диграфы в Си немного запутывают и вносят в код толику безумия

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

Для тех безумцев, которые захотят попробовать скопмилировать этот вариант «Морского боя» и сыграть, ещё раз привожу репозиторий проекта (только под «МакОСь») — https://github.com/bolknote/battleship.

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

Детская частная жизнь ★

Вкратце: есть ли у вас какие-то правила — что можно выкладывать о своих детях в интернет, а что нет?

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

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

Но эти видео — история более-менее приватная, их видим мы и бабушки-дедушки.

Теперь же я задумался над тем как и что писать о дочке тут — как она отнесётся к написанному, когда вырастет и существует ли уже такое явление как травля одноклассниками/одногруппниками за выложенное родителями в интернет?

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

Расскажите что вы считаете возможным выкладывать на публику о своих детях, а что у вас под запретом? Были ли конфликты с детьми на эту тему? Была ли травля сверстниками по мотивам того, что вы выкладывали? Хочу изучить чужой опыт, прежде чем вырабатывать какие-то свои правила.

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

«Глазелки» ★

Скриншот страницы блога «Глазелки: Путевой журнал» с заголовком «Архитектурный марафон #43. Бетьки. Церковь Владимирской иконы Божией Матери» и фото куполов храма на фоне неба.
Перерождённый на «Эгее» блог моего друга — «Глазелки.ру»

У моего хорошего друга, Олега Петровича несколько лет назад был очень интересный блог о путешествиях и краеведении — «Глазелки». Олег забросил его в 2016-м году, перестал платить за хостинг и домен. Хостер за это время разорился, содержимое блога потерялось.

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

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

Единственное, что пока не перенесено — комментарии. Сегодня, надеюсь, закончу и с этим, но их там немного, чтению блога это никак не мешает.

Рекомендую посетить обновлённые «Глазелки». Надеюсь Олег в скором времени напишет туда что-нибудь новое.

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

AppleScript Tetris ★

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

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

Для начала немного об ЭплСкрипте. Это скриптовый язык для автоматизации, который встроен в МакОС в незапамятные времена — в «Википедии» написано, что он появился аж в 1993 году, то есть широкоизвестный ПХП его младше аж на два года!

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

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

tell application "Microsoft Word" to quit
display dialog "Hello, world!"

print pages 1 thru 5 of document 2

Сильно популярным его не назовёшь, но в своей нише он хорош и продвинутые «маководы» о нём знают. До «Тетриса» я писал на нём «песню о пиве» и интерпретатор Брейфака.

За всё историю существования на ЭплСкрипте никто никогда не писал графических интерактивных игр. Причина проста: в языке нет поддержки графики и опроса клавиатуры. ?, расходимся!

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

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

Четыре одинаковых элемента интерфейса с кнопкой «Helvetica» и иконкой шрифта, расположенные в два ряда по три и один.

Для этого, в припципе, всё есть — ЭплСкрипт умеет запускать программы и управлять размерами и расположением окон:

tell application "TextEdit"
    set the bounds of 1st window whose id is wid to {x, y, (x + |size|), (y + |size|)}
end

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

На снежном стекле нарисованы чёрными точками контур дома и несколько снежинок, на заднем плане видны ели.

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

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

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

-- Get height of menu bar
tell application "TextEdit"
	activate
	make new document at the front
	set the bounds of 1st window to {0, 0, 0, 0}
	set coords to bounds of 1st window
	close 1st window
end

set minimalY to coords's item 2

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

Голову пришлось ломать очень долго, пока в один момент я не додумался заиспользовать под это опрос значения громкости — уменьшение и увеличение громкости как кнопки влево/вправо, а отключение динамика — для поворота фигуры.

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

Для этого на пуске я устанавливаю громкость на середину и в цикле опрашиваю текущее значение. После каждого изменения значение опять сбрасывается на среднее:

on levelReset()
    set volume output volume volumeMiddle without muted
end

on checkDirection()
    set level to output volume of (get volume settings)
    levelReset()
    _sign(level - volumeMiddle)
end

on checkRotate()
    return output muted of (get volume settings)
end

Тут _sign — моя собственная функция взятия знака, у ЭплСкрипта нет встроенной.

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

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

Полный исходный код есть на гитхабе.

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

Друг наш Лазарь уснул. Я иду разбудить его ★

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

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

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

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

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

Но в будущем технологии обязательно продвинутся настолько, что мы будем способны воспроизвести личность. Большой вопрос — готовы ли родственники к существованию в каком-то ином качестве? Или вот лично я? Готов ли к тому, что после смерти моё «я» откроет виртуальные глаза в виде какого-то хитрого тамагочи для моих потомков?

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

В общем, киберпанк стал на шаг ближе.

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

Але́кса против Яндекс.Станции ★

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

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

Чёрный умный динамик с синей подсветкой по краю, стоящий на светлой столешнице; на верхней панели видны кнопки управления.
«Але́кса» во всей красе — из минусов английский язык и плохая интеграция с «Сяоми»

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

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

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

Чёрный умный колонка Яндекс.Станция Мини с фиолетовой наклейкой «Я» и игрушечный робот на гусеницах стоят на столе рядом с двумя стеклянными подсвечниками и декоративной коробкой.
«Яндекс.Станция» в миниатюрном исполнении — глуховатый Петросян

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

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

Тут за натужный юмор «Алисы» начинаешь испытывать настоящий испанский стыд. Если кто не знает, «Алиса» пытается притворяться человеком — шутит, отвечает разнообразными фразами. Наверное это ещё будет хорошо работать, но пока всё портят две вещи — огрехи синтеза голоса и выхватывание случайных фраз из фонового разговора. «Алекса» в этом случае отвечает «I’m not sure» или подобное, а «Алиса», что-то там сконструировав себе из услышанных фрагментов, попадает впросак.

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

Из плюсов — русский язык. Общаться с помощником на русском заметно проще, русские названия «Алиса», разумеется, понимает лучше «Алексы» — особенно смешно, когда мы пытались заставить «Алексу» поставить песню Ёлки (на «Дизере» она есть), а получали сборник для йоги.

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

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

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

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

Старость и смерть ★

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

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

— Папочка, а ты немно́жечко постарел? Вот столько?

Почему-то мне стало весело, усилий стоило не рассмеяться, но отвечаю серьёзно:
— Да, совсем немножечко.

Продолжая тревожно на меня смотреть:
— А мы с тобой скоро в скелетиков превратимся?

Тут у меня как-то смех прошёл, меня самого эта тема тревожит.
— Нет, — отвечаю, — пройдёт много-много лет.
— А когда люди умирают, он потом исчезают?
— Ну… да.
— А потом снова появляются?
— Нет, доченька, не появляются.
— Почему?
— Так заведено, такие правила.

Долгая пауза. Потом хитрый вопрос с улыбкой в глазах:
— А Чеширской Кот пропадает, а потом появляется?
— Конечно!
— Ну что же, папочка, ты этого не знал, да?

Кажется ушли от темы.

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

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

Бум! ★

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

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

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

Вот в фильмах частенько какие-нибудь крутые ребята стреляют в замо́к, чтобы пройти сквозь запертую дверь. Как правило хватает одного-двух выстрелов, чтобы устранить препятствие. Реально ли это?

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

На помощь приходит Мэтт Каррикер — известный оружейный видеоблогер, ведущий канала «Разрушительное ранчо». На видео он проводит эксперимент — стреляет в замки́ из различного оружия, начиная с пистолета П22, заканчивая снайперской винтовкой Барретт 50-го калибра. Попробуйте угадать из какого оружия удастся так же непринуждённо открыть замок, как это делают в фильмах.

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

99 бутылок: ElanTele ★

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

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

// beer.et by Evgeny Stepanischev
вар бөтеннәрюлы := функция(ә) бу
    вар саннар := ["0","1","2","3","4","5","6","7","8","9"]
    вар олыара := ә/10
    вар нәтиҗә := саннар[ә - олыара*10 + 1]

    әгәр ә > 9 буочракта
        нәтиҗә := саннар[олыара + 1] + нәтиҗә
    бетте

    кайтар нәтиҗә
бетте

вар форматлау := функция(шешәләр) бу
    вар нәтиҗә

    әгәр шешәләр = 0 буочракта
        нәтиҗә := "no bottles"
    башкаочракта
        әгәр шешәләр = 1 буочракта
            нәтиҗә := "1 bottle"
        башкаочракта
            нәтиҗә := бөтеннәрюлы(шешәләр) + " bottles"
        бетте
    бетте

    кайтар нәтиҗә + " of beer"
бетте

вар ә, 

дәвамында ә эчендә 1..99 элмәк
     := форматлау(100-ә)
    яз  + " of beer on the wall, " +  + " of beer."
    яз "Take one down and pass it around, " + форматлау(99-ә) + " on the wall.\n"
бетте

яз "No more bottles of beer on the wall, no more bottles of beer."
яз "Go to the store and buy some more, 99 bottles of beer on the wall."

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

Расцветка синтаксиса программы редактором «СаблаймТекст 3»

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

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

Новости майнинга ★

Ряды серверов для майнинга криптовалюты на металлических стеллажах в помещении с голубой изоляцией стен и множеством кабелей.
Ферма по майнингу какой-то «крипты» на «айсиках»

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

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

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

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

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

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

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

PythonFuck ★

Давайте вспомним, что у меня блог ещё и про программирование.

Скриншот терминала bash с выполнением Python-кода через /dev/stdin, выводящего 'Hello!', и командой exit().

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

Для некоторых языков такого ещё никто не делал, приходится изобретать собственные приёмы, в конечном счете это интереснее всего. Я уже делал PHPFuck, BashFuck (и даже не один раз) и совмещал JavaScriptFuck с языком программирования Brainfuck.

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

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

_=(''<())+(''<());__=_**_**_
___='%'+('%'+`'±'`[_])%(__-_-_)

___*(_*_*_-_)%((
(__+_)*_*_,
`{_}`[_/_],
)+(`(''<'')`[_],)*_+\
(
__*_*_*_-__-_/_,
__*_+_/_,
))

Это запускается и работает (выводит строку «Hello!»), но только из командной строки и только во второй версии Пайтона. Когда напишу небольшой разбор кода, станет понятным почему.

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

Кара-бараз ★

Два рисунка: слева — ребёнок на летающем сундуке с ногами и краном; справа — ребёнок в ужасе от хаоса из предметов, включая сундук с лицом, ножницы и мыло «Нестор».
Мойдодыр в книжке Корнея Чуковского «Мойдодыр. Кинематограф для детей», М.-Л., «Радуга», 1924 год

Многих в стихотворении Чуковского «Мойдодыр» интригует, что «мочалок командир» появляется «из маминой из спальни» — вроде как что делать умывальнику в спальне, когда ему место в ванной?

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

Женщина в синем платье с кружевами сидит на плетёном стуле в комнате с винтажной мебелью, раковиной и портретами на стене.
Умывальник в женской спальне в доме-музее Арбузова (к сожалению снимка бо́льшего размера у меня нет)

Меня же больше интересовало что такое «Кара-барас»:

Он ударил в медный таз
И вскричал: «Кара-барас!»
И сейчас же щётки, щётки
Затрещали, как трещотки,
И давай меня тереть,
Приговаривать…

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

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

Иллюстрация к сказке «Бибигон — самая волшебная сказка»: человек с мечом сражается с огромным зверем в пещере, окружённой кустарником.
Первое появление Бибигона — журнал «Мурзилка» №11, 1945 год

Разгадка нашлась в другом произведении Корнея Ивановича — «Приключениях Бибигона». Там это слово повторяется несколько раз, как… заклинание:

— Вон погляди: бежит Барбос.
Ты думаешь, что это пёс?
Нет, это — старый Агафон,
Ваш деревенский почтальон.
Ещё недавно в каждый дом
С газетою или с письмом
Он приходил, но как-то раз
Колдун сказал: «Кара-бараз».

И вдруг — о чудо! — в тот же миг
Барбосом сделался старик.

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

Вишенкой на торте было бы указание на какой-нибудь источник, где Корней Чуковский мог это слово позаимствовать, но, увы, ничего такого найти не удалось.

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

ДТП ★

Ночная авария: белый автомобиль Uber столкнулся с чёрным седаном, повреждены передние части машин, на асфальте лужа жидкости, рядом стоят люди.

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

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

Если бы не был пристёгнут, без серьёзных травм не обошлось. Берегите себя!

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

Звательный падеж ★

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

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

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

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

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

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

С ком приветом из 1928 ★

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

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

Рукописное письмо от 25 мая 1928 г. с завода «Красный Октябрь» Александру Петровичу Трофимову с просьбой о справке и включении в члены товарищества; подпись М. Валиева (Трохище).

В книге памяти Татарстана удалось найти репрессированного Трохимуса Ромуальда Ивановича 1923 года рождения, возможно это сын человека, написавшего это письмо.

Приняв эту шаткую теорию за отправную точку, на сайте «Память народа» находим подходящую кандидатуру на роль автора — Трохимуса Ивана Петровича, литовца по национальности. Место его рождения — Ленинград, совпадает с дислокацией одного заводов «Красный Октябрь» (это название упоминается в письме). На момент написания письма ему должно быть около 38 лет.

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

Добавлено позднее: на основании комментария читателя исправил национальность с латыша на литовца.

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

Эколингвист ★

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

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

Когда читаешь, понимаешь, что «pomaga w leczeniu chorych» — это «помогает в лечении хворых», а «pigułki» — «пилюльки» («пилюли», «таблетки»), но на слух это воспринять значительно сложнее.

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

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

Отче наш, кторы јеси в небесах, нехај свети се име Твоје. Нехај пријде кральевство Твоје, нехај буде вольа Твоја, како в небу тако и на земји. Хлѣб наш всакоденны дај нам днес, и одпусти нам наше грѣхы, тако како мы одпушчајемо нашим грѣшникам. И не введи нас в покушенје, але избави нас од злого.

Попробовать свои силы в чтении можно на сайте Википедии на межславянском.

Возвращаясь к эксперименту. В ролике болгарин, поляк и хорват пытаются выполнить задания (prikaz), озвучиваемые на межславянском. Меня очень развлекло, krasiva zabava.

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

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

Дневник жизни №3 ★

Продолжаю перепечатывать свои дневники жизни — я уже выкладывал тетради №4 и №8, на этот раз перепечатал дневник №3. Это самый конец 1991 года, в тетради — подростковый бунт, моё бесценное мнение по развалу Союза, увлечение паранормальными явлениями, эксперименты с алфавитом и изобретение собственного способа отображать эмоции в тексте.

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

Теория разбитных окон ★

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

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

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

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

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

Флоатинг ★

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

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

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

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

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

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

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

Начал выкладывать дневники жизни ★

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

Записи доступны по тегу «дневники жизни».

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

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

Артемий Лебедев и дети ★

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

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

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

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

График «Поездки по годам» (2012–2019): количество дней в поездках, городов и стран за каждый год; красные полосы — дни поездок, серые — без поездок.
График поездок Артемия Лебедева по разным городам и странам (взято с личного сайта Артемия)

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

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

И я вот всё думаю — как же с такими разъездами можно хоть как-то участвовать в воспитании хотя бы одного ребёнка, не говоря о десятерых? Что в этих детях есть от него, кроме генетики? Возможно не даром он так подробно рассказывает о странах, которые он посетил, а об его детях почти ничего не известно, кроме количества?

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

sudo по отпечатку пальца ★

Окно macOS: sudo запрашивает пароль или Touch ID для администратора. Кнопки «Использовать пароль...» и «Отменить».
Запрос отпечатка пальца для команды sudo

На «Маке» я нередко использую командную строку — некоторые мои задачи через неё выполнять проще, чем через графический интерфейс. Как правило для этого используется непривилегированный пользователь, но иногда приходится что-то запускать с правами администратора. С этой целью в системе существует специальная команда sudo.

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

И вот сегодня один из сотрудников спросил — работает ли у меня на «Маке» sudo по отпечатку пальца.

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

/etc/pam.d/sudo

первой строкой добавить

auth sufficient pam_tid.so

И всё, при следующем запуске sudo можно просто приложить палец к сканеру. Экономит уйму времени, спасает от опечаток, никто не сможет подсмотреть пароль.

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

Вино с привкусом ног ★

Мужчина в шляпе и коричневой рубашке топчет виноград ногами в деревянной бочке, пока группа людей наблюдает за ним на фоне здания с окнами и декоративными элементами.
Адриано Челентано давит ногами виноград в фильме «Укрощение строптивого» (1980)

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

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

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

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

Как вы относитесь к такому способу получения сырья для вина? Если вы живёте в Италии, то как относятся там?

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

Судьба патефона ★

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

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

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

Прежде на патефон жалко было смотреть, а сейчас вид вполне музейный, небо и земля. И звучать стал очень хорошо — мастер оценил на «4+», я на столько даже и не рассчитывал.

Заодно попросил оценить все пластинки, которые перешли к нам вместе с патефоном. Их оказалась 31 штука, почти все — 50-х годов выпуска, кроме «Песни нефтяника / Кавказской застольной», произведённой в 1948 году. Оказалось, все пластинки в превосходном состоянии.

Виниловая пластинка с этикеткой «Кавказская застольная» в исполнении Рашида Бейбутова и Т. Кулиева (фортепиано), выпущенная трестом местной промышленности Коминтерновского района.
Пластинка «Песня нефтяника / Кавказская застольная», Завод металлопластмасс, 1948 год

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

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

Очень надеюсь, что когда дочка подрастёт, ей будет интересно узнать какие песни любили слушать её прадедушка и прабабушка.

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

ФИДО ★

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

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

Самое моё значимое участие в жизни Фидо — как-то я умудрился намертво повесить компьютер с OS/2 своего знакомого, где работал тоссер — программа, обслуживающая один из сегментов казанской сети.

Скриншот письма о появлении 13-го месяца 2018 года в московском метро: на табло станции «Кузнецкий Мост» отображается дата 01.13.2018 и время 03:44.
Гипертекстовый векторный фидонет на экране обычного смартфона; используется клиент HotdogEd под Андроид

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

Сегодня заявку одобрили и дали мне поинта (адрес) 2:5020/723.67. Скачал клиента HotdogEd под Андроид, установил ему плагин HotdogEd Fidonet Provider, заполнил настройки из присланного в ответ на заявку письма, и вот я в Фидо.

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

  • «Boss 3D FTN address» — адрес ноды (в моём случае — 2:5020/723)
  • «Your name» — «имя» из ответного на заявку письма
  • «Your 4D FTN address» — ваш поинт-адрес (в моём случае — 2:5020/723.67)
  • «Password» — пароль из письма

Потом останется подписаться на интересующие вас «эхи» (каналы) и можете начинать общаться. Я пока подписался на две локальные и на su.talks — всероссийскую болталку.

Пока причастности к легенде не почувствовал, но гештальт, надеюсь, закрыл.

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

Яндекс.Драйв ★

На экране мультимедийной системы автомобиля отображается навигационная карта с маршрутом по Бутырской улице, указанием поворота через 410 м и ограничениями скорости 55/60 км/ч.
«Яндекс.Навигатор» с голосовым ассистентом «Алиса» в автомобиле «Яндекс.Драйва»

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

Очень расстроен. Мне не понравилось.

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

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

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

☹️Я не впечатлён.

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

Физическое воплощение TCP-пакета ★

Синяя сумка-шоппер с белой схемой заголовка протокола TCP и надписью «TCP», рядом — распечатанный фрагмент документа RFC 793 с описанием формата заголовка.
Физическое воплощение TCP-пакета, обеспечивается гарантированная доставка, надо полагать

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

Я тоже заинтересовался — где такую взять и ценой вопроса. С заметным трудом разыскал источник — китайский мономагазин, сумка стоит по-божески — 48¥ ($7), но, судя по всему, на доставку по всему миру автор не рассчитывал.

Видимо не удастся такую получить, разве что найти кого-то в Китае, но я не припомню, чтобы у меня там жили знакомые. Жаль, принт вызывает слюноотделение, да и вещь не бесполезная — молния, внутренний карман, рассчитана на «Макбук Эйр» 13″. Я как раз собирался переходить со своей «прошки» на «Эйр» модели этого года.

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

Apple I ★

Скриншот окна эмулятора Apple Monitor III с зелёным текстом на чёрном фоне: шестнадцатеричные адреса и данные, символы ASCII, кнопки управления (Power Down, Sleep, Wake Up, Reset).
Моя первая программа в машинных кодах «Эпл I» бесконечно выводит таблицу символов

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

Не знаю, что ребята сделали, но направление верное, молодцы!

В общем, прочитал недавно там статью про самодельный «Эпл I» и сегодня не спал до двух ночи.

Нет, свой компьютер я не собрал, да и начиналось всё невинно — сначала скачал несколько эмуляторов, попробовал что-то позапускать готовое. Потом почитал про тамошний ассемблер (на борту там процессор 6502) и решил написать что-нибудь простое на нём.

Для этой цели мне очень подошёл «ОупенЭмулятор» и онлайн-компилятор с возможностью отладки «Асм80». Неожиданно удобная штука, кстати, не знаю сколько я бы без неё проваландался.

Скриншот кода на ассемблере с метками ECHO и LOOP, инструкциями TXA, JSR, INX, JMP и сообщениями о определении и использовании меток в строках 3, 4, 6, 8.
Программа, выводящая таблицу символов в компиляторе и отладчике «Асм 80»

Первая моя программа умела совсем мало — только бесконечно выводить на экран таблицу символов. Она такая короткая (всего восемь байт), так как для самого сложного — печати на экран, используется вызов ECHO, встроенной в «Эпл I» программы «Woz Monitor», — по всей видимости её писал Возняк, поэтому она так называется.

В ассемблере 6502 особо не развернёшься — три восьмибитных регистра (A, X, Y), 56 команд (не считая нескольких недокументированных), только целые числа, нет деления и умножения. Я совсем не помню свой первый ассемблер (для «Радио-86РК»), но кажется даже он был богаче.

Тем интереснее было написать что-нибудь чуть более серьёзное. Я написал, разумеется, «песню о пиве», в ближайшее время выложу. Машинные коды вбивал сначала руками прямо в «монитор», всё как в детстве, в начале 90-х, но ближе к ночи устал и написал на «Пайтоне» программу, которая hex-файл «Асма80» перебивает в эмулятор, имитируя нажатия на клавиши через «ЭплСкрипт».

Кстати, какое-то время пришлось ещё потратить на то, чтобы понять как работать с «монитором» Возняка — это предельно аскетичная командная строка, в которой без руководства не разобраться, что, учитывая скромные размеры программы, объяснимо. К счастью, в сети есть копия « Apple-I Operation Manual», которую я наскоро проштудировал.

Там всего несколько страничек, вникнуть просто и сейчас (о ужас!) мне даже удобно.

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

Самый долгий merge в моей жизни ★

Заметка будет интересна только программистам.

Фотография ниже лежит у меня на ноуте с августа 2013 года. Очень не люблю такое — всё нужное я привык закачивать в интернет, всё ненужное — удалять. Не мог определиться куда деть это фото, решил положить в блог, снабдив небольшим рассказом.

На стене вывешены десятки листов с текстом, справа висит записка с надписью «НЕ ТРОГАТЬ!
Каждый файл для слияния приходилось печатать на куче бумаги, раскладывать на полу и сравнивать вручную

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

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

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

Через год попытались слить две ветки воедино и получили конфликты почти во всех основных файлах проекта. Ничего совсем уж неожиданного, конечно, особенно с учётом того, что часть кода была переписана с ПХП на «Твиг», но никогда в ещё в жизни я не видел столько конфликтов. Затронуты были, если мне не изменяет память, несколько сотен файлов.

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

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

На фотографии — процесс разрешения конфликтов одного из файлов. Через неделю я был полностью разбит монотонностью работы, но ветки слил.

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

Барахолка на Гудованцева ★

На снежной улице на ветвях деревьев и верёвке сушатся шапки, варежки и одежда, покрытые снегом; видны разноцветные вещи на фоне зимнего леса.
Шапочное дерево на блошином рынке вдоль улицы Гудованцева (между Моисеева и Беломорской)

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

Сегодня едва успел к закрытию (торговать там начинают часов с 8, заканчивают около 12), к тому же сильно мешал снегопад, но всё же одним глазком глянул.

Ассортимент — поздний СССР, современный Китай и всякий подержанный скарб. Через снег трудно оценить, но в среднем как-то так.

На снегу лежат красная звезда-гирлянда, фигурка оленя и игрушечный енот.
Наши сегодняшние приобретения — звезда на ёлку времён СССР, олень и енот

Ходили с дочкой, поэтому в основном покупали игрушки (олень — 30₽, енот — 100₽), а мне приглянулась советская звезда на ёлку (150₽), два раза мимо неё прошёл, но всё же купил. Поторговаться пришлось только за звёздочку (сбил цену почти в два раза), остальное взял так.

Ещё не проверял, исправна ли звезда, если нет, поставлю внутрь яркий светодиод, сменю питание с 220 на низковольтное, так ещё и безопаснее. Главное ведь не лампочка накаливания внутри, а эмоциональный накал, который дарят такие, с историей вещи.

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

ТЭГК 2-2 ★

Термоэлектрический генератор «ТК-2-2» (1956 г.) с лампой накаливания, подвешенный на цепях; рядом табличка с описанием и фото двух мужчин у оборудования.
Термоэлектрогенератор ТЭГК 2-2 в омском музее радио

Полвека назад на территории нашей необъятной Родины многое было иначе. Люди обходились без «айфонов», интернета и иногда — электричества.

Электрификация страны началась в двадцатых, но к 50—60 годам ещё немало деревень и прочих населённых пунктов не знало «лампочки Ильича» — вместо неё избы освещала керосиновая лампа. Конечно и там людям хотелось быстро получать новости, знать чем живёт остальная страна.

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

На фотографии — «ТЭГК 2-2» из омского музея, где его сфотографировал один мой друг. Выпускался с 1956 года московским заводом «Металламп».

Немаленькая бандурина в 6,6 килограмма, состоящая из термоголовки и керосиновой лампы «Молния». Выдаваемой мощности в два ватта хватало для питания ламповых радиоприёмников «Новь», «Родина-52», «Искра», «Б-2», «Воронеж» и некоторых других.

Судя по тому, что инструкция к нему шла на трёх языках — русском, французском и английском, эта модель шла и на экспорт.

При объёме лампы 0,75 литра, расходе керосина в 70—80 г/ч и плотности 830—860 кг/м³, легко подсчитать, что радио можно было слушать около 7—9 часов на одной «заправке» (правда порядка 20 минут ещё съедал прогрев после каждого включения). Одновременно генератор являлся и источником света.

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

Красная ртуть ★

Ржавая механическая арифмометрическая машина с зелёными ценниками (500 и 1000) на красной ткани среди старых книг, телефона и бумаг на блошином рынке.
КДПВ — фотография с сегодняшнего посещения казанского блошиного рынка в парке им. Карима Тинчурина

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

После возвращения в Казань прочитал про «блошку» на Тинчурина у своего приятеля Б. К. и загорелся сходить. С тех пор иногда там что-нибудь покупаю.

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

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

Первая страница патента №18,105 от 10 сентября 1901 года Г. Маркони «Улучшения в когерерах или детекторах для электрических волн», с описанием изобретения и подписью автора.
Патент Гульельмо Маркони №18105 от 10 сентября 1901 года, где упоминается ртутный когерер

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

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

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

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

Музыкальная шкатулка ★

Винтажный музыкальный автомат с металлическим перфорированным диском и механизмом воспроизведения, установленный в деревянном корпусе.
Диск для музыкальной шкатулки с некой татарской мелодией

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

А то дисков у них много, а сил всё это перевести в электронный вид нету.

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

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

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

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

41 ★

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

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

Бородатый мужчина в футболке с надписью «ВОЛГА» и рисунком держит телефон и смотрит на него, рядом лежит фиолетовый воздушный шарик в форме собаки, на фоне детской игровой зоны.
Самое свежее фото, со дня рождения дочки, кажется единственное пока, где видно идёт ли мне налысо

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

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

Родовое дерево ★

Документ с рукописным текстом, печатью «Вексельная бумага на сумму до 700 рублей» и надписью «ЦЕНА 1 РУБ. 5 КОП.»; видна часть подписи и дата «Тысяча девятьсот...».
Долговой вексель, упоминаемый Павел Семёнович Степанищев — родственник предков по линии фамилии

Меня в последнее время несколько раз спрашивали — почему не публикую никаких новостей по родовому дереву? Забросил исследования?

Нет, не забросил, прекратил. Тому есть две причины.

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

Во-вторых, осознал такую простую вещь. В 19 веке Вильям Шенкс потратил 15 лет, чтобы вычислить число Пи до 707 цифры, сегодня на обычном сотовом телефоне можно вычислить миллион знаков примерно за минуту.

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

И тогда часть моих трудов, та что касается сидения над архивными делами, обесценится. Так к чему тратить время?

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

Клад! ★

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

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

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

Тем не менее на днях повезло — на частной территории (всё с ведома хозяев, всё легально) наткнулся на клад из более чем 170 медных монет времён Николая Второго. Ценность у него, естественно, никакая, но это не умаляет того факта, что это настоящий клад.

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

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

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

Книги детства ★

Обложка книги «Приключения Алисы в стране чудес» и «Алиса в Зазеркалье» Льюиса Кэрролла с иллюстрацией девочки и кота на дереве, лежащая на тёмном сиденье рядом с джинсами.
Книга Льюиса Кэррола про приключения Алисы, издание 1992 года, перевод Демуровой

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

Пока формирую на основе своих детских воспоминаний, — закуплены «Анечка Невеличка и Соломенный Губерт» Витезслава Незвала и две повести о приключениях Алисы Льюиса Кэррола. Причём именно в тех изданиях, которые у меня были в детстве.

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

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

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

Находки с Волкова ★

Ржавая металлическая коробка с крышкой лежит на деревянной доске; внутри — осколки керамики, монета и другие мелкие артефакты.
Керамика, запонка, гильза, резиновая пробка и несколько неопознанных находок, монета только одна — 1 копейка 1976 года

Во дворе того же дома на Волкова, где мне показали два дореволюционных клейма на кирпиче, прошёлся сегодня с металлодетектором. Спасибо хозяевам — А. и О., а так же М. за гостеприимство!

Искать было непросто — во дворе, как это обычно и бывает, очень много бытового металла — гвоздей, пробок от спиртного, фольги, но всё же упорство было вознаграждено. Из более-менее интересных находок — овальная запонка с рисунком и мосиновская гильза 1916 года компании United States Cartridge Company (Лоуэлл, Массачусет, США).

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

В ладони лежит старая медная монета с овальным рельефным узором в центре, покрытая зеленоватой патиной; фон размыт.
Овальная находка, предположительно — запонка, на обратной стороне видна обломанная ножка

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

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

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

Элиуд Кипчоге ★

Бегун в синей майке с логотипом Nike и номером BMW бежит по улице, на лице пот и сосредоточенность, на заднем плане размытые зрители.
Это Элиуд Кипчоге и он смотрит на ваши казуальные забеги в модных «Найки», как на говно

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

Я не являюсь хорошим бегуном, да и комплекция у меня не беговая, для меня бегать — трудно. Я никогда не пытался осилить марафон (42 километра, напоминаю), уверен, что пробегу его, если буду тренироваться. Но я никогда не считал это плёвым делом.

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

Это почти в два раза быстрее меня на всей дистанции! Со средней скоростью выше, чем я обычно езжу по городу на велике!

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

Чёрт возьми, такие достижения я уважаю!

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

PHP8 ★

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

Пока всё прогрессивное человечество переходит на ПХП7, а менее прогрессивное до сих пор чахнет над каким-нибудь 5.4, я решил разведать что там обещается в восьмой версии и когда её обещают.

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

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

Или вот похожий пример с константой:

class Sample
{
    const test = 'const';
    public static $test = 'variable';
}

$test = 'test';
// что ты такое?
var_dump(Sample::$test);
// на самом деле вернётся «variable», очевидно; константу придётся получить так:
var_dump(constant("Sample::$test"));

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

// так можно было бы получать константу по имени в переменной (не работает!)
var_dump(Sample::($text));

Самым серьёзным внутренним изменением нового релиза, вероятно будет добавление JIT, Дмитрий Стогов, человек, которому мы обязаны фантастическим ускорением в «семёрке», ещё в позапрошлом году написал в рассылку php.internals, что работа над динамической компиляцией начата. Получившийся к тому времени прототип показал 20% прироста на синтетических тестах и снижение производительности на реальных приложениях.

Кстати, это не первая попытка совместить динамическую компиляцию и ПХП, в языке HHVM, диалекте ПХП от «Фейсбука», такая компиляция даёт хороший прирост в скорости. Да и Дмитрий сотоварищи ещё в 14-м году делали попытку прикрутить JIT тогда ещё пятой версии ПХП. Тогда ускорение составило всего около пары процентов и эта неудача заставила Дмитрия исследовать интерпретатор на предмет «бутылочных горлышек», который и были устранены в седьмой версии.

Столбчатая диаграмма «Скорость выполнения» сравнивает версии 7.0.13 (синий), 7.1.0 (оранжевый) и JIT (серый): значения 0,670/0,495/0,208; 4,056/3,327/2,185; 15,562/9,228/4,680.
Результат сравнения разных версий, JIT убедительно выигрывает на фоне PHP7 и PHP7.1 на синтетических тестах

Более свежий тест того, что будет в ПХП8 показывает, что на трёх тестах (два стандартных зендовских теста и построение множества Мандельброта) динамическая компиляция уделывает версию 7.1.0 примерно вдвое. Это отличный результат! Но понятно, что в реальной жизни всё будет скромнее.

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

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

Баг ★

Принято считать, что слово «баг» появилось 9 сентября 1946 года, когда Грейс Хоппер, которая работала в тот момент в Гарвардском университете с ЭВМ «Марк II», проследила ошибку в работе программы до реле машины, куда попал мотылёк. Грейс вклеила насекомое в технический журнал, сопроводив шуткой «Первый реальный случай обнаружения жучка» («First actual case of bug being found»).

На самом деле это одна из версий проникновения термина в среду компьютерщиков. В выпущенном в 1892 году «Стандартизованном словаре электротехники» можно прочитать:

Баг — это любая неисправность или дефект в электрических соединениях или работе электрических аппаратов

Как видим слово появилось раньше 1946 и даже не в 20 веке. По одной из версий термин придумал и популяризировал Томас Эдисон — известный американский предприниматель, Стив Джобс своего времени.

Письмо Томаса Эдисона от 3 марта 1878 г. Уильяму Ортону: обсуждение насекомого в аппарате телефона, обещание подарить фонограф и приглашение посетить экспериментальную комнату.

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

Употреблял ли Эдисон это слово в знакомом нам значении? Да! Так 18 ноября 1878 года он написал Тивадару Пушкашу (венгерскому учёному, физику, и изобретателю первой в мире телефонной станции):

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

Так что термину в этом году исполняется по меньше мере 140 лет.

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

Казанская страховая доска ★

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

Металлическая табличка на красной кирпичной стене с надписью «ЗАСТРАХОВАНО ВЪ СѢВЕРНОМЪ ОБЩЕСТВѢ» в старорусском шрифте.

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

Ржавая овальная металлическая табличка с надписью «ПРИЕМНАЯ» и декоративными элементами, прикреплённая к деревянной стене из горизонтальных досок.

Узнать местоположение последней страховой доски оказалось непросто, возможно поэтому коллекционеры пока до неё не добрались. Даже зная примерный адрес, нашёл только через полчаса поисков. Доска маленькая, сильно заржавела, пришлось занимать объектив у приятеля, чтобы снять.

Написано там следующее: «въ обществѣ РОССІЯ застраховано». На фоне — почти уже незаметная восьмиугольная звезда, намёк на икону «Неопалимая Купина». «Неопалимая Купина» почитается как заступница при пожарах, так что такая страховая доска одновременно играла ещё и роль оберега.

Дополнение: позже оказалась, что эта страховая доска вовсе не последняя.

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

ProxyJump ★

Как-то писал заметку про .ssh/config и опцию ProxyCommand, а потом почти сразу после этого, перечитывая руководство по теме, наткнулся на схожую опцию ProxyJump:

Host 10.1.10.*
        IdentityFile ~/.ssh/id_rsa
        #ProxyCommand /usr/bin/ssh -W %h:%p bolk@rptn.tunnel
        ProxyJump rptn.tunnel

Возможности её у́же, зато пользоваться ею проще. Кроме указания в конфиге, её просто использовать и из командной строки, как ключ, причём цепочки выстраиваются очень просто:

ssh -J bolk.sed-php7:2258,rptn.tunnel 10.1.10.158

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

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

🍎 + 🍍 + 🍌 = 🥗 ★

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

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

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

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

Минимальные подходящие числа для уравнения такие (ответ проверял на ЯП «Эр»):

`🍎` <- 154476802108746166441951315019919837485664325669565431700026634898253202035277999
`🍌` <- 36875131794129999827197811565225474825492979968971970996283137471637224634055579
`🍍` <- 4373612677928697257861252602371390152816537558161613618621437993378423467772036

print(`🍎` / (`🍌` + `🍍`) + `🍌` / (`🍎` + `🍍`) + `🍍`/(`🍎` + `🍌`)) # [1] 4

Это числа от 79 знаков и больше! Где уж такое решить!

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

Ассемблер под Линукс ★

Заметка про полноту по Тьюрингу команды присваивания в ассемблере натолкнула меня на мысль, что я как-то не удосужился попрограммировать на ассемблере под Линукс — эту ОС я начал осваивать примерно в то же время, когда начал быстро терять интерес к ассемблеру.

Тогда не довелось, решил вчера попробовать. Теорию в очень общих чертах я знал — есть системные вызовы (сисколы), которые можно дёргать какой-то командой, имена сисколов мне знакомы через Си. Попробовал написать программу, которая выводит на вход то, что ей дают на вход. Быстро разобрался, что регистры сейчас имеют впереди букву «эр», а сисколы делаются прерыванием №128. Удобный способ, параметры идут в логичном виде — последовательно через регистры в почти алфавитном порядке (ближе к концу последовательность нарушается):

MOV RAX, 3 ; sys_read
MOV RBX, 0 ; stdin
MOV RCX, string ; адрес строки, которую выведем на экран
MOV RDX, len ; длина строки
INT 0x80

Но я где-то читал, что для сисколов есть команда новее — syscall, просто заменил вызов прерывания на эту команду — не заработало. Полез в интернет. Оказалось, у там другой набор параметров, да и сами сисколы имеют другие номера.

MOV RAX, 0 ; sys_read
MOV RDI, 0 ; stdin
MOV RSI, string ; адрес строки, которую выведем на экран
MOV RDX, len ; длина строки
SYSCALL

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

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

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

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

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

Дизассемблируй это ★

Скриншот игры: вид от первого лица в тёмном подземелье с синим полом и красным объектом; внизу интерфейс с здоровьем 100%, бронёй 0%, патронами 50 и портретом персонажа.
«ДУМ», скомпилированный с использованием одних только команд MOV

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

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

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

И вот оказалось, что эта команда — полная по Тьюрингу. Звучит невероятно, но это так. Некие ребята заморочились и сделали компилятор, который компилирует любую программу на Си в последовательность команд MOV. Причём им даже ДУМ удалось скомпилировать, правда один кадр рисуется семь часов. Кстати, такая программа неуязвима для горюшка века — Мелтдауна и Спектра.

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

Например, сравнение двух чисел делается при помощи следующего псеводокода:

mov [X], 0
mov [Y], 1
mov R, [X]

У нас есть два числа в аргументах «X» и «Y», результат сравнения которых попадает в «R» — там будет ноль, если числа не равны и единица в противном случае. Как же это работает?

Первой командой ноль записывается в ячейку по адресу «X». Это ассемблер, у нас тут всё — число, остальное — человеческие интерператации, поэтому записанное в «X» мы используем как адрес. Второй командой единица записывается в ячейку по адресу «Y». Третьей командой мы читаем значение по адресу «X» и если значения в «X» и «Y» совпадают, то ноль перетрётся единицей (и она попадёт в R), если нет, то в ячейке по адресу «X» ноль останется (который попадёт в R).

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

Возьмём, например, логическое «ИЛИ» («OR»), тут чуточку сложнее:

OR_ADDRS: dd OR_0, OR_1
OR_0: dd 0, 1
OR_1: dd 1, 1
; …
mov eax, X
mov edx, [OR_ADDRS + eax]
mov eax, Y
mov eax, [eax + edx]
mov R, eax

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

Что тут происходит? В регистр (переменную, с которыми работает процессор) «eax» записывается значение «X» (возможные входные значения у нас тут — ноль или единица, численное представление булевых значений).

Далее в регистр «edx» записывается число из адреса, который является суммой адреса массива OR_ADDRS и содержимого регистра eax. Таким образом в eax попадёт OR_0 или OR_1, в зависимости от того былы записаны в eax ноль или единица. Эти значения — тоже числа и являются адресами двух других массивов из двух элементов.

Далее в eax мы записываем аргумент Y, его значение складывается с адресом полученным на предыдущем шаге и из получившегося адреса мы читаем записанное там значение. В переводе на ПХП получается следующее:

function mov_or(int $X, int $Y): int
{
    define('OR_0', [0, 1]);
    define('OR_1', [1, 1]);

    define('OR_ADDRS', [OR_0, OR_1]);

    $R = OR_ADDRS[$X][$Y];

    return $R;
}

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

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

Интернет-археология: браузер ViolaWWW ★

Скриншот окна приложения с заголовком «vw» и стандартными кнопками управления окном macOS, пустое рабочее пространство
Моя попытка запустить браузер под Линукс пока завершилась провалом

Пока читал про «Си-минус-минус», наткнулся на браузер ViolaWWW. Браузер разрабатывался с 1991 года в университете Беркли одним-единственным человеком — Вэй Пей-Юанем.

Эта вещь достойна внимания из-за примечательного факта — там реализованы таблицы стилей, за несколько лет до появления CSS, а так же первый скриптовый язык — задолго до «ДжаваСкрипта» и «Си-минус-минуса»! Причём с событиями и подобием аякса!

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

\class {field}
\name {wave}
\parent {}
\children {wave.sb}
\script {
    switch (arg[0]) {
    case "graph":
        f = float(arg[1]);
        xx = width();
        r  = height() / 2.0;
        theta = 0;
        for (x = 20; x < xx; x += 2) {
            theta = theta + 0.1;
            y = sin(theta * f) * r + r;
            drawLine(x, y, x, y + 1);
        }
        return;
    break;
    }
    usual();
}
\width {300}
\height {200}
\
\class {slider}
\name {wave.sb}
\parent {wave}
\script {
    switch (arg[0]) {
    case "_shownPositionV":
        usual();
        send(parent(), "graph", arg[1]);
        return;
    break;
    }
    usual();
}
\x {2}
\y {2}
\width {15}
\height {200}
\shownSizeV {10}

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

Даже интересно какой бы веб мы увидели сейчас, если бы этот браузер тогда получил дальнейшее распространение! Получается в 90-х он умел больше, чем некоторые браузеры в двухтысячных. Например в скриптовом языке я заметил селекторы nthChild и даже nthWord!

Насколько я могу видеть, поддерживалось более десятка форматов графики, в том числе всем знакомый GIF, правда без анимации и в формате 1987 года, а так же сейчас уже экзотический XBM (до относительно недавнего времени поддерживался «Эксплорером», «Сафари» и «Оперой»).

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

Военный поиск ★

Палаточный лагерь (268.97КиБ)
Палаточный лагерь поискового отряда, крайняя левая палатка — моя

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

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

Захоронение (290.88КиБ)
Один из откопанных скелетов, в могилах никаких личных вещей не найдено

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

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

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

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

Билл «Кон» Гейтс ★

Скриншот командной строки 86-DOS v1.00 с датой 10-13-99, командой COPY NEW.BAT CON и сообщением «1 File(s) copied
Устройство «CON» в 86-DOS версии 1.00

Какой херни только по радио не услышишь! Ехал вчера в такси, а по радио рассказывают про файл с именем CON, который нельзя создать в Винде, якобы потому что это было прозвище Билла Гейтса в детстве и он поклялся, что в его системе такой файл нельзя будет создать!

Ну что за бред?

Во-первых, это специальное имя файла, всё, что в него записывается выводится на CONsole — консоль. Таких имён множество, в основном трёх- и четырёхсимвольных. Например, есть PRN — принтер, COM1 — первый ком-порт и другие. Они достались Винде ещё от ДОСа.

Во-вторых, первые версии системы, которую сейчас называют просто «ДОС» были написаны в «Сиэтл Компьютер Продактсе» Тимом Патерсоном и лишь версия 1.10 была приобретена во владение Микрософтом и переименована из 86-DOS в MS-DOS. Специальные имена файлов были добавлены в версии 0.74, если запустить версию 1.00, легко убедиться, что CON там имеет тот же специальный смысл, причём ещё в те времена, когда система не принадлежала Биллу Гейтсу.

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

AppleScript и Тетрис ★

Тетрис (20.11КиБ)
Непритязательный внешний вид получившегося Тетриса

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

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

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

Для тех, кто не знает, надо наверное пояснить. ЭплСкрипт — это язык автоматизации пользовательских сценариев работы, он умеет управлять приложениями (с разной степенью успеха) и кое-какими вещами в «МакОСи».

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

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

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

Кажется это первая и единственная игра в реальном времени на ЭплСкрипте.

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

Крещение дочки ★

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

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

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

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

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

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

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

«Жизнь» Конвея на «R» ★

«Жизнь» (18.72КиБ)
Одно поколение в игре «Жизнь», запущенной в терминале

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

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

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

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

life <<- matrix(as.integer(runif(rows * cols) < ratio), rows, cols)

Сравнение с переменной ratio и вызов as.integer тут применяется к каждому значению из множества, генерируемого функцией runif (Random Uniform Distribution, генерирует случайные значения с нормальным распределением). Так матрица игры заполняется случайными нулями и единицами.

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

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

# Any dead cell with exactly three live neighbours becomes a live cell
life.new[life == 0 & life.neighbors == 3] <- 1
# Any live cell with fewer than two or more than three live neighbours dies
life.new[life == 1 & (life.neighbors < 2 | life.neighbors > 3)] <- 0

Тут участвуют три матрицы: life — поле игры на предыдущем шаге, life.new — поле игры на текущем шаге и life.neighbors — матрица соседей (точка в «Эре» не имеет специального значения). Как видите матрица сравнивается с числом, как будто она скаляр, результат этой операции тоже матрица, но из булевых значений, в каждой клетке — результат операции. Такую матрицу можно использовать как индекс, в результате чего вернутся только те ячейки, по адресам которых в булевой матрице было TRUE.

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

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

Погодный плагин для «Sublime Text» ★

Скриншот редактора кода с файлом PogodaStatusBar.py, содержащим класс для отображения погоды в статус-баре Sublime Text с иконками и настройками.
Окно редактора «Саблайм Текст» с погодой и пробками в строке состояния

Написал свой первый плагин для «Саблайма» — для отображения в строке состояния погоды и пробок «Яндекса». Заодно немного повспоминал «Пайтон», давно на нём ничего не писал.

Удивительно, но факт — другого работоспособного плагина на эту тему не обнаружилось. Единственный конкурент использует старое АПИ «Яху», которое уже не работает, потому не работает и плагин.

Отдельное спасибо «Яндексу» за то, что их АПИ умеет определять текущее местоположение — ничего задавать в конфиге не надо, удобно.

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

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

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

Подал пул реквест на включение в саблаймовский пакетный менеджер, но особо упорствовать не буду, если откажут.

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

➿ Зарождение fashion'а на латиницу с русским окончанием ★

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

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

Ан нет, Яков Карлович Грот на странице 71 своей книги «Русское правописание» отмечает, что в в 1830 годах «Библиотеке для чтения» некто Сенковский подал этот дурной и невероятно заразительный пример. То есть этому способу уже почти два века.

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

🎬 Здравствуй, трёхмерное кино ★

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

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

Страница журнала с заголовком «Здравствуй, трехмерное кино» и текстом о голографическом кино, слева — чёрно-белые фото учёных.
Заметка про трёхмерное кино из книги «Москва»

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

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

Исследования продолжаются, а московские учёные разрабатывают проект первого голографического цветного кинотеатра на 200—400 мест. Мы ещё будем зрителями необыкновенного кинематографа.

Это была цитата из книги «Москва», издательство «Советская Россия», 1981 год. Виктор Григорьевич умер два года назад, а голографическое кино в кинотеатрах мы так и не увидели — только стереографическое (которое принято называть «три-дэ»).

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

С создания первого голографического фильма прошло почти 40 лет — премьерный показ состоялся 7 октября 1976 года. На экране первая в мире актриса голографического кино, Мария Воландина-Иванова перебирала драгоценности в хрустальной вазе.

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

🎱 Сложности при написании «99 бутылок» на «Электронике МК-61» ★

Микрокалькулятор Электроника МК-61 в картонной упаковке с описанием функций и рядом с самим устройством на светлом столе.
Тот самый калькулятор «Электроника МК-61», который попал мне в руки

Как и обещал в прошлый раз, хочу рассказать с какими сложностями мне пришлось столкнуться при написании «Песни о пиве» на программируемый калькулятор «Электроника МК-61».

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

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

Таблица 5: соответствие десятичных чисел (0–15), их двоично-десятичных кодов и символов на индикаторе, включая пробел.
По этой таблице калькулятор отображает шестнадцатеричные числа

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

Тем более мне очень повезло в том, что индикацией этого режима является именно восьмёрка, стоящая спереди — так похожая на первую букву в нужном мне слове. Как вы теперь понимаете, на экране в моей программе написано не «BEEr», с точки зрения калькулятора там одни числа и индикатор режима — «8.EEГ» или «EED» в привычной записи (десятичное «3821»).

Так же я воспользовался тем, что «F» в этой странной нотации — пробел, что позволило мне отделить число от «надписи». Дальнейшее — дело техники.

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

Маски и оставшиеся числа побитно накладываются двумя подпрограммами — по отдельности на диапазоны 0…5 и 6…9 — способы их получения разнятся. Я широко использую операцию «ИНВ» — она инвертирует биты числа, по логике инвертирования цифры 6…9 превращаются в на свои позициях 9…6, и тут никаких сложностей, а знаки в диапазоне 0…5 получаются сложнее — там накладываются сразу две специальные маски и счётчик.

Для примера кусочек подпрограммы, номер слева соответствует номеру инструкции при вводе в калькулятор и каждую строку я прокомментирую, но следует понимать, что в реальности эти комментарии частью программы не являются:

// когда что-то попадает в «X» предыдущее значение смещается в «Y» (там стек из 4 позиций)
45 1 // «1» кладётся в регистр «X», входной параметр сместился в «Y»
46 + // Y + 1, передаётся в «X», это коррекция данных после операций, которые шли выше
47 К П→Х 7 // в «X» помещается число из регистра (маска), указанного в регистре №7
48 + // Y+X → X
49 ИНВ // инвертирование битов в «X», сейчас на экране написано «8.EEГ» плюс некий пока мусорный символ
50 К П→Х 8 // в «X» помещается число из регистра, указанного в регистре №8
51 ^ // операция «И», на экране — «8.EEГ», из некого символа получилось требуемое число
52 В/О // возврат из подпрограммы

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

Подпрограмма вызывается два раза с разными параметрами — для десятков и единиц, получаются две маски, которые позднее накладываются друг на друга.

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

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

Оглядываясь на шахматы на sed (SedChess) ★

Это информационный пост, больше для себя. Для того, чтобы не забыть выводы и ощущения от сделанного.

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

Пара комментариев оттуда:

Комментарии с Реддита (81.73КиБ)

In Soviet Russia… 

Комментарии с Реддита (51.32КиБ)

Заодно мои «шахматы» попали на «ЛОР», «ОупенНет» и многие другие ресурсы (например, в английской «Википедии» в статье про sed, появилась ссылка на меня).

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

Сохранился один лист из блокнота на котором я расписываю как движется какая-то фигура (видимо, конь), её «стоимость» на каждой клетке и способ кодирования позиции в программе:

Конь ходит (90.68КиБ)

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

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

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

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

Удаляем раскладку «США» («U.S. English») из Mac OS X 10.9 («Maverick») ★

Как стало известно ещё на этапе появления ранних сборок «Маверика», раскладка «США» не удаляется из неё способом, который описал Артём Поликарпов (а я написал скрипт, автоматизирующий этот процесс).

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

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

После установки раскладки Бирмана, раскладок становится три: русская Бирмана, английская Бирмана и системная — «США». Последняя явно лишняя, но система удалить её не позволяет. Её удаётся удалить только в обмен на установку любой другой системной раскладки.

Но есть баг, спасибо ему, что он существует.

Настройка клавиатуры macOS: в списке языков выбран «Японский», справа отображается раскладка «Котоэри» и виртуальная клавиатура с латинскими символами.

Нужно поставить японскую раскладку «котоэри», потому удалить раскладку «США», потом «котоэри». В системе останутся только две раскладки Бирмана.

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

JavaScript, совмещённый с Brainf*ck: «hello friends» ★

Помните моё поздравление с Новым годом, написанное на запутанном Джаваскрипте? Такой же принцип я использовал для привлекающего внимание баннера нашей компании.

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

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

($=!{}[/-/+/\+@+@+!+/)-!{$:/>/+/!>/+/</}+
(_=!-{}-$+/>/)-~(/</)+
(_$=-$-{}-$+/>/)[$$=-(~-~$+~-~$-!+{$:/!</})+
_[$$+=~-~{$:/]/}+
_$-~{}+
_$[$$+~{_:-$>/]/}+
$-$$]

Оба интерпретатора выполняют её с разным результатом, Брейнфак выводит «hello», а Джаваскрипт — «friends»:

bolk@Bolk ~$ ./brainfuck <<<'($=!{}+[/-/]+/\+@+@+!+/)[-!{$:/>/+/!+>/+/<</}]+(_=!-{}+[-$]+/>/)[-~(/>[->+>+<<]>>[-<+<+>>]<<</)]+(_$=[-$][-{}]+[-$]+/>>/)
[$$=-(~-~$+~-~$-!+{$:/!+>+>+>+>+>+<<<<</})]+_[$$+=~-~{$:/[->++++>+>++++++++>++++++++>+++++++++++[<]]/}]+_$[-~{}]+_$[$$+~{_:-$>/[.>]/}]+$[-+-$$]'

hello

bolk@Bolk ~$ v8 -e 'print(($=!{}+[/-/]+/+@+@+!+/)[-!{$:/>/+/!+>/+/<</}]+(_=!-{}+[-$]+/>/)[-~(/>[->+>+<<]>>[-<+<+>>]<<</)]+(_$=[-$][-{}]+[-$]+/>>/)
[$$=-(~-~$+~-~$-!+{$:/!+>+>+>+>+>+<<<<</})]+_[$$+=~-~{$:/[->++++>+>++++++++>++++++++>+++++++++++[<]]/}]+_$[-~{}]+_$[$$+~{_:-$>/[.>]/}]+$[-+-$$])'

friends

Повозиться пришлось прилично, если честно, некоторые конструкции ДжЭс делит с Брейфаком (большинство квадратных скобок), а кое-где торчат чистые инструкции Брейнфака, засунутые в те места программы, где они не могут помешать своему соседу. Пустые циклы, которые образуются квадратными скобками я старался сводить к операции зануления ячейки („[-]“), сильно мешали плюсы, используемые в Джаваскрипте для объединения букв — они увеличивали содержимое ячейки в Брейнфаке на единицу, это приходилось учитывать.

Слово «friends» я выбрал потому что его легко записать:

"false"[0]+"true"[1]+"undefined"[5]+"true"[3]+"undefined"[1]+"undefined"[2]+"false"[3]

Принцип я когда-то более-менее подробно разбирал.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

END

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Сетевая игра на 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 комментарий

TrueColor GIF ★

TrueColor GIF (191.75КиБ)

Была у меня такая задумка — попробовать сделать полноцветную GIF-анимацию. Сразу скажу, идея провалилась, к сожалению.

Мысль-то простая — каждый полноцветный кадр должен представлять из себя полноцветный GIF. Общеизвестно, что формат GIF поддерживает только 256 цветов. Не страшно, разбиваем картинку так, чтобы каждый кадр содержал в себе не более 256 цветов и ляпаем их каждый поверх другого без задержки, в конце получится полноцветное изображение. Несколько таких изображений с задержкой между ними — и готова анимация.

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

Delay Time — If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered. This field may be used in conjunction with the User Input Flag field.

Но и если поставить задержку в 1/100 секунды, браузеры всё так же неторопливо отрисовывают картинку. Нарезанные кадры я собирал через утилиту gifsicle, она ещё и оптимизирует изображение — ненужные мне области я заливал прозрачным цветом, gifsicle умеет такие области отбрасывать, что уменьшает размер изображения:

gifsicle --delay 0 --crop-transparency -O3 out/*.gif > out.gif

Жаль, что ничего не получилось. Всё-таки надо переходить на APNG.

Зато выяснились любопытные подробности. Не знаю как это выглядит в IE (негде попробовать), а вот FireFox и Chrome умеют, один раз отрисовав конечную анимацию, потом мгновенно доставать её из кеша на перезагрузке страницы. «Опера», как и следовало ожидать, постоянно перерисовает анимацию — стоит только вернуться на страницу с другого таба или прокрутить её обратно до анимированного изображения.

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

data URL в IE ★

Пару лет назад я занимался проблемой data URL в Internet Explorer, добился определённых результатов, но то, что получилось, использовать было невозможно. Data URL (иногда его ещё называют «протокол data:») — возможность вставлять ресурсы (графику, CSS, JavaScript и так далее) в HTML код.

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

<img
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7" />

В Data URL указывает тип содержимого и способ его кодирования. Способа кодирования два — base64 (именно он и указан в примере), увеличивающий содержимое на треть и URL encoding (в этом случае способ кодирования не указывается) — привычный многим способ кодирования при помощи %xx, в лучшем случае вообще не увеличивает размер содержимого, в худшем — увеличивает в три раза.

Кстати, в настоящее время IE8b1 поддерживает data URL, но, увы, длиной не более 32Кб.

Теперь амбула.

Вчера ночью мне пришла в голову идея как можно попытаться корректно совместить data URL и включение картинок через протокол mhtml. То, что у меня не получилось два года назад, получилось сейчас.

Результат — готовый код на PHP из двух функций. Первую функцию («bolk_data_uri_header») нужно вызвать в самом начале перед выводом любого вашего кода, вторую («bolk_data_uri») собственно для включения картинки в код. Надеюсь на примерах всё понятно:

bolk_data_uri_header();

bolk_data_uri('myjpeg.jpg');
bolk_data_uri('ourpng.png', 'border: 2px dotted red');

Код самой библиотеки:

function bolk_data_uri_header()
{
    echo "<!--\n"
        ."Content-Type: multipart/related; boundary=\"=_NextPart_01C6A9B1.539AB070\"\n\n"
        ."--=_NextPart_01C6A9B1.539AB070\n"
        ."Content-Transfer-Encoding: base64\n"
        ."Content-Type: text/html\n"
        ."-->\n\n";

}

function bolk_data_uri($file, $style = '')
{
    if (!( file_exists($file) && ($data = @getimagesize($file)) )) return false;

    $name = uniqid('', true);

    if ($style <> '') $style = ' style="'.htmlspecialchars($style).'"';

    echo "<!--\n"
        ."--=_NextPart_01C6A9B1.539AB070\n"
        ."Content-Location: {$name}\n"
        ."Content-Transfer-Encoding: base64\n"
        ."Content-Type: {$data['mime']}; -->\n"
        ."<object data='data:{$data['mime']};base64,\n\n";

    echo base64_encode(file_get_contents($file));

    echo "' {$data[3]}{$style} type='\n{$data['mime']}'><img "
        ."src='mhtml:http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}!{$name}' {$data[3]}{$style} /></object>\n\n"
        ."<!--\n"
        ."--=_NextPart_01C6A9B1.539AB070-->";

    return true;
}

У данного метода, по сравнению с обычными data URL есть масса ограничений: необходим специальный заголовок в начале файла, т. е. этот метод невозможно использовать на чужих сайтах, этим методом нельзя воспользоваться (по крайней мере не в таком виде) для включения ресурсов внутрь CSS или JavaScript. В принципе, тут есть достаточно большое поле для экспериментов, возможно все или некоторые из проблем можно решить.

В разделе «храню» есть пример, который можно потестировать на имеющихся у вас браузерах. Уже протестировано на Opera 9.25 и 9.50b, FF 2.0.0.13 и 4 (Minefield), Safari 3.1 (Safari под iPhone — тоже), Internet Explorer 6.0SP2 и 7.0, Sony PSP browser, Opera mini, Netscape Navigator 9.0.0.5.

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