歩いたら休め

なんでこんな模様をしているのですか?

【メモ】「書かれていないこと」に注目する

私には英語圏出身の友達が何人かいるんですが、何を言ってるのか分からないときがあります。大抵プログラマーかアニメ・オタクなのですが、できるだけ自分の意見をしっかり(そしてなるべく建設的に)表明する能力や、時折日本人の私から見ると言動にカウンターカルチャーっぽさを感じることがあります。

人によっては日本語と英語をしゃべってるときに、それぞれの文化っぽく立ち振舞いの変わる人もいて面白いです。ある人は「私」を表すのに、日本人モードのときは顔を指差し、アメリカ人モードのときは心臓を指さします。

私も「(異なる文脈の相手に対して)建設的に意見を表明する」みたいなところは参考にしようと思っていて、それに影響した文化や歴史にそこそこ興味あったのですが、ちょうどいい本を見かけたので読んでいます。

授業力アップのための英語圏文化・文学の基礎知識 (英語教師アップシリーズ1)

授業力アップのための英語圏文化・文学の基礎知識 (英語教師アップシリーズ1)

ただ、その意図とはあまり関係ない箇所が気になったのでメモします。

P69~、「マルクス主義批評」の紹介で「『ダロウェイ夫人』という上流階級の小説の中で、労働者が暗黙の前提として描かれていない」ことを指摘する批評が紹介されています。

上流中産階級の彼女が徒歩で大きな荷物を抱え,帰宅することなど不可能で,タクシーを利用していることは間違いないのだが,ウルフはその「目に見えないタクシー」を暗黙の前提として,描いていない.「目に見えないタクシー」から下部構造が,書くにも値しないと無意識のうちに思われ削除される/搾取される人々の存在が現れる.タクシーだけでなく夫人の衣食住が彼女の労働によって得られたものではなく,多くの労働者の労働によって得られていることが見えるようになる.

こちらの本の『不可視の階級闘争をあぶり出せ』で紹介されている「Can Jane Eyre Be Happy?」という論文だそうです。今の日本なら「コンビニ外国人」なども似たような立場かもしれません。

知の教科書 批評理論 (講談社選書メチエ)

知の教科書 批評理論 (講談社選書メチエ)

www.msz.co.jp

同じように、ソフトウェアエンジニアの仕事でも「暗黙の前提として描かれていないもの」に悩まされることが多いように思います。例えば「企画があるもののどう実装するのか具体的でない」「良いものを作れば広まると信じ切って、営業活動が考慮されていない」「データを組み合わせることが前提だけど、必要なデータが揃っていない」など、考え始めるといくらでもあります。今まで「なんかこのプロジェクト、現実味無い気がするんだよなあ」って違和感もちながら進んでしまっていたものが、一部は説明(〇〇が前提だけど考慮されてないじゃないか)できるように思います。

そうすると次は「どうすれば不可視の前提として省略されてしまっているものに気づけるか」という問題が出てくる気がするんですが、今のところは「実際モノ作って動かしてみる」「ラフを描いて経験豊富な、そしていろいろな先輩に見せる」くらい無いと思っています。

【本】イケてないソフトウェアエンジニアのための『リサーチの技法』

我々ソフトウェアエンジニアは、日々自分なりに新しい技術動向を調べて、それをまとめて適切な分野に投資していく必要があります。

それでなくても、あの新しいライブラリやプログラミング言語が良いとかいう話から、日々の業務で同僚はなんだかよくわからない機械学習の手法の話もしてるし、はてはなかなか問題の尽きないコミュニケーションのスキルまで身につけながら対処していかなきゃいけません。

「自分の興味だけで調査すべき分野は見つからないし、どうすればいいんだ」「でもなぜか適切に学習できてる奴もいるから何かしら方法はあるはずだ」って悩んでる人も多いと思います。それでいろいろ調べていく中でこの本も読みました。

リサーチの技法

リサーチの技法

本書が提供する価値:「ぼんやりとした「興味」を、解決の意味ありと読者が判断する「課題」に持っていく方法」「読者が主張を真剣に受けとめてくれる「議論」を構築する方法」「見識はあるが批判的な読者の懸念事項を予測し、それに対して適切に答える方法」「「それがどうした?」という、読者による最も厳しい問いに答える序論と結論を書く方法」「自分が執筆した文書を読者の目線で読み、そして、いつ、どのようにしてそれを修正すべきかを判断する方法」全米70万部超の古典的名著。大学、企業、研究機関などでリサーチする人、必読。

この内容、ソフトウェアエンジニアでも使えそうじゃありません?この本の『PART II 問いを設定し、答えを見つける』をベースにメモをまとめてみます。

リサーチを計画する - 概観

「リサーチクエスチョン(課題に対する問い)」の決定の4つのステップはこんな感じ。

  1. トピックを見つける
  2. そのトピックに問いかけをしてみる
  3. エビデンスを決める
  4. エビデンスを見つけられるかを決める

エビデンスの調査」はエンジニアリングや企業の人間は「実際にテストして試してみる」ような方法もあるかもしれません。

3章 トピックから問いへ

「トピックに対する問いに対する答えが課題を解決する必要がある」ということを主張しています。これは「〇〇って言語は動作が早いから素晴らしい」って主張している人がいて、「じゃあ早いと何の課題が解決できるの?」ってことがセットじゃないといけないので同感ですね。

初心者は「このトピックでレポートを書くとき、十分な情報が集められるか」を心配しがちだ。また、必要以上に情報を集めたがる。しかし、そこに役立つものは少ない。選んだトピックが的を絞り切れていないからだ。的が絞りきれていないと、集めたエビデンスが、読者にはランダムな情報の山にしか見えない。

この章の要約です。

  • 興味からトピックへ: 自分の興味の惹く分野を選ぶと、「やり遂げる意志」が持てて良い
  • 漠然としたトピックから的を絞ったトピックへ: 文に置き換えると読者が興味を持てそうな主張になる動的なトピックを選ぼう
    • いい例) 商業飛行の初期の頃におけるDC-3開発への軍部の貢献[トピック]→商業飛行の初期の頃に、軍部がDC-3の開発に貢献した[主張]
    • 悪い例) 商業飛行の歴史[トピック]→商業飛行には歴史がある[主張]
  • 絞り込んだトピックから問いへ: 「できるだけ多く情報を集める」戦略を取りがちだが、問題を問いかけて調べることが重要
  • 最も重要な問い「それがどうした?」: 「私は〇〇について調べている。なぜならば、〜を知りたいからだ」というフォーマットを考え、更に想定読者の「それがどうした?」と質問に答える。
    • 例) 私は「北米の大きな哺乳動物が消滅した原因」についてリサーチしている。なぜならば、「最古の民族の狩猟によってその哺乳動物が絶滅したか」を知りたいからだ。それは、「原住民が自然と調和して生きていたか、それとも自然破壊を助長しながら生きていたか」についての読者の理解を助けるためだ。
    • ただ、始める段階ではこれに答えられずに進めてしまっても間違いではない

「できるだけ多く情報を集める」戦略がダメになりがちなのはそのとおりだと思います。「それがどうした?」に対しては、エンジニアなら「〇〇が実装できる」ってフォーマットになりそうな気がします。

また、最初に「興味」から始まっているのも面白いですね。最初は膨大な選択肢があるので、自分の趣味で選んでしまうのが効率いいのかもしれません。

4章 問いから課題へ

要約するとこんな感じです。ソフトウェアエンジニアは実用的課題の割合が大きそうですが。

  • 自分だけじゃなくて読者が興味を持つ課題を提起しなければいけない。
  • 課題は「実用的課題(何をすべきか?)」と「概念的課題(何を考えるべきか?)」の2種類がある。
  • 実用的課題は「オゾン層が薄くなっている」「それがどうした?」「薄くなると私達がより多くの紫外線にさらされて不健康になる」と答えられるもの。応用研究に対応。
  • 概念的課題(「Q1: 過去50年間でロマンチックな映画がどう変わったか?」)は更に重要な問題(「Q2: 私たちの文化のなかでロマンチックな恋愛の表現方法はどのように変わったか?」「Q3: 結婚と家族に対する男女の期待がどのように形成されてきたか?」)に答えるための助けになるもの。基礎研究に対応。

これ以降の章

  • できるだけ1次ソースを当たれ
  • 2次3次ソースは一般向けに書かれているので情報が足りていないことが多い。ただ、情報収集の観点では有用なこともある。
  • 図書館等で偶然有益な本が見つかる可能性もある

みたいな、情報収集方法やソースの信頼性の確かめ方が書かれています。

最後に

『リサーチの技法』は、こちらのツイートで知りました。自分自身個人でのリサーチの方法以外にも、その後の議論の方法についても書かれています。私もそこは途中です。

【本】 『組織化の社会心理学』を読みました

『コミュニケーション学がわかるブックガイド』で気になった本で読んだものです。他にも『誰のためのデザイン?』とかも読みました。こちらはプログラマー関連でも有名ですね。

気になったアイデアとしてはこれくらい。ちゃんと読めばいろいろな示唆が得られそうな本ですが、今の自分が面白く感じたのはこれくらいかな…。

  • 攻撃的/協力的な戦略の人がいるが、攻撃的な人は周囲も攻撃的にしてしまう(自己成就性)のに対して、協力的な人は「周囲の人には攻撃的/協力的な人が混ざっている」と考えている
  • 進化論の喩えで「淘汰」にも多くのページが割かれている。組織の習慣を「捨てる」ほうにも注目したほうがいいのかもしれない
  • フィードバックが複雑(非線形)な世界では行動してフィードバックを得るのが良さそう

組織化の社会心理学

組織化の社会心理学

【Python】pyppeteerでのクローリング時に別ドメインのCSSを読み込む

pyppeteerを使ってクローリングする際、「JSを実行して値を取り出す」ため、セキュリティのための制限にひっかかることが割とあるようです。

私の場合、CSSの情報を取り出す際に、以下の問題に引っかかりました。

> document.styleSheets[0].cssRules
VM52621:1 Uncaught DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
    at <anonymous>:1:25

一部のブラウザーでは、スタイルシートが異なるドメインから読み込まれている場合、cssRules の呼び出しで SecurityError が発生します。

自分や自社が管理するサイトの開発時のE2Eテストのような要件であればCORS (Cross-Origin Resource Sharing)の設定で対処できそうなのですが、私の場合はクローリングの案件だったのでその方法は使えません。Headless Chromeの起動オプションで指定できるそうなのでそちらで対処しました。

stackoverflow.com

上の記事ではpuppeteer(pyppeteerの元ネタのnode.jsのライブラリ)の話題ですが、pyppeteerでもほとんど同様に操作できます。

from pyppeteer import launch

async def main():
    browser = await launch(headless=True, args=['--disable-web-security'])
    # 以下、操作

小規模で、信頼できるサイトのクローリングならこれで問題ないと思っています。

【本】『わざ言語―感覚の共有を通しての「学び」へ』を読みました

年末なので本ばかり読んでます。普段と違う環境だと本に逃げてしまうので、なんとかプログラミングに集中する方法も見つけたいです。

わざ言語―感覚の共有を通しての「学び」へ

わざ言語―感覚の共有を通しての「学び」へ

これも『コミュニケーション学がわかるブックガイド』で気になった本の一つで、後輩のレビューのときに「エラーの調査」や「プログラムの設計」の部分など、おそらく暗黙知に近く教えづらい分野もあったので、それをうまく伝えるヒントが無いか調べるために読みました。また、(趣味の)音楽関連でも、実際のスキルと少なくとも同程度には、立ち振舞いや暗黙の何かが重要になることが多いように感じています。

私たち実務者にとって重要なのは、やはり「(今すぐじゃないにしても)自分や周囲の仕事にどう役立てられるのか」だと思うので、抽象的な問題にハマってしまうより、具体的な問題意識を持って読む/自分なりにサンプリングして試すようなことは重要だと思っています。

本の内容はこちらにある通りです。

www.keio-up.co.jp

自分の問題意識から、気になったところだけピックアップします。とりとめない内容ですみません。

適応的熟達者について

P41 第二章 熟達化の視点から捉える「わざ言語」の作用

近年の研究において、熟達者は、知識・技能の柔軟性や創意によって、適応的熟達者(adaptive expart)と手際のよい熟達者(routine expart)に分けて考える捉え方がなされている。

チームの目標によって、どちらの熟達者がいいかは少しずつ変わりそうですね。私が興味がある(この本のテーマ的も)後者なのですが、こう説明されています。

適応的熟達者は、必要や興味関心に応じて熟達化を深化させ、新たな熟達の展開を行う。それゆえ、適応的熟達に向かう学習者は、新しいこと、より困難な課題、より複雑な問題状況に対峙するために、そうした状況の中にあえて立ち入り、身を置き、格闘せざるを得ない。すなわち探索的な初心者(intelligent novices)を経て初めて適応的熟達体験が得られるのである。

技術の創造と設計

技術の創造と設計

以前、こちらで紹介されている本も似たテーマだった覚えがあります。

「わざ言語」の作用の様態を説明する六つの側面

P53

①「わざ言語」は、熟達化の過程で本人が「こういうことかな」、「いい感じだな」と気づくための態度や、気づくことのできるような状態に導く手がかりを与える。ただし熟達化には時間を要する。

②「わざ言語」は、直接的に問題解決を導くのではなく、問題解決の核を導く。

③「わざ言語」は、必然性をもつ文脈の中で用いられるものである。その文脈とは当人が求める感覚の状態によって規定される。

④「わざ言語」は、段階を経る中で、自動的な段階へと導く作用力をもつ。ただし、それは単なる自動化された動きを意味するのではなく、感覚が管理された、感覚が上乗せされた自動的な動きを意味する。

⑤「わざ言語」は、受け止める人の状態や体験等によって作用力が異なる。したがって、わざを教え学ぶ場では、感覚の共有が重要な意味を持つ。

⑥「わざ言語」によって導かれる状態は、最終到達形としてあるのではなく、さらなる洗練が目指される状態である。わざの探索と熟考は継続的に行われる。

思考を妨げる「文字知」

P103

では、なぜ「文字知」を拒むのか。問題視されるのは丸暗記である。西岡が、それでは分かったことにはならないと言うのは、丸暗記が頭での理解を目指すからである(西岡、1991、230頁)。しかし、宮大工の「知」は体得すべきもので、「できるかどうか」が重要となる。「教科書にあるような木はないんやから、もしかしたら真ん中は使えないかもしれない。外側の白太を外したら予定通りの寸法を取れないかもしれない」(小川、2001a、140頁)

(中略)

つまり、弟子を丸暗記に誘い込み、「思考」を停止させる危険性の回避のために「文字知」が拒まれたといえる。いかにして「考える人」を育てるか。「文字知」の拒否は、弟子に「思考」を促す工夫として理解できる。

これは工学系の分野でもその通りだと思います。特にITのシステム設計みたいな分野だと、割と「机上の空論で理想論だけなら割とどうとでも言える」ので、似たコンセプトのものが混在していて意味分からない感じになってますよね。だから先に「いろいろ試行錯誤させて『見る目』を養った後で、知識を教えよう」って話もある程度納得感があります。

また、レベルアップするために「手放される言葉」もあるというのも面白い話でした。

2つの「わざ言語」

P120

しかし佐藤氏の中では二つの区別がある。「われこれ複雑に言葉を尽くすよりも、一つの言葉ですとんと直ってしまう」言葉、そして「何かの現象を直すのではなく、自らの対峙によって悩み納得し、そうせざるをえないという質的変化を引き出す言葉」という区別である。本書の実践編からは割愛されたが、佐藤氏自身の命名に従って、以下、前者を「寄り添い型わざ言語」、後者を「誘(いざな)い型わざ言語」と呼ぶ。

全然関係ないかもしれないですが、「Hackers and Painters」のこの言葉も、自分にとっては「誘い型わざ言語」だった気がします。

他のものを創る人々、画家や建築家がどうやっているかを見れば、 私は自分のやっていることにちゃんと名前がついていると気づいていただろう。 スケッチだ。 私が言えるのは、大学で教わったプログラミングのやりかたは全部間違っていた ということだ。 作家や画家や建築家が、創りながら作品を理解してゆくのと同じで、 プログラマはプログラムを書きながら理解してゆくべきなんだ。

看護について

先程の「誘(いざな)い型わざ言語」の具体例のような内容。以下の本から引用されたこの文言をきっかけに学んでいく姿が指摘されていました。

看護の基本となるもの

看護の基本となるもの

ある意味において看護師は、自分の患者が何を欲しているのかのみならず、生命を保持し、健康を取り戻すために何を必要としているのかを知るために、彼の"皮膚の内側"に入り込まねばならない。

助産師のリフレクション(振り返り会)

P356

ーーそのサインというのはどういうことなのでしょう。後進の助産師の中には、熟練助産師がサインを送っているのに意味がわからない。隠そうとしているのに産婦の前で「ああ、これ、危ないですね」と思わず言ってしまうような助産師もいるわけですよね。そのサインは、どうしたらわかるでしょうか。

村上 ある後進の助産師は、その助産所に勤め始めたころは、どうしても言葉で言ってもらわないと意味がわからなかったと話しています。ただ、その助産所の熟練助産師は、お産の後に必ず、後進の助産師と共に振り返りをして、「ここはこうだったね」、「ああだったね」とか、「こういうサインを送ったのはわかった?」とか、わかってないかもしれないと思うときは、そのサインについて確認をしていると話してくれました。わかったという感覚、あるいは、危険だという感覚を共有している、共感していると思うのです。

【本】ソフトウェアエンジニアのための「アサーション入門」

…ってタイトルで書こうと思ったんですが、だいたいこのサイトに書いてある通りの内容ですね。

el.jibun.atmarkit.co.jp

アサーションと言っても、assert文を使った契約的プログラミングの話ではなく、この間の『コミュニケーション学がわかるブックガイド』で薦められてた本の一つの話です。

アサーション入門――自分も相手も大切にする自己表現法 (講談社現代新書)

アサーション入門――自分も相手も大切にする自己表現法 (講談社現代新書)

「自分らしくあってよい」「気持ちや考えを表現してよい」など、なんとなく認知行動療法っぽい内容だと感じたのですが、検索した限りではけっこう関連する分野のようです。私はある友達の立ち振舞いから同じような考え方を学んだのですが、他の友達や後輩に勧めるときにいいかもしれません。

ただ、第四章「アサーションで身につく三つの力」で人間関係を以下の2つの場面に分けるのはちょっと興味深い内容でした。

  • メンテナンス(関係維持)
  • タスク(課題)達成

【Python】asyncioの代替ライブラリtrioを調べてみた

この記事はPython その2 Advent Calendar 2018の遅れてきた15日目の記事です。

最近、クローリング用のプログラムのasyncioを使った並行処理のプログラミングをしており、「asyncioのベストプラクティス」という趣旨の記事を書こうと思っていたのですが、自分自身感覚を掴めておらず、「あれ?これってasyncioのAPI自体も微妙なのでは?」「そもそもasyncioのドキュメントのドキュメントを読んでも、どの機能をどう組み合わせて使えばいいか分からない」と思ってしまっていて記事を書きかねていました。

ただ、知人から「trioというライブラリのAPI設計が素晴らしい」と薦めて頂いたのと、あまりにも待たせてしまうのも申し訳ないのでひとまず「調べてみた」レベルでアウトプットを出します。

私はまだ並列/並行/非同期処理に詳しいわけではないので、大きな思い違いをしている可能性はあります。鵜呑みにせず、一緒に勉強しましょう。もし変な箇所があればコメント等で連絡ください。

trioとは

「async I/O for humans and snake people」を名乗るライブラリです。requestsなどのAPI設計が優れたライブラリ作者のKenneth Reitzさんっぽい文言ですが、その後に実際に彼のコメントが引用されています。

github.com

まず、こちらのstack overflowの「asyncioとtrioって何が違うの?curioってライブラリもあるそうなんだけど…」という質問に、trioの"primary author"でcurioの"contributor"でもあるNathaniel J. Smithさんが以下のように答えています。

  • asyncioのほうが成熟したライブラリだ
  • trioはコードをもっとシンプルにしてくれる
  • 詳細は多くの違いがある
    • asyncioや関連ライブラリではsome_functionを実行したときにコルーチンが実は完了していない場合もあり、例外やタイムアウト関連で厄介な問題が起きるが、trioの"nurseries"を使う方法ではその動作が完了していることを保証できる
    • trioのタイムアウトや中止の方法が今までにない新しいものである
    • asyncioはAPI設計に冗長な部分や、そのための落とし穴が多い

それでは、「asyncioよりシンプルなAPI」を実現するために、trioではどういう設計になっているのでしょうか?「Async concurrency for mere mortals - PyCon 2018」を引用しつつ紹介します。

Pythonでasync/awaitを使ったコードを書く時、Pythonの同期的な関数の中に、asyncio等のライブラリでasync/awaitの関数を実行して…とプログラミングしていきます。trioのアーキテクチャでは更に"Nurseries"と"Cancel Scope"が追加されています。

asyncioには存在しない"Nurseries"の層では、async with trio.open_nursery()ブロック中でstart_soonでコルーチンをセットしてバックエンドで実行開始し、async withブロックが閉じるときにこれらのコルーチンが処理を完了させている設計になっています。

そうすると、"nursery"のブロックの中でエラーが出たときに、ブロックに例外が通知され適切に処理できることが保証できます。その途中でgoto文論争や構造化プログラミングの話も出ていますが、おそらく「どこで何の処理が行われているか分からないと、適切にエラー処理できない」という例として触れているだけのようです。

次に"Cancel Scope"の説明です。ネットワークを介した処理を行う時、次の3つのことが起こりえます。

  • 成功
  • 失敗
  • どちらでもなく、永久にハングアップする

ハングアップした場合に備えて「必ずタイムアウト処理を書くべき」だとNathaniel J. Smithさんは主張しています。trioでは、async関数の中で「ブロック内の処理がn秒以内に終わらなかった場合はキャンセルする」ような機構が提供されているようです。

Design and internalsによると、この辺りが基となったライブラリの一つのcurioとの大きな違いのようなのですが、両方のAPIに精通しないと読めないですね…。この辺りのAPI設計があまり理解できていないので、tutorialを見てみようと思ったのですが、運悪く「When things go wrong: timeouts, cancellation and exceptions in concurrent tasks」はまだ未整備でした。

関連記事

参考にした記事や、「ここから学んでいけば良さそう」という記事をメモしておきます。

Trio talks

こちらが今回の記事のほぼ元ネタです。この記事では説明し尽くせていない部分もあるので、見ておくといいと思います。

github.com

www.youtube.com

What is core difference between asyncio and trio

stackoverflow.com

Some thoughts on asynchronous api design in a post async/await world

curioとasyncioの異なるアプローチを比較した記事。先述したNathaniel J. Smithさんが書いています。

Some thoughts on asynchronous API design in a post-async/await world — njs blog

Reading list

trioのReading list。trioのアイデアの元になった言語やライブラリが紹介されています。これは骨が折れそうですが、並列/並行処理全般の様々なアプローチを学べそうなので、徐々に読んでいこうと思っています。

github.com

Pythonをとりまく並行/非同期の話

並列・並行処理関連は情報が多くて最初は混乱すると思います。慣れてない方は「CPUプログラムのボトルネックとなる処理がCPUが原因なのか、IOが原因なのか」は重要なのでよく見ておきましょう。

tell-k.github.io

async/awaitはIOが原因となる処理を高速化するための手法です。その後、Nathaniel J. Smithさんの動画を見ると分かりやすいと思います。

あまり関係ないですが、"GIL"のことを"ギル"って発音していたのでビックリしました。自分は"ジル"って読んでたので…。

trioを知る前は「Go, Erlang, Haskellとかの並列・並行処理が得意な(と言われている)言語のアプローチを勉強しようか」って思っていたんですが、もう少し楽できそうです。

最後に

公式リポジトリにもあるように、まだtrioは新しくてやや実験的なプロジェクト(young and still somewhat experimental)のようです。私はプライベートでの開発で試していこうと思います。

他にも、いくつかアドバイスや注意点が書かれています。例えば以下のようなものです。

早くtrioくんと平和な非同期処理の世界に暮らせる日を待ち望んでいます。

わーすた / うるとらみらくるくるふぁいなるアルティメットチョコびーむ MUSIC VIDEO Short Ver. - YouTube

関連ライブラリ・リポジトリ

  • asyncio: みんなご存じ標準ライブラリ。
  • trio: 今回紹介したライブラリです。
  • curio: trioが影響を受けたライブラリの一つ。公式リポジトリの紹介によると、あるベンチマークではtrioの50%程度早いとか。
  • uvloop: asyncioのloopを"ultra fast"なものに置き換えてくれるライブラリ。今回は「使いやすいものを探す」って趣旨ですが一応触れておきます。