Recently in programming Category

 今日読んでいるコードに、知らなかったプリプロセッサ命令が出てきたのでメモ。

#include <stdio.h>

#define tcat(x,y,z) x ## y ## z
#define cat(x) # x

#define abc "Hello"

int main(void)
{
  printf("%s\n", tcat(a, b, c));
  printf("%s\n", cat(a b c));
  return 0;
}

実行すると、

chome@sid:~/src/test$ ./a.out 
Hello
a b c

となる。

dpkg-buildpackageメモ

| | TrackBacks (0)

 Debianパッケージの作成プロセスを自動化するコマンドであるdpkg-buildpackageのメモ。dpkg-buildpackageは以下の手順でパッケージを作成する。

  1. 環境変数の準備。dpkg-architectureでBuild archやHost arch等を設定し、またCCFLAGS、CXXFLAGS、LDFLAGS等を設定
  2. build-dependencyとbuild-conflictsのチェック。(-d でスキップ)
  3. debian/rule clean (-nc でスキップ)
  4. dpkg-source (-b, -B, -A のいずれかが設定されているとスキップ)
  5. -b, -B, -Aオプションによって以下のいずれかに分岐
    • debian/rules build (デフォルトまたは-b)
    • debian/rules binary-arch (-B)
    • debian/rules binary-indep (-A)
  6. dscファイルを署名 (-us でスキップ)
  7. dpkg-genchanges でchangesファイルを生成
  8. changesファイルを署名 (-uc でスキップ)
  9. もしも-tcが指定されていたら、debian/rules clean

-j で、並列に動かすCPUの数を指定することができる。はしょったところもあるので、dpkg-buildpackage(1)を確認のこと。

SingletonパターンをC++でまじめに書いてみた。Singletonは生成は簡単なんだけれど、後始末が難しい。GoF本とかには、後始末のことはあまり詳しく書かれていなかったような気がする。あとModern C++ Designにこのことは詳しくかかれている。

 今回は最初に思いついたリンクカウントを採用してみた。Singletonを参照しているオブジェクトの数を数えておいて、0になったらdeleteする。

#ifndef _SINGLETON_H
#define _SINGLETON_H

namespace impl{
template <class T>
class Singleton{
public:
  static Singleton* initInstance()
  {
    if(linkcount == 0){
      instance = new Singleton();
      linkcount = 1;
    }else{
      linkcount+=1;
    }
    return instance;
  }

  void destroy()
  {
    if(0 == (linkcount-=1)){
      delete instance;
    }
  }

  T* object(){
    return &obj;
  }

private:
  Singleton(){
  }

public:
  virtual ~Singleton(){
  }

private:
  static Singleton *instance;
  static int linkcount;
  T obj;
};


template <class T> Singleton<T> *Singleton<T>::instance;
template <class T> int Singleton<T>::linkcount = 0;
}

template <class T>
class Singleton{
 public:
  Singleton(){
    s = impl::Singleton<T>::initInstance();
  }
  
  T* operator->(){
    return s->object();
  }

  ~Singleton(){
    s->destroy();
  }

 private:
  Singleton(const Singleton&){}

 private:
  impl::Singleton<T> *s;
};
#endif // _SINGLETON_H

で、一つしかインスタンスを作りたくないクラスを定義してあげて、::Singletonのテンプレート引数に入れてあげればよい。例えばこんな感じ。

#include "singleton.h"
using namespace std;

class Hello
{
public:
  Hello()
  {
    i = 0;
  }

  void run()
  {
    i += 1;
    cout<< "Hello World "<< i<< endl;
  }

  ~Hello()
  {
    cout<< "destroy"<< endl;
  }
  int i;
};


int main(void)
{
  Singleton<Hello> i1;
  Singleton<Hello> i2;
  Singleton<Hello> i3;

  i1->run();
  i2->run();
  i3->run();

  return 0;
}

 このテストコードを実行すると、次のようになる。

Hello World 1
Hello World 2
Hello World 3
destroy

 同じテンプレート引数の::Singletonインスタンスを複数生成しているが、それらは同じインスタンス変数にアクセスしており、デストラクタは1度しか呼ばれていない。ちゃんと動いているようだ。ただこのコードでは、Helloの初期化をデフォルトコンストラクタでしかできない。これではちょっとカッコ悪い。もう少し考えなければ。

 WHATWGでHTML5仕様がLast Callになった。徐々にではあるが、Web Application が普及する環境が整いつつある。(どうもW3Cは聞いていなかったらしく、ちょっと揉めそうな感じみたいだが。)

 さて、以前もここで書いたとおりHTML5はそれまでの文書の構造化に加え、振る舞いの要素の追加が行われており、スクリプト言語のインターフェースも規定されている。このスクリプト言語は仕様の上では指定されているわけではないが、事実上JavaScriptだろう。ということでそろそろちゃんとJavaScriptを書けるようにならなきゃいかんのかなぁ。ということで、まずはクロージャーからやってみた。

<html lang="ja">
<head>
  <title>Closure Test</title>
  <meta http-equiv="Content-Type" content="text/plain;charset=UTF-8">
</head>

<body onload="onLoad()">
<script type="text/javascript">
var countUp;

function makefunc()
{
    var x=0;
    return function(){return x++;};
}

function onLoad()
{
    countUp = makefunc();
    window.setInterval(onTimer, 100);
}

function onTimer()
{
    document.getElementById('count').innerHTML = countUp();
}

</script>

<div id="count"></div>
</body>
</html>

 このコードは、100ms毎にカウントアップして表示するもの。makefuncがカウントアップする関数オブジェクトを作り、onloadハンドラでグローバル変数countupに保存しておく。それを100ms毎に呼び出している。実行すると下のようになる。

久しぶりにshell (bash) script。一つのデータが一行ごとに並んでいるファイルから必要な部分を取り出すスクリプト。今回はbashの組み込み関数である getopts を使ってみた。

#!/bin/bash
#
# clip.sh -f FROM -t TO FILE
#

while getopts "f:t:" i;do
	case $i in
		f) FROM=$OPTARG;; # Time From
		t) TO=$OPTARG;;   # Time To
	esac
done

shift $(($OPTIND - 1))
FILE=$1

LINES=`wc --line $FILE | cut -d " " -f 1`
FLINE=`grep -n $FROM $FILE | cut -d : -f 1 | head -n 1`
TLINE=`grep -n $TO $FILE | cut -d : -f 1 | head -n 1`

if [ $FLINE -ge $TLINE ]; then
	TMP=$FLINE;
	FLINE=$TLINE;
	TLINE=$TMP;	
fi

HEAD=$(($TLINE-$FLINE))
TAIL=$(($LINES-$FLINE+1))

tail -n $TAIL $FILE | head -n $HEAD

 たとえばこのようなファイルがあるとすると

11:00:17 24.93 72.9
11:00:17 24.94 72.8
11:00:17 24.94 72.7
11:00:18 24.95 72.4
11:00:19 24.96 72.1
11:00:20 24.97 71.9
11:00:21 24.97 71.8
11:00:22 24.98 71.7
11:00:23 24.99 71.4
11:00:24 25.00 71.2
....

このファイルをdata.txtというファイル名として、この中から12:00:00から13:00:00まで取り出したいとすると、

$ clip.sh -f 12:00:00 -t 13:00:00 data.txt

とすれば標準出力に出力される。

 ふ、例によって誰もついて来れまい。あ、ぴらふとCZDの二氏は除く。ってかこのくらいのコマンドは、textutilあたりにありそう。良い解法があればコメントよろ。

 前回の記事haveの指摘に従い、参照渡しをやめてヴェクタを返す関数にしてみた。

std::vector<string> 
slice(const std::string source, const std::string dem)
{
  std::string::size_type i1 = 0;
  std::string::size_type i2 = source.find(dem);
  std::vector<string> retval;

  if(std::string::npos == i2)
    return retval;

  std::string s = source + dem;

  do{
    retval.push_back(s.substr(i1, i2-i1));
    i1 = i2+1;
  }while(std::string::npos != (i2 = s.find(dem, i1)));

  return retval;
}

 ちょっと効率は落ちたが、Atomicになったので前回のコードにくらべ、マルチスレッドプログラミングで安全に使えるようになった。

Thanks! nice comment > Have

C++を書いていて、JavaのSttringTokenizerのようなことをやりたいことがある。C++標準ライブラリだけで書いてみた。

void slice(const std::string source, 
	   const std::string dem, 
	   std::vector<std::string> *retval)
{
  std::string::size_type i1 = 0;
  std::string::size_type i2 = source.find(dem);

  if(std::string::npos == i2)
    return;

  std::string s = source + dem;

  do{
    retval->push_back(s.substr(i1, i2-i1));
    i1 = i2+1;
  }while(std::string::npos != (i2 = s.find(dem, i1)));
}

 この関数は、sourceで指定した文字列をdemで指定した文字で切り分けて、切り分けた結果をretvalで指定したヴェクタに格納ものである。テストしてみると。


using namespace std;

int main(void)
{
  string source = 
    "DCV_,___,___,-00.0073E-3,DCV_,___,___,+00.000E-3,6247865";

  vector<string> vec;
  vec.clear();

  slice(source, ",", &vec);
  if(vec.empty()){
    cout<< "not found"<< endl;
    return -1;
  }

  cout<< vec[3]<< " "<< vec[7]<< endl;
  return 0;
}


$ ./a.out
-00.0073E-3 +00.000E-3

 ちゃんと値は切り出せている。listに結果を格納するようにすれば、もっとStringTokenizerっぽくなるかな。

久しぶりScheme

| | TrackBacks (0)
PHOTO: On Lisp Cover

 久しぶりにschemeでコードを書いてみた。実用のコードでは初かな。処理系はGaucheで、標準入力から数値を入力して標準偏差を計算するコード。

(define (ave-list lst)
  (/ (fold + 0 lst) (length lst)))

(define (var lst)
  (let ((ave (ave-list lst)))
    (/ (fold + 0 
	     (map (lambda (x) (* x x)) 
		  (map (lambda (x) (- x ave)) lst)))
       (length lst))))

(define (sd lst)
  (sqrt (var lst)))

(display (sd 
	  (map string->number (port->string-list 
			       (current-input-port)))))

リストを修正するコードの連鎖と高階関数。この感覚がLISPっぽい。

 新しいカメラは届きました。

2009-06-06 追記
 はぁ?LET?とか言われそうなので(誰に?)、LETなしバージョンは、sdをこうすれば良い。


(define (var lst)
  ((lambda (ave)
    (/ (fold + 0
	     (map (lambda (x) (expt x 2))
		  (map (lambda (x) (- x ave)) lst)))
       (length lst)))
   (ave-list lst)))

もう誰もついてきてないか....
あと写真を追加しました。

PHOTO: Ear Phone

 Microsoft Speech APIを触ってみた。.NETだとすごく簡単だった。Hello Worldは以下のとおり。Microsoft Windows XP上で、Microsoft Speech SDK 5.1をインストールし、Visual C# 2005 Express Editionで作成した。最初に参照設定で、"Microsoft Speech Object Library"を追加すること。
 このコードは、インストールされているすべてのVoiceで"It's fine today"と発音する。

using System;
using System.Collections.Generic;
using System.Text;
using SpeechLib;

namespace TTSTest
{
    class Program
    {
        static void Main(string[] args)
        {
            SpVoice voice = new SpVoice();
            ISpeechObjectTokens token = voice.GetVoices("", "");
            for (int i = 0; i < token.Count; i++)
            {
                voice.Voice = token.Item(i);
                Console.WriteLine(token.Item(i).GetDescription(0));
                voice.Speak("it's fine today", SpeechVoiceSpeakFlags.SVSFlagsAsync);
            }
            while (voice.Status.RunningState == SpeechRunState.SRSEIsSpeaking) ;
        }
    }
}

今月からJava読書会に参加する予定だ。課題図書はJavaネットワークプログラミングの神髄である。予習課題が出ているので早速やってみた。

About Me

中尾 圭佐(chomy)
千葉県船橋市在住のモノクロ写真に目覚めた研究者。
Twitter ID: jm6xxu
Skype: chomy

My Tweets

jm6xxu: Yesterday, I joined the summer school at Tsukuba. I could join only one day but i feel it is wonderful to know not knowing.

jm6xxu: VHDLは院生の時に書いたなぁ。簡単なロジックだったけど。最近は、Cからも論理合成できるらしい。RT @habutarou: HDLも大きく2種類あったな。おいらはVHDLを習った。なつかしい… RT @jm6xxu ま、その前にVHDLを思い出さなきゃいけないがな。

jm6xxu: ま、その前にVHDLを思い出さなきゃいけないがな。と思ったら、emacsにverilogモードなんてものがある。debパッケージにもなってるし、Verilogにするか。

jm6xxu: 9月なので本気出す。本格的にFPGAでデバイスを作ることにする。純正ダウンロードケーブルもSuzakuも注文したし、WebPack ISEもダウンロード中。再来週には無料セミナーにも行く。

jm6xxu: 四次元空間はドラえもんのらポケットの中の世界だって? 30点。パイロットは6次元で航空機を制御してる。所詮地ベタて満足してるヤツは自由度がもう一つあるコトを死ぬまで気づかないものさ

About this Archive

This page is a archive of recent entries in the programming category.

photograph is the previous category.

Find recent content on the main index or look in the archives to find all content.

Powered by Movable Type 4.261