«— Сколько раз я видел своими глазами, как верблюд не может пройти сквозь игольное ушко?
— Сколько раз я видел, как богач не может войти в Царствие Божие?
— Если Богу угодно, чтобы никто не был богат, зачем Он создал так много денег?»

Кристофер Бакли. «Господь — мой Брокер»

Шторкин.руМоя работа → Технодром

Технодром!Средневзвешенная система голосования.  (4 июля 2009 г. )

Средневзвешенная система голосования.


Добрый день. Хочу поделиться весьма объективной системой оценок и рейтингов, основанной на средневзвешенной системе с оценками по пятибалльной шкале.

Допустим, на проекте пользователи публикуют некие контентные единицы в различные разделы, например, фотографии разных жанров. Пользователь имеет право поставить за фотографии оценку, при этом рассчитывается рейтинг, в общем случае это среднее значение от всех выставленных за фотографию оценок. Но, как на любом многопользовательском ресурсе, есть более опытные пользователи, голос которых должен играть ведущую роль в рейтинге, а есть новички, с более слабым голосом. Здесь помогает понятие веса голоса, причем вес должен быть дифференцирован по разделам. Например, автор, работающий в жанре пейзажной фотографии, имеет максимальный вес голоса именно в этом разделе, но минимальный, скажем, в разделе «Обнаженная натура». Пришлось попотеть, прежде чем нашлись формулы, более или менее объективно описывающие вес голоса. Смысл веса голоса заключается в следующем (здесь и далее примеры будут касаться рейтингов работ и авторов на фотографическом сайте): автор должен подтвердить свою компетентность в том или ином разделе, набрав за свои работы  в нем как можно больший балл (по пятибалльной шкале). Наиболее оптимальным оказалось решение, в котором вес голоса изменяется от 0 до 1, точнее от 0.1 (для новичков). Формула для расчета веса голоса выглядит примерно так:

Weight = tanh(N/C)*(SUM(m_value*m_weight)/ SUM(m_weight))/5.0;  где

N - это число оценок, поставленных автору к публикациям в данном разделе,
C - нормирующая константа, зависящая от активности пользователей, чем больше пользователи ставят оценок, тем больше должна быть константа,
m_value и m_weight - значение и вес каждой конкретной оценки, принимающей участие в расчете веса голоса.

Гиперболический тангенс отношения поставленных автору оценок к нормирующей константе учитывает активность самого автора и интерес к нему - чем больше автор публикует работ, тем больше оценок ему ставят, чем интереснее работы, тем больше оценок ему ставят. Чем больше константа C, тем медленнее tanh() стремится к единице, это значит, что при высокой активности пользователей, для достижения максимального веса голоса (или близкого к максимальному), пользователю потребуется больше усилий. При значении отношения N/C больших 2, tanh(N/C) приближается к единице и перестает влиять на средневзвешенное значение от всех оценок. Кстати, если переходить на MySQL, то можно использовать арктангенс (ATAN), но, поскольку он стремится не 1 а к PI/2, следует внести соответствующую коррекцию.  Следует также помнить, что арктангенс медленнее стремится к PI/2, нежели гиперболический тангенс к 1, поэтому придется вносить поправку и в константу.

Что касается рейтинга конкретной публикации, тут все просто — формула без учета количества оценок будет выглядеть так:

Rate = SUM(m_value*m_weight)/ SUM(m_weight);

 

За два с лишним года использования на региональном фотосайте, система оценок показала себя весьма эффективным и объективным средством оценить труды авторов. Поскольку в расчетах рейтингов не принимают участие оценки с весом менее 0.2, исключены накрутки рейтингов клонами, ибо, чтобы достичь такого веса, клонам приходится работать на равных с основными пользователями, т.е. публиковать реальные работы (воровство работ и повторные публикации пресекаются) и набирать оценки от продвинутых пользователей ресурса. Эффективность системы веса автора в том или ином разделе сайта подтвердилась, когда ведущий фотосайт страны похвалил и перенял у моего проекта эту фишку. Но, поскольку они незадолго до этого перешли на накопительную систему рейтингов, им пришлось ограничиться лишь визуальным отображением состоятельности авторов в разных жанрах.

 

Желаю удачи и объективности на ваших ресурсах.
Искренне ваш, Семен Шторкин.

 


Технодром!Защита JavaScript и CSS от копирования. Оглядываясь назад  (18 июня 2009 г. )

Добрый вечер.

Хочу поделиться с вами историей о попытке создания системы защиты скриптов (JS и CSS) от копирования. Началось все с того, что однажды я решил написать универсальную систему, которая бы позволила разработчикам web-приложений не беспокоиться за ноу-хау, воплощенные в JavaScript или CSS-коде. Систему я написал, просидев пару недель в новогодние праздники перед компьютером, но получилось она как назло, ни сколько не универсальной (после ее размещения начали приходить сообщения, что система не работает под первым апачем) и глючной (если злоумышленник использовал Оперу или сидел за кэширующей проксей – он мог достать защищенный скрипт).

Принцип работы был предельно прост. В файл .htaccess была помещена одна строчка, которая перенаправляла запросы к файлам с расширениями .css, .js и .jpg к скрипту, который, собственно и определял, откуда пришел запрос на файл. Если переменная $_SERVER['HTTP_REFERER'] содержала имя хоста, где находится защищаемый сайт, то скрипт считал, что запрос пришел от браузера, и в зависимости от типа файла генерировал нужный заголовок и передавал контент файла вопрошающему. Но, если вдруг  $_SERVER['HTTP_REFERER'] указывала на чужой сайт или, не дай Бог, вообще была !isset(), это могло означать лишь одно – скрипт пытаются либо получить по прямой ссылке с другого ресурса, либо, просто введя прямую ссылку в адресную строку. В таком случае выдавалось сообщение о доступе к защищенному файлу, а в случае с картинкой, подсовывалась заранее подготовленная, с тем же предупреждением, на случай, если кто-то разместит защищенное изображение по прямой ссылке на другом сайте.

Все было хорошо, пока не обнаружилось, что скрипты и стили можно вытащить из кэша браузера, дав им загрузиться при легальном посещении сайта, а затем по прямой ссылке получить код из кэша. В связи с этим я начал думать над альтернативными способами подзагрузки JS-скриптов и стилей к странице, и решение оказалось прямо под носом. Не знаю, как остальные, но фреймворк JQuery позволяет импортировать скрипты, минуя "<script src=…></script>", что избавит скрипт от попадания в кэш, а значит, используя систему распознавания по $_SERVER['HTTP_REFERER'], мы сможем защитить скрипт от копирования. Кстати, если $_SERVER['HTTP_REFERER'] покажет, что скрипт запрашивается браузером, можно применить какой-нибудь пакер, чтобы облегчить пользователям сайта жизнь и трафик (только надо быть осторожным с уже запакованными скриптами, могут возникнуть непредвиденные ошибки, как например, с анимационным фреймворком jTweener, который никак не хочет проходить через пакер второй раз).  Кстати, можно избавиться от jQuery и воспользоваться встроенным в современные браузеры методом XMLHttpRequest, или вызвать через AсtiveXObject соответствующий метод для старых браузеров, что позволит сэкономить немного трафика на jQuery, но не позволит сделать следующее…

Все, кто когда-либо пользовался фреймворком jQuery знают, что доступ к HTML элементам на странице осуществляется посредством селекторов, которые практически идентичны оным в CSS-файлах, и имеется метод $().css, при помощи которого можно задавать нужному элементу стиль. Так вот, чтобы избавиться от привычного метода загрузки стилей через «<link …», можно написать простенький парсер, который будет загружать в синхронном режиме файл со стилями, и затем потрошить его и сопоставлять объектам на странице соответствующий стиль. Но это, конечно, сродни извращению, ибо метод имеет много минусов, один из которых, кстати, результат паранойи – невозможность кэширования. Файл со стилем будет загружаться каждое посещение страниц сайта.  То же самое будет и с JS-скриптами, но здесь есть одно НО: подобную систему можно использовать, если скрипты содержат уникальные алгоритмы, и имеют небольшой объем, но для ширпотреба, который тоннами разбросан по девелоперским сайтам, такой чести можно и не оказывать.

Здесь были приведены лишь некоторые принципы системы защиты скриптов, если кому-то будет интересно, на их основе он сможет попробовать написать собственную систему. Ясно одно – такая система может и должна быть создана.


Технодром!Защита кода внешних скриптов JavaScript и стилей CSS от копирования  (6 января 2009 г. )

Ради спортивного интереса озадачился проблемой защиты от воровства JavaScript и CSS. Не редко люди (веб-мастера), увидев какую-либо фишку на том или ином сайте, лезут в сорсы посмотреть, как это сделано. В большинстве случаев код JavaScript и CSS хранится во внешних файлов, которые подгружаются браузером по ссылкам, и легко по ним доступны (достаточно залезть в исходник HTML, и сделать копи-паст, скажем, ссылки на CSS в адресную строку, подставив имя домена, если путь относительный). После недолгих раздумий, в голову пришла простейшая защита от этого воровства:

 

Технодром!Как заставить форму с методом POST передать вводимый параметр методом GET  (3 января 2009 г. )

При проектировании пресловутого поиска по сайту (см. предыдущий пост) возникла необходимость передавать ключевые слова через адресную строку, что и человеку нагляднее и поисковику понятнее: вдруг ему вздумается засабмитить форму поиска  каким-нибудь релевантным ключевым словом, а тут раз, и что-нибудь найдется, и вся страница поиска с ключевым словом в URL страницы окажется в выдаче (для поисковыков наличие ключевого слова в URL — очень весомый фактор). Если бы я не использовал ЧПУ (Человеко-Понятные Урл, например вместо "index.php?do=search&keyword=никон"  — "/search/никон"), проблем бы это не вызвало, достаточно было в форме указать метод GET, хотя справедливости ради, стоит отметить, что в таком случае ключевое слово, скажем, "запись" преобразовалось бы в вид "%e7%e0%ef%e8%f1%fc", что ни для поисковика, тем более для человека не понятна. 


Технодром!Регулярные выражения. Выборка целых предложений, включающих ключевые слова.  (2 января 2009 г. )

Задача: написать паттерн для функции preg_match_all, предназначенной для выборки контекста для ключевых слов при полнотекстовом поиске.

$pattern = "/(?![^\.]\s+)(?![^\.]\s+[\(\"`'])([\"`']?[А-Я][^\.\!\?]*\W+(".
            $keyword_s.
            ")\.?[^\.\!\?]+([\.\!\?][^\.\!\?]*){1,3}?)(?=\.[\s\Z])/i";


Логика: предложение начинается с заглавной буквы, но при этом, ей не может предшествовать последовательность из НЕ-точки и пробела (например, Имена внутри предложения), так же как и последовательность из НЕ-точки, пробела и кавычки (разных видов) (например, "Названия" внутри предложения), концом предложения является либо точка, либо восклицательный, либо вопросительный знаки. Чтобы избежать захвата части сокращения, типа "т.д.", "т.п.", после завершающей точки должен слдоваться либо пробел, либо конец данных. Паттерн, будучи использован в preg_match_all вылавливает все предложения (или пару-тройку предложений), где фигурирует кейворд...

 

1 . 2

Уважаемые посетители, сайт частично находится на реконструкции.

 

Блог 20

 

Про фотографию 20 (+1)

 

Про кино 3

 


Если ты фотограф бойкий — приходи на «Фото Горький»!

На «Фото Горьком» значительно облагородился раздел «Свадебная фотография в Нижнем Новгороде».

И еще!
Помните, друзья, Don't feed The Troll!



  © 2007 – 2010 Семен Шторкин
Для связи:

Все права на представленные на сайте материалы принадлежат их авторам. Копирование материалов допускается лишь с согласия автора.

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


Задворки