Python 温泉 一日目♪

仕事おわってから合流

emacs の全画面表示

秋版から変更になった

;; Maximixe window size
(when (featurep 'carbon-emacs-package)
  (set-frame-parameter nil 'fullscreen 'fullboth))

なんか下があいちゃう><

iTerm が最近スバラシスギルらしい

軽くってサイコーって言われたので
入れてみる。
command + return で全画面に

ふつうのHaskell 写経

を少しだけ
Carbon Emacsruby-mode は入ってないくせに
haskell-mode は入ってる

Python 書いてないや

onelinerへの道


pit を oneliner にしてみよう!!


代入は lambda では出来ないので
とりあえずすべてグローバルに入れてみる。

global の使いかた

>>> g = globals()
>>> g.__setitem__('x',1)
>>> print x
1

おぉ!!

変数への代入はすべてグローバルへ

g = globals()
g.__setitem__("setitem", g.__setitem__)
.
.
.
        setitem('set_if_t', tempfile.NamedTemporaryFile())

テストを実行して壊れてない事を確認
テストの大事さを実感!!

複数処理を oneliner 化

複数の処理を一つの式にする

os.mkdir(DIRECTORY)
os.chmod(DIRECTORY, 0700)

を一つの処理にするためには両方実行されれば良い
Python の and は左辺を処理して True だったら右辺を実行するので

>>> 1+3 and 4+5
9

and で繋げれば一つの式に出来る

os.mkdir(DIRECTORY) and os.chmod(DIRECTORY, 0700)

これだと os.mkdir の評価結果が False だった時に右辺の処理が走らないので
左辺が必ず True と評価されるようにしなくてはいけない。

[os.mkdir(DIRECTORY)]

で括ると要素数 1 のリストになり、必ず True になる。
次の処理も and で繋げて動くように右辺も
で括る。

 [[os.mkdir(DIRECTORY)] and [os.chmod(DIRECTORY, 0700)]

if 文を oneliner 化

if not os.path.exists(Pit.DIRECTORY):
    [[os.mkdir(DIRECTORY)] and [os.chmod(DIRECTORY, 0700)]

これは三項演算子が出来たので楽

os.mkdir(DIRECTORY)] and [os.chmod(DIRECTORY, 0700)] if not os.path.exists(DIRECTORY) else True

else で True を返せばさらに and で処理を繋げられるので True を返す
……けど、全体を [] で括れば OK

[os.mkdir(DIRECTORY)] and [os.chmod(DIRECTORY, 0700)] if not os.path.exists(DIRECTORY) else True]

三項演算子を使わない場合は

(not os.path.exists(DIRECTORY)) and [[os.mkdir(DIRECTORY)] and [os.chmod(DIRECTORY, 0700)]]
さらに短くするために
  • 処理が評価結果として False になる事がわかってる時は or にすれば [] も省略できるので 3 文字縮められる
  • True は 1 で置き換えすれば 3 文字縮められる

クイックソート

Javaによるアルゴリズム事典

Javaによるアルゴリズム事典

の P.60 のクイックソートをやってみた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def _sort(list, first, last):
    x = list[(first + last) / 2]
    i = first
    j = last
    while True:
        print list
        while list[i] < x :
            i += 1
        while x < list[j] :
            j -= 1
        if i >= j :
            break
        swap = list[i]
        list[i] = list[j]
        list[j] = swap
        i += 1
        j -= 1
    if first < i -1 :
        _sort(list, first , i - 1)
    if j + 1 < last :
        _sort(list, j + 1 , last)
    return list

def sort(list):
    return _sort(list, 0, len(list) -1)
    

if __name__ == "__main__":
    print sort([5,8,2,3,4,1,6,4,0,2])

結果

[5, 8, 2, 3, 4, 1, 6, 4, 0, 2]
[2, 8, 2, 3, 4, 1, 6, 4, 0, 5]
[2, 0, 2, 3, 4, 1, 6, 4, 8, 5]
[2, 0, 2, 3, 4, 1, 6, 4, 8, 5]
[2, 0, 2, 3, 4, 1, 6, 4, 8, 5]
[1, 0, 2, 3, 4, 2, 6, 4, 8, 5]
[1, 0, 2, 3, 4, 2, 6, 4, 8, 5]
[0, 1, 2, 3, 4, 2, 6, 4, 8, 5]
[0, 1, 2, 3, 4, 2, 6, 4, 8, 5]
[0, 1, 2, 3, 2, 4, 6, 4, 8, 5]
[0, 1, 2, 3, 2, 4, 6, 4, 8, 5]
[0, 1, 2, 2, 3, 4, 6, 4, 8, 5]
[0, 1, 2, 2, 3, 4, 6, 4, 8, 5]
[0, 1, 2, 2, 3, 4, 4, 6, 8, 5]
[0, 1, 2, 2, 3, 4, 4, 6, 8, 5]
[0, 1, 2, 2, 3, 4, 4, 6, 5, 8]
[0, 1, 2, 2, 3, 4, 4, 6, 5, 8]
[0, 1, 2, 2, 3, 4, 4, 5, 6, 8]
[0, 1, 2, 2, 3, 4, 4, 5, 6, 8]

あとで書くかも

完全数

id:amachangid:nishiohirokazu と話してる時に完全数の話題がでた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def isPerfect(value):
    if value < 2:
        return False
    measure = []
    for i in xrange(1,value /2 + 1):
        if value % i == 0:
            measure.append(i)
    return value == sum(measure)


if __name__ == "__main__":
    for i in xrange(10000):
        if isPerfect(i):
            print i

とりあえず完全数を10個表示しようとしたら
時間がかかりすぎたので Wikipedia みてみたら,

2008年1月現在、発見されている完全数メルセンヌ素数と同じく44個である。

完全数 - Wikipedia

とんでも無いものを計算しようとしてたみたいw


ちなみに上記の結果。

yoshiori@yoshiori-ubuntu $ time python perfect.py
6
28
496
8128
python perfect.py  2.87s user 0.00s system 99% cpu 2.872 total

バブルソート

Javaによるアルゴリズム事典

Javaによるアルゴリズム事典

の P.249 のバブルソートをやってみた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def sort(list):
    k = len(list) - 1
    while(k >= 0):
        j = -1
        for i in range(1,k + 1):
            if list[i - 1] > list[i]:
                j = i - 1
                swap = list[j]
                list[j] = list[i]
                list[i] = swap
                
        k = j
    return list

if __name__ == "__main__":
    print sort([5,8,2,3,4,1,6,4,0,2])

コードだけ書いて日記に書く暇がなくて放っておいちゃったので
とりあえずコードだけ貼っておく

思いたったのでやってみる

Javaによるアルゴリズム事典

Javaによるアルゴリズム事典

の P.178 の素因数分解をやってみた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def factorize(x):
    print str(x) + ' = ',
    while x >= 4 and x % 2 ==0 :
        print "2 * " ,
        x /=2
    
    i = 3
    while i * i < x :
        if x % i != 0:
            i+=2
        else:
            print str(i) + " * ",
            x /= i
    print x


if __name__ == "__main__":
    factorize(6)
    factorize(360)
    factorize(75143)

僕が自力でやったのとの違いは

  • x が 4 以上だったら 2 で割りきれなくなるまで割る
  • その後は 3 以上の素数はすべて奇数なので +2 で奇数で割っていく
  • 関数名が英語でカッコイイ

といった感じでしょうか?


とりあえず 2 づつ加算していくのは
目から鱗でした><

素因数分解を突然やってみた

なんとなくおしっこしながら
素因数分解って俺、どうやってたの?」
と唐突に思いました。


まさか小さい素数から順に割り算していったわけじゃないよね?
とか思ったんですが、それ以外の方法が思いあたらなくて凹んだので
とりあえず何も調べずに自分で書いてみました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def isSosu(value):
    if value < 2:
        return True
    for i in xrange(2,value):
        if value % i == 0:
            return False
    return True

def getSoinsu(value):
    result = []
    i = 2
    while True:
        if value % i == 0 and isSosu(i):
            result.append(i)
            value = value / i
            if isSosu(value):
                result.append(value)
                return result
        else:
            i += 1

if __name__ == "__main__":
    print getSoinsu(6)
    print getSoinsu(360)
    print getSoinsu(75143)

本当に何も調べなかったので
僕の味方であるExite翻訳も開けずに関数名とか
すごくかっこ悪くてごめんなしあ><


で、答えあわせをしようと思って「どう書く」を見にいったんだけど
そんな問題がありませんでした><


でも、ここで色々みつけました。
http://www.asahi-net.or.jp/~kc2h-msm/mathland/math12/index.htm


とりあえずちゃんとアルゴリズムを勉強しなきゃ駄目だなぁと思ったので
id:tfunato
「Javaによるアルゴリズム事典」のアルゴリズムをPythonで実装してみる
をやってみようと思います。