Monthly Archives: Февраль 2014

Перевод десятичных грудусов в градусы, минуты и секунды

При работе с картами или GPS мы можем получить долготу (longitude) и широту (latitude) в виде виде десятичных грудусов. Например, 37.422006 (широта) и -122.084095 (долгота). Это где-то в Силиконовой долине. Нам может потребоваться перевести эти десятичные градусы в градусы, минуты и секунды, т.е. в формат более понятный человеку. Для справки:
  • Положительное значение широты - северная широта
  • Отрицительное значание широты - южная широта
  • Положительное значение долготы - восточная долгота
  • Отрицательное значение долготы - западная долгота
Преобразование будет реализовано в виде функции, принимающей в качестве параметра десятичный градуc (double), а в качестве результата возвращающая строку вида: X° Y′ Z″, где X - градусы, Y - минуты и Z - секунды. Реализация на Java:
public static String doubleToDegree(double value){
	int degree = (int) value;
	double rawMinute = Math.abs((value % 1) * 60);		
	int minute = (int) rawMinute;
	int second = (int) Math.round((rawMinute % 1) * 60);
	return String.format("%d° %d′ %d″", degree,minute,second);
}
Пример использования:
System.out.println(doubleToDegree(37.422006));//Результат: 37° 25′ 19″
System.out.println(doubleToDegree(-122.084095));//Результат: -122° 5′ 3″
Результаты можно интерпретировать следующим образом: 37° 25′ 19″ означает 37 градусов 25 минут 19 секунд северной широты. -122° 5′ 3″ означает 122 градуса 5 минут 3 секунды западной долготы.

RESTful веб-сервис в Seam Framework

Seam Framework уже включает в себя реализацию спецификации JAX-RS под названием RESTEasy. В библиотеках Seam вы можете увидеть три jar-файла, относящихся к RESTEasy:
  • jaxrs-api.jar
  • resteasy-jaxrs.jar
  • jboss-seam-resteasy.jar
Настройка В вашем проекте найдите и откройте файл components.xml. К корневому элементу components добавьте следующее пространство имен:
xmlns:resteasy="http://jboss.com/products/seam/resteasy"
Также необходимо добавить объявление префикса:

В нашем случае префикс будет restv1. Префикс обычно используется для версионности. Вид components.xml после внесения наших изменений:


            ....
            

Объявим наш класс, который будет обрабатывать REST-запросы:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@Path("/ttt")
public class Test {
    @GET
    public Response echo(){
        String msg = "Hello, World!!!";
        System.out.println(msg);
        return Response.status(200).entity(msg).build();
    }
}
Что делает этот класс? По пути /ttt принимает GET-запрос и выводит сообщение "Hello, World!!!" в лог и возвращает его же в качестве ответа. Сервис доступен по адресу: http://<Сервер>:<Порт>/<Имя веб-приложения>/seam/resource/restv1/ttt Если ввести в браузер этот адрес, то в лог и в браузер будет выведено сообщение: "Hello, World!!!" Более полную информацию смотрите в документации к Seam Framework: 24.4. RESTful HTTP webservices with RESTEasy

Треугольник Паскаля на Java

Треугольник Паскаля имеет практическое применение в комбинаторике для нахождения сочетания из n по k. Определение из Википедии: В комбинаторике сочетанием из n по k называется набор k элементов, выбранных из данного множества, содержащего n различных элементов. Наборы, отличающиеся только порядком следования элементов (но не составом), считаются одинаковыми, этим сочетания отличаются от размещений. Вы можете встретить два вида обозначения сочетения из n по k:
nk или cnk
Давайте придумаем задачу. Задача Пусть у нас есть множество из 5 элементов: {1,2,3,4,5}. Нужно найти кол-во сочетаний из трех элементов. Причем наборы вида: {1,2,3} и {1,3,2} считаются одинаковыми и засчитываются только один раз. Ответ Из 5 элементов мы можем составить 10 наборов по 3 элемента. Вот эти подмножества:
  1. {1,2,3}
  2. {1,2,4}
  3. {1,2,5}
  4. {1,3,4}
  5. {1,3,5}
  6. {1,4,5}
  7. {2,3,4}
  8. {2,3,5}
  9. {2,4,5}
  10. {3,4,5}
Решение Задача сводится к нахождению сочетания из 5 по 3, т.е. n = 5, k = 3. Для нахождения сочетания есть готовая формула: formula_short Подставим наши значения в формулу: formula c53 Пример реализации этой формулы на Java:
long C(int n,int k){
	return fact(n) / (fact(k) * fact(n-k));
}
long fact(int num){
	long val = 1;
	for (int i = 2; i <= num; i++) {
		val *= i;
	}
	return val;
}
Пример использования:
System.out.println(C(5,3));//возвратит 10
Вычисляя факториалы в формуле, мы проводим вычисления в числителе и знаменателе, и можно заметить, что некоторые операция умножения можно сократить. Усовершенствованная версия:
long C(int n,int k){
	int res = 1;
	for (int i = n - k + 1; i <= n; i++) {
		res *= i;
	}
	
	for (int i = 2; i <= k; i++) {
		res /= i;
	}
	return res;
}
Основная сложность при расчетах - это вычисление факториала. Вычисление факториала числа - очень затратная операция, особенно, если у вас задача с расчетом большого кол-во сочетаний из n по k. Можно, конечно, кэшировать факториалы, но в формуле производятся и другие математические операции. Кроме приведенной выше формулы с факториалами существует другой способ нахождения сочетания из n по k. Способ заключается в построении треугольника Паскаля, из которого уже берутся готовые значения. Классический вид треугольника Паскаля: classic_pascal Как строится треугольник? Треугольник строится построчно сверху вниз. На вершине всегда единица. Каждый элемент в треугольнике получается сложением двух элементом, между которыми и под которыми лежит данный элемент. Причем боковые элементы получаются равными 1. В программе мы будем хранить треугольник Паскаля в двумерном массиве, поэтому он несколько видоизменится: two_dimensional Элементы треугольника - это и есть наши искомые кол-ва сочетаний из n по k: values Теперь приступим к реализации Треугольник будем хранить в двумерном массиве C[][]. Нужно определиться с типом массива, так как числа будут получаться большими, будет переполнение переменных, а вы не заметите. Приведу таблицу типов и предельных значений, после которых будет переполнение в элементах массива.
Тип массиваБезопасный предел
intпри n <= 33
longпри n <= 66
BigIntegerограничено оперативной памятью
(ниже будет рассмотрено более подробно)
Реализация для int и long одинаковая, поэтому рассмотрим только long , а вот для BigInteger немного отличается. Реализация с использованием long-массива:
public class PascalTriangle {
	private int ubound;
	private long C[][];

	//инициализация треугольника
	public PascalTriangle(int ubound){
		if(ubound > 66){
			throw new RuntimeException("Data overflow");
		}
		this.ubound = ubound;
		C = new long[ubound+1][ubound+1];
		for (int n = 0; n <= ubound; n++) {
			//первый и последний элемент в строке равен 1
			C[n][0] = C[n][n] = 1;
			//далее вычисляем внутреннюю часть
			for (int k = 1; k < n; k++) {
				C[n][k] = C[n-1][k-1] + C[n-1][k];  
			}
		}
	}

	//вывод треугольника в консоль
	public void show(){
		for (int n = 0; n <= ubound; n++) {
			for (int k = 0; k <= n; k++) {
				System.out.print(C[n][k] + " ");
			}
			System.out.println();
		}
	}

	//метод, возвращающий кол-во сочетаний из n по k
	public long get(int n,int k){
		return C[n][k];
	}
}
Пример использования:
PascalTriangle pas = new PascalTriangle(66);
//pas.show();
System.out.println(pas.get(5, 3));//результат 10
Теперь рассмотрим случай с BigInteger. BigInteger - это прекрасный класс Java по работе с длинными числами. Все числа хранятся внутри класса, а математические операции производятся с помощью методов класса. Например, операция сложения, которую мы применим в коде, производится с помощью метода add.
public class BigPascalTriangle {
	private int ubound;
	private BigInteger C[][];

	//инициализация треугольника
	public BigPascalTriangle(int ubound){
		this.ubound = ubound;
		C = new BigInteger[ubound+1][ubound+1];
		for (int n = 0; n <= ubound; n++) {
			//первый и последний элемент в строке равен 1
			C[n][0] = C[n][n] = BigInteger.ONE;
			//далее вычисляем внутреннюю часть
			for (int k = 1; k < n; k++) {
				C[n][k] = C[n-1][k-1].add(C[n-1][k]);//аналог C[n][k] = C[n-1][k-1] + C[n-1][k] для длинной арифметики
			}			
		}
	}

	//вывод треугольника в консоль
	public void show(){
		for (int n = 0; n <= ubound; n++) {
			for (int k = 0; k <= n; k++) {
				System.out.print(C[n][k] + " ");
			}
			System.out.println();
		}
	}

	//метод, возвращающий кол-во сочетаний из n по k
	public BigInteger get(int n,int k){
		return C[n][k];
	}
}
Пример использования:
BigPascalTriangle pas = new BigPascalTriangle(100);
pas.show();
System.out.println(pas.get(5, 3));//результат 10
Теперь о минусах, точнее минусе. Построение треугольника требует затрат оперативной памяти. Для массива long при n <= 66 - это неощутимо. Но для реализации с BigInteger - ощутимо, и при не хватке памяти будет выброшена ошибка:
java.lang.OutOfMemoryError: Java heap space
Ниже я приведу табличку с примерными ограничениями. Внимание! Данные приведены только с учетом построения треугольника, без учета того, что вы можете хранить в программе еще другие данные. Также данные могут отличаться, т.к. на приграничных значениях программа может то выбрасывать исключение, то не выбрасывать. Время построения треугольника тоже варьируется. Поэтому данные примерные!
Оперативная памятьДопустимое значениеВремя построения треугольника
256 МБn = 1700840 мс
512 МБn = 21501200 мс
1024 МБn = 29603700 мс
2048 МБn = 34707200 мс
4096 МБn = 434016000 мс
p.s. Треугольник Паскаля можно применять для решения и других задач. В заключении приведу цитату Мартина Гарднера о треугольнике Паскаля: Треугольник Паскаля так прост, что выписать его сможет даже десятилетний ребенок. В то же время он таит в себе неисчерпаемые сокровища и связывает воедино различные аспекты математики, не имеющие на первый взгляд между собой ничего общего. Столь необычные свойства позволяют считать треугольник Паскаля одной из наиболее изящных схем во всей математике.

Всё, что я узнал о Лондоне

Решил записать всё то, что впечатлило меня в Лондоне. Прошло уже больше года и были мы там всего недельку в январе месяце, многое забылось, но что вспомню запишу:
  1. В середине января в Лондоне не было снега
  2. В четыре вечера уже темнеет
  3. Когда проходили паспортный контроль, думал будет как у нас в ЦОНах - электронная очередь, на там было довольно человечно. Освободившийся офицер поднимал руку (как в школе :)) и к нему можно было подойти в порядке живой очереди.
  4. Меня в первый раз в жизни назвали сэром, когда офицер попросил приложить мой палец к сканеру 🙂
  5. Как доказать, что потерянный телефон твой. При проходе через металлоискатель мы сложили вещи в специальные корзины, а когда забирали вещи обратно, то сотовый телефон остался на дне корзины. Через несколько минут мы выяснили, что потеряли сотку. Вернулись назад и видим, что у одного офицера в руках наша сотка. Сказали, что это мы потеряли. Тогда нас проверили, спросив какой язык интерфейса. Мы ответили: "Рашн", и нам вернули телефон
  6. Левостороннее движение просто ломает мозг
  7. Лондон очень плотно застроен, поэтому здесь проблема с местом. Улицы настолько узкие, что диву даешься как автобусы расходятся. В гостиничных номерах все в притык. Кажется, на трех квадратных метрах размещаются умывальник, унитаз и душевая кабина, а кровать занимает большую часть комнаты.
  8. В Лондоне нет центрального отопления - каждый греется как может. Поэтому в номерах очень толстые одеяла.
  9. На улицах очень много темнокожих и азиатов.
  10. В восторге от итальянцев и итальянской кухни.
  11. Т.к. в Великобритании левостороннее движение, а в большинстве стран - правостороннее, для пешеходов на перекрестках на асфальте c одной стороны дороги написано большими буквами "LOOK RIGHT", а с другой "LOOK LEFT". Это постоянное напоминание: при левостороннем движении нужно смотреть сперва направо, а потом налево. Будьте осторожны! Например, посмотришь налево по привычке и пойдешь, а справа нежданчик в виде машины или двухэтажного автобуса. LOOK RIGHT
  12. Во многих зданиях используются подвалы, скорее всего, из-за нехватки места. В ресторанах и кафе там может размещаться кухни, туалеты. Многие магазины также размещаются в подвалах.
  13. Как-то на вокзале хотел купить сэндвич, но меня сразу предупредили, что там содержится свинина.
  14. В основном все очень приветливые, но индусы-продавцы в магазинах нет, суровые 🙁
  15. На обратных сторонах монет изображена королева, причем на монетах отражен возраст королевы. Я был поражен, что в обороте есть очень старые монеты, одну я сохранил на память, она 1982 года!!!
  16. Лондонское метро - старейшее в мире. Благодаря метро можно быстро перемещаться по городу, и как туристу успеть побывать во многих местах. У входа в метро бесплатно раздаются толстенные газеты. Когда я это увидел, у меня вырвалось: "Они бесплатные?"(на русском), а проходящая мимо женщина сказал на русском: "Бесплатно, бесплатно!" 🙂
  17. Русскоязычных много в Лондоне. Много латышей, знающих русский, работают в сфере обслуживания.
  18. В городе я не встречал полицейских, однажды встретил на ж/д станции двоих, экипировка у них была боевая
  19. Все говорят на английском с акцентов, можно суда спокойно приезжать практиковаться.
  20. Если хотите побывать в городе стариков, приезжайте в город Бат. Здесь седовласые бабушки и дедушки просто везде: в супермаркетах, магазинах, кафешках и на улицах. Молодежь просто не встретишь. В этой местности есть целебные источники, поэтому люди в возрасте переезжают под старость лет сюда.
  21. Стоунхендж, на самом деле, не таких больших размеров (как мне казалось раньше). С недавних пор Стоунхендж стал более серьезнее охраняться ЮНЕСКО, сейчас к нему близко не подпускают, а раньше можно было прикоснуться.
  22. В январе люди там бегают в шортах. Хотя из-за влажности даже в пальто продрогаешь. Видимо, они закаленные.
  23. В январе даже есть зелень. Архитектура просто неописуемая. В первый раз, когда вышел из гостиницы деревья, кустарники, трава и здания просто крышу у меня снесли со словами: "Я в Лондоне!"
Статья не закончена...

На чём лучше перемещаться в Лондоне

Блогу исполнился 1 год!!! Вот решил написать о том, что хотел написать год назад, а именно, на чем лучше перемещаться в Лондоне. Пешком - не реально, Лондон очень большой город, и чтобы увидеть все достопримечательности нужно быстро перемещаться. На такси - очень и очень дорого. Самый идеальный вариант купить Oyster Card, эта пластиковая карточка позволит свободно пользоваться метро, автобусами и поездами. Oyster-card Обо всем по порядку: 1) Где купить? Для начала нужно спуститься в метро, там будет касса, в которой можно будет купить Oyster Card. 2) Нужно определиться на какой период вам нужна карта и по каким зонам Лондона вы будете путешествовать, от этого будет зависеть стоимость карты. В Лондоне мы были неделю, поэтому взяли карточку на неделю. Лондон поделен на 6 зон. Центр Лондона - первая зона, потом идет вторая, третья, ..., и окраина Лондона - шестая зона. К примеру аэропорт Хитроу находится в шестой зоне. Обычным туристам чтобы увидеть основные достопримечательность, хватит первой и второй зоны. Чем больше зон вам нужно будет, тем дороже будет Oyster Card. Мы собирались в гости к друзьям, которые жили в третьей зоне, поэтому купили карту с 1 по 3 зону. Вот чек с покупки Oyster Card: OysterCard В чеке отражена следующая информация: Z13 - зоны действия карты с 1 по 3 07Days - период действия карты £40.60 - общая стоимость карты, в которую включен депозит в 5 фунтов. 5 фунтов вам вернут, если вы вернете пластиковую карту. Т.к. в конце нашей поездки мы вернули пластиковые карточки, то в итоге они нам обошлись в £35.60. 3) Как пользоваться Oyster Card? oyster-metro 1. При входе и выходе из метро нужно провести карточкой по турникету и всё. 2. Для поездов аналогично, при входе или выходе с платформы провести картой по турникету. 3. Если решите прокатиться на знаменитых двухэтажных автобусах (одноэтажных просто нет :)), то рядом с водителем есть специальная панель, по которой нужно провести картой. oyster-card-bus Итого мы прокатились один раз на поезде, два раза на автобусе и несчетное кол-во раз на метро. Лондонское метро - это отдельная тема. Если бы не метро, многое бы не успели! И если бы не Oyster Card разорились бы!

Задание: создать клиент Twitter’а (OAuth и REST API)

Недавно проходил собеседование на должность удаленного Android-разработчика. Дали следующее тестовой задание: Задание Создать простой twitter-клиент. Приложение должно содержать следующие функции:
  • Отображение списка твитов авторизованного пользователя (основной экран)
  • Имена пользователей должны выделятся в тексте твита и при нажатии на имя пользователя должен отображаться список твиттов этого пользователя.
  • Создание нового твита (максимум 140 символов)
Требования:
  1. Реализация на языке Java.
  2. Разрешается использовать любые библиотеки кроме непосредственно twitter-библиотеки.
После выполнения задания нужно прислать код (либо ссылку на репозитоий на GitHub), указав количество потраченного на задание времени. Информация для чтения Twitter API: https://dev.twitter.com/docs/api От себя скажу, что задание очень понравилось. На всё про всё потратил около двух суток. С твиттером я был знаком очень слабо: раньше когда-то регистрировался, но толком не пользовался. Также у меня не было опыта по работе с OAuth (википедия) и REST API (википедия). Разобравшись с OAuth авторизацией и REST API, вы сможете по такому же принципу интегрироваться почти со всеми порталами и соц. сетями. Ниже приведу скриншоты того, что получилось. 1) При первом запуске приложение перенаправляет пользователя в браузер для авторизации. После успешной авторизации браузер обратно передает управление приложению. 01 2) Открывается главное окно с твитами текущего пользователя: 02 3) Если нажать на имя пользователя, то откроются твиты этого пользователя: 03 4) Нажав кнопку "Новый твит", откроете диалоговое окно ввода текста нового твита: 04 5) Нажав кнопку "Отправить", твит появиться в твитах авторизованного пользователя: 06 6) По нажатию кнопки "Выход" приложение снова откроет странице авторизации, в которой можно будет залогиниться под другим пользователем: 07 При написании приложения очень помог код с GitHub'а: https://github.com/ddewaele/AndroidTwitterSample Код моего приложения также есть на GitHub: https://github.com/Nyquest/twitterclient Можно также скачать исходный код отсюда APK-файл: скачать Подписанный APK-файл: скачать

SQL6031N Ошибка в файле db2nodes.cfg

Несколько раз сталкивался с подобной проблемой, когда при запуску DB2 выходило следующее сообщение:
SQL6031N Ошибка в файле db2nodes.cfg
SQL6031N В моих случаях причина была в том, что у компьютера (сервера) менялось имя, а в файле db2nodes.cfg было старое название компьютера. Нужно либо вернуть компьютеру прежнее название, либо переписать название в файле db2nodes.cfg. Для это любым текстовым редактором откройте файл db2nodes.cfg, который по умолчанию расположен в папке:
C:\Program Files\IBM\SQLLIB\DB2\
Примерное содержимое этого файла:
0 microsof-0a0782 MICROSOF-0A0782 0
db2nodes cfg Допустим, теперь имя компьютера TEST, внесем соответствующие изменения:
0 test TEST 0
Обратите внимание, что имя компьютера нужно заменить в двух местах, при чем в первом случае название в нижнем регистре, а во втором - в верхнем. Почему это так - не знаю)). Все! После сохранения внесенных изменений можно запускать DB2.