Python」タグアーカイブ

Python switch (match)

Python コードを書いていて文字列前後の空白を削除する必要があった。
うっかり trim() と書いたんですけど、こんな例外が。

trim

教えてくれてありがとう、Python では strip() でしたね。
いやぁ筆者を含めて Javascript と混同する人が多いんだろうな。
てかいつのまにこんな親切な例外表示になったんだ?

What’s New In Python 3.10 ? Python 3.10.4 ドキュメント

特に記述は無いけど Better error messages の一つかな。

そんなこんなで上記ページを初めて見たんですけど。
あら Python にもとうとう switch 文が、いや match ですけど。
と思ったんですけど何か変。

break いらないの?

#!/usr/bin/gjs

function func(num) {
    switch(num) {
        case 1:
            print('one');
            //break;
        case 1:
            print('once again');
            //break;
        default:
            print('default!');
    }
}

func(1);

/* output
one
once again
default!
*/

switch 文だとこうなる、C 言語等も同様。

#!/usr/bin/env python3

def func(num):
    match num:
        case 1:
            print('one')
        case 1:
            print('nce again')
        case _:
            print('default!')

func(1)

''' output
one
'''

なるほど、だから switch ではなく match か。

というかコレ if-elif-else の別表記でしかないんだな。
以上とか未満みたいな case はできないみたいだし使い所は微妙。
読みやすくなるかわりに階層が深くなるデメリットも。

でも一番問題なのは。。。。。
Gedit や gnome-text-editor で現状では強調表示されないことかも。

# Gedit
/usr/share/gtksourceview-4/language-specs/python3.lang

# gnome-text-editor
/usr/share/gtksourceview-5/language-specs/python3.lang

に自分で追記すればイケるはず、必要ならばだけど。
4 が GTK3 で 5 が GTK4 なのよ、バージョンがややこしくなったもんだ。

Fedora 36: ibus-anthy

PageUp/PageDown do not work to scroll candidates ? Issue #27 ? ibus/ibus-anthy ? GitHub

ibus-anthy の変換候補が PageUp/PageDown でページめくりできない件。
ずっと Wayland 対応が理由だと思っていたけどこれバグだったのか。

てかこの uneyama って人スゲェな、よくこんなの見つけたなって。
差分バッチを提供してくれているけど、当ててくれるかどうかだ。

anthy

今の anthy は Red Hat が管理しているはずなんだけどなぁ。
とはいえ anthy って Python 製なんだし。

/usr/share/ibus-anthy/engine/engine.py

を二行ほど書き換えするだけだ、自力バッジでやってもいいかも。

#!/usr/bin/env python3

'''
    コピペして sudo で実行しログインのやりなおし
    sudo python コピペしたソース.py
'''

import os

os.chdir('/usr/share/ibus-anthy/engine')

with open('engine.py') as f:
    txts = f.read().split('\n')
    s = txts[1521].strip()
    if s == 'self.do_page_up()':
        print(f'{s} を self.__page_up(0) に書き換え')
        with open('engine.py', 'w') as f:
            txts[1521] = '            self.__page_up(0)'
            txts[1528] = '            self.__page_down(0)'
            f.write('\n'.join(txts))

一旦ログアウトしてログイン。

よし PageDown が動くようになった。
Python の open ってネストできるんだ、勉強になって一石二鳥。

万が一失敗したら gnome-softwere から入れ直しで元通り。
今まで ibus-kkc に即換えしていたけど当分コレを使ってみる。
mozc は US 配列 RealForce だと不便なだけだし。

あと wmv ファイルがあるディレクトリを Nautilus で開くとが落ちる。
wmv のサムネイルを作成しようとしてクラッシュしているようです。

GStreamer: open source multimedia framework

GStreamer の対策版は出ているようだけど。
令和の現在ではそれほど問題にはならないしコレはのんびり待つか。

PHP を入れたら PHP 8.1.5 になっていた。
筆者の使用範囲では PHP7 と同様だけどコレも勉強しないとな。

今日はここまで。

GExif2 0.10 metadata

カメラを縦向きで撮影した写真は OM SYSTEM も LUMIX と同じだった。
つまり普通の横向き写真の Exif に回転情報を付加したもの。
検索すればすぐ解るけど反転情報を含めて 1 から 8 まである。
macOS の場合はプレビュー.app のインスペクタで「方向」にて確認できる。

1

ちなみにプレビュー.app は画像の回転情報の書き換えが可能。
command+R で回転させて command+S で上書き保存するだけ。

Fedora は Nautilus でも EOG でも確認できない。
よし GExif2 を使ってスクリプトを、と思ったら。

2

get_orientation が非推奨に。
代替え関数は何だ?

Generic image metadata handling: gexiv2 Reference Manual

どうやら try_*** の関数に変更する時に不要とされたみたい。
タグは以下で確認できる。

Exiv2 – Image metadata library and tools

ということで。
説明は macOS のインスペクタと同じになるよう Python で作ってみた。
回転方向はカメラの向きなので人によっては逆で説明している。

#!/usr/bin/env python3

import sys, gi
gi.require_version('GExiv2', '0.10')
from gi.repository import GExiv2

DESC = [
	'無し',
	'標準',
	'水平方向に反転',
	'180°回転',
	'垂直方向に反転',
	'反時計回りに90°回転および垂直方向に反転',
	'反時計回りに90°回転',
	'時計回りに90°回転および垂直方向に反転',
	'時計回りに90°回転']

with open(sys.argv[1], 'rb') as f:
    metadata = GExiv2.Metadata()
    metadata.open_buf(f.read())
    #ori = metadata.get_orientation() # Deprecate
    num = metadata.try_get_tag_long('Exif.Image.Orientation')
    print(f'{num} ({DESC[num]})')

3

時代は OS 標準、足りない機能はスクリプトですよ。
なんかさ、フリーソフトって文化はもう終わっているよね。

しかし M1 Mac って本当に速いんだな。
ハイレゾショット五千万画素写真の表示に一秒かからない。
i5 6500 マシンの Fedora では三秒もかかるのに。

それと OM SYSTEM の RAW も Finder で普通にサムネイル表示。
でもハイレゾショットの巨大な ORF では表示しないようです。

4

いやハイレゾは多分使わないけど、実験してみたかっただけ。
小型で機動力がウリのカメラに三脚必須機能なんてあってもさ。

M1 Mac Setting

macOS のサンドボックスってこんなにウザかったっけ?

sandbox1

端末アクセスごときにチマチマ許可を与えるのが面倒すぎる。
とっとと端末のサンドボックス設定をフルディスクアクセスに変えよう。
zsh という意味ではないです、Terminal.app のみに適用される。

full_disk

それと、こんなのを見つけたので前回の PyObjC を試す。

Macで実行しているアプリがIntel x86_64かApple Silicon arm64アーキテクチャかをメニューバーに表示してくれるオープンソースのユーティリティ「Silicon Info」がリリース。 | AAPL Ch.

端末から Python3 に渡して起動すると arm64 になる。
Atom から command+option+T で起動する端末は arm64 になる。
Atom から atom-runner でプロセス起動すると Intel になる。

Rosetta2 で起動した Python3 でも PyObjC は使えたんだね。
まあ Atom が arm64 になるまで端末利用かなって。

後は apache だな。
どうせまたアップデート毎に httpd.conf が初期化されるので。

#!/usr/bin/env python3

'''
    # Run on root
    sudo python3 httpd_rewrite.py
    #
    # start or restart
    sudo apachectl restart
    #
    # Auto start of service
    sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
'''

import shutil

CONF = '/etc/apache2/httpd.conf'
out = []
# User Rewright
ROOT = 'DocumentRoot "/Users/sasakima-nao/www"\n'
DIRC = '<Directory "/Users/sasakima-nao/www">\n'

shutil.copyfile(CONF, 'backup_httpd.conf')

with open(CONF, 'r') as f:
    for line in f:
        if 'php7_module' in line:
            out.append(line[1:])
        elif line.startswith('DocumentRoot'):
            out.append(ROOT)
        elif '<Directory "/Library/WebServer/Documents">\n' == line:
            out.append(DIRC)
        else:
            out.append(line)

with open(CONF, 'w') as f:
    for s in out:
        f.write(s)

以前 JXA で作ったけど手抜きだったので Python で描き直し。
これで同じ LAN に繋がった iPhone 等から
http://コンピュータ名.local
でアクセスできる、てか今までと変わっていなかった。

http

Mac の人は面倒なのに vim で書き換えしている人ばかりなのは何故?
スクリプトを作っておけば初期化されても一発で書き換えできるのに。
Python とかのスクリプト言語ってこういうことをする為にある。

これで 2018 Air の頃と同じように使えるようになった。
後は Lightroom か、arm64 版も出たみたいだし。
その前にサブスクについてもう少し調べなきゃだが。

macOS tree command

前回 CommandLineTools 以下に「SDK 丸ごと落とされる」と書いた。
情報として何という名のファイルが「ドコにドンダケ」ってほど入ってしまうのかを公開したい。
tree というまさしくソレ用みたいなコマンドがある。

あぁ、このコマンドって使い道があったんだなぁって思った筆者であった。
けれど macOS には tree コマンドが入っていなかった。

Fedora なら使えるのでリモート接続してリダイレクトしようかなと。
てなわけで、sftp でリモート接続した Fedora から tree コマンドを打ってみた。
けど、何時間たっても処理が戻ってこなくて諦めた。
こんなに遅いはずがない、サンドボックスかな?

普通に「macos tree コマンド」と検索するとションボリ。
何故みんなコンパイラを手に入れたのにインストールしかしないの?
brew 使う人って(以下略
てか Catarina 以降だと Gatekeeper にブロックされると思うんだけーが。

Catalina時代の「GateKeeper」と付き合う方法 – 新・OS X ハッキング!(257) | マイナビニュース

spctl は Windows でいうウイルス対策アプリを無効にする手段。
慎重に活用とかアホかと、その必要があるアプリは淘汰されるべき。

で。

実はそんなことをしなくても検疫機能を回避する方法がある。
自分でビルドすればいい、もしくは自分でスクリプトを書く。

tree コマンドが無い環境で tree コマンドを実現 – Qiita

シェルスクリプトだけでがんばった人がいた。
これでもいいけど、よし筆者は Python でがんばってみよう。
macOS で動かせるように標準モジュールだけを使う。

#!/usr/bin/env python3

'''
    tree command in Python 3.7
'''

import os, sys

all_dir_num = 0
all_file_num = 0

def flist(path):
    '''
        Exclude UNIX hidden files. and sorted.
    '''
    l = os.listdir(path)
    res = []
    for f in l:
        if f.startswith('.'): continue
        if f.endswith('~'): continue
        res.append(f)
    return sorted(res)

def tree(path, tab):
    files = flist(path)
    length = len(files)
    head = '├── '
    num = 1
    for f in files:
        if num == length:
            head = '└── '
        subdir = os.path.join(path, f)
        if os.path.isdir(subdir):
            if sys.stdout.isatty():
                # stdout
                print(f'{tab}{head}\033[34m{f}\033[0m')
            else:
                # Redirect
                print(f'{tab}{head}{f}')
            global all_dir_num
            all_dir_num += 1
            # Recursion
            tree(subdir, f'{tab}│   ')
        else:
            print(f'{tab}{head}{f}')
            global all_file_num
            all_file_num += 1
        num += 1

if __name__=='__main__':
    d = '.'
    if len(sys.argv) > 1:
        d = sys.argv[1]
        if d.startswith('~'):
            d = os.path.expanduser(d)
    print(d)
    tree(d, '')
    # footer
    print(f'\n{all_dir_num} directories, {all_file_num} file')

tree

stdout で色を付けるとリダイレクトでアララとなるから振り分けしてね。
os.listdir はカレントディレクトリならドットでいいのか、へー。

中身が一つだけの時に前の縦線を消すナイスな方法は思いつかなかった。
その中身がディレクトリで更に中身が一つだった場合等でチグハグになる。
それとディレクトリを青色にしたけど tree コマンドとなんか色が違う。
とはいえ完全に同じにする必要は無いんだしコレでいいかなと。

コレを mac で自分がパスを通した場所にコピーして。
tree という拡張子の無い名前を付け +x パーミッションを付けて。

tree /Library/Developer/CommandLineTools > cltool.txt

したものを置いておきます。
十七万五千行、17MB になってしまったので zip 圧縮した。
cltool.zip

python3 は先に自分で入れたものなのかコレに含まれているのかは解らない。
まあ微々たる差だ。
それより macOS だと場所によってはサンドボックスに引っ掛るのが困る。