Июнь 2008

Про.

29.06.2008

Про умных.
Одна из возможностей ума – возможность проводить различия. Пользуйтесь ей в полной мере, пожалуйста.

Про секрет.
А кто вам сказал, что можно подумать, что ты вожак и ты становишься вожаком?
1. Кто-то думает, что он вожак и по-этому он вожак.
2. Кто-то может знать пункт 1 и начать думать, что он вожак.
Видно разницу (смотрите выше про умных)? Мышление по второму пункту не делает вас вожаком. Оно делает вас рефлексирующим идиотом.

Про советы.
Расписывать из личной истории ничего не буду. Однако ситуацию обрисую.
Предположим, есть что-то, о чём ты думаешь так. А другой человек думает иначе. И, стараясь помочь тебе, даёт тебе совет. Получается, что тебе придётся выбрать из двух мнений.
1. Своё.
2. Другого человека.
Критериев выбора, по сути, обычно нет, выбирать приходится интуицией или жизненным опытом. И вот теперь вопрос – чьё мнение вы предпочтёте? Я, очевидно, предпочту своё. А если вы вместо своего выбираете мнение постороннего человека… Даже не знаю, наверное чмырили вас много в детстве, в себя уже не верите.

Есть два исключения.
1. Вы совет спросили сами. То есть, своего мнения нет, узнаёте чужое. Ключевое тут – спросили сами.
2. Человек для вас сильный авторитет. То есть ваш жизненный опыт подсказывает, что его слова обычно разумные, и сейчас к ним тоже стоит прислушаться.

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

Помню присказку из детства (лет 5-10) – «ему можно, а мне нельзя?». Всех детей уравнивали и если уж что-то разрешалось одному, остальным это тоже можно было. «Ты его слушаешь, а меня нет?» – из той же оперы. Помню уже в старших классах одному мачо можно было лапать всех девчонок класса. И вот после пары минут такой игры с одной он выходит из класса, а другой бойкий парень к ней подходит и хватает за груди. Его посылают в жёсткой форме. «Ему, значит, можно, а мне нельзя?». Её ответ – «Да. Ему можно, а тебе нельзя». Что, впрочем, очевидно.

Разумеется, найдутся те, кто будет втюхивать вам банальности, говоря при этом – «ты выслушай, а решение потом сам примешь». Но на Земле 6 с половиной миллиардов человек. Выслушать по туфте от каждого вы не успеете в принципе. Даже по умной мысли не успеете. К тому же, точно найдётся десять миллионов человек, которые умнее того, который вам чего-то пытается обьяснить. Лучше потратьте время на поиск этих людей.

Чем руководствоваться, когда даёшь советы другим? Теми же двумя исключениями.
1. Вас спросили? Можете сказать.
2. Вы явный авторитет для этого человека? И он и вы об этом знаете? Говорите, если есть что.
В других случаях молчите в тряпочку.

Да, кстати. Меня тоже можно не слушать. Разрешаю.

24 июня.

25.06.2008

Вчера весь рабочий день (4-5 часов) со студентом потратили на mod_rewrite.
Замечательная цепочка вышла.

Чего делает этот .htaccess? Давай всё разберём, а не только mod_rewrite -> Что такое CharsetDisable? -> Что такое кодировка? -> Почему они разные, нет, что б сделать одну. -> koi8-r и почему в ней буквы не по-порядку -> fido -> apranet -> fido и почтовые программы -> перевод из двоичной в десятичную, что б можно было обьяснить последствия потери старшего бита. -> koi8-r, windows-1251, utf-8 -> вебмастера-ламеры и DefaultCharset -> различия в интерпретации хедеров и мета разными браузерами -> CharsetDisable -> идём дальше, к третьей строчке .htaccess.

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

Но хотя бы поставили. Т.к. прогер за рабочий день умудрился сломать таблицу на полтора гига, починить, почистить винт, озаботиться нагрузкой на vds-ке, порадоваться охрененному обьёму трафа и позаниматься прочей лабудой. Из полезного он успел только рушные кейворды профильтровать (что особого смысла не имело, т.к. и так хорошие), перекодировать iconv-ом в utf и загнать в базу. Более чем солидный обьём работ.

Я же успел промониторить статсы и обьяснить кучу всякой лабуды студенту. Абсолютно адекватные сегодняшнему доходу трудозатраты. Доход этот максимален за последние 12-14 месяцев.

Сходил в магазин, поесть купить. Меня опять не интересуют цены (по-крайней мере в продуктовых магазинах). Но купить нечего. Ранее хотелось всего, не сильно, без денег желания исчезают, но периодически хотелось и того и сего и этого. А тут оглядываю магазин и взять совсем нечего. Единственно, грибов купил. Люблю маринованные грибы, к тому же не ел их с сентября.

Надо кого-то брать в руки и не работать, а результатов достигать, пора уже.

23 июня.

24.06.2008

Вот я вроде пьян, а писать всё равно не тянет.

Может микроблоггингом заняться? Выплесну вообще всё, даже все мелкие мысли, которые меня беспокоят. Интересно, чем это всё закончится.

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

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

Секрет.

24.06.2008

Здравствуйте.

Снова ночь и снова с вами в rss секретный канал.

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

В чём сила? Почему одни делают то, что хотят, получая за это то, что хотят, другие делают то, что нужно, не получая за это почти ничего?

Вы уже прокрутили мой текст до конца? Поискали ответ на главный ваш вопрос? А зачем? Хотели сэкономить 5 минут на чтение и сутки на понимание? Прожили 15, 25, 40 лет в неведении, а теперь секрет подавай быстрее, уже и ждать невмоготу? Это потому секрет, что спешащим к прозрению его давать несполезно, а не идущим – глупо. Прочих же столь мало, что они приходят к нему сами.

Чем отличается слабый от сильного? … Силой. А откуда она берётся? Она просто есть. Так что если её у вас нет, нажмите Alt+F4. Нажмите-нажмите, подожду…

Шутка. Изначально нет силы, просто думаешь, что она есть. Точнее, ты знаешь, что она есть и действуешь исходя из того, что она есть. Хотя её нет. Если продолжаешь действовать, сила набирается сама.

Ум. Ума тоже нет. Просто когда всё выходит, ты думаешь, что умный. Не выходит – думаешь, что глупый. Хоть ты и не меняешься. (Однако, если когда не выходит, а ты думаешь, что всё равно умный, значит ты дурак, каких мало).

Чёрт. Понт кончился, жаль. Останетесь вы без секрета. Ну то есть, с Секретом, конечно, но идею придётся высказать в двух словах.

Принцип стаи. Кто-то же должен быть вожаком. Поэтому если остальные не против (а они обычно не против), вожак тот, кто думает, что он вожак.

20 июня.

21.06.2008

Чем бы сегодня посотрясать воздух?

Ну, во-первых, мы в сотню вошли на умаксе. А точнее, на гордом 99-м месте тусуемся. Реально тащусь от топов. Первая сотня – и такие копейки. Впрочем, я уже год назад никому не советовал в доры идти – в банковской сфере входящий в топ 100к больше зарабатывает, чем в дорах входящий в топ 100. Хотя, конечно, первый двадцатник в каждой партнёрке на деньги не жалуется. Вы только прогеру и студенту (назовём его так) об этом не говорите, а то ещё разочаруются и работать перестанут.

Во-вторых, у нас совсем не хватает ресурсов вычислительных. Сервак брать что-то ссыкотно, мы ж без проксей, на паре vds-ок как-то лучше. Но vds-ок уже две + сервачок маленький. Брать 4-ю тачку – за ними следить тяжело. Оптимизировать скрипты – как-то некуда.

В индексе у нас, по грубым прикидкам (взял случайные доры, посмотрел, сколько в гугле), 300к страниц. Вряд ли больше, гугл, сволочь, умнеет на глазах, где это видано, что б наши доры банил? Ан нет, начал, за последний месяц забанил кучу. Было бы тысяч 400, если не больше. Сколько трафа с этого, говорить не буду. Очень мало. Соотношение страницы\хиты в день даже хуже, чем у этого блога, который под кеи ни под какие не заточен. Полагаю, что текст дерьмо. Дайте мне нормальный текст и можете рассчитывать на треть трафа.

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

Рассуждения о языке. Часть 2.

20.06.2008

Чем плох язык mysql? Зачем вообще каждый фреймворк содержит обвязку, интерфейс доступа к данным?

cake.
findAll(«(`time`>».(time()-3600).»)AND(`status`=’0′)», array(«user»,»title»),»time», 10, 1, 0);

wordpress.
Залез в wordpress (конечно, не фреймфорк, но стало интересно, как там), наткнулся на функцию mysql2date, испугался, резко закрыл. Селекты в wp написаны непосредственно на sql, однако для update и insert сделаны тупые обвязки.

symfony
$c = new Criteria();
$c->add(tablePeer::TIME, time()-3600, Criteria::GREATER_THAN);
$c->add(tablePeer::STATUS, 0);
$c->addAscendingOrderByColumn(tablePeer::TIME);
$c->setLimit(10);
$c->setOffset(10);
$data = tablePeer::doSelect($c);

Zend Framework
$select = $db->select()
->from(«table»,array(‘user’, ‘title’))
->where(‘`time` > ?’, time()-3600)
->where(«`status` = ‘0′»)
->order(«time»)
->limit(10, 10);
$t = $db->query($select);
$result = $t->fetchAll();

WACT
К сожалению, ничего интересного в стилях запросов нет. Запрос можно сделать через метод execute класса DBC.
Единственно, что примечательно, это документация и количество классов. Если б меня попросили сделать проект на WACT, используя его возможности и платили 100к баксов, я бы повесился. И делать бы не решился и отказаться нереально. 20 (?!?) классов для работы с бд, которые чёрт пойми что инкапсулируют, без какого-либо нормального описания.

То же самое на mysql
mysql_query(«SELECT `user`,`title` FROM `table` WHERE (`time`>».(time()-3600).») AND (`status`=’0′) ORDER BY `time` LIMIT 10,10″);

Риторический вопрос. Где код читабельнее и понятнее? Ну и стоило огород городить авторам фреймворков? Сначала ты думаешь, какой сделать запрос, потом переводишь его в значки для фреймворка. Никакой дополнительной логики они не превносят. Но делают несколько короче некоторые стандартные действия.

Зачем это делается, понятно. Структура базы никак не связана с логикой приложения. В попытке связать приложение с базой чем-то логичным и рождаются монстры, как у symfony (интересно, конечно, что они курили, когда это придумывали, но я бы это курить не рискнул, слишком сильное). Но потери при этом намного больше, чем выигрыш.

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

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

Рассуждения о языке. Часть 1.

20.06.2008

Наконец-то написал регалку.
Просто кошмар, сколько положено времени на 5,09 кб кода.

К сожалению, GetUrl убирает все проблемы с процессом регистрации, если сайт один, но когда есть два десятка похожих, но всё же разных сайтов, проблемы возникают по новой, из-за того, что один код (не geturl, а мой скрипт) должен обработать кучу разных вариантов. Один\два этапа регистрации, несколько разный набор полей и язык (ладно, это самое простое, тут автоматом), наличие подтверждения по мылу и некоторые другие мелочи, которые я уже не помню. По уму, надо было всё записывать, может программить научился бы когда-нибудь, если б анализировал после. Сейчас смотрю на код, и он выглядит вполне себе простым, однако часа три я грохнул на одну проблемку, которую сам себе создал. О ней и хочу поговорить.

Но для начала – об обвязках. Кто писал обвязку для Curl? Почему-то думается, что многие. Мой первый вариант постепенно разрастался и превратился в чудовище:
function get_curl($host,$cookie=»,$post=»,$header=0,$referer=»,$follow=0,$useproxy=true,$image=false)

Куки, текст пост-запроса, выдавать ли заголовки, реферрер, follow_location, брать ли прокси из глобального массива. А последняя опция вообще замечательная. Все странички у меня распаковывались (т.к. сервакам отдавался заголовок о том, что принимаю gzip), а потом переводились в кодировку windows-1251. Картинки, понятное дело, убивались напрочь. Пришлось ввести очередной параметр.

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

Пришлось переписать. Правда, ещё кучи возможностей не хватает. Заголовки серверам отдаются русские, а надо бы выбор сделать (будет параметр при инициализации обьекта и никакой возможности переопределения. Надо – создавай новый экземпляр), прокси (проверка на наличие $this->proxy и никаких новых параметров), на картинках тоже не тестировал, но это определяется по заголовкам, а никак не параметром функции. Сейчас выходит один опциональный параметр у $this->Get() и два – у $this->Post().

Вообщем, после GetRand, к которому вообще претензий нет и GetUrl, который потребуется позже немного расширить, я взялся за Storage – класс работы с данными. По сути – обвязка к mysql. Написал, всё красиво. Работа выглядит так:
$s=new storage("accounts");
if (!$s->init()) {$s->make("site(50) login(20) pass(20) email(30) url(50)");$s->init();}
$c=new GetUrl();
$c->Get($v);
if(!@$c->parseForm()) die('err form');
$c->formvars['bla']='value';
$c->fillForm($r);
$c->Post();
$s->data['site']='http://'.parse_url($v,PHP_URL_HOST).'/';
$s->data['login']=$c->login;
$s->data['pass']=$c->pass;
$s->data['email']=$c->email;
$s->save();

$s=new storage("accounts");
$s->init();
$s->loadRand(0,10); // с каким статусом (можно false - без учёта статуса) и сколько селектить
while($s->pop()){
// что-то делаем.
$s->changeStatus(1);
}

Возможно имеет смысл перекидывание данных из GetUrl в Storage сделать внутренним, но я не придумал понятный универсальный способ это сделать. Реализовывать поддержку частностей не хотелось бы.
while($s->pop()) для того, что б не делать десять loadRand (то есть, 10 запросов к базе).

А про то, как на самом деле нужно писать правильные обвязки к базам, в следующей серии.

19 июня. Деньги.

19.06.2008

Мы в умаксе в начале второй сотни в топе.

А ещё – не работали сегодня. Да и вообще я плохо работаю, написание банального скрипта тяну уже дней 5.

Авторитет.

17.06.2008

Напишу про авторитет. Наверное тезисно, ибо строить связный текст не в настроении.

С возрастом человек думает, что умнеет. Не важно, так ли на самом деле, но думает, это точно.

В каждый конкретный момент времени человек думает, что вот сейчас-то он умный. Особенно, когда что-то понял жизненное.

Сила эго не даёт согласиться с первым утверждением в отношении другого человека. (не суть, верное оно или нет для того человека, не соглашается всё равно). Даже если он старше, всё равно я умнее (впрочем, часто это так и есть).

Авторитет – функция от усилий по убеждению других в своём авторитете. Если ты одного убеждал, другого нет – авторитет у первого будет выше. Разумеется, фразой «я знаю, слушайте!» пользуются в основном люди с коэффициентом ума около нуля. Однако если просто говорить, что знаешь – это работает. (Если задавать вопросы – это работает лучше).

Известность != авторитет.

Авторитет != известность.

Показать человеку что-то вроде «вот я же тебе говорил» – работает изумительно. Покажешь так, как надо – получишь большой плюс. Покажешь не так – на авторитете можешь ставить крест.

Сегодня, кстати, показал неверно.

Искуственная нейронная сеть, пример.

17.06.2008

Покопался в гугле. Не нашёл ни одного вменяемого примера нейронной сети. Что б хоть понять, что это за лабуда такая. На вики есть пространные обьяснения, на специализированных сайтах умные теории с выкладками и формулами из странных значков. А на читабельном языке (php\python) ничего не нашёл.

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

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

Алгоритм обучения нейронной сети.

/*
  Пример нейронной сети, которая учится отличать маленькие русские буквы от всех остальных.
  Язык - php.
  Пожалуйста, не удаляйте этот текст при копировании. (c) Секрет. Realme.ru
*/
class S { // глаза сети. Каждый глазик видит свою часть данных.
  var $input=0;
}
class A { // нейроны
  var $inputWeights=array(); // нейрон связан с каждым глазом с разной силой.
  var $active=0;
/*
  нейрон получает от всех глаз данные, единицу или ноль. Умножаем на силу связи глаз-нейрон, считаем среднее, сравниваем с 0.2 - это число выбрано интуитивно. Если поставить 1, сети потребуется в 4-5 раз больше обучающих примеров.
*/
  function think($s){
    reset($this->inputWeights);
    $this->active=0;
    while($temp=each($s)) {
       $temp2=each($this->inputWeights);
       $this->active+=($temp[1]->input)*$temp2[1];
    }
    $this->active/=count($s);
    $this->active=($this->active > 0.2);
  }
/*
при создании нейрона связываем с глазами случайным образом.
*/
  function __construct($s){
    $this->inputWeights=array();
    reset($s);
    while($temp=each($s)) {
       $this->inputWeights[]=mt_rand(0,100)/100;
    }
  }
}

class R {  // Решатель. Смотрит, что пришло от нейронов, считает среднее, выдаёт ответ.
  var $answer=array();
  function think($a){
    $this->answer=array();
    while($temp=each($a)) {
       $this->answer[]=$temp[1]->active;
    }
    return ((array_sum($this->answer)/count($this->answer)) > 0.5);
  }
}

$s=array();
$a=array();
for($q=0;$q<8;$q++) $s[$q]=new S(); // В символе восемь бит. Сделаем 8 глаз.
/*
 Cделаем 20 нейронов. Собственно, для решения этой задачи достаточно одного нейрона, он нормально обучается. Стоит 20 просто для примера.
*/
for($q=0;$q<20;$q++) $a[$q]=new A($s);
$r=new R(); 

$correct=0;
for($ww=0;$ww<10000;$ww++){ // просто цикл.

$input=rand(0,255);
/*
  Буква ё сложная для обучения, у неё код символа далеко от остальных русских букв.
  Поэтому увеличим частоту её выпадания.
*/
if (rand(1,100)==1) $input=ord('ё');
// правильный ответ нужен для процесса обучения.
$answer=((($input<=ord('я'))AND($input>=ord('а')))OR(ord('ё')==$input));
// ну или preg_match('/[а-яё]/',$input);, кому так понятнее.

for($q=0;$q<8;$q++) $s[$q]->input=($input & pow(2,$q)) >> $q;  // глазки смотрят.
for($q=0;$q<20;$q++) $a[$q]->think($s); // нейроны думают.
/*
  Процесс обучения.
  Для каждого нейрона смотрим, ответил ли он правильно.
  Почему нейрон ошибается? Потому что не знает, от каких глаз данные важнее. Например, если старший бит ноль, то русской буквой символ точно быть не может. Этого нейрон не поймёт, но научиться, что данные от старшего бита важнее, он может. Изменяем силу связи с теми глазами, которые видели единицу. Единицы от одних глаз станут влиять на результат сильнее, от других - слабее.
*/
for($q=0;$q<20;$q++) if ($a[$q]->active != $answer) {
  foreach($a[$q]->inputWeights as $k=>$v){
    if ($s[$k]->input) {
      $a[$q]->inputWeights[$k]+=(($answer)?0.01:-0.01);
    }
  }
}
$think=$r->think($a);
// считаем, сколько раз подряд ответили верно.
if ($think == $answer) {
  $correct++;
} else {
  $correct=0;
}
echo (int)$think;
echo (int)$answer;
echo ' '.chr($input).'';
if ($correct>500) {
  echo "Для обучения сети потребовалось $ww обучающих примеров.";
  break;
}
}

var_dump($s);
var_dump($a);
var_dump($r);