A word against credit cards

Рубрика: Разное | 29 December 2006, 21:45 | juriy

Мы все уже привыкли к тому что кредитные карты прочно вошли в нашу жизнь. До сегодняшнего дня я относился к классу людей, которые верили в то, что кредитная карта намного лучше и удобнее морально устаревшей налички. Сегодня – я перестал относится к этому классу. Сейчас попробую объяснить свою точку зрения.
Сегодня я созрел на существенную покупку. Решил немного обновить свой парк элетроники. Я зашел в City.com – местный супермаркет электроники, выбрал “обновочки” на круглую сумму и смело пошел на кассы.
Действие стандартные: удостоверение личности, кредитка – миловидной кассирше немного провинциального вида. Смелое движение картой по разъему терминала – и ожидание чека… В этот момент второй кассирше приспичило поговорить по телефону и она подняла трубку.
- Куда ты, – прикрикнула на нее первая
- Ой, а ты карточку проводишь, – невинно захлопала ресницами вторая.
Из терминала выползла бумажка с надписью: “запрещено”
- А там был модем, – спокойно отшутился я, зная основные свойства транзакций.
- Ага, – ответила она.
Моему удивлению не было предела, когда из терминала вылезла вторая бумажа с надписью: “недостаточно средств”. (Как! Ведь я проверял ее перед тем, как войти в магазин…)
Началось самое забавное (в подробностях описывать не буду, уж очень длинная “пьесса” получится – больше часа с антрактом). Позвонили в банк – владелец карточки – транзакция прошла (уже что-то). В банке – получателе (банк – влделец терминала) сообщили, что транзакция неуспешна. (Вот в этом месте я начал действительно сильно нервничать).
Нет, деньги мне вернут – пообещали в обоих банках, но через 30 дней, когда транзакция будет опровергнута документально банком-получателем. Мне от этого легче не стало. Еще пол часа давления на агентов кол-центра, и они соизволили оформить запрос в виде факса на банк-получатель.
Деньги мне вернут не через 30 дней, а через 5, но все равно – мой подарок на новый год сорвался, и настроение крепко подпортилось.
P.S. Как же хорошо, что на карточке остались деньги “на жизнь”. Я себе не представляю, что бы я делал, если бы снял _всю_ сумму.

Last post in 2006

Рубрика: Блоггинг | 29 December 2006, 14:43 | Vadim Voituk

Вот проходит последний рабочий день уходящего 2006 года.
Хотя те, кто знает где и как я работаю наверное пошутят а-ля “Твой последний рабочий день года закончится 31 декабря в 23:59″ :)
А вообще эта заметка о моих финансово-проффесиональных планах на 2007-й.
Итак

  1. Получить сертификат о праве собственности на свою новую квартиру
  2. Забрать диплом с университета (вроде должны 10 лет хранить, но рисковать не стоит)
  3. Получить военный билет (пора бы уже эти всерьез заняться)
  4. Повысить свой доход как минимум в 2 раза (а лучше в 3 :))
  5. Сделать ремонт в новой квартире и поселить туда квартирантов
  6. Отдать долги за всю ту же квартиру
  7. Нормально изучить J2EE (“нормально” != “поделки на коленках”) и внедрить его в компании
  8. Заказать большой книжный стелаж на всю стену (количество Оксаниных книг на подоконнике растет экспотенциально)
  9. В январе-феврале сьездить покататься на лыжах (Закопане, Буковель или на худой конец Славское)
  10. Сделать то, что забыл написать в списке выше…

Писать о планах личного характера не писал нарочно – на то они и “личные” ;)

About Google. Again.

Рубрика: Google | 25 December 2006, 13:58 | Vadim Voituk

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

Пока же я ищу причины такого феномена, расскажу о выходе новой разработки от Google – Google Patent Search.
Создатели обещают поиск среди 7 миллионов патентов Американского патентного бюро собранные в период с 1790 по 2006 г.г.
С одной стороны достаточно интересная развлекуха, и возможность расширить кругозор исследуя патенты на скейтборд или солнцезачитные очки.
С другой же стороны возможность поиска патентированности неких собственных идей. А-ля “А не запатентовал ли кто-то это до меня?”.

Ещё довольно интересные патенты в области разработки ПО можно найти, задав в качестве строки поиска термин из ловаря разработчика.

Примеры:

Exception handling in java computing environments- Sun Microsystems Inc.

System and methodology providing compiler-assisted refactoring – Borland Corp.

Java C++ proxy objects – Hewlet-Packard

Type checking in java computing environments – Sun Microsystems Inc.

Flattening complex data structures in Java/Javascript objects – IBM
Вообщем читать-не-перечитать.
Да и применений такому поиску думаю можно найти побольше…

Find the food

Рубрика: Development | 24 December 2006, 04:17 | juriy

Зверек, который получился в прошлой заметке, был не слишком жизнеспособным: побегав некоторое время вокруг – он погибал от голода. В этой заметке я постараюсь сделать так, чтобы зверь мог найти корм, хотя бы под собственным носом.
Перед тем, как приступить к написанию кода, надо рассмотреть два важных вопроса: как зверь может получить сведения о внешнем мире, и как на основании этих сведений узнать, что в клетке есть источник пищи.
Начнем по порядку.
Общие сведения о мире, которые не меняются на протяжении игры, можно получить, воспользовавшись классом universum.bi.Constants. К таким сведениям относится, к примеру, размер “джунглей” (ширина и высота). Кроме того, в этом классе “живут” константы, которые определяют механику игры: какое минимальное число энергии необходимо, чтобы произвести потомство, сколько энергии необходимо потратить на атаку, сколько на перемещение. Полный список констант можно посмотреть прямо в исходниках класса.
Информацию о том, по каким правилам проводится игра (тип игры: “дуэль”, “блицкриг” или “джунгли”) можно получить из объекта класса UserGameInfo, который передается в метод reinit вашего зверя.
Последний, и самый важный тип данных: это данные о том, как воспринимает себя и окружающий мир ваш зверек непосредственно в момент хода. К примеру: количество энергии зверька, или данные о клетке, на которой он стоит, или список клеток, на которые зверь может перейти за ход. Всю эту информацию можно получить из объекта класса BeingInterface, который передается в метод makeTurn вашего зверя.
Ниже – пример кода, который получает различные сведения о текущем состоянии джунглей.
[java]

public void printInfo() {
  // Сколько у зверя энергии (на момент хода)
  float currentHealth = world.getEnergy(this);
  // У Грокка не самый лучший английский :-)
  System.out.println("Grokk hav da " + currentHealth + " energi");

  // Получаем координаты клетки в которой находится зверь
  int myPositionX = world.getLocation(this).getX();
  int myPositionY = world.getLocation(this).getY();
  System.out.println("I standin in " + myPositionX + ":" + myPositionY);

  // Получаем данные о клетке, в которой мы находимся
  PointInfo pointInfo = world.getPointInfo(this);
  // получаем данные о том, есть ли в клетке еда!
  float foodCount = pointInfo.getCount(this);
  if (foodCount > 0)
    System.out.println("Yumi, yum! Got " + foodCount + " food");
  else
    System.out.println("Oh, no food!");
}
public Event makeTurn(BeingInterface world) {
  this.world = world;
  printInfo();
  return makeRandomMove();
}

[/java]
Таким образом – есть все необходимые инструменты для того, чтобы “научить” зверя “видеть” еду, если она лежит прямо под ногами.
Остановимся немного на том, как “действует” еда в электронных джунглях. Вы уже запускали эмулятор джунглей, поэтому не могли не заметить маленькие “яблочки” разбросанные по полю. Это и есть источники еды. Каждый источник характеризуется тремя величинами: количеством еды, доступным сейчас, максимальным возможным количеством еды и приростом еды за ход. Получить эти значения для каждой клетки можно, используя функции PointInfo.getCount, PointInfo.getMaxCount, PointInfo.getGrowthRate.
Есть два вида источников: “обычные” и “золотые”. “Золотые” отличаются от “обычных” тем, что все три описанных параметра для них существенно выше (и заполучить такой источник, соответственно, намного приятнее).
Все что осталось – запрограммировать зверька таким образом, чтобы он искал “еду”.
Напишем одну простую функцию, которая будет определять: достаточно ли хорош источник для того, чтобы остановиться на нем:
[java]
private boolean isHive(PointInfo pointInfo) {
return (pointInfo.getCount(this) > 0);
}
[/java]
Создадим маленькую функцию, которая будет форировать событие ACTION_EAT:
[java]
private Event doEat() {
return new Event(EventKind.ACTION_EAT, MASS*Constants.K_bite);
}
[/java]
Теперь остается модифицировать функцию makeTurn:
[java]
public Event makeTurn(BeingInterface world) {
this.world = world;

if (isHive(world.getPointInfo(this)))
return doEat();
else
return makeRandomMove();
}
[/java]
Все готово к тестовому запуску. В этот раз эмулятор джунглей лучше запустить так:
java -jar ejungle_distr.jar -altui -debug
В “альтернативном интерфейсе” можно выбрать View->Show Grid, чтобы отображались границы клеток (так легче контролировать, что зверь действует “по плану”), а опция -debug будет выводить в консоль описания всех событий с параметрами.
Ниже – код того, что получилось:
[java]
package ua.net.lab.beings;
import java.util.List;
import universum.bi.Being;
import universum.bi.BeingInterface;
import universum.bi.BeingParams;
import universum.bi.Constants;
import universum.bi.Event;
import universum.bi.EventKind;
import universum.bi.Location;
import universum.bi.PointInfo;
import universum.bi.UserGameInfo;
import universum.util.Util;
public class Grokk implements Being {

private final static float MASS = 10f;
private final static float SPEED = 2f;

private BeingInterface world;

public String getName() {
return “Grokk”;
}
public String getOwnerName() {
return “Juriy”;
}
public BeingParams getParams() {
return new BeingParams(MASS, SPEED);
}
public void reinit(UserGameInfo info) {
}
public Event makeTurn(BeingInterface world) {
this.world = world;

if (isHive(world.getPointInfo(this)))
return doEat();
else
return makeRandomMove();
}

private boolean isHive(PointInfo pointInfo) {
return (pointInfo.getCount(this) > 0);
}

private Event doEat() {
return new Event(EventKind.ACTION_EAT, MASS*Constants.K_bite);
}

public Event stepOneRight() {
Location myLocation = world.getLocation(this);
Location targetLocation = new Location(myLocation.getX() + 1, myLocation.getY());
return new Event(EventKind.ACTION_MOVE_TO, targetLocation);
}
private Event makeRandomMove() {
// Получаем список клеток, в которые можно попасть за ход
List<Location> canReach = world.getReachableLocations(this);

// Выбираем клетку случайным образом и создаем событие – движение
// в выбранную клетку.
return new Event(
EventKind.ACTION_MOVE_TO,
canReach.get(
Util.rnd(canReach.size())));
}
public void processEvent(BeingInterface bi, Event e) {
}
}
[/java]

Let the Grokk Be

Рубрика: Development | 22 December 2006, 13:35 | juriy

По заявкам трудящихся: как сделать простого зверя.

В этой статье описан процесс создания простого зверька для онлайн соревнования искусственных интеллектов: Электро Джунгли. Детальнее про то, что это за проект можно на официальном сайте: http://www.electricjungle.ru или прочитать в моем маленьком обзоре http://voituk.kiev.ua/2006/12/22/elecrojungle-hunters-twilight/

Я использую Eclipse, поэтому я буду описывать весь “процесс” именно на примере этой IDE.
Итак, для начала необходимо подготовить среду разработки.

1. Создаем новый Java проект.
2. Добавляем в Build Path библиотеку, которую скачали с сайта (для тех, кто еще не скачал – можно взять тут: http://www.electricjungle.ru:8080/main.jsp?page=sdk).
3. Создаем новый package. Создаем в этом package новый класс, который будет описывать логику поведения зверя. В моем примере я буду использовать пакет ua.net.lab.beings, а класс будет называться Grokk. Класс должен реализовывать интерфейс universum.bi.Being.
4. После создания и автоматической генерации заглушек для абстрактных классов код выглядит так:

[java]

package ua.net.lab.beings;

import universum.bi.Being;
import universum.bi.BeingInterface;
import universum.bi.BeingParams;
import universum.bi.Event;
import universum.bi.UserGameInfo;

public class Grokk implements Being {

  public String getName() {
    return null;
  }

  public String getOwnerName() {
    return null;
  }

  public BeingParams getParams() {
    return null;
  }

  public void reinit(UserGameInfo info) {
  }

  public Event makeTurn(BeingInterface world) {
    return null;
  }

  public void processEvent(BeingInterface bi, Event e) {}
}

[/java]

Теперь нужно заполнить заглушки кодом. Начнем с самого простого. Функции getName() и getOwnerName() возвращают, соответственно имя зверюшки и имя создателя.
[java]

public String getName() {
  return "Grokk";
}

public String getOwnerName() {
  return "Juriy";
}

[/java]

Дальше идет функция getParams() – она определяет начальные параметры первого существа (параметры следующих поколений могут быть другими): его массу и скорость. Эти параметры лучше сразу вынести в константы: их придется подбирать экспериментально. Поскольку менять легче в одном месте, то так и поступим:
[java]

private final static float MASS = 10f;
private final static float SPEED = 2f;

....

public BeingParams getParams() {
  return new BeingParams(MASS, SPEED);
}

[/java]

Функция reinit(UserGameInfo info) – вызывается при старте. Из нее зверек может узнать базовые сведения про мир. Здесь немного отвлечемся от кода и снова глянем на правила: есть на сайте описано 3 типа игры:

SINGLE – твоя зверюга – одна в джунглях. Цель – получить за ограниченное количество ходов максимальную массу популяции.
DUEL – думаю, без комментариев – в джунглях 2 вида. Победит тот, у кого после определенного количества ходов – максимальная масса популяции.
JUNGLE – то же самое, что и DUEL, только видов может быть до 8.

В файле с описанием констант: universum.bi.GameKind есть описание еще для двух типов игр: PEACE_DUEL и DEBUG. Поскольку комментариев про эти типы игр нет, то я оставляю читателям трактовать значения.

Вернемся к коду. Поскольку существо не настолько умное, чтобы его поведение менялось в зависимости от типа игры, то функцию reinit(UserGameInfo info) оставим пустой. В более продвинутом зверьке в этой функции можно инициализировать static переменные. Функция вызывается один раз, до установки первого зверя на поле.

Дальше – самое интересное. Функция makeTurn(BeingInterface world) – сердце (вернее, мозг) вашего зверя. Тут зверь решает, куда ему пойти.
Параметр, который передается в функцию, позволяет зверю получить данные о мире, который его окружает. Поскольку для принятия решений о действиях эта переменная будет нужна постоянно, лучше ее с самого начала сделать полем класса, и обновлять каждый раз при вызове makeTurn(BeingInterface world).

[java]

private BeingInterface world;
...
public Event makeTurn(BeingInterface world) {
  this.world = world;
  return null;
}

[/java]

Пускай зверек двигается случайным образом в любую доступную клетку. Для этого я создал отдельную функцию – makeRandomMove(), которая возвращает Event – решение зверька о том, что делать дальше.
[java]

private Event makeRandomMove() {
  // Получаем список клеток, в которые можно попасть за ход
  List<Location> canReach = world.getReachableLocations(this);

  // Выбираем клетку случайным образом и создаем событие - движение
  // в выбранную клетку.
  return new Event(
      EventKind.ACTION_MOVE_TO,
      canReach.get(Util.rnd(canReach.size())));
}[/java]

Обратите внимание на Util.rnd(canReach.size()). Авторы не рекомендуют пользоваться java.util.Random для выбора случайных чисел. Util.rnd() - тот же Random только в профиль. Все чем он отличается: в режиме отладки он генерирует одинаковые последовательности случайных чисел.

Теперь остается поменять makeTurn(BeingInterface world) так чтобы зверь двигался в случайном направлении каждый ход.

[java]
public Event makeTurn(BeingInterface world) {
  this.world = world;
  return makeRandomMove();
}

[/java]

Все что осталось сделать - запаковать зверя в jar и не забыть добавить в MANIFEST.MF строку

Main-Class: ua.net.lab.beings.Grokk

Теперь отпускаем зверя на волю: запускаем эмулятор джунглей:

java -jar ejungle_distr.jar

в GUI добавляем в джунгли нового зверя: Add Being -> Add from jar.

Зверек немного побегает и сдохнет от голода: кушать он не умеет. Но научим мы его позже, сейчас немного поработать надо :)

Вот код того что получилось:
[java]

package ua.net.lab.beings;

import java.util.List;

import universum.bi.Being;
import universum.bi.BeingInterface;
import universum.bi.BeingParams;
import universum.bi.Event;
import universum.bi.EventKind;
import universum.bi.Location;
import universum.bi.UserGameInfo;
import universum.util.Util;

public class Grokk implements Being {
  private final static float MASS = 10f;
  private final static float SPEED = 2f;

  private BeingInterface world;

  public String getName() {
    return "Grokk";
  }

  public String getOwnerName() {
    return "Juriy";
  }

  public BeingParams getParams() {
    return new BeingParams(MASS, SPEED);
  }

  public void reinit(UserGameInfo info) {}

  public Event makeTurn(BeingInterface world) {
    this.world = world;
    return makeRandomMove();
  }

  private Event makeRandomMove() {
    // Получаем список клеток, в которые можно попасть за ход
    List<Location> canReach = world.getReachableLocations(this);

    // Выбираем клетку случайным образом и создаем событие - движение
     // в выбранную клетку.
    return new Event(
      EventKind.ACTION_MOVE_TO,
      canReach.get(Util.rnd(canReach.size())));
  }
  public void processEvent(BeingInterface bi, Event e) {}
}

[/java]

Elecrojungle: hunters twilight

Рубрика: Development | 22 December 2006, 12:07 | juriy

Уж не знаю, как это так выходит, но Вадим обо всем новом и интересном узнает раньше. Только я найду что-то стоящее внимания – кидаю ему ссылку, а он мне в ответ что-то вроде “Тю, ты только узнал, так это уже давно…”. Этот раз исключением не стал, только ссылку кинум не я ему, а он мне. Ссылка эта – http://www.electricjungle.ru/
Суть проекта – довольно интересна. Есть виртуальные джунгли – простая сетка, замкнутая по краям. Есть SDK, который позволяет написать зверька, который будет счастливо (или не очень, все зависит от рук создателя) жить в этих джунглях.
Жить в джунгях не просто, надо бороться за выживание с другими такими же умниками, как ты. Цель – сделать так, чтобы твоя популяция была самой большой после определенного количества ходов.
Правила достаточно просты – их можно посмотреть прямо на сайте. Тут я вкратце коснусь основ создания своего личного зверька.
Зверек характеризуется двумя величинами: размер и скорость. Кроме того у каждого индивида есть энергия, которую он может тратить на действия. Максимальное количество энергии равно массе существа.
Что может делать зверек:

1. Можно стоять и перекуривать (не делать ничего, пропустить ход). Энергии не требует.
2. Можно двигаться. Количество клеток, на которые зверь может перейти за ход – определяется его скоростью. Энергия, которая тратится на это действие прямо пропорционально массе и скорости существа (да, да, можно сделать слона, который будет догонять гепардов, но такая туша должна точно знать, где себя прокормить).
3. Можно есть. Понятно, что энергии не требует. Слопать за раз можно не больше чем 10% от максимальной энергии.
4. Можно атаковать: тратится около 1% энергии за атаку (точное значение нужно глянуть на сайте). Ну и повреждения, которые наносит зверек – пропорциональны массе.
5. Можно отдавать энергию другому существу (“лечить”, так и представляю клирика-носорога!).
6. Можно размножаться. Тут самое интересное. Во-первых, существа размножаются делением (партнер не нужен). Да и сам процесс интересен: чтобы разделиться нужно иметь минимум 80% энергии. 20% тратится на процесс. Половина того что осталось – переходит новому зверьку. Очень классная идея! При рождении новому зверьку можно передать “генокод” – произвольный объект, который затем можно использовать для определения поведение зверька! Кроме того, звери могут понемногу “эволюционировать”. За одно поколение можно изменить на 20% массу и скорость новой особи.

Разработка.
Разработка своего маленького кибернетического чуда – не составляет особого труда. Основная сложность на моем пути заключалась в том, что документация… нет она не плохая ее просто нет. Все чем вы располагаете вначале – это SDK с исходниками и один простой зверек, на которого можно смотреть.
Я опишу процесс создания и запуска простого зверька “с высоты птичьего полета”. Может, если тема будет развиваться напишу небольшой “kick-off”, который опишет процесс “по шагам”. Кстати, если будет интересно – пишите.

Для того чтобы создать зверя нужно создать класс, который реализует интерфейс Being, и, соответственно, реализовать несколько функций. Основная из них -

public Event makeTurn(BeingInterface world)

В ней зверек решает, что ему делать, основываясь на данных, полученных от внешнего мира и делает ход.
После этого – необходимо запаковать зверя в .jar и в манифесте указать в параметре Main-Class – класс зверя (мне кажется, это неправильный подход, ведь этот атрибут для другого предназначен). Теперь можно запустить софтинку, загруженную с сайта, и добавить зверя в джунгли. Все, можно наслаждаться наблюдением за ростом вашего чёртика!

J2ME 101 on ibm.com

Рубрика: Development | 19 December 2006, 09:38 | Vadim Voituk

В рамках колонки “J2ME 101″ на IBM DeveloperWorks опубликовано 2 русскоязычных статьи о высокоуровневых и низкоуровневых пользовательских интерфейсах в J2ME-приложениях.

Для новичков очень даже неплохо.

Updated: Добавлена статья “Доступ к мобильной базе данных”.
 

2 news from OnJava.com

Рубрика: Google, Java | 12 December 2006, 10:08 | Vadim Voituk

Google со своим GWT присоединяется к Eclipse Community и выпускает его по Apache Software License, а Джеймc Гослинг после выхода Java под GPL и релиза JDK6.0 Mustang пишет письма в Java community.
От второй новости чуть слезу не пустил :)

IE + GET + JavaScript

Рубрика: JavaScript/Ajax | 11 December 2006, 16:48 | juriy

Вот еще один “подводный камень” от IE. При попытке отправить боольшущую форму большим количеством полей и текста через GET, IE… не делает вообще ничего. Все намного хуже (как в моем варианте было) если форма отправляется JavaScript’ом. Тогда IE выдаст “ошибку синтаксиса” на строке, где вызывается submit().

Tomcat resource usage monitoring using jConsole

Рубрика: Development, Java | 7 December 2006, 11:21 | Vadim Voituk

Ни для кого не секрет что серверные Java-приложения требуют под себя относительно много оперативной памяти, а OutOfMemoryException достаточно частое явление в J2EE среде.
Потому мониторинг загруженности сервера является достаточно необходимой задачей.

Самым примитивным методом мониторинга является *nix команда top.
Вот только полезной информации она дает мало, да и мониторит загруженность всей программно-апаратной системы.
Меня же чаще всего интерисует сколько ресурсов “отьедает” мое приложение в паре с сервлет-контейнером.
Можно, конечно, смотреть сколько ресурсов отедают всуме все java-процессы, но это скорее костыль, чем решение.
К моему огромному счастью в Java 5 придумали JMX API а к нему и jConsole.

С этого момента жизнь становится “проще и уютней”. Запускаем Tomcat таким образом:
$export JAVA_OPTS='-Dcom.sun.management.jmxremote.port=8004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false'
$/usr/local/tomcat/bin/catalina.sh start

далее на рабочей машине запускаем jconsole и указываем удаленное подключение на сервер по укананному (8004-му) порту.
В результате видим подобную картину:

jconsole

Более подробно можно прочитать тут.

P.S. Достаточно интересно наблюдать работу Garbage Collector на Heap Memory Usage Monitor – получается такая себе “пила”.

Страница 1 из 212