2008/02/20

[Cocoa]Cocoaアプリケーションチュートリアル(途中まで)終了

大変お疲れさまでした

「Currency Converter」は単純なアプリケーションですが、これを作成することで、Cocoaプログラミングの概念とテクニックの多くを明らかにすることができました。ここまででCocoaアプリケーションの開発に必要な技能について理解を深めることができました。以下のことを学習しました。

Interface Builderでグラフィカルユーザインターフェイス(GUI)を作成する方法
Interface Builderでユーザインターフェイスをテストする方法
Interface Builderでクラスのアウトレットとアクションを指定する方法
Interface Builderでアウトレットとアクションを使って、コントローラインスタンスをユーザインターフェイスに接続する方法
Xcodeでモデル、ビュー、コントローラを実装する方法
Xcodeでアプリケーションをビルドする方法とビルドエラーを修正する方法
[2008/02/20引用]Cocoaアプリケーションチュートリアル: 大変お疲れさまでした(http://developer.apple.com/jp/documentation/Cocoa/Conceptual/ObjCTutorial/07BuildingRunning/chapter_7_section_5.html)
大変お疲れさまでしたと言われては仕方あるまい。
今日はここまで。

・ 今日の収穫

objective-c
  • @property(readwrite)の存在を知る
Interface Builder
  • Optionキーを押したまま要素の上にポインタをおくと、選択中の要素と、ポインタの下の要素の相対的な距離がわかる
  • 矢印キーで要素の細かい移動ができる
  • 要素の整列ができる
  • タブでの移動先の指定はnextKeyView
  • WindowからinitialFirstResponderでつなげると、最初に選択された状態になる

一行で書こうとするから訳の分からない日本語になるのよね。

しかしまぁ、今まで直感で使い続けていたのが馬鹿みたいだ、いや、馬鹿だ。
反省とともに続きをしよう、明日。

[Cocoa]Cocoa入門のための日本語文章

Apple Developer Documentation
Cocoaアプリケーションチュートリアル: Cocoaアプリケーションチュートリアルの紹介
Cocoa入門ならこの辺いくつかをやるだけで十分な気がしてきた...。
あとはリファレンスの読み方かな。
すこし調べただけじゃNSOutlineViewの使い方が解らない。
英語は嫌だなぁ。
いや、そもそもobjective-cが解らんのが一番の問題なのだけれどね。
勉強するか。

2008/02/18

2008/02/15

2008/02/05

2007-06-09 - techlog

メモ

prefork, worker, eventの違い。
その他参考の欄も見ておかねばね。

[Memo]USBメモリの書き換え限界寿命が来ると何が起きるのか

・ Memo

USBメモリの書き換え限界寿命が来ると何が起きるのか、実際に寿命が来たケースをレポート - GIGAZINE 経由
書込みはブロックでしか行えませんし、ファイルシステム自体の書込み制御もクラスターというI/Oの最低単位で行いますので、通常1回のファイル操作で最も負荷の掛かるROOTディレクトリは数回の書込みが発生する可能性を持っています。 例えば1日に20ファイルを作ったり、変更したりした場合、100日〜1000日しかもたない事になります。また、例え製造試験を通ったからと言え、正常だった箇所の劣化率は製造上のばらつきから全く同一ではありません。 場合によってはあっと言う間に劣化する事もありますので、バックアップは不可欠です。
[2008/02/05引用]メモリー雑学 : データ復旧のオントラック
変更20で最短100日ですか。
バックアップは大事だよということでひとつ。

2008/02/04

[Memo]ソフトウェア開発における初心者

Matzにっき(2008-02-04)

[Memo]開発環境としてのMac OS X Leopard

開発環境としてのMac OS X Leopard - 古橋貞之の日記 pbcopy/pbpasteとscreencaptureの項目はやっておこうかね。 ~/.zshrcに追加
alias pbcopy="nkf -w | pbcopy" export __CF_USER_TEXT_ENCODING=0x1F6:0x08000100:14
追記 command+shift+4を押した後にスペースキーでウィンドウ単位のキャプチャができるのね。

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]);
最初は無駄にクラス作っていたけれど削りに削って最終的にこんな感じになりました。
ほかのお題もやってみようかしら?