Ура, спама нет!
Помню несколько лет назад мне приходилось вставлять свой адрес электронной почты на страницу при помощи JavaScript, да и ещё не совсем тривиального, для защиты от спамеров. Попасть в полумифические «спамерские списки» было неприятно, ящик заваливало всякими «ликвидациями фирм», «сдачей площадей под офис» и прочим мусором. Корреспонденцию приходилось вылавливать, фильтры помогали мало, прогнозы давались самые неутешительные — что почта скоро перестанет существовать
Лучшие умы вместе с худшими думали над решением этой проблемы. Одно из решений, придуманных тогда — заставить программу, отправляющую письмо решить
В 2004 году появилась гугловская почта GMail, тогда ещё по инвайтам. Гугл сразу нацелилась на борьбу со спамом. Это была первейшая причина почему я захотел инвайт туда. Война со спамом велась с переменным успехом, а когда я обнаружил, что мусора стало приемлемое количество, я убрал свой замороченный JavaScript и написал email как есть.
Вчера я поймал себя на том, что давно уже не вижу спама во входящих. Ни на GMail,
Третий мир

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


Цветы неестественно яркие, листики насыщённо зелёные. Так не бывает. Любой другой цветок, включая те, которые растут в оранжереях, не настолько яркие. Как признались продавцы, те цветы, которые я сфотографировал в природе блёклые и серые, их поливают специальной краской, чтобы они стали яркими и разноцветными.
Что мне даёт право предположить, что и всё остальное поливают
Красавица → чудовище
Во время просмотра этого видео держите взгляд на перекрестии.
Ещё немного статистики
Почти половина (48,41%) поисковых переходов за прошедший месяц — это запросы
«петрушка наркотик»
и модификации.
Стань стальной крысой!
Решил показать жене
Сделал конвертор на «Пайтоне», преобразующий книгу с «Либрусека» в 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», который надо открыть браузером.
Купил 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)Про вред пассивного курения
Потом стали известны кливлендские исследования, неопровержимо доказавшие вред пассивного курения. Хирурги Кливлендского института, выполнявшие операции на легких, видели, что органы дыхания были повреждены дымом как у активных курильщиков, так и у пассивных. Только разные участки. Курящие люди вдыхают горячий сигаретный дым, поэтому дышат поверхностно. Пассивные курильщики вдыхают глубоко, от этого и повреждения, вызванные дымом, залегают у них глубже.
Из статьи «Город некурящих», с сайта «Аргументов и Фактов».
Немного статистики
Из 306 родственников, заведённых на сайте генелогического древа, больше всего Александров, Иванов, Валентин и Ольг.
Безопасная транзакция по банковской карте

Какой там HTTPS, 3D Secure и прочее? Гостиница «Островок»
В 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 — нет.
Лайфхак для стопщиков
Кто-то из великих автостопщиков, кажется Антон Кротов, говорил, что если не ладится контакт с водителем и кабину наполняет гнетущая тишина, следует посмотреть в окно и произнести волшебную фразу: «Довели, бл██ь, страну…» После этого даже самый угрюмый водитель оживляется и следующие два часа вы проведете в живой беседе, где вам даже не обязательно отвечать.Примерно то же самое происходит, когда вы едете в плацкарте, а уж тем более — когда лежите в больнице.
Отличный лайфхак у Каганова нашёл. Я пользовался им зеркально — когда водитель очередного «мотора» произносит эту фразу, достаточно поддакнуть в тон и всё, можно не переживать за водителя — ему тишина уже не кажется гнетущей. Мне она никогда гнетущей не кажется, если мне хочется молчать, я молчу, но почему бы не послушать человека, если тому от этого легче?
Теперь можно не доводить человека до неудобной ситуации, а позволить заполнить тишину до того как она стала гнетущей.
Признаки того, что человек тонет
За редким исключением, тонущие люди физиологически неспособны позвать на помощь. Дыхание — основная функция дыхательной системы, а речь — дополнительная. Чтобы говорить, необходимо иметь возможность дышать.
Рот утопающего периодически скрывается под поверхностью воды и появляется снова. Времени, которое рот находится над водой, недостаточно, чтобы выдохнуть, вдохнуть и позвать на помощь. Утопающий успевает только быстро выдохнуть и вдохнуть.
Утопающие не могут размахивать руками, зовя на помощь. Инстинкты заставляют их раскинуть руки в стороны и отталкиваться от воды, пытаясь поднять тело вверх, чтобы рот показался над поверхностью и они могли сделать очередной вдох.
При инстинктивной реакции утопающего человек не может управлять движениями рук. Утопающий физиологически неспособен перестать совершать инстинктивные движения и начать совершать осмысленные, например, размахивать руками, двигаться к спасателю или хвататься за спасательные приспособления.
Пока продолжается инстинктивная реакция утопающего, тело человека остаётся вертикально в воде, без малейших признаков поддерживающих движений ногами. Если его не спасут, утопающий может продержаться в воде от 20 до 60 секунд перед полным погружением.
Из переводной статьи «Утопление не выглядит таковым». Статья стоит того, чтобы прочитать её полностью. Ещё полезно прочитать комментарии спасателей по ссылкам в конце статьи.
Отпуск
С 22 июля по 7 августа мы с женой в отпуске. Маршрут выглядит следующим образом.
Москва ✈ Нижнекамск → Лениногорск → Сергиевск → Казань ✈ Москва ✈
Галереи теперь в трансляциях
Сделал, как многие просили, фотогалереи в трансляциях RSS. Теперь всюду, куда транслируется мой блог («Ярушка», ЖЖ и т. д.), видно бо́льшую часть фотографий (не более десяти). Галереи там, конечно, условные — с миниатюры ссылка ведёт на полное фото.

Вот, кстати, о чём совершенно забыли создатели современной версий HTML — это форматирование HTML там, где всё плохо с CSS. В читалках RSS (тут CSS режется из соображений безопасности) и почтовых клиентах (те же соображения, плюс примитивные движки в некоторых приложениях). Я, пока отлаживал трансляции, убедился, что единственный способ всё отформатировать как надо — использовать таблицы и винтажные 0.gif. Но чем дальше, тем меньше можно сделать атрибутами тегов, да ещё и в условиях, когда лента встроена в документ, где уже есть стили (например
Конечно это правильно, разделение данных и представления, но HTML5 не предлагает взамен безопасного внедрения чужого контента в изолированном окружении, что полностью решило бы проблему. Есть специальный режим у IFRAME, но фреймы — это совсем не то, они не ведут себя как часть страницы, скорее как окошко в другой документ. Полосы прокрутки, развыв выделения текста и так далее. Всё не то.
«Без булдырабыз»
Я всё меньше с каждым днём понимаю «Идиотеку» у Студии. Да, раньше там были фотографии, посмотрев на которые, так и хотелось воскликнуть «Идиоты!». Потом там пошли фотографии природных явлений, съёмок со специально выбранного ракурса, когда у памятника неудачно торчит палец в районе брюк, теперь вот —
В чём
Автоэкзотика — 2011
Сходили сегодня на «Автоэкзотику» на Тушинском аэродроме города Москвы. Шоу «Автоэкзотика» — это выставки автомобилей, мотициклов, гонки и вообще всё, что связано с машинами. Шоу проходит с первого по десятое июля.
Мы посмотрели машины и увидели мотоциклетный стантрайдинг. Более задерживаться не стали — сегодня очень жарко, побоялись обгореть.
















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








В следующем году надо обязательно сходить ещё, но на этот раз надо будет внимательно изучить программу шоу и сделать поправку на то, что будет жарко — взять холодной воды и головные уборы.
«Гонка версий»
Смешно,
Пока фирма 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 я в список не включил — это отдельная ветка, её для «Мака» делали, так же как и другие, ещё менее известные подверсии для других систем.
Как мне 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 много странного писал в своё время.
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