Brainfuck на AppleScript
Для развлечения написал интерпретатор языка Brainfuck на AppleScript.
Особенности: для ввода программы используется текстовое поле, которое выглядит как однострочное, но на деле понимает многострочный текст. Операция «,» у меня с буфером, это значит, что при запросе можно вводить сразу строку, при надобности интерпретатор сам будет брать оттуда значения. Если их не хватит, запросит ещё.
AppleScript медленный язык, следовательно и получившийся интерпретатор медленный (никаких оптимизаций я не делал), лучше всего на нём запускать небольшие программы. Например, «Hello, world»:
++++++++[>+++++++++<-]>.<+++++[>++++++<-]>-.+++++++..+++.<
++++++++[>>++++<<-]>>.<<++++[>------<-]>.<++++[>++++++<-]>
.+++.------.--------.>+.Не уверен, что нигде не ошибся Интерпретатор Brainfuck на AppleScript.
#!/usr/bin/osascript
-- AppleScript Brainfuck interpreter
-- Evgeny Stepanischev 1 Jul 2011 //bolknote.ru
set Cells to {}
repeat 30000 times
set end of Cells to 0
end repeat
display dialog "Enter your BF program" default answer ""
set Bf to text items of text returned of result
set Pointer to 1
set CmdPointer to 1
set Output to ""
set Input to {}
set Stack to {}
repeat while CmdPointer ≤ (count of Bf)
set Cmd to item (CmdPointer) of Bf
if Cmd is equal to ">" then
set Pointer to Pointer + 1
if Pointer > 30000 then set Pointer to 1
else if Cmd is equal to "<" then
set Pointer to Pointer - 1
if Pointer < 1 then set Pointer to 30000
else if Cmd is equal to "+" then
set Val to (item (Pointer) of Cells) + 1
if Val is greater than 255 then set Val to 0
copy Val to item (Pointer) of Cells
else if Cmd is equal to "-" then
set Val to (item (Pointer) of Cells) - 1
if Val is less than 0 then set Val to 255
copy Val to item (Pointer) of Cells
else if Cmd is equal to "." then
set Output to Output & (ASCII character item (Pointer) of Cells)
else if Cmd is equal to "," then
if Output ≠ "" then
display alert Output
set Output to ""
end if
if Input is {} then
display dialog "Enter one or more characters" default answer ""
set Res to text returned of result
set item (Pointer) of Cells to ASCII number of character 1 of Res
try
set Input to rest of text items of Res
end try
else
set item (Pointer) of Cells to ASCII number of item 1 of Input
set Input to rest of Input
end if
else if Cmd is equal to "[" then
if item (Pointer) of Cells = 0 then
set CmdPointer to CmdPointer + 1
set Deep to 1
repeat while CmdPointer ≤ (count of Bf)
set Cmd to item (CmdPointer) of Bf
if Cmd is equal to "[" then
set Deep to Deep + 1
else if Cmd is equal to "]" then
set Deep to Deep - 1
if Deep is 0 then exit repeat
end if
set CmdPointer to CmdPointer + 1
end repeat
else
set Stack to (CmdPointer - 1) & Stack
end if
else if Cmd is equal to "]" then
if item (Pointer) of Cells ≠ 0 then
copy item (1) of Stack to CmdPointer
end if
set Stack to rest of Stack
end if
set CmdPointer to CmdPointer + 1
end repeat
if Output ≠ "" then
display alert Output
end if
Как мне AppleScript
Миша, мой коллега, под постом, где я написал про интерпретатор Brainfuck на AppleScript с беспокойством осведомился, не подсел ли я на AppleScript.
Краткий ответ: нет.
Длинный ответ таков.
Мне непонятно текущее состояние AppleScript. Очевидно, что концепция «пользователь пишет программы на английском» вполне себе ничего. Для непрограммистов это был бы выход. А для программистов такой язык жутко неудобен. По понятными причинам. Программисты привыкли писать много, а на велиречивом AppleScript писать не каждому понравится (не пишу «никому», потому что существует же Objective C). Все эти сокращения в языке — «собачки», доллары и разные скобочки, их нужно помнить, но они здорово экономят время при написании программы и при её чтении. Потому что они короткие и их больше помещается на экране.
Текущее состояние непонятно, потому что цели своей авторы языка не достигли. До сих пор нужно писать «set Var to Var + 1» и нельзя «set Var to Var plus one», какой же это английский? При этом язык уже полтора года не развивается.
То есть проблема «иногда быстро писать мелкие программы» явно пока не решена. Так как для этого «иногда» надо иметь память робота, чтобы вспомнить через несколько месяцев как в этом языке
Например, чтобы вызвать текстовый редактор и написать там «Hello», нужно сделать следующее:
tell application "TextEdit"
activate
tell application "System Events" to keystroke "hello"
end tellЯ открываю приложение TextEdit (так встроенный в MacOS текстовый редактор называется) и прошу System Events понажимать в редактор несколько клавиш. Выделенное наклонным — это как раз пример такого API. Причём, если написать в кавычки «³˚¹⁄₃¹⁄₂», то программа либо не сделает ничего, либо напечатает в редактор ерунду. Всё устроено так, как будто System Events действительно жмёт клавиши на клавиатуре. А вот эти символы система не знает как ввести. То же будет с китайскими иероглифами, например.
Ещё, когда я только начал знакомиться с AppleScript, у меня было заблуждение, что AppleScript — язык общего назначения, вроде PowerShell или Bash. Ничего подобного, вместо bash в Mac OS есть bash. AppleScript толком не умеет даже получить данные от пользователя, скажем перехватить нажатие клавиши (и нет ничего встроенного, что может ему в этом помочь), а уж о том, как мало он умеет самостоятельно выводить и говорить нечего.
Так что симпатии к языку у меня не появится, думаю. Не для меня он. Но писать я на нём иногда буду, я и на CMD много странного писал в своё время.
«Гонка версий»
Смешно,
Пока фирма Netscape выпускала свои бесконечные 1.00, 1.1, 1.22, 2.0, 2.01, 2.02, 3.0, 3.01, 3.02, 3.03, 3.04, 4.0, 4.01, 4.01a, 4.02, 4.03, 4.04, 4.05, 4.06, 4.07, 4.08, 4.5, 4.51, 4.6, 4.61, 4,7, 4.72, 4.73, 4.74, 4.75, 4.76, 4.77, 4.78, 4.79 и 4.8, «Микрософт» выпускала и продолжает выпускать IE 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 5.5, 6, 7, 8, 9 и 10. Причём, последние версии ещё и ноль в конце потеряли.
Версия 1.5 была явным заблуждением, а 4.5 я в список не включил — это отдельная ветка, её для «Мака» делали, так же как и другие, ещё менее известные подверсии для других систем.
Автоэкзотика — 2011
Сходили сегодня на «Автоэкзотику» на Тушинском аэродроме города Москвы. Шоу «Автоэкзотика» — это выставки автомобилей, мотициклов, гонки и вообще всё, что связано с машинами. Шоу проходит с первого по десятое июля.
Мы посмотрели машины и увидели мотоциклетный стантрайдинг. Более задерживаться не стали — сегодня очень жарко, побоялись обгореть.
















Уже жалею, что у меня нет суперзума. Бо́льшую часть потрясающих трюков спортсменов я не смог снять








В следующем году надо обязательно сходить ещё, но на этот раз надо будет внимательно изучить программу шоу и сделать поправку на то, что будет жарко — взять холодной воды и головные уборы.
«Без булдырабыз»
Я всё меньше с каждым днём понимаю «Идиотеку» у Студии. Да, раньше там были фотографии, посмотрев на которые, так и хотелось воскликнуть «Идиоты!». Потом там пошли фотографии природных явлений, съёмок со специально выбранного ракурса, когда у памятника неудачно торчит палец в районе брюк, теперь вот —
В чём
Галереи теперь в трансляциях
Сделал, как многие просили, фотогалереи в трансляциях RSS. Теперь всюду, куда транслируется мой блог («Ярушка», ЖЖ и т. д.), видно бо́льшую часть фотографий (не более десяти). Галереи там, конечно, условные — с миниатюры ссылка ведёт на полное фото.

Вот, кстати, о чём совершенно забыли создатели современной версий HTML — это форматирование HTML там, где всё плохо с CSS. В читалках RSS (тут CSS режется из соображений безопасности) и почтовых клиентах (те же соображения, плюс примитивные движки в некоторых приложениях). Я, пока отлаживал трансляции, убедился, что единственный способ всё отформатировать как надо — использовать таблицы и винтажные 0.gif. Но чем дальше, тем меньше можно сделать атрибутами тегов, да ещё и в условиях, когда лента встроена в документ, где уже есть стили (например
Конечно это правильно, разделение данных и представления, но HTML5 не предлагает взамен безопасного внедрения чужого контента в изолированном окружении, что полностью решило бы проблему. Есть специальный режим у IFRAME, но фреймы — это совсем не то, они не ведут себя как часть страницы, скорее как окошко в другой документ. Полосы прокрутки, развыв выделения текста и так далее. Всё не то.
Отпуск
С 22 июля по 7 августа мы с женой в отпуске. Маршрут выглядит следующим образом.
Москва ✈ Нижнекамск → Лениногорск → Сергиевск → Казань ✈ Москва ✈
Признаки того, что человек тонет
За редким исключением, тонущие люди физиологически неспособны позвать на помощь. Дыхание — основная функция дыхательной системы, а речь — дополнительная. Чтобы говорить, необходимо иметь возможность дышать.
Рот утопающего периодически скрывается под поверхностью воды и появляется снова. Времени, которое рот находится над водой, недостаточно, чтобы выдохнуть, вдохнуть и позвать на помощь. Утопающий успевает только быстро выдохнуть и вдохнуть.
Утопающие не могут размахивать руками, зовя на помощь. Инстинкты заставляют их раскинуть руки в стороны и отталкиваться от воды, пытаясь поднять тело вверх, чтобы рот показался над поверхностью и они могли сделать очередной вдох.
При инстинктивной реакции утопающего человек не может управлять движениями рук. Утопающий физиологически неспособен перестать совершать инстинктивные движения и начать совершать осмысленные, например, размахивать руками, двигаться к спасателю или хвататься за спасательные приспособления.
Пока продолжается инстинктивная реакция утопающего, тело человека остаётся вертикально в воде, без малейших признаков поддерживающих движений ногами. Если его не спасут, утопающий может продержаться в воде от 20 до 60 секунд перед полным погружением.
Из переводной статьи «Утопление не выглядит таковым». Статья стоит того, чтобы прочитать её полностью. Ещё полезно прочитать комментарии спасателей по ссылкам в конце статьи.
Лайфхак для стопщиков
Кто-то из великих автостопщиков, кажется Антон Кротов, говорил, что если не ладится контакт с водителем и кабину наполняет гнетущая тишина, следует посмотреть в окно и произнести волшебную фразу: «Довели, бл██ь, страну…» После этого даже самый угрюмый водитель оживляется и следующие два часа вы проведете в живой беседе, где вам даже не обязательно отвечать.Примерно то же самое происходит, когда вы едете в плацкарте, а уж тем более — когда лежите в больнице.
Отличный лайфхак у Каганова нашёл. Я пользовался им зеркально — когда водитель очередного «мотора» произносит эту фразу, достаточно поддакнуть в тон и всё, можно не переживать за водителя — ему тишина уже не кажется гнетущей. Мне она никогда гнетущей не кажется, если мне хочется молчать, я молчу, но почему бы не послушать человека, если тому от этого легче?
Теперь можно не доводить человека до неудобной ситуации, а позволить заполнить тишину до того как она стала гнетущей.
В IE10 не будет попадать под conditional comments
«Микрософт» решила, что conditional comments не должны обнаруживать IE10. То есть, по идее, условия «[if IE]», «[if IE 10]», «[if IE gt 5]» работать не должны, а «[if IE lte 9]»
Поведение изменено
Because some features in earlier versions of IE aren’t compatible with HTML5 parsing, we’ve removed them from IE10 mode. Sites that rely on these legacy features will still work when running in legacy modes. This way, sites that work today will continue to work with IE10 even if the developers of the site don’t have the time to update them.
Причём «Микрософт» тут же признаётся, что парсер ни при чём:
This means conditional comments can still be used, but will only target older versions of IE.
Если часть условия conditional comments
Скорее «Микрософт» этим шагом заявляет, что «мы так всё идеально поддерживаем, что нет нужды отделять IE от других браузеров». Может быть это и так. Но я был бы рад, если бы conditional comments появились в других браузерах, а не исчезли был из IE.
Помимо этого из IE10 исчезнут Element Behaviors и XML Data Islands.
Добавлено позднее: мы тут поговорили с Вадимом Макеевым, кажется, я ошибаюсь. В режимах эмуляции старых браузеров (вероятно в этот момент работает отдельный движок), conditional comments работают, в режиме IE10 — нет.
Безопасная транзакция по банковской карте

Какой там HTTPS, 3D Secure и прочее? Гостиница «Островок»
Немного статистики
Из 306 родственников, заведённых на сайте генелогического древа, больше всего Александров, Иванов, Валентин и Ольг.
Про вред пассивного курения
Потом стали известны кливлендские исследования, неопровержимо доказавшие вред пассивного курения. Хирурги Кливлендского института, выполнявшие операции на легких, видели, что органы дыхания были повреждены дымом как у активных курильщиков, так и у пассивных. Только разные участки. Курящие люди вдыхают горячий сигаретный дым, поэтому дышат поверхностно. Пассивные курильщики вдыхают глубоко, от этого и повреждения, вызванные дымом, залегают у них глубже.
Из статьи «Город некурящих», с сайта «Аргументов и Фактов».
Купил SD Card 64ГБ

Готовлюсь к отпуску — купил карточку для фотоаппарата SD Card на 64ГБ. Я, конечно, сталкивался, с «коммерческим гигабайтом»,
macos-x:~ bolk$ dd if=/dev/zero of=/Volumes/Photo/zero
Add: /Volumes/Photo/zero: No space left on device
118568449+0 records in
118568448+0 records out
60707045376 bytes transferred in 5609.439860 secs (10822301 bytes/sec)Стань стальной крысой!
Решил показать жене
Сделал конвертор на «Пайтоне», преобразующий книгу с «Либрусека» в HTML (может так же использовать любое «зеркало», например копию на «Флибусте».). Получается гиперигра (работает только в современных браузерах), плюс я запрограммировал простенький ДОСП (см. книгу) на JavaScript.
# coding: utf-8
import re, urllib
n, articles, skip = 0, {}, True
content = urllib.urlopen('http://lib.rus.ec/b/115854/read')
for line in content.readlines():
line = re.sub(u'<[^>]+>', '', line.decode('utf-8'))
if line.find(u'Добро пожаловать!') != -1:
skip = False
elif line.find(u'Оглавление') != -1:
break
if skip: continue
try:
n = int(line)
except ValueError:
line = re.sub(r'\[\s*(\d+)\s*\]', r'[<a href="#a\1">\1</a>]', line)
try:
articles[n] += line
except KeyError:
articles[n] = line
articles[0] = re.sub(r'\[([^\]]+)\]', r'[<a href="#a30">\1</a>]', articles[0])
t = u"""
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8" />
<title>Стань стальной крысой</title>
<style type="text/css">
html {
background: white;
}
body {
background: #eee; color: black;
font: 14px/1.4em Helvetica, 'Trebuchet MS', Arial, sans-serif;
padding: 20px;
margin: 100px;
}
header {
font-size: 25px;
margin: 0 0 20px;
padding: 0 0 5px;
border-bottom: 2px solid #ccc;
color: #ccc;
}
article {
display: none;
white-space: pre-wrap;
}
article:last-of-type {
display: block;
}
article:target ~ article:last-of-type {
display: none;
}
article:target {
display: block;
}
footer {
margin-top: 10px;
color: #ccc;
text-align: right;
font-size: x-small;
}
i {
cursor: pointer;
background: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQECAQECAgMCAgICAgQDAwIDBQQFBQUEB-
QUFBggHBQYHBgUFBwkHBwgICQkJBQcKCgoICggJCQj/wgALCAAtACwBAREA/8QAGwAAAgMBAQEAAAAAAAAAAAAABgcEBQgCAwn/2gAIAQEAAAAB+zdD-
Wxyy5FAAc4AtfBIfe0adbXjDJ+UuXGa9nRF1ti8ReInBsko//8QAHhAAAgMBAQADAQAAAAAAAAAABAUBAgMABhESExT/2gAIAQEAAQUC23rhXT9LxNx46Cv-
ykUyhMdGn2s2IYV6qi9uJ0MBHqwNDJGIzLHpMQOyy23J5nWJFMr9aeTcUoBiw/lC1YyTAZND7mD5cbNddfEAVaLfTLZwpnlr8w0/DPW55FSxt22y1eMqA5340I-
mWXp26ojyqc/wBNZSmXJBu//8QANRAAAgECAwQFCgcAAAAAAAAAAQIDAAQRITEFEhNBEBRRYaEiJDJSU3GBkbHhBkJDcsHC0f/aAAgBAQAGPwLFgWY5Ko1Y-
1vXU5iX2cRw8dayt9/vbWsUZ4+4tvCsNJBqOiW7bPMpEOwff/KgjsVXiyEgyyejF8OdFrnat3PMeYmKD5LSx8TrGeAkbWo7tZmYqccCcjUNzFnG67wq0jGixL9K2-
YqjzdZDLIfcMAPHw6Ix+YvRq4tZv0Z9we4qrf2q2jnUvcRebS9zrl4jA0E4W7HiDrnkcanS3Q70Z3W54HCg7XflgeguYrhKcF1Y9g5mr7ahUxxz3bsgPYFVfqpq/2r-
aw8VpFTirjpun0vkT8qZYCt2VALKh8oD3ULYR8FPUAwxP81iIuqwevJ5K/eoPw/sKUvdSk9bm9ggOp9XuGpyq02bZpuW0KCNR0SX1lOdnXAXQDeTly5acjTWnX-
7iXBeHiLhlGOWeHw8a6xcbae1XcCtw48ZGH7mJw05Cuq7Ot+ChO87E4tI3ax5no//8QAIxABAAEDBAICAwAAAAAAAAAAAREAITFBUWGBEHGRobHh8P/aAAgB-
AQABPyEqxIGdgVfUsJ+Ru6gr73E/JlqZ5yH4hx1FNLcYbJueByIk0WF7E+qLSPukAzuOhxQ2XA7eIgpxNKh4mzFl5qU2VaGpHNMPBcE6UzklnNtQPJc6r2mfg/LyD0-
H78Qb26cP5Kq0e745LoKYNx4vQZaYpG8I4IGJ9NXxDiMb26dNGYrOxr/B4cCmRDpTYK7Qdh4c0owRRcCOuIS+KSNRXOjKpqXev7Yaz9CWrIs9hBjaZWuCSLV6n-
FkGfbmvunXUnUitIcWA4oVjEQY3zu1o9mPoOicwXIG9RPIIHstu274//2gAIAQEAAAAQ2dRilY//xAAhEAEBAAICAgMAAwAAAAAAAAABEQAhMUFRYRBxgZGhwf/-
aAAgBAQABPxCWwNoyhKHSqoAKoFyNtZF/Ggp5TeHJYaOLr3/oYqGcsVdn0/b3llDWp5X2cUdi76XCLvgQuH7VnJHWMFrCpmiO1uCq5PGT7rUN6R+3ASpkpRBA-
DZpsNi1wp72Lwl4AKM6c5+K8UCqnY0fY5YWk9kv6TGNaoB9kOE+G/lT8LF/k4NnJgUQ3s0thUGxBwMpLQDQaLlWnddQSJsOnKgTTCGICgXiXGrMihvNBj7PI4Kk-
PKg1HoC/1zjTHn2P0ezQTkwAlegiHQE2iKtFDBaAq17SIHaW6x4rugOBoqKtKub+vSsjRplWzSnRjAnKRqMeUdR0AB+C0A61Tsq9riCIgEiJRMMifRjYvlnAnk5eelvIr-
ZUqRz3rYO3LAmNdBkFRMXKK4ZalhVTlfj//Z');
display: block;
width: 44px; height: 45px;
margin-top: 10px;
}
</style>
<script type="text/javascript">
function Coin(n) {
location.hash = '#a' + n[Math.floor(Math.random() * n.length)];
}
</script>
</head>
<body>
<header>Стань стальной крысой. Гарри Гаррисон</header>
%(articles)s
<article id="a0">%(welcome)s</article>
<footer>Адаптировано Евгением Степанищевым. <a href="//bolknote.ru">bolknote.ru</a></footer>
</body>
</html>
"""
def dosp(v):
v = v.strip()
if re.search(u'ДОСП|(?i)случайных процессов', v, re.U):
n = ','.join(re.findall(u'href="#a(\d+)"', v, re.U))
return v + u'\n<i onclick="Coin([' + n + u'])" title="ДОСП"></i>'
else:
n = re.findall(u'\[[^]]+\]', v, re.U)
return v + (u'\n\nИдём дальше? ' if len(n) == 1 else u'\n\nКуда дальше? ') + ', '.join(n) + '.'
welcome = articles[0]
articles = ''.join(
'<article id="a' + unicode(k) + '">' + dosp(v) + '</article>'
for k, v in articles.iteritems() if k
)
t = t.replace('-\n', '') % vars()
open('index.html', 'w').write(t.encode('utf-8'))Конвертор создаёт на диске файл «index.html», который надо открыть браузером.
Ещё немного статистики
Почти половина (48,41%) поисковых переходов за прошедший месяц — это запросы
«петрушка наркотик»
и модификации.
Красавица → чудовище
Во время просмотра этого видео держите взгляд на перекрестии.
Исскуственное или настоящее?
Мы с женой сегодня в «Мосцветторг» ходили, покупать её коллеге букет на день рождения. Цены там действительно низкие, как и твердит реклама на каждой бумажке, валяющейся около метро. Но низкие цены — это не интересно. Интересно, что цветы, которые там продаются я перепутал с исскуственными. Пару минут я тыкал пальцами в каждый из них и спрашивал — «Этот настоящий? И этот?».


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

Мне тут стало интересно что такое «третий мир» и где находится второй. Поскольку я ни разу за жизнь не слышал упоминания мира второго, то думал, что это
Третий мир — географический термин второй половины XX века, обозначавший страны, не участвующие прямо в холодной войне и сопутствующей ей гонке вооружений. В современном употреблении мало отличается от термина «развивающиеся страны»…
Изначально он относился к странам, которые во время холодной войны не относились ни к первому миру (НАТО), ни ко второму миру (Варшавский договор).
Отсюда, кстати, следует, что Россия (как наследница СССР) не относится к странам третьего мира, мы — второй мир, так как СССР одна из стран Варшавского договора. А картинке сверху выделены страны третьего мира.
Ура, спама нет!
Помню несколько лет назад мне приходилось вставлять свой адрес электронной почты на страницу при помощи JavaScript, да и ещё не совсем тривиального, для защиты от спамеров. Попасть в полумифические «спамерские списки» было неприятно, ящик заваливало всякими «ликвидациями фирм», «сдачей площадей под офис» и прочим мусором. Корреспонденцию приходилось вылавливать, фильтры помогали мало, прогнозы давались самые неутешительные — что почта скоро перестанет существовать
Лучшие умы вместе с худшими думали над решением этой проблемы. Одно из решений, придуманных тогда — заставить программу, отправляющую письмо решить
В 2004 году появилась гугловская почта GMail, тогда ещё по инвайтам. Гугл сразу нацелилась на борьбу со спамом. Это была первейшая причина почему я захотел инвайт туда. Война со спамом велась с переменным успехом, а когда я обнаружил, что мусора стало приемлемое количество, я убрал свой замороченный JavaScript и написал email как есть.
Вчера я поймал себя на том, что давно уже не вижу спама во входящих. Ни на GMail,
Последний газовый фонарь Москвы
Сегодня выполнил квест — искал последний газовый фонарь Москвы. По крайней мере утверждается, что он газовый. Понятное дело никто точно не знает последний ли он, вот я не обратил бы внимания на такую деталь арки, так что может и ещё
Такие фонари в Москве были окончательно заменены электрическими в 1932 году, значит этому фонарю должно быть около 80 лет.
Надо будет сообщить музею «Огни Москвы» о его существовании, может посмотрят что это на самом деле и отреставрируют, если он
Добавлено позднее: получил ответ от музея:
Спасибо, Евгений! Про этот фонарь мы уже знаем. Не уверена, что он газовый. Нужно проверять. Есть еще несколько газовых фонарей в нашем городе. Сейчас мы собираем информацию и в скором времени будем пытаться сделать так, чтобы их все взяли под контроль. По крайней мере всем директорам предприятий обслуживающих наружное освещение уже дано указание перед демонтажем фонарей старше
70-х годов ХХ века обращаться к сотрудникам музея. Спасибо за Вашу заботу. Будем рады, если отыщете ещечто-нибудь интересное. С уважением, Наталья.
Москва ✈ Казань ✈ Москва
В пятницу вечером срочно вылетаю в Казань, пробуду по вечера субботы. Ничего особенного, рабочие вопросы.
33000 и анимированный GIF

По всей видимости, «Опера» немного неправильно обрабатывает анимированные «гифы».
Анимированный GIF устроен очень просто — поверх первого кадра через заданное время лепится следующий. Задержка задаётся в сотых долях секунды и, согласно спецификации, поля для её хранения имеет размер беззнаковое слово (2 байт), то есть максимальное значение — 655,35 секунд или почти 11 минут.
Распространённая ошибка в Си и похожих языках — использовать вместо беззнакового число со знаком. Тогда максимальное значение по модулю сокращается в два раза.
Вот я и проверил — не содержат ли кодеки популярных браузеров эту ошибку. На картике — число «1», если оно через
У меня на ноуте на FF 5, Safari 5.0.5, Chrome 12.0.742.122 цифра меняется, а на «Опере» 11.50 — нет. Сейчас попробую найти ноут с Windows 7 и попробую там. Попробуйте тоже на своих браузерах.
Добавлено: меняются ещё цифры на Андроиде 2.3.4, на FF 4.0.1 (Windows), а так же под Internet Explorer 9.0 и 10PP2 (Windows 7).
Добавлено ещё позднее: всё в порядке у «Оперы», разъяснил один из читателей — «Опера» начинает анимацию заново, если GIF не было видно. Дожидаясь, я переключал табы, поэтому анимация стартовала всегда сначала и «2» не появлялась. Так что ложная тревога, но любопытный факт.
Оператор goatse в Перле
Внезапно вспомним Перл.
Есть такая шутка, что Перл единственный язык, программа на котором до и после
not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort splitЕсли не верите, попробуйте запустить, ничего страшного не произойдёт. Очень много шуток есть по поводу того, каким ненатуралом надо быть, чтобы программировать на этом языке и в этом тоже есть доля правды.
Я постараюсь пропустить неаппетитные подробности, но есть такой мем «goatse» — это картинки мужичка, в деталях показывающего свою тёмную неизвестность, а так же пародии на неё. Не гуглите пожалуйста это, прошу, нет, даже умоляю, не надо. Та картинка, как любой
Для нас важно, что после того как картинка стала мемом, появился смайлик „=()=“, довольно точно отражающий её суть. Я знаю эту преамбулу, потому что однажды
Например, вам нужно подсчитать сколько цифр содержится в строке. На помощь вам придёт goatse operator!
my $s = "Hello, world! This is a Perl! 123456";
my $c =()= $s =~ /\d/g;
print $c;В результате будет напечатано число шесть.
Как это работает и почему нельзя
Сначала отвечу на первую часть.
Самое правое выражение в рассматриваемой строчке — регулярное выражение, которое ищет одну цифру, оператором «=~» мы применяем его к конкретной переменной, а ключ «g» в конце регулярки говорит, что искать надо все вхождения.
В Перле есть понятие скалярного и списочного контекста. Результат может сильно отличаться в зависимости от того ожидается ли
Например, если я попробую напрямую присвоить результат выполнения регулярного выражения на переменной „s“ в скалярную переменную (начинается с доллара), то я получу флаг, показывающий встретились ли вообще цифры в рассматриваемой переменной. Если же присвоить тот же результат массиву (имя переменной начинается с «@»), то я получу массив совпадений.
С goatse operator происходит следующее.
На деле «() =
Получается «SCALAR = LIST0 = LISTREGEXP», что возвращает нам количество элементов массива LISTREGEXP при любом не константном LIST0. Двумя присваиваниями, идущими подряд, вряд ли
Теперь ответ на второй вопрос. Нельзя ли
my $s = "Hello, world! This is a Perl! 123456";
my @c =$s =~ /\d/g;
print scalar @c; # массив в скалярном контексте вернёт количество элементовНо это скучно.
Макбук под рентгеном

Меня вчера на Охотном ряду остановили в метро, попросили рюкзак положить в эту «микроволновку» и даже совершенно не препятствовали тому, чтобы я это всё сфотографировал (правда на телефон, фотоаппарат в рюкзаке остался). Итого на фото видно мой Макбук (в алюминиевом корпусе) и фотоаппарат (продолговатое тёмное на фоне ноута).
location.reload() ≠ location.href=location.href
Увидел у Никиты Васильева во внутренних бложиках, что вызов «location.reload()» не эквивалентен присваиванию location.href в себя же. Оказывается, последний перезагружает страницу из кеша во всех браузерах, кроме «Оперы».
Нет ли тут расизма?

Не хочу я выключать ноут в самолёте-2
Помните мы обсуждали нужно ли выключать технику в самолёте?
Я сегодня летел
Через проход сидел дядька, смотрел с «айПада»
В двух сидениях позади меня техникой пользоваться уже нельзя (я не раз летал рейсами S7), хотя я ближе к кабине (собственно, на рейсовых самолётах я в первый раз в жизни летел в первом ряду).
Дополнено позднее: обратно летел совместным рейсом «Аэрофлота»
Плагины по запросу в «Опере»

Хочу похвалить «Оперу» за галочку в настройках, которая недавно появилась. С ней стало удобнее. Теперь можно выключить плагины (Flash, Java, Silverlight и остальное, в куче) для всех сайтов разом, а потом включить их для определённых сайтов (YouTube, RuTube, video.yandex.ru и так далее) в отдельных «Настройках для сайта» (открывается по клику правой на странице).
На местах, где должны показываться плагины, если установлена галочка «включать плагины только по запросу», показывается большая серая треугольная кнопка проигрывания, которая запускает
Очень удобно. Спасибо, ребята!
Сравнение объектов встроенных типов в Пайтоне
Некоторым ребятам показалось, что в заметке про «goatse operator» в Перле я поругал этот язык. Это не так, можно прочитать заметку от и до, чтобы в этом убедиться. Мне очень нравится Перл, но это язык не для современного продакшна. Давайте я
В Пайтоне всё что только можно — объект и нет примитивных типов. С объектами можно делать всё что хочется — сравнивать, умножать, производить битовые операции. Чтобы программист мог указать как объекту следует себя вести рядом
In [26]: "Это строка".__eq__
Out[26]: <method-wrapper '__eq__' of str object at 0x10136f770>
In [27]: "Это строка".__ne__
Out[27]: <method-wrapper '__ne__' of str object at 0x10139cf70>Сравнивать между собой можно большинство встроенных типов — список с со словарём, строку с кортежем и так далее. Есть исключения (например, set нельзя сравнить ни с чем, кроме set и frozenset), но их мало. Какой же будет результат сравнения? Давайте попробуем:
In [44]: "">()
Out[44]: False
In [45]: ""<()
Out[45]: True
In [46]: []>()
Out[46]: False
In [47]: []<()
Out[47]: True
In [48]: []<{}
Out[48]: False
In [49]: []>{}
Out[49]: TrueДаже пустые объекты разных типов не равны между собой,
In [52]: [1,2,3,4,5,6]<(0,)>[100000]
Out[52]: TrueНе знаю где это написано в документации, не искал, но я совершенно случайно,
True < {} < [] < object() < "" < () < u""
# b < d < l < o < s < t < uРешение мне кажется, мягко говоря, неудачным, но уж какое выбрали. Я не вижу ничего страшного в том, чтобы сравнение встроенных типов всегда выдавало False (попробуйте сравнить между собой два None) или выдавать исключение при попытке их сравнения (кажется
Моё рабочее место

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

Фотографии макаки, которая якобы сфотографировала себя на фотоаппарат, случайно оставленный
У меня большие сомнения, что макака могла найти нужную кнопку и понять закономерность, ну да бог с ними, нас убеждают, что фото сделала макака, давайте поверим.
Итак, фото сделано макакой. Внимание вопрос: кому принадлежат копирайты на данные фотографии?
Вроде бы очевидно, что это теперь общественное достояние, так как фотограф (по первой озвученной версии) случайно оставил фотоаппарат и на кнопку нажимало (являлось автором творчества) живое разумное существо (пусть и с низким IQ), права которого не регулируются законами о копирайте.
Тем не менее, фотограф, которому принадлежит фотоаппарат и агенство, которому были (я так думаю) проданы снимки не согласны. Интересно будет посмотреть за развитием событий.
У клиента дохлый канал?
В 1997 году, когда я впервые увидел веб через графический браузер (до этого у меня был опыт выхода в интернет через терминал на базе i80286 через текстовый браузер Lynx), у меня была выделенка, дело было в Казанском Государственном Университете и ещё очень долго я не знал что такое диалап и оплата за трафик.
Сейчас выделенки у большинства, но нередко встречается и такое, что клиент приходит на сайт через «дохлый канал» или с оплатой по трафику (например, через сотовый телефон).
Хорошо было бы об этом
Я вижу несколько путей.
- можно замерить время за которое страницу удалось отдать клиенту целиком. У меня пока нет оформившихся мыслей о том как это делать и есть недостаток — когда мы узнали о том, что у клиента плохой канал, содержимое уже выдали, ничего поменять нельзя. Можно выдавать
chunked-контент, как предлагал Сергей Чикуёнок, но первый кусок должен быть значительным - после загрузки страницы «пропинговать» хост. То есть обратиться через XHR на свой же сайт и замерить время ответа. Опять же, что делать с этими данными? Есть возможность в следующий раз показать более бедное содержимое, но следующий запрос может идти через другой канал. Возможное решение — сохранять
IP-адрес запроса - смотреть с какого браузера клиент приходит, если это «Опера Мини», вероятнее всего, канал плохой или с оплатой
- опять же «Опера», если включена функция «Опера Турбо» (определяется
по IP-адресу клиента), клиент экономит трафик, значит канал с оплатой - проверить грузятся ли картинки, способов много, но данные получаем постфактум, после загрузки страницы. Логика та же — выключил картинки, экономит. Загрузку Flash контролировать смысла не имеет — многие выключают, чтобы не видеть рекламы
- проверять не пришёл ли человек через канал сотового оператора
(по IP-адресу). Безлимиток, которые бы не деградировали по скорости послекакого-то лимита пока исчезающе мало, так что имеет смысл отдавать в этом случае «обеднённый» контент. Мобильные браузеры определять смысла не имеет — клиент может прийти через WiFi - в комментариях подсказали, что в «Андроидах» 2.2 и выше есть специальное
API, чтобы определять способ подключения - ещё вариант из комментариев — определять модель телефона/планшета и по базе смотреть есть ли у него GSM/3G или WiFi
Кто-нибудь ещёкакие-то пути видит?
Кодировка rot13 в Пайтоне
В стандартном интерпретаторе Пайтона есть много такого, что иначе как «пасхальным яйцом» не назовёшь. Например, можно попробовать импортировать модули «__hello__», «this» или сделать «from __future__ import braces» (попробуйте), но следующее просто гениально, хотя, видимо, получилось случайно.
В файле программы на Пайтоне в специальном коментарии принято указывать кодировку файла. В случае с латиницей работает и без этого, если применяется
Вот вполне валидная программа, которая выполняется и делает нечто осмысленное:
# coding: rot13
vzcbeg __uryyb__
cevag "Zl anzr vf Ritral Fgrcnavfpuri nxn Obyx!".rapbqr("rot13")Кодируется только текст программы,
Проверка типа соединения в «Андроидах»
Оказывается в «Андроидах», начиная с версии 2.2 есть специальное свойство у navigator.connection, которое позволяет узнать тип соединения: «navigator.connection.type». Объект «navigator.connection» содержит так же несколько констант, с самодокументируемыми названиями, которые содержат все возможные значения типа соединения: UNKNOWN, ETHERNET, WIFI, CELL_2G, CELL_3G.
with (navigator.connection)
if (type == CELL_2G || type == CELL_3G) {
// медленное и/или платное
}На последней, на данный момент прошивке iOS на iPhone 4, увы, это свойство не поддерживается.
JPEG vs. DjVu
Мне кажется, формат DjVu получает незаслужено мало внимания. Те, кому надо хранить документы, делают это, чаще всего, в JPEG или TIFF (а то и в PNG), а об DjVu вообще мало кто слышал. Я взял первый попавшийся в поиске документ, чтобы проиллюстрировать всю мощь формата.

Картинку я уменьшил (до 636 по ширине) и сконвертировал в два формата. Слева на картинке JPEG, справа DjVu. Картинка в JPEG занимает 85КБ (качество — 85%, сжато jpegtran), в DjVu — 13КБ (качество — «normal», сжималось any2djvu). Выигрыш в 6,5 раз при сходном качестве.
За счёт чего достигается такой результат?
Дело в том, что JPEG — формат общего назначения, он ничего не знает о том какое изображение хранит, DjVu придумывался специально под текстовые документы и знает — внутри него, в основном,
Поэтому обрабатываемое изображение разделяется на три слоя: фон, передний план и маску. По сути, изображение разделяется на две части: то, что будет сохранено с низкой детализацией (иллюстрации и фон) и то, что с высокой детализацией (текст). Маска нужна, чтобы при просмотре наложить одно на другое. Обе части сжимаются
Эффективность сжатия DjVu сильно зависит от того есть ли на картинке задний фон, если его нет и изображение только
Спяааат устааалые игрушки, книжки спяааат…
Сегодня скрипач в метро, в переходе с Театральной на Охотный ряд играл «Спят усталые игрушки…». А у меня рефлекс ещё с советских лет, я же в детстве смотрел «Спокойной ночи, малыши!», там если играла эта музыка, то всё, Хрюша и Степашка прощаются с вами, пора спать. Весь рабочий настрой с утра сбил! Нельзя так, товарищ!
☁☁ ✈ ☁☁ ☀
Мы тут с женой в отпуск собрались, не теряйте! Как получится писать не знаю. Повторяю маршрут, если что. Сегодня в 22:40 вылетаем.
Москва → Нижнекамск → Лениногорск → Сергеевск → Казань → Москва →
По родным

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

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

Здравствуй, ночной Питер! Расположились на тринадцатом этаже, в хостеле «Островок». Хороший, чистый хостел с бесплатным WiFi. Горизонт завален, сил ни на что больше нет, пойдём спать.
P.S. Это не белые ночи, это выдержка 30 секунд.
Питерское метро

Мы в Питере второй раз, а в метро — в первый. По сравнению с московским станции скучные или мы были
Сильно поразили выходы на некоторые станции — останавливаешься в тоннеле, вдруг стена открывается и через двери видно станцию. Безопасность выше, но иногда неудобно — если сидишь в первом вагоне, то не все двери могут открыться, для самых первых таких «ворот» в стене может не оказаться.
А вот странность — купил карточку на 10 поездок, оказалось, что между активациями должно проходить не менее 10 минут. В Москве иначе — я могу по карточке пройти хоть 10 раз подряд или провести 10 человек. С чем связано это ограничение я не понимаю.
Новая «Лада»
Хостел
До недавнего времени я не знал что такое «хостел», кажется до той самой поры, когда Илья Бирман в гостях у Инфотаньки не оборонил, что остановился в хостеле.
Хостел — это такой отель с общими на все номера «удобствами». Варинты встречаются самые разные — от койки в комнате на двенадцать человек,
Мы в Питере останавливались в двух хостелах. В «Островке», который ближе к югу города, чтобы из аэропорта быстрее добраться до кровати и в «Суперхостеле» на Пушкинской, в центре, где сейчас и живём. В обоих сутки пребывания обходятся в 1300 рублей за двухместный номер.
Расскажу о последнем, чтобы вы имели представление о том, какие бывают хостелы.
Сначала недостатки.
Это центр, пять минут до Невского проспекта и даже ночью тут кипит жизнь, что в открытое, по причине жары, окно слышно превосходно. А ещё в окно влетают, одурев от такого гостеприимства, прыткие питерские комары. Так что ночь сегодня была тяжёлая. А так же, нам всё равно, но для многих недостаток — нет телевизора (в «Островке» — был).

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















До свидания, Питер! Сегодня поедем в Хельсинки, поезд через два часа.
Напоследок побывали в океанариуме, красиво — безумно.
