2008/01/30

[Memo]Mapクラスの正しい使用法

Mapクラスの正しい使用法 - ITアーキテクト [IT Architect]
  • すべてのキーと値を取得する場合はentrySetを使う。
  • LinkedHashMap—登録順序を保持するMap(初めて登録された順番、上書きは登録に入らない)
  • IdentityHashMap—IDでキーを判定するMap(キー同士の同一判定を==で行う)
  • WeakHashMap—弱参照で値を保持するMap

2008/01/25

寝不足って怖い

添削してもらったはずの論文の後半4割くらいが今さっきプリンタから出てきた。
............。

おいおい。

確認してみると、やっぱり添削に出した論文の後ろが無い。
どうりでいろいろ言われるわけだ。
具体例あれだけ書いてまだ足りないのか、厳しいなぁとか思ってましたよ。
なんでそんなことに気づかなかったんだろうね。
当時は精神的にいろいろやばかったのだと思われますよ。

こんなことで大丈夫なのだろうか、不安だなぁ。

2008/01/24

卒論開発(!?)環境

卒業論文の開発環境
  • OS : Mac OS X
  • 構成 : FreeMind
  • 図形作成 : keynote(使用期間切れで保存はできない)+画面キャプチャ
  • ソース作成 : mi
  • 清書 : plaTeX
何やらすごい無理矢理感が...。 Macってフリーで手軽なアウトラインエディタって無いみたいね。 逆にいろいろ体験できて面白かったっす。

卒論添削中!

なんという開放感。 これから真っ赤になった原稿が返ってくるなんて信じられないぜ...。 なんかいろいろ知識たまったからちょっとアウトプットしたい気分だけどいつになることやら。

2007/12/11

まとめって難しいね。

入力:出力=5:5が理想?

 とか聞くけれど、今回私すごい比率になってますよ?
 実行するのに5分、理解するのに10分、まとめるのに1時間って感じ。15:60= 1:4。自分がやったことをまとめるというのはやっぱり難しいね。
 いやはや全く。

2007/06/21

docstringとdoctest…Pythonのドキュメント?

pythonではクラス(メソッド)の説明を次のように書くらしい。
で、次のように書くとそれでテストもできるらしい。
>>> class test:
   """test class

   >>> test = test();
   initted
   >>> test.hello();
   HELLO
   """
   def __init__(self):
      """testclass's init"""
      print "initted";
   def hello(self):
      """print 'HELLO'"""
      print "HELLO";

>>> import doctest;
>>> doctest.testmod();
*** DocTestRunner.merge: '__main__.test.__init__' in both testers; summing outcomes.
*** DocTestRunner.merge: '__main__.test.hello' in both testers; summing outcomes.
*** DocTestRunner.merge: '__main__.doc' in both testers; summing outcomes.
*** DocTestRunner.merge: '__main__.test' in both testers; summing outcomes.
*** DocTestRunner.merge: '__main__' in both testers; summing outcomes.
(0, 2)

※上のはPython Shellでの入出力です。
宣言の直後にコメントを付ける。それがクラスを説明した文章で、docstringと呼ばれている。
docstringにはクラスの説明とクラスの宣言方法、使い方とその出力を記述する。
docstringにクラスの宣言方法、使い方を記述すると、doctestモジュールでテストが行える。
ただし、そのつど出力の変わるようなもののテストはできない。(現在時刻を表示するメソッドなど)

関連項目?

2007/06/15

お題4:入れ子リストの中身を順に表示

お題4:入れ子リストの中身を順に表示 (Python Workshop the Edge 2007)

お題4:入れ子リストの中身を順に表示

整数かリストが入っているような入れ子になったリストを考える。
(例:[1, [2, 3, 4], 5, [[[6], [7, 8], 9], 10])

* 入れ子リストが与えられたときに中身を順に表示するような関数を作れ。
* 与えられたオブジェクトが「整数とリストだけでできている」かどうかをチェックしてTrueかFalseを返す関数を作れ。

というわけで作ってみた。
眠いのでコメント控えめ。
#/usr/bin/env python2.5
# -*- coding: utf-8 -*-

class SearchList:
   def isInt(self, obj):
      if (obj.__class__ == int):
         return True;
      else:
         return False;
   def isList(self, obj):
      if (obj.__class__ == list):
         return True;
      else:
         return False;
   def canRead(self, obj):
      if (self.isInt(obj)):
         return True;
      elif (self.isList(obj)):
         for var in obj:
            if (not self.canRead(var)):
               return False;
         return True;
   def printList(self, obj, message = ""):
      if (self.canRead(obj)):
         for var in obj:
            if (self.isInt(var)):
               message = message + str(var);
            else:
               message = message + str(self.printList(var, message));
      else:
         message = "このオブジェクトは読み込めませんてば。";
      return message;

if ( __name__ == "__main__"):
   #以下、ひたすら動作確認
   list1 = [1, [2, 3, 4], 5, [[[6], [7, 8], 9], 10]];
   list2 = [1, [2, 3, 4], 5, [[[6], [7, "string"], 9], 10]];
   sl = SearchList();
   
   print sl.canRead(list1);
   print sl.printList(list1);

   print sl.canRead(list2);
   print sl.printList(list2);
リストの要素を全てプリントする関数を作って、そこにもしその要素がリストだったらという分岐を加える。
で、リストだったらそのリストの中身を全てプリントする関数(自分自身)を呼び出す。
って感じで関数を作りました。
なぜかクラスにまとめてありますが。
これと課題1を組み合わせればフォルダの中身も全て同期するプログラムが書けるわけですね。

2007/06/14

課題3:シングルトン パート2

リベンジ?
いや、違うけれど…。
#!/usr/bin/env python2.5
# -*- coding: utf-8 -*-

## InstantiatedError
#シングルトン用の例外?
class InstantiatedError(Exception):
   def __init__(self,klass):
      self.message = str(klass) + ' このクラスのインスタンスは一つしか作れません。';

   def __str__(self):
      return repr(self.message);   

class Singleton:
   __instance = None;
   def __init__(self):
      if (self.__class__.__instance != None):
         #インスタンスがあれば例外をはく
         raise InstantiatedError(self.__class__);
      else:#インスタンスが無いなら今作ったものを__instanceに入れる
          self.__class__.__instance = self;

   def getInstance(self):
      if (self.__class__.__instance == None):#インスタンスが作られていなければ作る
         self.__class__.__instance = self;
         return self.__class__.__instance;
      else:#インスタンスが既にあればそれを返す
         return self.__class__.__instance;
      
class Memo(Singleton):
   __text = "";
   def setText(self,text):
      self.__class__.__text = text;#※

   def getText(self):
      return self.__class__.__text;#※

#※ 必ずクラス変数を参照するようにする。

if (__name__ == "__main__"):
   #以下、ひたすら動作確認
   mem1 = Memo();
   try:
      mem2 = Memo();
   except InstantiatedError:
      print "インスタンスが既にありますよ。";
同じインスタンスを作ったら例外をはくようにしてみた。
…なんかこうよくわからない。

お題3:シングルトン

お題3:シングルトン (Python Workshop the Edge 2007)

お題3:シングルトン

Pythonでシングルトンを作れ。

まぁ、シングルトンってなに?っていうところから始めなければならないのよね。
Singleton パターン - Wikipedia
Singletonコンストラクタが一つしか無いことを保証するらしい。 で、作ってみた。
#!/usr/bin/env python2.5
# -*- coding: utf-8 -*-

class Singleton:
   __instance = None;
   def getInstance(self):
      if (self.__class__.__instance == None):
         self.__class__.__instance = self;
         return self.__class__.__instance;
      else:
         return self.__class__.__instance;

class Memo(Singleton):
   __text = "";
   def setText(self, text):
      self.__class__.__text = text;

   def getText(self):
      return self.__class__.__text;

class Memo2(Singleton):
   __text = "";
   def setText(self, text):
      self.__class__.__text = text;

   def getText(self):
      return self.__class__.__text;

if (__name__ == "__main__"):
   #以下、ひたすら動作確認
   mem1 = Memo().getInstance();
   mem2 = Memo().getInstance();
   mem3 = Memo();
   
   print mem1;
   print mem2;
   print mem3;
   
   mem1.setText("momonga");
   
   print mem1.getText();
   print mem2.getText();
   print mem3.getText();
   
   mem3.setText("musasabi");
   
   print mem1.getText();
   print mem2.getText();
   print mem3.getText();
   
   mem2.setText("hattori");
   
   print mem1.getText();
   print mem2.getText();
   print mem3.getText();
   
   tex1 = Memo2().getInstance();
   tex2 = Memo2().getInstance();
   tex3 = Memo2().getInstance();
   
   print tex1;
   print tex2;
   print tex3;
   
   tex1.setText("text2");

   print tex1.getText();
   print tex2.getText();
   print tex3.getText();

   print mem1.getText();
   print mem2.getText();
   print mem3.getText();
…新しいインスタンスの作成自体は防げていない…という出来損ない?
pythonではデータ、メソッドの隠蔽が出来ないらしいのでお手上げ。
newClass = NewClass().getInstance();でインスタンスを取得。
最初に作成されたインスタンスをクラス変数として保存し、すべてのメソッドはそこからテータを取ってくる。
結局これで良いのかどうかもよくわからない。

2007/06/13

お題2:単語数カウント

お題2:単語数カウント (Python Workshop the Edge 2007)

お題2:単語数カウント

英文のテキストファイルを読み込んで単語の出現数を数えるプログラムを作れ。

例えばテキストファイルの中身が「It's fine day, isn't it? Yes, it is!」ならばit'sが1回、fineが1回、dayが1回、isn'tが1回、itが2回、yesが1回、isが1回となるように数えてよい。
(isn'tにはisが含まれているな、とか、It'sの'sはisの省略形だな、などと判断するのはとてもむずかしいので)

余力があれば出現頻度の多い順に出力するプログラムも書け。

で、作ってみた。
#!/usr/bin/env python2.5
# -*- coding: utf-8 -*-

import re;

## wordCount
# 文字列を渡すと、英単語に分解して出現頻度を求める
# splitPattern = 区切り文字のパターン指定(それっぽいものを適当に並べただけ)
# text = 指定した区切り文字で受け取った文字列を分割し、リストを作成する
# words = {単語:出現数}の辞書
def wordCount(src):
 splitPattern = re.compile(' |\t|\n|\r|\?|\!|\(|\)|\"|\.|\,');
 
 text = splitPattern.split(src);

 words = {};

 #単語の出現回数を数える
 for word in text:
  #空の単語は無視する
  if (word != ''):
   if (word in words):#今までに出たことがあるなら出現回数に+1する
    words[word] += 1;
   else:#初めての単語なら新規作成
    words[word] = 1;
 
 return words;

## sort
# wordCountで作った辞書をソートする。
# wordCount専用だからいっそclassにまとめた方が良いかも…。
def sort(dict):
 #出現回数、アルファベットの順にプリントしていく
 for word, count in sorted(words.iteritems(), lambda x,y:(y[1] == x[1] and cmp(x[0].lower(), y[0].lower())) or y[1]-x[1]):
  print word + ": " + str(count) + ",",

if (__name__ == "__main__"):
 from sys import argv,exit;
 if (len(argv) != 2):
  print 'ファイル指定は一つまででお願いします。';
  exit();
 
 text = open(argv[1]).read();
 words = wordCount(text);
 print words;
 sort(words);
うへぇ。
ソートの仕方が全くわかりませんでした。
lambda式とsortedが組合わさると、両方わからない私にとってはどんな魔法だって感じですよ。
sortedの第一引数で指定したリストから2つ取って来て第二引数に渡す。
戻り値が+だとそのままで-だと入れ替える?(頭が働かない…)
とりあえず呪文は暗記しておこうかね?

lambdaとかについて

これ(↓)を、
def sort(dict):  #出現回数、アルファベットの順にプリントしていく
 for word, count in sorted(words.iteritems(), lambda x,y:(y[1] == x[1] and cmp(x[0].lower(), y[0].lower())) or y[1]-x[1]):
  print word + ": " + str(count) + ",",
lambda式を使わない、かつ、もっと細かくて順を踏んで書くとこんな(↓)感じになるらしい。
def sort(dict):
 sortedWords = sorted(words.iteritems(), cmp_custom);
 for word, count in sortedWords:
  print word + ": " + str(count) + ",",

def cmp_custom(x,y):
 if (y[1] == x[1]):
  return cmp(x[0].lower(), y[0].lower());
 else:
  return y[1]-x[1];
ソートで使う比較用の関数を新しく作り、sortedの第二引数でその関数を指定してあげる。
それで、ソート済みのリスト((ワード,出現回数)のタプルが入ったリスト。print sortedWordsで見てみると良くわかる?)が取得できる。
取得したリストをfor文でぶん回して出力すればOKらしい。
…それにしても、変数の命名にかなりの問題がある気がする。

Pythonの勉強のために

Python Workshop the Edge 2007のお題をやって見ようと思う。
お題1:ファイルの同期 (Python Workshop the Edge 2007)

お題1:ファイルの同期

二つのディレクトリ下のタイムスタンプを比較して、同期を取るプログラムを作りたい。

二つのディレクトリ(フォルダ)を指定すると、そのディレクトリの下の全てのファイルについて「片方にしかないファイルはもう片方へコピーし、両方にあるけどもタイムスタンプ(更新時刻)の異なるファイルは新しい方で古い方を上書きする」という処理を行うプログラムを作りなさい。

で、作ってみた。
#! /usr/bin/env python2.5
# -*- coding: utf-8 -*-

from os import listdir, stat, sep;
from os.path import getmtime;
from shutil import copy2;

## sync
# 二つのディレクトリを比較し、同期をとる。
# filesX = ディレクトリの中身の集合
# to1Files = ディレクトリ1へコピーするファイル集合(2にしかないファイル集合)
# to2Files = ディレクトリ2へコピーするファイル集合(1にしかないファイル集合)
# bothFiles = 両方のディレクトリにあるファイル集合(後でタイムスタンプを比較するファイル集合)
def sync(dir1, dir2):
   #ディレクトリ1,2それぞれのファイル集合を作成
   files1 = set(listdir(dir1));
   files2 = set(listdir(dir2));

   #どのファイルをどのsetに入れるか振り分ける。
   to1Files = files2.difference(files1);
   to2Files = files1.difference(files2);
   bothFiles = files1.intersection(files2);

   #bothFilesに含まれるファイルのタイムスタンプを比較し振り分ける
   for file in bothFiles:
      #比較するファイルのパス作成
      file1 = dir1 + sep + file;
      file2 = dir2 + sep + file;

      #タイムスタンプの比較と振り分け。
      if (getmtime(file1) > getmtime(file2)):
         to2Files.add(file);
      elif (getmtime(file2) > getmtime(file1)):
         to1Files.add(file);
   
   # to1Files,to2Filesのファイルをコピーすべきディレクトリへコピーする
   for file in to1Files:
      copy2(dir2 + sep + file, dir1 + sep + file);
   for file in to2Files:
      copy2(dir1 + sep + file, dir2 + sep + file);
   
if (__name__ == "__main__"):
   from sys import argv, exit;
   if (len(argv) != 3):
      print "ディレクトリを2つ指定して下さい。";
      exit();
   
   sync(argv[1],argv[2]);
最初は無駄にクラス作っていたけれど削りに削って最終的にこんな感じになりました。
ほかのお題もやってみようかしら?

2007/03/23

[普通の日記]たこの話

電車にて、隣に座った親子の会話。

『なにそれ?拳だこ?
『うん、仕事してるといつのまにかできちゃうのよね』
『へぇー、大変だねぇ』

どんな仕事だよ。
とか思ったけれども、普通に考えると拳だこでなくてペンだこですわな。

あ、それだけです。
でわ、でわ。

2006/12/27

[C言語]バッファオーバーフローの練習

■今回のプログラム

長さ5のchar配列を作成。
gets()で標準入力。
printf()で標準出力。

■ソースファイル
#include <stdio.h>
#define NUM 5

int main(void)
{
//文字列バッファ宣言(長さは5)
char s[NUM];

printf("s address:%X¥n", &s);
printf("s length:%d¥n¥n", sizeof(s));
printf("input string:");
gets(s);//バッファのサイズを渡せないのでチェックのしようが無い
printf("%s¥n", s);
}
■実行結果
$ ./BOFTest
s address:BFFFFCBB
s length:5

warning: this program uses gets(), which is unsafe.
input string:fdsafdas
fdsafdas

親切にwarningが出てますが無視して大量入力。
宣言した領域をはみ出して書き込んでますね。
printf()も領域完全無視で読みにいってるみたいです。
fscanf()が嫌われてるのもこれが理由らしいです。
作るのは簡単(よりもたちが悪い)なだけに対策が難しいですね。

[C言語]文字列の検索

■処理の流れ

string1からstring2[i]の文字列を探す。
それだけ。

■ソースファイル
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){
//検索される文字列
char string1[] = "Hey mommy where is my shoes.";

//検索する文字列(する、されるじゃいまいちわかり難いね)
char *string2[] = {"Hey", "mommy", "where", "is", "my", "shoes", NULL};

//string2のインデックス用
int i = 0;

//string1の表示と先頭アドレスの表示
printf("string1 = ¥"%s¥"¥n", string1);
printf("string1はここから始まってますよ:%X¥n",&string1);

//string2の単語を先頭から検索、NULLになったらやめる
while(string2[i] != NULL){
printf("%sはメモリの%X番地から始まってますよ。¥n", string2[i], (int)strstr(string1, string2[i]));
i++;
}
}
■実行結果
$ ./SearchTest
string1 = "Hey mommy where is my shoes."
string1はここから始まってますよ:BFFFFC8F
HeyはメモリのBFFFFC8F番地から始まってますよ。
mommyはメモリのBFFFFC93番地から始まってますよ。
whereはメモリのBFFFFC99番地から始まってますよ。
isはメモリのBFFFFC9F番地から始まってますよ。
myはメモリのBFFFFC96番地から始まってますよ。
shoesはメモリのBFFFFCA5番地から始まってますよ。

1文字1バイト=一つの番地に収まる。
という訳でこういう場合わかりやすいね。
あとはstrlen()と組み合わせていろいろできそう。

[C言語]ファイルに出力

■何となく流れっぽいもの

コマンドライン引数を取得。
引数一つを1行にしてoutput.txtに出力する。

■ソースファイル
#include <stdio.h>

int main(int argc, char *argv[])
{
int i;

//ファイルポインタ宣言
FILE *fp;

//ファイルオーオプン
fp = fopen("output.txt","w");

if(fp == NULL){
printf("Can not open...");
return 1;
}

//書き込む
fputs("書き込み開始\n", fp);
for(i=1; i <= argc; i++){
fputs(argv[i], fp);
fputs("\n", fp);
}
fputs("書き込み終了\n", fp);

//別な書き込み方
fprintf(fp, "書き込み開始\n");
for(i=1; i <= argc; i++){
fprintf(fp, "%s\n", argv[i]);
}
fprintf(fp, "書き込み終了\n");
//ファイルクローズ
fclose(fp);
}
■実行結果
$ ./FileOutputTest This is a pen.
$ cat output.txt
書き込み開始
This
is
a
pen.
(null)
書き込み終了
書き込み開始
This
is
a
pen.
(null)
書き込み終了
■ソース書くだけでいっぱいいっぱい

別に良いよね、需要無いし。
(こういう考え方がいけないんだ…)

2006/12/26

[Mac][備忘録]"\"バックスラッシュが打てない

■Win用のJISキーボードを使うと、¥(エン)マークしか打てない。

という訳でいろいろ調べてみた。
やっぱり解決方法がありましたよ。(ネタ元URL参照)
キーマップを自作して適用するらしい。

■必要なもの

Ukeleleのダウンロード

■手順

1.Uklele.appを開いたら"New Keyboard Layout"ってウィンドウで"Copy of other keyboard layout"を選択する。
2.Ukeleleのフォルダから"System Keyboards→Japanese→ROMAJI.keylayout"を選択。
3.メニューから"Keyboard→Set keyboard type..."
4."Select Keyboard Type"ウィンドウで(左)"Third party"、(右)JISとしてやる。
5."~/Library/Keyboard Layouts"に保存。
6.いったんログアウト。
7.システム環境設定→言語環境→入力メニューにさっき保存したキーボードがあるからチェックを入れる。
8.ことえりの入力モードに追加されているのでそれを選択する。

■こんな感じで

OKでした。

2006/12/21

[C言語]コマンドライン引数を使ってみる

■mainの第一引数に引数の数、第二引数に文字列配列

具体的にはこんな感じ。

#include <stdio.h>

int main(int argc,char *argv[])//argcが引数の数、argv[]が実際の引数
{
int i;
//第一引数から最後の引数まで順番に表示
for(i = 1; i <= argc; i++){
printf("第%d引数:%s\n",i,argv[i]);
}
return 0;
}

ちなみに、第零引数は実行ファイルへのパス。 (多分カレントディレクトリからの相対パス)

■実行結果
$ ./InputEcho Is this a pen ?
第1引数:Is
第2引数:this
第3引数:a
第4引数:pen
第5引数:?
第6引数:(null)

[C言語]ファイルから入力

■ファイル入力テスト

ソースファイルはこちら

#include <stdio.h>
#define NUM 256

int main(void)
{
FILE *fp;
char string[NUM];
char s1[NUM],s2[NUM];

//ファイルオープン
fp = fopen("inputfile.txt","r");

//オープン成否判定
if(fp == NULL){
printf("ファイルが開けませんよ?\n");
return 1;
}

printf("ファイル読み出し開始\n");
//ファイル読み出し
while(fgets(string, NUM, fp) != NULL){
printf("%s", string);
}
printf("ファイル読み出し終了\n");

//現在位置(どこから読み込むか)を先頭に戻す
fseek(fp, 0, 0);

printf("二度目のファイル読み出し開始\n");
//ファイル読み出し2
while(fscanf(fp, "%s %s", &s1, &s2) != EOF){
printf("名:%s 姓:%s\n", s1, s2);//fscanfの場合最後の改行は空白に変換されるらしい
}
printf("二度目のファイル読み出し終了\n");

//ファイルクローズ
fclose(fp);
return 0;
}

読み込むファイルはこれ

命 大雪
板 かまぼこ
だんご 笹

実行結果はこれ

ファイル読み出し開始
命 大雪
板 かまぼこ
だんご 笹
ファイル読み出し終了
二度目のファイル読み出し開始
名:命 姓:大雪
名:板 姓:かまぼこ
名:だんご 姓:笹
二度目のファイル読み出し終了

fscanfは嫌われているみたいね。
扱い方が独特らしい。 あとエラー処理が面倒くさくなるみたい。

2006/12/20

[ブログ改造日記]あちらをたてればこちらがたたず

■改行を<br />に変換…

なんて処理をbloggerまかせにしていたので、タグを使った編集すると改行入りまくりですよ。
やはりタグ使うと結構改行するので…。
古い設定を残すと新しいのに影響するという罠。
しかも今の設定も既に改善案があったりしてもうどうしたら良いのやら…。
WEBデザインは熟慮してから決めましょうねって話ですかね。

[ブログ改造日記]CSSの勉強

■中見出し

中見出しの中身。
こんな感じでどうですか?

■色分け表示

ファイルの内容とかコンソール画面とかはこういう表示。

> こんな感じで

どうよ?