Programming」カテゴリーアーカイブ

Linux Python 3

そろそろ Python を 3 に移行しようと思う。
はて、日本語はどうなるのだろう?
Linux ではまったく使っていなかったから解らない。

Gio Tips – L’Isola di Niente

多分組み込みの open() 関数はツジツマを合わせていると思う。
GIO での読み書きはどうなるやら、実験。

# Write and Length Check
s = '日本語'
f = open('test.txt', 'w')
f.write('{0}\n{1}'.format(len(s), s))
f.close()

# g_file_load_contents
from gi.repository import Gio
gfile = Gio.File.new_for_path('test.txt')
res = gfile.load_contents(None)
print(res)

# Streaming I/O
fstream = gfile.read(None)
dstream = Gio.DataInputStream.new(fstream)
print(dstream.read_line_utf8(None))
print(dstream.read_line_utf8(None))
fstream.close(None)

うん、文字列はシッカリ gunichar(UCS-4) だね。
やはり組み込み関数は仕事キッチリか。

g_file_load_contents だと、、、バイナリ扱いになってしまった。
読み込んでも UTF-8 のままで保持するということみたい。
文字列の読み書きに利用するなということなのだろう。

Streaming I/O では文字列自体は UCS-4 化するみたいだけど文字列長は UTF-8 バイナリでカウントしている。
試しに dstream.read_Line(None) に書き換えたら予想通り文字列がバイナリに。
GFileOutputStream は UCS-4 の文字列を普通に UTF-8 として書き込みできた。

うーん、やはり文字列が UCS-4 だと扱い辛いぞ。

GTK+ の GtkEntry の文字列はどうなるんだろう?

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
 
from gi.repository import Gtk
 
class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_title('たいとるばぁ')
        self.connect('delete-event', Gtk.main_quit)
        self.entry = Gtk.Entry()
        button = Gtk.Button('保存')
        button.connect('clicked', self.on_clicked)
        vbox = Gtk.VBox()
        vbox.pack_start(self.entry, False, False, 0)
        vbox.pack_start(button, False, False, 0)
        self.add(vbox)
        self.show_all()
 
    def on_clicked(self, widget, data=None):
        f = open('gtk.txt', 'w')
        f.write(self.entry.get_text())
        f.close()
 
if __name__ == '__main__':
    w = Win()
    Gtk.main()

タイトルバー等の文字列も GtkEntry とのやりとりも UCS-4 の内部文字列のままでイケてしまうようである。
GIO で文字列を扱う場合以外は Python2 時と同様に使えると思ってよさそう。
なんて思っていたら落とし穴がありそうだが…

もう少し検証したいけど Boxes 上の Ubuntu では辛い。
「クリップボードを共有」を ON にしているのに何故かホストと共有できなくて面倒くさいぞコノヤロウ。
Fedora に入れたいけどデフォルトで使えるコードというポリシーに反するし。
18 にはデフォルトで入るみたいだが β すらまだ出ていない。

ちなみに本サイトのメール送信フォームを利用して文字列のやりとりというバカなことをやっていたりする、サイトを作っておくと便利だよ。

Ubuntu 12.10 Programming

せっかく Ubuntu 12.10 を仮想で導入したのでプログラミング環境等をチェック。

やったぜ、mono という巨大なゴミがデフォルトで入らなくなった!
と思ったけど 12.04 から既に無かったのか、気がつきもしなかった。
もしかして valac が…あるわけないか。

なんと Python 3 がデフォルトで入るようだ。
LXDE に変更したから入ったのかもしれないけど。

Python 3 からは pygtk はやっぱり使えません。
その他 Python 2 で提供されていた静的バインディングも当然全滅。
gi による動的バインディングなら問題ない。
一応書くと Python 2 も PyGtk も当然あるよと。

gcc はあるけど g++ は無いのは以前と同じ。
Gjs も Seed も無い、Ubuntu は JavaScript に消極的か。

Fedora なんかは Python に依存する体制から脱却しようとしているみたいだけど結局戻りそうな予感。
今の Linux では GLib 等の動的バインドに対応できるなら言語なんて何でもいいんだけど Python は標準ライブラリが絶妙だからね。

GTK+ のバージョンは…あれ? Nautilus や Totem のバージョンが 3.4 だ。
Gedit と eog は 3.6 って何だこれ。
まあつまり GTK+ は 3.6 であるということか、何故アプリはバラバラ?
Ubuntu って最新環境を最速で提供が売りではなかったのかな。

おかげで Nautilus にメニューバーがあるけどw
Nautilus 3.6 はかなり大胆に変更されているし、アプリケーションメニューに対応できなかっただけかもしれない。
GNOME は今後このメニュー主体になるわけで、GNOME を捨てたくせに GNOME の成果物に依存している Ubuntu の今後はいかに。

Gnome Files (aka Nautilus) 3.6 (3.5.92) Preview | Worldwide Edition – YouTube

しかし LXDE の設定には「ルックアンドフィールの設定」なんてのがあるけど Ubuntu ではまったく適用されない。
GTK2 はクリアルックス固定だし GTK3 に至っては Windows95 みたいだ。

元の Ubuntu が GTK2 と GTK3 を同じ見た目にするために標準を無視して特殊なことをしているからだろうけどカッチョワルイ。
Lubuntu ならこの辺りをなんとかしているのだろうか。
仮想だからいいけどホスト OS でこの環境を使いたくないないな。

というか LXDE 自体が GTK2 であるわけで。
この環境で GTK3 アプリを作ろうと思う人はいないだろうな。

GTK3 に移行したい人は素直に GNOME 3 を使いましょうということでしょう。
良さげならホスト化しようと思ったけどやっぱり次も Fedora にしよう。

Gst 1.0

Novacut/GStreamer1.0 – Ubuntu Wiki
~jderose/+junk/gst-examples : contents of video-player-1.0 at revision 72

こんなページを見つけた。
これでやっと Y901x の GTK3 化に進歩が…

GStreamer 1.0 用だった。
つーか今まで 1.0 パッケージが公開されたことを知らなかったという…
バージョンは 0.11 のようですけど、0.10 と共存可能らしい。

PPA for GStreamer developers : “GStreamer developers” team

Fedora 17 にデフォルトで入っている GStreamer は 0.10 だ。
0.10 用のサンプルは PyGtk コードのまま。

~jderose/+junk/gst-examples : contents of video-player-0.10 at revision 72

でも 1.0 のコードを 0.10 に書き換えすれば動くかも。
よく見たら Python も Python3 じゃないの、とにかくコピペして書き換え。

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

# python2

from os import path

import gi
gi.require_version('Gst', '0.10') #'1.0')
from gi.repository import GObject, Gst, Gtk

# copy...

on_sync_message がやはり発行されない…
ということは on_message を作っても msg は空のまま。
0.10 のバインディングは Fedora 15 時と何も変わっていないということみたい。

このアプリを試すためだけに GStreamer 1.0 を導入してくれ。
なんて言えないよ、てか私も今は入れたくないし。

Fedora や Ubuntu の次期版次第だ、とりあえず覚書ということで。

しかしサンプルコードが Python3 なのも気になる。
実用では見向きもされないままで Linux ではガン無視されている Python3 は失敗作ということで Winamp のごとく Python5 が出るとばかり思っていたのだが。

とにかく文字列が Unicode だと local が utf-8 の Linux では都合が悪すぎ。
とずっと思っていたけど前回 gunichar が ucs-4 だと気がついたっけ。
検索してみる。

DSAS開発者の部屋:Python2.x/3.0のunicode内部表現について

あれ、Fedora の Python って u’str’ は UCS-4 だということなの?
おいおい、私みたいに勘違いしていた人って多くないか?
ならば端末からチト試してみよう。

普通に u” のままで日本語出力ができた、なんじゃこりゃ!
と思ったけど format で成形すると駄目。
ついでにスクリプトファイルにすると直 stdout も駄目になる。

ならばスクリプトを ucs-4 で保存、、、スルーされてしまった。
まあ ucs-4 でスクリプトを保存する人はいないし変換すればいいだけ。
まあとにかくそういう動作をするようだ。

うん、そういうことなら Python3 でも別にいいかなと。
でもデフォルトで入るようになるまで手を出したくない。
「このコードを試すためだけに Python3 を入れてくれ」なんて嫌だよね。

gunichar

C 言語で文字列メンドクサイ | PaePoi

以前こんなことを書いたけど

Eye of GNOME 3 plugin Create | PaePoi

上記をやった時に早く気がつけよ。
g_utf8_strlen なんて解りやすい関数があるじゃないの。
一文字ずつ書き出すための変換関数もあるし。

ついでに、Linux の wchar_t は 4 byte だから多分 UCS-4 だよね。
まあ GLib を使うなら gunichar になるわけだが。
typedef guint32 gunichar;
になっているけど、つまりは 4 byte ということだし。
いわゆる普通に Unicode と呼ばれているものは gunichar2 でいいみたい。

変換は UTF-16 ではなく UCS-4 にしたほうがよさげ。
g_unichar_to_utf8 なんて楽できそうな関数もあるわけで。
Unicode Manipulation

UTF-16 に変換しようと考えてしまう所はやはり Windows でしかプログラミングできなかった頃のバカな頭がまだ抜けきらないということか。
でも UCS-4 でも str[int] の添字でイケるのかな、実験だ。

test.c

#include <glib.h>
#include <string.h>

int
main (int argc, char *argv[])
{
    /* Including Japanese characters */
    gchar c[] = "Linux 勉強中";
    /* UTF-8 Length */
    g_printf ("%s is %d characters\n", c, g_utf8_strlen(c, sizeof(c)));
    /* Converted to UCS4 */
    GError * error = NULL;
    gunichar * ucs;
    glong len = sizeof(c);
    ucs = g_utf8_to_ucs4 (c, -1, NULL, &len, &error);
    if (!ucs) {
        g_print (error->message);
        int retval = error->code;
        g_error_free (error);
        return retval;
    }
    /* Export single character */
    int i = 0;
    for (i; i<len; i++) {
        gchar cc[4];
        memset(&cc, '\0', sizeof(cc));
        g_unichar_to_utf8 (ucs[i], cc);
        g_printf ("%s\n", cc);
    }
    g_free(ucs);
    return 0;
}

Makefile

ucs: test.c
	gcc -o ucs test.c `pkg-config --cflags --libs glib-2.0`

ucs.tar.gz

添字で普通に一文字づつ取り出せるみたいね。
変換エラーチェックを入れてもコレだけだ、簡単。

しかし memset しないと ‘\0’ を入れてくれない。
まあそりゃ普通に char の %c 指定ならンナモンいらないわけだし。
どうでもいいけど ZeroMemory は Windows しか使えないと今頃知った。
やっぱり Windows でしかプログラミングをやらないのではバカになる。

端末入力なら下記でイケるみたい。
\n が入ってしまうので強引に \0 を挿入とかしているけど。

#include <glib.h>
#include <stdio.h>
#include <string.h>

int
main (int argc, char *argv[])
{
    /* Including Japanese characters */
    gchar c[256];
    fgets(c, sizeof(c), stdin);
    /* Remove '\n' */
    c[strlen(c)-1] = '\0'; 
    /* Length */
    glong len = g_utf8_strlen(c, sizeof(c));
    g_printf ("%s is %d characters\n", c, len);
    /* Converted to UCS4 */
    GError * error = NULL;
    gunichar * ucs;
    ucs = g_utf8_to_ucs4 (c, -1, NULL, &len, &error);
    /* Export single character */
    int i = 0;
    for (i; i<len; i++) {
        gchar cc[4];
        memset(&cc, '\0', sizeof(cc));
        g_unichar_to_utf8 (ucs[i], cc);
        g_printf ("%s\n", cc);
    }
    g_free(ucs);
    return 0;
}

なんかもっとスマートな方法がありそうな気がするけど。

TenKey

先日 Y901x を +,- キーで再生速度変更できるようにした。
まてよ、テンキーの +,- キーの存在を忘れていた!

だってオイラの RealForce にはテンキーが無いモン。
それに英語配列だと丁度いい位置に +,-,= キーがあるので私自身はコレでいい。
けど一応公開アプリなんだよな。

日本語配列だと絶対に + が押しにくいと思うし。
「テンキーも使える」にしておけば大半の人が問題無いだろう。
等速に戻す = キーの代わりはテンキーの Enter で代用かな。

更にメディアキーなんつーものも存在するのを今頃気がつく。
昔使っていたテンキーとメディアキーの付いている日本語配列キーボードを引っ張り出して実験と対応処理をすることにした。

テンキー超邪魔、スペースキーちっさ、いらないキー多すぎ!
せめてテンキーは左側に付けてくれと、マウス置き場に困る。
最近のノートパソコンとか何を考えて無理やりテンキーを載せているの?
ついでに記号を間違えまくる、慣れって怖い。

とにかく xev を使ってテンキーの割り当てを調べる。

gtk.keysyms.KP_Add
gtk.keysyms.KP_Subtract
gtk.keysyms.KP_Enter

なのね、コレさえ解れば処理は簡単。
KP_Plus とかが gtkkeysyms で見つからなかったけどこんな名前なのね。
NumLock off でもコレらのキーコードは同じだと今頃知った。

次はメディアキー。
だが、xev で確認できない。

totem のソースを見る。
totem-media-player-keys.c を見ると DBus を使っている。
DBus って 0.3.3 の時にマルチスレッド処理に影響が出たので外したんだが…
できれば避けたい。

というか今頃気がついたけど Rhythmbox や Totem はアクティブでない場合でもメディアキーに反応するのね。
BGM を流した状態で作業を行っている最中に再生アプリをアクティブ化せずとも Play/Pause や次を再生にできるということ。
Global Hotkey というみたい。

検索してみるとこのキーを使っている人って結構多いのね。
WinAmp とか有名どころは上記動作ができたらしい。
パソコンで音楽なんて聴かないから知らなかったよ。
というか音楽自体を全然聴かなくなったような…

つか動画では無意味な機能だ。
バックグラウンドムービーなんて相当痛々しい奴しかやらネェってば。

よし、Y901x では無視しようw
ということで変更はソレだけなのだけど 0.3.9 の公開。

それよりキーボードのストレスが凄い、RealForce に戻す。

とはいえ Global Hotkey というのは少し興味ある。
常駐している秀丸をホットキーで呼び出すみたいな動作を Linux でやりたいとか思う時があるかもしれない。
GNOME なら Alt+F2 を使えで終わるけどさ。
「gnome-ter」まで打ち込んで Tab キーを叩くとあら不思議みたいな。
…やっぱりいらないな。