Архив рубрики: software

Больше нот!

Семь лет назад я замерял скорость нотного набора, когда используешь LilyPond — на простых хоровые нотах без аккомпанемента получалось около 0,8 листа в час. С аккомпанементом, как я предполагал, скорость должна была упасть ещё в несколько раз.

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

Как добавить флаги в меню выбора языков Google Translate

Google Translate знает много языков. Очень много. И выбирать их только мышкой без помощи клавиатуры сложновато — из-за большого количества выглядящих похожим образом элементов трудно быстро найти нужный, не тратя время на чтение всех названий.

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

Существуют браузерные дополнения, позволяющие задавать свои стилевые правила для конкретных сайтов — для Firefox, Google Chrome и других брауеров, основанных на Chromium, это делает Stylebot. Попробуем добавить стилевые правила для отдельного пункта — укажем не только иконку (пусть будет флаг), но и цвет:

div[data-language-code="lt"] div.Llmcnf {
  color: #060;
}

div[data-language-code="lt"] div.Llmcnf:before {
  content: "🇱🇹";
  padding-right: .25em;
}

Стало гораздо заметнее:

Как долго в Google Translate будет использоваться название класса Llmcnf — не возьмусь предсказывать, но пока такой метод работает и работает уже не первую неделю.

Если помечать таким образом не все языки, а только нужные, их найти будет достаточно легко — например, раньше я всё время очень долго искал немецкий, потому что искал не German, а Deutsch — теперь же вижу его сразу:

Re: Как сдвинуть одинокую вершину

Я пробовал добавлять в граф невидимые вершины и рёбра для того, чтоб управлять положением видимых вершин. Но есть и другой способ: можно поместить вершины в один кластер — вершины сдвинутся:

digraph G {
    graph [ rankdir=LR ]
    node [ shape=box, fontname="PT Mono", fontsize=32 ]

    subgraph cluster_values {
        color=blue
        style="rounded,dashed"

        "'value'" [ fontcolor=grey, color=grey ]
        42
    }

    name [ shape=cds, style=filled, fillcolor=wheat ]
    name -> 42
}

Попутно обнаружился ряд интересных моментов:

  1. Имя субграфа должно начинаться со слова cluster для того, чтобы можно было его раскрасить и подписать. Если не будет, то параметры style, color, fillcolor, label и аналогичные будут проигнорированы.
  2. Если субграф используется только для группировки вершин, а отображать его совсем не надо, можно дать ему любое имя, но в таком случае надо добавить параметр rank=same для того, чтобы вершины выстроились рядом.

Концы строк в LibreOffice

Writer — текстовая часть пакета LibreOffice — аналог Microsoft Word — имеет странную особенность: если поставить в диалоге замены галочку «Регулярные выражения», то выражение \n будет иметь разное значение в зависимости от того, где его написать: в строке поиска оно соответствует переводу строки ↲, вставляемому сочетанием клавиш Shift+Enter, но в строке замены это же самое будет уже концом абзаца ¶, который вставляется одиночным нажатием клавиши Enter.

Как же заменить концы абзацев на переводы строк?

На форуме по LibreOffice нашёлся рецепт:

  • Вводим где-нибудь перевод строки (Shift+Enter), копируем его в буфер обмена
  • Вызываем диалог поиска и замены клавишами Ctrl+H либо через меню: Edit → Find & Replace
  • В поле Search for пишем $
  • Раскрываем при необходимости группу параметров Other options и отмечаем там Regular expressions
  • Нажимаем кнопку Find All — выделятся концы абзацев, закрываем диалоговое окно
  • Вставляем из буфера переводы строк
диалог поиска и замены

Я проверил в LibreOffice 6.1.5.2 — работает.

Добавление существующего git-хранилища на GitHub

Иногда код, хранимый локально, дорастает до состояния, что его уже можно выложить на GitHub. Конечно же, с сохранением уже накопленной истории изменений. Если установлен gh — клиент для Гитхаба с интерфейсом командной строки, то решить такую задачу будет просто: достаточно зайти в каталог с существующим кодом, создать командой gh repo create новое GitHub-хранилище — оно автоматически будет указано в качестве удалённой ветки (remote branch) — после этого останется отправить всё наружу командой git push origin master (да, git всё-таки ещё главную ветвь называет мастером, а не main). То есть, достаточно всего двух команд.

path/to/code$ gh repo create slide-python --public -d 'Slides for Python classes'
? This will create 'slide-python' in your current directory. Continue? Yes
✓ Created repository shoorick/slide-python on GitHub
✓ Added remote git@github.com:shoorick/slide-python.git
path/to/code$ git remote -v
origin git@github.com:shoorick/slide-python.git (fetch)
origin git@github.com:shoorick/slide-python.git (push)
path/to/code$ git push origin master
Enumerating objects: 370, done.
Counting objects: 100% (370/370), done.
Delta compression using up to 4 threads
Compressing objects: 100% (368/368), done.
Writing objects: 100% (370/370), 832.24 KiB | 13.87 MiB/s, done.
Total 370 (delta 249), reused 0 (delta 0)
remote: Resolving deltas: 100% (249/249), done.
To github.com:shoorick/slide-python.git
[new branch] master -> master

Как сдвинуть одинокую вершину

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

digraph G {
    graph [ rankdir=LR ]
    node [ shape=box, fontname="PT Mono", fontsize=32 ]

    name [ shape=cds, style=filled, fillcolor=wheat ]
    name -> 42

    "'value'" [ fontcolor=grey, color=grey ]
}
Вершина value находится слева

Вершина оказывается слева, но я хочу сдвинуть её правее. Подсмотрел на stackoverflow идею сделать невидимое ребро и попробовал применить её в своём случае. Для начала попробуем добавить ещё одну вершину и связать её ребром с той, которую надо сдвинуть — успешно:

none -> "'value'"

Сделаем невидимым ненужное ребро:

none -> "'value'" [ style=invis ]
Невидимое ребро

и ненужную вершину — тоже. После этого получится именно то, что надо:

none [ style=invis ]
Вершина value сдвинута вправо

Скачивание видеороликов с попутным их склеиванием

Если что-то в интернете можно посмотреть, значит, это можно и скачать, хоть это и не всегда удобно.

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

Как известно, если нельзя, но очень хочется, то можно.

Метод

1. Заходим на страницу с архивом, находим нужный фрагмент, открываем отладчик (клавишей F12), переключаемся на вкладку Network — так и в Google Chrome, и в Mozilla Firefox.

2. Запускаем воспроизведение — отладчик покажет выполненные запросы.

3. Когда запросы перестанут идти (то есть, всё нужно, уже скачалось), можно, щёлкнув по ним правой кнопкой, выбрать пункт “Save all as HAR” — запросы и ответы на них будут сохранены единым файлом с расширением HAR — на самом деле это JSON.

В отладчике открыта вкладка Network

4. Берём какой-нибудь HAR-extractor (есть всякие варианты — мне подошёл первый попавшийся, написанный на Node.JS), натравливаем его на HAR-файл, получаем папку, в одной из подпапок которой будут лежать видеофайлы с расширением TS.

5. Смотрим эти видеофайлы — под линуксом с гномом можно использовать стандартный видеоплеер totem или всеядный mpv (ну или mplayer, из которого он и вырос).

6. Создаём текстовый файл, каждая строка которого состоит из слова file, пробела и имени файла в апострофах:

file 'cam42_16-10-2020_26778689266.ts'
file 'cam42_16-10-2020_26778699914.ts'

7. Склеиваем мелкие видеофрагменты в один большой файл:

ffmpeg -f concat -i список.txt -codec copy результат.mp4

Всё!


Аналогичный способ — сохранение кучи мелких файликов через HAR — можно использовать для того, чтоб добыть тайлы — небольшие квадратные картинки из которых состоят интерактивные карты на сайтах, а потом, делая свою карту, разместить эти тайлы где-нибудь у себя, чтоб не создавать лишнюю нагрузку на тайлопровайдера — они этого не любят: OpenStreetMap просит не брать тайлы непосредственно у них, а фонд ВикиМедиа всё время клянчит денег на поддержку функционирования Википедии. Реальный пример такого подхода — карта Global SUSU на сайте Южно-Уральского университета: тайлы там сгенерированы Википедией из общедоступных данных OpenStreetMap, но хранятся на одном из университетских серверов.

Копирование с Gist на GitHub

Бывает, что мелкие фрагменты программного кода, заброшенные на Gist, со временем разрастаются до состояния, когда надо бы выделить им отдельное нормальное хранилище на Гитхабе — с багтрекером и остальными плюшками.

На https://gist.github.com/ishu3101/830b556b487de5d69690 нашёлся и был испытан на практике такой метод:

1. Создать новый репозиторий на Гитхабе.

2. Склонировать гист:

git clone git@gist.github.com:4b84d4a8d8404ede668225de68fb96ba.git

3. Переименовать получившийся каталог и зайти в него.

4. Добавить удалённый репозиторий (см. Pro Git 2.5 Git Basics — Working with Remotes, по-русски Основы Git — Работа с удалёнными репозиториями):

git remote add github https://github.com/username/repository-name

5. Отправить на Гитхаб:

git push github master

Но есть и более простой способ — импортировать через https://github.com/new/import

Импорт проекта на Гитхаб

Такой способ подходит, если надо всего лишь скопировать файл на Гитхаб и не заниматься дальнейшим его поддержанием в актуальном состоянии и на gist.github.com

Двенадцатое Комодо — бесплатные баги

Недавно вышла Komodo IDE 12 — интегрированная среда разработки, где, помимо прочего, есть, как и раньше, отладчик перловых скриптов, прогон тестов, профилировщик, г̶у̶й̶^W графический интерфейс к системам контроля версий и ещё дофига всего. В сильно похожем на неё редакторе Komodo Edit, который стал бесплатным ещё раньше, этих плюшек нет — есть лишь схожий вес.

Теперь оно всё бесплатное, но, увы, радоваться рано:
во-первых, глюки и тормоза никуда не делись, потому что внутри — всё тот же файрфокс, питон с библиотеками и яваскрипт суммарным весом в четверть гигабайта,
во-вторых, Komodo IDE теперь интегрируется с ActiveState Platform тех же авторов и требует для чего-то, выходящего за пределы простого редактирования и связи с СКВ, загадочных танцев с бубном: то, что раньше работало «из коробки» (например, отладка и запуск скриптов), теперь не запускается никак, даже после р̶а̶с̶к̶у̶р̶и̶в̶а̶н̶и̶я̶ ̶м̶а̶н̶о̶в̶^W^W внимательного чтения документации.

Если оно не заработает как надо, придётся снова править код, например, в Geany, а отлаживать и коммитить — с командной строки.