Python」タグアーカイブ

ぱい

super pi を作ろう – ぴょぴょぴょ? – Linuxとかプログラミングの覚え書き –

というのを見つけた。
正直よく解らないけど(だから素人のままなんだ…)
super pi みたいなのを自作するのは面白そう、もっと勉強せねば。

とにかく Python でπの無限出力はどうすればいいのだろう?
スクリプト言語はこの手の計算は不得意だと解っているけどやってみたい。

math.pi では小数点以下 16 桁までしか出力してくれないし。

B. 浮動小数点演算、その問題と制限

ということで Web を探す。
とにかく例の一つでもないと私のような素人はさっぱり解らない。

情報処理 II, 第6回

簡単に見つかった…
早速 circleratio.py というのを落として実験。
エンコードが何故に latin-1 ? utf-8 に変更しておこう。

print はきちんと括弧でくくったのに例外出まくリング…

そういえば Python 3 って他にも沢山変わっていたんだっけか。

特集:もっと知りたいPython3000|gihyo.jp … 技術評論社

input() は eval(input()) にしないと文字列になるので書き換えて。
/ は // にしないと float になっちゃうので書き換えて。

#!/bin/env python
#-*- coding: utf-8 -*-
# 2007.4.9
#
# ガウスの公式による円周率の計算

from math import *  # 数学関数を使うためのまじない
from time import *  # 時間関数を使うためのまじない
from sys import *   # システム関数を使うためのまじない

# arctan(1/n) の小数展開
def expansion(n):
    x = ( p * q ) // n
    nn = n * n
    c = 1
    s = x
    k = 1
    while x > 0:
        x = x // nn
        k = k + 2
        c = - c
        s = s + c * ( x // k )
    return s

print ('円周率を計算します。')
print ('桁数を指定してください。')
prsn = eval(input())

t0 = time()     # 開始時刻
p = 10**prsn
q = 10**10

y = 4 * ( 12 * expansion(18) + 8 * expansion(57) - 5 * expansion(239) )
y = y // q
u = y // p
v = y - u * p
t1 = time()     # 終了時刻

print ("%d.%d" % (u,v))
print ('計算時間 =', t1 - t0)
fin = stdin.readline()  # Enter キーで終了

メンドクセ!
40 行のコードでコレでは大きなプログラムはマジ大変だろうなぁ。

そういえば math,time,sys は IronPython にも組み込まれているはずだよなぁ。
やってみたら一行目を消さなきゃエンコードを認識しないかやはり。
Linux の IronPython は何故か imput() ができなのでパス。

pi

IronPython 遅っ!
コンマ付きの print もおかしいし、やはり普通の Python 代わりは無理だわ。

しかし実行中は見事にデュアルコア CPU の 50 %利用ってのが笑えるよ。
ちなみに AMD Athlon64 X2 4200+ と AMD 690G というショボい構成のまま。

picpu

十万桁に 89 秒も掛かった、百万桁なんて恐ろしくて出来ん。
つか、こういうのはやはり C 言語でやるべきだよと。

ctypes で WindowsAPI

Python には Windows の DLL に直接アクセスできるモジュールがあるようで。

14.14 ctypes — Pythonのための外部関数ライブラリ。

面白そうなので試してみる。
実験だから簡単なのにしたいなぁ。
MessaageBox 関数ならロードする関数は一つなのでコレでいこう。

14.14.1.2 ロードしたdllから関数にアクセスする

に書いてあるけど Windows の関数は Ansi 版と UNICODE 版がある。
当然 TCHAR マクロも使えない、これは VC++ がコンパイル時に変換しているから。

MessageBox 関数も例外ではない。
MessageBoxA と MessageBoxW にコンパイル時に振り分けされる。
幸いにも Python3.0 の文字列は UNICODE なので MessageBoxW を使う。

そして MessageBoxW は user32.dll にあります。
ということで。

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

import ctypes

MB_OK = 0
MB_OKCANCEL = 0x00000001
IDOK = 1

dll = ctypes.windll.user32
res = dll.MessageBoxW(0, str(dll), "たいとる", MB_OKCANCEL)

if res == IDOK:
    dll.MessageBoxW(0, "OK を押しました", "りざると", MB_OK)
else:
    dll.MessageBoxW(0, "きゃんせるを押しました", "りざると", MB_OK)

mbox

うわぁコレでいけちゃうんだ。
MB_OK とかの定義は WindowsSDK の WinUser.h を見てちょ。

全部 DLL から呼び出せばウインドウもコントロールも作れるね。
でも定数を全部自分で定義せにゃいかんのが面倒そう…

えむえでぃた

とりあえず Windows での Python は EmEditor で行こうと思う。
一応こんな設定にしてみた。

emedit

Home キーでカーソルをインデントの先頭に行かせる。
Shift+Tab でインデント分カーソルを戻す。
という動作は秀丸ではできないっぽいんで。

PyScripter なんてのも見つけたけど普通のテキストエディタのほうがエエわ。
スクリプト言語を IDE で書くなんて馬鹿げていると思うようになったよ。
更に言語ごとに別の IDE だなんて何がしたいの?みたいな。

とりあえずコイツにはスニペットプラグインもあるしガンガン登録してしまえ!
と思ったけどこのスニペットって単語登録ができるだけっぽいな。
それも Tab キーで補完じゃなく選択して Enter なんだ、ガッカリ。

まあ EmEditor はアウトプットがあるから便利だ。
と思ったけど…

output

おもくそ文字化けしとるやないの。
コンソールなら普通に表示できるのになんやこれ、ガッカリ。

それとツールに Python と IronPython を登録。
これでボタンを選ぶだけでどちらも動作確認ができるぞと。
アウトプットが化けるから pythonw.exe でなく python.exe にしておくか…

Ruby も一応ツールに登録していたんだけど全く使わないので登録解除。
IronRuby なんてもう忘れられた子になっている、そんなのあったなぁ…

他に VL ゴシックにしたり読み書きは BOM 無し UTF-8 に指定したり。
なんか意地でも Ubuntu の gEdit に合わせようとしている自分が怖い。

しかし弄くれば弄くるほど Windows と Linux の文化の違いを感じるよ。
テキストエディタに求められているものが違いすぎ。

追記

アウトプットの文字化けは私の設定ミスだった…
出力エンコードを UTF-8 にしていた、システム規定でよかったのね。
江村さんごめんなさい。

それと Shift+Tab の動作だが Tab 分カーソルが戻るだけだった。
文字列を選択していない場合は逆インデントをやってくれない。
これは困る、逆インデントに BackSpace を4回叩くなんてやってられないよ。

しかたがないのでマクロを作る。

if (document.selection.IsEmpty) {
	document.selection.DeleteLeft(4);
} else {
	document.selection.UnIndent(1)
}

を作り Shift+Tab の割り付けをコッチに変更という強引なワザで。
これで範囲選択状態の動作は維持しながら未選択の場合は前方四文字削除だ。
というか gEdit と同じ動作。

問題はインデントの先頭で実行することしか考えていないことだったりする。

環境変数の対応リストを作る

Windows では os.environ[“HOME”] が例外になってしまった。
環境変数が違うようだ、Windows が用意しているのってどんなのがあるのだろう?
C++ では Windows SDK に個別取得する関数があるのであまり気にしていなかった。

今後のプログラム用に環境変数の対応リストが作りたい。

ということで environ のキーと値を書き出す簡易スクリプト。
Windows でも Linux でも動きます、一応 Windows 版は Python 3.0 で試した。
print でリダイレクトしたほうが今の私は早いけど Python だけでやってみよう。

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

# 環境変数の書き出し

import os

keys = os.environ.keys()
result = ""
for key in keys:
	result += key + "\n" + os.environ[key] + "\n\n"

f = open("env.txt", "w")
f.write(result)
f.close()

ちなみに私の環境ではこうなった(合体しています)

env.txt

同じモンがありゃしねぇ、こりゃ環境変数を利用したコードの共有は無理だ。
どうでもいいけど Windows 用 Python での \n は CRLF になるんだね。

ちなみに IronPython では下記の要領で同じことができます。

# -*- coding: UTF-8 -*-

import System

# IronPython は clr なので \n では LF 固定になってしまう
nn = System.Environment.NewLine

# IDictionary が返る
dic = System.Environment.GetEnvironmentVariables()
result = ""
# DictionaryEntry に展開
for ent in dic:
	result += ent.Key + nn + ent.Value + nn + nn

sr = System.IO.StreamWriter("env.txt")
sr.Write(result)
sr.Close()

なんか Python らしくないコードだ、なんたって値取得に括弧が付いていない。
プロパティから取得する部分には当然括弧は付かないわけでこうなってしまう。
大文字が多いのはしかたがないが CPython コードとの見分けになると思えば…

#! /usr/bin/env python は言うまでもなく書いてはいけません。
つーか *.py は Windows での振り分けにはどうしよう?関連づけは CPython だし。

なんて解説をしているのでもう解ると思うけどこのコードは mono でも動きます。
Ubuntu 8.10 デフォルト状態でも IronPython 1.1.2 ならそのまま動かせる。

linux_ipy

とはいえ Linux で IronPython というのは凄く無駄を感じますけど。
動かせるとはいえ実用となると今後もビミョーとしか言いようがない。

一応書くと Mac は全然解りません。

通信

PyGtk アプリで多重起動防止をやりたい。
それには引数を既に起動している自分自身に送信する必要がある。
いわゆるプロセス間通信というやつです。

Windows なら WM_COPYDATA という単純な方法が使える。
デスクトップ内での通信ならソレで十分なので他の通信を勉強していない。
そのツケで今苦しんでいる。

第10章 2重起動を防ぐ

を見つけて Python に書き直しテストとかやってみた。
PyGtk 2.13.0 の gtk.SelectionData では get_length() メソッドが使えなかった…

gtk.SelectionData

てかこの方法って selection_convert を実効しないとサーバーは取得しないってことかな?
なんか私のやりたい通信とは違うみたい、まだよく理解していないが早く気がつけ俺。

次に Plug と Socket を使ってみようと考えた。

10.13. Plugs and Sockets

うん、これなら PyGtk の範囲で使えるから楽そうだ。
ダウンロードしたサンプルをそのまんま試して動いたし理解しやすい。
しかしこの Socket ってつまりコンテナとして実装する必要があるってことみたい…
ということはどう実装…なんかコレも違う。

そういえば gEdit のソースを落としたんだっけ、見てみよう。
Bacon なんちゃらという関数が見つかったけど…何がどうだかまったく解らんぞ!
Linux での C 開発は私のレベルではまだ無理だと実感。
だってどのヘッダがどの役割とか全然知らないもん。

色々探すと Gnome は Bonobo という通信手段を用意しているらしい。
これがもう更に何がなんだか解らない。

あぁ、通信についてもっと勉強しておくべきだった。

D-BUSを使用してデスクトップ・アプリケーションを接続

こんなのまで見つけてしまった、もうドツボか。
と思ったけど D-BUS って Bonobo から置き換えられるそうだ。
ならばコッチを勉強したほうがよさそう。
しかし Python のコードをコピペしてみたけど動かないぞ!

Linux 日記 2005

そうか仕様変更されまくっているのか、やっぱり動かない。
どこかに現行版の解りやすいサンプルコードは無いのだろうか。
というか私はアプリ間で文字列の送信受信さえできれば十分なんですけど。

Message from D-BUS

うん、HelloWorld は上手く通信できた。
やっと先が見えてきた、以上 URL 覚書だけで終わった日記でした。