カテゴリー: ソフトウェア

  • Python のバージョン管理、pyenv のインストールと使い方

    今まで Python 2.xで開発を行っていましたが、Python 3.x に移行する必要があって 2.x と 3.x が混在する環境をどう構築するか悩んでいました。pyenv や virtualenv, pyvenv という便利なものがあるようですが、それぞれ役割が違うようです。

    今回はバージョン管理だけを行いたかったので、pyenv に絞った内容です。

    簡単な説明

    pyenv  が主に行うのはユーザー環境下での Python のバージョン管理です。ユーザー環境下であってシステム全体ではないところが重要で、システムを利用する他のユーザに影響を与えません。

    以下は提供サイト(https://github.com/pyenv/pyenv)にある説明です。

    pyenv does…

    • Let you change the global Python version on a per-user basis.
    • Provide support for per-project Python versions.
    • Allow you to override the Python version with an environment variable.
    • Search commands from multiple versions of Python at a time. This may be helpful to test across Python versions with tox.

    特定のディレクトリで使う Python のバージョン(per-project Python versions)、それ以外のディレクトリで使う Python のバージョン(global Python version) を簡単に切り替えられるのが特徴です。仕組としてはシェルの PATH の探索順を利用しているようです。

    インストール

    環境は Debian (Raspbian) 8.0 を想定しています。

    インストールといってもシェルスクリプトなので、git からコピーして環境変数を設定するだけです。

    # pyenv installのとき必要になるパッケージのインストール
    $ sudo apt update
    $ sudo apt install build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils
    
    # gitのインストール(gitが入っていたら不要)
    $ sudo apt install git
    
    # pyenvのインストール
    $ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
    
    # 環境変数の設定
    $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    $ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
    $ source ~/.bashrc
    
    # 確認
    $ pyenv -v
    pyenv 1.2.4-2-gdad0fc7

    簡単な使い方

    まず最初にインストールされているバージョンを確認します。

    $ pyenv versions
    * system (set by /home/pi/.pyenv/version)
    $ python -V
    Python 2.7.9

    何もインストールしてないので、システムに標準で入っている Python のみ状態です。この状態から pyenv 環境に使いたいバージョンの Python を追加していきます。

    インストールできる Python のバージョンは “pyenv install -l”  または “pyenv install –list”で確認できます。

    $ pyenv install -l
    Available versions:
     2.1.3
    ...
    ...(省略)...
    ...
     stackless-3.5.4

    この中から、例えば Python 3.6.5 をインストールするなら次のようにするだけです。ビルドを伴うのでそれなりに時間がかかります。

     $ pyenv install 3.6.5
    Downloading Python-3.6.5.tar.xz...
    -> https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz
    Installing Python-3.6.5...
    Installed Python-3.6.5 to /home/pi/.pyenv/versions/3.6.5
    
    $ pyenv versions
    * system (set by /home/pi/.python-version)
     3.6.5

    インストールが完了したらバージョンを切り替えてみます。現在のディレクトリにだけ効力を持たせるには local を、全てのディレクトリで効力を持たせるには global を指定します。

    $ pyenv local 3.6.5
    $ python -V
    Python 3.6.5

    local の挙動

    local は指定したディレクトリ以下(子ディレクトリも含む)で効果を持ちます。そのディレクトリだけでなく、子ディレクトリにも影響が及ぶことに注意します。

    $ python -V
    Python 2.7.9
    $ pyenv local 3.6.5
    $ python -V
    Python 3.6.5
    $ cd ..
    $ python -V
    Python 2.7.9
    $ cd ./user/dir/
    $ python -V
    Python 3.6.5

    global の挙動

    global はそのユーザがログインしているとき、全てのディレクトリで効果を持ちます。どのディレクトリに移動しても、global で指定されたバージョンが実行されます。このとき、local でバージョンが指定されているディレクトリは local で指定したものが優先されます。

    $ python -V
    Python 2.7.9
    $ pyenv local 3.6.5
    $ python -V
    Python 3.6.5
    $ cd ..
    $ python -V
    Python 3.6.5
    $ cd ./user/dir/
    $ python -V
    Python 3.6.5

    Python の仮想環境

    Python のバージョン管理を行う pyenv の説明は以上です。2.x と 3.x の共存や切替はこれで簡単に行えますが、環境が複数になると次はプロジェクト毎にモジュールの管理を行う必要が出てきます。

    そこで冒頭に挙げた virtualenv や venv といったものが登場します。これらはまた別の記事にまとめます。

  • ムームードメインからさくらインターネットへの.comドメイン移管

    ムームードメインからさくらインターネットへの.comドメイン移管

    GMO のムームードメインから、さくらインターネットへ.comドメインの移管を行ったときの記録です。

    ムームードメインで「認証コード(AuthCode)」を取得する

    ムームードメインのコントロールパネルにログイン後、左メニューの「ドメイン管理」 – 「ドメイン操作」 – 「ドメイン一覧」と辿ります。

    ムームードメイン 認証コード

    移管するドメイン名を開きます。ページ中ほどに「認証コード(AuthCode)」があるので控えておきます。

    ムームードメイン 認証コード

    さくらインターネットで転入を申し込む

    • 【gTLDドメイン】転入マニュアル – さくらのサポート情報

    さくらインターネットの「お申し込み」から「ドメイン管理」 – 「gTLDドメインの移管(転入)」 – 「オンラインサインアップ」を開きます。

    さくらインターネット 転入

    ログイン後、移管するドメイン(*.com)を入力します。約款に同意したら「次へ」進みます。

    さくらインターネット 転入

    先ほど控えた認証コード(AuthCode)を入力し、Whois に登録された登録者名を入力します。

    さくらインターネット 転入

    支払情報を確認し、必要事項を埋めます。今回は既にクレジットカード決済にしてあるため、カードのセキュリティコードを入力するのみでした。

    「最終のご確認」で内容を確認して、申込完了です。

    さくらインターネット 転入

     JPRS から承認メールが届くので承認する

    「[JPRS] レジストラトランスファー承認手続きのご案内」という表題のメールが届くので、メール内に書かれた URL を開いて「承認」すれば後は待つだけです。

  • jQuery の autocomplete で任意のタイミングで候補を探索

    <input type="text" name="title" id="title">

    とあったとして

    $("#title").autocomplete("search");

    で好きなタイミングで候補を表示できる。

  • HTML の文字参照(数値文字参照、文字実体参照)

    もう 20 年以上も使っているのに憶えられないのでメモ。

    数値文字参照

    10 進数表記
    $#1234;
    16 進数表記
    $#xABCD;

    文字実体参照

    &amp; &lt; &gt; といった名前での参照。

  • SQLite3 で 1 Query で BOOL 値の toggle

    SQLite3 で BOOL 値を扱うとき、SQLite3 には BOOLEAN 型がないので INTEGER で代用することになる。

    0 を false, 1 を true とするときに、例えば

    • 現在の値が 0 なら 1 にセット
    • 現在の値が 1 なら 0 にセット

    としたいときがあると思う。

    現在の値を確認するために、まず “SELECT …” で値を読み込んで、その値から判断して “UPDATE …” とすると、2 Queries になってしまう。

    Making an sql “toggle” using a single query?」を参考に

    UPDATE table SET flag = flag + 1 % 2 WHERE id = 127;

    と剰余を使ってできた。他の SQL 環境では MOD 関数を使って

    MOD(flag + 1, 2)

    のような感じなるだろう。

  • jQuery UI + Python で ajax な autocomplete

    社内向けシステムの使い勝手向上と、今後のシステム開発に向けてフォームにオートコンプリートをつけようと苦戦した記録。

    静的候補を表示する

    jQuery で autocomplete を実現しようとすると jQuery UI のお世話になる。参考にしたページはこちら。

    最も簡潔な実装方法は、フォームと同じファイルにリストを用意する方法。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css">
    https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
    
    $(function() {
        var data = [
            'にんじん',
            'たまねぎ',
            'じゃがいも',
            'きゅうり'
        ];
        
        $('#item').autocomplete({
            source: data
        });
    });
    
    <title>autocomplete のサンプル</title>
    </head>
    <body>
    <input type="text" id="item" value="" />
    </body>
    </html>
    

    最も簡潔な例はこんな感じ。単に配列を用意するだけ。

    Ajax で動的に候補を読み込む

    これも同じサイトの別記事を参考にした。

    $(function() {
        $('#item').autocomplete({
            source: './autocomplete.py'
        });
    });
    

    パラメータ “source” を候補を取得する CGI 等にするだけで OK. CGI 側は候補を JSON で返せば良い。クライアント側の実装はこれで完了なのだが、サーバ側の実装で苦戦したのでそれについて記述する。

    動的候補を用意するサーバ側の実装

    今回は実装しているサーバの都合で Python による実装としている。(余談だが、PHP 使わなかったのは Linux PHP + FreeTDS + Windows SQL Server という特殊な環境でどうしても PHP のドライバが落ちて使えなかったから。ソースを修正してリビルド……というところまでしたけど、実用に持っていくのに手間がかかりすぎて使い慣れた Python  に逃げた)

    今になって冷静に読んでみると参考ページには書いてあるのだが、初めクライアントからの入力途中の値を得るのにフィールドの名前がわからずに随分と彷徨った。答えは簡単で、 term というフィールドがそれだ。

    なので例えば Python であれば

    import cgi
    
    form = cgi.FieldStorage()
    term = form.getfirst('term')

    という感じで取得する。

    取得した term を使ってデータベースなどに照会をかけて、得られた結果をクライアントに JSON 形式で返す。

    以下は簡潔にするため固定値の場合。

    import json
    
    data = [
        {label: 'にんじん', value: '00000001'},
        {label: 'たまねぎ', value: '00000002'},
        {label: 'きゅうり', value: '00000003'}
    ]
    
    print('Content-type: application/json; charset=UTF-8\r\n')
    print(json.dumps(data))

    Content-type を出力していないと 500: Internal Server Error をはいてしばらく悩んだ。

    Ajax でのデバッグは通信内容が目に見えないことも多いので、例えば IE なら F12 キーで Web 開発ツールを起動して Network の通信内容を見てみると原因を特定しやすい。