Monthly Archives: Апрель 2014

Вывод числа с точностью до заданного количества цифр после запятой

Иногда требуется вывести определенное количество цифр после запятой, даже если цифры — концевые нули.

Данную задачу решает класс DecimalFormat, которому в конструктор класса необходимо передать шаблон числа.
Рассмотрим несколько вариантов использования:
1) Пример округления до трех знаков

DecimalFormat df = new DecimalFormat("0.000");
System.out.println(df.format(13.6784));//результат 13,678
System.out.println(df.format(13.6785));//результат 13,678
System.out.println(df.format(13.67851));//результат 13,679
System.out.println(df.format(13));//результат 13,000

Разделителем между целой и дробной частью в данном случае выступает запятая, но это зависит от текущей локализации.
Если в качестве разделителя требуется точка, то можем это сделать, указав американскую локализацию.
2) Округление до двух знаков и американская локализация

DecimalFormat df = new DecimalFormat("0.00",DecimalFormatSymbols.getInstance(Locale.US));
System.out.println(df.format(13.6749));//результат 13.67
System.out.println(df.format(13.6750));//результат 13.68
System.out.println(df.format(13.6751));//результат 13.68
System.out.println(df.format(13));//результат 13.00

3) Если вы были внимательны, то могли заменить, что округление работает странным образом.
Например,

System.out.println(df.format(13.6785));//результат 13,678

Хотя ожидаемый ответ: 13,679.
Все дело в том, что по умолчанию используется округление HALF_EVEN, где округление идет в сторону ближайшего четного. Это так называемое «Округление банкиров», которое используется главным образом в США. Такой способ округления позволяет снизить накопление ошибок при округлении.
Рассмотрим пример: дробные части .49 и .51 уравновешивают друг друга, одно число округляется в меньшую, а второй в большую строну. Но как быть с дробной частью .50, которая, допустим, всегда увеличивается в большую строну. Для этого придумали следующую систему: смотрим соседнее число, если число нечетно, то округляем в большую сторону; если четное, то округляем в меньшую сторону. Или проще говоря, округляем половину до ближайшего четного числа. Рассмотрим два случая:

1) Число 13.6785 после округления будет 13.678, 
т.к. цифре 5 предшествует четная цифра 8 (округляем вниз).
2) Число 13.6795 после окгруления будет 13.680. 
т.к. цифре 5 предшествует нечетная чифра 9 (округляем вверх).

Пример кода, описывающего эту ситуацию (HALF_EVEN):

DecimalFormat df = new DecimalFormat("0.000");
System.out.println(df.format(13.6785));//результат 13,678
System.out.println(df.format(13.6795));//результат 13,680

Если вас не устраивает такое округление, то можно переключиться на округление, более привычное нам — округление в большую сторону (HALF_UP):

DecimalFormat df = new DecimalFormat("0.000");
df.setRoundingMode(RoundingMode.HALF_UP);
System.out.println(df.format(13.6785));//результат 13,679
System.out.println(df.format(13.6795));//результат 13,680

Экранирование символов в названии файла

Всем нам известно, что нельзя использовать некоторые символы в названиях файлов. И на разных операционных системах эти запрещенные символы различны.
Например, в Windows это следующие символы: \ / : * ? < > |
invalid_characters
Если в вашем приложении названия файлов генерируются автоматически, то нужно подстраховаться, заменив запрещенные символы на какой-нибудь разрешенный.
Ниже будет представлена функция, которая заменяет перечисленные выше символы на символ подчеркивания «_»:

public static String screeningFileName(String fileName){
	return fileName.replaceAll("[\\\\/:*?\"<>|]","_");
}

Пример использования:

System.out.println(screeningFileName("report*2014-04-29 17:46:00.pdf"));
//результат выполнения функции: report_2014-04-29 17_46_00.pdf

Номера версий Android

Номера версий Android:

Кодовое название

Версия

Уровень API

1.0

API level 1

1.1

API level 2

Cupcake

1.5

API level 3, NDK 1

Donut

1.6

API level 4, NDK 2

Eclair

2.0

API level 5

Eclair

2.0.1

API level 6

Eclair

2.1

API level 7, NDK 3

Froyo

2.2.x

API level 8, NDK 4

Gingerbread

2.3 — 2.3.2

API level 9, NDK 5

Gingerbread

2.3.3 — 2.3.7

API level 10

Honeycomb

3.0

API level 11

Honeycomb

3.1

API level 12, NDK 6

Honeycomb

3.2.x

API level 13

Ice Cream Sandwich

4.0.1 — 4.0.2

API level 14, NDK 7

Ice Cream Sandwich

4.0.3 — 4.0.4

API level 15, NDK 8

Jelly Bean

4.1.x

API level 16

Jelly Bean

4.2.x

API level 17

Jelly Bean

4.3.x

API level 18

KitKat

4.4 — 4.4.2

API level 19

Оригинальная версия: https://source.android.com/source/build-numbers.html

Отправка письма через SMTP c NTLM-аутентификацией

Однажды, придя к заказчику, я не смог подключиться к их заранее заведенному электронному адресу для рассылок. Назовем его noreply@sample.com. Пришлось демонстрировать систему с ящиком yandex.ru. Основное предположение было то, что дело в домене. Так и оказалось, для подключения к SMTP нужно было пройти NTLM-аутентификацию (Статья о NTLM в Википедии).
Сперва у меня не получалось, т.к. использовал старую библиотеку mail.jar (версия: 1.4, размер: 379 КБ), потом скачал новую версию библиотеки, которая поддерживает NTLM: javax.mail.jar (версия: 1.5, размер: 533 КБ).
Эту версию можно скачать отсюда: javax.mail.jar

В этот статье вы встретите две реализации: одна реализация с обычным подключением к SMTP, а другая реализация с NTLM-авторизацией.

Для начала рассмотрим обычное подключение, чтобы потом увидеть разницу.
Созданим класс MailHelper, в конструкторе этого класса будут задаваться все необходимые параметры для подключения к почтовому ящику, а метод send будет отвечать за отправку писем согласно переданным в этот метод параметрам:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
 
public class MailHelper {
 
	private Properties properties;
	private Session session;
	private String currentEmail;
 
	public MailHelper(String host,String port,final String user,final String password){
		properties = new Properties();
		properties.setProperty("mail.smtp.auth","true");
		properties.setProperty("mail.smtp.host", host);
		properties.setProperty("mail.smtp.port",port);
		currentEmail = user;
		session = Session.getInstance(properties,
		  new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(user,password);
      			}
      		  });
	}
 
	public void send(String email,String subject,String body) throws Exception{
		MimeMessage msg = new MimeMessage(session);
		msg.setFrom(new InternetAddress(currentEmail));
		msg.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
		msg.setSubject(subject);
		msg.setContent(body, "text/html; charset=utf-8");
		Transport.send(msg);
	}
}

Пример использования этого класса:

MailHelper mailHelper = new MailHelper(
		"smtp.sample.com","25",
		"noreply@sample.com","password123");
try {
	mailHelper.send("target@sample.com", "Проверка", "Привет, <b>Target</b>!");
} catch (Exception e) {
	e.printStackTrace();
}

В конструктор передаются: адрес SMTP-сервера, порт, логин и пароль.
В метод send передаются: электронный адрес получателя, заголовок и содержимое письма.

Теперь рассмотрим реализацию с NTLM. Практически тоже самое, только при создании объекта класса PasswordAuthentication нужно указать имя учетной записи в домене, а адрес электронной почты передается отдельным параметром.

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
 
public class MailHelper {
 
	private Properties properties;
	private Session session;
	private String currentEmail;
 
	public MailHelper(String host,String port,
		final String user,final String password,String email){
		properties = new Properties();
		properties.setProperty("mail.smtp.auth","true");
		properties.setProperty("mail.smtp.host", host);
		properties.setProperty("mail.smtp.port",port);
		currentEmail = email;
		session = Session.getInstance(properties,
      		  new javax.mail.Authenticator() {
      			protected PasswordAuthentication getPasswordAuthentication() {
      				return new PasswordAuthentication(user,password);
      			}
      		  });
	}
 
	public void send(String email,String subject,String body) throws Exception{
		MimeMessage msg = new MimeMessage(session);
		msg.setFrom(new InternetAddress(currentEmail));
		msg.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
		msg.setSubject(subject);
		msg.setContent(body, "text/html; charset=utf-8");
		Transport.send(msg);
	}
}

Пример использования:

MailHelper mailHelper = new MailHelper("192.168.0.2","25",
	"noreply","password123","noreply@sample.com");
try {
	mailHelper.send("target@sample.com", "Проверка", "Привет, <b>Target</b>!");
} catch (Exception e) {
	e.printStackTrace();
}

Конструктор принимает следующий параметры:
Адрес и порт SMTP-сервера, доменную учетную запись и пароль, а также адрес электронной почты, от имени которой будут уходить письма.
Метод send принимает те же параметры, что и в предыдущем примере: адрес получателя, тема и содержимое письма.

В итоге на указанный ящик должно прийти сообщение:

Привет, Мир! 

Шпаргалка по MySQL (Утилиты)

Запуск MySQL-клиента:

mysql -uroot -p

Запуск MySQL-клиента c указанием хоста:

mysql -h192.168.0.2 -uroot -p

Запуск MySQL-клиента c указанием хоста и порта:

mysql -h192.168.0.2 -P3307 -uroot -p

Создание резервной копии:

mysqldump -uroot -p test > test.sql

Создание резервной копии c указанием максимального размера пакета:

mysqldump -uroot -p --max_allowed_packet=128M test > test.sql

Восстановление резервной копии:

mysql -uroot -p < test.sql test

Смена пароля:

mysqladmin -uroot -p password mynewpass

Биржевая диаграмма на Flot

Как-то мне дали задание:

Сделать рандомно растущий график используя любые инструменты. 

Образцом была следующая gif-ка:
graph

Просмотрев несколько инструментов для рисования графиков, остановился на Flot.
Flot — JavaScript библиотека для jQuery для рисования графиков.
Скачать Flot с примерами можно с официального сайта http://www.flotcharts.org. Стоит отметить наличие хороших примеров использования Flot для построения различных графиков и диаграмм.

За вечерок смог реализовать на Flot задание.
В статике это выглядит так:
stock_chart

В динамике это выглядит так: http://kesh.kz/stock_chart/.

Кстати, мне так и не ответили справился ли я с заданием. Не пропадать же потраченному времени зря, поэтому выкладываю весь пример целиком, может кому пригодится: Скачать 🙂