Як в Linux завантажувати аудіо з списків відтворення vk.com?

Зазвичай я не використовував ніяких лишніх інструментів для того аби качати аудіо з вконтакту, бо всі інструменти вже є в лінуксі, досить лише зберегти плейліст в файл audio.html, та виконати:

wget -c `grep https://.*mp3 -o audio.html`

Але тоді каталог заповнюється файлами виду 7b6e2b1e3f81.mp3 і хоча й більшість mp3 плеєрів читають їх теги і нормально керують колекцією музики, все одно важко наприклад чистити каталоги від зайвих, чи копіювати потрібну музику за маскою. Тому я вирішив написати трішки кращий фільтр ніж grep.

Для його використання потрібно вже дві команди:

wget -O list.py https://bunykprogs.googlecode.com/hg/vk_downloader.py
python3 list.py audio.html | sh

Але результат повинен виправдати зусилля. Перший рядочок – “інсталяція” додаткового скрипта, другий – його виконання. Щоб все працювало, ви повинні мати wget, python3 та lxml для python3.


Працює скрипт просто роздруковуючи команди скачування в термінал. Щоб їх виконати, не обов’язково перенаправляти вивід в файл, можна зразу в sh.

Ви можете запитати, а чому я не зробив так аби скрипт сам скачував аудіо, а не генерував код на sh який це робить? Та тому, що з цим я можу зробити наприклад таке:

python3 list.py audio.html | grep "German" | sh # скачати все з словом German в назві файлу
python3 list.py audio.html | wc -l # показати довжину списку.

Хоч одна програма для викачування музики з вконтакту так вміє? От, от.

Код виглядає ось так:

import sys

from lxml import html
from lxml import etree

def clear_param(txt):
    return txt.strip().replace('"', r'\"')

def parse(fl):
    tree = html.parse(fl)
    elements = tree.xpath('//div[@id="initial_list"]//input')
    urls = []
    for el in elements:
        urls.append(el.attrib['value'].split(',')[0])

    elements = tree.xpath('//div[@id="initial_list"]//div[@class="title_wrap fl_l"]')
    for el, url in zip(elements, urls):
        performer = clear_param(el.xpath('b/a/text()')[0])
        title = clear_param(el.xpath('span[@class="title"]//text()')[0])
        print('wget -c -O "{performer} - {title}.mp3" "{url}"'.format(
            url=url, performer=performer, title=title
        ))

def main():
    if len(sys.argv) > 1:
        parse(sys.argv[1])
    else:
        print('Pass file name', file=sys.stderr)


if __name__=='__main__':
    main()

Filed under: Інструменти, Кодерство, Павутина Tagged: музика, linux, Python

Дівчина-салат

Дівчина-салат – це робоча назва прототипу підручника німецької який я на тих вихідних створив, але все не мав нагоди про це написати.

Власне якби я був голлівудським продюсером, я б вже давно на додачу до людини-павука, людини-кажана, жінки-кішки і решти людей-гібридів зняв би “дівчину-салат”. Це історія про дівчинку яка народилась від того що її мама з’їла генетично-модифіковану рослину (а які ви думаєте ще можуть рости на городі у відьми?) з виду Valerianella locusta, також відому як Рапунцель. А вони зняли якусь “Заплутану історію”, яку я не дивився, зате, прочитав оригінал братів Грімм. Казка містить глибоку мораль, суть якої в тому, що коли дітей недостатньо виховали, то навіть якщо їх замкнути в вежі, це не допоможе.

Казочку я читав мовою оригіналу, і це перший текст німецькою який я осилив. Осилив я його активно заглядаючи в словник, і виглядало це ось так:

Рапунцель з нотатками

Рапунцель з нотатками

І під час того я постійно думав, що це взагалі мій улюблений спосіб вчитись, тому що це не нудно і швидко набирається словниковий запас. Але чи вчусь я, поки гортаю сторінки словника? Здається єдине чого я вчусь – швидше відкривати потрібну сторінку і швидше знаходити на ній слово. На запам’ятовування самого слова йде менше часу і це напевне не добре.

Тому я подумав, що класно було б мати книжки, де словник знаходиться прямо на тій сторінці яку я читаю. Як в Gerda malaperis! (коли з’явиться українська стаття, нагадайте замінити посилання, не соромтесь). Gerda malaperis звісно виняткова книжка, бо написана саме з навчальною метою і на жаль аналогічних я більше не знаю.

Ще я подумав що подібним чином можна адаптувати звичайні твори. І саме для цієї мети мають чудово підходити зноски які вміє робити LaTeX. Їх було так багато, що довелось застосувати деякі нестандартні модулі аби спростити нумерацію. А ще довелось застосувати XeTeX, він знає про Unicode-шрифти. Бо в звичайному TeX Live отримати одночасно німецькі умляути й кирилицю дуже важко.

Є ще метод Іллі Франка, але він мені чомусь не дуже йде, напевне тому що там дізнаватись значення слова занадто просто і я ловлю себе на тому що читаю не німецькою а російською, пропускаючи все що не в дужках.

Коментарі щодо мого розуміння німецької граматики (і української), підказки щодо вдосконалення оформлення видання (ось код для XeTeX, рев’ю можна робити як тут, так і прямо на Google Code) та інша критика вітається.


Filed under: Всяке, Конспекти, Розмітка Tagged: deutsch, книжки, освіта

Як встановити пакет LaTeX, та як зробити так щоб зноски починали нумеруватись на кожній сторінці заново?

Спочатку відповім на друге запитання, бо воно простіше. В заголовку документа прописуємо:

\usepackage{perpage}
\MakePerPage[1]{footnote}

Друга команда вказує на те що зноскам варто на кожній сторінці починати нумерацію з 1.

При компіляції документа може вилізти така помилка:

! LaTeX Error: File `perpage.sty' not found

Це означає що вам бракує встановленого пакета bigfoot.

Потрібно завантажити архів, розпакувати його, та запустити команду latex bigfoot.ins. Вона розпакує з файлу bigfoot.dtx інші файли.

Далі нам потрібен лише perpage.sty. Його треба скопіювати кудись, а щоб дізнатись куди, для TeX Live потрібно виконати таку команду:

bunyk@xubuntyk:~/bigfoot$ texhash
texhash: /usr/local/share/texmf: directory not writable. Skipping...
texhash: /var/lib/texmf: directory not writable. Skipping...
texhash: /var/lib/texmf: directory not writable. Skipping...
texhash: /var/lib/texmf: directory not writable. Skipping...
texhash: Done.

Я вибрав /usr/local/share/texmf і створив там шлях tex/latex/bigfoot. Куди й кинув файл perpage.sty (повний шлях /usr/local/share/texmf/tex/latex/bigfoot/perpage.sty).

Далі потрібно запустити:

bunyk@xubuntyk:~/bigfoot$ sudo texhash

Це все, документ скомпілювався і я досяг чого хотів, а якщо хочете, можете читати більше про встановлення пакетів.


Filed under: Кодерство, Розмітка Tagged: LaTeX

bwikibot 0.4.2, відтепер з автовиправленням правопису!

Правда не всього правопису, а лише деяких іменників чоловічого роду в родовому відмінку, але й це вже краще ніж нічого.

bwikibot встановлюється просто як:

sudo pip install bwikibot

Або, якщо цією програмою ще хтось крім мене користується (дякую вам) і вже встановив, то оновлюємо:

sudo pip install --upgrade bwikibot

Нагадаю що pip повинен бути для третього Python, підтримка другого можлива лише теоретично, якщо хтось допоможе мені з тестами.

Після чого виправлення правопису запускається командою:

python3 main.py spell "Пориньте у Python 3/Модульне тестування"

correction_diff

І якщо вказана сторінка існує на вікі, на яку він залогінений, то текст цієї сторінки буде прочитано, будуть здійснені всі можливі автозаміни, вам буде показаний диф між новою і старою версіями (треба буде подумати над тим, як зробити так аби цей диф виглядав коротшим) і після отримання від вас згоди на запис, виправлена версія записана назад у вікі.

Що він може? Небагато, поки-що. В нього є словник genitive_a_u.txt, в якому містяться слова чоловічого роду в родовому відмінку з закінченнями “а”, “у”. Словник поки що невеликий, містить сім слів: аргументу, графа, менеджменту, методу, об’єкта, параметра, файла.

Проте це слова які я не вмію правильно писати, хоча пишу часто. :) Словник буде доповнюватись. Потім може ще додам словник автовиправлень частих помилок загального виду, і якісь n-грами.

Ну і щойно виявив помилку. Мій коректор хоче замінювати слово “аргументами” на “аргументуми”. :) Треба згадати що там в кінці шаблону треба поставити… Здається "аргумент\b"?

А ще, коли проект виросте до справді корисного, напевне варто буде його відокремити і додати можливість перевірки і автовиправлення блоґу через xml-rpc.

Ах, і якщо хтось знає як не винаходити велосипед, а інтегрувати aspell чи щось подібне – поділіться досвідом.

Доповнення на 16:15 : Помилку з “аргументуми”, занадто довгі дифи, виправлено в версії 0.4.3, також для цієї версії тести проходяться як в Python3 так і в Python2, але вручну я тестував тільки 3.


Filed under: Інструменти, Кодерство, Павутина Tagged: вікіпедія, мова, Python

Багатомовність і суржик

Щось давненько я про політику не писав, треба виправлятись, правда народ? ;)

Знати багато мов добре, кажуть ще що скільки мов ти знаєш – стільки разів ти програміст. Але при їх використанні має відбуватись якесь перемикання контексту. А якщо мови мають подібні парадигми – часом це перемикання відбувається не повністю. Тут на сторожі мали б стояти граммар-наці – аналізатори синтаксису, але буває так що вони занадто поблажливі.

Ось наприклад якось я написав подібний код:

function hello(msg='Hello world!') {
    alert(msg);
}
hello(1); hello();

Ви нічого підозрілого не помітили? Я теж. Зауважу, що це JavaScript. Тестую в FireFox. Він каже “1″, “Hello world!”. Я щасливий, закриваю браузер, закриваю редактор і йду спати.

Потім проходить певний час, і мені пишуть що нічого не працює. Я відкриваю FireFox, все працює… Шляхом деяких переговорів встановлено що не працює воно в Chrome.

Відкриваю в Chrome, а там:

Uncaught SyntaxError: Unexpected token =

Виявляється, що те що я написав вище – таки не JavaScript, а Python-суржик. :) Правильно писати параметри за замовчуванням в JavaScript наступним чином:

function hello(msg) {
    if(typeof(msg) === 'undefined') msg = 'Hello world!';
    alert(msg);
}

Тепер думаю, невже SpiderMonkey реалізує якусь надмножину JavaScript?

Ну й простіше звісно було б знати одну мову добре, а не всі по трохи, тільки от біда, ніяк не вгадаєш яку саме треба знати добре. :)


Filed under: Кодерство, Павутина Tagged: JavaScript

Створення бази й користувача MySQL

Це щоб не лазити через рута, і аби не змінювати налаштування з’єднання з базою при розгортанні.

create database database_name character set utf8 collate utf8_bin;
create user 'user_name'@'localhost' identified by 'some_password';
grant all privileges on database_name.* to 'user_name';

Більше триндіти про це не буду, назад до роботи. Якщо ж вам хочеться поговорити – розкажіть в коментарях звідки сисадміни стільки всього знають?

UPDATE: Не знаю чому я це сюди запостив, якщо є вікіпідручник


Filed under: Кодерство Tagged: SQL

Теорія вивчення іноземної мови

Перейти зразу до суті.

Наука дослідження людини, а особливо її мозку куди складніша ніж наприклад комп’ютерні науки, тому нема чого дивуватись що в цій галузі існує купа найрізноманітніших напрямків. А міждицсциплінарних – ще більше. І виявляється на стику прикладної лінгвістики (як використовувати мову з користю?) і когнітивної психології (як люди думають своєю головою?) існує наука про опанування другої мови (second language acquisition). Відрізняється вона від науки опанування першої мови тим що опановуючи першу мову ви використовуємо лише наші вроджені інстинкти мавпування, а не підручники і спілкування з викладачем. Я прочитав про цю науку, і хоча там роблять публікації ще з 80-тих, але поки що не сильно наблизились до проекту Вавилонської вежі.

Правда одна ідея мені таки запам’яталась: існує два типи навчання: елементне та системне. Я так зрозумів це як синтетичний та аналітичний підхід. В першому випадку ми вчимо окремі елементи мови: слова, речення, певні фрази і т.п. В другому випадку ми вчимо якісь систематичні правила.

І особисто для мене працює лише елементне навчання. Правила я все одно не можу запам’ятати бо для їх використання треба думати. А мова це така штука яка повинна сидіти десь глибше свідомості. Ви бачите слово immer, always, ĉiam, всегда, いつも чи завжди і у вас залежно від контексту автоматично повинно засвічуватись поняття \forall t. Чи в крайньому випадку при immer повинно засвічуватись “це німецькою завжди”. Далі контекст повhttps://github.com/bunyk/item_lang_learnинен переключитись і всі наступні слова вже автоматично беруться зі словника.

Правда можуть виникнути сюрпризи наприклад коли ви чуєте “Bei mir bist du schein” і пробуєте перекласти з німецької, а потім інтернет підказує що то насправді ідиш, а німецькою пишеться “Für mich bist du schön”.

Крім того, я думаю що іноземні мови так важко вчити в школі тому що їх там вчать люди які самі вивчили лише одну-дві мови і то займались цим все життя. Тому вони й не знають як взагалі вчити мову… Крім того всі чомусь вчать однаково, хоча всі мислять по різному і читають різні книжки. Ще іноді групу ділять на “шарящі та нешарящі”, але вчили то всіх однаковими способами, просто останнім здається більше повторювали і вони читали і обговорювали менше цікавих текстів.

Коротше кажучи зараз я намагаюсь перевірити гіпотезу того чи можна мову вивчити самостійно на рівні читання газет, просто читаючи. Хоча я вже прослухав Pimsleur German I, подивився Extr@ auf Deutsch (тепер залишилось вивчити німецьку і можна буде ще раз подивитись), прочитав по 50 сторінок Langenscheidt Німецька мова 20 хвилин щодня, і С.О. Носков “Самовчитель німецької мови”, потім знайшов ключі до вправ і подумав що їх все таки напевне варто робити.

Тепер про мою теорію вивчення мови. Щоб навчитись читати, треба читати тексти. Коли ви читатимете тексти, ви зустрічатимете незнайомі слова, і будете змушені користуватись словником. А чим слово важливіше тим частіше зустрічається, а чим частіше зустрічається тим частіше ви заглядатимете в словник, а чим частіше ви заглядатимете в словник тим краще вивчите слово. Крім того ви краще будете знати слова саме в сфері своїх зацікавлень.

Проте все одно, щоб читання не було таким болісним, на перших етапах хотілось би якось уникнути текстів що містять багато низькочастотних слів, і читати якісь учбові тексти. Ідеальною була б книжка на зразок “Gerda malaperis”, але вона чомусь одна така, і лише для есперанто.

Плюс книжки Gerda malaperis в тому що це детектив, який дає якусь напругу, і викликає постійне бажання дізнатись що там далі. Часом настільки що починаєш пропускати половину слів, сюжет все одно від того не змінюється. Це мінус. Тому щоб себе стримувати повинен бути якийсь тест. “Після прочитання цього розділу ви повинні знати наступне. Якщо не знаєте – потрібно читати уважніше”. Плюс будь-якого тесту, навіть найлегшого в тому що він змушує задуматись. І я придумав теорію як зробити тести складнішими.

По суті

Є набір пар запитання – відповідь. В нашому випадку запитання – це слова або фрази на зразок “es tut mir leit”. Відповіді – це їх переклад, в даному випадку “мені шкода”. Треба перевірити знання цих пар, і вказати користувачу слабкі місця. Яким чином визначити слабкі місця? 10 разів перевірити чи користувач знає слово. Якщо він 9 разів з десяти знає – то так і записати – це слово користувач знає на 9 з десяти. Далі вибирати слова які користувач знає найгірше і давати їх йому.

Тести з варіантами відповіді – найкращі для комп’ютера тому що їх просто перевіряти. Для тестів “введіть відповідь” потрібно буде зробити неслабенький синтаксичний аналізатор і зведення відповіді до “канонічної форми”.

Правда тести занадто легкі, тому що наприклад тест “entschuldigung: а) сонце б) їсти в) прошу пробачення г) або” можна вирішити просто тому що варіанти а, б, та г точно не підходять. Але тести можна поступово ускладнювати.

Якщо користувач раптом помиляється, і обирає варіант б) ми записуємо в табличку з помилками пару entshuldigung – їсти, і кажемо що при 10 показах слова enshuldigung користувач обрав цей неправильний переклад 2 рази. І таким чином коли ми наступного разу будемо показувати тест зі словом “пробачте” користувачу, ми з більшою ймовірністю домішаємо туди помилковий варіант “їсти”, просто тому що користувач частіше робить цю помилку.

Таким чином можна буде виявити слова які я плутаю, наприклад: besuchen – відвідувати, гостювати; brauchen – потребувати; bekommen – отримувати, і вчити мене їх не плутати.

Я вирішив підівчити JavaScript, і написати програмку для цього. Вчора виклав її прототип на github. https://github.com/bunyk/item_lang_learn.

Проблеми на даний момент – я здається якось неправильно прив’язую події до кнопок з варіантами відповідей, бо після кількох кліків завжди запускається тільки подія для неправильної відповіді. Напевне варто переписати з однаковим обробником для всіх кнопок, але присвоїти кнопкам різні ідентифікатори.

Друга проблема – якщо робити модель на основі localStorage – треба буде за допомогою JavaScript багато сортувати, і взагалі робити речі які гарна база даних робила б за нас. А localStorage не вміє.

Ну, і ще проблема в тому аби зробити оформлення нормальним. jQueryUI і Bootstrap ніби непогані, але лише їх недостатньо.

Але наступного року придумаю як з цим розібратись.


Filed under: Кодерство, Нещоденник, Павутина Tagged: освіта, JavaScript

pip & virtuaenv

Вирішив коротенько занотувати найновіший метод встановлення пітонячих пакетів. Він дає багато переваг для розробника, бо в випадку коли щось поламалось можна знести все нафіг і почати спочатку. Для Python3 звичайно.

Інтернет зберігає багато інформації про яйця. Яйця застарілі. Як і easy_install. Тому що ще простіше ніж написати easy_install можна написати pip install. setuptools застарілий, замість нього треба використовувати distribute.

Разом з pip радять користуватись virtualenv. Це штука яка дозволить тримати окремий набір пакетів для кожного проекту, тримати їх в довільній директорії, і ставити без прав суперкористувача.

Щоб поставити virtualenv вибираємо каталог в якому він стоятиме, і пишемо:

wget https://raw.github.com/pypa/virtualenv/master/virtualenv.py

Готово! :) Тепер ним можна користуватись.

Для того щоб поставити pip і створити нове середовище наприклад для python3 пишемо:

python3 virtualenv.py env_name # замість env_name можна підставити щось довільне

Що накрутіше, цей скрипт працює і для Python 2, тільки в створеному середовищі ставить setuptools замість distutils.

Після того як він трохи попрацює копіюючи файли, в нас з’явиться каталог env_name. Для того щоб активувати середовище, потрібно перейти в каталог, і запустити bin/activate

bunyk@xubuntyk:~/python$ cd env_name/
bunyk@xubuntyk:~/python/env_name$ source bin/activate
(env_name)bunyk@xubuntyk:~/python/env_name$

Все, тепер в дужках ми бачимо що середовище активовано. Це означає що команди pip і python тепер локальні. pip install можна запускати без sudo.

Наприклад:

(env_name)bunyk@xubuntyk:~/python/env_name$ pip install bpython
downloading blablabla installation blablabla ....
(env_name)bunyk@xubuntyk:~/python/env_name$ which bpython
/home/bunyk/python/env_name/bin/bpython
(env_name)bunyk@xubuntyk:~/python/env_name$ which python
/home/bunyk/python/env_name/bin/python

Як бачимо всі пакети не вилазять за межі створеного їм середовища.

Щоб перейти в нормальний режим роботи, пишемо:

(env_name)bunyk@xubuntyk:~/python/env_name$ deactivate 

І пакетів як і не було, хоча Python на місці:

bunyk@xubuntyk:~/python/env_name$ which bpython
bunyk@xubuntyk:~/python/env_name$ which python
/usr/bin/python

Далі спробую розібратись як створити пакет залежний від httplib2 і зробити так щоб він сам свої залежності ставив.


Filed under: Кодерство Tagged: Python

Відкрити браузер і передати йому html

На роботі часто пишу email розсилки. І перед тим як їх тестувати на живому сервері (і на живих клієнта) ми стараємось тестувати їх в локальних умовах. Раніше для цього в конфігу вмикалась опція яка замінювала адресу отримувача на всіх листах що відправляються на адресу розробника чи тестера, після чого десь на порталі натискалась кнопка, чи з інтерактивної сесії Python запускалась функція яка збирала всі дані для заповнення шаблону, рендерила його і посилала листа.

Але це заморочливо. Тепер я вмію мокати smtplib і листи почнуть покриватись тестами. І тоді вже почнеться повне TDD і всім буде добре, бо розробники зможуть виправляти помилки ще до того як відправити їх тестерам.

Тільки от біда, що є речі які автоматичними тестами не покриваються. Наприклад треба переконатись що текст не вилазить за межі кнопочки шаблон якої зверстали наші круті стиляги-верстальщики.

Рішення яке використовую я – під час розробки показати html що генерується у браузері. Як у webtest може об’єкт responce.

Перед тим як щось робити самому я звичайно погуглив, і знайшов спосіб, який щоправда трохи застарілий. Потрібно хоча б заголовок Content-Type передавати, тому що його не задають в мета-тегу, а в заголовках формату MIME.

Власне ось сам код – веб-сервер в одній функції що відповідає на один запит:

import webbrowser
from wsgiref.simple_server import make_server
def show_in_browser(html):
        html = html.encode('utf-8')
        def wsgiapp(environ, start_response):
        headers = [('Content-type', 'text/html; charset=utf-8'),
                   ('Content-Length', str(len(html)))]
        start_response('200 OK', headers)
        return [html]

    # нульовий порт означає "знайди вільний сам"
    server = make_server('127.0.0.1', 0, wsgiapp)
    webbrowser.open('http://127.0.0.1:%s' % server.server_port)
    server.handle_request() # один запит

Мене на рев’ю запитали чому ж я не запишу html в тимчасовий файл? Видно я вже занадто веб-девелопер, бо раніше не знав як таке зробити. Зараз знаю як створити тимчасовий файл, але щось локальні файли відкриваються неадекватно. В текстовому редакторі.


Filed under: Кодерство, Розмітка Tagged: HTML, розробка, Python

Грандіозніше ніж всесвіт і фантастичніше за уяву

Фрактали всі вже бачили, всі вже знають, та все ж… Тут мова піде про світові рекорди. :)

Всесвіт настільки великий, що його розміри важко уявити. Всесвіт, досліджуваний астрономами, — частина матеріального світу, що доступна дослідженню астрономічними засобами, які відповідають досягнутому рівневі розвитку науки (часто цю частину всесвіту називають метагалактикою), простягається на 1,6\cdot 10^{27} метрів і нікому не відомо, наскільки він великий за межами видимої частини.

Атомне ядро має розмір 10^{-15} метрів.

Тепер, якщо ми маємо зображення всесвіту (в PNG наприклад :) ), то для того щоб побачити на ньому ядро атома потрібно збільшити його в 10^{42} рази. Уявляєте собі цей зум?

А тепер я вам покажу картинку, на якій роблять зум 8 \cdot 10^{606}. Це не в мільйони разів більше ніж оцей маштаб всесвіту. Це в мільйони мільонів мільйонів… і так повторити ще сто раз. Одним словом дивіться:

Для такого відео потрібна ефективна реалізація високоточної арифметики (це вам не double), написаної спеціалістом з оптимізації чисел з плаваючою комою компанії Valve, і дні і ночі обчислень на швидких багатоядерних комп’ютерах.

Те відео – здається світовий рекорд. Але думаю це не довго, бо зроблене воно більш ніж рік тому. Може з того часу хтось рік рендерив нове відео, і щоб побити рекорд залишилось ще кілька місяців обчислень?


Filed under: Всяке, Графіка Tagged: графіка, філософія