alpine に lxml をインストールした docker を構築する

alpine に lxml をインストールしようとするとこんなエラーが出る。

...
** make sure the development packages of libxml2 and libxslt are installed **
...
*********************************************************************************
Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed
*********************************************************************************
error: command 'gcc' failed with exit status 1
...
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-96bb0z1d/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-i0hoswq1/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-96bb0z1d/lxml/

結論としては Dockerfile を次のようにしてインストールできた。

FROM python:3-alpine
RUN apk --no-cache add gcc libc-dev libxml2-dev libxslt-dev
RUN pip3 install lxml

libxml2-dev と libxslt-dev は本家に必要と書いてあった
https://lxml.de/installation.html
また g++ と gcc をインストールしてたが、こちらの stackoverflow によるとlibc-dev と gcc でよさそう
https://stackoverflow.com/questions/35931579/how-can-i-install-lxml-in-docker

Docker を調べるのに使ったリンク集

Docker を調べるのに使ったリンクをまとめておく

docker コマンドまとめ
https://qiita.com/voluntas/items/68c1fd04dd3d507d4083
https://qiita.com/curseoff/items/a9e64ad01d673abb6866

起動中のコンテナのシェルに入る
https://qiita.com/sekizo/items/27cc9b406332afc674f6
alpine の場合は
https://qiita.com/yutaChaos/items/56dd7ea09d7e2b0d9173

docker-compose コマンドまとめ
https://qiita.com/wasanx25/items/d47caf37b79e855af95f#down
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa

Docker コンテナとイメージを消す
https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae

Docker イメージをいろいろと小さくする工夫
https://qiita.com/pottava/items/970d7b5cda565b995fe7

ベストプラクティス。あとで読み返したい。
http://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practice.html#add-copy

docker のタイムゾーンを設定
http://yoru9zine.hatenablog.com/entry/2017/01/12/224637

ここらへんを読んでなんとなーく Docker を構築できるようになった

ドメイン取りました

http://ororog.org を取得した。
色々調べたところ、無料でドメインを設定してくれるところがあるっぽいので、いくつか試してブログ部分が移行できるか試したい。
ホストとしては、次の2つを試す

有名

  • netlify

調べてたら知った。CI とかできて便利そう。

ブログツールとしては hugo を試す。
hatena みたいに web だけで完結しないので、更新がめんどくなるかもしれないしそうでもないかもしれない。

Requests + BeautifulSoup で html から form データの雛形作成他

Requests と BeautifulSoup は忘れた頃に使って何度も調べるのでメモ。小ネタ。

Requests を使ってログイン処理をするときはだいたいこんな処理をかく。

s = requets.Session()
r = s.get('http://example.com/login')
soup = BeautifulSoup(r.content, 'html.parser')
payload = {
  'id': 'id',
  'password': 'password'
}
s.post('http://example.com/login', data=payload)

payload の部分がこれくらいシンプルならいいけど、csrf token とかをつけて送る場合に BeautifulSoup を使って token 部分を抜き出す必要がある。そんなときはだいたい以下のようなコードを書いて payload の雛形を作る

内包表記ver

payload = {
    input['name']: input['value'] if input.has_attr('value') else ''
    for input in soup.select('form input')
    if input.has_attr('name')
}

for でシンプルに書くとこんな感じ

payload = {}
for input in soup.select('form input'):
    if not input.has_attr('name'):
        continue
    value =  input['value'] if input.has_attr('value') else ''
    payload[input['name']] = value

あとはこの payload に適当に id/pass を詰め込んで post すればよい。

その他メモ

  • BeautifulSoup はdict の ように in を使って要素があるか問い合わせてはダメ('value' in input みたいな)。has_attr を使う。
  • Cookie とか使うなら Session を使う。
  • Session の save / load は pickle でいけそう
import requests, requests.utils, pickle
session = requests.session()
with open('somefile', 'w') as f:
    pickle.dump(session, f)
with open('somefile') as f:
    session = pickle.load(f)
  • findAll ? find_all ? どっちやねん > find_all らしい (最近のpythonのスタイルに従う)

python - beautifulsoup findAll find_all - Stack Overflow

AtCoder ABC 105 D

python に慣れるため久しぶりにプロコンをやってみた。今の AtCoder になってから初だと思う。

D: Candy Distribution - AtCoder Beginner Contest 105 | AtCoder

code

from collections import defaultdict

N, M = map(int, input().split())
A = list(map(int, input().split()))

Amod = defaultdict(int)
sum_mod = 0
for v in A:
    sum_mod = (sum_mod + v) % M
    Amod[sum_mod] += 1

sum_mod = 0
ans = 0
for v in A:
    ans += Amod[sum_mod]
    sum_mod = (sum_mod + v) % M
    Amod[sum_mod] -= 1

print(ans)

解き方、感想

0 .. r (r = 0 .. N) の範囲の和の mod を hash に覚えておく。
0 .. l で l を動かして、0 .. r の和のmodから 0..l の 和の mod を引いて、mod が 0 になるようなもの (hash[ 0..l の和のmod] で個数がすぐに出せる)を足していく感じ。

python は慣れてないけど、defaultdict ないと面倒くさそう。
他の人のコードみて勉強せな。

  • AtCoder は気軽に他の人のコード見れない?topcoder は見れるから勉強しやすい。
  • AtCoder の解説は結構あっさりしてて、わかる人向けの解説って感じがする(解いたけど解説読んでもよくわからない…)。動画を見ればいいのかな。

emacs vue-mode で構文チェックする領域がおかしくなったの対処方

vue-mode で書いていると構文チェックする領域がおかしくなるときがある。vue-mode の、というより mmm-mode で発生する現象なのかもしれない。
具体的には

広告を非表示にする

(小ネタ) BetterTouchTool で右ALT、 左ALT の使い分け

自分は右ALTをほとんど使わないので、右ALT を修飾キーに使えたら便利だな〜と思って調べたら、普段から使ってる BetterTouchTool にその機能があった。

使い方はこう
Add New Shortcut... を押して、左下に出てくる歯車アイコンをクリック
f:id:ororog:20180808204802p:plain

ここでDifferentiate between ... にチェックを入れると左右ALTが別になる。
f:id:ororog:20180808204849p:plain

自分は Mac の Ctrl + PNFB による移動ができないとき、いちいちアローキーを触っていたが、これでだいぶストレスが改善された。もっと早く知っていれば…

ちなみに、Key Repeat も設定できる。
この部分。
f:id:ororog:20180808205822p:plain