Я в интернете

РСС    Джейсон-фид

Есть автоматические трансляции в Тумблер и Же-же. Если не работает, напишите мне: ilyabirman@ilyabirman.ru.

Избранное

Позднее Ctrl + ↑

Точка и запятая между цифрами

Целая часть от дробной в русском языке отделяется только запятой. Однако из этого не следует, что везде в русском тексте точка между цифрами должна быть заменена запятой: нужно сначала убедиться, что перед нами именно дробь.

Номера версий программных продуктов и ай-пи-адреса не являются дробями.

Пищащие светофоры

Есть объяснения каким-то явлениям, которые люди слышат и съедают, не вникая. То есть, многим достаточно, чтобы объяснение просто было; оно не должно объяснять. Например, запредельное количество людей, услышав, что номера линий на схеме московского метро введены для дальтоников, спокойно принимают такое объяснене; у них не возникает следующего вопроса: «А каким хреном нумерация линий должна помочь дальтоникам?» (правильный ответ: никаким; нумерация не нужна).

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

Существуют пищащие сфетофоры. Когда пешеходу горит зелёный, они пищат. «Это для слепых». Я никогда не мог понять, как слепой должен сориентироваться на перекрёстке, ведь там светофор по идее должен всё время пищать (переходить-то можно всегда, просто разные дороги). Но на этот мой вопрос ни у кого, кому я его задавал, нет ответа — оказывается, никому это даже в голову не приходит.

Но наверняка те, кто это придумали, задавались этим вопросом. Каков же правильный ответ? Неужели слепой должен прислушиваться, с противоположной стороны какой из дорог пищит другой светофор? Может быть, сфетофор должен пищать только когда разрешён переход с севера на юг, но не с запада на восток? Или, может, в зависимости от направления, светофоры пищат по-разному?

Почему указатели трудны и что с этим делать

Указатели сложны не потому, что это объективно что-то сложное, а потому, что авторы языка Си — козлы, которые позаботились об экономии числа нажатий при печатании, а о том, удобство чтения кода куда важнее, чем удобство его написания, они не подумали. Чего только стоят все эти название функций типа strcspn () и feof ().

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

int n[10]; // здесь n хранит адрес, но нет ни звёздочки, ни амперсанда
n[5] = 77; // незаметно поиграли в указатели
*(n + 5) = 77; // здесь звёдочка означает «значение по адресу» (уже заметно)

char *s; // здесь звёздочка уже означает «переменная хранит не значение, а адрес»

unsigned int m = 2131;
*((char *) &m + 1) = 'A'; // теперь, если у меня правильно взорвался мозг, m ""=="" 2113

Если бы вместо звёздочки и амперсанда использовались конструкции addressof () и valueat (), для объявления типов был бы модификатор address, а для кастинга использовался бы оператор as указатели бы понимало в 10 раз больше человек. Назовём такой язык Ди (хоть такой уже и есть).

Квадратные скобки в выражениях в Ди пусть означают «значение по адресу с указанным сдвигом», тогда есть для любого x будет справедливо:

x == x[0] == valueat (addressof (x) + 0).

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

int address n[10];
valueat (n)[5] = 77; // пока получается некрасиво
valueat (n + 5) = 77; // а тут — нормально

Так обращение к элементам массива, как видно, получается слишком громоздким. Но кто нас заставляет вообще играть в указатели там, где это не нужно? Квадратные скобки в объявлении переменной у нас просто резервируют памяти на несколько таких переменных, но в указатель её не превращают. Так не будем этого делать и мы, выкинем слово address:

int n[10]; // так само n будет хранить значение нулевого инта (n == n[0], напомню)
n[5] = 77; // значение со сдвигом — как раз то, что нам нужно
valueat (addressof (n) + 5) = 77; // длинная запись того же самого

Теперь простая вещь выглядит просто, а игры с указателями выглядят как игры с указателями, но вдобавок не теряют понятности. Синонимичность последних двух строк тоже очевидна. Это прекрасно. А вот другие наши сишные строчки в переводе на Ди:

char address s;

unsigned int m = 2131;
valueat ((addressof (m) as char address) + 1) = 'A'

Теперь, если мы что-нибудь перепутаем, это сразу будет видно:

valueat ((m as char address) + 1) = 'A' // пытаемся представить значение в качестве адреса

valueat (m) = 'A' // пытаемся взять значение по адресу m, в то время как m не является адресом

Такой язык не требует ни больших вычислительных ресурсов, чем Си, ни каких-либо ещё достижений современности, зато читать его легче. Чтобы его придумать, нужно было просто отнестись к задаче чуть внимательнее, чем к ней отнёсся тот, кто нажимал Шифт+цифры в поисках ещё незадействованных символов.

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

Древовидность и урлы

Продолжим тему нормальных урлов. Некоторые ребята думают, что хороший урл получается, если бездумно заменить в адресе всю служебную хрень на прямые слеши. Эти идиотские урлы видны невооружённым глазом. Например, вместо site.ru/?article=4972304 делают site.ru/article/4972304/.

Такой «красивый» урл ничем не лучше исходного. Он даже хуже: он показывает нам древовидность там, где её нет. Кажется, будто текущая страница — дочерняя для страницы site.ru/article/, на которой 404 или вообще какая-нибудь ошибка ПХП отображается.

Вместо article должно быть написано articles, а по адресу site.ru/acticles/ должен быть список статей. А если он и так показывается на главной, то страница отдельной статьи должна быть дочерней по отношению к главной: site.ru/4972304/. Если уж очень хочется запихать слово article в адрес, то нужно писать: site.ru/article-4972304/.

Урлы с бессмысленным набором слов и чисел, разделённых слешами, являются следствием бездумной конвертации внутренней логики веб-приложения в формат, «похожий на урл». Есть какой-нибудь класс Article, или файл article.php, или функция article (), и в урл его название и попадает.

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

Математика в дизайне

Некоторые видели, что происходит, если на Маке ввести неправильный пароль для входа в систему. Вместо того, чтобы показывать модальное окно с кнопкой OK, он просто немножко подёргивает окошко влево-вправо, как будто вертит головой. Кроме того, что это весело, это ещё и не заставляет пользователя нажимать кнопку ОК.

Задача: сделать такую же штуку в E2 (проверить пароль, не перезагружая страницу, не проблема; мы займёмся только анимацией).

Многие дизайнеры и даже программисты настолько плохо дружат с физикой и математикой, что когда нужно добавить элементу массы (т. е. инерции) или реализовать правдоподобное подёргивание окна, они не в состоянии ничего придумать. Это печально. Мне понадобилась минута, чтобы придумать формулу, ещё 5 — чтобы сделать рабочий скрипт, а потом ещё 5, чтобы подобрать удачные коэффициенты.

Для начала пойдём в Гугль и спросим у него, где можно в онлайне построить график функции. Интернет — великая вещь: первая же ссылка приведёт нас на подходящий сайт. Отличное место, чтобы придумать формулу зависимости горизонтальной координаты окна от времени.

Колебания естественно ассоциируются с синусом, но нам нужно, чтобы они постепенно затухали. Первое, что пришло мне в голову — домножить синусоиду на гиперболу: (1 / x) × sin x.

Синусоида, умноженная на гиперболу

Конечно, головой мы качаем совсем не так, зато так получится приятная пружинистость.

Предел sin x / x в нуле равен единице, что, конечно, лучше, чем бесконечность но всё-таки хочется, чтобы в точке 0 значение было нулевым, иначе в начале окно вдруг окажется на сто (например) пикселей правее, чем было до начала анимации. Нам нужно, чтобы гипербола в нуле получила конечное значение, тогда домножение на sin 0, равный нулю, даст ноль. Сдвинем гиперболу чуть левее, чтобы её точка разрыва уехала в неинтересующую нас отрицательную область: [1 / (x + 1)] × sin x.

Поскольку гипербола при увеличении x стремится к нулю, но никогда не достигает его, наши колебания, несмотря на затухание, будут продолжаться бесконечно. Можно, конечно, остановить их, когда они станут меньше пикселя, но намного проще чуть-чуть опустить гиперболу, чтобы она всё же достигла нуля через некоторое время: [1 / (x + 1) − 0,01] × sin x.

Чтобы было понятнее, взглянем на саму гиперболу, без синуса (1 / (x + 1) − 0,01):

Гипербола, сдвинутая так, чтобы пересекать оси

Сдвиги на 1 левее и на 0,01 ниже взяты от балды; после того, как скрипт уже написан, можно заниматься повышением реалистичности путём изменения этих чисел и примешивания всяческих коэффициентов.

Итоговая формула, с учётом перерисовки каждую 0,01 с, у меня получилась вот такая: [1 / (x1,25 / 20 + 0,5) − 0,05] × sin (x / 2) × 25.

Возведение в степень 1,25 понадобилось, чтобы слегка выгнуть гиперболу, которая затухает слишком стремительно (можно было просто сдвинуть её ещё левее, но так мне больше понравилось).

Дизайнер, который не знает математики, в два раза хуже дизайнера, который её знает. Естественно, на место математики тут можно поставить любой другой предмет — литературу, историю, русский язык, английский язык, биологию, географию, программирование, физику, химию. Кстати, большую половину из перечисленных предметов я знаю крайне плохо.

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

Шаблон Сафари для рисования эскизов

Скриншот сайта просто на белом фоне трудно воспринимать как сайт, поэтому в почти в любом портфолио веб-дизайнера сайты показывают в браузере. Многие дизайнеры предпочитают и эскизы рисовать «как бы в браузере».

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

Дело в том, что на Маке у окон обычно нет «рамки»: сверху заголовок (возможно, с тулбаром), а под ним идёт от первого до последнего пикселя по горизонтали — внутренности окна. Если у окна нет строки состояния, то «контентная область» и снизу продолжается до конца.

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

Окно на Маке

В общем, если в Фотошопе сверху влепить «шапку» от Сафари, забив на полупиксельный рамку (фотошоп всё равно рисует рамку вокруг канвы), то а) координата X любого элемента продолжит отсчитываться с нуля, а не с трёх, допустим, пикселей; б) можно будет легко изменять canvas size по вертикали, если страницу нужно сделать длинее, без необходимости сдвигать или перерисовывать какие-то нижние элементы.

Но смысл рисования сайта внутри браузера не только в повышении реалистичности. Главное (собственно, то, ради чего я перешёл на такой формат) — это доступность строки заголовка и адресной строки. Теперь на эскизах страниц я пишу их тайтлы, вставляю фавыконку и придумываю им нормальные урлы, что позволяет заметно упростить взаимодействие с верстальщиками и технологами. И не забудешь, что это тоже надо делать. Опять же, если я имею в виду, что на какой-то странице должен быть РСС, я могу дополнительно намекнуть на это, прицепив иконку РССа в конец адресной строки.

Короче, дарю всем желающим ПСД-шаблон (68 КБ), в котором все значимые элементы браузера сделаны отдельными слоями, в т. ч. заголовок окна (с правильной рельефностью) и урл в виде текста. Ширина картинки — 1000 пикселей. В названиях слоёв используется нехитрая нотация: точкой заканчиваются слои, которые по любому должны быть, а вопросиком — те, которые можно включать/выключать по вкусу. Ещё можно вместо обычного заголовка выбрать 5 табов, чтобы реально оценивать влезабельность своего тайтла.

Добавлено в 14:32: Сергей Чикуёнок оставил полезнейший комментарий.

Красный курсор для русского языка

Когда-то Артём изобрёл отличный способ индикации текущей раскладки: красить текстовый курсор в тот или иной цвет.

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

С тех пор, как я переехал на Мак, я не без удовольствия ковыряюсь в местных средствах разработки. Постепенно я научился: отслеживать момент смены раскладки клавиатуры; изменять цвет курсора в текстовом поле моей программы, определять текущее «ключевое» (т. е. отвечающее за обработку клавиатурных событий) окно приложения, определять текущую раскладку клавиатуры.

Оставалось только научиться встраиваться в чужие приложения и находить там текущий активный контрол. Я начитался документации и понял, что моей программе нужно стать инпутменеджером, то есть приложением, посредством которого производится текстовый ввод (это АПИ, видимо, сделано для организации всяких альтернативных способов ввода). Поскольку инпутменеджер — это, по сути, совершенно любой твой код, который выполняется от имени любого другого приложения (и, соответственно, с его правами), то это как бы опасная штука. Вроде как в Тигре даже был какой-то вирус, использовавший этот механизм, поэтому в Леопарде к инпутменеджерам стали предъявляться сверхстрогие требования.

С помощью интернета и Славы Карпенко я разобрался с тем, как сделать и установить инпутменеджером собственный бандл (connecting the dots!) и сделал пруф-оф-концептовый инпутменеджер, реализующий идею Артёма. Он далёк от совершенства:

  1. Работает только в Какао-приложениях (Мейл, Адрес-бук; Адиум, Скайп; системное меню Спотлайта...), но не работает в Карбон-приложениях (Айтюнс, Файндер, весь Адоби). С одной стороны, в Снежном барсе все родные приложения должны будут перейти на Какао. С другой, нельзя исключать, что поддержку инпутменеджеров прибьют.
  2. Работает только в стандартных текстовых полях. Например, в поле комментариев в браузере работать не станет. В поле написания письма в мейле тоже не заработает, так как там тоже используется какой-то контрол на базе WebView (потому что там можно писать ХТМЛ-письма и вставлять туда атачи).
  3. Использует таймер, чтобы не пропустить момент, когда человек переходит из одного текстового поля в другое (ловить activeConversationChanged:toNewConversation: у меня пока не получается).
  4. Не исключено, что он где-нибудь «течёт» (берёт память и не освобождает потом) — я не очень силён в таком хардкорном программировании, поэтому мог упустить что-то. Учитывая, что он выполняется в чужих приложениях, а не сам по себе, масштаб бедствия (если оно есть) существенно увеличивается. Ну, а если он течёт в том коде, который выполняется по таймеру, то всё вообще очень плохо.
  5. Он тупо красит курсор в красный цвет, если среди поддерживаемых текущей раскладкой языков не встречается английский, то есть никакой настройки раскладок/цветов нет.

Он называется Lipstick (LIP — это как бы Language Insertion Point, ну, или, Layout, или Locale). Чтобы установить его, нужно:

  1. Скачать архив.
  2. Создать в /Library/InputManagers (именно в корне!) папку Lipstick
  3. Кинуть туда оба файла (инфо и бандл) из архива.
  4. Сказать терминалу (ввести пароль при необходимости):
    sudo chown -R root:admin /Library/InputManagers
    sudo chmod -R 555 /Library/InputManagers

В каждом Какао-приложении он заработает после его перезапуска (перезапускать систему, по крайней мере, Леопард, не нужно). Спотлайт в правом верхнем углу можно перезапустить так:

killall Spotlight

Картинка:

Липстик в почте

Если какое-нибудь приложение начнёт тормозить или падать в неположенном месте, вполне может быть, что это из-за Липстика. Чтобы его выключить, просто уберите Lipstick из папки /Library/InputManagers и перезапустите соответствующее приложение.

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

Работы ограждения

ТСЖ навтыкало под дворники машинам, стоящим вдоль забора, объявлений:

Уважаемые автовладельцы! 7 мая 2009 года с 8.00 до 17.00 будут проводиться сварочные работы металлического ограждения. Просим переставить автомобиль на другое место.

Хочется плакать. Сварочные работы металлического ограждения! Я не понимаю, как люди могут до такой степени не уметь говорить на родном языке. Мозги же должны совсем засохнуть, чтобы стали получаться такие фразы. И я ещё удивляюсь, что никто деепричастными оборотами пользоваться не умеет. Ёлки, да тут взрослые люди простое предложение составить не могут!

А по двору дети гуляют, читают эти бумажки.

Склоняю числительные

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

8. Просклоняйте количественное числительное 1245 (книг).

  1. Тысяча двести сорок пять книг стоят на полке.
  2. Тысячи двухсот сорока пяти книг недосчитался библиотекарь.
  3. И тысяче двумстам сорока пяти книгам не рассказать всех несмешных анекдотов!
  4. Уж тысячу двести сорок пять книг прочёл, а всё бестолку.
  5. Тысячью двумястами сорока пятью книгами можно натопить небольшую баню.
  6. О тысяче двухстах сорока пяти книгах мне надоело придумывать дурацкие предложения.

9. Просклоняйте порядковое числительное 3892 (преподавателя).

Если числительное порядковое, то почему «преподавателя»? Видимо, ошибка в тесте. Пришлось склонять сразу и так, и эдак.

  1. Три тысячи восемьсот девяносто два преподавателя пинают плохого студента три тысячи восемьсот девяносто второй раз.
  2. Трёх тысяч восьмисот девяноста двух преподавателей достаточно, чтобы вкрутить лампочку с три тысячи восемьсот девяносто второго раза.
  3. Трём тысячам восьмистам девяноста двум преподавателям пришлось ещё раз дать по башке три тысячи восемьсот девяносто второму (в рейтинге успеваемости) студенту.
  4. Три тысячи восемьсот девяносто двух преподавателей наказали за избиение три тысячи восемьсот девяносто второго (в рейтинге успеваемости) студента.
  5. Тремя тысячами восьмьюстами девяноста двумя преподавателями (в смысле, таким большим составом) можно доехать на работу три тысячи восемьсот девяносто вторым троллейбусом (ПКиО — Юпитер)
  6. О трёх тысячах восьмистах девяноста двух преподавателях можно составить в три тысячи восемьсот девяносто два раза больше бессмысленных предложений, чем о три тысячи восемьсот девяносто втором кабинете главного корпуса (тем более, что такого нет).
Ранее Ctrl + ↓