Обновить

Скрипт для мониторинга портов серверов и уведомление админа

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

Решение — под катом
Читать дальше →

AJAX: упаковка кириллицы

Во время отладки одного из скриптов случайно наткнулся на такую картину. Функция json_encode шикует размером сроки и на упаковку одного кириллического символа тратит аж 6 байт. Например, такая строка:

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми.
(210 байт в cp1251, 341 байт в utf-8)

варится вот в такую вот кашу:

JSON (\u0430\u043d\u0433\u043b. JavaScript Object Notation) — \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 JavaScript \u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c. \u041a\u0430\u043a \u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u044b, JSON \u043b\u0435\u0433\u043a\u043e \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043b\u044e\u0434\u044c\u043c\u0438.
(865 байт)

865/210 ~=~ 4,11
Мягко говоря, расточительно.
Закодируем?
Самое простое и легальное что можно сделать — заменить все кириллические символы (будем рассматривать только русские а-яА-ЯёЁ) на латинские. Просто «в лоб» реплэйсить не получится, т.к. нужно сохранить возможность писать на английском, поэтому символы будем заменять участками, а между этими участками вставим специальную строчку-разделитель.
Определимся с таблицей замен, на 66 русских символов (больших и мелких) приходится 26*2=52 латинских. Недостачу дополним цифрами и даже маленько позаримся на спец-символы.

<?php
class cyr{
private static $result; // результат
private static $cyr; // текущий режим (кириллица = true/латиница = false)
private static $key; // ключ-переключатель режимов
private static $table = array( // таблица замен
'а' => 'a', 'А' => 'G',
'б' => 'b', 'Б' => 'H',
'в' => 'c', 'В' => 'I',
'г' => 'd', 'Г' => 'J',
'д' => 'e', 'Д' => 'K',
'е' => 'f', 'Е' => 'L',
'ж' => 'g', 'Ж' => 'M',
'з' => 'h', 'З' => 'N',
'и' => 'i', 'И' => 'O',
'й' => 'j', 'Й' => 'P',
'к' => 'k', 'К' => 'Q',
'л' => 'l', 'Л' => 'R',
'м' => 'm', 'М' => 'S',
'н' => 'n', 'Н' => 'T',
'о' => 'o', 'О' => 'U',
'п' => 'p', 'П' => 'V',
'р' => 'q', 'Р' => 'W',
'с' => 'r', 'С' => 'X',
'т' => 's', 'Т' => 'Y',
'у' => 't', 'У' => 'Z',
'ф' => 'u', 'Ф' => '0',
'х' => 'v', 'Х' => '1',
'ц' => 'w', 'Ц' => '2',
'ч' => 'x', 'Ч' => '3',
'ш' => 'y', 'Ш' => '4',
'щ' => 'z', 'Щ' => '5',
'ъ' => 'A', 'Ъ' => '6',
'ы' => 'B', 'Ы' => '7',
'ь' => 'C', 'Ь' => '8',
'э' => 'D', 'Э' => '9',
'ю' => 'E', 'Ю' => '^',
'я' => 'F', 'Я' => '#',
'ё' => '$', 'Ё' => '~',
);
private static function change() // переключаем режимы: кириллица/латиница
{
self::$result .= self::$key;
self::$cyr = !self::$cyr;
}
private static function genKey(&$str) // получаем ключ-переключатель
{
static $keyChars = '*%&_()+|-={}[]@:;?,.!';
$charsCount = strlen($keyChars);
for($i=0; $i<$charsCount; ++$i)
for($j=0; $j<$charsCount; ++$j)
if(false === strpos($str, $key = $keyChars[$i].$keyChars[$j])) // ключ не встречается в исходной строке
return $key;
return '/\\';
}
public static function encode($str)
{
self::$result = '';
self::$key = self::genKey($str); // генерим подстроку, которая будет переключать раскодировщик между режимами кириллица/латиница
// {некодированный участок} $key {кодированный участок} $key {некодированный участок}
self::$cyr = true; // по умолчанию находимся в режиме "кириллица"
self::$result .= self::$key; // в самое начало добавляем ключ, для раскодировщика
preg_match_all('~.~u', $str, $m); // получаем все символы в utf-8 строке, лучше способа не нашёл :-[
foreach($m[0] as $char)
if(array_key_exists($char, self::$table)) // наткнулись на кириллицу
{
if(!self::$cyr) // если текущий режим не кириллический
self::change(); // меняем его
self::$result .= self::$table[$char];
}
else // латиница
{
// меняем режим только если данный символ используется для кодирования кириллицы
if(self::$cyr && in_array($char, self::$table))
self::change();
self::$result .= $char;
}
return self::$result;
}
public static function getJSONTable() // генерим JSON-хеш таблицы для раскодировщика
{
$table = 'var table = {';
foreach(self::$table as $cir=>$lat){
$table .= "'{$lat}':'{$cir}',";
}
return substr_replace($table, '};', -1);
}
}

// а теперь:
echo cyr::encode($str);


И вот результат:

****JSON (**andl. **JavaScript Object Notation) — **sfkrsocBj uoqmas obmfna eannBmi, ornocannBj na **JavaScript **i obBxno irpolChtfmBj imfnno r Dsim FhBkom. Qak i mnodif eqtdif sfkrsocBf uoqmasB, **JSON **lfdko xisafsrF lEeCmi.
(228 байт)

228-210 = 18 байт скушали метки-звёздочки.

На стороне клиента всё это добро должно превратиться назад в читаемый текст, с помощью вот этой JS-функции:

function cyrDecode(str){
// обратная таблица замен:
var table = {'a':'а','b':'б','c':'в','d':'г','e':'д','f':'е','g':'ж','h':'з','i':'и','j':'й','k':'к','l':'л',
'm':'м','n':'н','o':'о','p':'п','q':'р','r':'с','s':'т','t':'у','u':'ф','v':'х','w':'ц','x':'ч','y':'ш','z':'щ',
'A':'ъ','B':'ы','C':'ь','D':'э','E':'ю','F':'я','G':'А','H':'Б','I':'В','J':'Г','K':'Д','L':'Е','M':'Ж','N':'З',
'O':'И','P':'Й','Q':'К','R':'Л','S':'М','T':'Н','U':'О','V':'П','W':'Р','X':'С','Y':'Т','Z':'У','0':'Ф','1':'Х',
'2':'Ц','3':'Ч','4':'Ш','5':'Щ','6':'Ъ','7':'Ы','8':'Ь','9':'Э','^':'Ю','#':'Я','$':'ё','~':'Ё'};
// выделяем первые 2 символа (ключ-переключатель) и экранируем его для RegExp'а
var key = str.substring(0, 2).replace(/[\[\].{}*+|()?]/g, "\\$&");
// и выполняем раскодирование кодированных участков:
return str.replace(new RegExp(key+"(.*?)(?:"+key+"|$)", 'g'), function(m, str){
var res = '';
for(var i=0; i<str.length; ++i)
res += table[str.charAt(i)]||str.charAt(i);
return res;
});
}


PS: код рассчитан на работу с UTF-8

PHP-GTK. Простая графическая программа.

PHP-GTK — это расширение языка программирования PHP для разработки ПО с графическим интерфейсом с использованием GTK+. Оно обеспечивает объектно-ориентированный интерфейс к классам GTK+. Т.е., грубо говоря, это библиотека для создания оконных приложений на PHP.

Для работы будущей нашей программы потребуется установить следующий софт:


Преамбула



Я предлагаю разработать программу, которая будет запрашивать у пользователя текстовую строку и возвращать её MD5-хэш. Таким образом будет описан процесс создания окна, расположения в нём виджетов (текста, полей ввода и кнопок) и вызова пользовательских функций в ответ на действия пользователя.

В рамках данной статьи мы только создадим окно с виджетами. Обработка данных будет в следующей статье при получении инвайта :).

Разработка



Начинаем:
  1. $window = new GtkWindow();
  2. $window->set_size_request(450, -1);
  3. $window->connect_simple('destroy', array('Gtk', 'main_quit'));


Здесь мы создаём окно с помощью класса GtkWindow() и методом set_size_request() устанавливаем его размеры. -1 говорит, что высота подбирается автоматически по содержимому. Третья строчка является очень важной. Ей мы обеспечиваем чистый выход из программы. Она говорит, что при закрытии окна (сигнал 'destroy') необходимо вызвать встроенную функцию Gtk::main_quit(), которая убьёт процесс. Без этой строчки окно закроется, но процесс останется.

Далее создаём необходимые виджеты:
  1. $label_source = new GtkLabel('Введите текст:');
  2. $entry_source = new GtkEntry();
  3. $label_md5 = new GtkLabel('Получившийся md5:');
  4. $entry_md5 = new GtkEntry();
  5. $button = new GtkButton('_Расчитать');
  6. $button_close = new GtkButton('_Закрыть');


Это 2 кнопки GtkButton(), 2 строки GtkLabel() и 2 поля ввода GtkEntry().

GtkWindow позволяет расположить в себе только один виджет. А у нас их шесть. Для таких случаев в PHP-GTK имеются специальные контейнеры, в которые можно поместить неограниченное число виджетов. В данном случае лучше всего использовать таблицу GtkTable(). Она создаётся незамысловатым способом:
  1. $table = new GtkTable();


Теперь необходимо добавить виджеты в таблицу. Это делается с помощью метода attach(). Первым параметром ему передаётся добавляемый виджет. Следующими четырьмя параметрами указываются номера промежутков между ячейками (первые два — по горизонтали, последние — по вертикали). Отсчёт ведётся с нуля. Для лучшего понимания приведу рисунок:
image
Шестой и седьмой параметры отвечают за расположение виджета внутри ячейки. Хабрахабр искорежил код. Там где пустые параметры должны быть нули (0).
  1. $table->attach($label_source, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
  2. $table->attach($entry_source, 1, 2, 0, 1);
  3. $table->attach($label_md5, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
  4. $table->attach($entry_md5, 1, 2, 1, 2);
  5. $table->attach($button_close, 0, 1, 2, 3, Gtk::FILL, Gtk::FILL);
  6. $table->attach($button, 1, 2, 2, 3, Gtk::FILL, Gtk::FILL);


Теперь осталось поместить таблицу в окно:
  1. $window->add($table);


И вывести окно на экран:
  1. $window->show_all();
  2. Gtk::main();


В итоге должно получиться следующее (естественно, внешний вид элементов интерфейса будет отличаться в зависимости от установленной GTK-темы):
image

Плагин контроля количества вводимых символов для jQuery

В разных проектах часто возникает необходимость ограничить количество вводимых пользователем символов в поля формы.

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

Конечно же данный плагин ни в коем случае не отменяет необходимость соответствующей проверки на стороне сервера перед добавлением или публикацией. Плагин предназначен только для визуального информирования пользователя.

Страница демонстрации работы плагина.

Подключение плагина:
$(selector).sControl()

Доступные параметры:
maxLength: int — максимальное количество вводимых символов (по-умолчанию — 10);
blockEnter: true/false — запрет / разрешение перевода строки (по-умолчанию — true);
bgStyle: color — цвет фона сообщения (по-умолчанию — #eeeeee);
fontSize: size — размер шрифта сообщения (по-умолчанию — 9pt);
text: text — текст сообщения (по-умолчанию — «Максимальное количество символов:»)

Плагин тестировался во всех популярных броузерах: IE, Mozilla, Safari, Chrome

Загрузить плагин

Проверка работоспособности сервисов сети

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

Решение — под катом
Читать дальше →

USB-боксы и пусковой ток дисков

Начало
Купил как-то раз я себе внешнюю коробку для диска.

Конец
Она у меня сдохла.

Середина
Известно, что у дисков ток запуска выше рабочего. Но мне никогда не приходило в голову поинтересоваться, насколько именно выше. Производитель на самом диске заботливо указывает что-то вроде +5V 0.85A/+12V 0.75A. А вот пусковой ток, как оказалось, для 3.5” дисков обычно около 2.8A. Это производитель тоже указывает, но на сайте, на отдельной закладке «Технические характеристики», среди 2-х десятков других параметров (START-UP POWER REQUIREMENTS).

БП бокса по какой-то причине имел на выходе 2A (а не 3, например), но каким-то чудом переживал запуск диска. Собственно, если работал, то с чего вдруг перестал? А я ему помог.

В какой-то момент у меня «посыпался» диск. Как водится — рабочий (ещё бывают бэкапы). При сливе файлов, после наползания на очередной bad, диск отваливался — пропадал как USB устройство. Помогало выключить/включить коробку. Когда уже почти всё было слито, диск перестал даже заводиться. — Совсем сдох — подумал я. А сдох, как выяснилось полгода спустя, не он, а БП бокса ViPower, от постоянного перезапуска. Что и подтвердилось вскрытием. Примечательно, что вольты у БП на месте, а вот амперы ушли и не вернулись.

Будьте бдительны.

По мотивам записи в блог.

Buxfer — домашний бюджет с интересными возможностями

Я хочу рассказать о сервисе для ведения домашнего бюджета Buxfer. Думаю все представляют себе, как выглядит обычный сервис подобного рода, поэтому остановлюсь только на возможностях, которые отличают Buxfer от ему подобных.
Читать дальше →

Шаблонизатор для написания конфигов виртуальных хостов для apache и nginx

Есть у меня «слабенький» VDS сервер, — я оттюниговал я его как смог: Nginx frontend, Apache — backend.
Никаких «панелей» для управления виртуальными хостами ставить не хочется — и так машинка «по памяти» слабая. И поэтому «админю» виртуальные хосты правкой файлов:
/etc/nginx/conf.d/virtual.conf
и
/etc/httpd/conf.d/vhost.conf
(пути могут какие угодно, это просто для примера)

Но когда сайтов перевалило за десяток — правка конфигов надоела, т.к. это «повод» для появления ошибки. Поэтому я сделал небольшой шаблонизатор.

В каталоге vhost лежат файлики — параметры каждого сайта, например:
[name] gituha.ru
[alias] www.gituha.ru
[home] /home2/gituha
[no_acceler] |.htm|.html|.jpg|.jpeg|.png|.gif


Скрипт по этим входным данных «строит» конфиг для виртуального сервера.

С этим добром, можно ознакомится
http://gituha.ru/_root/redirect.php?projects/vhost_templater/dload/

Волков бояться в лес не ходить… поиск работы

Сегодня прочитал одну замечательную статью чтобы как-то окончательно утвердиться в своем решении переехать в г.Москва. Спросите зачем?! Не смогу ответить — семейные обстоятельства.
Вот и решили. Нужно искать работу! Вакансии есть но мала вероятность того что, я подхожу (по личным ощущения). Вообще сфера моей профессионально деятельности это — Программист Oracle. Опыт конечно не большой, но есть (3 года). До этого тоже работал в сфере ИТ но в другом качестве. Мне казалась, что все это не мое. И наконец повстречался мне мистер ORACLE. Вначале он мне показался очень не приветливым но на деле оказалось все зависит от того сколько ты жопачасов освоил (не втупую сидя ВКонтакте, Однокласниках… хотя и не без этого). Думаю, в дальнейшем буду заниматься в этом направлении.

Для возможности оценить всю картину решил почитать форумы, блоги и наткнулся на следующий блог — «О собеседованиях»,автор:WebByte. Я провинциал (Кемеровская область) опыт свой получал на большом химическом предприятии КОАО «АЗОТ». Сначала отчеты Oracle Reports,Forms6 для OEBS. Через годик вручили проект создания OLTP системы для метрологии… вообщем «о ремонтах». Написал, внедрил, работает. Вернусь к вопросу о этом блоге. Прочитал, оценил… для меня это актуально. Но я во многом не согласен с автором (ничего личного). Руководствуясь чем, он выбирал сотрудников? Заданиями?! Мне кажется в первую очередь нужно было понять:
Набираем команду с нуля – тогда где-то он прав.
Но если набираем в существующий костяк, подход не совсем «НЕ ОЧЕНЬ ЧТОБЫ ОЧЕНЬ». (моё субъективное)

К вопросу о задании..(автор комента:apple_fan
Дана таблица [product (string), price (int)]. Как написать запрос на выборку 5 самых дорогих продуктов. Использовать всякие штуки вроде LIMIT нельзя

Найденное решение (автор комента:galaxy)
select g1.price, g1.product
from goods g1
join goods g2 on (g1.price <= g2.price)
group by g1.price, g1.product
having count(1) <= 5

смотрим далее…
apple_fan отвечает, цитирую...«Супер, это то, что я имел в виду!».

Извините, а как же «Использовать всякие штуки вроде LIMIT нельзя». В данном запросе фигурирует COUNT.

Если вы хотели человека проверить на знание того или иного синтаксиса так спрашивайте а не ставьте расплывчатых задач, где рамки поставлены, но не определены.
Если вы хотели спросить о JOIN так и спросите. А так получается, что Вы сами своим ограничениям противоречите.

О да забыл, выдержка: «Неужели всех интересуют только деньги, а не то, чем предстоит заниматься и какой опыт можно получить, работая над проектами, в которых вся соль — их большая посещаемость?» (автор данной статьи:WebByte)

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

А если вы ищите сотрудника работающего за ИДЕЮ… хм ну что ж… скорее всего вы родились слишком поздно. Вам бы эдак на 40 лет назад нужно было родиться. Когда металлурги перевыполняли план в знак протеста АМЕРИКАНСКОЙ ВОЕНЩИНЕ. ))))

P.S. А вообще ищу работу. Программист Oracle. Пишите michmur42(сАбака)yandex.ru

Всем спасибо за внимание.

*nix --> yakuake

yakuake — сабж из серии: «как я жил без нее?»
— install in *buntu: sudo apt-get install yakuake
Yakuake — удобный эмулятор терминала
Yakuake is a drop-down terminal emulator based on KDE Konsole technology.

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

Все эти проблемы решает Yakuake – замечательная программулина. Это „A Quake-style terminal emulator base on KDE Konsol technology“, а говоря попросту одна из разновидностей терминальных эмуляторов…

Использование программы просто как три копейки – запускаете её один раз, и за одно закидываете в автостарт, а потом, когда Вам необходима консоль – просто жмёте F12 и она выплывает сверху. По повторному нажатию F12 она заплывает обратно наверх. Возможности програмулинки такие же как и у стандартного КДЕшного терминала, плюс можно настраивать скорость выпадания и заезжания, а так же размеры окна (у меня на весь экран).

Все настройки выполняются через кнопку, которая находится в правом нижнем углу окна посередине: между кнопкой фиксации окна и кнопкой закрытия. Настройки настолько просты, что описывать их не имеет смысла. Скажу только, что пользователям openSUSE надо помнить, что по F12 так же запускается Beagle – локальный поисковик, т.е. этот вопрос надо решить или его отключением или переназначением ему другой кнопки, а если вы к нему привыкли на столько, что по F12 ничего кроме Beagle себе не представляете, то можно переназначить клавишу открытия Yakuake. Это делается через упомянутое меню в пункте Configure Global Shortcuts.

Открытие нового таба осуществляется по комбинации CTRL+SHIFT+N а закрытие по CTRL+SHIFT+R. Но это всё очень гибко настраивается, как и многие другие горячие клавиши в пункте меню Configure Shortcuts.

Links:
yakuake.uv.ro — home page
kde-apps.org — distr, tools/skins

Typogridphy – типографический css фреймворк от Гарри Робертса

Я думаю, многие уже в курсе, о появлении такого замечательного фреймворка, ну а тем, кто не в курсе и посвящается данная заметка. Надеюсь, она окажется полезной.

Typogridphy – это типографический css фреймворк, созданный на базе популярной сетки 960 Grid System, человеком по имени Гарри Робертс.

Читать дальше →

Поиск с ног на голову, на человеческую голову

Поиск с ног на голову. Поисковый движок NiLis.

— Кто лучше знает, что ищет пользователь? Компьютер или сам ищущий?
— Кто лучше определяет соответствие запроса и найденного текста? Компьютерный мозг или человеческий?
— Кого больше – пользователей поисковой машины или компьютеров поискового сервиса?
— Во сколько раз мощность совокупного разума пользователей поискового сервиса больше, чем мощность всех компьютеров этого сервиса?
image
Обычно поисковые компании пытаются использовать компьютерные мозги, чтобы вычислить, насколько та или иная страничка в интернете соответствует критериям поиска. Но, стоило бы задуматься – что или кто находится по другую сторону провода от поисковой машины и увидеть огромный человеческий супермозг из десятков миллионов пользователей, с их способностью мгновенно определять соответствие найденной странички критерию поиска. Причем не просто критерию, а смыслу поиска. Таким образом, поиск будет не просто точным соответствием заданным условиям, а точным соответствием желанию пользователя, что не одно и то же.

Движок NiLis. Смотреть не то что другие искали, а ЧТО и КАК другие НАШЛИ.
Ремарка:
-Указанные в описании численные значения взяты «с потолка» и указаны лишь для лучшего понимания работы движка.
-Чем больше страниц сайта получили дополнительные очки, тем выше будет ранг сайта в системе ранжирования сайтов.


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

1. Категории
После поиска движок выдает ленту уточнений под поисковым запросом:
Товары, купить(ХХ шт.); Новости, статьи почитать(ХХ шт.); Документы, скачать(ХХ шт.), Картинки, посмотреть(ХХ шт.); Видео(ХХ шт.), посмотреть; еще категории(ХХ шт.) – адреса, фирмы и т.д.

2. Поисковые стратегии ЧТО нашли
2.1. Удачный поиск. Пользователь щелкает на выведенных на страничку ссылках, чтобы открыть их для просмотра. Таким ссылкам повышается рейтинг (+1 point), так как пользователь определил, что они больше соответствуют критерию. Не получившие клика не получают ничего, если поиск без категорий или получают значительное понижение рейтинга (-10 point) в поиске с использованием категорий, чтобы на их место в следующий раз попали другие ссылки.
Для всех ссылок, похожих на получившую штраф (-10 point),
также понижается рейтинг (-3 point).
Итак:
— открытая ссылка (+1 point)
— проигнорированная ссылка в простом поиске (0 point)
— проигнорированная ссылка с категориями (-10 point)
— похожие на проигнорированную ссылку с категориями (-3 point)

Так как ссылки открываются «скопом»(Опытные пользователи так делают — пока они смотрят одну страницу, подгружаются остальные, чтобы потом их не ждать), успешную ссылку определить невозможно. Все открытые ссылки с последней поисковой страницы считаются успешными и поднимается их рейтинг (+2 point) в подобных запросах. Для всех предыдущих поисковых страниц рейтинг:
— открытые ссылки (+1 point),
— проигнорированные ссылки (-10 point)
— Итак, мы получаем алгоритм:
— открытая ссылка (+1 point)
— открытая ссылка с последней страницы (+2 point)
— проигнорированная ссылка в простом поиске (0 point)
— проигнорированная ссылка с категориями (-10 point)
— похожие на проигнорированную ссылку с категориями (-3 point)

2.2. Неудачная выдача. Если информация не найдена, то пользователь открывает еще несколько поисковых страниц, а потом видоизменяет запрос. По статистике ясно, сколько, в среднем, страниц открывает пользователь, прежде чем изменить запрос из-за неудачной выдачи. Т.е. ссылкам с последней открытой страницы НЕ присваивается повышенный рейтинг (+2 point)

2.3. Кратковременные всплески новостных поводов.
Если какая-то поисковая фраза совпадает с появившимися новостями, то предыдущий механизм для простого поиска отключается, но в поисковую выдачу в первую очередь попадают новостные сайты и тематически связанные с новостью(новый клип певца – новости про певца, статьи про него и т.д.)

3. Поисковая система на сайте клиента.
Когда для поиска на сайте используется API NiLis, то движок NiLis добавляет результаты поиска по сайту в общую статистику поиска по интернету.

4. Служба аналитики.
Если владельцы ресурсов используют службу анализа посещаемости страниц, то поисковый движок NiLis использует данные о посещаемости страниц от аналитической службы, чтобы присвоить высокопосещаемым страницам дополнительный общий рейтинг. Если на сайт клиента службы аналитики попали со страницы поиска, то движок NiLis запоминает всю цепочку от запроса до всех последующих открытых страничек, чтобы улучшить выдачу на запрос.

5. Использование собственной панели к браузеру.
При инсталляции поисковой панели в браузер появляется возможность отслеживать добавление ссылок в «Избранное» и время нахождения на сайте:
— добавление ссылки в «избранное» после поиска (+100 point)
(для борьбы с использованием вирусов используем статистику, ненормальная активизация добавлений игнорируется)

Сумма прописью на Javascript

/*
*****************************************************************************
* ВЫВОД ЧИСЛА (СУММЫ) ПРОПИСЬЮ *
* (С) Roman V Doronin, Март 1994 (перевод на JavaScript Январь 2007) *
*****************************************************************************
*/

//------------------------------------------------------------------------------
// Запись числа прописью
function numberInWords(sum){
// Параметры: sum — сумма (целое число)
// Возврат: число прописью или false-error
sum=Number(Math.round(sum));//-для подстраховки
if (sum>999999999){return false;}//-ожидалось число меньше 1.000.000.000
if (sum==0) return ' ноль';
//переведем число в 9-ти битную строку
var ax='000000000'+String(sum);ax=ax.substr(ax.length-9);
var retVal='';
//сформируем массивы
var listWords={
1:{1:' сто',2:' двести',3:' триста',4:' четыреста',5:' пятьсот',6:' шестьсот',7:' семьсот',8:' восемьсот',9:' девятьсот'},
2:{1:' десять',2:' двадцать',3:' тридцать',4:' сорок',5:' пятьдесят',6:' шестьдесят',7:' семьдесят',8:' восемьдесят',9:' девяносто'},
3:{1:' один',2:' два',3:' три',4:' четыре',5:' пять',6:' шесть',7:' семь',8:' восемь',9:' девять'},
4:{1:' одиннадцать',2:' двенадцать',3:' тринадцать',4:' четырнадцать',5:' пятнадцать',6:' шестнадцать',7:' семнадцать',8:' восемнадцать',9:' девятнадцать'},
5:{1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},
6:{1:'а',2:'и',3:'и',4:'и',5:'',6:'',7:'',8:'',9:''}
};
var listEnding={1:' миллион',2:' тысяч',3:' '};
var arrBit=[0,4,2,1];
//формирование выходной строки
for (i=1;i<4;i++){
bx=ax.substr((i-1)*3,3);
if (Math.round(bx!=0)){
c=0;for (i1=1;i1<4;i1++){if (bx.substr(i1-1,1)!='0') c+=arrBit[i1];}
for (i1=1;i1<4;i1++){
if (bx.substr(i1-1,1)=='0') continue;
if (i==2 && i1==3 && bx.substr(3-1,1)=='1'){retVal+=' одна';continue;}
if (i==2 && i1==3 && bx.substr(3-1,1)=='2'){retVal+=' две';continue;}
if (bx.substr(2-1,1)=='1' && c/2!=Math.round(c/2) && i1==2){retVal+=listWords[4][Math.round(bx.substr(3-1,1))];i1=3;c-=1;continue;}
retVal+=listWords[i1][bx.substr(i1-1,1)];
}
}else if (i!=3) continue;
//-сформируем окончание
if (Math.round(c/2)==c/2){
if (i==1)retVal+=' миллионов';
if (i==2)retVal+=' тысяч';
if (i==3) continue;
}else {
if (i==3) continue;//-пропустим рубли
retVal+=listEnding[i]+listWords[4+i][Math.round(bx.substr(3-1,1))];}
}
return retVal;
}

//------------------------------------------------------------------------------
// Перевод числа в сумму прописью
// Вызов: receiveInWordsSum(<число>[,<тип валюты>][,<флаг вывода дробного числа>][,<флаг вывод с заглавной буквы>])
function receiveInWordsSum(sum){
// Параметры: sum — сумма (число или строковый тип-если дробная часть может оканчиваться на 0)
// сurrency — валюта:
// 0 — рубли (по умолчанию)
// 1 — доллары
// 10 — тонны
// 11 — километры
// 12 — литры
// 13 — штуки
// flagCopeck — флаг вывода с копейками:
// false или 0 — без копеек (по умолчанию)
// 1 — копейки числом
// 2 — копейки прописью (не реализовано)
// flagUpper — true — первый символ переводится в заглавный
// false — подавить перевод первого символа в заглавный (по умолчанию)
// Возврат: сумма прописью в формате сurrency и в зависимости от флага сurrency
var сurrency=arguments[1] || 0;
var flagCopeck=arguments[2] || 0;
var flagUpper=arguments[3] || false;
//массив валют
var listCurrency={
0:{1:'рубл',2:'копе'},
1:{1:'доллар',2:'цент'},
10:{1:'тонн',2:'килограмм'},
11:{1:'километр',2:'метр'},
12:{1:'литр',2:''},
13:{1:'штук',2:''}
};
//-массив окончаний валют
var listEndingCurrency={
0:{0:'ей',1:'ь',2:'я',3:'я',4:'я',5:'ей',6:'ей',7:'ей',8:'ей',9:'ей'},//-рубли
1:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},//-доллары
10:{0:'',1:'а',2:'ы',3:'ы',4:'ы',5:'',6:'',7:'',8:'',9:''},//-тонны
11:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},//-километры
12:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},//-литры
13:{0:'',1:'а',2:'и',3:'и',4:'и',5:'',6:'',7:'',8:'',9:''} //штуки
//1:{0:'',1:'',2:'',3:'',4:'',5:'',6:'',7:'',8:'',9:''},//зарезервировано
};
//-массив окончаний дробных частей валют
var listEndingDenominatorCurrency={
0:{0:'ек',1:'йка',2:'йки',3:'йки',4:'йки',5:'ек',6:'ек',7:'ек',8:'ек',9:'ек'},//-копейки
1:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},//-центы
10:{0:'',1:'',2:'а',3:'а',4:'а',5:'',6:'',7:'',8:'',9:''},//-килограммы
11:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'}//-метры
12:{0:'ов',1:'',2:'а',3:'а',4:'а',5:'ов',6:'ов',7:'ов',8:'ов',9:'ов'},//-литры
13:{0:'',1:'а',2:'и',3:'и',4:'и',5:'',6:'',7:'',8:'',9:''} //штуки
//1:{0:'',1:'',2:'',3:'',4:'',5:'',6:'',7:'',8:'',9:''},//зарезервировано
};

//формируем выходную строку
if (isNaN(sum)) return '';
sum=String(sum).match(/(\d+)\W*(\d*)/);
if(!sum) return '';
var numerator=sum[1] || 0;
var denominator=sum[2] || '00';
//сформируем целую часть
var retVal=numberInWords(numerator)+' '+listCurrency[сurrency][1]+listEndingCurrency[сurrency][Number(String(numerator.substr(numerator.length-1,1)))];
//формируем дробную часть
if (flagCopeck==1 && listCurrency[сurrency][2]) retVal+=' '+denominator+' '+listCurrency[сurrency][2]+listEndingDenominatorCurrency[сurrency][Number(String(denominator.substr(denominator.length-1,1)))];
//Переведем первую букву в заглавную
if (flagUpper){
retVal=firstSymbolToUpper(retVal);
}
return retVal;
}

//------------------------------------------------------------------------------
// Начинает предложение с большой буквы
function firstSymbolToUpper(val){
//Параметры: val — обрабатываемая строка
//Возвращает: полученную строку val в которой первый символ переведен в заглавный
return val.substr(1,1).toUpperCase()+val.substr(2);
}

4 правила, как добиться успеха на Rent A Coder

Дорогие хабравчане, фрилансеры, представляю вашему вниманию собственный перевод статьи с популярной online фриланс-биржи Rent A Coder (RAC).

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



Сейчас прошло уже более трех лет, мы выполнили более 250 проектов и заработали много прекрасных отзывов (мы постоянно находимся в топе среди всех кодеров сайта). Я бы хотел рассказать о 4 важных правилах, которые помогли нам добиться такого высокого рейтинга (важно отметить, что всю работу мы делали в свободное от основной деятельности время) и заработать большое количество денег.



Следите за вашей репутацией


Когда ваш клиент (buyer) принимает решение о том какого работника (coder) выбрать, он обращает внимание на две важные вещи — это ваша ставка и ваша репутация. Я не хочу сказать, что программисты с невысокой репутацией не могут получить работу (могут), но для этого им придется уменьшать свою ставку (bid amount). Хорошая репутация в сервисе — залог получения хорошей работы с достойной оплатой.



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



Делайте ставку разумно


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



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



Будьте честны с вашими клиентами


Учитесь быть честным с клиентом! Да, очень обидно потерять проект из-за того, что вы честно сказали вашему работодателю, что не сможете выполнить его заказ на 100%, но еще более обидно будет если вы покажите себя с отрицательной стороны и в будущем вы не сможете получить подобный проект и, как следствие не заработаете денег, а также заработаете отрицательный рейтинг, только потому что вы не были честны с самого начала.



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



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



Максимизируйте ваш доход


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



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



Возможно, лучшее решение данной проблемы — стараться убедить ваших клиентов работать с вами снова. Клиент у которого проект подпадал под ваши профессиональные навыки будет иметь похожие проекты и в будущем (это могут быть совершенно другие проекты или прежние, нуждающиеся в изменениях). Если работодатель доволен вашей работой и вашими навыками общения, и если вы дадите ему понять, что вы готовы в будущем работать с ним снова, то у вас большие шансы на то, что в скором времени он свяжется с вами, сохранив ваше время и увеличит вашу прибыль, и каждый последующий одиночный (one-to-one) аукцион поможет вам заработать больше денег.



Другое решение — «играть по крупному». Я ничего не имею против небольших проектов, но скажем прямо: малые проекты приносят малую прибыль, все потому что вы потратите столько же времени на согласование большего количества небольших проектов сколько и на согласование крупных, но в втором случае ваше вознаграждение будет гораздо большим. Учтите этот момент, когда будете согласовывать крупный проект, вы не будете беспокоиться о поисках новых, других проектов, и сможете сфокусироваться на текущей работе, сделав ее более качественно и заработав в конечном счете хорошие деньги.



Существует гораздо больше полезных правил которые можно было бы добавить в данную статью, но цель ее, не быть исчерпывающим руководством, а дать вам 4 важных совета котрые помогут в работе на RentACoder.com

Сайдбар гаджет для быстрого en-ru, ru-en перевода

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

Благо МСДН подписка у меня есть, ОС и Visual Studio поставил но что делать с переводчиком? Вроде как привык использовать Lingvo но перевожу наверно раз-два в месяц и куча онлайн переводчиков поэтому покупать не хотелось (жаба давила), тем более что на работу уже одну версию купил, хватит. Недавно поставил Вин7 и не бог нарадоваться саидбаром без саидбара и тут-же решил найти в интернетах полезных гаджетов на мою тему. Как оказалось нет в галерее переводчиков основанных на lingvo.ru поэтому решил сделать сам.

Оказалось это совсем не сложно, весь процесс, вместе с обучением занял пару часов. Я не буду делать стэп бай стэп потому что их уже и так развелось тьма. Расскажу только про те проблемы которые у меня возникли и как я их решил.

LingvoTranslate

Читать дальше →

SMath Studio 0.80 (Desktop / Handheld / Live)

image
Релиз: SMath Studio 0.80 Stable
Бесплатный математический пакет с графическим интерфейсом для вычисления математических выражений и построения двумерных и трёхмерных графиков для различных платформ.
Теперь доступна AJAX версия программы!
Читать дальше →

wifi адаптер как точка доступа

Разберём на следующем примеру, что имеем:

1. ОС Linux
2. Беспроводной PCI-адаптер D-Link AirPlusG DWL-G51

Есть такой фильтр пакетов iptables.
В случае если интернет подключен через ADSL модем:
iptables -t nat --flush
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o dsl0 -j MASQUERADE

В случае если интернет подключен через выделеную линию:
iptables -t nat --flush
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
где 192.168.2.0 — подсеть беспроводного адаптера, с адресом(к примеру) 192.168.2.1

*Имена интерфейсов в разных системах могут называться по разному.

Включаем форвард пакетов между интерфейсами:

1. Открываем файл /etc/sysctl, находим строчку IP_FORWARD, правим на IP_FORWARD=«yes» и сохраняем.
2. Вводим в консоли sysctl -e -p

В настройках устройства(Бук или КПК) задаем ip-адрес(к примеру) 192.168.2.2 шлюз 192.168.2.1 и радуемся.

Временное органичение голосавания на основе кэширования

Надеюсь, то, чем я с вами сейчас поделюсь, не будет «баяном», т.к. я подобной практики не встречал.

В процессе создания системы рейтинга «плюс минус» для своего хобби-проекта, мне хотелось сделать ее максимально элегантной. Использовать для ограничения голосования Cookies не хотелось, а засорять серверную логику и БД лишними методами и данными тем более. И тут я вспомнил про кэширование =).
Читать дальше →

Тотальный переход с ext3/ntfs на ext4.

Ext4 ImageПосле недавнего обновления ubuntu до версии 9.04 мне захотелось окончательно избавиться от windows-атавизмов, таких как 2 ntsf раздела, и заодно полностью перевести ubuntu на ext4. Всё это вылилось в небольшое howto, которое я вам и предлагаю

Читать дальше →

Федеральный Интернет Экзамен. Вся «кухня» изнутри.

Видя то, какие бурные обсуждения вызвали статьи о ФЭПО


я решил рассказать о нем то, что скрыто от посторонних глаз. В силу сложившихся обстоятельств я работаю в одном из ВУЗов нашей страны и в этом году был ответственным инженером за проведения этого «экзамена» на одном из факультетов.
Для начала хотелось бы подчеркнуть, что этот экзамен является частью аккредитации университета и на жизнь и оценки студентов никак не влияет. .В связи с этим фраза «Федеральный Интернет Экзамен — уже вводиться в большинстве ВУЗов, как альтернатива обычному» в одной из статьей не имеет никакого смысла
Сам экзамен оценивает так называемые остаточные знания и считается он сданным, если все дидактические единицы усвоены более, чем у 50% студентов.

Говорить о корректности вопросов я думаю уже не стоит. Поверьте не только в IT сфере они составлены безграмотно. Однако, немногие знают о самом тестирующем модуле, о программе, тестирующие студентов.
Нужно отметить, что сам экзамен несмотря на то, что он называется «Интернет Экзаменом» никогда не проводиться он-лайн. На деле, после прохождения теста на локальном компьютере создается файл с результатами. Потом нужно собрать их ручками с каждой машины, с помощью специальный программы эти файлы объединить в один и залить на сайт ФЭПО. К сожалению, автоматизировать этот процесс невозможно, так как версия программы создающая файл с результатами сразу на сервере просто не работает.
Очевидно, что на этом «кривизна» организации процесса не закончена: файл с результатами должен быть загружен на сайт в в течении времени, предоставленного для экзамена, иначе результаты недействительны.
А, что если их сайт лежит? и такое поверьте было :)

Но самое поразительное другое. Конечно, никто из мин образования не обратил внимания, что 3/4 экзаменов сданы на 100%, им это только на руку, зато они обратили внимания на 2 экзамена, которые студенты умудрились завалить(и как только у них это получилось? Учитывая, что они могли пользоваться конспектами, интернетом и даже преподами) и великодушно решили дать возможность пересдать эти экзамены.
Говорят, чтобы эта ситуация не повторилась, за компы в этот раз посадят самих преподавателей.

Вывод: Этот «Интернет-экзамен» лишь очередная завеса для глаз. Непонятно кого он экзаменуют, чью работу проверяет. Возможно, он был бы хорош с точки зрения внедрения IT в образование, но как вы сами видите и здесь ребятами показали себя не лучшим образом.