программирование
Минус ноль в JavaScript
Я, конечно, знаю, что JavaScript хранит числа по стандарту IEEE 754, но всё больше
Но вот о существовании минус нуля я
Но, оказывается, в редких случаях отрицательный ноль может себя проявлять иначе, чем ноль положительный.
Как вы можете получить минус ноль? Например, просто написав
Похоже, что в реальном коде минус ноль может проявить себя в двух вещах: делении и операции atan2, именно так его и можно отличить от положительного нуля:
function isNegativeZero(x) {
return x === 0 && (1 / x) === -Infinity
}
function isNegativeZeroToo(x) {
return x === 0 && Math.atan2(x, x) < 0
}Пайтон обогнал PHP по популярности

Опубликован февральский рейтинг языков программирования. Пайтон обогнал PHP по популярности, кроме того, сильно сдал позиции Perl.
Internet Explorer 9 RC
Вышел Internet Explorer 9 Release Candidate. Из значимых
Выход этого RC для меня печальное событие. Это значит, что в девятой версии не появится cache manifest, а я очень на это расчитывал. Это единственный браузер из современных, который не будет поддерживать эту интереснейшую технологию. Увы.
Bogosort
Сегодня на собеседовании (я всё ещё ищу пайтонистов, ау) всплыли алгоритмы сортировки и я решил немного почитать на эту тему. Оказывается есть смешной алгоритм сортировки Bogosort, который на практике не применяется, а служит только иллюстративным целям:
Bogosort (также рандомная сортировка, сортировка ружья или обезьянья сортировка) является очень неэффективным алгоритмом сортировки. Её используют только в образовательных целях, противопоставляя другим, более реалистичным алгоритмам. Если bogosort использовать для сортировки колоды карт, то сначала в алгоритме нужно проверить, лежат ли все карты по порядку, и если не лежат, то подбросить колоду в воздух, проверить лежат ли теперь все карты по порядку, и повторять процесс, пока не отсортируется колода.
Я, для интереса, написал его на Пайтоне и поразвлекался с запускам на разных данных. Вот код, если интересно:
from random import shuffle
from itertools import izip, islice
def bogosorted(arr):
for x, y in izip(islice(arr, 1, None), islice(arr, 0, len(arr) - 1)):
if y > x: return False
return True
def bogosort(arr):
while arr and not bogosorted(arr):
shuffle(arr)
return arr
print bogosort([1, 1, 3, 2, 2, 2])
Синтаксис @font-face, совместимый с IE
@font-face {
font-family: 'MyFontFamily';
src: url('myfont-webfont.eot#') format('eot'),
url('myfont-webfont.woff') format('woff'),
url('myfont-webfont.ttf') format('truetype'),
url('myfont-webfont.svg#svgFontName') format('svg');
}У IE
Посмотрите на третью строку, видите там „#“? IE
Вот такой простой и красивый трюк.
Добавлено позднее: не все поняли. После решётки в адресе страницы идёт идентификатор внутри страницы. Эта часть на сервер на отсылается.
У вас компьютер какого пола?
Шутка пару дней гуляет по интернету, я её только несколько улучшил — теперь компьютер сам называет свой пол и можно пускать из командной строки (программист я или копипастер?). Работает только на Windows.
Нажимаете Win+R (или просто запускаете из командной строки), копируете туда следующую строку:
mshta "javascript:close((V=(v=new ActiveXObject('SAPI.SpVoice')).GetVoices()).count&&v.Speak('Hello! I am '+V(0).GetAttribute('Gender')))"Потом нажимаете «Enter» и слушаете.
У меня оба ноута — девочки.
JavaScript: небезопасная изоляция скриптов
Я смотрю многие начинают задумываться об изоляции JavaScript, подключаемых в контекст страницы. Например, вы подключаете
Сейчас считается, что безопасным методом является
(function (window, alert) {
alert('Функция «alert» изолирована и доступ к методу из «window» теперь получить нельзя');
})({}, function (){})Это не правильно.
Такой вызов вас ни от чего не защищает, более того, можно запросто «восстановить справедливость» и получить изнутри такого скрипта доступ к оригинальному window:
<script>
(function(window, alert){
alert('Пичалька');
(function(){ with(this) {
alert('Уже всё хорошо');
}}).call(null);
})({}, function(){})
</script>В общем случае идея такой изоляции — плохая. Я не видел ни одного удачного примера подобной изоляции и не смог придумать его самостоятельно.
Внимание: MySQL считает, что буквы «ё» и «е» — одно и то же.
Увы, MySQL, если выбрать кодировку Unicode, считает, что «е» и «ё» — это одно и то же. Багом это не считается, в официальной таблице, где описано как MySQL 6.0 сравнивает символы, эти символы в одном ряду.
mysql> set names utf8 collate utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> select 'е'='ё', 'ё'='ѐ'\G
*************************** 1. row ***************************
'е'='ё': 1
'ё'='ѐ': 1
1 row in set (0.00 sec)Самое печальное, это нелогичное поведение всплывает, если есть потребность перевести базу с CP1251
mysql> set names cp1251;
Query OK, 0 rows affected (0.00 sec)
mysql> select 'е'='ё', 'ё'='ѐ'\G
*************************** 1. row ***************************
'е'='ё': 0
'ё'='ѐ': 0
1 row in set (0.00 sec)Чем это может быть плохо? Например, у нас
mysql> set names utf8 collate utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> create table surname(surname varchar(255) primary key);
Query OK, 0 rows affected (0.07 sec)
mysql> insert into surname values('Рублёв');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into surname values('Рублев');
ERROR 1062 (23000): Duplicate entry 'Рублев' for key 'PRIMARY'Я придумал только один способ, исправляющий это поведение (но у него есть недостаток):
mysql> create table surname(surname varchar(255) primary key collate 'utf8_bin');
Query OK, 0 rows affected (0.02 sec)
mysql> insert into surname values('Рублёв');
Query OK, 1 row affected (0.00 sec)
mysql> insert into surname values('Рублев');
Query OK, 1 row affected (0.00 sec)
mysql> select * from surname where surname='рублев';
Empty set (0.00 sec)Я выключил case insensitive у данного столбца, явным указанием «collate». Это полностью решает проблему с «ё», но лишает нас удовольствия искать, не заботясь о совпадении регистра.
Нужен сисадмин и разработчик на Пайтон
Привет!
Мне в группу внутренних сервисов компании «Яндекс» нужен разработчик на Пайтон. Так же ребята из группы администрирования попросили написать, что нам нужен системный администратор (Linux).
Пишите либо в комментарии, либо на почту (
Небольшая задача на Пайтоне
Вот вам небольшая задача на Пайтоне, для того, чтобы понять как у вас с функциональным программированием. Выполнить надо в уме (я смог, значит это возможно). Что вернёт следующее выражение:
(lambda x:x(x))(lambda z: lambda y:z)(1)(2)(3)Добавлено позднее: если
(function (x) x(x))(function (z) function (y) z)(1)(2)(3)Невероятный JavaScript
Насколько запутанный JavaScript вы можете написать? Хотя
В блоге Shadowflux образчик хорошо запутанного кода с объяснением работы:
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](_/_)Выглядит довольно страшно, но, если разобраться, ничего сложного. Напоминает старый добрый Perl.
Антиалиасинг шрифтов: кто прав, Microsoft или Apple (ответ — никто)
Как сэкономить один байт в GIF

Я понимаю, один байт — не бог весть что, но, возможно,
Файл в формате GIF должен заканчиваться символом с кодом 0x3B («;»), который называется «trailer». На самом деле, этот символ чаще всего не требуется декодерами (хотя обязателен в стандарте). Я проверил на сервисе скриншотов, все браузеры, которые там перечислены, кроме Konqueror 4.2 и выше, поддерживают файлы GIF без этого байта.
Я так же вывесил такой GIF у себя на сайте, обнаружилось, что его так же не поняли агенты, которые подписываются как Java/1.6.0_xx (думаю, это
Вывод: если вас это не смущает, то можете сократить свои GIFы на один байт. Или, напротив, проверьте имеют ли ваши GIF этот байт, если для вас
Internet Explorer показывает не все GIF
Нашёл в ЖЖ DiBR’а GIF, который не показывает Internet Explorer. Забавно, хотя в отличие от JPEG, который не показывает современная «Опера», этот GIF несколько некорректен.
Вот текст комментария из ЖЖ, который разъясняет принцип:
Согласно описанию формата, сразу за заголовком («GIF89a») идет Logical Screen Descriptor (в котором как раз и прописан размер 80×80), затем Global Color Table, а уж за ним — всякие Extensions и данные изображений. В обсуждаемом файле Global Color Table просто отсутствует (так что IE ведет себя вполне адекватно). Зато присутствует картинка размером 100×100, которую и видят менее привередливые рендереры.
Конструкцию «with» убрали в strict mode в ECMAScript 5?
with(){} statements are dead when strict mode is enabled — in fact it even appears as a syntax error. While the feature was certainly
mis-understood and possiblymis-used I’m not convinced that it’s enough to be stricken from the record.
Я, конечно, понимаю чем плоха конструкция with, но отключать её в strict mode… Мне кажется излишним.
ECMAScript 5, кстати, будет в FireFox 4.
MakeCorner shell

Хочу порекламировать MC Shell — графическую оболочку для моего консольного скруглятора картинок, которую пишет oldTV, в архив программы уже входит моя утилита, так что ничего дополнительно качать не нужно.
Сериал для программистов на JavaScript
Не пропустите новогодний сериал для программистов — мы с неким LO сокращаем мой второй вариант игры «Tank 1K», написанный по рождественским правилам конкурса JS1K (программ на JavaScript, умещающихся в 1КБ).
Уже сократили с 1023 до 773 770 759 752 723 байта (более чем на 29% и это на таком крошечном размере).
Для меня — полезное соревнование, тренинг, о котором только можно мечтать, у LO отлично варит голова. Для вас — возможность посмотреть как в JS можно сократить размер программы. Уже сейчас видно, что из некоторых ходов вполне можно вывести правила, например: «если у тебя в программе есть пустые скобки любого вида, посмотри нельзя ли их
Если
«Опера» 9.50 и выше показывает не все JPEG

Случайно выяснилось, что «Опера»
Добавлено: «Опера» 9.00, 9.27, 9.63, 10.00, 11.00, 11.01а и Opera Mini 5.1 не показывает. «Опера» 8.54 — показывает. Значит сломали в девятой версии.
Расширение для «Оперы»: сайт только у меня не видно?
Артемий Трегубенко написал расширение для «Оперы» «У всех работает».

Смысл в том, что если ваша «Опера» показывает экран с ошибкой «Невозможно найти удалённый сервер», это расширение при помощи сервиса «Down for everyone or just me» проверяет доступность того же сайта для других пользователей.
Полезно, можно узнать проблема с сайтом или у вашего провайдера.
А картинка, которая в этом посте, только в моей «Опере» не показывается или в вашей тоже?
Добавлено: картинка не открывается под любой платформой в последней «Опере», сейчас потестирую в других.
Чуть позже: «Опера» 8.54 показывает, 9.63 — уже нет. Я заменил картинку на такую, которую «Опера» понимает.
localStorage для Internet Explorer 6 и 7
Написал небольшой класс в JavaScript для поддержки API localStorage в IE 6 и 7. localStorage — это браузерное хранилище
Доступ к значениям как к свойствам класса не реализован. Прежде всего потому, что в JS в этих версиях IE нет сеттеров и геттеров, а для того, чтобы воспользоваться onpropertychange мой объект надо поместить в DOM, что порождает массу гемороя, типа присутствия свойств из DOM, а не из хранилища.
Так же я не сделал события onstorage и onstoragecommit, потому что не придумал для чего это нужно (а второе корректно реализовать вообще нельзя).
Ещё не реализовал нестандартное, но полезное расширение remainingSpace, потому что в общем случае нельзя сказать сколько места ещё осталось в userData, так как квота зависит от зоны сайта (доверенная, интранет и так далее).
С большой вероятностью эта зона, конечно же, «интернет» (то есть квота 1МБ), но квоты localStorage сильно отличаются по механизму от userData, у последнего две квоты — на документ (в зоне «интернет» это 128КБ) и на домен (упомянутый мегабайт). Вполне может случится, что квота «на документ» ещё не исчерпана, а доменная уже да.
Зато я реализовал exception, который бросается в том случае, если IE говорит, что квота исчерпана.
В общем, основные вещи есть. Пример использования:
// .-~*´¨¯¨`*·~-.¸ тут подключаем библиотеку ,.-~*´¨¯¨`*·~-.¸
// записываем два значения
try {
localStorage.setItem('key1', 'myvalue1');
localStorage.setItem('key2', 'myvalue2');
} catch (e) {
if (e.description == 'QUOTA_EXCEEDED_ERR') {
alert('Нет места');
} else {
alert('Что-то не так, не знаю что.');
}
}
// смотрим значение по ключу «key1»
alert(localStorage.getItem('key1'));
// смотрим первое значение (по номеру), нумерация с нуля
alert(localStorage.key(0));
// удаляем значение по ключу «key1»
alert(localStorage.removeItem('key1'));
// смотрим сколько ключей осталось
alert(localStorage.length);
// очищаем хранилище полностью
alert(localStorage.clear());