Блог Обо мне Храню Читаю Ем 99  

страница № 120



HTC X7500

HTC X7500 (29.35KB)


Купил себе HTC X7500 на день рождения.

VGA (640x480), дисплей 5 дюймов, 262144 цветов, 128Мб RAM, 256Мб ROM, встроенный microdisk в 8Гб (если не хватит, если возможность вставить flash-карту miniSDHC до 32Гб), есть съёмная QWERTY-клавиатура, GPS, WiFi, Bluetooth, TV/VGA-выход, две камеры (3 мегапикселя), одна из них — со вспышкой, встроенный телефон (3G, EDGE, HSDPA, GSM, UCDMA).

Поставил Windows Mobile 6.1, пока всё нравится. Есть масса недостатоков, но я рад, что выбрал систему на Windows, под неё есть всё, что душе угодно.

Основные паттерны использования: MP3-плеер, читалка книг, выход в интернет (браузер, почта), GPS-навигатор, телефон, камера для заметок.

темы: gadget
26.09 16:42
26.09 16:42


Анекдот про Python

Приходит первый элемент итератора к доктору.

— Доктор, меня все игнорируют.
— next

Смешно?

темы: python, joke
25.09 18:41
25.09 18:41


noindex в поисковике Sphinx

В замечательном поисковике Sphinx (кстати, очень рекомендую, есть биндинги в Ruby, Python, PHP, Perl), как известно, нет поддержки тега NOINDEX. Я два дня был на конференции РИТ: высокие нагрузки, ради доклада по Sphinx (доклад читал автор) встал в восемь часов, зато узнал, общаясь с автором в кулуарах, несколько полезных трюков.

Один из них — как сделать NOINDEX, простой и очевидный, но я не успел до него догадаться. У Sphinx есть опция html_remove_elements, которая позволяет указывать содержимое каких HTML-тегов следует игнорировать. Обычно там указаны SСRIPT и STYLE, добавляем туда NOINDEX и результат достигнут.

P.S. Dizzy57, привет!

темы: webdev, sphinx
23.09 15:27
23.09 15:27


Киев

Съедили в Киев на выходные. Красивый, (относительно) чистый, добрый, старинный город. Оооочень много красивых старых зданий, всё (по сравнению с Москвой) очёнь дёшево. Украинская речь понимается на слух без каких-либо проблем, но большая часть людей в Киеве разговаривает по-русски.

Украинский очень милый язык («подарункы», «кава» и «смачно» ласкают слух), первый день понравился больше всего, на второй день был ливневый дождь, попытка посушиться в жлобском отеле и холодный и поломанный поезд №4, который почему-то называют «фирменным».

Из приятных мелочей — множество растений (каштаны, о!), в переходах — куча цветов, которые не продаются у нас, и интересная фишка — на телефоне, где высвечивается информация о базовой станции, в метро показывается название станции метро (проезд в метро стоит 50 копеек, т.е. около 2.5 российских рублей!).

В итоге, поездка (включая номер в отеле, который мы сняли, потому что нам нужно было посушиться), с дорогой, едой и посещениями музеев, обошлась около 6500 рублей на человека.

Юра, спасибо что позвал!
22.09 18:30
22.09 18:30


Когда начинается старость?

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

до 15 лет — детство
16—30 лет — юность
31—45 — молодость
46—60 — зрелость
61—75 — пожилой возраст
76—90 — старческий возраст
91 и старше — долгожители

Я недавно завязал с юностью и шагнул в молодость.
19.09 19:20
19.09 19:20


Python iterstrip: itertools для чайников

Я общел рассказать как работает конструкция, которую мы, в итоге, в Ваней породили для тех, кто не знаком с itertools в Python. Для начала формулировка задачи: есть список (list) последовательности строк. В нём все поледовательности пустых строк, длиной более двух надо заменить на одну пустую строку, а пустые строке в начале и конце списка удалить.

Из ['', 1, 2, 3, '', '', '', '', 4, '', ''] мы должны получить аккуратное [1, 2, 3, '', 4].

Код, который получился в итоге, с некоторыми упращениями, выглядит вот так:
return list(
            chain(
                *(
                    [[''], grp][item or len(grp)<3]
                        for item, grp in (item, list(grp))
                            for item, grp in groupby(chain(['']*3, letter, ['']*3), lambda x:x))
                )
                )
        )[1:-1]
Заголовок функции я приводить не буду, чтобы не плодить отступы, в функцию входит параметр letter, который содержит обрабатываемый список, возвращается, соответственно, обработанный список. Я постараюсь обойтись без определения генераторов и итераторов, просто представьте, что данные «текут» по функциям, что позволяет их обрабатывать очень экономично, даже если они бесконечные.

Центральное место этой программы, функция groupby группирует входящий список, пользуясь результатом функции, записанной во втором параметре, как признаком группировки. Список не пересортируются, в группы объединяются данные, идущие подряд. На выходе появляется список туплов (tuples), состоящих из результата работы функции, применительно к группе и списка (точнее объекта _grouper) объединённых результатов:

[(x, list(k)) for x, k in groupby([1,2,3,-4,-1,2], lambda x: x>=0)]

Я тут прошёлся по списку [1, 2, 3, -4, -1, 2], объединяя его значения при помощи функции x>=0. Т.е. все подряд идущие числа с одинаковым знаком будут сгруппированы. Получится вот что:

[(True, [1, 2, 3]), (False, [-4, -1]), (True, [2])]

сверху на groupby я навесил генератор — по сути, цикл, который проходит по всем элементам groupby, раскладывая тупл (tuple) в два элемента — x и k. Этот цикл для каждой итерации возвращает результат, форма которого записана перед циклом. Это тупл, состоящий из двух элементов: k (где записан результат группировочной функции) я оставил неизменным, а объект _grouper я преобразовал в список.

Функция chain объединяет итератор, для простоты можно пока представить, что она склеивает списки. Конструкция «['']*3» эквивалентна ['', '', ''] — трём пустым строкам. Таким образом, строка «for item, grp in groupby(chain(['']*3, letter, ['']*3), lambda x:x))» делает следующее: по итератору, состоящему из трёх пустых строк, нашего списка letter и ещё трёх пустых строк, проходит функция groupby, которая группирует элементы по самому простому признаку: «lambda x: x», т.е. группируются одинаковые элементы, далее по получившемуся списку туплов проходит цикл, каждый тупл раскладывается на два элемента: item и grp, где из grp делается список (при помощи вызова «list»).

Выше находится конструкция «[ ['', grp] ][item or len(grp)<n]», выглядит она страшно и кажется «птичим языком», но на деле широко применяется в самых разнообразных языках, включая PHP, сейчас я её объясню. Результатом «item or len(grp)<n» будет True или False. Условие, на мой взгляд, очевидное: если строка не пустая или последовательность меньше 3, то True. True и False используются как индекс списка и выбирают, соответственно, первый или нулевой элемент массива, т.е. список, содержащий пустую строку или группу символов.

Цепочка такая:

Иcходная последовательность:
['', '1', '1', '', '', '', '3', '', '5']
Добавили с двух сторон пробельные строки:
['', '', '', '', '1', '1', '', '', '3', '', '5', '', '', '']
Прошли groupby и генератор:
[ ('', ['', '', '', '']), ('1', ['1', '1']), ('', ['', '']), ('3', ['3']), ('', ['']), ('5', ['5']), ('', ['', '', '']) ]
Прошли через условие на птичьем языке:
[ [''], ['1', '1'], ['', ''], ['3'], [''], ['5'], [''] ]

Далее у нас стоит chain, который принимает аргументом всё, что получилось, но с префиксом звёздочка. Chain, как я писал выше, объединяет итераторы, для простоты мы считаем, что это, с натяжкой, эквивалентно объединению списков. У нас есть список, содержащий списки. Хорошо бы эти списки склеить.

В PHP есть функция call_user_func_array, которая принимает на вход два параметра: фукнцию, которую надо вызывать и массив её параметров. В PHP я бы склеил эти списки вот так: call_user_func_array('array_merge', $letter). В Python делается всё то же самое, только синтаксис этого вызова другой: func(*args). Это означает, что когда будет вызвана функция func, список args станет списком её аргументов, chain принимает на вход любое количество элементов.

Таким образом мы получим вызов
chain(*[ [''], ['1', '1'], ['', ''], ['3'], [''], ['5'], [''] ]), что эквивалентно
chain([''], ['1', '1'], ['', ''], ['3'], [''], ['5'], ['']). На выходе мы получим следующий итератор, который как список выглядит вот так:
['', '1', '1', '', '', '3', '', '5', ''].

Легко заметить, что какое бы количество пробельных строк не было по краям, в конце всегда остаётся по одной. От них нам нужно избавиться. Делается это просто, в Python есть срезы, которыми я и пользуюсь: список[1: -1] означает «вернуть список с первого элемента, убрав ещё один с конца». В PHP это будет array_slice($list, 1, -1).

В итоге ['', '1', '1', '', '', '3', '', '5', ''][1:-1] даст нам искомое: ['1', '1', '', '', '3', '', '5'].

Мда. Что-то как-то не очень всё просто получилось :)

темы: webdev, python
19.09 18:50
19.09 18:50


Спираль истории: @font-face

Когда на земле было всего два браузера — IE и Netscape Navigator, они оба поддерживали разные виды внедряемых шрифтов. IE поддерживал своё, но бесплатное решение, Netscape использовал платное решение от BitStream. В те времена вебмастера интересовались возможностями браузеров ещё меньше, чем сейчас и этой возможностью мало кто пользовался.

Хотя в Татарстане, где я жил, технологию внедряемых шрифтов использовали очень часто для поддержки татарского алфавита на сайтах.

Суть технологии очень проста: шрифт подключается как любой внешний ресурс (другие примеры — графика, CSS, JS) и им можно писать что-то на странице. Netscape помер, а решение Microsoft всё-таки вошло в CSS, хотя и в изменённом виде.

На данный момент, оказывается, во всех браузерах, включая альтернативный, на какой-то стадии есть поддержка внедрения шрифтов (@font-face): Хочу сразу сказать почему я считаю, что у IE наиболее удачное решение: разработчик может указать какие именно знаки оставить в шрифте, что даёт огромную экономию по размеру. Другие же браузеры поддерживают шрифты в форматах TrueTypeFont и OpenType. Легко представить к чему это приведёт: подключать будут гигантские Unicode-шрифты, содержащие всё что только возможно, вплоть до вымерших алфавитов.

темы: webdev, css
19.09 15:31
19.09 15:31


За что я люблю свою жену

Диалог по SMS:

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

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

P.S. Ссылка от Кости Коломейца: картонный папа.
18.09 19:13
18.09 19:13


PHP: мануалы читать необходимо

Я изучаю новый язык следующим образом: сначала всегда полностью читаю руководство (вот с «Пайтоном» мне не повезло — в руководстве, которое я выбрал, об itertools было упомянуто вскользь), потом уже пробую что-то писать, изредка показывая куски кода для критики.

Конечно, руководство полностью наизусть я не помню, но зато всегда помню, что «что-то где-то было», это частно избавляет от изобретения велосипедов.

В свежей статье на «Хабре» — один из подобных велосипедов:
function uptime() {
	$fp=@popen('uptime','r');
	$s=@fgets($fp);
	@fclose($fp);

	@preg_match('#load average: ([0-9\.]+)#', $s, $m);
	return $m[1];
};
Во-первых, в PHP есть функция sys_getloadavg, во-вторых, (если версия PHP ниже 5.1.3) эту информацию можно добыть значительно проще: «(float) substr(strstr(`uptime`, "load average:"), 13)», в третих, можно (на Линуксах) читать /proc/loadavg.

В этой статье вообще масса забавного: в разделе «временные припарки», где index.php заменили для снятия нагрузки, для чего-то использовался print, вместо того, чтобы выдать сообщение голым html, memcached используется как база данных и так далее.

темы: webdev, php
18.09 13:46
18.09 13:46


Разум проснулся: Python itertools

С подсказки Вани в комментариях к предыдущему посту посмотрел itertools. И вот что я вам скажу товарищи. Если за что-то и любить «Пайтон», то за итераторы и генераторы (а ещё за суперпозицию функций, но это отдельная тема), а переписанный код из предыдущего поста выглядит теперь вот так:
from itertools import groupby, chain,  starmap

def ntrim(letter, n=3, replby=1):
	return list(chain(
			*starmap(
				lambda item, grp: [grp, [''] * replby][item and len(grp)>=n],
				((item, list(grp)) for item, grp in
					groupby(chain(['']*n, letter, ['']*n), lambda x:x)
				)
			)
		))[replby:-replby]
Я модифицировал исходную задачу: последовательности из трёх и более пустых строк заменяются на одну, пустые элементы в начале и конце списка удаляются. И ещё я прибил ленивый триплет из Python 2.5, потому что на домашнем ноуте у меня 2.5, а на рабочем сервере будет 2.4. Надо, кстати, будет посмотреть не цепляется ли он как-то через __future__. Завтра посмотрю, сейчас — спать.
17.09 00:23
17.09 00:23


Сон разума: снится Python

Вот что родил мой мозг в текущем проекте:
def trim(letter):
    SKIPLEAD = object()
    SKIPINNE = object()

    todelete, stage, skipped = [], SKIPLEAD, 0

    for idx, blank in enumerate([x == '' for x in letter]):
        if stage == SKIPLEAD:
            if blank:
                todelete.append(idx)
            else:
                stage = SKIPINNE
        else:
            if blank:
                skipped += 1
                todelete.append(idx)
            else:
                if 0 < skipped < 3:
                     todelete = todelete[0:-skipped]
    return [letter[idx] for idx in set(range(0, len(letter))) - set(todelete)]

16.09 17:16
16.09 17:16


Питон — это такая змея

Меня удивляет, что некоторые программисты со рвением называют язык программирования «Пайтон» «Питоном». Безотносительно истории происхождения названия, должен заметить, что названия не переводятся. Ruby никто не называет «Рубином», язык «Си» языком «Вэ», а SmallTalk «Непринуждённой Беседой».

Python — это «Пайтон».

темы: python
16.09 13:01
16.09 13:01


Расширение RSS: «Яндекс», поиск по блогам

«Яндекс» выпустил специальный RSS-плагин к популярным PHP-форумам для сервиса «Поиск по блогам». Автор — известный PHP-программист Дима Смирнов. На медленно стухающей «Хабре» немедленно появились те, кто «не читал, но обсуждают».

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

Сервис поиска по блогам «Яндекса», как вытекает из названия, индексирует блоги и многим кажется, что на этом его отличие от основного поиска заканчивается. Как бы не так! Поисковик «Яндекса» индексирует HTML-страницы, поисковик поиска по блогам индексирует RSS, а в RSS сайты отдают какое-то небольшое количество последних постов.

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

Дима с командой поиска по блогам придумали очень простую и эффективную штуку. RSS — формат расширяемый, для него уже масса расширений, это нормальная практика. Если заглянуть в RSS любого диминого сайта, то можно увидеть, что в нём упоминается новое расширение: «ya:more», т.е. новый тег «more» в пространстве имён «ya».

Для того, чтобы его использовать, в тег «rss» нужно дописать строку «xmlns:ya="http://blogs.yandex.ru/"» и вставить тег «ya:more», содержащий URL, указывающий на RSS, содержащий предыдущие N постов:
<rss xmlns:ya="http://blogs.yandex.ru/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">
<ya:more>http://coprophagous.ru/rss/posts/740</ya:more>
Получается много связанных этим тегом документов, в последнем из которых тег «ya:more» отсутствует. Таким образом индексатор поиска по блогам может пройтись по всем постам блога и проиндексировать их. СЕОшники должны оценить.

Заслуга Димы заключается не только в том, что он придумал простое решение проблемы и мотивировал команду поиска реализовать её, но ещё и в том, что он написал готовые плагины, которые добавляют эту функциональность для трёх популярных форумов на языке PHP: PHPBB, vBulletin и IP.Board.

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

темы: webdev, yandex, rss
15.09 23:21
15.09 23:21


То, что мешало плохому танцору, теперь у музыканта

тестигитара (49.58KB)


Не знаю что это, но выглядит забавно. Нашлось поиском в «Яндексе» по какому-то из запросов, исходный сайт не отвечал.
15.09 00:28
15.09 00:28


The reports of my deatch are greatly exaggerated.

Пока я праздновал свой день рождения ЖЖисты из сообщества «kazan», модератором коего я являюсь, похоронили президента республики Татарстан Минтимера Шаймиева. Якобы президент умер в Кемере, где отдыхал с семьёй.

Главную «виновницу» переполоха, которая первой поделилась новостью, уже вызывали в «куда следует». Центральные издания информацию опровергают, а в качестве источника сведений о кончине президента цитируют, в основном, ЖЖ Ирека Муртазина, который поделился новостью позднее, но зато является заметной фигурой в официальных кругах. Хотя кое-кто уже цитирует официальный некролог одной из казанских газет.

Теорий у народа на этот счёт две: президент умер или кто-то намеренно распускает «дезу», чтобы сыграть на падении акций предприятий Татарстана.
13.09 22:55
13.09 22:55

страница № 120

Евгений Степанищев (imbolk@gmail.com)
t=3.969