среда, 2 марта 2011 г.

Графическая интерпретация тригонометрических функций (graphical interpretation of trigonometric functions)

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

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

Графическая интерпретация тригонометрических функций

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

вторник, 1 марта 2011 г.

Простой RSS-ридер на PHP (Simple RSS reader using PHP)

Думаю, что такое RSS все знают, это базовый XML формат для публикации сводной информации по сайту. Сама аббревиатура RSS как раз это и раскрывает: Really Simple Syndication (RSS 2.x), что дословно переводится как «очень простой сбор сводной информации».

Допустим, у нас есть главный сайт и отдельно блог с новостями, они разнесены на разные поддомены и работают с разными БД, на разных CMS. Нам необходимо встроить в новостной блок на главной странице последние новости, опубликованные в блоге. Для этого нам вовсе не понадобится писать функций импорта, который будет обращаться к другой БД, разбираться со структурой таблиц, например, движка WordPress. Есть более простой путь это реализовать – сделать экспорт-импорт через RSS.

Функцию экспорта краткой версии новостей (постов из блога) нам писать не придётся, RSS-каналы есть в любом блоггерском движке. А вот написать клиентскую часть, на PHP, тоже не составит труда, для этого надо написать простой парсер RSS-канала.

Что же представляет из себя RSS-канал, давайте рассмотрим. Корневой элемент RSS-документа содержит единый элемент channel. Элемент channel содержит метаданные о канале, включая интересующие нас title (заголовок), language (язык), pubDate (дата обновления канала) и link (URL блога). Так же внутри содержатся статьи, заключённые в тег item. Каждый item имеет элемент link, с URL на статью, ну и непосредственно заголовок title и описание description, которые содержат простой текст.

PHP5 имеет достаточно «жирные» инструменты, для доступа к различным узлам XML, а всё благодаря SimpleXML API. Есть прекрасная функция simplexml_load_file(), которая и делает всю работу. Она не только загружает документ из указанного URL, парсит (разбирает) документ, но и ставит указатель на корневой элемент документа, которым выступает у нас 'rss'.

Приведу пример простого RSS-ридера на PHP используя SimpleXML API:

<?php
$items_to_display = 2;
$url = "http://webaurum.blogspot.com/feeds/posts/default";
$rss = simplexml_load_file($url);
if ($rss)
{
  echo '<h1>' . $rss->channel->title . '</h1>';
  echo '<br/>' . $rss->channel->pubDate . '<br/>';
  $items = $rss->channel->item;
  $item_count = 0;
  foreach($items as $item)
  {
    $title = $item->title;
    $link = $item->link;
    $ts = strtotime($item->pubDate);
    $published_on = date("Y-m-d", $ts);
    $description = $item->description;
    echo '<h3><a href="' . $link . '">' . $title . '</a></h3>';
    echo '<span>' . $published_on . '</span>';
    echo '<p>' . $description . '</p>';
    if(++$item_count >= $items_to_display)
      break;
  }
}
?>

Скрипт обращается по адресу указанному в переменной $url, считывает RSS feed, парсит документ, и выводит количество записей, ограниченных количеством, заданном в переменной $items_to_display.

Такой скрипт вообще можно положить отдельным файлом на сервере, и делать простой SSI include в обычную статичную html страницу, во всех местах, где нужен этот блок новостей.

пятница, 18 февраля 2011 г.

Функция цитирования текста для ответного сообщения (function for wrapping/quoting text on replies)

Писал приложение, в котором была необходимость создать внутреннюю почту, с возможностью отослать письмо и c возможностью на это email потом ответить. Возникла задача цитирования текста предыдущего сообщения при ответах на входящие письма, наподобие, как делают всякого рода email clients, или тот же gmail с web-интерфейсом.

Например:

> Это quoted text.
> Всё что тут было написано, было написано
> не мной, во входящем сообщении.

Можно, конечно, взять и написать примитивную логику, подобно:

str_replace("\n","\n> ","> ".$text);

Но, это плохое решение, если хочется сделать красивое повторное цитирование уже ранее процитированного текста. Обратите внимание, как это делает gmail или другие email клиенты:

> повторное цитирование:
>
>> Это quoted text.
>> Всё что тут было написано, было написано
>> не мной, во входящем сообщении.

При повторном цитировании текста,  вначале строки, возле угловой скобки ставится отступ лишь в том случае, если рядом стоит «чистый текст», ранее не обвёрнутый в кавычки цитирования. Так что без дополнительной логики, простым str_replace() тут не обойтись.

Оказалось, что найти такую функцию на PHP среди готовых решений не так-то просто. Поэтому предлагаю свой вариант реализации на PHP:

// function for wrapping/quoting text on replies
public function quote_text(&$body)
{
  $body_quote = ">";        // quotation mark
  $rewrap_body = explode("\n", $body);
  $body = '';
  $cnt = count($rewrap_body);
  for ($i=0;$i<$cnt;$i++)
  {
    if (preg_match("/^(>+)/", $rewrap_body[$i], $matches)) {
      $gt = $matches[1];
      $body .= $body_quote . str_replace("\n", "\n" . $body_quote
         . "$gt ", rtrim($rewrap_body[$i])) ."\n";
    } else {
      $body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n" . $body_quote . (!empty($body_quote) ? ' ' : ''), rtrim($rewrap_body[$i])) . "\n";
    }
    unset($rewrap_body[$i]);
  }
}

Функция quote_text принимает переменную по ссылке в качестве единственного параметра. Результатом работы этой функции будет процитированный текст, обвёрнутый в метки $body_quote, по схеме цитирования, описанной выше.

четверг, 3 февраля 2011 г.

Подсказки в input: text полях (default search text at input using jQuery)

На сайтах часто попадаются подсказки в input: text полях, например, в полях для поиска, когда написан текст «Поиск по сайту», а при вводе в него значения – он исчезает и пользователь может ввести критерий поиска.

Алгоритм работы данного функционала прост. Задается текст-подсказка (описание поля) по умолчанию, зачастую бледного цвета, а при фокусе на элементе всё очищается. При потере фокуса, если значение поля осталось пустым, то снова возвращается текст подсказка.

Самый простой способ, для «любителей» размещать весь код инлайн, реализуется при помощи JS, навесив два события onfocus и onblur на input элемент формы:

<input type="text" value="Поиск по сайту…" onfocus="if (this.value == 'Поиск по сайту…') {this.value = '';}" onblur="if (this.value == '') {this.value ='Поиск по сайту…';}" />

Есть, конечно, и много уже готовых плагинов для отображения подсказки в input полях, но мне почему-то больше всех приглянулся jquery.hint.js (как пользоваться расписано тут).  Как мне показалось, jquery.hint.js вполне удачное, маленькое и элегантное решение для такой задачи.

В любом случае, плагины уже нашёл после того, как написал собственное решение для этой задачи, да и подгружать отдельный js файл на каждую html страницу - непозволительная роскошь, из-за одного маленького input в блоке поиска. Вот этот кусочек js-кода, который с использованием jQuery навешивает подсказку для input text поля с id-шником search:

$('#search').focus(function(){
    if($(this).val() == $(this).attr('title')){
      $(this).val('').css('color','#333');
    }
  }).blur(function(){
    if($(this).val() != $(this).attr('title') && $.trim($(this).val()).length == 0){
      $(this).val($(this).attr('title')).css('color','#AAA');
    }
}).blur();

Сам элемент input выглядет следующим образом:

<input id="search" type="text" name="search" value="" title=" Поиск по сайту…" />

Скрипт использует значение, которое задано в атрибуте title в качестве текста подсказки и выводит его серым цветов в самом input. Как только пользователь ставит/убирает курсор в поле для ввода, срабатывает событие focus/blur, которое и показывает/скрывает текст подсказки и меняет CSS стиль для элемента.

Для того чтобы submit формы не происходил с нашим фейк-значением подсказки, я навесил дополнительное событие onsubmit="checkFakeSearchValues();" на элемент form. Эта функция выглядит следующим образом:

function checkFakeSearchValues(){
  var search = $('#search');
  if($(search).val() == $(search).attr('title')){
    $(search).val('');
  }
}

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

четверг, 21 октября 2010 г.

Коды кнопок добавления в социальные закладки (Share Button Codes)

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

Код формирования ссылки для сервиса Facebook:
http://www.facebook.com/sharer.php?u={ссылка на страницу}
Код формирования ссылки для сервиса Twitter:
http://twitter.com/home/?status={заголовок страницы}+{ссылка на страницу} 
Код формирования ссылки для сервиса Google Buzz:
http://www.google.com/buzz/post?url={ссылка на страницу}&title={заголовок страницы}
Код формирования ссылки для сервиса Я.ру:
http://my.ya.ru/posts_add_link.xml?URL={ссылка на страницу}&title={заголовок страницы}
Код формирования ссылки для сервиса Вконтакте:
http://vkontakte.ru/share.php?url={ссылка на страницу}
Код формирования ссылки для сервиса LiveInternet:
http://www.liveinternet.ru/journal_post.php?action=n_add&cnurl={ссылка на страницу}
Код формирования ссылки для сервиса Livejournal:
http://www.livejournal.com/update.bml?event={ссылка на страницу}&subject={заголовок страницы}
Код формирования ссылки для сервиса Memori:
http://memori.ru/link/
Код формирования ссылки для сервиса Мой Мир (mail.ru):
http://connect.mail.ru/share?share_url={ссылка на страницу}
Возможно ещё что-то упустил - смело пишите в комментариях - добавлю.

четверг, 24 июня 2010 г.

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

Читая сегодня Хабр не смог удержаться, чтобы не процитировать золотые слова, с которыми я согласен на все 100%:

Программист должен проверять результат своей работы перед передачей в тестирование
«Моё дело писать код, а их дело проверять», «Ну а их-то зачем понанимали?» — можно услышать в таких командах. Это элементарное отсутствие гигиены, работа ради «отписаться». Где вы видели журналиста, который не перечитывает свою статью перед тем, как передать её в редакцию? Если в коллективе есть программист, который проповедует такой подход, его нужно как можно скорее ликвидировать. Какой бы он ни был классный специалист.

MySQL поиск и удаление дубликатов в таблице

Как найти и удалить дубликаты в таблице MySQL? - оказывается это довольно частый вопрос, возникающий на практике, особенно когда надо установить UNIQUE constraint.

Задачу поиска дубликатов в SQL-таблице всегда можно решить таким простым запросом:

SELECT login, COUNT(login) AS cnt
FROM users GROUP BY login
HAVING ( COUNT(login)>1 );

Этот запрос вернёт все дубликаты login из таблицы пользователей. Ситуация несколько искусственна, на практике врядли будут дубликаты логинов в таблице пользователей, но для примера запроса сгодится.
Другой вариант, возможно более прост для понимания, при SELECT-е сделать простой JOIN таблицы самой на себя. К примеру, есть таблица scriptsettings с настройками какого-то скрипта, в ней нужно найти все дубликаты, где param (имя параметра) и group (логическое название группы параметров) дублируются. Запрос через JOIN примет вид:

SELECT s1.id AS id1, s1.group, s1.param, s2.id AS id2 FROM scriptsettings s1
INNER JOIN scriptsettings s2 ON s2.id>s1.id AND s1.param=s2.param AND s1.group=s2.group;

Удаление дубликатов из таблицы так же можно сделать простым JOIN таблицы самой на себя:

DELETE s1 FROM scriptsettings s1, scriptsettings s2 WHERE s1.param=s2.param AND s1.id>s2.id;

Пока писал, в голову пришёл более лаконичный и элегантный способ удаления дубликатов при помощи MySQL:

ALTER IGNORE TABLE scriptsettings ADD UNIQUE INDEX(param);

Рекоммендую

Попробуйте надёжный хостинг от Scala Hosting