Make it possible with Python.

最近Pythonから離れ気味、その他物作りに寄り気味です。

リストやディクショナリ、変数へのデータの収納の仕方

今も会社で空き時間を見つけては、単純作業自動化ツールを少しずつ書いています。

そんな中でのたぶんプログラミングの基本的な気づきを1つ。

多次元リストやディクショナリに値を収納するときの話。

最近、徐々に複雑なデータを扱うようになってから、出力しやすいことを考えるだけじゃなくて、処理もしやすいように収納する必要があることがわかった。

具体的には、データの持つ「意味」で分ける。

実験サンプル名とそのサンプルにおける実験データと各データのラベルを取り込んで出力したいとき、それらをリストに同じレベルで混ぜて並べてはいけない。

階層が深くなってもいいから、最上位のリストには、[[name],[label],[data]]、みたいに、それぞれの子リストが意味で明確に分けられるように構造を作る必要がある。

出力をするだけなら、上から順に出力すればいいので、異なる意味のデータが混ざっていてもリストの階層が浅いほうがラクなんだけど、

これだと抽出や並び替えの処理に困る。

データの行と列を入れ替えたかったり、データを4つに分割したかったりすると、そのたびに面倒な手順が入る。

なので、しばらくはきちんと階層を作ってデータを収納してみようと思います。

photo by pasukaru76

AnacondaがPython3.4ベースに!

Anacondaが2.0にバージョンアップしたというメールが来ました。

Anaconda Scientific Python Distribution

ついに、Python2.7に加えて3.4もでデフォルトでインストールされるそうです。

難しいインストールを気にすることなく、以下のモジュール、ツールがPython3ベースで使えることを意味するはずです!

  • Numpy
  • Scipy
  • pandas
  • IPython
  • IDE Spyder

これで、日本語の扱いが楽になったり、より日本人に優しいツールになるのでしょうか?

今はPython(x,y)で上記モジュール類を使っていますが、1~2ヶ月様子を見て移行をしようと思います。

codecs.open() とcsv.reader の組み合わせでUnicodeEncodeErrorエラー

Python2.7でこんなコードを書いたらUnicodeEncodeErrorエラー。

    infile = codecs.open(file, "r", "cp932")   
    
    dat = csv.reader(infile)   
    
    y_sig = []
    
    for row in dat:
        
        y_sig.append(row[6])

IDE上ではエラーにならないが、ソースコードを実行するとエラーになる。

それも、なぜかforの行でUnicodeEncodeErrorエラーが発生。

原因はたぶん、csv.readerがunicode型に対応していないらしいこと。(詳細は不明)

このバージョンの csv モジュールは Unicode 入力をサポートしていません。また、現在のところ、 ASCII NUL 文字に関連したいくつかの問題があります。従って、安全を期すには、全ての入力を UTF-8 または印字可能な ASCII にしなければなりません。

13.1. csv — CSV ファイルの読み書き — Python 2.7ja1 documentation

そこで、以下のように、decodeしてunicode型にするタイミングを後ろにずらしたらokになった。

    infile = codecs.open(file, "rb")   
    
    dat = csv.reader(infile)   
    
    y_sig = []
    
    for row in dat:
        
        y_sig.append(row[6].decode('cp932'))

ついでにunicode型と decode,encodeについて勉強。 特に参考になったページのリンクをメモ。

PythonのUnicodeEncodeErrorを知る - HDEラボ ゼロから概念を学ぶのに役立ちました。わかりやすい。

Unicode HOWTO 詳細で明確に記載されている。

今回は特殊なケースだけど、通常は、できるだけ早めにunicode型にして、その後はギリギリまでunicode型を保つのがいいらしい。

python3で標準がunicode型になると、こんな煩わしさもなくなるんだろうか。

herokuは諦めます。

正確には、しばらくは諦めます。 きつすぎました。

思ったよりいっぱいエラーが出て、解決法を調べても調べても、芋づる式にわからない言葉が出てきて収拾がつかなくなりそうなので。

UNIXもサーバーもhttpもsshもunicodeすら知らない人間にはちょっと早かったかもしれない。

herokuだけじゃなく、pythonにも言えることだけど、こういう抽象度の高いプログラミング言語って、

「短時間で」「簡単に」ものが作れるけど、それって

「内部の仕組みを知ってる人なら」っていう限定がつくんですね。

初心者でもうまくいけば作れるけど、エラーが出たときには、結局解決のために内部の仕組みを学ばないと行けない。

まあ、それでもできあがるコードが短く簡潔になるのであれば、長いコードを書いて手のつけようがなくなるよりは楽なんだろうけど・・・。

まずは会社の業務自動化を進める中で言語仕様をもう少ししっかり覚えて、コードの書き方も勉強して、それからVPS経由でwebサービスを学んでいくことにします。

python2.7は文字コードについてしっかり勉強する機会をくれそうなので、まずはそこから。

Spyderが起動しなくなった問題と、その解決法

PythonのSpyderが起動しなくなった。

Spyder.exeを実行すると、一瞬コマンドプロンプトに文字列が表示された後、エラーで終了しているように見える。

Python(x,y)まるごとアンインストール、python27フォルダを全削除して再インストールしても起動しない。

spyderのDocumentsにあった、--reset も、--defaultsもきかない。

でも、コマンドラインで起動するとコマンドプロンプトの内容が消えずに残ったので、内容の確認ができた。

C:\Users\USER_name.spyder2.spyder.ini

でエラーが起きているらしい。

そのファイルを開いてみたら、ファイルの後半が盛大に文字化けしていた。

2014- 05-08 23 :59:34,  Info  CBSLSessio n: 30370 510_5316 99695 in itialize d by cli ent Wind@owsUpd 錢

みたいな文字列がひたすら並んでいる。 このファイルをリネームしたら、新規に設定ファイルが生成されて、Spyderが起動できた。

たしか、5月8日頃にPCのシステム全体がフリーズしたので、その余波ではないかと思われます。

virtutalenv絡みで、Pythonと環境変数についてちょっと調べた

virtualenvは環境変数を変更することで、仮想環境を作り出しているらしい。

そこで、

  1. 環境変数とはどういうもので、

  2. Pythonではどう使われていて、

  3. virtualenvではどう使われているのか

について、少し調べてみた。たぶん間違いもあると思います。

環境変数とは

一言で言えば、Windowsシステム全体のプログラムが共有する変数のこと。

Windowsシステムが使用する環境変数は、特別な意味を持つ。 例えばPATH変数は、「プログラムを実行するときにそのフォルダを探す」という意味を持つ。

環境変数をマスターする [Javaプログラミング] All About

virtualenv絡みでは、PYTHONPATH と PYTHONHOME がよく出てくるので、それについて調べてみる。

PYTHONが使う環境変数

まとめると、こんな意味らしい。

PYTHONHOMEは Pythonに共通で含まれる標準ライブラリのパスを、 PYTHONPATHは Pythonに追加されるモジュールファイルの検索パスを追加するらしい。

PYTHONHOME(原文)

標準 Python ライブラリの場所を変更します。デフォルトでは、ライブラリは prefix/lib/pythonversion と exec_prefix/lib/pythonversion から探されます。ここで、 prefix と exec_prefix はインストール依存のディレクトリで、両方共デフォルトでは /usr/local です。

PYTHONHOME が1つのディレクトリに設定されている場合、その値は prefix と exec_prefix の両方を置き換えます。それらに別々の値を指定したい場合は、 PYTHONHOME を prefix:exec_prefix のように指定します。

PYTHONPATH(原文)

モジュールファイルのデフォルトの検索パスを追加します。この環境変数のフォーマットはシェルの PATH と同じで、 os.pathsep (Unix ならコロン、 Windows ならセミコロン) で区切られた1つ以上のディレクトリパスです。存在しないディレクトリは警告なしに無視されます。

通常のディレクトリに加えて、 PYTHONPATH のエントリはピュアPython モジュール(ソース形式でもコンパイルされた形式でも) を含む zip ファイルを参照することもできます。拡張モジュールは zip ファイルの中から import することはできません。

デフォルトの検索パスはインストール依存ですが、通常は prefix/lib/pythonversion で始まります。 (上の PYTHONHOME を参照してください。) これは 常に PYTHONPATH に追加されます。

上の インターフェイスオプション で説明されているように、追加の検索パスディレクトリが PYTHONPATH の手前に追加されます。検索パスは Python プログラムから sys.path 変数として操作することができます。

[http://docs.python.jp/2/using/cmdline.html#using-on-envvars:title]

ちなみに、実行中のPythonインタプリタから上記pathを調べるには、インタプリタ上で

import sys
sys.path

を打てばOK。

ここで出てくるpathは、このように決まっているらしい。

カレントディレクトリを自動的に登録する。最初の空文字列”がこれです。
環境変数PYTHONPATHがあれば、そこに指定されたディレクトリを登録する。
レジストリにPythonPathエントリがあれば、そこで指定されたディレクトリを登録する。
環境変数PYTHONHOMEが設定されていれば、そこから、なければ、python.exeのあるディレクトリから、Lib\os.pyを特定し、PYTHONHOMEを推定して、必要なサブディレクトリをsys.pathに登録する。
PYTHONHOMEもPYTHONPATHも特定できず、レジストリのエントリもない場合は、デフォルトの相対パスが使われる。
モジュール検索パスに、拡張子 .pth のファイルがあれば、そこに書かれたパス(相対パスでも絶対パスでもよい)を、sys.path の最後に付け加える。

Python2.7 と Python3.3 を Windows で併用する | ユニマージュ

virtualenvがやっていること

activate.batをちょっと見てみたけど、理解できず中断。

期待された方、ごめんなさい。

わかる方、教えてください。

heroku で プロンプトからSSH-key 生成ができないので、全部GUIから実施した。

herokuの使い方を学び中。

PaaSやサーバーの知識皆無のため、一番シンプルな以下のチュートリアルから実施した。 https://devcenter.heroku.com/articles/getting-started-with-python

もちろんこれでも問題多発。

heroku初回ログイン後のSSH Key生成でエラー発生。

Could not find an existing public key.
Would you like to generate one? [Yn] Y
Generating new SSH public key.
 !    Could not generate key: 'ssh-keygen' は、内部コマンドまたは外部コマン
 !    操作可能なプログラムまたはバッチ ファイルとして認識されていません。

以下サイトを参考に、環境変数を作成してもダメ。念のためコマンドプロンプトやPCを再起動してもダメ。

herokuの初回ログイン時にキーが作れなかった時のメモ - Qiita

SSH Key生成はインストールしたSourcetreeでできそうなので、それでキーを作成。

SourceTree 設定手順 覚書【Windows】 - Qiita

さらに、作成したPublic keyを herokuのwebサイトからコピペで登録した。

これで行けるはず・・・?

※その他参考サイト Heroku で Flask + SQLAlchemy を使う - Twisted Mind

pythonは確かに簡単な言語だけど、webアプリとか、言語以外のいろいろなものが絡み合う使い方を求めると、結局かなり複雑になるんですね。