shoorick: (Рыжий)
Учёт домашних доходов с расходами — сплошное расстройство. Теперь вот вместо того, чтоб спать, пытаюсь вспомнить, что же умею делать за деньги, потому что на одну зарплату прокормить семью вообще нереально.

Могу:

  • Программировать на Перле — как древние CGI-приложения, так и современные, с использованием фреймворков Mojolicious, Dancer, Catalyst.

  • Программировать на PHP: в основном допиливать существующие приложения, а не писать с нуля что-то большое.

  • Настраивать CMS Drupal и WordPress, а также дорабатывать их темы оформления.

  • Настраивать и дорабатывать Open Journal Systems, включая реализацию многоязычности имён — делал это в OJS 2.4.2, 2.4.7.1, 2.4.8.1, думаю, и в Open Conference Systems смогу реализовать.

  • Кроссбраузерно верстать веб-страницы.

  • Немножко программировать на Руби (в том числе, с использованием Ruby on Rails) — наверное, на юниорском уровне.

  • Немножко программировать на ЯваСкрипте — как голый JavaScript, так и с jQuery.

  • Постоянно внушать коллегам необходимость использования багтрекера и системы контроля версий.

  • (хоть и не считаю это основными профессиональными навыками) фотографировать, петь, аккомпанировать на шестиструнной гитаре, водить легковой автомобиль, быть Дедом Морозом, набирать ноты в MuseScore и LilyPond — медленно, но красиво.


1000 рублей

Хочу от 15 USD / 1 kRUB в час.




Statt zu schlafen (нем.) — вместо того, чтобы спать

http://shoorick.ru/2016/10/18/statt-zu-schlafen/
shoorick: (Рыжий)
В перловых приложениях, написанных с импользованием фреймворка Mojolicious, лежащие в каталоге t тесты запустить достаточно просто — одна из доступных «из коробки» команд приложения — как раз test, которая без дополнительных параметров запускает все имеющиеся тесты:
$ ./app-name.pl test
[Fri Sep  9 13:21:06 2016] [debug] Some message
Running tests from "/path/to/t".
/path/to/t/1868-prev-next.t .. ok     
/path/to/t/1869-design.t ..... ok     
...
All tests successful.
Files=8, Tests=171,  5 wallclock secs ( 0.08 usr  0.01 sys +  3.76 cusr  0.28 csys =  4.13 CPU)
Result: PASS

Для упрощения процесса я обычно создаю Makefile, в котором пишу
SCRIPT=info.pl
APP=perl $(SCRIPT)

test: $(SCRIPT)
        $(APP) test

и всё, в общем-то, прекрасно работает — тесты запускаются привычной командой make test.

Недавно поставил себе свежую ActiveState Komodo IDE и, пока испытательный срок не кончился, пробую всякие её возможности, среди которых есть и тестирование. Выяснилось, что Komodo пытается найти Makefile и запустить тесты через него, но понять результаты оно не может и выводит перед каждой строкой сообщение **** Unrecognized input

Тестирование в Komodo IDE не может распознать вывод

Можно запускать тесты по-другому — командой prove — она выдаёт похожий результат:
$ prove -l
t/1868-prev-next.t .. ok     
t/1869-design.t ..... ok     
...
All tests successful.
Files=8, Tests=171,  5 wallclock secs ( 0.07 usr  0.00 sys +  3.86 cusr  0.23 csys =  4.16 CPU)
Result: PASS

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

Успешное тестирование в Komodo IDE

http://shoorick.ru/2016/09/09/testing-with-komodo-ide/
shoorick: (Рыжий)
Вроде, недавно только поменял процесс подпиливания ильменского сайта — там теперь TDD — а уже каким-то образом 220 тестов написал. Хотя файлов, конечно, сильно меньше :-)
All tests successful.
Files=11, Tests=220, 14 wallclock secs ( 0.12 usr  0.02 sys +  9.66 cusr  0.64 csys = 10.44 CPU)
Result: PASS

Хотя тесты сразу надо было начинать писать, с момента начала переписывания тринадцать месяцев назад.

http://shoorick.ru/2016/06/24/involve/
shoorick: (Рыжий)
Обнаружил в попавшемся на глаза чужом скрипте чтение переданных через командную строку параметров без упоминания массива @ARGV. Проверил — работает:
#!/usr/bin/perl

my $shifted = shift or die 'Not shifted';

print "Shifted value is $shifted\n";

Выдаёт
$ ./shift.pl
Not shifted at ./shift.pl line 3.
$ ./shift.pl ARGV?!
Shifted value is ARGV?!

Век живи — век учись.

http://shoorick.ru/2016/02/20/without-argv/
shoorick: (Рыжий)
Попробовал в яваскриптовый файл добавить shebang, чтоб проще было запускать:
#!/usr/bin/node
console.log('Hallo, Welt!');

Прекрасно работает. Node.js на shebang не ругается.

http://shoorick.ru/2015/09/11/shebang/
shoorick: (Рыжий)
Функция selectall_arrayref перлового модуля DBI хороша для тех, кому лень писать:
This utility method combines "prepare", "execute" and "fetchall_arrayref" into a single call. It returns a reference to an array containing a reference to an array (or hash, see below) for each row of data fetched.

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

Реальный пример: скрипт, извлекающий тайлы из пакета, созданного Тайлмиллом, пытался читать данные как раз функцией selectall_arrayref. Зная, что применяется запрос
SELECT * FROM tiles

и что представление tiles содержит, помимо прочего, содержимое тайлов, занимающее места больше всего остального, нетрудно догадаться, что попытка выполнения запроса потребует выделения памяти в объёме, сопоставимом с размером файла, в котором сидит база (пакет с тайлами — это база SQLite).

Набор тайлов для территории размером 600×400 км в средних широтах — например, с Челябинском по центру, Ашой на западе, Карталами на юге и Тюменью на северо-востоке — займёт больше гигабайта для набора масштабов не больше шестнадцатого. На практике так и получилось: скрипт отжирал больше гигабайта памяти и всё никак не мог приступить к полезной части, пытаясь отожрать ещё. Если же увеличивать масштаб, затраты вырастут ещё сильнее: добавим семнадцатый зум масштаб — понадобятся ещё три-четыре гигабайта, Добавим восемнадцатый, которого хватит даже для любопытных исследователей карт — ещё на десять-двадцать объём вырастет. Если будем сохранять тайлы с глубиной цвета 24 бита, а не восемь — ещё больше места израсходуем. Получается, что средних размеров российская область может занять своими тайлами десятки гигабайт. И скрипт бы безуспешно пытался эти десятки получить.

Переписал:
-my $tiles = $dbh->selectall_arrayref(
-    'SELECT * FROM tiles',
-    { Slice => {} },
-);
-
-foreach my $tile ( @$tiles ) {

+my $sth = $dbh->prepare('SELECT * FROM tiles');
+   $sth->execute;
+
+while ( my $tile = $sth->fetchrow_hashref ) {

и всё наладилось: скрипт перестал жрать память (ему хватило десяти мегабайт) и ждать её выделения — сразу работает.

Вывод: не всегда надо экономить рабочее время программиста — иногда надо и о машинном времени задумываться.

http://shoorick.ru/2015/08/26/more-code/
shoorick: (Рыжий)
Давно хотел улучшить ильменский сайт, да всё руки не доходили. Уж подумывал и переписать совсем. Что только не пробовал — и тяжёлый перловый фреймворк Catalyst, и написанные на PHP системы управления сайтами — Друпал да ВордПресс. И всё никак не получалось дойти за какого-то осмысленного результата. В итоге всё свелось к переписыванию на Mojolicious::Lite — это всяко веселее, чем набор древних CGI-скриптов.

Начал в мае 2011 года — бросил. Подобрал в мае тринадцатого — снова бросил. Пришёл май пятнадцатого — снова взялся и как-то всё-таки дошёл до завершения первого этапа: воссоздал на моджо всю функциональность прошлого сайта, который был запущен ещё в 2003 году. Ну и перекрасил попутно. Свежий сайт да ещё и на новом железе с другими ОС и веб-сервером работает гораздо шустрее старого: отдаёт 50 страниц в секунду, а не две. Кстати, Друпал с ВордПрессом (правда, без нормального кэширования) работают ещё медленнее, чем старый сайт.

Новый сайт лежит на test.ilmeny.org, в выходные потестирую, в понедельник, наверное, запущу его вместо старого.

test.ilmeny.org

Если увидите на свежем сайте что-то неправильное — сообщите, пожалуйста.

P. S. Попутно выяснил: боевой режим в Mojolicious называется не production, как я почему-то думал, а deployment.

upd/14:40: мне тут товарищ подсказывает, что в Mojolicious всё-таки production, а deployment — это значение переменной окружения PLACK_ENV, которую выставляет Starman.

http://shoorick.ru/2015/06/06/test-ilmeny-org/
shoorick: (Рыжий)
Несколько лет назад написал move-images.pl — скрипт, который сливал кадры с фотоаппарата, раскладывая их по папкам в зависимости от даты съёмки. Кажется, digiKam умел делать что-то подобное, но мне он не нравился своей неповоротливостью — вот и пришлось свою программу написать. Время от времени приходилось менять какие-нибудь параметры — и тогда я лез в исходный код, потому что лень было прикрутить разбор параметров командной строки, хотя в этом ничего сложного: всё украдено до нас есть модуль. Сегодня собрался и наконец-то прикрутил. На тестовом наборе в десять файлов — работает. Завтра проверю на куче из двухсот тысяч файлов — не руками же их сортировать!

http://shoorick.ru/2015/04/07/move-images-cli/
shoorick: (В бабочке)
Вчера, чтоб отдохнуть от конфигурирования редмайна, решил набрать внезапно свалившуюся на нас партитуру — хору надо выучить к региональному туру Всероссийского хорового фестиваля песню «Смело мы в бой пойдём за власть Советов» «Мы смело в бой пойдём», написанную лет сто назад. Те ноты, что выложены на сайте Свердловского областного методического центра по художественному образованию — позор какой-то: криво отсканированные растровые картинки не очень высокого разрешения. Из спортивного интереса решил набирать сразу исходный текст, не пользуясь музыкальными редакторами MuseScore или Denemo. Ну и скорость набора засёк — из того же спортивного интереса.

Итоги:

  • Мои ноты гораздо лучше выглядят, чем оригинал и легче читаются.

  • На набор одного листа, содержащего четыре вокальные партии с текстом, но без партии фортепиано вместе с вычиткой, прослушиванием и подглядыванием в справочные материалы ушло 75 минут. То есть, скорость набора составляет всего-то 0,8 листа в час. С аккомпанементом получается в разы медленнее. Как люди умудряются набирать в Лилипонде до трёх с половиной листов в час — не знаю, мне до этого далеко.

  • Развивать свою скорость лилипондового набора нет смысла — нецелесообразно экономически. Лучше уж время на программирование потратить — это более щедро оплачивается.



http://shoorick.ru/2015/01/23/speedup-lilypond-typesetting/
shoorick: (Рыжий)
Про перловый веб-фреймворк Catalyst когда-то говорили, что он за собой тянет чуть ли не половину CPAN :-)

Решил я в дополнение к Каталисту и Моджо писать и на Дансере — так сложилось. На perldancer.org пишут:
Key features:
...
Few dependencies - Dancer depends on as few CPAN modules as possible making it easy to install.

Ставлю Dancer — и где эти самые few depencies? Утром модули ставил, сейчас — ставлю, а они всё не кончаются и не кончаются...

http://shoorick.ru/2015/01/23/dancer-depencies/
shoorick: (Рыжий)
Предварительные финансовые итоги уходящего года неутешительны: мало того, что от кредиторской задолженности не удалось избавиться — она многократно выросла, превысив месячный доход. Учёт расходов не помог их уменьшить — не на чем экономить. Значит, надо больше зарабатывать. Для начала попробуем взять дополнительную работу на несколько часов в день, не бросая работу основную: на ней никак не выйдет передать дела за две недели — слишком много накопилось за пятнадцать лет.

Итак,
ищу работу программистом, желательно на перле, удалённо либо в Челябинске, до 20 часов в неделю, от 15 долларов в час.
Резюме — http://shoorick.ru/resume/alexander_sapozhnikov.html
shoorick: (Рыжий)
Чисто перловые HTTP-клиенты, включая широко известный модуль LWP — не самые быстрые, что вполне логично. Гораздо быстрее работают, например, те модули, что используют cURL. В одном из рабочих проектов понадобилось ускорить чтение из сети — это оказалось узким местом. Я проверил — действительно, cURL работает шустрее, чем LWP, при этом к cURL в перле есть несколько интерфейсов. Результаты моего замера вышли такими:
                    Rate     LWP WWW::Curl::Simple   Net::Curl::Easy
LWP                474/s      --              -38%              -88%
WWW::Curl::Simple  760/s     60%                --              -82%
Net::Curl::Easy   4115/s    768%              441%                --

(под LWP здесь понимается LWP::UserAgent).

Шустрый LWP::Curl выбыл из соревнования, потому что я не нашёл, как в нём добавить нужный заголовок к HTTP-запросу. Был проверен ещё и WWW::Curl::Easy — он показал ту же скорость, что и Net::Curl::Easy, вывалив при этом кучу предупреждений — так что он тоже выбыл из забега.

Однако при проведении замера я столкнулся со странным поведением Net::Curl::Easy — при выполнении метода perform на экран (точнее, в STDOUT) иногда выводились полученные данные. Выяснилось, что правильный способ запуска описан в руководстве не на Net::Curl::Easy, а на WWW::Curl — надо не только выполнить запрос, но и указать до выполнения запроса, куда писать полученное содержимое:
# A filehandle, reference to a scalar or reference to a typeglob can be used here.
my $response_body;
$curl->setopt(CURLOPT_WRITEDATA,\$response_body);

В Net::Curl::Easy это тоже сработало.
http://shoorick.ru/2014/11/27/clean-net-curl-easy/
shoorick: (Рыжий)
Для подсчёта количества байт, символов, слов и строк в юникосоподобных операционных системах предназначена программа wc. Иногда хочется запускать её, например, раз в секунду, чтоб следить за выполнением какого-нибудь долгого процесса.

Сделал по-быстрому скрипт, который просто вызывает wc и выводит его результат, пока пользователю не надоест и он не нажмёт Ctrl+C
#!/usr/bin/perl

print STDERR "Press ^C to exit\n";
my $cmd_line = 'wc ' . join ' ', @ARGV;
my $out;
while (1) 
    $out = `$cmd_line`;
    chomp $out;
    print "\cM$out";
    sleep 1;

Запустить можно, например, так:
wcloop -l some-big-file.txt

http://shoorick.ru/2014/11/18/watch-for-filesize-in-infinite-loop/


upd/15:48: товарищ подсказывает:
watch -n 1 wc -l?
И верно ведь посдказывает!
shoorick: (Default)
Чтоб не вспоминать кажыдй раз команды перлового отладчика, сделал шпаргалку — скопировал на лист размера A4 текст, выводимый отладчиком по команде h, и добавил верблюда:

Perl Debugger Cheatsheet

Большой файл доступен в форматах PDF и PNG (300 dpi).
shoorick: (Рыжий)
Отлаживаю скрипт, получаю развесистую структуру данных, чей дамп, сделанный модулем Data::Dumper, занимает почти 9000 строк. Вывел дамп на экран, потянулся к мышке, чтоб скопировать и засунуть в файл, да вовремя остановился — есть же простой метод: достаточно написать в отладчике всего пару строк:
use File::Slurp
write_file 'big-structure.pl', Dumper $structure

P. S. А если вместо Data::Dumper использовать Data::Dumper::Perltidy, результат получается более симпатичным.

update/07.04.2014: Иногда, когда содержимое в UTF-8, лучше писать так:
write_file 'big.txt', {binmode => ':utf8'},  $unicode-data
Впрочем, к данным, выводимым через Data::Dumper[::Perltidy], это не относится: там символы, не попадающие в ASCII, представлены как \x{HHH}, где HHH — шестнадцатеричный код символа.
shoorick: (Рыжий)
Интересный способ округления увидел сейчас в http://3site.eu/examples/snow/snow.js — для этого там используется сдвиг:
style.left = ((random() * offsetWidth) >> 0) + "px";

Проверил — так и есть:
5 / 2      == 2.5
5 / 2 >> 0 == 2

Но в чём смысл? Сэкономить буквы, отказавшись от Math.floor?

Не zip

Dec. 4th, 2013 10:24 am
shoorick: (Рыжий)
На сайте prostopleer.com есть, вроде бы, возможность скачать целиком музыкальный альбом. Но потом — сюрприз! — скачавшийся zip-файл вовсе не является ZIP-архивом: ни unzip, ни 7z не желают его открывать. Лишь всемогущий mplayer спокойно играет одну пьесу за другой.

Анализ содержимого показал: в начале архива идёт стандартная сигнатура PK♥♦ (50 4B 03 04), но за ней — имена файлов вместе с мусором и сами файлы, без какого-либо сжатия. Достать музыку из такого файла при наличии перла — легко!
#!/usr/bin/perl -0777 -n

=head1 DESCRIPTION

Split big pseudo zip-archive from prostopleer.com into small mp3 files.

=head1 USAGE

 ./split.pl big-pseudo.zip

=head1 SEE ALSO

L<< https://gist.github.com/shoorick/7785185 >>

=head1 AUTHOR

Alexander Sapozhnikov
L<< http://shoorick.ru/ >>
Lshoorick@cpan.orgE

=cut

binmode(STDIN);

my $divisor = "ID3\x04\x00";
my @chunks = split $divisor;
shift @chunks;

my $i = 1;
foreach my $chunk ( @chunks ) 
    open(my $fh, '<', sprintf('%02d.mp3', $i++))
        or die "cannot open for writing: $!";
    print $fh $divisor, $chunk;
    close $fh;

Оно же — на гитхабе: https://gist.github.com/shoorick/7785185

upd/11.12.13:: Спасибо Игорю Белому [livejournal.com profile] bujhm за наводку — я неделю подкинутую им музыку слушаю, до сих пор нравится и работать не мешает.
shoorick: (Default)
В 2013 году в CMS WordPress появилась новая тема — Twenty Thirteen, которая достаточно хороша: написана с использованием HTML5, корректно ведёт себя на разных размерах экрана и не страдает обилием ненужных финтифлюшек. Но не обошлось и без ложки дёгтя: в теме используются взятые с Google Fonts шрифты Bitter и Source Sans Pro — они весьма хороши, но в них нет кириллицы. Понятно, что можно, создав дочернюю тему, поправить используемые в ней стилевые правила, указав нужные шрифты, однако хочется сделать всё правильно: и загрузить нужный шрифт, и избежать загрузки ненужного.

Поиск не дал готового решения (что, вообще-то, странно) — пришлось изобретать самому, руководствуясь тем, что нашлось. Итак, для замены шрифтов надо:

  1. Создать дочернюю тему;

  2. В стилевом файле style.css дочерней темы указать нужные шрифты;

  3. Отключить загрузку ненужных и добавить загрузку нужных шрифтов, добавив в файл functions.php дочерней темы такой код:


if ( ! function_exists('child_fonts_url')) {
    function child_fonts_url() {

        $fonts_url = '';

        $open_sans = _x( 'on', 'Open Sans font: on or off', 'child' );
        $open_sans_condensed
           = _x( 'on', 'Open Sans Condensed font: on or off', 'child' );

        if ( 'off' !== $open_sans || 'off' !== $open_sans_condensed ) {
            $font_families = array();

            if ( 'off' !== $open_sans )
                $font_families[] = 'Open Sans:400italic,400,700';

            if ( 'off' !== $open_sans_condensed )
                $font_families[] = 'Open Sans Condensed:300';

            $query_args = array(
                'family' => urlencode( implode( '|', $font_families ) ),
                'subset' => urlencode( 'latin,cyrillic' ),
            );
            $fonts_url = add_query_arg(
                $query_args,
                '//fonts.googleapis.com/css'
            );
        }

        return $fonts_url;
    } // function child_fonts_url
}

function disable_twentythirteen_fonts() {
    wp_deregister_style('twentythirteen-fonts');
}

add_action( 'wp_enqueue_scripts', 'disable_twentythirteen_fonts', 11 );
wp_enqueue_style( 'child-fonts', child_fonts_url() );

Здесь child — имя дочерней темы. Функция child_fonts_url списана с twentythirteen_fonts_url из темы Twenty Thirteen — изменены лишь используемые шрифты (имена шрифтов и переменных, список начертаний и наборов символов) да название функции.
shoorick: (Рыжий)
Итак, наступила пятница, тринадцатое сентября, двести пятьдесят шестой день года. Пора отмечать!
С ходу вспоминаются два праздника: День программиста и День рождения Челябинска.
Дважды ура!

А ещё, если верить википедии, тридцать лет назад создали «Несчастный случай» познакомились студенты МГУ Валдис Пельш и Алексей Кортнев. «НС» живёт в твиттере @nsmusicband и уже принимает поздравления.
shoorick: (Рыжий)
Придумал способ, позволяющий вдвое уменьшить число пробелов в начале строки в текстовом файле:
perl -pi~ -e 's/^( +)\1(?=\S)/$1/' filename.ext

Profile

shoorick: (Default)
shoorick

December 2016

S M T W T F S
    1 23
45678910
11121314151617
18 19 2021222324
25262728293031

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 26th, 2017 01:46 am
Powered by Dreamwidth Studios