Как власти используют теракты в политических целях
zhtw
Оригинал взят у maxkatz в Как власти используют теракты в политических целях
Террористические акты для силового блока правительства открывают большие возможности. Никакое общественно-политическое событие не даёт провести в жизнь подобные решения, которые общество готово съесть под предлогом борьбы с терроризмом и заботой о безопасности.
Любая смерть это трагедия, а беспричинная смерть людей, которые невинно ехали в метро или летели в самолёте, это вдвойне страшно.

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

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

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




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



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

Ради обеспечения безопасности граждан принимался и закон Яровой, обязывающий всех операторов связи записывать все телефонные разговоры абонентов и хранить их 3 года.

Теракт в Беслане, когда была захвачена школа и погибли дети, послужил поводом для отмены выборов губернаторов в 2004 году. Тогда Путину необходимо было укреплять «вертикаль власти» и ослаблять губернаторов, теракт позволил оправдать эти действия, выборы губернаторов вернулись лишь через 8 лет.
Драматургия Путиным была выбрана тогда безошибочно: прошло менее двух недель с момента трагедии в Беслане, где погибли невинные дети. И тут заседание правительства, посвященное борьбе с терроризмом, на нём Путин объявляет о важной мере укрепления государственной власти: отмене выборов губернаторов.

Есть менее глобальные примеры использования терактов для реализации своих политических и коммерческих целей. Например, после взрыва в аэропорту Домодедово было открыто уголовное дело на его владельца. Аэропорт давно хотели отжать и искали повод, и теракт пришёлся как нельзя кстати. Владельца обвинили в том, что на входе в аэропорт не было контроля (с чего бы ему там вообще быть?).
Полгода Дмитрий Каменщик провёл под домашним арестом, пока уголовное дело не закрыли за отсутствием состава преступления.

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

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

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

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



Вероятности умереть от чего-либо неплохо изучены, так как страховые компании зарабатывают таким образом деньги. Вот неплохая инфографика на тему. А вот некоторые цифры по США (где проблема терроризма стоит острее):

1 к 9,300,000 — риск погибнуть от террористической атаки

1 к 18,600       — риск погибнуть в ДТП (в 490 раз выше),
1 к 18,000       — риск быть убитым (в 490 раз выше),
1 к 812,000     — риск утонуть в собственной ванной (в 12 раз выше),
1 к 81,500       — риск погибнуть при пожаре (в 110 раз выше),
1 к 576,000     — риск погибнуть от удара молнии (в 16 раз выше)
1 к 700,000     — риск умереть от укуса собаки (в 13 раз выше)
1 к 20,000       — риск умереть от падения с высоты своего роста (в 465 раз выше)
1 к 370,000     — риск умереть, подавившись едой (в 25 раз выше)


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

Не впадайте в истерию, не дайте террористам вместе с пропагандистами и политиканами изменить вашу жизнь и нашу страну.





Я в интернете
zhtw
Я в соц. сетях. (В ЖЖ больше не пишу.)

UPD: Правильней начать с моего профиля на keybase.io.

Вот эту икону запретили публиковать?
zhtw
Просто стало интересно, что будет.
pussy riot

Map-reduce
zhtw
Каждый раз, когда я с кем-то разговариваю на тему map-reduce, у меня складывается впечатление, что мы говорим на разных языках.

Поэтому я решил написать, что я понимаю под map-reduce, и, надеюсь, все, кто понимают под этим что-то другое, ткнут мне пальцем.


Итак, оператор map.

Вот один из вариантов его определения.

Даны множества X, и Y.

Map -- это оператор, отображающий пары (A, f) в B, где A ⊂ X, B ⊂ Y, f: X → Y, такие, что f(A) = B, а точнее B = { f(x) | x ∈ A }.

Пример 1. f(x) = 2x. map(f, {1, 2, 4}) = {2, 4, 8}.

Пример 2. f(x) = 3x mod 6, map(f, {3, 4, 0}) = { 3, 0 }.

Это лишь пример возможного определения. Когда map реалзуется в языках программирования, обычно делают некоторые отступления. Например, множества могут быть представлены в виде списков или массивов, и, раз уж массивы и списки могут содержать одинаковые элементы, и порядок играет роль, то тогда A и B -- кортежи с равным числом элементов из X и Y соответственно.

Классический вариант map в Лиспе для списков:


(define (map f l)
  (if (null? l)
    '()
    (cons (f (car l)) (map f (cdr l)))))


Или на Питоне для массивов (они же списки)


def map(f, l):
  return [f(x) for x in l]


(Для реализации через генераторы, нужно квадратные скобки заменить на круглые.)

Оператор reduce.

Даны множества X и Y. Reduce отображает тройку (x0, f, <x1, x1... xn>) в x, где

f: X×Y → X,
x, x0 ∈ X,
x1... xn ∈ Y, причем
x = f(...f(f(x0, x1), x2)...)

Пример 1.

f(a, b) = a + b
reduce(0, f, <1, 2, 3, 4, 5>) = 0 + 1 + 2 + 3 + 4 + 5 = 15.

Пример 2.
f(A, b) = A ∪ { b }.
reduce(∅, f, <1, 2, 3, 2, 4>) = { 1, 2, 3, 4 }.

Когда reduce реализуют в языках программирования, кортеж представляют в виде списка, массива или отложенной последовательности.
Классический вариант reduce на Лиспе для списков:


(def (reduce x0 f l)
  (if (null? l)
    x0
    (reduce (f x0 (car l)) f (cdr l)))


На Питоне:

def reduce(x0, f, l)
  res = x0
  for x in l:
    res = f(res, x)
  return res


Reduce очень универсальная операция. Через нее легко определить очень много операций. С первого взгляда неочевидно, но через reduce можно даже определить реверс списка.

Пример на Лиспе:


(def (reverse l)
  (reduce '() (lambda (a b) (cons b a)) l))


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

Map и reduce в сочетании дают очень мощный механизм написания алгоритмов работы с последовательностями.

На самом деле reduce -- это лишь одна из двух симметричных операция folding'а: rfold и lfold. Rfold -- это reduce, а lfold получается, если в f поменять аргументы местами, и определить x так:

x = f(x1, f(x2, ...f(xn, x0)...))

Но это не очень важно.

Так вот, map и reduce -- простейшие операции, известные миллион лет, определены в библиотеках всех известных языков программирования.

А интересны они стали в последнее время исходя и того простого факта, что map легко паралеллится. Reduce тоже паралеллится, но только в частном случае, когда f ассоциативна. В общем же случае, это не так.

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

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

Различные реализации того, что сейчас называют распределенной моделью вычислений map-reduce, вводят и другие ограничения на элементы, чтобы предоставить всякие удобства для программиста. Например, кроме ключа можно еще ввести подключ, и предоставить возможность сортировки каждого из отрезков по подключу, перед тем, как выполнять reduce над ними. Map может принимать в качестве f многозначную функцию и пр.

Как бы то ни было. Чтобы иметь общее представление о том, какие алгоритмы «ложатся» на модель map-reduce, важно помнить что такое базоыве map и reduce.

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

Статистика по одному китайскому тексту
zhtw
Я взял рассказ 浪迹天涯话买卖 современной тайваньской писательницы 三毛. Посчитал статистику и получил вот что.
Текст содержит 3606 иероглифов (включая название), различных иероглифов всего 812, из них 463 составляют 90% текста. 336 иероглифов встречаются ровно один раз.


的 - 192 活 - 9 望 - 5 诞 - 3 难 - 2 放 - 2 闹 - 1 究 - 1 散 - 1 城 - 1
我 - 92 方 - 9 成 - 5 认 - 3 镑 - 2 摇 - 2 长 - 1 税 - 1 教 - 1 坏 - 1
是 - 91 很 - 9 情 - 5 表 - 3 错 - 2 推 - 2 镶 - 1 称 - 1 政 - 1 圈 - 1
了 - 66 常 - 9 怪 - 5 虚 - 3 酸 - 2 排 - 2 锅 - 1 科 - 1 收 - 1 图 - 1
不 - 59 头 - 9 度 - 5 荷 - 3 酱 - 2 掌 - 2 销 - 1 福 - 1 撩 - 1 园 - 1
在 - 45 吃 - 9 己 - 5 药 - 3 转 - 2 拿 - 2 银 - 1 票 - 1 撒 - 1 嘱 - 1
那 - 41 他 - 9 定 - 5 茫 - 3 跳 - 2 拍 - 2 钟 - 1 示 - 1 掏 - 1 嘛 - 1
来 - 41 事 - 9 孩 - 5 至 - 3 跟 - 2 把 - 2 醒 - 1 确 - 1 掉 - 1 啡 - 1
去 - 36 中 - 9 如 - 5 结 - 3 越 - 2 打 - 2 醉 - 1 研 - 1 据 - 1 啊 - 1
个 - 34 迷 - 8 夜 - 5 红 - 3 走 - 2 房 - 2 酒 - 1 石 - 1 捧 - 1 啃 - 1
货 - 33 进 - 8 回 - 5 累 - 3 贵 - 2 或 - 2 邀 - 1 睡 - 1 拮 - 1 哭 - 1
得 - 32 觉 - 8 品 - 5 等 - 3 贩 - 2 懂 - 2 遥 - 1 目 - 1 括 - 1 哈 - 1
大 - 32 街 - 8 向 - 5 笔 - 3 质 - 2 感 - 2 通 - 1 盘 - 1 拚 - 1 咖 - 1
公 - 31 真 - 8 同 - 5 竿 - 3 豆 - 2 怎 - 2 途 - 1 盖 - 1 拖 - 1 咐 - 1
百 - 30 日 - 8 变 - 5 竹 - 3 谜 - 2 忆 - 2 逐 - 1 疼 - 1 拒 - 1 味 - 1
有 - 28 年 - 8 其 - 5 童 - 3 调 - 2 微 - 2 透 - 1 疚 - 1 拉 - 1 周 - 1
时 - 28 实 - 8 倒 - 5 穿 - 3 话 - 2 征 - 2 选 - 1 甜 - 1 抽 - 1 吸 - 1
司 - 28 她 - 8 你 - 5 程 - 3 计 - 2 往 - 2 退 - 1 甘 - 1 抱 - 1 启 - 1
可 - 27 太 - 8 件 - 5 睛 - 3 言 - 2 彩 - 2 迹 - 1 瓶 - 1 抛 - 1 吧 - 1
人 - 26 卖 - 8 买 - 5 皮 - 3 解 - 2 弄 - 2 返 - 1 璃 - 1 扫 - 1 否 - 1
里 - 24 前 - 8 乐 - 5 白 - 3 袜 - 2 应 - 2 辈 - 1 珂 - 1 托 - 1 吗 - 1
这 - 24 再 - 8 马 - 4 痛 - 3 落 - 2 广 - 2 较 - 1 玻 - 1 慕 - 1 叹 - 1
生 - 23 间 - 7 需 - 4 班 - 3 菜 - 2 干 - 2 躲 - 1 玩 - 1 愿 - 1 另 - 1
小 - 23 课 - 7 门 - 4 牙 - 3 荣 - 2 带 - 2 踏 - 1 玉 - 1 惑 - 1 句 - 1
家 - 22 虽 - 7 铺 - 4 片 - 3 草 - 2 布 - 2 超 - 1 猜 - 1 惋 - 1 古 - 1
天 - 22 给 - 7 重 - 4 爱 - 3 节 - 2 已 - 2 赴 - 1 牌 - 1 惊 - 1 发 - 1
西 - 21 种 - 7 逛 - 4 满 - 3 脱 - 2 差 - 2 购 - 1 烟 - 1 悍 - 1 双 - 1
么 - 21 次 - 7 边 - 4 渴 - 3 职 - 2 将 - 2 贪 - 1 炼 - 1 息 - 1 友 - 1
要 - 20 杂 - 7 跑 - 4 流 - 3 者 - 2 寄 - 2 责 - 1 点 - 1 恨 - 1 及 - 1
也 - 20 本 - 7 起 - 4 沙 - 3 群 - 2 宝 - 2 负 - 1 激 - 1 性 - 1 压 - 1
都 - 19 月 - 7 费 - 4 氛 - 3 缘 - 2 娱 - 2 贝 - 1 滩 - 1 急 - 1 厉 - 1
美 - 19 最 - 7 记 - 4 楚 - 3 纹 - 2 姐 - 2 谓 - 1 湾 - 1 思 - 1 印 - 1
看 - 19 快 - 7 被 - 4 梦 - 3 纸 - 2 够 - 2 读 - 1 渺 - 1 怕 - 1 南 - 1
上 - 19 形 - 7 行 - 4 柏 - 3 繁 - 2 外 - 2 该 - 1 港 - 1 律 - 1 医 - 1
就 - 17 它 - 7 舍 - 4 条 - 3 糊 - 2 境 - 2 诗 - 1 渐 - 1 影 - 1 区 - 1
着 - 16 四 - 7 背 - 4 服 - 3 簿 - 2 堂 - 2 许 - 1 淋 - 1 归 - 1 力 - 1
以 - 16 叫 - 7 老 - 4 更 - 3 管 - 2 垃 - 2 讲 - 1 淇 - 1 强 - 1 副 - 1
然 - 15 只 - 7 缺 - 4 春 - 3 答 - 2 坐 - 2 让 - 1 涨 - 1 引 - 1 刷 - 1
好 - 15 做 - 7 绿 - 4 支 - 3 租 - 2 圾 - 2 角 - 1 涌 - 1 式 - 1 初 - 1
十 - 15 住 - 7 经 - 4 挤 - 3 秘 - 2 喷 - 2 观 - 1 海 - 1 异 - 1 凳 - 1
下 - 15 业 - 7 纯 - 4 拾 - 3 神 - 2 喳 - 2 襟 - 1 测 - 1 座 - 1 凤 - 1
金 - 14 香 - 6 算 - 4 报 - 3 社 - 2 喜 - 2 裘 - 1 泪 - 1 府 - 1 凡 - 1
说 - 14 衣 - 6 相 - 4 批 - 3 磨 - 2 喃 - 2 袖 - 1 法 - 1 庙 - 1 准 - 1
又 - 14 花 - 6 淡 - 4 才 - 3 碗 - 2 商 - 2 袍 - 1 沉 - 1 库 - 1 净 - 1
东 - 14 笑 - 6 校 - 4 手 - 3 破 - 2 唱 - 2 衬 - 1 汤 - 1 幽 - 1 决 - 1
想 - 13 站 - 6 林 - 4 所 - 3 直 - 2 唯 - 2 薪 - 1 永 - 1 幸 - 1 冬 - 1
心 - 13 眼 - 6 极 - 4 戏 - 3 番 - 2 咻 - 2 蒂 - 1 毫 - 1 幢 - 1 写 - 1
学 - 13 现 - 6 无 - 4 张 - 3 界 - 2 员 - 2 营 - 1 比 - 1 巨 - 1 具 - 1
子 - 13 照 - 6 改 - 4 师 - 3 电 - 2 吱 - 2 菊 - 1 死 - 1 岛 - 1 关 - 1
到 - 13 每 - 6 换 - 4 巷 - 3 由 - 2 北 - 2 茶 - 1 歪 - 1 岂 - 1 先 - 1
面 - 12 意 - 6 惜 - 4 少 - 3 瓜 - 2 动 - 2 苦 - 1 步 - 1 岁 - 1 假 - 1
过 - 12 德 - 6 念 - 4 奇 - 3 珍 - 2 利 - 2 艺 - 1 正 - 1 山 - 1 信 - 1
色 - 12 对 - 6 必 - 4 块 - 3 牛 - 2 冰 - 2 般 - 1 歉 - 1 属 - 1 俗 - 1
自 - 12 女 - 6 并 - 4 场 - 3 烂 - 2 兴 - 2 航 - 1 款 - 1 屐 - 1 例 - 1
店 - 12 台 - 6 层 - 4 圣 - 3 漫 - 2 入 - 2 腿 - 1 欠 - 1 屉 - 1 余 - 1
没 - 11 口 - 6 客 - 4 因 - 3 漠 - 2 光 - 2 脚 - 1 橄 - 1 尽 - 1 低 - 1
当 - 11 却 - 6 字 - 4 哪 - 3 游 - 2 傻 - 2 脑 - 1 横 - 1 尤 - 1 但 - 1
工 - 11 儿 - 6 失 - 4 命 - 3 混 - 2 修 - 2 胸 - 1 榄 - 1 尘 - 1 休 - 1
多 - 11 使 - 6 地 - 4 告 - 3 涯 - 2 伏 - 2 胜 - 1 概 - 1 宿 - 1 仙 - 1
出 - 11 似 - 6 呢 - 4 合 - 3 浸 - 2 从 - 2 肿 - 1 棺 - 1 宽 - 1 仓 - 1
几 - 11 会 - 6 名 - 4 单 - 3 浮 - 2 仍 - 2 肉 - 1 梯 - 1 容 - 1 仁 - 1
们 - 11 份 - 6 加 - 4 华 - 3 浪 - 2 今 - 2 翻 - 1 梨 - 1 害 - 1 亮 - 1
什 - 11 些 - 6 分 - 4 半 - 3 洗 - 2 二 - 2 羡 - 1 梅 - 1 宠 - 1 交 - 1
为 - 11 五 - 6 冷 - 4 千 - 3 洋 - 2 丽 - 2 置 - 1 树 - 1 宜 - 1 亚 - 1
钱 - 10 高 - 5 内 - 4 化 - 3 毛 - 2 两 - 2 罚 - 1 标 - 1 完 - 1 于 - 1
道 - 10 连 - 5 八 - 4 包 - 3 母 - 2 七 - 2 缴 - 1 柜 - 1 安 - 1 争 - 1
还 - 10 足 - 5 书 - 4 别 - 3 此 - 2 黑 - 1 缤 - 1 果 - 1 守 - 1 习 - 1
车 - 10 赚 - 5 食 - 3 切 - 3 歌 - 2 鲜 - 1 缎 - 1 松 - 1 存 - 1 乘 - 1
水 - 10 见 - 5 顾 - 3 六 - 3 欲 - 2 骨 - 1 绣 - 1 杏 - 1 婆 - 1 久 - 1
总 - 10 装 - 5 非 - 3 全 - 3 欢 - 2 验 - 1 绝 - 1 朵 - 1 始 - 1 丢 - 1
开 - 10 第 - 5 青 - 3 克 - 3 案 - 2 骇 - 1 绕 - 1 术 - 1 妇 - 1 世 - 1
国 - 10 竟 - 5 阵 - 3 像 - 3 格 - 2 饭 - 1 练 - 1 替 - 1 套 - 1 专 - 1
和 - 10 空 - 5 问 - 3 代 - 3 根 - 2 飘 - 1 纷 - 1 暗 - 1 奋 - 1 万 - 1
后 - 10 离 - 5 部 - 3 乱 - 3 样 - 2 风 - 1 纳 - 1 普 - 1 奈 - 1 丁 - 1
候 - 10 知 - 5 追 - 3 丝 - 3 板 - 2 颜 - 1 紫 - 1 晚 - 1 夏 - 1
便 - 10 用 - 5 远 - 3 三 - 3 材 - 2 鞭 - 1 紧 - 1 晓 - 1 备 - 1
作 - 10 理 - 5 身 - 3 颗 - 2 木 - 2 靠 - 1 米 - 1 易 - 1 处 - 1
亲 - 10 物 - 5 路 - 3 预 - 2 曾 - 2 陷 - 1 简 - 1 昏 - 1 墨 - 1
之 - 10 清 - 5 趣 - 3 静 - 2 明 - 2 院 - 1 签 - 1 昂 - 1 墙 - 1
能 - 9 深 - 5 赶 - 3 露 - 2 早 - 2 阳 - 1 筛 - 1 旷 - 1 塞 - 1
而 - 9 求 - 5 象 - 3 雾 - 2 新 - 2 阱 - 1 窗 - 1 旁 - 1 堵 - 1
父 - 9 气 - 5 语 - 3 零 - 2 文 - 2 队 - 1 穷 - 1 数 - 1 堕 - 1

Предисловие к книжке Теория и практика жонглирования
zhtw
Я уже писал про книжку. Она замечательная. Решил вот перевести предисловие, написанное знаменитым фокусником Пеном Джтлеттом (да, звучит по-дурацки, но вроде именно так его имя должно склоняться).

-----

Я жонглирую дольше, чем Джейсон Гарфилд жив. Я усилю свое утверждение: я зарабатываю деньги на донглировании дольше, чем Джейсон Гарфилд жив.

Я научился жонглировать, мне было 12. Мне было нечего делать кроме жонглирования — я уж точно не мог трахаться. Мой способ научиться жонглировать — это метод грубой силы. Я тупо продолжал подкидывать вещи в воздух до тех пор, пока они не переставали падать на землю. То есть на самом деле никакого конкретного способа не было, метод заключался в следующем: вкладываешь время и получаешь результат. И я совсем не парился на счет времени. А стоило. Если бы я потратил эти бесконечные часы на тренировку с Джейсоном, это было бы намного эффективнее и по-настоящему намного прикольнее. В 1974-м с Майклом Мошеном Мак-Артуром Гениальным в качестве партнера был очень хорошим жонглером. Вместе мы перекидывали девять булав. Мы думали тогда, что мы первые в мире, кто может перекидывать девять, но оказалось, что чертовы русские нас сделали (девять булав, и Спутник, будь они прокляты!) Майкл и я занимались как ненормальные. Мы занимались шесть полных восьмичасовых рабочих дней в неделю. И это продолжалось месяцами. А когда мы не могли заниматься все время (типа когда нужно было работать или учиться), мы все равно загимались много. Мы занимались много и мы стали крутыми, но опять же, если бы нас тренировал Джейсон, мы бы были круче, намного круче.

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

Я видел, как Джейсон тренирует брата и сестру Гальченко (чертовы русские). Когда они познакомились в Джейсоном, они знали как жонглировать лучше, чем кто-либо. Джейсон не учил их жонглиовать. Но я наблюдал, как он учит их тренироваться. Джейсон научил их учиться, тренироваться и выступать. Они были отличными жонглерами до Джейсона, они стали лучшими в мире после Джейсона. Он продумывает все, что касается я жонглирования. Как-то пару месяцев назад я жонглировал на лужайке с Джейсоном. Он жонглировал пятью булавами за спиной и отрабатывал жонглирование семью, а я пытался контролировать четыре булавы. Он понаблюдал за мной и вежливо спросил, не сможет ли он помочь. Он предложил попробовать стоять в другом положении, дал еще несколько советов. Я думал: «Я начал жонглировать раньше, чем ты родился, ты лысый качек. Иди лучше надень шапку и поотжимайся», но его советы помогли. Благодаря только тем нескольким его комментариям тогда на лужайке я стал жонглировать лучше — и это после 35-и лет.

-----
Оставшиеся пару абзацев переведу чуть позже.

Как настроить публичный репозиторий на Ртути.
zhtw
Я использую Ртуть. Я люблю Ртуть. Если хочется расшарить ртутный репозиторий по http, нет ничего проще, чем использовать встроенный http-сервер.

Просто запускаете hg serv и готово. Чтобы запустить hg serv с несколькими репозиториями, можно ему передать простой файлик конфигурации через ключ --web-conf:

hg serve --web-conf conf

В файлике conf должно быть что-то вроде этого:


[paths]
oop = /var/hg/k806/oop
da = /var/hg/k806/da
os = /var/hg/k806/os
algorithms = /var/hg/k806/algorithms


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

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

Что для этого нужно? Нужно создать каталог, где будет конфигурация вашего репозитория, например /etc/hg-k806. В этом каталоге нужно создать файлик run со следующим содержимым:


#!/bin/sh
exec setuidgid nobody envdir env sh -c 'hg serv -p $port --web-conf conf'


Туда же положить вышеуказанный файлик conf. Там же создать каталог env с файликом port, в который записать номер порта, на котором будет слушать сервер.

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


#!/bin/sh
exec multilog t /var/log/hg-k806


Сами репозитарии должны находится в тех местах, которые указаны в conf.

Все. Теперь, после создания символической ссылки на каталог /etc/hg-k806 из каталога /service (основного каталога, в котором svscan ищет конфигурации сервисов), веб-сервер будет стартовать автоматически. Управлять им можно стандартным способом утилитой svc:

svc -t /etc/hg-k806 — рестартовать,
svc -d /etc/hg-k806 — остановить,
svc -u /etc/hg-k806 — поднять и так далее.

Daemontools берет на себя всю заботу о логах, сохрании pid'а и пр.
Но самое удобное заключается в том, что скрипт run можно запускать и вручную, что удобно для отладки и позволяет автору сервера не думать о проблеме, которая решена уже миллион раз миллионом людей.

С тех пор как я узнал о daemontools, я использую их везде и для всего. Это чрезвычайно удобный набор утилит.
Важно заметить, что распространенный подход, когда каждая программа сама берет на себя заботу о сохранинии pid'а и пр. после daemontools кажется (и является!) убогим. Это, совершенно очевидно, очень плохой подход. Daemontools предоставляет настоящий unix way для демонизации серверов.

Ну и последнее. Если на сервере работает что-нибудь еще, кроме Ртутного веб-интерфейса, имеет смысл запускать его на каком-нибудь своем порту, а на 80 повесить nginx. Это полезно и для настройки виртуального хоста.

Вот фрагмент nginx.conf, который смотрит на наш hg-k806:


server {
 listen 80;
 listen [::]:80;
 server_name hg.k806.ru;
 location / {
  proxy_pass http://localhost:4080/;
 }
}


Как это все выглядит в жизни: hg.k806.ru. Или еще: hg.umc8.ru

Еще про Шелл
zhtw
Давайте я расскажу про другую интересную конструкцию на Шелле. Теперь про такую, которая работает.
Иногда нужно выполнить кое-какие действия над файлом и результат положить в два разных файла. При этом действия легко сделать за один проход.

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


rm -f out2
while read x y; do
  echo $x
  echo $y >>out2
done >out1 <in


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

Как написать хорошо? Элементарно!


while read x y; do
  echo $x
  echo $y >&3
done >out1 3>out2 <in


Разве это не прекрасно? (Я понимаю, что код по-прежнему внешне не симметричен, но нас интересует внутренняя красота: логика работы с out1 и out2 -- одинаковая.)

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

Шелл — мой любимый язык программирования
Ĵonglado
zhtw
Все, кто хоть чуть-чуть программировал на шелле, знают о том, что будет, если забысть сделать в нужный момент set -ue, или хотя бы set -e.

Я знаю, что есть приемы написания кода, которые позволяют обойтись без set -e. Но они не универсальные и при постоянном использовании делают код не очень читабельным.

Так вот, мы с вами люди нормальные и мы никогда не забываем в первой строчке писать

#!/bin/sh -ue

(Можно и bash. Не люблю башистов, но на чистом posix-Шелле программировать действительно бывает неудобно.)

Мы также помним (мы же опытные программисты), что set -e отключается внутри условия if-then и умеем с этим жить.

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

Как думаете, вернет ли ошибку вызов функции proc, если файл nonexistent не существует?


proc()
{
  x=$(cat nonexistent)
  ...
}


Да, вернет. Ну, хорошо, а если так?

proc()
{
  local x=$(cat nonexistent)
  ...
}



Объяснение, почему оно так, звучит вполне логично. Но это ж ничего не меняет. Ни один человек без заглядывания в документацию не сможет предсказать такого рода поведение.
Tags: ,

Про шелл
Ĵonglado
zhtw
Почему (head -n $n; cat) <$file не эквивалентно tail -n -$n $file
Давайте я сначала расскажу, почему можно подумать, что это эквивалентные конструкции.

Очень просто:


(head -n $n; cat) <$file


Что тут происходит? Сначала fork, потом закрывается стандартный ввод, потом открывается $file. Дискриптор при этом выделяется 0-й. Дальше дважды fork/exec. Первый раз для head, второй —для cat.

После fork'а для head'а дочерний процесс имеет копию дискриптора родительского процесса. Это значит, что при закрытии стандартного ввода head'ом, файл не закрывается, ведь у родительского осталась копия дискриптора. И текущая позиция в файле тоже осталась прежней. Fork перед exec для cat'а копирует дискриптор еще один раз и cat продолжает читать с той позиции, где head закончил.

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

У head'а нет возможности прочитать со ввода ровно заданное число сторк, потому что для этого бы пришлось читать побайтно. Терминал в обычном режиме буферизирует данные как раз построчно. А вот при чтении из файла с диска, размер буфера определяется через stat.

Поэтому head обычно читает больше, чем мы его просим. (На вывод он копирует, конечно же, столько, сколько нужно.)

Как жаль. А ведь такая красивая конструкция!
Tags: ,

?

Log in