中野智文のブログ

データ・マエショリストのメモ

linux で文字化けしたときにやることメモ

背景

毎度Linuxを始めに使うとき文字化けしてググっているのでメモ。日本語を使わないという選択肢もあるけど、データの中身が日本語だったりすると、結局やらなくちゃいけないことになる。

方法

locale コマンドで確認

$ locale -a

すると、こんな感じで日本語入っていない。(WSL2の場合)

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
C.UTF-8
POSIX
en_US.utf8

locale.gen を編集

$ sudo vi /etc/locale.gen

で、

ja_JP.UTF-8 UTF-8

のコメントを外す。

locale-gen の実行

$ sudo locale-gen

これで有効化されるはず、念の為、locale -a などで確認

まとめ

文字化けしたときに思い出したいコマンド locale

Dell の Ubuntu モデルを探す

背景

Dellのコンピュータで、Ubuntsu モデルを探したい。なかなか見つからない。

方法

build your own というのがOSなどが選べるモデルとなる。よってそれをキーワードサーチして検索する。 それが次のリンク。

www.dell.com

まとめ

14インチFULLHD、メモリ16GB、英語キーボード、Ubuntsu、だと、こんな感じ(133,760円)。

www.dell.com

15インチFULLHD、メモリ16GB、英語キーボード、Ubuntsuだと、こんな感じ(133,100円)

www.dell.com

いずれも、CPUをceleron にしてケチっていますが…。メモリをケチってビルド自体できないことがあるってのがいいわけ。

emacs の cask が "Missing dependency" とか表示されてうまく行かない

背景

emacs の package をガバっとインストールできてめちゃくちゃ便利な cask ですが、emacs version 26 以上になると調子悪い。

対策その1: もう cask に頼らない

emacs -q で起動後、

下記を eval する。

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")

その後、

(require 'package)

;; package-archivesを上書き
(setq package-archives
      '(("melpa" . "https://melpa.org/packages/")
        ;; ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("org" . "https://orgmode.org/elpa/")
        ("gnu" . "https://elpa.gnu.org/packages/")))

;; 初期化
(package-initialize)

みたいな感じで package を読み込み、

の後、

M-x package-refresh-contents

その後、

M-x package-install <install したいパッケージ名>

で個別にインストール。

対策その2: やっぱり cask コマンドを使う

~/.cask/bin/cask.el

の初めの方の行に、

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")

を貼り付けて保存した後、cd ~/.emacs.d/ に移動し、cask を実行

gsutil compose で 32より多いファイルを結合したいとき

背景

gsutil compose はファイルを結合する便利コマンド。しかし32より多いファイルは結合できない。

解決策

xargs -L31 を使う。

 echo -n | gsutil cp - gs://your-bucket/total.gz
 gsutil ls gs://your-bucket/your_file*.gz | xargs -L31 | xargs -I{} echo gsutil compose gs://your-bucket/total.gz {} gs://your-bucket/total.gz | sh

ここで、your-bucketバケット、total.gz はコピー先、your_file*.gz はコピー元を示す。

詳細

本当は xargs を一つにまとめたかったのだが、-I オプション(リプレイス)を使うと、強制的に -L31-L1 に変更されてしまうので、こうなった。 また echo ... | sh になっているのは、リプレイス先がスペースを含んだ複数のファイルが一つのファイルと認識されてしまうため。

Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。

background

firestore からデータを取得する良い方法を探して公式ドキュメントを眺める。

firebase.google.com

すると、

一部の言語では、カスタムのオブジェクト タイプを使用する方が便利な場合が多くあります。

と書いてあるではないか?

doc_ref = db.collection(u'cities').document(u'BJ')

doc = doc_ref.get()
city = City.from_dict(doc.to_dict())
print(city)

Cityというカスタムのオブジェクトタイプに戻すのか。pythonはどうやらfrom_dict関数によってサポートされているらしい。

カスタムのオブジェクトタイプとは?

どうやらデータの追加のセクションにあるらしい。

firebase.google.com

つぎのような心強いお言葉が。

Cloud Firestore では、カスタムクラスを使ったドキュメント作成をサポートしています。
Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。

Webのサンプルコードは次の様。

class City(object):
    def __init__(self, name, state, country, capital=False, population=0,
                 regions=[]):
        self.name = name
        self.state = state
        self.country = country
        self.capital = capital
        self.population = population
        self.regions = regions

    @staticmethod
    def from_dict(source):
        # ...

    def to_dict(self):
        # ...

    def __repr__(self):
        return(
            f'City(\
                name={self.name}, \
                country={self.country}, \
                population={self.population}, \
                capital={self.capital}, \
                regions={self.regions}\
            )'
        )

肝心な from_dict クラスは省略されている。このカスタムオブジェクトクラスも、単なる objectクラスから作られていない?

Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。

ってどういう意味だろう。日本語の翻訳誤りかな。英語で見てみると、

Cloud Firestore converts the objects to supported data types.

誤りはなさそうだ。。。だが、何もサポートされていないじゃないかな…。一応コードを見てみる。

github.com

全部自前でやってるじゃないか。どこにもライブラリでなんとかしている箇所がない。

まとめ

Cloud Firestore は、オブジェクトをサポートされているデータ型に変換しません。 ご自分で頑張って下さい。

BQで地域メッシュコード(2分の1)のポリゴン

背景

BQで地域メッシュコード(2分の1)からポリゴンを作ることになった。

クエリ

とはいっても、ほとんど temp function ですが。

create temp function INT(S STRING) AS (CAST(S AS INT64));
create temp function STR(F FLOAT64) AS (CAST(F AS STRING));
create temp function FINT(F FLOAT64) AS (CAST(F-0.5 AS INT64));
create temp function SS1(CODE STRING, POS INT64) AS ( INT(SUBSTR(CODE, POS+1, 1))); 
create temp function SS2(CODE STRING, POS INT64) AS ( INT(SUBSTR(CODE, POS+1, 2))); 
create temp function LA4(CODE STRING) AS (FINT((SS2(CODE, 8)-1)/2));
create temp function LAT4(CODE STRING, I INT64) AS ((SS2(CODE, 0)+(SS1(CODE, 4)+(SS1(CODE, 6)+(LA4(CODE)+I)/2)/10)/8)/1.5);
create temp function LAT40(CODE STRING) AS (STR(LAT4(CODE, 0)));
create temp function LAT41(CODE STRING) AS (STR(LAT4(CODE, 1)));
create temp function LO4(CODE STRING) AS (FINT(MOD((SS2(CODE, 8)-1), 2)));
create temp function LON4(CODE STRING, I INT64) AS (SS2(CODE, 2)+100+(SS1(CODE, 5)+(SS1(CODE, 7)+(LO4(CODE)+I)/2)/10)/8);
create temp function LON40(CODE STRING) AS (STR(LON4(CODE, 0)));
create temp function LON41(CODE STRING) AS (STR(LON4(CODE, 1)));
create temp function WKT4(CODE STRING) AS ("POLYGON((" || LON40(CODE) || " " || LAT40(CODE) || ", " || LON41(CODE) || " " || LAT40(CODE) || ", " || LON41(CODE) || " " || LAT41(CODE) || ", " || LON40(CODE) || " " || LAT41(CODE) || ", " || LON40(CODE) || " " || LAT40(CODE) || "))" );

select ST_GEOGFROMTEXT(WKT4("533946113")) AS geog

まとめ

とりあえず、できた。エラーチェックなどはないので、偉い人は自分でつくろう。

参考文献

https://www.stat.go.jp/data/mesh/pdf/gaiyo1.pdf

Azure Storage Blob に python で、stream upload

背景

Azure Storage Blobにpython で、stream upload したので、メモ。

こうした

Azure 自体触ったことないので、よくわからないが、

from azure.storage.blob import BlobServiceClient

というライブラリを使った方法(レガシーなライブラリも存在するらしい)。 詳しくは、ここを参照。

    blob_service_client = BlobServiceClient(account_url=AZURE_STORAGE_ACCOUNT_STRING)
    blob_client = blob_service_client.get_blob_client(container=CONTAINER_NAME, blob=BLOB_NAME)
    blob_client.upload_blob(sys.stdin.buffer, length=length)

ここで、AZURE_STORAGE_ACCOUNT_STRINGは、然るべき方法で取得した文字列(実は知らない)。 CONTAINER_NAMEはコンテナ名の文字列、BLOB_NAME はblobの文字列。 sys.stdin.buffer は標準入力のバイナリ。 大切なのは、length 。これがないと、エラー。 ストリームなのに、サイズが分かってないとダメ。これは仕様(書いてないけど)としては厳しいなあ…

まとめ

stream upload したければ、サイズを先に調べて、lengthに渡す。