orangain flavor

じっくりコトコト煮込んだみかん2。知らないことを知りたい。

神戸Pythonの会でクローリングとスクレイピングについて話した

だいぶ日が経ってしまいましたが、神戸Pythonの会でクローリング・スクレイピングについて2回話してきました。

1回目はRequestsとBeautiful Soupを使った基本的なスクレイピングについて、2回目はHeadless Chromeを使ったスクレイピングについて話してきました。

資料は概要的なもので、これだけ読んでもあまり役立たないですが、以下のリンク先にあります。

演習問題もやりました。こちらのほうがメインです。

github.com

感想など

神戸Pythonの会は去年から始まったコミュニティで、しばしば参加させてもらってます。登壇者との距離が近くて質問しやすく、演習問題などでコードを書く時間を多く取っているのが好みです。

参加者の皆さんは研究や業務など、様々な目的でクローリング・スクレイピングに興味を持たれていました。終了後に感想を伺うとPythonのライブラリの便利さに驚いたといった声や、やりたかったことができそうという声があり、少しは役立ったかなと思います。

参加者の中にはPythonクローリング&スクレイピングを購入してくださった方も多く、とてもありがたかったです。2回目には書籍を読んでから私のTwitterアカウントを知り、Twitterでの告知を見て参加してくださった方も居て、なんとも感激でした。

ちなみにPythonクローリング&スクレイピングは先日また増刷され、半年余りで第4刷になりました。編集者さんからは「新人著者にしてはかなりのヒット」というお言葉をいただき、注目の集まる題材でタイミング良くオファーを頂いたことの幸運を噛みしめるとともに、お世話になった関係者・読者の皆様に改めて感謝しております。今後ともよろしくお願いします。

scraping-book.com

「スモールコンパイラの制作で学ぶプログラムのしくみ」を読んだ

最後まで実装したわけではないが、とりあえず関数呼び出しや四則演算を伴う鶴亀算のコードは動くようになり、あとは時間さえかければ機能を増やせるところまでできたので満足した。

結果として、知識としてなんとなく知っているレベルだったことに実感が伴うようになった。再帰的下向き構文解析とか、実行時のプログラムカウンターやスタックの動きとか。特に、関数呼び出しの時に引数をスタックに積んでから関数内のスコープから負のアドレスで参照するというのはなるほどだった。

スモールコンパイラ の制作で学ぶ プログラムのしくみ

スモールコンパイラ の制作で学ぶ プログラムのしくみ

例え話はわかりにくいがとっつきやすい

この本はずっと昔に買って、いつかやろうと思って本棚に寝ていた。記憶が曖昧だが、おそらく以下の記事を読んで一番とっつきやすそうなのを選んだのだと思う。勧められていた気がしたが、改めて読んだら「文章に難あり」と書いてあった。。

プログラミング名著100選 - やねうらおノーゲーム・ノーライフ http://d.hatena.ne.jp/yaneurao/20050912

この記事のコメントやAmazonのレビューにも書かれているけど、りんごの例え話が意味分からないというのが一番のツッコミどころである。

まあでも例え話は適当に読み飛ばして、コードと虎の巻の部分をちゃんと読み込めばなんとかなる。Javaで書いてるのにC言語的なコードになっているのは辛いが、いい感じにEnumとかMapとかListとかで置き換えればこれも許容範囲。全体的にとっつきやすさがあって良かった。

本を書いたことがある身としては、10年以上経っても問題なく読める本というのはすごいなぁという印象である(携帯電話のiアプリはなくなってしまったが、些細な問題である)。

仕様に対する説明があると嬉しい

さて、上に挙げたツッコミどころを我慢できる場合、次に気になるのは題材として作る言語・コンパイラVMの仕様がなぜこうなっているかという解説が足りていないところである。限られたスペース・難易度で説明する都合上、仕様を簡略化するのは当然なのだが、実際のプロダクトとの比較があると良かった。

例えば、int型の変数宣言vIとint型の関数の戻り値Iが別のキーワードになっている言語は使いづらいと思うけど、なんでこうしたのかとか。まあ関数宣言と変数宣言を最初のトークンで区別できるようにしないとLL(1)にならないからなのだけど、じゃあ同じキーワードを使えるようにするためにはこうする必要がありますとか。

他にもワンパスでコードから直接VMの命令に変換してるけど、一旦構文木を作ったほうがコードの見通しが良くなるのではとか。

よく知らないけどVMの命令セットはこんなものなのだろうか。ディスプレイの退避と回復がditdikなの、イケてないのだが。一般的なものと比較してどうだとかの解説があると良かった。

扱えるデータ型としては整数のみから始まり、3章で文字列型を使えるように拡張するのだけど、文字列型専用のスタックを別に用意するという実装方法になっていた。これだと拡張性がないので一般的な実装方法を知りたかった。ヒープにオブジェクトを確保してポインタをスタックに詰む感じなのかな。

今後

こんな感じでいろいろとツッコミどころがあるゆえに、もっと詳しく勉強したくなる本だった。 とりあえず発展的に学習できそうな以下の3冊を注文してみた。

コンパイラ (新コンピュータサイエンス講座)

コンパイラ (新コンピュータサイエンス講座)

ふつうのコンパイラをつくろう

ふつうのコンパイラをつくろう

言語実装パターン ―コンパイラ技術によるテキスト処理から言語実装まで

言語実装パターン ―コンパイラ技術によるテキスト処理から言語実装まで

しかし、この方面は頑張って勉強・実装しても結局既存の言語を内部DSLとして使ったほうが便利なことがほとんどなので、あまり時間をかけたくないという思いも常に抱えている。その辺の合理的な判断を一時の熱中で抑えてどこまで進めるかが勝負なのかもしれない。

言語を改良する方向性だけでなく、Haskellみたいな関数型言語を使うとパーサーが書きやすいという方向性で勉強するのもいいかもしれない。とりあえず注文した本が届くまで、これまた積まれているHaskell本をやってみる。

プログラミングHaskell

プログラミングHaskell

将棋の定跡を勉強するためのアプリ「Kifu Notebook」を作った

最近3月のライオンを見て、子供の頃以来の将棋を始めるなどした。

適当なアプリをダウンロードしてコンピューターと対戦すると、ちょっと悪い手を指すだけで付け込まれて負けてしまう。序盤の定跡というものの理解が足りていない。相手の指す手に合わせて最適な手を指し続けなければならないので、1つの戦法だけ知っていても意味がない。

図書館で将棋の本を借りてきたり、勉強のためのアプリを購入するなどしてみた。解説されている個別の戦法は理解できるものの、考えられるすべての指し手(ここでは指し手空間*1と呼ぶことにする)における、その戦法の位置づけが把握できない。もちろん指し手空間は膨大なのだが、それをある程度限定するのが序盤の定跡という考え方のはずだ。

というわけで、指し手空間を樹形図のような形で可視化したかった。世の中の人はどうやって勉強しているのだろう。よくわからないので、とりあえず自分で樹形図的にメモを取れるアプリを作ってみた。それがKifu Notebookである。Pythonの人には自明かと思うがJupyter Notebookにインスパイアされている*2

使い方

GitHubReleasesから自分のOS用のバイナリをダウンロードしてきて、以下のように起動する。引数にはメモを保存するJKFファイルのパスを指定する。最初はサンプルファイルをダウンロードするとわかりやすいと思う。存在しないファイルのパスを指定したらまっさらな局面から始まり、Saveしたときにファイルが作成される。

kifu-notebook joseki.jkf

ブラウザーで以下のような画面が開く。

f:id:mi_kattun:20170419120557p:plain

主な使い方は次のとおりである。

  • 盤面でドラッグ&ドロップして(ルール通りに)駒を動かすと指し手が画面下部の樹形図に追加される。
  • 樹形図の指し手をクリックするとその局面に移動できる。
  • 既に次の指し手がある局面で別の手を指すと、分岐として記録される。
  • 樹形図の指し手にホバーした時に表示されるボタンで、指し手を左右に移動したり、削除したりできる。
  • 右のコメント欄にその指し手のコメントを書ける。コメントがある指し手には*がつき、ホバーするとツールチップでコメントが表示される。
  • bad:で始まるコメントがある指し手はそれ以降薄い色になる。指し手はいけない手を記録するのに役立つ。
  • 右上のSaveボタンをクリックすると、コマンド起動時の引数に指定したJKFファイルに現在の状態を保存できる。
  • Auto Saveにチェックを付けておけば、変更する度に自動的に保存される。

実装

ソースコードorangain/kifu-notebookに置いてある。

Kifu for JS

将棋盤はKifu for JSのものを使用している。Reactのコンポーネント自体はライブラリとしてエクスポートされていなかったので、とりあえずforkしたものを使用している。

Kifu for JSはReactで作成されており、コンポーネント単位でいい感じに再利用できたので非常に助かった。

JSON棋譜フォーマット (JKF)

メモを記録するファイル形式としてJSON棋譜フォーマット (JKF) を使用している。Kifu for JSと同じくna2hiroさんのライブラリである。こうやって1人で界隈の必要なものを作っているのはカッコよくて憧れる。

JKFはKifu for JSにおける標準形式?であり、指し手の分岐やコメントなどの必要な要素が満たされており、JSONで使いやすかったので使わせてもらった。ただ、JKFはメインの棋譜があってそこに分岐を付け足す形なので、分岐を平等に扱うKifu Notebookで求められるデータ構造とは若干異なっていた。このため内部的には別の木構造を使っており、入出力の際にJKFと相互変換している。

shogi-piece-images

Kifu for JSでは将棋の駒画像として将棋アプリ用クリエイティブコモンズ画像が使われているが、PNG形式で解像度が低いのでRetinaディスプレイではちょっと気になった。錦旗一字駒はベクター形式も公開されているが、あまり好みじゃなかった。

そこでWikimedia Commonsに公開されていたHari Seldonさんによる駒のSVG画像を改変(枠の除去、背景色・影の追加など)して使用した。shogi-piece-imagesとして、CC BY-SA 3.0 Unportedで公開している。

React

Web UIにはReactを使っている。これまで使ったことなかったけど、Kifu for JSで使われていたので触ってみた。最初はKifu for JSを直接書き換える形で作っていたが、差分が大きくなってきた頃にcreate-react-appを使って1から作り直した。

最初はLocal Stateを使っていたが、複数のコンポーネントで状態を共有したほうが綺麗になる気がしたのでReduxを使うことにした。Presentational ComponentとContainer Componentを分けるという考え方は、propsとstateが混ざっていて気持ち悪かったので納得感があった。React/Redux界隈から漏れ聞こえてくるMiddlewareが重要だなという問題意識までは追いついたが、特に解決できているわけではない。

Go

コマンドはGo言語で書いた。みんなのGo言語に書かれていたgo-assets-builderを使ってビルドしたReactアプリを含めただけのコマンドにしている。

なんとなくブラウザで動かしたかったのでコマンドにしたけど、ユーザー層を考えるとElectronアプリとかのほうが使いやすかったかもしれない。この辺は検討の余地がある。

まとめ

Kifu Notebookという将棋の定跡を勉強するためのアプリを作った。将棋の指し手を樹形図のように可視化してメモできる。

Reactでの開発が面白くて将棋の勉強は放ったらかしになっている。早めにKifu Notebookを使って勉強を始めないと将棋への熱が冷めてしまう。

もしご存知の方がいれば、iPhoneで以下の条件をなるべく満たすオススメの将棋アプリを教えてもらえるとありがたい。

  • 有償で構わないので広告がない
  • 1人でコンピューターと対戦できる
  • 待ったができる
  • 相手のコンピューターの強さを調整できる
  • (可能なら)相手のコンピューターの戦法を指定できる(例えばコンピューターを先手にして居飛車で戦ってほしいなど)

*1:コンピューター将棋における探索空間と同じ意味で使っているが、探索という言葉はしっくりこない。適切な言葉があれば知りたい。

*2:参考: https://twitter.com/orangain/status/839398377410326528

Glance NewsというAndroidアプリを公開しました

Glance Newsはサッと見るだけで世の中の流れをつかむためのニュースアプリです。 NHK NEWS WEBのトップニュース7つを表示するだけの機能を持っています。 デフォルトでは毎日4回、朝8時、昼12時、夕方18時、夜21時に更新され、通知が表示されます。

Android版をGoogle Playで無料公開しています。最近iPhoneに乗り換えて、iOS版は作りかけなのでそのうち公開するかもしれません。

なぜ今さらニュースアプリを作ったか

世の中にはニュースアプリはたくさんあります。しかしなかなか気に入るものがありませんでした。(使ってみた範囲では)どのアプリも基本的に滞在時間を長くするように作られています。無料アプリは滞在時間を長くしたほうが広告収入が増えますし、有料アプリも価格に見合う価値を提供しないといけないので豊富なコンテンツを持っています。

しかし根本的な問題として、私はニュースを見るのにそんなに時間を割きたくないのです。世の中の話題についていくための必要最低限のニュースを知ることができれば十分で、ダラダラといろんなニュースを読み続けるのは時間の無駄です。自身の専門分野であるIT系のニュースは別の方法で購読します。

また、特に無料のアプリにはタイトルで目を引くものの中身が少ない記事も目立ちます。このような記事を読むのは本当に時間の無駄なので、表示されないでほしいのです。

新聞のメリット

さて、このアプリを作るにあたって参考にしたのは新聞です。新聞は終わりゆくメディアみたいなイメージがありますが、良いところもあります。

  • 1日のニュースがまとまっているので、1日1回読めば良い
  • 編集者の手で重要度に応じて並べられている

インターネットではリアルタイムに更新されるのが当たり前でそれが正義という風潮がありますが、ニュースの内容を仕事にしているのでなければ、多少遅れて読んだところで困りません。それどころかリアルタイムで更新されないことが、読む時間を無駄にしないというメリットを生むと考えています。また編集者の手が入ることで、今知っておくべき重要なニュースだけを読めるので、時間を節約できます*1

しかし媒体が紙であることや、紙に由来するレイアウトであることには価値を見いだせないので、自分なりに新聞というメディアをスマホに置き換えてみたのがGlance Newsというアプリです。1回の通知で重要なニュース7個だけが表示されるので、短時間で世の中の流れを追いかけられます。

時間を無駄にしないために

とにかく短時間で重要なニュースだけを読めることにこだわりました。既存のアプリでよくあるのは、通知をタップしてからコンテンツの読み込みが始まって待たされるとか、気になる通知をタップしたときには別のニュースがトップに表示されていて、読みたかったニュースは見当たらないというケースです。

Glance Newsではバックグラウンドでニュースを読み込んでから通知を表示します。通知をタップしたタイミングでは通信は発生しないので待たされることはなく、通知の内容と異なるニュースが表示されることもありません。

ニュースの一覧画面には、ニュースのタイトルと画像の他にニュース本文の冒頭部分が表示されます。既存のアプリではタイトルと画像しか表示されないものが多いですが、冒頭部分が表示されることで興味がある内容かどうか一覧画面で判断できます。ニュースの一覧画面から詳細画面に遷移するときに通信が発生することもありません。

ニュースにお金をかけること

新聞を参考にしているのにNHKのニュースを表示するのは不思議に思われるかもしれません。広告収入で運営されているWebサイトのコンテンツを広告なしで読めるようにするツールを配布するのは、褒められた行為ではありません。その点NHKは受信料で運営されており、Webサイトに広告は表示されません。私も受信料を支払っているので、NHKのニュースを表示することにしました*2。目を引くだけで時間の無駄になるようなニュースがほとんど掲載されないというのも理由の1つです。

ニュースの制作にはお金がかかります。無料で享受するには対価として広告を見なくてはなりません。かと言って月数千円のサービスを契約するのも私にはオーバースペックでした。月数百円で重要なニュースだけを最高のUXで読めるサービスがあると嬉しいのですが。「スマホ時代の新常識!月々800円で世の中の流れを知ろう」みたいな新社会人や就活生向けのビジネスは儲からないでしょうか。

ちなみにこのアプリは無料ですが、あくまでツールとしての価格です。本当は有料にしたかったのですが、Google Playで有料アプリを販売するのに住所公開が必須なことと、ある日突然動かなくなるかもしれないアプリを有料で販売するのは面倒そうという理由で無料です。アプリを気に入って頂けた場合、ぜひNHKの受信料を快く支払ってください(もし支払う条件を満たしていて支払っていなかった場合)。言うまでもないかもしれませんが、私はNHKの関係者ではありません。

実装について

NHKのニュースにはAPIがありません。トップニュースのRSSは提供されていますが、URLとタイトルと概要のみで画像やニュース本文は含まれていません。仕方ないのでニュースの詳細ページのJavaScriptからDuktape Androidを使ってスクレイピングしています。Duktapeについては以下の記事に書きました。

orangain.hatenablog.com

スクレイピングはアプリ側で行っているので、Pythonで動いているわけではありません。が、最初にプロトタイプを作成するときにはPythonを使ってササッと作りました。クローリング・スクレイピングができると、このような活用方法もあります。

まとめ

Glance Newsはサッと見るだけで世の中の流れをつかむためのニュースアプリです。ご興味ありましたらぜひ試してみてください。

Get it on Google Play

*1:もちろんメディアの偏向みたいな話は当然起こり得るので、批判的な目も持ちながら読むのは大切です。

*2:まあ公共放送というのなら、APIを用意してニュースをオープンデータとして公開してほしいようにも思いますが。

Pythonクローリング&スクレイピングの増刷が決まりました

おかげさまで売れ行き好調のようで、Pythonクローリング&スクレイピングの増刷が決まりました。

scraping-book.com

現在Amazonでは新品の紙の本が品切れで、在庫のステータスも表示されない状態になっていますが、2月1日以降は順次在庫が復活するとのことです。 ヨドバシ.comなど他のサイトやリアル書店には在庫がありますので、お急ぎの場合はそちらをご利用ください。電子書籍版も好評発売中です。

Code for Kobeや神戸Pythonの会などの所属コミュニティで話をする機会をいただいたときには、結構買ってくださった方がいて嬉しかったですが、著者の周辺以外でもちゃんと売れているようで本当にありがたいことです。

今後ともよろしくお願いします。

関連記事:

orangain.hatenablog.com

RequestsとBeautiful Soupでのスクレイピング時に文字化けを減らす

多様なWebサイトからスクレイピングする際、Webサイトによっては文字化けが発生することがあります。 RequestsとBeautiful Soupを組み合わせる場合に、なるべく文字化けを減らす方法を解説します。

Beautiful Soupはパーサーを選択できますが、ここではhtml.parserに絞って解説します*1

結論

以下の2点を守ると概ね幸せです。 Content-Typeヘッダーのエンコーディングを参照するコードは下の方に掲載しています。

1. Chardetをインストールしておく。

$ pip install chardet

2. RequestsのResponseオブジェクトをrとしたとき、BeautifulSoupのコンストラクターには(r.textではなく)r.contentを渡す。

import requests
from bs4 import BeautifulSoup

r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')

環境

Webページのエンコーディング

Webページのエンコーディングの指定・推定方法は以下の3つがあります。どれも間違っていることがあるので、これらを組み合わせて正しそうなエンコーディングを選択します。

  1. HTTPレスポンスのContent-Typeヘッダーのcharsetで指定されたエンコーディング
    • この記事ではContent-Typeのエンコーディングと呼ぶ
    • 正しくなかったり、charsetが指定されてなかったりすることがある(特に静的ページの場合)
  2. HTMLの<meta>タグまたはXMLXML宣言で指定されたエンコーディング
  3. HTTPレスポンスのバイト列から推定されたエンコーディング
    • この記事では推定されたエンコーディングと呼ぶ
    • ある程度の長さがあれば概ね正しく推定できる
    • 上記2つに比べて処理に時間がかかる

Requestsとエンコーディング

RequestsではResponseオブジェクトをrとすると次のようになります。

以下の点は注意が必要です。

  • Requestsは<meta>タグのエンコーディングは見ない(HTTPのライブラリなので)
  • Content-Typeにtextが含まれていてcharsetがない場合、r.encoding'ISO-8859-1'となる *3*4
    • この場合、日本語のサイトではr.textが文字化けする

Beautiful Soupとエンコーディング

コンストラクターBeautifulSoup()の第1引数には、HTMLの文字列をstr型またはbytes型で指定できます。

str型のHTML文字列を渡した場合は、Beautiful Soup側ではエンコーディングに関しては特に何もしません。

bytes型のHTML文字列を渡した場合は、Beautiful Soup側でstr型にデコードされます。以下のエンコーディングによるデコードを順に試して、正しくデコードできたものが使われます*5

  1. キーワード引数from_encodingで指定したエンコーディング
  2. <meta>タグのエンコーディング
  3. 推定されたエンコーディング(Chardetがインストールされている場合)

どうしたら文字化けしないのか

ここまで見てきたように、Requestsのr.encodingr.textをそのまま使うと、文字化けしやすくなります。 基本的な戦略としては、以下の2点を守るのがオススメです。

  • Chardetをインストールしておく
  • BeautifulSoup()r.contentを渡してBeautiful Soup側でデコードする

大体OKなのでオススメなコード

記事冒頭にも書きましたが、Chardetをインストールした上で、次のようにすると大体の場合文字化けを回避できます。 シンプルなのでオススメです。

import requests
from bs4 import BeautifulSoup

r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')

このコードでは次の順でエンコーディングを見ます。

  1. <meta>タグのエンコーディング
  2. 推定されたエンコーディング

Content-Typeヘッダーの指定を尊重したい場合のコード

Content-Typeヘッダーの指定を尊重したい場合は、次のようにできます。

r.encoding'ISO-8859-1'の場合は無視することで、Content-Typeヘッダーにcharsetが指定されていない時に文字化けするのを回避できます。ただし、Content-Typeヘッダーが間違っていた場合には文字化けすることがあります*6

import requests
from bs4 import BeautifulSoup

r = requests.get(url)
content_type_encoding = r.encoding if r.encoding != 'ISO-8859-1' else None
soup = BeautifulSoup(r.content, 'html.parser', from_encoding=content_type_encoding)

このコードでは次の順でエンコーディングを見ます。

  1. Content-Typeのエンコーディング
  2. <meta>タグのエンコーディング
  3. 推定されたエンコーディング

まとめ

なるべく文字化けに遭遇することなくスクレイピングしたいですね。

Pythonクローリング&スクレイピングではライブラリを個別に紹介していて、組み合わせたときの話はあまり詳しく書いていませんでした。普段はBeautiful Soupよりlxml推しですが、Beautiful Soupを使う機会があったのでまとめておきました。

scraping-book.com

*1:軽く試した範囲では、lxmlはhtml.parserと同様の結果になり、html5libは推定されたエンコーディングの判別に失敗することがありました。html5libは先頭100バイトしかChardetに渡さないようです。html5libを使う場合は、「Content-Typeヘッダーの指定を尊重したい場合のコード」を使ったほうが良いかもしれません。

*2:requests/models.py参照

*3:requests/utils.py参照

*4:ISO-8859-1はRFC 2616で定められたデフォルト値です。RFC 7231ではこのデフォルト値はなくなったので、3.0に向けての議論はありますが、Kenneth Reitz氏はあまり乗り気ではなさそうです。

*5:詳しくはbs4/builder/_htmlparser.pybs4/dammit.pyを参照

*6:from_encodingに指定したエンコーディングで正しくデコードできない場合は無視されるので、文字化けしないこともあります。

2016年を振り返って

2016年を振り返って

今年はやはり書籍「Pythonクローリング&スクレイピング」を出版できたのが大きかったです。お陰様で良い評価をいただけているようで、ありがたいことです。

scraping-book.com

2013年の振り返りの時点で、やりたいことの1つとして「ブログよりも長いまとまった記事を執筆する」を挙げており、なんとなく書籍の執筆とかやってみたいとは思ってました。ですが、こんなにも都合よく機会が来るとは思いもしませんでした。

コミュニティ活動や発表をしてたわけでもなく、ただブログを書いていただけで、面識のない編集者からオファーを頂けたのは、話すより書くほうが好きな自分にとっては幸せでした。2年かかりましたが、自分の実績として残るものができて嬉しいです。

今年からできた神戸Pythonの会にも参加しています。Pythonについてオフラインで話せる機会・人が増えて、毎回楽しいです。

あとは、今年からボードゲームをよくやるようになりました。カタンパンデミックから始めてどんどんハマっていきました。月に1回ほど集まって友人・知人とプレイしています。いつも気付くと夕方になっていて、世の中にある楽しいゲームの多さにただ驚くばかりです。ボードゲームの楽しさをまだうまく言語化できていませんが、結局のところ、自分なんかよりずっと賢いゲームデザイナーの手のひらの上で懸命に頭を使って踊るのが楽しいのではないかと思っています。

各方面で多くの方のお世話になりました。ありがとうございました。

2017年に向けて

長い間本を書いていて、他のことに使える時間が少なかったので、今後はいろいろ作りかけのものを完成させて公開したいです。2015年の振り返りにも同じことが書いてあり、成長していない感じが辛いですが、来年こそは進められるはずです。

書籍の執筆という大きな仕事も落ち着いたので、今後どのように生きていくかじっくりと考えたいと思います。

今後ともよろしくお願いします。