Обновить
57
1.8

Пользователь

Отправить сообщение
А еще есть Netsted Intervals, у которых этих недостатков меньше, благодаря тому, что left и right задаются рациональными числами. Статья:
www.dbazine.com/oracle/or-articles/tropashko4, математика: arxiv.org/abs/0806.3115v1
Можно багрепорт? :)
  """Использовать регулярку не хотелось бы для одного поиска"""
    translated_text=answer[index:answer.find("</div", index)]
    translated_text=replace_html_mnemonics(translated_text)
    translated_text=translated_text.decode("koi8-r")

А почему koi8-r? В answer есть указание на кодировку страницы в виде.
<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>

Мне вот такое выдал… Дергайте от charset= и до " и передавайте значение в translated_text.decode(). Хотя идеологически правильнее было бы декодировать сам answer, прежде чем разгребать.
В убунте еще StarDict, умеет переводить, используя google. Нужно приложить вот такой патч:
#! /bin/sh /usr/share/dpatch/dpatch-run
## google.dpatch by  <funca@localhost>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.

@DPATCH@
diff -urNad stardict-3.0.1~/src/stardict.cpp stardict-3.0.1/src/stardict.cpp
--- stardict-3.0.1~/src/stardict.cpp	2007-11-05 08:39:51.000000000 +0500
+++ stardict-3.0.1/src/stardict.cpp	2009-08-22 23:36:01.000000000 +0600
@@ -1943,7 +1943,7 @@
 			}
 		}
 	} else if (engine_index == 0) {
-		#define GoogleTranslateStartMark "<div id=result_box dir=ltr>"
+		#define GoogleTranslateStartMark "<div id=result_box dir=\"ltr\">"
 
 		char *p = g_strstr_len(buffer, buffer_len, GoogleTranslateStartMark);
 		if (p) {

сразу подумалось об обратном — модуле к fuse, монтирующим форумы (phpbb2, скажем) как файловую систему. %)
база не позволяет сделать поле `Path` длиннее 1000 символов (#1071 — Specified key was too long; max key length is 1000 bytes), что значит, что, если у нас средняя длина ID будет 4 символов мы не сможем делать деревья глубже 1000/(4+1), то есть самое глубокое возможное дерево в таком случае — 200 элементов. и 166 при средней длине ключа 5 цифр (если на сайте более 50000 комментариев в среднем)

Materialized path можно строить иначе. В таблице, описывающией иерархию будем хранить ссылку на объект (ElemId) и путь (Path).
ElemId, Path

В каждом сегменте пути будем записывать номер узла в поддереве по порядку (а не ElemId). И сделаем размер сегмента пути фиксированной длины (скажем 3 символа), чтобы сортировка по такому пути выдавала нам дерево в естественном порядке.
"000" -- первый уровень
"000000" -- второй уровень
"000001000"
"000001001"
"000002"
"001"
"002"

Уровень узла в таком дереве вычисляется по формуле Level = strlen(path) / 3.

Сейчас в каждом поддере можно создать не более чем 10^3 = 1000 узлов. Но если увеличить основание системы счисления, то емкость дерева возрастет. В php функция base_convert позволяет увеличить базу до 36. Т.е. емкость уже составит 36^3 = 46656. Для комментов этого достаточно. И размер пути получается небольшим. 1000 символов хватит для кодирования 1000/3 = 333 уровней. Ну, а скажем путь к комменту на 20-м уровне составит 20*3 = 60 символов. В MySQL есть аналогичная функция. Поэтому всю математику связанную с пересчетом пути при модификации дерева можно записывать прямо в запросе.

Конкретно под комментарии стратегию создания пути можно еще оптимизировать. Понятно что, чем глубже уровень, тем меньше «ветвистость» комментов. Максимальное число комментов стоит ожидать лишь на первом уровне. Поэтому только у первого сегмента пути оставим длину 3 символа. А остальные сегменты можно сократить и до 2-х. 1296 комментов на подуровне хватит заглаза. Таким образом путь к комменту на 20 уровне будет составлять всего 41 символ.
"000" -- первый уровень
"00000" -- второй уровень (2 символа в сегменте)
"0000100"
"0000101"
"00002"
"001"
"002"

Да, нужно обязательно ограничить длину индекса в таблице MySQL, для поля Path. Это не сильно скажется на производительности, зато позволит прилично сэкономить по памяти.
нитки/процессы vs событийные.
вот что интересно. если приложение чисто вычислительное (рассчитывает координаты сферического коня в вакууме, или отдает «Hello, World!» :) ), то использование ниток или процессов производительности не прибавляет, а даже наоборот. процессор все равно один и лишние переключения контекста ни к чему. другая картина получается, когда приложение часть времени проводит в ожидании (синхронного ввода-вывода, результата sql запроса, или стоит таймаут на пару секунд :) ). в это время процессор не задействован, сервер может обрабатывать другие соединения. картина производительности будет иная.
серверы, использующие событийную модель, как лицензия gpl: заражают ей все приложение. :)
вот любопытно. если разделить transfer rate (клобайт/сек) на request per seconds, то получим килобайт / запрос.
1014,09	/ 3484,67	0,291
754,55	/ 3140,87	0,240
720,04	/ 3262,5	0,221
654,98	/ 1202,8	0,545
639,66	/ 2651,86	0,241
171,23	/ 712,78	0,240

интересно, что у «flup 2 процесса / 5 тредов» эта величина больше чем у других конфигураций в два с небольшим раза. он что, строчку «Hello World!» отдает в юникоде? =)
Вот так, через дом2:
<a id='target'>click me</a>

$('#target').get(0).addEventListener('click', function(e) { window.console.log('test1') }, false)
$('#target').get(0).addEventListener('click', function(e) { window.console.log('test2'); throw "Error1"; }, false)
$('#target').get(0).addEventListener('click', function(e) { window.console.log('test3') }, false)

...
test1
test2
test3
Error!

Логика диспетчеризации запроса для получения свойства с использованием прототипа, примитивна до безобразия:
— Эй, Объект, гони сюда свойство property!
— Хм… а нету… (если есть, был обязан выдать)
— Тогда пусть вернет тот, кто тебя породил, такого урода! (объект бежит просить в словаре у своего конструктора)

Если и у конструктора такого свойства нет, то обычно, на этом все и заканчивается, ибо конструктор конструктора уже не при делах: «вассал моего вассала не мой вассал». Это все, что доступно в JS.

Диспетчеризация запроса по иерархии классов отражает совсем другое отношение: конкретное-общее (класс -> супер-класс) — и логика диспетчеризации запросов тут совершенно иная. Единственное что их роднит с «объект-конструктор», это транзитивное отношение «instanceOf», которое может означать и «объект типа», и «объект класса» (см. диаграмму www.cafepy.com/article/python_types_and_objects/images/relationships_transitivity.png). Но из-за этого «двойного» смысла и возникает путаница, будто одно можно выразить через другое. Это не так (не даром, на диаграмме стрелки выглядят по разному).
Вы пишете obj.property, явно желая получить о объекта «obj», нечто, связанное с именем «property». Но где объект возьмет это «нечто»? В конструкторе? В __dict__? В каком-то из супер-классов? Для этого, в new-классах python используются умопомрачительные правила: www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html#id402018 (следующая статья по вашей ссылке :) ). Другие типы (не-new-классы) имеют другие правила. А благодаря «магическим» методам (__getattr__, __setattr__ и т.п.) и вы можете придумать что-то свое. Но, что бы вы там не напридумывали, «снаружи» это все равно будет выглядить как «obj.property». Вот это и есть абстракция доступа.

В Javascript можно реализовать подобные правила, и описать их внутри методов. Но тогда и «снаружи» они будут выглядить как вызовы методов. Мне попадалось, например, такое: value = obj.findName('property').get(). Внутри findName() реализован механизм ресолвинга свойства по иерархии классов, а при помощи get() абстрагирован доступ к value. Т.е. логически все сделано. Но без абстракции доступа (синтаксического сахара, со стороны языка, если хотите).
Вот за что я не люблю jQuery, так это за то как, он относится к пользовательским событиям. Пример:
$().bind('test', function() { window.console.log('test1') })
$().bind('test', function() { window.console.log('test2'); throw 'Error!'; })
$().bind('test', function() { window.console.log('test3') })
$().trigger('test');
...
test1
test2
Error!

'test3' нет. Т.е. если какой-то обработчик обломался и бросил исключение, то обработчики, стоящие в цепочке после него, событие не получат.

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

В других фреймворках (том же prototype.js) такого глюка нет.
Для целеуказания по id лучше использовать a.href.

<a class="link" href="#target">click me</a>

<div id="target"></div>
...
$('.link').click(function() {
  $(this).attr('href').trigger('showFloat');
  return false;
}}
тогда будет уже две проблемы: написать обертку вокруг libev и написать программу на php, которая будет использовать эту обертку. :)
Приятно, конечно, что прототипы позволяют избавиться от лишнего слоя абстракций в виде классов и, тем более, метаклассов. Более того, эти сущности при желании можно моделировать средствами JS.

Извиняюсь за сумбурность вышесказанного. Ведь хотелось подвести к прямо противоположному выводу. :) Объекты и типы — вот базовая штука в ООП. А классы — это такой жутко полезный тип, — которого в javascript, как раз, серьезно не хватает. Ну и они там не реализуется по-человечески, поскольку язык не позволяет абстрагировать основную оопшную точкозапись «obj.property».
Итак, классический ООП подразумевает наличие только классов и объектов.

В ООП достаточно объектов и типов. Оффтопичный Javascript обходится лишь этим. Я не спорю. В этой области с терминологией творится полный кошмар.

Как показано на картинке по ссылке выше, пунктирчато-стрелочное отношение instanceOf транзитивно. Но, тем не менее, у каждого объекта есть один единственный, самый близкий ему тип. Тот, который его породил.

В Javascript отношение между объектом и «самым близким типом» реализуется через неявную ссылку obj.[[Prototype]], который можно выдернуть, сказав obj.constructor. В python — через obj.__class__ (который, не смотря на название, содержит-таки ссылку на этот «самый близкий тип»). Это я к тому, что термины: constructor и __class__ это синонимы. Поэтому, когда речь заходит об объекте, создающим объекты, то его стоит называть конструктором. Правда это не то же самое, что __init__(self), которая всего лишь процедура инициализации, связанная с объектом (она ни чего не создает, ей объект прилетает уже созданным, в самом первом аргументе self :) ).

В принципе, ссылки от объекта к своему конструктору (который тоже объект и у которого есть свой конструктор, котор…) уже достаточно для того, чтобы порождать магию instanceOf (то бишь typeof), и говорить о наследовании. Т.е. если представить, что у питоньего объекта есть лишь __class__ и __dict__, то станет понятно как живется несчастному жаваскрипту, без классов. :)

Но, в самом деле, как же «класс-ическое» ООП без классов? :) Class это обычный конструктор, характерной чертой которого является поддержка пусто-стрельчатого отношения IsA (т.е. наследования как показано на картинке) между объектами. Для этого в питоньих классах и появляется атрибут __bases__, где хранится кортеж супер-классов (список непосредственных родителей для данного класса, в смысле), суровое шаманство для иерархического поиска атрибутов в этой куче (в дополнение к поиску по иерархии типов), логика instanceOf начинает использовать isA, и определенные правила для манипуляции с object.__dict__. Мрак.

Для того, чтобы создавать классы «на лету» не обязательно придумывать новые конструкторы (мета-классы). Python предоставляет несколько встроенных и шикарную библиотеку (import types) на все оставшиеся 90% случаев жизни. Например:
>>> ClassOfPythons = type('ThePython', (object,), {'voice': 'sh-sh-sshhhhhh....'})
>>> squasher = ClassOfPythons()
>>> squasher.voice
sh-sh-sshhhhhh....

ну или так:
ClassOfPythons = object.__class__('ThePython', (object,), {'voice': 'sh-sh-sshhhhhh....'})

что абсолютно тоже самое, поскольку id(object.__class__) == id(type)

Мета-класс это узко-специальная магия для того, чтобы класс мог выбрать себе конструктора. Фактически это ситуация равносильна тому, когда хвост станет махать собакой — бессмыслица, но иногда очень нужно. :) В метакласс в django-модели используется сугубо как синтаксический сахар. Пол-статьи ни о чем. А вот пример с абстрактным классом, просто красавчик. За это даже плюсик в карму, если получится. :)
ну вот и напутал. конечно же связывать нужно не сущности с таблицами, а их типы с таблицами. т.е. Entity2Table это бред. читать:
EntityType2Table: (entity_type:int, table:int)
, PK(entity_type, table), FK(entity_type -> EntityType.id, ), FK(table -> Table.id)
Table: (int:int, name:string)
, PK(id), FK(id -> Entity.id)

а extends из ООП extends это EntityType2Table.

В этом случае, для в ставки юзера потребуется лишь два запроса: в Entity и в User.
Есть достаточно наивный вариант, чтобы не хранить информацию о типе записи в каждой таблице.

Создадим таблицу Entity (сущности), в которой будем хранить информацию о всех идентификаторах и типах. Дополнительно создадим таблицу EntityType для хранения данных о самом типе (например, имени типа 'name'). Структуру табиц буду записывать в формате: имя_таблицы: (список полей), PK(поле первичного ключа), FK (внешний ключ)

Entity: (id:autoincrement, type:int) , PK(id), FK(type -> EntityType.id)
EntityType: (id:int, name:string), PK(id), FK(id -> Entity.id)

Поле EntityType.id не генерирует значения идентификатора, а ссылается на Entity.id. Т.е. тип это тоже какая-то сущность.

Аналогично — пользователи это тоже сущности.
User: (id:int, firstname:string)
, PK(id), FK(id -> Entity.id)

Пользователем, который запостил статью, может быть не любая абстрактная сущность, а лишь некто из таблицы User:
Article: (id:int, user:int)
, PK(id), FK(id -> Entity.id), FK(user -> User.id)

Продолжим:
Comment: (id:int, user:int, item:int)
, PK(id), FK(id -> Entity.id), FK(user -> User.id), FK(item -> Entity.id)
Vote: (id:int, user:int, item:int)
, PK(id), FK(id -> Entity.id), FK(user -> User.id), FK(item -> Entity.id)

В таблице Comment поле item ссылается на абстрактный Entity.id. Поэтому комментировать можно любые сущности: статьи, пользователей, типы,…, какие-то другие сущности, которые появятся в будущем. Аналогично для Vote.

В приципе, на одну и ту же сущность могут ссылаться id из разных таблиц. Для хранения этих данных создадим таблицу Table, где в поле name будем хранить имя табицы. А для связи таблицы таблиц с таблицей сущностей используем отношение многие-к-многим через таблицу Entity2Table:
Entity2Table: (entity:int, class:int)
, PK(entity, class), FK(entity -> Entity.id, ), FK(class -> Table.id)
Table: (int:int, name:string)
, PK(id), FK(id -> Entity.id)

Таким образом для записи инфомации о новой сущности (допустим User) придется делать следующие вставки: в таблицу Entity, в таблицу User и в таблицу Entity2Table для связи вновь созданного юзера и таблицы User.

Такая структура отображается на соответствующие понятия ООП: Entity => Object, Table => Class, EntityType => DataType, Entity2Table => extends (classes).

зы: сори за сумбурность. это скорее мемори дамп.
или как пропатчить kde под freebsd

Информация

В рейтинге
1 541-й
Зарегистрирован
Активность