yurikhan: (Default)

Какие есть хорошие инструменты для ревью кода?

Критерии хорошести, в нулевом приближении, следующие:

  • Установка on-premise.
  • Одно ревью может включать несколько коммитов из разных (но заранее известных) Git-репозиториев. Коммиты каждого репозитория линейно упорядочены. Для каждого файла в ревью ревьюер может смотреть дифф любого подинтервала по своему выбору. (Как в Crucible, если бы он порядок брал из графа, а не выводил из временных меток.)
  • Коммент, не являющийся ответом на другой коммент, привязывается к произвольному, в общем случае не непрерывному, подмножеству строк файла. (Как в Crucible.)
  • Работает подсветка синтаксиса как минимум для C++, Python’а, Go, шелла, XML, JSON и YAML. Распознавание того, какой синтаксис применять к файлу, работает более умно, чем просто по расширению (в частности, #!/usr/bin/python3 или #!/usr/bin/env python3 для файлов без расширения однозначно указывают на Python).
  • Невозможна ситуация, когда отображается строка файла N (типично документационный комментарий) с комментом к ней и при этом существует и не отображается строка N+1 (типично заголовок или прототип функции с аргументами). (То есть не как в GitLab’е.)
  • Работает скроллинг средней кнопкой в Firefox’е. (А не как в Crucible — {overflow-y: hidden; overflow-x: auto} и привет, средней кнопкой скроллится только в стороны.)

Большая зелёная кнопка «вмёржить это в master прямо сейчас не думая» категорически нафиг не нужна.

yurikhan: (Default)

Если при наведении мышью в какую-то точку кнопки или пункта меню ты эту кнопку или пункт подсветил или поменял курсор мыши на «палец» — ты обязан реагировать на клик в этой конкретной точке.

Типичная схема нарушения: на клики реагирует ссылка с текстом, а подсветка по :hover’у и вообще всё оформление кнопки висит на контейнере-обёртке с margin’ом в пол-эма. Попадаешь в margin — подсветка есть, реакции на клик нет.

Лучи поноса в общем направлении Tiny Tiny RSS и Atlassian Crucible.

yurikhan: (Default)

В предыдущих сериях: иконочные шрифты, отсутствие хинтинга в SVG-иконках.

Новый идиотский тренд: мало того, что иконки запихивают в шрифт, так ещё и задают как лигатуры. То есть слово search, набранное шрифтом Material Icons, превращается в иконку лупы.

При отсутствии соответствующего шрифта всё это выглядит как ужас:

yurikhan: (Default)
while not done():
    task = pop(queue)
    try:
        do(task)
    except Exception as e:
        log("Cannot do %s: %s", task, e)
        # possibly sleep(5)
        # possibly push(queue, task)

Что не так на этой картинке?

Read more... )
yurikhan: (Default)

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

Название бинарника может быть глаголом в повелительном наклонении (reboot) или существительным в роли обращения (firefox, git). В последнем случае отсутствие аргументов соответствует запуску приложения с пользовательским интерфейсом; если аргументы есть, то первый — это опять глагол в повелительном наклонении (git fetch).

Ключ без аргумента соответствует наречию, обычно в роли обстоятельства образа действия (--quietly, --verbosely; по истерическим перчинам устоялось написание без суффикса -ly).

Ключ с аргументом — это косвенное дополнение, где имя ключа играет роль предлога (install -t /usr/bin fooустановить в /usr/bin foo); или уточняющее родовое слово в составе прямого дополнения (install -d /var/lib/fooустановить каталог /var/lib/foo).

Позиционный аргумент — это прямое дополнение (git clone git://github.com/git/git.git).

Это, конечно, не все паттерны — что-то я наверняка упустил.

Базовый язык для команднострочного интерфейса — разумеется, английский. (Если бы командную строку изобрёл японец, глагол ставился бы последним, а sudo записывалось бы как 下さい [kudasai] после глагола.)

Собственно, я это всё к чему? У системы виртуализации/контейнеризации LXC есть команды lxc-start, lxc-stop и несколько других. И все они принимают название контейнера, над которым работать, именованным аргументом (lxc-start -n foo). Жутко бесит. Очевидно же, что это должно быть прямое дополнение.

yurikhan: (Default)

Когда я пришёл в веб, считалось дурным тоном делать сайты, не помещающиеся в 800×600.

Потом распространились разрешения 1024×768, 1152×864, 1280×1024 и, наконец, 1600×1200. В какой-то момент вебостроители решили, что 1024 пикселя в ширину есть у всех. А у кого нет, тот лох.

Потом пошла мода на 16:10 и 16:9 и разрешения типа 1920×1080. И вот про это разрешение поговорим подробнее.

Дело в том, что при 24 дюймах диагонали, формате 16:9 и разрешении 1920×1080 CSS-пикселей (тех, которые 1/96 дюйма, а не обязательно один минимальный элемент изображения) уже начинает быть удобно работать не с одним развёрнутым на весь экран окном, а с двумя неперекрывающимися половинками. И в такой конфигурации сайту в браузере остаётся 960px ширины, с поправкой на скроллбар — ≈940px.

Сто́ит вспомнить правила приличия девяностых и двухтысячных. Сайт не должен вызывать горизонтального скроллинга при ширине окна в 940px.

(Персональные лучи поноса — Альфа-Клику, Гитхабу, Гуглу, Джире, Пейпэлу, библиотеке Сафари Букс Онлайн, всей сети Стек Эксчендж и Яндекс-Погоде.)

yurikhan: (Default)

Когда-то в прошлой жизни я сидел на Windows. Там был FAR. FAR был инструментом для всего.

Потом я пересел на X11/GNU/Linux. Там FAR’а нет. Есть отдельно Midnight Commander, у которого убогий редактор, и отдельно Emacs, у которого убогий файловый менеджер. Об Emacs’е я здесь и сейчас говорить не буду. Буду говорить о классе программ, позиционирующихся как файловые менеджеры. Говорить буду резко и в основном для себя и про себя. Всем остальным читателям к каждому высказыванию неявно добавлять «IMHO».

Итак, что такое файловый менеджер? Многие считают, что файловый менеджер — это две синие панельки, между которыми можно копировать файлы. Ну и изредка запускать команды шелла. А вот и ни фига.

Read more... )
yurikhan: (Default)

Или о бесявости отсутствия таковых.

Альфа-Клик, интернет-банк Альфа-Банка. Чтобы сделать перевод между счетами, приходится (1) навестись на «Переводы» в строке меню, (2) в попап-меню ткнуть в «Между своими счетами», выбрать в выпадающих списках сначала (3) счёт Откуда, потом (4) счёт Куда, потом (5) ввести сумму. Именно в этом порядке, потому что преждевременная валидация ввода.

Как должно быть: В списке счетов вижу название и текущий остаток. (1а) Дрэг-эн-дроп из текущего остатка на другой счёт открывает форму перевода, заранее заполненную исходным и целевым счетами, остаётся только (2а) ввести сумму. (1б) Клик в название открывает выписку. На экране выписки тоже должна быть (2б) кнопка «Перевести отсюда», открывающая ту же форму с предзаполненным исходным счётом, остаётся (3б) выбрать целевой счёт и (4б) ввести сумму. Если переводим не между своими счетами, то сценарий (б) тот же самый, только в (3б) указываем счёт получателя не выбором из списка своих счетов, а каким-то другим способом (выбор из закладок или, на худой конец, заполнение формы с опциональным созданием закладки).

Zabbix, система мониторинга с веб-мордой. Вижу график трафика по семи серверам. Хочу добавить к нему недавно развёрнутый восьмой. Для этого приходится: (1) в строке меню навестись на Configure; (2) вспомнить, определён ли график для какого-то Хоста или в каком-то Шаблоне; (3) ткнуть соответственно в Hosts или Templates; (4) найти нужный хост или шаблон в двухстраничной таблице; (5) ткнуть в ссылку Graphs в его строке; (6) в открывшемся списке графиков этого хоста ткнуть в нужный график.

Как должно быть: На странице с графиком должна быть кнопка «Конфигурировать это».

Outlook Web Access, веб-морда к корпоративной почте. Чтобы подписаться на рассылку, приходится: (1) в меню опций ткнуть в Options; (2) ткнуть в Groups; (3) нажать кнопку Join; (4) в открывшемся диалоге ткнуть в нужную группу; (5) в окне информации о группе нажать кнопку Join.

Как должно быть: (1) На вкладке People или на главной можно поиском найти нужную группу. (2) В панели информации о группе должна быть кнопка «Вступить в это».

Gajim, jabber-клиент. Чтобы добавить контакт, нужно: (1) выбрать в меню Actions | Add contact | (нужный jabber-аккаунт); (2) в диалоге ввести JID; (3) в выпадающем списке выбрать группу.

Как должно быть: Ростер уже сгруппирован сначала по аккаунтам, потом по группам. (1) В контекстном меню группы должен быть пункт «Добавить сюда». Остаётся (2) в диалоге ввести JID.

Magit, git-фронтэнд для Emacs’а. Чтобы создать новую ветку от текущего коммита, нужно: (1) нажать b B (magit-branch-and-checkout); (2) ввести хэш или имя ветки начального коммита или согласиться на предлагаемый по умолчанию; (3) ввести имя новой ветки.

Как должно быть: (1) В графе коммитов навести курсор на нужный коммит; (2) дать команду «создать ветку отсюда»; (3) ввести имя новой ветки.

Jenkins, инструмент для continuous integration. Чтобы склонировать задачу, нужно (1) ткнуть New Item, (2) выбрать радиокнопку Copy existing item, (3) выбрать клонируемую задачу из комбо-списка.

Как должно быть: В контекстном меню задачи должен быть пункт «Склонировать это».

Правило: Пользователь, видящий в интерфейсе объект, должен мочь непосредственно с него отдавать команды, принимающие этот объект в качестве любого параметра.

Положительные примеры: на картах в карточке здания «Проехать сюда» и «Проехать отсюда». В почтовиках «Filter messages like this».

yurikhan: (Default)

В вебфорумостроительстве есть типичная холиварная тема: Плоские темы vs Древовидные темы. У того и другого подходов есть свои плюсы и минусы, мы их здесь обсуждать не будем.

Почти все почтовые клиенты сходятся в том, что email относится к Древовидным. (Единственное известное мне исключение — Gmail, который считает, что к Плоским.)

Далее, почти все клиенты, умеющие группировать письма, отображают их в виде, натурально, леса. Где сообщения — вершины, а рёбра выражают тот факт, что одно сообщение является ответом на другое (в терминах заголовка In-Reply-To).

Внимание, вопрос! Что не так на этой картинке?

Read more... )
yurikhan: (Default)

Поскольку скоро о Winamp’е можно будет говорить либо хорошо, либо ничего, то нужно успеть сейчас.

Именно Winamp виновен в двух преступлениях против человечества:

  1. Зоопарк кодировок в ID3-тэгах. По спецификации в ID3v2 допустимы ISO 8859-1 и три вида юникода. А он туда писал текущую ANSI-кодировку винды, маркируя её как ISO 8859-1.
  2. Популяризация скинованных интерфейсов. Именно после Winamp’а разработчики стали массово нарушать гайдлайны UI, оправдываясь тем, что «это работает».
yurikhan: (Default)

Вводная: У меня на работе два монитора и Linux с X’ами (хотя все дальнейшие размышления одинаково справедливы и для других систем). Для простоты предположим один workspace (виртуальный стол).

У типичного переключателя окон (скажем, Static Application Switcher в Compiz’е) есть две клавиши (скажем, Alt+Tab и Alt+Shift+Tab), которые показывают список всех окон, позволяют выбрать из них одно, выносят его наверх (в z-порядке) и переключают на него фокус.

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

  • На каком мониторе отображается список? А на каком мониторе он должен отображаться?
  • В списке отображаются окна какого монитора? А должны?

Ответ на левую половину первого вопроса мне неясен. То ли на том, где было активное окно, то ли на том, где мышь. В любом случае, в половине случаев оно вылазит не там, где я ожидаю. Представляется, что в идеале список окон должен отображаться на том мониторе, куда я смотрю. А смотрю я, скорее всего, на тот монитор, где находится то окно, в которое я собираюсь переключиться.

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

Поскольку устройства типа «хрустальный шар» ещё относительно ненадёжны и дороги, а камеры для eye tracking’а тоже ещё та головная боль, есть мысль завести два набора переключающих клавиш. Скажем, LAlt+Tab LAlt+LShift+Tab на левой руке для левого монитора, а RAlt+Enter RAlt+RShift+Enter — на правой руке для правого. Каждый набор показывает список на своём мониторе и отображает окна только своего монитора. Если нажимается переключатель того же монитора, на котором (большей частью) находится активное до этого окно, то сразу выбираем следующее окно; если же другого монитора — то сначала выбираем верхнее окно на нём.

Может показаться, что эта схема требует от пользователя помнить, где у него какие окна. По этому поводу гипотеза состоит в том, что он и так это помнит, причём подсознательно. Кроме того, некоторые панели задач (в частности, панель xfce4) умеют показывать кнопки только своего монитора.

Внимание, вопрос. Что не так в этих рассуждениях? Если всё так, то почему нет никаких наработок по этой теме?

yurikhan: (Default)

В комментах у Реймонда нашего Чена о том, почему в Windows пришлось заменить иерархическое Start Menu поиском по помойке.

Коротко — потому что производители программного обеспечения развели там помойку.

И это объясняет, почему в типичном дистрибутиве Linux’а такую замену делать не нужно: потому что у нас все приложения более-менее аккуратно разложены по группам, групп не слишком много, каждый производитель не стремится показать в главном меню название своей компании. Главный фактор помойки — натурально, Wine.

yurikhan: (Default)

А вот скажите мне такую вещь. Когда вы включаете свет, на какую сторону выключателя давите — верх, низ, лево или право? И почему, с рациональной точки зрения, правильно именно так?

Read more... )
yurikhan: (Default)

Вот почему, когда Mozill’овцы предлагают спрятать меню, все начинают орать «Ribbon, Ribbon!»?

Ribbon — по определению Microsoft — это тулбары в табах, хитро#опо реагирующие на увеличение/уменьшение доступного горизонтального пространства. В предлагаемом решении ничего этого нет. Это просто «спрятать меню в кнопку».

Это было о терминологии. А теперь — что лично мне во всём этом нравится и не нравится.

Read more... )
yurikhan: (Default)

У нас в отделении Сбербанка поставили платёжный терминал. Я вам сейчас про него расскажу.

Во-первых, к нему приставлен Специально Обученный Органический Оператор. Которая обращает внимание плательщиков на его существование и иногда помогает тыкать в нарисованные кнопочки.

Во-вторых, в него можно воткнуть карточку или нажать кнопку «Оплата наличными». При этом набор доступных сервисов различен. Кроме того, набор сервисов различается в случаях, когда карточка выпущена Сбербанком и другими банками.

В-третьих, когда приходишь платить за холодную воду или там электроэнергию, он радостно спрашивает номер лицевого счёта в соответствующей организации. Вот вы помните номер своего лицевого счёта во всех этих организациях? И я нет. Зато я помню свой адрес, по которому, по идее, все эти номера счетов можно было бы из базы вытащить. Система «Город» же умеет. А вот этот ихний терминал, сцобако, не умеет.

В-четвёртых, вот я пришёл платить налог на имущество (квартиру). Оно спросило у меня номер платёжного документа (ну ладно, он напечатан на тех бумажках, которые из налоговой пришли). Показало данные платежа (что характерно, без моей фамилии), спросило подтверждения. Показало правила оплаты, спросило подтверждения. Ещё раз показало те же правила оплаты, снова спросило подтверждения. Только в первый раз кнопка «Согласен» была сверху, а второй раз — снизу. Зачем так сделано, Специально Обученный Органический Оператор объяснить затруднилась.

И таки про правила оплаты. Сдачи автомат не даёт, приходите с разменянными деньгами. Нет, Специально Обученный Органический Оператор разменом не занимается.

Внимание, вопрос. На Кой Хрен эти двое там стоят?

yurikhan: (Default)

Понадобилось это мне сегодня взять два куска кода из Visual Studio и показать на них наглядно, как похожи и чем отличаются. А что может быть нагляднее, чем жёлтый маркер в Word’е?…

Запускаю Word. Втыкаю в него код. А он раскрашивает мне все слова в коде в красную и зелёную волнистую линию — типа орфография и грамматика.

А Word, с#ка, 2007-й. Переключаю все вкладки в Ленте, ищу, где у этой сволочи кнопка. Не нахожу. Вижу внизу на статусбаре кнопку с птичкой и рядом слово «русский». Тыкаю в кнопку. Мне предлагают пофикскить очередное слово, не найденное в словаре. Тьфу. Нафиг. Тыкаю в слово «русский». Мне показывают кучу языков и внизу флажок «Не проверять». Тыкаю флажок. Волнистым линиям хоть бы хны.

Срываюсь. «Албанский, б##!» О, а это идея! Крашу весь текст в албанский язык. Поскольку соответствующего проверочного модуля в комплекте не предусмотрено, проверка отключается %)

yurikhan: (Default)

В Windows, если ты открываешь мышью контекстное меню, оно открывается по отпусканию кнопки, справа и внизу от текущего положения курсора. За очень редким исключением. Потому что контекстные меню открываются функцией API, у которой именно так заданы умолчания.

В Ubuntu, даже в пределах одной framework — GNOME — поведение отличается в зависимости от контекста.

  • Меню верхней панели открывается по нажатию, так, что мышь оказывается на первом пункте, и отпускание кнопки ведёт к выполнению его.
  • Меню нижней панели «подставляет» свой последний пункт.
  • Меню элементов панели (launcher’ов, часов, индикатора языка ввода) — вываливается по нажатию, выравнивается верхним краем по нижнему краю панели (или нижним — по верхнему). При коротком нажатии открывается, при длинном — открывается и закрывается обратно.
  • Меню заголовка окна вываливается по нажатию, при отпускании кнопки сразу меню остаётся висеть, при этом следующий клик в той же точке ведёт к выполнению первой команды. Так же ведут себя меню текстового редактора в gedit и pidgin и меню терминала.
  • Меню Firefox’а открываются по отпусканию, справа и внизу. По клику в том же месте закрывается без выполнения какой-либо команды.

Эта шизофрения указывает на то, что в API никаких разумных умолчаний на этот счёт нет. Либо все разработчики считают себя умнее и выставляют неумолчательные значения.

А как с этим в KDE? А на Mac’е?

yurikhan: (Default)

Посмотрел на это чудо инженерной мысли.

Во-первых, у него не работает пробел. То есть он работает, но только в полноэкранном режиме. А в оконном функция Pause/Play назначена на клавишу P. Почему Так Сделано, я не понимаю. Самая главная функция должна висеть на самой большой клавише и вести себя независимо от других функций, это же самые основы хорошего дизайна.

Во-вторых, полноэкранный режим включается по F11. Что может сколько угодно соответствовать общей концепции GNOME, но не соответствует моим взглядам (которые, вкратце, состоят в том, что мой видеоплеер должен переключаться в full screen по Enter’у — второй по величине клавише на клавиатуре).

В-третьих, клавиши не настраиваются (исключая вариант взять исходники и пересобрать. А я именно этот вариант пока хочу исключить).

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

Так что всё-таки mplayer. Без гуя.

yurikhan: (Default)

Все знают виндовый калькулятор. У него есть режим Standard с основными операциями и режим Scientific с поддержкой четырёх систем счисления, тригонометрии и статистики. Начиная с Windows 95 и до Windows XP включительно можно было потыкать каждую кнопочку правой кнопкой мыши и прочитать What’s This. В What’s This было краткое описание, что кнопка делает, и какой клавишей это можно вызвать с клавиатуры.

Работало всё это через компонент WinHelp, который в Windows Vista решено было убить как устаревший. Поэтому в калькуляторе под Вистой What’s This’а нет. Есть раздел в help’е, где все операции сведены в две таблицы — одна описывает функции, а вторая клавиши.

Так вот, к чему это я всё? Запомните, дети, так делать нельзя.

  • Во-первых, «Что это за хрень?» — это первый вопрос, возникающий у нормального пользователя при виде незнакомой кнопки, и негуманно заставлять его искать ответ в хелпе.
  • Во-вторых, таблица в хелпе должна быть одна: кнопка – операция – клавиша.
  • В-третьих, операции в этой таблице следовало сгруппировать и показывать в том же порядке, что и в окне калькулятора. А они их все свалили в одну кучу и отсортировали. То есть вот идёт tan, потом идёт Xor, и потом идёт x^2. А надо было — отдельно sin, cos и tan, отдельно And, Or, Xor, Lsh и Not, и отдельно x^2, x^3, x^y и Exp.
yurikhan: (Default)

А вот бывает ли какая-нибудь XML-схема плюс софт для рисования диаграмм?

Нет, я, конечно, знаю про SVG. Который кое-как отображается Firefox’ом и почти совсем никак Internet Explorer’ом. И WYSYWIG’ные редакторы, позволяющие (в теории) собрать собаку из атомов водорода, углерода, азота и кислорода. Но я хочу собирать собаку не из атомов, а из головы, туловища, лап и хвоста. И, желательно, не опускаясь до деталей вида «голова расположена в точке (0, 0), а хвост в точке (175, 0)», из-за которых собака порвётся сразу, как только я захочу поменять ей породу.

То есть вот, возьмём, к примеру, UML-диаграмму статической структуры. Я могу взять Visio, вбить в него описание своих классов, раскидать классы по странице, провести между ними ассоциации, и они будут сохраняться при перемещении. Это хорошо. Но описывать классы приходится в гуёвом диалоговом окне, обладающем рядом фундаментальных недостатков.

  • Оно модально. Я открываю окно атрибутов класса, добавляю атрибут, вспоминаю, что у меня в модели ещё нет его типа. Чертыхаюсь, закрываю окно атрибутов, добавляю тип в модель, открываю окно атрибутов, прописываю тип последнего атрибута, добавляю следующий атрибут. Я хотел бы описывать свои атрибуты в немодальном текстовом редакторе с каким-нибудь более или менее вменяемым синтаксисом. Если не C++, то хотя бы XML. Но чтобы я мог поставить закладку, пойти на страницу вверх, вписать новый тип, вернуться к закладке.
  • Оно не злопамятно. Вот есть колонка типов атрибутов. Она по умолчанию имеет ширину такую, что в ней умещается имя моего namespace’а. А собственно типы скрыты за многоточием. Я хочу видеть тип целиком. Я растаскиваю окно пошире, потом колонку имени поуже, работаю с атрибутами одного класса. Закрываю, создаю новый класс. Ширина окна сохранилась, а ширина колонок — нет. В текстовом редакторе я настрою разамер шрифта и ширину табуляции и буду видеть всё.
  • Оно ориентировано на мышевозилу гуёвого. Я хочу писать тип руками, а не выбирать из длинного списка, лишённого каких-либо средств поиска и фильтрации. Или хочу написать первые три буквы и чтоб мне предложили два подходящих типа.
  • Оно не поддерживает групповые операции. Я хочу выделить все атрибуты и назначить им всем видимость public.

Ну и потом, когда я таки введу всю модель, мне всё равно придётся раскидывать классы по странице вручную, и они не будут подстраиваться, когда я добавлю в какой-нибудь толстый класс ещё пару атрибутов. Классы налезут друг на друга, но им и в голову (или что у них есть… ещё там) не придёт подвинуться.

Это всё типа мелочи, но именно из-за вот таких мелочей я предпочитаю UML не рисовать, а когда сильно приспичит, рисовать карандашом на бумаге.

Productivity hint: Когда надо reverse-engineer’нуть какую-нибудь мрачную базу данных или систему классов, я беру лист бумаги, режу его на маленькие карточки и рисую на каждой карточке один класс или таблицу. Потом их можно произвольно размещать на поверхности стола или на другой бумажке и вырисовывать ассоциации или foreign keys.

Profile

yurikhan: (Default)
Yuri Khan

June 2017

S M T W T F S
    123
45678910
1112 1314151617
18192021222324
252627282930 

Links

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated 2017-09-19 22:23
Powered by Dreamwidth Studios