12.31.2012

Scala: How to Create Countdown Twitter Bot

Scala: カウントダウンを行う Twitter ボットの作成方法

2ヶ月ほど前に、予備知識ゼロの状態から bot を作ってみた。その時のメモ。

 

使用したテクノロジー、サービス

 

1. TwitterAPI の設定

まずは、Twitter 側の環境セットアップから。

 

1.1 アカウント開設

bot 用の新規アカウントを作成する。

ユニークなメールアドレスの登録が必要だが、gmail のアカウントを持っているなら
ドットの位置を変えたり、エイリアスを付けることで同じメールアカウントを共有できるので便利だ。 

https://support.google.com/mail/bin/answer.py?hl=en&answer=10313
http://support.google.com/mail/bin/answer.py?hl=en&answer=12096

 

1.2 認証用トークンの取得

TwitterAPIに接続するためには、OAuth認証を行う必要がある。そのための準備。

  • 以下のURLを開く
    https://dev.twitter.com/apps/new
  • 先ほど作成したアカウントでサインイン
  • 必要な情報を入力して Create your Twitter application を押下Create an application | Twitter Developers 2
    • Application Details -> Name: ユニークなアプリケーション名 (32文字以内)
          ツイートの「○○から」(via ○○) の部分に使用される。日本語可。 
    • Application Details -> Description:  アプリケーションの説明 (10文字〜200文字)
    • Application Details -> Website:  WebサイトのURL
          ツイートの 「○○から」(via ○○) のリンクとして使用される。
    • Application Details -> Callback URL:  コールバックURL
          ブラウザアプリケーションの場合は必要だが、今回は
          クライアントアプリケーションなので ブランクのままとする。
    • Developer Rules of the Road: (規約を読んでから) Yes, I agree にチェックする
    • CAPTCHA: 画像にかかれた文字を入力
  • アプリケーションの登録に成功すると、以下のような画面が表示される。
     m
  • OAuth アクセス権限の変更
    デフォルトでは Read only となっているため、このままではツイートの作成ができない。 
    Settings タブ -> Application Type -> Access を Read and Write に変更し、
    Update this Twitter application's settings ボタンを押下。
  • アクセストークンの取得
    Detail タブに戻り、Your access token -> Create my access token ボタンを押下。
    Access level が Read and Write と表示されていることを確認。
  • 以下の4種類のパラメータを、後ほどアプリケーションから指定することとなる。
    • OAuth settings -> Consumer key
    • OAuth settings -> Consumer secret
    • Your access token -> Access token
    • Your access token -> Access token secret

 

2. 開発環境の準備

このチュートリアルに従って、環境のセットアップを行う。
https://devcenter.heroku.com/articles/scala 

 

2.1 Scala のインストール

公式サイト、パッケージ管理システムなどからパッケージをダウンロードし、インストール。
詳細は割愛する。
http://www.scala-lang.org/downloads

 

2.2 sbt のインストール

こちらも公式サイト、パッケージ管理システムなどからパッケージをダウンロードし、インストールする。

ただし、必ず heroku でサポートされているバージョンを導入すること。
https://devcenter.heroku.com/articles/scala-support#build-behavior 

手動インストールを行う場合は、jar ファイルと起動スクリプトを設置すればよい。
http://www.scala-sbt.org/release/docs/Getting-Started/Setup.html 

 

2.3 JDKの準備

OpenJDK バージョン6 上で動作させること。

 

2.4 heroku アカウントの作成

下記のページからメールアドレスを登録するだけで heroku を利用できる。
https://api.heroku.com/signup

随所に見られる日本へのリスペクトを感じさせてくれるデザインが嬉しい。
 Heroku | Login

 2.5 heroku toolbelt のインストール

下記のURLから heroku toolbelt をインストールする。
https://toolbelt.heroku.com/

heroku toolbelt とは、以下の3つのツールが同梱されたパッケージである。

  • Heroku client: heroku 管理用のCLIツール
  • Foreman: Procfile ベースのプロセス管理ツール
  • Git

 

3. sbtプロジェクトの作成

sbt 用のディレクトリおよび設定ファイルの作成を行う。

 

3.1 ディレクトリの作成

以下のような構成でディレクトリを作成する。

プロジェクトディレクトリ
├── project
└── src
    └── main
        └── scala

 

3.2 設定ファイルの作成

 

4. プログラム作成

いよいよプログラム本体の作成に入る。

 

4.1 ソースコードの作成

プロジェクトディレクトリ/src/main/scala 配下に Scalaプログラムのソースを作成する。

色々と改善の余地はあると思うが、できたものはこんな感じ。
https://github.com/mogproject/scalaconfjp-countdown/blob/master/src/main/scala/ScalaConfJPCountDown.scala

仕様

  • OAuth認証のパラメータは全て環境変数に設定することとし、tweet() という関数を定義。
  • java の Calendar クラスを利用して現在の日時を取得。
    カウントダウンの目的の日との日数の差を求め、その値によって異なるメッセージをツイートする仕様。 

注意点

  • heroku の日時は UTC で得られるので、それを前提に実行時間の計算ロジックを作ること
  • TwitterAPI の制約に注意
    • 同一のメッセージは "Status is a duplicate." エラーとなり、受け付けられない
    • レート制限 (TwitterAPI v1.0 では、OAuth接続の場合 350コール/時)
      https://dev.twitter.com/docs/rate-limiting 

 

4.2 ローカル環境変数の設定

プログラム中で参照するOAuth認証のための環境変数をローカルマシン上で設定する。 

  • CONSUMER_KEY
  • CONSUMER_SECRET
  • ACCESS_TOKEN
  • ACCESS_TOKEN_SECRET

 

4.3 sbt 実行テスト

この段階でローカルで sbt からプログラムを実行できるようになる。

プロジェクトディレクトリにて、以下のコマンドを実行する。

  • ビルド
    初回はダウンロードなどが行われるので時間がかかる。
    $ sbt clean compile stage
  • 実行
    $ sbt run

 

5. foreman の設定

プロジェクトディレクトリ直下に Procfile というファイルを作成する。

本来はWebサービスなどのプロセスを指定するのだが、今回の用途はバッチ処理のみなので
行頭に # を付けて内容をコメントアウトする。

(例) https://github.com/mogproject/scalaconfjp-countdown/blob/master/Procfile 

 

6. git リポジトリの作成

heroku を利用する前に、ローカルに git リポジトリを作成する。

 

6.1 .gitignore ファイルの作成

プロジェクトディレクトリ直下に .gitignore ファイルを作成し、git の管理対象としないファイルの定義を行う。

ひとまずこんな感じで指定。(おそらく管理対象外とすべきファイルは他にもあると思われる)
https://github.com/mogproject/scalaconfjp-countdown/blob/master/.gitignore 

最終的に、ファイル構成はこのようになった。

プロジェクトディレクトリ
├── .gitignore
├── Procfile
├── build.sbt
├── project
│   ├── build.properties
│   └── plugins.sbt
└── src
    └── main
        └── scala
            └── (クラス名).scala

 

6.2 リポジトリの作成

プロジェクトディレクトリ直下で以下のコマンドを実行し、最初のコミットを行う。

$ git init
$ git add .
$ git commit -m "init"

 

7. heroku アプリケーションの作成

プログラムを heroku へデプロイし、スケジュール実行の設定を行う。

 

7.1 アプリケーションの新規作成

プロジェクトディレクトリ直下で以下のコマンドを実行する。

$ heroku login
Enter your Heroku credentials.
Email:
Password (typing will be hidden):
Authentication successful.
$ heroku create

アプリケーションの名前は一意のものがランダムに設定される。(後で変更可能)

 

7.2 資源のデプロイ

リモートリポジトリ heroku は自動的に設定されているため、以下のコマンドを行うだけでよい。

$ git push heroku master

 

7.3 heroku 環境変数の設定

heroku 上での環境変数を設定するため、heroku config:add コマンドを実行する。

(実行例)

$ git config:add CONSUMER_KEY=xxxxxxxxxxxxxxxxxxxxxx
$ git config:add CONSUMER_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ git config:add ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ git config:add ACCESS_TOKEN_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

7.4 手動実行テスト

ここで、heroku 上でのプログラム実行テストが可能となる。
heroku run コマンドを行えばよい。

$ heroku run 'target/start (クラス名)'

 

7.5 スケジュール設定

heroku のアドオンである Heroku Scheduler を利用する。

heroku dashboard (heroku のサイトへログインした後の画面) から、Add-ons をクリックすれば
アドオンの選択画面に入る。

Utilities -> Heroku Scheduler を選択し、登録を行う。 

Heroku | Add ons

Heroku Scheduler 自体は無料のアドオンであるが、この時クレジットカードの登録を要求される。

登録が終わったら heroku dashboard に戻り
Apps -> 今回作成したアプリケーション -> Resources -> Add-ons -> Heroku Scheduler Standard と選択していく。

Add job… ボタンを押下し、
コマンド(target/start (クラス名))、頻度(10分おき/1時間おき/1日おき)、実行時間
を選択して Save すればスケジュール設定完了。

時間の指定は UTC となる。

 

8. heroku の運用

運用中の heroku コマンド。実行時にはログインが必要である。 
プロジェクトディレクトリ直下でコマンドを実行すれば、アプリケーションの指定(--app)を省略できる。

 

8.1 アプリケーション一覧の参照
$ heroku apps
=== My Apps
xxx
yyy
zzz

 

8.2 ログの参照
$ heroku logs 

 

8.3 プロセス状態の参照
$ heroku ps 

今回のプログラムに関しては、Webサービスではないので常駐プロセスは存在しない。

 

8.4 コンソールの操作

bash

$ heroku run bash

sbt コンソール

$ heroku run sbt console

 

 

References

作ったもの
https://twitter.com/scalaconfjp_cd

ソース置き場
https://github.com/mogproject/scalaconfjp-countdown 

12.26.2012

JScript: Run External Commands Asynchroniously

JScript: 外部コマンドを並列実行する

コマンド(文字列)の配列をパラメータに取り、指定されたコマンドを並列実行し、
各コマンドのリターンコードを配列として返す関数。

コマンドが見つからない場合は –1 を返す。

var executeAsyncCommands = function(commands) {
  var n = commands.length;
  var processes = new Array(n);
  var returns = new Array(n);
  var success = new Array(n);
  var shell = new ActiveXObject("WScript.Shell");

  for (var i = 0; i < n; ++i) {
    try {
      processes[i] = shell.Exec(commands[i]);
      success[i] = true;
    }
    catch(e) {
      success[i] = false;
    }
  }

  L: while (true) {
    WScript.Sleep(100);
    for (i = 0; i < n; ++i) {
      if (success[i] && processes[i].Status == 0) continue L;
    }
    break;
  }

  for (var i = 0; i < n; ++i) {
    returns[i] = success[i] ? processes[i].ExitCode : -1;
  }
  return returns;
};

12.24.2012

Eclipse: Convert Line Delimiters

Eclipse: 改行コードの変換

対象ファイルを選択した状態で、メニューから File -> Convert Line Delimiters To を選べばよい。

以下3種類から選択可能。

  • Windows (CRLF)
  • UNIX (LF)
  • MaxOS 9 (CR)

12.20.2012

Timeit in JavaScript

JavaScript で時間計測処理を実装する

関数をパラメータに取り、その所要時間(秒数)を出力する関数を定義する。
print はユーザ定義のメソッド。

var Timer = function() {};

Timer.timeit = function(description) {
  return function(func) {
    var start = (new Date).getTime();
    func();
    var elapse = ((new Date).getTime() - start) / 1000;
    print(description + ": " + elapse + " sec");
  };
};

以下は JScript(WSH) で500ミリ秒のスリープを行う例

// test code for WSH
var print = function(msg) { WScript.echo(msg); };

Timer.timeit("test code")(function() { WScript.sleep(500); });

出力例

test code: 0.5 sec

インスタンスメソッドで時間測定をしたい場合は、組み込み Function オブジェクトに
このような bind メソッドを定義すると便利だ。 (prototype.js 等を参照)

Function.prototype.bind = function(context) {
  var method = this;
  return function() { return method.apply(context, arguments); };
};

呼び出し例

// test code for WSH
var Klass = function(x) { this.x = x; }; Klass.prototype.f = function() { Timer.timeit("Klass.f")(function() { WScript.sleep(this.x); }.bind(this)); }; var klass = new Klass(1000); klass.f();

出力例

Klass.f: 1 sec

12.14.2012

Updated: HtaMarkdownViewer

HTA版 マークダウン ビューアの更新

マークダウン記法で書かれたテキストファイルの内容をHTA上でレンダリングするツール。

ファイルオープンの際のエラー処理を追加。

GitHub
https://github.com/mogproject/mogproject/blob/master/script/HtaMarkdownViewer.hta 

 

Related posts

HtaMarkdownViewer
http://mogproject.blogspot.jp/2012/11/htamarkdownviewer.html

12.05.2012

C++: Join the Strings, then Split into Integers

C++: 文字列を結合し、区切って数値へ変換する

動機

次のような数字と空白で構成された文字列(string)の vector がある。

{ "10", "2 3", "456", " 789 ", "0" }

これらを先頭から順に結合し、空白の位置で再度分割し、数値(int)の vector へ変換したい。

1. 文字列の結合

Scalaの心地よさに触発されたので、foldLeft関数を実装してみた。
自作のfoldLeftに対してSTL標準のplusファンクタ(Scalaで言う_+_)を適用することで結合を実現する。

template <typename Iterator, typename Tp, typename Func>
Tp foldLeft(Iterator first, Iterator last, Tp seed, Func f) {
  for (Iterator it = first; it != last; ++it) seed = f(seed, *it);
  return seed;
}

template <typename Container>
typename Container::value_type join(Container const& container) {
  typedef typename Container::value_type Tp;
  return foldLeft(container.begin(), container.end(), Tp(), std::plus<Tp>());
}

join関数の中で使っている Container::value_type は、typename キーワードを付けないとコンパイルが通らない。
テンプレート変数が型なのか値なのか、今回のようなケースではコンパイラは推論することができないためだ。

2. 文字列の分割

下記URL参照。stringstream と getline を利用した実装。

std::vector<std::string> split(std::string const& str, char delimiter = ' ') {
  std::istringstream iss(str);
  std::string buf;
  std::vector<std::string> result;
  while (std::getline(iss, buf, delimiter)) result.push_back(buf);
  return result;
}

3. 文字列から数値へ変換

こちらも Functional Programming ライクな map 関数を作成した。
std::map との名前の競合を避けるため fmap と命名したのは不本意であるが詮方無しか。

現状では std::vector から std::vector への変換しかできないが、他のコンテナへも適用可能にするなど
改善の余地はありそうだ。

テンプレート変数の Func は、argument_type および result_type という型名の定義を必要とする仕様とした。
通常は std::unary_function を継承すればよい。

template <typename Func>
std::vector<typename Func::result_type> fmap(
    std::vector<typename Func::argument_type> const& src) {
  std::vector<typename Func::result_type> result(src.size());
  std::transform(src.begin(), src.end(), result.begin(), Func());
  return result;
};

template <typename Arg, typename Result>
class toNumeric : public std::unary_function<Arg, Result> {
public:
  Result operator()(Arg const& str) const {
    Result result;
    std::istringstream iss(str);
    iss >> result;
    return result;
  }
};
typedef toNumeric<std::string, int> toInt;
typedef toNumeric<std::string, long long int> toLong;

個々の文字列から数値への変換は、toNumeric という独自のファンクタを作成した。
この処理でも stringstream を活用している。
toInt が int 型への変換、toLong が long long int 型への変換処理である。

コード全体

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>

// join
template <typename Iterator, typename Tp, typename Func>
Tp foldLeft(Iterator first, Iterator last, Tp seed, Func f) {
  for (Iterator it = first; it != last; ++it) seed = f(seed, *it);
  return seed;
}

template <typename Container>
typename Container::value_type join(Container const& container) {
  typedef typename Container::value_type Tp;
  return foldLeft(container.begin(), container.end(), Tp(), std::plus<Tp>());
}

// split
std::vector<std::string> split(std::string const& str, char delimiter = ' ') {
  std::istringstream iss(str);
  std::string buf;
  std::vector<std::string> result;
  while (std::getline(iss, buf, delimiter)) result.push_back(buf);
  return result;
}

// map
template <typename Func>
std::vector<typename Func::result_type> fmap(
    std::vector<typename Func::argument_type> const& src) {
  std::vector<typename Func::result_type> result(src.size());
  std::transform(src.begin(), src.end(), result.begin(), Func());
  return result;
};

template <typename Arg, typename Result>
class toNumeric : public std::unary_function<Arg, Result> {
public:
  Result operator()(Arg const& str) const {
    Result result;
    std::istringstream iss(str);
    iss >> result;
    return result;
  }
};
typedef toNumeric<std::string, int> toInt;
typedef toNumeric<std::string, long long int> toLong;

#define each(i,c) for (typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)

using namespace std;

int main(int argc, char **argv) {
  string s[] = { "10", "2 3", "456", " 789 ", "0" };
  vector<string> vs(s, s + sizeof(s) / sizeof(s[0]));

  vector<int> vi = fmap<toInt>(split(join(vs)));
  each(i,vi) cout << *i << endl;
}

実行例

102
3456
789
0

 

References

Story of Your Life » Blog Archive » C++で文字列のsplit:
http://shnya.jp/blog/?p=195

11.25.2012

Scala: Find Fibonacci Numbers Using Matrix Multiplication

Scala: 行列累乗でフィボナッチ数列を解く

目的

  • いくつかの方法でフィボナッチ数列を求めるプログラムをScalaで実装してみる
  • 次の操作にかかる時間を測定し、比較する
    1. 0番目〜100番目のフィボナッチ数を列挙する
    2. 100,000番目のフィボナッチ数を求める

 

時間計測用の処理

このようなメソッドを予め用意した。
処理中に例外が発生した場合は、その概要が出力される。

import scala.util.control.Exception._

object Fibonacci {
  def timeit(description: String = "")(proc: => Unit) {
    val start = System.currentTimeMillis()
    allCatch.either(proc) match {
      case Left(e) => println(e)
      case _ =>
    }
    println(description + ": " + (System.currentTimeMillis() - start) + " msec")
  }
}

 

1. ワンライナー版

行列を使わずに、Streamで実装されたもの。
Scalaらしく、非常にエレガントなコードだ。

object FibonacciOneLiner {
  val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }
}

呼び出しは以下のようにする。

object Fibonacci {
  def main(args: Array[String]) {
    val n = 100
    val m = 100000
    timeit("[1] Enum first 100 Fibs") {
      FibonacciOneLiner.fibs.take(n + 1).zipWithIndex.foreach { x => println(x._2 + " : " + x._1) }
    }
    timeit("[1] Find 100,000th Fib") {
      println(m + ": " + FibonacciOneLiner.fibs.take(m + 1)(m))
    }
  }
}

計測結果は以下の通り。

  • 100番目までの列挙 => 390 ms
  • 100,000番目の表示 => java.lang.OutOfMemoryError 発生

 

2. 行列累乗版

行列の積によってフィボナッチ数列が求められることと、
平方行列のn乗が Θ(lg n) の計算時間で算出できることを利用して解く方法。

数学的な解説はReferencesを参照。

import annotation.tailrec

object FibonacciMatrix {
  type Matrix = Array[Array[BigInt]]

  implicit def arrayArrayInt2Matrix(m: Array[Array[Int]]): Matrix = {
    m.map {
      a: Array[Int] => a.map {
        x: Int => BigInt(x)
      }
    }
  }

  def mul(m1: Matrix, m2: Matrix) = {
    val res = Array.fill(m1.length, m2(0).length)(BigInt(0))
    for (row <- (0 until m1.length);
         col <- (0 until m2(0).length);
         i <- 0 until m1(0).length) {
      res(row)(col) += m1(row)(i) * m2(i)(col)
    }
    res
  }

  def pow(a: Matrix, n: Int) = {
    @tailrec
    def powLocal(a: Matrix, b: Matrix, n: Int): Matrix = n match {
      case 0 => b
      case x if (x & 1) == 1 => powLocal(mul(a, a), mul(a, b), x >> 1)
      case x => powLocal(mul(a, a), b, x >> 1)
    }
    val unit = Array(Array(BigInt(1), BigInt(0)), Array(BigInt(0), BigInt(1))) // 単位行列
    if (n < 0) throw new IllegalArgumentException
    powLocal(a, unit, n)
  }

  def fib(n: Int) = {
    val m = Array(Array(1, 1), Array(1, 0))
    pow(m, n)(1)(0)
  }
}

行列(Matrix)をBigIntの二次元配列で表現。
Intの二次元配列からBigIntの二次元配列への暗黙の型変換メソッドを作成。
累乗を求める部分では、内部関数として末尾再帰の最適化が行われるよう工夫した。

呼び出し部分はこちら。

object Fibonacci {
  def main(args: Array[String]) {
    val n = 100
    val m = 100000
    timeit("[2] Enum first 100 Fibs") {
      (0 to n).foreach { i => println(i + ": " + FibonacciMatrix.fib(i)) }
    }
    timeit("[2] Find 100,000th Fib") {
      println(m + ": " + FibonacciMatrix.fib(m))
    }
  }
}

計測結果は以下の通り。

  • 100番目までの列挙 => 108 ms
  • 100,000番目の表示 => 120 ms

OutOfMemoryが発生しない上に、処理時間そのものも大幅に短縮できた。

 

3. 行列累乗(並列処理)版

行列計算の mul メソッドを par を使って並列化したバージョン。

import annotation.tailrec

object FibonacciMatrix {
  type Matrix = Array[Array[BigInt]]

  implicit def arrayArrayInt2Matrix(m: Array[Array[Int]]): Matrix = {
    m.map {
      a: Array[Int] => a.map {
        x: Int => BigInt(x)
      }
    }
  }

  def mul(m1: Matrix, m2: Matrix) = {
    val res = Array.fill(m1.length, m2(0).length)(BigInt(0))
    for (row <- (0 until m1.length).par;
         col <- (0 until m2(0).length).par;
         i <- 0 until m1(0).length) {
      res(row)(col) += m1(row)(i) * m2(i)(col)
    }
    res
  }

  def pow(a: Matrix, n: Int) = {
    @tailrec
    def powLocal(a: Matrix, b: Matrix, n: Int): Matrix = n match {
      case 0 => b
      case x if (x & 1) == 1 => powLocal(mul(a, a), mul(a, b), x >> 1)
      case x => powLocal(mul(a, a), b, x >> 1)
    }
    val unit = Array(Array(BigInt(1), BigInt(0)), Array(BigInt(0), BigInt(1))) // 単位行列
    if (n < 0) throw new IllegalArgumentException
    powLocal(a, unit, n)
  }

  def fib(n: Int) = {
    val m = Array(Array(1, 1), Array(1, 0))
    pow(m, n)(1)(0)
  }
}

呼び出し方法。

object Fibonacci {
  def main(args: Array[String]) {
    val n = 100
    val m = 100000
    timeit("[3] Enum first 100 Fibs") {
      (0 to n).foreach { i => println(i + ": " + FibonacciMatrixParallel.fib(i)) }
    }
    timeit("[3] Find 100,000th Fib") {
      println(m + ": " + FibonacciMatrixParallel.fib(m))
    }
  }
}

計測結果は以下の通り。

  • 100番目までの列挙 => 498 ms
  • 100,000番目の表示 => 106 ms

100,000番目の算出はごく僅かに速くなったが、100番目までの列挙は逆に遅くなってしまった。

 

References

MIT OCW - Lecture 3: Divide-and-Conquer: Strassen, Fibonacci, Polynomial Multiplication
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005/video-lectures/lecture-3-divide-and-conquer-strassen-fibonacci-polynomial-multiplication/

ワンライナー・フィボナッチ
http://stackoverflow.com/questions/7388416/what-is-the-fastest-way-to-write-fibonacci-function-in-scala

行列の積の求め方
http://blog.scala4java.com/2011/12/matrix-multiplication-in-scala-single.html 

11.18.2012

IntelliJ IDEA Editor Settings

IntelliJ IDEA エディタ設定まとめ

デフォルトから変更した内容のメモ。

設定画面の入り方は
  Windows, Linux => File –> Settings –> IDE Settings
  Mac => IntelliJ IDEA –> Preferences… –> IDE Settings

エディタ

  • Editor
    • Virtual Space –> Allow placement of caret after end of line: ON => OFF
      フリーカーソル(キャレットを行末以降に移動可能)の無効化。
  • Editor –> Apperance
    • Show line numbers: OFF => ON
      エディタに行番号を表示
    • Show whitespaces: OFF => ON
      エディタにホワイトスペース(空白、タブ)を表示
  • Editor –> Editor Tabs
    • Tab Apperance –> Mark modified tabs with asterisk: OFF => ON
      変更したファイルには、タブにアスタリスクを表示する
  • Editor –> Code Completion
    • Code Completion –> Case sensitive completion: First letter => None
      コード補完を行う際、大文字・小文字を区別しない。慣れたら変えるかも。
    • Code Completion –> Autopopup documentation in (ms): OFF => ON(1000)
      コード補完中にドキュメントを自動ポップアップ(1000ms後)

 

キーマップ

  • Keymap
    • Keymaps: Default
    • Other –> Run context confitguration: F10 を追加で割り当て
      編集中のコードを「F10」で実行できるようにする。
      Mac Book Air だと不便なので、とりあえず Mac + Enter に割り当て。
    • Other –> Comment with Line Comment: Ctrl + / などを必要に応じて割り当て
      行コメントの有効化/無効化
      既に他のコマンドに割り当てられている設定は残す(Leave)。
    • Editor Actions –> Tab: Tab キーを削除
    • Editor Actions –> Emacs Tab: Tab キーを割り当て
      直前のコード位置を検知してタブ補完する。

 

テンプレート

  • Live Templates
    • scala 配下で右上の + ボタンを押下
      • テンプレート sout を作成
        • Abbreviation: sout
        • Description: Prints a string to System.out
        • Template text:
          println($END$)
        • Applicable in: Scala
        • Options –> Reformat according to style: OFF => ON

 

References

http://d.hatena.ne.jp/kaiseh/20091105/1257447866

11.13.2012

HtaMarkdownViewer

HTA版 マークダウン ビューア

マークダウン記法で書かれたテキストファイルの内容をHTA上で
レンダリングするツールを作成。

コンバートの実装は「showdown.js」をそのまま流用。

HTAにパラメータを渡せばそのファイルを開き、そうでない場合は「ファイルを開く」ダイアログを出している。

最低限の機能しか無いので、印刷などは右クリックかショートカットキーでの
代用が必要。

インターネット接続もソフトのインストールも禁止されている、レガシーなWindows環境向けに。

 

References

showdown.js - A JavaScript port of Markdown
https://github.com/coreyti/showdown 

11.12.2012

HTA Template with JavaScript

JavaScript版 HTAテンプレート

VBScript の部分を JavaScript に書き換え。

 

 

Related Posts

http://mogproject.blogspot.jp/2012/04/general-purpose-hta-template.html

GnuWin32 Error - ld.exe Entry Point Not Found

GnuWin32 エラー - ld.exe - エントリポイントが見つかりません

概要

Windows 上で実行可能なUNIX系コマンドセットの1つである GnuWin32 を導入したところ、g++ の実行で以下のようなエラーが発生した。

ld.exe - エントリ ポイントが見つかりません

プロシージャ エントリ ポイント libiconv がダイナミック リンク ライブラリ libiconv-2.dll から見つかりませんでした。

原因

これは、インストールツールである GetGnuWin32.exe [1] が古いバージョンのモジュールをダウンロードしてしまうためである。

対応

GnuWin32\bin 配下の libiconv-2.dll (Ver.1.8) を最新化 (1.14) したら直った。

ただしその他のモジュールも古いものが散見されるので、素直にMinGW/MSYS や Cygwin を使った方が良さそうだ。

 

References

[1] http://sourceforge.net/projects/getgnuwin32/files/

11.11.2012

Sharing a Personal Eclipse Project with Dropbox + Git

Dropbox + Git を使って個人用の Eclipse プロジェクト(今回はC++)を共有する方法

 

2013-01-13 手順更新
mog project: Sharing a Personal Eclipse Project with Dropbox + Git [Updated]

 

何番煎じか分からないけど、意外とハマったのでメモ。

1. 事前準備

  • Git の導入
    • Linux では $ sudo apt-get install git-core
  • Eclipse プラグイン EGit の導入
  • EGit の共通設定
    • メニューから Window -> Preferences (Mac は Eclipse -> Preferences)
    • Team -> Git
      • Default repository folder を適宜設定 (デフォルトは ~/git)
    • Team -> Git -> Configuration
      • User Settings -> Add Entry... を押下
      • Key: user.name, Value: ユーザ名 を設定
      • Key: user.email, Value: メールアドレス を設定

2. ローカルリポジトリの作成

  • まずは普通にプロジェクトを作成。今回はCDTプロジェクトとした。
  • プロジェクトのコンテキストメニューから、Team -> Share Project…
  • Share Project: Git
  • Configure Git Repository
    • 今回のプロジェクトはワークスペースの直下にあるため、
      Use or create repository in parent folder of project にはチェックを付けない
Git リポジトリの配下にプロジェクトのディレクトリが作成される。
ワークスペースと同じ場所にリポジトリを作るのは非推奨。
      • Repository -> Create を押下
        • Parent directory: ローカルマシン上のディレクトリ
        • Name: プロジェクトの集合の名前を入力し Finish
作業用レポジトリをローカルに作成することで、Dropbox の使用量および通信量を節約できる。
    • 設定例
      • Current Location: ワークスペース/プロジェクト名
      • Target Location: ~/git/eclipse/プロジェクト名
    • プロジェクトにチェックが付いていることを確認し Finish
  • この段階ではまだ NO-HEAD
  • プロジェクトディレクトリ直下にファイル .gitignore を作成
    ※ファイル末尾に改行を入れないと、Macでは最後の行が評価されなくなったので注意
.DS_Store
Release/
Debug/
.settings/
  • プロジェクトのコンテキストメニューから Team -> Commit…
    • Commit message: 適当なメッセージ
    • Files: Select All アイコン(右上のチェックマーク)を押下し全て選択
    • Push the changes to upstream のチェックを外してから Commit

3. Dropbox 上のリポジトリの設定

  • Eclipse でプロジェクトのコンテキストメニューから Team -> Show in Repositories View
  • Git リポジトリビューのアイコン Create a new Git Repository and add it to this view を選択
    • Create a New Git Repository
      • Parent directory: ここで Dropbox 配下のディレクトリを指定
      • Name: リポジトリの名前 (例: eclipse)
      • Create as bare repository: チェックを付ける
  • Git リポジトリビューでローカルリポジトリのコンテキストメニューから Push
    • Destination Git Repository
      • URI: 先ほど作成したDropbox 配下のディレクトリを指定
      • Connection -> Protocol: file
    • Push Ref Specifications
      • Source ref: master [branch] (refs/heads/master)
      • Add Spec を押下
      • Finish を押下し、Push Results を確認
  • Git リポジトリビューでローカルリポジトリ -> Remotes のコンテキストメニューから Create Remote… を選択
    • Remote name: dropbox などの適当な名前
    • Configure fetch を選択
    • Configure push for remote 'dropbox'
      • URI: Dropbox配下のリポジトリを指定
      • Ref mappings: +refs/heads/*:refs/remotes/dropbox/* であることを確認
      • Save and Fetch を押下し、everything up to date と表示されればOK
  • Git リポジトリビューでローカルリポジトリのコンテキストメニューから Properties を選択
    • Configuration -> Add Entry… を押下
    • Key: branch.master.remote, Value: dropbox (リモートに指定した名前)
    • Key: branch.master.merge, Value: refs/heads/master
    • Key: branch.master.rebase, Value: true

4. 別のPCで Dropbox と同期

  • Eclipse を起動し、Window -> Show View -> Other… -> Git -> Git Repositories
    • Git リポジトリビューのアイコン Clone a Git Repository and add the clone to this view
    • Source Git Repository
      • Location -> URI: Dropbox 配下のディレクトリを指定
      • Connection -> Protocol: file
      • Branch Selection: master
      • Local Destination
        • Destination -> Directory ローカルリポジトリの保存先
        • Initial branch: master
        • Clone submodules: チェック無し
        • Configuration -> Remote name: dropbox など
        • Projects -> Import all existing projects after clone finishes: チェック無し
        • Projects -> Add projects to working sets: チェック無し
        • Select a wizard to use for importing projects: Import existing projects
  • メニューから File -> Import…
    • Select: Git -> Projects from Git
    • Select Repository Source: Local
    • Select a Git Repository: 先ほどクローンを作成したローカルリポジトリを指定
    • Select a wizard to use for importing projects: Import existing projects
    • Import Projects: プロジェクトが選択されていることを確認し Finish
    • Source Git Repository
      • Location -> URI: Dropbox 配下のディレクトリを指定
      • Connection -> Protocol: file
    • Branch Selection: master
    • Local Destination
      • Destination -> Directory ローカルリポジトリの保存先
      • Initial branch: master
      • Clone submodules: チェック無し
      • Configuration -> Remote name: dropbox など
      • Select a wizard to use for importing projects: Import existing projects 

本来であればインポートウィザードで直接クローンを作りたかったのだが、Mac+CDTという環境が悪いのか、どうにもうまくいかなかった。

(具体的には、Dropbox上のリポジトリを選択した後でプロジェクトの一覧に何も出てこない状態に陥る)

リポジトリビューから操作を行うことで、なんとか事象を回避することができた。

 

環境
  • Ubuntu natty(11.04) 64bit: Elipse Juno(4.2) + CDT 8.1.0 + EGit 2.1.0 + Git 1.7.4.1
  • OS X Mountain Lion(10.8.1): Eclipse Juno(4.2) + CDT 8.1.0 + EGit 2.1.0 + Git 1.7.9.6 

 

References

EGit User Guide
http://wiki.eclipse.org/EGit/User_Guide 

Eclipse RCP, RAP Blog: EGit によるソースコード管理(1) ローカルリポジトリの作成:
http://brissyu.blogspot.jp/2012/02/hudson-tycho-4.html 

eclipse 4.2×EGit環境でPush/Pullのハマりどころを回避する  - mooapp 

Git チートシート
http://www.textdrop.net/doc/git-cheat-sheet-ja/ 

11.06.2012

Mac: Uninstalling IntelliJ IDEA 11 CE

Mac: IntelliJ IDEA 11 Community Edition のアンインストール

  • Applications からプログラムを削除
    $ rm -r /Applications/IntelliJ\ IDEA\ 11\ CE.app/
  • $HOME/Library配下から設定・プラグイン関連のファイルを削除
    $ rm -r ~/Library/Preferences/IdeaIC11/
    $ rm -r ~/Library/Preferences/com.jetbrains.intellij.ce.plist
    $ rm -r ~/Library/Application\ Support/IdeaIC11/
    $ rm -r ~/Library/Caches/IdeaIC11/
  • プロジェクトディレクトリを削除

 

References

はじめてのIntellij IDEA - アンインストール - Yamkazu's Blog
http://yamkazu.hatenablog.com/entry/20110609/1341328718

11.04.2012

SyntaxHighlighter: How to Set Alternate Row Colors

SyntaxHighlighter: 行の背景色を互い違いにする方法

SyntaxHighlighter 3.x では、shCoreDefault.css (※) の設定内容を変えれば奇数行と偶数行の背景色を変えることができる。

※ヘッダ部で shCoreDefault.css をインクルードしている場合。

タイトル行、奇数行、偶数行の背景色の変更

shCoreDefault.css の以下の部分を変えればよい。

タイトル行 => .syntaxhighlighter
偶数行     => .syntaxhighlighter .line.alt1
奇数行     => .syntaxhighlighter .line.alt2

.syntaxhighlighter {
  background-color: white !important;
}
.syntaxhighlighter .line.alt1 {
  background-color: white !important;
}
.syntaxhighlighter .line.alt2 {
  background-color: white !important;
}
.syntaxhighlighter {
  background-color: #c9c9c9 !important;
}
.syntaxhighlighter .line.alt1 {
  background-color: #efefef !important;
}
.syntaxhighlighter .line.alt2 {
  background-color: white !important;
}

ハイライト行の背景色の変更

さらに、ハイライト行の背景色もカスタマイズしてみた。

.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
  background-color: #e0e0e0 !important;
}
.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
  background-color: #a9ffa9 !important;
}

 

References

http://ateitexe.com/wordpress/syntaxhighlighter-customize/

11.03.2012

Mac: Coding Scala with IntelliJ IDEA (2)

Mac: IntelliJ IDEA で Scala コーディング (2)

前回(http://mogproject.blogspot.jp/2012/11/mac-coding-scala-with-intellij-idea-1.html)の続き。

  • 前提条件

Scala がインストールされていること
  参考 http://mogproject.blogspot.jp/2012/06/installing-scala-in-mac-os-x.html)

3. プロジェクトの作成

手順に入る前に、IDEAの用語について理解する必要がある。

Eclipse FAQ - http://wiki.jetbrains.net/intellij/Eclipse_FAQ

にあるように、Eclipse の『プロジェクト』は、IDEAでは『モジュール』と呼ぶ。
そして、Eclipse の『ワークスペース』(複数のプロジェクトをまとめた単位)に相当するのが、
IDEAの『プロジェクト』である。

それを踏まえ、まずはプロジェクト(最も大枠の単位)を作成する。

IntelliJ IDEA 11 1 4

Welcome 画面から、Quick Start -> Create New Project をクリック。
New Project 2 ウィザードが立ち上がるので、一番上の Create project from scratch (プロジェクトの新規作成)を選択、Next をクリック。
New Project

プロジェクト名(Project name)、格納先(Project files location)を適宜指定。

その下の Create Module にチェックを付けると、プロジェクトと一緒にモジュールを作成することができる。

今回はモジュールも作成するが、後から追加することも簡単にできる。
特に複数のモジュールでプロジェクトを構成するような場合には、このタイミングでモジュールを作成しなくてもよさそうだ。

モジュールの設定では、Select type にて Java Module を指定し、Next をクリック。

New Project

ソースディレクトリの作成に関する指定。

通常はデフォルトのとおり、src ディレクトリを作成しておくのが無難。

Next をクリック。

New Project

Java SDK の指定画面。

初期状態では何もないので、右上の Configure… をクリック。

New Project

JDKのインストール先を選択。

今回は
  /Library/Java/JavaVirtualMachines/
    1.7.0.jdk/Contents/Home
を選択。 

戻った画面で Next をクリック。

New Project

左側のペインで Scala を選択。

Use Scala distribution を選択してから
Scala のパス: 手元の環境なら
  /usr/local/Cellar/scala/2.9.2/libexec
を選択。 

brew でインストールした場合には、ここでlibexec まで指定しなければならないので注意。

  => 参照

しかしまだ何やら警告が出ている。
/doc/scala-devel- … が見つからないとのこと。

$ cd /usr/local/Cellar/scala/2.9.2/libexec
$ mkdir -p ./doc/scala-devel-docs
$ cd ./doc/scala-devel-docs
$ curl -O http://www.scala-lang.org/downloads/distrib/files/scala-docs-2.9.2.zip
$ unzip ./scala-docs-2.9.2.zip
$ mv -i ./scala-docs-2.9.2 ./api
$ rm -i ./scala-docs-2.9.2.zip

上記の参照先に解決方法が載っていた。

このURLからドキュメントをダウンロードし、Scala ホーム配下の doc/scala-devel-docs/api ディレクトリへ配備しないといけないようだ。

コマンド実行例は左記のとおり。 

New Project

エラーが消えたら、プロジェクトに対応する『ファセット』の設定を行う。

ファセットとは、直訳すると面、様相、一面。
フレームワークや言語のコンフィギュレーションをひとまとめにした単位のことらしい。

今回は、コンパイラおよびライブラリの名前にバージョンを付け足し、適用レベルを global に変えてみた。

Finish をクリック。

Tip of the Day

プロジェクトがロードされ、Tip of the Day がランダムに表示される。

読む必要がなければ、Show Tips on Startup のチェックを外して Close すればよい。

Hello scala   proj hello scala

プロジェクトのウィンドウはこのような感じ。

右上にメッセージが出た場合は、Event Log からもその内容を確認できる。

 

4. ソースコードの作成

「hello_scala」パッケージの「HelloScala」というオブジェクトを作成する。
内容はメッセージを1行表示するだけ。 

Pasted Image 6 src ディレクトリで右クリックし、
New -> Package を選択。 
New Package パッケージ名を入力し、OK をクリック。
Pasted Image 11 6 12 8 23 AM 作成された hello_scala パッケージを右クリックし、New -> Scala Class を選択。
Create New Scala Class

オブジェクト名を入力し、Kind に Object と指定して OK をクリック。

ちなみに、このとき hello_scala.HelloScala というように <パッケージ名>.<オブジェクト名>と指定すれば、パッケージ作成処理を省略できる。

Pasted Image

ここからは、ソースコードの編集。
Vimキーバインドが心地よい。 

オブジェクトを実行可能にする方法を2つ紹介する。

1つ目は、scala.App トレイトを継承する方法。

オブジェクトの定義に
  extends App
と追加すればよい。

このとき、実際のキー入力は
  e <タブ> Ap <タブ> 
だけでよかった。

HelloScala scala   hello scala  hello scala   proj hello scala

 2つ目は、コード補完を利用して main メソッドを定義する方法。

main と入力してタブキーを押下すると・・・

HelloScala scala   hello scala  hello scala   proj hello scala 自動的に main メソッドのテンプレートに置き換わる。 
Pasted Image 11 6 12 10 30 PM ソースコードを書き終わったら、右クリックして Run 'HelloScala.main()' を選択。
 HelloScala scala   hello scala  hello scala   proj hello scala プログラムが実行され、コンソールウィンドウに処理結果が表示された。

 

Related Posts

Mac: Coding Scala with IntelliJ IDEA (1)
http://mogproject.blogspot.jp/2012/11/mac-coding-scala-with-intellij-idea-1.html

 

References

Getting Started with IntelliJ IDEA Scala Plugin
http://confluence.jetbrains.net/display/SCA/Getting+Started+with+IntelliJ+IDEA+Scala+Plugin 

Project Configuration Explained
http://devnet.jetbrains.net/thread/290032

11.01.2012

Google Chrome: Could Not Get Temp Directory

Google Chrome 拡張機能インストールエラー

Windows XP で、ハードディスク・ドライブをダイナミック・ディスク(※)として使っている場合、
Google Chromeの拡張機能をインストールできないという不具合がある。

http://code.google.com/p/chromium/issues/detail?id=117106

パッケージをインストールできませんでした: COULD_NOT_GET_TEMP_DIRECTORY

先日正式版がリリースされた「Chrome リモート デスクトップ」を試してみようと思ったのだが、これは酷い。

別途ベーシック・ディスク(またはリムーバブル・メディア)を用意してマウントし、そこにユーザデータ領域を指定する
(--user-data-dirオプション)くらいしか回避方法がないらしい。

References

http://windows.microsoft.com/ja-JP/windows-vista/What-are-basic-and-dynamic-disks

Mac: Coding Scala with IntelliJ IDEA (1)

Mac: IntelliJ IDEA で Scala コーディング (1)

Best IDE としての呼び声も高い IntelliJ IDEA に触れてみたいと思い、インストールを行ってみた。
その手順をメモとして残しておく。

1. インストール

まずは、IntelliJ IDEA のダウンロードページを開く。
http://www.jetbrains.com/idea/download/

 Screenshot

Ultimate Edition (有償) と Community Edition (無償) の 2種類を選べるが、
今回はMac用の Community Edition を選ぶこととする。現時点の最新版は Version:11.1.4 だった。

システム要件 (System Requirements ページより)
  • Mac OS X 10.5 or higher, up to 10.7 (Lion)
  • 1 GB RAM minimum, 2 GB RAM recommended
  • 300 MB hard disk space + at least 1 GB for caches
  • 1024x768 minimum screen resolution
  • JDK 6
IntelliJ IDEA 11 CE ダウンロードした ideaIC-11.1.4.dmg を実行すると、このような画面が出る。
「IntelliJ IDEA 11 CE.app」を左上の Applications フォルダへドラッグ&ドロップする。

 

2. 初回起動とプラグインのインストール

 Launchpad などから IntelliJ IDEA を起動。

B22D9520 61B3 4147 A241 56745E2DC799 2 初回起動時には警告が出る場合は Open を選択。
(メッセージの言語は環境に依存)
Complete Installation 以前のバージョンから設定を引き継ぐ場合は上のオプションを選択。
今回は新規インストールなので下のオプションのまま OK
IntelliJ IDEA 11 1 4

無事に起動できた。

ここで、プロジェクトを作成する前にプラグインを追加する。
右上の Plugins -> Open Plugin Manager を選択。

Plugins 左下の Browse repositories… を選択。
Browse Repositories

プラグイン Scala を選択し、右クリックして Download and Install
確認に対して Yes を選択。

右上の検索窓から探すと早い。

今回はさらに、Vim キーバインドのプラグイン IdeaVIM もインストールした。

Screenshot 2

OK を押して戻っていくと、IDEAの再起動を求められる。

Restart を選択し、IDEAを再起動。

Vim Keymap settings 4

IDEA 再起動後、Vim キーマップの設定が表示される。

  • Mac OS X 10.5+
  • Mac OS X
  • Emacs
  • Visual Studio
  • Eclipse
  • Net Beans 6.5
  • JBuilder 
から選ぶことが可能。今回は「Mac OS X 10.5+」にしてみた。(※1)
 

※1 キーマップの違いはこちらを参照。
KeyMap for Windows/Linux http://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf
KeyMap for Mac OS X http://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard_Mac.pdf
Mac にはなぜ2種類のキーマップがあるのか ---- (KeyMap for Mac OS X より)

IntelliJ IDEA を Mac OS X のみで利用するのなら、"Mac OS X 10.5+" を推奨する。
デフォルトの "Mac OS X" のスキーマは、他のプラットフォームも使用しているユーザのために
Windows/Linux と近いキーマップになるよう用意したものである。

 

Related Posts

Mac: Coding Scala with IntelliJ IDEA (2)
http://mogproject.blogspot.jp/2012/11/mac-coding-scala-with-intellij-idea-2.html 

 

References

IntelliJ IDEA - http://www.jetbrains.com/idea/
Scala プラグイン - http://confluence.jetbrains.net/display/SCA/Scala+Plugin+for+IntelliJ+IDEA
IdeaVIM - https://github.com/JetBrains/ideavim

10.28.2012

Shell: Copy Files with Timestamp

シェルスクリプト:タイムスタンプ付きの名前にコピーする

例えば基盤の設定ファイルを変更するとき、あるいはディレクトリ配下のモジュールを更新するときなど、
変更前の状態を今日の日付をつけた名前にバックアップを取ることがよくある。

例)
cp -pi /etc/hosts /etc/hosts.20121028 

その処理をbkという名前でシェルスクリプト化した。

  • test -e オプションを使っていないのは、Solaris の Bシェルにも対応させるためである。
  • 既に日付つきのファイルが存在している場合には、日付のあとにユニークな連番をつけてコピーする。
    例)file1.20121028.0, file1.20121028.1, file1.20121028.2 … 

bk
https://github.com/mogproject/mogproject/blob/master/script/bk 

README
https://github.com/mogproject/mogproject/blob/master/script/README.md

10.27.2012

How to Notify My Blogger Posts to Twitter

Twitter に Blogger ブログの更新を通知する方法

ブログの投稿を Twitter へ連携する方法やサービスはいくつかあるが、Google のサービスである FeedBurner を利用してみたのでその手順をメモしておく。

  1. FeedBurner のサイトを開く
    http://feedburner.google.com/
  2. Google アカウントでログイン
  3. Burn a feed right this instant. Type your blog or feed address here:
    の下にBloggerのアドレスを入力し、「Next」
  4. 複数のフィードが検出された(Identify Feed Source)ので、Atom の方を選ぶ
    mog project - Atom: http://mogproject.blogspot.com/feeds/posts/default
    mog project - RSS: http://mogproject.blogspot.com/feeds/posts/default?alt=rss
  5. フィードのタイトルとアドレスを入力
    タイトルは「mog project」、アドレスは「mogproject」としてみた。
  6. FeedBurner フィードの作成に成功。以下のアドレスを確認して「Next」
    http://feeds.feedburner.com/mogproject
  7. トラフィック分析の設定。デフォルトのまま「Next」
  8. feedburner の管理画面が表示されるので、Publicize(集客支援) –> Socialize を選択。
    尚、右上の「Languages」をクリックすれば、日本語表示も可能。
  9. 「Add a Twitter Account」ボタンを押下し、Twitter 認証を行う。
  10. 各種設定を行い、「Activate」ボタンを押下。
    とりあえず Additional text を追加しただけで他はデフォルト。

参考:
http://www.kuribo.info/2010/08/twitter-feedburner-socialize.html

10.25.2012

Play-Framework: Installation Failed

Playフレームワーク: インストール失敗

Windows XP の端末に Playフレームワークをインストールし
こちらのチュートリアルに従ってアプリケーション「todolist」を「play run」した。
http://playdocja.appspot.com/documentation/2.0.3/ScalaTodoList

ここまでは問題なかったのだが、ブラウザで「localhost:9000」を開くと
以下のようなエラーとなってしまい、いきなりハマってしまった。

Action not found.

for request 'GET /'

No router defined.

悪戦苦闘したものの原因は分からなかったが、以下の手順で無事復旧できた。

  • 最新版のJDK(jdk1.7.0_09)をインストール、javac のパスを通す
    http://www.oracle.com/technetwork/java/javase/downloads/index.html
  • ドライブルート直下に「.sbt」フォルダが存在していたので削除 (アプリをEドライブに置いたので「E:\.sbt」)
  • アプリケーション「todolist」をプロジェクトから作り直し

以上、備忘録まで。

10.08.2012

Using FTP Commands in Shell Script

Shell: FTP処理の実行

コマンド「ftp」とヒアドキュメントを使ってFTP処理を実行することができる。

・FTP通信でファイルリストを取得する例

#!/bin/sh

ftp_list() {
  ftp -n $1 <<==
user $2 $3
ls $4
quit
==
}

ftp_list 'host' 'user' 'pass' 'path'

10.07.2012

Oracle: How to Find Location of SPFILE

Oracle: SPFILE(Server Parameter File) の場所を確認する方法

Oracle 9i- の初期化パラメータファイルの参照順は以下のとおり。

1. 起動時にpfileを指定した場合はそのファイル (startup pfile='<path>')
2. spfile<sid>.ora
3. spfile.ora
4. init<sid>.ora
5. init.ora

SPFILE のパスは、SQL*Plus で以下いずれかのコマンドを実行すれば確認できる。

SQL> show parameter spfile
SQL> select value from v$parameter where name = 'spfile';

PFILE のパスはコマンドでは確認できない。
デフォルトは Windows => $ORACLE_HOME/database, Linux/UNIX => $ORACLE_HOME/dbs 配下。

参考:
http://www.searchman.info/oracle10g_backup/1030.html

10.06.2012

How to Show Network Interface Settings in Solaris

Solaris: ネットワークインタフェースの通信速度・デュプレックス設定の確認方法

・netstat -i

(実行例)

$ netstat -i

有効なNICの一覧を表示。

・ndd

(実行例)

# ndd -set /dev/hme 0
# ndd /dev/hme link_speed
# ndd /dev/hme link_duplex
# ndd /dev/hme adv_autoneg_cap

デバイスの番号を指定してから表示を行う。「-set」を付けなければ「-get」を指定したのと同じ。

link_duplex        : 0 => 半二重通信(half)               , 1 => 全二重通信(full)
adv_autoneg_cap: 0 => 自動ネゴシエーション無効, 1 => 自動ネゴシエーション有効

・netstat -k (Solaris 8-9)

(実行例)

$ netstat -k hme0
$ netstat -k | awk '/^hme0/,/^$/'

 現時点のステータスを表示。link_speed (Mbps)、ifspeed (bps) などを確認。

・kstat (Solaris 10-11)

(実行例)

$ kstat -p hme

・dladm (Solaris 11)

(実行例)

$ dladm show-phys
LINK         MEDIA                STATE      SPEED  DUPLEX    DEVICE
e1000g0      Ethernet             up         1000   full      e1000g0

参考:
http://docs.oracle.com/cd/E26924_01/html/E25834/gkipd.html 

9.27.2012

WebLogic Server: How to Get the File Descriptor Limit

WebLogic Server: FD上限の確認方法

WebLogic Server プロセスのFD(File Descriptor/ファイル記述子)数上限値を確認する3種類の方法。

1. WebLogic 起動時のサーバログを確認

$ grep BEA-000416 <サーバログ>
<main> <<WLS Kernel>> <> <BEA-000416> <Using effective file descriptor limit of: 1,024 open sockets/files.>

2. pfiles コマンドで確認

$ ps -ef | grep java    # WebLogicのプロセスIDを取得
$ pfiles <プロセスID> | grep rlimit
Current rlimit: 1024 file descriptors

pfiles コマンドは実行中プロセスをロックするので運用環境での実行は注意。

3. plimit コマンドで確認

$ ps -ef | grep java    # WebLogicのプロセスIDを取得
$ plimit <プロセスID>

参考:
https://blogs.oracle.com/imc/entry/weblogic_server_too_many_open

9.23.2012

Mac: How to Change Your Login Shell

Mac: ログインシェルの変更方法

OS X Mountain Lionの場合。

System Preferences -> Users & Groups

- 左下の鍵アイコン Click the lock to make changes. を選択
- ログインパスワードを入力し Unlock
- ユーザに対して右クリックし、Advanced Options… を選択
- Login shell を変更し OK 

Bitwise Operations in C++

TC++: ビット操作関連の関数

C++ でビット操作の実装。

・最右ビットの分離、最左ビットの分離(=2の冪乗で切り捨て)、1のビットの数を数えるコードと実行例

#include <cmath>
#include <iostream>
#include <ctime>

using namespace std;

// RMB(right-most bit)  : 01011000 => 00001000, 00000000 => 00000000
// LMB(left-most bit)   : 01011000 => 01000000, 00000000 => 00000000
// POP(population count): 01011000 => 3
template <typename T> T RMB(T x){return x&-(unsigned long long)x;}
unsigned int LMB32(unsigned int x){x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;return x-(x>>1);}
unsigned long long LMB(unsigned long long x){x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;x|=x>>32;return x-(x>>1);}
int POP32(unsigned x) {
  unsigned y=0x33333333;x-=(x>>1)&0x55555555;
  x=(x&y)+((x>>2)&y);x=(x+(x>>4))&0x0f0f0f0f;x+=x>>8;x+=x>>16;return x&0x3f;}
int POP(unsigned long long x) {
  unsigned long long y=0x3333333333333333ULL;x-=(x>>1)&0x5555555555555555ULL;
  x=(x&y)+((x>>2)&y);x=(x+(x>>4))&0x0f0f0f0f0f0f0f0fULL;x+=x>>8;x+=x>>16;x+=x>>32;return x&0x7f;}

#define sz(a) static_cast<int>(sizeof(a) / sizeof((a)[0]))
#define rep(i,n) for(int i=0;i<n;++i)
#define check32(val, name) \
  rep(i, sz(val)) { \
    printf("%s %08x: RMB=%08x, LMB=%08x, POP=%d\n", name, \
        val[i], RMB(val[i]), LMB32(val[i]), POP32(val[i])); \
  }
#define check64(val, name) \
  rep(i, sz(val)) { \
    printf("%s %016llx: RMB=%016llx, LMB=%016llx, POP=%d\n", name, \
        val[i], RMB(val[i]), LMB(val[i]), POP(val[i])); \
  }

int main(int argc, char *argv[]) {
  int ints[] = {0, 1, 88, 0x7fffffff, 0x80000000, 0xffffffff};
  unsigned uints[] = {0, 1, 88, 0x7fffffff, 0x80000000, 0xffffffff};
  long long lls[] = {0, 1, 88, 0x7fffffff, 0x80000000LL, 0xffffffffLL,
      0x7fffffffffffffffLL, 0x8000000000000000LL, 0xffffffffffffffffLL};
  unsigned long long ulls[] = {0, 1, 88, 0x7fffffff, 0x80000000LL, 0xffffffffLL,
      0x7fffffffffffffffLL, 0x8000000000000000LL, 0xffffffffffffffffLL};

  check32(ints , "int ");
  check32(uints, "uint");
  check64(lls  , "ll  ");
  check64(ulls , "ull ");
  return 0;
}

・実行結果

int  00000000: RMB=00000000, LMB=00000000, POP=0
int  00000001: RMB=00000001, LMB=00000001, POP=1
int  00000058: RMB=00000008, LMB=00000040, POP=3
int  7fffffff: RMB=00000001, LMB=40000000, POP=31
int  80000000: RMB=80000000, LMB=80000000, POP=1
int  ffffffff: RMB=00000001, LMB=80000000, POP=32
uint 00000000: RMB=00000000, LMB=00000000, POP=0
uint 00000001: RMB=00000001, LMB=00000001, POP=1
uint 00000058: RMB=00000008, LMB=00000040, POP=3
uint 7fffffff: RMB=00000001, LMB=40000000, POP=31
uint 80000000: RMB=80000000, LMB=80000000, POP=1
uint ffffffff: RMB=00000001, LMB=80000000, POP=32
ll   0000000000000000: RMB=0000000000000000, LMB=0000000000000000, POP=0
ll   0000000000000001: RMB=0000000000000001, LMB=0000000000000001, POP=1
ll   0000000000000058: RMB=0000000000000008, LMB=0000000000000040, POP=3
ll   000000007fffffff: RMB=0000000000000001, LMB=0000000040000000, POP=31
ll   0000000080000000: RMB=0000000080000000, LMB=0000000080000000, POP=1
ll   00000000ffffffff: RMB=0000000000000001, LMB=0000000080000000, POP=32
ll   7fffffffffffffff: RMB=0000000000000001, LMB=4000000000000000, POP=63
ll   8000000000000000: RMB=8000000000000000, LMB=8000000000000000, POP=1
ll   ffffffffffffffff: RMB=0000000000000001, LMB=8000000000000000, POP=64
ull  0000000000000000: RMB=0000000000000000, LMB=0000000000000000, POP=0
ull  0000000000000001: RMB=0000000000000001, LMB=0000000000000001, POP=1
ull  0000000000000058: RMB=0000000000000008, LMB=0000000000000040, POP=3
ull  000000007fffffff: RMB=0000000000000001, LMB=0000000040000000, POP=31
ull  0000000080000000: RMB=0000000080000000, LMB=0000000080000000, POP=1
ull  00000000ffffffff: RMB=0000000000000001, LMB=0000000080000000, POP=32
ull  7fffffffffffffff: RMB=0000000000000001, LMB=4000000000000000, POP=63
ull  8000000000000000: RMB=8000000000000000, LMB=8000000000000000, POP=1
ull  ffffffffffffffff: RMB=0000000000000001, LMB=8000000000000000, POP=64

・ アルゴリズム実測

LMB(最左のビットを求める計算)については、いくつかの異なるアプローチがある。

1) Divide & Conquer で 左端の1のビットを伝播させる。分岐不要。
2) 左端から1ビットずつ移動してチェック。 大きいビットが立っている場合に有利。
3) 最右の1のビットを消し込んでいく方法。1のビットが少ない場合に有利。
4) log2関数を使う方法。ただし、long long型の大きな数になると精度不足で誤った結果となってしまったので
 最初に一回だけ分岐を行った。

次のようなコードで実装した。

#include <cmath>
#include <iostream>
#include <ctime>

using namespace std;
typedef unsigned long long ULL;
#define sz(a) static_cast(sizeof(a) / sizeof((a)[0]))
#define rep(i,n) for(int i=0;i>i;return x-(x>>1);}

ULL LMB_BRANCH_FREE(ULL x) {rep(i,6)x|=x>>(1<<i);return x-(x>>1);}
ULL LMB_BRANCH_FREE2(ULL x) {x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;x|=x>>32;return x-(x>>1);}
ULL LMB_SHIFT(ULL x) {ULL y=0x8000000000000000;while(y>x)y>>=1;return y;}
ULL LMB_POP(ULL x) {ULL y;do{y=x;x=x&(x-1);}while(x);return y;}
ULL LMB_LOG2(ULL x) {ULL y=0x8000000000000000;return x&y?y:x?1ULL<<static_cast<int>(log2(x)):x;}

double time_it(int iter, int count, T func, U val) {
  double elapsed = 1e30;
  for (int i = 0; i < iter; ++i) {
    clock_t t = clock();
    for (int j = 0; j < count; ++j) {
      func(val);
    }
    clock_t s = clock();
    elapsed = min(elapsed, static_cast(s - t) / CLOCKS_PER_SEC);
  }
  return elapsed;
}

int main(int argc, char *argv[]) {
  ULL a[] = {0, 1, 0x6666666666666666ULL, 0x7fffffffffffffffULL, 0xffffffffffffffffULL};
  ULL (*f[])(ULL) = {LMB_BRANCH_FREE, LMB_BRANCH_FREE2, LMB_SHIFT, LMB_POP, LMB_LOG2};
  int iter = 3, count = 10000000;
  rep(i, sz(f)) rep(j, sz(a)) {
    printf("val=%016llx  elapsed=%.6f  count=%d  ret=%016llx\n",
        a[j], time_it(iter, count, f[i], a[j]), count, f[i](a[j]));
  }
}

手元のMacで実測した結果。

val=0000000000000000  elapsed=0.173500  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.169051  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.164456  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.162661  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.164984  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.104226  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.104737  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.104844  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.104384  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.104266  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=1.761051  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=1.732183  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.048205  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.048141  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.040281  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.049773  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.050759  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=1.017678  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=1.995849  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=2.025537  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.049091  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.253222  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.233752  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.233075  count=10000000  ret=8000000000000000
val=ffffffffffffffff  elapsed=0.044856  count=10000000  ret=8000000000000000

グラフにするとこんな感じ。当然ながら、ブランチフリー版が最も安定していた。
NewImage

9.17.2012

C++: 2D/3D Accumulator Class

C++: 2次元・3次元の累積和を求めるクラス

あるリストの特定区間の総和を繰り返し求める必要がある場合、更新が多いケースでは Binary Indexed Tree(BIT) が有効だ。
http://mogproject.blogspot.jp/2012/02/binary-indexed-tree-bit-in-c.html

ただし、更新は一度だけであとは参照するだけといった場合、単純な累積和テーブルを持たせれば計算量 Θ(1) で計算可能である。
これは、以下のように 2次元・3次元のリストにも適用できる。

区間の総和を求めるには、Inclusion–exclusion principle を利用する。
http://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle

・コード

template <typename T=int> class Acum2D {
public:
  Acum2D(int x, int y) {
    data_ = std::vector<std::vector<T> >(x + 1, std::vector<T>(y + 1, 0));
  }
  // must set values in ascending order
  void Set(int x, int y, T value) {
    data_[x + 1][y + 1] =
        value + data_[x][y + 1] + data_[x + 1][y] - data_[x][y];
  }
  // get the sum of data[x][y] such that:
  //     min_x <= x <= max_x and min_y <= y <= max_y
  T Get(int min_x, int min_y, int max_x, int max_y) const {
    if (min_x > max_x || min_y > max_y) return 0;
    ++max_x; ++max_y;
    return data_[max_x][max_y]-
        data_[min_x][max_y] - data_[max_x][min_y] + data_[min_x][min_y];
  }
private:
  std::vector<std::vector<T> > data_;
};

template <typename T=int> class Acum3D {
public:
  Acum3D(int x, int y, int z) {
    data_ = std::vector<std::vector<std::vector<T> > >(x + 1,
        std::vector<std::vector<T> >(y + 1, std::vector<T>(z + 1, 0)));
  }
  // must set values in ascending order
  void Set(int x, int y, int z, T value) {
    data_[x + 1][y + 1][z + 1] = value + data_[x][y + 1][z + 1] +
        data_[x + 1][y][z + 1] + data_[x + 1][y + 1][z] - data_[x][y][z + 1] -
        data_[x + 1][y][z] - data_[x][y + 1][z] + data_[x][y][z];
  }
  // get the sum of data[x][y][z] such that:
  //     min_x <= x <= max_x and min_y <= y <= max_y and min_z <= z <= max_z
  T Get(int min_x, int min_y, int min_z,
      int max_x, int max_y, int max_z) const {
    if (min_x > max_x || min_y > max_y || min_z > max_z) return 0;
    ++max_x; ++max_y; ++max_z;
    return data_[max_x][max_y][max_z] - data_[min_x][max_y][max_z] -
        data_[max_x][min_y][max_z] - data_[max_x][max_y][min_z] +
        data_[min_x][min_y][max_z] + data_[max_x][min_y][min_z] +
        data_[min_x][max_y][min_z] - data_[min_x][min_y][min_z];
  }
private:
  std::vector<std::vector<std::vector<T> > > data_;
};

・使用例

int data2d[5][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}, {30, 31, 32}, {40, 41, 42}};
Acum2D<> acum2d(5, 3);
for (int i = 0; i < 5; ++i) for (int j = 0; j < 3; ++j) {
  acum2d.Set(i, j, data2d[i][j]);
}
// data[2][1] + data[2][2] + data[3][1] + data[3][2] + data[4][1] + data[4][2]
// = 21 + 22 + 31 + 32 + 41 + 42 = 189
std::cout << acum2d.Get(2, 1, 4, 2) << std::endl;

double data3d[3][3][3] = {
    {{ 0.0,  0.1,  0.2}, { 1.0,  1.1,  1.2}, { 2.0,  2.1,  2.2}},
    {{10.0, 10.1, 10.2}, {11.0, 11.1, 11.2}, {12.0, 12.1, 12.2}},
    {{20.0, 20.1, 20.2}, {21.0, 21.1, 21.2}, {22.0, 22.1, 22.2}},
};
Acum3D<double> acum3d(3, 3, 3);
for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) for (int k = 0; k < 3; ++k){
  acum3d.Set(i, j, k, data3d[i][j][k]);
}
// data[0][1][2] + data[0][2][2] + data[1][1][2] + data[1][2][2]
// = 1.2 + 2.2 + 11.2 + 12.2 = 26.8
std::cout << acum3d.Get(0, 1, 2, 1, 2, 2) << std::endl;

9.16.2012

Ubuntu: Keyboard Layout Reverting on Reboot

Ubuntu: 再起動するたびにキーボードレイアウトが元の状態に戻ってしまう

Ubuntu 10 で、例えば英語配列キーボードを使用している場合、キーボードレイアウトの設定で「日本語」を削除し
英語配列のみが有効な状態にする。

しかし、OSが再起動するとキーボードレイアウトの設定が復元され、再度「日本語」がデフォルトになってしまっている
という事象が発生した。

一旦ログアウトを行い、ログイン画面で以下の操作を行ったところ問題は解消した。

・ログインするユーザを選択
・パスワード入力の画面で画面下部のキーボードレイアウト(左から2番目のリスト)を適切なもの(今回の場合は英語)に設定
・パスワードを入力しログイン

参考:
https://bugs.launchpad.net/indicator-applet/+bug/688936

9.14.2012

C++: Froyd-Warshall Algorithm

C++: ワーシャルフロイド法の実装

アルゴリズム解説:
http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm

コード:

// Froyd-Warshall Algorithm: O(|V| ^ 3)
template <typename T=int>
class FroydWarshall {
public:
  FroydWarshall(int num_nodes, T infinite=1000000001)
      : num_nodes_(num_nodes), infinite_(infinite) {
    data_ = std::vector<std::vector<T> >(
        num_nodes_, std::vector<T>(num_nodes, infinite_));
    for (int i = 0; i < num_nodes_; ++i) { data_[i][i] = 0; }
  }
  void MakeEdge(int from, int to, T weight) {
    data_[from][to] = weight;
  }
  void Update() {
    for (int k = 0; k < num_nodes_; ++k) {
      for (int i = 0; i < num_nodes_; ++i) {
        for (int j = 0; j < num_nodes_; ++j) {
          data_[i][j] = std::min(data_[i][j], data_[i][k] + data_[k][j]);
        }
      }
    }
  }
  bool IsReachable(int from, int to) { return data_[from][to] != infinite_; }
  std::vector<T> operator[](int from) { return data_[from]; }

private:
  std::vector<std::vector<T> > data_;
  int num_nodes_;
  T infinite_;
};

使用方法:

FroydWarshall<> g(100);
g.MakeEdge(0, 1, 10);
g.MakeEdge(1, 3, 20);
g.Update();  // must do this to calculate
std::cout << g.IsReachable(0, 2) << std::endl;  // print "0": cannot reach this vertex
std::cout << g.IsReachable(0, 3) << std::endl;  // print "1": can reach
std::cout << g[0][3] << std::endl;  // print "30": shortest path from vertex[0] to vertex[3]

9.11.2012

Eclipse: Problems During Content Assist

Eclipse: コンテンツアシストのエラー

MacマシンにSubclipseを導入した頃からであろうか、CDTでコンテンツアシストが走るたびに
以下のようなエラーが出るようになってしまった。

Screen Shot 2012 09 08 at 11 45 05 PM

mylyn プラグイン・Parsing-based Proposals (Task-Focused) で問題が発生しているようだが、プラグインを
削除したり、Parsing-based Proposals (Task-Focused)を無効にしても状況は改善しない。

結論としては、Eclipseの再インストールで直った。またこれを機に Eclipse 4.2 Juno へ乗り換えてみた。

備忘のため、再インストールの手順をメモしておく。

- 設定をバックアップ
 File -> Export…
 General -> Preferences を選択し Next
 Export all にチェック
 To preference file: に保存先のパスを入れて Finish

- /Applications/eclipse ディレクトリを削除

- Eclipse IDE for Java EE Developers MacOS X 64Bit をダウンロードして実行
 http://www.eclipse.org/downloads/ 

 前回は Eclipse IDE for C/C++ Developers を導入したが、今回は変えてみた。

- CDT のインストール
 Help -> Install New Software... 
 Work with: から Juno - http://download.eclipse.org/releases/juno を選択 
 Programming Language -> C/C++ Development Tools
                                              -> C/C++ Development Tools SDK
 を選択し、Next 以下手順にインストール。

- eclipse.ini の書き換え
 /Applications/eclipse/Eclipse.app/Contents/MacOS/eclipse.ini を編集し、ヒープサイズを増やす。
 今回はひとまず -Xmx512m を -Xmx1024m へ拡張。

- Scala IDE のインストール
 Scala IDE のインストール先は本来ならここなのだが、現行の 2.0.2 Release は Eclipse Juno に対応していない。
 http://scala-ide.org/download/current.html 

 Nightly バージョンの特別版をインストールする必要がある。
 http://scala-ide.org/download/nightly.html#scala_ide_helium_nightly_for_eclipse_42_juno 

 Help -> Install New Software... 
 Work with: に http://download.scala-ide.org/nightly-update-juno-master-29x を指定
 Scala IDE for Eclipse を選択し、Next 以下手順にインストール。

- Vrapper のインストール
 Help -> Install New Software... 
 Work with: http://vrapper.sourceforge.net/update-site/stable

 インストール後、~/.vrapperrc を適宜修正

- Subclipse のインストール
 Help -> Install New Software... 
 Work with: http://subclipse.tigris.org/update_1.8.x

- Marketplace Client のインストール
 Help -> Install New Software... 
 Work with: Juno - http://download.eclipse.org/releases/juno
 General Purpose Tools -> Marketplace Client 

- Eclipse Color Theme
 Help -> Eclipse Marketplace...
 "Eclipse Color Theme" で検索 

- 設定のインポート
 File -> Import... 
 General -> Preferences を選択し Next
 From preference file: に設定ファイルのパスを入力
 Import all にチェックして Finish

9.10.2012

Eclipse CDT Editor Color Settings

Eclipse: CDT エディタのカラー設定

Eclipse CDT(C/C++ Development Tools) を使っている場合、Eclipse Color Theme だけでは色が変わらない部分で文字が見えづらくなり、微調整が必要となることがある。

http://mogproject.blogspot.jp/2012/01/setting-eclipse-cdt-color-theme.html

この色の設定はどこなのか、と迷ってしまうことが多々あるので整理しておく。

- General -> Appearance -> Color Theme

  ここはカラーテーマを指定するだけ

Screen Shot 2012 09 10 at 3 36 46 AM

 

- General -> Appearance -> Colors and Fonts

  主にフォントを変えたい場合に利用
Screen Shot 2012 09 10 at 3 37 07 AM

- General -> Editors -> Text Editors

  現在行ハイライト、印刷マージン等を設定可能
Screen Shot 2012 09 10 at 3 37 28 AM

 

- General -> Editors -> Text Editors -> Annotations

  黒背景のテーマの場合、オカレンスの色を調整しないと目障りとなることが多い。
Screen Shot 2012 09 10 at 3 38 11 AM

- C/C++ -> Editor

  プリプロセッサによって無効化されたコードの背景色(Inactive code highlight)はここで指定する。
  これが一番分かりにくい場所だった。 
 Screen Shot 2012 09 10 at 3 38 37 AM

- C/C++ -> Editor -> Syntax Coloring

  シンタックスに応じた色の個別設定。

Screen Shot 2012 09 10 at 3 39 02 AM

 

9.07.2012

Vundle for Windows

Windows 環境で Vundle を使う

Vim プラグイン管理ツール Vundle を Windows マシンで使えるようにするためのメモ。

ここに従って作業を進める。
https://github.com/gmarik/vundle/wiki/Vundle-for-Windows

1. msysgit のインストール

 ここからダウンロード。
 http://code.google.com/p/msysgit/downloads/list
 途中で「Run Git from the Windows Command Prompt」を選択してパスを通す。

 コマンドプロンプトから、「git –-version」で稼働確認。

2. curl のセットアップ

 下記URLの内容を、{Git インストールディレクトリ}\cmd\curl.cmd として保存する。
 https://gist.github.com/912993

 コマンドプロンプトから、「curl -–version」で稼働確認。

3. Vumdle のセットアップ

 コマンドプロンプトから、以下のコマンドを実行と書いてある。(gvimにパスが通っている必要がある)

> cd %USERPROFILE%
> git clone http://github.com/gmarik/vundle.git .vim/bundle/vundle
> gvim _vimrc

 その後、こちらのステップが必要らしい。
 https://github.com/gmarik/vundle/blob/master/README.md

続きはまた後日。

8.28.2012

Mac: Eclipse CDT - "make" is not found

Mac: Eclipse CDT ビルドエラー "make" が見つからない

Mac OS X Lion + Xcode + Eclipse CDT の環境から OS を Mountain Lion へアップグレードしたら、Eclipse CDT からmake が使えなくなった。

Xcode をアップデートし、Command Line Tools をインストールしなおしたら直った。

参考:
http://stackoverflow.com/questions/9418928/eclipse-cdt-binary-not-found-mac-os-x-lion

8.08.2012

David MacKay: Information Theory, Inference, and Learning Algorithms

David MacKay: Information Theory, Inference, and Learning Algorithms

無料でダウンロードできたので、Kindle に入れてみた。
何か、少しでも吸収できれば。

http://www.inference.phy.cam.ac.uk/mackay/itila/book.html

Pure CSS Speech Balloon

CSS+HTMLのみで吹き出しを作る
ソーシャルボタンの横にあるようなカウンタ吹き出し(「ツイート」とか「いいね!」ボタンの横にあるやつ)を CSS だけで作りたいと思ったけど、IE6 環境でも動作させたい場合は意外な落とし穴があったので備忘録。
<要件>
・二等辺三角形+長方形の形の吹き出しを HTML で出力する
・画像、JavaScript は使わない
・IE6、IE8、Firefox10、HTA(IE6、IE8) で正しく表示されること
・長方形部分の四隅は直角のままでよい(丸めなくてよい)
・吹き出しの輪郭は黒の線になるようにし、その内部は白で塗りつぶす

1. コンテナの作成

まず手始めに、内部の要素を相対座標で指定できるようにするため、描画対象全てを div で囲みこむ。
ここで height を指定しておけば、後々の高さ調整が楽になると思う。
div.balloon {
  position: relative;
  height  : 18px;
}

2. 外側の三角形

偉大なる先人の知恵である border ハックを利用して三角形を描画する。(詳細は記事末尾のリンク先を参照)
外側の黒い三角形を tail1、内側に少しずらした白い三角形を tail2 とする。

綺麗な三角形になるように、font-size と line-height を 0 で指定しておくのがポイント。
:before/:after 擬似要素はIE8 以降しか動作しないため、使用しない。
div.balloon .tail1, .tail2 {
  position    : absolute;
  top         : 4px;
  height      : 0px;
  width       : 0px;
  border      : 5px solid transparent;
  border-left : none;
  border-right: 9px solid #333333;
  font-size   : 0px;
  line-height : 0px;
}
div.balloon .tail1 {
  border-right-color: #333333;
}
しかし、IE6 では早くもここで問題が発生。
border: transparent による透明化処理が行われず、color の色で上・左・下の部分が描画されてしまった。
さらに、border-left: none も無効化されてしまったようである。
ネットで検索してみた結果、これは IE6 の CSS 解釈に不具合があるためらしい。
苦肉の策だが、div 内部で使わないような色(ここでは pink)を指定し、chroma フィルターで透明化することで対応した。また、border-top、border-bottom を個別に指定したら border-left: none が反映されるようになった。
div.balloon .tail_ie6 {
  border-top   : 5px solid pink;
  border-bottom: 5px solid pink;
  filter       : chroma(color=pink);
}
・表示例

 

3. 吹き出し本体

吹き出し本体は、単純な div の設定でよい。ただし、位置取りやフォントサイズは微調整が必要。
div.balloon .body {
  position        : absolute;
  left            : 8px;
  border          : 1px solid #333333;
  background-color: #ffffff;
  color           : #333333;
  font-family     : "Century Gothic";
  font-size       : 11px;
}
・表示例
 0123456789 

 

4. 内側の三角形で縁取り

外側の三角形と同じサイズで色を変えたものを、2ピクセル右にずらして描画する。
尚、z-order を指定すれば、必ずしもこの順番で配置しなくてもよいはず。
div.balloon .tail2 {
  left              : 2px;
  border-right-color: #ffffff;
}
・表示例
 0123456789 

 

5. 全体のコード

<html>
<head>
<style type="text/css"><!--
div.balloon {
  position: relative;
  height  : 18px;
}
div.balloon .body {
  position        : absolute;
  left            : 8px;
  border          : 1px solid #333333;
  background-color: #ffffff;
  color           : #333333;
  font-family     : "Century Gothic";
  font-size       : 11px;
}
div.balloon .tail1, .tail2 {
  position    : absolute;
  top         : 4px;
  left        : 0px;
  height      : 0px;
  width       : 0px;
  border      : 5px solid transparent;
  border-left : none;
  border-right: 9px solid #333333;
  font-size   : 0px;
  line-height : 0px;
}
div.balloon .tail1 {
  border-right-color: #333333;
}
div.balloon .tail2 {
  left              : 2px;
  border-right-color: #ffffff;
}
div.balloon .tail_ie6 {
  border-top   : 5px solid pink;
  border-bottom: 5px solid pink;
  filter       : chroma(color=pink);
}
--></style>
</head>
<body>
<div class="balloon">
  <div class="tail1"></div>
  <div class="body">&nbsp;0123456789&nbsp;</div>
  <div class="tail2"></div>
</div>

<!-- For IE6
<div class="balloon">
  <div class="tail1 tail_ie6"></div>
  <div class="body">&nbsp;0123456789&nbsp;</div>
  <div class="tail2 tail_ie6"></div>
</div>
-->
</body>
</html>

 

参考:
http://www.howtocreate.co.uk/tutorials/css/slopes
http://log.noiretaya.com/164
IE6の対応について
http://stackoverflow.com/questions/5714356/ie6-issue-border-colortransparent-not-working