はてなキーワード: Pythonとは
Python2.5のときは、新スタイルクラスのインスタンスは辞書のキーとして必ず使用できたけど、Python 2.6ではそういうわけじゃなくなってるぽい。という話。
class TestClass(object): def __init__(self, i_name): self._name = i_name def __eq__(self, i_other): if not isinstance(i_other, TestClass): return False return self._name == i_other._name print 'object.__hash__ = ' + str(object.__hash__) print 'TestClass.__hash__ = ' +str(TestClass.__hash__)
上記のようなコードを実行したら、Python 2.5とPython 2.6で結果が違いました。
Python 2.5の場合の結果。
object.__hash__ = <slot wrapper '__hash__' of 'object' objects> TestClass.__hash__ = <slot wrapper '__hash__' of 'object' objects>
Python 2.6の場合の結果。
object.__hash__ = <slot wrapper '__hash__' of 'object' objects> TestClass.__hash__ = None
Python 2.6だと、objectクラスを継承すると、__hash__がNoneになっちゃってる。このままだと辞書のキーとして使えないね。objectを継承したクラスで__hash__を実装すれば、大丈夫みたい。
「ハッシュ値の計算方法 (2)」というページも参考になりそう。
Visual Studio 2005しかインストールしてない場合、Python 2.5だとdistutilsが正しく動かないっぽいので、どうにかしたいYO!
distutilsでVisual Studioを使うときのコンパイル環境は、sysモジュールのversionプロパティを参照して環境を選択をしているようです。Pythonのインタプリタを起動して、以下のような命令を実行してみると、sys.versionプロパティが確認できます。
import sys;print sys.version
Python 2.5.2だと、以下のようになっています。Visual Studio 2003の環境が使われるようです。
2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)]
Python 2.6a1だと、以下のようになっています。Visual Studio 2008の環境が使われるようです。
2.6a1 (r26a1:61155, Mar 1 2008, 12:11:56) [MSC v.1500 32 bit (Intel)]
以上から察するに、Python 2.5.2とPython 2.6のどちらでも、Visual Studio 2005の環境が選択されることはないっぽいです。うーん、困った!
「Python 2.6とVisual Studio 2008をインストールしよう!」というのを真っ先に思いつきましたが、あんまり環境を変えたくないんだよなー。というわけで、環境の変更を最低限に抑えてどうにかしてみました。簡単に言うと、distutilsだけの置き換えをしました。
Python 2.6の公式ダウンロードページから、Windows版のインストーラーをダウンロードして、適当な場所にインストールしてください。
"Python-2.5.2/Lib/distutils"を別の場所に移動し、"Python-2.6a1/Lib/distutils"を"Python-2.5.2/Lib"以下にコピーしてください。以降はPython 2.6は必要ないので、アンインストールして構いません。
上記の2点の変更を行います。distutilsディレクトリに、以下のパッチをあててください。
Index: msvccompiler.py =================================================================== --- msvccompiler.py +++ msvccompiler.py @@ -170,6 +170,7 @@ if majorVersion == 6: minorVersion = 0 if majorVersion >= 6: + return 8 return majorVersion + minorVersion # else we don't know what version of the compiler this is return None Index: msvc9compiler.py =================================================================== --- msvc9compiler.py +++ msvc9compiler.py @@ -128,7 +128,7 @@ "sdkinstallrootv2.0") else: raise KeyError("sdkinstallrootv2.0") - except KeyError as exc: # + except KeyError, exc: # raise DistutilsPlatformError( """Python was built with Visual Studio 2008; extensions must be built with a compiler than can generate compatible binaries. @@ -172,6 +172,7 @@ if majorVersion == 6: minorVersion = 0 if majorVersion >= 6: + return 8 return majorVersion + minorVersion # else we don't know what version of the compiler this is return None @@ -455,7 +456,7 @@ try: self.spawn([self.rc] + pp_opts + [output_opt] + [input_opt]) - except DistutilsExecError as msg: + except DistutilsExecError, msg: raise CompileError(msg) continue elif ext in self._mc_extensions: @@ -482,7 +483,7 @@ self.spawn([self.rc] + ["/fo" + obj] + [rc_file]) - except DistutilsExecError as msg: + except DistutilsExecError, msg: raise CompileError(msg) continue else: @@ -495,7 +496,7 @@ self.spawn([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) - except DistutilsExecError as msg: + except DistutilsExecError, msg: raise CompileError(msg) return objects @@ -520,7 +521,7 @@ pass # XXX what goes here? try: self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: + except DistutilsExecError, msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) @@ -598,7 +599,7 @@ self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: + except DistutilsExecError, msg: raise LinkError(msg) else:
python.exeと同じディレクトリに、以下のXMLを"python.exe.manifest"として保存してください。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly>
これで終わりです。
「やる夫がIT土方になったようです」を見てガクブルしている新人さんのために。
刺身にたんぽぽを載せる仕事と違って「量」ではなく「質」が求められるんだよ。
ひとつの要望に適った美味しいレシピにたどり着く為に、チームの皆が腕を振るって何度かの試行錯誤を経てひとつの結果にたどり着く。それはソフトウェア開発に似ている。
良いレシピを得るためには何が決め手だと思う?
それは投入した時間の「量」ではなく、その時間の「質」だ。専門性や経験の深さといった、知識や知恵が如何に効果的に働いたかという「質」が決め手となる。
素人が集まって1024人月の間 材料をこねくり回すより、知識と経験のあるチームが作って試して改良してのステップを何回か踏んだ方がより美味しいレシピに辿り着けそうじゃない?
だから、エンジニアは質を磨く事が大事なんだよ。
よく「体力勝負」やそれを揶揄して「土方」なんて言葉が舞っているけど、それが量を指す言葉なら違和感を感じて違うなぁと思えるのが普通のエンジニアだと思うよ。
もうひとつ量と質について。
ソフトウェア開発には「work 40 hours per week」というプラクティスがある。
人間の集中持続時間には限界があるし、質の良い知識労働を提供するには仕事以外の時間 - 大切な人と過ごしたり、感性に刺激を与えたり、興味の赴くままに技術で遊ぶ時間 - が必要だ。
だから長期的に見て週 40 時間を仕事に投入するのがちょうど効率がよいと言われている。
どう?納得出来そうじゃない?
勿論、残業もあるし40時間以上を求められる環境に放り込まれるかも知れない。
でも肝心なのは、自分がどうするかだと思うんだ。
「仕事をこなす」事を考えるに当たって、量でなく質のアプローチを取ろう。
例えば、8時間の密度を高める事を考える。
フレックスで働ける職場を選ぼう。自分でハンドルを握れる環境を選ぶ。そして不平を言い合う仲間に参加するのを止める。
生活のサイクルを整え、仕事中のインタラプトを減らし、如何に集中力を高めて8時間を過ごすか、それに心を砕こう。
努力目標のようなアバウトなものでなく、測定出来る問いかけを作ろう。
「今日は集中出来たか?」
を自分に投げかけてみよう。
「何故、そう言えるか?」
を考え、測定可能な指標を持とう。例えばアウトプットを数えたり、繰り返し使う幾つかの質問を作ったり。
毎日、そして1週間や1ヶ月ごとに振り返り、自分の「8時間の密度」を確認し改善していこう。
人事考課を四半期に一度くらい行うような会社なら振り返りのちょうど良いタイミングにもなるね。
個人で上手くいったのなら仲間に広げ、会社に広げ、周囲に影響を与える事を考えてみよう。
そうやって、プロフェッショナルを目指そう。
そう、「プロフェッショナル」だ。
今の世の中、プログラムなんて誰でも組めるんだよ。日曜日に趣味でコードを書いている人が普段仕事としてそれをこなす人より優秀だなんて今は普通にある話だ。
やる夫の話でも何の知識も無い人たちが放り込まれて動いてたよね。
でもそれを見てどう思った?
自分がお客さんだとして、この人たちに安心して仕事を任そうと思う?
尊敬出来る?
あの話を見てそんな気持ちが湧いてこないのは、それは彼らがプロではないからだと僕は思っている。
プロって何だろう?
先に書いたように、プログラミングは特別なスキルじゃないし、特別な道具もいらない。
そういったスキルの有無や道具が専門性を隔てる時代は色んな場所でとうに終わっている。
例えば、料理は昔からそうだったよね。誰でも作れる。今はレシピも道具も材料も普通に手に入るようになり、ますます「料理」は普通になった。
でも、プロは消えてないよね。それどころか、一般層が料理へのスキルや知識を蓄えるにつれ、ますますプロは存在感を増したように思える。
優れた一皿に出会ったとき、それで幸せな時間を過ごせたとき、また来たい、またこの時間を持ちたいと自然と思わない?それを提供してくれた人たちへの畏敬の念を感じない?
それがプロフェッショナルだと思うんだ。
もう少しソフトウェア業界に近い話をしよう。デザイン業界がそうだ。
紙媒体のデザインは DTP によって、またデザイン分野自体も web デザインが入ったり、コンピュータの普及によって道具の壁が無くなり、スキルの壁が下がり(ロットリングって何?)誰もがデザインに携われるプロアマ不可分の世界に晒された。
でも彼らはその中でデザインの本質を問い、プロフェッショナル性を追求し、デザイナがデザイナである故の理由を手に入れて質によって生き延びてきた。
生き延びるというと失礼だ。優れたデザイナの仕事は一目でそれと分かるくらい強烈に違うし、大きな価値をもたらしている。彼らは競争に晒されてより大きく進化したのだと思う。
スキルや道具が最早壁でなくなり誰もがこの業界に流れ込んでくる今だからこそ、僕らはプロフェッショナル性について考えなければならない。
そうする事で自分に関わる人たち - 仲間やお客さん、お客さんの向こうにある社会全体 - により大きな価値をもたらす事が出来る。
ちょうど魂のこもった一皿に出会ったときのように、鳥肌が立つくらいのデザインに触れたときのように、大きな価値ある仕事を生む事が出来るようになる。
プロフェッショナルになろう。
プロフェッショナルとはどういう事か、考え、学び、改善を重ね、楽しもう。
環境に不平を言うのではなく、自分の行動を変えよう(そのために環境選択の自由を行使したっていいんだよ)。
「エンジニアでよかった!」とか「コードで世界を変える!」とか、ちょっと探せば気概と希望に満ちた言葉も先輩達も直ぐに見つかるよ。
勉強会に顔を出せばそんな人たちと直に出会えるし、いっぱい刺激を貰えるよ。
オープンソースコミュニティや PHP、Perl、Python、Ruby といった Lightweight 言語のコミュニティがお勧めだよ。まずは weblog を辿ってみよう。楽しそうと思ったら試してみよう。
今はどこにいても「学び続ける」ことが問われて行く時代だ。
コードを書く楽しさだけでなく、学び続けたり考えるために必要なスキルが最も身に付く職業だ。
この春からエンジニアになるあなたはとても素敵なポジションにいると思う。
エンジニア職でプロになろうと頑張る中で手に入るものはとても多いよ。凄い事じゃない?
今の世の中は楽しんだもの勝ち。
「楽する」の楽しいではなく、夢中にさせちゃう「楽しさ」ね。
だから悲観的な話や自嘲の声でお茶を濁すのは適当なところで止めて、別の方向を追ってみようよ。
楽しさが見えてくるハズだよ。
どこかで会う機会があれば僕もそれを伝えたいと思うし、何より日々の行動の中で示して行きたいと思っている。
あなたの会社に幸せそうに仕事をして未来を語り「コード楽しいぜぃ」と語るお酒好きの先輩がいればそれは僕かも知れない。
楽しくするのもしないのも、すべて自分次第。せっかくなら、楽しい方を選んでみない?そっちに耳を傾け、そっちを一緒に考えようよ。
以上のような組み合わせで出くわした困ったことと、その解決策をメモしておきます。
Python was built with Visual Studio 2003;
extensions must be built with a compiler than can generate compatible binaries.
Visual Studio 2003 was not found on this system. If you have Cygwin installed,
you can try compiling with MingW32, by passing "-c mingw32" to setup.py.
setup.pyに.iファイルとか.cppファイルを記述して実行すると、こんな感じのエラーメッセージが表示されました。うーん、困った!
http://labs.cybozu.co.jp/blog/mitsunari/2007/08/vc2005boostpython.html
上記のページを参考にして、"%Pythonをインストールしたフォルダ%/Lib/distutils/msvcompiler.py"を以下のように修正してみたら解決できました。ありがとうありがとう!
--- msvccompiler.py 2007-04-04 17:17:12.000000000 +0900 +++ @@ -126,7 +126,7 @@ self.set_macro("FrameworkDir", net, "installroot") try: if version > 7.0: - self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") + self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv2.0") else: self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") except KeyError, exc: # @@ -252,7 +252,10 @@ def initialize(self): self.__paths = [] - if os.environ.has_key("DISTUTILS_USE_SDK") and os.environ.has_key("MSSdk") and self.find_exe("cl.exe"): + if self.__version >= 7.1 or ( + os.environ.has_key("DISTUTILS_USE_SDK") and + os.environ.has_key("MSSdk") and + self.find_exe("cl.exe")): # Assume that the SDK set up everything alright; don't try to be # smarter self.cc = "cl.exe" @@ -288,10 +291,16 @@ self.preprocess_options = None if self.__arch == "Intel": - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', - '/Z7', '/D_DEBUG'] + if self.__version >= 7.1: + self.compile_options = [ + '/nologo', '/Ox', '/MD', '/W3', '/EHsc', '/DNDEBUG'] + self.compile_options_debug = [ + '/nologo', '/Od', '/MDd', '/W3', '/EHsc', '/Z7', '/D_DEBUG'] + else: + self.compile_options = [ + '/nologo', '/Ox', '/MD', '/W3', '/GX', '/DNDEBUG'] + self.compile_options_debug = [ + '/nologo', '/Od', '/MDd', '/W3', '/GX', '/Z7', '/D_DEBUG'] else: # Win64
setup.pyを実行するとcl.exeが見つからないみたいなエラーが表示されました。これは、アレだ。「パス通せ!」ということですね。bashを起動するときのバッチファイル(たぶん"cygwin.bat"とか)で、以下のような行を入れてやれば解決しました。
call "%VS80COMNTOOLS%vsvars32.bat"
d:\python25\include\pyconfig.h(189) : fatal error C1083: include ファイルを開けません。'basetsd.h': No such file or directory
setup.pyを実行すると、上のようなエラーが表示されました。
http://d.hatena.ne.jp/ousttrue/20070531/1180556273
上記のサイトを見るとインクルードパスが通っていない場所に"basetsd.h"があるのが原因なので、"cygwin.bat"にインクルードパスの設定をしておきました。
call "%VS80COMNTOOLS%vsvars32.bat" set INCLUDE=C:\Program Files\Microsoft Platform SDK\Include;%INCLUDE%
link: extra operand `/INCREMENTAL:NO'
詳しくは `link --help' を実行して下さい.
これは、cygwinのほうのlink.exeが実行されてるのが原因でした。スマートな解決策ではありませんが、cygwinのほうのlink.exeをリネームして解決。パスの設定順序とかでどうにかできるといいんだけど、どうすればいいんかな。
MSVCR80.dllが見つからなかったため、このアプリケーションを開始できませんでした。アプリケーションをインストールし直すとこの問題は解決される場合があります。
SWIGが生成した.pyファイルをimportしたら、こんな感じのエラーダイアログが表示されたよ。うーん、困った!
http://d.hatena.ne.jp/moriyoshi/20070525
上記のページを参考にして、"%Pythonをインストールしたフォルダ%/python.exe.manifest"として以下のようなファイルを新しく作ったら、解決できました。ありがとうありがとう!
あとこれ、bashから実行したらエラーダイアログが表示されず、importするモジュールが見つからないみたいなエラーメッセージが出力されるだけだったよ。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly>
あるプログラミング言語を取り上げて、ここが優れているとかここが劣っているとか言ってる人がいるが、ほんとにくだらない。というのは、時代時代の要望があって言語仕様やプログラミング作法が決定されているはずだから。
たとえば、C言語とかで勝手に構造体の値を変える馬鹿がいて「バグが出てうぜー!」という時代があって、Javaとかのアクセッサメソッドな流れになり、んで、それが逆にウザくなってきたんでPythonの「勝手にフィールドいじるやつなんていねーだろw」という設計になったはず。
後発の言語はそれまでにあった言語になんらかの不満があったからこそ出てきたので、その点を取り上げて、ある言語がある言語より優れているとかいうのは馬鹿らしい。その点を誇っていいのは、言語設計者であり、ただその言語を使っているだけの人が偉そうに話しているのは意味がわからない。
自分が使ってる言語を誇りたいんだったら、さっさとプログラム書いてその言語の利用実績を増やしていくことのほうが、こんなことで議論しているよりよっぽど重要。
すっごい前の記事だけど。
http://anond.hatelabo.jp/20071110221822:title
ruby だとこんな感じじゃないでしょうか。
ruby には関数はないです(多分)。全部メソッド。で、関数に見えるのはトップレベルにある Kernel オブジェクトのメソッド。メソッドを変数にして実行したいなら、method オブジェクトを作るか、send メソッドを使ってメッセージパッシングすればいい。でも普通 proc を使うと思う。
def foldr(callee, lst, obj) if lst.empty? obj else callee.call(lst[0], foldr(callee, lst[1..-1], obj)) end end def apply(callee, obj) callee.call(obj) end def plus5(num) num + 5 end def times10(num) num * 10 end def divide2(num) num / 2 end foldr(method(:apply), [:plus5, :times10, :divide2].map{|m| method(m)}.reverse, 10) foldr(method(:apply), ([:plus5, :times10].map{|m| method(m)} + [lambda {|num| num / 2}]).reverse, 10)
同意だよ。
初心者が本当に注意しなければいけないのは、スクリプトの脆弱性よりもサーバーのセキュリティ。
PHPなら大抵どこのレンタルサーバーも利用可能なので殆ど問題がない。
なにがいいって現段階においてはPHPは非常に多くの人に使われている。
だからもし見当違いなことをやっていたら注意してくれる人がいっぱいいる。
そして何よりも大きいのはサーバー運営業者などがノウハウを吸収しているということ。
PHPでシステムコマンドなんかは大体止められているしRFIなんかの攻撃に対しても不正なファイルが埋め込まれたりすたら通報してくれるところもある。
現段階のRubyでそれができるだろうか?
大手のレンタルサーバーでさえまだ設定があやふや。
そのままじゃ動かなかったりしている。
じゃぁ自前サーバーならいけるのかというと、正直初心者には無理なんじゃないの?
Mongrelあたりを入れて、あれ、これメモリ漏れてねぇ?とかそういう心配をしたり、24時間監視できるわけがない。
まだ「いいえ」なんじゃないの?
Rubyをちゃんとできる人や教えられる人はまだ少なすぎる。
PHPをぐだぐだ言うひとはちゃんとできるひとなのかな?
どうなのよ?
まあ異論はあるかもしれないが。。
あと、こっちは、一般的に同意をえられるとおもうんだけど、
スクリプトが垂れ流す脆弱性よりもroot権限のっとられたマシンの方が怖くね?
んでもって、遥かに有害だよね。
そんなに言うならSQLインジェクションの穴のひとつでも見つけて報告してごらんよ。
SQLインジェクションなんて、DBに接続ができるようなレベルになれば最近のマニュアル本には当たり前に書いてあるじゃない。しかもこれは何もPHPに限った話しじゃないじゃない。
穴なんて時間の経過とともに増えるんだから、メンテナンスされてないサービスのほうが怖いわけですよ。
ローカル言語やサーバー使ってそのままになってしまうほうが最悪なんじゃないかな。
もし、素人がぐだぐだにつくったPHPサービスとかで問題があるとすれば・・・
・SQLインジェクションで中の情報が漏れる(そんなサービスに漏れて大切な情報登録するなよ)
・メール送信系でヘッダー偽装でスパムの踏み台にされる(これは意外と多いかもしれないね)
・クローラーが他のサーバに負荷をかけまくる
まあどれもPHP”だから”というわけでもないよね。
97年頃にはperlだって掲示板やアップローダーだって穴だらけだったじゃない。
coderedがでるまでiisで建ってたサーバーだって山ほどあった。
そのころにはSQLインジェクションに対応していないサイトは本当に簡単に見つけられた。
初心者は主流からはいるのがいろんな意味でみんなのためじゃない。
今の主流はphpということでいいんじゃないの?
PHPは発展期
RonRは成長期(すくなくともあと1年ぐらいは)
perlは爛熟期
あとは・・・
pythonからColdFusionのにおいしてない・・・?
あと、なんかLLってあったっけ?
curlがなんかいまさらだけど脚光をあびるような予感がしている。
ところでさ、
PHPを批判しているような人はPHP6の仕様とかちゃんとフォローしてるのかね?
そもそも何かを作り上げることができる人というのは非常に少ない希少種なのに、
そこに入ろうとする前途ある人達のモチベーションを使用言語がどうこうと、
挫こうとするのはなんか憤りを感じるよ。
Matzみたいな人がそれをやってどうするんだよとか、ちょっと思った。
http://www.rubyist.net/~matz/20080126.html
そもそもMatzのこの一文が事の発端。原文ではPHPこきおろしってわけではなく
「PHPまぁ、イケてるよ!だけど落し穴が多いから十分気をつけてほしい!」くらいのノリなのに。
http://mindblind.net/2008/01/24/attacking-php/
次。
http://blog.livedoor.jp/dankogai/archives/50993137.html
>>PHPなめんな」と「(Perl|Python|Ruby)をなめんな」の違い<<
まぁ、でもあらかた同意。
--
私的まとめ
PHPは確かに素敵な言語ではあるが、その裏には十分気をつけておかなければいけない事が沢山ある。
脆弱性の高いWEBアプリケーションが多く溢れる現状を見つめ、より多くの有用な情報を
また、WEB業界全体のこういった無駄な論争が多い事態の改善として、
僭越ながら私の意見を述べさせてもらうと
大物プログラマになるにはPHPを貶さなきゃいけないらしいぜ。
そうしないとあれな人達の支持を得られないからな。
PHPにはおかしなところがたくさんある。
自分から提案しないと無理だし、技術者が少なすぎて大きな案件は無理。
5、6人で回せるぐらいのをこまごまやっていくしかない。
新規ならまだしも、既存システムとの連携を考えるとRubyとかはまだ工数掛かりすぎ。
Pealなんか開発案件としては昔から極端に小さいものしかない。
はてなやmixiがperlなのはセルフビルドだからであって、
発注元がいたらperlという選択はなかったんじゃないかな。
Perlはちょっと違うと思うけど、RubyやPythonで人材の募集をかけると、
PHPで募集をかけるよりまっとうな人材が取りやすいのはある。
お嬢さん「Rubyって…。ただのオブジェクト指向のスクリプト言語じゃない。オブジェクト指向は『クラス』と『例外』でしょ。」
男「では、このPHP5もオブジェクト指向ですが…。これと、そのRuby…。果たして同じ物ですかい? お嬢さん。」
お嬢さん「…。同じじゃないわ…。」
ただ、RubyとかLLとかいう単語が大した脈絡もなく出てくると「ああ、またか」
って感じがして一気に興ざめるんだよね。
たとえばRubyの言語としての能力を語るときに、ルーツとして
SchemeやC++やPythonに遡及するのは必然的なんだけど、Rubyどっぷりの人は
いつも話題がRubyどまりでそこから進展することがない。ここまでステロタイプな
信者ではないにしても、事あるごとにRubyやらLLやら言い出す人は
「俺、ちゃんと流行に乗っかってますよ」的な言外のメッセージを出しすぎていて、
なのでJavaSciptの勉強がてら、ニコニコ動画関連のブックマークを見えなくするユーザースクリプトを作った。DOMがよくわからないので変なところがあるかも。スコープやノードリストなんかもよくわかってないので、無駄なところもあるかも。
以下ソース。
// ==UserScript== // @name NicoNico Eraser // @include http://b.hatena.ne.jp/entrylist* // @author Hatena Anonymous User MASUDA // @version 0.0.1 // ==/UserScript== (function(){ document.onload = main; function main(){ var entryList = filterByTagAndClass("div", "entry"); checkAndErase(entryList); } function filterByTagAndClass(tag, name){ var list = document.getElementsByTagName(tag); var newList = []; for(var i = 0; i < list.length; i++){ if(list[i].className == name){ newList.push(list[i]); } } return newList; } function checkAndErase(nodeList){ for(var i=0; i < nodeList.length; i++){ var elem = nodeList[i].getElementsByTagName("a")[0]; if(elem.href.substring(0,30) == "http://www.nicovideo.jp/watch/"){ nodeList[i].parentNode.removeChild(nodeList[i]); } } } })();
// ==UserScript== // @name NicoNico Eraser // @include http://b.hatena.ne.jp/entrylist* // @description version:0.0.1 // ==/UserScript== main(); function main(){ var entryList = filterByTagAndClass("div", "entry"); checkAndErase(entryList); } function filterByTagAndClass(tag, name){ var list = document.getElementsByTagName(tag); var newList = []; for(var i = 0; i < list.length; i++){ if(list[i].className == name){ newList.push(list[i]); } } return newList; } function checkAndErase(nodeList){ for(var i=0; i < nodeList.length; i++){ var elem = nodeList[i].getElementsByTagName("a")[0]; if(elem.href.substring(0,30) == "http://www.nicovideo.jp/watch/"){ nodeList[i].parentNode.removeChild(nodeList[i]); } } }
まぁ、これだと初音ミクやアイドルマスター以外の動画も見えなくなるんだけどね。
つーかJavaScriptだとPythonみたいなfor文使えないの?
perlで提供されてるサービスにphpユーザーはつかないのかもしれないね。
はてな界隈だとrubyは話題になっててもそれを扱う人をちゃんと評価できているとも見うけられないし。
いや、居るんだよ。php使いもruby使いもPython使いも。
だって増田にだってたまに湧くじゃない。
はてなダイアリーのユーザーだって、おーと思うようなruby使いとかもいるんだけどね、
でも発言権のあるユーザーにはなりえてない。
http://rails.drecom.jp/award2007
例えば、ここで受賞しているユーザーでaspブログサービスを利用しているユーザーの殆どがhatenaユーザー。
だけど、ここにでてくるような人達がホットエントリーに並ぶことはない。
あと1年ぐらいはdankogaiの天下だし、perl使いの天下なんじゃないかな。
でもperlの案件なんて最近(というかずっと昔しから)殆ど無いとおもうんだけどね…。
IT業界の12兆円の市場規模からしたらon webのコンシューマーなんてほんと微々たるもののはず、
でもそこだけしか注目が集まらない。
つまりはそういうことなんじゃないかな。
Pythonではなぜ string.len() でなく len() なのか?
string = MyString("Hello world")
class String def len self.length end end print "Ruby on Rails".len #=> 13
いくつか考えてみた
(問1)高階関数と再帰関数を必ず使って数値を要素とするリストの要素の総和を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
(問2)二つの引数をとり二つのうち大きいほうを返す関数と高階関数、再帰関数をつかって数値のリストの最大値を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
というのは簡単すぎるか?簡単すぎるなら
(問3)高階関数と再帰関数を必ず使ってある数値に5を足し、10かけて2で割った数を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
こっちの方がいいかな。でもトリッキーすぎる気もする。
一応問題を出したので、SchemeとPythonで自分で想定している答えを書いておいた。はてなではSchemeが人気のようなので、あまり知らなかったけど関数言語ではSchemeで書いておいた。Pythonで書くのはSchemeだけだとわかりにくいので、なにかスクリプト言語で書いておこうと思ったから。Rubyの方が人気なので、はじめはRubyで書こうと思ったけど挫折した。だれかRubyで書いてくれないかな・・・。コードオブジェクトってなによ。というか関数はオブジェクトなのに引数にできないの?なんで?(以下疑問と愚痴の嵐なので略)Perlは古株が多くてユーザー数も多そうだけど、・・・その・・・無理です・・・。あの言語仕様はやる気がしない。ぶっちゃけ理解できない。Pythonを知らないひとは多そうだけど、知らなくてもSchemeよりは感じは掴めると思うのでPythonでも書いておくことにした。
http://anond.hatelabo.jp/20071110215936
http://anond.hatelabo.jp/20071110220132
これで大部分のひとがこの問題に興味をもたなくて解答するひとがいなくても、興味を持ったひとは安心だね!
追記:
問3で次のは無しとしておきたい。
(define continuous-apply (lambda (lst obj) (cond ((null? lst) obj) (else (continuous-apply (cdr lst) ((car lst) obj)))))) (define plus5 (lambda (num) (+ num 5))) (define times10 (lambda (num) (* num 10))) (define divide2 (lambda (num) (/ num 2))) (define plus5-times10-divide2 (lambda (num) (continuous-apply (list plus5 times10 divide2) num))) (plus5-times10-divide2 2)
def continuousApply(lst, obj): if lst: return continuousApply(lst[1:], lst[0](obj)) else: return obj def plus5(num): return num + 5 def times10(num): return num * 10 def divide2(num): return num / 2 def plus5_times10_divide2(num): return continuousApply([plus5, times10, divide2], 2) plus5_times10_divide2(2)
(問1)
def foldl(func, obj, lst): if lst: return foldl(func, func(obj, lst[0]), lst[1:]) else: return obj def plus(num1, num2): return num1 + num2 def mySum(lst): return foldl(plus, lst[0], lst[1:])
・例
mySum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
(問2)
def foldl(func, obj, lst): if lst: return foldl(func, func(obj, lst[0]), lst[1:]) else: return obj def large(num1, num2): if num1 >= num2: return num1 else: return num2 def myMax(lst): return foldl(large, lst[0], lst[1:])
・例
myMax([34, 55, 77, 1, 2, 3, 4, 100, 98])
(問3)
def foldr(func, lst, obj): if lst: return func(lst[0], foldr(func, lst[1:], obj)) else: return obj def myApply(func, obj): return func(obj) def plus5(num): return num + 5 def times10(num): return num * 10 def divide2(num): return num / 2 def plus5_times10_divide2(num): funcList = [plus5, times10, divide2] funcList.reverse() return foldr(myApply, funcList, num)
・例
plus5_times10_divide2(5)
(参考)
def makeProceduce(lst): lst.reverse() return lambda num: foldr(myApply, lst, num)
・例
divide2_plus5_times10 = makeProceduce([divide2, plus5, times10]) divide2_plus5_times10(4)
あくまで自分でこう答えるという話。
(問1)
(define fold-left (lambda (func obj lst) (cond ((null? lst) obj) (else (fold-left func (func obj (car lst)) (cdr lst)))))) (define my-sum (lambda (lst) (fold-left + (car lst) (cdr lst))))
・例
(my-sum '(1 2 3 4 5 6 7 8 9 10))
(問2)
(define fold-left (lambda (func obj lst) (cond ((null? lst) obj) (else (fold-left func (func obj (car lst)) (cdr lst)))))) (define large (lambda (x y) (cond ((>= x y) x) (else y)))) (define my-max (lambda (lst) (fold-left large (car lst) (cdr lst))))
・例
(my-max '(58 90 1 2 4 3 100))
(問3)
(define fold-right (lambda (func lst obj) (cond ((null? lst) obj) (else (func (car lst) (fold-right func (cdr lst) obj)))))) (define my-apply (lambda (func obj) (func obj))) (define plus5 (lambda (num) (+ num 5))) (define times10 (lambda (num) (* num 10))) (define divide2 (lambda (num) (/ num 2))) (define plus5-times10-divide2 (lambda (num) (let ((lst (list plus5 times10 divide2))) (fold-right my-apply (reverse lst) num))))
・例
(plus5-times10-divide2 5)
全部畳み込み関数を使っているのは、はじめ使い道がないと思ってたのにかなり使い道があることがわかったので、それを示したかったから。あとmap関数あたりはほかの言語でもあるから、すぐに思いつくだろうし。
というか最後のやつは手続きを抽象化することでリストの形で扱えるようにしているから、関数プログラミングでは重要だと思う。関数プログラミングの肝は計算によって手続きを含めたすべて表すことができることだと思っている。その例だと思うんだけどね。例えばSchemeなら上記の答えを応用して、似たような「手続き」を生み出す関数を作ることができる。
(define make-proceduce (lambda (fst . rest) (let ((lst (cons fst rest))) (lambda (num) (fold-right my-apply (reverse lst) num)))))
これを使うと次のようにできる。
(define divide2-plus5-times10 (make-proceduce divide2 plus5 times10)) (divide2-plus5-times10 2) (define divide2-times10-plus5 (make-proceduce divide2 times10 plus5)) (divide2-times10-plus5 2)
関数合成がつかえるならそっちのほうが楽だけど、リストという形で「手続き」をつくり出していることがわかるだろうか?手続きをリストで操作できるのだ。こういうのが関数プログラミングの肝だと勝手に思っている。
こうやってくると型推論や多相型の重要性もわかると思うんだよ。上記のようなことはPythonでもできる。でも高階関数はつかいすぎるとわかりにくい。どっかにバグが入ってくるかもしれない。それを機械的に防ぐのが型推論。型という観点から型推論でおかしいところを探し出してくれる。それならC言語でもいいのではないかという人もいるかもしれない。だがC言語は融通が利かない。例えばapply関数にしても引数の型が数値なら数値、文字なら文字と決まっている必要がある。だから数値に向けにapply関数を作っても文字には使えない。こうした型のデメリットをなくす一方、そのメリットを享受するためにあるのが多相型。これによってapply関数やmap関数を一般的に作ることができ、型のメリットを享受しながらデメリットをなくすことができる。このように関数で手続きなんかを抽象化するときに型推論や多相型があると便利なのだ。
http://anond.hatelabo.jp/20071021143442
その理由は知らないが、なければ作ればいいじゃないか。
class MyString(str): def length(self): return len(self)
というクラスを作って
string = MyString("Hello world") print string.count("o"), string.length()
とRubyライクにやれば
2 11
とでるよ。え、リストもlist.length()が使いたいって?それも簡単。
class MyList(list): def length(self): return len(self) l = MyList([1, 2, 3, 4, 5, 6]) l.length()
6
きちんと他のメソッドも使えるよ。
l[1:]
[2, 3, 4, 5, 6]
l.reverse() l
[6, 5, 4, 3, 2, 1]
ね。簡単でしょ。
Pythonは仕組みが統一されているものが多いので、いじりやすいのですよ。上の例のやつは組み込みのクラスオブジェクトとユーザー定義のクラスオブジェクトがおおむね統一されているからこそ簡単にできる。他にも関数なんかもほかのオブジェクトと同じオブジェクトなので、高階関数なんてもの簡単に作ることができて関数プログラミングぽくできる。例えば今はなきapply関数なんかは
def myApply(func, *args): return func.__call__(*args)
と定義できる。実際に
def sumUpThree(num1, num2, num3): return num1 + num2 + num3
でためしてみる。
myApply(sumUpThree, 1, 2, 3)
結果はちゃんと
6
とでる。将来廃止されそうなmap関数も簡単に定義できる。他にも複数の引数をもつ関数の部分適用のようなことを行う関数も次のように簡単に定義できる。
def partial(func, *oldArgs): def wrapper(*newArgs): return func.__call__(*(oldArgs + newArgs)) return wrapper
sum_1 = partial(sumUpThree, 1) sum_1(2, 3)
6
sum_1_5 = partial(sum_1, 5) sum_1_5(9)
15
sum_10_20 = partial(sumUpThree, 10, 20) sum_10_20(30)
60
こういう風に高階関数が簡単にできるのは関数がオブジェクトで関数の実行とはメソッドの呼び出しにすぎないからだ。以上のように組み込みオブジェクトとユーザー定義オブジェクトの差があまりないことや関数もオブジェクトであることに見られるようにPythonは仕組みが統一されていてシンプルだ。そのためひとつのことがわかれば他のこともわかることが多いし、簡単にいじることもできる。
だからなければpythonをいじればいいと思うよ。
最後にラムダ式信者のためにpartialをラムダ式を使って書いておく。
def partial(func, *oldArgs): return lambda *newArgs:func.__call__(*(oldArgs + newArgs))
plone.jpへようこそ — plone.jp portal
Plone CMS: Open Source Content Management JZUG Wiki - PloneSiteInJapan
管理者でログイン
Site Setup
Language
Japanese
もっと知りたいPython:第2回 高機能WebフレームワークPlone|gihyo.jp
Ploneは,必要な機能をすべて備えたオールインワンのパッケージとして作られています。
データベースやWebサーバはPloneに内蔵されていますので,ApacheやMySQLなどを別途インストールする必要がありません。
Linuxなどのサーバを特別にたてる必要はなく,使っていないWindowsがインストールされたPCに,Ploneをインストールしておきます。
アカウントを作るとユーザ専用のスペースが割り当てられますので,文書やファイルをアップロードすれば情報共有ができます。
Plone3をリモートフォルダとして使う — Papasan's Home
Plone3のWindowsパッケージは数回のクリックでWebサーバー、FTPサーバー、データベースなど全てが構築できます。楽チン!!
Plone 3.0 を Windows 環境にインストール - tkykhgの日記
dev blog/CMS インストールガイド:Plone 2
Plone用Blogプロダクト,COREBlog2について — Blog on Plone ! : coreblog.org
PloneのSMTP設定にGMailを指定 - 清水川Web
Zope/Ploneサイトの構築 - 蓄積したTipsを公開するサイト(京大情報系技術職員)
【特選フリーソフト】安倍晋三氏の公式サイトが採用したオープンソースCMS Plone:ITpro
【コラム】Yet Another 仕事のツール (68) ZMIの日本語化とデザインのカスタマイズ | エンタープライズ | マイコミジャーナル
Amazon.co.jp: 開発のプロが教える標準Plone完全解説 (デベロッパー・ツール・シリーズ): 本: アンディ マッケイ,Andy McKay,クイープ,システムサポート
Amazon.co.jp: オープンソース徹底活用 Ploneによる簡単Webコンテンツ管理 (オープンソース徹底活用): 本: 寺田 学,伏見 潤,永井 孝,CMSコミュニケーションズ