среда, 30 апреля 2014 г.

Offtopic. Наблюдения со стороны...

Читаю вот это всё - http://forum.ru-board.com/topic.cgi?forum=33&topic=13825&start=960

И понимаю, что я "с другой планеты"...

Особенно вот это:

"Цитата:
запрос на паскалевидный язык, тем более с классическим компилятором, будет еще долгое время. Это нишевая, но устойчивая клиентская платформа.

Его FreePascal + Lazarus закрывают с лихвой."

- "доставило"...

Кто-то НАПИСАЛ на FreePascal + Lazarus хотя бы ПЯТЬ МИЛЛИОНОВ строк?

Можно ПОСМОТРЕТЬ на ЭТИХ людей?

Пожму им РУКУ!

Пока... Я не видел таких...

А я ЛИЧНО - написал строк 20-ть.. миллионов.. на Delphi.. И что с ними делать?

И я ЛИЧНО пару раз пытался "портироваться" на FreePascal... Безуспешно...

На Kylix кстати тоже "пару раз" пытался портироваться...

Тоже - безуспешно...

И что с этим делать?

А на XE3, XE4, XE5 - портировался вполне успешно....

Просто "паскалевидный язык" говорите...

вторник, 29 апреля 2014 г.

Offtopic. О России и Украине. Но не то, что вы подумали

Сегодня буду брюзжать. Непатриотично.

Россия и Украина - "место гиблое". Там пропадают даже уважаемые "западные бренды".

К тому, что в ИКЕА и Макдональдсе в туалетах убираются ХУЖЕ, чем 10-15 лет назад это - ПРАВДА. К этому уже "все привыкли".

И то что "детские комнаты" в ИКЕА не справляются с потоком желающих - это тоже ФАКТ.

Ну "не справляются", ну что поделать. Всяко бывает... Но ЗАЧЕМ тогда услугу РЕКЛАМИРОВАТЬ на каждом шагу?

И ещё я писал - http://18delphi.blogspot.ru/2013/04/blog-post_9.html

Приведу свежий пример.

Был сегодня в Райфайзен банке. Не в каком-то "занюханом ватниковском Сбербанке", а во вполне себе респектабельном Райфайзен банке. Австрия. Все дела.

Так вот.. Прихожу в отделение... ЗАКРЫТО...

Дёргаю дверь.. "закрыто подумал Штирлиц"...

Ещё раз дёргаю.. Закрыто...

А время между тем - БОЛЕЕ ЧЕМ УРОЧНОЕ...

ОКАЗЫВАЕТСЯ - "инкассация идёт"... В УРОЧНОЕ время.. И шла она "минут тридцать"...

Хоть бы "табличку какую повесили"...

И то - Австрия... Родина Гитлера... Die Ordnung muss sein....

Или в Австрии теперь "тоже так"?

И таких примеров - МАССА.

Когда "уважаемые западные бренды" превращаются "в ничто".

Россия - СИЛЬНЕЕ. Её бардак - ПОГЛОЩАЕТ ВСЁ.

И ВТОРОЕ....

Я БОЛЕЕ чем ХОРОШО отношусь к Геннадию Кернесу. И мне ОЧЕНЬ жаль, что с ним случилась БЕДА.

И Дай бог ему здоровья.

Но!

Есть "один звоночек"...

Понимаете... Городской голова, который в минуты БЕДЫ вынужден лечиться НЕ У СЕБЯ в городе, а за границей (http://top.rbc.ru/society/29/04/2014/921299.shtml), в Израиле. Это - "заслуживает того, чтобы над этим задуматься".

Это - "звоночек".

И ведь город - не какой-нибудь "усть-урюпинск", а - ХАРЬКОВ - ВТОРОЙ город Украины.

Жаль.. Честное слово.

Жаль, что "приходится лечиться за границей", жаль, что "приходится отправлять детей на учёбу за границу".

Жаль.. Всего этого жаль.

"Патриотам" России скажу - не обольщайтесь. В России с больницами - НЕ СИЛЬНО лучше.

Если что-то СЛУЧИЛОСЬ и ЕСТЬ ВОЗМОЖНОСТЬ, то ВЕЗУТ в Москву из "усть-урюпинска".

В Москву! А НЕ в ОБЛАСТНОЙ ЦЕНТР.

А если СИЛЬНО есть ВОЗМОЖНОСТЬ, то в Германию или Израиль.

Блин!

Ну что же у нас за страны такие? Что за "территория отчуждения"?

Почему мы не можем по-другому?

И ещё...

Спросите "как это к программированию относится"? Отвечу - у меня ИНОГДА создаётся ОЩУЩЕНИЕ, что мы и "программируем так же"...

Как говорил наш ВЕЛИКИЙ преподаватель - Фернадо Жозевич Фильф - "как вы учите физику, так они вас лечат"....

Что делать?

P.S. И ещё.. все новости "про Украину", а вот про пострадавших в пожаре в Забайкалье - "коротко в подвале"... Не буду выносить "субъективных оценок"...

P.P.S. "Хочется сказать.. Приходили ко мне тут "мастера из МГТС"... ПЕРВОЕ что они мне сказали - "эй мужик - бери провод отматывай сколько тебе надо"... Так и хочется спросить - "я пил с ними" или может быть "верёвки по скалам вешал"? ПОЧЕМУ они мне "тыкают"? Да ладно это..."

Ссылка. Становимся лучше: тернистый путь программиста. Часть 1

http://habrahabr.ru/post/220761/

Самая главная цитата - "Вопреки устоявшемуся мнению, кровь программирования это общение программиста с программистом, а не общение программиста с компьютером."

И ещё цитата из комментариев:
"Музыка, архитектура, живопись, лепка из пластилина, в конце концов. То, что сделано своими руками — всегда будет хорошим с субъективной точки зрения. Своя рубаха ближе к телу."

Вот - НАДО ПОНИМАТЬ, что программирование это НЕ МУЗЫКА и НЕ ЖИВОПИСЬ...

Это - РЕМЕСЛО...

Долгое и нудное...

понедельник, 28 апреля 2014 г.

Offtopic. "Об истории"

Читаю "интернеты".

(Всё по поводу Украины)

Там развернулась "вторая информационная война".

Из плоскости "сам дурак" война перешла в плоскость "сам дурак, потому что история учит "тому-то и тому-то""...

Так вот...

ИСТОРИЯ - НИЧЕМУ НЕ УЧИТ!

Это надо ПОНЯТЬ!

История не учит и не объясняет.

Она лишь рассказывает.

Все те, кто аппелирует к истории занимаясь "фалометрией" типа - "русские - не русские, а татары" или "Киев самый правильный русский город" или "украинцы сохранили самую настоящую русскость, а вы фино-угры" или "нет такого народа как Украинцы" или "Харьков всегда был русским" и т.д. и т.п. - занимаются ГЛУПОСТЬЮ.

Ещё раз.

ИСТОРИЯ - НИЧЕМУ НЕ УЧИТ и НИЧТО НЕ ОБЪЯСНЯЕТ.

История лишь показывает "как оно наверное было" и "как оно наверное могло бы быть".

Не занимая НИЧЬЮ сторону (ибо это глупо) - скажу лишь - прочтите для начала Вернадского (http://ru.wikipedia.org/wiki/%D0%92%D0%B5%D1%80%D0%BD%D0%B0%D0%B4%D1%81%D0%BA%D0%B8%D0%B9,_%D0%93%D0%B5%D0%BE%D1%80%D0%B3%D0%B8%D0%B9_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B8%D1%87) и Грушевского (http://ru.wikipedia.org/wiki/%D0%93%D1%80%D1%83%D1%88%D0%B5%D0%B2%D1%81%D0%BA%D0%B8%D0%B9,_%D0%9C%D0%B8%D1%85%D0%B0%D0%B8%D0%BB_%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B5%D0%B2%D0%B8%D1%87). ВМЕСТЕ их, параллельно. И сравните. И сделайте выводы.

А теперь к тому - "к чему этот пост".

Мы учили историю Великой Отечественной Войны по "странным учебникам", где писалось "были не готовы.. не хватало.. застали врасплох..."

Так вот...

Прочитайте вот этот сайт ОТ КОРКИ ДО КОРКИ:

http://bdsa.ru/

И ТОЛЬКО ПОТОМ - мните себя "знатоком истории"...

И то - ВРЯД ЛИ...

Сарказм в том, что ДАЖЕ Вернадский и Грушевский - НЕ ЗНАЛИ историю ДОСКОНАЛЬНО.

В ЛЮБОЙ истории есть лишь "взгляд"...

P.S. а когда прочтёте - пишите мне - я вам ещё источники для чтения подкину... БЕЗ "субъективных оценок"...

P.P.S. А для любителей заявлений типа "Харьков всегда был русским" приведу контр-примеры (как положено в математике) - "Смоленск всегда был польским" или "Казань всегда была татарской" или "Юкон всегда был русским".. Или "Гавайи всегда были русскими"...

Ну вы понимаете.. (Кто хочет понять)...

Слово ВСЕГДА - "очень СЛОЖНОЕ слово"...

P.P.S. Для тех кто "кричит, что вы не русские, а татары" - скажу - я очередной раз перечитаю Гумилёва (который тоже небесспорен), улыбнусь и очередной раз пойму, что сравнение с татарами мне льстит :-)

P.P.P.S. Стал кстати отмечать тот факт, что по российскому ТВ стали "пиарить Гумилёва", что не может не радовать. Правда был бы пиар "белый".. А не на мельницу "очередных толкователей истории".. Ну я - наивный.. Я - НАДЕЮСЬ...

Порвало. Ещё раз о "технарях и математиках"

По мотивам - http://programmingmindstream.blogspot.ru/2014/04/blog-post_3.html

Я очень "грубо" и "неконкретно" пытался объяснить.

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

Так вот.

Когда я говорю о "хороших преподавателях" и "хороших объяснениях на пальцах" - я имею в виду вот что:

"На одной из п̶ь̶я̶н̶о̶к̶ редколлегий «Популярной механики» речь зашла о науке.
- Опять в журнале какие-то матерные слова написаны! – пожаловались девушки из отдела рекламы.
- Где???
- Да вот же: «бо-зе-эйн-штейн-ов-ский кон-ден-сат»! Да тут не только язык сломаешь, вообще непонятно, что такое и о чем это! Спорим, ты и объяснить не сможешь простым людям!

Ах, даже вот так? Ну вот вам бозонный конденсат и квантовые эффекты для блондинок.

Смотрите: существуют два типа л̶ю̶д̶е̶й̶ частиц, “мальчики” и “девочки”. Мальчики одеты в брюки, на которые уходит 1 метр полотна. Это - целый спин. Такие частицы-мальчики называются ̶б̶и̶з̶о̶н̶ы̶ бозоны. Девочки одеты в юбки, на которые уходит 0,5 метра полотна. Это - полуцелый спин, а частицы-девочки - фермионы.

Ведут они себя по-разному.
Когда бозоны собираются вместе на чисто мужскую вечеринку и обнаруживают, что все одеты в абсолютно одинаковые костюмы, они радостно улыбаются, садятся рядом, хлопают друг друга по плечу, ставят друг другу пиво, становятся лучшими друзьями и действуют как единое целое. Это – бозонный конденсат (он же конденсат Бозе-Эйнштейна). А когда раздается крик «наших бьют!», все частицы-мальчики устремляются на защиту - в одном направлении и не мешая друг другу. Это - сверхтекучесть.

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

Теперь представим себе торговый центр с двумя входами-выходами с разных сторон. Это - проводник. Внутри - множество магазинов и бутиков. Это - кристаллическая решетка. Если запустить через один вход частицу-девочку (фермион), то вместо того, чтобы пройти прямо насквозь и выйти с другой стороны, она будет испытывать многочисленные столкновения с магазинами, и выйдет с изрядно похудевшим кошельком. Это - механизм электрического сопротивления (электроны являются фермионами).

А теперь представим, что на входе девочка встречает подругу, и они ̶з̶а̶ц̶е̶п̶л̶я̶ю̶т̶с̶я̶ ̶я̶з̶ы̶к̶а̶м̶и̶ начинают болтать о моде, прическах и мальчиках. При этом две девочки (фермионы) действуют как единое целое. Это - куперовская пара. Увлеченные разговором, подруги не замечают магазинов и проходят торговый центр насквозь, не испытывая соударений с бутиками и не потратив ни копейки денег, то есть ведут себя точно так же, как мальчик (бозон). Это - сверхпроводимость.
Ну вот, теперь вы знаете столько же, сколько студенты-физики узнают в рамках годового курса квантовой теории. Ну, почти ."

И ещё...

"На пальцах".

Есть такой алгоритм. "Алгоритм Дейкстры". Он служит для нахождения "минимального пути во взвешенном графе".

Так вот.

"На пальцах".

Суть алгоритма состоит в том, что "мы пускаем волну из начальной вершины и когда волна достигнет конечную вершину - задача решена".

Там много "тонкостей". Но ГЛАВНОЕ - "запомнить про волну".

И ещё о "фильтрах и генераторах"

В продолжение темы - http://programmingmindstream.blogspot.ru/2014/04/blog-post_25.html

Как выглядит SetTo?

А очень просто:

type
 TElementFilter = class(Generator)
 ..
  class procedure SetTo(var theFilter: Generator);
 end;//TElementFilter

...

class procedure TElementFilter.SetTo(var theFilter: Generator);
var
 l_This : TElementFilter;
begin
 l_This := Self.Create;
 l_This.Next := theFilter;
 FreeAndNil(theFilter);
 theFilter := l_This;
end;

P.S. Для тех кто хочет "пообсуждать FreeAndNil" посоветую для начала прочитать вот это - http://18delphi.blogspot.ru/2013/04/iunknown.html

Продолжение про "фильтры и генераторы"

В продолжение темы - http://programmingmindstream.blogspot.ru/2014/04/blog-post_24.html

Как выглядят фильтры?

А очень просто.

Вот примерно так:

type
 TEmptyParaEliminator = class(TElementFilter)
 ...
 THyperlinkEliminator = class(TElementFilter)
 ...
 TPageBreakEliminator = class(TElementFilter)
 ...

function TEmptyParaEliminator.NeedWriteElement(anElement: Element): Boolean;
begin
 Result := not anElement.IsKindOf('TextPara') OR not anElement.Attribute['Text'].Empty;
end;

...

function THyperlinkEliminator.NeedWriteElement(anElement: Element): Boolean;
begin
 Result := not anElement.IsKindOf('Hyperlink');
end;

...

function TPageBreakEliminator.NeedWriteElement(anElement: Element): Boolean;
begin
 Result := not anElement.IsKindOf('PageBreak');
end;

Мысль понятна?

По-моему - банально...

четверг, 24 апреля 2014 г.

Ещё немного о "фильтрах и генераторах"

В продолжение вот этой темы - http://programmingmindstream.blogspot.ru/2014/04/sax.html

Пусть нам надо преобразовать RTF в HTML и при этом выкинуть пустые параграфы, а также выкинуть гиперссылки и выкинуть разрывы страниц.

Выглядит это так:

var
 G : Generator;
begin
 G := THTMLWriter.Create(anOutput); // - писатель HTML (anOutput - выходной поток)
 try
  TEmptyParaEliminator.SetTo(G); // - фильтр выкидывающий пустые параграфы
  THyperlinkEliminator.SetTo(G); // - фильтр выкидывающий гиперссылки
  TPageBreakEliminator.SetTo(G); // - фильтр выкидывающий разрывы страниц
  TRTFReader.Create(anInput).SetTo(G); // - читатель RTF (anInput - входной поток)
  G.Execute;
 finally
  FreeAndNil(G);
 end;//try..finally
end;

Мысль понятна?

Чем хорош SetTo?

Тем, что его легко можно добавить или закомментировать.

Если же мы хотим сделать всё то же самое, но перемыть RTF в RTF, то код меняется в одной строчке:

var
 G : Generator;
begin
 G := TRTFWriter.Create(anOutput); // - писатель RTF (anOutput - выходной поток)
 try
  TEmptyParaEliminator.SetTo(G); // - фильтр выкидывающий пустые параграфы
  THyperlinkEliminator.SetTo(G); // - фильтр выкидывающий гиперссылки
  TPageBreakEliminator.SetTo(G); // - фильтр выкидывающий разрывы страниц
  TRTFReader.Create(anInput).SetTo(G); // - читатель RTF (anInput - входной поток)
  G.Execute;
 finally
  FreeAndNil(G);
 end;//try..finally
end;

Ну и по аналогии RTF в DOC:

var
 G : Generator;
begin
 G := TDOCWriter.Create(anOutput); // - писатель DOC (anOutput - выходной поток)
 try
  TEmptyParaEliminator.SetTo(G); // - фильтр выкидывающий пустые параграфы
  THyperlinkEliminator.SetTo(G); // - фильтр выкидывающий гиперссылки
  TPageBreakEliminator.SetTo(G); // - фильтр выкидывающий разрывы страниц
  TRTFReader.Create(anInput).SetTo(G); // - читатель RTF (anInput - входной поток)
  G.Execute;
 finally
  FreeAndNil(G);
 end;//try..finally
end;

вторник, 22 апреля 2014 г.

Offtopic. Ссылка. Отечественный процессор «Эльбрус-4С» скоро запустят в серийное производство

http://habrahabr.ru/post/220241/

Читаю комментарии и удивляюсь тому сколько у нас специалистов по микроэлектронике и экономике и прочим чудным дисциплинам.

понедельник, 21 апреля 2014 г.

Ссылка. Today I learned… :) I didn’t know about this syntax for properties…

http://www.delphifeeds.com/go/f/115017

Цитата:

 ...
 FStrings: array [0..1] of string;
 ...
 property String0: string read FStrings[0] write FStrings[0];
 property String1: string read FStrings[1] write FStrings[1];

пятница, 18 апреля 2014 г.

Ссылка. 5 стадий некомпетентности программиста

http://habrahabr.ru/post/88443

«Вы знаете, полиморфное наследование, на самом деле — жалкая замена функциональным литералам и динамическому типизированию.»  :-)

четверг, 10 апреля 2014 г.

Offtopic. Embarcadero опубликовала вакансию "евангелиста"

Вакансия:

"Должность:
Менеджер по продуктам - средства разработки Embarcadero
(Sales consultant, Evangelist)
Территория: Россия, СНГ, Грузия, Монголия
Расположение:
Москва, Московское представительство Embarcadero
проезд Серебрякова, 6
Должностные функции:
- Продвижение технологий и средств разработки Embarcadero в России и СНГ
- Взаимодействие с сообществом разработчиков
- Проведение семинаров и вебинаров, выступление на конференциях
- Работа в социальных сетях
- Техническая экспертиза и поддержка специалистов по продажам в коммерческих проектах
- Взаимодействие с подразделениями R&D по вопросам свойств, характеристик и рыночного
позиционирования продуктов
- Взаимодействие со службами маркетинга относительно контента маркетинговых программ и материалов
- Локализация технических и маркетинговых материалов
Требования к кандидату:
- 5+ лет опыта практической работы с Delphi, C++Builder, RAD Studio
- Способность быть экспертом по использованию этих продуктов
- Знание и понимание технологий разработки, широкий кругозор в области языков программирования
- Опыт разработки корпоративных систем, понимание технологий работы с промышленными базами данных
- Опыт публичных выступлений и проведения презентаций
- Опыт взаимодействия в социальных сетях, ведения блогов
- Совершенное владение русским языком (устным и письменным)
- Fluent English (speaking and writing skills), навыки и опыт переводчика технических материалов приветствуются
- Готовность ездить в командировки
В высшей степени ценятся:
- "Общая адекватность" и интеллигентность
- Умение работать в команде
- Аналитический склад ума
- Организованность и пунктуальность
- Умение отстаивать свои убеждения и уважение к мнению других
Условия по компенсации:
- Обсуждаются индивидуально
Что сделать:
- Прислать свое резюме на русском и английском языках на russia.info@embarcadero.com,
- Mожно приложить Вашу фотографию;
- По возможности - ссылки на Ваши блоги, YouTube-материалы, другие интернет ресурсы, публикации,
если таковые имеются по темам, связанным с описанной выше деятельностью
- В случае приглашения на интервью быть готовым провести презентацию или демонстрацию продукта
(Delphi) по темам, близким Вам по опыту и интересам."

Видимо взамен Леонова.

С одной стороны - "хотелось бы попробовать".

С другой стороны:

1. Вряд ли возьмут.
2. Непонятно что там с деньгами.
3. Бросать "всё что нажито" - жаль, да и "подло".
4. Всё-таки программирование - интереснее.

Маниловщина. Про RichEdit для FM

Тут по мотивам поста - http://programmingmindstream.blogspot.ru/2014/04/sax.html меня спросили - "а чего мол сам не сделаешь RichEdit под FireMonkey?"

Что сказать?

Я бы сделал. Даже "знаю как". И есть наработки.

Как минимум под две платфомы было написано:

1. Windows - полноценный WYSIWYG редактор - http://everesteditor.chat.ru/
2. iOS/MacOS - рендеринг текста - http://18delphi.blogspot.ru/2013/11/coretext.html и http://18delphi.blogspot.ru/2013/10/coretext_30.html

Так что - "я бы сделал".

Но!

С одной стороны - нет времени, а с другой стороны - есть сомнения в "необходимости всего этого".

Даже Сергей Ткаченко  (http://trichview.com) написал что-то вроде -"мы бы сделали под FM, но это пока не в приоритете".

Посему.

Если тема ДЕЙСТВИТЕЛЬНО интересная и ВАЖНАЯ, то у меня есть предложение:

Давайте сделаем Open-Source проект - "RichView для FM".

В свободное от работы время.

Приглашаю всех желающих.

Готов делиться идеями и кодом.

ОДИН я - не потяну.

Работы там минимум на пол-года-год. Для одного.

Если интересно - пишите. Эта тема для меня сильно "роднее", чем даже UML и тесты.

Тем более, что Леонов вроде как покинул Embarcadero (http://programmingmindstream.blogspot.ru/2014/04/offtopic-embarcadero.html) - посему тема тестов - "временно закрывается". Вебинара видимо не будет. К сожалению.

Но я с субботы в отпуске. Озвученный план статей - http://programmingmindstream.blogspot.ru/2014/03/blog-post_5.html - допишу как раз.

Offtopic. Всеволод Леонов похоже покинул Embarcadero

https://www.facebook.com/vsevolod.leonov.9/posts/529853197125887

Всеволод Леонов похоже покинул Embarcadero.

Мне очень жаль. Столько ещё недоделано.

Обработка текстов. Генераторы, фильтры, трансформаторы и "SAX на коленке"

Вводная.

Пусть есть множество форматов текстов.

Например:

RTF
DOC
DOCX
HTML
TXT

И пусть стоит задача сделать преобразование из одного формата в другой.

Как это сделать?

Можно конечно написать набор преобразований типа:
RTF -> DOC
RTF -> HTML
RTF -> DOCX
HTML -> RTF
HTML -> DOC

ну и так далее...

Только тут вот какая штука - в итоге получаем "Це из Эн по Ка".

Нездорово как-то...

Что делать?

У меня есть ОТВЕТ продиктованный моей МНОГОЛЕТНЕЙ практикой обработки документов.

Надо для начала ввести ОДИН так называемый "канонический формат", который включает в себя всё многообразие "вариантов использования".

Т.е. этот "канонический формат" должен уметь "вмещать в себя" все остальные форматы.

Одним из кандидатов на "каноничность" является XML (точнее XML-подобные структуры), в силу его "расширяемости".

Ну или NSAttributedString.

Подробности чуть позже.

А пока - опишу идею.

Если мы выбрали "канонический формат", то дальше мы делаем вот что:

Мы делаем набор "читателей" и набор "писателей".

Точнее сначала мы "стандартизуем" интерфейс "генератора" типа:

type
 IGenerator = interface
  procedure AddAttribute(aName: String; aValue: String);
  procedure StartStructure(aName: String);
  procedure StartArray(aName: String);
  procedure Finish;
 end;//IGenerator

"Мою" реализацию можно посмотреть тут - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2Interfaces.pas и тут - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2Prim.pas

Она выглядит так:

 Ik2TagGenerator = interface(IUnknown)
  {* Генератор тегов }
   ['{694DAEA5-80F3-4E12-9CCF-2B9950479734}']
   procedure pm_SetCharsInLine(aValue: Integer);
   function pm_GetCurrentStartLevel: Integer;
   function pm_GetNextGenerator: Ik2TagGenerator;
   procedure pm_SetNextGenerator(const aValue: Ik2TagGenerator);
   function pm_GetContext: Ik2Op;
   function Get_CurrentVersion: Integer;
   procedure Set_CurrentVersion(aValue: Integer);
   procedure AddStringAtom(TagID: Integer;
    const Value: AnsiString;
    aCodePage: Integer = CP_ANSI); overload; 
     {* добавить строковый атом. }
   procedure AddPCharLenAtom(TagID: Integer;
    const Value: Tl3WString);
     {* добавить строковый атом. }
   procedure AddObjectAtom(TagID: Integer;
    Value: TObject;
    Shared: Boolean = true);
   procedure AddStreamAtom(TagID: Integer;
    aStream: TStream);
     {* добавить атом из потока. }
   procedure AddTransparentAtom(TagID: Integer);
     {* добавить "прозрачный" атом. }
   procedure AddIntegerAtom(TagID: Integer;
    Value: Integer);
     {* добавить целочисленный атом. }
   procedure AddBoolAtom(TagID: Integer;
    Value: Boolean);
   procedure AddAtom(AtomIndex: Integer;
    TK: Tk2TypeKind;
    const Value);
     {* добавить атом. }
   procedure AddStringAtom(TagID: Integer;
    Value: Tl3PrimString); overload; 
   procedure AddAtomEx(AtomIndex: Integer;
    const Value: Tk2Variant);
   procedure Start;
     {* начать генерацию. }
   procedure StartChild(TypeID: Integer);
     {* начать дочерний объект тега. }
   procedure StartDefaultChild;
     {* начать дочерний объект тега с типом по-умолчанию. }
   procedure StartTag(TagID: Integer);
     {* начать вложеный тег. }
   procedure Finish(NeedUndo: Boolean = false);
     {* закрыть скобку этапа генерации. }
   procedure Rollback(CheckBrackets: Boolean = false);
     {* откатить все открытые "скобки". }
   function Pixel2Char(Pixel: Integer): Integer;
   function Char2Pixel(Ch: Integer): Integer;
   procedure AddStringAtomClone(TagID: Integer;
    Value: Tl3CustomString);
   procedure AddInt64Atom(aTagID: Integer;
    aValue: Int64);
     {* Добавляет 64-битный атом }
   property CharsInLine: Integer
     write pm_SetCharsInLine;
   property CurrentStartLevel: Integer
     read pm_GetCurrentStartLevel;
   property NextGenerator: Ik2TagGenerator
     read pm_GetNextGenerator
     write pm_SetNextGenerator;
     {* следующий генератор в цепочке. }
   property Context: Ik2Op
     read pm_GetContext;
     {* Контекст генерации }
   property CurrentVersion: Integer
     read Get_CurrentVersion
     write Set_CurrentVersion;
     {* Текущая версия формата }
 end;//Ik2TagGenerator

И тогда получаем примерно такую картину:

Входной файл -> Читатель -> Писатель (реализующий интерфейс IGenerator) -> Выходной файл.

Что мы имеем?

Читатель читает входной файл из конкретного формата и "преобразует" его к "каноническому формату".

Писатель получает "канонический формат" и преобразует его к конкретному выходному формату.

Т.е. получаем набор читателей:

TRTFReader
TDOCReader
TDOCXReader
THTMLReader
TTXTReader

И набор писателей:

TRTFWriter
TDOCWriter
TDOCXWriter
THTMLWriter
TTXTWriter

Примеры можно посмотреть тут:

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdReader.pas
https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdWriter.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdXMLReader.pas
https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdXMLWriter.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/dd/ddHTMLReader.pas
https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/dd/ddHTMLWriter.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/dd/ddRTFReader.pas
https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/dd/ddRTFWriter.pas

ну и так далее...

Таким образом мы получаем уже не "Це из Эн по Ка", а N - Reader'ов и N Writer'ов. Со стандартизованным входом и выходом.

Любой Reader можно прикрутить к любому Writer'у.

Можно даже сделать нуль-преобразование:

TRTFReader -> TRTFWriter

или

THTMLReader -> THTMLWriter

и таком образом протестировать ПОЛНОТУ преобразования "формата самого в себя".

Далее вот как разовьём тему.

Предположим нам не только надо преобразовывать форматы, но и трансформировать их.

Ну например выкидывать какие-то данные или добавлять новые.

Тогда картинка получается следующая:

Входной файл -> Читатель -> Фильтр1 -> Фильтр2 -> Фильтр3 -> Трансформатор1 -> Трансформатор2 -> Трансформатор3 -> Фильтр4 -> Фильтр5 -> Фильтр6 -> Трансформатор4 -> Трансформатор5 -> Трансформатор6 -> Писатель -> Выходной файл

Что Фильтр, что Трансформатор - опять же поддерживают интерфейс IGenerator.

Примеры:

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdHyperlinkEliminator.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdAllDocumentSubsEliminator.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdCommentFilter.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/EVD/evdCommentFilter.pas

Т.е. мы можем не только ПРЕОБРАЗОВЫВАТЬ форматы, но и ПРЕОБРАЗОВЫВАТЬ данные.

Простейший пример:

Входной файл -> TRTFReader -> Фильтр выкидывающий пустые параграфы -> TRTFWriter -> Выходной файл

Или:

Входной файл -> TRTFReader -> Фильтр выкидывающий гиперссылки -> TRTFWriter -> Выходной файл

Или:

Входной файл -> TRTFReader ->  Фильтр выкидывающий гиперссылки ->Фильтр выкидывающий пустые параграфы -> TRTFWriter -> Выходной файл

Мысль понятна?

Ещё на ту же тему:

http://18delphi.blogspot.ru/2013/04/blog-post_10.html
http://18delphi.blogspot.ru/2013/04/blog-post_8517.html
http://18delphi.blogspot.ru/2013/11/coretext.html
http://18delphi.blogspot.ru/2013/10/coretext_30.html
http://18delphi.blogspot.ru/2013/10/offtopic-evd-coretext.html
http://18delphi.blogspot.ru/2013/10/coretext-glyphrunnerdelegate.html
http://18delphi.blogspot.ru/2013/10/coretext-nsattributedstring.html

Аналогичным образом строится работа с редактором:

Чтение:

Входной файл -> Читатель -> Буфер документ (как разновидность генератора) -> Редактор

Запись:

Буфер документа (принадлежащий редактору) -> Писатель -> Выходной файл

Пример буфера(ов) тут:

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2DocumentGenerator.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2DocumentBuffer.pas

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2InPlaceGenerator.pas

Мысль понятна?

Тема вообще интересна?

Продолжать?

P.S. Ну и на закуску - ForkGenerator - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/RealWork/K2/k2ForkGenerator.pas

Ну я думаю, что понятно что он делает:
                                                     
                                          Писатель1 -> Выходной файл1
                                         /
Входной файл -> Читатель -> ForkGenerator 
                                         \
                                          Писатель2 -> Выходной файл2

Мысль понятна?

P.P.S. Написали тут:

"Ну просто идея уж больно "естественная"
правда возникает она после 2-3 перекодировщика
с поправкой на 3-4 итерацию, при первой кажется проще написать прямой"

среда, 9 апреля 2014 г.

Ссылка. Создание непрямоугольных форм в Delphi и C++Builder

http://alexanderbondar.blogspot.ru/2014/03/7-delphi-c-4.html

Из комментариев:

"Отдать HTCAPTION в ответ на WM_NCHITTEST - никак? Раз уж SetWindowRgn осветили.
А то ведь прочитает молодежь - мол, переместить невозможно, поскольку окно без заголовка. Уж больно категорично и безапелляционно."

:-)

Ну и "от себя" - http://18delphi.blogspot.ru/2013/03/blog-post_8379.html

Offtopic. Сканы журнала "Техника Молодёжи". 33-го - 55-го годов

https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/TM/

Это - ОФИГЕННО.

Это показывает "суть времени" и "историческую правду".

Достаточно найти:

1. План застройки Москвы от 35-го года (включая план обводнения).
2. Статью "с фотоаппаратом по линии Зигфрида".
3. Статью про немецкие пикирующие бомбардировщики.
4. Несколько статей про Дворец Советов.
5. Статью про "польский освободительный поход".

Offtopic. Руководитель должен постоянно находиться у себя на производстве и вникать во всё, что там происходит

Цитирую "байку":

"Крупный бизнесмен приходит к раввину:
- Ребе, у меня проблемы. Завод приносит одни убытки, дисциплины никакой, производительность труда на нуле, долги растут, налоги заели. Что делать?
- Возьми Талмуд, положи его подмышку и обходи весь завод два раза в день.
Через месяц приходит радостный бизнесмен к раввину и говорит:
- Теперь всё просто замечательно! Воровство прекратилось, бездельники уволены, производительность выросла, с долгами покончено. В чём секрет?
- Руководитель должен постоянно находиться у себя на производстве и вникать во всё, что там происходит.
- А Талмуд зачем?
- Для солидности."

Знаете... ПОРВАЛО!!! Порвало вдрызг и ПОПОЛАМ...

Ссылка. Паралич анализа: вы знаете слишком много, чтобы просто писать код

http://habrahabr.ru/post/218345/

Есть такая "болезнь".

За собой замечал.

Одно только могу сказать пока - "пишите тесты и излечитесь".

Даст бог - напишу и об этом.

Коротко. Как повод "для размышления". Интерфейсы vs. объекты

Опять ничего анализировать или "разжёвывать" не буду.

Просто приведу код:

type
 ISomeInterface = interface
  procedure SomeMethod;
 end;//ISomeInterface

 TSomeClass = class(TInterfacedObject, ISomeInterface)
  public
   procedure SomeMethod;
 end;//TSomeClass

...

procedure TSomeClass.SomeMethod;
begin
 if (Self = nil) then
  Write('nil')
 else
  Write(ClassName);
end;

...

var
 l_Nil : TSomeClass;
 l_NotNil : TSomeClass;
begin
 l_Nil := nil;
 l_Nil.SomeMethod; // - в выводе - nil
 ISomeInterface(l_Nil).SomeMethod; // AV

 l_NotNil := TSomeClass.Create;
 l_NotNil.SomeMethod; // - в выводе - TSomeClass
 ISomeInterface(l_NotNil).SomeMethod; // - в выводе - TSomeClass
end;

Ни на что "не претендую"...

Просто "заметки на полях"...

Просто тут есть момент "задуматься" - когда использовать интерфейсы, а когда - нет.

"Примерно" то же относится и к виртуальным методам.

Ну и ещё.. Не надо забывать про паттерн null-object - http://ru.wikipedia.org/wiki/Null_object_(%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

пятница, 4 апреля 2014 г.

Продолжаем про "особенности Supports"

Предыдущая серия была тут - http://programmingmindstream.blogspot.ru/2014/04/supports.html

Поступил тут вопрос:

http://programmingmindstream.blogspot.ru/2014/04/supports.html?showComment=1396620657041#c4522417805967527391

"Извините но я не понимаю как мы ожидаем С. Если это метод класса TC. Мы же даже объект не создаем ?"

Разовью тему.

Итак был пример:

type
 ISomeInterface = interface
  procedure SomeMethod;
 end;//ISomeInterface

 TA = class(TObject, ISomeInterface {IUnknown тут СПЕЦИАЛЬНО опущен})
  function _AddRef: Integer;
  function _Release: Integer;
  function QueryInterface(const anID: TGUID; out anObj): hResult; virtual; 
  procedure SomeMethod;
 end;//TA

 TB = class(TA)
  function QueryInterface(const anID: TGUID; out anObj): hResult; override;
 end;//TB

 TC = class(TIntefacedObject, ISomeInterface)
  procedure SomeMethod;
 end;//TC

...

function TA._AddRef: Integer;
begin
 Result := -1;
end;

function TA._Release: Integer;
begin
 Result := -1;
end;

function TA.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if Self.GetInterface(anID, anObj) then
  Result := S_Ok
 else
  Result := E_NoInterface;
end;

procedure TA.SomeMethod;
begin
 Write('A');
end;

function TB.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if IsEqualGUID(anID, ISomeInterface) then
 begin
  Result := S_Ok;
  ISomeInterface(Obj) := TC.Create;
 end//IsEqualGUID(anID, ISomeInterface)
 else
  Result := inherited QueryInterface(anID, Obj);  
end;

procedure TC.SomeMethod;
begin
 Write('C');
end;

...
var
 l_A : ISomeInterface;
 l_B : ISomeInterface;
 A : TA;
 B : TB;
begin
 A := TA.Create;
 B := TB.Create;
 if not Supports(A, ISomeInterface, l_A) then
  Assert(false);
 l_A.SomeMethod; // - в консоли видим A
 if not Supports(B, ISomeInterface, l_B) then
  Assert(false);
 l_B.SomeMethod; // - в консоли видим A, а "хотелось бы" - C
end;

Теперь напишем ТАК:

type
 ISomeInterface = interface
  procedure SomeMethod;
 end;//ISomeInterface

 TA = class(TObject, IUnknown {тут ПОЯВИЛСЯ IUnknown}, ISomeInterface)
  function _AddRef: Integer;
  function _Release: Integer;
  function QueryInterface(const anID: TGUID; out anObj): hResult; virtual; 
  procedure SomeMethod;
 end;//TA

 TB = class(TA)
  function QueryInterface(const anID: TGUID; out anObj): hResult; override;
 end;//TB

 TC = class(TIntefacedObject, ISomeInterface)
  procedure SomeMethod;
 end;//TC

...

function TA._AddRef: Integer;
begin
 Result := -1;
end;

function TA._Release: Integer;
begin
 Result := -1;
end;

function TA.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if Self.GetInterface(anID, anObj) then
  Result := S_Ok
 else
  Result := E_NoInterface;
end;

procedure TA.SomeMethod;
begin
 Write('A');
end;

function TB.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if IsEqualGUID(anID, ISomeInterface) then
 begin
  Result := S_Ok;
  ISomeInterface(Obj) := TC.Create;
 end//IsEqualGUID(anID, ISomeInterface)
 else
  Result := inherited QueryInterface(anID, Obj);  
end;

procedure TC.SomeMethod;
begin
 Write('C');
end;

...
var
 l_A : ISomeInterface;
 l_B : ISomeInterface;
 A : TA;
 B : TB;
begin
 A := TA.Create;
 B := TB.Create;
 if not Supports(A, ISomeInterface, l_A) then
  Assert(false);
 l_A.SomeMethod; // - в консоли видим A
 if not Supports(B, ISomeInterface, l_B) then
  Assert(false);
 l_B.SomeMethod; // - ТЕПЕРЬ в консоли видим C
end;

Мысль понятна?

Изменилась ОДНА строчка. А КАКОВА РАЗНИЦА!

Продолжим.

Напишем теперь так:

type
 ISomeFakeInterface = interface
 end;//ISomeFakeInterface

 ISomeInterface = interface
  procedure SomeMethod;
 end;//ISomeInterface

 TA = class(TObject, ISomeInterface {IUnknown тут СПЕЦИАЛЬНО опущен}, ISomeFakeInterface)
  function _AddRef: Integer;
  function _Release: Integer;
  function QueryInterface(const anID: TGUID; out anObj): hResult; virtual; 
  procedure SomeMethod;
 end;//TA

 TB = class(TA)
  function QueryInterface(const anID: TGUID; out anObj): hResult; override;
 end;//TB

 TC = class(TIntefacedObject, ISomeInterface)
  procedure SomeMethod;
 end;//TC

...

function TA._AddRef: Integer;
begin
 Result := -1;
end;

function TA._Release: Integer;
begin
 Result := -1;
end;

function TA.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if Self.GetInterface(anID, anObj) then
  Result := S_Ok
 else
  Result := E_NoInterface;
end;

procedure TA.SomeMethod;
begin
 Write('A');
end;

function TB.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if IsEqualGUID(anID, ISomeInterface) then
 begin
  Result := S_Ok;
  ISomeInterface(Obj) := TC.Create;
 end//IsEqualGUID(anID, ISomeInterface)
 else
  Result := inherited QueryInterface(anID, Obj);  
end;

procedure TC.SomeMethod;
begin
 Write('C');
end;

...
var
 l_A : ISomeInterface;
 l_B : ISomeInterface;
 A : TA;
 B : TB;
begin
 A := TA.Create;
 B := TB.Create;
 if not Supports(A, ISomeInterface, l_A) then
  Assert(false);
 l_A.SomeMethod; // - в консоли видим A
 if not Supports(B, ISomeInterface, l_B) then
  Assert(false);
 l_B.SomeMethod; // - в консоли видим A, а "хотелось бы" - C

 if not Supports(ISomeFakeInterface(B), ISomeInterface, l_B) then
  Assert(false);
 l_B.SomeMethod; // - в консоли видим C, ВУАЛЯ!!!
end;

УДИВИТЕЛЬНО!

Не правда ли?

НЕСИММЕТРИЯ метода Supports - ОЧЕВИДНА.

По-моему...

"Сухой остаток":

overload - "вреден", "вообще" и в ДАННОМ случае "в частности".

Особенно вреден overload с "ковариантными" типами.

Да и вообще говоря, можно было бы обойтись (на месте Borland'а) ТОЛЬКО методом Supports(IUnknown), а не "ГОРОДИТЬ" ещё один КРАЙНЕ НЕОЧЕВИДНЫЙ метод Supports(TObject).

Мысль понятна?

Сразу оговорюсь - "тема далеко не для всех".

Посему не бросайтесь комментировать, а сначала - "вкурите" проблему.

Надеюсь, что помог кому-то.

P.S. Если подобные "экзерсисы" с объектами vs. интерфейсы - ИНТЕРЕСНЫ - пишите. У меня "в кармане" ещё есть "запасец".

P.P.S. Ну и я надеюсь понятно, что GUID'ы в описании интерфейсов - ОПУЩЕНЫ. Их можно вставить по Crtl-Shift-G.

P.P.P.S. Ну и "в тему":
http://18delphi.blogspot.ru/2013/11/queryinterface.html
http://18delphi.blogspot.ru/2013/11/supports.html
http://18delphi.blogspot.ru/2013/10/supports.html

P.P.P.P.S Один из читателей любезно предоставил компилируемый пример - https://bitbucket.org/ingword/temp/src

Ссылка. Книга. Build Your Own Lisp

http://www.buildyourownlisp.com/

Описание:

"If you're looking to learn C, or you've ever wondered how to build your own programming language, this is the book for you.
In just a few lines of code, I'll teach you how to effectively use C, and what it takes to start building your own language.
Along the way we'll learn about the weird and wonderful nature of Lisps, and what really makes a programming language. By building areal world C program we'll learn implicit things that conventional books cannot teach. How to develop a project, how to make life easy for your users, and how to write beautiful code.
This book is free to read online. Get started now!"

Offtopic. Мы ищем Delphi-разработчика

Мы ищем Delphi-разработчика.

Хотелось бы знания DUnit и UML.

Также хотелось бы знания "промышленных" БД. Типа Postgres, Interbase.

Oracle, Cache, MongoDB и прочие "изыски" - приветствуются, но не рассматриваются, как "реальные движки".

Что нужно делать?

Нужно писать "сервер приложений", который бы работал с БД и раздавал бы данные клиентским приложениям.

Сейчас используется БД HyTech (в файл-серверном виде) и "сервера" как такового - нет. Но очень хочется.

Есть "зачатки" серверного приложения, которое обрабатывает запросы от пользователей. Например "пакетная обработка документов".

Собственно этот "сервер" и хочется развивать.

Коротко. Об особенностях Supports

Не буду заниматься анализом или "разжёвыванием".

Просто приведу пример.

Просто, "чтоб вы знали".

Вот такой код:

type
 ISomeInterface = interface
  procedure SomeMethod;
 end;//

 TA = class(TObject, ISomeInterface {IUnknown тут СПЕЦИАЛЬНО опущен})
  function _AddRef: Integer;
  function _Release: Integer;
  function QueryInterface(const anID: TGUID; out anObj): hResult; virtual; 
  procedure SomeMethod;
 end;//TA

 TB = class(TA)
  function QueryInterface(const anID: TGUID; out anObj): hResult; override;
 end;//TB

 TC = class(TIntefacedObject, ISomeInterface)
  procedure SomeMethod;
 end;//TC

...

function TA._AddRef: Integer;
begin
 Result := -1;
end;

function TA._Release: Integer;
begin
 Result := -1;
end;

function TA.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if Self.GetInterface(anID, anObj) then
  Result := S_Ok
 else
  Result := E_NoInterface;
end;

procedure TA.SomeMethod;
begin
 Write('A');
end;

function TB.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
 if IsEqualGUID(anID, ISomeInterface) then
 begin
  Result := S_Ok;
  ISomeInterface(Obj) := TC.Create;
 end//IsEqualGUID(anID, ISomeInterface)
 else
  Result := inherited QueryInterface(anID, Obj);  
end;

procedure TC.SomeMethod;
begin
 Write('C');
end;

...
var
 l_A : ISomeInterface;
 l_B : ISomeInterface;
begin
 A := TA.Create;
 B := TB.Create;
 if not Supports(A, ISomeInterface, l_A) then
  Assert(false);
 l_A.SomeMethod; // - в консоли видим A
 if not Supports(B, ISomeInterface, l_B) then
  Assert(false);
 l_B.SomeMethod; // - в консоли видим A, а "хотелось бы" - C
end;

Хотя "всё очевидно". Смотрим на код:

function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean;
var
  LUnknown: IUnknown;
begin
  Result := (Instance <> nil) and
            ((Instance.GetInterface(IUnknown, LUnknown) and Supports(LUnknown, IID, Intf)) or
             Instance.GetInterface(IID, Intf));
end;

Почему я это пишу?

Просто потому, что я видел людей, которые сильно удивляются этому.

Для тех кто хочет "откомментировать" скажу - "я не из их числа".

Хотя... И сам "нажирался"...

четверг, 3 апреля 2014 г.

Offtopic. Ссылка. 10 советов тридцатилетним от тех, кому за сорок

http://nnm.me/blogs/EugenieM/10-sovetov-tridcatiletnim-ot-teh-komu-za-sorok/

ОЧЕНЬ В ТЕМУ!

1. Начинайте делать сбережения на старость сейчас, без промедления
2. Начинайте заботиться о своем здоровье сейчас, без промедления
3. Не общайтесь с людьми, которые плохо к вам относятся
4. Относитесь хорошо к тем, кто вам небезразличен
5. Всего на свете вы не добьетесь — сфокусируйтесь на том, что у вас получается действительно хорошо
6. Не бойтесь рисковать, вы все еще можете измениться
7. Вы должны продолжать расти и развиваться
8. Никто не понимает, что он делает. Привыкайте к этому
9. Вкладывайтесь в свою семью — оно того стоит
10. Будьте добры к себе, уважайте себя

Ну и "сухой остаток" так сказать "от себя"...

СЕМЬЯ и ВЛОЖЕНИЯ (в семью и детей).

И - "резко" - друзей к сорока годам у вас УЖЕ НЕ БУДЕТ. Это - ФАКТ!

СЕМЬЯ - вот что будет у вас. А друзья это "что-то из прошлого". Есть "хорошие знакомые", люди, которые "вам небезразличны". Но друзья - по-моему - нет...

Коллеги - да.
Семья - да.
Знакомые - да.
Хорошие знакомые - да.

Но НЕ ДРУЗЬЯ.. К сожалению..

Друг это кто? Это ТОТ, кто ГОТОВ УМЕРЕТЬ ради вас, и ТОТ РАДИ кого ВЫ ГОТОВЫ УМЕРЕТЬ.

В 40-к лет это возможно?

В 20-ть лет - ВОЗМОЖНО. В 30-ть - ТОЖЕ ВОЗМОЖНО.

Но не в 40-к. Может быть дальше - тоже можно, но я до этого пока не дожил.

Попробуйте попросить у человека, которого вы считаете другом о чём-нибудь более "прозаичном", ну чтобы он поддержал вас в "споре", например на "совещании у начальства" или "на просторах интернета". Каков результат?

Или БАНАЛЬНО, чтобы он "встал на вашу позицию", или "вы на его"...

Обсудить "БГ или Макаревича" или "Путина"... Нет.. "ты мне друг, но истина дороже".. Вместо того, чтобы "хрен с ними со всеми, пойдём пива выпьем"...

Или ещё проще.. Попробуйте "дать взаймы" или "взять взаймы".. Всё равно..

Я резок?

Ссылка. "О технарях и "математиках"..."

http://18delphi.blogspot.ru/2013/11/blog-post_13.html

Я к чему "всё это"? Не к тому, что "я такой умный" и "сыплю терминами".

НАОБОРОТ.. Это к тому, что "я такой глупый", что я НЕ ПОНИМАЮ ни "линейной алгебры", ни "тензорного счисления".

Но!

Я вот что "хочу сказать" - "у меня есть ощущение", что ПРОГРАММИРОВАНИЕ и ПРОЕКТИРОВАНИЕ (в программировании) это вещь, которую можно "объяснить на пальцах".

Что "это - РЕМЕСЛО".

Где МОЖНО дать "примеры микросхем" (http://18delphi.blogspot.ru/2013/04/uml_22.html http://18delphi.blogspot.ru/2013/04/blog-post_5722.html) или "примеры шаблонных решений".

Я иногда "нутром чувствую", что можно "дать пример проектирования" скажем так "на пальцах".

Но "мысль - ускользает"... И до "идей на бумаге" - не доходит.. К сожалению...

Может быть я не одинок?

Может у кого-то тоже "мысль ускользает"?

Как A*x=B => x = B/A... (симплекс-метод)

Чтобы "на пальцах"...

Ну там "шаблоны проектирования"... Например Observer или Strategy.

Может быть мы "вместе" сможем "рассказать на пальцах"?

Скажем так.. Как в решении дифференциальных уравнений:
1. Есть КЛАСС ЗАДАЧ - "такой-то".
2. Он решается - "так-то".

Если уж в математике были ВЫЧЛЕНЕНЫ "шаблоны решений", то почему это не сделать в программировании?

Программирование уж куда проще математики...