Works by

Ren's blog

@rennnosuke_rk 技術ブログです

【Python】IPythonをつかう

IPython

Pythonをインストールすると、標準のインタラクティブシェルがすでに使えるようになっているが、 別のPythonインタラクティブシェルであるIPythonを使うとより快適にPythonコードを実行できる。

インストール

pip install ipython

んで

$ ipython2

bash-3.2$ ipython2
Python 2.7.6 (default, Sep  9 2014, 15:04:36) 
Type "copyright", "credits" or "license" for more information.

IPython 3.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: 

IPythonではプロンプト上の入力部分がインタラクティブシェルのような>>>ではなく、In [1]のように入力回数をあらわすものになっている。

自動補完

In [1]: im<TAB>

In [1]: import

複数の候補があると、一覧表示される。

In [1]: __<TAB>
__                 __builtin__        __name__
__IPYTHON__        __debug__          __package__
__IPYTHON__active  __doc__            
___                __import__

情報の参照

IPython中で定義した変数の後に???を付加すると、様々な情報を取ってこれる。

In [12]: obj = 1

In [13]: obj?
Type:        int
String form: 1
Docstring:
int(x=0) -> int or long
int(x, base=10) -> int or long

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is floating point, the conversion truncates towards zero.
If x is outside the integer range, the function returns a long instead.

If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal in the given base.  The
literal can be preceded by '+' or '-' and be surrounded by whitespace.
The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

履歴を残す

標準インタラクティブシェルを終了すると、以前の実行履歴は消えてなくなってしまう。 IPythonは、逐次実行履歴をpythonファイルとして残しておける。

In [1]: %logstart log.py
Activating auto-logging. Current session state plus future input saved.
Filename       : log.py
Mode           : backup
Output logging : False
Raw input log  : False
Timestamping   : False
State          : active

In [2]: print ('%logstartでログ開始')
%logstartでログ開始

In [3]: %logoff
Switching logging OFF

In [4]: print ('%logoffでログ一時中断')
%logoffでログ一時中断

In [5]: %logon
Switching logging ON

In [6]: print ('%logonで再開')
%logonで再開

In [7]: %logstop

In [8]: print ('%logstopでログ終了')
%logstopでログ終了

ログはこんな感じ↓

# IPython log file

get_ipython().magic(u'logstart log.py')
print ('%logstartでログ開始')
get_ipython().magic(u'logoff')
print ('%logonで再開')
get_ipython().magic(u'logstop')

シェルコマンドの実行

インタラクティブシェル上でシェルコマンドもできる。 !+[シェルコマンド]で使用可能。

In [18]: !ls
Applications            Sensor-Bin-MacOSX-v5.1.2.1
Desktop             TEST
Documents           apatch
Downloads           bin
Dropbox             build
Library             dotfiles
Movies              ...

【python】デコレータ

pythonにはデコレータ構文が標準で実装されている。デコレータを使うことで、既存の関数に対し簡単に別の機能を付加(デコレート)することができる。


例えば、以下の様なコードを書いたとする。

def cake():
    print("cake")

cake()

とくれば、もちろん出力は

cake

となる。

次に、新たな関数を以下のように書き加えてみる。

def chocolate(func):
    print("chocolate")
    func()

@chocolate
def cake():
    print("cake")

cake

出力:

chocolate
cake

出力結果を見ると、cake()の出力の前に呼び出してもいないchocolate()の出力が表示されている。@chocolateをくっつけたcakeを呼び出しただけで、 chocolate()の提供する機能を実行している。これがデコレータ。

もっと言うと、変更後コード中の関数呼び出しcakeは以下と等価とのこと。

cake = chocolate(cake)

すなわち、変数cakeに、関数オブジェクトchocolateが同じく関数オブジェクトであるcakeを引数に取りつつ格納されているとみなせる。cake()呼び出し時に括弧が外れていたのはそのため。



また当然ながら、chocolate()内部で引数に取る関数の呼びたしタイミングは任意に決めることができる。

def chocolate(func):
    
    print("chocolate")
    

@chocolate
def cake():
    print("cake")

cake

出力:

cake
chocolate



ネストも可能。

def jam(func):
    print("jam")
    return func

def chocolate(func):
    print("chocolate")
    return func

@jam
@chocolate
def cake():
    print("cake")

cake()

デコレータ用の関数で関数を返戻しているのは、ネストした関数を正しく呼び出すため。

例えば以下のようにすると、

def jam(func):
    print("jam")
    func()

def chocolate(func):
    print("chocolate")
    func()

@jam
@chocolate
def cake():
    print("cake")

cake

以下の様なエラーを吐く。

Traceback (most recent call last):
chocolate
  File "/Users/.../Test/calc/__init__.py", line 14, in <module>
cake
    @chocolate
jam
  File "/Users/.../Test/calc/__init__.py", line 7, in jam
    func()
TypeError: 'NoneType' object is not callable

当然といえば当然で、この時のcakeは

cake = jam(chocolate(cake))

と等価で、中の

chocolate(cake)

は関数呼び出しであり、ひと通りchocolate()が実行されたあともその返戻値はNoneTypeである。したがって「NoneTypeは関数呼び出しできませんよー」と怒られている。

タスク処理が遅い

最近、タスクの処理がめっぽう遅い!と感じるようにもなったし、外からのアクションもそれっぽくなってきたので、 なんで遅いんだろう、と考えた結果を書き留めておこうと思いました。

プログラミングとは殆ど関係ない(?)内容ですが、 自戒の意味を込めて。

1.ゴールを設定していない、意識していない

こういうモノを作ろうとか、こういうコトをしようといった、
その作業の末に到達するであろう目的を明確化していない。
手段が目的より先行している時に起こりがちな気がする。

なぜこんな考えに至ったのかといえば、今までの経験で「この作業をした時ははかどってたなあ」と感じたのは明確に発表したい内容のあるプレゼン資料を作っていたときだったから。
あとはそこに対して不足知識と調べつつ自分の考えを書き足すだけだった。

2.具体的な時間設定をしていない

「〇〇今日中にやる」でも、例えば午後6時に終わるのと午後11時に終わるのとでは5時間も違う。 5時間でできること、学べることなどいやほどある。 逆にきっちり時間を決めすぎても、例のアレなのか、最低稼働時間が指定時間いっぱいになってしまう事が多い。

3.取り組んだという事実に概ね満足している

結局そこまでの完成品を見てがっかりしているけれども。
目標よりも完成度の低い成果物の状態でタイムアウトになったときは、これか4.の場合が多い。または両方。

4.見積の精度が低い

具体的な時間設定〜同様。見積もるのはいいが、あてにならない。 前の結果を踏まえていない。

じゃあどうすればいいのよ

上から順に愚直に解決しようとするならば、
1.目標を明確化し、
2.時間設定を明確化し、
3.終了時の作業進捗を目標と比較し、ギャップを把握
4.3より、見積もりをし直す
となるのかな。まるでPDCAなんちゃらのよう。

加えて重要なことには、そのタスクを消化する(した)ことに対する報酬を自分にちらつかせるのがよいのかも。
これができたら、新しいものが作れるようになる。認めてもらえる。これをやったら、楽しいかも。面白いかも。とか。
「めんどくさい」以上の動機を与えてやる必要がある。

ここまで書くのに一時間かかりました。 あれ・・・?

Android:rotate時のActivity再生成

すごい雑だけどメモ。

Caution: Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout).

画面回転をアプリ側で許可している時、回転した瞬間にActivityは再生成されている。 再生成される前の情報はBundleオブジェクトに保存され、再度読み込まれる。

再生成するのは、画面回転によるパラメタの変更に際して別のリソースが必要となるため。

あとBundleオブジェクトは各々のViewの情報を保持できるKVS(Key-Value Store)で、Activityがdestroyされても生きている。例えばChromeブラウザを終了しても前回開いたタブ情報がそのまま、といった事が可能になる。

参考サイト

http://developer.android.com/training/basics/activity-lifecycle/recreating.html

文字列switchについて

気になったのでメモメモ。あとこの機能、Java8からのものだと思ってた。

java7実装の文字列switch

文字列switch構文内で分岐するとする。

public static String getSwitchString(String str) {

    switch (str) {
    case "a":
        return "str is a";
    case "b":
        return "str is b";
    default:
        return "str is not a nor b";
    }

}

Stringはオブジェクトである以上nullである可能性がある。 仮に上記のようなswitch文に対してStringのnullオブジェクトが渡った場合、defaultではキャッチされず、そのままぬるぽを吐く。

Exception in thread "main" java.lang.NullPointerException at SwitchTest.getSwitchString(SwitchTest.java:10) at SwitchTest.main(SwitchTest.java:4)

なので、

public static String getSwitchString(String str) {

    if (str == null) {
        return "null...";
    } else
        switch (str) {
        case "a":
            return "str is a";
        case "b":
            return "str is b";
        default:
            return "str is not a nor b";
        }

}

}

のようにしてnullを退避。

switch構文をそのままelseに繋げられるのは初めて知った。

ZigBeeについて

備忘録。通信モデルについて書くとか言って6日も放置した挙句別のこと書いてすんません。

ZigBeeとは

ZigBeeとは近距離の無線通信規格(無線PAN)の一つです。伝送速度は250kbpsと比較的低速なのですが、省電力なのが強みの無線PANです。

通信データが小さく、ネットワーク運用中に端末の移動などが考えられる場合に適しています。主に遠隔監視・制御用のデータを送受信するために使われるらしいです。

またZigBeeネットワークに参加できる最大接続端末数は65535個であり、これはBluetoothWiFiと比較すると非常に多いです(Bluetoothが7個,WiFiが32個)。

なお名前はミツバチがジグザグに飛ぶのに由来しているとのこと。

無線PAN

Personal Area Network- 実用範囲の狭い無線通信ネットワークです。無線LANの小型版のようなものです。ZigBeeのほか、BluetoothIrDAなどがこれに該当します。

ZigBeeのデバイスタイプ

ZigBeeで使われるデバイスには2通りの見方があります。一つは物理デバイス、もうひとつは論理デバイスです。

物理デバイスは、機能を完全に備えたFFD(Full Function Device)と、コスト的に廉価なRFD(Reduced Function Device)に分けられます。FFDはネットワーク上のルータ、コーディネータ(ネットワーク立ち上げ機能を持つ)、エンドポイントとして働く一方で、RFDはエンドポイントとしてしか働きません。

そして論理デバイスはこの物理デバイスの振る舞いによる分類で, 以下のようになります。

  • ZigBeeルータ:ルータとしてデータ転送機能を持つデバイス
  • ZigBeeコーディネータ:コーディネータとしてネットワーク立ち上機能を持つデバイス
  • ZigBeeエンドポイント:その他エンドポイント

これらのデバイスから、ZigBeeネットワークは形成されます。

トポロジ

ZigBeeのネットワークトポロジにはスター型とPeer to Peer(PtoP)型の二種類存在します。

スター型ネットワークはその名の通り星形にノードを配置するネットワークです。中心にZigBeeコーディネータを置き、それを取り巻くようにエンドポイントを接続していきます。

またスター型のネットワーク全体を一つのエンドノードに見立て、階層的にスター型ネットワークを構築することもできます。これをクラスタツリー型ネットワークといいます。

PtoP型ネットワークは全ノードをFFD、つまり転送可能なルータノードとし、あるノードからの送信データが他のノードによって転送されるネットワークを構築します。PtoPとは対等なノード同士が通信を行うというアーキテクチャです。バケツリレーの如く、各ノードが届く範囲のノードへとデータを転々と回していくことで、送信元ノードからの電波が届かないノードへもデータを送信できます。

これらのネットワークトポロジは組み合わせて構築することも可能です(そもそも、クラスタツリー型はスター型の再帰)。

参考サイト

http://www.atmarkit.co.jp/frfid/special/5minzb/01.html http://ja.wikipedia.org/wiki/ZigBee http://tocos-wireless.com/jp/tech/ZigBee/ZigBee.html http://ja.wikipedia.org/wiki/Peer_to_Peer

プロトコルについて

ネットワークについて書くことが多くなりそうなので、ひとまずプロトコルの話をちょいと書いてみようと思います。

プロトコルとは?

プロトコルは一言で言うと「お約束事」です。

例えば私達を取り巻く日常会話を想像してみてください。内容や場所がどうであれ、もし日本人で日本に住んでいるのであれば、少なくとも「日本語」を話しているはずです。私達の普段の会話には、「日本語で話す」という暗黙の了解があります。もちろん外国の人に英語で話しかけられたら、そこには「英語で話す」というルールが生まれるかもしれません。

ここで重要なのは日本語か英語かということではなく、そこに前提となるルールがあることです。そのルールに則っているからこそ、双方向的なコミュニケーションを生むことができます。

コンピュータネットワークも同様で、ある通信のルールに則ることでネットワークを通じてデータの送受信が可能となるわけです。どんなケーブルを使うか、どんなフレームでデータを送信するか、どんな通信経路を経るか・・・いろいろな約束事の上で通信は成り立ちます。逆にこの約束事がを決めず、フレーム長も経路情報もてんでんばらばら、ともなると通信に齟齬が生じます。なんてこった。

なのでこのプロトコルは通信においてとても重要な意味を持ちます。確かに末端のエンドユーザレベルではこのことを意識することなくアプリケーションを利用し、通信を行うことができます。日常会話もおんなじです。「うわ、この人超日本語喋ってる」なんて日本人同士で思うことはそうそうないです。

ですがネットワークに限らず、セキュリティ分野や実際のアプリケーション開発などでも、プロトコルを意識する場面は少なくありません。そういう意味でも、プロトコルに対する知識と理解は重要です。

プロトコルの概略についてさっと書きました。 明日はOSI基本参照モデルについてこりこり書きたいと思います 短めに日中に書き終えて連続記録維持とか全然考えてないです。全然。