20.07.11

Каждый человек... и т.д. Дополнение

В дополнение к посту про вождение.
Это моя бумажка с вождения, в ней отмечены все сделанные мной ошибки.

18.07.11

Каждый человек имеет право. Часть вторая. Вождение

Итак, теория сдана, деньги за вождение заплачены, дата определена. Самое время пойти и взять пару уроков сдачи экзамена. Да-да, именно сдачи экзамена, а не вождения. Водить любой дурак может и примеров этому — тысячи. И все вокруг нас.
Но вернемся к вождению. Стоит хотя бы раз проехаться с инструктором в районе где будет проходить сдача теста и выполнить все те действия, которые будут на экзамене. Так я и сделал. Заодно понял, что опыт вождения не гарантирут сдачу экзамена. Главное на экзамене — крутить головой (показательно, чтобы экзаменатор видел), контролировать скорость и парковаться на расстоянии от 15 до 30 сантиметров от бровки :)
Я взял два урока — один раз просто так, а второй раз — непосредственно перед сдачей.
На сдачу вождения надо приехать на своей машине. Поскольку моя осталась на расстоянии в семь с половиной тысяч км, пришлось искать другой вариант. Это кстати еще один повод взять уроки — инструктор легко, баксов за 100-120, предоставит вам свой пепелац для сдачи экзамена.
Во время экзамена рядом сидит скучный экзаменатор и бубнит “turn left on a next street”, “change lane to the left and back” и т.д. И все записывает. Не проверил слепую зону при перестроении — галочка в списке ошибок, не посмотрел по сторонам проезжая перекресток — галочка, превысил скорость — галочка, едешь 50 при ограничении 60 — галочка. Всего можно набрать до 29 галочек. Правда если сделать более двух однотипных ошибок — все, экзамен не сдан. Спасает то, что ошибки однотипные, но в разных разделах теста. И если в первый раз не проверил слепую зону при перестроении на хайвее, а второй раз — при парковке в жилой зоне, то эти две однотипных ошибки считаются разными.
В общем 12 ошибок из 29, congratulations, you have passed the test и я иду к стойке получать права. Права выдают временные, напечатанные на листике, пластиковая карточка прийдет по почте недели через полторы. Права выдаются на 5 лет. Через пять лет надо будет пойти сфотографироваться, заплатить денежку и получить новую карточку на следующие 5 лет.

Каждый человек имеет право

Расскажу про то, как я получал канадские права. Еще раз отмечу, что мой опыт относится к провинции Онтарио, в других местах все может быть по другому.
Прежде всего о системе категорий. Для права управления легковыми автомобилями, водитель должен иметь категорию G. Получить ее просто так нельзя. Сначала надо сдать Written Test, по-нашему - теорию. После этого выдаются права категории G1, с которыми уже можно ездить. Но при этом в машине рядом с водителем должен находиться другой водитель с правами категории G и минимум 4 годами стажа. Ну и на самого водителя накладывается куча ограничений, где и как он может ездить.
Проездив таким образом год, можно сдавать вождение - G1 exit test. Сдав его, молодой водитель получает категорию G2. С ней уже, наконец, можно ездить самостоятельно. По прежнему нельзя ни капли спиртного и нельзя сажать в машину больше пассажиров, чем есть ремней безопасности. Проездив год с категорией G2, можно опять сдавать вождение - G2 exit test. Тут проверят еще умение ездить по хайвею. Сдав и этот тест, наконец-то получаешь вожделенные права категории G.
Если вы в Онтарио понаехали уже с родными правами то можно себе жизнь упростить. Если в правах все написано по английски или французски, ну или если права перевести в консульстве, то вождение можно сдать сразу и сразу получить G2. Если еще взять из консульства бумажку, подверждающую немеряный опыт управления самодвижущимися повозками в этих ваших странах, то можно сдавать сразу на G.
Мои старые украинские права (картонка в ламинате) не проканали, пришлось их переводить. Новые, пластиковые, проканывают. Еще один нюанс - если имя в правах и в паспорте написано по разному, то придется еще брать из консульства справку про то, что вы - это вы, как бы вас не писали.
Сам экзамен довольно прост. Состоит из двух частей по 20 вопросов. В каждой части можно сделать до 4-х ошибок. Самые на мой взгяд поганые вопросы - про наказания за нарушения. Но их всего 4 или 5 в билете, так что применяя здравый смысл и везение, довольно легко уложиться в 20% ошибок. Я к теории практически не готовился, прочитал скачанный PDF с правилами вечером перед экзаменом.
Вся процедура с регистрацией, тестом зрения и оплатой заняла минут 40. Но это потому, что я пришел за пол-часа до открытия центра и был первый в очереди.

В следующий раз - про сдачу вождения.

Держим в банко миллионо...

Один из важных пунктов для начинающего гастарбайтера - банковский счет, на который благодарный работодатель сможет перечислять честно заработанное бабло.
Открыть счет просто — идете в любой банк, который нравится и говорите, что хотите счет. Через минут 30-40 у вас будет счет (даже два — chequing и savings) , несколько чеков и дебитная карточка. Вариантов разных тарифов довольно много, возможно для начала будет достаточно того, что предложат в банке.
Пара вещей, не очевидных для граждан, прибывших из стран, в которых банковская система ориентирована на то, что люди тратят те деньги, которые у них есть. Первое - транзакции по дебитной карте — платные. Обычно в пакет входит некоторое количество бесплатных транзакций в месяц, за остальные придется отдавать свои кровные денежки. Стоимость транзакции можно уменьшить, если положить на счет какую-то сумму, например не менее 3000 долларов. Второе — дебитная карта не годится для использования в интернете. Она не принадлежит ни к какой платежной системе, ее номер может состоять не из 16 цифр, а из, к примеру, 19 и на ней нет ни имени владельца, ни CVV2 кода.
В любом случае, лучше всего сразу получать кредитную карту — это поможет в создании кредитной истории, без которой могут быть сложности со снятием жилья, покупкой чего-либо в кредит и т.д.
Но без кредитной истории вам кредитную карту просто так не сделают. Вот такой замкнутый круг получается. Чтобы этот круг разорвать потребуются деньги. Вы эти деньги кладете на свой savings счет, и банк их там замораживает как гарантию того, что вы погасите кредит. Банк выдаст вам кредитную карту с лимитом равным сумме, замороженной на счету. Это называется secured credit card. Через какое-то время (зависит от банка — у меня это 2 года), когда банк убедится, что вы исправно погашаете кредит, вы сможете получить unsecure credit card, а деньги вам вернутся.
Кредитную карту так же можно получить в каком-нибудь крупном магазине, типа Wal-Mart. Ее предлагают всем, но могут не выдать, если им не понравится ваша кредитная история. Так что лучше начать с банковской кредитки, а волмартовскую получить месяца через три-четыре. У магазинной кредитки есть также бонус в виде скидки на покупку в этом магазине.
Так же стоит сразу же при получении карты заказать чековую книжку. Она понадобится при съеме квартиры. Обычно, снимая жилье, вы платите за первый и последний месяц, на остальной срок выдаете хозяину 10 чеков, датированные каждым последующим месяцем. Если вы не закажете чековую книжку, то у вас будет только несколько (в моем банке 4,  в других может отличаться) чеков, чего явно не достаточно. Учитывая, что чековая книжка придет к вам по почте через 7-10 дней после заказа, не стоит с этим затягивать.

Где находится Канадá?

Канада в данный момент находится вокруг меня. В основном на север, немного на восток и много на запад.
Вообще-то нифига я не планировал писать про Канаду. Хотел обойтись фотками. Однако в Greater Toronto Area особых красот за прошедшие две с половиной недели я не обнаружил, а вот экспириенса в плане гастарбайтерства немного получил.
Поэтому когда в очередной раз надоело читать книжку в отеле, я решил попробовать чего-нибудь написать. Поделиться, так сказать, опытом. Just for lulz.
Канада, как вы все безусловно помните по школьным занятиям географией, является конфедерацией. Я нахожусь в провинции Онтарио, возможно в других провинциях все на самом деле по другому, я не знаю.

23.04.11

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

Вчера получил это:
Congrats! Be Informed that, £1,500,000 British Pounds has been Awarded to your Email held in April, 2011;
Fill Form;
Name....
Address...
Country...
Tel...
We await your Response

А сегодня этот шедевр лаконичности:
Your email address have won 2.5 million pounds.Names:Address:Country:Age:
Измельчали, измельчали

10.04.11

Андроид: Поддержка нескольких языков и переключение их из настроек приложения.

Нелегкая судьба андроид-программиста заставила меня принять участие в Контесте андроид-разработчиков, проводимом HTC.

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

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

А еще хотелось, чтобы пользователь мог переключать язык из настроек приложения.

Cyanogenmod поддерживает возможность установки украинской локали. Однако, по понятным причинам, не стоит ожидать, что жюри в конкурсе HTC будет использовать устройства с цианогеном.

Я остался перед выбором:

  • в качестве языка по умолчанию использовать украинский. После окончания конкурса заменить его на английский, а русский и украинский оставить тем, у кого включена соответствующая локаль.
  • забыть про системные средства локализации, сделать свой менеджер локализации. 

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

Поэтому я остановился на 1-м варианте. Но не сразу. Я таки сделал маленький mock-менеджер локализации и попробовал как он работает. Получилось отвратительно. Но! Благодаря этому я получил в настройках приложения опцию Language, которую мне не хотелось выбрасывать.

И я стал думать дальше. В процессе размышлений я дошел до класса Locale и его метода setDefault().  Сам по себе он не помог, поскольку менеджер ресурсов андроида использует локаль из своих настроек. Но и эти настройки можно изменить.

Итак, что я сделал.
В ресурсы я добавил два массива для окна настроек:

<string-array name="languages">
    <item>English</item>
    <item>Українська</item>  
    <item>Русский</item>
</string-array>
 
<string-array name="language_values">
    <item>en</item>
    <item>uk</item>
    <item>ru</item>
</string-array>

GUI для выбора языка я поместил в стандартное PreferenceActivity.
Моя PreferenceActivity реализует интерфейс OnSharedPreferenceChangeListener . В метод onSharedPreferenceChanged помещаем следующий код:

String lang = prefs.getString(key, Consts.DEFAULT_LOCALE);
Utils.setLocale(this, lang);
Const.DEFAULT_LOCALE - это просто строка "en".
И вот в методе Utils.setLocale() и происходит волшебство, размером всего в 5 строчек кода.

public static void setLocale(Activity a, String lang) {
    Locale locale2 = new Locale(lang);
    Locale.setDefault(locale2);
    Configuration c = new Configuration(a.getBaseContext().getResources().getConfiguration());
    c.locale = locale2;
    a.getBaseContext().getResources().updateConfiguration(c, a.getBaseContext().getResources().getDisplayMetrics());
}
locale2 - это наша новая локаль, создаваемая с переданным кодом языка. Код берется из массива language_values. Сперва мы устанавливаем ее как локаль по умолчанию для Java, а затем изменяем конфигурацию менеджера ресурсов андроида. Благодаря этому при загрузке ресурсов будут использоваться ресурсы, соответствующие новой локали. Все активити, созданные после этого будут использовать ресурсы в только-что установленной локали. Правда, все активити, которые уже созданы не поменяются.

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

Ах, да. Самое главное. В основной активити, которая запускается первой (ну и вообще в любой активити, которая может быть запущена интентом) я вызываю следующий метод в onCreate(), сразу после super(): Utils.setLocale(this);. Это перегруженный метод setLocale, который берет текущий язык приложения из SharePreferences. Выглядит он так:

public static void setLocale(Activity a) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(a);
    setLocale(a, prefs.getString(Consts.PREF_LOCALE, Consts.DEFAULT_LOCALE));
}
Теперь мое приложение поддерживает локализацию на три языка - английский, украинский и русский, использует только стандартные средства системы андроид и позволяет пользователю менять язык приложения на лету через окно настроек. PROFIT!!!

31.10.10

Погодная станция на Ардуино

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


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

Итак, в ролях:
  • Arduino Duemillanove
  • BMP085 от Bosch Sensortec - датчик давления и температуры
  • HIH-4030 от Honeywell - датчик влажности

Датчик влажности прост и незамысловат - подаете на него 5 вольт и получаете напряжение, линейно зависящее от влажности.
Датчик давления и температуры сложнее, он подключается по шине I2C и, кроме того,  использует для питания 3.3V.

Итак собираем схему.
Датчик влажности подключаем к земле и питанию, ногу out подключаем к аналоговому входу №0 ардуино.

Датчик давления подключаем к земле и питанию 3.3 вольта, выходы SDA и SLC подключаем к аналоговым входам 4 и 5 соответственно.

Для получения значения влажности нам понадобятся некоторые константы, которые можно найти в даташите на HIH-4030:


static const int offset = 958;
static const int slope_coef = 10;
static const int slope = 307;

offset - напряжение, соответствующее нулевой относительной влажности, а slope - соотношение между напряжением и влажностью, составляющий 30.68 mV. Поскольку я собираюсь использовать только целочисленную арифметику, то slope заведем как 307 и добавим дополнительный делитель 10.

Функция получения относительной влажности будет выглядеть так:


int get_humidity() {
   long voltage = analogRead(0); // получить значение 0..1023
   voltage = voltage * 5000 / 1023; // преобразовать в микровольты
   // вычислим относительную влажность в процентах
   return ((voltage - offset) * slope / slope_coef) / 100;
}

Код для работы с BMP085 я стянул тут. Имейте в виду, у меня этот код не заработал сразу из-за путаницы с использованием типов int, unsigned int и long. Работающий код можно взять из репозитория на bitbucket.org или из zip-файла в конце статьи.

Для удобства все функции для работы с датчиками удобно собрать в библиотеку. Библиотека в IDE Arduino - это папка с файлами, лежащая в каталоге libraries в каталоге arduino. Библиотека содержит как минимум два файла - заголовочный h-файл и cpp-файл с кодом.

Я сделал такой заголовочный файл:


/*
Library of utility classes and functions for Arduino weather station
*/

#ifndef WEATHER_H
#define WEATHER_H

#include "WProgram.h"

// interface for humidity sensor HIH-4030
class Humidity {
  private:
    static const int offset = 958;
    static const int slope_coef = 10;
    static const int slope = 307;

    int pin;
  public:
    Humidity(const int pin = 0);

    // returns relative humidity in percents * 10
    // to get actual humidity delete results by ten
    long get_humidity();

    int get_humidity_int();
};

#define I2C_ADDRESS 0x77
#define DEFAULT_OVERSAMPLING 3

class TemperaturePressure {
  private:
    int i2c_address;
    unsigned char oversampling_setting; //oversamplig for measurement

    static const unsigned char pressure_waittime[];// = { 5, 8, 14, 26 };

    //taken straight from the BMP085 datasheet
    int ac1, ac2, ac3;
    unsigned int ac4, ac5, ac6;
    int b1, b2, mb, mc, md;

    int _temp;
    long _pressure;

    void get_calibration_data();
 
    int read_int_register(unsigned char reg);
    char read_register(unsigned char reg);
    void write_register(unsigned char reg, unsigned char value);

    unsigned int read_ut();
    long read_up();

    void read_temperature_and_pressure();
  public:
    TemperaturePressure();
    TemperaturePressure(const int i2c_address, const int oversampling);

    void read_data_from_sensor();

    int get_temperature();
    long get_pressure();

    long get_pressure_hg();

    void begin();
};

#endif

Как видно, библиотека содержит два класса - Humidity, для работы с датчиком влажности и TemperaturePressure, для работы с датчиком давления и температуры.
Для работы с датчиком давления используется библиотека Wire, которая включена в стандартный набор библиотек Arduino. К сожалению я не понял, как можно задействовать в своей библиотеке стандартные библиотеки ардуино, так что пришлось в программе включать два заголовочных файла - Wire.h и Weather.h

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

Ну и наконец скетч для ардуино, который использует библиотеку Weather:

#include <wire.h>
#include <weather.h>

#define HUMIDITY_PIN 0

Humidity humidity(HUMIDITY_PIN);
TemperaturePressure tempPres;

void setup() {
  Serial.begin(9600);
  Serial.println("Calibrating...");
  tempPres.begin();
  Serial.println("Calibrated");

  // Light the LED when ready
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}

void loop() {
  int h = humidity.get_humidity_int();

  tempPres.read_data_from_sensor();
  int t = tempPres.get_temperature();
  float p = tempPres.get_pressure() * 7.5006e-3; // convert to mmHg

  Serial.print(t/10.0);
  Serial.print(";");
  Serial.print(p);
  Serial.print(";");
  Serial.println(h);

  delay(60000);
}

Скетч получает данные о температуре, относительной влажности и давлении и передает их через последовательный порт на десктоп, где простой python-скрипт записывает их в CSV-файл. Из результирующих данных можно, к примеру, построить графики изменения параметров во времени.


Исходники библиотеки и скетча можно скачать отсюда или с помощью Mercurial забрать с bitbucket

30.10.10

Design patterns



Then there was another book that everybody thought was the greatest thing ever in that same period—Design Patterns—which I just thought was crap. It was just like, programming via cut and paste. Rather than thinking through your task you looked through the recipe book and found something that maybe, kinda, sorta felt like it, and then just aped it. That’s not programming; that’s a coloring book. But a lot of people seemed to love it. Then in meetings they’d be tossing around all this terminology they got out of that book. Like, the inverse, reverse, double-back-flip pattern—whatever. Oh, you mean a loop? OK. -- Jamie Zawinski from "Coders at Work". 


Just what I always felt about all this stuff with patterns, but could not express clearly.

13.04.10

Камень в огород Apple

Натолкнулся у Simon Wilson на следующую цитату:
Imagine if 10% of the apps on iPhone came from Flash. If that was the case, then ensuring Flash didn’t break release to release would be a big deal, much bigger than any other compatibility issues. [...] Letting any of these secondary runtimes develop a significant base of applications in the store risks putting Apple in a position where the company that controls that runtime can cause delays in Apple’s release schedule, or worse, demand specific engineering decisions from Apple, under the threat of withholding the information necessary to keep their runtime working.
Не могу понять почему яблофаны считают что сторонние поставщики ПО будут влиять на платформу Эппл. И еще большее недоумение вызывает тот факт, что такое влияние — это негативный фактор.

Платформа будет интересна пользователям, если для нее существуют приложения, этим пользователям нужные. Не зря Баллмер прыгал по сцене с воплями "Developers, developers". Microsoft понимает, что систему делают приложения, как короля — свита. И все равно на каком языке эти приложения написаны и какие фреймворки используют. И пользователям по большому счету все равно. Им будут нравиться удобные, быстрые и безглючные приложения и не нравится тормозные глюкавые уродцы.

Если при этом Эпплу придется расширять API, потому что какой-то функционал будет востребован разработчиками, это, в итоге, будет играть на руку пользователям платформы — они получат новые нужные им приложения. А это будет плюсом для самой Apple, ведь лояльность пользователей увеличится, и тот же человек понесет Джобсу свои деньги и за iPhone 4 и за iPad 2, 3 и т.п.

Будем наблюдать за противостоянием iPhone OS/Android — история расставит все по местам.