четверг, 31 декабря 2009 г.
Итоги 2009
Этот год проходил под высоко поднятым знаменем кризиса, кризис сразу же свел с ума большую часть раньше дремавших граждан и начал выплескиваться в самых неожиданных местах самым неожиданным образом. Я полагаю, что подводить итоги года сейчас несколько преждевременно, все станет понятно только лет через 10. Утверждения политиков стоят значительно меньше, чем они сами, хоть это и почти невозможно. Так что это точно, не конец, и не дно. Дно будет в 2012 году, притом после этого дна не будет вообще ничего. Ну вы знаете, смотрели ведь все уже "2012".
Для меня - все сложилось неплохо. Есть даже небольшой рост. Но не удвоение, как было раньше каждый год. Год закончился возвращением меня на докризисные занятия. Плюс, в этом году я сознательно начал себя совершенствовать. Если раньше я что-то делал для себя, только, если это приносило непосредственную радость, теперь система несколько другая. Времени слишком мало, чтобы терять его только на том, что приносит тупое удовлетворение. Конечно, это стоит совершенно адской усталости. Но - оно того стоит.
Прогнозов на 2010 давать не буду. Мой текущий прогноз - "На Новый Год не будет снега в Москве". Так что, прогнозы пусть дают аналитики, а у меня есть совесть.
С Новым Годом!
воскресенье, 27 декабря 2009 г.
Мысли синего воротничка о трудоустройстве
И тут мы сталкиваемся с традиционным для нашей страны: рекрутеры некомпетентны. Кадровые агентства некомпетентны. Можно сделать так, есть три стороны: заказчик, который просит найти кадровое агентство кандидата (эта сторона хочет получить за минимум денег максимум возможностей), кадровое агентство (которое хочет получить максимум денег за минимум времени) и работник (хочет максимум денег при минимальном соответствии требованиям). Совершенно очевидно, что кадровое агентство не ухудшает ситуацию, вводит только некоторые добавочные финансовые издержки, но ухудшать не должно. Если добросовестно работает. Теперь мы попадаем в реальный мир. Кадровое агентство за трудоустройство на выгодную позицию берет деньги не только с заказчика, но и с клиента (здесь только идиоты так не делают), при таком раскладе соответствие требованиям становится формальностью. Ну и классическая ситуация заказчик-исполнитель: клиент хотел одно, заказчик понял другое, а в реальности получилось третье. Итак, мы видим вакансии кадрового агентства полные формальных требований. Нам требуется программист для программирования нашей уникальной системы, с опытом программирования такой уникальной системы и знанием такого-то языка. Ну да, только все лучшие специалисты этой уникальной системы находятся в самой компании, а все остальные требования ничего не скажут вам о способностях кандидата.
Т.е. я не вижу для работодателя никакого смысла в использовании кадровых агентств. Во всяком случае в их текущем виде.
Далее, резюме - совершенно бесполезная вещь. Я видел резюме, от прочтения которых хотелось пасть на колени перед этим светочем и начать обильно причмокивать. Мы же живем в реальности. Светочей нет, вокруг одни дебилы. Но с интересным резюме. По каждому пункту резюме требуется информация о пользе и результативности сотрудника для компании и для конечных клиентов. И эту информацию сотрудник и его резюме выдать не может. Плохо то, что и компания не будет выдавать эту информацию.
В чем же решение? Должна быть система регистрации выполненных конкретным человеком проектов, система с возможностью анонимизации, и это не является критичным. Т.е. если человек хочет предоставить не анонимную информацию, она должна быть подтверждена его работодателем. Если нет, он должен предоставить способ подтверждения своей информации. Это как кредитная история. Т.е. по моей идее человек всегда должен быть заинтересован в поиске работы и работать в плотном контакте с "кадровым агентством", в тот момент, когда он вдруг захочет сменить работу, у него будет множество предложений соответствующих его реальным способностям. Если есть проект, которым можно гордиться, а не просто написать - разработка биллинговой системы для крупной компании - вы же обязательно это напишите. А если ваша биллинговая система для крупной компании никогда не заработала, а вы ушли из компании до окончания проекта проставив себе очередной пунктик в резюме - теперь такая информация не пропадет. Страна должна знать своих героев. Итак, мы почти улучшили работу кадровых агентств (на самом деле, хорошие кадровые агентства уже должны так работать). Осталось последнее. Компания вами довольна, проект вы сдали. Чего же не хватает, пункт в резюме ведь есть? Не хватает отзыва клиента. Вот он, идеальный кандидат: им могут быть довольны в компании, могут быть довольны клиенты, он может сам быть собой очень доволен - теперь работодатель может выбрать по большему числу параметров и фактически - автоматически. Нравятся "прыгуны" - поставили параметр такой-то, хотите увеличить число жополизов в штате - пожалуйста, вам нужны удовлетворители клиентов - подняли параметр номер такой-то, нужно профессионально распилить бабло - жмем вот на эту кнопочку, "буду жрать говно, лишь бы платили" - коричневый счетчик со звуковым эффектом, "насру и ищите меня в поле" - что-то у меня уже фантазия на кнопочки иссякла.
Мне вот интересно, как заставить такую систему работать? С одной стороны, многим моим знакомым станет тяжеловато найти работу. С другой - говна в мире станет поменьше, многие наконец поймут, что их место в супермаркете или на автозаправке. ИТ ведь такая интересная область, тут некомпетентность на любом уровне подчас тяжело оценить "в полете", зато всегда можно оценить по итогу. Вот меня по моей системе можно очень жестко оценить, поэтому я и пишу все это, ведь на текущий момент получается идиотская ситуация, я не вижу вакансий, где требовалось то, что я могу, можно получать вполне достаточно и с меньшими знаниями и навыками. Т.е. с одной стороны, я не могу найти вакансию, где бы требовалось то, что я знаю. С другой, чтобы достойно платили этого и не надо. Но я так вроде как не хочу. Такие унылые размышления синего воротничка...
Новогодние предложения от сотовых операторов
Насколько подаваемая реклама соответствует истинной "сути" операторов? Опыт подсказывает, что не сильно. Так что МТС наверно можно назвать даже более честными. Они свою кровожадность не скрывают.
Ждем появления community-based провайдеров услуг сотовой связи.
суббота, 26 декабря 2009 г.
понедельник, 21 декабря 2009 г.
понедельник, 14 декабря 2009 г.
mozilla, bing и личные данные
Да, microsoft и bing - это верх демократии и заботы о личных данных. Попробовал естественно bing найти себя. И не смог. Он так заботится о моих личных данных, что даже на CPAN с трудом находит. А уж статьи учебника найти просто не получилось. Ну это конечно же только бета версия. В финальной версии и на CPAN не найдет.
Вообще, наличие таких дешевых шлюшек в стане mozilla заставляет задуматься.
воскресенье, 13 декабря 2009 г.
100
Поэтому он собственно про это. Что произошло за эти 100 постов. Где-то 10% из них посвящены GnuCash, но именно они получают 90% внимания посетителей. Которых не так мало, так что считаю мой труд в этом направлении не напрасным, что-нибудь я бы все равно писал, а так - еще и кому-то может пригодиться. Дальнейшие планы я уже озвучивал, это систематизация, расширение географии, освоение новых способов донесения информации. Но это всего навсего 10% моего блога, а если взять меня самого, то даже и процента не набежит. Так что буду пробовать писать и о интересных мне вещах, не связанных с финансами, тем более в последнее время я стал снова много программировать. Что не может не радовать.
Забавная деталь, один из самых дешевых и неблагодарных способов повысить посещаемость - это писать о злободневном. Так, написал я про то, как накололся с МТС, и это интересно людям. Народ валит. Кликает на банеры. И может быть кому-то и эта информация полезна. Но, 90% больше ничего не читают, и в целом - просто портят статистику. Мне больше импонируют люди, которые проводят хотя бы 4 минуты на моих страничках, и просматривают хотя бы 2 страницы. Притом посты, которые привлекают таких посетителей - это наш реальный актив, так как со временем он не становится хуже. А вот писать на злобу дня - это все равно, что работать :) А этого нам совсем не надо, так как мы же стремимся к финансовой свободе в ближайшую пятилетку.
воскресенье, 6 декабря 2009 г.
Работа с GnuCash. Часть 7. Плановые проводки.
Один из первых вопросов, который возникает у человека после первого знакомства с gnucash, это - а как автоматизировать получение процентов по депозиту, начислений по кредиту, налоговых отчислений, платежей за квартиру и т.п.
Итак, представим себе простейший случай. Каждый месяц 6 числа мы платим 1000 рублей за обеспечение нас Интернетом. Допустим, что мы это делаем безупречно, или это делаем не мы. Но ровно 6 числа счет оплачен. Для отражения таких проводок в gnucash предназначен механизм плановых проводок. Выбираем меню Действия->Плановые проводки->Редактор плановых проводок. Появляется закладка "Плановые проводки".

Рис 7.1. Закладка "Плановые проводки".
Выбираем создание новой проводки. В наименование вводим "Платеж за Интернет". На закладках оставляем все по умолчанию. Идем на закладку "Шаблон проводки". Здесь мы вводим нашу проводку. Только вот вводим мы каждую часть проводки отдельно. Т.е. сначала вводим кредит счета наличных на сумму 1000 рублей, а затем - дебет счета услуг интернета на 1000 рублей. В итоге получаем следующую картину:

Рис 7.2. Вводим детали шаблона проводки.
Проводка введена. Пора бы попробовать ее исполнить, тем более, сегодня как раз еще нужное нам число. Выбираем Действия->Плановые проводки->С момента последнего запуска...

Рис 7.3. Список сформированных проводок.
Все достаточно просто.
Теперь, как можно это использовать дальше? Не для простейшего случая. Тоже начисление процентов по депозиту - достаточно сложная вещь. В расчете участвует как ставка рефинансирования, так и много других параметров, как срок нахождения средств на счету, средний или наименьший остаток средств и так далее. Да, еще выходные дни, их тоже надо учитывать. Вообщем, я считаю, что к сожалению, механизм плановых проводок gnucash слабо подходит для решения таких задач. Но, для тех кто все же хочет попробовать приходят на помощь формулы. Дело в том, что вместо суммы мы можем указать формулу, которая будет расчитываться. Плюс возможно использование параметров, ну и есть возможность получить номер текущей плановой проводки. Основной недостаток - формуле тяжело получить текущее состояние счета, например (во всяком случае, я пока не знаю, как это сделать, а те, кто в рассылках gnucash про это пишут, утверждают, что это невозможно). Формулы доступные можно посмотреть в /usr/share/gnucash/scm/fin.scm. Вызывать можно формулы с префиксом gnc:, указывать их соответственно надо без этого префикса. Т.е. чтобы вызвать функцию gnc:foobar с параметром 1000 надо писать foobar(1000). Для разделения передачи нескольких параметров используется :. Естественно, определенных стандартных функций мало кому хватит. Поэтому мы создадим простейшую функцию, которая вернет разницу от переданной базы - проценты, притом мы будем передавать базу числом, а проценты - как параметр для уточнения при создании проводки. Забавно, что человек, который в рассылке gnucash отвечает на вопросы предлагал это делать в оригинальном файле. Это явно нехорошо. Мы попробуем сделать это в файле ~/.gnucash/config.user:
(define (gnc:kilork base tax) (- base tax))
Перезапускаем gnucash и снова создаем плановую проводку, но на этот раз вместо 1000 мы пишем kilork(1000,tax), где kilork - наша функция, а tax - переменная, значение которой мы пока не знаем. Хочу обратить внимание, что не получится использовать символ "-" в имени функции, хотя все тот же автор из рассылки приводит именно такой пример.

Рис 7.4. Использование функции в плановых проводках.
Вызываем создание проводок, и видим, что теперь требуется ввести значение параметра tax, чтобы наша проводка создалась:

Рис 7.5. Создание проводки с использование функции и параметров.
Таким образом можно реализовать собственную функцию расчета любой сложности на языке Scheme, но к сожалению, удобного доступа к таким нужным параметрам, как остатки по счетам найти пока не удается.
P.S. На самом деле для учета поступлений из внешних источников мне кажется неправильным использовать плановые проводки. Я вижу правильным в данном случае загрузку из online источников. Т.е. это должно выглядеть так, мы подключаемся к нашему банку, получаем выписку по счету, после чего все остатки меняются соответственно. В gnucash есть возможности online-банкинга, но в нашей стране мало банков поддерживают такой формат. Соответственно, для нас дело чести реализовать провайдеров для как можно большего числа источников, чтобы сделать мир еще чуть-чуть лучше.
воскресенье, 29 ноября 2009 г.
Холивары
Но в целом, я конечно не совсем прав. Нельзя наставлять стадо на какой-то путь.
Так вот сижу я, размышляю на эту тему. И вижу очередную статью, где рассказывается, как все плохо в виндовсе, и как хорошо - в линуксе. Ну да, все так. Но я точно знаю, что это правда только с одной стороны. Люди привыкают к хорошему. Или к тому, что у них есть. И потом лишь малая часть может взглянуть на происходящее с другой стороны. И в этом нет ничего плохого. Наоборот, это же хорошо.
Т.е. я никому не буду рассказывать, как мне удобно пользоваться линуксом, и как неудобно - виндовсом. Я просто буду пользоваться тем, что мне удобно. Ну и может расскажу, как именно я делаю свою жизнь чуть проще. И склонять всех к тому же - неблагодарное занятие. Человек может сам выбирать, и выбор не обязательно обосновывать.
вторник, 24 ноября 2009 г.
Дружим java и python через web services
Мне потребовалось подружить java с python, для сервера мы используем jax-ws, а для клиента нашли сначала SOAPpy, но уперлись в то, что данная библиотека как-то плохо дружелюбна со сгенерированными jax-ws wsdl. Притом решать я начал проблему не с того конца. Я научился расширять генератор wsdl собственными классиками. Подцепился в самые нутри, добился таки смены targetNamespace... и налетел на ошибку через еще пару строчек SOAPpy.
Стало очевидно, что дальше с SOAPpy нам не по пути. Еще несколько минут поиска, и мы выходим на suds. Пока что моя кожа благодаря этой библиотеке - мягкая и шелковистая.
Про jax-ws выяснились откровенно говоря неприятные подробности: нутри страшные, индусско-японские, и совершенно дурацкие. Я вообще обычно тревожусь, когда для того, чтобы понять, куда надо ткнуться, мало прочитать статью автора, надо еще самолично проанализировать код, выругаться 10 раз, найти хак для того, чтобы сделать то, что надо нам, но что невозможно сделать тем механизмом, что поставил автор, и все это в первую неделю пользования либом. Зачем было пользоваться такими корявыми классами и так их коряво сращивать. И меня бы все это не волновало, если бы оно все работало. Так ведь нет, не работает еще вдобавок. Reference Implementation, называется.
понедельник, 16 ноября 2009 г.
Vim и Blogger: Dependency hell
Я решил освоить в нагрузку ко всему еще и vim. Возможно, это было
ошибкой. Но было интересно. Итак, решаем привычную задачу - постим
записи из редактора. Даже не так. Как все было: я хотел запостить
сообщение с своим скриптом для сборки свежей версии gentoo-sources
ядра. Запостить из vim. Что для этого надо? Естественно, нужен vim,
плагин для vim для blogger. И еще хорошо бы раскрасить башевский
скрипт всеми цветами радуги перед постом. Итак, идем по шагам.
Шаг 1. Vim
Этот шаг оказался на самом деле самым простым. Я не говорю о
установке самого vim, я говорю о настройке плагинов. Оказалось есть
замечательный GLVS (GetLatestVimScripts). Он вроде как уже впаян в
vim. Так что нам остается только подправить его настройки.
Прописать там наш плагин blogger.vim, и настроить параметры
автоинсталляции в .vimrc . Все бы хорошо, но оказалось, что я
создал файл .vimrc не совсем в корне домашней директории, что
помешало инсталляции автоматом. Ну ничего, я и сам смог распаковать
папочку. И доставить потом еще один плагин, от которого зависит наш
пациент.
А дальше мы выясняем, что корни нашего плагина уходят в ruby.
Достаточно интересный поворот.
Шаг 2. Ruby
Здесь мы имеем gentoo с ее системой пакетов. Первая зависимость -
nokogiri, имеется, так что:
phoenix kilork # emerge nokogiri
Со второй обстоит дело хуже. В портежах его нет, зато можно
поставить очень просто через gem:
gem install rpeg-markdown
Вроде бы все. Пробуем запустить и бац. Опять не работает. На этот
раз не хватает net-https-wrapper. И его нет ни в портэжах, ни в
gem. Что за зверь такой? Оказывается, это гениальная поделка автора
blogger.vim. О зависимости от которой он естественно забыл
упомянуть. Находим, закачиваем, распаковыем, делаем:
kilork@phoenix ~ $ gem build net-https-wrapper.gemspec
kilork@phoenix ~ $ gem install net-https-wrapper-1.0.gem
Хочу обратить внимание, что я ставлю под рутом только то, что
ставлю портэжами.
Счастье близко. Список записей мы уже можем вытащить. Но, дальше,
что-то не работает снова. Видимо, это последняя зависимость из
списка автора, которому как выясняется - верить не стоить. Верить
вообще никому нельзя. На этот раз мы выясняем, что требуется
установка pandoc, а это - haskell.
Шаг 3. Haskell
Выясняем, что чтобы поставить pandoc, нам лучше всего
воспользоваться cabal, аналог gem и cpan, но для haskell. Чтож,
легко:
phoenix kilork # emerge cabal
Должно было быть легко, но как выяснилось, все не так хорошо, как
хотелось бы. Этот cabal, это совсем не тот cabal, который нужен.
Нужно делать на самом деле так:
phoenix kilork # emerge haskell-platform
Вот теперь можно сделать под обычным пользователем:
kilork@phoenix ~ $ cabal update
kilork@phoenix ~ $ cabal install pandoc
Добавляем в пути наш каталог с бинарными файлами cabal, где лежит
тот самый pandoc. Ссылки на требуемый на самом деле html2markdown
там пока что нет, файл лежит где-то в недрах share в поддиректориях
.cabal . Создаем на него символическую ссылку, назначаем полномочия
на исполнение. И... Ничего. Опять ничего, теперь он еще почему-то
не работает. Тут я уже устал мучаться, залез в собственно
html2markdown, обнаружил у него две проверяемые зависимости: tidy и
pandoc. Ругается на pandoc. Проверку тупо убираем, он же у нас
есть, зачем ругаться, да?
С tidy все не так плохо, она есть в портэжах:
phoenix kilork # emerge htmltidy
Шаг 4. .vimrc
Вот это позволит нам найти наш блог:
let g:blogger_blogid = 'your_blogid_here'
let g:blogger_email = 'your_email_here'
let g:blogger_pass = 'your_blogger_password_here'
И все, работает.
Получение записей блога:
:e blogger:list
Ходим по списку, жмем enter, редактируем, жмем :w . Все просто.
Создание новой записи:
:w blogger:create
Итоги.
Все как в анекдоте про допил напильником. И все работает через одну
хитро закрученную жопу. Ну и может быть мое руководство кому-то
поможет. Или кто-то посмотрит, и скажет, как можно было все сделать
по правильному. А я пока подумаю, как бы мне tag проставлять...
четверг, 12 ноября 2009 г.
GGD 2009
понедельник, 9 ноября 2009 г.
Все говно, кроме мочи
Очень точно подмечено. То что с виду кажется не г..., при ближайшем рассмотрении все равно оказывается им самым.
В эти выходные наконец таки реализовал скрипт для сборки нового ядра и почистки старых. Экономия нервных клеток на этой операции будет оценена не скоро, но думаю - будет приятно. Мне кажется, именно в этом суть программистского подхода к делу, все рутинные операции учить делать машину. Если мы делаем это больше чем один раз, это уже надо автоматизировать. Очередной пункт в личном todo-листе выполнен. Выложу тут и код этого сокровища в следующий раз. А пока оставшиеся пункты:
1. python-скрипт для заполнения ежедневных отчетов на работе
2. perl-скрипт Finance::Quote::Sberbank - исправить накопившиеся ошибки (есть 9-месячный багрепорт, а это ужасно)
3. локализовать openerp
4. lfs-нуть нетбук
5. найти или написать штуку для проверки торговой стратегии на архивных данных
6. написать собственно штуку для торговой стратегии
7. сделать информеры на svn репозитории в виде notify в gnome
И еще много чего, что мне хочется сделать. Каждый день я сижу где-то до 2-х часов ночи, стараясь сделать сегодня чуть-чуть больше чем вчера. И главное - ни один день не должен пройти без познания или создания чего-то нового. Это настоящее счастье - узнавать новое.
воскресенье, 1 ноября 2009 г.
24 часа
среда, 28 октября 2009 г.
Тува
В данном случае я целиком на стороне милиции, поставьте себя на его место. Лучше быть обвиненным в "превышении полномочий", чем потом мозги собирать по мостовой. Для применения оружия достаточно ощущения угрозы, а не реальной угрозы, это ключевой момент. Реальность угрозы в экстремальной ситуации установить проблематично, или даже скорее - невозможно, поэтому действовать приходится считая опасность максимальной.
И никому ведь неинтересно, как так, 17-летний школьник за рулем, и размахивает чем-то похожим на оружие. Но, конечно незачет, надо было в него влить алкоголя немного хоть, чтобы за версту несло.
МНОГО редактирования
my $bproc = 0;
my $bfunc = 0;
my $bout = 0;
my $bbody = 0;
my $inselect = 0;
sub checkpar {
$bout = 1 if(/\sout\s/ and $bproc == 1);
if($bbody == 1) {
print "declare\n" if (!/^begin$/);
$bbody = 0;
}
if(/\)/ and $bproc == 1) {
$bproc = 0;
$bbody = 1;
print;
print " returns void" if($bout == 0);
print " as \$\$" ;
}
elsif(/\)\s*return\s+(\S+)/ and $bfunc == 1) {
$bfunc = 0;
$bbody = 1;
s/return/returns/;
print;
print " as \$\$" ;
}
else {
print;
}
print "\n";
}
while(<>) {
s/\r\n//;
next if /^\s*(as|is)\s*$/;
$inselect++ if(/select/);
if($inselect != 0) {
s/^(\s*)([a-zA-Z_.0-9]+)(\s+)([a-zA-Z_.0-9]+)(\s*,\s*)$/$1$2$3as $4$5/;
s/^(\s*,\s*)([a-zA-Z_.0-9]+)(\s+)([a-zA-Z_.0-9]+)(\s*)$/$1$2$3as $4$5/;
}
$inselect-- if(/from/);
s/^(\s*from T_OBJ o), ([^\s]+\s+)([^\s]+)$/$1 left join $2$3 on o.ID=$3.ID/;
s/ and \S\.ID \(\+\)= \S\.ID//;
s/varchar2/varchar/g;
s/number/numeric/g;
s/nvl\(/coalesce\(/g;
s/c_pkgcore\.gt_cursor/refcursor/gi;
s/"ADD"/ADD/g;
s/substr\(t_pkgVOC\.fGet([^(]+)\(t_pkgVOC\.fGetVOC\(([^)]+)\), ([^)]+)\), 1, \d+\)/t_pkgVOC__fGetVOC$1\($2, $3\) as/g;
s/substr\(c_pkgCore\.fGetSysUser([^(]+)\(([^)]+)\), 1, \d+\)/c_pkgCore__fGetUser$1\($2\) as/ig;
s/substr\((.*), (\d+), (\d+)\)/substring\($1 from $2 for $3\)/g;
s/substr\((.*), (\d+)\)/substring\($1 from $2\)/g;
s/t_pkgVOC\./t_pkgVOC__/gi;
s/t_pkgObj\./t_pkgObj__/gi;
s/t_pkgView\./t_pkgView__/gi;
s/c_pkgCore\./c_pkgCore__/gi;
s/SQL%NOTFOUND/not found/gi;
if(/function\s+([^(\s]*)([^\n]*)/) {
$bfunc = 1;
$_ = "/* $1 */\ncreate or replace function t_pkgRpt__$1$2";
}
if(/procedure\s+([^(\s]*)([^\n]*)/) {
$bproc = 1;
$_ = "/* $1 */\ncreate or replace function t_pkgRpt__$1$2";
}
if(!/^\s+$/) {
checkpar;
}
}
print "\$\$ language plpgsql;\n\n";
понедельник, 26 октября 2009 г.
Новости короткоствола
Пьяный милиционер застрелил сотрудника ГИБДД, ранил второго и покончил с собой. Кто знает, как все было на самом деле, невменяемый милиционер, или невменяемое взятничество, иногда тяжело сойтись в цене. Одно понятно, теперь милиционеров на освидетельствование будут возить только в одном виде, с пушкой в жопе. Только такой способ обеспечит проведение экспертизы. Ну и нарушителей правил либо не будут останавливать вообще, либо - класть лицом в пол независимо от их данных, и за любое неподчинение - пуля в филейную часть. Модель очень хорошо работает в развитых демократических странах, там невменяемость преступника не считается смягчающим обстоятельством.
Медведев молодец, уволил оперативно. Хотя, вообщем-то не факт, возможно, к моменту суда выяснится, что застрелили двух переодетых милиционерами шлюх из оружия Евсюкова.
P.S. К версии с невменяемым взятничеством я, кстати, склоняюсь все больше. Т.е. я думаю это был честный упившийся с горя от понимания реальности до белой горячки страж закона. И он честно ехал пьяный домой, и был готов отдать за это вменяемые деньги. Но, денег попросили много и в грубой форме, вот вам и короткоствол, человек просто сорвался.
понедельник, 19 октября 2009 г.
Joke of a day
Knight, seeing what the student was doing, spoke sternly: "You cannot fix a machine by just power-cycling it with no understanding of what is going wrong."
Knight turned the machine off and on.
The machine worked.
"
Повеселило. Иногда добираешься и радуешься по настоящему древним баянам...
понедельник, 12 октября 2009 г.
суббота, 10 октября 2009 г.
Ай, моська! Знать она сильна, раз лает на слона!
Собственно, я на начало матча не знал, за кого болеть. Но понял это, когда услышал поведение российских болельщиков во время гимна команды соперника. В одном этом проявляется вся суть нации. А такой нации нельзя побеждать. В этот раз футбол показал именно свою силу, поведение болельщиков предопределило исход матча. Быдло должно знать свое место. Поведение российских болельщиков в матче - отвратительное, поведение футболистов - отвратительное, тупые злобные моськи, место которым на заблеванной помойке, а не на чемпионатах мира. Футбол хорош тем, что методы НАШИх здесь не работают, после 90 минут времени все становится на свои места. Жаль, что 1:0.
Сборной Германии - большое спасибо за отличную игру.
понедельник, 5 октября 2009 г.
Осторожно, мошенники! Валим из МТС или что делать, если пришло sms с номера 770262 контент-провайдера 88003330190
Итак, как я стал жертвой лохотронщиков:
1. приходит смс с номера 770262 с информацией, о том, что продлена некая подписка, затем с другого номера 770160 приходит предложение отписаться.
2. в конце месяца МТС радует нас списанием лишних 100 рублей со счета за волшебную смс (входящую, мы же не реагируем на звонки и смс от незнакомых людей).
Все гениальное просто. В саппорте услужливо дают номер контент провайдера, и предлагают решать свои проблемы самому. Ну или тарифный план сменить. Неплохо, отключаюсь от МТС нафиг.
Ну собственно, я далеко не первый, в интернете про этих деятелей пишут достаточно. Все хорошо опосля. Хочется только напомнить контент-провайдеру как закончилась жизнь главного спамера России. Особенно, цитирую: "...смерть Кушнира наступила от закрытой черепно-мозговой травмы и множественных ушибленных ран головы...". Желаю Вам того же.
P.S. Этот пост активно обсуждали на auto.ru. Решил уточнить некоторые моменты:
1. от того, что человек наивен лохотрон не перестает быть лохотроном
2. ответственность лежит как на лохотронщике (поставщик контента), так и на тех, кто его покрывает (МТС). После двух-трех обращений граждан такие вещи просто не должны были быть никогда, ан нет - каждый раз, как первый раз.
3. Я не кровожадный, и моих потерянных денег мне конечно жалко, но это не повод кому-то желать смерти, повод - умножьте абонентскую базу МТС хотя бы на одну такую платную sms, а это уже вполне приличная именно украденная (можно сколько угодно называть это другими словами, но это именно воровство) сумма. Я убежден, что получение такой суммы человеком с такими моральными качествами (допустимостью извлекать выгоду из обмана людей) - повод для дальнейших трагических событий. Просто я пытаюсь смотреть чуть дальше, чем перед своим носом, что однако не мешает мне иногда вляпываться вот в такое вот говно :) Но, на ошибках учатся.
P.P.S. Операторы таки предприняли шаги к исправлению ситуации. Это не может не радовать. Хотелось бы получить от кого-то подтверждение, что это действительно работает.
P.P.P.S. На сегодня (12.05.2010) шаги операторов оказались лишь маркетинговой галочкой, никаких реальных действий для защиты интересов клиентов по прежнему не предпринимается.
P.P.P.P.S. Столкнулся с еще одним способом мощенничества: читаем.
Ужастик
Итак, юг России, или, можно даже на Украине. Группа молодых людей приехала на отдых. И все бы ничего, но прямо на их глазах падает самолет. Притом падает очень забавно, в крутом вираже ложась под 90 градусов на крыло, заваливается, и переворачивается. Даже не горит. Естественно, все бегут на помощь. Но на подходе к месту катастрофы появляются странные детали, вонючее обгорелое мясо раскидано там, где казалось бы и быть его не должно. К самолету подойти не удается, всю группу молодых туристов отчаянно мутит от увиденного. Ничего не понятно.
Появляются военные. Гражданских собирают в местной больнице на импровизированную пресс-конференцию. Притом, главные военные заходят наполовину обгоревшими (в частности, у самого главного буквально в пепел превращено пол головы, что нисколько ему не мешает), вносят нескольких полудохлых негров (вот уж не знаю, откуда взялись негры, притом обгоревшие, у российских военных, описываю что видел). Итак, военные начинают откуда-то издалека и непонятно, но внимание всех приковано к подыхающему негру. Соответственно, негр подыхает, и тут всем показывают чудовищные генетические изменения, произошедшие с уже телом. Зубы заострились и челюсть превратилась в чудовищную пасть, руки - в когтистые отростки, все покрыто слизью. Ну сами понимаете, вообщем.
Собственно, здесь все выясняется, хотя и немного: есть вот такие гады, военные с ними борятся, и не допустят гибели мирного населения. Мирное население в шоке, обгорелые вонные, дохлые мутанты, все понимают, что наступает быстрая хана.
Вовремя забегает какой-то солдатик и кричит, что где-то вокруг бегает еще один. Народ распределяют по зданию вдоль стен и накрывают некой невидимостью (вот тут я реально не понял, может это будущее), главное при виде мутанта - не шевелиться и не паниковать. Короче, построили всех вдоль стеночки. Ну и мимо идет один из обгоревших в военной форме, рядом врач, врачу он говорит, "начну превращаться, мочи меня". Для гражданских уже все очевидно, но поскольку инструкция была дана стоять вдоль стеночки и не шевелиться, народ пока стоит (но скоро начнется паника, и толпы мутантов).
В это время включается картинка из физкультурного зала (видимо, дело происходит в школе местной). Двое бойцов держат третьего, который прямо на глазах меняется. Врачи пытаются ему что-то вколоть. Мутант притом вполне сознательный, ему не нравится страх в глазах одного из солдат, от него он приходит в еще большую ярость, сначала освобождает руку, выхватывает инструмент у врача, ну а дальше вырывается окончательно и первым делом быстренько и смачно разрывает на кусочки застремавшегося солдатика, при этом приговаривая "а вот не надо Нас бояться, и тем более не надо делать из Нас Охотников". Оба на. На фоне добивают остатки медицинской бригады, а мы теперь знаем, что есть некие Охотники, которых делают из этих мутантов, чтобы с ними бороться. Т.е. явно заговор военных и все такое, что все любят.
Продолжение я смотреть не стал, надо было вставать, да и не люблю я ужастики. Так что могу только предположить, что дальше появляются Охотник, гражданских тотально уничтожают мутанты, а парочка человек прибиваются к Охотнику. А может и нет. В любом случае, конец фильма будет предполагать, что ничего не понятно, максимум на что могут расчитывать главные герои - выживание, но не более чем на время титров. Кровищи море, лучшие декорации - кафель любой советской постройки, удешевить съемки можно проведя их на территории мясокомбината образца развала Союза. Снимать надо так, чтобы было мало цвета - все цвета очень холодные, а кровь - почти черная. Ну вот как-то так.
Тут главное - соблюсти баланс дебилизма, и не делать банальностей (аля, толпа зомбей). А то, без некоторых элементов, в кино даже известные актеры не помогут, получится тупой малобюджетный трэш. Так что если кто хочет знать, что надо для успеха этого кино, пишите мне письма, обсудим, гонорар у меня достаточно скромный, а кино будет - просто чума. Гошу Куценко и Безрукова звать в кино не будем, народ засмеет. Так что, успех - гарантирован.
воскресенье, 13 сентября 2009 г.
Воспроизводим звук по сети: pulseaudio + ubuntu + gentoo
Все очень просто, нужна всего лишь флэшка. Копируем фильм на оба устройства, одновременно жмем проигрывать... и, получаем искомый результат.
А чего, в первый раз я так и сделал. Но звук немного расползается, да и на паузу ставить неудобно.
Дальше мы включаем google. Находим padevchooser, ставим (на нетбуке, где у нас ubuntu), запускаем:
kilork@pantogan:~$ sudo apt-get install padevchooser
kilork@pantogan:~$ padevchooser &
В трее появляется иконка, жмем на нее, выбираем "Configure Local Sound Server...", там включаем все что понравится на закладке "Network Access". Все, на нетбуке все.
Теперь в gentoo ставим флаг pulseaudio для mplayer'а, запускаем кино воспроизводиться, установив переменную окружения PULSE_SERVER адресом нашего нетбука (да, чуть не забыл, у нас еще и wifi работает, так что способ с флэшкой - это просто позор):
kilork@phoenix:~$ PULSE_SERVER=192.168.1.2 mplayer -ao pulse ~/kilork_the_best.avi
192.168.1.2 - как нетрудно догадаться, адрес нетбука. Если все у нас хорошо, то на большом экране заиграет видео, а звук будет играть на нетбуке. У меня все было именно так.
Но этого мало, ведь чтобы поставить на паузу по прежнему надо пойти и нажать на паузу (у меня конечно, беспроводная клава, но все равно, это не то). Итак, чтобы все было совсем хорошо, заходим по ssh с нетбука и добавляем еще два параметра к запуску: DISPLAY и XAUTHORITY. Приблизительно так:
kilork@phoenix:~$ XAUTHORITY=/var/run/gdm/auth-for-kilork-blablabla/database DISPLAY=:0.0 PULSE_SERVER=192.168.1.2 mplayer -ao pulse ~/kilork_the_best.avi
Теперь, все путем, нетбук превращается в окончание звукового штекера и пульт управления.
воскресенье, 6 сентября 2009 г.
100000 км, отпуск и ремонт
Я проездил на Левине более 100000 км, точно момент перехода не заметил, но все же. Конечно, это уже не та машинка, что была, но он все еще на ходу, что достаточно удивительно, учитывая мое весьма халатное отношение к его техническому и эстетическому состоянию. Один из фактов, что машина и ее обслуживание обошлись дешевле, чем бензин и мздоимство.
С начала лета мы начали ремонт в квартире. Капитальный ремонт. Поменяно все, что только можно было поменять, имея на руках ограниченные в некоторых рамках средства. Теперь я сижу в чистой, уютной, современной, но абсолютно пустой квартире. У вещей нет памяти и надо будет наполнять эту пустоту, думаю, мы справимся.
Надежды провести тяжелое время на даче не оправдались, хотя все же я свой месяц смог умыкнуть. Две недели в командировке, две - на даче. Можно сказать, что я в какой то степени готовился к такой смене обстановки, поэтому у меня был eee и cdma модем skylink. Первый помогал мне вообще везде, пару недель я даже на нем реально работал (но тяжеловато, я люблю работать на большом экране), в основном он был именно тем, чем должен быть - средством для получения информации из глобальной сети. Благодаря модему, я был на связи на достаточно высокой скорости и две дачные недели. Фактически, никакого отрыва от нужной мне цивилизации. Итого, eee - лучшее приобретение последнего года, отдача от него просто потрясающая. Модем себя пока что просто оправдал, я подключил тарифный план, смысл которого только в нахождении на даче, в городе - только на самый крайний случай (1 руб/Мб против 5 руб/Мб).
воскресенье, 9 августа 2009 г.
Оптимизация себя: избавляемся от ненужных преобразований
воскресенье, 2 августа 2009 г.
Дело GnuCash живет и побеждает - модуль Finance::Quote для ММВБ (Micex)
Публикую: http://atsave.narod.ru/micex-pm/index.html.
Подозреваю, держателей ценных бумаг будет больше, чем держателей обезличенных металлических счетов, и если они не интрадеят, такой модуль позволит им учитывать свои вложения в замечательной программе GnuCash значительно проще.
Поскольку обнаружилось, что у народа возникают вопросы по публикации своих модулей на CPAN, в ближайшее время постараюсь вспомнить свой опыт регистрации и изложить его в виде статьи.
Даешь больше модулей для GnuCash!
З.Ы. 21.01.2011 - поменялась ссылка на сайт автора, обновил. Попробую опубликовать на CPAN для облегчения инсталляции, тем более, что мой родной модуль что-то в последнее время поломался...
понедельник, 27 июля 2009 г.
Юпитер трясет
Но уже сегодня новость с трудом находится на новостных сайтах. Что-то мне подсказывает, что совершенно зря, прозевать такое, это гораздо круче, чем допустить новые атаки террористов.
Мне кажется, что как сейчас мы ставим камеры в подъездах, чтобы следить за хулиганами, так и в космосе должно быть развитое око Большого Брата, а то болтается один дохлый Хаббл, который только через 5 дней успевает посмотреть на вселенскую катастрофу, и что с этого толку? Хотя, возможно, и не так уж плохо, если эту лавочку так прикроют :)
воскресенье, 12 июля 2009 г.
Зло
Просмотрел сегодня плафоновый мафон, подумалось, что аум синрике не туда пустило свой газ. Не в смысле убийства, но просто, с эстетической точки зрения, морг заваленный стразами - это круто :)
понедельник, 25 мая 2009 г.
Я - фанат Google
P.S. У блоггеров почему-то принято в начале каждого поста ни о чем раз в 6 месяцев писать про свою страшную занятость, про то, что впредь они будут писать и писать, и т.п. и т.д. Люди просто думают, что на них свет клином сошелся, какая разница, пишете, не пишете, если приходится себя заставлять, наверно не надо. По мне, так иногда хочется писать, иногда нет. И все. Поэтому никакого расписания постов нет, может быть как сегодня, а может - и раз в год/другой :)
Серые мыши, сидите потише
- майор устроил бойню в супермаркете
- милиционер отрезал голову за 60 рублей
- милиционер сбил насмерть беременную женщину и скрылся с места проишествия
- пьяные милиционеры пытали и пытались утопить мужчину "потому что лысый"
- омоновец, угрожая оружием, угнал машину на мкад
Было и еще, всего не упомнишь. Вывод только один: гражданин должен соблюдать закон, а если он его не соблюдает, его место - в тюрьме, либо, за пределами общества. Если же те, кто закон соблюдать должны по определению, его в особо циничной форме нарушают, значит они не могут считаться его представителями. Собственно. всегда всю свою жизнь боюсь милиции больше, чем преступников, именно по той причине, что вполне законопослушен. Эти деятели считают, что им закон преступать просто таки на роду написано, поэтому если видишь, что кто-то делает что-то непотребное - 90%, что это либо миллиционер, либо, лицо с милицией аффилированое ("да я сейчас буду звонить своему другу-"грушнику" (фсбшнику, фсошнику, по обстоятельствам)).
GnuCash - лечим получение котировок валют.
Все это конечно ужасно, но поправимо. Меня всегда удивляли люди, которые ругали опенсурс за ошибки. Увидел ошибку - докажи, что сам чего-то стоишь: поправь ее. Ну или баг-репорт отправь.
Итак, как вылечить gnucash? Ответ как всегда в модуле Finance::Quote. Надо его немного поправить.
Ищем, куда спрятался Quote.pm в нашей локальной инсталяции (мы же не будем править то, что ставим дистрибутивом):
kilork@phoenix ~ $ find ~/perl -name Quote.pm
/home/kilork/perl/lib64/perl5/site_perl/5.8.8/Finance/Quote.pm
Правим его. Тут особых подробностей не напишу, кроме того, что освоил debug perl под emacs (M+x perldb). Сами авторы дают резервный вариант для получения котировок валют, но почему-то, чтобы им воспользоваться, приходится попрограммировать. Я для вас поставлю свой вариант исправления, который работает у меня. В upstream пока погожу слать, подожду версии 1.17 Finance::Quote. Ну а если вдруг кому пригодится, то смотрите, как я поправил.
Ищем оригинал (каюсь, не сделал бэкапа, поэтому сравниваем с тем, что идет в дистрибутиве):
phoenix kilork # equery f Finance-Quote | grep Quote.pm
/usr/lib64/perl5/vendor_perl/5.8.8/Finance/Quote.pm
Сравниваем:
kilork@phoenix ~ $ diff -u {/usr/lib64/perl5/vendor,/home/kilork/perl/lib64/perl5/site}_perl/5.8.8/Finance/Quote.pm
--- /usr/lib64/perl5/vendor_perl/5.8.8/Finance/Quote.pm 2009-05-23 23:26:49.000000000 +0400
+++ /home/kilork/perl/lib64/perl5/site_perl/5.8.8/Finance/Quote.pm 2009-05-25 00:56:28.000000000 +0400
@@ -42,9 +42,9 @@
$VERSION $TIMEOUT %MODULES %METHODS $AUTOLOAD
$YAHOO_CURRENCY_URL $USE_EXPERIMENTAL_UA/;
-$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/currency/convert?amt=1&submit=Convert&";
+#$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/currency/convert?amt=1&submit=Convert&";
# If the above URL ever fails, try rewriting this module to use the URL below.
-# $YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/q?s=USDCAD%3DX";
+$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/q?s=";# USDCAD%3DX";
@ISA = qw/Exporter/;
@EXPORT = ();
@@ -241,16 +241,11 @@
my $ua = $this->user_agent;
- my $data = $ua->request(GET "${YAHOO_CURRENCY_URL}from=$from&to=$to")->content;
- my $te = HTML::TableExtract->new( headers => ['Symbol', 'Bid', 'Ask'] );
- $te->parse(decode_utf8($data)); # The web page returns utf8 content which gives
- # a warning when parsing $data in HTML::Parser
-
- # Make sure there's a table to parse.
- return undef unless ($te->tables);
-
- my $row = ($te->rows())[0];
- my ($exchange_rate) = $$row[1];
+ my $data = $ua->request(GET "${YAHOO_CURRENCY_URL}$from${to}%3DX")->content;
+ if($data !~ /Bid:.+>(\d+.\d+)<.+Ask:/g) {
+ return undef;
+ }
+ my $exchange_rate = $1;
$exchange_rate =~ s/,// ; # solve a bug when conversion rate
# involves thousands. yahoo inserts
# a comma when thousands occur
Данное решение считаю костылем, жду 1.17 с исправлением досадной ошибочки, или 1.16.1. Надеюсь, костыль не будет передаваться из рук в руки, и пригодится только мне :)
понедельник, 27 апреля 2009 г.
Москва отжигает
Гости столицы собираются в автоколонны и паля из огнестрела колесят по Садовому. Где же милиция, спросите Вы? А милиция в это время интенсивно пьет, чтобы затем прогуляться до супермаркета, и там устроить небольшой постал. Правда, в отличие от нормальных постальщиков, эти идут на дело совершенно неподготовленными, да и себя пристрелить не в силах.
Честно говоря, я с ними совершенно со всеми согласен, дали бы мне огнестрел, уже давно бы пошел зачищать улицы. Начинаю подумывать о службе в милиции. Внештатником. Только пушку дайте, а уж бухать и стрелять во всех попало, это я легко :)
А про гостей столицы тоже все понятно, житель столицы должен иметь лицензию на охотничье оружие, и в случае появления горных баранов в столь непривычном месте, немедленно прибивать себе новенькую трофейную баранью башку на стену. Ну или на столбах их на 101 километре выставлять, как это было принято у первобытных племен. Так бы бараны все же выбрали бы себе другой ареал. Притом очевидно, что ассоциировать себя с баранами сможет именно правильная категория живых существ, так что все будет очень правильно действовать.
Единственное, в чем сложность, это в том, чтобы отделить людей от животных законодательно, т.е. нужны какие то общие признаки, которыми обладают как горные бараны, так и майоры милиции, эти признаки должны быть закреплены в законах. Притом пока красную книгу можно даже не трогать, угрозы вымирания для этих видов нет.
воскресенье, 19 апреля 2009 г.
Религия
Всех действительно верующих прошу воспринимать мою ересь как бред заблудшего еретика, продолжайте блеять в своем просветленном стаде.
P.S. Тут решил что-то вроде опроса среди своих провести, кто из верующих в Бога верит также и в инопланетян (в том смысле, что они регулярно посещают всех подряд), и если да, то в какого Бога верят эти инопланетяне, если в того же, то сколько таких миров, ну и так далее...
вторник, 7 апреля 2009 г.
Работа с GnuCash. Часть 6. Получение котировок автоматически.
Я совершенно забыл рассказать о том, как организовал ежедневное получение котировок.
Собственно, все как всегда просто, если не требовать слишком много. Хотелось бы знать, какое число пользователей gnucash - пользователи Windows. А для пользователей unix-подобных систем вполне удобен способ с использованием cron.
Итак, для получения котировок для файлика $HOME/finans без запуска gui-клиента достаточно выполнить следующую команду:
gnucash --add-price-quotes $HOME/finans
Кроме этого, нам надо бы загрузить требуемые переменные окружения, так как мы используем наши собственные модули получения котировок (Quote::Sberbank). Есть еще одна занятная особенность, связанная с установкой текущей локали: GnuCash получает котировки для той валюты, которая связана с текущей локалью. Особенность состоит в том, что при запуске cron эта переменная может оказаться и пустой. В итоге оформляем все это в виде небольшого скрипта:
kilork@phoenix ~ $ cat gnucash_fetch.sh #!/bin/bash if [ -z "$PERL5LIB" ] then PERL5LIB=~/perl/lib64/perl5/site_perl/5.8.8 else PERL5LIB=$PERL5LIB:~/perl/lib64/perl5/site_perl/5.8.8 fi MANPATH=$MANPATH:~/perl/share/man export PERL5LIB MANPATH export LANG="ru_RU.UTF-8" export LC_ALL="ru_RU.UTF-8" FQ_LOAD_QUOTELET="-defaults Sberbank" gnucash --add-price-quotes $HOME/finans
Уже почти все, теперь вписываем вызов этого скрипта в crontab:
kilork@phoenix ~ $ crontab -l # DO NOT EDIT THIS FILE - edit the master and reinstall. # (/tmp/crontab.XXXXbHRdTU installed on Sat Jan 10 00:36:54 2009) # (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $) 55 23 * * * $HOME/gnucash_fetch.sh > $HOME/gnucash_fetch_log 2>&1
Таким образом, каждый день в 23:55 мы будем получать котировки и всегда будем видеть актуальное состояние наших активов без лишних телодвижений.
воскресенье, 5 апреля 2009 г.
Использование vpnc
Для меня все в основном повторяет шаги из gentoo wiki.
Смотрим на описание пакета и ставим его:
mexidol kilork # emerge -s vpnc
Searching...
[ Results for search key : vpnc ]
[ Applications found : 5 ]
...
* net-misc/vpnc
Latest version available: 0.5.3
Latest version installed: 0.5.3
Size of files: 96 kB
Homepage: http://www.unix-ag.uni-kl.de/~massar/vpnc/
Description: Free client for Cisco VPN routing software
License: GPL-2 BSD
...
mexidol kilork # emerge vpnc
В моем случае, от старого клиента cisco остался настроенный файлик pcf.
Основу для конфигурации получаем как раз из него:
mexidol kilork # pcf2vpnc /etc/opt/cisco-vpnclient/Profiles/hsbk.pcf /etc/vpnc/hsbk.conf
Создаем ссылку для запуска сервиса:
mexidol kilork # ln -s /etc/init.d/vpnc /etc/init.d/vpnc.hsbk
Все настроили, теперь можно запускать:
mexidol kilork # rc-config start vpnc.hsbk
Одна проблема, роуты плохи, мне надо чтобы через vpnc шло только для одной подсети. Чтобы это исправить, создаем файлик /etc/vpnc/scripts.d/hsbk-postup.sh:
#!/bin/sh
route del -net 0.0.0.0 netmask 0.0.0.0 dev tun0
route add -net 172.20.0.0 netmask 255.255.0.0 dev tun0
Некрасиво здесь, что прошито имя tun0. Но поскольку время поджимало, пока так.
пятница, 6 марта 2009 г.
emacs и highlight
Решить оказалось проще, чем сделать, но, вот она функция, и одновременно результат:
(defun kilork-highlight (start end syntax)
"kilork's highlight"
(interactive "r\nssyntax: \n")
(shell-command-on-region start end (concat "highlight --style=vim-dark -f -X --syntax=" syntax) 1))
Я писал текст прямо в emacs. Т.е. по окончании ввода команды я нажал C+x C+e. Затем перешел в начало функции, нажал С+Space. Снова в конец функции и M+x kilork-highlight. Итак, получили приглащение к вводу языка для раскраски, вводим lisp, ввод. Текст заменился на подкрашенный.
Все же, я добился желаемого, и буду и дальше осваивать emacs lisp. Есть ощущение, что я смогу найти много способов сделать свою жизнь более интересной благодаря удивительным свойствам этого языка в применении к этому редактору. Задание на доработку команды для возможности внесения правки в код и повторного переподкрашивания.
суббота, 21 февраля 2009 г.
GNU и Стивен Фрай
Для меня этот актер, это прежде всего Дживс из соответствующего сериала. Так же, как Хью Лаури - не доктор Хаус, а Вустер. Заглянув в википедию обнаружил несколько интересных вещей, есть еще совместные работы у этого актерского дуэта, ну и как водится, выяснилось, что Фрай - гомосексуалист и страдает биполярным расстройством. Да, со временем узнаешь много чего интересного, чего бы и знать совсем не хотелось. А вот другие работы постараюсь посмотреть, если найду.
пятница, 20 февраля 2009 г.
Статистика и скука
Если пересчитать в у.е. за коммит, получится очень круто, хотя - у.е. за строчку будет тоже немало. Ну а что вы хотели, класс то растет, скоро даже мой взгляд на репозиторий будет стоить как текущая месячная зарплата.
При этом работы на самом деле сделано очень много. Но чужими руками, или результаты не попадают в svn (например, старые клиенты, для которых все еще используется PVCS).
В последнее время убеждаюсь, как хорошо быть хорошим программистом, и как плохо быть хорошим программистом и руководить людьми, с целью получить программный продукт. Если бы я был плохим программистом, меня бы так не трясло от всей ереси, которую приходится фильтровать. Поэтому наверно, менеджеры не должны уметь программировать, не чтобы получать более качественный продукт в заданные сроки, а совсем с другой целью, чтобы в мире не прибавлялось вселенского зла. Люди, утверждающие, что управление людьми интересное занятие - не искрени до безобразия. Это все равно, что шахтеры будут утверждать, что их работа легка и полезна для здоровья. Ну или уборщица, с радостью стирающая блевотину в подъезде. Утешение находится в том, что хоть какие-то вещи можно делать интересными и на такой позиции. И их немало, так что скуку удается побороть.
пятница, 13 февраля 2009 г.
Работа с GnuCash. Часть 5. Finance::Quote. Придание модулю Sberbank полезных функций.
Для разнообразия решил писать этот пост в emacs. Несколько странно, поскольку делаю это уже где-то в 4-й раз, привыкаю к emacs, потом начинаешь пользоваться "классическим редактором", и emacs забывается. А зря. На eee есть правда существенный недостаток - справа нет ctrl, что делает пользование несколько осложненным. В четвертый раз вместо забоя пользуюсь backspace, что свидетельствует о наличии застарелых рудиментарных атавизмов, а ведь одна из главных идей emacs - отказ от лишних и утомительных движений, а тянуться к backspace между прочим очень утомительно. Все, хватит о emacs, вернемся к нашим баранчикам.
Чтобы сделать что-то полезное, зайдем на сайт Сбербанка на страничку с котировками ОМС. Текст странички сохраняем на диск. Файл с котировками в формате xls аналогично. Начнем разбираться с последним. Для работы с excel файлами используется модуль Spreadsheet::Read. Все тонкости работы с excel нам не нужны, достаточно с первой странички получить значение из ячейки с известным адресом. Делается это следующим образом:
#!/usr/bin/perl
use Spreadsheet::Read;
my $xls = ReadData("dm1002.xls");
print "$xls->[1]{'A1'}\n";Этот код выведет первую ячейку, с первой страницы.
Нам надо существенно больше. Найти котировки счетов и вытащить цену покупки/продажи. Но простота обращения с модулем облегчит нам задачу. Теперь надо разобраться со страничкой. Если взглянуть на реализации других модулей для Finance::Quote, то можно понять, что люди предпочитают HTML::TableExtract. Нам же только вытащить ссылку с первой строчкой, так что сойдут и более простые методы. Котировки в Сбербанке идут по месяцам. Страница для января 2009 года это:
http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=2009&month114=01
Получаемая страница содержит котировки с датами, идут они в обратном порядке. Пример HTML кода с котировками:
<li class="xls"><a href="/common/img/uploaded/c_list/sdmet/download/2009/01/dm0131.xls" target="_blank">31 января 2009 года</a><!-- --> (с 00 часов 00 мин.)</li>
Для отбора нам понадобится регулярное выражение. Наверно это самый сложный для понимания кусок, но к счастью, писать регулярные выражения существенно проще, чем читать. Итак, на основе предыдущего текста:
<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})Еще один кусок кода. Пора объединить все это в единое целое. В модуле Finance::Quote::Sberbank находим метод sberbank. Сейчас он имеет следующий вид:
sub sberbank {
my $quoter = shift;
my @stocks = @_;
}Для получения текста страничек нам понадобится user agent. К счастью, он есть у нас, итак, первая строка:
my $ua = $quoter->user_agent;
Теперь можно и запросить страничку.
my $year = 2009;
my $mon = 1;
my $url = "http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=${year}&month114=${mon}";
my $response = $ua->request(GET $url);Важно стараться сделать какую-никакую, но обработку ошибок, в случае с запросом странички, стоит проверить успешность операции. А если неуспешно, нам надо правильно выставить статусы ошибок. Статусы ошибок записываются в @stocks следующим образом:
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
Т.е. для каждого запрашиваемого инструмента ставим статус success = 0 и errormsg = HTTP failure. Какая-то обработка ошибок. Теперь надо разобрать содержимое на предмет интересующих нас ссылок:
my $link = "";
my $content = $response->content;
if($content =~ /<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})/g) {
$link = $1;
}Получили ссылку на файлик xls, теперь надо бы его получить, и наконец уже зачитать наши котировки. Единственное, надо бы определиться как мы их назовем. Например, вот так:
Золото SBRF.AU Серебро SBRF.AG Платина SBRF.PT Палладий SBRF.PD
Итак, ссылка найдена, и мы получаем котировки:
if($link) {
$url = "http://sbrf.ru/".$link;
$response = $ua->request(GET $url);
unless($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
$content = $response->content;Загружаем его как xls-файл:
my $xls = ReadData($content);
Теперь нам надо найти начало котировок ОМС. Это место начинается со строки, определяемой следующим регулярным выражением:
/\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/
Пробегаем примитивным поиском:
my $start = 1;
while($xls->[1]{"A$start"} !~ /\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/ && $start < 100) {
$start++;
}Определим хэш значений для поиска, в соответствии с определенными выше кодами для различных ОМС:
my %map = ( 'Золото' => 'SBRF.AU', 'Серебро' => 'SBRF.AG', 'Платина' => 'SBRF.PT', 'Палладий' => 'SBRF.PD' );
Начиная с этого момента нам осталось только пробежать по оставшимся строкам в файле, найти наши котировки и заполнить соответствующие части в info:
while($xls->[1]{"A$start"}) {
$start++;
my $name = $xls->[1]{"A$start"};
if($name) {
my $stock = $map{$name};
next unless($stock);
$info{$stock, "symbol"} = $stock;
$info{$stock, "name"} = $name;
$info{$stock, "currency"} = "RUB";
$info{$stock, "method"} = "sberbank";
$info{$stock, "bid"} = $xls->[1]{"E$start"};
$info{$stock, "ask"} = $xls->[1]{"D$start"};
$info{$stock, "last"} = $info{$stock, "bid"};
$quoter->store_date(\%info, $stock, {today => 1});
$info{$stock, "success"} = 1;
}
}Теперь осталось только сделать тесты. Здесь на помощь приходит модуль Test::More. Открываем t/Finance-Quote-Sberbank.t и пишем там такое:
use encoding 'utf8';
use Test::More;
plan tests => 5;
use_ok('Finance::Quote');
use_ok('Finance::Quote::Sberbank');
my $quoter = Finance::Quote->new("Sberbank");
ok(defined $quoter, "created");
my %info = $quoter->fetch("sberbank", "SBRF.PD");
ok(%info, "fetched");
ok($info{"SBRF.PD", "name"}, "palladium");
Запускаем тесты в терминале и если все получилось, то видим следующее:
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make test cp lib/Finance/Quote/Sberbank.pm blib/lib/Finance/Quote/Sberbank.pm PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/Finance-Quote-Sberbank....ok All tests successful. Files=1, Tests=5, 1 wallclock secs ( 1.05 cusr + 0.06 csys = 1.11 CPU)
Это хорошо, теперь можно смело делать make install и запускать gnucash с загрузкой нашего свежего модуля:
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make install Manifying blib/man3/Finance::Quote::Sberbank.3pm Installing /home/kilork/perl/share/perl/5.8.8/Finance/Quote/Sberbank.pm Installing /home/kilork/perl/man/man3/Finance::Quote::Sberbank.3pm Writing /home/kilork/perl/lib/perl/5.8.8/auto/Finance/Quote/Sberbank/.packlist Appending installation info to /home/kilork/perl/lib/perl/5.8.8/perllocal.pod kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ FQ_LOAD_QUOTELET="-defaults Sberbank" gnucash gnc.bin-Message: main: binreloc relocation support was disabled at configure time. Found Finance::Quote version 1.15
Заходим в редактор цен, жмем "Получить котировки", убеждаемся, что все получилось:

Рис 5.1. Получение котировок новым модулем Sberbank.
В заключение, полный текст модуля и скриншот набора текста в emacs:
package Finance::Quote::Sberbank;
use 5.008008;
use strict;
use warnings;
use encoding 'utf8';
use HTTP::Request::Common;
use Spreadsheet::Read;
require Exporter;
our @ISA = qw(Exporter);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use Finance::Quote::Sberbank ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
);
our $VERSION = '0.01';
# Preloaded methods go here.
sub methods { return ( sberbank => \&sberbank ); }
{
my @labels = qw/name last bid ask date isodate currency/;
sub labels { return ( sberbank => \@labels ); }
}
sub sberbank {
my $quoter = shift;
my @stocks = @_;
my %info;
my $ua = $quoter->user_agent;
my $year = 2009;
my $mon = 1;
my $url = "http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=${year}&month114=${mon}";
my $response = $ua->request(GET $url);
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
my $link = "";
my $content = $response->content;
if($content =~ /<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})/g) {
$link = $1;
}
if($link) {
$url = "http://sbrf.ru/".$link;
$response = $ua->request(GET $url);
unless($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
$content = $response->content;
my $xls = ReadData($content);
my $start = 1;
while($xls->[1]{"A$start"} !~ /\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/ && $start < 100) {
$start++;
}
my %map = (
'Золото' => 'SBRF.AU',
'Серебро' => 'SBRF.AG',
'Платина' => 'SBRF.PT',
'Палладий' => 'SBRF.PD'
);
while($xls->[1]{"A$start"}) {
$start++;
my $name = $xls->[1]{"A$start"};
if($name) {
my $stock = $map{$name};
next unless($stock);
$info{$stock, "symbol"} = $stock;
$info{$stock, "name"} = $name;
$info{$stock, "currency"} = "RUB";
$info{$stock, "method"} = "sberbank";
$info{$stock, "bid"} = $xls->[1]{"E$start"};
$info{$stock, "ask"} = $xls->[1]{"D$start"};
$info{$stock, "last"} = $info{$stock, "bid"};
$quoter->store_date(\%info, $stock, {today => 1});
$info{$stock, "success"} = 1;
}
}
}
return wantarray() ? %info : \%info;
}
1;
__END__
Рис 5.2. Набор этого поста в emacs.
Очередная часть могучего труда готова. Удачи и успехов в освоении gnucash!
среда, 4 февраля 2009 г.
Reading trends
Удивило то, что за оверлеем экспериментального гнома кроме меня следит только один человек, на искуственный интеллект подписалось 6 (оно и не удивительно, один спам). Да и вообще, за пакетами в генту через гугл.ридер люди не следят.
Общий вывод - из всего, что меня интересует, стоящим является около 1/10 процента. Меньше десятой части процента. Все остальное - шлак. А остальное меня даже не интересует. Ну или я еще не нашел. Мир ужасно скучный.
пятница, 30 января 2009 г.
Работа с GnuCash. Часть 4. Finance::Quote. Разработка собственных модулей получения котировок.
В предыдущей части мы вплотную подошли к необходимости автоматизировать процесс получения котировок. И gnucash предоставляет нам для этого отлично средство - Finance::Quote. Finance::Quote - это perl-модуль, и этим очень многое сказано. В комплекте поставки версии 0.15 множество разнообразных подмодулей. Но нужных нам, естественно, все равно нет. Написаны модули на perl. Множество уже в страхе будут бежать без оглядки, так как perl ассоциируется у всех с чем-то сложным и совершенно непонятным. Скажу, так оно и есть. Но в данном случае, модули очень просто написаны, откомментированы. Я убежден, что для того, чтобы написать собственный модуль под Finance::Quote нужны минимальные познания в программировании, не требуется глубокое знание perl, и нужно только желание достичь цели. В состав Finance::Quote входит документация о разработке собственных модулей получения котировок. Используя это руководство мы сделаем простой модуль для получения котировок ОМС Сбербанка. Процесс создания разобьем на шаги. Начнем с того, что у нашего пользователя нет опыта работы с perl. Прекрасно, тогда переходим к созданию нашего модуля для новичков в perl.
Создание модуля.
Мне кажется, очень много для популярности того или иного языка делают вовсе не его качества именно как языка, а какие-то маленькие удобные фенечки, или большие удобные фенечки. В perl главная большая удобная фенечка - это CPAN, гигантский архив готовых модулей, которые ставятся через единый интерфейс, с зависимостями, тестами, и прочим. Очень большая удобная фенечка. Есть фенечки поменьше. Например, утилитки для генерации каркаса модуля. Открываем терминал, идем в папочку проектов (у себя назову ее ~/Desktop/test):
kilork@pantogan:~$ mkdir Desktop/test kilork@pantogan:~$ cd Desktop/test kilork@pantogan:~/Desktop/test$
Надо определиться с названием. Я обычно весьма много времени трачу на придумывание названия. Как говорил небезизвестный персонаж, как вы яхту назовете, так она и поплывет. Поэтому название надо очень тщательно выбирать. Наш модуль будет жить в пространстве имен Finance::Quote и относится к Сбербанку, назовем его Finance::Quote::Sberbank. Итак, воспользуемся командой h2xs:
kilork@pantogan:~/Desktop/test$ h2xs -AX -n Finance::Quote::Sberbank Defaulting to backwards compatibility with perl 5.8.8 If you intend this module to be compatible with earlier perl versions, please specify a minimum perl version with the -b option. Writing Finance-Quote-Sberbank/lib/Finance/Quote/Sberbank.pm Writing Finance-Quote-Sberbank/Makefile.PL Writing Finance-Quote-Sberbank/README Writing Finance-Quote-Sberbank/t/Finance-Quote-Sberbank.t Writing Finance-Quote-Sberbank/Changes Writing Finance-Quote-Sberbank/MANIFEST
Как видно, одна маленькая команда насоздавала нам множество файликов. Один, очевидно, сам каркас модуля. Затем идет генератор Makefile'ов. Файлик с README, файлик тестов. Лог изменений Changes. И MANIFEST. Чудеса, да и только, почти вся работа сделана за нас этой маленькой чудесной командой. Главное - не давать никому знать об этом.
Сгенерируем Makefile. Укажем дополнительный параметр, говорящий о нашем желании ставить модули в локальную директорию пользователя.
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ perl Makefile.PL PREFIX=~/perl Checking if your kit is complete... Looks good Writing Makefile for Finance::Quote::Sberbank
Отлично, теперь мы можем собирать, тестировать, инсталлировать, и собирать дистрибутив следующими простыми командами:
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make # собираем cp lib/Finance/Quote/Sberbank.pm blib/lib/Finance/Quote/Sberbank.pm Manifying blib/man3/Finance::Quote::Sberbank.3pm
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make test # тестируем PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/Finance-Quote-Sberbank....ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.08 cusr + 0.01 csys = 0.09 CPU)
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make install # инсталлируем Installing /home/kilork/perl/share/perl/5.8.8/Finance/Quote/Sberbank.pm Installing /home/kilork/perl/man/man3/Finance::Quote::Sberbank.3pm Writing /home/kilork/perl/lib/perl/5.8.8/auto/Finance/Quote/Sberbank/.packlist Appending installation info to /home/kilork/perl/lib/perl/5.8.8/perllocal.pod
kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make dist # собираем дистрибутив rm -rf Finance-Quote-Sberbank-0.01 /usr/bin/perl "-MExtUtils::Manifest=manicopy,maniread" \ -e "manicopy(maniread(),'Finance-Quote-Sberbank-0.01', 'best');" mkdir Finance-Quote-Sberbank-0.01 mkdir Finance-Quote-Sberbank-0.01/lib mkdir Finance-Quote-Sberbank-0.01/lib/Finance mkdir Finance-Quote-Sberbank-0.01/lib/Finance/Quote mkdir Finance-Quote-Sberbank-0.01/t Generating META.yml tar cvf Finance-Quote-Sberbank-0.01.tar Finance-Quote-Sberbank-0.01 Finance-Quote-Sberbank-0.01/ Finance-Quote-Sberbank-0.01/MANIFEST Finance-Quote-Sberbank-0.01/lib/ Finance-Quote-Sberbank-0.01/lib/Finance/ Finance-Quote-Sberbank-0.01/lib/Finance/Quote/ Finance-Quote-Sberbank-0.01/lib/Finance/Quote/Sberbank.pm Finance-Quote-Sberbank-0.01/t/ Finance-Quote-Sberbank-0.01/t/Finance-Quote-Sberbank.t Finance-Quote-Sberbank-0.01/Changes Finance-Quote-Sberbank-0.01/README Finance-Quote-Sberbank-0.01/Makefile.PL Finance-Quote-Sberbank-0.01/META.yml rm -rf Finance-Quote-Sberbank-0.01 gzip --best Finance-Quote-Sberbank-0.01.tar
Команд немного, все очень просто, на текущем этапе нам понадобятся команды make и make test. Затем make install, если надо будет использовать модуль из gnucash или других программ, и наконец - make dist, если нам вдруг захочется все это дело выложить на CPAN (мне захотелось, можно поискать Sberbank на http://search.cpan.org).
Каркас модуля мы создали, подготовили среду к сборке и тестированию, приступаем к реализации модуля для Finance::Quote.
Реализация модуля для Finance::Quote.
Открываем Sberbank.pm в нашем любимом текстовом редакторе. Текст снабжен неплохими комментариями, так что понятно назначение той или иной секции в сгенерированном файле. Нам надо удалить все лишнее, и реализовать методы для Finance::Quote. Самое забавное, что реализуя модуль под Finance::Quote нам вовсе не надо что-то знать о Finance::Quote, не надо даже упоминать ее в нашем модуле. Достаточно поддержать нужный интерфейс и подложить модуль в правильное место.
Находим строку "# Preloaded methods go here.". Отсюда мы и начнем определять наши методы. Первый метод, который нам понадобится, это метод methods. Этот метод будет вызван Finance::Quote для получения списка нестандартных методов, определяемых нашим модулем. Это как раз та строчка, которую мы увидим, когда подключим наш модуль в gnucash. Кроме этого нам понадобится метод, который вернет список поддерживаемых нами атрибутов labels, ну и собственно, главный метод, в котором мы и будем лазить на сайт Sberbank'а, и забивать значения атрибутов. Пока определим только стандартные методы, и пустышку для главного метода. Вот, что у меня получилось:
sub methods { return ( sberbank => \&sberbank ); }
{
my @labels = qw/name last bid ask date isodate currency/;
sub labels { return ( sberbank => \@labels ); }
}
sub sberbank {
my $quoter = shift;
my @stocks = @_;
}
Получился метод sberbank с двумя параметрами, загадочный $quoter, и не менее загадочные @stocks. Метод ничего не возвращает, а вообще говоря - должен. Тем не менее, это уже вполне минимально подходящий для использования модуль Finance::Quote.
Делаем make, make test, make install. Запускаем gnucash командой:
kilork@pantogan:~/Desktop$ FQ_LOAD_QUOTELET="-defaults Sberbank" gnucash
У меня открылся наш последний пример из 3-й части руководства. Есть золото, но котировки надо вбивать руками. Теперь мы попробуем настроить получение котировок с помощью нашего новомодного модуля. Пустышки правда пока.
Идем в редактор ценных бумаг, находим там наше золото, выбираем "Правка", на открывающеся форме настройки ставим галочку "Получить онлайн котировки", устанавливаем радио-переключатель в положение "Неизвестный", в выпадающем списке находим "sberbank" и выбираем. Жмем "Ок".

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

Рис 4.2. Получение котировок с новым "пустым" модулем приводит к ошибке.
Уже чего-то мы достигли, наш модуль виден gnucash, и выдает даже какую-то ошибку при попытке запроса. В следующей части мы постараемся научить его делать более полезные вещи.