Saturday 26 September 2009

Мнимая единица

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

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

Итак, более формально:
Определение: Мнимой единицей называется корень квадратный из минус единицы и обозначается следующим образом

Собственно загвоздка, которую способен обнаружить любой школьник:  
Пояснения: 
1. Первое равенство пришло из определения. 
2. Второе образовалось из понимания того, что любое (подчеркиваю: любое) число разделенное на единицу равно само себе. 
3. Далее имеем полное право умножить числитель и знаменатель на одно и то же число, отличное от нуля, в данном случае это число -1. При этом получаем в числителе единицу, а в знаменателе -1. 
4. Корень из дроби равен корню из числителя поделенному на корень из знаменателя. 
5. Корень из единицы есть не что иное, как сама единица. 
6. Из определения можем смело заменить корень из -1 на i

Итого:  

7. Домножим обе части равенства на i (на вполне законных основаниях, поскольку коэффициент домножения отличен от нуля):  
8. Однако исходя из определения (а точнее нашего определения возведённого в квадрат) следует, что:  

Результат:  

Собственно вопрос: Какое из утверждений/преобразований не верно?

archive

Wednesday 2 September 2009

FreeMarker SimpleHash problem

Обработка шаблонов (Template processing) довольно часто встречается в нынешнее время в разнообразных проектах. Некоторые языки программирования даже совмещают написание логики с "шаблонизатором", что правда зачастую затрудняет поддержку логики. Я же в последнее время пользуюсь открытой библиотекой FreeMarker, которая не привязана к конкретным (особенно веб-ориентированым) технологиям и представляет удобный инструмент и богатый шаблонный язык разметки для Java проектов.

Подробнее о FreeMarker можно узнать по приведенной ссылке, а я сегодня хотел остановиться на некоторой особенности данной библиотеки. Работа с фримаркером начинается с настройки конфигурации, подготовки модели данных и собственно шаблона. Фримаркер - это инструмент отображения вашей модели, потому каждый объект модели оборачивается в специальный класс-обёртку, который не позволяет изменять модель данных из шаблона, а также закрывает доступ к небезопасным методам, которые могут кардинально изменить ход исполнения вашего приложения. Обёртками управляет инстанс ObjectWrapper класса.
Собственно проблема: java.util.Map оборачивается в обёртку, которая оперирует ТОЛЬКО ключами типа String. И если вдруг в Вашей модели попадается что-то вроде java.util.Map<Integer, SomeObject> - ну что ж Вам не повезло... Из данной ситуации есть выход - сменить ObjectWrapper (в поставке от FreeMarker их два) , либо написать свою реализацию, что немного затратно и неудобно. Смена фабрики обёрток ни к чему хорошему не приводит - появляются другие проблемы. Для знакомых с синтаксисом фримаркера:

<#list map?keys as key>
${key}=${map[key]}
<#list>

Начинает возвращать не только ключи мапы, а и названия методов, что очень не удобно для итерирования и естественно выдаёт исключение в ${map[key]}

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


this.configuration = new Configuration(); this.configuration.setDefaultEncoding("UTF-8");
this.configuration.setURLEscapingCharset("UTF-8"); this.configuration.setBooleanFormat("true,false");
this.configuration.setDateFormat( DateFormatUtils.ISO_DATETIME_FORMAT.getPattern() );
this.configuration.setWhitespaceStripping(true);
this.configuration.setLocalizedLookup(true);
this.configuration.setClassForTemplateLoading(this.getClass(), "/your/package/here");

if ( null != autoincludes )
this.configuration.setAutoIncludes(autoincludes);

BeansWrapper objectWrapper = BeansWrapper.getDefaultInstance();
objectWrapper.setStrict(true);
objectWrapper.setExposeFields(true);
objectWrapper.setSimpleMapWrapper(true);
this.configuration.setObjectWrapper(objectWrapper);


Собственно основное внимание должно быть уделено использованию BeansWrapper и objectWrapper.setSimpleMapWrapper(true);
После этого итерирование по мапе с ключами в виде чисел сводиться к немного изменённому синтаксису (обратите внимание на использование круглых скобок вместо квадратных):

<#list map?keys as key>
${key}=${map(key)}
<#list>

archive