くりーむわーかー

プログラムとか。作ってて ・試しててハマった事など。誰かのお役に立てば幸いかと。 その他、いろいろエトセトラ。。。

プログラム

AWS CDK AutoScaling+ALBの制約

AutoScalingをLBのターゲットにするとき、Stack通して1ターゲットでしか使えなくなってる。

下記エラー。

Cannot add AutoScalingGroup to 2nd Target Group

で、これのISSUE

困ってる人はそこそこいるような気がしますが、まだ入らないっぽいですね。

コレ出来ないと、一つのサーバ内でポート分けて複数のアプリを動かすのが無理なんだよなー。

ISSUEに記載の回避策を試してみるか。。。

Python インクリメントもどき

Pythonには他の言語で言うところのインクリメントの式がない。

「i++」こういうやつ。

言うほど困らないのですが、例えば、

a["hoge"] = x[i++]
a["fuga"] = x[i++]

みたいな事、書きたくなった時に1行で評価するの書けないので、

i += 1
a["hoge"] = x[i]
i += 1
a["fuga"] = x[i]

みたいに書くしかない。

どうにかして「x[i++]」みたいな書き方したいなーと、やっきになってみた。

グローバル変数的なものとか、クラス変数みたいな外部に変数置くのは無しで。


結論:無理矢理出来た。

他にもいいやり方あるんだろうなーとは思いますが、ちょっと探してみても出てこなかったので記載。

  • 結果のコード
def make_counter():
    def count_up(dummy=[]):
        dummy.append(1)
        return len(dummy)

    return count_up

counter = make_counter()

x[counter()] = 1
x[counter()] = 2
x[counter()] = 3


Pythonの関数定義でdefault値を定義出来るのですが、このdefault値って結構特殊な動きをする。

公式にも確か注意してね、みたいな事が書いてあったと思う。

特にlistとかdictみたいなオブジェクトをdefault値にすると、デフォ値の参照が固定される。

def xyz(a=[]):
   a.append(1)
   print(a)

xyz() -> [1]
xyz() -> [1,1]
xyz() -> [1,1,1]
xyz() -> [1,1,1,1]

↑みたいな。で、この性質を使って無理矢理作った感じ。


めちゃんこダサいのですが、まー1行で評価までいけたからとりあえずいいかな?

他にいい方法あったらぜひぜひ教えていただきたいです。

python classかどうかを判定

メタプログラミングみたいなことやってると、クラスの判定みたいなことをやりたくなる。

typeとかisinstanceとかは良く見るのですが、class定義なのかどうなのかの判定をしたい場合。

import inspect

# class定義かどうか(これが結構出てこない)
print(inspect.isclass(mod))

# オブジェクトがclassのインスタンスかどうか
print(isinstance(obj, XXX))
print(type(obj) == XXX)

# AがBの子classかどうか
print(issubclass(XXX,XXX))

CentOS AmazonLinux で デスクトップのGifアニメを録画するツール

デスクトップのGif動画を撮るツールってScreenToGifっていうのがWindowsではある。

ScreenToGif( 公式 | GitHub )

で、Linuxで似たようなツールを探したのですが、下記がインストールも楽だった。

peek ( GitHub )

ReadMeには色んなインストールが載ってて分かりにくいのですが、

CentOS、AmazonLinuxなら下記flatpak使うのが楽っぽい。

# flatpakを入れて、flathubのリポジトリ登録
sudo yum install flatpak
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

# 端末再起動

#peekのインスト
flatpak install flathub com.uploadedlobster.peek

#peekの実行
flatpak run com.uploadedlobster.peek

使い勝手もなかなか良いと思います。素晴らしい。

CSVのRFC

完全にメモ。

RFC4180 [原本] [和訳]

CapsLockとUX

とある解説サイト?見てたら、記事のランキングで下記になってた。

img-rank

「週間8位がCapsLockってマジか、、、」と一瞬思ったんだけど、そういえばPC触り始めは自分も似たような事思ったなーとか懐かしくなった。


っていう事はですよ、これが8位になるくらい、CapsLockってUX的にダメなんじゃね?と。

知らず知らずのうちに、自分も常識にハマってるなー。

アインシュタインさんも

常識とは十八歳までに身につけた偏見のコレクションのことをいう

なんてこと言ってますし、「そういうもんだ」と思ってるところってかなり怪しいところでもあるよね。

とか思った昼下がりなのでした。

各ブラウザのサロゲとIVSとIPAmj明朝の表示

IPAがやっている、IPA文字情報基盤というのがある。

https://mojikiban.ipa.go.jp/

そこで出しているフォントがIPAmj明朝。

結構前からやってたと思うのですが、そろそろ各自治体での利用が

広がりそうなのでちょっとまとめ。マイナンバーのフォントはこれ使ってるらしい。

ほんとかどうかは不明。

前に国が似たようなブラウザ表示の確認をやってて、報告書みたいなのがネットに転がってたと思うのですが、相当古かったと思うので今の時点だとどうかというところ。


日本語で気を付けないといけないのは、通常のUniの文字以外に、

UNI+IVS、サロゲ、サロゲ+IVSあたりがある。※あとは外字。

IPAmj明朝はそういうところもやってるので、表示が出来るかどうかというところ。

とりあえず、Chrome・Edge・Firefoxの結果。

使った各ブラウザのバージョンは下記。

Chrome
86.0.4240.183(Official Build) (64 ビット)

FireFox
82.0.2 (64 ビット)

Edge
Microsoft Edge 42.17134.1098.0
Microsoft EdgeHTML 17.17134


OSはWindows10

フォント指定のCSS

.ipafont {
  font-family: 'IPAmjMincho', 'IPAmj明朝';
}


font-test

実HTML置いておくので、自環境で確認したい場合はご利用ください。※クライアントにIPAmj明朝インストールしないとまともに表示されません。

パターン CODE 字(HTML) input textarea 正解画像
UNI u+845B MJ022336
UNI+IVS u+845B U+E0102 葛󠄂 MJ022335
サロゲ U+20000 𠀀 MJ030312
サロゲ+IVS U+20000 U+xE0101 𠀀󠄁 MJ030313

UNIとUNI+IVSはどのブラウザも問題無し。

問題はサロゲ。EdgeとFireFoxはOK。ChromeはIPAフォント使えてない...

Chromeさんバグってます?

あと、inputのmaxlength。

Edgeだけはどのパターンの文字も一文字としてカウントしてくれてる。

FireFoxとChromeさんは例えば、maxlength="4"って指定しても、サロゲ+IVSなんかだと、1文字しか入力できなくなる。

日本語の文字・フォントの扱いは「Edge > |超えられない壁| > FireFox > Chrome」って感じかしら。

Edgeがだいぶ優秀ですね。

つか、日本語みたいな少数民族の文字なんて英語圏の開発者からみたら正直どうでもいいでしょうしね。しょうがないと言えばしょうがない...

inputのmaxlengthは自前で作らないとダメそう。

chromeさんの表示がダメなのは治るのを期待して気長に待つしかないかな?

と思ったけど、別環境のchromeで見るとちゃんと表示されてる...

ん?何か違うか?謎。要確認。

追記

Chrome、複数環境で何個か確認したけど、やっぱりちゃんと表示されていた(Linux含む。

最初に確認した環境のみおかしいっぽい。Chromeさん濡れ衣でした。スミマセン。

でも何で最初の環境はおかしいんだろうか?EdgeとかFireFoxは大丈夫なんだけども...


あと、以下のIPAが出してる文字一覧でひそかに謎の定義が存在する。

ipa-moji

”ここだけ”IVS定義が重複して存在するという...

ホントこういうのは止めて欲しいところ。何か理由があるのでしょうけども。


2021/1/2追記

自治体システム標準化でこのフォントが標準になっていくと思うのですが、Webで扱うにはデカ過ぎるんですよね。本体30MBくらいあったと思う。これWebフォントにしろとか言わないよね...

標準化するならクライアントにこのフォントをインストールする前提で考えさせてほしいところ。

昔に比べたら十分早くはなっていると思うのですが、全面Webフォントとかクソ重くなりそう...

業務システム的に考えると、結局CSVとかエクセルとか落として、事務的な計算とかをやるので、そっちでフォント使えないと結局アレですし。ローカルインストール前提にして欲しいよね。

まーでも、人名や住所で外字がなくなるとは思えないので、IPAmj明朝にする意味がどこまであるのやら。。。

標準システムで、本気で外字の利用をNGにしてくれるんならいいんだけどなー。まー無理そう。国としてオープンデータの流れに持っていきたいのであれば、この辺の基礎的な部分はガチガチに固めてくれてもいいと思うんだけど。

SEの端くれ的な感覚で、エンジニア側の都合だけで考えれば統一してよって感じではある。何もしないで標準で動くのが一番良い。というか楽。

ただ、やっぱり自分の名前や文字っていうのは一つの文化なわけで、そこのこだわりを捨てろっていうのも暴論な気もするし難しいところですね。

全国で文字の字形の同定を行って外字に入ってる文字の統一は、作業的には出来なくはない(恐ろしく手間かかるし、泥臭い作業になりますが。。。

ただ、それをやった場合に、既存データの置き換えを自治体毎に置換のPG組まないとダメそうだし、データ移行な作業もとんでもないコストかかりそうだし、やっぱりなかなか難しそうですね。。。

サロゲートとIVSの正規表現

サロゲートとIVSの正規表現まとめ。

IVS含めたものってなかなか見ないので。

どうなんだろ。皆どうやってるんでしょね。


サロゲートのコード範囲

上位サロゲート:U+D800-U+DBFF

下位サロゲート:U+DC00-U+DFFF

IVSのコード範囲

32bit表現:U+E0100-U+E01EF

で、これの16bit表現がなかなか出てこなくて困った。

なので計算して求める。とりあえず結果。

16bit表現:U+DB40 [U+DD00-U+DDEF]


なので、正規表現は下の感じ。

// javascript

// サロゲートがあるかどうか
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF])/)

// IVSがあるかどうか
str.match(/(\uDB40[\uDD00-\uDDEF])/)

// サロゲート+IVSがあるかどうか
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF])|(\uDB40[\uDD00-\uDDEF])/)

// サロゲートを含む文字列を一文字ずつの配列にする
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])/g)

// サロゲート+IVSを含む文字列を一文字ずつの配列にする
str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])(\uDB40[\uDD00-\uDDEF])?/g)

32bit表現が使える場合は下の感じ

//Python

// サロゲート+IVSを含む文字列を一文字ずつの配列にする
re.findall('([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])[\U000E0100-\U000E01EF]?', strs)


IVSの32bit表現を16bit表現にする計算。

計算方法:wiki : 拡張領域→サロゲートペアの項

0xE0100            1110 0000 0001 0000 0000
0xE01EF            1110 0000 0001 1110 1111

上をサロゲートペアとしてエンコーディング

①0x10000を引く

 0xE0100            1110 0000 0001 0000 0000
-0x10000            0001 0000 0001 0000 0000
=0xD0100            1101 0000 0001 0000 0000

 0xE01EF            1110 0000 0001 1110 1111
-0x10000            0001 0000 0001 0000 0000
=0xD01EF            1101 0000 0001 1110 1111

➁これを上位10ビット値と下位10ビット値に分割する。

0xD0100            1101 0000 00(0x0340)    01 0000 0000(0x0100)
0xD01EF            1101 0000 00(0x0340)    01 1110 1111(0x01EF)

➂ハイサロゲート形成として上位ビットに0xD800を加える。

 0x0340            0000 0011 0100 0000
+0xD800            1101 1000 0000 0000
=0xDB40            1101 1011 0100 0000

 0x0340            0000 0011 0100 0000
+0xD800            1101 1000 0000 0000
=0xDB40            1101 1011 0100 0000


④ローサロゲート形成として上位ビットに0xDC00を加える。

 0x0100            0000 0001 0000 0000
+0xDC00            1101 1100 0000 0000
=0xDD00            1101 1101 0000 0000

 0x01EF            0000 0001 1110 1111
+0xDC00            1101 1100 0000 0000
=0xDDEF            1101 1101 1110 1111

⑤上記から

0xE0100 ⇒ \uDB40\uDD00
0xE01EF ⇒ \uDB40\uDDEF

⑥なのでコードの範囲は下位8bitの範囲(00-EF:240個)として表現しちゃってよい(上16bit分は固定)ので下記正規表現

\uDB40[\uDD00-\uDDEF]

PythonとサロゲートとIVS

PythonのIVS(異字体セレクタ)対応を調べてたのですが、全く出てこない...

誰も困ってないのかしら?

Pythonで普通に文字数とか取得しようとするとIVSはとりあえずダメになると思うんだけど。

s = '\U00008FBB'
print(s, len(s))  # 辻(2点ツジ), 1
s = '\U00008FBB\U000E0102'
print(s, len(s))  # 辻(1点ツジ), 2

色々調べたのですが、lenとかsubstringとか良い感じにカウントしたり、処理したりしてくれるライブラリ的なものも無い。。。

どーなんだろ。

まーいいや。ないなら作るしかあるまい。

という事で作った。

# 文字数カウント
def newLen(s):
    l = re.findall(
        '([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])[\U000E0100-\U000E01EF]?', s)
    return len(l)

# substring
def newSubstring(s, st, ed):
    l = re.findall(
        '([\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])[\U000E0100-\U000E01EF]?', s)
    return ''.join(l[st:ed])

substringの方はかなり適当でエラー処理的なものとかガン無視。

重要なのは正規表現でサロゲとIVS考慮で一文字ずつの配列に変換して、

その配列の要素数やsliceでsubstringの代替をする感じ。

出来上がる配列は↓の感じ。

"あ\uE000\U00008205\U00008204\U000E0101\U00020C25\U0002B7CB\U000E0102"
↓
["あ","\uE000","\U00008205","\U00008204\U000E0101","\U00020C25","\U0002B7CB\U000E0102"]
※[普通の字 , 外字 , UNI , UNI+IVS , サロゲ , サロゲ+IVS]

ちなみに、javascriptでもほぼ同じロジックで同じこと出来るはず。

ただ、まともに検証してないので、今度ちゃんとやろ。

CentOS7 Python3.9のインストール

まだyumのリポジトリとかには登録されてなさそう?

なのでソースからコンパイルする必要がある模様。

# コンパイル辺りに必要なもの
sudo yum install gcc openssl-devel bzip2-devel libffi-devel zlib-devel 

# ソース取得
wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz 
tar xzf Python-3.9.0.tgz 

# make install
cd Python-3.9.0
sudo ./configure --enable-optimizations
sudo make install

#確認
python3.9 -V

#仮想環境作っておく
cd ~/
python3.9 -m venv pyenv3.9

#仮想環境に切り替え
source ~/pyenv3.9/bin/activate
問合せ