PHPには'shuffle'というその名の通り配列をシャッフルしてくれる関数がある。
例えば以下のようなコードがあったとしたら

<?php
$numbers = range(1, 5);
shuffle($numbers);
print_r($numbers);
?>

こんな感じでシャッフルされる

Array
(
    [0] => 2
    [1] => 4
    [2] => 5
    [3] => 3
    [4] => 1
)

たまにこういった処理が必要になるが他の言語ではどうすればいいか?

どの言語でも

10 * 3

という式を評価するとたいていは

30

という数値が得られる。
単純に10という数値に3を掛けた結果だ。
この'*'という演算子はRubyやPythonでは文字列に対しても適用できる。
例えば

MacPortsのMySQLとOSに標準で入っているPythonの組み合わせでライブラリ"MySQL-python"をインストールしようとしたがうまくいかなかった。
解凍したMySQL-python-1.2.2ディレクトリの中にある"setup_posix.py"というファイルの中に"mysql_config.path"という変数を設定している場所があるがここが

mysql_config.path = "mysql_config"

こんな感じになってる。
たぶん、コマンドのサーチパスから"mysql_config"を探そうとするが見つからないのでエラーになってしまうという事だろう。

データをひとまとめにして扱いたい時、配列やハッシュというデータ型を使う事が出来る。
配列は0から始まる数値で値を管理するため狙った値にアクセスするにはどんな順序で並んでいるかを把握していなければならない。
ハッシュはキーと呼ばれる(主に文字列)もので値を管理するため必ずしもその値の場所を覚えておく必要がない。というよりは逆に順番では覚えられない。
いわばデータにラベルが付いてるような物だ。
例えばaというハッシュがあれば

プログラムを書いてるとき実験用のデータとして人物名が何人分か欲しいとする。
こういった事は結構あるだろう。
この場合一人一人それらしい名前を考えるのも意外と面倒だったりする。
ましてや数十人分欲しいとなると名前を考えるだけで一苦労だ。
こんなとき、例えば3人分の名字、3人分の名前をすべて組み合わせて9人分の架空人物名を作る事が出来る。

PHPには可変関数というものがあるが、これは変数に格納された文字列を関数名として展開してくれる機能だ。
これを使用すれば、後から文字列を使って関数を呼び出せる事になる。
例えば

Pythonの関数

beanz (2008年11月20日 01:16) | コメント(0) | トラックバック(0)

Pythonにも当然関数を定義したり定義した関数を呼び出したりする機能がある。
簡単な関数定義は以下のような感じだ

PerlやPHPでは文字列を連結する時と数値を足す時では演算子が違うので例えば

$num1 = 10;
$num2 = 20;
print $num1 . $num2."\n";
print $num1 + $num2."\n";

上の例ではそれぞれ

1020
30

と出力される。
では数値と文字列に対してそれぞれの演算子を適用してみる。

いろいろなプログラム言語があるがたいていどの言語もファイルを開いて読み書きする操作(関数やメソッド)が用意されている。
openと付く関数名が多いようだ。例えばPerlの場合は

配列の内容を処理していく時だが、交互に処理内容を変えたいときがある。
例えば要素をリストタグで囲って表示するのに背景色を交互に変えたいといった時だ。
PHPではこの作業は多分頻繁に発生するだろう。

$names = array("Tatsunori", "Koji", "Greisinger", "Hisanori", "Nomaguchi");

上のような配列があったとして

<li class="foo">Tatsunori</li>
<li class="bar">Koji</li>
<li class="foo">Greisinger</li>
<li class="bar">Hisanori</li>
<li class="foo">Nomaguchi</li>

こんな出力を得たいといった時だ。
これを実現するのはそれほど難しくない。

Rubyの0は真になる

beanz (2008年11月17日 00:55) | コメント(0) | トラックバック(0)

前回のエントリーではPythonを使い、辞書の値でソートする方法について書いたが同様の事を他の言語でやりたい時はどうすればいいか?
例によって名前と年齢のハッシュがあったとする。例えばPerlの場合、

my %smap = ('nakai' => 36, 'kimura' => 35, 'katori' => 31, 'kusanagi' => 34, 'inagaki' => 34);

こんなデータがあり、これを年齢でソートしてみる。
ざっとこんな感じだ。

Pyhonで辞書のソート

beanz (2008年11月14日 13:52) | コメント(0) | トラックバック(0)

Pyhonでリストをソートしたい時はリストのsortメソッドか組み込みのsorted()関数がある。
どちらも特に難しくない。例えば

Pythonの名前空間

beanz (2008年11月13日 14:34) | コメント(0) | トラックバック(0)

Pythonの名前空間はちょっとした曲者だ。
モジュールのトップレベルでだけでプログラミングしているだけなら気にする事は無いが関数を定義してたりすると注意が必要だ。
Pythonで関数定義をした場合新たに関数内だけのスコープが作られる。いわゆるローカルスコープだ。
ただし、変数を参照するだけならばグローバルな変数にもアクセスできる。
例えば

Pythonの辞書型

beanz (2008年11月12日 01:01) | コメント(0) | トラックバック(0)

Pythonのデータに辞書という型があるが、これは他の言語でいうハッシュや連想配列と思って大丈夫だろう。
言語によって違いはあるが普通に

uniform_number = {
 'Hisanori': 21,
 'Tatsunori': 88,
 'Greisinger': 29,
 'Takuya': 0
 }

などとして

print uniform_number['Hisanori']

とすれば

21

と出力される。

Rubyを使って簡単なクラスを定義してみる。

class Person
    attr_reader :name
    def initialize(name)
        @name = name
    end
end

Pythonのreversed関数

beanz (2008年11月 3日 21:57) | コメント(0) | トラックバック(0)

以前のエントリーでも似たような事を書いたが、Pythonのリスト用のメソッドでsortやreverseがあるが、これらは自身を書き換えてしまういわゆる破壊的なメソッドだ。
そして意味のある値は返さないのでforループなどでは使えない。

書き方いろいろ

beanz (2008年11月 3日 01:18) | コメント(0) | トラックバック(0)

前回のエントリーでmap関数(mapメソッド,map演算子)について書いているが、書いているうちにいろいろと気づく事があった。

たとえばRubyのコード

#!/usr/bin/env ruby
Dir.chdir File.dirname(ENV["_"])
Dir.open(".") do |dir|
    fileAndSize = dir.select {|i| i =~ /^[^.]/}.map {|i| [i, FileTest.size(i)]}
    fileAndSize.each {|l| puts "#{l[0]} => #{l[1]}byte"}
end

では、まずEnumerableモジュールのselectメソッドを呼び出しリストの内容をふるいにかけた後mapメソッドで変換の作業をしている。
次の部分だ。

各言語のmap関数

beanz (2008年11月 2日 00:29) | コメント(1) | トラックバック(0)

リスト(配列等)の内容を元に別の内容に変換したリストが欲しい時map関数(メソッド)が使える。
まずは簡単なサンプルを

Pythonの変数はリファレンスという仕組みを使っている。
例えば

a = 1
b = 1

という代入文があったとしたら、これは変数aもbもおなじオブジェクト(数値の1)を参照しているという事だ。
なので

id(a)
id(b)

を実行してみるとそれぞれ同じIDが出力されるはずだ。
その後

b = 2

とすれば変数bはオブジェクト(数値の2)を参照することになり

id(a)
id(b)

を見てみるとここでは違ったIDが出力される。

では

a = 1
b = a

とした場合はどうだろうか?

普段Macを使って作業をしているが、ちょっとしたプログラムを書いてテストするときはよくデスクトップに保存してからターミナルを起動する。chmod +xとして該当のプログラムファイルをドラッグし、実行の属性を与え、もう一度そのファイルをドラッグして実行。
テストプログラムを書く時はこれの繰り返しだ。

Pythonのsortメソッド

beanz (2008年10月28日 01:27) | コメント(0) | トラックバック(0)

Rubyだと以下のような文が書ける

list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/
list2 = list1.sort

これはlist1の配列を並べ替えた新規の配列list2を作成している。
list1は元の順番のまま何の変更も加えられていない。
さらに以下のような文も書ける

list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/
list2 = list1.sort!

上の文との違いはsortの後ろに感嘆符(!)が付いているかいないかだけだが感嘆符がついた方はlist1自身を並べ替えてしまう。
つまりはlist1とlist2は同じ順番で並んだ全く同じ配列となる。

プログラミングを学び始めた頃は当然分からないことだらけで多分本を読んでも理解できない事の方が圧倒的に多い。
"式が値を返す"というのも最初は何の事だかいまいちピンとこなかった。
"関数が値を返す"というのは何となく分かりやすい、関数定義の中で

sub {
    my $name = shift;
    return $name;
}

とすれば名前が返ってくるんだなと。

pythonのforループはいわゆるCのfor(for (int i; i < count; i++))なんかと違ってJavascriptのfor inループの様な書き方をする。
通常は多分問題になる事は無いがこのループだといわゆるindexを参照できない。要は今何番目の要素の処理をしているのかが分からない。
なので例えばPHPなんかで

Pythonのpop()

beanz (2008年10月21日 17:05) | コメント(0) | トラックバック(0)

Pythonでプログラミングをしていると他の言語に比べてなんか足りないなと思うことがしばしばある。

他のLL言語には配列を操作する関数(メソッド)でshiftというのがある。
配列の最初の要素を削除してその要素を返すという機能だがこれがPythonには無い。
Perlであればshift(@list)、PHPであればarray_shift($list)、Rubyならarray.shiftとそれぞれそろっているから当然Pythonにも、と思ったのだがいくら探しても見つからなかった。

ただ今日、ふと本を読んでいたら代替のメソッドが見つかった。list.pop()だ。このメソッドも同様に配列を操作するためのものだがshiftと違って配列の最後の要素を返すものだ。

それぞれPerlやPHPにも有るがPythonのそれは引数にインデックスを指定する事でどの要素を返すかを指定できるようになっている。
引数無しだと最後の要素、0を指定すると最初の要素を返す。
要はlist.pop(0)で他の言語のshiftの代わりになるという事だ。
なるほどこれで関数名を1つ節約できる訳だ。
たぶんpythonistaにしてみたら超基本的な事なんだろうなあ。
勉強になりました。