歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Python】pyppeteerを非同期コンテクストマネージャー用のクラスでラップして遊ぶ

Pythonから簡単にHeadless Chromeを利用できるpyppeteerというライブラリがあります。Headless Chromeの操作をラップしてくれてかなり便利なのですが、ほとんどの関数やメソッドが非同期(async)nあので、しばらく遊んでasync/awaitを使った実装に慣れる必要がありそうです。

ただ、公式リポジトリのサンプルコードを見ても分かる通り、browser.newPage()close()などの前処理・後処理のコードがあります。

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto('http://example.com')
    await page.screenshot({'path': 'example.png'})

    dimensions = await page.evaluate('''() => {
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight,
            deviceScaleFactor: window.devicePixelRatio,
        }
    }''')

    print(dimensions)
    # >>> {'width': 800, 'height': 600, 'deviceScaleFactor': 1}
    await browser.close()

同期的な関数であれば、これをクラスでラップしてコンテキストマネージャ(with句)で実装したくなりますよね?私もそう思って調べたところ、async withという非同期用のコンテキストマネージャがあるそうです。

qiita.com

これを使えば、以下のようにasync withで定形コードをまとめて実装できました。

import asyncio
from pyppeteer import launch


class Session(object):
    async def __aenter__(self):
        self._browser = await launch()
        self._page = await self._browser.newPage()
        return self

    async def get(self, url):
        await self._page.goto(url)
        return self._page # Pageを返す

    async def __aexit__(self, exc_type, exc, tb):
        await self._browser.close()


async def main():
    async with Session() as s:
        page = await s.get("https://google.com")
        await page.screenshot(path="./example.png")
        result = await page.mainFrame.content()
        print(result)

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

async/awaitはHaskellのIO型のdo記法に近いものだと思えばなんとかなりそうです。詳しい人なら、ここでモナドの話を始めるんだと思います。

async with構文はこちらのPEP 492で提案されたもののようなので、後で読んでみます。

www.python.org

【メモ】『アスペルガーと知らないで結婚したらとんでもないことになりました』を読みました

偶然見かけたこちらの本を読んだのですが、個人的にはかなり面白い内容でした。

アスペルガーと知らないで結婚したらとんでもないことになりました (旦那(アキラ)さんはアスペルガー)

アスペルガーと知らないで結婚したらとんでもないことになりました (旦那(アキラ)さんはアスペルガー)

  • 作者: 野波ツナ,宮尾益知(どんぐり発達クリニック理事長)
  • 出版社/メーカー: コスミック出版
  • 発売日: 2017/08/21
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

特にこちらのシーンが印象的でした。(画面キャプチャを貼っているので怒られるかもしれませんが)

相手に「悪意がない」からといって、つらく無いかと言われればそうではないでしょう。特に「自分が主導権を持って意思決定しなければならない→行動に対する責任も積み重なって身動きが取れなくなる」というのもよくある光景なんじゃないかなと思います。

特に結婚相手という身近な相手だと、大きな形で軋轢が出てくるので大変だと思います。その分、そこから学ぶことも多そうですが。

当てはまる面も当てはまらない面もありますが、どんな相手でも、相手も自分自身も無理のないように工夫していくしかないと思います。

gendai.ismedia.jp

【Python】Requests-HTMLでスクリーンショットを撮る

Pythonの著名なHTTPクライアントライブラリのrequestsに似たAPIで、シンプルなAPIスクレイピングに必要な機能が実装されています。実際には他のいくつかのライブラリをラップしています。

Requests-HTML: HTML Parsing for Humans (writing Python 3)! — requests-HTML v0.3.4 documentation

以下のようなコードで、簡単にChroniumを自動でダウンロードしてブラウザでレンダリングして、HTMLをパースして必要な情報を取り出すことができます。Chroniumの操作は内部ではpyppeteerを利用しているようです。

r = session.get('http://python-requests.org/')

>>> r.html.render()

>>> r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>'

今回試したこと

今回私はE2Eテストのようなことを行いたく、

という利用用途でした。ドキュメントには陽にその方法が書かれていなかったのですが、以下のISSUEを参考に、一応は実装することができました。screenshotのメソッドが非同期の関数なので、asyncioを使って結果を待つ必要があります。

github.com

import asyncio
from requests_html import HTMLSession

session = HTMLSession()
r = session.get("https://kiito.hatenablog.com/")
r.html.render(keep_page=True)
loop = asyncio.get_event_loop() 
loop.run_until_complete(r.html.page.screenshot({'path': 'example.png'}))

スクリーンショットの結果

r.html.pageが「pyppeteer.page.Page」のクラスであり、そのメソッドを呼び出せます。

問題点

ただ、現状いくつかの問題点があり、直接pyppeteerのライブラリを操作してクローリングしたほうが良いと判断しました。具体的には以下の3つです。

  • pyppeteerの世界に入ると、急にasync関数になるから難しい
  • ブラウザ自体の操作はそこまでサポートされていない(スクロールダウンしながらページ全体をスクリーンショットしたい)
  • たまに以下のようなエラーが出てしまい、ちゃんと調べていませんが、おそらく「ページを閉じた後にスクリーンショットを撮る」ような挙動になっている
  File "/Users/takeshi/.local/share/virtualenvs/aaa-LzyUpoQe/lib/python3.6/site-packages/pyppeteer/connection.py", line 85, in send
    raise ConnectionError('Connection is closed')
ConnectionError: Connection is closed

参考記事

作者のKenneth Reitzについて

requests_htmlでは他にも、1メソッドでHeadless Chromeインストールから実行までしてくれる下のオシャレなAPIも個人的なお気に入りです。

今まで「(簡単な用途であれば)requestsとBeautifulSoupを使ってクローリングすればいいや」と思っていたのですが、こちらの文言で気になって試してみました。

blog.ikedaosushi.com

pyppeteerの製作者の記事です。

h-miyako.hatenablog.com

【プログラム】Google Apps Scriptで簡単にSlackニュース通知を作るスクリプトを書きました

社会人になって数年も経つと、オタク趣味を続けるのも大変になってきました。

以前はいくらでも音楽の情報を追って遊んでられていたのですが、そこそこ真面目にプログラマーやろうとすると「あのグループって今は活動してるんだっけ?」とか「知らないうちにアルバムいくつも出してた」とかあります。

Google Apps Script(GAS)とSpreadSheetsを使って、「簡単なURLと正規表現の設定で、最新のニュース告知をクローリングして通知する」ようなスクリプトを実装しました。

github.com

正規表現を使ってパースしているのは、「必ずしもRSSATOMを用意しているページばかりではない」「GASのXMLServiceが必ずしもHTMLを読み込めない(エラーを出すこともある)」ためです。

こちらの記事のプログラムを全面的に真似しています。

qiita.com

実装は参考になるものがあったので、ほぼ苦労せずにできたのですが、

GASも、JavaScript(ほぼ構文が同じ)もあまり詳しくし、運用も始めたばかりなので微妙な点もあるかもしれません。特にエラーが発生したとき、次回実行は自動でスキップする設定が欲しいです。あと、GASでも開発ツールがないと、テストコードも無くprintデバッグしか選択肢が無いのも辛いことを実感しました。

折を見て修正していこうと思います。

【メモ】『ノートによる情報管理』を身につけるために読んだ本

エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)』を読んだり、知り合いにいろいろ聞いてから、自分の情報・タスク管理法、勉強法を見直そうかなと思っています。

ただ、こういうのは人それぞれです。例えば私の周りのある人は「ノートにまとめる必要はない」と言っており、彼は優秀なエンジニアなのですが、その点参考にならないなと思っていました。そのため、周辺ジャンルの本をいろいろ読んでいて、今日のブログはその中間報告的な文章です。

1440分の使い方

1440分の使い方 ──成功者たちの時間管理15の秘訣

1440分の使い方 ──成功者たちの時間管理15の秘訣

タスク管理術として「様々なデジタル管理ツールを試したが、筆者にとっては手書きのほうが良かったからモレスキンのノート使ってる」というようなことが書かれていました。他もなかなかいい内容ですが、今の興味として学べたのはこれだけかな。

情報は1冊のノートにまとめなさい

情報は1冊のノートにまとめなさい[完全版]

情報は1冊のノートにまとめなさい[完全版]

一回手書きノート派になろうかと思って読みました。個人的に、既に社内の仕事ではやるべきタスクや、思いついたものをメモするページを作って管理しているので、あまり違和感無い内容でした。

友達はSONYDPT-CP1というデジタルペーパーを薦めていたのですが、正直7万円するので、すぐに手を出すのはアレかなと思って手をだしていません。

www.sony.jp

また、正直後から見返すことはそれほど考えておらず、一旦実ノートでいいかなと思っています。また、「ブログやSNSに全部書いちゃう」「Tumblrを非公開にして使う」みたいなことも考えたのですが、正直広く外向けに書けないこともあるのと、「頭の中を整理する」という目的のためにはアナログでいいかなと思いました。

「ノートが大きいと持ち運びづらいし、小さいと書きづらい」ということが書かれていたので、持ちやすさ優先でA5サイズの大学ノートを試してます。

また、知り合いに聞いたら、「GoogleSlideにまとめながら作業している。図も書きやすいので便利」と言っていました。これもPCの作業が多い場合は便利ですね。

ハーバード式 大人のADHDパーフェクトガイド

ハーバード式 大人のADHDパーフェクトガイド

ハーバード式 大人のADHDパーフェクトガイド

  • 作者: クレイグサーマン,カレンウェイントラーブ,ティムビルキー,福西勇夫,福西朱美,Craig Surman,Karen Weintraub,Tim Bilkey,村木美紀子
  • 出版社/メーカー: 法研
  • 発売日: 2015/02/23
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

自分や家族がADHD(注意欠陥・多動性障害)で悩んでいる方向けの本。「タスク管理が苦手な特性の人」向けに書かれているので、「どうやって管理すればいいか」「習慣づければいいか」が丁寧に書かれている印象があります。

例えば「こういうことは一般の仕事術の本にも書かれているが、ADHDで無い人に比べてなおさら、ツールに順応する必要がある」みたいにこの本自体にも書かれていました。

また、「ポップコーン現象」の話で、「いろいろと考えが浮かんで本来の仕事に集中できない」というのは自分にも当てはまる気がします。今の所のノートの目的が「目の前の仕事を明確化させたい」だと思っていたのですが、その他に、自分にとっては「浮かんできた考えを一旦吐き出し、後で検討できる状態にして、元の仕事に集中できる状態を作る」って機能も必要なのを自覚できました。

難解な本を読む技術

難解な本を読む技術 (光文社新書)

難解な本を読む技術 (光文社新書)

これも『エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)』で紹介されていましたね。私はかなり速読に寄っているため、難しい本(数学や哲学)の本はちょっと苦手意識ありました。

この本でも「読書ノートを書きながら読む」という方法が紹介されていました。また、「登山型」「ハイキング型」の分類はかなり本質を突いていると思います。

【メモ】知り合いから薦められた仕事本のアタックリスト

【まとめ】プログラマーが愚直に仕事を進めるための方法 - 歩いたら休め

「最近仕事でもプライベートでも忙しい時期が続いて、『やらなきゃいけないこと』が管理できなくなってきたからGTDの本読んでるんだ」って話したら、知り合いからいろいろと薦められました。とりあえずチェックしてみます。

もし「イシューからはじめよ」読んでなかったら絶対読んだ方がいいと思う。こっちは「仕事を一番はやく終わらせるには仕事をしない(減らす)こと」という観点から、仕事への考え方を変えるきっかけになる。プロダクティビティ以外でも活用できて読んでからダイレクトに成果が変わったと思う。

イシューからはじめよ―知的生産の「シンプルな本質」

イシューからはじめよ―知的生産の「シンプルな本質」

「1440分」にはGTDよりももう少し過激なことが書いてあって「タスクリストは無意味」「スケジューリングしないとダメ」って書いてある。ある調査によるとタスクリストに追加されたタスクの7~8割は消化されないらしい。なので、1週間の予定は週の初めに考えるのと、今日〜明後日くらいまでの予定は頭の中で組み立ててる(と言ってもざっくり「これとこれをやる」くらいだけど)

これはKindle Unlimitedにもあるのでありがたいですね。

1440分の使い方 ──成功者たちの時間管理15の秘訣

1440分の使い方 ──成功者たちの時間管理15の秘訣

GTDとポモドーロの運用はRebuild higeponさん回がおすすめ。

rebuild.fm

【まとめ】プログラマーが愚直に仕事を進めるための方法

最近、精神的に大変な仕事とか、プライベートでやっているイベントとか、いろいろ重なってしまって大変でした。

私は全く器用なタイプではなく、複数いろいろやっていると、例えば「他の仕事のことが気になってこっちの仕事もなかなか進まない」というような負のスパイラルに陥りがちでした。ただ、大変だった中で他の方からのアドバイスで学んだことや、「これじゃいけない」と思って諸々の本を学んで、多少マシな状態にはなりました‥いや、多分なったと思います(笑)。そこで、最近似たようなことで悩んでいる人もよく見かけるので、軽くまとめておきます。

私を実際に知ってる人が見ると、「いやいや、お前言うほどできてないじゃんw」って思われるかもしれませんが、後でこっそり教えてください。

すべてを実験だと捉える

プログラミングの仕事を進めていると、どうしても仕様が明確でない、後から修正しなくてはいけないことがあります。 100%想定通り進むことは絶対にありません。また、チームの他メンバーと常に認識を合わせることも、ほぼ不可能だと言っていいでしょう。

それなら、我々には「想定外のことが起きませんように」と祈ってるしかないのかというと、そうではないはずです。

確かめたいことに対して、「サーバーが突然落ちないかどうかは負荷テストの段階で(可能な限り)チェックしよう」とか、「(非プログラマーとややこしい仕事するとき)用語についての認識の齟齬が起きやすいので、定例ミーティングで確認するようにしよう」とか、できるだけ早い段階で実験して拾えるように工夫しましょう。

ありがちなのが、他の人に渡すドキュメントをまとめる際に、「すごく詳細にまとめてるけど、これって欲しい情報じゃないんだよね」って言われ、複雑な割に「使えない」ドキュメントになってしまうことです。こういうのは、「目次」を作った段階で相手にそれとなく「今こういう方針でまとめてます」って相手にチャットして、大まかな方針レベルで問題が無いのか「実験」しておくようにしましょう。プログラムの場合は実装方針とかクラス図とかのレベルですかね。

ちょっと余談ですが、知り合いのデータサイエンティストが「開発先とのやり取りで多目的最適化のソルバーを使っている」「最初に出てくる仕様だと最適化問題の目的関数がちゃんと決まらないことがある。その時に多目的最適化で考えられる解を実際にいくつか出して議論すれば、何を優先するのか決められる」と言っていました。私は今まで単に「多目的最適化は解が一つに決まらないので自動化するプログラムで使いづらそうだな」と思っていたので、専門知識を活かしてうまく『実験』していたことに驚きました。

タスクを実験だと捉えると、いきなりうまくいく方法が見つからなくても、

  1. 「こうすればうまくいくんじゃないか」という仮説を見つける
  2. 「仮説が正しい」を証明するための実験(テスト)計画を作る
  3. テストを実行する

ことで愚直に進められるので、少なくとも全く身動きができなくなることは無いと思います。仮説が正しい場合、安心して実装していい範囲が広がり、間違っている場合でも仮説を修正してリトライすればいいだけです。

タスクを全部書き出す

私のように「他の仕事が気になって進まない」という状況になりがちな人は、ツールに頼って、「ここを立ち返ればとりあえず見落としがない」ような状況を作って、頭の中から一旦全部追い出してしまうことです。おそらく理想は、一人ひとりに『秘書』がいることだと思いますが、少なくとも現在ではそれなりに偉い人でないと難しいでしょう。

最近私が「いいな」と思っている方法は、以下のやり方です。

  1. 自分が「気になってること」をとりあえず全部箇条書きにする(例えば「毎朝」くらいの頻度で)
  2. そいつの中から「今日やるべきこと」をピックアップする

これだけで、「とりあえず今やるべきこと」に集中しやすくなると思います。また、書き出す前には仕事の把握だけで無限の時間がかかるように思われる場合でも、実際にはひとつずつ潰していけばなんとかなることが分かることが多いと思います。

ところで、最近発売した『エンジニアの知的生産術』で紹介されていたGTDという方法が、これをもっと詳しくしたようなやり方だそうです。ただ、自分自身の性格や特性は人によって違うので、いろいろと実験して修正していく必要があるはずです。

全面改訂版 はじめてのGTD ストレスフリーの整理術

全面改訂版 はじめてのGTD ストレスフリーの整理術

エンジニアの知的生産術』を見ていて一番面白かったのは、「やる気の出し方」として「タスクを分割する」ことがまず書かれていたことです。 こういうのは(自分でも他人でも)本人の努力の問題にしがちですが、できるだけシステマティックにやってしまったほうがお互いに安心できると思います。

インターフェイスを取っ掛かりにする

プログラミングのアドバイスを受けているときに「先輩が言ってる方針ってうまく行きそうにない/そもそもよく理解できないけど、なんでこういうこと言ってるのかな?」って疑問に思い、さらに質問してもよく分からない返答が返ってくることも多いと思います。後から考えると、それは大きく2つ理由がありえると思います。

  1. 自分が「当然伝わってるだろう」という前提が伝えられていない
  2. 相手が対象について深いレベルで理解していない(更にそれを自覚できていない)

この辺の違和感を感じた時は、100%ではないにしても、実際に何か問題があることも多いので無視しないほうが良いです。なんとか対処しましょう。調べてみるとしょうもない思い違いや勘違いであることも多いですが(笑)。

①については自分の問題なので、「前提条件で伝わってない部分があるのか」を愚直に確かめていけば大丈夫だと思います。まあ大変ですががんばりましょう。

ただ、②の場合も、相手がかなり優秀な方でもけっこうありえるので困りますよね。自分自身を振り返っても「ちゃんと分かってないことが分かってない」ことは滅茶苦茶あったと思います。その場合は自力で勉強するとか、同じ質問を他のもっと詳しそうな人に質問するとか、なんとか工夫して勉強する必要があります。(だから、私は相手がわけわからない質問や、「それって当たり前じゃね?」と思うような質問をしてきた際にも、少なくともバカにしたり「デキないやつ」みたいなレッテルを貼らないようにしようと思っています)

特に、技術関連だと「オブジェクト指向」とか「設計のベストプラクティス」とか「静的型/動的型」の話題とか、その他だと「人事制度」とか「技術教育」とかの話は、相手が自分の経験したことのある範疇の話しか話ができないことが多く、割と地雷が多い(他人に頼って知識をつけるのが難しい)と思います。もしそういうところまで、自分の知識の限界を知りつつ論理的に話できる人がいたら大切にしましょう。

自分で勉強する場合は、以下の2点のどちらかに注目して調べていくと良いと思います。他人に教えて貰う(質問する)場合でも、ここをとっかかりにして議論を始めることができるでしょう。

  1. その技術を使うときのインプット/アウトプット
  2. その技術が作られた目的や経緯

ここに調べていくと、「〇〇は××という目的のために作られたでライブラリある」ということがわかり、××について調べると「他にも△△というライブラリがある」「実は自分の目的のためにはそっちのほうがいい」みたいに調べられて、最初の取っ掛かりはつかめると思います。

インプット/アウトプットが同じで、自分の目的に合っていれば、「他のツールやライブラリ差し替える」「どちらが良いか検討する」というような発想ができるようになると思います。こういうのってちょっとポリモルフィズムっぽい気もしますね。技術以外でも、同じような発想で「普段かかわらない相手と仕事するのでその分野を勉強しなきゃいけない」ような状況で、最初の取っ掛かりを掴めるかもしれません。

知識が足りずに身動きのとれない状況が減る(少なくとも勉強しなきゃいけない箇所や、質問すべきことは分かる)と思います。

多少は強引に進める

最近、「必要以上に全員の合意を取ろうとしてブロックしていることが多いのでなんとかしてほしい」と先輩から言われて反省しています。問題が無い場合でも全員にOKもらわないと先に進めないので、単純に効率が悪いと言われ、その通りだなと思ってしまいました。

単に「(チームメイトが)問題が無いので静観している」ような場合もあるので、「とりあえず今出してる案で問題あれば出してください。無ければ○月×日までで一旦出しちゃいます」。もしそのときに無茶なことを言ってしまっても、周りから「いや、それじゃあ期限がカツカツすぎるから後3日くらい欲しいよ」みたいにツッコんで貰えるはずです。

もしかすると、自分がすごく偉い立場で、周りを萎縮させている場合には「え?リーダーが○月×日までって言ってるなら間に合わせなきゃ」って無理させてしまうかもしれませんが、今の所私はそうではないので考えていません(笑)。

他に、私の場合は「(割と慎重すぎるタイプなので)もうちょっとスピード重視で進めちゃっていいよ」と言われ「じゃあちょっとクオリティ下げて進めるか」と思って、ちょっとプログラムが雑すぎると怒られることもありました。その時分かっていれば良かったのですが、実際にはスピード重視 OR クオリティ重視の二者択一であることはあまり無く、上のように「チェックしてもらう期間を決める」みたいにどちらも担保できる方法は割と考えられます。

ただ、試行錯誤している間(つまり人生のほとんど)は、多少痛い目を見るのはしょうがありません。こういうときにちゃんと仮説を持って「これは実験だ」という意識があると、後に活かせるので多少前向きになれると思います。

自分自身の特性を知る

自分自身の特性を知って、苦手分野をシステム的に、もしくは周りのチームメンバーとのやり取りでカバーする方法は身につけておくべきです。

例えば、大勢と交流するとエネルギーを貰うタイプとか、逆にストレスを感じるタイプとかいます。例えば、私は社内行事で集団行動すると正直かなり疲れる(一応言うと苦手な人がいるわけではありませんw)のですが、違うタイプの人が多い環境にいると、自分の性質が分からずに無理してしまうことが多いように思います。そういう性質と対処法を知るために、次の本が役に立ちました。

片づけられない人のための仕事の本

片づけられない人のための仕事の本

プログラマーという世界だけに限ると、(きれいに分かれるわけではないし、他人へのレッテル貼りにもなりかねないので危険ですが)ADD/ADHD的な性質を持つ人が多いように思います。

この本では、3つのタイプに分けて、ADD/ADHDについて3つのタイプに分けて、それぞれの性質や対処法について説明しています。私は割と②のタイプが参考になりました。

  1. 多動が目立つタイプ
  2. 内部で混乱してるタイプ
  3. 枠組みに頼って生きてるタイプ

もちろんADD/ADHD的な性質の人だけじゃないし、この本のタイプ分けもざっくりしているので、これだけで自分や他人を分かった気になるのは危険だと思います。

ただ、世間一般を見ると「この人、特定の枠組みに頼りすぎてるな」とか、自分自身の性格や性質に合わないやり方を無理にやろうとしている人が多いようには思います。私の場合は「物覚えが良い方じゃないのに、(すごい知り合いのエンジニアのやり方を無理に参考にして)タスクの管理方法を考えずに仕事に着手してしまう」ようなことがありました。人それぞれ、自分自身に合ったやり方を身に着けていく必要があります。

まとめ

一番危険なのは「現状を把握できてなく、どこから着手すればいいか分からない」ような状態だと思います。上の考え方なら、とりあえず試行錯誤して先に進め、少しずつ改善できるようにはなるはずです。少しずつ改善できるなら、まあ数年後にはそれなりのものにはなっているはずです(なっているといいなあ!)。

それでは、お互い無理せずがんばりましょう。