月別アーカイブ: 2006年6月

村上氏逮捕

村上ファンドの村上さんが逮捕されて、あっちゃこっちゃで大騒ぎ。僕は個人的には全然興味ないんだけど、どうもテレビで見かける人々の反応には首をかしげてしまうことも。星野仙一監督が天罰発言を以前にしてた関係で、当時頭にきていただろう大阪のおばちゃんが「天罰や〜」と発言していたけど、これで本当に天罰になるのだろうか。我々が信じられないほどのお金持ちだろうし、インサイダー取引で何年かブタ箱入ることになったって、ちょっと我慢すればまた悠々自適の生活が待っているわけなんだし、そんな何年かを「天罰」なんて呼べるかな。今回の逮捕で溜飲を下したんだろうけど、彼に天罰下って欲しいって本気で思ってるんだったら「まだ足りないんじゃない」というのが僕の意見です。ちなみに僕は、村上氏に対して特に何も思っていない。彼も堀江氏と同じく、歯に衣着せない「成功者」だっただけだ。その内のどちらか一つの要素でも欠ければ、このように叩かれることもなかったであろう。

それにしてもたまたまテレビ付けてたら見ちゃったんだけど、昨日のアッコにおまかせ。なんだあの身体検査の下劣なイメージ図(まあ実際ああやるんだろうけど)。犯罪者だったらどんな風にさらしても構わないってことかい。ここの番組のディレクターかなんかは相当村上氏に煮え切らない想いでも持っていたんだろうか。子供はいないけど、子供がいたら正直見せたくないね、あの番組。昼間から止めて欲しいし、文句があったらストレートに「村上ざまぁみろ!」とか言って欲しいんだけどな。

それと日本人はもう少し「上場」の意味について考えた方がいいと思う。

ヘタなことは書き込めないってか

The NewYork Times : For Some, Online Persona Undermines a Résumé

When a small consulting company in Chicago was looking to hire a summer intern this month, the company’s president went online to check on a promising candidate who had just graduated from the University of Illinois.

At Facebook, a popular social networking site, the executive found the candidate’s Web page with this description of his interests: “smokin’ blunts” (cigars hollowed out and stuffed with marijuana), shooting people and obsessive sex, all described in vivid slang.

It did not matter that the student was clearly posturing. He was done.

企業が採用判断の一環としてSNSを見たり、志願者をWEBでチェックしているって話。そうすると志願者の思わぬ人柄が見えてくるということだろう。実名が主なアメリカだけに、ヘタなことは書き込めないという話ですね。なかなか興味深い記事です。

SNSやブログは、書きようによっては採用に大きくプラスの影響を与えることも出来ると思う。例えばそれなりに有名な技術系のブログを書いていれば、採用活動のときに担当者に「ここ見てください」とアピールすることも出来るだろうし、既に相手が知っていたとすれば話は早い。

いずれにせよ、あまり見られて困るようなことは書くべきではないね。

あるファイル内の単語数を調べる

初めてのPython 第2版

以前書いた「文章内の単語数を調べる関数」も、文字列のsplit関数とfilter関数の組み合わせで簡単に書き直せた。ちなみにsplit関数とは、文字列を指定した区切り文字で分割し、それぞれをリストの要素として返す関数である。今回は与えられた文字列を空白で分割するようにしている。

def countwords(s):
return len(filter((lambda c: c != ''),s.split(' ')))

これを応用して、今度はあるファイル内にある単語数を調べる関数を作成してみる。引数はファイルパス。

def countwords(s):
return len(filter((lambda c: c != '' and c != '\n'),s.split(' ')))
def countwordsinfile(file):
L = map(countwords,open(file).readlines())
return reduce((lambda x,y: x + y),L)

countwords関数を少しいじったのは、例えば改行だけの行があったときに1文字と認識されてしまう現象が起きたため。open(file).readlines()はファイル内の全ての行をリストの形で返してくれる便利な関数。map関数でそれぞれに行に対してcountwords関数で単語数を調べ、最後にreduce関数で各要素を足していく。

読むファイルは以下。改行コードとEOFは表現のしようがなかったので、とりあえず手書きで加えておきました。

news.txt

The declaration came after the deaths of at least seven Palestinian civilians on a Gaza beach\n
from an apparently errant Israeli artillery shell.\n
\n
Delphi expanded its buyout deal to include all U.A.W. members, signaling a stepped-up effort\n
to avoid a strike.\n
[EOF]

実行結果。

>>> countwordsinfile('news.txt')
41

一つの単語がcondi- tion と二行に亘る場合などに対応できてませんが、とりあえず出来ましたね。

シーザー暗号でも作ってみる

う、時間とネタがないので、今日はシーザー暗号でも作ってみます。暗号化する関数encryptcaesarと、復号する関数decryptcaesarを以下のように定義する。

caesar.py

def encryptcaesar(str,shift=1):
L = list(str)
return ''.join(map(chr,map((lambda s: ord(s) + shift),L)))
def decryptcaesar(str,shift=1):
return encryptcaesar(str,shift*-1)

文字列をリストに直すlist関数と、ある文字のASCIIコードを返すord関数、そしてmap関数を用いると一行で書けてしまいます。

実行結果。

>>> str = encryptcaesar('I love my wife!')
>>> str
'J!mpwf!nz!xjgf"'
>>> decryptcaesar(str)
'I love my wife!'
>>> str = encryptcaesar('Python is great',3)
>>> str
'S|wkrq#lv#juhdw'
>>> decryptcaesar(str,3)
'Python is great'
>>> 

いまどきこんなの暗号とは言えないけど、まあ基本ってことで。

reduce関数でニュートン法

楽しくなってきたんで続けます。

ゲームプログラムめも日記:平方根

会社のプログラム見ていたら、平方根を求める関数があったので、
Pythonで書いてみました。

(中略)

reduceを使えば、2行で書けることが判明しました…!

なんと便利な。早速真似して僕も実践。Newton法を用いてある数の平方根を求める関数mysqrtを作成する。繰り返しの回数が精度を決めるが、とりあえず10回を初期値としておく。

mysqrt.py

from __future__ import division
def mysqrt(x,loop=10):
return reduce((lambda a,x: a - (a**2 - x) / (2 * a)),[x]*loop)

実行結果。

>>> mysqrt(2)
1.4142135623730951
>>> mysqrt(3)
1.7320508075688772
>>> mysqrt(5)
2.2360679774997898
>>> mysqrt(10)
3.1622776601683791
>>> mysqrt(625)
25.0
>>> mysqrt(1024)
32.000000000000803

from __future__ import divisionをきちんと書かないと、割り算の結果が全て切り捨てられてしまうのでご注意を。今気付いたけど、これだと繰り返し9回が初期値か。まあいいや。

何年ぶりかに手書きでもニュートン法を計算してみましたが、プログラムのありがたさがよく分かります。

ちなみに以下のようにmathモジュールをインポートしても、sqrt関数が使えないんだけど何でなんだろう。マニュアル見てもこれで良さそうなのだが。

>>> import math
>>> sqrt(10)
Traceback (most recent call last):
File "<pyshell#56>", line 1, in -toplevel-
sqrt(10)
NameError: name 'sqrt' is not defined

追記:

ちなみに同じ関数をループ使って書くとこんな感じになった。やっぱりスマートじゃないな。

def mysqrt(x):
a = x
cnt = 0
while cnt < 10:
a = a - (a**2 - x) / (2 * a)
cnt += 1
return a

reduce関数で階乗計算をしてみる

関数で遊んでばっかりだけど、これが最後かな。まだリスト内包表記もあるけど。
reduce関数は与えられた式とリストに対して、計算の結果と次の値をまた計算し、その結果と次の値をまた計算し…というのを繰り返してくれる関数。

前に階乗計算を

def factorial(x):
if x == 1:
return 1
else:
return x * factorial(x - 1)

と書いたけど、reduce関数を使えばわずか、

def factorial(x):
return reduce((lambda x,y: x * y),range(1,x+1))

で済んじゃう。速度的なメリットもあるというし、分かりづらいコードにならないのであれば、こっちを使いたくなるのがプログラマ根性ってやつかな。

実行結果は以下。

>>> factorial(1)
1
>>> factorial(2)
2
>>> factorial(3)
6
>>> map(factorial,[4,5,6,10])
[24, 120, 720, 3628800]

人生計画が足し算な人、逆算な人

LIGAYA REPORT:二十代や三十代の「使い方」

上の文章は少し大袈裟だとは思いますが、インキュベーション事業(起業支援事業)を行っている当社としても、二十代や三十代の「使い方」は非常に大切であると考えています。

「二十代」でググッたら引っかかった文章。どうやら大前研一氏の即戦力の磨き方 (PHPビジネス新書)に対する書評らしい。以下の文章が印象的だったのでちょっと引用。

「ゼネラリスト」と「スペシャリスト」の差は何かというと、人生計画を「足し算」で考えているか、「逆算」で考えているか、という違いが大きいと思います。
「スペシャリスト」は、人生を逆算して考えています。35歳までに独立すると決め、そのためには今は何をすべきかを常に考えています。そして実行に移しています。
「ゼネラリスト」は、人生を足し算で考えていますので、このまま行けば35歳で年収800万円かな? というような空想しか描けません。行動力もありません。

例えば三十台前半で「何がしかのスペシャリスト」になる為に、まず二十代は様々なことに真剣に取り組んでみる。二十代を「まずはやってみる」時期と規定しよう、というのが一応当ブログのテーマ。物理現象で例えてみると、二十代は「振幅」のすごく大きなグラフだけど、だんだんその振幅が小さくなってきて、三十台半ばくらいから一つの軸に収束していくという感じかな。この「振幅を最初は大きくしておこう」っていうのは結構ポイントだと思っている。引用した逆算理論は非常に正しいと思っているのだが、中にははじめから逆算しすぎていきなり振幅の小さなグラフになろうとする若者がいるのも事実。まずは色々と本気出して取り組んでみた方が、より自分がどこに収束すべきか見えてくるだろう、と僕は考えます。

ちなみに日本では「スペシャリスト」と言っても「社内のある業務のスペシャリスト」に向かってしまう人が多く、それはそれで重宝がられる人間なんだけど、ちょっと若人が描いているイメージとは違いますよね。これも振幅が大きな段階では経験しておいても悪くないだろうけど。

しかし話は逸れるが、大前氏は良くも悪くも変わらない人である。彼の著作を何冊か読めば気付くことだが、世間というか日本のビジネスパーソンに対してひたすら同じ事を言い続けている。氏のメッセージはビジネスパーソンであればすべからく吸収しておくべきだと思うが、内容もあまり変わらないし、僕は何冊か読んだ時点で一度氏の書籍からは距離を置いている。そろそろまた一冊読んでみようかな、と思ったりもするのだが、即戦力の磨き方 (PHPビジネス新書)はそれに適した内容だろうか。

filter関数で遊ぶ

Foundations of Python Network Programming

filter関数も非常に便利な関数だ。前にやったIPアドレス取得のプログラムを少し改造した関数を作り、IPアドレスをある個数以上持つホスト名を選び出すフィルタを作ってみよう。

以下のような関数countipaddrを作る。返り値はIPアドレスの個数。

import socket
def countipaddr(hostname):
try:
return len(socket.getaddrinfo(hostname,None))
except socket.gaierror:
return 0

実行結果。

>>> filter((lambda s:countipaddr(s) >= 3),['www.yahoo.co.jp','www.gogle.com','www.hatena.ne.jp','www.yahoe.co.jp','mixi.jp'])
['www.yahoo.co.jp', 'www.gogle.com', 'mixi.jp']
>>> filter((lambda s:countipaddr(s) >= 3),['www.yahoo.com','www.msn.com','www.cnet.com','www.amazon.com','www.goo.co.jp'])
['www.yahoo.com']

AmazonなんかはIPアドレスたくさん持ってないんですね(調べたら一つだった)。逆にmixiはたくさん持ってるな。

filter関数を使えば、前回やったエラトスセネスの篩のアルゴリズムもより簡素の形になるだろう。今度やってみるか。

IPアドレス取得プログラム

Foundations of Python Network Programming
前にJavaでも作ったけど、今度はPythonでIPアドレスの取得プログラムを作ってみる。要はDNSへの問い合わせ。標準入力から受け取ったホスト名称に該当するIPアドレスを返すようにする。

せっかくネットワークの本を買ったんだから、こういうのも作らないと。

ipaddrget.py

import socket
while(1):
name = raw_input()
if name == '':
break
try:
result = socket.getaddrinfo(name,None)
for item in result:
print item[4]
except socket.gaierror:
print "DNS coundn't find %s" % (name)

実行結果。

www.google.com
('66.102.7.147', 0)
('66.102.7.99', 0)
('66.102.7.104', 0)
www.yahoo.com
('66.94.230.48', 0)
('66.94.230.49', 0)
('66.94.230.50', 0)
('66.94.230.75', 0)
('66.94.230.32', 0)
('66.94.230.42', 0)
('66.94.230.44', 0)
('66.94.230.46', 0)
www.hatena.co.jp
('202.181.97.45', 0)
www.yahoe.co.jp
DNS coundn't find www.yahoe.co.jp

getaddrinfoはリストの形で結果を返す関数で、リストの四番目の要素がIPアドレスとポート番号のタプル。今回は実行時にポートを指定していないから0返って来ている模様。ホスト名称が見つからない場合には、socket.gaierrorが返されるから、それに関する処理も入れてみた。

まだ分からないことも多いんで、もう少し突っ込んで学ぶ必要あるな。

エラトスセネスの篩

初等整数論には題材が豊富だ。今度はエラトスセネスの篩をやってみよう。以下に引数を指定すると、2からその引数までの間にある素数を表示する関数、eratosthenesを作成する。

eratosthenes.py

def deletemultiples(pn,L):
for i in L:
if i != 0 and i != pn:
if i % pn == 0:
L[i-2] = 0
return L
def eratosthenes(n):
L = range(2,n+1)
for i in L:
if i != 0:
L = deletemultiples(i,L)
for i in L:
if i != 0:
print i,

実行結果。

>>> eratosthenes(10)
2 3 5 7
>>> eratosthenes(100)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
>>> eratosthenes(1000)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997

アルゴリズムはもっとやりようあるけど一応出来た。forループに使っているリストを、forループの中でいじれるのか心配だったけど、どうやらやってもいいみたい。助かった。