ドメイン取りました
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のスタイルに従う)
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)
emacs vue-mode で構文チェックする領域がおかしくなったの対処方
vue-mode で書いていると構文チェックする領域がおかしくなるときがある。vue-mode の、というより mmm-mode で発生する現象なのかもしれない。
具体的には
(小ネタ) BetterTouchTool で右ALT、 左ALT の使い分け
自分は右ALTをほとんど使わないので、右ALT を修飾キーに使えたら便利だな〜と思って調べたら、普段から使ってる BetterTouchTool にその機能があった。
使い方はこう
Add New Shortcut... を押して、左下に出てくる歯車アイコンをクリック
ここでDifferentiate between ... にチェックを入れると左右ALTが別になる。
自分は Mac の Ctrl + PNFB による移動ができないとき、いちいちアローキーを触っていたが、これでだいぶストレスが改善された。もっと早く知っていれば…
ちなみに、Key Repeat も設定できる。
この部分。
Vue で動的にコンポーネントを追加
Vue で動的にコンポーネントを追加したい
よくある TODO アプリで言うと、ボタンを押したらTODO を追加したい。
UIとしたらこんな感じ
TODO追加ボタンを押すたびにコンポーネントを追加したい。
new するやり方(正しくないやり方)
先に書いておくとこのやり方はたぶん正しくないが、最初にこのやり方で調べてしまったので書いておく。
TodoItem を次のように定義する。
<template> <li class="todo-item">{{text}}</li> </template> <script> export default { name: 'TodoItem', props: { 'text': String } } </script>
これをボタンが押されるたびに追加する。
TodoList の方はこう
<template> <div class="todo-list"> <div> <ul ref="todo-list"> </ul> </div> <form v-on:submit.prevent="onSubmit"> <textarea v-model="text"/> <input type="submit" value="TODO追加"/> </form> </div> </template> <script> import TodoItem from './TodoItem' import Vue from 'vue' export default { name: 'BadTodoList', components: { 'todo-item': TodoItem }, data () { return { text: '' } }, methods: { onSubmit () { let clazz = Vue.extend(TodoItem) let instance = new clazz({ propsData: { text: this.text } }).$mount() this.$refs['todo-list'].appendChild(instance.$el) this.text = '' } } } </script> <style scoped> .todo-list { text-align: left; } </style>
ポイントは、Vue.extend。Vue のコンポーネントはインポートしただけでは class の設計図の状態で、new できないようだ。そこで Vue.extend することで new できる形になる。
また、new しただけではまだ dom は作られていないので、$mount() をよんで上げることで実体化する。実体化したコンポーネントのdom は $el で参照できるので、それを appendChild してやればよい
data を使うやり方(正しそうなやり方)
そもそも、todo を vue のデータに乗っけないで自分で管理するのはおかしい。なので、以下のやり方が正しいはず。
<template> <div class="todo-list"> <div> <ul> <todo-item v-for="todo in todos" v-bind="todo" /> </ul> </div> <form v-on:submit.prevent="onSubmit"> <textarea v-model="text"/> <input type="submit" value="TODO追加"/> </form> </div> </template> <script> import TodoItem from './TodoItem' export default { name: 'TodoList', components: { 'todo-item': TodoItem }, data () { return { text: '', todos: [] } }, methods: { onSubmit () { this.todos.push({ text: this.text }); this.text = '' } } } </script> <style scoped> .todo-list { text-align: left; } </style>
v-for として todo-item を呼び出して、todo 自体は array で管理する。
なんとなくだけど、前半のやり方は他のライブラリを呼び出す用途以外では基本的に間違っている気がする。
Vue で Uncaught RangeError: Maximum call stack size exceeded
VueJs でコンポーネントを作っていたら真っ白なページが表示されている。
コンソールを見るとこんなエラーが出ていた。
Uncaught RangeError: Maximum call stack size exceeded at Watcher.get (vue.esm.js?efeb:3156) at new Watcher (vue.esm.js?efeb:3131) ....
何が原因かと小一時間悩んだ結果、コンポーネントの中で自分自身を呼び出していたのが原因だった。
例えば
<template> <ErrorComponent></ErrorComponent> </template> <script> export default { name: 'ErrorComponent' } </script>
内部で ErrorComponent(自分自身) を呼び出さなければ解決。