JBIG2

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

Пока мы такие документы помещаем в ПДФ сканами в хорошем качестве в формате ДжПЕГ. Увы, это довольно расточительно. К счастью, ПДФ поддерживает не один, а целых три формата графики — ДжПЕГ, ДжПЕГ 2000 и ДжБИГ2. На последний я возлагал большие надежды.

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

Ошибки JBIG2 (34.98КБ) К сожалению, у формата есть серьёзный недостаток, на который я тут же и наткнулся.

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

Посмотрите, у меня на скриншоте выше — оригинальный ПДФ (слева) и ПДФ, где графика перекодирована в ДжБИГ2. Как видно при кодировании были перепутаны «п» и «и», «п» и «н». Для слов в документах может это ещё и не смертельно, но для цифр в суммах — беда.

Мне неясно можно ли что-то сделать в этом месте, возможно можно подредактировать кодек так, чтобы он реагировал только на 100% совпадение, но тогда, скорее всего, пропадёт всякий смысл использовать ДжБИГ2.

Остаётся ещё вариант с ДжПЕГом 2000, но с ним возможно, выигрыш будет столь незначительным, что затраты на конвертацию просто не окупятся.
8 комментариев
22 мая 2015 10:30

Подарок от бывших коллег

250ГБ в подарок (22.37КБ) «Яндекс.Диск» сделал подарок — всем бывшим коллегам подарили по 250ГБ места. Очень приятно, спасибо!

Правда сообщение ещё не успели поправить — раньше дополнительные 250 давали пока работаешь в «Яндексе».
4 комментария
19 мая 2015 09:52

99 бутылок пива на «Электронике МК85»

«Электроника МК85» и «99 бутылок пива» (86.34КБ) Как я уже сказал, Бейсик (в руководстве он называется «БЭЙСИК») на «МК85» отличается странностями. Например, там фиксированное количество переменных с определёнными (только однобуквенными именами), причём только одна строковая переменная может содержать не более 30 символов (её имя — символ доллара), остальные могут содержать не более семи символов.

Или запись массивов — все числовые переменные, по сути, являют собой один массив. Индекс «один» массива с именем «А» совпадает с переменной «B», а индекс «два» переменной «B» — это переменная «D» и так далее. Так что вы можете использовать что-то одно — либо массив полностью, либо переменные.

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

В общем, представляю вашему вниманию программу «99 бутылок пива на стене», написанную на БЭЙСИКе микрокомпьютера «Электроника МК-85», я запускал, работает:
10FOR B=99 TO 1 STEP -1
20A=B:GOSUB90:PRINT" of beer on the wall, ";:GOSUB90:PRINT"."
30PRINT"Take one down and pass it around, ";:A=B-1:GOSUB90
40PRINT" of beer on the wall."
50NEXT B
60PRINT"No more bottles of beer on the wall, no more bottles of beer."
70PRINT"Go to the store and buy some more, 99 bottles of beer on the wall."
80END
90GOTO100*(SGN(A-1)+2)
100PRINT"no bottles";:RETURN
200PRINT"1 bottle";:RETURN
300PRINT A;" bottles";:RETURN
Микрокомпьютер имеет интересную особенность — длинные строки, не помещающиеся на экране, он автоматически прокручивает, а чтобы человек успел прочитать, после каждой строки происходит остановка интерпретатора, для продолжения надо нажать клавишу «EXE». Точка с запятой после оператора «PRINT» говорит интерпретатору, что строка не кончилась, что позволяет печатать длинные строки несколькими операторами.

Ещё одна особенность — программируемый символ. Один символ, имеющий специальный код можно нарисовать попиксельно. Завтра попробую побаловаться.
4 комментария
17 мая 2015 01:22

Электроника МК85

Электроника МК85 (123.33КБ) Был в гостях у братишки, нашёл свой старый микрокомпьютер «Электроника МК85» 1992 года выпуска. Когда-то я на нём довольно бодро программировал (внутри встроен некий странноватый диалект «Бейсика») и даже зарабатывал.

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

Блок питания, к сожалению, потерян, но сохранились чехол (на фото слева) и само устройство. От батареек для лазерной указки микрокомпьютер не заработал (несмотря на уверения анонимов из интернета), зато заработал от УСБ-порта «Мака», правда на пределе яркости. На фото результат выполнения недокументированной команды «WHO» (выводит «Программу разработал Подоров А. Н.»).

Внешний вид «МК85» был полностью скопирован с калькулятора фирмы «Касио», но внутренности сильно различались. Например, в «каське» стоял четырёхразрядный процессор, а в «МК85» — шестнадцатиразрядный Т36ВМ1-2 (он же — КА1013ВМ2). Для тех лет это был настоящий прорыв.

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

Попробую завтра попрограммировать, если все кнопки там ещё работают.
4 комментария
16 мая 2015 23:14

Itertools для PHP: продолжение

Библиотеку itertools для ПХП я всё же переписал: теперь на вход всем функциям можно передавать что угодно итерируемое. Из ограничений осталось только два: функция iter в моём варианте принимает только один аргумент, а у функций product и izip_longest последний аргумент является обязательным.

Вот, кстати, как переписывается программка итерстрип, написанная мной семь лет назад на «Пайтоне», теперь её можно повторить на ПХП почти один-в-один:
require 'itertools.php';
use function itertools\groupby, itertools\xrange, itertools\chain, itertools\repeat;

function ntrim($letter, $n=3, $replby=1)
{
    $shrink_groups = function($letter, $n) {
        foreach (groupby(chain(repeat('', $n), $letter, repeat('', $n))) as list($item, $grp)) {
            $grp = iterator_to_array($grp);

            yield $item || sizeof($grp) < $n ? $grp : '';
        }
    };

    return array_slice(iterator_to_array(chain(...$shrink_groups($letter, $n))), $replby, -$replby);
}

print_r(ntrim(['', 1, 2, 3, '', '', '', '', 4, '', '']));
Увы, на ПХП всё ещё не так компактно (из-за отсутствия генераторных выражений), но уже очень близко.
4 комментария
11 мая 2015 13:17

Upsert в PostgreSQL

Ура, появился коммит, добавляющий к оператору INSERT «Постгреса» конструкцию, которая позволяет использовать его как upsert (в «Оракле» это конструкция MERGE, в «Майэскуэеле» — INSERT… ON DUPLICATE KEY UPDATE):
-- Обновить, если не удалась вставка
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
ON CONFLICT (did) DO UPDATE
SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
WHERE d.zipcode != '21201';

-- Если не удалась вставка, ничего не делать
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
ON CONFLICT (did) WHERE is_active DO NOTHING;
Счастье-то какое!

Itertools для PHP

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

В прошлом, программируя на «Пайтоне» я не раз восторгался модулем itertools и тем как «Пайтон» легко позволяет обращаться с генераторами — есть несколько способов, хорошее разнообразие.

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

Пример использования ниже (для запуска примера и работы библиотеки требуется ПХП 5.6 и выше):
require 'itertools.php';

use function itertools\islice, itertools\cycle, itertools\iter;

foreach (islice(cycle(iter("ABC")), 10) as $el) {
    echo $el;
}
От оригинальной библиотеки несколько отличий.

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

Во-вторых, в «пакет» добавлены несколько полезных функций, которые входят в ядро «Пайтона» — iter, slice, enumerate и xrange, работают они так же, как и в «Пайтоне».

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

Если не заброшу библиотеку, то, возможно, всё-таки откажусь от указания типов и приведу всё к более совместимому виду.
17 комментариев
8 мая 2015 10:09

Личный пост Евгения Дорохина

Дорохин Евгений (51.60КБ) Я читаю немало блогов и по сравнению с тамошний публикой у меня место довольно тихое — из последних истерик мне запомнилась разве что самовыпиливание некого товарища, нервная система которого не перенесла факта, что я занимаю позицию одного из топ-менеджеров в нашей компании. До сих пор не понимаю чем его так потрясло это открытие.

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

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

В общем, последнее я вкратце изложил этому типчику.

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

Для меня просто параллельная Вселенная открылась. Буду ждать оттуда ещё каких-нибудь новостей. Евгений, я вам, как видите, даже пост отдельный создал. Всё для вашего удобства. Порадуйте меня чем-нибудь ещё таким, ну, как вы умеете, не лебезя.
22 комментария
5 мая 2015 23:40

Нельзя цитировать?

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

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

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

Закон устроен таким образом, что любые требования, противоречащие закону, не являются законными, даже если они являются частью договора, под которым стоит моя подпись. Мне интересно, не натыкался ли кто-то на точку зрения издательств в этом вопросе, я, к сожалению, ничего такого не нашёл.
6 комментариев
30 апреля 2015 15:18

Жизнь учительницы Шмелёвой в 1951 году

Учительская газета (87.90КБ) Фото из Музея счастливого детства, который мы недавно посетили с женой. Находится в Казани на Университетской, 9. Экспозиция немного пустовата, но интересна (остальные фото можно посмотреть в моих альбомах на «Яндекс.Фотках»).

Выше школьная стенгазета «Голос учителя» 1951 года. Там с правой стороны, над рисунком кровати с ковром, написано: «учительница Протопоповской школы Шмелёва сама ещё справляет религиозные обряды и держит иконы в своей квартире».
Комментировать
23 апреля 2015 11:14

Тактаки

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

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

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

Тактаки (который более правильно называется сранан-тонго) — молодой региональный язык на основе английского с большим количеством заимствований из нидерландского, португальского, а также центрально- и западноафриканских языков, существуют словари, по которым легко убедиться, что слов в языке гораздо больше трёх с половиной сотен.
2 комментария
23 апреля 2015 10:35

Легенда о порошковом вине

Цитата на тему «порошкового вина», всплывшего в разговоре о безалкогольном вине пару лет назад:
Теперь необходимо сказать несколько слов о т.н. «порошковом вине», разговоры о котором не утихают уже не первое десятилетие. На самом деле, конечно же, «порошковое вино» — не более, чем городская легенда. Даже если отвлечься от тонкостей технологического процесса, выпаривать виноградное сусло до состояния порошка с тем, чтобы после вновь разводить его водой, — затея, требующая создания огромных промышленных установок и гигантского расхода энергии.
— пишет главный редактор портала о вине «Грозди.Ру», Александр Милицкий.
7 комментариев
13 апреля 2015 11:24

Моя маленькая лепта в PHP7

Исправление в ПХП7 (57.09КБ) Читал исходники ПХП7, заметил небольшую ошибку в функции копирования потоков (stream), сегодня мой коммит перенесли в код.
4 комментария
8 апреля 2015 10:22

Долгожитель сельца Михайловка

Михайловка (95.08КБ) В самарском фонде №150, описи 1, деле 85а всплыл настоящий долгожитель. Государственный крестьянин Иван Семёнович Попов, которому на 1834 год было 129 лет. Прожил он ещё дольше — до 1841, умер в сельце Михайловка Оренбургской губернии Бузулукского округа Пронькинской волости. Чему оно соответствует на современной карте я не знаю, но ясно, что надо искать вокруг города Бузулука, который существует до сих пор. Попов Иван Семёнович (40.68КБ) Точных дат рождения и смерти нет (для этого надо искать метрические книги, а сохранились ли они — неизвестно), но можно подсчитать, что он прожил 135 или 136 лет! То есть родился он при Петре Первом, а умер — при Николае Первом. В списке долгожителей в «Википедии» Иван Семёнович, кстати, не числится.

Обновление (ревизия 1834 года)

Мне всё-таки стало интересно — есть ли в предыдущих ревизиях этот долгожитель и я посмотрел записи 1834 года, благо в «народном каталоге» 150-го фонда быстро нашлась запись о нужном сельце. Итак, в фонде 150, описи 1, деле 17 на листе 508об находится запись: Попов Иван Семёнович в 1834 году (29.00КБ) Важно обратить внимание на начало вертикальной записи, которую я срезал. Там написано следующее: «перешли в 1830-м году [из] Омской области Петропавловского уезда из деревни Пузевой». То есть можно более ранние следы поискать в омском архиве, но туда я обращаться вряд ли буду.
10 комментариев
6 апреля 2015 08:48

AltoCar

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

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

Судя по всему, я в купленные 500 км должен уложиться, если это действительно так, то экономия существенная — пять тысяч рублей (а 3990 и подавно) несколько ниже, чем семь. «Альтокар» запускается 15 апреля, но ребята предложили протестировать их сервис заранее, предупредив, что многое не готово.

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

Сегодня я проехал свою третью поездку, хочу поделиться впечатлениями. Машины вполне комфортные — много таксистов перебралось из такси «Татарстан», там разбитые «вазы» попадались редко. Водители вежливые, спрашивают нужно ли включать музыку и полны энтузиазма. Такси (727.10КБ) Приложение, как я сказал, находится в стадии «альфы», поэтому выглядит пока незатейливо. Вот экран вызова такси, минимализм: Экран вызова такси (170.95КБ) Показан мой баланс в километрах, адрес, есть поле для коментария и отметка требуется ли детское кресло, это всё. Следующий экран так же содержит только самый минимум, состояние заказа и кнопка отмены: Экран состояния заказа (180.15КБ) Больше информации приходит по СМС, там можно увидеть номер и марку машины, а так же имя водителя: SMS (200.72КБ) После поездки на почту приходит небольшой отчёт, километраж, адрес, время простоя и так далее: Отчёт (310.93КБ) Время простоя — важный фактор, потому что бесплатны только первые 10 минут ожидания и 40 секунд остановки, дальше каждая минута тарифицируется как 0,3 километра. Есть и другие вещи, о которых стоит знать — поездки менее двух километров приравниваются к двум километрам, а каждый километр за городом (более 40 от Казани) умножается на 1,2.

Все эти факторы (а так же выбор маршрута водителем из-за пробок, например), могут влиять на километраж в сторону увеличения от ожидаемого. Например, сегодня, судя по картам «Яндекса» я должен быть проехать 6,2 км, а на деле потратил 7,32. Разница невелика, но я и не в час пик ездил.

Так же сказывается недостаток водителей — «Альтокар» ещё толком не запускались, поэтому водителей мало. Обещают время ожидания около 20 минут, но по факту приезжают за 5—10. Думаю, это пока связано с тем, что клиентов тоже мало.

В общем, пока впечатления положительные, дальше посмотрим.
16 комментариев
4 апреля 2015 18:51