hippos's blog

マルチキーのソートでおバカした

in

vectorに突っ込んでいるオブジェクトを2つのキーでソート(要するにselect name,age,height from persons order by age,height)したくて、まぁ、operator<をごにょごにょすればなんとかなるかとか思っていたらなんか調子悪くてぜんぜんできない。カッとしてつい、いったんageでソートして、部分的にheightでソートするという暴挙をしでかしてしまった。

struct order_by_height : public binary_function<person,person,bool>
{
  bool operator()(const person& lp,const person& rp) { 
    return lp.height() < rp.height(); 
  }	
};
bool person::operator<(const person& p) const
{ // order by age
  return this->_age < p.age();
}

としといて、

boost::xpressive 静的正規表現で書いてみた

VS2008以後は削除されてしまったCAtlRegExpのかわりにwindowsアプリの時はboost::xpressiveを使ってきましたが、はじめて静的正規表現を使ってみました。また、xpressiveはマルチバイト文字列非対応なんで_Unicodeプリプロセッサ付きです。(普段は国際化なんて意識していないのでTCHAR.h系の関数に慣れてなくて結構イライラしました...)

boost::xpressiveのイテレータ型の対応は、boost.Xpressive(日本語訳)(すばらしい!感謝)にあります。

string::const_iterator char* const wstring::const_iterator wchar_t* const
basic_regex<> sregex cregex wsregex wcregex
match_results<> smatch cmatch wsmatch wcmatch
regex_compiler<> sregex_compiler cregex_compiler wsregex_compiler wcregex_compiler
regex_iterator<> sregex_iterator cregex_iterator wsregex_iterator wcregex_iterator
regex_token_iterator<> sregex_token_iterator cregex_token_iterator wsregex_token_iterator wcregex_token_iterato

今回はワイド文字列対応なんで、wsregexとwsmatchを使います。先にも書きましたがこれまでは(仕様さえ決まってしまえば)特に動的である必要はないのに動的正規表現を使っていた怠慢を反省し静的正規表現で書いてみました。とりあえず、現状決まっているのは、文字列を「最後の空白」空白がなければ、「最初の数字」で区切るです。

pair<wstring,wstring> split_wstr(const wstring& wstr)
{
  boost::xpressive::wsmatch matched;

  //最後の空白で分割
#ifdef _DYNAMIC_REGEX_
  boost::xpressive::wsregex regex_lastw = 
    boost::xpressive::wsregex::compile(_T("^(\\S.+)\\s(.+)$"));
#else
  boost::xpressive::wsregex regex_lastw = 
    bos >> (s1=~_s >> +_) >> _s >> (s2=+_) >> eos;
#endif
  if (boost::xpressive::regex_match(zname,matched,regex_lastw))
  {
    return pair<wstring,wstring>(matched.str(1),matched.str(2));
  }

  //最初の数字で分割
#ifdef _DYNAMIC_REGEX_
  boost::xpressive::wsregex regex_firstn = 
    boost::xpressive::wsregex::compile(_T("^(\\D+)(\\d.+)$"));
#else
  boost::xpressive::wsregex regex_firstn = 
    bos >> (s1=+~_d) >> (s2=_d >> +_) >> eos;
#endif
  if (boost::xpressive::regex_match(zname,matched,regex_firstn))
  {
    return pair<wstring,wstring>(matched.str(1),matched.str(2));
  }

  // 以下仕様に応じていろんな分割が続く
  :
}

ご覧の通り、普段perlやrubyなんかで正規表現書いている人にとっては一見わかりにくいのが弱点でしょうか?特にドットをアンダースコアにするとか*や+が前に来るなどなかなか習慣からは抜け出せないと思うので、コメントとデバグの意味を込めて動的正規表現も併記したほうが後々のためかもしれません。

エンジニアのための時間管理術

in

久しぶりに読書メモ。読書メーターでも何人かの方が書いていますがエンジニアに特化した内容じゃないです。エンジニアには13章の「自動化」のあたりが面白いかもしれませんが、まぁ、大抵のギーク連中はこんなこととっくにやっているだろうから今更感があるかもしれません。それよりも、エンジニアやSA(原題もfor System Administrators)にだけあてはまることじゃない部分、2章「集中と割り込み」あたりが面白く、ネガティブな意味じゃなくて「悪印象を与えずに追い払う」とかは僕にとっては意外と盲点だったりして、うまく実践に取り入れてみたい。PDAやオーガナイザを使おうとかちょっと古い香りのするところもありますが、逆にこの手の本にありがちなガジェットの宣伝(今ならiPhoneやアプリの紹介)っぽいのがほとんどないのも好印象。

僕自身はプログラマでありながら、社内のシステムのお守り役も兼ねているわけで大好きなプログラミングのための時間をすこしでも多く捻出するため、本書の内容をいろいろ試してみようと思う次第です。

エンジニアのための時間管理術 エンジニアのための時間管理術
Thomas A. Limoncelli 株式会社クイープ

オライリー・ジャパン 2006-10-19
売り上げランキング : 107700

Amazonで詳しく見る by G-Tools

redmineのインストール

記事書くのホント久しぶりです。最近はひたすら本読んだりしてあまりプログラムも書いてないし書くネタがなくて。昨日、久しぶりCentOS6にredmineをインストールしたんでそのことを。

といっても、ほとんどRedmine 1.3をCentOS 6にインストールする手順 | Redmine.JP Blogにある手順どおりにやっただけなのですが、いくつか手順どおりでうまくいかなかったところがあるので後の人のためのメモ。ほぼCentOS6をインストールした直後からスタートしてます。

まず、単純なタイポから。『必要なパッケージのインストール』のところと『RMagickのインストール』のところ。

yum install imagemagick imagemagick-devel
gem install RMagick --no-rdoc --no-ri

は、

yum install ImageMagick ImageMagick-devel
gem install rmagick --no-rdoc --no-ri

大文字もしくは小文字でした。

『Ruby EnterPrise Editionの展開とインストーラの実行』では、「ファイルタイムスタンプがおかしいからシステム日付をチェックしろ!」みたいなエラーがでました。で、確認したらなぜかロケーションがボストンになってた!インストール時には東京にしたはずなのに...これを直したらふつうにできました。それにしても、Ruby Enterprise Editionなんてもの初めて知りました。もう、ずっとRuby周りを追いかけてなかったので衝撃的。でも、個人的にはあるプロダクトに、XXX-Editionみたいなのがあるのはあんまり好きじゃないかなぁ。

『Redmine用データベースとユーザの作成』の権限付与の部分は

grant all on db_redmine.* to user_redmine@loalhost identified by '*****';

としておかないと初期化の時に蹴られます。

『Redmineの初期設定とデータベーステーブルの作成』の前にrailsとrdocがないと叱られます。これは、大前提なのかもしれませんが、OSセットアップ直後に手順通りにやったので... :-)

gem install -v=2.3.14 rails
gem install rdoc

これだけ。後は100%Redmine 1.3をCentOS 6にインストールする手順 | Redmine.JP Blogのとおりでバッチリ。良記事をありがとうございます。

たくさんのチェックボックスを一度にON/OFFする方法

in

makePasswordの中で31個のチェックボックスを使うのですが、例えばすべてのチェックボックスをONにしたりOFFにしたりするにはCocoaではどうやるのか悩みました。オーソドックスにはOutletで接続して

[myCheckBox setState:YES]

とかするのだろうけど、31個のOutletはさすがに面倒。似たような場合MFCなら、コントロールのIDを連続的に定義しておいて

int firstControl = IDC_XXXXX;
for(int controll = IDC_FIRST_XXX; controll < IDC_LAST_XXX; ++controll)
{
  CButton* myButton = (CButton*)GetDlgItem(controll);
  myButton->SetCheck(1);
}

みたいなカンジでいちいちコントロール変数を定義しておかなくとも一気にセットできるのに。

結局、巧いテが見つからず今回はNSButtonのサブクラスを作成しコントロールクラスからtag値の配列をブロードキャスト

[[NSNotificationCenter defaultCenter] 
  postNotificationName:@"ChangeSpecialCharacterNotify" object:arrayContolsTag]; 

各コントロールクラスでは通知に自分のtag値が含まれていたらON、含まれていなければOFFにする

- (void)awakeFromNib
{
  NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
  [nc addObserver:self selector:@selector(handleSetState:) 
  name:@"SpecialCharacterNotify" object:nil];
}

-(void)handleSetState:(NSNotification*)aNotification
{
  NSArray* characters = [aNotification object];
  if (characters != nil && 
  [characters containsObject:[NSNumber numberWithInteger:[self tag]]])
  {
    [self setState:YES];
  }
  else
  {
    [self setState:NO];
  }
}

っていう実装にしたんですが、もっと巧いやり方はないものか...なんかモヤモヤがとれません。ダイレクトに送る方法はないのかな?

mkpasswd作りました

in

ランダムなパスワードを生成するツールが欲しくて作りました。時間がなかったのでLinux等に付属のmkpasswdを流用しようと思ったのですが、ソースをみているうちに単なるrandom()を少しアレンジしただけのものでもいいかという気になったので、一気に作成しました。本当は、ANSI X9.17で乱数生成するつもりだったんですけど面倒なのでヤメました。

ソースはGitHub::makePasswordにあります。

サイモン・ペイントン・ジョーンズの9冊

in

Coders At Worksの7章はサイモン・ペイントン・ジョーンズさんの章ですが、面白そうな本や論文がいくつか出てきたのでメモ。インタビューは『無人島にもっていくべきプログラマのための本リストは?』に答えて6冊。他に話の流れの中で出てきたなんかも含めています。切りよく10冊ってしたかったけど1つ足りず9冊です。まぁ、ネタっぽくてすいません。(^^ゞ

珠玉のプログラミング(ジョン・ベントリー)

有名な本だし翻訳も手に入れやすいのに何故か読んでない本のひとつ。。なんでだろ?プログラミング本は好きなのに何故か触手が伸びません。これを機会に読んでみよう。

Writing Programs for The Book(ブライアン・ヘイズ)

「ビューティフル・コード」の33章に収録されてます。「ビューティフル・コード」は持っているのですがまだこの章は読んでませんでした。(^^ゞ原文はhttp://bit-player.org/bph-publications/BeautifulCode-2007-Hayes.pdfにありす。

The Art of Computer Programming(ドナルド・クヌース)

これは説明不要ですね。僕もプログラマの一人として本棚に飾りたい(いや熟読したい)シリーズ。チト高価ですがいつか買います。(いや、読みます)同書のクヌース先生自身の章でも触れていますが通読するような本でもないのでいつも傍らにおいてチラ見して楽しむのがよいのかも。

Purely Functional Data Structures(クリス・オカサキ)

あちこちで見かける評判の高い本です。が、ずっとアマゾンのカートに入ったまま。

計算機プログラムの構造と解釈(エイブルソン&サスマン)

これも説明不要ですかね。一部には熱狂的なファンもいるようですがこれも未読。っつーか最後まで読み通せる気がしないので敬遠している一冊。

Compilimg With Continuations(アンドリュー・アペル)

amazon.jpでは入手困難な感じ。中古でバカ高い値がついてます。海外のサイトならふつうの値段で買えそう。google ブックスでかなりの部分が立ち読みできます。後、似たような論文はたくさんあるみたいです。これを読むほどCSPを理解していないし親しんでもいません。

プログラミング原論(E.W.ダイクストラ)

ステパノフの同名(邦訳)がありますが、こちらは残念ながら絶版。とりあえず復刊リクエストしましたが望み薄そう。

The computer scientist as toolsmith(フレデリック・ブルックス)

http://www.cs.unc.edu/~brooks/Toolsmith-CACM.pdfで読めます。長い文章ではないしテーマも面白そうだからまずこれから読んでみようかと。

Why Functional Programming Matters(ジョン・ヒューズ)

原文とWhy Functional Programming Matters、邦訳なぜ関数プログラミングは重要か(山下さん訳)が読めます。

なんだ、結局僕にとっての未読リストというオチ。あれもこれもと手を広げすぎても仕方がないのでとりあえず邦訳があるものやPDFが公開されているものから読んでいこうかと思ってます。後、この章で一番グッときたのは、サイモンがカレッジで講師の仕事をしている時に受けたアドバイス

どんなにつまらなく見えることでもいいから、何かを始めなさい

ですね。サイモンはそれがすごく重要なアドバイスだったと語っています。

PhotorecでSDカードの復元。助かった!

まさか、使う日が来るとは。奥さんがやってしまいました、SDカードの初期化。最近のは容量があるのでなかなかマックに取り込まず撮りっぱなしで子どもの入学式の写真とかが逝っちゃいました。で、PhotoRecの出番。いまどきににはめずらしくCUIです。

なのでまず、SDカードをマウントして、ターミナルからphotorecを起動。ブートディスクは表示されないようで(sudo すれば対象にできるみたいです。)僕の環境ではSDカードのみが表示されてますので選択してリターン

photorec 01

.netでSFTPをしてみる 2

in

案件ではパスワードを使わず鍵だけでログインする仕様になりそうなので引き続き調べたところ、addIdentity()で鍵ファイル指定を追加してやるだけであっさりできました。(StrictHostKeyCheckingの設定はC# - SSH / SFTP connection issue using Tamir.SharpSshを参考にしました。)

private void sftp_pubkey_j
  (string host, string user, string identify,string passphrase,Int32 port)
{
  Tamir.SharpSsh.jsch.JSch jsch = 
    new Tamir.SharpSsh.jsch.JSch();
  jsch.addIdentity(identify,passphrase);

  System.Collections.Hashtable hashConfig = 
    new System.Collections.Hashtable();
  hashConfig.Add("StrictHostKeyChecking", "no");

  Tamir.SharpSsh.jsch.Session session = jsch.getSession(user, host, port);
  session.setConfig(hashConfig);
  session.connect();

  Channel channel = session.openChannel("sftp");
  channel.connect();

  ChannelSftp c = (ChannelSftp)channel;
  Tamir.SharpSsh.java.io.FileInputStream source = 
    new Tamir.SharpSsh.java.io.FileInputStream("a.txt");

  c.cd("temp");
  c.put(source, "a.txt");

  c.exit();
  session.disconnect();
}

ラッパークラスを使えばもう少しスッキリしたコードになるし、JavaXXXなんてのを目にしなくても良いです。

.netでSFTPをしてみる

in

FTP/SSLか、SFTPの実装が必要になりそうなので準備。C#でやろうと思っているので、FTP/SSLのほうは.net標準のFtpWebRequestにまかせてSFTPのほうをググってみたら

この2つが見つかりました。サンプルをザッとながめてみたらSharpSSHがのほうが簡単そうだったのでとりあえずサンプルコードを書いてみました。

private void runUpload()
{
  Tamir.SharpSsh.jsch.JSch jsch = new Tamir.SharpSsh.jsch.JSch();
  Tamir.SharpSsh.jsch.Session session = jsch.getSession("foo", "example.com", 22);
  UserInfo uinfo = new MyUserInfo();
  session.setUserInfo(uinfo);
  session.connect();
  Channel channel = session.openChannel("sftp");
  channel.connect();
  ChannelSftp c = (ChannelSftp)channel;      
  Tamir.SharpSsh.java.io.FileInputStream source = 
    new Tamir.SharpSsh.java.io.FileInputStream("xyz.txt");
  c.cd("temp/data");     
  c.put(source, "abc.txt");
  c.exit();
  session.disconnect();
}

public class MyUserInfo : UserInfo
{
  public String getPassphrase() { return null; }
  public String getPassword() { return "foovar"; }
  public bool promptPassword(String message) { return true; }
  public bool promptPassphrase(String message) { return true; }
  public bool promptYesNo(String message) { return true; }
  public void showMessage(String message) 
  { 
     MessageBox.Show
       (message, "SSH", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
  }
}

これ、Javaで実装されたjschのAPIを利用していてそこここにJavaの名前が見えるところが面白いっちゅうか世界は広い。暗号化関連はMentalis.org Crypto Libraryを使ってます。

サンプルではMyUserInfoのところをUI実装してごにょごにょしていましたが、僕の場合はそこらへんは不要なのでそのまま値を返すように変更。とりあえずテストはできたのでこれで検討してみます。後はパスワードじゃなくて鍵を使う場合のほうも調べなきゃいけないし、週明けもう少し詳しく調べてみる予定。

コンボボックスの高さと幅を計算してみる

MFCでコンボボックスを使うときはフォームにコントロールを貼り付けてマウスでうにょ〜んって調整していたのですが、プログラムから動的に作成する場合それができないので、意味のあるウィンドウサイズを指定する必要があります。特に項目を追加したり削除したりといったことを頻繁におこなうときは結構面倒です。といっても所詮コンボボックスのウィンドウrectを指定するだけなんで何を指定するのかはある程度想像がつくのですが明示的に「こうしなさい」っていうドキュメントが見当たらなかったのでメモ。

C++のtemplateはやっぱすごいや

in

「プログラミング原論」第三章のお題でフォボナッチ数列をやったんですけど、Project Eulerでもやったなぁって思い出して探してみたらProblem25で使ってました。そのとき書いたのが、

fib :: [Integer]
fib = 0:1:(zipWith (+) fib (tail fib))

たったの2行のコレ。

前回のエントリで、うんうん言いながらC++をHaskellで書き直したpower_fib_accumulateとかpower_fibって何だったの?ってくらいのシンプルさ。Haskellのウリのひとつに"簡潔な実装が可能"っていうのよく見かけますけどホントですね。

その一方で、C++で書いたpower_accumulateとかpowerなんてのは汎用でこの章でやったようにオペランドの型を選びません。intだろうがpairだろうがpower_accumulateやpowerを使うことができます。Haskellでは(先のコードのように2行で済むなら最初からpower_accumulateやpowerを書き直してまで使う必要はないんですが)タプルの二項演算を受け付けるように書き直す必要がありました。厳密な型がじゃまをします。

どちらがどうと言うことはないんですが、第三章までをとおしてC++のテンプレートの強力さを見せつけられ(まぁ、著者がAlexander Stepnovですから...)改めてC++(with STL,Boost,Loki...)ってスゲーなって思い知らされました。

一番長いこと触れている言語だけどこのところHaskellばかり勉強していて疎遠になっているのでC++で書く仕事でも探してみるかというちょっとシアワセな気分。

プログラミング原論・第三章

三章は、結合演算子opを引数として受け取り、opに対するa^nを計算するアルゴリズムを最適化していきます。結合規則を意識しない左右べき乗からはじめて、共通部分式の除去・末尾再帰・ループ処理への変換・ループ式の最適化・蓄積変数の除去・特別ケース手続きへと、まあ見事に最適化していきます。

「プログラミング原論」の長い道のり。ようやく二章まで

「プログラミング原論」ようやく第二章まで読み終えました。キツイです。前書きに「順に」読むように書いてあるので飛ばすこともできず、一章二章を行きつ戻りつようやく三章に入ろうというところ。しかもこの二章を完全に理解できたとはとうてい言えず、読み終えることができるのか不安は増すばかりですぅ。

一章は「用語の定義」、第二章は、変換f(x)の軌跡(orbit)の接続点や衝突点を求めるアルゴリズムの実装ですが、頭の中だけでは到底追い切れないので実際にコードを書きながら読みましたが、肝心の「なぜ」のところの理解が甘いので本のコードをなぞるだけになっちゃた感は否めません。

たとえば、2.3節では、 衝突点は変換fと開始点xの衝突点(collision point)は、次のような一意のyです。

とあるのですが、なぜこの式が衝突点を示すのか理解できてません。注釈によればこのアルゴリズムはクヌース先生と懇意のW.Floyd(ロバート・フロイド)さんというすごい人が考えたらしいので、僕ごときが簡単に理解できるはずないのですが、いつの日かこういった知識の断片が役に立つことを信じて進むしかない気がします。各章に結論の節があるのでそれを頼りにヨチヨチと読み進めていくのがやっと。

VisualStudio2010で出力ファイル名を変更するとIDEからデバグできない件

このところ仕事ではずっとVS2010に浸ってます。昨日は自分のプログラムではなくVSのバグ(だと思う)を発見。

リンク設定で出力ファイル名をプロジェクト名以外に変更するとIDEからデバグできません。例えば、プロジェクト"foo"を作成し、出力ファイル名を"bar"に変更。

IDEから実行すると...

とか言われちゃいます。ビルド自体は正常で、bar.exeも作成されているんですけどね....試しにVS2008で同じ事をしてみたらこちらはちゃんとできました。まったく....テキトーなプロジェクト名は付けられませんね。ええ、「名前重要」ですとも。(ちなみに未だにC++/MFCプロジェクトです。C#のプロジェクトとかでは試してません、恐ろしくて)

コンテンツの配信