yosida95https://yosida95.com/2023-12-31T00:00:00+09:00yosida95 の 2023 年まとめ2023-12-31T00:00:00+09:002023-12-31T00:00:00+09:00yosida95tag:yosida95.com,2023-12-31:/2023/12/31/year-in-review.html<p>こんばんは、 yosida95 です。</p>
<p>やめ …</p><p>こんばんは、 yosida95 です。</p>
<p>やめ時を見失った。むやみに 13 年間続けてしまい、やめる勇気も持っていないので 1 年ぶりにブログ記事を書く。</p>
<div class="section" id="section-1">
<h2>健康</h2>
<p>ことし、低音障害型感音難聴を発症した。
文字通り低音域の音が聞こえづらくなる病で、ほかにもわたしは常に耳鳴りが聞こえている。</p>
<p>発症のメカニズムや原因、好発する人の層などがメニエール病と共通していて、「めまいのないメニエール病」とも呼ばれているようだ。
実際、治療もメニエール病改善薬を服用している。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">メニエール病のシロップ薬のイソソルビド、医者にも薬剤師にも異口同音に「本当においしくない」「冷やすとましになるらしい」などと噂まで交えて脅されたので期待半分、不安半分で服用したところ、ベースは甘くてピリピリ刺激はあるが言うほど不味いわけではない。これならちゃんと服用を続けられる。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1643237556673466368?ref_src=twsrc%5Etfw">April 4, 2023</a></blockquote><p>幸い、発症した頃に比べ症状は和らぎ検査上も聴力が正常域までは回復しているが、もとの聴力が他人よりもよかったこともあって完全回復には至っていない。
内耳にたまったリンパ液のむくみ具合で症状の程度が変動するので、調子のよい日とそうでない日がある。</p>
<p>若い女性に多い病気とされるが、アラサー男性であるわたしも発症してしまった。
新型コロナウイルスワクチンの副反応もそうだったが、統計的に稀なことがわたしの身にはよく起こるようだ。</p>
<p>この病気を発症したことで、人の五感だったり外を出歩くための健康だったりは、思っていたよりも危ういものであることを痛感した。
特に、やはり聴力に対する不安が大きくなり、意識的に楽器の練習時間を増やしたり今まで行くことのなかったコンサートに足を運ぶようにした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E7%99%BD%E3%81%A8%E8%8A%B1%E6%9D%9F%E3%83%84%E3%82%A2%E3%83%BC?src=hash&ref_src=twsrc%5Etfw">#白と花束ツアー</a> (@ 東京国際フォーラム in 千代田区, 東京都) <a href="https://t.co/ykw5EOMOpx">https://t.co/ykw5EOMOpx</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1703740585386115344?ref_src=twsrc%5Etfw">September 18, 2023</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%83%A8%E3%83%AB%E3%83%8A%E3%82%A4%E3%83%88?src=hash&ref_src=twsrc%5Etfw">#ヨルナイト</a> <a href="https://twitter.com/hashtag/%E3%83%A8%E3%83%8A%E3%83%95%E3%82%A7%E3%82%B9?src=hash&ref_src=twsrc%5Etfw">#ヨナフェス</a> / I'm at LINE CUBE SHIBUYA in 渋谷区, 東京都 <a href="https://t.co/Hc2LZeewHe">https://t.co/Hc2LZeewHe</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1720711134108639378?ref_src=twsrc%5Etfw">November 4, 2023</a></blockquote></div>
<div class="section" id="section-2">
<h2>仕事</h2>
<p>バイト期間を含めて勤続 10 年を超えた。
相変わらず完全仮想化、コンテナ仮想化、 DNS 、SMTP 、 Web PKI 、 OAuth 、 WebAuthn 、 HTTP 、 gRPC なんかの周りでパソコンカタカタをしている。</p>
<p>例年との違いとして、ことしは今まで避けてきた Web フロントエンドについに手を出した。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ウェッブフロントエンドの知識が 10 年前で止まっていてかろうじて Backbone.js 、他には手で DOM API をゴリゴリ触るやり方しか知らないけれど、速を出すためにいよいよキャッチアップせざるを得ない状況になってきた</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1669605227392274436?ref_src=twsrc%5Etfw">June 16, 2023</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">本件、結局 Next.js とその周辺のいろいろを一から学んでフルスクラッチしたのだけれど、それで勢いがついて今度は Remix を学び始めた</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1722190861654725021?ref_src=twsrc%5Etfw">November 8, 2023</a></blockquote><p>このことで Node.js まわりのエコシステムや JavaScript ツールチェインにもそれなりに慣れ、いざというときにコードを追う必要がある技術選定の選択肢が広がった。
その流れで Eleventy を個人的に触ったあと、かねてから管理や執筆フローが課題になっていた WordPress サイトを Eleventy で置き換える仕事もした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Eleventy 、とにかく困ったら JavaScript を書いたらよいという割り切りがあって気持ちよい。自分で自分の足を撃ち抜いているかもしれないが……。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1737139496116945118?ref_src=twsrc%5Etfw">December 19, 2023</a></blockquote><p>ほかには、仕事上必要になったので mysqld_exporter を UNIX ドメインソケット対応したりバグを直したり、ローマ字とカタカナを相互変換する <a class="reference external" href="https://github.com/yosida95/romaji">yosida95/romaji</a> を書いたりした。</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/prometheus/mysqld_exporter/pull/707">prometheus/mysqld_expporter#707</a></li>
<li><a class="reference external" href="https://github.com/prometheus/mysqld_exporter/pull/714">prometheus/mysqld_exporter#714</a></li>
</ul>
</div>
<div class="section" id="section-3">
<h2>ことし買ってよかったもの</h2>
<div class="section" id="mac-mini">
<h3>Mac mini</h3>
<p>去年 3 月に 8 年間使った Mac mini を新しくしたばかりなのに、それから 10 ヶ月で M2 Mac mini に買い替えた。
M1 Mac mini は計算速度にこそ不満はなかったものの、ただでさえ 16 GB しか載らないメモリを Google Chrome がすべて食いつぶすばかりか、さらに数 GB のスワップを持っていく状況で体験が悪かった。</p>
<p>Mac mini M2 は 32 GB のメモリをつめるようになったのですぐに飛びついた。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">my new gear… <a href="https://t.co/pvYyXFTrKF">pic.twitter.com/pvYyXFTrKF</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1622838493222424577?ref_src=twsrc%5Etfw">February 7, 2023</a></blockquote></div>
<div class="section" id="section-4">
<h3>ヘルシオ</h3>
<p>2014 年にひとり暮らしを始めてから使っていた電子レンジが壊れた。
新生活で揃えた洗濯機やら冷蔵庫やらのポイントで購入したもので、温めのみの単機能で、タイマーも手でひねるゼンマイ式のものだった。</p>
<p>数世代とびどころか隔絶された文明の利器を手に入れて、意気揚々と芋を焼いたり芋をふかしたりしている。
ガスレンジでメインの焼き物をしている間に、サッと切ったり手で割いたりした野菜やきのこを蒸して副菜を増やすこともできる。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">my new gear… <a href="https://t.co/OJq572mjit">pic.twitter.com/OJq572mjit</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1621470090821779456?ref_src=twsrc%5Etfw">February 3, 2023</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">サンキューヘルシオ <a href="https://t.co/gzFIrSwXt3">pic.twitter.com/gzFIrSwXt3</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1721804507187990820?ref_src=twsrc%5Etfw">November 7, 2023</a></blockquote><p>電子レンジとしても、今まで使っていたものは 750W という使い道の限られる出力だったのに、ヘルシオは 500W / 600W / 1,000W と選択できるので冷凍食品のパッケージ裏に書いてある指示通りに温められる。</p>
<p>ただし、ヘルシオを Wi-Fi に接続してアプリと連動したり Web 上のレシピを指定して調理するインターネット連携機能はまるで使い道がなく、アプリの作りもびっくりするくらい悪い。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>ことし寄付した先</h2>
<p>ことし寄付した先は次の 2 団体です。</p>
<div class="section" id="section-6">
<h3>日本赤十字社</h3>
<p>昨年に引き続き、ことしも日本赤十字社に通常寄付と義援金を寄付した。
前回の年報で触れたように出生時に日赤病院で命を拾ったので、これからも継続して支援できるよう毎年自動で寄付する設定をした。</p>
</div>
<div class="section" id="wikimedia-foundation">
<h3>Wikimedia Foundation</h3>
<p>Wikimedia Foundation への寄付は 2014 年から始め、 2018 年 7 月からは毎月の定額寄付を行っており、ことしもこれを継続しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wikipedia (Wikimedia) さま、 2014 年から継続して寄付をし続けているわたしにも寄付のお願いを表示して閲覧を邪魔してくるので体験が悪い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1301408825648377856?ref_src=twsrc%5Etfw">September 3, 2020</a></blockquote></div>
</div>
<div class="section" id="section-7">
<h2>おわりに</h2>
<p>健康で穏やかに暮らしたい。</p>
<p>低音障害型感音難聴はストレスや睡眠不足、カフェイン摂取が悪影響を及ぼすとされている。
もともと入眠に難があり、ベッドに入った後に何時間も寝付けなかったり朝を迎えたりすることがよくある。</p>
<p>2024 年の目標は早寝早起き・規則正しい生活です。</p>
</div>
<div class="section" id="section-8">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2018/12/31/year-in-review.html">yosida95 の 2018 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/12/31/year-in-review.html">yosida95 の 2019 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2020/12/31/year-in-review.html">yosida95 の 2020 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2021/12/31/year-in-review.html">yosida95 の 2021 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2022/12/31/year-in-review.html">yosida95 の 2022 年まとめ</a></li>
</ul>
</div>
yosida95 の 2022 年まとめ2022-12-31T00:00:00+09:002022-12-31T00:00:00+09:00yosida95tag:yosida95.com,2022-12-31:/2022/12/31/year-in-review.html<p>こんばんは、 yosida95 です。</p>
<p>ブロ …</p><p>こんばんは、 yosida95 です。</p>
<p>ブログを初めてから 13 回目の大晦日です。</p>
<p>昔ほどブログを書かなくなり前回の記事は 2021 年の大晦日という有様ですが、せめて毎年続けているこの振り返り記事だけはと思い、アニメ「平家物語」の視聴を中断して書いています。</p>
<p>それではことしもまとめていきましょう。</p>
<div class="section" id="section-1">
<h2>ことし買ってよかったもの</h2>
<div class="section" id="mac-mini">
<h3>Mac mini</h3>
<p>2014 年 10 月以来 8 年ぶりに Mac mini を新しくしました。</p>
<p>散々言われている通り M1 チップは速く、 CPU アーキテクチャの互換性の問題も仮想マシンを動かす用途以外では発生しませんでした。</p>
<p>ただ、 8 年前のパソコンなら何と比較しても同じ感想になる気もします。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">my new gear… <a href="https://t.co/pXtwGmVvyu">pic.twitter.com/pXtwGmVvyu</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1506936242692272131?ref_src=twsrc%5Etfw">March 24, 2022</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">どちらも 8 年以上前に買った Mac mini と Kindle Paperwhite を今週立て続けに更新したところ、あまりの性能の差にこの 8 年間にわたしが無駄にした時間に想いを馳せずにはいられなくなっていふ</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1508036549371260931?ref_src=twsrc%5Etfw">March 27, 2022</a></blockquote><p>どうやら 3 年もの間、新しいパソコンが欲しいといいつつグダグダと悩み続けていたようです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">新しいパソコンが欲しいんだけれど、引き続き Mac mini を買うか、それとも適当な BTO パソコンに Debian 入れるかで悩んでいる。 10 年近く macOS を使っているけれど最近は特にこれを使い続ける理由がないように思う……。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1174214412607119360?ref_src=twsrc%5Etfw">September 18, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">あたらしいパソコンを買うとなった時もはや macOS じゃなくていいという実感はありつつ、とはいえその他の選択肢としてわたしは Linux Desktop しかもっておらず、しかし Linux Desktop 元年はまだ訪れていないので結局 Mac mini を消極的に選択してしまう気がするんだよね</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1384078052909457414?ref_src=twsrc%5Etfw">April 19, 2021</a></blockquote></div>
<div class="section" id="section-2">
<h3>ドラム式洗濯乾燥機</h3>
<p>2014 年に購入し、 1 度修理を歴て使い続けていたドラム式洗濯乾燥機が 5 月に壊れてしまいました。</p>
<p>すぐに買い換えればよいものを様々な言い訳をしつつ騙し騙し使っていましたが、いよいよ騙しきれなくなったので購入しました。</p>
<p>店頭で購入した翌日には配送・設置が完了し、大変よい買い物体験でした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">4年前に買った洗濯乾燥機が故障してしまったのでメーカーの技術者に出張修理を依頼したところ、2万3千円あまりの予定外の出費をしてしまい厳しい。しかし、料金の内訳を見たところ技術料が半分以上を占めていてもっとも高額で、わしは技術にしっかり金を払ったんやという誇らしい気分になっている。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1051661637503971329?ref_src=twsrc%5Etfw">October 15, 2018</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">洗濯乾燥機のヒートポンプが壊れたみたい(前回故障時と同じ症状)なんだけれど、現下の生産・物流情勢で果たして交換部品なり買い替え機種なりは入手できるのだろうか……</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1524300807746641921?ref_src=twsrc%5Etfw">May 11, 2022</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">洗濯機を店員さんのセールストークを聞きながら買いたいが今人混みにでたり対面で会話することははばかられる。オンライン対面販売やってくれないかな……</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1555123339655790592?ref_src=twsrc%5Etfw">August 4, 2022</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">洗濯乾燥機を買い替えたぞ! (@ ヨドバシカメラ マルチメディアAkiba - <a href="https://twitter.com/yodobashi_akiba?ref_src=twsrc%5Etfw">@yodobashi_akiba</a> in 千代田区, 東京都) <a href="https://t.co/35lu1R1Ds0">https://t.co/35lu1R1Ds0</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1601497463562674178?ref_src=twsrc%5Etfw">December 10, 2022</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「温水洗浄でにおいスッキリ」という触れ込みで新しい洗濯機を買ったものの、現在のところ強烈な「新品の匂い」が服に移ってしまってそれどころではない</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1602627341997457410?ref_src=twsrc%5Etfw">December 13, 2022</a></blockquote></div>
<div class="section" id="section-3">
<h3>標準電波リピータ</h3>
<p>自宅は標準電波の受信状況が悪く、せっかくの電波時計を頻繁に手動で時刻あわせする必要がありました。</p>
<p>そこで NTP と同期して標準電波と同じ信号を送信するリピーターを購入しました。
購入したのは <a class="reference external" href="https://prod.kyohritsu.com/P18-NTPLR.html">共立プロダクツ P18-NTPLR</a> です。</p>
<p>西日本の周波数を吹くように設定したところ、送信機と離して置いてある 1 台がなぜか東日本の送信所と同期するようになりました。</p>
<p>このリピーターは同期する NTP サーバーを自由に設定できるので、 <a class="reference external" href="https://developers.google.com/time">Google Public NTP</a> と同期させています。</p>
<p>我が家の時計にもついに <a class="reference external" href="https://developers.google.com/time/smear">Leap Smearing</a> に対応したぞなどと喜んでいたところ、 <a class="reference external" href="https://japan.zdnet.com/article/35196336/">うるう秒自体が廃止</a> されてしまいました。</p>
</div>
</div>
<div class="section" id="section-4">
<h2>ことし寄付した先</h2>
<p>ことし寄付した先は次の 3 団体です。</p>
<div class="section" id="section-5">
<h3>日本赤十字社</h3>
<p>日本赤十字社にはことし初めて寄付を行いました。</p>
<p>わたしは新生児のときに赤十字病院で交換輸血により命をつなぎとめた経験もあるので、来年以降も継続して寄付を行えればと思っています。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wikipedia (Wikimedia) さま、 2014 年から継続して寄付をし続けているわたしにも寄付のお願いを表示して閲覧を邪魔してくるので体験が悪い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1301408825648377856?ref_src=twsrc%5Etfw">September 3, 2020</a></blockquote></div>
<div class="section" id="unhcr">
<h3>国連 UNHCR 協会</h3>
<p>国連 UNHCR 協会にもことし初めて寄付を行いました。</p>
</div>
<div class="section" id="wikimedia-foundation">
<h3>Wikimedia Foundation</h3>
<p>Wikimedia Foundation への寄付は 2014 年から始め、 2018 年 7 月からは毎月の定額寄付を行っており、ことしもこれを継続しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wikipedia (Wikimedia) さま、 2014 年から継続して寄付をし続けているわたしにも寄付のお願いを表示して閲覧を邪魔してくるので体験が悪い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1301408825648377856?ref_src=twsrc%5Etfw">September 3, 2020</a></blockquote></div>
</div>
<div class="section" id="section-6">
<h2>おわりに</h2>
<p>ことしも 1 年ありがとうございました。
また 2023 年末にお会いしましょう。</p>
<p>よいお年をお迎えください。</p>
</div>
<div class="section" id="section-7">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2018/12/31/year-in-review.html">yosida95 の 2018 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/12/31/year-in-review.html">yosida95 の 2019 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2020/12/31/year-in-review.html">yosida95 の 2020 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2021/12/31/year-in-review.html">yosida95 の 2021 年まとめ</a></li>
</ul>
</div>
yosida95 の 2021 年まとめ2021-12-31T00:00:00+09:002021-12-31T00:00:00+09:00yosida95tag:yosida95.com,2021-12-31:/2021/12/31/year-in-review.html<p>こんばんは、 yosida95 です。</p>
<p>年の …</p><p>こんばんは、 yosida95 です。</p>
<p>年の瀬にわたし自身の 1 年を個人的に振り返るこの記事も気づけばこれで 12 本目です。
干支を一回りしてしまいました。</p>
<p>昔ほどブログを書かなくなり、もはや 1 年に 1 度のこの記事が主な投稿となっています。</p>
<p>1 年のまとめ記事は執筆にあたりその年を総括できることはもちろんですが、後年自分の身に起こった出来事を振り返る上でも有意義だと感じているので、せめてこの投稿だけは継続していきたいものです。</p>
<p>それではことしもまとめていきましょう。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-1" id="toc-entry-1">ボイストレーニング</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-2">筋力トレーニング</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-3">ことし合格した資格試験</a><ul>
<li><a class="reference internal" href="#section-4" id="toc-entry-4">測量士補</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-5" id="toc-entry-5">ことし買ってよかったもの</a><ul>
<li><a class="reference internal" href="#flexispot" id="toc-entry-6">Flexispot 電動昇降スタンディングデスク</a></li>
<li><a class="reference internal" href="#aeron-chair" id="toc-entry-7">Aeron Chair</a></li>
<li><a class="reference internal" href="#section-6" id="toc-entry-8">でかい冷蔵庫</a></li>
<li><a class="reference internal" href="#qhd" id="toc-entry-9">27" QHD 液晶ディスプレイ</a></li>
<li><a class="reference internal" href="#nintendo-switch" id="toc-entry-10">Nintendo Switch</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-7" id="toc-entry-11">ことし寄付した先</a><ul>
<li><a class="reference internal" href="#internet-archive" id="toc-entry-12">Internet Archive</a></li>
<li><a class="reference internal" href="#wikimedia-foundation" id="toc-entry-13">Wikimedia Foundation</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-8" id="toc-entry-14">おわりに</a></li>
<li><a class="reference internal" href="#section-9" id="toc-entry-15">これまでのまとめ</a></li>
</ul>
</div>
<div class="section" id="section-1">
<h2>ボイストレーニング</h2>
<p>ことしも 1 年間ボイストレーニングを受講しました。
2018 年の 7 月にボイストレーニングスクールに入所したので、およそ 3 年半継続していることになります。</p>
<p>2020 年初頭に新型コロナウィルス感染症の影響で対面レッスンが行えなくなりオンラインレッスンに移行しましたが、ことしは 1 年丸々オンラインでレッスンを受けました。</p>
<p>オンラインレッスンはカメラとマイクを通して行うために講師に伝わる情報量に制限があります。
このほか自宅の防音の問題などもあり、やはり内容に制限があります。
その制限の中でできることは概ねやり尽くしてしまった感じがあります。</p>
<p>しかし、わたしの感染症への不安の度合いや、わたしが実施している感染症対策の強度の面から対面レッスンに切り替える目処は立っていません。</p>
<p>このため、そろそろ今後の計画を考える必要がありそうです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ボイストレーニングほど感染症対策と相性の悪いアクティビティもないわね。防音ブースという密室で、大きく太い声で飛沫を飛ばし、腹式呼吸で換気量を増やす。マスクは酸欠が怖い。いまわたしはオンラインでレッスンを受けているけれど、それも防音やタイムラグの問題で完全ではないし……。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1265895339661262849?ref_src=twsrc%5Etfw">May 28, 2020</a></blockquote></div>
<div class="section" id="section-2">
<h2>筋力トレーニング</h2>
<p>2020 年に引き続き、ことしも自宅での自重トレーニングとダンベルトレーニングをやりました。</p>
<p>通っていたジムは再開したものの、未だ感染症の不安を拭いきれずにいます。
ジムのウェブサイトを見ては「そろそろ重たいバーベルを持ちたいな〜しかしまだ行けないな〜」と嘆息することを数週間に一度繰り返しています。</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="13" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-3">
<h2>ことし合格した資格試験</h2>
<p>ことしは一切の資格試験を受験しませんでした。</p>
<p>しかし、昨年実施されことし合格の発表がされた試験があります。</p>
<div class="section" id="section-4">
<h3>測量士補</h3>
<p><a class="reference external" href="https://yosida95.com/2021/01/25/assistant-surveyor.html">測量士補試験に合格しました</a> 。</p>
<p>試験自体は 2020 年 11 月に(半年の延期を経て)実施されましたが、その合格通知がことしになって届きました。</p>
<p>例によりこの資格もわたしの仕事や生活の上では役に立つ見込みはありません。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>ことし買ってよかったもの</h2>
<p>ことしはたくさんの大きなものを買いました。</p>
<p>ワクチンにより免疫を獲得しただろうことの達成感と開放感に託けて、以前から欲しい・必要だと思っていたものの費用や製品を選ぶ手間のことを考えて躊躇していた品々をまとめて買ってしまいました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">免疫を獲得して出歩くことのリスクが低減されたら家具のショウルームに行って椅子を買ったり、電気屋に行ってデカイ冷蔵庫を買ったりするぞと決めているが、これにより外出自粛中で増えた貯蓄を超えるお金を一気に吐き出しそう</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1405773817213984770?ref_src=twsrc%5Etfw">June 18, 2021</a></blockquote><div class="section" id="flexispot">
<h3>Flexispot 電動昇降スタンディングデスク</h3>
<p>これまで 2014 年にひとり暮らしを始める際に IKEA で購入したガラス天板のデスクを使っていましたが、天板が長方形ではなく「オシャレに」湾曲していて物を置ける実質の面積を稼ぐことができないことや、ガラス天板が汚れやすく冬は冷たいことなどに不満がありました。</p>
<p>そこで近年 IT 技術者の界隈で話題となっている電動昇降スタンディングデスクを導入することにしました。</p>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">いま避難が必要になるとまずい <a href="https://t.co/jSUpL1X5pf">pic.twitter.com/jSUpL1X5pf</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1353213194647465989?ref_src=twsrc%5Etfw">January 24, 2021</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">進捗あります! <a href="https://t.co/W1lTcANvOQ">pic.twitter.com/W1lTcANvOQ</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1353271875669909505?ref_src=twsrc%5Etfw">January 24, 2021</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">FlexiSpot のスタンディングデスクをひとりで組み立てたんですが、特に躓くこともなく 2 時間弱でなんとかなった。持ち上げた感じおそらく 50 - 60 kg あって、組み上げてからこれをひっくり返す必要があるので、腕の長さや筋力が足らなければ難しかったと思う。それから電動ドライバーは文明。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1353273171810476032?ref_src=twsrc%5Etfw">January 24, 2021</a></blockquote></div>
<div class="section" id="aeron-chair">
<h3>Aeron Chair</h3>
<p>これもデスク同様ひとり暮らしを始める際に IKEA で購入したかろうじてオフィスチェアと呼べるような椅子を使ってきましたが、腰のサポートやフィット感などで気に入らない点が多くあったこと、 7 年間の使用で椅子の傷みが目についてきたことから買い替えることにしました。</p>
<p>日本橋にあるオフィスチェアのショウルーム WORKAHOLIC さんに足を運び、「チェアコンシェルジュ」の方につきっきりで相談しながら椅子を探したところ、結局高級オフィスチェアとしてド定番の Aeron Chair を選ぶことになりました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2 時間つきっきりで椅子選びを手伝ってくれて完全によい体験だった! (@ ワーカホリック - <a href="https://twitter.com/WORKAHOLIC_web?ref_src=twsrc%5Etfw">@workaholic_web</a> in 中央区, 東京都) <a href="https://t.co/T4aQ40QbDD">https://t.co/T4aQ40QbDD</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1452536872299859968?ref_src=twsrc%5Etfw">October 25, 2021</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="en" dir="ltr">my new gear… <a href="https://t.co/8i2WPvGdDg">pic.twitter.com/8i2WPvGdDg</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1453594734312656899?ref_src=twsrc%5Etfw">October 28, 2021</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">正直、体に一番フィットしたのは Gesture だったんだけれど、背もたれがクッション製で試座している間にも背中がぽっかぽかしてきて夏が不安になったので次点の Aeron Chair Remastered にした</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1453596291578036226?ref_src=twsrc%5Etfw">October 28, 2021</a></blockquote></div>
<div class="section" id="section-6">
<h3>でかい冷蔵庫</h3>
<p>Aeron Chair を購入したその日、でかい冷蔵庫も購入しました。</p>
<p>でかい冷蔵庫に対する憧れは Twitter をさかのぼる限り遅くとも 2017 までには持っていましたが、ことし念願かなってようやく大きな冷蔵庫を手に入れました。
設置場所の問題からさすがに 600L というわけにはいきませんでしたが、 3 人家族向けとされる 451 L の三菱電機 MR-MB45G を少し廊下にはみ出して使っています。</p>
<p>ヨドバシ Akiba の店頭で購入しましたが、わたしを担当した店員さんに第一声で「大きければ大きいほどよいと思っています」と伝えて製品選びを手伝ってもらいました。</p>
<p>半導体不足により冷蔵庫の納期にも影響が出ていましたが、今回選んだものはヨドバシの倉庫に在庫があったため、購入の 3 日後に設置してもらえました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ひとり暮らしだけど600Lくらいのでかい冷蔵庫欲しくなってきた</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/862974429998981120?ref_src=twsrc%5Etfw">May 12, 2017</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">これからひとり暮らしを始める皆さんに 6 年間ひとり暮らしをするわたしからひとつだけ確実にアドバイスできることは、とにかくでかい冷蔵庫を買えの 1 点に尽きる。家に置ける最大のサイズのものを買え。冷蔵スペースと同じくらい冷凍スペースの広さも重要だ。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1306904592253218816?ref_src=twsrc%5Etfw">September 18, 2020</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">my new gear… (でかいのと部屋が狭いのとで写真に収まりきらなかった) <a href="https://t.co/PGLm4vbnhD">pic.twitter.com/PGLm4vbnhD</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1453594294850232323?ref_src=twsrc%5Etfw">October 28, 2021</a></blockquote></div>
<div class="section" id="qhd">
<h3>27" QHD 液晶ディスプレイ</h3>
<p>これまで 23 インチの Full HD ディスプレイを横に 2 枚並べていましたが、年々ウェブサイトが要求する(特に横の)解像度が大きくなってきていて、ウェブブラウザを全画面表示せずに複数のウィンドウを並べて使うスタイルの限界を感じていました。</p>
<p>また、コーディングの際も 1 行の最大文字数を 80 文字とするスタイルは時代遅れになりつつあり、 Full HD のままではエディタを縦分割すると行が溢れてしまうようになりました。</p>
<p>そこで 1 画面に表示できる情報量を増やすべく QHD の液晶ディスプレイを購入しました。</p>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">新しいディスプレイ、めちゃくちゃ賑やかで 5 秒毎に色が変わる <a href="https://t.co/NjDJqH0jh9">pic.twitter.com/NjDJqH0jh9</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1348902219307864065?ref_src=twsrc%5Etfw">January 12, 2021</a></blockquote></div>
<div class="section" id="nintendo-switch">
<h3>Nintendo Switch</h3>
<p>昨年ほしいと思ってから 1 年越しに Nintendo Switch を購入しました。</p>
<p>自宅にはテレビがないため、ことし買った 27" ディスプレイに接続して遊んでいます。</p>
<p>もっぱら Fit Boxing 2 専用機です。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">my new gear... (15 年ほどぶりにゲーム機を手に入れた) <a href="https://t.co/rWFVRmZ7mP">pic.twitter.com/rWFVRmZ7mP</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1373245384009555970?ref_src=twsrc%5Etfw">March 20, 2021</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わたしが最後に持っていたゲームハードはニンテンドー DS Lite なんだけれど Switch はちょっと欲しいと思っている。 Fit Boxing で早見沙織トレーナーに指導されたい。</p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1228193650196111360?ref_src=twsrc%5Etfw">February 14, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やりました。寝違えて継続は 95 日で途絶えてしまった <a href="https://twitter.com/hashtag/NintendoSwitch?src=hash&ref_src=twsrc%5Etfw">#NintendoSwitch</a> <a href="https://t.co/E8SwRbYU8j">pic.twitter.com/E8SwRbYU8j</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1410949448419528707?ref_src=twsrc%5Etfw">July 2, 2021</a></blockquote></div>
</div>
<div class="section" id="section-7">
<h2>ことし寄付した先</h2>
<div class="section" id="internet-archive">
<h3>Internet Archive</h3>
<p>調べ事をしているときにうっかり頼まれてしまったので、初めて Internet Archive に寄付を行いました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">頼まれると断れないがちなので…… | I just donated to the Internet Archive, the world's largest digital library and home of the Wayback Machine. Join me and chip in what you can! <a href="https://t.co/T3tH7Rwko9">https://t.co/T3tH7Rwko9</a> <a href="https://t.co/9AR92h7hPJ">pic.twitter.com/9AR92h7hPJ</a></p>— よしだ (@yosida95) <a href="https://twitter.com/yosida95/status/1465953802649931776?ref_src=twsrc%5Etfw">December 1, 2021</a></blockquote></div>
<div class="section" id="wikimedia-foundation">
<h3>Wikimedia Foundation</h3>
<p>Wikimedia Foundation への寄付は 2014 年から始め、 2018 年 7 月からは毎月の定額寄付を行っており、ことしもこれを継続しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wikipedia (Wikimedia) さま、 2014 年から継続して寄付をし続けているわたしにも寄付のお願いを表示して閲覧を邪魔してくるので体験が悪い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1301408825648377856?ref_src=twsrc%5Etfw">September 3, 2020</a></blockquote></div>
</div>
<div class="section" id="section-8">
<h2>おわりに</h2>
<p>2021 年はいかがお過ごしでしたでしょうか。</p>
<p>わたしにとっては 2020 年に起こった生活様式の大きな変化がことしも続き、多くの期間で外出自粛を求められ満足に行動できない年でした。</p>
<p>一方で徐々に 2020 年以前の日常も取り戻しつつあるように思います。
2020 年以来休止されていた催事が 2 年ぶりに実施される様子もちらほらと観測しています。</p>
<p>また、こうした休止を余儀なくされた催事がオンライン配信に活路を開き、年がら年中インターネットを摂取しているわたしにとってはむしろ身近なものとなりました。</p>
<p>そういった接触から新たに興味をもったアーティストもたくさんいて、ことしはわたしの人生で最もたくさんの CD を買った年となっています。</p>
<p>これまで滅多に足を運んだことのなかったコンサートにも行ってみたいという気持ちが高まっています。</p>
<p>2022 年は2020 年以前の日常の回復とニューノーマルの定着により、 2 年間我慢してきたこれまでの楽しみとこの 2 年で見つけた新たな楽しみがどちらも広がる 1 年になればよいと願っています。</p>
<p>ことしもよろしくお願いします。</p>
</div>
<div class="section" id="section-9">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2018/12/31/year-in-review.html">yosida95 の 2018 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/12/31/year-in-review.html">yosida95 の 2019 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2020/12/31/year-in-review.html">yosida95 の 2020 年まとめ</a></li>
</ul>
</div>
測量士補試験に合格しました2021-01-25T00:00:00+09:002021-01-25T00:00:00+09:00yosida95tag:yosida95.com,2021-01-25:/2021/01/25/assistant-surveyor.html<p>こんにちは、 yosida95 です。</p>
<p>2020 (令 …</p><p>こんにちは、 yosida95 です。</p>
<p>2020 (令和 2 )年 11 月 22 日に実施された測量士補試験に合格したのでご報告します。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-2" id="toc-entry-1">測量士補とは</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-2">受験のきっかけ</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-3">出願</a></li>
<li><a class="reference internal" href="#section-5" id="toc-entry-4">学習</a></li>
<li><a class="reference internal" href="#section-6" id="toc-entry-5">試験</a></li>
<li><a class="reference internal" href="#section-7" id="toc-entry-6">合格</a></li>
<li><a class="reference internal" href="#section-8" id="toc-entry-7">今後</a></li>
<li><a class="reference internal" href="#section-9" id="toc-entry-8">これまでに取得した国家資格</a></li>
</ul>
</div>
<div class="section" id="section-2">
<h2>測量士補とは</h2>
<p>日本では国または公共団体が行う土地の測量について、測量の重複を防いだり、測量の精度を確保することなどのために測量法という法律が施行されています。</p>
<p>この測量法では測量に従事するための要件として、測量士または測量士補として国土地理院の名簿に登録されている必要があるとされています。</p>
<blockquote>
<div class="line-block">
<div class="line">(測量士及び測量士補)</div>
<div class="line">第四十八条 技術者として基本測量又は公共測量に従事する者は、第四十九条の規定に従い登録された測量士又は測量士補でなければならない。</div>
<div class="line">2 測量士は、測量に関する計画を作製し、又は実施する。</div>
<div class="line">3 測量士補は、測量士の作製した計画に従い測量に従事する。</div>
</div>
<p class="attribution">—<a class="reference external" href="https://elaws.e-gov.go.jp/document?lawid=324AC0000000188">測量法 | e-Gov法令検索</a></p>
</blockquote>
<p>この度わたしが受験し合格した測量士補試験は、この測量士補として土地の測量に従事するに足る法律理解、測量の原理や手順に関する知識および技能を有していることを認定するために行われている試験で、国土地理院が実施しています。</p>
<blockquote>
<div class="line-block">
<div class="line">測量士補試験</div>
</div>
<div class="line-block">
<div class="line">(1)測量に関する法規</div>
<div class="line">(2)多角測量</div>
<div class="line">(3)汎地球測位システム測量</div>
<div class="line">(4)水準測量</div>
<div class="line">(5)地形測量</div>
<div class="line">(6)写真測量</div>
<div class="line">(7)地図編集</div>
<div class="line">(8)応用測量</div>
</div>
<div class="line-block">
<div class="line">※ 上記の各専門科目に関連して技術者として測量業務に従事する上で求められる一般知識(技術者倫理、測量の基準、基礎的数学、地理情報標準等)についても出題する。</div>
</div>
<p class="attribution">—<a class="reference external" href="https://www.gsi.go.jp/sokuryosidou/R2_testpolicy.html">令和2年測量士・測量士補試験問題作成方針</a></p>
</blockquote>
</div>
<div class="section" id="section-3">
<h2>受験のきっかけ</h2>
<p>一言で言えば(国家)資格コレクションの一貫です。</p>
<p>仕事で必要になったというわけではなく、測量計画機関や測量作業機関として働く予定があるわけでもありません。</p>
<p><a class="reference external" href="http://www.shikakude.com/paje/kokkashikaku.html#k11">国家資格の一覧</a> を眺めていたときに目についたことがきっかけだったと思います。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">記憶力や思考力が衰える前に日常生活はおろかソフトウェアエンジニア職でも役に立たないんだけれどその筋の業界では重宝される資格みたいなのを集めて遊びたいな</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1007619068348600320?ref_src=twsrc%5Etfw">June 15, 2018</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">持っていても仕事はおろか趣味でも役に立たないがしかし欲しい免許や資格(合格率や必要資金的にそこそこ難関)がいくつかあり、人生は短いから取ってしまおうという気持ちと人生は短いからもっと有効に使おうという気持ちがせめぎ合っている</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1091365080279613441?ref_src=twsrc%5Etfw">February 1, 2019</a></blockquote></div>
<div class="section" id="section-4">
<h2>出願</h2>
<p>今回も例にもれず、願書の発送を締め切り当日のギリギリのタイミングで行いました。
というか、配布されている願書を受け取ったのも締め切り当日で、その日の内に記入して郵便局に持っていきました。</p>
<p>同様のことを宅地建物取引士(宅建士)出願時にもやって懲りたはずなのに、再び同じ轍を踏んでしまったばかりか、今回は更に状況が悪化してしまいました。</p>
<p>願書には返信用の封筒を同封する必要があるのですが、郵便窓口で買った切手をその場で窓口の方に貼付してもらい、さらにのりを借りてその場で封をして発送する始末でした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">きょうの消印で行政機関に出さなくてはいけない書類があり、きょうは有給休暇なのにも関わらずオフィスに来て机と文房具を借りて記入し、郵便局を 2 往復することで窓口が閉まる 15 分前に発送を完了することができた</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1221717548510531585?ref_src=twsrc%5Etfw">January 27, 2020</a></blockquote></div>
<div class="section" id="section-5">
<h2>学習</h2>
<p>こうしてなんとか出願を済ませ、その後学習を始めたわけですが、ここにおいても生来の先延ばし癖が発現してしまい、結局受験直前の 1 週間、賞味 15 時間程度で間に合わせました。</p>
<p>主に参考書 1 冊を 1 周だけ通読したほか、その参考書のチャプター末にある過去の出題を改題した参考問題を解いて理解を確認しました。
また、過去の出題を分野ごとにまとめた問題集も購入していたので、これは直前の 1 日と当日の朝、そして会場に向かう電車の中で、図形問題を中心に考え方や補助線の引き方、立式が正しいことを確認しました。</p>
<p>ところで、願書を 2020 年 1 月に提出していることから窺えるように、本来この試験は 2020 年 5 月 17 日に予定されていました。
しかし、この日は東京を含む 8 つの都道府県で 1 度目の緊急事態宣言が発令されていた頃で、延期となってしまいました。</p>
<p>半年以上も試験実施が延期になったことから万全の準備を決意するタイミングが 2 度もあったはずなのに、今回のわたしもダメでした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">基本的に怠惰な上に経験からすら学ばない愚者なのに記憶力と要領のよさだけでここまで生き残ってしまい、剰えセルフハンディキャピングに対しても成功体験を積み重ねてきてしまったために生存バイアスが強いことがコンプレックスにも関わらず努力を覚えられずに、いまや能力の自転車操業じみてきた……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1161209416361709569?ref_src=twsrc%5Etfw">August 13, 2019</a></blockquote></div>
<div class="section" id="section-6">
<h2>試験</h2>
<p>今回の試験で何より厳しかったことは計算機を利用できないことでした。
桁数 6 桁程度の四則演算を手計算で行う必要があり、また、三角関数や平方根の計算も問題冊子末尾の表から値を写して利用することが求められます。</p>
<p>こういった作業は高校の数学考査以来 7 年以上ぶりで、当時にくらべて我ながら驚くほど計算速度と計算の正確さが損なわれていました。</p>
<p>結局 15 時間の学習ではこのリハビリができず、試験中も計算間違いによる手戻りや値の転記ミスでかなりの時間を浪費してしまい、とても焦りました。</p>
</div>
<div class="section" id="section-7">
<h2>合格</h2>
<p>前述のように試験では手計算に苦戦し、他の受験生が解答を終え続々と途中退席していく中で、わたしは試験時間を目一杯使い切りました。</p>
<p>そのせいで時間配分を間違え、「解いたもののこれ合っているのか?」という問題もいくつかありました。</p>
<p>したがって、国土地理院から A4 サイズ 3 つ折りの封書を受け取ったときには「合格証にしては小さすぎるし、よもや落ちたのでは」と不安がよぎりました。</p>
<p>わたしがこれまでに受けた国家試験では A4 サイズや B5 サイズの合格証が届いていたので、測量士補では合格の事実と合格番号を告げる封書のみが届くとは知らなかったのです。</p>
<p>いずれにしても、無事に合格することができてホッとしています。</p>
</div>
<div class="section" id="section-8">
<h2>今後</h2>
<p>今後も折りをみて何らかの面白そうな資格をとっていこうと思います。</p>
<p>その時は、今度こそ余裕出願・余裕学習で臨みたいです。</p>
<p>しかし、目下のところは感染症の流行が落ち着くまで、受験は控えます。
わたしの受験は不要不急の最たるものだと思いますし、せっかく仕事や習い事も在宅でやっている中、受験会場で感染症をもらっては元も子もないので。</p>
<p>実のところ、 2020 年中はほかにも出願して受験手数料も払っていた試験が複数ありましたが、感染拡大防止のために当日会場に行くことを控えました(出願を次回以降に繰り越せれば嬉しいのに……)。</p>
<p>ひとまずは <a class="reference external" href="https://yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html">知的財産の管理と活用ができて</a> 、 <a class="reference external" href="https://yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html">資産設計業務ができて</a> 、 <a class="reference external" href="https://yosida95.com/2019/12/04/real-estate-transaction-agent.html">不動産取引や国土利用などにも詳しい</a> 、ソフトウェアエンジニアとして活動していきます。</p>
</div>
<div class="section" id="section-9">
<h2>これまでに取得した国家資格</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">3 級ファイナンシャル・プランニング技能士になりました</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html">2 級ファイナンシャル・プランニング技能士になりました</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html">2 級知的財産管理技能士になりました</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/12/04/real-estate-transaction-agent.html">宅地建物取引士資格試験に合格しました</a></li>
</ul>
</div>
yosida95 の 2020 年まとめ2020-12-31T00:00:00+09:002020-12-31T00:00:00+09:00yosida95tag:yosida95.com,2020-12-31:/2020/12/31/year-in-review.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。</p>
<p>2020 年もあと数時間を残すのみとなりました。
わたしがインターネットに棲み着くようになってから毎年継続している 1 年のまとめ記事もこれで 11 本目となります。</p>
<p>ことしは生活様式に大きな変化を求められた年でした。
それでも変わったこと・変わらなかったことがあります。</p>
<p>ことしもまとめてゆきましょう。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-1" id="toc-entry-1">はじめに</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-2">ボイストレーニング</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-3">筋力トレーニング</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-4">旅行</a></li>
<li><a class="reference internal" href="#section-5" id="toc-entry-5">読んだコミック</a><ul>
<li><a class="reference internal" href="#section-6" id="toc-entry-6">ここは今から倫理です。 / 雨瀬シオリ</a></li>
<li><a class="reference internal" href="#section-7" id="toc-entry-7">先生のお人形 / 藤のよう</a></li>
<li><a class="reference internal" href="#section-8" id="toc-entry-8">娘の友達 / 荻原あさ美</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-9" id="toc-entry-9">観たアニメ</a><ul>
<li><a class="reference internal" href="#section-10" id="toc-entry-10">うさぎドロップ</a></li>
<li><a class="reference internal" href="#section-11" id="toc-entry-11">甘々と稲妻</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-12" id="toc-entry-12">買ってよかったもの</a><ul>
<li><a class="reference internal" href="#iphone-se-2nd-gen" id="toc-entry-13">iPhone SE (2nd Gen.)</a></li>
<li><a class="reference internal" href="#section-13" id="toc-entry-14">グラファイトヒーター</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-14" id="toc-entry-15">ことし寄付した先</a><ul>
<li><a class="reference internal" href="#mozilla-foundation" id="toc-entry-16">Mozilla Foundation</a></li>
<li><a class="reference internal" href="#wikimedia-foundation" id="toc-entry-17">Wikimedia Foundation</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-15" id="toc-entry-18">おわりに</a></li>
<li><a class="reference internal" href="#section-16" id="toc-entry-19">これまでのまとめ</a></li>
</ul>
</div>
</div>
<div class="section" id="section-2">
<h2>ボイストレーニング</h2>
<p>ことしも 1 年間ボイストレーニングを継続しました。</p>
<p>しかし、感染症対策のため 4 月からオンラインレッスンに切り替わり、6 月から教室での対面レッスンが再開したものの、わたしはそのままオンラインレッスンを継続しました。</p>
<p>このため、どうしても対面に比べてラグや情報量の欠落が気になるオンラインレッスンで、また自宅ではあまり大きな声を出せないことも相まって満足な体験を得ることはできず、モチベーションも下がりつつあります。</p>
<p>ただ、レッスン自体は楽しいことに変わりないので、より早く感染症の脅威が過ぎ去ることを願っています。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ボイストレーニングほど感染症対策と相性の悪いアクティビティもないわね。防音ブースという密室で、大きく太い声で飛沫を飛ばし、腹式呼吸で換気量を増やす。マスクは酸欠が怖い。いまわたしはオンラインでレッスンを受けているけれど、それも防音やタイムラグの問題で完全ではないし……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1265895339661262849?ref_src=twsrc%5Etfw">May 28, 2020</a></blockquote></div>
<div class="section" id="section-3">
<h2>筋力トレーニング</h2>
<p>2018 年 7 月から始めたトレーニングですが、昨年 2019 年 10 月に膝を怪我して脚を満足にトレーニングできなくなり、それもぼちぼち治ってきてトレーニングを再開しようかというタイミングだった 4 月からはジムが閉鎖され利用できなくなるという散々な 1 年でした。</p>
<p>ジムが再開されて以降もできるだけ人との接触を避けるためジムに通うことをやめ、自宅でのトレーニングに切り替えました。</p>
<p>2019 年 3 月に自宅に簡単なトレーニング用具を揃えていたので、これを活用しています。
しかし、やはり自宅では大きな重量を扱うことができないので、十分な強度のトレーニングはできていません。</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="13" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BvRL9ykhKP8/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>1 月には人と一緒にボルダリングを始め、教本なんかも揃えてやっていくぞと意気込んでいたところで人と会えなくなってしまったので、そのまま再開するタイミングを窺っていたら 1 年が終わってしまいました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">様子 <a href="https://t.co/nFl2e3qKCf">pic.twitter.com/nFl2e3qKCf</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1221310297589219328?ref_src=twsrc%5Etfw">January 26, 2020</a></blockquote></div>
<div class="section" id="section-4">
<h2>旅行</h2>
<p>ことしは旅行に行くことができませんでした。
また、 <a class="reference external" href="https://ekimemo.com/">駅メモ</a> のために大回り乗車をするようなこともなく、東京都から出ることのない 1 年でした。</p>
<p>もし東京オリンピックが予定通り開催されていれば、避暑と人を避けることを兼ねてしばらく北海道で暮らすことを予定していましたが、これも実現できずじまいでした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">本来ならオリンピック開会式の翌日となっていたきょう、わたしたちは開会式のために捻出された 4 連休を虚無とともに過ごしているわけですよ……(なお、旅行先として検討していた北海道旭川市にはふるさと納税をしました)</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1286934579643703296?ref_src=twsrc%5Etfw">July 25, 2020</a></blockquote><p>なお、旅行とは違いますが、南極観測船しらせ船内分室と南極にある昭和基地内分室に消印を郵頼していたはがきが無事に戻ってきて、南極と「 <a class="reference external" href="http://yorimoi.com/">宇宙よりも遠い場所</a> 」に思いを馳せることはできました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/B_HdtJMF_x4/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="13" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/B_HdtJMF_x4/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/B_HdtJMF_x4/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-5">
<h2>読んだコミック</h2>
<p>ことしは記録がある限り 448 冊のコミック・ライトノベルを読んだようです。
すべての記録は <a class="reference external" href="https://bookmeter.com/users/662877/books/read">yosida95さんの読んだ本 - 読書メーター</a> で公開しています。</p>
<p>この中でもことし新たに出会って読み始めたシリーズ(ことしより前に刊行されたものを含む)で特に印象に残ったものは以下です。</p>
<div class="section" id="section-6">
<h3>ここは今から倫理です。 / 雨瀬シオリ</h3>
<a class="reference external image-reference" href="https://www.amazon.co.jp/dp/4088907914/"><img alt="「ここは今から倫理です。」" src="https://cover.openbd.jp/9784088907918.jpg" style="width: 30%;" /></a>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">「ここは今から倫理です。」の 1 巻だけ買って 2 週間くらい積んでいたんだけれど、きょうになって既刊 4 巻まで一気に読んでしまった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1236649451239788544?ref_src=twsrc%5Etfw">March 8, 2020</a></blockquote><p>高校倫理教諭・高柳が彼の授業を選択した生徒が抱える問題に対して、心の有り様や持ち方を示すことで共に向き合い、「善く生きる」方法や考え方を探っていく物語です。</p>
<p>わたしはこの物語やこの物語で引用される哲学者の言葉を通じて哲学、特に西洋哲学に対する興味がわき、手始めに本棚で眠っていた高校倫理の教科書を取り出して学び直しを始めました。</p>
</div>
<div class="section" id="section-7">
<h3>先生のお人形 / 藤のよう</h3>
<a class="reference external image-reference" href="https://www.amazon.co.jp/dp/4046041129/"><img alt="「せんせいのお人形」" src="https://cover.openbd.jp/9784046041128.jpg" style="width: 30%;" /></a>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">読んでよかったコミック of the Year 2020 に藤のようさんの「せんせいのお人形」がノミネートされました</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1251781346046783488?ref_src=twsrc%5Etfw">April 19, 2020</a></blockquote><p>ネグレクトを受け親戚中をたらい回しにされていた少女・スミカが、その状況やスミカの有り様を見かねた親類で高校教員の昭明に引き取られ、昭明のもとで教育を受け、通い始めた学校での友達との出会いもあり、世界への希望や好奇心を取り戻していく物語です。</p>
<p>前述の「ここは今から倫理です。」と共に、なぜ学ぶか、いかに生きるかという共通するテーマを感じられます。</p>
</div>
<div class="section" id="section-8">
<h3>娘の友達 / 荻原あさ美</h3>
<a class="reference external image-reference" href="https://www.amazon.co.jp/dp/4065166004/"><img alt="「娘の友達」" src="https://cover.openbd.jp/9784065166000.jpg" style="width: 30%;" /></a>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">萩原あさ美「娘の友達」 6 巻、発売当日に読み始めたのにどんどん怖くなってきて中盤でページをめくる手が止まり、未だに読み終わっていない</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1332710533854756864?ref_src=twsrc%5Etfw">November 28, 2020</a></blockquote></div>
</div>
<div class="section" id="section-9">
<h2>観たアニメ</h2>
<p>すべての履修履歴は <a class="reference external" href="http://animetick.net/users/yosida95">Animetick</a> で公開しています。</p>
<div class="section" id="section-10">
<h3>うさぎドロップ</h3>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">観てよかったアニメ of the Year 2020 に「うさぎドロップ」がノミネートされました</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1214914612220416000?ref_src=twsrc%5Etfw">January 8, 2020</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">コミックも読んでみようかと Wikipedia であらすじを読んでみたけれど、アニメ化されていない第 2 部はわたしの好みとは違いそうだった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1214919172565520384?ref_src=twsrc%5Etfw">January 8, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2011 年にアニメ化されていたみたいですね。りんが小学生になる(原作 4 巻まで)を、原作は未読なので忠実かどうかは分かりませんが、丁寧に描いている印象でした。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1215138364120154112?ref_src=twsrc%5Etfw">January 9, 2020</a></blockquote></div>
<div class="section" id="section-11">
<h3>甘々と稲妻</h3>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">観てよかったアニメ of the Year 2020 、「甘々と稲妻」もよかったけれど、いまのわたしには「うさぎドロップ」ほどは響かなかった。ただ、原作への興味はこちらの方が惹かれた。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1218493593771360256?ref_src=twsrc%5Etfw">January 18, 2020</a></blockquote></div>
</div>
<div class="section" id="section-12">
<h2>買ってよかったもの</h2>
<div class="section" id="iphone-se-2nd-gen">
<h3>iPhone SE (2nd Gen.)</h3>
<p>長年 iPhone SE 初代を使ってきましたが、いよいよバッテリーの劣化が実用上問題になってきたので買い換えることにしました。</p>
<p>わたしが買い替えを行った時点では iPhone 12 mini は未発売だったため、画面サイズから iPhone SE 2nd Gen. しか候補がありませんでした。
購入直後に iPhone 12 mini が発売されたことから再度の買い替えも検討しましたが、 iPhone 12 mini には Touch ID が搭載されなかったことから、引き続き iPhone SE 2nd Gen. を使い続けています。</p>
<p>メモリが足らないような挙動が少し気になるものの、概ね満足しています。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">家から一歩も出ていないのに iPhone SE (初代) のバッテリーは 1 日持たなかったし、そろそろ買い換えるなりした方がよいんだろうな。もう少しわたしの手が大きければ躊躇なく買い換えるんだがな……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1293885191178473472?ref_src=twsrc%5Etfw">August 13, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わたしは Touch ID が乗り換えない理由になる程度には便利に使っていて、こうした生体認証は外出時に役立ちますが(衆人環視でパスコードを打たなくてよい)、ニューノーマルではユニバーサルマスクが求められるので Face ID は厳しいんですよね。 iPhone 12 mini 羨ましいですが……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1329026088413007872?ref_src=twsrc%5Etfw">November 18, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">iPhone SE2 が通知の度にバイブレーションで移動して目を離すとすぐに高いところから落ちようとする。君は乳幼児かな?</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1319525288057864192?ref_src=twsrc%5Etfw">October 23, 2020</a></blockquote></div>
<div class="section" id="section-13">
<h3>グラファイトヒーター</h3>
<p>冬になる度に暖のとり方に頭を悩ませており、これまでホットカーペットやパネルヒーター、オイルヒーターなどを試してきました。
しかし、これまでの経験からほんのり暖める系の暖房はわたしには力不足だということがわかってきたので、今冬はより直接的に暖めてくれるグラファイトヒーターを導入したところ、大成功を収めました。</p>
<p>購入したのは Aladdin の最大 1000W 出力できるものですが、現在のところ最小出力の 250W でポカポカと快適に暮らせています。</p>
<p><a class="reference external" href="https://aladdin-aic.com/wp-download/c/pdf/2019.pdf">Aladdin AEH-G100A</a></p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">この冬の足元の冷えはホットカーペットで乗り超えるか、それともファンヒーター + ラグマットで乗り超えるかを悩んでいます</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1321031382907285504?ref_src=twsrc%5Etfw">October 27, 2020</a></blockquote></div>
</div>
<div class="section" id="section-14">
<h2>ことし寄付した先</h2>
<p>ことし寄付した先は以下の 2 団体でした。</p>
<div class="section" id="mozilla-foundation">
<h3>Mozilla Foundation</h3>
<p>ことしの夏頃に Mozilla Foundation の経営危機が報じられ、普段から MDN Web Docs のお世話になっている身として少しでも貢献できればと思い寄付しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MDN Web Docs には足を向けて寝られないので Mozilla Foundation に寄付してきた / I donated to <a href="https://twitter.com/mozilla?ref_src=twsrc%5Etfw">@mozilla</a> today because I <a href="https://twitter.com/hashtag/lovetheweb?src=hash&ref_src=twsrc%5Etfw">#lovetheweb</a>. Join me and help fight for a better and healthier internet, for all. <a href="https://t.co/fLQxGYCD9z">https://t.co/fLQxGYCD9z</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1293755017283821568?ref_src=twsrc%5Etfw">August 13, 2020</a></blockquote></div>
<div class="section" id="wikimedia-foundation">
<h3>Wikimedia Foundation</h3>
<p>Wikimedia Foundation への寄付は 2014 年から始め、 2018 年 7 月からは毎月の定額寄付を行っており、ことしもこれを継続しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wikipedia (Wikimedia) さま、 2014 年から継続して寄付をし続けているわたしにも寄付のお願いを表示して閲覧を邪魔してくるので体験が悪い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1301408825648377856?ref_src=twsrc%5Etfw">September 3, 2020</a></blockquote></div>
</div>
<div class="section" id="section-15">
<h2>おわりに</h2>
<p>これはいまさらわたしが語るまでもなく多くの場所で語られていることですが、 2020 年はこれまでの年とは大きく異なる年となりました。</p>
<p>幸いわたしの日常が大きく変わることはなく、収入も安定しており、リモートワークも従来の週 4 日程度から週 5 日になったという軽度な変化でした。</p>
<p>購買行動も従来からずっと通販が大半を占めており、食材もネットスーパーを利用してきたので、 2020 年以前から Stay Home に対する準備が十分に整っていたと言えるかもしれません。</p>
<p>趣味も楽器演奏や読書、筋トレなど、 1 人で自分の内側に向きあうものが多かったため、むしろ Stay Home を意識することで趣味が充実した面もあります。</p>
<p>しかし、それでも相手がある習い事がオンラインレッスンに切り替わったり、個人では揃えられない道具が目当てのジムは閉鎖されたりなどの影響があり、そのせいで体験の質が低下したという実感があります。</p>
<p>また、外出の頻度も 2 週間に 1 、 2 度程度まで低下しており、人との出会いも大きく減ってしまいました。</p>
<p>日々報道される感染症の状況は悪化の一途をたどっており大きな不安を感じますが、一刻も早い沈静化と QoL の向上を願ってやみません。</p>
<p>ことしも 1 年おつかれ様でした。</p>
</div>
<div class="section" id="section-16">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2018/12/31/year-in-review.html">yosida95 の 2018 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/12/31/year-in-review.html">yosida95 の 2019 年まとめ</a></li>
</ul>
</div>
yosida95 の 2019 年まとめ2019-12-31T00:00:00+09:002019-12-31T00:00:00+09:00yosida95tag:yosida95.com,2019-12-31:/2019/12/31/year-in-review.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。</p>
<p>2010 年から毎年続けてきた 1 年のまとめ記事もこれで 10 本目です。
2019 年は数え年で 25 にあたる本厄の 1 年間でしたが、平穏無事に乗り切ることができたようです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ことしは厄年(数え年で25歳)らしい。信心深くないわたしは何かが起こるとは思っていないんだけれど、もし何かにしくじったときは「厄年だから仕方ないね」と自分を甘やかしていこうと思っています。みなさんもそのつもりでわたしを甘やかしてくださるようお願いします。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1082209070507933696?ref_src=twsrc%5Etfw">January 7, 2019</a></blockquote><p>それでは、ことしもまとめてゆきます。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-1" id="toc-entry-1">はじめに</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-2">ボイストレーニング</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-3">筋力トレーニング</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-4">旅行</a><ul>
<li><a class="reference internal" href="#section-5" id="toc-entry-5">北海道</a></li>
<li><a class="reference internal" href="#section-6" id="toc-entry-6">静岡県</a></li>
<li><a class="reference internal" href="#section-7" id="toc-entry-7">駅メモ</a><ul>
<li><a class="reference internal" href="#section-8" id="toc-entry-8">山万ユーカリが丘線</a></li>
<li><a class="reference internal" href="#section-9" id="toc-entry-9">東急全線乗りつぶし</a></li>
<li><a class="reference internal" href="#section-10" id="toc-entry-10">伊豆急行線乗りつぶし</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#section-11" id="toc-entry-11">読んだコミック</a></li>
<li><a class="reference internal" href="#section-12" id="toc-entry-12">観たアニメ</a></li>
<li><a class="reference internal" href="#section-13" id="toc-entry-13">観た映画</a></li>
<li><a class="reference internal" href="#section-14" id="toc-entry-14">買ったもの</a></li>
<li><a class="reference internal" href="#section-15" id="toc-entry-15">取得した資格</a><ul>
<li><a class="reference internal" href="#section-16" id="toc-entry-16">ファイナンシャル・プランニング技能士</a></li>
<li><a class="reference internal" href="#section-17" id="toc-entry-17">知的財産管理技能士</a></li>
<li><a class="reference internal" href="#section-18" id="toc-entry-18">宅地建物取引士資格試験</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-19" id="toc-entry-19">寄付した先</a><ul>
<li><a class="reference internal" href="#wikipedia-wikimedia-foundation" id="toc-entry-20">Wikipedia (Wikimedia Foundation)</a></li>
<li><a class="reference internal" href="#section-20" id="toc-entry-21">アラートループ事件</a></li>
<li><a class="reference internal" href="#coinhive" id="toc-entry-22">Coinhive 事件</a></li>
<li><a class="reference internal" href="#sequel-pro" id="toc-entry-23">Sequel Pro 開発支援</a></li>
<li><a class="reference internal" href="#section-21" id="toc-entry-24">京都アニメーション事件</a></li>
<li><a class="reference internal" href="#gnome" id="toc-entry-25">GNOME 特許ゴロ事件</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-22" id="toc-entry-26">おわりに</a></li>
<li><a class="reference internal" href="#section-23" id="toc-entry-27">これまでのまとめ</a></li>
</ul>
</div>
</div>
<div class="section" id="section-2">
<h2>ボイストレーニング</h2>
<p>昨年はじめたボイストレーニングはことしも継続して取り組みました。
ただし、日常のルーティンが増え忙しくなってしまったため頻度を下げ、プロの声優さんによる指導は月に 3 時間だったものを 2 時間にしました。</p>
<p>ところで、ボイストレーニングを進める中で時折アクセントを指摘されることがあり、アクセントは東京で生まれ育ったために油断していたため、正しいアクセントを調べるためにアクセント辞典が必要になりました。</p>
<p>アクセント辞典としては NHK 放送文化研究所が 2016 年に刊行した「 <a class="reference external" href="https://www.nhk-book.co.jp/detail/000000113452016.html">日本語発音アクセント新辞典</a> 」が業界では広く使われています。
この辞典は 1998 年に刊行された「 <a class="reference external" href="https://www.nhk-book.co.jp/detail/000000111121998.html">日本語発音アクセント辞典</a> 」の改訂版ですが、改訂前には提供されていたスマートフォンアプリが新辞典では 3 年以上に渡り提供されていませんでした。</p>
<p>このスマートフォンアプリの提供を待ち望んでいる旨のツイートをしたところ、その 6 日後の今月 12 月 24 日にスマートフォンアプリが発売されるという最高の体験がありました。</p>
<p>このスマートフォンアプリではアクセント記号の他に、すべての見出し語の 10 万を超えるアクセントについて NHK アナウンサーによる読み上げ音声が収録されており、さらにアクセントの規則などについて解説された付録も収録されている最高の仕上がりとなっています。</p>
<p>みなさんにも大変おすすめです。</p>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">NHK 出版さまには後生だから「日本語発音アクセント新辞典」の iOS アプリを出してほしい。欲を言うなら音声が収録されていると最高。<a href="https://t.co/pS8QgOdOlV">https://t.co/pS8QgOdOlV</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1207214606994698240?ref_src=twsrc%5Etfw">December 18, 2019</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">NHK 出版さま、本当にありがとうございます。めちゃくちゃタイミングがよくて驚いてしまった。 <a href="https://t.co/LHja93kHvc">https://t.co/LHja93kHvc</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1209269073982312448?ref_src=twsrc%5Etfw">December 24, 2019</a></blockquote></div>
<div class="section" id="section-3">
<h2>筋力トレーニング</h2>
<p>筋力トレーニングにも引き続き取り組みました。
こちらはボイストレーニングとは対照的に、ジムの契約を利用可能時間に制限がないプランにアップグレードし、 2 日に 1 度程度の頻度で通いました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">大きい筋肉を中心に、<br>- ベンチプレス<br>- チェストプレス<br>- チンニング<br>- ラットプルダウン<br>- トランクカール<br>- ニーレイズ<br>- バーベルスクワット<br>- レッグプレス<br>を 10 回 3-5 セットくらいで、あとは気が向けばショルダープレスとかレッグカールとかツイストシットアップとかを同じ回数かな</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1178606370695761921?ref_src=twsrc%5Etfw">September 30, 2019</a></blockquote><p>しかし、 10 月に膝をケガをしてしまい脚のトレーニングをまともにできなくなってしまいました。
それ以来現在でもなお、治療のため定期的に膝関節に神経ブロック注射を打ちつつ、痛みの具合をみて段階的にトレーニングを再開するリハビリを進めています。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「筋肉は裏切らないが関節は裏切る」を体現してしまい、膝の捻挫により痛み止めの内服薬と湿布とサポーターが処方されし、サポーターで蒸れて膝の裏がかぶれた……。しかもトレーニング中ではなく日常生活で椅子から立ち上がるときに捻った……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1179403713905070084?ref_src=twsrc%5Etfw">October 2, 2019</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">両膝に注射を受けてしまってな…… ( 2 週間ぶり 6 度目)</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1203944717412519936?ref_src=twsrc%5Etfw">December 9, 2019</a></blockquote><p>12 月 26 日に測定した体組成では、体重が 63.5 kg 、筋肉量が 31.8 kg で体脂肪率が 11.2% と、トレーニングを開始する直前の 2018 年 7 月と比べて体重を 7.5 kg 、筋肉量を 4.0 kg それぞれ増やすことができ、順調にトレーニングの成果がでています。</p>
<p>ケガにより心配された脚の筋肉量ダウンは見られなかったことが不幸中の幸いでした。</p>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">進捗です。 3 ヶ月で体重 +0.7kg 、筋肉量 +1.0kg 、体脂肪量 -0.9kg ( -1.5 ポイント)でした。怪我してトレーニングできなかった脚も衰えなくてよかった。トレーニング開始直前の 2018 年 7 月と比較すると、体重 +7.5kg 、筋肉量 +4.0kg 、体脂肪量 +1.1 kg ( +0.5 ポイント)です。 <a href="https://t.co/0MNfJrkZqL">pic.twitter.com/0MNfJrkZqL</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1210127930275160065?ref_src=twsrc%5Etfw">December 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div class="section" id="section-4">
<h2>旅行</h2>
<p>ことしは 1 月に北海道、 6 月に静岡県を旅行しました。</p>
<p>詳細はそれぞれ次の記事にまとめてあります。</p>
<div class="section" id="section-5">
<h3>北海道</h3>
<blockquote>
<a class="reference external image-reference" href="https://yosida95.com/2019/01/31/hokkaido-trip.html"><img alt="ひがし北海道フリーパスで4泊5日冬の北海道縦断旅行をした" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/polar-bear.jpg" style="width: 80%;" /></a>
<p class="attribution">—<a class="reference external" href="https://yosida95.com/2019/01/31/hokkaido-trip.html">ひがし北海道フリーパスで4泊5日冬の北海道縦断旅行をした</a></p>
</blockquote>
</div>
<div class="section" id="section-6">
<h3>静岡県</h3>
<blockquote>
<a class="reference external image-reference" href="https://yosida95.com/2019/06/25/shizuoka-trip.html"><img alt="静岡県ひとり旅" src="https://blogmedia.yosida95.com/2019/06/25/shizuoka-trip/tumbnail.jpg" style="width: 80%;" /></a>
<p class="attribution">—<a class="reference external" href="https://yosida95.com/2019/06/25/shizuoka-trip.html">静岡県ひとり旅</a></p>
</blockquote>
</div>
<div class="section" id="section-7">
<h3>駅メモ</h3>
<p>また、現実の鉄道駅を利用した位置情報ゲームの <a class="reference external" href="https://ekimemo.com/">駅メモ</a> で年間を通じて遊んでいました。</p>
<p>ブログでは房総半島を一周した「 <a class="reference external" href="https://yosida95.com/2019/06/09/trip-around-boso-peninsula.html">亀戸駅・錦糸町駅間(徒歩 10 分)を 99 駅・ 8 時間 24 分かけて移動した話</a> 」を書いていますが、他にも東急前線乗りつぶしや静岡県伊豆の伊豆急行線乗りつぶしなどをしました。</p>
<p>なお、 1 年間のゲーム内通貨メロンの購入総額は 41,560 円でした。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/12/31/year-in-review/ekimemo.png"><img alt="駅メモ" src="https://blogmedia.yosida95.com/2019/12/31/year-in-review/ekimemo.png" style="width: 20%;" /></a>
<div class="section" id="section-8">
<h4>山万ユーカリが丘線</h4>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BzQovvrBezP/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BzQovvrBezP/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BzQovvrBezP/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-06-28T16:21:14+00:00">Jun 28, 2019 at 9:21am PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-9">
<h4>東急全線乗りつぶし</h4>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/B4cZtOyB1Rc/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/B4cZtOyB1Rc/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/B4cZtOyB1Rc/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-11-04T12:37:41+00:00">Nov 4, 2019 at 4:37am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/B4cadXBBltv/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/B4cadXBBltv/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/B4cadXBBltv/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-11-04T12:44:15+00:00">Nov 4, 2019 at 4:44am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-10">
<h4>伊豆急行線乗りつぶし</h4>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/B5P7IBtFX9k/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/B5P7IBtFX9k/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/B5P7IBtFX9k/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-11-24T12:50:58+00:00">Nov 24, 2019 at 4:50am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
</div>
</div>
<div class="section" id="section-11">
<h2>読んだコミック</h2>
<p>ことしは記録がある限り 261 冊( Kindle で購入したもののみ)のコミックを新たに購入して読んだようです。</p>
<p>この中でも、ことしよりも前に読みはじめたシリーズを除いた、ことし読みはじめたシリーズで特に印象に残った 3 作品は次の通りです。</p>
<blockquote>
<a class="reference external image-reference" href="https://bookmeter.com/books/13265713"><img alt="「できそこないの姫君たち」" src="https://m.media-amazon.com/images/I/51vVofMGz3L._SL500_.jpg" style="width: 20%;" /></a>
<p class="attribution">—<a class="reference external" href="https://bookmeter.com/books/13265713">「できそこないの姫君たち」</a></p>
</blockquote>
<blockquote>
<a class="reference external image-reference" href="https://bookmeter.com/books/13409584"><img alt="「付き合ってあげてもいいかな」" src="https://m.media-amazon.com/images/I/51fPfnjIj4L._SL500_.jpg" style="width: 20%;" /></a>
<p class="attribution">—<a class="reference external" href="https://bookmeter.com/books/13409584">「付き合ってあげてもいいかな」</a></p>
</blockquote>
<blockquote>
<a class="reference external image-reference" href="https://bookmeter.com/books/8058290"><img alt="「働かないふたり」" src="https://m.media-amazon.com/images/I/612RDYpLDdL._SL500_.jpg" style="width: 20%;" /></a>
<p class="attribution">—<a class="reference external" href="https://bookmeter.com/books/8058290">「働かないふたり」</a></p>
</blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">先月と今月 (so far) は平均の月よりも 5 万円以上ずつお金を使っていて、なんでだろうと調べたら先月は Kindle コミックを 48 冊買っているし、今月も 41 冊買ったほか向こう 10 年で 1 度しか使わないのではという工具セットを 3 万円で購入している……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1198182990662094848?ref_src=twsrc%5Etfw">November 23, 2019</a></blockquote><p>すべての履修履歴は <a class="reference external" href="https://bookmeter.com/users/662877/books/read">yosida95さんの読んだ本 - 読書メーター</a> で公開しています。</p>
</div>
<div class="section" id="section-12">
<h2>観たアニメ</h2>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">観てよかったアニメ of the Year 、「狼と香辛料」シリーズということで落ち着きそう</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1210552566016118784?ref_src=twsrc%5Etfw">December 27, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「キノの旅」のアニメの 2003 年版と 2017 年版を交互に観ていたんですが、現代の声優さんの達者さと録音技術の凄さがとてもよく分かった。脚本も 2003 年版に比べて寓話的要素が薄まったきらいはあるものの、 2017 年版はテンポがよく、セリフ順や言い回しの変更などにより理解しやすくなっている。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1158371372139106306?ref_src=twsrc%5Etfw">August 5, 2019</a></blockquote></div>
<div class="section" id="section-13">
<h2>観た映画</h2>
<p>7 本観た昨年に対して、ことしは新海誠監督の「 <a class="reference external" href="https://tenkinoko.com/">天気の子</a> 」しか観ませんでした。</p>
<p>「天気の子」は正直「まぁこんなものかな」という感想で、特別引っかかったり響いたりすることはありませんでした。</p>
<p>しかし、その考察記事である「 <a class="reference external" href="https://nazology.net/archives/46406">【考察】『天気の子』の「違和感」の正体は結局何だったのか? 心理学から解説してみる(ネタバレ有り)</a> 」はとても興味深く読め、腑に落ちる点も多く、素晴らしいものでした。
「天気の子」を視聴した方で本記事をまだ読んでいない方はぜひ読んでみてください。</p>
<blockquote>
<a class="reference external image-reference" href="https://nazology.net/archives/46406"><img alt="【考察】『天気の子』の「違和感」の正体は結局何だったのか? 心理学から解説してみる(ネタバレ有り)" src="https://i1.wp.com/nazology.net/wp-content/uploads/2437bd78c3f0bdc4bca929a6f498b9f2.jpg?fit=1588%2C806&#038;ssl=1" style="width: 40%;" /></a>
<p class="attribution">—<a class="reference external" href="https://nazology.net/archives/46406">【考察】『天気の子』の「違和感」の正体は結局何だったのか? 心理学から解説してみる(ネタバレ有り)</a></p>
</blockquote>
</div>
<div class="section" id="section-14">
<h2>買ったもの</h2>
<p>ことしの買い物らしい買い物といえば、 iPad mini 3 から買い替えた iPad mini 5 と、ダイソンのハンディ掃除機から買い替えた Panasonic のワイアードキャニスター掃除機くらいでした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わたしの新しい iPad mini 5 の動作が軽快で本当に驚いている。これまで iPad mini 3 を長年だましだまし使ってきたけれど違いが歴然で、久しぶりによい買い物をした。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1112962072499777537?ref_src=twsrc%5Etfw">April 2, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">国内メーカー産の掃除機には、身長 176cm と日本の成人男性としては決して高くないわたしでも、腰を屈めないと使えないという大きな問題がある……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1209003515030278144?ref_src=twsrc%5Etfw">December 23, 2019</a></blockquote></div>
<div class="section" id="section-15">
<h2>取得した資格</h2>
<p>ことしは、わたしが高校 2 年生だった 2012 年に基本情報技術者を取得して以来、 5 年ぶりに国家資格の取得に取り組みました。</p>
<p>動機としては、かねてから思っていた、記憶力や思考力がピークのうちにコレクターとして国家資格をコレクションしようという遊び本意のものです。
そのタイミングとして「令和初の合格者」を自称できることしの 5 月以降が都合よかったのです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">記憶力や思考力が衰える前に日常生活はおろかソフトウェアエンジニア職でも役に立たないんだけれどその筋の業界では重宝される資格みたいなのを集めて遊びたいな</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1007619068348600320?ref_src=twsrc%5Etfw">June 15, 2018</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">持っていても仕事はおろか趣味でも役に立たないがしかし欲しい免許や資格(合格率や必要資金的にそこそこ難関)がいくつかあり、人生は短いから取ってしまおうという気持ちと人生は短いからもっと有効に使おうという気持ちがせめぎ合っている</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1091365080279613441?ref_src=twsrc%5Etfw">February 1, 2019</a></blockquote><div class="section" id="section-16">
<h3>ファイナンシャル・プランニング技能士</h3>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">3 級ファイナンシャル・プランニング技能士になりました</a></li>
<li><a class="reference external" href="https://yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html">2 級ファイナンシャル・プランニング技能士になりました</a></li>
</ul>
</div>
<div class="section" id="section-17">
<h3>知的財産管理技能士</h3>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html">2 級知的財産管理技能士になりました</a></li>
</ul>
</div>
<div class="section" id="section-18">
<h3>宅地建物取引士資格試験</h3>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2019/12/04/real-estate-transaction-agent.html">宅地建物取引士資格試験に合格しました</a></li>
</ul>
</div>
</div>
<div class="section" id="section-19">
<h2>寄付した先</h2>
<p>ことしは記録のある限り 6 案件に合計で 41,000 円と $ 100.00 USD を寄付しました。</p>
<div class="section" id="wikipedia-wikimedia-foundation">
<h3>Wikipedia (Wikimedia Foundation)</h3>
<p>Wikimedia 財団には定期自動寄付で 2018 年 7 月から毎月 500 円ずつ寄付していて、 2019 年も 12 ヶ月間きっちり継続しました。</p>
</div>
<div class="section" id="section-20">
<h3>アラートループ事件</h3>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">アラートループ家宅捜索(いわゆる「兵庫県警ブラクラ摘発」)事件に関する寄付の呼びかけに賛同し寄付しました<a href="https://t.co/Qg9OMoTJw5">https://t.co/Qg9OMoTJw5</a> <a href="https://t.co/phK8BYYN8b">pic.twitter.com/phK8BYYN8b</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1110153149455597568?ref_src=twsrc%5Etfw">March 25, 2019</a></blockquote></div>
<div class="section" id="coinhive">
<h3>Coinhive 事件</h3>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わたしも寄付しました / Coinhive事件裁判費用の寄付のお願い - 一般社団法人日本ハッカー協会 <a href="https://t.co/ViwSr232QI">https://t.co/ViwSr232QI</a> <a href="https://t.co/a8LTWtTZn3">pic.twitter.com/a8LTWtTZn3</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1118756036062527488?ref_src=twsrc%5Etfw">April 18, 2019</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ところで note はアカウントがないと投げ銭できないっぽくて厳しい。 note を利用したいわけではなく note を選んだ投稿者のほうを支援したいわけで、アカウント登録が不要な方が投稿者に集まる金額も大きくなるのではないかな。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1113750870506663939?ref_src=twsrc%5Etfw">April 4, 2019</a></blockquote></div>
<div class="section" id="sequel-pro">
<h3>Sequel Pro 開発支援</h3>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Sequel Pro に寄付したことがあるつもりでいたけれど Cyberduck と混同していたので改めて寄付しました <a href="https://t.co/WEB95LtdUp">pic.twitter.com/WEB95LtdUp</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1126779677157146625?ref_src=twsrc%5Etfw">May 10, 2019</a></blockquote></div>
<div class="section" id="section-21">
<h3>京都アニメーション事件</h3>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ほんの心ばかりですが京都アニメーションの公式口座に支援金を振り込みました <a href="https://t.co/aLLRtQz4Fg">https://t.co/aLLRtQz4Fg</a> <a href="https://twitter.com/hashtag/PrayForKyoani?src=hash&ref_src=twsrc%5Etfw">#PrayForKyoani</a> <a href="https://twitter.com/hashtag/PrayForKyotoAnimation?src=hash&ref_src=twsrc%5Etfw">#PrayForKyotoAnimation</a> <a href="https://t.co/QdRDHA4KYH">pic.twitter.com/QdRDHA4KYH</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1153968408716701696?ref_src=twsrc%5Etfw">July 24, 2019</a></blockquote></div>
<div class="section" id="gnome">
<h3>GNOME 特許ゴロ事件</h3>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GNOME が patent troll と戦えるように 50 USD を寄付しました / Join me: I'm raising funds to help GNOME Patent Troll Defense Fund <a href="https://t.co/qnQxIXXok8">https://t.co/qnQxIXXok8</a> <a href="https://t.co/IWRrGZSQuH">pic.twitter.com/IWRrGZSQuH</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1186903713794772992?ref_src=twsrc%5Etfw">October 23, 2019</a></blockquote></div>
</div>
<div class="section" id="section-22">
<h2>おわりに</h2>
<p>ことしは大きな波もなく安定した 1 年を過ごすことができました。</p>
<p>ピアノ演奏や筋力トレーニング、ボイストレーニング、旅行といったかねてからの趣味を継続して楽しめた他、新しい趣味として(国家)資格取得を始め、そちらでも成果を出せた 1 年でした。</p>
<p>先日あった友人に「仕事の後や合間にジムに通い、料理はほとんど自炊し、休日はピアノを弾いてすごしている」という話をしたところ、「あまりに所帯じみている」と言われてしまったので、来る年ではもう少し冒険をした方がよいのかと考えているところです。</p>
<p>ことしお世話になった皆様にお礼を申し上げます。
2020 年も引き続きよろしくお願いいたします。</p>
<p>よいお年をお迎えください。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/B6nfYIXBrUp/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/B6nfYIXBrUp/?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/B6nfYIXBrUp/?utm_source=ig_embed&utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-12-28T13:01:40+00:00">Dec 28, 2019 at 5:01am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>こちらは前述の友人と食べた中華料理です。</p>
</div>
<div class="section" id="section-23">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2018/12/31/year-in-review.html">yosida95 の 2018 年まとめ</a></li>
</ul>
</div>
宅地建物取引士資格試験に合格しました2019-12-04T00:00:00+09:002019-12-04T00:00:00+09:00yosida95tag:yosida95.com,2019-12-04:/2019/12/04/real-estate-transaction-agent.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>去る 10 月 20 日に実施された令和元年度宅地建物取引士資格試験の合格発表が本日あり、無事に合格していたのでご報告します。</p>
</div>
<div class="section" id="section-3">
<h2>宅地建物取引士とは</h2>
<p>宅地建物取引士とは宅地建物取引業者(不動産会社)における必置資格であり、重要事項説明書( 35 条書面)の交付と口頭説明ならびに契約書( 37 条書面)の記名・押印を独占業務とする国家資格です。</p>
<p>住宅を購入したり賃貸マンションを契約したりする際に営業の人とは別に、こちらの理解度を確認しながら重要事項を説明してくれる人が現れたという経験があるかもしれませんが、あれが宅地建物取引士であり宅地建物取引士にしかできない業務です。</p>
<p>この宅地建物取引士となるために今回の宅地建物取引士資格試験に合格する必要があります。</p>
<p>なお、宅地建物取引士となるためには資格試験合格のほかに宅地建物取引業の実務経験またはそれに代わる講習の受講歴が必要ですが、わたしにはそのいずれもないため、現時点でわたしは資格試験合格者ではあるものの宅地建物取引士ではありません。</p>
</div>
<div class="section" id="section-4">
<h2>受験のきっかけ</h2>
<p>もともと親類に複数の宅地建物取引士(当時は宅地建物取引主任者)が居て、わたしが小学生の頃はその試験が如何に難しいかという話を聞かされて育ってきました。</p>
<p>そんな折 <a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">3 級フィナンシャル・プランニング技能士を受検した</a> 後にふらっと立ち寄った八重洲ブックセンターに宅地建物取引士資格試験の参考書が並んだ一角を見つけ、何気なしに立ち読みをしたところ聞かされていたほど困難な試験には思えなかったので興味を惹かれ、その場で参考書を購入しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブックセンターに初めて来たけれどここすごくて、無限に時間が溶けてゆく</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1132536760569880576?ref_src=twsrc%5Etfw">May 26, 2019</a></blockquote><p>それからしばらくは参考書を本棚に差したままにしていましたが、受験申請の最終日に再び参考書を開いたらやはり合格できそうな気がしたので受験を決め、近所の書店で受験申請書をもらったあと郵便局で受験料の納付と受験申請書の記入を行い、そのまま簡易書留で発送しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">きょうが期限の国の手続きなのに、 15 時を過ぎてから用紙を受け取って記入して手数料を払い込んで郵便窓口で発送するというめちゃくちゃ危険なことをやってしまった。しかも同じことをひと月前にやって、しかも失敗しているから進歩がない……。 <a href="https://t.co/sOLQolbC4B">https://t.co/sOLQolbC4B</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1156456959781900288?ref_src=twsrc%5Etfw">July 31, 2019</a></blockquote></div>
<div class="section" id="section-5">
<h2>受験まで</h2>
<p>宅地建物取引士資格試験は試験範囲が広く、不動産に関連するものでは宅地建物取引業法を始め、建築基準法、国土利用計画法、都市計画法、農地法、土地区画整理法、宅地造成等規制法、不動産登記法、区分所有法、借地借家法などが含まれます。
また、契約行為や賃貸借、権利関連の基礎として民法が、不動産取得税や固定資産税、相続税などで税法が関連してきます。
これらに加え、実際の係争において法律の解釈を示した裁判所の判例知識も問われます。</p>
<p>しかし、最終日の受験申請に成功した事に満足してしまいそのまま 1 ヶ月間手を付けず、 9 月に入ってからは <a class="reference external" href="https://yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html">2 級フィナンシャル・プランニング技能士</a> の準備や <a class="reference external" href="https://ekimemo.com/">駅メモ</a> の遠征などで時間が過ぎ去り、受験準備を開始したのは試験日のちょうど 4 週間前でした。
また 9 月中には別の試験も受験したためこの準備に 1 週間を要しました。</p>
<p>このため、巷では仕事をしながら宅地建物取引士資格試験に合格するためには 4 ヶ月から6 ヶ月程度の準備期間が必要と言われていますが、わたしは 3 週間で合格を目指すことになりました。</p>
<p>わたしが購入した参考書は合計 700 ページほどの分量があり、ちょうど分野ごとに 3 分冊になっていたので、 1 週間で 200 ページちょっとの分冊を 1 冊ずつ片付けていきながら関連分野の過去問を解くスケジュールとなりました。
過去問を時間を測って最初から最後まで解いたのは試験前日と当日の朝の 2 回のみでした。</p>
</div>
<div class="section" id="section-6">
<h2>受験当日</h2>
<p>受験当日は過去問を解くため、また 13 時から始まる試験までに会場に到着するために、普段より数時間も早く目を覚ます必要があり、起床直後に数年ぶりにモンスターエナジーを摂取しました。
その結果、事前にトイレを済ませていたにも関わらず、試験開始直後に尿意を催して尿意と戦いながら 2 時間の試験を乗り越えるというハチャメチャな展開となってしまいました。</p>
<p>流石に 2 時間を耐えきることはできず試験監督に申し出て、不正防止のために試験監督に付き添われながらトイレを済ませるという人生で初めての体験をしました。</p>
<p>試験終了後は資格予備校が提供してくれた解答速報により例年の合格ラインを超えていることを確認し、マークミスがないことを祈りつつ本日の合格発表を待っていました。</p>
</div>
<div class="section" id="section-7">
<h2>今後</h2>
<p>無事に資格試験に合格することができましたが、この先自身が不動産契約をする際に不動産会社に示して重要顧客として扱ってもらう程度にしか使いみちがないであろう宅地建物取引士証のために、必要講習やその後の資格登録申請料として 4 万円以上の費用を負担して資格登録するかどうかは検討中です。</p>
<p>これからは <a class="reference external" href="https://yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html">知的財産の管理と活用ができて</a> 、 <a class="reference external" href="https://yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html">資産設計業務ができて</a> 、不動産取引や国土利用などにも詳しい、ソフトウェアエンジニアとして活動していきます。</p>
</div>
2 級ファイナンシャル・プランニング技能士になりました2019-10-21T00:00:00+09:002019-10-21T00:00:00+09:00yosida95tag:yosida95.com,2019-10-21:/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>先月 9 月 8 日に実施された検定の合格発表があり、無事に合格していました。
これによりわたしは国家試験に合格した 2 級ファイナンシャル・プランニング技能士になりました。</p>
<p>5 月 26 日に行われた <a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">前回検定で 3 級に合格</a> していましたので、今回で級を上げた形になります。</p>
<p>なお、ファイナンシャル・プランニング技能士は名称独占資格であるため、わたしがこの合格によりできることは引き続きこの技能士名を名乗ることのみです。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<p>前回の 3 級受検とほぼ同様です。
今回も特定非営利活動法人日本ファイナンシャル・プランナーズ協会(日本 FP 協会)が実施する検定を受検したので、実技科目は資産設計業務です。</p>
<p>また、検定日直前になって勉強を始めたところまで前回と同様です。
今回は本当に時間的な余裕がなかったので、過去問を解くことすらできませんでした。</p>
<p>ただ、 3 級と同様の範囲をより詳細に問われる内容の検定だったと思うので、 3 級で学習した内容をベースに参考書を一通り読んで理解を深めることで合格することができました。</p>
</div>
<div class="section" id="section-4">
<h2>おわりに</h2>
<p>ひとまず 2 級まで合格することができたので、 1 級については今後気が向いた時に検討する感じでもよいかなと思っています。</p>
<p>これからはソフトウェアの設計と実装ができて <a class="reference external" href="https://yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html">知的財産の管理と活用もできる</a> 、 2 級ファイナンシャル・プランニング技能士として活動していきます。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning/result.png"><img alt="完全合格" src="https://blogmedia.yosida95.com/2019/10/21/2nd-grade-certified-skilled-professional-of-financial-planning/result.png" /></a>
</div>
2 級知的財産管理技能士になりました2019-09-02T00:00:00+09:002019-09-02T00:00:00+09:00yosida95tag:yosida95.com,2019-09-02:/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosia95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosia95 です。</p>
<p>去る 7 月 21 日に実施された国家試験に合格し 2 級知的財産管理技能士になりましたのでご報告します。</p>
<p>知的財産管理技能士とは、特許・実用新案・著作権などの権利や独占禁止法・不正競争防止法についての知識を基に、弁理士や弁護士と連携して自身や自社の知的財産を保護・活用する能力を<a class="reference external" href="http://www.kentei-info-ip-edu.org/">知的財産管理技能検定</a>により国家が証明する国家資格です。</p>
<p>なお、知的財産管理技能士は業務独占資格ではなく名称独占資格であるため、わたしがこの資格によりできることは「 2 級知的財産管理技能士」を名乗ることのみです。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<div class="section" id="section-4">
<h3>実務経験要件の確認</h3>
<p>知的財産管理技能検定では 1 級から 3 級までの区分があり、 3 級は受検資格に制限がない一方で、 1 級と 2 級には下位級の合格もしくは実務経験またはその両方が受検資格として課せられます。
受検資格として認められる実務経験とは「知的財産の創造・保護・活用のいずれかに係る業務に携わった経験を指します。」(出典: <a class="reference external" href="http://www.kentei-info-ip-edu.org/exam_keiken">実務経験について</a>)とされています。</p>
<p>これについて、わたしが現職で実施しているソフトウェアの設計・開発およびウェブサイトの制作が該当するかが判然としなかったため、知的財産教育協会に問い合わせました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">気になることがあってとある協会にきのう送った問い合わせに期待通りの回答が得られて最高</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1110086911635259392?ref_src=twsrc%5Etfw">March 25, 2019</a></blockquote></div>
<div class="section" id="section-5">
<h3>参考書の音読</h3>
<p>ここからは前回 <a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">ファイナンシャル・プランニング技能士になった</a> 時と同様で、参考書の音読をしました。
知的財産管理技能検定を知ったのは 2 年前に Facebook の友達による受検報告を見かけたことがきっかけで、参考書はその直後に立ち寄った本屋さんで購入したものの、1 度も開かずに書店のブックカバーを被ったまま本棚で眠らせていたものがあったので、ようやく今回の受検に際して活用することができました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">時間を潰すために寄った本屋で、これまで名前しか知らなかった資格の参考書を眺めていたらその気になり、うっかり買ってしまったのでやっていくぞ</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/861153702870106112?ref_src=twsrc%5Etfw">May 7, 2017</a></blockquote><p>ただ、 2 年前に購入した、現在から 3 年前の法律を前提として解説されている本であるため、 TPP 発効に伴う著作権保護期間の延長や著作権侵害の非親告罪化、地理的表示など法改正や新しい制度についての解説がなく、そこは文化庁や農林水産省など担当官庁のウェブサイトから情報を得ました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">読んでいる本が古くて過去 3 年分くらいの法改正を反映していない……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1152621128210190337?ref_src=twsrc%5Etfw">July 20, 2019</a></blockquote><p>勉強の様子です。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">J-PlatPat を検索したところ「サトウのごはん」は商標登録されていないが、サトウの鏡餅のパッケージは立体商標として登録されているという知見を得た。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1150380519177084931?ref_src=twsrc%5Etfw">July 14, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">東京都がバンクシーによるものと思われる落書きを展示する行為について、これは日本国内における著作なので日本国の著作権法によりバンクシーが保有する著作者人格権の公表権については、落書きが東京都に対して原作品を譲渡とする行為とみなされ公表の同意があるものとして処理されるのでしょうか</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1151535971181006848?ref_src=twsrc%5Etfw">July 17, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">そもそもバンクシーによる公共物への落書きが著作権法における公表として扱われる場合は、作者自身が公表権を行使したという事になりこの懸念は当たらなく、そして落書きという行為が原作品の譲渡であるならばその所有者たる東京都が現作品を展示することは展示権が制限される場合にとなるのでしょうか</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1151544947075510272?ref_src=twsrc%5Etfw">July 17, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">“🔭 著作物に表現された思想又は感情の享受(桑原俊) – 早稲田大学知的財産法制研究所[RCLIP]” <a href="https://t.co/fuyv2CUeuU">https://t.co/fuyv2CUeuU</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1152131310111997953?ref_src=twsrc%5Etfw">July 19, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ライオン株式会社はその商標である LION を回転した NO17 を商標登録していますが、わたしの知る限り過去 3 年間に国内でこの商標を使用しておらず、これは不使用による登録取消事由に当たるように思えるのですが、実際のところどうなのでしょうか <a href="https://t.co/5mbtWPt40c">https://t.co/5mbtWPt40c</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1152166692560048134?ref_src=twsrc%5Etfw">July 19, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">法律の解説に日本語として不自然な逆説があって気になって調べてみたら、解説が実際の規定と正反対のことを書いていることがわかっておいおい……となった回</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1152579806350852098?ref_src=twsrc%5Etfw">July 20, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">"除斥期間" / 1件のコメント <a href="https://t.co/VIBrnDWWSD">https://t.co/VIBrnDWWSD</a> “法律用語解説~新銀座法律事務所” <a href="https://t.co/Phyf9TSgpp">https://t.co/Phyf9TSgpp</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1152603878338154497?ref_src=twsrc%5Etfw">July 20, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">商標登録は掲載公報の発行から 2 ヶ月以内であれば異議申立、過誤登録について 5 年の除斥期間内であれば取消審判を何人でも利用でき、また権利者であれば無効審判を提起できます。登録商標の指定商品・役務が異なる場合でも「著名商標」として認められる場合には取消・無効事由になることがあります。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1153302387592818689?ref_src=twsrc%5Etfw">July 22, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">出願公開制度のないパリ条約加盟国で商標出願した上で、第三国で優先権を主張して権利化する手口は上手いな "Apple Inc.は、リヒテンシュタインの他にジャマイカにも優先権主張の基礎となる商標登録出願を行っています" / “商標登録出願を秘密にすることはできますか? | …” <a href="https://t.co/TFg4e5t4e6">https://t.co/TFg4e5t4e6</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1156853777820835840?ref_src=twsrc%5Etfw">August 1, 2019</a></blockquote><p>なお、今回もタスクを先延ばしにする悪癖により勉強を開始したのは受検 6 日前の 7 月 15 日からでした。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">基本的に怠惰な上に経験からすら学ばない愚者なのに記憶力と要領のよさだけでここまで生き残ってしまい、剰えセルフハンディキャピングに対しても成功体験を積み重ねてきてしまったために生存バイアスが強いことがコンプレックスにも関わらず努力を覚えられずに、いまや能力の自転車操業じみてきた……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1161209416361709569?ref_src=twsrc%5Etfw">August 13, 2019</a></blockquote></div>
<div class="section" id="section-6">
<h3>過去の検定問題</h3>
<p>知的財産管理技能検定のウェブサイトで <a class="reference external" href="http://www.kentei-info-ip-edu.org/exam_kakomon.html">過去 3 年分の検定問題と正答が公開されている</a> ので、これを解いて理解を確かめました。</p>
<p>ただ、いかんせん準備期間が足らなかったため、実際には最新 1 回の学科試験を前日夜に解き、当日の昼と受験会場に向かう電車の中で最新 1 回の実技試験を解いたのみでした。</p>
<p>そのようにしていたら、会場に向かう電車で左隣に座った方と、そのさらに左隣の方も同様に「知財検定」と書かれた参考書を眺めていたので、彼女たちは恐らくわたしよりも準備をしているだろうけれど、それでも結局やることは同じなのだなと思って面白くなってしまいました。</p>
</div>
</div>
<div class="section" id="section-7">
<h2>おわりに</h2>
<p>準備に 6 日間しかかけられなかったり、利用した参考書の情報が古くて法改正による重要な変更を抑えきれなかったりしましたが、無事に合格することができました。</p>
<p>今後はソフトウェアの設計と実装ができて <a class="reference external" href="https://yosida95.com/2019/07/03/be-a-financial-planner.html">資産設計業務</a> もこなせる「 <a class="reference external" href="https://www.jpo.go.jp/support/general/chizai_skill_ver_2_0.html">知財人材</a> 」としてやっていきます。
なお、知的財産管理技能検定 1 級を受検するかは検討中です。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management/result.png"><img alt="試験結果" src="https://blogmedia.yosida95.com/2019/09/02/2nd-grade-certified-specialist-of-intellectual-property-management/result.png" style="width: 100%;" /></a>
</div>
3 級ファイナンシャル・プランニング技能士になりました2019-07-03T00:00:00+09:002019-07-03T00:00:00+09:00yosida95tag:yosida95.com,2019-07-03:/2019/07/03/be-a-financial-planner.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>2019 年 5 月 26 日実施検定を受検し、本日合格が発表されました。
これによりわたしは国家試験に合格した「3 級ファイナンシャル・プランニング技能士」になりました。</p>
<p>なお、ファイナンシャル・プランニング技能士は業務独占資格ではなく名称独占資格であるため、ファイナンシャル・プランニング技能士ができることは「(合格級)級ファイナンシャル・プランニング技能士」を名乗ることのみです。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<div class="section" id="section-4">
<h3>検定申し込み</h3>
<p>ファイナンシャル・プランニング技能士は一般社団法人金融財政事情研究会(きんざい)と特定非営利活動法人日本ファイナンシャル・プランナーズ協会(日本 FP 協会)の 2 団体が検定を実施しています。
このためどちらかの団体を選択した上で申し込みを行う必要があります。</p>
<p>検定は学科試験と実技試験から成り、学科試験は共通問題を利用しているものの、科目選択制の実技試験では一方でやっている科目は他方では実施されていないため、基本的には実技試験で選択する科目により申し込む団体が決まることになります。</p>
<p>ちなみに、実技試験の合格率は日本 FP 協会実施検定の方が幾分高いようですが、共通問題を利用する学科試験の合格率にも大きな差があるため、受検者の属性などが異なり意味のある比較にはなっていないかもしれません( <a class="reference external" href="https://www.kinzai.or.jp/fp/news-fp/22448.html">きんざい 2019年1月実施検定合格率</a> 、 <a class="reference external" href="https://www.jafp.or.jp/exam/syutoku/result/20190103.shtml">日本 FP 協会 2019 年 1 月実施 3 級検定合格率</a> )。</p>
<p>わたしは日本 FP 協会で受検しましたが、もともとはきんざいで受検しようと思っていました。
しかし、きんざいの Web 申し込みシステムがかなり不安になる作りをしていて、また公式サイトも日本 FP 協会に比べて手が行き届いていない様子が見て取れたので、「ここに住所やクレジットカード情報などを入力したくない」という気持ちになって日本 FP 協会を選択しました。
なお日本 FP 協会でも決済はクレジットカードではなくコンビニ店頭払いを利用しました。</p>
</div>
<div class="section" id="section-5">
<h3>参考書の音読</h3>
<p>勉強期間はちょうど 1 週間で、 5 月 19 日から始めました。</p>
<p>当初の計画では改元に伴う 10 連休を勉強に充てようと思っていましたが、惰眠を弄っていたらあっという間に過ぎてしまいました。
なお、この日を迎えるまで随分前に購入した参考書はずっとスピーカーの台座として使っていました。</p>
<p>基本的な勉強方法は参考書を音読することで、検定日までの一週間で音読により 1 度通読しました。
参考書の説明が足らなかったり理解できなかった点は、国税庁のウェブサイトや保険会社のウェブサイトにある説明で補完しました。</p>
<p>ノートはそれを作ることが目的になってしまいそうだったので作らず、参考書に蛍光マーカーやボールペンで先のウェブサイトで得たり自分でまとめたりした補足情報を直接書き込みました。</p>
<p>なお、わたしが使用した参考書は解説の不足や頻出項目の漏れが多く、また用語の索引が「コンピューターの方がもっと形態素解析が上手だぞ」というレベルでかなり使いづらかったので、ここでは紹介しません。</p>
</div>
<div class="section" id="section-6">
<h3>過去の検定問題</h3>
<p>検定前日(と検定当日の未明)は <a class="reference external" href="https://www.jafp.or.jp/">日本 FP のウェブサイト</a> で公開されている <a class="reference external" href="https://www.jafp.or.jp/exam/mohan/">過去の検定問題</a> のうち、昨年 2018 年の全 3 回分とことし 2019 年 1 月検定の計 4 回分の学科試験と実技試験を解きました。</p>
<p>すべての実施回で、学科試験と実技試験どちらもだいたい 20 分程度で解き終わり、正答率も合格基準の 60 % を超える 80% を超えたので、これなら本検定も大丈夫だろうと自信がつけることができました。</p>
<p>ただ、時間に追われていたために 4 回分の検定問題を一度に解き一度に答え合わせをするというスタイルでやったところ、解く度に誤った理解を訂正するというフィードバックができず、かつ誤った理解を反復してアウトプットしたためにそれが定着してしまうという問題が発生しました。
インプットとアウトプットのフィードバックループを細かく回すことの大切さを認識しました。</p>
<p>なお、過去の検定問題の解き方として、問題用紙に解答を直接記入し、答え合わせ、誤答の訂正とその解説も問題用紙に記入するという方法を採ったことで、それ単体でわたしの誤答の傾向とそれに対する正答と正しい理解がまとまった資料を作ることができました。
検定会場に移動する電車内と検定開始前の検定会場でこの資料を読むことで、かなり効率的な最後の足掻きをすることができました。</p>
<p>ちなみに、わたしの自宅にはプリンターがないため試験問題をセブンイレブンのマルチ複合機で印刷しました。
その際に両面印刷された用紙を 2 つ折りした上で中綴じして小冊子にする設定をした上で、原稿が 50% に縮小されるように A4 用紙を選択したところ、用紙枚数が本来の 1/4 になった上にコンパクトな A5 サイズの冊子ができてめちゃくちゃ便利でした。
ただ、日本 FP 協会の実技試験で出題される会社四季報や新聞記事を読み取る出題に添付される資料の文字がめちゃくちゃ細かくなって、それらの読み取りは難儀しました。</p>
</div>
</div>
<div class="section" id="section-7">
<h2>これから</h2>
<p>2 級ファイナンシャル・プランニング技能士検定を受検することを予定しています。
今回の 3 級受検では短期間で知識を詰め込んだために、時間経過とともに多くを忘却していく恐れがあり、また、資産設計の実践における能力にはまだ不安があるため、それらを 2 級を目指すことにより補おうと思います。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/07/03/be-a-financial-planner/result.png"><img alt="合格発表" src="https://blogmedia.yosida95.com/2019/07/03/be-a-financial-planner/result.png" style="width: 80%;" /></a>
</div>
静岡県ひとり旅2019-06-25T00:00:00+09:002019-06-25T00:00:00+09:00yosida95tag:yosida95.com,2019-06-25:/2019/06/25/shizuoka-trip.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>6 月の 25 日と 26 日に 1 泊 2 日で静岡県を旅してきました。
静岡県は自宅がある東京から近いので何度も訪れていますが、ひとり旅はこれが初めてです。</p>
<p>そもそもひとり旅をするようになってからもまだ 1 年経っていませんが。</p>
</div>
<div class="section" id="section-3">
<h2>きっかけ</h2>
<p>わたしが所属する会社では誕生月に誕生日休暇が付与されます。
この誕生日休暇を利用してどこかに行こうと思っていたところ、わたしが最近はじめた <a class="reference external" href="https://ekimemo.com/">駅メモ!</a> が 5 周年イベントを実施するということなので、このタイミングで電車に乗る旅をすることにしました。</p>
<p>なお、梅雨で天候が不安だったので、この旅行を決心したのは旅行前日でホテルも前日に予約しました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">本日6/26で、駅メモ!は誕生から5周年を迎えました🎉<br>誕生5周年を記念して、本日限定で5周年記念ストーリーがゲットできるログインボーナスを実施しております!忘れずに駅メモ!を起動してくださいね🎁<br><br>また、15:00頃にはちょっとした発表も予定しているのでお楽しみに(❁′ᗨ‵❁) <a href="https://twitter.com/hashtag/%E9%A7%85%E3%83%A1%E3%83%A2?src=hash&ref_src=twsrc%5Etfw">#駅メモ</a></p>— 駅メモ!公式 (@ekimemo) <a href="https://twitter.com/ekimemo/status/1143534314690244608?ref_src=twsrc%5Etfw">June 25, 2019</a></blockquote></div>
<div class="section" id="section-4">
<h2>行程</h2>
<p>今回も Google My Maps で行程をまとめました。</p>
<iframe src="https://www.google.com/maps/d/embed?mid=1QqzVzNfmFzvyHi-Clyo7AATV_aLycal3" width="640" height="480"></iframe><div class="section" id="section-5">
<h3>1 日目</h3>
<p>夕方に仕事を切り上げて最低限の荷造りをした後、在来線に乗って静岡駅を目指しました。
JR 東日本管内から JR 東海管内へは Suica では乗り入れられず、また今回は東海道本線ではなく御殿場線を乗り潰す大回りをするため、今回は乗車券が必要でした。</p>
<p>平日火曜日の 18 時台に出発したため、見事帰宅ラッシュに巻き込まれてえらい目にあいました。</p>
<p>静岡に到着したときには 22 時を回っていたため、この日はホテルで休むのみとなりました。</p>
</div>
<div class="section" id="section-6">
<h3>2 日目</h3>
<p>ホテルで朝食をとったあと、レンタカーを借りて自分の運転で気ままに周辺を巡りました。</p>
<div class="section" id="section-7">
<h4>久能山東照宮</h4>
<p>久能山東照宮は徳川家康を祀る神社で、本殿が国宝に指定されているほか、多数の門などの建造物も重要文化財に指定されています。</p>
<p>久能山東照宮は久能山という山の中に位置するため、参拝するには山を登る必要があります。
ロープウェイが整備されていますが、わたしは山下から 1,159 段の石段により参拝しました。</p>
<p>思いの外急な石段でさくさくと登っていたら汗だくになり息切れした上、おまけに日焼けして日光かぶれを起こすという有様でした。</p>
<p>ただ、周囲に生えるあじさいなどの他、山中から臨む海もきれいでした。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BzQkhLCBIWd/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BzQkhLCBIWd/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BzQkhLCBIWd/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-06-28T15:44:18+00:00">Jun 28, 2019 at 8:44am PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">I'm at かどや商店 in 静岡市駿河区, 静岡県 <a href="https://t.co/dmORUo1N8i">https://t.co/dmORUo1N8i</a> <a href="https://t.co/OjpEBBVEm1">pic.twitter.com/OjpEBBVEm1</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1143728122656935936?ref_src=twsrc%5Etfw">June 26, 2019</a></blockquote></div>
<div class="section" id="section-8">
<h4>三保の松原</h4>
<p>次は世界文化遺産である富士山を構成する景勝地でもある三保の松原を訪れました。
三保の松原は <a class="reference external" href="https://ja.wikipedia.org/wiki/%E7%BE%BD%E8%A1%A3%E4%BC%9D%E8%AA%AC">羽衣伝説</a> の舞台で、天女が羽衣をかけたとする羽衣の松のほか、その羽衣の松を依り代として降臨する 2 柱を祀る御穂神社、三保の松原から御穂神社に続く松並木である神の道など多くの見どころがありました。</p>
<p>そして何よりも三保の松原から続く海浜が素晴らしくて、ただただ「美しい」という感情以外の感情がなくなる場所でした。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BzQll-sBRu7/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BzQll-sBRu7/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BzQll-sBRu7/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-06-28T15:53:41+00:00">Jun 28, 2019 at 8:53am PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-9">
<h4>三保灯台</h4>
<p>次は三保の松原と併せて富士山に関連する世界文化遺産の構成要素である三保灯台を訪れました。
もともと訪れるつもりはありませんでしたが、 Google Maps を眺めていたらその存在に気づき、せっかくなので足を伸ばしてみました。</p>
<p>三保灯台は日本で最初の鉄筋コンクリート造の現役の灯台で、その歴史的文化財的な価値が高いとされているようです。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BzQmq33BDr0/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BzQmq33BDr0/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BzQmq33BDr0/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-06-28T16:03:06+00:00">Jun 28, 2019 at 9:03am PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-10">
<h4>静岡科学館る・く・る</h4>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">I'm at 静岡科学館 る・く・る in Shizuoka, 静岡県 <a href="https://t.co/HEFA1zzpcY">https://t.co/HEFA1zzpcY</a> <a href="https://t.co/VWoZHdbjrM">pic.twitter.com/VWoZHdbjrM</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1143778163450896384?ref_src=twsrc%5Etfw">June 26, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">こども向けの体験展示が主で、大人がひとりで楽しめる系の科学館ではなかった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1143783650594447360?ref_src=twsrc%5Etfw">June 26, 2019</a></blockquote></div>
<div class="section" id="section-11">
<h4>甲府駅</h4>
<p>静岡の観光を終えそのまま東京に帰ってもよかったですが、せっかくなので静岡駅から特急ふじかわに乗って山梨県の甲府駅を経由することにしました。
この経路は身延線の全線を含むため、身延線の乗りつぶしを達成できました。</p>
</div>
<div class="section" id="section-12">
<h4>舞鶴城公園</h4>
<p>甲府駅で途中下車して 1 時間あまりの短時間でしたが甲府駅の周辺を探索して、舞鶴城公園にも寄ってみました。
日が落ちて周囲はすっかり真っ暗になっていましたが、 iPhone の懐中電灯を頼りに園内の案内看板や説明看板や天守台からの夜景を楽しみました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BzQnxcuh6f2/" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BzQnxcuh6f2/" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BzQnxcuh6f2/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-06-28T16:12:44+00:00">Jun 28, 2019 at 9:12am PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
</div>
</div>
<div class="section" id="section-13">
<h2>感想</h2>
<p>今回は景勝地を中心に巡りましたが、振り返ればとにかく三保の松原の海浜が美しかったという感想に尽きます。</p>
<p>この他、交通マナーがよく、車を運転する人に歩行者優先の意識が根付いているという印象も受けました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">静岡の人たち、信号のない横断歩道を徒歩で渡ろうとするとほとんどの車が止まって道を譲ってくれるので気持ちがよい。 JAF の調査も伊達ではない。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1143748075233529857?ref_src=twsrc%5Etfw">June 26, 2019</a></blockquote></div>
<div class="section" id="section-14">
<h2>余談</h2>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">前の恋人との旅行の写真を Google Photos が去年のきょうの思い出として知らせてきて、朝から複雑な心境になっている。しかも写真によるときょうのわたしは偶然にも上から下まで去年と全く同じ服装をしている……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1143675558510788608?ref_src=twsrc%5Etfw">June 26, 2019</a></blockquote></div>
亀戸駅・錦糸町駅間(徒歩 10 分)を 99 駅・ 8 時間 24 分かけて移動した話2019-06-09T00:00:00+09:002019-06-09T00:00:00+09:00yosida95tag:yosida95.com,2019-06-09:/2019/06/09/trip-around-boso-peninsula.html<p>こんにちは、 yosida95 です。</p>
<p>さて …</p><p>こんにちは、 yosida95 です。</p>
<p>さて、鉄道ファンの間ではよく知られた話であるようですが、 JR では目的地まで複数の経路を選択できるような地域における乗車券の取り扱いを簡便にするため、予め設定された <a class="reference external" href="https://ja.wikipedia.org/wiki/%E5%A4%A7%E9%83%BD%E5%B8%82%E8%BF%91%E9%83%8A%E5%8C%BA%E9%96%93_(JR)">大都市近郊区間</a> では乗車経路が重複しない(一筆書きという)限り、いかなる経路を利用して移動したとしても購入した乗車券の経路を利用したとみなすという特例が存在します。</p>
<p><a class="reference external" href="https://www.jreast.co.jp/kippu/1103.html">「運賃計算の特例:JR東日本」</a> でも説明されている通り、この特例により実際の乗車経路に関わらず運賃が最安となる経路の乗車券を利用することができます。
特に IC 乗車券では自動的に最安経路における運賃が適用されるため、大都市近郊区間を日常的に利用する人は(知らず知らずのうちに)この特例を利用しているかもしれません。</p>
<p>鉄道ファンの間ではこの特例を最大限好意的に解釈して、初乗り運賃でいかに遠回りとなる経路を選択できるかを競う風習があり、これを大回り乗車というようです。</p>
<p>わたしも今回、亀戸駅から乗車し通常は徒歩でも 10 分で到達できる隣駅の錦糸町駅まで、 99 駅を経て房総半島を一周する経路を選択し 8 時間 24 分かけて移動してみました。</p>
<div class="section" id="section-2">
<h2>移動経路</h2>
<iframe src="https://www.google.com/maps/d/embed?mid=1Q4AE5RXYO_jPsMljCe_IRRvRqrnbVB9C" width="640" height="480"></iframe><p>移動経路を Google My Maps を使ってプロットしました。
鉄道路線ごとにレイヤーを分割しています。</p>
<ul class="simple">
<li>中央・総武緩行線<ul>
<li>13:20 発 亀戸駅</li>
<li>13:46 着 津田沼駅</li>
<li>13:51 発 津田沼駅</li>
<li>14:06 着 千葉駅</li>
</ul>
</li>
<li>総武本線<ul>
<li>14:14 発 千葉駅</li>
<li>14:59 着 成東駅</li>
</ul>
</li>
<li>東金線<ul>
<li>15:37 発 成東駅</li>
<li>15:57 着 大網駅</li>
</ul>
</li>
<li>外房線<ul>
<li>16:09 発 大網駅</li>
<li>16:22 着 茂原駅</li>
<li>16:38 発 茂原駅</li>
<li>18:04 着 安房鴨川駅</li>
</ul>
</li>
<li>内房線<ul>
<li>18:06 発 安房鴨川駅</li>
<li>18:49 着 館山駅</li>
<li>18:51 発 館山駅</li>
<li>20:27 着 蘇我駅</li>
</ul>
</li>
<li>京葉線<ul>
<li>20:31 発 蘇我駅</li>
<li>21:20 着 東京駅</li>
</ul>
</li>
<li>総武本線<ul>
<li>21:36 発 東京駅</li>
<li>21:44 着 錦糸町駅</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-3">
<h2>きっかけ</h2>
<p>なぜこのような苦行を実行したかというと大きく 2 つの理由があり、最大の理由がスマートフォンゲームの <a class="reference external" href="https://ekimemo.com/">「駅メモ!」</a> にハマったため、もう一つの理由が <a class="reference external" href="https://yosida95.com/2019/01/31/hokkaido-trip.html">「ひがし北海道フリーパスで4泊5日冬の北海道縦断旅行をした」</a> ことで単に鉄道に乗っていることが楽しいということに気づいたためです。</p>
<p>駅メモ!では他のユーザーが作成した乗車経路を共有する「メモリールート」という機能があり、そこで房総半島を一周するルートが共有されていたことから興味がわいてチャレンジしてみることにしました。</p>
<p>また、北海道で知った鉄道に乗る楽しみとして、地域によって異なる車窓の風景や車内の雰囲気を観察するというものがあり、今回もそれを楽しめるのではという目論見もありました。</p>
</div>
<div class="section" id="section-4">
<h2>感想</h2>
<p>当初の目論見どおり楽しめました。
改札からは出ていないため派手な楽しさはありませんが、じんわりとした楽しさが長時間にわたって継続しました。</p>
<p>総武本線の成東駅では 40 分ほど電車待ちをして、着ていた黒いカーディガンに蜂が寄ってきてヒヤッとした場面もありましたが、終始うぐいすの鳴き声が聞こえていたことが印象的で、とてものどかでクラシックな雰囲気の駅でした。</p>
<p>その成東駅から乗った東金線は全区間単線で折り返し運転をする 5 つしか停車駅がない路線なのに、一面の田畑から、開発された住宅街まで風景が目まぐるしく変わるほか、ほとんどが地元の人なのか、乗客もまばらでゆったりとした雰囲気が心地よかったです。</p>
<p>内房線から京葉線に乗り換え、最初はまばらだった乗客も海浜幕張駅で座席が埋まる程に増え、さらに舞浜駅ではディズニー帰りと思われる傾いた格好した人たちが大挙して乗り込んでくるなど、わずか 1 時間足らずの乗車時間なのに景色にとどまらず車内の雰囲気まで目まぐるしく変遷する様がとてもおもしろかったです。</p>
<p>ただ、全行程を通して、この一週間の厳しい暑さから一転した涼しい陽気で夜には雨も降り出したことから、車内やホームでじっとしていることが寒くてしんどかったことが難点でした。
駅構内の自動販売機のラインナップが夏仕様に入れ替わっていて、どこを見ても冷たい飲み物しか無いことも寒さに拍車をかけました。</p>
<p>また、ターミナル駅のような特に大きな駅でない限り売店が改札内にないため、予め食べるものを持ち込めばよかったという教訓を得ました。
夕方ごろには低血糖に苦しんだため、自動販売機で購入した甘いココア(ただし冷たい)を飲んでなんとかしのぎました。</p>
<p>なお、駅メモ!ではこれまでの最高スコアを稼ぎ、かつ最高ランクを獲得できました。</p>
<img alt="" src="https://blogmedia.yosida95.com/2019/06/09/trip-around-boso-peninsula/ekimemo01.png" style="width: 50%;" />
<img alt="" src="https://blogmedia.yosida95.com/2019/06/09/trip-around-boso-peninsula/ekimemo02.png" style="width: 50%;" />
</div>
ひがし北海道フリーパスで4泊5日冬の北海道縦断旅行をした2019-01-31T00:00:00+09:002019-01-31T00:00:00+09:00yosida95tag:yosida95.com,2019-01-31:/2019/01/31/hokkaido-trip.html<!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/polar-bear.jpg"><img alt="旭山動物園 しろくま" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/polar-bear.jpg" style="width: 100%;" /></a>
<p>期間は1月25日から1月30日まで。前回の旅行は …</p><!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/polar-bear.jpg"><img alt="旭山動物園 しろくま" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/polar-bear.jpg" style="width: 100%;" /></a>
<p>期間は1月25日から1月30日まで。前回の旅行は12月25日から1泊2日の <a class="reference external" href="https://yosida95.com/2018/12/25/trip-to-nagoya.html">名古屋旅行</a> だったので、ちょうど1ヶ月ぶりの旅行でした。</p>
<p>北海道を訪れるのはこれで3度目で、1度目は2012年11月にわたしがまだ高校生だったころに <a class="reference external" href="https://yosida95.com/2012/11/22/033659.html">さくらインターネット石狩データセンターの見学ツアーに参加した</a> 際、2度目は2016年7月の会社の出張の際でした。</p>
<div class="section" id="section-2">
<h2>きっかけ</h2>
<p>きっかけは何より初めてのひとり旅だった前回の名古屋旅行が楽しかったことで、名古屋から帰ってきてからすぐに、次はどこへ行こうかと一生分くらい旅行系のキュレーションサイトを眺めていました。</p>
<p>そんな折に1月10日支給分の給与明細を眺めていたところ、年末調整により手取り額の2割弱が還付されたこと、そして2月1日に失効する有給休暇が7日分あることに気が付きました。資金と時間が揃い、旅行にこれ以上のタイミングはないだろうということで1月中に旅行に出ようと決めました。</p>
<p>行き先として北海道を選んだのは、せっかく1週間の休みがあるなら広大な地域の方が旅行し甲斐があろうと思ったこと、東京で生まれ育ったわたしにとって真冬の北海道の未知が魅力的だったためです。</p>
<p>そして最大の決め手は JR 北海道が LCC 利用者に限り管内の広大なエリアが5日間、 <strong>特急列車も含め乗り放題</strong> になる <a class="reference external" href="https://www.jrhokkaido.co.jp/travel/freepass/">ひがし北海道フリーパス</a> を発売していたことです。</p>
<blockquote>
<a class="reference external image-reference" href="https://www.jrhokkaido.co.jp/travel/freepass/"><img alt="ひがし北海道フリーパス" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/jr-freepass.gif" style="width: 100%;" /></a>
<p class="attribution">—<a class="reference external" href="https://www.jrhokkaido.co.jp/travel/freepass/">ひがし北海道フリーパス・きた北海道フリーパス|JR北海道- Hokkaido Railway Company</a></p>
</blockquote>
<p>また、北海道での鉄道旅行を検討しているときにちょうど目にした、次の記事がわたしの背中を押してくれました。</p>
<blockquote>
<a class="reference external image-reference" href="https://travel.spot-app.jp/ekimemo_hokkaido/"><img alt="真冬の北海道全駅制覇。クリスマスから始まった6日間の記録_PR" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/ekimemo_hokkaido.jpg" style="width: 100%;" /></a>
<p class="attribution">—<a class="reference external" href="https://travel.spot-app.jp/ekimemo_hokkaido/">北海道の全駅を真冬に制覇しに行ったら普通に悪夢だった_PR | SPOT</a></p>
</blockquote>
</div>
<div class="section" id="section-3">
<h2>行程</h2>
<p>行程を Google My Maps でまとめました。日程でレイヤーを分けています。</p>
<iframe src="https://www.google.com/maps/d/embed?mid=18W_9PmoZDxBDeV1dJVl7tpcU9fliUQNi" width="640" height="480"></iframe><div class="section" id="section-4">
<h3>1日目</h3>
<div class="section" id="section-5">
<h4>成田空港</h4>
<p>1日目は京成スカイライナーで成田空港第2ビル駅に行き、駅からバニラエアのターミナルがある第3ターミナルまで徒歩で移動しました。機内持ち込みするバックパックの計量を終え計量済み札を付けてもらい、保安検査までの待ち時間を利用してフードコートで朝ごはんを食べました。</p>
<p>保安検査を終えると通勤ラッシュのごとく混雑したバスに押し込まれ、搭乗する飛行機まで輸送されました。外は結構な勢いで雪が降っていて、除雪が必要になった影響で30分程度遅れたものの無事に離陸しました。</p>
<p>この成田空港で見た雪が5日間の行程の中でもっとも激しい降雪でした。</p>
</div>
<div class="section" id="section-6">
<h4>新千歳空港</h4>
<p>新千歳空港に到着したところでそのまま JR 新千歳空港駅に行き、みどりの窓口でひがし北海道フリーパスを購入しました。バニラエアを利用したことの証明である航空券の提示と U25 割引を受けるために身分証明書の提示を求められました。</p>
<p>乗りたい電車の出発まで1時間ほど時間があったので、新千歳空港内を巡ったりフードコート内の雪印パーラーで空港ソフトを食べたりして時間を潰しました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVwy6GhNyL/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVwy6GhNyL/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVwy6GhNyL/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T12:59:25+00:00">Feb 1, 2019 at 4:59am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-7">
<h4>帯広駅</h4>
<p>新千歳空港から2時間ほどかけて帯広駅に移動し、まずはホテルにチェックインしました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">乗っている電車が急に減速したと思ったら「野生のエゾシカが前を走っているため減速しています」というアナウンスが流れて、なるほど俺は北海道に来たんやなという実感が湧いてきた</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1089009722764587008?ref_src=twsrc%5Etfw">January 26, 2019</a></blockquote></div>
<div class="section" id="section-8">
<h4>ばんえい競馬</h4>
<p>ホテルにバックパックを置いて、財布と飲み物をコンビニのレジ袋に入れて駅まで移動し、駅前で拾ったタクシーでばんえい競馬が開催される帯広競馬場を訪れました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">この旅行に持ってきた唯一の荷物であるバックパックをホテルに置いてきたため財布と飲み物が入ったコンビニ袋だけを持って競馬場に出入りしていて、見かけは完全に "プロ" になってしまった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1089071117203959813?ref_src=twsrc%5Etfw">January 26, 2019</a></blockquote><p>これまでの人生で初めて競馬場に足を踏み入れました。もちろん馬券の買い方も知りませんでしたが、せっかくの機会なのでものは試しと館内に掲示されている馬券の種類や購入方法を学んで、次のレースの三連複の馬券を購入してみました。</p>
<p>馬券を購入してレースの始まりを待っていたところ、外国人観光客に話しかけられ馬券の購入方法を訊ねられるという出来事があり、いま覚えたばかりの馬券の購入方法を英語で説明したところ無事に購入することができていました。</p>
<p>なお、わたしが購入した馬券は一切かすりもせずに外れました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVxLKIhB6_/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVxLKIhB6_/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVxLKIhB6_/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:02:43+00:00">Feb 1, 2019 at 5:02am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/banei-tokachi.gif"><img alt="ばんえい競馬" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/banei-tokachi.gif" style="width: 100%;" /></a>
</div>
<div class="section" id="section-9">
<h4>豚丼</h4>
<p>ばんえい競馬の見学を終え、駅前にあるホテルまでは徒歩で戻りました。途中にあったドラッグストアで手袋を購入しました。</p>
<p>ホテルに戻って周辺の食事を調べたところ、十勝地域の名物は炭火で焼いた豚肉を米飯にのせた豚丼だということが分かったので豚丼を食べました。</p>
</div>
</div>
<div class="section" id="section-10">
<h3>2日目</h3>
<div class="section" id="section-11">
<h4>帯広百年記念館</h4>
<p>2日目は7時ごろに起床しホテルのバイキングで朝食を済ませました。9時ごろにホテルを出発して帯広駅の周辺を徒歩で散策しつつ、博物館 <a class="reference external" href="http://museum-obihiro.jp/occm/">帯広百年記念館</a> を訪れました。帯広百年記念館は、帯広地域の開拓の歴史や、地学、農業、工業についての常設展示がある博物館です。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVxqJ8hf4I/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVxqJ8hf4I/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVxqJ8hf4I/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:06:57+00:00">Feb 1, 2019 at 5:06am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>帯広百年記念館は <a class="reference external" href="https://www.city.obihiro.hokkaido.jp/toshikensetsubu/midorinoka/a_01midorigaoka.html">緑ヶ丘公園</a> という広大な公園の中にあり、この公園も1時間ほど散策しました。公園内は結構な積雪となっていましたが、散歩しているご夫婦やそり遊びをしている親子連れ、犬の散歩をする人がちらほらいて、雪が日常にある姿とたくましさを感じました。</p>
</div>
<div class="section" id="section-12">
<h4>阿寒湖温泉</h4>
<p>この日滞在する阿寒湖温泉の周辺には鉄道が通っていないので、滞在するホテルの送迎バスを利用することにしました。この送迎バスが十勝駅前にある <a class="reference external" href="https://www.city.obihiro.hokkaido.jp/tokachiplaza/a600110tokachiplaza.html">とかちプラザ</a> から出発するとのことなので、緑ヶ丘公園の散策を終えたわたしは徒歩で帯広駅まで戻り、バスの出発時刻までの時間を利用して、とかちプラザ内にあるレストランで昼食にスパゲティを食べました。</p>
<p>帯広駅前を出発したバスは4時間弱で阿寒湖温泉に着きました。チェックインを済ませしばらく休憩したところで夕食の時間となり、食堂で夕食を取りました。夕食は山菜の炊き込みご飯やそば、豚肉の白湯鍋、茶碗蒸し、わかさぎの天ぷら、お造り、ビーフシチューなど品目が多く、どれも外れはありませんでした。</p>
<p>そして、阿寒湖温泉ということで目当ては温泉です。温泉、そして大浴場は中学校の修学旅行以来でおよそ10年ぶりの経験です。うっすらとそんな予感はあったものの、当時と違って大浴場が精神的に「無理」になってしまったことが実体験として判明しました。</p>
<p>今後は大浴場を避けて生きていく運びとなりましたが、ひとり旅では温泉で個人風呂という選択は無いに等しいと思うので、今後の旅では温泉も避けていくこととなりそうです。</p>
<p>そんな感じでこの日の目的は完遂したので早めに就寝しました。</p>
</div>
</div>
<div class="section" id="section-13">
<h3>3日目</h3>
<div class="section" id="section-14">
<h4>阿寒湖</h4>
<p>この日も7時ごろに起床してホテルでバイキングの朝食を済ませました。帰りも送迎バスを利用する事になっていたので、バスの出発時刻まで阿寒湖を散策しました。阿寒湖の湖面は完全に凍結していて、湖上ではスノーモービルやわかさぎ釣りなどのアクティビティが開催されていました。</p>
<p>Google によるとこの時間の気温は -22 °C でこの旅行での最低気温を体験しました。呼吸をしているだけで鼻の中が凍るという体験は初めてでしたが、歩いている限りは特別寒いということもなくヒートテックの面目躍如でした。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVycMPhQv0/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVycMPhQv0/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVycMPhQv0/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:13:47+00:00">Feb 1, 2019 at 5:13am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-15">
<h4>博物館網走監獄</h4>
<p>ホテルを出発して送迎バスに乗り3時間ほどで網走駅に到着しました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">網走駅で見かけた穏やかじゃないポスト <a href="https://t.co/k8QewILWrA">https://t.co/k8QewILWrA</a> <a href="https://t.co/JYIySTzAWe">pic.twitter.com/JYIySTzAWe</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1091333255964454916?ref_src=twsrc%5Etfw">February 1, 2019</a></blockquote><p>網走駅で荷物をコインロッカーに預け、財布と飲み物、そして前日に帯広で購入した酔い止めの薬をダウンジャケットのポケットに突っ込んだ他は手ぶらで駅前で拾ったタクシーに乗り、 <a class="reference external" href="https://www.kangoku.jp/">博物館網走監獄</a> に行きました。</p>
<p>博物館網走監獄は、網走刑務所を改築するにあたって対象となった建物を保存のために移築し展示した博物館で、北海道開拓の基礎となった <a class="reference external" href="https://ja.wikipedia.org/wiki/%E5%9B%9A%E4%BA%BA%E9%81%93%E8%B7%AF_(%E6%97%A5%E6%9C%AC%E5%8F%B2)">囚人による道路建設</a> の様子や、当時の囚人の暮らしなどについて学ぶことができます。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">入獄 (@ 博物館 網走監獄 in 網走市, 北海道) <a href="https://t.co/1l5DvR07qT">https://t.co/1l5DvR07qT</a> <a href="https://t.co/ahXXPBXZKR">pic.twitter.com/ahXXPBXZKR</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1089738016980197376?ref_src=twsrc%5Etfw">January 28, 2019</a></blockquote></div>
<div class="section" id="section-16">
<h4>先回りするタクシー</h4>
<p>博物館網走監獄の見学を終え、タクシーを呼んでもらうよう網走監獄の受付の方にお願いしました。受付の方がタクシー会社に電話して配車の手配をしたところ、「すでにタクシーが到着しているらしいのでそのまま乗ってください」と言われました。</p>
<p>そんなこともあるのかと思いつつ指定された網走監獄の駐車場に到着しているタクシーに乗り込んだところ、なんと往路で網走駅から送ってくれた運転手さんのタクシーで、「道中にお聞きした予定からそろそろお迎えが必要かと思い先回りして待機していました。」とのことでした。</p>
<p>名古屋旅行では都内とは違って流しのタクシーは存在しないということを学び、今回はそれを踏まえタクシーは電話で配車をお願いするという方針でやっていましたが、まさか往路のタクシーが先回りしてわたしを待っているという経験をするとは思ってもみませんでした。なお、わたしが乗車することを予見して駐車場で待っていたタクシーでしたが、迎車料金はきっちり取られました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">網走監獄から帰るときに電話でタクシーを呼んだら「もう到着しています」と言われ、乗ってみたら「道中でお聞きした観光予定から、そろそろ来る頃だと思って先回りしていました」と、網走駅から送ってくれた運転手さんが待ってくれていた。すごい体験だった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1089766615338561537?ref_src=twsrc%5Etfw">January 28, 2019</a></blockquote></div>
<div class="section" id="section-17">
<h4>流氷観光砕氷船おーろら</h4>
<p>先回りして待っていてくれたタクシーに乗って、流氷観光砕氷船おーろらの乗船場である <a class="reference external" href="http://www.hokkaido-michinoeki.jp/michinoeki/2986/">道の駅流氷街道網走</a> まで送ってもらいました。道中も北海道における積雪の地域差や、阿寒湖温泉のホテルにまつわる話、タクシーで阿寒湖温泉街を走っていたら海外で暮らすご息女夫婦が家族旅行で来日しているところに出くわした話などで楽しませてくれました。</p>
<p><a class="reference external" href="https://www.ms-aurora.com/abashiri/">流氷観光砕氷船おーろら</a> はその名の通り網走の沖合に流れ着いた流氷を船上から観測するアクティビティで、氷をかき分け進んでいきます。インターネットから事前に予約を取れますが、わたしが旅行を計画し始めた時点ではこの日しか予約が取れなかったため、この乗船日に合わせて旅行の出発日を決めました。</p>
<p>時季によっては流氷が漂着しておらずただのクルーズとなってしまう回もあるようですが、わたしが乗船した日は写真や動画の通り海面を覆い尽くす流氷を観測することができました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVy23BBRqp/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVy23BBRqp/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVy23BBRqp/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:17:26+00:00">Feb 1, 2019 at 5:17am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>船内には座席と大きな窓があり、暖房が効いた船内から風に当たらずに流氷を眺めることもできますが、水面に近い1階のデッキや2階のデッキ及び屋上の展望デッキに出て観測することもでき、わたしは航行中のほとんどの時間をデッキで過ごしました。</p>
<p>1階や2階のデッキから船首付近を眺めることも楽しいですが、船尾から船によってどけられた流氷が作る道筋を眺めることも楽しかったです。</p>
</div>
</div>
<div class="section" id="section-18">
<h3>4日目</h3>
<div class="section" id="section-19">
<h4>旭川駅</h4>
<p>流氷観測を終えて網走駅に戻り、その日のうちに網走駅から特急でおよそ4時間かけて旭川駅に向かいました。旭川駅を出るとちらちらと雪が舞っていて、5日間の北海道旅行で体験した唯一の降雪となりました。</p>
<p>4日目の朝を旭川で迎え、旭川市博物館に向かう道すがら旭川駅周辺を散策しました。旭川はこの北海道旅行の中で最も雪深い地域でした。車道に氷の層ができていてその上を車が行き交っている他、歩道は駅前を除いて除雪も融雪もされておらず、新雪も残っているためスニーカーで歩くことがとても難しく、人とすれ違う目的などで新雪に足を踏み入れるとスニーカーが完全に埋まってしまうため、靴にどんどん水が染みてきました。</p>
<p>ただ、このような環境からもっとも「北海道に来たぞ」感を得ることができる楽しい街でした。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">旭川市は本当に積雪がすごくて、駅前を除いては融雪はおろか除雪もされていないところがあって歩道に 20cm くらい積もっていたり 車道に踏み固められた 5cm くらいの氷の層ができていたりするんだけれど、バスもタクシーも乗用車も当たり前のようにバンバン飛ばしていてそれでいて事故らないからすごい</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090088998192656384?ref_src=twsrc%5Etfw">January 29, 2019</a></blockquote><blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVze4qBvRf/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVze4qBvRf/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVze4qBvRf/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:22:54+00:00">Feb 1, 2019 at 5:22am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-20">
<h4>旭川市博物館</h4>
<p><a class="reference external" href="http://www.city.asahikawa.hokkaido.jp/hakubutukan/">旭川市博物館</a> はアイヌの歴史や文化を中心に、北海道開拓の歴史や旭川市周辺の動植物や地質など自然に関する展示もある総合博物館です。3時間もあれば十分にじっくり回れる規模で、平日の午前中ということもあって十分に堪能することができました。</p>
<p>特に全体の半分を占めるアイヌに関する展示は見事で、アイヌ式の住宅を再現した展示の中で聴くアイヌ語による伝承物語の読み聞かせが印象に残っています。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">わたしが小学生の時の社会科見学先で、平日にも関わらずのんびり観覧している人がいていつも不思議だったけれど、15年越しに謎が解け未来のわたしの姿だったんだなと腹落ちした</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090082449483157505?ref_src=twsrc%5Etfw">January 29, 2019</a></blockquote></div>
<div class="section" id="section-21">
<h4>旭山動物園</h4>
<p>言わずと知れた知名度を誇る <a class="reference external" href="http://www.city.asahikawa.hokkaido.jp/asahiyamazoo/">旭山動物園</a> にも行きました。冬季は一部の動物は屋内で飼育され展示されていないのですが、寒い地方に生息する動物や水棲動物、温度管理された室内で展示される爬虫類は見ることができ、特に雪中で過ごす動物は旭山動物園が得意とする行動展示とも相まってより楽しむことができたような気がします。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtVz3t-BpT0/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtVz3t-BpT0/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtVz3t-BpT0/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:26:17+00:00">Feb 1, 2019 at 5:26am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>普段動物園で見かけない動物としてはカラスが展示されています。北海道札幌市出身の作家である <a class="reference external" href="https://ja.wikipedia.org/wiki/%E5%A4%AA%E7%94%B0%E7%B4%AB%E7%B9%94">太田紫織</a> さんによる <a class="reference external" href="https://ja.wikipedia.org/wiki/%E6%AB%BB%E5%AD%90%E3%81%95%E3%82%93%E3%81%AE%E8%B6%B3%E4%B8%8B%E3%81%AB%E3%81%AF%E6%AD%BB%E4%BD%93%E3%81%8C%E5%9F%8B%E3%81%BE%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B">「櫻子さんの足下には死体が埋まっている」シリーズ</a> では主人公の館脇少年がハシブトガラスとハシボソガラスについて言及するシーンが(たしか何度か)あり、彼が言っていたのはこの事かという発見がありました。</p>
<p>また、展示されている動物のほか、飼育員による動物の生態などを解説した掲示物も面白く、「今、動物園でシマフクロウを飼育する意義とは」という掲示は特に面白かったです。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/owl.jpg"><img alt="旭山動物園 「今動物園でシマフクロウを飼育する意義とは」" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/owl.jpg" style="width: 100%;" /></a>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/seal.gif"><img alt="旭山動物園 あざらし" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/seal.gif" style="width: 100%;" /></a>
</div>
<div class="section" id="section-22">
<h4>平和通買物公園</h4>
<p>旭山動物園から旭川駅に戻ってきたものの乗りたい特急の発車まで90分ほどあったので、まずは旭川駅に直結している <a class="reference external" href="https://asahikawaekimae-aeonmall.com/">イオンモール旭川駅前</a> を巡って発車までの時間を過ごすことにしました。</p>
<p>イオンモール内にある未来屋書店に入ったところ、先述の太田紫織さんによる <a class="reference external" href="https://www.amazon.co.jp/dp/4041071003/">「昨日の僕が僕を殺す」</a> を見つけたので購入してみました。これに加えて文庫本一冊では旅行中に読み切ってしまうかもと思ったので、先日映画館で観た <a class="reference external" href="http://penguin-highway.com/">「ペンギン・ハイウェイ」</a> の原作小説である森見登美彦さんの <a class="reference external" href="https://www.amazon.co.jp/dp/4041005612/">同名小説</a> も購入しました。</p>
<p>イオンモールを巡り終わってもまだ時間があったので、平和通買物公園もふらっと通ってみました。きょろきょろしながら歩いていたところ外国人観光客に英語でイオンモールまでの道のりを訊かれ、その道を真っ直ぐ行くだけだったものの、「 Google Maps 上で目的地を指さして」と頼まれて画面を覗き込んだらアラビア文字で面食らうという出来事もありました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">道案内を求められて、「その場所を地図の上で指してくれない?」って見せられた Google Map がアラビア文字だったことに面食らった。北海道みたいに道が碁盤の目になっていなければ分からないところだった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090229063233331200?ref_src=twsrc%5Etfw">January 29, 2019</a></blockquote><p>ここでもバックパックを駅のコインロッカーに預け、手には本屋さんの袋だけを下げているという格好だったので、地元の人に見えて道をききやすかったのか、それともいかにも観光客風だから英語が通じそうということで声をかけられたのか、という疑問が生じました。わたしの前にも何人か通行人がいたものの、その人達は素通りしてわたしをターゲットにしていました。</p>
</div>
</div>
<div class="section" id="section-23">
<h3>5日目</h3>
<div class="section" id="section-24">
<h4>小樽</h4>
<p>前日のうちに旭川駅から3時間弱かけて小樽駅まで移動しました。移動中に旭川で買った太田紫織さんの「昨日の僕が僕を殺す」を読むゆったりとした時間を過ごしました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">きのうの夜は旭川で購入した、小樽が舞台の太田詩織さんの本を小樽に向かう電車と小樽のホテルで読むという贅沢な夜だった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090430474659328001?ref_src=twsrc%5Etfw">January 30, 2019</a></blockquote><p>このような感じで5日目の朝は小樽で迎えました。小樽での行動予定は決めていなかったので、小樽三角市場や小樽運河から南小樽駅周辺までを徒歩で3時間ほど散策しました。</p>
<p>小樽は体感温度がこの5日間の中でもっとも高く、旭川での格好のまま歩いていると汗ばむほどでした。また実際の気温も高く、歩道上の氷が緩んでいたため、とてもよく滑りました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtV015GB9vj/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtV015GB9vj/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtV015GB9vj/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:34:46+00:00">Feb 1, 2019 at 5:34am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">小樽運河で見かけた押せない押しボタン式信号 <a href="https://t.co/zmH35wMBoA">pic.twitter.com/zmH35wMBoA</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1091334140560007168?ref_src=twsrc%5Etfw">February 1, 2019</a></blockquote></div>
<div class="section" id="section-25">
<h4>札幌</h4>
<p>小樽観光を終え、予定ではそのまま新千歳空港に戻る予定でしたが、乗り換えの札幌駅で途中下車して札幌の街も1時間ほど散策しました。札幌はこれまでの北海道旅行でも毎回訪れている街ですが、冬に訪れることは初めてで、さっぽろ雪まつりの準備が進む大通り公園や、北海道庁の旧本庁舎である赤れんが庁舎などを巡りました。</p>
<p>札幌でも声をかけられて立ち止まったところ、今回は日本語による宗教勧誘だったので丁寧にお断りしてその場を去りました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BtV1XcBB4yA/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BtV1XcBB4yA/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BtV1XcBB4yA/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2019-02-01T13:39:21+00:00">Feb 1, 2019 at 5:39am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script></div>
<div class="section" id="section-26">
<h4>新千歳空港</h4>
<p>札幌観光を終え新千歳空港に戻りました。北海道旅行を決めてから見つけたこちらの Togetter 記事を参考に、2時間弱を新千歳空港で過ごしました。</p>
<blockquote>
<a class="reference external" href="https://togetter.com/li/1310367">北海道・新千歳空港のお土産売り場は物産展の10倍くらいの規模なのでリサーチ必須→道民からのおすすめ情報「制限エリア内まで、道内地域限定飲食店が進出」</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">この旅の初海鮮 (@ 新千歳空港 五十七番寿し in 千歳市, 北海道) <a href="https://t.co/9yLNijbEHF">https://t.co/9yLNijbEHF</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090519995648540672?ref_src=twsrc%5Etfw">January 30, 2019</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Royce' のポテトチップチョコレートという脂質と糖質が合体した悪魔のような食べ物を食べており、半端ではない罪悪感と背徳感を味わっている <a href="https://t.co/jGgO0Ha19d">https://t.co/jGgO0Ha19d</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1091282486435315712?ref_src=twsrc%5Etfw">February 1, 2019</a></blockquote></div>
<div class="section" id="section-27">
<h4>東京</h4>
<p>新千歳空港から羽田空港に戻る飛行機の中では旭川で購入した「ペンギン・ハイウェイ」を読んで過ごしました。復路は ANA とのコードシェア便である AIRDO 便で、機内でドリンクサービスを受けられた他、 <a class="reference external" href="http://www.scu.ac.jp/news/pressrelease/40984/">AIRDO 就航20周年を記念して札幌市立大学のデザイン学部生がデザインしたステッカー</a> が希望者に配布されていたので、アテンダントさんにお願いしてステッカーをいただきました。</p>
<p>普段は在宅勤務をしている中せっかく外に出たのだからということで、羽田空港に着いたその足でオフィスにお土産を渡しに行きました。ちょうどオフィスに居た <a class="reference external" href="https://twitter.com/isidai">@isidai</a> さんからの第一声「すごい、完全防備ですね」や、 <a class="reference external" href="https://twitter.com/nasu_ch">@nasu_ch</a> ちゃんから「すごく暖かそうですね」という声を掛けられました。</p>
<a class="reference external image-reference" href="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/gift.jpg"><img alt="勤務先へのお土産" src="https://blogmedia.yosida95.com/2019/01/31/hokkaido-trip/gift.jpg" style="width: 100%;" /></a>
</div>
</div>
</div>
<div class="section" id="section-28">
<h2>学び</h2>
<div class="section" id="section-29">
<h3>服装</h3>
<p>ダウンジャケットのほか、ヒートテックのウルトラウォーム <strong>超極暖</strong> のTシャツとタイツ、そしてフードが邪魔にならないようにパーカーではなくフリースジャケットを購入した他、手持ちのコットンの厚手のニットセーターとニット帽も持っていきました。</p>
<ul class="simple">
<li><a class="reference external" href="https://www.uniqlo.com/jp/store/goods/409325/">ウルトラライトダウンシームレスパーカ</a></li>
<li><a class="reference external" href="https://www.uniqlo.com/jp/store/goods/408993/">フリースフルジップジャケット</a></li>
<li><a class="reference external" href="https://www.uniqlo.com/jp/store/goods/408120/">ヒートテックウルトラウォームクルーネックT</a></li>
<li><a class="reference external" href="https://www.uniqlo.com/jp/store/goods/400231/">ヒートテックウルトラウォームタイツ</a></li>
</ul>
<p>防寒はこれで十分で -22 °C の阿寒湖や海上で風もある流氷観光砕氷船おーろら乗船中も動いている限りは寒くありませんでしたし、 -1 °C 程度だった小樽ではむしろ暑いくらいでした。初日の帯広で念のためにカイロを購入しましたが結局使わずに東京に持って帰ってきました。</p>
<p>また、着替えはコインランドリーがあるホテルを利用することで、バックパックに入れた2日分と初日に着用していた分の計3日分で十分間に合いました。</p>
<p>他には雪に備えてスノーブーツを買いましたが、履きなれていないブーツに靴擦れの兆候があったので家を出てから引き返して普段のスニーカーに履き替えました。5日間を通して滑ることには滑りましたがバランスを取れば転ぶことはありませんでした。ただ、これから雪上を歩くときは安全と防寒のためもっと早くから準備してブーツに慣れておこうと思います。</p>
</div>
<div class="section" id="section-30">
<h3>持ち物</h3>
<p>前回の旅行ではメガネを持っていくことを忘れて入浴時や就寝時に困ったので、今回は付箋紙に「メガネ」と書いて玄関ドアに貼っておいたら忘れませんでした。</p>
<p>心配な点として今回は飛行機を利用したので持ち込み制限のことがありましたが、国内線ならスプレーや刃物でない限り割となんでも持ち込めるということが判りました。</p>
<p>カバンはキャリーケースかバックパックかで迷いましたが、今回の旅行は雪中を移動するためにホイールが役に立たなくなるだろうことが予想できたこと、移動が大きな割合を占めることから両手を塞がないようにしたかったことからバックパックを選択しました。また、普段なら大きな荷物を持ち歩かなくて済むように財布などの携帯品はカバンを分けますが、今回は毎日滞在する場所が変わることからすべての荷物をバックパックに詰めました。</p>
<p>しかしこれは杞憂で、駅にはコインロッカーという大変便利な物が存在するため、コインロッカーに預けてしまうことを考えれば小さなカバンもあったほうが便利でした。今回はダウンジャケットのポケットに財布と飲み物、スマートフォンだけを入れて観光することになりました。また、コインロッカーを利用するために100円玉を大量に用意するとよいことも判りました。</p>
</div>
<div class="section" id="section-31">
<h3>飛行機</h3>
<p>往路はひがし北海道フリーパスの購入条件からピーチかバニラエアと決まっていたので、あとはわたしが起きられそうな時間帯を考慮に入れて予約しました。バニラエアは羽田空港ではなく成田空港をハブ空港としているので空港を間違えないことが最大の課題でしたが、日暮里に向かう山手線の中で指定席券を購入した京成スカイライナーが JR からの専用改札口がある上に空港ターミナルにも直結していて便利でした。</p>
<p>復路は往路の初めての LCC にがっかり、或いはうんざりしている可能性を考慮して AIRDO 便を予約しました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">行きは成田発のバニラエアで帰りは羽田着の AIRDO ( ANA コードシェア便) で、初めてのバニラエアは短時間ならこれで十分だと思って今もそれは変わらないんだけれど、しかし AIRDO に乗って「ああ、これこれ」という感想に落ち着いてしまった。そもそもお得な切符が目当てでバニラエアにしたからな……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1090575917443764225?ref_src=twsrc%5Etfw">January 30, 2019</a></blockquote></div>
<div class="section" id="section-32">
<h3>ホテル</h3>
<p>ホテルは4日分すべて予約しましたが振り返ってみればこれは失敗で、今回の旅行のように毎日 200-300km を移動するような旅行では道中に何があるか分からず、またせっかく乗り降り自由のフリーパスで旅行をしているので、より行き当たりばったりに気になったところを巡りつつ、その日にたどり着いた地で宿泊するくらいの感じのほうが気忙しくなくてよかったかなと思いました。</p>
<p>特に冬の北海道は大雪のために頻繁に電車が遅延したり運休になったり、そもそも日に数本しか目的地にたどり着ける電車が運行されていなかったりするため、幸い今回の旅行では予定通り行動することができましたが、少しのミスで連鎖的に後の行程に響く恐れもありました。</p>
</div>
</div>
<div class="section" id="section-33">
<h2>おわりに</h2>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">5日間北海道旅行をした成果です <a href="https://t.co/uMywLB7Xns">pic.twitter.com/uMywLB7Xns</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1093795309405138944?ref_src=twsrc%5Etfw">February 8, 2019</a></blockquote><p>さーて、次はどこに行こうかな。</p>
</div>
yosida95 の2018年まとめ2018-12-31T00:00:00+09:002018-12-31T00:00:00+09:00yosida95tag:yosida95.com,2018-12-31:/2018/12/31/year-in-review.html<!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、2019年に厄年を迎えるらしい …</p></div><!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、2019年に厄年を迎えるらしい yosida95 です。
ことしもまとめてゆきます。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-1" id="toc-entry-1">はじめに</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-2">ことし始めたこと</a><ul>
<li><a class="reference internal" href="#section-3" id="toc-entry-3">自動車の運転</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-4">筋力トレーニング</a></li>
<li><a class="reference internal" href="#section-5" id="toc-entry-5">ボイストレーニング</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-6" id="toc-entry-6">ことし買ってよかったもの</a><ul>
<li><a class="reference internal" href="#section-7" id="toc-entry-7">電子ピアノ</a></li>
<li><a class="reference internal" href="#section-8" id="toc-entry-8">パネルヒーター</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-9" id="toc-entry-9">ことし観た映画</a><ul>
<li><a class="reference internal" href="#section-10" id="toc-entry-10">「恋は雨上がりのように」</a></li>
<li><a class="reference internal" href="#section-11" id="toc-entry-11">「未来のミライ」</a></li>
<li><a class="reference internal" href="#search-1" id="toc-entry-12">「 search 」</a></li>
<li><a class="reference internal" href="#section-12" id="toc-entry-13">「スマホを落としただけなのに」</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-13" id="toc-entry-14">ことし観てよかったテレビアニメ</a><ul>
<li><a class="reference internal" href="#section-14" id="toc-entry-15">「宇宙よりも遠い場所」</a></li>
<li><a class="reference internal" href="#section-15" id="toc-entry-16">「月がきれい」</a></li>
<li><a class="reference internal" href="#section-16" id="toc-entry-17">「まおゆう魔王勇者」</a></li>
<li><a class="reference internal" href="#section-17" id="toc-entry-18">「舟を編む」</a></li>
<li><a class="reference internal" href="#section-18" id="toc-entry-19">「魔法科高校の劣等生」</a></li>
<li><a class="reference internal" href="#gosick-1" id="toc-entry-20">「 GOSICK 」</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-19" id="toc-entry-21">ことし寄付した先</a><ul>
<li><a class="reference internal" href="#arch-linux" id="toc-entry-22">Arch Linux</a></li>
<li><a class="reference internal" href="#wikipedia-wikimedia-foundation" id="toc-entry-23">Wikipedia (Wikimedia Foundation)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-20" id="toc-entry-24">おわりに</a></li>
<li><a class="reference internal" href="#section-21" id="toc-entry-25">これまでのまとめ</a></li>
</ul>
</div>
</div>
<div class="section" id="section-2">
<h2>ことし始めたこと</h2>
<p>ことし始めた主なことは以下の3つです。</p>
<ul class="simple">
<li>自動車の運転</li>
<li>筋力トレーニング</li>
<li>ボイストレーニング</li>
</ul>
<p>このうち、筋力トレーニングとボイストレーニングについては10月のブログエントリ「 <a class="reference external" href="https://yosida95.com/2018/10/05/greetings.html">ご報告</a> 」でも触れました。</p>
<div class="section" id="section-3">
<h3>自動車の運転</h3>
<p>もともと「自動車が空を飛ぶようになるまで車は運転しない」という信念を持っていました。
しかし、友人が運転する車にのせてもらったり、また「平成生まれが自分でハンドルを握ることが許される最後の人類になるのでは」と予感するにつれ、自分でも自動車を運転したくなってしまいました。</p>
<p>そこで去年(2017年)の11月に自動車教習所に入校して、仕事の合間に授業を受けたり実習を受けたりして、ことしの4月に卒業しました。
<a class="reference external" href="https://news.mynavi.jp/kikaku/gehirn-2/">フレックスタイム勤務が便利</a> でした。</p>
<p>せっかくなら免許証の趣味性を高めてやろうと思い、「小型特殊」「原動機付自転車」「普通自動車」を連日(祝日を除く試験実施日)受験して、フルビットを狙える取り方をしました。
初めて交付される運転免許証はグリーン免許証ですが、わたしのように続けて異種免許を取得すると3年後の更新を待たずにブルー免許証が交付されます。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">初心運転者になりました (@ 江東運転免許試験場 in 江東区, 東京都) <a href="https://t.co/Ihxqm0GioU">https://t.co/Ihxqm0GioU</a> <a href="https://t.co/tIx0l9j04m">pic.twitter.com/tIx0l9j04m</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/993375936572723200?ref_src=twsrc%5Etfw">May 7, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">初心運転者だけど免許が緑色だった期間が24時間しか無い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/993376939384586241?ref_src=twsrc%5Etfw">May 7, 2018</a></blockquote><p>もし運転免許証の取得に失敗したら転職して完全自動運転自動車を開発するぞと決意していましたが、無事に自動車教習所を卒業して運転免許を取得することができました。</p>
<p>普通自動車の運転免許を取得した当日に加入したカーシェアリングサービスを活用して、長年トラックの運転手をしている父を助手席に乗せて教習では経験しない高速道路や山道での運転を練習したり、郊外型ショッピングモールに自分の運転で行ったり、旅行先で自分の運転で気ままに観光地を巡ったりしています。
カーシェアリングサービスの記録によれば、運転免許を取得してからのおよそ半年で 2,951km 運転したようです。</p>
</div>
<div class="section" id="section-4">
<h3>筋力トレーニング</h3>
<p>7月4日にジムに入会しました。
目的は「筋力トレーニングを通して自覚的な『努力』を継続する力をつける」ことです。</p>
<p>入会初日の身体測定結果を基準にトレーナーと相談の上、体脂肪率を維持したまま筋肉量を 7.9kg 増やすことを目標に、現在に至るまで週に2、3日のペースでトレーニングを継続できています。
基本的にはひとりで黙々とトレーニングをしつつ、2週に1度程度パーソナルトレーナーについてもらってフォームの確認や新種目の導入をしています。</p>
<p>現在は主に以下の種目に取り組んでいます。</p>
<ul class="simple">
<li>ベンチプレス</li>
<li>チェストプレス</li>
<li>ケーブルクロスオーバー</li>
<li>チンニング</li>
<li>ラットプルダウン</li>
<li>シットアップ</li>
<li>クランチ</li>
<li>レッグレイズ</li>
<li>バーベルスクワット</li>
<li>レッグプレス</li>
<li>レッグカール</li>
<li>レッグエクステンション</li>
</ul>
<p>12月27日にトレーニング納めをしたところベンチプレスとバーベルスクワットでこれまでで最高の重量を持つことができ、自分の体重を超える負荷をかけられるようになったので成長を感じています。
実感としても特に大胸筋、上腕二頭筋および上腕三頭筋がはっきりと発達してきています。</p>
<p>ただ、筋肉を発達させるために食事量や食事内容をリッチにした影響で体脂肪も筋肉と同程度に増えてきてしまっているため、来年は有酸素運動の時間と強度を高めて増えてしまった体脂肪を落とすことにも取り組んでいきたいです。</p>
</div>
<div class="section" id="section-5">
<h3>ボイストレーニング</h3>
<p>ジムに入会した翌週の7月12日にはボイストレーニングを行っているカルチャースクールに入所しました。
ボイストレーニングといってもボーカルトレーニングではなく、よりよい声のだし方や日本語の正しい発音方法、声の抑揚や高低による表現方法を学ぶものです。</p>
<p>入所の目的は、無機質な喋り方を脱して感情に富んだ表現方法学ぶことで、自分の感情をできるだけ豊かに会話相手に伝えられるようになる足がかりにしようというものです。
また副次的な目的として、もともと喉が弱く長めに話すと喉を痛めることが多く、また自分の声質に若干のコンプレックスがあったので、それらを改善できるのではないかという期待もありました。</p>
<p>入所してからおよそ半年になる現在は、基礎的なテクニックの習得が終わり、ナレーション原稿を読むなどして長文の中の適所で習得したテクニックを活用する訓練をしているところです。</p>
<p>講師の指摘により、もともと響きが豊かで通りやすいよい声質を持っているのに、どういうわけかその声の帯域を使わずにわざわざ無理をして通りづらい声で話していたということが判明しました。
この指摘により現在では無理のない発声で通りやすい声を出せるようになり、このことだけでも入所した価値がありました。</p>
<p>講師陣は Wikipedia にも項目があるような実績のあるプロの声優さんで、そのような講師陣から指導を受け、また元の声質にもよい評価を受けたことで、これまでに比べ自分の声に自信を持てるようになりました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">きょうはプロの声優さんに「キミは生まれつきよい声質を持っているのに、それを活かさずにわざわざ通りづらい声で話しているけれど、なんで?」と訊かれ、それはわたしが知りたいわ、23年生きてきて初めて知ったわとなった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1042391479946076161?ref_src=twsrc%5Etfw">September 19, 2018</a></blockquote><p>これからのこととしてより実践的な表現の手段として演劇に興味がわいており、趣味の範囲で所属できる社会人劇団を探したりもしていますが、いかんせん全くの未経験で観劇の習慣も無く何から手を付けてよいのかも分からいので、とりあえず来年からは観劇に取り組もうと考えています。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>ことし買ってよかったもの</h2>
<p>ことし買ってよかったものは次の2点です。</p>
<ul class="simple">
<li>電子ピアノ</li>
<li>パネルヒーター</li>
</ul>
<div class="section" id="section-7">
<h3>電子ピアノ</h3>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BnFr5NPn6aV/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BnFr5NPn6aV/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BnFr5NPn6aV/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-08-30T04:00:22+00:00">Aug 29, 2018 at 9:00pm PDT</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>わたしが4歳だったころに保育園の先生に憧れて習い始めたピアノでしたが、それから20年弱が経過した現在でも趣味として継続しています。
しかし4年前にひとり暮らしを始めて以来の家にピアノがない生活により「いつかは買うぞ」という思いが募って臨界点を突破したので、ついに決心して <a class="reference external" href="https://jp.yamaha.com/products/musical_instruments/pianos/clavinova/clp-675/index.html">YAMAHA の CLP-675</a> を購入しました。</p>
<p>楽器屋さんで店員さんの説明を受けながらいろいろな機種を弾き比べてみましたが、実家で弾いていた YAMAHA のアップライトピアノ UX3 にタッチや音色が似ていて違和感がなかったこと、同じシリーズの下位機種と比較してこのグレードから有意に音質が向上することからこの機種を選択しました。
ただ、純正の高さ可変椅子の最低設定が高く弾きづらかったため、いまは粗末なパイプ椅子を使っています。</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Rypz1aKDyqc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<iframe width="560" height="315" src="https://www.youtube.com/embed/hWrROBJVszM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
<div class="section" id="section-8">
<h3>パネルヒーター</h3>
<p>冷え性です。特に足元が冷えます。</p>
<p>自宅でパソコンに向かって仕事をする時に足元が冷えて集中力が続きません。
去年はひとり用のホットカーペットを導入してみましたがあまり暖まらず、そもそも脚を組むとまったく恩恵にあずかれず失敗しました。</p>
<p>そこでことしはパネルヒーターを導入してみました。
仕組みはホットカーペットと変わりませんが、三つ折りにして自立させて使用する構造になっており、これで足元を囲むように設置することで立体的に暖めることができます。</p>
<p>購入したのはアイリスオーヤマの <a class="reference external" href="https://www.irisohyama.co.jp/seasonal/desk_heater/ph-tsa.html">PH-TSA デスクパネルヒーター</a> です。</p>
<a class="reference external image-reference" href="https://www.irisohyama.co.jp/seasonal/desk_heater/ph-tsa.html"><img alt="アイリスオーヤマ PH-TSA デスクパネルヒーター" src="https://blogmedia.yosida95.com/2018/12/31/year-in-review/panel-heater.png" /></a>
<p>ただ、パネルヒーターを設置しても足をフローリングに置いているとそこから熱を奪われてしまうので、パネルヒーターの手前にタイルカーペットを敷きました。
購入した製品は無印良品の <a class="reference external" href="https://www.muji.net/store/cmdty/detail/4547315830602">ポリエステルクリンプタイルカーペット</a> です。</p>
<p>このタイルカーペットはゴムの下地が厚めで断熱と滑り止めに優れ、毛足が長いので暖かくまだ裸足でも気持ちがよいです。</p>
</div>
</div>
<div class="section" id="section-9">
<h2>ことし観た映画</h2>
<ul class="simple">
<li><a class="reference external" href="http://koiame-movie.com/">「恋は雨上がりのように」</a></li>
<li><a class="reference external" href="http://asagao-anime.com/">「あさがおと加瀬さん。」</a></li>
<li><a class="reference external" href="http://mirai-no-mirai.jp/">「未来のミライ」</a></li>
<li><a class="reference external" href="http://kametome.net/index.html">「カメラを止めるな!」</a></li>
<li><a class="reference external" href="http://penguin-highway.com/">「ペンギン・ハイウェイ」</a></li>
<li><a class="reference external" href="http://www.search-movie.jp/">「 search 」</a></li>
<li><a class="reference external" href="http://www.sumaho-otoshita.jp/index.html">「スマホを落としただけなのに」</a></li>
</ul>
<div class="section" id="section-10">
<h3>「恋は雨上がりのように」</h3>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">「恋は雨上がりのように」ストーリ展開がよくて面白かった。店長が大人としてかっこいい。原作は前に1巻だけ買って得意な感じじゃなかったからそのままにしていたけれど映画は楽しめた。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1003981870344749057?ref_src=twsrc%5Etfw">June 5, 2018</a></blockquote></div>
<div class="section" id="section-11">
<h3>「未来のミライ」</h3>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">きょう「未来のミライ」を観てきて、キャラデザいいなとか福山雅治がかっこいいとかはあるんだけれど、ストーリーとしては家を建て替えて仕事で独立して第二子を授かってと世間の評価として幸せな家族像の中で、それに価値を感じて幸せを実感しているのは親だけだ……ということに気づくと辛くなった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1020693682633109504?ref_src=twsrc%5Etfw">July 21, 2018</a></blockquote></div>
<div class="section" id="search-1">
<h3>「 search 」</h3>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">一方で「 search 」は、主人公(パパ)の人物像が本当に身近で、時代考証や展開も無理が無いこと、それでいて全編 PC の画面や記録映像など媒体を介したものであるという挑戦がちゃんと成立していることなどとてもよかったので、まだご覧になっていなければおすすめです。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1064809689358065664?ref_src=twsrc%5Etfw">November 20, 2018</a></blockquote></div>
<div class="section" id="section-12">
<h3>「スマホを落としただけなのに」</h3>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">「 search 」を先に観ずに順番が逆だったらもう少しは楽しめたかなぁ……。いかにも「日本のドラマ」的だった。全てが心情と人間ドラマに収束していくような。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1064535579885371393?ref_src=twsrc%5Etfw">November 19, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">そうですね、展開というか整った仕組み的に最有力だった人にちゃんと収まったのは後味スッキリでした。犯人像は「日本のテレビドラマに出てくる変質者」そのものだったというか、多分物語を成立させるために用意しただけの部分を脚本で掘り下げて却って薄くなってしまった感じでしたがw</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1064809585851027457?ref_src=twsrc%5Etfw">November 20, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">あさみんの恋人が入れたアプリや若手刑事の聞き込み中の行動など、ここにつなげたいんだろうなみたいな伏線がしっかり作中で言及されていることもよかったです。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1064809648287506439?ref_src=twsrc%5Etfw">November 20, 2018</a></blockquote></div>
</div>
<div class="section" id="section-13">
<h2>ことし観てよかったテレビアニメ</h2>
<p>ことし視聴したアニメで、ことし放映されたアニメ以外も含みます。</p>
<ul class="simple">
<li><a class="reference external" href="http://yorimoi.com/">「宇宙よりも遠い場所」</a></li>
<li><a class="reference external" href="https://tsukigakirei.jp/">「月がきれい」</a></li>
<li><a class="reference external" href="http://maoyu.jp/">「まおゆう魔王勇者」</a></li>
<li><a class="reference external" href="http://www.funewoamu.com/">「舟を編む」</a></li>
<li><a class="reference external" href="https://mahouka.jp/tv/">「魔法科高校の劣等生」</a></li>
<li><a class="reference external" href="https://www.tv-tokyo.co.jp/anime/gosick/">「 GOSICK 」</a></li>
</ul>
<div class="section" id="section-14">
<h3>「宇宙よりも遠い場所」</h3>
<p>南極に行くという夢を周囲に無理だと嘲笑されながらも信じて取り組み続け、そのひたむきな姿に共鳴して集った仲間とともに南極に到達するという、女子高生4人の青春の物語です。
作品の評価も高くたくさんの論評もありますが、何を差し置いてもとにかく第1話24分を観れば続きを観ずにはいられなくなります。</p>
<p>フォーマットは「女の子だけが出てくるアニメ」ではありますが、決して教室や部室で無為な時間を過ごすような話では(そのような日常系も好きですが)ありません。</p>
<blockquote>
<p>三宅日向「ふたりだけはなんか別だなぁって。なんか空気が違うっていうか。」「嘘ついてない感じ」</p>
<p class="attribution">—第2話</p>
</blockquote>
<blockquote>
<p>白石結月「だってみなさん親友同士じゃないですか」</p>
<p>三宅日向「親友?」</p>
<p>白石結月「違うんですか?」</p>
<p>三宅日向「わたしたち出会って1ヶ月も経ってないぞ」</p>
<p>小淵沢報瀬「一緒に遊びに行ったこともないし」</p>
<p>玉木マリ「ただ同じところに向かおうとしているだけ。今のところは」</p>
<p class="attribution">—第3話</p>
</blockquote>
<p>小淵沢報瀬ちゃんを筆頭に登場人物は性格に一癖も二癖もあり、だからこそ登場人物が現実味を帯び、心理描写が鮮やかになって物語の深みを増しています。</p>
<p>ことし観てもっともよかったアニメです。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">小淵沢報瀬ちゃんに会いにきた (@ 南極観測船ふじ in Nagoya-shi, 愛知県) <a href="https://t.co/aZ6GVs0sJ7">https://t.co/aZ6GVs0sJ7</a> <a href="https://t.co/POGc8Vfiwb">pic.twitter.com/POGc8Vfiwb</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077111023239348224?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote></div>
<div class="section" id="section-15">
<h3>「月がきれい」</h3>
<p>高校生男女の初々しいけれども真剣な恋愛を瑞々しく描いた作品です。</p>
<p>心がだめになっていた時期に観てさらに心を抉られました。
観る時期が違っていれば評価も変わったかもしれません。</p>
<p>作中で園田涼子のキャラクターボイスを担当した東山奈央さんが主題歌と往年の名曲をカバーした挿入歌を担当していて、その素朴な歌い方が作品の雰囲気ともマッチして味わい深くなっています。</p>
</div>
<div class="section" id="section-16">
<h3>「まおゆう魔王勇者」</h3>
<p>魔王とそれを討伐することを目指す勇者がいるというファンタージ作品でよくある世界設定ながら、魔王(女性)が勇者(男性)に「わたしのものになれ」と持ちかけ、相互所有契約を結ぶところから始まる物語です。</p>
<p>魔王軍と人間が争う戦乱の世の中で魔王は人類の21世紀初頭レベルに該当する経済や農業を始めとする高度な知識を有しており、それを人間に伝授していくことで戦争特需や中央政府に頼らずとも豊かな生活ができるよう経済を発展させていくという切り口が面白かったです。</p>
</div>
<div class="section" id="section-17">
<h3>「舟を編む」</h3>
<p>辞書の編纂に人生をかける冴えない出版社員たちの物語です。</p>
<p>ゆったりとした作中時間の流れながら、物語性には乏しくて取るに足らないような人々の人生がリアリティを持って描かれ重厚な余韻がありました。
このような「お仕事系」のアニメも好きで、ライトな作品では <a class="reference external" href="http://shirobako-anime.com/">「 SHIROBAKO 」</a> や <a class="reference external" href="http://www.hanasakuiroha.jp/tv/">「花咲くいろは」</a> もよい作品でした。</p>
</div>
<div class="section" id="section-18">
<h3>「魔法科高校の劣等生」</h3>
<p>魔法を学ぶ国立大学附属高校が舞台の作品で、魔法がテーマの作品ながらファンタジーではなく、魔法が科学技術として体系的に整理され研究されている SF 世界の物語です。</p>
</div>
<div class="section" id="gosick-1">
<h3>「 GOSICK 」</h3>
<p>ミステリー・推理ものの作品ではありますが、そこを楽しみたいのであれば他の本格的な作品を観たほうがよいと思います。</p>
<p>見どころは序盤は露悪的で人を遠ざけるような言動を取っていた探偵役のヴィクトリカと、彼女に振り回されながらも根気よく付き合っていた久城一弥が次第に惹かれあっていき、第二次世界大戦の戦乱によってふたりが引き裂かれてもお互いを求めて足掻いていくストーリーです。
そして悠木碧さんの声が素敵です。</p>
</div>
</div>
<div class="section" id="section-19">
<h2>ことし寄付した先</h2>
<p>ことし寄付した先は以下の2つです。</p>
<ul class="simple">
<li>Arch Linux</li>
<li>Wikipedia (Wikimedia Foundation)</li>
</ul>
<div class="section" id="arch-linux">
<h3>Arch Linux</h3>
<p><a class="reference external" href="https://wiki.archlinux.org/">Arch Linux</a> を Linux ディストリビューションとして使っていた期間はごく短いですが、 Linux 全般のトラブルシューティングについて <a class="reference external" href="https://wiki.archlinux.org/">ArchWiki</a> には数え切れないほど助けられているので、この度 Arch Linux に寄付することにしました。
金額は $10 USD * 12 months として $120 USD です。</p>
<p>寄付してからしばらくして Arch Linux の <a class="reference external" href="https://www.archlinux.org/donate/">donors</a> に名前を載せてもらえました。</p>
</div>
<div class="section" id="wikipedia-wikimedia-foundation">
<h3>Wikipedia (Wikimedia Foundation)</h3>
<p>これまでも <a class="reference external" href="https://ja.wikipedia.org/">Wikipedia</a> には2014年から毎年数千円程度の寄付を行ってきましたが、ことしの7月からは毎月 ¥ 500円ずつ寄付する継続寄付するようにしました。
ことしの寄付額の合計は ¥ 3,000円です。</p>
<p>来年も引き続き寄付を行っていく予定です。</p>
</div>
</div>
<div class="section" id="section-20">
<h2>おわりに</h2>
<p>平成最後のまとめなのでことしはリッチに「ことし始めたこと」「ことし買ってよかったもの」「ことし観た映画」「ことし観てよかったテレビアニメ」「ことし寄付した先」をまとめてみました。</p>
<p>なお、平成最後の大晦日は以下のような感じで始まりました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">2018年最後の日にトイレが詰まりラバーカップ片手に格闘するという締まらない大晦日を迎えている</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1079414467350261760?ref_src=twsrc%5Etfw">December 30, 2018</a></blockquote><p>ことしお世話になった皆さまにこの場を借りてお礼申し上げます。
2019年も引き続きよろしくお願い申し上げます。</p>
<p>よいお年をお迎えください。</p>
</div>
<div class="section" id="section-21">
<h2>これまでのまとめ</h2>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2017/12/31/greetings.html">yosida95 の 2017 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
</ul>
</div>
名古屋で初めてのひとり旅をした2018-12-25T00:00:00+09:002018-12-25T00:00:00+09:00yosida95tag:yosida95.com,2018-12-25:/2018/12/25/trip-to-nagoya.html<!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<p>12月24日から25日にかけて1泊2日で人生初めてのひとり旅をしました。</p>
<div class="section" id="section-2">
<h2>きっかけ</h2>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">これまでの …</p></blockquote></div><!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
<http://www.w3.org/2003/entities/xml/>.
Processed by unicode2rstsubs.py, part of Docutils:
<https://docutils.sourceforge.io>. -->
<p>12月24日から25日にかけて1泊2日で人生初めてのひとり旅をしました。</p>
<div class="section" id="section-2">
<h2>きっかけ</h2>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">これまでの人生で自主的な旅行を一度もしたことがなく、それなのに「とにかく旅行するぞ!!!」という気持ちだけが溢れて自分がどこへ行きたいかも判然としないので、一生分くらいキュレーションメディアを見て学んでいる</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/959809547547197441?ref_src=twsrc%5Etfw">February 3, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">主体的な旅行についてここしばらく検討していたんだけれど、踏んだ場数が少なすぎて自分がなにを好むのか自分の事がよく分からん……となってしまった。テーマに沿って調べてまとめて計画することは人より得意なので、テーマを自主設定できるようになるまでダーツを投げて決めるみたいなのがよさそう。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/965540988105113600?ref_src=twsrc%5Etfw">February 19, 2018</a></blockquote><p>このようにことしの初めごろから旅行をするぞという機運が醸成されていた中、12月8日に乗った総武線車内で <a class="reference external" href="https://www.aichi-now.jp/dc/">愛知ディスティネーションキャンペーン</a> の宣伝広告を見かけ、調べるに付けて関心が増し2日後の12月10日に旅行代理店のサイトから申し込みを行いました。</p>
<p>ホテルと新幹線、そして2日間有効で愛知県内の鉄道・バスが乗り放題になる「愛知 DC フリーきっぷ」がセットで ¥ 27,800円でした。</p>
<a class="reference external image-reference" href="https://www.aichi-now.jp/dc/"><img alt="愛知ディスティネーションキャンペーン" src="https://blogmedia.yosida95.com/2018/12/25/trip-to-nagoya/aichi-dc.gif" /></a>
</div>
<div class="section" id="section-3">
<h2>初日</h2>
<p>朝が弱いので11時23分東京駅発13時4分名古屋着ののぞみ333号で名古屋に向かいました。
到着してすぐに、新幹線地下街エスカから出発できるよう予約しておいたカーシェアリングサービスの車を借りて名古屋周辺の観光地を巡りました。</p>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="en"><p lang="ja" dir="ltr">I'm at 名古屋城 - <a href="https://twitter.com/CityNagoyajo?ref_src=twsrc%5Etfw">@citynagoyajo</a> in 名古屋市, 愛知県 <a href="https://t.co/m4Z6zopYcL">https://t.co/m4Z6zopYcL</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077064184016314368?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BrzdHLdhwdT/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BrzdHLdhwdT/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BrzdHLdhwdT/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-12-25T08:41:51+00:00">Dec 25, 2018 at 12:41am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">I'm at 名古屋市科学館 in Nagoya, 愛知県 <a href="https://t.co/EOXClteYtb">https://t.co/EOXClteYtb</a> <a href="https://t.co/hJADN27MpR">pic.twitter.com/hJADN27MpR</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077081358709809152?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">小淵沢報瀬ちゃんに会いにきた (@ 南極観測船ふじ in Nagoya-shi, 愛知県) <a href="https://t.co/aZ6GVs0sJ7">https://t.co/aZ6GVs0sJ7</a> <a href="https://t.co/POGc8Vfiwb">pic.twitter.com/POGc8Vfiwb</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077111023239348224?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote><p>南極観測船ふじが係留されている名古屋港では24日に <a class="reference external" href="https://isogaihanabi.com/">ISOGAI 花火劇場 in 名古屋港</a> が開催されており、花火大会が始まってからでは車で周辺から抜け出すのに3時間かかると駐車場で脅されたので、南極観測船ふじの見学もそこそこに名古屋港を後にしました。</p>
<p>この花火の様子は遠目ながらもホテルの窓から観ることができました。</p>
<div class="section" id="section-4">
<h3>「名古屋走り」</h3>
<p>なお、名古屋周辺地域の運転マナー(の悪さ)はよく <a class="reference external" href="https://ja.wikipedia.org/wiki/%E5%90%8D%E5%8F%A4%E5%B1%8B%E8%B5%B0%E3%82%8A">「名古屋走り」</a> として揶揄され、それを肯定する意見と否定する意見の両方がインターネットで散見されます。
わたしも名古屋で運転をするにあたりどんなものかと期待と不安を同じ程度抱いていましたが、わたしの所感では少なくとも全くのデマということは無いと思いました。</p>
<p>少なくとも普段都内を主に千葉や茨城で運転しているときには見られない危険運転を頻繁に見ました。
特に直進レーンの先頭から発進したところ、左隣の左折専用レーンに居た車が左折せずに直進してきてわたしの前に割り込まれた時は追突するかとヒヤッとしました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">初上陸の名古屋でレンタカー借りて色々まわっているんだけれど、名古屋人(主語がでかい)の運転は本当に怖く、10分程度の運転で右左折専用通行帯への割り込みを3度見た</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077080668956372992?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">「名古屋走り」、わたしが名古屋を2時間強運転した感じでは誇張などの類ではなく、信号無視・車線またぎ・右左折専用通行帯からの直進・ウィンカー無しでの車線変更・信号手前の車線変更禁止場所からの割り込みをそれぞれ複数回みた。あとサンキューハザードを出す人をわたし以外に見なかった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077144870211309568?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote></div>
</div>
<div class="section" id="section-5">
<h2>2日目(最終日)</h2>
<p>2日目は愛知 DC フリーきっぷを活用して、午前9時40分に名古屋駅を出発してからひたすら電車に乗っていました。</p>
<div class="section" id="section-6">
<h3>竹島水族館</h3>
<p>まずは蒲郡駅で降りてタクシーで <a class="reference external" href="http://www.city.gamagori.lg.jp/site/takesui/">竹島水族館</a> に向かいました。
タクシーの運転手さんが気さくな方でいろいろな話をしてくれて楽しかったです。
「この周辺には最近来たばかりで時々やらかすのでナビを使いますね」といって、車載のカーナビではなくスマートフォンの Google Maps を設定した瞬間が最高でした。</p>
<p>竹島水族館は <a class="reference external" href="http://www.itmedia.co.jp/business/articles/1806/08/news041.html">「お金なし、知名度なし、人気生物なし 三重苦の弱小水族館に大行列ができるワケ」</a> を読んでからというものいつかは訪れてみたいと思っていて、これはチャンスと名古屋からは距離が離れますが訪ねてみました。</p>
<p>こぢんまりとした館内で目玉となるような大型魚がいるわけでもありませんでしたが、展示方法や魚の解説が独創的でとても面白かったです。
他の人にもぜひ足を運んでもらいたい水族館です。</p>
<p>タイミングよく前述の記事にも登場する館長さんによるカピバラショーを最初から最後までみることができました。
館長さんの軽快なトークで集まったたくさんの人たちを沸かせていました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/Bry8HE0B4GL/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/Bry8HE0B4GL/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/Bry8HE0B4GL/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-12-25T03:53:28+00:00">Dec 24, 2018 at 7:53pm PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>また、水族館の裏手から橋が架かっていて徒歩で渡れる <a class="reference external" href="https://www.aichi-now.jp/spots/detail/137/">竹島</a> にも上陸してみました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/Bry5glhhL5L/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/Bry5glhhL5L/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/Bry5glhhL5L/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-12-25T03:30:45+00:00">Dec 24, 2018 at 7:30pm PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>駅まではタクシーで戻るつもりでしたが全然タクシーが捕まらなかったので、結局徒歩で15分ほどかけて戻りました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">東京とは違ってタクシーとは流しているものを拾う乗り物ではなく、電話で呼び出す乗り物なんだなということを痛感している</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077408314177216512?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote></div>
<div class="section" id="section-7">
<h3>リニモ</h3>
<p>日本で唯一営業運転を行っている磁気浮上式リニアモーターカーである <a class="reference external" href="http://www.linimo.jp/">リニモ</a> を初体験してきました。
八草駅から乗車して愛・地球博記念公園駅で下車、再度同駅から藤が丘駅まで、リニモを端から端まで体験しました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BrzF9DLBKVU/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BrzF9DLBKVU/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BrzF9DLBKVU/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-12-25T05:19:29+00:00">Dec 24, 2018 at 9:19pm PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script><p>途中で下車した愛・地球博記念公園駅では、愛・地球博記念公園内にある愛・地球博記念館を見学してきました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">愛・地球博記念館すごかった。何がすごいって、職員はワンオペでわたし以外のお客さんは3人しか見なかった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077440068602580994?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote></div>
<div class="section" id="section-8">
<h3>南極観測船ふじ</h3>
<p>初日にも訪れましたが、初日は時間的な余裕がなかったためにじっくり見てまわれなかった <a class="reference external" href="http://pier.nagoyaaqua.jp/fuji/index.html">南極観測船ふじ</a> を再度訪れました。</p>
<p>完全にアニメ <a class="reference external" href="http://yorimoi.com/">「宇宙よりも遠い場所」</a> に影響を受けました。</p>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/BrzZYP2BiQQ/?utm_source=ig_embed&utm_medium=loading" data-instgrm-version="12" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/p/BrzZYP2BiQQ/?utm_source=ig_embed&utm_medium=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div><div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/p/BrzZYP2BiQQ/?utm_source=ig_embed&utm_medium=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Kohei YOSHIDA (@yosida95)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2018-12-25T08:09:13+00:00">Dec 25, 2018 at 12:09am PST</time></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="en"><p lang="ja" dir="ltr">小淵沢報瀬ちゃんに会いにきた(1日ぶり2度目) (@ 南極観測船ふじ in Nagoya-shi, 愛知県) <a href="https://t.co/4CxUN6IZZ3">https://t.co/4CxUN6IZZ3</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077458827631624192?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">きょう南極観測船ふじを見てきたので、その流れで「宇宙よりも遠い場所」の2周目を観始めたのだけれど、この後の展開とか玉木マリちゃんの変化との対比とかで、一話開始十分で涙が止まらなくなってしまった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077252155482955776?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote><p>また、南極観測船ふじが係留されている名古屋港には名古屋港検潮所もあるので、こちらも外から眺めてきました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">はれるんが船長やってた <a href="https://t.co/iZuPbXejo6">pic.twitter.com/iZuPbXejo6</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077472201601835008?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote></div>
</div>
<div class="section" id="section-9">
<h2>感想</h2>
<p>初めての一人旅に想定外の困りごとが起こらないかと不安もありましたが、終わってみれば何ということはありませんでした。</p>
<p>わたしの性格上、行き先や旅のテーマを決めるということは不得手なものの、周辺情報を調べてタイムスケジュールを組んだり、その実現のために必要な準備をするということは得意である自信がありましたが、今回の旅行でこの自信が補強されました。</p>
<p>電車内で見かけた「愛知ディスティネーションキャンペーン」の宣伝広告では、「愛知県」という行き先と「科学館などの文化的施設を巡る」というテーマが提示されていたので、これに乗っかることでうまいこと楽しむことができました。</p>
<p>また、仕事で半年に一度程度出張をしていた時期もあったことで、旅の準備に慣れていたことも奏功しました。
足らない者があれば現地調達しようという割り切りもあり、実際にモバイルブースターを持っていっていなかったので、コンビニで乾電池式のものを調達して事なきを得ました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">ホテルの近所のコンビニで入浴剤を買ってホテルに持ち込むという <a href="https://twitter.com/isidai?ref_src=twsrc%5Etfw">@isidai</a> さん直伝のワザを使った</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077204299099254789?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">化粧水やら保湿クリームやらはちゃんと持ってきたのにメガネを忘れたのでコンタクトレンズを外したくても外せない状況。メガネを現地調達するのはちょっとな……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077178785546461186?ref_src=twsrc%5Etfw">December 24, 2018</a></blockquote><p>一人旅で、また行程が予め決まっているツアー旅行でもないため、誰に気兼ねすることなく自分だけのペースで自分の行きたいところだけに行ける今回の旅行は、わたしの性格上最高でした。</p>
<p>「愛知 DC フリーきっぷ」もとても有用で、 JR も名古屋市営地下鉄も愛知環状鉄道もリニモもすべてのこのきっぷで乗車できました。
2日目の鉄道での総移動距離は 141.4 km でした。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">愛知県内の電車とバスが2日間乗り放題になる「愛知 DC フリーきっぷ」の定価が4,000円だった(旅行代理店にホテルと新幹線とセットで取ってもらった)んだけれど、計算したらきょう1日で3,200円分電車に乗っていたことが分かった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077508233705574400?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote><p>なお、今回図らずもクリスマス・イブとクリスマスにかかっていましたが、当日までそのことに気づいておらず、振り返ってみるとクリスマスらしいこととして辛うじて鶏肉を食べていました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">クリスマスらしいこととして名古屋コーチンの手羽先を食べました <a href="https://t.co/FWPTeCiKMN">pic.twitter.com/FWPTeCiKMN</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1077530377713999872?ref_src=twsrc%5Etfw">December 25, 2018</a></blockquote><p>他に行ってみたい地域もいくつか目星を付けているので、時期をみてまたそれらにも訪れてみたいと思います。</p>
</div>
ご報告2018-10-05T00:00:00+09:002018-10-05T00:00:00+09:00yosida95tag:yosida95.com,2018-10-05:/2018/10/05/greetings.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>個人の日記で …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>個人の日記です。</p>
<p>恋人と破局しました。3ヶ月前のことです。喧嘩をしたというわけではなく、わたしの至らなかった点について指摘してもらったり、それについてわたしの気持ちを聞いてもらったりした上の結論としての破局であり、円満なものであるといえるかと思います。最後まで真摯で誠実に向き合ってくれた彼女には感謝しており、また尊敬もしています。</p>
<p>しかし、破局について納得できてしまっているという点から後悔も大きく、これまでの人生でも何度か経験してきたはずの出来事であるにもかかわらず、これまでになく落ち込んでいます。</p>
<p>元恋人は中学生時代の同級生で楽しかった当時の思い出を共有している相手であったことが、わたしをわたしの青春に明確な終止符が打たれた気分にさせて気分の落ち込みに拍車をかけているのかもしれません。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">ここしばらく悩んでいたことに望んでいなかった結論が出てしまい、すごく感傷的になっていて多分しばらく引きずるんですが、なぜここに至ってしまったのかについて仮説をたて冷静に考察している自分や、対人的には普段どおりに振る舞えてしまっている自分が既にいて、そのことにさらに落ち込んでいる。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1014525578743934976?ref_src=twsrc%5Etfw">July 4, 2018</a></blockquote><p>幸いなことによい友人たちを持ったもので、 Twitter で知り合ってから7年来の付き合いになる友人に加え、アメリカに移住した高校の同期も一時帰国したタイミングでわたしを連れ出した上でアドバイスをくれ、なんとか前向きに立ち直ることができています。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">これまでなんでも一人で解決してきたから、いざ友達に頼ろうとすると信頼できる友達とは交友期間から関係が固定されていてどうしたらよいか分からない。今回も一人で乗り越えられるはずだけれど、その先で自分をしなやかに成長させるために頼り方を覚えたい。辛うじて一人には打ち明けられたけど……。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1014791794389762049?ref_src=twsrc%5Etfw">July 5, 2018</a></blockquote><p>なお、この記事の推奨 BGM は東山奈央「月がきれい」です。できればフルで聴いてください。</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/nw2Uw0Eww_w?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></div>
<div class="section" id="section-3">
<h2>「努力」について</h2>
<p>わたしが好きな<a class="reference external" href="https://www.amazon.co.jp/dp/4575838365/">「森永みるく作『 GIRL FRIENDS 』」の5巻</a>に「私…あの頃努力してなかったなあって思うんだ…」「一緒にいるための努力…努力しなくても仲良しでいられるのが友達だし好きあってれば同じ気持ちなはずだし一緒にいられるのが当たり前って思ってたのね…」というセリフがあります。</p>
<p>これまでのわたしの人生を振り返ると、何事においても「努力」を「努力」として取り組んだことがないように思います。楽しくてただ続けてきたことを他者からは努力だと評価されることはありますが、わたしとしてはあくまでもそれが努力であったとは考えていません。</p>
<p>もっともそれが理想的で、努力をしなくて済むなら、あるいは努力を努力と認識せずにできてしまうなら、それに越したことはないとも思います。</p>
<p>しかし、相手がいることである以上「楽しいこと」だけで済むはずはなく、また先を見据えて努力をしなくてはたどり着けない高みを目指したくなったとき、その経験がないわたしはちゃんと努力できるのか、そもそも努力するという発想に至るのかと考えると恐怖を感じました。</p>
</div>
<div class="section" id="section-4">
<h2>これからについて</h2>
<p>幸い、自身を客観視した上での自己分析とその結果に基づいた問題解決をすることはそれなりにできると認識しているので、この3ヶ月間はいわば自分をハックすることに取り組んで来ました。</p>
<div class="section" id="section-5">
<h3>スポーツジム</h3>
<p>まずは努力を努力と認識した上でちゃんと取り組む練習をすることを目的にスポーツジムに入会しました。</p>
<p>スポーツは小学2年生の頃に少年野球チームに1年ほど所属していたほかは、学校でリレーの選手に選抜されて簡単な練習をした程度の経験しかなく、つぶしが利かない分野であると言えます。</p>
<p>その中で筋肥大を目指す筋力トレーニングに取り組んでいます。当面の具体的な目標は筋肉量を7月はじめの時点から 7.9kg 増やすことで、9月はじめの時点(精度の高い最新の測定結果)では 1.5kg 増やすことができ順調に推移しています。</p>
<p>「筋肉は裏切らない」という言葉もある通り、自分の努力が筋肉量として定量的に評価できる点で努力の練習として適していると思い取り組んでいます。</p>
<p>また、一年間解約できないプランを契約した上で別途パーソナルトレーナーにもついてもらい、約束の相手を自分のほかにも作ることで筋肉のほかにわたしの精神も追い込むという継続するための対策もとっています。</p>
</div>
<div class="section" id="section-6">
<h3>ボイストレーニング</h3>
<p>さらに、スポーツジムへの入会に加えてボイストレーニングを行うカルチャースクールにも入校しました。</p>
<p>わたしには自分のことやその感情を一歩引いて常に冷静に見てしまう嫌いがあります。あるいは理性が臆病なほどに強すぎて、自分の感情やその感情からくる行動を表出させられないとも言えます。この点は元恋人からも指摘されました。</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">「お前は AT フィールドが厚すぎる」「自己防御がすぎる」などと複数の友人に言われてきて、また常に感情よりも理性を優先させてしまう自分に気づいていて、それがポジティブに捉えられることもあるけれど、今回はそれらの点が負に作用していて、それなのにそういった自分が主張してきて辛い……</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1014527560430964736?ref_src=twsrc%5Etfw">July 4, 2018</a></blockquote>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">やらかしを受けたときにわたしにとっては謝罪よりもその事象の経緯が重要で、第三者委員会の調査報告書とかを読み通すタイプなんだけれど、誰もがそうでないということは当たり前のことで、わたしがやらかした時に経緯の説明に力を割くと言い逃れのように映る事があるんだなと言うことを学び反省した。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1009090507450937344?ref_src=twsrc%5Etfw">June 19, 2018</a></blockquote><p>また、表出させるにしても経験や場数が足らず「撮って出し」のそれを表現できないという欠点もあると感じました。知識としての語彙はあっても、こと感情においてはそれを尽くせないというもどかしさがあります。</p>
<p>そこで、まずは自分の感情をできるだけありのままに、そして豊かに表現できるようになりたい、その技術を習得する努力の緒としてのボイストレーニングです。</p>
<p>ボイストレーニングでは呼吸の仕方から発音するときの口の形や舌の位置、そしてフレーズのニュアンスやアクセントの付け方などを学んでいます。</p>
<p>わたしはどうも技術の理解とその実践が速いらしく、講師からは「君のカルテはふわっとポジティブなことばかりが書いてあって面白い」などと評価されており、こちらは楽しく身につけていくことができそうです。</p>
<p>また、「君みたいなタイプは技術の実践として劇団で演劇でもやってみるとよい」という話もされ、そういうことも楽しそうだなと少し興味を抱いています。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">きょうはプロの声優さんに「キミは生まれつきよい声質を持っているのに、それを活かさずにわざわざ通りづらい声で話しているけれど、なんで?」と訊かれ、それはわたしが知りたいわ、23年生きてきて初めて知ったわとなった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/1042391479946076161?ref_src=twsrc%5Etfw">September 19, 2018</a></blockquote></div>
</div>
<div class="section" id="section-7">
<h2>結びに</h2>
<p>きょうはこの3ヶ月について振り返って自分なりにまとめました。今の気持ちや意識を文章として残しておくことで、さらに時間が経過した自分が今を振り返り現在の目的意識を再認識するための資料となることを願います。</p>
<p>また、冒頭に記したようにわたしを連れ出し直接話を聞いてくれた友人の他にも、わたしの様子を心配してくださった人がいらしたので、できるだけ飾らない言葉で何が起こったのか、そして現在は問題解決に取り組めていることを伝えることができたら幸いです。</p>
</div>
yosida95 の 2017年まとめ2017-12-31T00:00:00+09:002017-12-31T00:00:00+09:00yosida95tag:yosida95.com,2017-12-31:/2017/12/31/greetings.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
さて、光陰矢の如しとはよく言ったもので、2017年も残すところ1時間を切りました。</p>
<p>yosida95 を初めて名乗ってからも11年が経ち、このブログを振り返るとこれまで7年連続で1年のまとめを書いてきたので、ことしもまとめていきます。</p>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2016/12/31/yearly_report.html">yosida95 の 2016 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
</ul>
</div>
<div class="section" id="section-2">
<h2>ことし始めたこと</h2>
<p>ことし新しく手を付けた主なものを振り返ります。</p>
<div class="section" id="kubernetes">
<h3>Kubernetes</h3>
<p>Google Kubernetes Engine でわちゃわちゃやっています。
すでに所属先の本番環境の一部が稼働しています。</p>
</div>
<div class="section" id="spinnaker">
<h3>Spinnaker</h3>
<p>これまで自作のデプロイシステムや <a class="reference external" href="https://github.com/pinterest/teletraan">pinterest/teletraan</a> などを使っていましたが、自作システムにはスケールの問題などが、 Teletraan は出来が悪いなどの問題があり、また両者に共通して Config Drift などの問題があったので、一念発起して Spinnaker を導入しました。</p>
<p>Kubernetes の上で動かしていますが、デプロイしてからしばらく放っておくと既知のバグや Kubernetes ノードの再起動などで大破するので、定期的に <cite>hal deploy apply</cite> を叩いています。</p>
</div>
<div class="section" id="rust">
<h3>Rust</h3>
<p>Rust に入門しました。
まだなにか実用的なものは作るところには至っておらず、習熟度はいまいちなので引き続き力を入れていきます。</p>
</div>
<div class="section" id="prometheus">
<h3>Prometheus</h3>
<p>Service Discovery や PromQL や Alertmanager がとにかく便利です。
これまでの監視システムでは障害の予兆や原因が現れる所を予想してそこだけを見ていく形でしたが、 Prometheus ではとにかくデータを先に集めてしまってから PromQL を使って必要なものを効果的な角度で見るという事ができるようになりました。</p>
<p>これまで個人的なシステムは Zabbix + Munin を主に、所属先では Nagios + Munin を主に使ってきましたが、どんどん置き換えていっています。</p>
<p>監視システムの置き換えに伴ってアラーティングも見直しており、 Prometheus ドキュメントで紹介されている <a class="reference external" href="https://docs.google.com/a/boxever.com/document/d/199PqyG3UsyXlwieHaqbGiWVa8eMWi8zzAn0YfcApr8Q/edit">My Philosophy on Alerting</a> based on Rob Ewaschuk's observations at Google を参考に、自動修復の期待があるロードの一時的な上昇やミドルウェアやインスタンスの問題などから、エラーレートやレイテンシなどユーザーに影響を与える指標にアラーティングやページの軸を移すことで、ぐっすり眠れる夜を目指しています。</p>
</div>
<div class="section" id="section-3">
<h3>上場株取引、確定拠出年金</h3>
<p>これまで投資信託を毎月一定額を買う資産運用をしてきましたが、ことしから国内外(日本、米国)の上場株の取引と確定拠出年金の拠出もはじめました。</p>
<p>株式は数十万の範囲で取引をしていて年間の成績はトータルで1割くらいのプラスくらいでしたが、ことしは相場環境がだいぶよかったので来年以降はどうなるか分かりません。</p>
<p>確定拠出年金は資産形成というよりはおもに節税の目的で始めました。
とりあえず会社員としての上限額である23,000円を毎月拠出していますが、確定申告のタイミングで効果を見極めつつ拠出額の見直しをする予定です。</p>
</div>
</div>
<div class="section" id="section-4">
<h2>2018年やっていきたいこと</h2>
<div class="section" id="section-5">
<h3>資産運用</h3>
<p>主に株式取引をやっていきます。
ことしは準備運動のつもりで触ってみたら相場環境に後押しされたので、2018年はしっかり狙って同程度以上の成績を出せたらよいと思います。</p>
</div>
<div class="section" id="section-6">
<h3>英会話</h3>
<p>仕事がら英語のドキュメントやブログなどは日常的に読んでおりそれほど不自由はしていませんが、あくまでも語彙が IT に偏った活字を読むことに限った話です。
日常的な意思疎通ができるように読み書きも会話もできるように取り組んでいきます。</p>
</div>
</div>
<div class="section" id="section-7">
<h2>終わりに</h2>
<p>ことしを振り返ってみると思いの外新しいことを始めていたと気付きました。
日常的には気付きませんが、なんだかんだでやりたいことをやっているようです。</p>
<p>来年もこんな感じで前に進んでいきたいと思います。
今後ともよろしくお願いします。</p>
</div>
yosida95 の2016年まとめ2016-12-31T00:00:00+09:002016-12-31T00:00:00+09:00yosida95tag:yosida95.com,2016-12-31:/2016/12/31/yearly_report.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。</p>
<p>さて、早いもので2016年もあと30分足らずで終わろうとしています。
ことしの年越し蕎麦は温かいきつね蕎麦と冷たいざる蕎麦を作って食べました。</p>
<p>それでは、例年同様2016年を振り返って参ります。</p>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2015/12/31/yearly_report.html">yosida95 の 2015 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
</ul>
</div>
<div class="section" id="section-2">
<h2>主な出来事</h2>
<div class="section" id="section-3">
<h3>成人した</h3>
<p>2015年6月に20歳の誕生日を迎え、ことしの1月に成人式に列席しました。
当時は東京都千代田区に居住していたため千代田区から成人式の招待状が届きましたが、そちらには行かず、代わりにぼくが生まれ育った東京都葛飾区が開催したものに参加して来ました。</p>
<p>成人式がきっかけで、中学卒業以来5年ぶりに再会した友人たちとまた遊ぶようになり、人生が少し豊かになりました。</p>
</div>
<div class="section" id="section-4">
<h3>月報をやめた</h3>
<p>2015年1月から書き続けていた月報でしたが、ことしの3月まとめを最後に書くことをやめました。</p>
<p>これには大した理由はなく、月報を書くことに飽き始め、年度の切り替わりにやめればちょうどよいかなと思ったためです。</p>
</div>
<div class="section" id="section-5">
<h3>引っ越した</h3>
<p>19歳から始めたひとり暮らし2年の節目に、これまで居住していた東京都千代田区から東京都江東区に引っ越しました。
引っ越しの理由は、部屋が手狭に感じたためと、より充実した設備のマンションに住みたかったためです。</p>
<p>オフィスからは少し離れてしまいましたが、かわりに生活が豊かになりました。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>終わりに</h2>
<p>2016年を振り返ってみると、とても穏やかな一年だったように感じます。
穏やかであるということはよいことでもありますが、反面動きが無く少しもどかしい気持ちも感じます。</p>
<p>2017年は毎日を漫然と過ごすのではなく、目標を持って実りあるものにしていければと思います。</p>
<p>最後に、2016年中お世話になったすべての皆さんにお礼申し上げます。
ありがとうございました。</p>
<p>2017年も引き続きよろしくお願いします。</p>
<p>ところで、うすうす予期してはいましたが、やはり書き終える前に年が明けました。</p>
<p>来年から本気だすぞ。</p>
</div>
はてなブログの AtomPub API を使って記事を更新する2016-05-29T00:00:00+09:002016-05-29T00:00:00+09:00yosida95tag:yosida95.com,2016-05-29:/2016/05/29/update_whole_entries_in_hatena.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。
昨日お知らせとおり、ぼくのブログをはてなブログから yosida95.com へと移動しました。</p>
<p>これに伴って、ぼくのすべてのはてなブログエントリの本文を、対応する yosida95.com の新しい URL へと誘導する内容に差し替えました。
はてなブログでは138記事を公開していましたが、このすべての記事を差し替えることは人間のやる仕事ではありません。</p>
<p>幸いはてなブログでは <a class="reference external" href="http://developer.hatena.ne.jp/ja/documents/blog/apis/atom">AtomPub に則った API</a> を公開してくれているので、これを使って自動で差し替えることができました。
雑に書いたコードですが、そのまま捨てることももったいないので、同じことをしたい人やはてなブログ AtomPub API の具体的な利用例になればと思い公開することにします。</p>
</div>
<div class="section" id="section-2">
<h2>はてなブログのすべての記事を自動で更新する</h2>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">'''</span>
<span class="sd">Copyright (c) 2016, Kohei YOSHIDA <https://yosida95.com/>. All rights reserved.</span>
<span class="sd">Redistribution and use in source and binary forms, with or without</span>
<span class="sd">modification, are permitted provided that the following conditions are met:</span>
<span class="sd"> * Redistributions of source code must retain the above copyright</span>
<span class="sd"> notice, this list of conditions and the following disclaimer.</span>
<span class="sd"> * Redistributions in binary form must reproduce the above copyright</span>
<span class="sd"> notice, this list of conditions and the following disclaimer in the</span>
<span class="sd"> documentation and/or other materials provided with the distribution.</span>
<span class="sd"> * Neither the name of the copyright holder nor the names of its</span>
<span class="sd"> contributors may be used to endorse or promote products derived from</span>
<span class="sd"> this software without specific prior written permission.</span>
<span class="sd">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span>
<span class="sd">"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span>
<span class="sd">LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR</span>
<span class="sd">A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT</span>
<span class="sd">HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
<span class="sd">SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT</span>
<span class="sd">LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span>
<span class="sd">DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY</span>
<span class="sd">THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="sd">(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span>
<span class="sd">OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="sd">'''</span>
<span class="kn">import</span> <span class="nn">copy</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">from</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="n">b64encode</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">urljoin</span><span class="p">,</span>
<span class="n">urlparse</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">xml.etree</span> <span class="kn">import</span> <span class="n">ElementTree</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="n">ENDPOINT_PREFIX</span> <span class="o">=</span> <span class="s1">'https://blog.hatena.ne.jp/</span><span class="si">{はてなID}</span><span class="s1">/</span><span class="si">{ブログID}</span><span class="s1">/atom/'</span>
<span class="n">YOUR_HATENA_ID</span> <span class="o">=</span> <span class="s1">'yosida95'</span>
<span class="n">YOUR_API_KEY</span> <span class="o">=</span> <span class="s1">'dummyapikey'</span>
<span class="n">PATH_TO_APACHE_REWRITE_RULES</span> <span class="o">=</span> <span class="s1">'/var/www/blog.yosida95.com/.htaccess'</span>
<span class="n">nsmap</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">atom</span><span class="o">=</span><span class="s1">'http://www.w3.org/2005/Atom'</span><span class="p">,</span>
<span class="n">app</span><span class="o">=</span><span class="s1">'http://www.w3.org/2007/app'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">build_rewrite_rules</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="n">rewrite_rules</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">tokens</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'RewriteRule'</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">source</span><span class="p">,</span> <span class="n">dest</span> <span class="o">=</span> <span class="n">tokens</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span>
<span class="n">re_source</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
<span class="n">rewrite_rules</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">re_source</span><span class="p">,</span> <span class="n">dest</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'$'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\\</span><span class="s1">'</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">rewrite_rules</span>
<span class="k">def</span> <span class="nf">find_redirect_to</span><span class="p">(</span><span class="n">entry_url</span><span class="p">,</span> <span class="n">rewrite_rules</span><span class="p">):</span>
<span class="n">entry_path</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">entry_url</span><span class="p">)</span><span class="o">.</span><span class="n">path</span>
<span class="n">redirect_to</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">rewrite_to</span><span class="p">)</span> <span class="ow">in</span> <span class="n">rewrite_rules</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pattern</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">entry_path</span><span class="p">):</span>
<span class="k">continue</span>
<span class="n">redirect_to</span> <span class="o">=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">rewrite_to</span><span class="p">,</span> <span class="n">entry_path</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">return</span> <span class="n">redirect_to</span>
<span class="k">def</span> <span class="nf">make_new_content</span><span class="p">(</span><span class="n">entry_url</span><span class="p">):</span>
<span class="n">template</span> <span class="o">=</span> <span class="s1">'''<p>この記事は yosida95.com に移動しました。<br></span>
<span class="s1">新しい URL は <a href="</span><span class="si">{entry_url}</span><span class="s1">"></span><span class="si">{entry_url}</span><span class="s1"></a> です。</p></span>
<span class="s1"><p>お手数をお掛けしますが、ブックマークの付け替えをお願いします。</p></span>
<span class="s1"><!-- more --></span>
<span class="s1"><script type="text/javascript"></span>
<span class="s1"> location.href = "</span><span class="si">{entry_url}</span><span class="s1">" + location.search;</span>
<span class="s1"></script>'''</span>
<span class="k">return</span> <span class="n">template</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">entry_url</span><span class="o">=</span><span class="n">entry_url</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">make_wsse_token</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="n">nonce</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">16</span><span class="p">))</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
<span class="n">created</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">'%Y-%m-</span><span class="si">%d</span><span class="s1">T%H:%M:%SZ'</span><span class="p">)</span>
<span class="n">credential</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">nonce</span><span class="p">,</span> <span class="n">created</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">),</span>
<span class="n">password</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">)))</span>
<span class="n">digest</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">credential</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
<span class="n">tmpl</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'UsernameToken Username="</span><span class="si">{uname}</span><span class="s1">",'</span>
<span class="s1">'PasswordDigest="</span><span class="si">{digest}</span><span class="s1">",'</span>
<span class="s1">'Nonce="</span><span class="si">{nonce}</span><span class="s1">",'</span>
<span class="s1">'Created="</span><span class="si">{created}</span><span class="s1">"'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">tmpl</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">uname</span><span class="o">=</span><span class="n">userid</span><span class="p">,</span>
<span class="n">digest</span><span class="o">=</span><span class="n">b64encode</span><span class="p">(</span><span class="n">digest</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">),</span>
<span class="n">nonce</span><span class="o">=</span><span class="n">b64encode</span><span class="p">(</span><span class="n">nonce</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">),</span>
<span class="n">created</span><span class="o">=</span><span class="n">created</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">update_entry_element</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">new_content</span><span class="p">):</span>
<span class="n">inheritable_elements</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'{{</span><span class="si">{atom}</span><span class="s1">}}title'</span><span class="p">,</span>
<span class="s1">'{{</span><span class="si">{atom}</span><span class="s1">}}category'</span><span class="p">,</span>
<span class="s1">'{{</span><span class="si">{app}</span><span class="s1">}}control'</span><span class="p">)</span>
<span class="n">inheritable_elements</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">name</span><span class="p">:</span> <span class="n">name</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">nsmap</span><span class="p">),</span>
<span class="n">inheritable_elements</span><span class="p">))</span>
<span class="n">content_tag</span> <span class="o">=</span> <span class="s1">'{{</span><span class="si">{atom}</span><span class="s1">}}content'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">nsmap</span><span class="p">)</span>
<span class="n">new_entry</span> <span class="o">=</span> <span class="n">ElementTree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">entry</span><span class="p">:</span>
<span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">tag</span> <span class="o">==</span> <span class="n">content_tag</span><span class="p">:</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="s1">'text/html'</span><span class="p">)</span>
<span class="n">node</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">new_content</span>
<span class="n">new_entry</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">node</span><span class="o">.</span><span class="n">tag</span> <span class="ow">in</span> <span class="n">inheritable_elements</span><span class="p">:</span>
<span class="n">new_entry</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">node</span><span class="p">))</span>
<span class="k">return</span> <span class="n">new_entry</span>
<span class="k">def</span> <span class="nf">update_entry</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">rewrite_rules</span><span class="p">,</span> <span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="n">is_draft</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'app:control/app:draft'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">)</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s1">'yes'</span>
<span class="k">if</span> <span class="n">is_draft</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">entry_id</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'atom:id'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">)</span><span class="o">.</span><span class="n">text</span>
<span class="n">edit_url</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'atom:link[@rel="edit"]'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">)</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s1">'href'</span><span class="p">]</span>
<span class="n">entry_url</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'atom:link[@rel="alternate"]'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">)</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s1">'href'</span><span class="p">]</span>
<span class="n">redirect_to</span> <span class="o">=</span> <span class="n">find_redirect_to</span><span class="p">(</span><span class="n">entry_url</span><span class="p">,</span> <span class="n">rewrite_rules</span><span class="p">)</span>
<span class="n">new_content</span> <span class="o">=</span> <span class="n">make_new_content</span><span class="p">(</span><span class="n">redirect_to</span><span class="p">)</span>
<span class="n">new_entry</span> <span class="o">=</span> <span class="n">update_entry_element</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">new_content</span><span class="p">)</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'X-WSSE'</span><span class="p">:</span> <span class="n">make_wsse_token</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">),</span>
<span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/atom+xml;type=entry'</span><span class="p">}</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">ElementTree</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span><span class="n">new_entry</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf8'</span><span class="p">)</span>
<span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">edit_url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">body</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">','</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">entry_id</span><span class="p">,</span> <span class="n">entry_url</span><span class="p">,</span> <span class="n">redirect_to</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">iter_collections</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="n">collection_url</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">ENDPOINT_PREFIX</span><span class="p">,</span> <span class="s1">'./entry'</span><span class="p">)</span>
<span class="k">while</span> <span class="n">collection_url</span><span class="p">:</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'X-WSSE'</span><span class="p">:</span> <span class="n">make_wsse_token</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">)}</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">collection_url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">ElementTree</span><span class="o">.</span><span class="n">fromstring</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
<span class="k">yield</span> <span class="n">root</span>
<span class="n">next_</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">'atom:link[@rel="next"]'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">)</span>
<span class="k">if</span> <span class="n">next_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">collection_url</span> <span class="o">=</span> <span class="n">next_</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s1">'href'</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">rewrite_rule_file</span><span class="p">):</span>
<span class="n">rewrite_rules</span> <span class="o">=</span> <span class="n">build_rewrite_rules</span><span class="p">(</span><span class="n">rewrite_rule_file</span><span class="p">)</span>
<span class="k">for</span> <span class="n">collection</span> <span class="ow">in</span> <span class="n">iter_collections</span><span class="p">(</span><span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">collection</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s1">'atom:entry'</span><span class="p">,</span> <span class="n">nsmap</span><span class="p">):</span>
<span class="n">update_entry</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">rewrite_rules</span><span class="p">,</span> <span class="n">userid</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">(</span><span class="n">YOUR_HATENA_ID</span><span class="p">,</span> <span class="n">YOUR_API_KEY</span><span class="p">,</span>
<span class="n">PATH_TO_APACHE_REWRITE_RULES</span><span class="p">)</span>
</pre></div>
<div class="section" id="section-3">
<h3>前提</h3>
<ol class="arabic simple">
<li>Python 3 系でしか動きません</li>
<li><a class="reference external" href="https://pypi.python.org/pypi/requests">requests</a> のインストールが必要です</li>
</ol>
</div>
<div class="section" id="section-4">
<h3>使い方</h3>
<p>冒頭で定義されている以下の変数にそれぞれ適切な値を代入してください。</p>
<ul class="simple">
<li>ENDPOINT_PREFIX</li>
<li>YOUR_HATENA_ID</li>
<li>YOUR_API_KEY</li>
<li>PATH_TO_APACHE_REWRITE_RULES</li>
</ul>
<p>PATH_TO_APACHE_REWRITE_RULES には移転前のブログパスから移転後の URL へ転送する RewriteRule を対応づけた .htaccess へのパスを指定して下さい。
もっとも、新しいブログの URL を本文に記載する必要がない場合は、 <cite>update_entry</cite> 関数内の <cite>make_new_content</cite> の呼び出し周辺をいい感じに改変してあげて下さい。</p>
<p>本文は <cite>make_new_content</cite> 関数を改変することでいい感じになります。</p>
</div>
<div class="section" id="section-5">
<h3>ライセンス</h3>
<p>ソースコードに記載の通り修正 BSD ライセンスで提供するので、このライセンスが許す範囲内で自由に実行、改変、再配布して下さい。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>最後に</h2>
<p>今後ともよろしくお願いします。</p>
</div>
【重要】【 Action Required 】ブログを移転しました2016-05-28T00:00:00+09:002016-05-28T00:00:00+09:00yosida95tag:yosida95.com,2016-05-28:/2016/05/28/move_my_blog.html<p>こんばんは、 yosida95 です。</p>
<div class="section" id="section-1">
<h2>ブロ …</h2></div><p>こんばんは、 yosida95 です。</p>
<div class="section" id="section-1">
<h2>ブログを移転しました</h2>
<p>これまでぼくのブログははてなブログでホスティングしていましたが、 <a class="reference external" href="http://www.sphinx-doc.org/en/stable/">Sphinx</a> ベースの静的ブログエンジン <a class="reference external" href="http://tinkerer.me/">Tinkerer</a> を使って自分でホスティングするようにしました。
これに伴ってエントリの URL はもちろんのこと、 RSS フィードや Atom フィードの URL も変更になっています。</p>
<p>各種フィードを購読中の皆さまにはお手数をお掛けしますが、新しい RSS フィードの URL である <a class="reference external" href="https://yosida95.com/rss.xml">https://yosida95.com/rss.xml</a> への切り替えをお願いします。</p>
</div>
ErgoDox というキーボードを買った2016-04-22T00:00:00+09:002016-04-22T00:00:00+09:00yosida95tag:yosida95.com,2016-04-22:/2016/04/22/bought-ergodox.html<a class="reference external image-reference" href="https://yosida95.com/photos/trNdf.raw.jpeg"><img alt="ErgoDox EZ" src="https://yosida95.com/photos/trNdf.resized.jpeg" /></a>
<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><a class="reference external image-reference" href="https://yosida95.com/photos/trNdf.raw.jpeg"><img alt="ErgoDox EZ" src="https://yosida95.com/photos/trNdf.resized.jpeg" /></a>
<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。</p>
<p>最近、 ErgoDox というキーボードがにわかに流行り始めています。</p>
<p><a class="reference external" href="http://ergodox.org/">ErgoDox: Split Ergonomic Keyboard</a></p>
<p>このように、 ErgoDox を購入したユーザーが次々にブログエントリを公開しています。</p>
<ul class="simple">
<li><a class="reference external" href="http://kammers.aa0.netvolante.jp/20150928201048/">ergodoxを買いました | kammers</a></li>
<li><a class="reference external" href="http://nippondanji.blogspot.jp/2016/01/ergodox.html">漢(オトコ)のコンピュータ道: キーボードを新しくした話(ErgoDox)</a></li>
<li><a class="reference external" href="http://ymotongpoo.hatenablog.com/entry/2016/03/25/203734">ErgoDoxを購入して人生がバラ色になった - YAMAGUCHI::weblog</a></li>
<li><a class="reference external" href="http://blog.restartr.com/2016/03/31/got-my-ergodox-ez/">ErgoDox EZが届いた &middot; I Will Survive</a></li>
</ul>
<p>わたしも流行に便乗して ErgoDox を購入したので、今日はその話をします。</p>
</div>
<div class="section" id="ergodox-1">
<h2>ErgoDox</h2>
<p>ErgoDox とはエルゴノミクスデザイン、つまり人間の構造や特徴を考慮した設計をすることで、従来のキーボードとくらべて自然な姿勢や運指で扱うことができ、その結果疲れや負担が軽減されるというキーボードです。
エルゴノミクスデザインのキーボードは昔から広く販売されていますが、 ErgoDox の特徴として左右セパレートであることとオープンソースであることが挙げられます。</p>
<p>左右セパレートであることの利点は、腕を開いて胸を張った自然な姿勢で利用できることです。</p>
<p>両足を床に付け背筋を伸ばして椅子に座った状態から、セパレートでないキーボードを利用する姿勢に移行してみてください。
肩を内側にすぼめ、背筋も猫背になったはずです。
そのままゾーンに入れば、2、3時間は指以外微動だにしない状態が続くわけです。
それは肩だって凝るわ、ということが分かります。</p>
<p>ErgoDox のように左右がセパレートであるキーボードを利用すれば、背筋を伸ばして胸を張った状態で自然にキーボードを利用できるようになります。</p>
<p>次に、オープンソースであることです。
ErgoDox は、そのデザインからファームウェアに至るまですべてがオープンソースで公開されています。
特にファームウェアがオープンソースであるということの利点が大きく、例えば自分でファームウェアを改変して好みのキーマップにすることだってできるのです。</p>
</div>
<div class="section" id="section-2">
<h2>きっかけ</h2>
<p>ソフトウェアエンジニアという職業柄、毎日何万文字もタイプするので、元来キーボードにはこだわりがありました。
そんなわたしは4年前から一貫して <a class="reference external" href="https://www.pfu.fujitsu.com/hhkeyboard/hhkbpro2/">Happy Hacking Keyboard Professional2</a> を利用して来ました。
これは、心地よい打鍵感とコンパクトなボディ、そして無刻印モデルがあることが気に入ったためです。</p>
<p>しかし昨年のことです。
親指の付け根に腱鞘炎を患い、親指を包帯で固定しないと痛みでキーボードを叩けない状態になりました。
その原因として真っ先に思い当たった事が、親指を内側にくぐらせる運指です。</p>
<p>Happy Hacking Keyboard を含め、流通しているキーボードの配列はたいていの場合長いスペースバーの隣に Alt キーや Cmd (Windows) キーが配置されています。
ホームポジションを維持したままこれらのキーを押す時、とくにキーボードショットカットを利用するためにこれらのキーを含む複数のキーをホールドする時に、親指を内側にくぐらせる運指をしがちです。</p>
<p>腱鞘炎からは回復したものの、このキー運指を繰り返している限りは再発しかねないと思っていた最中に出会ったキーボードが ErgoDox でした。
ErgoDox には長いバーはありません。
代わりに左右の親指が来る位置にそれぞれ複数のキーが配置されています。
そのため、親指をくぐらせる運指をすること無く、親指を活用して自然に複数のキーをタイプすることができるのです。</p>
</div>
<div class="section" id="section-3">
<h2>購入方法</h2>
<p>ErgoDox は先ほど述べたとおりオープンソースのキーボードです。</p>
<p>公開されている ErgoDox の仕様を元に、海外では複数のサイトが ErgoDox を構成するパーツを販売しています。
また、自分で選んだパーツをアセンブリした完成品の状態で発送するサービスを提供しているところもあります。
それらについて詳しくは、「 <a class="reference external" href="http://kammers.aa0.netvolante.jp/20150928201048/">ergodoxを買いました | kammers</a>」がとても参考になります。</p>
<p>ただ、どのパーツを選べばよいのか、適切でないパーツを選んでしまわないか、すべてのキーについて半田付けを上手にできるかなどの不安があるかもしれません。
わたしもそうでした。</p>
<p>そこで調べた所、 <a class="reference external" href="https://www.indiegogo.com/">INDIEGOGO</a> でクラウドファンディングを成功させた <a class="reference external" href="https://www.indiegogo.com/projects/ergodox-ez-an-incredible-mechanical-keyboard">ErgoDox EZ</a> が目に止まりました。
こちらは、 ErgoDox を完成品として製品化したもので、購入する上で選択する必要があるオプションは「キーボードをティルトさせるための脚をつけるか」と「キースイッチをどれにするか」だけです。
また、バラバラのパーツをそれぞれ組み合わせる場合に比べて、デザインに統一感があり、高級感もあります。
さらに ErgoDox EZ のロゴが入ったオリジナルのリストレストも入手することができます。
とにかく ErgoDox が欲しいという場合には、 ErgoDox EZ がオススメです。</p>
<p>3月29日に INDIEGOGO のサイトから、ティルトの脚付きでリストレストとセットの "ErgoDox EZ Bundle: Blank" を発注しました。
その日の内にキースイッチを選択して欲しいと、回答フォームのリンクが添付されたメールが送られてきました。
キースイッチを選択した後は、向こうから一切のインタラクションがなく、4月19日になって UPS から「荷物を預かったので発送する」というトラッキングナンバー付きのメールが届きました。
台湾から発送されて、一度中国の深センを経由してから成田空港より入国して、翌20日の昼過ぎに東京都千代田区のわたしの手元に届きました。
送料は 1,300 円でした。
発注から3週間で手元に届きました。</p>
</div>
<div class="section" id="section-4">
<h2>使用感</h2>
<p>ErgoDox の利点は最初に述べたとおりです。
ErgoDox を長い時間使うほど、その利点が肩や指の疲労感として実感できます。</p>
<p>また、チルトするための脚が3点にあることがとても便利で、腕を内側にひねることなく、さらに自然な姿勢でキーボードを操作できます。</p>
<a class="reference external image-reference" href="https://yosida95.com/photos/TjZfa.raw.jpeg"><img alt="ErgoDox Tilt Kit" src="https://yosida95.com/photos/TjZfa.resized.jpeg" /></a>
<p>打鍵感は Happy Hacking Keyboard と同じ押下圧 45g の赤軸を選択したため、違和感なく乗り換えることができました。
キートップの質感についても、 Happy Hacking Keyboard と遜色ありません。
打鍵音は ErgoDox の方が若干静かに感じます。</p>
<p>ただし、 ErgoDox のデフォルトのキーマップは到底便利とは言えません。</p>
<a class="reference external image-reference" href="https://cdn.shopify.com/s/files/1/1152/3264/files/ergodox_ez_keymap_highres.png"><img alt="ErgoDox EZ Default Firmware Keymap" src="https://yosida95.com/photos/St38N.resized.png" /></a>
<p>引用元: <a class="reference external" href="https://www.indiegogo.com/projects/ergodox-ez-an-incredible-mechanical-keyboard">ErgoDox EZ: An incredible mechanical keyboard</a></p>
<p>例として、 Q キーの左隣の Tab キーがあって欲しい場所に Delete があったり、 A キーの左隣の Ctrl キーが有って欲しい場所に Backspace があります。
もっとも、 ESC キーがメジャーなキーボードのチルダが配置される場所にある Happy Hacking Keyboard を不自由なく4年間使っていたので、慣れによるところが大きいと思います。</p>
<p>しかし思い出して下さい。
ErgoDox の特徴は、すべてがオープンソースであることです。
従って、 OS 側でキーマップを再割当てするなど面倒なことをせずとも、ファームウェアを書き換えることによって自由自裁にキーマップを変更できるのです。</p>
<p>わたしは、 ErgoDox EZ を受け取ったその日の内にファームウェアを書き換えて自分好みのキーマップを作りました。
現時点でのわたしのベストは <a class="reference external" href="https://github.com/yosida95/qmk_firmware/tree/keymap-yosida95/keyboard/ergodox_ez/keymaps/yosida95">yosida95/qmk_firmware</a> です。</p>
<a class="reference external image-reference" href="https://yosida95.com/photos/TiYqC.raw.png"><img alt="yosida95 keymap for ErgoDox EZ" src="https://yosida95.com/photos/TiYqC.resized.png" /></a>
<p>ファームウェアを書き換えると言っても、キーマップを書くだけなら特別 C や組み込み系に精通している必要はありません。
README とそこからリンクされている各ドキュメントに一通り目を通せば、何をすればよいかということは把握できます。
あとは各キーに対応する配列データの各要素にキーコードを置いていくだけで、どうってことはありません。</p>
<p>どうしても C を書きたくない場合は、 Massdrop の <a class="reference external" href="https://keyboard-configurator.massdrop.com/ext/ergodox">ErgoDox Layout Configurato</a> を利用すれば、どのキーにどのキーコードを設定するかを選択するだけでカスタマイズしたキーマップのコンパイル済ファームウェアをダウンロードすることもできます。</p>
<p>そんな感じで、最初から自分好みのキーマップにしたこと、もともとキーボードの QWERTY 部分についての運指は左右が教科書どおりに綺麗に分担していたことで、非セパレートからセパレートに乗り換えた事の影響はありませんでした。
ただ、職場の同僚2人がわたしの ErgoDox EZ を試した所、「自分にはまだ早すぎた」と言っていました。</p>
</div>
<div class="section" id="section-5">
<h2>まとめ</h2>
<p>ErgoDox EZ を使うことで、疲れや痛みなどに気をとらわれる事なく、ソフトウェア開発に集中することができます。
すでに肩こりや腱鞘炎に悩んでいる場合も、 ErgoDox を使うことで軽減させられる余地があります。</p>
<p>超オスでなくとも、左右セパレートしているキーボードであるところの ErgoDox の恩恵に十分預かることができます (参考: <a class="reference external" href="http://nippondanji.blogspot.jp/2016/02/ergodox.html">漢(オトコ)のコンピュータ道: あの超オスもセパレート式キーボードを使ってるらしい(ErgoDoxじゃないけど)</a> )。
医者には低体重といわれ、 CT スキャンを撮れば皮下脂肪がほとんど無いと言われた、このわたしでもです。</p>
<p>そんな感じで、 ErgoDox は本当によい買い物でした。
なお、 ErgoDox EZ は会社においてきたため、この記事を書くために使っているキーボードは Happy Hacking Keyboard であることは秘密です。</p>
<p>こちらからは以上です。</p>
</div>
2016 年 3 月まとめ2016-04-08T00:00:00+09:002016-04-08T00:00:00+09:00yosida95tag:yosida95.com,2016-04-08:/2016/04/08/monthly_report.html<p>こんばんは yosida95 です。
危う …</p><p>こんばんは yosida95 です。
危うく3月分のまとめを書き忘れるところでした。
3月を振り返っていきます。</p>
<div class="section" id="section-2">
<h2>やったこと</h2>
<ul class="simple">
<li>8日<ul>
<li>歯科医院に行った</li>
</ul>
</li>
<li>9日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/28">yosida95/golang-jenkins#28</a> をマージした</li>
</ul>
</li>
<li>14日<ul>
<li>内科医院に行った</li>
<li>Microservices Casual Talks に行った</li>
</ul>
</li>
<li>16日<ul>
<li>歯科医院に行った</li>
</ul>
</li>
<li>18日<ul>
<li><a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> と焼き肉に行った</li>
</ul>
</li>
<li>22日<ul>
<li>内科医院に行った</li>
</ul>
</li>
<li>23日<ul>
<li>CT スキャンをした</li>
</ul>
</li>
<li>26日<ul>
<li>美容院に行った</li>
</ul>
</li>
<li>28日<ul>
<li>内科医院に行った</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/29">yosida95/golang-jenkins#29</a> をマージした</li>
</ul>
</li>
<li>30日<ul>
<li>歯科医院に行った</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-3">
<h2>所感</h2>
<div class="section" id="section-4">
<h3>病院</h3>
<p>3月は病院に行ってばかりでした。</p>
<p>歯科は歯の痛みを感じて診察してもらった所、初回は原因は分からないけれど噛みあわせだと思うから調整すると歯を削られ、それで治らなかった2回目では10年くらい前の治療痕が原因かも知れないと言われて歯を削られました。
3回目では、2回目に削った箇所に詰め物を詰められました。
今のところ2回目の診断が正しかったようで、快方に向かっています。</p>
<p>内科の初回は咳と発熱、湿疹、呼吸が苦しいといった複数の症状をまとめて診察してもらうために行きました。
それぞれ独立した異なる原因だと思っていましたが、診断はすべてアレルギーで説明がつくと言われ、血液サンプルを採った後、複数種類の内服薬と気管支拡張パッチと軟膏を処方されました。
2回目ではアレルギー検査の結果を説明してもらいました。
やはり様々なアレルゲンに反応していて、過去に別の医院で受けたアレルギー検査の結果と比較すれば少し改善しているけれど、大抵の場合25歳あたりでぶり返して酷くなるから覚悟しておいてと脅されました。</p>
<p>また別件で、半年前から継続しているものの別の医院では触診で問題ないと言われた、腹部の内側の痛みについて相談しました。
今回の診察でも、別の医院の診察と同様問題無いとは思うけれど、不安を解消するためにも念のためということで CT 検査をすることになりました。
2日後に紹介状を持って CT 設備がある医院で CT スキャンを撮影してもらい、さらにその5日後に紹介元の医院で結果を説明してもらいました。
結果としては、内蔵には病変などの異常はないが、骨格はかなり珍しく、本来寸胴の様に並んでいる肋骨が、ぼくの場合は骨盤に向かうにつれて激しくくびれているため、内蔵の配置に余裕がなく、加えて低体重でクッションとなる皮下脂肪もほとんどついていないため、内臓やその周りの神経が圧迫されやすくなっていて、そのことが痛みの原因とみて間違いないと言われました。
低体重を改善して皮下脂肪を増やせば、皮下脂肪がクッションの役割をして痛みは和らぐだろうが、脂肪を増やすことが健康によいとは言えないので難しい、根本的にはなんともならないからそういうものだと思って付き合ってくれとのことでした。</p>
<p>このような感じで、病院に行ってばかりの3月は、診察料と多量の薬によって支出自体とと支出に占める医療費の割合が愉快な感じになりました。
しかし、いろいろ検査してもらった結果、今後も健康に生きていけそうだということが分かりました。</p>
</div>
<div class="section" id="oidong1">
<h3>oidong1 と肉を食べた</h3>
<p>ぼくが社会人になった頃からこれまでの2年間、振り返ってみれば oidong1 とは四半期に一度くらいのペースで、焼肉や寿司、天ぷらなどを食べに行っています。
今回も27年度が終わるタイミングだったので、年度を締めていくぞという思いで焼き肉を食べに行きました。</p>
<blockquote>
<p>oidong 「相談事において、男性は相手に解決策を、女性は相手に同情を求めると言うが、俺だって同情が欲しい」</p>
<p>yosida95 「悩み事の解決策は自力で導くから、解決の過程で出てしまったゴミを分かち合いたい」</p>
</blockquote>
<p>だいたいこんな感じの会合です。</p>
<p>oidong1 と面識ができたのは2011年8月で、ぼく達が高校1年生の時でした。
それから4年半が経過してそれぞれの環境も変化してきましたが、お互いに成長しながらよい友人関係を築けていると思います。</p>
<p>帰り際に次回の話もしたので、また2016年の第一四半期が終わる頃に開催するんだと思います。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>おわりに</h2>
<p>以上、2016年3月の月報でした。
4月も頑張っていくぞ。</p>
</div>
2016 年2 月まとめ2016-03-06T00:00:00+09:002016-03-06T00:00:00+09:00yosida95tag:yosida95.com,2016-03-06:/2016/03/06/monthly_report.html<p>こんにちは yosida95 です。
少し …</p><p>こんにちは yosida95 です。
少し遅くなりましたが、今月も月報を書きます。</p>
<div class="section" id="section-2">
<h2>やったこと</h2>
<ul class="simple">
<li>1日<ul>
<li><a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> 正式提供開始</li>
</ul>
</li>
<li>8日<ul>
<li>休暇</li>
</ul>
</li>
<li>9日<ul>
<li>休暇</li>
<li>成人式で再会した友人たちと遊んだ</li>
</ul>
</li>
<li>18日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/26">yosida95/golang-jenkins#26</a> をマージ</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/27">yosida95/golang-jenkins#27</a> をマージ</li>
</ul>
</li>
<li>26日<ul>
<li>yosida95 歴11年目に突入</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-3">
<h2>所感</h2>
<p>8日と9日に休暇を取ったことで、土日と合わせて4連休になりました。
8日は役所を回ったり翌日に備えて部屋を片付けたりして、9日は成人式で再会した友達と遊びました。
充実した完全によい4日間でした。</p>
<p><a class="reference external" href="https://github.com/yosida95/golang-jenkins">yosida95/golang-jenkins</a> には今月も Pull Request があり、うち2本をマージしました。
来た Pull Request は問題なさそうであれば基本マージしてしまうので、そろそろコードの秩序を取り戻すための作業が必要だなと思いつつ、まだ手を出せていません。</p>
<p>そして、26日には yosida95 歴11年目に突入しました。
2006年2月26日に、当時10歳だったぼくがオンラインゲームサイトに登録するために名乗ったハンドルネームが yosida95 でした。</p>
</div>
<div class="section" id="section-4">
<h2>最後に</h2>
<p>3月もいつも通りやっていきます。</p>
</div>
2016 年 1 月まとめ2016-02-02T00:00:00+09:002016-02-02T00:00:00+09:00yosida95tag:yosida95.com,2016-02-02:/2016/02/02/monthly-report.html<p>こんばんは yosida95 です。
2016年も月報を書きます。
よ …</p><p>こんばんは yosida95 です。
2016年も月報を書きます。
よろしくおねがいします。</p>
<p>2016年初回の月報は <a class="reference external" href="https://www.gehirn.jp/">Gehirn Infrastructure Services</a> の正式リリース準備に追われていつもより少し遅くなりました。</p>
<div class="section" id="section-2">
<h2>やったこと</h2>
<ul class="simple">
<li>5日<ul>
<li>仕事始め</li>
</ul>
</li>
<li>11日<ul>
<li>成人式</li>
<li>同窓会</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-3">
<h2>所感</h2>
<p>成人式に参加してきました。
成人式は前日まで朝起きられたら参加しようというスタンスでいて、当日はギリギリ間に合わないくらいの時間に目を覚ましたのですが、前日馴染みの美容師さんに参加することを勧められたことを思い出して急いで準備して間に合わせました。</p>
<p>前世での行いが悪かったので18歳から年金や各種税金を収めてきましたが、成人式を経たことでこれににてようやく社会から社会人のひとりとしての承認を得られたということになりました。</p>
<p>参加してみれば参加してみたで、小学生のときの友達と12年ぶりに再開したり、友達の慣れない晴れ着姿を見られたりと、なかなかに有意義なものでした。</p>
<p>ぼくの服装は普段着に加えてネクタイを絞めジャケットを羽織ったのですが、友達からは普段着かよとツッコまれました。
もともと普段着で参加する予定でしたが、夜から予定されている同窓会では「成人式に参加するようなフォーマルな格好」というドレスコードが設定されていたので、それを受けて少しだけフォーマルっぽくした上で、成人式に参加するという既成事実を作っておきました。</p>
<p>成人式は午前中で終わりましたが、式の後は中学生の時に間毎日のように連んでいた友達3人とお昼ごはんを食べに行き、その後もその内のひとりが運転する車で近所を回りながら同窓会まで時間を潰していました。
彼らとの会話には独特の空気感や言い回しがあったのですが、それが未だに健在で5年ぶりという感じは一切なく、土日挟んだ週明けの感じだとみんなして言い合いました。</p>
<p>同窓会はホテルの宴会場を借りて中学の同窓生50人ほどが集まって開催されました。
5年ぶりに話す友達との会話は楽しく、また意外な職業に就いている人や、すでに配偶者や子がいる人などがいて、5年前との違いに濃く人生を感じました。</p>
<p>終電の関係から残念ながらぼくは二次会が終わって帰ったのですが、それでもここ数年で最も楽しい時間を過ごせました。
成人式から二次会が終わるまで、12時間くらいずっと喋り続けていたら案の定喉がダメになって、翌々日までまともに声がでない状況が続きました。</p>
<p>数人の友達とは2月中にまた集まって遊ぶという約束をしたので、とても楽しみです。</p>
</div>
<div class="section" id="section-4">
<h2>おわりに</h2>
<p>2016年も頑張るぞい!</p>
</div>
2015 年 12 月まとめ2015-12-31T00:00:00+09:002015-12-31T00:00:00+09:00yosida95tag:yosida95.com,2015-12-31:/2015/12/31/monthly_report.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/11/30/memoir-201511.html">2015 年 11 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>6日<ul>
<li><a class="reference external" href="http://eventdots.jp/event/573121">Go Conference 2015 Winter</a> で登壇</li>
</ul>
</li>
<li>18日<ul>
<li>「<a class="reference external" href="https://yosida95.com/2015/12/18/gehirn_dns_api_spec.html">Gehirn DNS API 仕様</a>」を公開</li>
</ul>
</li>
<li>22日<ul>
<li>会社の忘年会に参加</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<p>こうして振り返ると、今月は「やったこと」に書けることがいつにもまして少ない月でした。
仕事ではいろいろやっているのですが、休日は Netflix に無限に時間を吸われました。
とにかく「 BONES 」「 Prison Break 」「 Leverage 」が面白く、休日はもちろん平日もほぼ毎日欠かさず観ていたら他の事が手につきませんでした。</p>
<div class="section" id="go-conference-2015-winter">
<h3>Go Conference 2015 Winter</h3>
<p>ただ、久しぶりに対外発表として Go Conference 2015 Winter に登壇しました。</p>
<script async class="speakerdeck-embed" data-id="fe2293c9637b46a6bf718eff4c6b7c19" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script><p>ただ、準備に割ける時間が少なく準備不足の状態だったので、もう少し技術的な詳細や詳しいことをお話できればよかったのですが、それは叶わず全体的なふわっとしたことしか共有できませんでした。
次回はもう少し詳細な話ができるように調整していこうと思います。</p>
<p>発表の後は懇親会に加え有志二次会まで参加して来ました。
勉強会の後の懇親会に参加することも久しぶりで、以前から知っている方にご挨拶したり、面白そうな方に話しかけてみたりしました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/gocon?src=hash">#gocon</a> with <a href="https://twitter.com/enneff">@enneff</a> <a href="https://t.co/uTGJvV9R0T">pic.twitter.com/uTGJvV9R0T</a></p>— Taichi Nakashima (@deeeet) <a href="https://twitter.com/deeeet/status/673501435451990016">December 6, 2015</a></blockquote></div>
</div>
<div class="section" id="section-5">
<h2>おわりに</h2>
<p>気づけば、今年始めた月報を1年間完走することができました。
月報を書くことは自分にとってよい影響があったので、2016年も続けていこうと思います。</p>
<p>そうそう、1月11日の成人の日ですが、居住する千代田区から成人式への招待状が届いたことでぼくが新成人であることを認識しました。
千代田区には19歳から住み始めて知り合いがいなくてどうしようかと思って調べたら、出身中学がある区の成人式にも出席できるらしいことが分かりました。
朝早く起きないといけなくて厳しいのですが、一生に一度の機会なので、朝起きることができたら参加してこようと思っています。</p>
<p>以上です。
来年も頑張るぞい!</p>
</div>
yosida95 の 2015 年まとめ2015-12-31T00:00:00+09:002015-12-31T00:00:00+09:00yosida95tag:yosida95.com,2015-12-31:/2015/12/31/yearly_report.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
年末感が一切ありませんが、早いもので今年もつつがなく終わろうとしています。</p>
<p>例年同様、今年もこの1年を振り返ってみようと思います。</p>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2014/12/29/130000.html">yosida95 の 2014 年まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/12/31/111207.html">yosida95 の2013年を振り返る</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">2012 年にぼくがさせていただいたこと</a></li>
<li><a class="reference external" href="https://yosida95.com/2011/12/31/235927.html">2011年が終わるね!!</a></li>
<li><a class="reference external" href="https://yosida95.com/2010/12/31/115758.html">2010 年</a></li>
</ul>
</div>
<div class="section" id="section-2">
<h2>やったこと</h2>
<p>今年にやったことで印象深いものを幾つか上げていきます。</p>
<div class="section" id="section-3">
<h3>月報を書き始めた</h3>
<p>まず、月報を書き始めたのは今年からでした。
三日坊主で知られるぼくがこうして1年欠かさずに月報を完走できたことに我ながら感心しています。</p>
<p>月報を書くことで、年単位ではなくて月単位で振り返ることで、記憶が鮮明なうちに行動や思考の反省ができ、短いタームで修正や向上に取り組むことができました。</p>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2015/02/02/122434.html">2015 年 1 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/03/04/110000.html">2015 年 2 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/03/31/110000.html">2015 年 3 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/04/30/130000.html">2015 年 4 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/05/31/123000.html">2015 年 5 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/06/30/113000.html">2015 年 6 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/07/31/220000.html">2015 年 7 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/08/31/120000.html">2015 年 8 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/09/30/120000.html">2015 年 9 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/10/31/200000.html">2015 年 10 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/11/30/memoir-201511.html">2015 年 11 月まとめ</a></li>
<li><a class="reference external" href="https://yosida95.com/2015/12/31/monthly_report.html">2015 年 12 月まとめ</a></li>
</ul>
</div>
<div class="section" id="gehirn-infrastructure-services">
<h3>Gehirn Infrastructure Services をリリースした</h3>
<p>4月1日にはぼくが所属する<a class="reference external" href="https://www.gehirn.co.jp">ゲヒルン</a>が <a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> をリリースしました。
この日の事やぼくがどのように Gehirn Infrastructure Services に取り組んできたかについては「<a class="reference external" href="https://yosida95.com/2015/04/01/173000.html">Gehirn Infrastructure Services の Public Preview 開始によせて</a>」に書いています。</p>
<p><a class="reference external" href="https://youtu.be/tOWZB9tFgu8">自宅サーバーで VPS サービスを作った</a> り、 chroot や jail で分離したホスティングサービスの検討をしたりなど、もともと個人的な趣味として高校生のときに遊んでいたインフラストラクチャ、とりわけホスティングの領域に今や仕事として取り組んでいて、こうして対外的にお見せするものがあるということを嬉しく思います。</p>
<p>また、そもそも中学生の時に存在を知り漠然と憧れていた <a class="reference external" href="https://twitter.com/isidai">@isidai</a> さんが創業したゲヒルンで彼と一緒に働いていること、そしてぼくの能力を評価してもらえていることに達成感を感じています。
今では「社内で一番の天才です」と外部の方には紹介されています。</p>
</div>
<div class="section" id="nhk">
<h3>NHK の番組に出演した</h3>
<p><a class="reference external image-reference" href="http://yosida95.com/photos/32xZE.raw.png"><img alt="ニッポンのジレンマ" src="https://yosida95.com/photos/32xZE.resized.png" style="width: 100%;" /></a></p>
<p>「<a class="reference external" href="http://www.nhk.or.jp/jirenma/20150829.html">ニッポンのジレンマ</a>」という番組です。
ぼくの姿が NHK で放送されるとしたら、他人の PC を遠隔操作する事件を起こした後に猫カフェで遊んでいる姿ぐらいだと思っていたので、まさか討論番組に出演するとは思っていませんでした。</p>
<p>しかし我が家にはテレビがないので、放送をリアルタイムで視聴することは叶いませんでした。</p>
</div>
<div class="section" id="erlang">
<h3>Erlang を始めた</h3>
<p>8月に Erlang を学び直し始めました。
そして、10月からは仕事でも Erlang を使い始めるようになり、今では日常生活で書くコードの3割程度が Erlang です。</p>
<p>ようやく流暢に指先から Erlang が流れ出てくるようになりましたが、 Python 3 と Go 言語、そして Erlang を書き分ける日があり、このような日は思考のスイッチにエネルギーを持って行かれて厳しい感じがあります。</p>
</div>
<div class="section" id="section-4">
<h3>分散システム</h3>
<p>もともと高校生の時に <a class="reference external" href="http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf">Amazon Dynamo ペーパー</a>を読んで Consistent Hashing や Gossip Algorithms の実装をした事はあったのですが、そこ止まりで実際にそれらを使って分散システムを作る事は殆どありませんでした。</p>
<p>しかし今年になって InfluxDB や etcd が目につき、そこで使われている Raft というコンセンサスアルゴリズムに興味を持ったことから分散システムを学び始めました。</p>
<p>今回は前回と違って、アルゴリズム単体を追ったのではなく、実際に使われているソフトウェアから Deep Dive した点、また得た知識をすぐに適用できる問題があったことから熱が覚めずに続けられています。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>所感</h2>
<p>2015年はインプットが質・量ともに向上した年でした。
それは、 SMTP を実装するために RFC を読みまくっていたら技術文書程度の英語なら苦なく読めるようになったこと、インプットの量を意図的に増やすことで情報の取捨選択が上手にならざるを得ない状況を作ったことによるものだと感じています。</p>
<p>2016年もこの調子で着実に堅実に精進していこうと思います。</p>
</div>
<div class="section" id="section-6">
<h2>おわりに</h2>
<p>最後になりましたが、今年一年ぼくに関わって下さった皆さまには大変お世話になりました。
この場を借りてお礼申し上げます。
ありがとうございました。</p>
<p>来年も変わらぬご高配を賜れますよう、よろしくおねがいします。</p>
</div>
Gehirn DNS API 仕様2015-12-18T00:00:00+09:002015-12-18T00:00:00+09:00yosida95tag:yosida95.com,2015-12-18:/2015/12/18/gehirn_dns_api_spec.html<div class="section" id="section-1">
<h2>追記</h2>
<p><a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社 …</a></p></div><div class="section" id="section-1">
<h2>追記</h2>
<p><a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社</a>として公式に Gehirn DNS を含む <a class="reference external" href="https://support.gehirn.jp/apidocs/">Gehirn Web Services API Documentation</a> を公開したので、今後はそちらを参照して下さい。
今後、この非公式ドキュメントはメンテナンスしません。</p>
</div>
<div class="section" id="section-2">
<h2>はじめに</h2>
<p>このドキュメントは、<a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社</a>が Public Preview で提供している <a class="reference external" href="https://www.gehirn.jp/gis/dns.html">Gehirn DNS</a> の API 仕様を説明するものです。
ただし、これはゲヒルン株式会社として提供する公式なドキュメントではなく、あくまでも個人として、公式のドキュメントが公開されるまでの期間、暫定的に公開するものです。</p>
<p>また、ここで説明する仕様は、<a class="reference external" href="http://support.gehirn.jp/information/maintenance/2015/12/17/1185/">2015年12月21日17時に予定しているメンテナンス</a>が終了した後に有効となります。</p>
</div>
<div class="section" id="api">
<h2>API 仕様</h2>
<dl class="docutils">
<dt>Root endpoint</dt>
<dd><a class="reference external" href="https://api.gis.gehirn.jp/dns/v1">https://api.gis.gehirn.jp/dns/v1</a></dd>
<dt>Content-Type</dt>
<dd>application/json</dd>
<dt>Authentication</dt>
<dd>API キーを用いた Basic 認証</dd>
</dl>
<div class="section" id="section-3">
<h3>認証</h3>
<p>すべてのリクエストで認証が必要となります。
認証様式は、 API キーのトークンを usreid 、シークレットセールを password とする Basic 認証です。</p>
<p>API キーは<a class="reference external" href="https://gis.gehirn.jp/">コントロールパネル</a>から発行することができます。
また、リクエストに用いる API キーには適切な権限が設定されている必要があります。</p>
<p>Gehirn DNS の操作で必要になる権限は [DNS] -> [全般管理] -> [ゾーン] と [DNS] -> [ドメイン] -> [操作対象のゾーン] で、それぞれ読み取り以上が必要です。
読み取りは HTTP Verb の GET に、フルアクセスは HTTP Verb の GET に加え、 POST 、 PUT 、そして DELETE に対応します。</p>
</div>
<div class="section" id="section-4">
<h3>リクエスト</h3>
<p>API を用いて行える操作は以下に示すとおりです。
行いたい操作に合わせて、 Root endpoint と当該 Path からなるエンドポイントに対して、当該 HTTP Verb を用いたリクエストを行って下さい。</p>
<p>リクエストボディが必要な場合は、当該 JSON Schema に適合する形式の JSON を送信して下さい。
なお、この場合 <cite>Content-Type: application/json</cite> リクエストヘッダーが必要となります。</p>
</div>
<div class="section" id="section-5">
<h3>ゾーン</h3>
<div class="section" id="json-schema">
<h4>JSON Schema</h4>
<div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"name"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">4</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"current_version_id"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"current_version"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"name"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">255</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<table border="1" class="docutils">
<colgroup>
<col width="28%" />
<col width="46%" />
<col width="25%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">フィールド</th>
<th class="head">意味</th>
<th class="head">リクエスト時要否</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>id</td>
<td>ゾーンを特定する一意な ID</td>
<td>不要</td>
</tr>
<tr><td>name</td>
<td>ドメイン名</td>
<td>必要</td>
</tr>
<tr><td>current_version_id</td>
<td>現在アクティブなバージョンの ID</td>
<td>不要</td>
</tr>
<tr><td>current_version</td>
<td>現在アクティブなバージョン</td>
<td>不要</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="section-6">
<h4>ゾーンの作成</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones</cite></dd>
<dt>HTTP Verb</dt>
<dd>POST</dd>
<dt>Request Body</dt>
<dd>必要</dd>
</dl>
<p><strong>リクエスト例</strong></p>
<div class="highlight"><pre><span></span><span class="nf">POST</span> <span class="nn">/dns/v1/zones</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">api.gis.gehirn.jp</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="na">Authorization</span><span class="o">:</span> <span class="l">Basic dG9rZW46c2VjcmV0</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yaml.jp"</span>
<span class="p">}</span>
</pre></div>
<p><strong>レスポンス例</strong></p>
<div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
<span class="na">Server</span><span class="o">:</span> <span class="l">nginx</span>
<span class="na">Date</span><span class="o">:</span> <span class="l">Fri, 18 Dec 2015 10:41:01 GMT</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json; charset=UTF-8</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">388</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"92e52aab-81ac-4c87-b659-b7b36e05cb7f"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yaml.jp"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"current_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"234b6f0e-8b64-4cd9-8647-16cd26133266"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"current_version"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"234b6f0e-8b64-4cd9-8647-16cd26133266"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"editable"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"\u6700\u521d\u306e\u30d0\u30fc\u30b8\u30e7\u30f3"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2015-03-05T10:49:04Z"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"last_modified_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2015-03-05T10:49:04Z"</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="section-7">
<h4>ゾーンのリストの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-8">
<h4>ゾーンの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-9">
<h4>ゾーンの削除</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>DELETE</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
</div>
<div class="section" id="section-10">
<h3>バージョン</h3>
<div class="section" id="json-schema-1">
<h4>JSON Schema</h4>
<div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"name"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">255</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<table border="1" class="docutils">
<colgroup>
<col width="27%" />
<col width="46%" />
<col width="27%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">フィールド</th>
<th class="head">意味</th>
<th class="head">リクエスト時要否</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>id</td>
<td>バージョンを特定する一意な ID</td>
<td>不要</td>
</tr>
<tr><td>name</td>
<td>任意のバージョン名</td>
<td>必要</td>
</tr>
<tr><td>editable</td>
<td>編集可否</td>
<td>不要</td>
</tr>
<tr><td>created_at</td>
<td>バージョン作成時刻</td>
<td>不要</td>
</tr>
<tr><td>last_modified_at</td>
<td>バージョン最終更新時刻</td>
<td>不要</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="section-11">
<h4>バージョンの作成</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions</cite></dd>
<dt>HTTP Verb</dt>
<dd>POST</dd>
<dt>Request Body</dt>
<dd>必要</dd>
</dl>
<p><strong>リクエスト例</strong></p>
<div class="highlight"><pre><span></span><span class="nf">POST</span> <span class="nn">/dns/v1/zones/234b6f0e-8b64-4cd9-8647-16cd26133266/versions</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">api.gis.gehirn.jp</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="na">Authorization</span><span class="o">:</span> <span class="l">Basic dG9rZW46c2VjcmV0</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"新しいバージョン"</span>
<span class="p">}</span>
</pre></div>
<p><strong>レスポンス例</strong></p>
<div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
<span class="na">Server</span><span class="o">:</span> <span class="l">nginx</span>
<span class="na">Date</span><span class="o">:</span> <span class="l">Fri, 18 Dec 2015 10:41:01 GMT</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json; charset=UTF-8</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">218</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"f66504b0-bb65-4766-9d7c-18c4e8406071"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"editable"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"\u65b0\u3057\u3044\u30d0\u30fc\u30b8\u30e7\u30f3"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2015-12-18T10:49:13Z"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"last_modified_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2015-12-18T10:49:13Z"</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="section-12">
<h4>バージョンリストの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-13">
<h4>バージョンの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-14">
<h4>バージョンの編集</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>PUT</dd>
<dt>Request Body</dt>
<dd>必要</dd>
</dl>
</div>
<div class="section" id="section-15">
<h4>バージョンの削除</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>DELETE</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
</div>
<div class="section" id="section-16">
<h3>レコードセット</h3>
<div class="section" id="json-schema-2">
<h4>JSON Schema</h4>
<div class="highlight"><pre><span></span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">36</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"name"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">5</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"enable_alias"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"boolean"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"alias_to"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"ttl"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minimum"</span><span class="o">:</span><span class="w"> </span><span class="mf">30</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maximum"</span><span class="o">:</span><span class="w"> </span><span class="mf">2147483647</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"records"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"array"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"minItems"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"items"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"prio"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minimum"</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maximum"</span><span class="o">:</span><span class="w"> </span><span class="mf">32767</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"address"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">3</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">39</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"cname"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"exchange"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"nsdname"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"target"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">256</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"port"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minimum"</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maximum"</span><span class="o">:</span><span class="w"> </span><span class="mf">65535</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"weight"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minimum"</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maximum"</span><span class="o">:</span><span class="w"> </span><span class="mf">65535</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="s2">"data"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"minLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"maxLength"</span><span class="o">:</span><span class="w"> </span><span class="mf">64000</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<table border="1" class="docutils">
<colgroup>
<col width="18%" />
<col width="50%" />
<col width="32%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">フィールド</th>
<th class="head">意味</th>
<th class="head">リクエスト時要否</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>id</td>
<td>レコードセットを特定する一意な ID</td>
<td>不要</td>
</tr>
<tr><td>name</td>
<td>ホストネーム</td>
<td>必要</td>
</tr>
<tr><td>type</td>
<td>レコードタイプ (A, AAAA, CNAME, MX, NS, SRV, TXT)</td>
<td>必要</td>
</tr>
<tr><td>enable_alias</td>
<td>エイリアス機能利用</td>
<td>必要</td>
</tr>
<tr><td>alias_to</td>
<td>エイリアス先 (エイリアス機能利用時)</td>
<td>enable_alias が true の時のみ</td>
</tr>
<tr><td>ttl</td>
<td>TTL</td>
<td>enable_alias が false の時のみ</td>
</tr>
<tr><td>records</td>
<td>レコードのリスト</td>
<td>enable_alias が false の時のみ</td>
</tr>
<tr><td>records.prio</td>
<td>Priority</td>
<td>type が MX または SRV の時のみ</td>
</tr>
<tr><td>records.address</td>
<td>IPv4 または IPv6 アドレス</td>
<td>type が A または AAAA の時のみ</td>
</tr>
<tr><td>records.cname</td>
<td>CNAME</td>
<td>type が CNAME の時のみ</td>
</tr>
<tr><td>records.exchange</td>
<td>メールサーバーのドメインネーム</td>
<td>type が MX の時のみ</td>
</tr>
<tr><td>records.nsdname</td>
<td>ネームサーバーのドメインネーム</td>
<td>type が NS の時のみ</td>
</tr>
<tr><td>records.target</td>
<td>ターゲットのドメインネーム</td>
<td>type が SRV の時のみ</td>
</tr>
<tr><td>records.port</td>
<td>ターゲットのポート番号</td>
<td>type が SRV の時のみ</td>
</tr>
<tr><td>records.weight</td>
<td>ターゲットの重み</td>
<td>type が SRV の時のみ</td>
</tr>
<tr><td>records.data</td>
<td>TXT データ</td>
<td>type が TXT の時のみ</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="section-17">
<h4>レコードセットの作成</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id/records</cite></dd>
<dt>HTTP Verb</dt>
<dd>POST</dd>
<dt>Request Body</dt>
<dd>必要</dd>
</dl>
<p><strong>リクエスト例</strong></p>
<div class="highlight"><pre><span></span><span class="nf">POST</span> <span class="nn">/dns/v1/zones/234b6f0e-8b64-4cd9-8647-16cd26133266/versions/f66504b0-bb65-4766-9d7c-18c4e8406071/records</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">api.gis.gehirn.jp</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="na">Authorization</span><span class="o">:</span> <span class="l">Basic dG9rZW46c2VjcmV0</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yaml.jp."</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"ttl"</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"enable_alias"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"records"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="s2">"192.0.2.10"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="s2">"192.0.2.11"</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
<p><strong>レスポンス例</strong></p>
<div class="highlight"><pre><span></span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="ne">OK</span>
<span class="na">Server</span><span class="o">:</span> <span class="l">nginx</span>
<span class="na">Date</span><span class="o">:</span> <span class="l">Fri, 18 Dec 2015 10:41:01 GMT</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json; charset=UTF-8</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">218</span>
<span class="p">{</span>
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"e590d62a-3676-4b08-832a-a1fdd6dfefdf"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yaml.jp."</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"enable_alias"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"ttl"</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"records"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"192.0.2.10"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"192.0.2.11"</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="section-18">
<h4>レコードセットリストの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id/records</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-19">
<h4>レコードセットの取得</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id/records/:record_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>GET</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
<div class="section" id="section-20">
<h4>レコードセットの編集</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id/records/:record_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>PUT</dd>
<dt>Request Body</dt>
<dd>必要</dd>
</dl>
</div>
<div class="section" id="section-21">
<h4>レコードセットの削除</h4>
<dl class="docutils">
<dt>Path</dt>
<dd><cite>/zones/:zone_id/versions/:version_id/records/:record_id</cite></dd>
<dt>HTTP Verb</dt>
<dd>DELETE</dd>
<dt>Request Body</dt>
<dd>不要</dd>
</dl>
</div>
</div>
</div>
2015 年 11 月まとめ2015-11-30T00:00:00+09:002015-11-30T00:00:00+09:00yosida95tag:yosida95.com,2015-11-30:/2015/11/30/memoir-201511.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
今後ブログは yosida95.com で書いていきます。</p>
<p>今月分の月報です。
先月分は <a class="reference external" href="https://yosida95.com/2015/10/31/200000.html">2015 年 10 月まとめ</a> です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>1日<ul>
<li>出張先の宮崎県から東京に帰ってきた</li>
</ul>
</li>
<li>9日<ul>
<li><a class="reference external" href="http://eventdots.jp/event/573121">Go Conference 2015 Winter</a> にセッションが採択された</li>
</ul>
</li>
<li>15日<ul>
<li>新しい本棚を購入した</li>
</ul>
</li>
<li>23日<ul>
<li>15日に購入した本棚が届いた</li>
</ul>
</li>
<li>24日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/19">yosida95/golang-jenkins#19</a> をマージ</li>
</ul>
</li>
<li>25日<ul>
<li><a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> と天ぷらを食べた</li>
</ul>
</li>
<li>29日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/20">yosida95/golang-jenkins#20</a> をマージ</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="section-5">
<h3>本棚を買った</h3>
<p>本の前に二段に本を並べたり、本の上に本を積んだり、本棚の天板の上に本を積んだりしても溢れてきていた折、父が家に遊びに来るとのことだったので、運搬を手伝ってもらう目論見で一緒に本棚を購入しにいきました。</p>
</div>
<div class="section" id="go-conference-2015-winter">
<h3>Go Conference 2015 Winter</h3>
<p>採択発表の日を数日過ぎていたので落選したかと思っていたのですが、連絡が遅れていただけで、無事に採択していただくことができました。
「 Go が支えるインフラストラクチャサービス」というタイトルで、ぼくが所属するゲヒルンが提供する <a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> について20分ほどお話してきます。</p>
<p>ちょうど29日の夜から発表用資料を作っていたのですが、明け方までかかっても完成しなかったので、今週は資料の続きをコツコツ作っていくことになりそうです。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>おわりに</h2>
<p>以上です。
来月も頑張るぞい!</p>
</div>
2015 年 10 月まとめ2015-10-31T00:00:00+09:002015-10-31T00:00:00+09:00yosida95tag:yosida95.com,2015-10-31:/2015/10/31/200000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/09/30/120000.html">2015 年 9 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>3日<ul>
<li>東京スカイツリータウンに行った</li>
</ul>
</li>
<li>9日<ul>
<li>蒼樹うめ展に行った</li>
</ul>
</li>
<li>18日<ul>
<li>次世代 Web カンファレンスに参加した</li>
</ul>
</li>
<li>30日<ul>
<li>宮崎県にある株式会社アラタナに来た</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="section-5">
<h3>スカイツリータウン</h3>
<p>東京に住んでいながら初めてスカイツリータウンに遊びに行きました。
すみだ水族館を見て回ったあとスカイツリーの展望台に上りました。
展望台のチケットを事前に Web で取って置いたら、エレベーター以外では一切並ぶ事なく上れました。</p>
<p>チケットの入場時間帯をその日の日没の頃にあわせて取ったところ、一周目は夕方と夜のグラデーションが、二周目は街の灯りや車の往来がそれぞれ美しかったです。
一緒に行った子にも目論見通り喜んでもらえて嬉しかったのですが、自分にとっても想像以上に楽しかったです。</p>
</div>
<div class="section" id="web">
<h3>次世代 Web カンファレンス</h3>
<p>1,000 人以上が申し込んだ<a class="reference external" href="http://nextwebconf.connpass.com/event/19699/">次世代 Web カンファレンス</a>でしたが、運良く抽選に当たったので行ってきました。
10時から開演ということで、普段正午くらいから働き始めるぼくにとって朝起きられるかという心配がありましたが、ぼくが住んでいる千代田区にある会場で開催されるということもあり、なんとか遅れずに参加できました。</p>
<p>聴講したセッションは、 server_pref 、 server_arch 、 security 、 identity 、 monitoring と趣味と仕事を兼ねたチョイスをしました。
server_arch は上西さんのお話を目当てに選んだところ当日都合がつかなかったということでお話を聴けなくて残念でしたが、後日ご本人がブログ記事で当日お話しされたかったことを列挙されていたので、満足しました。</p>
<p>どのセッションでも話されている内容や方向性はだいたいぼくの肌感と合っていて、ちゃんと未来のある方角へ進んで行けているということを確認できました。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>宮崎にきた</h2>
<p>ぼくが所属するゲヒルンの親会社である株式会社アラタナに出張しています。
30日の飛行機で宮崎入りし、このエントリも宮崎のホテルで書いています。
30日のアラタナはオフィス内に大量の魚の鯖が置かれいて、とても生臭かったです。</p>
</div>
<div class="section" id="section-7">
<h2>その他</h2>
<p>今月はずっと Erlang を書いていました。</p>
<p>もともと、8月は毎日の業務時間の冒頭を使って「<a class="reference external" href="http://www.amazon.co.jp/dp/4274067149">プログラミング Erlang</a>」(通称、飛行機本) を一章から二章ずつ読み直すことで Erlang を学びなおすという取り組みを趣味半分仕事半分で勝手にやっていました。</p>
<p>そして、9月下旬にプロダクトコードを Erlang で書き始めるということを、ぼくひとりだけのチームなのでぼくの裁量で決めて、そのまま10月はずっと Erlang で仕事をしていました。
最初はたどたどしくて Build-in Funcations や stdlib のドキュメントを調べながら書いていたのですが、今では無事に Erlang が指先から流れ出てくるようになりました。</p>
<p>余談ですが、ぼくがまだ高校生でゲヒルンの非常勤職員だった頃、初めて Go
を採用すると決まった時も、3日かけて言語仕様と言語の流儀を標準ライブラリのソースコードリーディングなどを通して学び、その後は本番開発をしながらスキルを高めていく中で指先から流れ出てくるようになったので、なんだか懐かしい気持ちになっています。</p>
<p>以上です。
来月も頑張るぞい。</p>
</div>
2015 年 9 月まとめ2015-09-30T00:00:00+09:002015-09-30T00:00:00+09:00yosida95tag:yosida95.com,2015-09-30:/2015/09/30/120000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/08/31/120000.html">2015 年 8 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>3日<ul>
<li>「<a class="reference external" href="http://news.gehirn.jp/security/652/">Debian Security Announcements の不正な DKIM 署名が修正されました</a>」を公開</li>
</ul>
</li>
<li>13日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/14">yosida95/golang-jenkins#14</a> をマージ</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/15">yosida95/golang-jenkins#15</a> をマージ</li>
</ul>
</li>
<li>16日<ul>
<li><a class="reference external" href="http://unixtime.jp/">unixtime.jp</a> を作った</li>
</ul>
</li>
<li>18日<ul>
<li>「<a class="reference external" href="http://news.gehirn.jp/security/717/">新しくなった Gehirn DNS のエイリアス機能を使う</a>」を公開</li>
<li>「<a class="reference external" href="http://news.gehirn.jp/dev/727/">旧 Gehirn DNS から新しい Gehirn DNS へ移転する</a>」を公開</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="unixtime-jp-uuid-jp">
<h3>unixtime.jp と uuid.jp</h3>
<p><a class="reference external" href="http://unixtime.jp">unixtime.jp</a> というドメインが空いていることに気づいたので、アクセスすると現在の時刻を Unix Time で返すだけのウェブサービスを30分くらいで作りました。
ソースコードは <a class="reference external" href="https://github.com/yosida95/unixtime.jp">yosida95/unixtime.jp</a> で公開しています。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>curl<span class="w"> </span>unixtime.jp
</pre></div>
<p>を実行すると現在の unixtime が返ってきて便利です。</p>
<p>似たコンセプトのウェブサービスとして <a class="reference external" href="http://uuid.jp">uuid.jp</a> があります。
こちらはアクセスする度に異なる UUIDv4 をレスポンスしてくれます。
このサービスも、ぼくがコードを書いて運用しています。
ドメインはぼくが所属するゲヒルンで登録しているものです。</p>
<p>これらのサービスは権威 DNS を <a class="reference external" href="https://www.gehirn.jp/gis/dns.html">Gehirn DNS</a> でホスティングしていて、サーバーも <a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">Gehirn RS2 Plus</a> を使っています。
Web は Gehirn RS2 Plus の TCP + WSGI モードを使い、デーモンプロセス管理・監視機能で立ち上げている uWSGI にリバースプロキシすることで運用しています。</p>
<p>他のサービスにはない機能がウェブサービスの運用を便利にしてくれていて理想的なドッグフーディングをできています。
自画自賛になりますが、とても便利です。</p>
<p><a class="reference external" href="https://yosida95.com/2015/04/01/173000.html">Gehirn Infrastructure Services の Public Preview 開始によせて</a></p>
</div>
<div class="section" id="gehirn-news">
<h3>Gehirn News</h3>
<p>今月は3本記事を書きました。
そのうち1本はぼくが smtpd をフルスクラッチした <a class="reference external" href="https://www.gehirn.jp/gis/mta.html">Gehirn MTA</a> の運用中に気づいた Debian Security Announcements の問題について、2本はぼくが開発した新しい <a class="reference external" href="https://www.gehirn.jp/gis/dns.html">Gehirn DNS</a> についてのものでした。</p>
</div>
<div class="section" id="yosida95-golang-jenkins">
<h3>yosida95/golang-jenkins</h3>
<p>ここのところ毎月 <a class="reference external" href="https://github.com/yosida95/golang-jenkins">yosida95/golang-jenkins</a> に Pull Request が来ていて、ちゃんと使われているんだなぁと感じています。
しかし、オーナーのぼくはここの所 Jenkins を使っておりません。</p>
</div>
</div>
2015 年 8 月まとめ2015-08-31T00:00:00+09:002015-08-31T00:00:00+09:00yosida95tag:yosida95.com,2015-08-31:/2015/08/31/120000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/07/31/220000.html">2015 年 7 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>1日<ul>
<li>ゲヒルン社内ハッカソンに参加した</li>
</ul>
</li>
<li>10日<ul>
<li><a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> と寿司を食べた</li>
</ul>
</li>
<li>11日<ul>
<li><a class="reference external" href="http://www.nhk.or.jp/jirenma/">新世代が解く! ニッポンのジレンマ</a>という番組の公開収録に論客として参加した</li>
</ul>
</li>
<li>12日<ul>
<li><a class="reference external" href="http://twitter.com/grapswiz">@grapswiz</a> さんと「ジュラシックワールド」を観たりした</li>
</ul>
</li>
<li>13日<ul>
<li>高校の同窓生と後輩、「ニッポンのジレンマ」の公開収録で出会った大学生とご飯を食べた</li>
</ul>
</li>
<li>16日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/8">golang-jenkins#8</a> をマージした</li>
</ul>
</li>
<li>20日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/9">golang-jenkins#9</a> をマージした</li>
</ul>
</li>
<li>21日 - 22日<ul>
<li>YAPC::Asia Tokyo に最初で最後の参加</li>
</ul>
</li>
<li>23日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/10">golang-jenkins#10</a> をマージした</li>
</ul>
</li>
<li>24日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/11">golang-jenkins#11</a> をマージした</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/12">golang-jenkins#12</a> をマージした</li>
</ul>
</li>
<li>29日<ul>
<li>「ニッポンのジレンマ」の放送日だった</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="section-5">
<h3>夏休み</h3>
<p>ゲヒルンの夏季休暇に重ねる形で有給をとったため、土日を含めて8日から16日までの長い休みとなりました。
普段の土日だとインターネッツの面白記事を共有したり雑談に参加したりするために
Slack を開いてしまいますが、今度の夏季休暇では一切 Slack
を開かない、一切のメンションを無視するためにメール通知を切るという自分縛りをしました。
それに加え、ありがたいことに、夏季休暇申請時点では公開収録以外に何も無かった予定が次から次に埋まりました。
おかげで、完全なオフとなりとてもリフレッシュできた気がします。</p>
</div>
<div class="section" id="yapc-asia-tokyo">
<h3>YAPC::Asia Tokyo</h3>
<p>夏休みが明けた週の金曜日には会社に行かず
YAPC::Asia Tokyo
に最初で最後の参加をしてきました。
主にインフラ系のセッションをずっと聴いていましたが、裏でやっているどのセッションも興味を惹かれるものでとても楽しかったです。
また、あれほど多くの人が参加して活気に満ちていること、お弁当の提供や高品質の同時通訳など、ホスピタリティの高さにも驚かされました。
しばらく会っていなかった方や、インターネットでしか知らない方にも挨拶ができて、まさに同窓会と言った感じでした。</p>
<p>2日目に「<a class="reference external" href="http://yapcasia.org/2015/talk/show/5ccd78be-4879-11e5-ad76-8fe87d574c3a">21世紀の E-Mail</a>」というタイトルで、 Golang で商用 MTA を実装する話をしたいと LT を申し込みましたが、残念ながら落選してしまいました。</p>
</div>
<div class="section" id="section-6">
<h3>ニッポンのジレンマ</h3>
<p>ロボットクリエイターで高校の同窓生でもある <a class="reference external" href="http://twitter.com/nanaju_">@nanaju_</a> の紹介によって、ぼくに出演のオファーがありました。
ぼくの姿が NHK で放送されるとしたら、他人の PC を遠隔操作する事件を起こした後に猫カフェで遊んでいる姿ぐらいだと思っていたので、これはよい経験になりそうだと思って参加してきました。</p>
<p>オーディエンスとして公開収録に参加していた小学校の同級生と数年ぶりに話をしたり、プロの方にメイクをしていただいたり、実際にとてもよい経験となりました。
テレビの出演者は男性でもメイクをされるという噂は真実でしたし、それだけではなく収録が終わった後は丁寧に落としていただけるという知見も得られました。</p>
<p>中学校の生徒会副会長時代やピアノ発表会、プログラミングカンファレンスでの講演経験など大勢の前で何かをするという経験は人より多いので緊張することはないだろうと思っていて、実際に収録中に緊張しているという自覚も無かったのですが、反省をすると普段ならもっと面白い返しができた質問があったり、脳内で組み立てた話の流れが落ちて導入部分で終えてしまうなど、明らかにパフォーマンスが落ちていたので緊張していたことに気付きました。</p>
<p>なお、<a class="reference external" href="http://www.nhk.or.jp/jirenma/20150829.html">論客プロフィール</a>で使われているぼくのプロフィール写真は、ゲヒルン社内ハッカソンの会場で <a class="reference external" href="http://twitter.com/umisama">@umisama</a> に撮っていただいたものです。
ありがとうございました。
つまり @umisama は NHK に採用されたこともある写真家です。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">マメ知識ですが、よしだ先生のプロフィール写真は僕が撮影したものなので今後は「NHKに採用されたこともある写真家」と名乗っていきます。</p>— うみさま (@umisama) <a href="https://twitter.com/umisama/status/629875658307407872">August 8, 2015</a></blockquote><p>今月の月報は以上です。
来月も頑張るぞい!</p>
</div>
</div>
2015 年 7 月まとめ2015-07-31T00:00:00+09:002015-07-31T00:00:00+09:00yosida95tag:yosida95.com,2015-07-31:/2015/07/31/220000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/06/30/113000.html">2015 年 6 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>3 日<ul>
<li>6月27日に購入した iPad mini 3 を受け取った</li>
</ul>
</li>
<li>8 日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins">yosida95/golang-jenkins</a> に来た <a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/6">PullRequest#6</a> をマージした</li>
</ul>
</li>
<li>20 日<ul>
<li><a class="reference external" href="https://github.com/yosida95/python-jsonrpc">yosida95/python-jsonrpc</a> のトランスポーターに response_encoding パラメーターを追加した</li>
</ul>
</li>
<li>27 日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/07/25/120000.html">/etc/shadow などで使われるハッシュ関数、 crypt(3) を Go 言語で実装しました</a>を公開した</li>
</ul>
</li>
<li>31 日<ul>
<li>社内ハッカソンに参加した</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>まとめ</h2>
<p>今月は大した事をしていない気がします。</p>
<p><a class="reference external" href="https://github.com/yosida95/golang-jenkins">yosida95/golang-jenkins</a> は自分が欲しかった部分だけ実装して公開しておいた所、各位が思い思いの機能を実装して Pull Request をくださったおかげで機能が増えてきました。</p>
<p><a class="reference external" href="https://github.com/yosida95/python-jsonrpc">yosida95/python-jsonrpc</a> は JSON-RPC 2.0 のクライアント実装で、既存のライブラリがトランスポート層に HTTP を使うことしか考慮していないことについカッとして作った、 TCP socket や Unix Domain Socket をトランスポート層に使えるライブラリでしたが、現在では <a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">Gehirn RS2 Plus</a> の重要な部分を担っています。</p>
<p><a class="reference external" href="https://github.com/GehirnInc/crypt">GehirnInc/crypt</a> は以前から公開しているライブラリですが、この度バグフィックスをしてリライセンスしました。
このライブラリも、 <a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">Gehirn RS2 Plus</a> で利用しています。</p>
<p>こちらからは以上です。
来月も頑張るぞい!</p>
</div>
/etc/shadow などで使われるハッシュ関数、 crypt(3) を Go 言語で実装しました2015-07-25T00:00:00+09:002015-07-25T00:00:00+09:00yosida95tag:yosida95.com,2015-07-25:/2015/07/25/120000.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
UNIX や Linux ではユーザーパスワードのハッシュ関数として crypt(3) が使われています。
この crypt(3) を Pure Go で実装したのでご紹介します。</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/GehirnInc/crypt">GehirnInc/crypt</a></li>
</ul>
</div>
<div class="section" id="section-2">
<h2>経緯</h2>
<p>もともとは <a class="reference external" href="https://github.com/jeramey/go-pwhash">jeramey/go-pwhash</a> という実装があり、こちらの開発が滞っていたため、 <a class="reference external" href="https://github.com/kless">kless</a> 氏がフォークした kless/crypt で開発が行われていました。</p>
<p>この kless/crypt に存在したいくつかのバグを修正するために、昨年の春に Pull Request を送ってマージしてもらったのが、ぼくの crypt 開発の始まりです。</p>
<p>今年になって再び kless/crypt に幾つものバグを見つけたためパッチを送ろうと思った所、 kless/crypt がレポジトリごと消えていました。</p>
<p>jeramey/go-pwhash の開発は前述のとおり滞っていて、 jeramey/go-pwhash はコピーレフト条項のない修正 BSD ライセンスで配布されていました。</p>
<p>それらを踏まえて、この度ぼくが乗っ取って開発を継続することにしました。
そして、ぼくがこれまでに見つけたバグの修正がすべて終わりましたので、ここにご報告させていただきました。</p>
</div>
<div class="section" id="section-3">
<h2>実績</h2>
<p>この <a class="reference external" href="https://github.com/GehirnInc/crypt">GehirnInc/crypt</a> は、 <a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">Gehirn RS2 Plus</a> というサービスですでにプロダクション利用しています。</p>
</div>
<div class="section" id="section-4">
<h2>おわりに</h2>
<p><a class="reference external" href="https://github.com/GehirnInc/crypt">GehirnInc/crypt</a> は修正 BSD ライセンスのオープンソースソフトウェアです。
不具合などのご報告やパッチをお待ちしています。</p>
<p>よろしくお願いします。</p>
</div>
2015 年 6 月まとめ2015-06-30T00:00:00+09:002015-06-30T00:00:00+09:00yosida95tag:yosida95.com,2015-06-30:/2015/06/30/113000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
20 歳になりました。
今月も月報を書きます。
先月分は<a class="reference external" href="https://yosida95.com/2015/05/31/123000.html">2015 年 5 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>2日-3日<ul>
<li>AWS Summit Tokyo に参加</li>
</ul>
</li>
<li>7日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/06/07/220000.html">SMTP で使われる Sender Policy Framework (SPF) のマクロを使う</a>を書いた</li>
</ul>
</li>
<li>16日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/06/16/123000.html">20歳になりました</a></li>
</ul>
</li>
<li>26日<ul>
<li>誕生日休暇の振替休日をとった</li>
</ul>
</li>
<li>27日<ul>
<li>むしゃくしゃして <a class="reference external" href="https://github.com/yosida95/timetable">yosida95/timetable</a> を書いた</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="aws-summit-tokyo">
<h3>AWS Summit Tokyo</h3>
<p>AWS Summit Tokyo では Developper Conference をひたすら聴講していました。
セッションもさることながらホスピタリティの高さに感動しました。
ノベルティとして頂いたステンレスのカップはオフィスで常用しています。</p>
</div>
<div class="section" id="section-5">
<h3>20歳になりました</h3>
<p>今月、ついに20歳になりました。
Amazon の<a class="reference external" href="http://www.amazon.co.jp/registry/wishlist/3B4Y3FGMQHMV5?sort=priority">ほしいものリスト</a> から誕生日プレゼントを贈ってくださった皆さん、本当にありがとうございました。
改めてお礼申し上げます。</p>
<p>また、昨年同様、誕生日プレゼントは誕生日の364日後まで受け付けています。
よろしくお願い致します。</p>
<ul class="simple">
<li><a class="reference external" href="http://www.amazon.co.jp/registry/wishlist/3B4Y3FGMQHMV5?sort=priority">わたしのほしいものリスト</a></li>
</ul>
</div>
<div class="section" id="yosida95-timetable">
<h3>yosida95/timetable</h3>
<p>数年前からインターネットラジオのものを含むラジオ番組を録音するシステムを運用していて、ラジオ番組を録りだめて来たのですが、春の改編に追随することを忘れ、録音ライブラリが壊滅的な被害を受けていました。</p>
<p>録音スケジュールを組み直すにあたり、番組表を眺めながら手で入力することは人間の仕事ではないことに気付き、スケジュールを crontab で吐き出すコマンド <a class="reference external" href="https://github.com/yosida95/timetable/tree/master/cmd/tt-filter">tt-filter</a> を含むライブラリを書きました。
それが、 <a class="reference external" href="https://github.com/yosida95/timetable">yosida95/timetable</a> です。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>おわりに</h2>
<p>以上です。
ありがとうございました。
来月も頑張るぞい!</p>
</div>
20歳になりました2015-06-16T00:00:00+09:002015-06-16T00:00:00+09:00yosida95tag:yosida95.com,2015-06-16:/2015/06/16/123000.html<p>こんにちは、 yosida95 です。
20歳になりました。
ほ …</p><p>こんにちは、 yosida95 です。
20歳になりました。
ほしいものリストは<a class="reference external" href="http://www.amazon.co.jp/registry/wishlist/3B4Y3FGMQHMV5?sort=priority">こちら</a>です。</p>
<p>ふと、小学4年生、10歳の時に総合的な学習の時間のカリキュラムで、誕生から10歳までをまとめた自分史という文集を作ってたことを思い出しました。
懐かしくなって読み返したところ、将来の夢について「弁護士になって、人のためになる仕事がしたい。」と書いていました。</p>
<p>この頃のことはよく覚えていて、小学2年生の時にクラスメートから受け取った年賀状の中で「昼休みに裁判ごっこをするのはやめて欲しい」という苦情を書かれるくらいには、法曹界へのあこがれがありました。</p>
<p>また、この文集の中に20歳になったぼく自身へ向けた手紙もあって、これによると10年前のぼくは弁護士になるために東京大学法学部に進学していて、もしかするとすでに司法試験に合格しているかもしれないと信じて疑っていなかったようです。</p>
<p>さて、それから10年。
20歳を迎えたぼくは大学には進学せずに、工業高校を卒業した後、在学中からアルバイトをしていた小さなベンチャー企業でソフトウェアエンジニアをしています。
10歳当時のぼくには、それこそ夢にも思わなかった現実で、実に人生はままならないものだと思います。</p>
<p>もっとも、夢や目標というものは環境の変化や周囲からの刺激、テレビの影響だとかで移り変わるもので、小学校の卒業文集には「将来はウェブクリエイターになる」と書いていました。
少し職種は違えど IT 業界で働こうという8年来の夢は遂げられました。</p>
<p>人生はよく坂道に例えられますが、ぼくが思うにその頂点は30代にあって、これからの10年はそこへ向かって着実に歩みを進めていこうと思います。
そんな次の10年に向けて新たに定めた目標があります。</p>
<p>それは、おもしろお兄さんになるというものです。
社会を舐めた若者になるという目標と迷ったのですが、すでに半分以上達成していると思いますし、経年劣化して社会を舐めたおっさんにはなりたくないという思いがあったので、こちらの目標に定めました。</p>
<p>末筆ながら、ぼくが今こうして毎日を何事もなく過ごせているのは周囲の皆さんの生暖かい目あってこそのものだと思います。
本当にありがとうございます。
20代に突入したぼくにも、旧来と変わらぬご高配を賜りたく存じます。
今後ともよろしくお願い致します。</p>
<p>ほしいものリストは<a class="reference external" href="http://www.amazon.co.jp/registry/wishlist/3B4Y3FGMQHMV5?sort=priority">こちら</a>です。</p>
SMTP で使われる Sender Policy Framework (SPF) のマクロを使う2015-06-07T00:00:00+09:002015-06-07T00:00:00+09:00yosida95tag:yosida95.com,2015-06-07:/2015/06/07/220000.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、気 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、気づけば 20 歳の誕生日が9日後に迫っていた yosida95 です。
ご存知のように、私は商用 SMTP サーバーをフルスクラッチして、現在もその運用を行っています。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">Gehirn MTA が穏やかではないのは、ぼくが SMTP サーバーを golang でフルスクラッチしたという点です</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/580718274897260544">March 25, 2015</a></blockquote><p><a class="reference external" href="https://yosida95.com/2015/04/01/173000.html">Gehirn Infrastructure Services の Public Preview 開始によせて</a></p>
<p>この記事では、その経験から <a class="reference external" href="https://tools.ietf.org/html/rfc7208">Sender Policy Framework</a> (SPF) の verifier を書いている過程で知ったマクロ機能をご紹介します。</p>
</div>
<div class="section" id="spf">
<h2>SPF とは</h2>
<div class="section" id="section-2">
<h3>目的</h3>
<p>メールサーバーを運用したり、あるいは Google Apps や Amazon SES などを利用している方などはご存知だと思いますが、 SPF とは <strong>ドメインの所有者が、そのドメインからのメールを送信するメールサーバーを宣言する</strong> するための仕組みです。
この宣言を行うことで、メールを受信したメールサーバーは、受け取ったメールがドメイン所有者から送信元として認証を受けたメールサーバーから送られたものであるかどうかを確認できます。
もし確認できない場合は、送信者を偽ったスパムメールである可能性が高いと判断して、リジェクトすることができます。</p>
</div>
<div class="section" id="section-3">
<h3>仕組み</h3>
<p>送信元メールサーバーの宣言はメール送信者が DNS に、自身のドメインの TXT レコードを追加することで行います。
メールを受信したメールサーバーは、送信者が SMTP の MAIL FROM で名乗ったメールアドレス (envelope from) のドメインの TXT レコードを参照し、その記述内容によって送信元メールサーバーが認証を受けているかどうかを確認します。
メッセージの From ヘッダー、あるいは Sender ヘッダーで宣言されているメールアドレスと envelope from は必ずしも一致しない事に留意が必要です。</p>
</div>
<div class="section" id="section-4">
<h3>記述の方法</h3>
<p>SPF の記述は、4つの演算子と8つのメカニズムを組み合わせたディレクティブを並べることによって行います。
メカニズムと演算子はそれぞれ、ディレクティブがマッチする条件と、マッチした場合の送信者の評価結果を表します。</p>
<p>各メカニズムと各演算子の説明は以下で行いますが、例えば <tt class="docutils literal">+ip4:192.0.2.100</tt> というディレクティブがあった場合、送信者の IP アドレスが 192.0.2.100 であればドメイン所有者から認証を受けた正当な送信者して扱います。</p>
<p>ディレクティブは左から右へと評価され、評価の途中でも一致するメカニズムが見つかった場合にはそこで評価が終了します。</p>
<div class="section" id="section-5">
<h4>演算子</h4>
<table border="1" class="docutils">
<caption>表1. SPF の演算子</caption>
<colgroup>
<col width="15%" />
<col width="85%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">演算子</th>
<th class="head">意味</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>+</td>
<td>認証を受けた送信者として扱う (pass)</td>
</tr>
<tr><td>~</td>
<td>認証を受けた送信者として扱わない (softfail)</td>
</tr>
<tr><td><ul class="first last simple">
<li></li>
</ul>
</td>
<td>認証を受けた送信者として扱わない (fail)</td>
</tr>
<tr><td>?</td>
<td>認証を受けた送信者であるかどうかを確認しない (neutral)</td>
</tr>
</tbody>
</table>
<p>表1に SPF で使える演算子の一覧を示しました。
送信可否に併記したものは内部的な評価結果で、注目すべきは softfail と fail の違いです。
softfail と fail はどちらも認証を受けた送信者としては扱われませんが、 softfail のほうが fail よりも意味合いが弱く、メールサーバーの設定によっては softfail のメールは受け取るが、 fail のメールは受け取らないとなっている場合があります。</p>
</div>
<div class="section" id="section-6">
<h4>メカニズム</h4>
<table border="1" class="docutils">
<caption>表2. SPF のメカニズム</caption>
<colgroup>
<col width="7%" />
<col width="59%" />
<col width="34%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">メカニズム</th>
<th class="head">マッチする条件</th>
<th class="head">引数要否</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>all</td>
<td>すべての場合</td>
<td>不要</td>
</tr>
<tr><td>include</td>
<td>引数で渡されたドメインの SPF レコードを評価して pass になった場合</td>
<td>必要</td>
</tr>
<tr><td>a</td>
<td>引数で渡されたドメインを正引き (A/AAAA) 結果の IP アドレスが送信者と一致する場合</td>
<td>検証中のドメインが暗黙的に使われるため不要だが、指定することも可能</td>
</tr>
<tr><td>mx</td>
<td>引数で渡されたドメインの MX レコードに指定されたメールサーバーを正引きした結果の IP アドレスが送信者と一致する場合</td>
<td>検証中のドメインが暗黙的に使われるため不要だが、指定することも可能</td>
</tr>
<tr><td>ip4</td>
<td>引数で渡された IPv4 アドレスが送信者と一致する場合</td>
<td>必要</td>
</tr>
<tr><td>ip6</td>
<td>引数で渡された IPv6 アドレスが送信者と一致する場合</td>
<td>必要</td>
</tr>
<tr><td>exists</td>
<td>引数で渡されたドメインに A レコード ( IPv6 によって接続を受けたとしても) が存在する場合</td>
<td>必要</td>
</tr>
<tr><td>ptr
Do not use</td>
<td>引数で渡されたドメインが検証済みドメイン <a class="footnote-reference" href="#verified-domain" id="footnote-reference-1">[1]</a> か、そのサブドメインである場合</td>
<td>検証中のドメインが暗黙的に使われるため不要だが、指定することも可能</td>
</tr>
</tbody>
</table>
<p>表2に SPF で使われるメカニズムの一覧と、それぞれメカニズムが使われる条件を示しました。
ptr は、参照する DNS レコードの数がほかよりも多いことや、 arpa ルートサーバーにクエリが集中することなどから Do not use とされていることに注意してください。</p>
<p>また、 a, mx, ip4, ip6 では CIDR 形式で IP アドレスの範囲を表現することもできます。</p>
<table class="docutils footnote" frame="void" id="verified-domain" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>送信者の IP アドレスを逆引きして得られたドメインのうち、それを正引きした結果が送信者の IP アドレスと一致するもの</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="section" id="section-7">
<h2>マクロ</h2>
<p>SPF 自体の説明が長くなりましたが、ここからが本題です。
メカニズムの説明を見る限りでは、ドメイン単位でしか認証できない様な印象を受けると思います。
また、マクロを説明している文章は珍しいため、 RFC に当たらない限りそのように勘違いしている方も多くいらっしゃるものと想像します。</p>
<p>しかし、 SPF にはマクロという仕組みが定義されていて、これを使うことによって実に細かく SPF の評価結果を制御することができます。</p>
<table border="1" class="docutils">
<caption>表3. SPF で使用できるマクロの一覧</caption>
<colgroup>
<col width="10%" />
<col width="90%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">マクロ</th>
<th class="head">展開される結果</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>%{s}</td>
<td>送信者が SMTP の MAIL FROM コマンドで名乗ったメールアドレス</td>
</tr>
<tr><td>%{l}</td>
<td>%{s} の @ よりも左側の部分 (メールアドレスのアカウント部分、ローカルパートという)</td>
</tr>
<tr><td>%{o}</td>
<td>%{s} の @ よりも右側の部分 (メールアドレスのドメイン部分)</td>
</tr>
<tr><td>%{d}</td>
<td>評価中の SPF レコードが設定されているドメイン</td>
</tr>
<tr><td>%{i}</td>
<td>IPv4 の場合は 8bit ずつ10進数で、 IPv6 の場合は 4bit ずつ16進数で表現し、各パートを "." で連結した送信者の IP アドレス</td>
</tr>
<tr><td>%{p}
Do not use</td>
<td>%{i} を逆引きした結果のドメイン</td>
</tr>
<tr><td>%{v}</td>
<td>%{c} が IPv4 アドレスの場合は "in-addr", IPv6 アドレスの場合は "ipv6" という文字列</td>
</tr>
<tr><td>%{h}</td>
<td>送信者が SMTP の HELO/EHLO コマンドで名乗ったドメイン</td>
</tr>
<tr><td>%{c}</td>
<td>送信者の IP アドレス</td>
</tr>
<tr><td>%{r}</td>
<td>SPF 検証を行っているメールサーバーのドメイン</td>
</tr>
<tr><td>%{t}</td>
<td>現在のタイムスタンプ</td>
</tr>
</tbody>
</table>
<p>表3に SPF で使用できるマクロの一覧を示しました。
これも %{p} が ptr メカニズムと同様の理由で Do not use となっていることに注意してください。</p>
<p>これらのマクロを含んだ文字列を各メカニズムの引数として渡してやることで、実に多彩で手の込んだ設定ができるということは想像に難くないと思います。</p>
<div class="section" id="r">
<h3>r トランスフォーマー</h3>
<p>また、マクロには "r" トランスフォーマーというものも定義されています。
これは、各マクロの値を "." で区切ってリバースさせるというもので、例えば IPv4 アドレスの場合 <tt class="docutils literal"><span class="pre">%{ir}.%{v}.arpa</span></tt> という文字列を評価すると、そのまま逆引き時のクエリを導くことができます。
デフォルトでは "." で区切られますが、マクロの閉じカーリーブレイスの直前に区切り文字を指定すればその文字列で区切ったものをリバースし、 "." でつなぎあわせたものが得られます。</p>
</div>
<div class="section" id="section-8">
<h3>スライス</h3>
<p>さらに、マクロの値を "." で区切ったパーツのうち、先頭から何個までを使うかを指定することもできます。
クライアントの IPv4 アドレスが 192.0.2.200 の時に <tt class="docutils literal">%{l3}</tt> を評価すると <tt class="docutils literal">192.0.2</tt> を得ることができます。
r トランスフォーマー同様、区切り文字を指定することもできます。</p>
</div>
<div class="section" id="section-9">
<h3>マクロの例</h3>
<p>送信者が名乗ったメールアドレスが <a class="reference external" href="mailto:strong-bad@email.example.com">strong-bad@email.example.com</a> で、送信者の IP アドレスが IPv4 の場合 192.0.2.3 、 IPv6 の場合は 2001:db8::cb01 で、送信者の IP アドレスを逆引きした結果が mx.example.org の場合の例を <a class="reference external" href="https://tools.ietf.org/html/rfc7208#section-7.4">RFC7208 Sender Policy Framework §7.4</a> より引用して以下に示します。</p>
<pre class="literal-block">
macro expansion
------- ----------------------------
%{s} strong-bad@email.example.com
%{o} email.example.com
%{d} email.example.com
%{d4} email.example.com
%{d3} email.example.com
%{d2} example.com
%{d1} com
%{dr} com.example.email
%{d2r} example.email
%{l} strong-bad
%{l-} strong.bad
%{lr} strong-bad
%{lr-} bad.strong
%{l1r-} strong
macro-string expansion
--------------------------------------------------------------------
%{ir}.%{v}._spf.%{d2} 3.2.0.192.in-addr._spf.example.com
%{lr-}.lp._spf.%{d2} bad.strong.lp._spf.example.com
%{lr-}.lp.%{ir}.%{v}._spf.%{d2}
bad.strong.lp.3.2.0.192.in-addr._spf.example.com
%{ir}.%{v}.%{l1r-}.lp._spf.%{d2}
3.2.0.192.in-addr.strong.lp._spf.example.com
%{d2}.trusted-domains.example.net
example.com.trusted-domains.example.net
IPv6:
%{ir}.%{v}._spf.%{d2} 1.0.b.c.0.0.0.0.
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6._spf.example.com
</pre>
</div>
</div>
<div class="section" id="spf-1">
<h2>SPF を設定する上で注意する点</h2>
<p>SPF を設定する上で気をつけていただきたい点として、 DoS 攻撃に対応するためひとつの SPF レコードを評価するために発行できる DNS クエリの数が制限されているということがあります。
そのため、ディレクティブをたくさん並べて凝った設定をしても、左側のいくつかしか使われていなかったり、あるいはエラーとして評価自体されていないということがあります。
<a class="reference external" href="https://tools.ietf.org/html/rfc7208#section-4.6.4">RFC7208 Sender Policy Framework §4.6.4</a> ではメカニズム毎に細かく発行できる DNS クエリの上限が決められています。
多くの場合、この制限は厳しすぎるため緩める設定が行われていると思いますが、それでも制限は存在するので気をつけてください。</p>
</div>
<div class="section" id="section-10">
<h2>おわりに</h2>
<p>マクロを使うことによって如何に詳細に SPF レコードを設定することがお分かりいただけたかと思います。</p>
<p>読み返してみて気づいたのですが、 SPF の modifier に関する説明が抜けていました。
特に exp modifier は SPF の検証に失敗した場合のメール送信者への通知を自然言語で設定するための機構で、マクロを存分に活用できます
興味があれば RFC7208 を調べてみてください。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">smtpd の運用を適切に行うためには SMTP とその関連仕様への理解が不可欠で、それだけじゃく smtpd の複雑な設定や dovcot などとの連携にも気を使わなくてはいけないから絶対にオススメできない。商用 smtpd を書いて運用している今でもこの気持ちは変わらない。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/607444053811064832">June 7, 2015</a></blockquote><p>ありがとうございました。</p>
</div>
SSH 公開鍵ユーティリティを Go と Python で作った2015-05-31T00:00:00+09:002015-05-31T00:00:00+09:00yosida95tag:yosida95.com,2015-05-31:/2015/05/31/121709.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 NHK …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 NHK 技研公開に行った所、何度も「学生さんですか?」と訊かれた yosida95 です。</p>
<p>タイトルのとおり、 Pure Go と Pure Python で SSH 公開鍵ユーティリティを作ったのでご案内します。</p>
<dl class="docutils">
<dt>Go</dt>
<dd><a class="reference external" href="https://github.com/yosida95/golang-sshkey">yosida95/golang-sshkey</a></dd>
<dt>Python</dt>
<dd><a class="reference external" href="https://github.com/yosida95/python-sshkey">yosida95/python-sshkey</a></dd>
</dl>
</div>
<div class="section" id="ssh">
<h2>SSH 公開鍵ユーティリティ</h2>
<pre class="code literal-block">
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95
</pre>
<p>上に示したのが SSH 公開鍵で、ちなみに普段ぼくが使っているものです。
よく見るフォーマットだと思います。</p>
<p>この公開鍵は、目に見える通り3つのパートから成っていて、左からアルゴリズム、公開鍵、コメントとなっています。
また、2つめの公開鍵のパートは BASE64 エンコードされていて、デコードすると RSA の場合は "ssh-rsa", exponent (E), modulus (N) のように、アルゴリズムと公開鍵のパラメーターが含まれています。</p>
<p>今回作ったユーティリティでは、 Printable ASCII で表現される公開鍵をデコードし、コメントや鍵長を取得したり、フィンガープリント(鍵指紋)を計算したり、 golang-sshkey の場合は <a class="reference external" href="https://godoc.org/crypto/rsa">crypto/rsa</a> の *rsa.PublicKey のような標準的な構造体に変換したりできます。</p>
</div>
<div class="section" id="section-2">
<h2>インストール</h2>
<div class="section" id="golang-sshkey">
<h3>golang-sshkey</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>go<span class="w"> </span>get<span class="w"> </span>github.com/yosida95/golang-sshkey
</pre></div>
</div>
<div class="section" id="python-sshkey">
<h3>python-sshkey</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>sshkey
</pre></div>
</div>
</div>
<div class="section" id="section-3">
<h2>使い方</h2>
<div class="section" id="golang-sshkey-1">
<h3>golang-sshkey</h3>
<div class="highlight"><pre><span></span><span class="kn">package</span><span class="w"> </span><span class="nx">main</span>
<span class="kn">import</span><span class="w"> </span><span class="p">(</span>
<span class="w"> </span><span class="s">"crypto"</span>
<span class="w"> </span><span class="s">"crypto/rsa"</span>
<span class="w"> </span><span class="s">"fmt"</span>
<span class="w"> </span><span class="s">"github.com/yosida95/golang-sshkey"</span>
<span class="p">)</span>
<span class="kd">const</span><span class="w"> </span><span class="p">(</span>
<span class="w"> </span><span class="nx">marshaledPub</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95"</span>
<span class="p">)</span>
<span class="kd">func</span><span class="w"> </span><span class="nx">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">pubkey</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sshkey</span><span class="p">.</span><span class="nx">UnmarshalPublicKey</span><span class="p">(</span><span class="nx">marshaledPub</span><span class="p">)</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">nativePub</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">pubkey</span><span class="p">.</span><span class="nx">Public</span><span class="p">().(</span><span class="o">*</span><span class="nx">rsa</span><span class="p">.</span><span class="nx">PublicKey</span><span class="p">)</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">pubkey</span><span class="p">.</span><span class="nx">Type</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">sshkey</span><span class="p">.</span><span class="nx">KEY_RSA</span><span class="p">)</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">nativePub</span><span class="p">.</span><span class="nx">E</span><span class="p">)</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">pubkey</span><span class="p">.</span><span class="nx">Length</span><span class="p">())</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">pubkey</span><span class="p">.</span><span class="nx">Comment</span><span class="p">())</span>
<span class="w"> </span><span class="nx">fp</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sshkey</span><span class="p">.</span><span class="nx">PrettyFingerprint</span><span class="p">(</span><span class="nx">pubkey</span><span class="p">,</span><span class="w"> </span><span class="nx">crypto</span><span class="p">.</span><span class="nx">MD5</span><span class="p">)</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">fp</span><span class="p">)</span>
<span class="w"> </span><span class="c1">// Output:</span>
<span class="w"> </span><span class="c1">// true</span>
<span class="w"> </span><span class="c1">// 65537</span>
<span class="w"> </span><span class="c1">// 2048</span>
<span class="w"> </span><span class="c1">// yosida95@yosida95</span>
<span class="w"> </span><span class="c1">// 17:59:d1:53:0a:38:33:91:ff:8c:f8:f6:16:89:ed:f0</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="python-sshkey-1">
<h3>python-sshkey</h3>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">sshkey.public</span>
<span class="n">marshaled_pub</span> <span class="o">=</span> <span class="s1">'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95'</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">pub</span> <span class="o">=</span> <span class="n">sshkey</span><span class="o">.</span><span class="n">public</span><span class="o">.</span><span class="n">from_openssh</span><span class="p">(</span><span class="n">marshaled_pub</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">pub</span><span class="o">.</span><span class="n">type</span><span class="p">)</span> <span class="c1"># => sshkey.public.SSHKeyType.RSA</span>
<span class="nb">print</span><span class="p">(</span><span class="n">pub</span><span class="o">.</span><span class="n">length</span><span class="p">)</span> <span class="c1"># => 2048</span>
<span class="nb">print</span><span class="p">(</span><span class="n">pub</span><span class="o">.</span><span class="n">comment</span><span class="p">)</span> <span class="c1"># => yosida95@yosida95</span>
<span class="nb">print</span><span class="p">(</span><span class="n">pub</span><span class="o">.</span><span class="n">pretty_finger_print</span><span class="p">())</span> <span class="c1"># => 17:59:d1:53:0a:38:33:91:ff:8c:f8:f6:16:89:ed:f0</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="section-4">
<h2>実績</h2>
<p>実は今回作ったのは golang-sshkey の方だけで、 python-sshkey の方は半年前に作って公開していたものです。
この python-sshkey にはすでに、私が所属するゲヒルンが提供する <a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> の <a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">RS2 Plus</a> で使われているという実績があります。</p>
<p><a class="reference external image-reference" href="https://blogmedia.yosida95.com/2015/05/31/121709/added_publickey.png"><img alt="Gehirn RS2 Plus 公開鍵の管理" src="https://blogmedia.yosida95.com/2015/05/31/121709/added_publickey.png" style="width: 100%;" /></a>
<a class="reference external" href="http://news.gehirn.jp/dev/641/">[シリーズGWS]第4回 Gehirn RS2 Plus のアカウントを作り SSH でログインする</a></p>
<p>また、近々 golang-sshkey の方も同様に Gehirn RS2 Plus で利用する予定があります。</p>
</div>
<div class="section" id="section-5">
<h2>おわりに</h2>
<p>どちらのパッケージも3条項 BSD ライセンスで公開しています。
ご活用ください。
また、コントリビュートをお待ちしています。</p>
<p>こちらからは以上です。</p>
</div>
2015 年 5 月まとめ2015-05-31T00:00:00+09:002015-05-31T00:00:00+09:00yosida95tag:yosida95.com,2015-05-31:/2015/05/31/123000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。
今月も月報を書きます。
私は取り組みを習慣化できないことに定評がありますが、今年から始めた月報はこれで5本目です。
先月分は<a class="reference external" href="https://yosida95.com/2015/04/30/130000.html">2015 年 4 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>1日<ul>
<li>宮崎出張2日目</li>
</ul>
</li>
<li>2日<ul>
<li>東京へ戻ってきた</li>
</ul>
</li>
<li>7日<ul>
<li>アラン・チューリングの伝記映画であるイミテーションゲームを観た</li>
</ul>
</li>
<li>11日<ul>
<li><a class="reference external" href="http://news.gehirn.jp/dev/641/">[シリーズGWS]第4回 Gehirn RS2 Plus のアカウントを作り SSH でログインする</a> を書いた</li>
</ul>
</li>
<li>17日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/05/17/203841.html">VyOS で Policy Based Routing して複数の ISP を使い分ける</a>を書いた</li>
</ul>
</li>
<li>25 日<ul>
<li><a class="reference external" href="https://github.com/yosida95/python-jsonrpc">yosida95/python-jsonrpc</a> を公開した</li>
<li><a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> と焼き肉を食べた</li>
</ul>
</li>
<li>28 日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-sshkey">yosida95/golang-sshkey</a> を公開した</li>
</ul>
</li>
<li>30 日<ul>
<li>新宿バルト9で「這いよれ! ニャル子さん F 」初日舞台あいさつを鑑賞した</li>
<li>NHK 放送技術研究所で行われている「 NHK 技研公開」を見学した</li>
</ul>
</li>
<li>31 日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/05/31/121709.html">SSH 公開鍵ユーティリティを Go と Python で作った</a>を書いた</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<div class="section" id="section-5">
<h3>ゴールデンウィーク</h3>
<p>ゴールデンウィークはなかなか楽しめた。
<a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> の開発中が忙しかった時は、長期の休暇中でもどうしても仕事のことを考えてしまって、気づいたら調べ物したり仕事のコードを書いたりしていたので、このゴールデンウィークは絶対に仕事をしないということを目標にしていた。</p>
<p>その結果、料理をしたり、積読を片付けていったり、 Erlang の勉強を進めていったり、映画を観に行ったり、と充実の内容だった。
一週間ちょっとのゴールデンウィークだったが、気づいたらあっという間に終わっていた。</p>
</div>
<div class="section" id="yosida95-python-jsonrpc">
<h3>yosida95/python-jsonrpc</h3>
<p>必要に迫られて JSON-RPC の Python クライアントライブラリを調査した所、既存のすべてのライブラリが HTTP にペイロードを載せてやりとりすることしか想定されておらず、それ以外の方法に対応していなかった。
<a class="reference external" href="https://github.com/yosida95/python-jsonrpc">yosida95/python-jsonrpc</a> は、 <a class="reference external" href="https://docs.python.org/3.4/library/xmlrpc.client.html">xmlrpc.client</a> を参考に、 transport を差し替えることで HTTP に載せずとも RPC できるようになっている。</p>
</div>
<div class="section" id="yosida95-golang-sshkey">
<h3>yosida95/golang-sshkey</h3>
<p>これは Pure Go 実装の SSH 公開鍵ユーティリティで、フィンガープリントを計算したり、鍵長を取得したり、 BASE64 エンコードされている鍵を Go の標準ライブラリに定義されている構造体 ( 例えば、 <a class="reference external" href="https://godoc.org/crypto/rsa">crypto/rsa</a> の *rsa.Client ) に変換したりできる。</p>
<p>以前、同様のライブラリである <a class="reference external" href="https://github.com/gokyle/sshkey">gokyle/sshkey</a> にコントリビュートして DSA 鍵対応を追加したが、このライブラリには C のコードに依存していて、 Go の世界でクロスコンパイルできないという問題があったり、コードもあまり綺麗では無かったため、1から作り直すということをした。</p>
</div>
</div>
<div class="section" id="section-6">
<h2>おわりに</h2>
<p>以上です。
ありがとうございました。
来月も頑張るぞい!</p>
</div>
VyOS で Policy Based Routing して複数の ISP を使い分ける2015-05-17T00:00:00+09:002015-05-17T00:00:00+09:00yosida95tag:yosida95.com,2015-05-17:/2015/05/17/203841.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
先月4月26日の話なのですが、ブログエントリになっていなかったので、今になって書いてみます。</p>
<p><a class="reference external" href="https://yosida95.com/2014/09/19/083000.html">昨年の9月にひとり暮らしを始め</a> てから今まで、 WG1800HP で PPP してゲートウェイとして使ってきました。
しかし、定期的に具合が悪くなり PPP セッションが切れる事、足元には Xeon と Intel NIC を計4ポート積んだサーバーが眠っていてもったいないと感じていた事から、このサーバーを KVM で仮想化して、ソフトウェアルーターである VyOS をそのゲストとして動かすことで、 WG1800HP をタダの WiFi AP として運用することにしました。</p>
<div class="line-block">
<div class="line">今回組んだネットワークのネットワーク図は以下の通りです。</div>
<div class="line-block">
<div class="line"><a class="reference external image-reference" href="https://yosida95.com/photos/i2Vlz.raw.png"><img alt="ネットワーク図" src="https://yosida95.com/photos/i2Vlz.raw.png" style="width: 100%;" /></a></div>
</div>
</div>
<p>ここまでは実家に居たころと変わらず、 <a class="reference external" href="https://yosida95.com/2013/02/03/081842.html">2年以上前に前に書いた Vyatta の記事</a>ともほとんど変わらないのですが、自宅では2つの ISP と契約しています。
これを有効活用するため、今回は DMZ からインターネットへ出ていくパケットと、それ以外のネットワークからインターネットへ出て行くパケットのソースを分けることにしました。</p>
</div>
<div class="section" id="section-2">
<h2>設定例</h2>
<p>今回の設定をするにあたっていくらか検索してみたのですが、なかなか上手な設定をみつけられず、 if-pre-up などのフックを使って VyOS の世界から抜けてしまっているような例もあったため、必要な部分のみを抜粋したものを参考例としてここに書いておきます。</p>
<pre class="code literal-block">
interfaces {
ethernet eth0 {
pppoe 0 {}
pppoe 1 {}
}
ethernet eth1 {
address 172.16.10.1/24
}
ethernet eth2 {
address 172.16.20.1/24
}
ethernet eth3 {
address 172.16.30.1/24
}
}
nat {
source {
rule 10 {
outbound-interface pppoe1
translation {
address masquerade
}
}
rule 20 {
outbound-interface pppoe0
source {
address 172.16.10.0/24
}
translation {
address masquerade
}
}
}
}
policy {
route dmz {
rule 1 {
set {
table 1
}
source {
address 172.16.10.0/24
}
}
}
}
protocols {
static {
table 1 {
interface-route 0.0.0.0/0 {
next-hop-interface pppoe0 {
}
}
interface-route 172.168.20.0/24 {
next-hop-interface eth2 {
}
}
interface-route 172.168.30.0/24 {
next-hop-interface eth3 {
}
}
}
}
}
</pre>
<p>ポイントは、 <em>policy route dmz</em> で DMZ から出てきたパケットに対して、 <em>protocols static table 1</em> で定義しているルールをあてている点です。
このルールでは、既知の内部宛てのパケットは適切なインターフェースに、未知のアドレス宛てのパケットはデフォルトで使われる pppoe1 ではなく pppoe0 から出て行くようにルーティングを曲げています。</p>
<p>また、 DMZ でもそうでないネットワークも IP アドレスの数以上に端末が居るため、 nat セクションで NAPT してあげています。</p>
</div>
<div class="section" id="section-3">
<h2>終わりに</h2>
<p>遊んでいたサーバーをルーターにして、また MTU などの値を調整したことで、体感できるほどネットワークの品質が高くなり、ルーターが動いているということで24時間サーバーを落とせなくなって体感できるほど電気代が高くなり、このサーバーの排熱によって室温が体感できるほど高くなりました。</p>
<p>サーバーで遊んでいると yosida95VPS を作って運用していた頃のことを思い出し、とても楽しいです。
yosida95VPS は <a class="reference external" href="http://2012.pycon.jp/program/sessions.html#session-15-1100-room433-ja">2012年に PyCon JP で発表</a>して以降も、ゲストとして <a class="reference external" href="https://yosida95.com/2013/05/19/003744.html">Ubuntu のパッケージリポジトリミラー</a>を動かしたり、 L2TP/IPSec VPN サーバーが動いていたりと、現役です。</p>
<p>こちらからは以上です。</p>
</div>
<div class="section" id="section-4">
<h2>追記</h2>
<p>【2015-05-18 00:36 追記】ソースルーティングとポリシーベースルーティングを混同していたので、タイトルを変えました。</p>
</div>
2015 年 4 月まとめ2015-04-30T00:00:00+09:002015-04-30T00:00:00+09:00yosida95tag:yosida95.com,2015-04-30:/2015/04/30/130000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。
宮崎県宮崎市にあるアラタナに向かっています。
それでは今月も月報を書こうと思います。
先月分は<a class="reference external" href="https://yosida95.com/2015/03/31/110000.html">2015 年 3 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>1日<ul>
<li><a class="reference external" href="https://yosida95.com/2015/04/01/173000.html">Gehirn Infrastructure Services Public Preview を開始</a>した。ぼくがゲヒルンに入社して以来ずっと携わってきた仕事がようやく公になった。</li>
</ul>
</li>
<li>18日<ul>
<li>GitHub の Streak がついに途絶えた。 65日続いていた。</li>
</ul>
</li>
<li>21日<ul>
<li>弊社が属するグループ内で技術勉強会があったので、 Gehirn Infrastructure Services について話してきた。
資料は <a class="reference external" href="https://speakerdeck.com/yosida95/2015-dot-04-dot-21-bracket-x-aratana-x-gehirn-mian-qiang-hui">Bracket x Aratana x Gehirn 勉強会</a>で公開している。</li>
</ul>
</li>
<li>26日<ul>
<li>自宅で遊んでいたサーバーを KVM ホストにして、そこに VyOS をホストして自宅のルーターをリプレースした。
そのうちブログにまとようと思う。</li>
</ul>
</li>
<li>30日<ul>
<li>宮崎県宮崎市にあるアラタナへ出張している。</li>
</ul>
</li>
</ul>
<p><img alt="GitHub Streak" src="https://yosida95.com/photos/0TTJT.raw.png" style="width: 100%;" /></p>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<p>今月は Gehirn Infrastructure Services のリリースがあったことが何よりも大きかったです。
バックエンドアプリケーションと API サーバーは入社以来ずっとぼくが1人で書き続けてきていて、 <a class="reference external" href="https://www.gehirn.jp/gis/mta.html">Gehirn MTA</a> に至っては SMTP サーバーをフルスクラッチするという異常な努力をした、大変に思い入れのあるプロダクトなので、とても感慨深いです。</p>
<p>ただ、リリースをしてからというものどうも力が抜けてしまって、 GitHub の Streak も途切れてしまったように、月の前半はこれまでに比べればほとんど仕事をしていない気がします。
先月の月報では、「4月は時計の針の進みを早める仕事をします。」と書きましたが、一切手を付けていないです。</p>
<p>一方で、月の後半からは復調してきて、仕事はもちろん趣味でも、いろいろと面白いことをしています。
例えば、引っ越してきて以来ずっと遊ばせていたサーバーに火を入れて自宅のネットワークを構築しなおしたり、本腰を入れて Erlang の勉強を始めたり、最近まったく進捗が無かった MPEG2 TS のパーサーも再開する準備を始めたりしています。
仕事で大きな山を超えて余裕が出てきたのだと思うのですが、趣味が再び楽しくなってきました。</p>
<p>以上です。
ありがとうございました。
5月も頑張るぞい!</p>
</div>
urllib3 や requests で使用する Cipher Suite を指定する2015-04-29T00:00:00+09:002015-04-29T00:00:00+09:00yosida95tag:yosida95.com,2015-04-29:/2015/04/29/202514.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>今日は祝日でぼくも休暇でしたが、先日リリースした <a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> でサーバーエラーが発生した旨 Sentry から通知が届き、その修正のデプロイを試みたところ、デプロイスクリプトが依存する <a class="reference external" href="https://pypi.python.org/pypi/requests">requests</a> で <tt class="docutils literal">requests.exceptions.SSLError</tt> 例外が発生してデプロイに失敗したため、この原因と回避方法を調べていました。</p>
<p>トレースバックは以下です。</p>
<div class="highlight"><pre><span></span><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/fabric/main.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">743</span><span class="p">,</span> <span class="ow">in</span> <span class="n">main</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/fabric/tasks.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">384</span><span class="p">,</span> <span class="ow">in</span> <span class="n">execute</span>
<span class="n">multiprocessing</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/fabric/tasks.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">274</span><span class="p">,</span> <span class="ow">in</span> <span class="n">_execute</span>
<span class="k">return</span> <span class="n">task</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/fabric/tasks.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">174</span><span class="p">,</span> <span class="ow">in</span> <span class="n">run</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">wrapped</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/deploy/fabfile.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">166</span><span class="p">,</span> <span class="ow">in</span> <span class="n">upload</span>
<span class="n">source</span> <span class="o">=</span> <span class="n">package</span><span class="p">()</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/deploy/fabfile.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">147</span><span class="p">,</span> <span class="ow">in</span> <span class="n">package</span>
<span class="nb">dict</span><span class="p">(</span><span class="n">loglevel</span><span class="o">=</span><span class="n">env</span><span class="o">.</span><span class="n">loglevel</span><span class="p">))</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/deploy/fabfile.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">100</span><span class="p">,</span> <span class="ow">in</span> <span class="n">render_template</span>
<span class="n">auth</span><span class="o">=</span><span class="n">env</span><span class="o">.</span><span class="n">kvs_registry_auth</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/requests/sessions.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">477</span><span class="p">,</span> <span class="ow">in</span> <span class="n">get</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s1">'GET'</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/requests/sessions.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">465</span><span class="p">,</span> <span class="ow">in</span> <span class="n">request</span>
<span class="n">resp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">prep</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/requests/sessions.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">573</span><span class="p">,</span> <span class="ow">in</span> <span class="n">send</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">adapter</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"/Users/yosida95/src/DNS/debug/lib/python2.7/site-packages/requests/adapters.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">431</span><span class="p">,</span> <span class="ow">in</span> <span class="n">send</span>
<span class="k">raise</span> <span class="n">SSLError</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">request</span><span class="o">=</span><span class="n">request</span><span class="p">)</span>
<span class="n">requests</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">SSLError</span><span class="p">:</span> <span class="p">[</span><span class="n">Errno</span> <span class="mi">1</span><span class="p">]</span> <span class="n">_ssl</span><span class="o">.</span><span class="n">c</span><span class="p">:</span><span class="mi">510</span><span class="p">:</span> <span class="n">error</span><span class="p">:</span><span class="mi">14077410</span><span class="p">:</span><span class="n">SSL</span> <span class="n">routines</span><span class="p">:</span><span class="n">SSL23_GET_SERVER_HELLO</span><span class="p">:</span><span class="n">sslv3</span> <span class="n">alert</span> <span class="n">handshake</span> <span class="n">failure</span>
</pre></div>
</div>
<div class="section" id="section-2">
<h2>発生原因</h2>
<p>大雑把にいうとクライアントにインストールされている OpenSSL のバージョンが古いと発生します。</p>
<p>urllib3 は Cipher として</p>
<pre class="code literal-block">
ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:!eNULL:!MD5
</pre>
<p>を使っています(<a class="reference external" href="https://github.com/shazow/urllib3/blob/91090230697dd0b301588344573cbaffde015f79/urllib3/util/ssl_.py#L41-L45">該当ソースコード</a>)。</p>
<p>このリストに対して Mac OS X にデフォルトでインストールされている OpenSSL 0.9.8zd と、最新の OpenSSL 1.0.2a ではサポートする Cipher Suite にこれだけの差があります。</p>
<div class="highlight"><pre><span></span>*** openssl0.9.8zd.txt 2015-04-29 19:16:26.000000000 +0900
<span class="gd">--- openssl1.0.2a-1.txt 2015-04-29 19:17:01.000000000 +0900</span>
***************
*** 1,9 ****
<span class="gd">--- 1,73 ----</span>
<span class="gi">+ AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD</span>
<span class="w"> </span> AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
<span class="gi">+ AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD</span>
<span class="w"> </span> AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1
<span class="gi">+ AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256</span>
<span class="gi">+ CAMELLIA128-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(128) Mac=SHA1</span>
<span class="gi">+ CAMELLIA256-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(256) Mac=SHA1</span>
<span class="w"> </span> DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1
<span class="gi">+ DH-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ DH-DSS-AES128-SHA SSLv3 Kx=DH/DSS Au=DH Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ DH-DSS-AES128-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ DH-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ DH-DSS-AES256-SHA SSLv3 Kx=DH/DSS Au=DH Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ DH-DSS-AES256-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(256) Mac=SHA256</span>
<span class="gi">+ DH-DSS-CAMELLIA128-SHA SSLv3 Kx=DH/DSS Au=DH Enc=Camellia(128) Mac=SHA1</span>
<span class="gi">+ DH-DSS-CAMELLIA256-SHA SSLv3 Kx=DH/DSS Au=DH Enc=Camellia(256) Mac=SHA1</span>
<span class="gi">+ DH-DSS-DES-CBC3-SHA SSLv3 Kx=DH/DSS Au=DH Enc=3DES(168) Mac=SHA1</span>
<span class="gi">+ DH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ DH-RSA-AES128-SHA SSLv3 Kx=DH/RSA Au=DH Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ DH-RSA-AES128-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ DH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ DH-RSA-AES256-SHA SSLv3 Kx=DH/RSA Au=DH Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ DH-RSA-AES256-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(256) Mac=SHA256</span>
<span class="gi">+ DH-RSA-CAMELLIA128-SHA SSLv3 Kx=DH/RSA Au=DH Enc=Camellia(128) Mac=SHA1</span>
<span class="gi">+ DH-RSA-CAMELLIA256-SHA SSLv3 Kx=DH/RSA Au=DH Enc=Camellia(256) Mac=SHA1</span>
<span class="gi">+ DH-RSA-DES-CBC3-SHA SSLv3 Kx=DH/RSA Au=DH Enc=3DES(168) Mac=SHA1</span>
<span class="gi">+ DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD</span>
<span class="w"> </span> DHE-DSS-AES128-SHA SSLv3 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1
<span class="gi">+ DHE-DSS-AES128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD</span>
<span class="w"> </span> DHE-DSS-AES256-SHA SSLv3 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1
<span class="gi">+ DHE-DSS-AES256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(256) Mac=SHA256</span>
<span class="gi">+ DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(128) Mac=SHA1</span>
<span class="gi">+ DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(256) Mac=SHA1</span>
<span class="gi">+ DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD</span>
<span class="w"> </span> DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1
<span class="gi">+ DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD</span>
<span class="w"> </span> DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
<span class="gi">+ DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256</span>
<span class="gi">+ DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1</span>
<span class="gi">+ DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1</span>
<span class="gi">+ ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ ECDH-ECDSA-AES128-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA384</span>
<span class="gi">+ ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1</span>
<span class="gi">+ ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ ECDH-RSA-AES128-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ ECDH-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA384</span>
<span class="gi">+ ECDH-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1</span>
<span class="gi">+ ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384</span>
<span class="gi">+ ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=3DES(168) Mac=SHA1</span>
<span class="gi">+ ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD</span>
<span class="gi">+ ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1</span>
<span class="gi">+ ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256</span>
<span class="gi">+ ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD</span>
<span class="gi">+ ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1</span>
<span class="gi">+ ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384</span>
<span class="gi">+ ECDHE-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=RSA Enc=3DES(168) Mac=SHA1</span>
<span class="w"> </span> EDH-DSS-DES-CBC3-SHA SSLv3 Kx=DH Au=DSS Enc=3DES(168) Mac=SHA1
<span class="w"> </span> EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1
</pre></div>
<p>このため、クライアントにインストールされている OpenSSL のバージョンが古くサポートしている Cipher が少ない状態で、加えてサーバーでは古い Cipher や脆弱な Cipher のサポートが切られている場合、サーバーとクライアントが共通でサポートしている Cipher がひとつもなくなり、ハンドシェイクに失敗する場合があるのです。</p>
</div>
<div class="section" id="section-3">
<h2>回避方法</h2>
<p>urllib3 では <tt class="docutils literal">urllib3.util.ssl_.DEFAULT_CIPHERS</tt> を書き換えてやることで利用する Cipher を指定することができます。
requests を使っている場合は、 <tt class="docutils literal">requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS</tt> です。</p>
<p>この値を</p>
<pre class="code literal-block">
ALL:!aNULL:!SSLv2:!LOW:!EXP:!MD5
</pre>
<p>など、サーバーがサポートする Cipher が含まれるような無難な値にすることで正常にハンドシェイクできるようになります。</p>
<p>ただし、上記の方法は Python 標準の ssl モジュールを使っている場合で、 ssl モジュールの代わりに <a class="reference external" href="https://pypi.python.org/pypi/pyOpenSSL">pyOpenSSL</a> を利用している場合は、 <a class="reference external" href="https://urllib3.readthedocs.org/en/latest/contrib.html#module-urllib3.contrib.pyopenssl">ドキュメントで説明されている</a>ように、 <tt class="docutils literal">requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST</tt> を変更する必要があります。</p>
<p>なお、 requests を使っている場合は、 pyOpenSSL がインストールされていると<a class="reference external" href="https://github.com/kennethreitz/requests/blob/cfb9e66b04136f014412a8d638b2d69603557c1d/requests/__init__.py#L51-L56">勝手に pyOpenSSL を使ってくる</a> ので注意してください。</p>
</div>
<div class="section" id="section-4">
<h2>おわりに</h2>
<p>気づいたら祝日も終わりに差し掛かっています。
明日からは宮崎出張です。
ぼくの休日とは一体……</p>
<p>ありがとうございました。</p>
</div>
Gehirn Infrastructure Services の Public Preview 開始によせて2015-04-01T00:00:00+09:002015-04-01T00:00:00+09:00yosida95tag:yosida95.com,2015-04-01:/2015/04/01/173000.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
先ほど <a class="reference external" href="http://news.gehirn.jp/information/603/">Gehirn News でお伝えした</a>とおり、 <a class="reference external" href="https://www.gehirn.jp/gis/">Gehirn Infrastructure Services</a> の <a class="reference external" href="https://www.gehirn.jp/publicpreview.html">Public Preview</a> を開始しました!</p>
<p>Gehirn Infrastructure Services はぼくが<a class="reference external" href="https://yosida95.com/2013/08/01/222538.html">ゲヒルンでアルバイトを始めた</a> 2013年の8月からずっと開発に携わってきたプロジェクトで、いよいよ形になってこのように Public Preview を始められることに大変な感慨を覚えています。
おそらく10代最後になる大仕事が Gehirn Infrastructure Services であることを誇りに思います。</p>
<p>Gehirn Infrastructure Services が提供する新機能や技術的な詳細は会社のブログ、 <a class="reference external" href="http://news.gehirn.jp">Gehirn News</a> で追ってご説明しようと思っていますので、この個人のブログではぼくが Gehirn Infrastructure Services にどのように関わってきたかを振り返りたいと思います。</p>
</div>
<div class="section" id="gws02">
<h2>GWS02</h2>
<p>2013 年の時点では実は既存の Gehirn RS2 と Gehirn DNS の API を Go でフルスクラッチして、機能はそのままに信頼性とスケーラビリティを高めようとしていました。
当時のぼくは Go について文法を知っている程度で到底実務レベルではありませんでしたが、ひたすらコードを書いて読むことで知見をため、入社3日後にはプロダクトコードを書いていました。</p>
<p>このプロジェクト、 GWS02 はサーバー側のコードはほぼほぼ出来てきたという時点になって、エッジの効きすぎた API 仕様が仇となり主に古いブラウザとの互換性の問題が浮上しました。
その結果、検討を重ねましたがあえなく提供見送りとなりました。</p>
<p>これはぼくがゲヒルンの正職員となった 2014 年 4 月頃の話です。</p>
</div>
<div class="section" id="gehirn-id-center">
<h2>Gehirn ID Center</h2>
<p><a class="reference external" href="https://www.gehirn.jp/idcenter/">ID Center</a> はもともと GWS02 用の認証を担うために OpenID 2.0 Provider として Go で開発を始め、 <a class="reference external" href="https://github.com/GehirnInc/GOpenID">GopenID</a> のような成果もあったのですが、 Google などを始めとする各社が OAuth 2.0 を拡張した <a class="reference external" href="http://jp.techcrunch.com/2014/02/27/20140226openid-foundation-launches-openid-connect-identity-protocol-with-support-from-google-microsoft-others/">OpenID Connect へ乗り換える動きが活発に</a>なったため、急遽 OpenID 2.0 から OpenID Connect へ切り替えることにしました。</p>
<p>この時、 Go 言語で普通の Web サービスを作ることの辛さを感じていたので、既存のコードベースを捨てて慣れ親しんでノウハウもあった Python で実装を開始しました。
この時に作ったのが、 <a class="reference external" href="https://github.com/GehirnInc/py3oauth2">py3oauth2</a> と <a class="reference external" href="https://github.com/GehirnInc/python-oidc">python-oidc</a> です。</p>
</div>
<div class="section" id="gehirn-rs2-plus">
<h2>Gehirn RS2 PLUS</h2>
<p><a class="reference external" href="https://www.gehirn.jp/gis/rs2.html">Gehirn RS2 PLUS</a> はこれまでの RS2 で問題となっていた暴走プロセスによる他のユーザーへの影響や、 Production Ready が宣言される前に採用した ZFS on Linux の問題などを低減するために Linux Containers (LXC) でリソースが分離された新しいコンセプトのレンタルサーバーとして社長の <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さんが設計と技術検証をはじめました。</p>
<p>そしてアーキテクチャが固まってきた2014年10月にぼくに引き継がれ、まずはコンテナを作成するところから開発をはじめました。
コントロールパネルからデーモンプロセスの管理ができるプロセス機能は当初ありませんでしたが、 supervisord を RS2 PLUS の API から操作できるようにしたら最高便利だと思いついてそのまま実装したことから提供が決まりました。
開発の過程で LXC のバグを幾つか踏み抜いたので、その原因と回避方法を開発しつつ、簡単に直せそうなものは LXC に<a class="reference external" href="https://github.com/lxc/lxc/pull/408">パッチを投げ</a>たりもしました。</p>
</div>
<div class="section" id="gehirn-dns">
<h2>Gehirn DNS</h2>
<p><a class="reference external" href="https://www.gehirn.jp/gis/dns.html">Gehirn DNS</a> はこれまでの機能を踏襲しつつ、ゾーンのバージョン管理や、バージョンの指定時刻での自動切り替え、それに向けた TTL の自動調整(つまり、多くの人が「浸透」などの言葉に煙にまかれているレコードキャッシュ問題をエンジニアリングで解決する)などの新機能を盛り込んだサービスです。</p>
<p>なお、新しい Gehirn DNS をリリースして初めてのマイグレーションは、本日 0:30 の <a class="reference external" href="https://www.gehirn.jp/">www.gehirn.jp</a> でした。</p>
</div>
<div class="section" id="gehirn-mta">
<h2>Gehirn MTA</h2>
<p><a class="reference external" href="https://www.gehirn.jp/gis/mta.html">Gehirn MTA</a> はこれまでにないメール送受信サービスとして <strong>SMTP サーバーのフルスクラッチ</strong> から始めた新サービスです。
SMTP サーバーの開発中は SMTP プロトコルを定めた RFC5321 とメールのフォーマットを定めた RFC5322 を中心に 20 を超える関連 RFC をとにかくひたすら読みまくり、順番に実装しました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">Gehirn MTA が穏やかではないのは、ぼくが SMTP サーバーを golang でフルスクラッチしたという点です</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/580718274897260544">March 25, 2015</a></blockquote></div>
<div class="section" id="gehirn-edj">
<h2>Gehirn EDJ</h2>
<p><a class="reference external" href="https://www.gehirn.jp/gis/edj.html">Gehirn EDJ</a> は MTA で受け取ったメッセージや配送ステータス、障害やメンテナンスなどゲヒルンからのお知らせをユーザーが受け取りやすい形で配送するためのサービスです。</p>
<p>このサービスは MTA の開発中に思いついてそこから3日間で作ったのですが、その後他のサービスの開発が進むにつれて、各サービス間の連携に使用している、ぼくが開発した独自 RPC の仕様改訂に追随する必要が発生したり、 HTTP フックの署名をより検証しやすいものに変更して利便性の向上を図ったりするために、後になって再実装しました。
また、この再実装において、 HTTP フックと Slack だけを予定したサブスクライバーに Twilio や Pushover などを追加しました。</p>
</div>
<div class="section" id="section-2">
<h2>まとめ</h2>
<p>このように Gehirn Infrastructure Services の開発を振り返ってきましたが、ぼくは Gehirn Infrastructure Services が提供するすべてのサービスのバックエンドアプリケーションをひとりで開発するという形で携わってきました。</p>
<p>フロントエンドは、親会社のエンジニアだった <a class="reference external" href="http://twitter.com/satoshi_m8a">@satoshi_m8a</a> さんに Angular をベースに SPA フレームワークの構築と RS2 PLUS と DNS のコントロールパネルを実装していただき、社長の <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さんも参戦して satoshi_m8a さんが構築したフレームワークの上に EDJ と MTA のコントロールパネルを実装しました。
なお、 @satoshi_m8a さんはそのままゲヒルンに転籍して気づいたらぼくの同僚となっていました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">サーバの設計と構築、Ansibleは僕 RT <a href="https://twitter.com/yosida95">@yosida95</a>: この際なので言いますが Gehirn Infrastructure Services はバックエンドをぼくひとりで、フロントを宮崎の親会社から連れてきたぼくの同僚と、加えて社長が自らの 2 名が開発しています。</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/580720542912684032">March 25, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">フロントエンドのデザインは専務自らがひとりで行いました</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/580720774941552640">March 25, 2015</a></blockquote><div class="section" id="yosida95-2014">
<h3>「 yosida95 の 2014 年まとめ」について</h3>
<blockquote>
# ぼくがゲヒルンに入社して以来戦い続けてきたプロジェクトは( Twitter や facebook で何度か愚痴ったり皮肉ったりしたように)紆余曲折がありましたが、経営陣に呼ばれて実施された個人面談で思っていることをはっきり言わせてもらったことや、それによってチームの編成が変わっりしたことも追い風となってようやく勝つことができそうです。
# ぼくの一連の投稿を受けてかなり本気の心配を頂いたり、強い共感をを頂いたりしていたので、状況が好転したことをひとまずここでご報告させていただきます。
-- <a class="reference external" href="/2014/12/29/130000.html#anchor">yosida95 の 2014 年まとめ</a></blockquote>
<p>フロントエンドの開発でも紆余曲折があり、もともとは昨年末退職したぼくと同じ年の職員が専任で開発を続けてきましたが、「できた」と宣言した機能が蓋を開ければ未実装、業務を放棄して第三者にメールで依頼された作業をするなど、他にも多くの信義に関わる問題があり、そもそもの品質の低さと未実装機能の多さも相まって、彼のコードベースを捨て前述の体制での開発になりました。</p>
<p>このめでたき日に水を差すことを言わないのがオトナの振る舞いだとは思うのですが、前述のような経緯があり、また唯一残っている彼の仕事がすでに品質と保守性の観点から負債の扱いを受けフルスクラッチが検討されている中で、彼が事実とかけ離れた割合でこのサービスにコミットしたという言説を吹聴していると伝え聞いたので、ここに事実を書いておきます。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">大人な対応を取る相手は、その場でも後からでもそこで譲歩された意味に気づける、つまり反省のある相手でないとただ損をするだけという気づきがあるので、これからは反省のない人間に対しては同じレベルでバカだのチョンだのと応戦していきたい</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/540400786354606080">December 4, 2014</a></blockquote></div>
</div>
<div class="section" id="section-3">
<h2>最後に</h2>
<p>このように紆余曲折を経ていよいよ Gehirn Infrastructure Services の提供を予告できるとなった段階では、わくわくする一方で果たしてユーザーに受け入れてもらえるかという強い緊張もありました。
この予告を行った3月25日は <a class="reference external" href="http://twitter.com/isidai">sidai</a> さんが書いた下書き原稿を、メールを配信する直前まで <a class="reference external" href="http://twitter.com/N_taka">@N_taka</a> さんとぼくとで校正し、発表後も終電が無くなった後までこの3人でオフィスに残り Twitter の反応を見ていました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ゲヒルンからの重要なお知らせを配信するにあたって、これまでに無いくらい緊張している</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/580716750494257153">March 25, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">今めっちゃ手が震えてる</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/580718532108775424">March 25, 2015</a></blockquote><p>今日から Gehirn Infrastructure Services の Public Preview の提供を開始ということで、どのような使い方をしていただけるのか、果たしてぼくらが夢見たインフラサービスはユーザーに受け入れたもらえるのかなど、とてもわくわくしています。
Public Preview で Gehirn Infrastructure Services に触っていただき、一緒にわくわくしていただけたら幸いです。</p>
</div>
<div class="section" id="section-4">
<h2>追伸</h2>
<p>この記事を書くなかで気づいたのですが、今日はぼくがゲヒルンの正職員として2年目を迎える区切りの日のようです。</p>
</div>
2015 年 3 月まとめ2015-03-31T00:00:00+09:002015-03-31T00:00:00+09:00yosida95tag:yosida95.com,2015-03-31:/2015/03/31/110000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
3 月分の月報です。
2 月分は<a class="reference external" href="https://yosida95.com/2015/03/04/110000.html">2015 年 2 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やっとこと</h2>
<ul class="simple">
<li>11 日<ul>
<li><a class="reference external" href="http://gunosygo.connpass.com/event/12343/">Gunosy Go 利用の現状確認会</a>という勉強会で10分間 LT をしてきた。
使ったスライドと発表原稿は SpeakerDeck の <a class="reference external" href="https://speakerdeck.com/yosida95/2015-dot-03-dot-11-gunosy-dot-go">2015.03.11 Gunosy.Go</a> に置いてある。</li>
</ul>
</li>
<li>25 日<ul>
<li>弊社の親会社が ZOZOTOWN で知られるスタートトゥデイに買収され、弊社も東証一部上場企業のグループ企業になった。</li>
<li>弊社が提供している Gehirn RS2 と Gehirn DNS の新規受付終了の案内をした。</li>
<li>終了した Gehirn RS2 と Gehirn DNS の後継サービスである Gehirn Infrastructure Services を正式公表した。</li>
</ul>
</li>
<li>29 日<ul>
<li><a class="reference external" href="https://github.com/ansible/ansible-modules-core">ansible/ansible-modules-core</a> に送っていた、 <a class="reference external" href="https://github.com/ansible/ansible-modules-core/pull/266">Riak CS のような S3 like オブジェクトストレージでも TLS 接続できるようにする Pull Request</a> がマージされた。</li>
</ul>
</li>
<li>30 日<ul>
<li>気が向いたので出勤前に花見がてら北の丸公園を 1 時間弱散歩した。</li>
</ul>
</li>
</ul>
<p><a class="reference external image-reference" href="https://yosida95.com/photos/u1BDB.raw.png"><img alt="GitHub Activity" src="https://yosida95.com/photos/u1BDB.raw.png" style="width: 100%;" /></a></p>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<p>今月の最も大きかった出来事は、なんといっても Gehirn Web Services の終了予告と後継サービス Gehirn Infrastructure Services の発表でした。
会社として正式に発表を行った25日は社長と専務とぼくとで発表の直前まで発表内容の校正を行い、発表後も終電が無くなった後まで会社にいて Twitter の反応を見ては一喜一憂していました。</p>
<p>これまでなかなかゲヒルンがやっていることは表に出なくて、「ゲヒルンって何やっているの?w」みたいなことを訊かれて答えに窮することもありましたが、ぼくが一昨年の夏にゲヒルンに入社して以来ずっと取り組んできたプロジェクトがいよいよ形になってきて、3月11日の <a class="reference external" href="https://speakerdeck.com/yosida95/2015-dot-03-dot-11-gunosy-dot-go">Gunosy Go 利用の現状確認会</a>ではようやく自分がゲヒルンで取り組んできたことを公に発表することが出来ました。</p>
<p>そして、 25 日は会社として正式に Gehirn Infrastructure Services の提供を予告し、4月1日からの Public Preview の開始を告知することができるに至りました。</p>
<p>Public Preview から正式提供に移行するまでまだ予断を許されませんが、一新したゲヒルンのインフラサービスを多くの方にご利用頂ける日を迎えるための準備が整いつつあることに、とてもわくわくしています。</p>
</div>
<div class="section" id="section-5">
<h2>これから</h2>
<p>4 月は時計の針の進みを早める仕事をします。</p>
</div>
2015 年 2 月まとめ2015-03-04T00:00:00+09:002015-03-04T00:00:00+09:00yosida95tag:yosida95.com,2015-03-04:/2015/03/04/110000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
今月も月報を書いてみようと思います。
先月分は <a class="reference external" href="https://yosida95.com/2015/02/02/122434.html">2015 年 1 月まとめ</a>です。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul>
<li><p class="first">10 日</p>
<ul>
<li><p class="first">会社で新年会があって焼き肉を食べた。</p>
<p>今月から正職員が2名増えてオフィスが賑やかになってきた。
今年も頑張るぞいという気持ちを新たにした。</p>
</li>
</ul>
</li>
<li><p class="first">11 日</p>
<ul>
<li><p class="first">社長の @isidai さんと同僚の @satoshi_m8a さんと NHK 番組技術展に行ってきた。</p>
<p>興味深い展示も幾つかあって楽しかった。
今回がぼくにとって 2 回目だったけれど、前回から今回までの間に Go で MPEG2-TS パーサー <a class="reference external" href="https://github.com/yosida95/tsparser">yosida95/tsparser</a> を書いたり、社長による熱心な NHK 推しを事あるごとうけたりして、放送技術への興味が前回よりも高まっていたのでより楽しめたと思う。</p>
</li>
</ul>
</li>
<li><p class="first">12 日</p>
<ul>
<li><p class="first"><a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> と焼き肉を食べた。</p>
<p>昨年の11月25日にも一緒に焼き肉を食べに行ったけれど、やっぱり会社の外の同じ年とあって話すと刺激があって面白い。</p>
</li>
</ul>
</li>
<li><p class="first">13 日</p>
<ul class="simple">
<li>Pixiv で行われた<a class="reference external" href="http://connpass.com/event/11463/">外部キー Night</a> というニッチな勉強会に参加してきた。</li>
</ul>
</li>
<li><p class="first">21 日</p>
<ul class="simple">
<li>少し Scala に用事ができたので、スマートニュースで行われた<a class="reference external" href="http://nulab-inc.com/ja/blog/nulab/jissenscala/">実践での Scala</a> という勉強会に参加して現状を確認してきた。</li>
</ul>
</li>
<li><p class="first">12 日から 28 日</p>
<ul class="simple">
<li><img alt="GitHub Contributions" src="https://yosida95.com/photos/rXP9Q.raw.png" style="width: 100%;" /></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<p>先月のように出張したり、どこかにパッチを投げたりという活動がなかったので特筆することはないけれど、とにかく開発が忙しい1ヶ月だった。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">最近の気付きとして、 24 時間はどう頑張っても 24 時間だし、ぼくは 1 人しかいない</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/571953664664838144">March 1, 2015</a></blockquote><p>1 月に続いて 2 月も会社に常勤の正職員が増えて(今年に入って正職員が2.5倍に増えた!)これからもっと楽しくなりそうだなぁというわくわくがあるのだけれど、一方でゲヒルンの職員ではない、ゲヒルンの職員とは結構質の異なる人間の出入りが激しくなって、そういうのが自分にとって結構ストレスになっているなぁということも感じている。</p>
<p>これは恒久的に続くものではないし、自分が適応するしかないと思うのだけれど、ふとしたことが気になって仕方がなくて、とても知的生産ができる状況では無かったので、今月はかなりの時間を在宅勤務に割り振った。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">このクソ忙しくて少しでも多く時間が欲しい状態において、集中して仕事をするためにオフィスに出てきたばかりに却って集中力を削られるのは我慢ならないのでしばらくレアキャラになろう</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/570905917186650112">February 26, 2015</a></blockquote></div>
<div class="section" id="section-5">
<h2>これから</h2>
<p>11 日に開催される<a class="reference external" href="http://gunosygo.connpass.com/event/12343/">Gunosy Go利用の現状確認会</a> という勉強会の LT を申し込んだ。
ぼくの進捗に左右されるけれど、ぼくが最近取り組んでいる面白い話ができればいいなぁと思っている。</p>
<p>ぼくがインターネッツに生息し始めてから毎年年末にまとめて1年を振り返っていたのだけれど、それに比べてこうし 1ヶ月単位で振り返ると記憶に新しくて感情も鮮明なうちに1ヶ月の反省ができるので結構面白いという気づきを得た。
来月も書くぞい。</p>
</div>
2015 年 1 月まとめ2015-02-02T00:00:00+09:002015-02-02T00:00:00+09:00yosida95tag:yosida95.com,2015-02-02:/2015/02/02/122434.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
個人のブログなのではっきり言って個人の日記レベルのことを書きます。
2015 年になって恐ろしいほどあっという間に1ヶ月が経ってしまい、このままではなんの感動もなく2015年が終わって気づいたら2016年になってしまうのではないかという危機感を覚えたので月報を書いてみます。</p>
</div>
<div class="section" id="section-3">
<h2>やったこと</h2>
<ul class="simple">
<li>1 日<ul>
<li>午前3時くらいから自宅がある岩本町方面から小川町方面に向かって散歩を始めて、神田明神まで足を伸ばしてみた</li>
</ul>
</li>
<li>4 日<ul>
<li>髪を切った</li>
<li>9月12日の引っ越しの時に実家においてきた本棚と本をようやく自宅に運んできた。
今まではベッドの下に本を山積みにしていた。
すでに本棚が一杯になっている。</li>
</ul>
</li>
<li>5 日<ul>
<li>社長と 2 人で飛行機で宮崎に飛んで親会社のアラタナに行った</li>
</ul>
</li>
<li>7 日<ul>
<li>親会社の社員が昼休みにやっている Aratana FM に引っ張り出されて喋ってきた</li>
</ul>
</li>
<li>10 日<ul>
<li>出張が終わり宮崎から東京に帰ってきた</li>
</ul>
</li>
<li>13 日<ul>
<li>新年初出社</li>
</ul>
</li>
<li>20 日<ul>
<li>寿司</li>
</ul>
</li>
<li>22 日<ul>
<li>Linux Containers (<a class="reference external" href="https://github.com/lxc/lxc">LXC</a>) にバグを見つけて <a class="reference external" href="https://github.com/lxc/lxc/pull/408">パッチ</a> を書いた</li>
</ul>
</li>
<li>25 日<ul>
<li>LXC にパッチをマージされた</li>
</ul>
</li>
<li>28 日<ul>
<li>ぼくが作った <a class="reference external" href="https://github.com/yosida95/golang-jenkins">golang-jenkins</a> に来ていた <a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/3">パッチ</a> をマージした</li>
</ul>
</li>
<li>29 日<ul>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins">golang-jenkins</a> に来た別の <a class="reference external" href="https://github.com/yosida95/golang-jenkins/pull/4">パッチ</a> をマージした</li>
</ul>
</li>
<li>31 日<ul>
<li>Riak CS のドキュメントがマークアップのミスで壊れていたので <a class="reference external" href="https://github.com/basho/basho_docs/pull/1515">パッチ</a> を書いたところ、その1分後にマージされた</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-4">
<h2>所感</h2>
<p>1 週間の出張から始まった、とにかく忙しい年始だった。</p>
</div>
自動デプロイとアプリケーションの設定値と etcd2015-01-13T00:00:00+09:002015-01-13T00:00:00+09:00yosida95tag:yosida95.com,2015-01-13:/2015/01/13/113000.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
2015 年初めてのブログエントリです。
今年もよろしくお願いします。</p>
<p>ぼくが所属するゲヒルンでは CircleCI を使って CI を回しています。
以前はぼくが社内にたてた Jenkins を使っていて、ときどき Jenkins にバグ報告を上げたりもしていたのですが、ライブラリをオープンソースにする過程で TravisCI を使いこむようになって Jenkins のバグと運用から開放される喜びを知り、その後クローズドソースなプロダクトでも SaaS の CI を利用したく複数のサービスを検討した結果 CircleCI を契約しました。
最初のころは個人でのみ CircleCI を利用していたのですが、個人の契約に任意の Organization を Piggyback させられることを知り <a class="reference external" href="https://github.com/GehirnInc">GehirnInc</a> アカウントでも CircleCI を利用できるようにしました。
そして現在は社内で開発している多くのプロダクトで CircleCI が利用されるようになりました(というか、ぼくが参加するプロジェクトでは、ぼくが開発をしないリポジトリに対しても CircleCI を使うための Pull Request を投げています)。</p>
</div>
<div class="section" id="ci">
<h2>CI と自動デプロイ</h2>
<p>CI ではだいたいの場合単体テスト・結合テストまでが実施され、変更の粒度がある程度育ってきたらステージング環境にデプロイして実際に触ってみて機能テストを行うのではないかと思います。
Git-flow や GitHub-flow による開発をしている場合、 topic ブランチや feature ブランチを切って必要な変更とそれに対するテストを書いて CI を通したら元のブランチにマージしますが、この "元のブランチ" にマージされたタイミングで CI がキックされすべてのテストケースが通ったらそのままステージング環境に勝手にデプロイされてほしい訳です。</p>
</div>
<div class="section" id="section-2">
<h2>自動デプロイとアプリケーションの設定値</h2>
<p>CI でアプリケーションをデプロイすることそのものは簡単なことです。
それこそ適当にシェルスクリプトを書いて、 rsync でアプリケーションを deliver したり、あるいはサーバーにログインして <tt class="docutils literal">git pull</tt> すればいいだけのことです。
しかし現実的に、アプリケーションはデータベースに接続してユーザーデータを永続化しなければなりませんし、マッシュアップアプリケーションなら外部サービスの API をコールしなくてはなりません。
データベースにユーザーデータを永続化するためにはデータベースに接続するための情報、ホスト名やポート番号、それにデータベース名を、外部サービスの API をコールするにはその API に接続するためのクレデンシャルを、それぞれアプリケーションが知っている必要があります。
多くの場合これらのパラメーターは YAML や INI 、あるいは JSON など任意の設定ファイルにまとめられ、アプリケーションのエントリーポイントがこれら設定ファイルを読み込んで起動する仕組みになっていることでしょう。</p>
</div>
<div class="section" id="section-3">
<h2>設定ファイルのこれまで</h2>
<p>では自動デプロイをする場合において、それらの設定ファイルはどのように管理すればよいのでしょうか。
昨年頃から大きな流れとなっている Immutable Infrastructure の概念ではアプリケーションのデプロイは一度だけで、アプリケーションに変更があればサーバーごと捨ててしまえるので大きな問題とはならないのですが、その方法によって解決できない領域が存在します。
例えばぼくが所属しているゲヒルンが行っているレンタルサーバーサービス。
ユーザーは割り当てられたファイルシステムに自由にデータを書き込み、自由にデーモンを立ち上げ、その結果再現不可能なサーバーが誕生します。
レンタルサーバーサービスに新機能を追加すると、既存のサーバーの上に新たな、あるいは更新されたアプリケーションをデプロイする必要が生じます。
このようなアプリケーションの設定ファイルは、職人が都度書く、長い間伝承されてきた設定ファイルを scp で転送するなどは自動デプロイの文脈では問題外としても、リポジトリに平文で含む、 Ansible Vault の様なものを使って暗号化した上でリポジトリに含むなどがこれまで試みられてきた方法だと思います。
リポジトリに平文で含む方法の問題点は少し考えただけで簡単に見つけられますが、そこで妥協点として暗号化してリポジトリに含むという感じなのでしょうか。
しかしアプリケーションの実装と、それを運用する設定ファイルはできるだけ分離されているべきだと思います。</p>
</div>
<div class="section" id="etcd-1">
<h2>etcd を使った設定値の共有</h2>
<p>そこでぼくが最近実験的に試している方法が、リポジトリには「どこにファイルを配置し、どこを読めば設定値を知ることができるか」という情報のみを含み、設定値自体は外部に切り出してしまうというものです。
この設定値の切り出し先として使っているサーバーが Core OS が開発している <a class="reference external" href="https://github.com/coreos/etcd">coreos/etcd</a> です。
etcd は最近波に乗っている Docker のホストサーバー向け OS である CoreOS が利用しているということで一度は耳にしたことがあるのではないでしょうか。
設定値を共有するための高可用性分散 KVS ということで、早く言ってしまえば Go 言語で書かれた ZooKeeper です。
etcd 単体の機能として通信経路の TLS 暗号化と、クライアント証明書による認証が使えて大変便利です。</p>
<p>ぼくがゲヒルンで実験的に取り入れている etcd を使った具体的なデプロイのフロー以下の様なものです。</p>
<ol class="arabic simple">
<li>変更を staging ブランチにマージする</li>
<li>変更を検知して CircleCI がテストを実行する</li>
<li>ステージング環境で<ol class="arabic">
<li><tt class="docutils literal">git fetch && git reset <span class="pre">--hard</span> origin/staging</tt> を実行する</li>
<li>必要な依存パッケージのインストールを行う</li>
<li>アプリケーションのビルドを行う</li>
</ol>
</li>
<li>リポジトリに含んだトリプル DES で暗号化された秘密鍵を復号する</li>
<li>復号した秘密鍵と証明書を使って etcd にアクセスして設定ファイルを生成する</li>
<li>設定ファイルをステージング環境の特定のパスに配置する</li>
</ol>
<div class="section" id="section-4">
<h3>例</h3>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">"""</span>
<span class="sd">Copyright (c) 2015, Kohei YOSHIDA <license@yosida95.com>. All rights reserved.</span>
<span class="sd">Redistribution and use in source and binary forms, with or without</span>
<span class="sd">modification, are permitted provided that the following conditions are met:</span>
<span class="sd"> * Redistributions of source code must retain the above copyright</span>
<span class="sd"> notice, this list of conditions and the following disclaimer.</span>
<span class="sd"> * Redistributions in binary form must reproduce the above copyright</span>
<span class="sd"> notice, this list of conditions and the following disclaimer in the</span>
<span class="sd"> documentation and/or other materials provided with the distribution.</span>
<span class="sd"> * Neither the name of the copyright holder nor the names of its</span>
<span class="sd"> contributors may be used to endorse or promote products derived from</span>
<span class="sd"> this software without specific prior written permission.</span>
<span class="sd">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span>
<span class="sd">"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span>
<span class="sd">LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR</span>
<span class="sd">A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT</span>
<span class="sd">HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
<span class="sd">SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT</span>
<span class="sd">LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span>
<span class="sd">DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY</span>
<span class="sd">THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="sd">(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span>
<span class="sd">OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="sd">"""</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">urlparse</span> <span class="kn">import</span> <span class="n">urlparse</span>
<span class="kn">import</span> <span class="nn">etcd</span>
<span class="k">class</span> <span class="nc">ConfigRegistry</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">parent</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">root</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">Config</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">root</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">keyname</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">Config</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">'/'</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">key_prefix</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
<span class="k">return</span> <span class="s1">'/'</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">keyname</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">root</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keyname</span><span class="p">)</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">root</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keyname</span><span class="p">,</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
<span class="k">def</span> <span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ConfigRegistry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Config</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">client_cert</span><span class="p">,</span> <span class="n">client_key</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">url</span> <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span> <span class="k">else</span> <span class="n">url</span> <span class="o">+</span> <span class="s1">'/'</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__etcd_registry__</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">path_parts</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'/'</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">path_parts</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">4</span>\
<span class="ow">or</span> <span class="n">path_parts</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'keys'</span><span class="p">:</span> <span class="c1"># /v2/keys/appname/staging</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key_prefix</span> <span class="o">=</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">path_parts</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">etcd</span><span class="o">.</span><span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">parsed</span><span class="o">.</span><span class="n">hostname</span><span class="p">,</span>
<span class="n">port</span><span class="o">=</span><span class="n">parsed</span><span class="o">.</span><span class="n">port</span><span class="p">,</span>
<span class="n">protocol</span><span class="o">=</span><span class="n">parsed</span><span class="o">.</span><span class="n">scheme</span><span class="p">,</span>
<span class="n">cert</span><span class="o">=</span><span class="p">(</span><span class="n">client_cert</span><span class="p">,</span> <span class="n">client_key</span><span class="p">))</span>
<span class="k">def</span> <span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__etcd_registry__</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__etcd_registry__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">ConfigRegistry</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__etcd_registry__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
</pre></div>
<div class="highlight"><pre><span></span><span class="n">config</span> <span class="o">=</span> <span class="n">PasteConfig</span><span class="p">(</span><span class="s1">'https://etcd.example.com:4001/v2/keys/appname/staging'</span><span class="p">,</span>
<span class="s1">'./etcd.cer'</span><span class="p">,</span>
<span class="s1">'./etcd.key'</span><span class="p">)</span>
<span class="n">config</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">bar</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="c1"># https://etcd.example.com:4001/v2/keys/appname/staging/foo/bar</span>
</pre></div>
<p>この config オブジェクトを任意のテンプレートエンジンに渡すことで、簡単に設定ファイルを生成できるようになります。</p>
<p>この方法ではリポジトリに設定ファイルを含まずに、アプリケーションのパラメーターを etcd に切り出して machine readable な形で提供しています。
こうすることによって設定ファイルを自動生成できるようになり、人の手を介さない完全自動デプロイが実現されています。
また etcd へはクライアント認証に成功した者、つまりトリプル DES のパスフレーズを知っている者のみがアクセス可能なため、センシティブな情報の保護も同時に実現しています。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>おわりに</h2>
<ul class="simple">
<li>Immutable ではない Infrastructure 上に自動デプロイするアプリケーションの設定方法についてのベストプラクティスを知りたい<ul>
<li>この方法はベターではあると思うけれど etcd という新しいものに飛びつきたかったという側面も否めない</li>
</ul>
</li>
<li>ポエムを書こうとしたけれど文章がまとまらなかった<ul>
<li>世の中のポエマー各位すごい</li>
</ul>
</li>
</ul>
</div>
yosida95 の 2014 年まとめ2014-12-29T00:00:00+09:002014-12-29T00:00:00+09:00yosida95tag:yosida95.com,2014-12-29:/2014/12/29/130000.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
2014年も残り僅かとなり、そろそろ今年を総括してもよいころなのではないかと思った次第です。</p>
</div>
<div class="section" id="section-2">
<h2>引っ越し</h2>
<p><a class="reference external" href="https://yosida95.com/2014/09/19/083000.html">秋葉原に引っ越した</a>、19歳にして初めての1人暮らしをはじめました。
通勤時間が大幅に圧縮され、精神的にも体力的にも余裕が生まれました。
引っ越しと同時に自炊もはじめましたが、小さいころから料理をやっていた素地があったので、楽しみながら凝った美味しいものを食べられるようになったので最高という感じです。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">.<a href="https://twitter.com/umisama">@umisama</a> に今日はムニエルを作ると言う話をしたら「なんでそんな面倒臭そうな料理を家庭で作るのか」と突っ込まれたので、「せっかく自分の時間を割いて作るのだから家庭料理を作っても仕方なくて、そうするくらいなら外に食べに行く」と答えたんだけど賛同を得られなかった。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/541894740954722304">December 8, 2014</a></blockquote><p>また、ぼくの引っ越しの1週間後に弊社社長が徒歩30秒のところに引っ越してきました。
ぼくが空腹で困っている時に夕食をデリバリーしてくださるなど、最高にエキサイティングな生活が始まりました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> いまUDXですけど、とんかつとかお好み焼き、お届けしましょうか?</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/516201112420896772">September 28, 2014</a></blockquote></div>
<div class="section" id="section-3">
<h2>ゲヒルン勤続 1 年 5 ヶ月</h2>
<p>2013 年の8月にアルバイトとして転職し高校卒業を待って2014年4月に正職員登用されたゲヒルンですが、なんだかんだでアルバイト期間を含め勤続期間が1年5ヶ月になりました。
<a class="reference external image-reference" href="https://yosida95.com/photos/rZTg6.raw.jpeg"><img alt="雇用契約書" src="https://yosida95.com/photos/rZTg6.raw.jpeg" style="width: 100%;" /></a></p>
<p>ゲヒルンでは主に GitHub の <a class="reference external" href="https://github.com/GehirnInc">GehirnInc</a> アカウントでの OSS 活動と <a class="reference external" href="http://news.gehirn.jp/">Gehirn News</a> のライター、社内チャットにいる slackbot の開発・運用などを主にやってきたとかそんな訳はないのですが、現時点でぼくから公開できる情報は特に無いです。
twitter でゲヒルンの活動がよくわからないという声もちらほらみかけますが、多岐にわたっていて実際ぼくにもよくわからないです。
ただ、ぼくが入社した2013 年8月と比べてオフィスの面積が圧倒的に広くなり、職員も2倍以上になりました。</p>
<p>26 日の金曜日にあった納会と二次会のカラオケから帰ってきて1年間を振り返ってみましたが、風通しの良い会社で自由にのびのびとさせてもらっていて、技術的にも組織で働く人間としても大きく成長した気がしました。
ありがたいことに転職のお誘いやヘッドハンティングをいただくことがあるのですが、まだゲヒルンでやりたいことがあるのでしばらくはお応えすることができません。</p>
</div>
<div class="section" id="oss">
<h2>OSS 活動</h2>
<p>今年は GitHub で <a class="reference external" href="https://github.com/yosida95">yosida95</a> アカウントと <a class="reference external" href="https://github.com/GehirnInc">GehirnInc</a> アカウント両方でいくつかのプロダクトを OSS にし、またいくつかの OSS にコントリビュートしました。
yosida95 アカウントで活動するか GehirnInc アカウントで活動するかの差は概ね勤務時間中に書いたか否かだけで、開発動機や設計思想には差はありません。</p>
<div class="section" id="oss-1">
<h3>OSS にしたプロダクト</h3>
<p>ざっくりとですが印象深くて今後も力を入れていこうと思っている順に並べてみました。</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/yosida95/tsparser">yosida95/tsparser</a><ul>
<li><a class="reference external" href="http://www.arib.or.jp/english/html/overview/doc/2-STD-B10v4_8.pdf">ARIB STD-B 10</a> (PDF) で定義されている日本の地上デジタル放送における MPEG-2 TS パケットをパースする Go ライブラリ</li>
<li>TS から Event Information Table に含まれる日本語の番組情報をコンソールに表示できた時は感動しました</li>
<li>開発していく意思はまだありますが、引っ越しでテレビのない生活を始め、テレビ放送は原作を知っているアニメだけを視聴するようになったので、このライブラリを使っていろいろ自動化するという動機がすこし薄れてきてしまっている気はします。
<a class="reference external" href="https://amzn.to/yosida95">テレビや PT3 や HDD なんかを贈って</a> 頂けると開発が活発化するかもしれません (/ω・\)チラッ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/python-jsmapper">yosida95/python-jsmapper</a><ul>
<li>Python のクラス定義を JSON Schema に変換するライブラリで、 ORM のように受け取った JSON データから定義クラスのインスタンスを生成することができます</li>
<li>手前味噌ながらかなり便利で、ゲヒルンで開発しているプロダクトの多くで採用しています</li>
<li>詳しくは<a class="reference external" href="https://yosida95.com/2014/06/15/233351.html">JSONSchema を Python のオブジェクトとマッピングするライブラリを作った</a>をご覧ください</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/py3oauth2">GehirnInc/py3oauth2</a><ul>
<li>Python 3 製 OAuth 2.0 プロバイダ ( サーバー ) ライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/python-oidc">GehirnInc/python-oidc</a><ul>
<li>Python 3 製 Open ID Connect のプロバイダ ( サーバー ) ライブラリ</li>
<li>Open ID Connect の規格は OAuth 2.0 を拡張したものなので、 <a class="reference external" href="https://github.com/GehirnInc/py3oauth2">GehirnInc/py3oauth2</a> を継承する感じで作ってあります</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/python-jwt">GehirnInc/python-jwt</a><ul>
<li>Python 3 で一連の JSON Web Token (JWT) 関連仕様 (JSON Web Token (JWT), JSON Web Signature (JWS), JSON Web Key (JWK)) をエンコード・デコードするライブラリです</li>
<li>欲しい部分だけ書いたので JSON Web Encryption (JWE) 部分は実装していません</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/python-sshkey">yosida95/python-sshkey</a><ul>
<li>OpenSSH 形式の鍵ペアをパースする Python 3 ライブラリ</li>
<li>これも欲しいところだけしか書いていないので RSA, DSA, ECDSA の各公開鍵をデコードして finger print と鍵長を計算するか、各アルゴリズムの公開鍵から OpenSSH 形式にエンコードするくらいしかできません</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/GOpenID">GehirnInc/GOpenID</a><ul>
<li>Go 製 OpenID 2.0 サーバーライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/crypt">GehirnInc/crypt</a><ul>
<li><a class="reference external" href="http://linux.die.net/man/3/crypt">crypt (3)</a> の手順にしたがってパスワードの salt 付きハッシュを計算する Go ライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/GehirnInc/puttykey">GehirnInc/puttykey</a><ul>
<li>PuTTY 形式の SSH 鍵をパース・シリアライズする Go ライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-gehirndns">yosida95/golang-gehirndns</a><ul>
<li><a class="reference external" href="http://www.gehirn.jp/dns.html">Gehirn DNS</a> の Go で書かれた API クライアントライブラリ</li>
<li>詳しくは<a class="reference external" href="https://yosida95.com/2014/07/03/163536.html">Gehirn DNS の Golang API Client を書いた</a>をご覧ください</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/twitter-trailer">yosida95/twitter-trailer</a><ul>
<li>Twitter Streaming API の Go で書かれたクライアントライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/golang-jenkins">yosida95/golang-jenkins</a><ul>
<li>Jenkins API の Go で書かれたクライアントライブラリ</li>
<li>勢いで書いてすっかり忘れて放置していましたが、先日 Pull Request を頂いて思い出しました</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/recvknocking">yosida95/recvknocking</a><ul>
<li>ポートノッキングを扱う Go ライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/gitpull">yosida95/gitpull</a><ul>
<li><a class="reference external" href="https://github.com/yosida95/recvknocking">yosida95/recvknocking</a> の活用例として作った、ポートノッキングを受けて git pull コマンドを実行するアプリケーション</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/ip2country">yosida95/ip2country</a><ul>
<li>IP アドレスをそのアドレスが割り当てられた地域の ISO 3166 に示されるコードに変換する Python ライブラリ</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/yosida95/random">yosida95/random</a><ul>
<li>ランダムなアスキー文字列を生成する Go ライブラリ</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="oss-2">
<h3>コントリビュートした OSS</h3>
<ul class="simple">
<li><a class="reference external" href="https://github.com/youzaka/ariblib">youzaka/ariblib</a><ul>
<li>ARIB STD-B 10 にもとづき MPEG-2 TS をパースする Python 3 ライブラリ</li>
<li>pep8 に従う Pull Request とファイルの実行権限を修正する Pull Request を投げたらマージされました</li>
<li>Python 3 になって変更された文法に対応しきれていなかったことでバグを作ってしまいその節はご迷惑をお掛けしました<ul>
<li>twitter でライブラリの利用者に指摘されて大変申し訳無いという気持ちになりました</li>
</ul>
</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/danryan/hal">danryan/hal</a><ul>
<li><a class="reference external" href="https://github.com/github/hubot">github/hubot</a> を置き換えようとする Go 製チャットボット</li>
<li>CoffeeScript に辟易とし Go で Hubot を置き換えるツールを書こうと考えていた時に出会ったライブラリです</li>
<li>外部からの HTTP フックを受けられなかったので Pull Request を出したらマージされました</li>
<li>イケていない仕様があったのでパッチを出すために Issue で開発者と設計について議論したら開発者自ら修正してくれました</li>
</ul>
</li>
<li><a class="reference external" href="https://github.com/plouc/go-gitlab-client">plouc/go-gitlab-client</a><ul>
<li>GitLab の Go で書かれた API クライアントライブラリ</li>
</ul>
</li>
</ul>
<p>この他にも、 <a class="reference external" href="https://github.com/ansible/ansible-modules-core">ansible/ansible-modules-core</a> や <a class="reference external" href="https://github.com/robbyrussell/oh-my-zsh">robbyrussell/oh-my-zsh</a> などの Pull Request を投げているプロジェクトがいくつかありますが、いつもだいたい衝動だけで Pull Request を投げているので、忘れたことにマージされて必死に記憶を辿るようなことが時々あります。</p>
</div>
</div>
<div class="section" id="section-4">
<h2>おわりに</h2>
<p>2014 年中は人にも仕事にも恵まれ、高校を(無事ではないながらも)卒業し、ゲヒルンでの正職員登用、引っ越しなどのイベントがあり、大変よい方向へと向かった1年でした。
お世話になった方々には厚くお礼申し上げます。</p>
<p>2015 年にはようやく 20 歳になります。
20 歳になれば社会生活を送る上での法律的な制約からもだいぶ開放され、今まで以上に自由になるだろうと思っています。
拡充した自由の裏にある責任にも目を向けしっかりと向き合っていき、実りある1年にしていきたいと意気込んでいます。
また、年々減っているブログエントリ数をみて悲しくなったので、ブログエントリを含めてアウトプットを増やしていく所存です。
2015 年も変わらぬご高配をなにとぞよろしくお願いします。</p>
<div class="line-block" id="anchor">
<div class="line"># ぼくがゲヒルンに入社して以来戦い続けてきたプロジェクトは( Twitter や facebook で何度か愚痴ったり皮肉ったりしたように)紆余曲折がありましたが、経営陣に呼ばれて実施された個人面談で思っていることをはっきり言わせてもらったことや、それによってチームの編成が変わっりしたことも追い風となってようやく勝つことができそうです。</div>
<div class="line"># ぼくの一連の投稿を受けてかなり本気の心配を頂いたり、強い共感をを頂いたりしていたので、状況が好転したことをひとまずここでご報告させていただきます。</div>
</div>
<p>余談ですが、昔アイデンティティについて思案して Write Only な Twitter Client を作ったり、だれでも匿名でぼくのアカウントから発言できるようにしていた頃に Twilog を消してしまったのですが、<a class="reference external" href="http://twisave.com/yosida95/search/%E5%8A%A9%E3%81%A3%E4%BA%BA+OR+%E9%9F%B3%E4%BF%A1%E4%B8%8D%E9%80%9A+OR+%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%83%88+-Qiita+OR+%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88+OR+%E7%A4%BE%E5%86%85%E3%83%8B%E3%83%BC%E3%83%88+OR+%E7%A4%BE%E4%BC%9A%E7%9A%84">ツイセーブというサービス</a> の存在を知り登録したところ、 tweets.zip から過去の発言を登録できて最高に便利でした。
おかげでぼくの twitter での過去の発言を簡単に発掘でき、この記事を書くぼくの助けとなりました。</p>
</div>
秋葉原に引っ越した2014-09-19T00:00:00+09:002014-09-19T00:00:00+09:00yosida95tag:yosida95.com,2014-09-19:/2014/09/19/083000.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
さて、タイトルの通り9月12日から秋葉原に住んでいます。
19歳にして初めてのひとり暮らしを始めました。
ここに引っ越しの流れをメモがてら残しておきます。</p>
</div>
<div class="section" id="section-3">
<h2>引っ越しまでの過程</h2>
<div class="section" id="section-4">
<h3>8 月 31 日</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">マンションの内見申し込んだった</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/505993706474708992">August 31, 2014</a></blockquote></div>
<div class="section" id="section-5">
<h3>9 月 1 日</h3>
<p>仕事を途中で抜けてマンションの内見をしました。
内見を申し込んだのは神保町の物件だったのですが、不動産屋が同じ条件 (家賃, 地域) の物件を10部屋程度ピックアップしてくれ、その中から3部屋を内見しました。</p>
<p>3部屋目を内見しているその場で「ここに住みたいです」と伝え、その日のうちに申し込みを行いました。</p>
</div>
<div class="section" id="section-6">
<h3>9 月 3 日</h3>
<p>申し込んだ部屋は保証人が不要で保証会社に保証してもらうタイプなのですが、この保証会社による審査が通りました。
この段階に進んで初めて、実家で同居していた母にひとり暮らしをすることを宣言しました。</p>
</div>
<div class="section" id="section-7">
<h3>9 月 5 日</h3>
<p>インターネット回線の申し込みを行いました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ネット回線申し込みの件で電話があって対応したんだけど、担当の人の要領や話のテンポがすこぶる悪くて、よっぽど別の人に変わって貰おうか悩んだ。ただの開通までの流れの説明なのにどうしてあんなにまごまごしてんだよ</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/507739057611214849">September 5, 2014</a></blockquote></div>
<div class="section" id="section-8">
<h3>9 月 6 日</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">本命 (@ IKEA 船橋 in 船橋市, 千葉県) <a href="https://t.co/haLsxT80vq">https://t.co/haLsxT80vq</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/508147562386182144">September 6, 2014</a></blockquote><p>ベッドと作業用の机と椅子を購入しました。</p>
</div>
<div class="section" id="section-9">
<h3>9 月 7 日</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">I'm at 東急ハンズ 渋谷店 in 渋谷区, 東京都 <a href="https://t.co/cqJBvPLb8h">https://t.co/cqJBvPLb8h</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/508531775836934144">September 7, 2014</a></blockquote><p>マニフレックスのマットレスを購入しました。</p>
</div>
</div>
<div class="section" id="section-10">
<h2>9 月 9 日</h2>
<p>父に初めてひとり暮らしを始めることを伝え、引っ越しの手伝いを依頼しました。</p>
<div class="section" id="section-11">
<h3>9 月 12 日</h3>
<p>この日が入居日でした。
管理会社立ち会いのもと鍵の交換と室内設備の点検を行いました。</p>
<p>無事に鍵の引き渡しが済んだ後、 IKEA や東急ハンズで購入した家具が届き組立を行いました。
これによって、寝る場所と作業場所が確保され、最低限度の生活が可能な状態になりました。</p>
<p>ライフラインのうち電気と水道は開栓済みで、部屋に置いてある契約書を記入して送付するだけでした。
ガスは開栓のためにガス会社の人を呼んで作業をしてもらう必要があるのですが、そのことをすっかり失念していて慌てて東京ガスに連絡を入れたところ、その日のうちに開栓作業を行ってくれて大変助かりました。</p>
<p>インターネット回線の開通日もこの日だったのですが、プロバイダの手違いで入居日よりも前に PPPoE のクレデンシャルが書かれた書類が送付されてしまい受け取れなかったため、仕方がないので Interlink の無料お試しでインターネットに接続しました。</p>
</div>
<div class="section" id="section-12">
<h3>9 月 13 日</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">2 週連続 (@ IKEA 船橋 in 船橋市, 千葉県) <a href="https://t.co/lJvXNXy1RO">https://t.co/lJvXNXy1RO</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510674100734668800">September 13, 2014</a></blockquote><p>最低限度の生活には必要がないもののあると生活が便利になるラグマットや収納用品などを購入しました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">間違えた (@ ヨドバシカメラ マルチメディアAkiba in Chiyoda, 東京都) <a href="https://t.co/al8hsQgORY">https://t.co/al8hsQgORY</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510737587255148544">September 13, 2014</a></blockquote><p>冷蔵庫、洗濯乾燥機、電子レンジを購入しました。
販売員のお姉さんを長い時間捕まえて、製品のことに始まりお姉さんがひとり暮らしをしていた時代の冷蔵庫や洗濯機の使用頻度などまで訊いて散々悩んだ挙句の購入で、大変満足できる買い物が出来ました。</p>
</div>
<div class="section" id="section-13">
<h3>9 月 14 日</h3>
<p>ニトリでカーテンを購入し、実家から一時的に借りていたカーテンとリプレースしました。
また、島忠ホームズでクローゼットで使う収納を購入しました。
この日は父の同僚に車を出してもらい移動していたのですが、こういう時に荷物を積んで移動できる車は便利なのだなと感じました。
車が空を飛ぶか自動運転が普及するまでは免許を取らない、という決意が揺るぎそうになりました。</p>
</div>
<div class="section" id="section-14">
<h3>9 月 15 日</h3>
<p>ヨドバシカメラで買った洗濯機と冷蔵庫が届きました。
これで本格的に生活が落ち着きました。</p>
</div>
<div class="section" id="section-15">
<h3>9 月 16 日</h3>
<p>会社がある九段下までの定期券を購入してから出社しました。
出社後、会社へ住所の変更と通勤経路の変更を届出ました。</p>
</div>
</div>
<div class="section" id="section-16">
<h2>雑感</h2>
<p>不動産屋に初めて連絡をしてから2週間足らずで引っ越すという弾丸スケジュールだったため、毎日のように不動産屋や保証会社などから日に数本入る電話への対応をしたり、休日は家具や家電を買うために長距離を移動したり、9月の前半はめちゃくちゃ忙しかったです。</p>
<p>また、ぼくが19歳で未成年ということもあり、ぼくが契約者本人になれない契約 (フレッツ回線) や、親権者同意が必要な契約 (保証会社) があり、この社会は自活をする若者に厳しいなということ感じました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">郊外型ショッピングモール、マジで郊外で辛い</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510670943018942465">September 13, 2014</a></blockquote><p>引っ越しが済んで生活が落ち着いてからは、秋葉原という土地の便利さを実感しています。
また、会社まで電車で3駅で行けるため、電車移動によるモチベーションの低下も無視できるレベルになりました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ドンキホーテが朝 5 時までやってるの、どう考えても人類を幸せにしている</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510436248809271297">September 12, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">自宅から秋葉原駅や電気街まで徒歩で出られるの、革命的すぎる</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510629226903384064">September 13, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">マニフレックスのマットレスを買って昨日初めて使ったんだけど、昨日の睡眠ログの快眠度が今までで 1 番高かったので効果があるんだと思う</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/510620783169658880">September 13, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">引っ越しにあたって 14 万円という大変お高い洗濯機を買ったわけなんだけど、出社前にスイッチを入れて帰ってくると乾燥まで済んだ状態なの、素晴らしいとしか言えない。雨の日も梅雨も怖くない。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/512150772511805440">September 17, 2014</a></blockquote></div>
<div class="section" id="section-17">
<h2>終わりに</h2>
<table border="1" class="docutils">
<colgroup>
<col width="73%" />
<col width="27%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">項目</th>
<th class="head">金額</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>敷金</td>
<td>家賃 1 ヶ月分</td>
</tr>
<tr><td>礼金</td>
<td>家賃 1 ヶ月分</td>
</tr>
<tr><td>前家賃</td>
<td>家賃 1 ヶ月分</td>
</tr>
<tr><td>仲介手数料</td>
<td>家賃 0.5 ヶ月分</td>
</tr>
<tr><td>家電 (洗濯乾燥機, 冷蔵庫, 電子レンジ, WiFi AP)</td>
<td>20 万円</td>
</tr>
<tr><td>家具 (ベッド, マットレス, 机, 椅子, カーテンなど)</td>
<td>15 万円</td>
</tr>
<tr><td>生活用品/消耗品 (調理器具, タオル, 洗剤など)</td>
<td>5 万円</td>
</tr>
<tr><td>(合計)</td>
<td>70 万円</td>
</tr>
</tbody>
</table>
<p>これまで実家暮らしをしていたために全てを買い揃える必要があり、どうせ買うなら長く使えるよい物をと贅沢をした結果、思っていたより出費がかさみました。
新型 Mac mini が出たらすぐに買ってやろうと目論んでいましたが、これ以上貯金が減るのは精神衛生上よくないので、しばらくは見送りになりそうです。</p>
<p>そんなわたしへの引っ越し祝いをお待ちしています!! - <a class="reference external" href="http://www.amazon.co.jp/registry/wishlist/3B4Y3FGMQHMV5?sort=priority">わたしの欲しいものリスト</a></p>
</div>
Zabbix や munin のアラートを Pushover 経由でスマートフォンにプッシュ通知する2014-08-24T00:00:00+09:002014-08-24T00:00:00+09:00yosida95tag:yosida95.com,2014-08-24:/2014/08/24/114617.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>この記事は昨 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>この記事は昨年書いた「<a class="reference external" href="https://yosida95.com/2013/05/27/005303.html">Zabbix のメディアタイプに Growl を指定し、手元のマシンの Growl で障害情報を受け取る方法</a>」の焼き直しです。</p>
<p>こんにちは yosida95 です。
Pushover はスマートフォンにプッシュ通知を送ることに特化したサービスで、スマートフォンにレシーバーとなるアプリをインストールしておき、 REST API に通知内容を POST することで手軽にプッシュ通知を送れます。
類似サービスとしては <a class="reference external" href="http://im.kayac.com/">im.kayac.com</a> なんかが挙げられます。
IFTTT と連携させると最高便利です。</p>
<p>そんな Pushover を使って Zabbix や munin のアラートを手持ちのスマートフォンに通知してみようという試みです。</p>
</div>
<div class="section" id="zabbix">
<h2>Zabbix</h2>
<div class="section" id="pushover-zabbix-py">
<h3>pushover_zabbix.py</h3>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">urllib2</span>
<span class="kn">from</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="n">urlencode</span>
<span class="n">APPTOKEN</span> <span class="o">=</span> <span class="n">YOUR_APPLICATION_TOKEN</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">usertoken</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">params</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="n">token</span><span class="o">=</span><span class="n">APPTOKEN</span><span class="p">,</span>
<span class="n">user</span><span class="o">=</span><span class="n">usertoken</span><span class="p">,</span>
<span class="n">title</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
<span class="n">message</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s1">'https://api.pushover.net/1/messages.json'</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">urlencode</span><span class="p">(</span><span class="n">params</span><span class="p">))</span>
<span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
<ol class="arabic simple">
<li><tt class="docutils literal">zabbix_server.conf</tt> の <tt class="docutils literal">AlertScriptsPath</tt> で指定したディレクトリに置く</li>
<li>chmod で実行権限を与える</li>
<li>Zabbix の Web コントロール画面からメディアタイプに指定する</li>
<li>Pushover を使って通知を受け取りたい Zabbix ユーザーに、上記で追加したPushover メディアタイプを追加する<ul>
<li>この時、送信先として Pushover のユーザートークンを指定する</li>
</ul>
</li>
</ol>
<p>より詳細な設定手順は<a class="reference external" href="https://yosida95.com/2013/05/27/005303.html">Zabbix のメディアタイプに Growl を指定し、手元のマシンの Growl で障害情報を受け取る方法</a>を参照してください。</p>
</div>
</div>
<div class="section" id="munin">
<h2>munin</h2>
<pre class="code literal-block">
contacts pushover
contact.pushover.command /path/to/pushover_munin.py
</pre>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">urllib2</span>
<span class="kn">from</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="n">urlencode</span>
<span class="n">APPTOKEN</span> <span class="o">=</span> <span class="n">YOUR_APPLICATION_TOKEN</span>
<span class="n">USERTOKEN</span> <span class="o">=</span> <span class="n">YOUR_USER_TOKEN</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">params</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="n">token</span><span class="o">=</span><span class="n">APPTOKEN</span><span class="p">,</span>
<span class="n">user</span><span class="o">=</span><span class="n">USERTOKEN</span><span class="p">,</span>
<span class="n">message</span><span class="o">=</span><span class="n">message</span><span class="p">)</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s1">'https://api.pushover.net/1/messages.json'</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">urlencode</span><span class="p">(</span><span class="n">params</span><span class="p">))</span>
<span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
<ol class="arabic simple">
<li>pushover_mnin.py を munin がアクセスできるパスに munin がアクセスできる権限で設置する</li>
<li>pushover_munin.py に実行権限を与える</li>
<li>munin.conf に上記 2 行を追記する</li>
</ol>
</div>
<div class="section" id="section-2">
<h2>おわりに</h2>
<p><a class="reference external image-reference" href="https://yosida95.com/photos/oUryv"><img alt="Zabbix pushover" src="https://yosida95.com/photos/oUryv.resized.jpeg" style="width: 100%;" /></a></p>
<p>写真のような通知が iPhone に飛んできて最高便利です。</p>
<p>以上です。
ありがとうございました。</p>
</div>
Ubuntu で Zabbix Server を 1.8 系から 2.2 系へアップグレードした時のコマンドメモ2014-07-31T00:00:00+09:002014-07-31T00:00:00+09:00yosida95tag:yosida95.com,2014-07-31:/2014/07/31/033319.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>わたしが運用 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>わたしが運用しているすべてのサーバーは munin と Zabbix によって監視しています。
これまで Ubuntu 12.04 の apt リポジトリで提供されている Zabbix 1.8 を利用していましたが、 Web コントロールパネルが壊れたことを契機に、これを直すのではなく 2.2 にアップグレードしました。</p>
<p>アップグレードは 27 日の夜中に行い無事終了しましたが、どこかに記録を残して置かないともったいないと思い立ったので .zsh_history を元に手順をメモしておきます。</p>
</div>
<div class="section" id="section-2">
<h2>手順</h2>
<div class="highlight"><pre><span></span><span class="nb">cd</span><span class="w"> </span><span class="nv">$HOME</span>
<span class="c1"># Stop Zabbix Server (1.8)</span>
sudo<span class="w"> </span>service<span class="w"> </span>zabbix-server<span class="w"> </span>stop
<span class="c1"># Create a backup</span>
mkdir<span class="w"> </span>./zabbix-backup
mysqldump<span class="w"> </span>-uroot<span class="w"> </span>-p<span class="w"> </span>zabbix<span class="w"> </span>><span class="w"> </span>./zabbix-backup/dump.db
sudo<span class="w"> </span>cp<span class="w"> </span>/etc/zabbix/<span class="o">{</span>apache.conf,zabbix_server.conf<span class="o">}</span><span class="w"> </span>./zabbix-backup
sudo<span class="w"> </span>cp<span class="w"> </span>-r<span class="w"> </span>/etc/zabbix/alert.d<span class="w"> </span>./zabbix-backup
<span class="c1"># Remove Zabbix Server (1.8) and Zabbix frontend</span>
sudo<span class="w"> </span>apt-get<span class="w"> </span>remove<span class="w"> </span>zabbix-server-mysql<span class="w"> </span>zabbix-frontend-php
<span class="c1"># Add official apt repositories</span>
sudo<span class="w"> </span>zsh<span class="w"> </span>-c<span class="w"> </span><span class="s1">'cat << EOF > /etc/apt/sources.list.d/zabbix.list</span>
<span class="s1">deb http://repo.zabbix.com/zabbix/2.2/ubuntu/ precise main</span>
<span class="s1">deb-src http://repo.zabbix.com/zabbix/2.2/ubuntu/ precise main</span>
<span class="s1">EOF'</span>
curl<span class="w"> </span>-o<span class="w"> </span>-<span class="w"> </span>http://repo.zabbix.com/zabbix-official-repo.key<span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>apt-key<span class="w"> </span>add<span class="w"> </span>-
sudo<span class="w"> </span>apt-get<span class="w"> </span>update
<span class="c1"># Make sure Zabbix Server(2.2) will be installed and install it</span>
sudo<span class="w"> </span>apt-cache<span class="w"> </span>policy<span class="w"> </span>zabbix-server-mysql<span class="w"> </span>zabbix-frontend-php
sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>zabbix-server-mysql<span class="w"> </span>zabbix-frontend-php
sudo<span class="w"> </span>service<span class="w"> </span>zabbix-server<span class="w"> </span>stop
<span class="c1"># Edit configuration file</span>
sudo<span class="w"> </span>vimdiff<span class="w"> </span>./zabbix-backup/zabbix_server.conf<span class="w"> </span>/etc/zabbix/zabbix_server.conf
sudo<span class="w"> </span>vimdiff<span class="w"> </span>./zabbix-backup/apache.conf<span class="w"> </span>/etc/zabbix/apache.conf
<span class="c1"># Download source code of Zabbix Server(2.2) and migrate database schemas from 1.8's one to 2.0's</span>
apt-get<span class="w"> </span><span class="nb">source</span><span class="w"> </span>zabbix-server-mysql
<span class="nb">cd</span><span class="w"> </span>./zabbix-2.2.5/upgrades/dbpatches/2.0
mysql<span class="w"> </span>-uroot<span class="w"> </span>-p<span class="w"> </span>zabbix<span class="w"> </span><<span class="w"> </span>./patch.sql
<span class="c1"># Start Zabbix Server(2.2) and monitor progress of auto database schema migration</span>
sudo<span class="w"> </span>service<span class="w"> </span>zabbix-server-mysql<span class="w"> </span>start
watch<span class="w"> </span><span class="s1">'sudo tail -n 20 /var/log/zabbix/zabbix_server.log'</span>
</pre></div>
</div>
<div class="section" id="section-3">
<h2>おわりに</h2>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">Zabbix を OS の標準リポジトリに入っている 1.8 系から 2.2.4 にアップグレードした。長い道のりだった。主に mysqldump でのバックアップ作成と 1.8 から 2.0 の時のデータベースマイグレーションが。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/493613687597318144">July 28, 2014</a></blockquote><p>1.8 から 2.0 へのデータベースマイグレーションバッチは 500 万レコードくらいのテーブルに対して容赦なく ALTER TABLE を仕掛けてくるのでめちゃくちゃ時間がかかります。
あまりに時間がかかったので、夜中バッチを起動して翌朝に完了していることを期待してそのまま眠りました。</p>
</div>
Gehirn DNS の Golang API Client を書いた2014-07-03T00:00:00+09:002014-07-03T00:00:00+09:00yosida95tag:yosida95.com,2014-07-03:/2014/07/03/163536.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。</p>
</div>
<div class="section" id="gehirndns">
<h2>GehirnDNS</h2>
<p><a class="reference external" href="http://www.gehirn.jp/dns.html">Gehirn DNS</a> という DNS サービスがあることをご存知でしょうか。
<a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社</a> という会社が 2 ゾーンまで無料、 3 ゾーン以上はどれだけゾーンを増やしても 300 円(税抜き)という価格で提供している、低額の DNS サービスです。</p>
<p>この DNS サービスでは、使いやすく先進的なコントロールパネルと、開発者にありがたい REST API を提供していて、低額で提供されていることが信じられないほどです。</p>
<p>このイケている DNS サービス、 <a class="reference external" href="http://www.gehirn.jp/dns.html">Gehirn DNS</a> には 1 つだけイケていない点があります。
それは、オフィシャル・アンオフィシャル問わず <a class="reference external" href="http://golang.org/">Go 言語</a>で書かれた API Client が無いということです。</p>
</div>
<div class="section" id="golang-gehirndns">
<h2>golang-gehirndns</h2>
<p>無いのであれば作ろう、ということで作りました。</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/yosida95/golang-gehirndns">yosida95/golang-gehirndns</a></li>
<li><a class="reference external" href="http://godoc.org/github.com/yosida95/golang-gehirndns">GoDoc</a></li>
</ul>
<p>今回ぼくが <a class="reference external" href="https://github.com/yosida95/golang-gehirndns">golang-gehirndns</a> を書いたことによって <a class="reference external" href="http://www.gehirn.jp/dns.html">Gehirn DNS</a> のイケていない点が無くなってしまいました。
ということで、 <a class="reference external" href="http://www.gehirn.jp/dns.html">Gehirn DNS</a> は超イケている DNS サービスです。</p>
</div>
<div class="section" id="section-2">
<h2>おわりに</h2>
<p>ぼくが<a class="reference external" href="https://yosida95.com/2013/08/01/222538.html">昨年の 8 月に転職した</a>こととこの記事の内容は無関係です。</p>
</div>
AWS の CloudFront で独自 SSL 証明書を利用する2014-07-01T00:00:00+09:002014-07-01T00:00:00+09:00yosida95tag:yosida95.com,2014-07-01:/2014/07/01/021829.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。</p>
<p>昨 6 月 30 日の 2 時から 5 時の間に、さくら VPS の一部ホストマシンでハードウェア交換のメンテナンスがありました。
運の悪いことに、<a class="reference external" href="https://miteru.yosida95.com/">見てるなう</a> などを提供しているインスタンスがこのメンテナンスの影響を受け、サービスの提供を一時的に停止しました。</p>
<p>twitter では事前に予告したのですが、ありがたいことに<a class="reference external" href="https://miteru.yosida95.com/">見てるなう</a> は多くの方にご利用いただいており、もちろんその中にはぼくのフォロワーさんでない方もいらっしゃるので、これだけでは周知が不十分です。</p>
<p>そこで、 Route53 の Health Check 機能とこれに連動した Failover 機能を使って、サーバーが止まっている間だけ A レコードを書き換え、影響を受ける全てのサービスの全てのパスで CloudFront にホストしたメンテナンスを知らせるメッセージを表示できるようにしてみました。</p>
<p>Route53 を使った Failover 先として一般的に使われる先は Amazon S3 です。
Amazon Web Services の公式ブログにも Failover 先として S3 を利用する方法が紹介されています。</p>
<p>今回、なぜ CloudFront を利用したかというと、それは <strong>独自の SSL 証明書を利用する必要があった</strong> ためです。
<a class="reference external" href="https://miteru.yosida95.com/">見てるなう</a> を始めとするぼくが提供している Web サービスをご利用頂いている方はお気づきかもしれませんが、全ての通信を SSL に乗せて暗号化しています。
障害を検知して Failover に成功したとしても、 SSL 証明書の検証に失敗してユーザーに警告画面が表示されるようでは意味がありませんので、今回は独自の SSL 証明書を使える CloudFront を利用しました。</p>
</div>
<div class="section" id="iam">
<h2>証明書を IAM にアップロードする</h2>
<div class="section" id="awscli">
<h3>awscli のインストール</h3>
<p>まずは、 CloudFront で利用する証明書を Amazon Web Services の IAM にアップロードする必要があります。
証明書のアップロードについては、 API が用意されているものの Web コントロールパネルからはその操作ができません。
そのため、今回は Python で書かれたコマンドラインツールである<a class="reference external" href="http://aws.amazon.com/jp/cli/">AWS コマンドラインインターフェース</a> (<tt class="docutils literal">awscli</tt>) をインストールし、コマンドラインから証明書のアップロードを行います。</p>
<div class="section" id="homebrew">
<h4>Homebrew を使ったインストール</h4>
<p>Mac OS X で Homebrew を利用している方は以下のコマンドで簡単にインストールすることができます。</p>
<div class="highlight"><pre><span></span>brew<span class="w"> </span>install<span class="w"> </span>awscli
</pre></div>
</div>
<div class="section" id="pip">
<h4>pip を使ったインストール</h4>
<p><tt class="docutils literal">awscli</tt> は PyPI に登録されていますので、 <tt class="docutils literal">pip</tt> によってもインストールすることができます。</p>
<div class="highlight"><pre><span></span>pip<span class="w"> </span>install<span class="w"> </span>awscli
</pre></div>
<p>Homebrew を利用していない方、または <tt class="docutils literal"><span class="pre">/usr/local/lib/pythonX.X/site-packages</span></tt> を汚したくない方は、この方法でインストールすることをおすすめします。</p>
</div>
</div>
<div class="section" id="section-2">
<h3>証明書のアップロード</h3>
<p><tt class="docutils literal">awscli</tt> のインストールが完了したら、次に示すコマンドによって証明書のアップロードを実行します。</p>
<div class="highlight"><pre><span></span><span class="nv">$name</span><span class="o">=</span><span class="s2">"name of certificate"</span>
<span class="nv">$certificate</span><span class="o">=</span>/path/to/server-certificate.pem
<span class="nv">$privkey</span><span class="o">=</span>/path/to/server-private-key.pem
<span class="nv">$certchain</span><span class="o">=</span>/path/to/intermediate-certificate-chain.pem
aws<span class="w"> </span>iam<span class="w"> </span>upload-server-certificate<span class="w"> </span>--path<span class="w"> </span>/cloudfront/<span class="w"> </span>--server-certificate-name<span class="w"> </span><span class="nv">$name</span><span class="w"> </span>--certificate-body<span class="w"> </span><span class="s2">"file://</span><span class="nv">$certificate</span><span class="s2">"</span><span class="w"> </span>--private-key<span class="w"> </span><span class="s2">"file://</span><span class="nv">$privkey</span><span class="s2">"</span><span class="w"> </span>--certificate-chain<span class="w"> </span><span class="s2">"file://</span><span class="nv">$certchain</span><span class="s2">"</span>
</pre></div>
</div>
</div>
<div class="section" id="cloudfront-ssl">
<h2>CloudFront に独自 SSL 証明書を適用する</h2>
<p>証明書のアップロードが完了したら、最後に CloudFront にアップロードした証明書を適用します。</p>
<ol class="arabic simple">
<li>Amazon Web Service の Web コントロールパネルを開きます</li>
<li>CloudFront のコントロールパネルに移動します</li>
<li>Distributions の中から Failover 先の Distribution を選択し、 Distribution Settings に移動します</li>
<li>General タブの Edit ボタンを押します</li>
<li>以下のスクリーンキャプチャを参考に設定します <a class="reference external image-reference" href="https://yosida95.com/photos/cAy7p.raw.png"><img alt="CloudFront 設定画面" src="https://yosida95.com/photos/cAy7p.resized.png" style="width: 100%;" /></a></li>
</ol>
<p>以上です。
あとは Distribution の Status が Deployed に変わったら、独自のドメインで SSL 通信ができることを確認して完了です。</p>
<p>ありがとうございました。</p>
</div>
19 歳になった2014-06-16T00:00:00+09:002014-06-16T00:00:00+09:00yosida95tag:yosida95.com,2014-06-16:/2014/06/16/000021.html<p>19 歳になりました。
18 歳 …</p><p>19 歳になりました。
18 歳の時はゲヒルンに入社したり、<a class="reference external" href="https://yosida95.com/2013/12/22/000222.html">年の瀬にブログエントリをバズらせた</a>り、高校を卒業したり、と大きなイベントが幾つかありました。
法律上結婚もできるようになりました。
もっとも、法律的に結婚が許されていることと実際に結婚ができることは別のことです。</p>
<p>しかし、 19 歳になったところで人生のターニングポイント的な大きなイベントがあるようには思えません。
未成年なので酒は飲めませんし、選挙権ももらえません。
国税庁の民間給与実態統計調査によれば 20 代後半から 30 代前半に相当する額の給与所得を得てその分しっかりと納税の義務を果たし、前世の行いが悪かったせいもあり、年老いた時にまともにもらえるとも思えない年金を 18 歳から納めていますが、それでも選挙権はもらえません。</p>
<p>こうして年を重ねる毎に日常が平坦て刺激のないものになってしまうのかと思うと涙を禁じ得ないので、受け身ではなく自らイベントを起こしていく姿勢で、実りある 19 歳にしていきたいと思います。</p>
<p>そんな 19 歳の誕生日を迎えたぼくへの<a class="reference external" href="http://amzn.to/yosida95">誕生日プレゼント</a>をお待ちしています。</p>
<p><a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> 先生からはすでに誕生日プレゼントをもらいました。
<img alt="birthday present 1" src="https://yosida95.com/photos/m5jkB.raw.jpeg" style="width: 100%;" /></p>
<p>koba789 先生は大変に気の利く男で、可能な限り誕生日直前になるような配送時刻の指定を行っていました。
世の中はこういった気の利かせられる人間ほど結婚できやすい仕組みになっているように感じます。
<img alt="birthday present 2" src="https://yosida95.com/photos/438Oi.raw.jpeg" style="width: 100%;" /></p>
<p>ただし、このような狂気的な誕生日メッセージはいただけません。
<img alt="birthday present 3" src="https://yosida95.com/photos/tckWb.raw.jpeg" style="width: 100%;" /></p>
<p>ぼくは誕生日の 364 日後まで誕生日プレゼントを受け付けていますので、気の利く方はぼくに<a class="reference external" href="http://amzn.to/yosida95">誕生日プレゼントをお贈りください</a>。
今はまだ気の利かない方も 364 日以内に気を利かせられるようになって誕生日プレゼントを贈ってください。
お待ちしています。</p>
<p>若い女性に限ってはご自身にリボンを巻き、「私がプレゼントです。」といった形のプレゼントでもよいです。
むしろそちらのほうがよいです。
よろしくお願いします。</p>
<p>以上です。
ありがとうございました。</p>
JSONSchema を Python のオブジェクトとマッピングするライブラリを作った2014-06-15T00:00:00+09:002014-06-15T00:00:00+09:00yosida95tag:yosida95.com,2014-06-15:/2014/06/15/233351.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
世の中には <a class="reference external" href="http://json-schema.org/">JSONSchema</a> という規格があります。</p>
<p>これは JSON データの format を JSON で定義しようという趣旨の規格で、合わせてバリデーションに関する定義もなされているので、 API ドキュメントとしてこの JSONSchema を公開しておくことでどのようなフォーマットのデータを送ればよいのかということを統一した方法で API 利用者に伝えられ、 API 提供者も受け取ったデータを公開した JSONSchema によってバリデーションすることができます。</p>
<p>JSONSchema の仕様を見ていくほど、無理に core と validation を切り分けようとして残念な感じになっている部分とか、複雑になっている部分とかが散見されて残念な気持ちになりますが、まだ draft4 なので目をつぶります。</p>
</div>
<div class="section" id="jsonschema-in-python">
<h2>JSONSchema in Python</h2>
<p>ぼくがメインとしている言語の 1 つである Python にも JSONSchema に則ってデータのバリデーションをしてくれるその名もズバリ <a class="reference external" href="https://pypi.python.org/pypi/jsonschema">jsonschema</a> というライブラリがあります。
このライブラリは jsonschema の draft v3 と draft v4 をサポートしていて、問題なくデータのバリデーションを行ってくれるのですが、不便な点に JSONSchema の定義を Python の <tt class="docutils literal">dict</tt> として与えるというものがあります。</p>
<p>つまり、このようにします。</p>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="kn">from</span> <span class="nn">jsonschema</span> <span class="kn">import</span> <span class="n">validate</span>
<span class="o">>>></span> <span class="c1"># A sample schema, like what we'd get from json.load()</span>
<span class="o">>>></span> <span class="n">schema</span> <span class="o">=</span> <span class="p">{</span>
<span class="o">...</span> <span class="s2">"type"</span> <span class="p">:</span> <span class="s2">"object"</span><span class="p">,</span>
<span class="o">...</span> <span class="s2">"properties"</span> <span class="p">:</span> <span class="p">{</span>
<span class="o">...</span> <span class="s2">"price"</span> <span class="p">:</span> <span class="p">{</span><span class="s2">"type"</span> <span class="p">:</span> <span class="s2">"number"</span><span class="p">},</span>
<span class="o">...</span> <span class="s2">"name"</span> <span class="p">:</span> <span class="p">{</span><span class="s2">"type"</span> <span class="p">:</span> <span class="s2">"string"</span><span class="p">},</span>
<span class="o">...</span> <span class="p">},</span>
<span class="o">...</span> <span class="p">}</span>
<span class="o">>>></span> <span class="c1"># If no exception is raised by validate(), the instance is valid.</span>
<span class="o">>>></span> <span class="n">validate</span><span class="p">({</span><span class="s2">"name"</span> <span class="p">:</span> <span class="s2">"Eggs"</span><span class="p">,</span> <span class="s2">"price"</span> <span class="p">:</span> <span class="mf">34.99</span><span class="p">},</span> <span class="n">schema</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">validate</span><span class="p">(</span>
<span class="o">...</span> <span class="p">{</span><span class="s2">"name"</span> <span class="p">:</span> <span class="s2">"Eggs"</span><span class="p">,</span> <span class="s2">"price"</span> <span class="p">:</span> <span class="s2">"Invalid"</span><span class="p">},</span> <span class="n">schema</span>
<span class="o">...</span> <span class="p">)</span> <span class="c1"># doctest: +IGNORE_EXCEPTION_DETAIL</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="o">...</span>
<span class="n">ValidationError</span><span class="p">:</span> <span class="s1">'Invalid'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">of</span> <span class="nb">type</span> <span class="s1">'number'</span>
</pre></div>
<p>スキーマが小さかったり、扱うスキーマの数が少ない場合にはこれでも十分かもしれませんが、 API が大規模になってくると <tt class="docutils literal">dict</tt> で宣言することは不便です。</p>
<p>この問題を解決するために <a class="reference external" href="https://pypi.python.org/pypi/jsmapper">jsmapper</a> というライブラリをこの jsonschema ライブラリのフロントエンドとして作りました。</p>
</div>
<div class="section" id="jsmapper">
<h2>jsmapper</h2>
<p>jsmapper では全ての JSONSchema を JSONSchema というクラスのインスタンスとして宣言します。
また、 JSONSchema における primitive 型には対応する Python のクラスが存在します。
先ほど jsonschema 例に挙げたスキーマを、 jsmapper では以下のように定義します。</p>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">from</span> <span class="nn">jsmapper</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">JSONSchema</span><span class="p">,</span>
<span class="n">Object</span><span class="p">,</span>
<span class="n">Number</span><span class="p">,</span>
<span class="n">String</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">Schema</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span>
<span class="nb">type</span><span class="o">=</span><span class="n">Object</span><span class="p">(</span>
<span class="n">properties</span><span class="o">=</span><span class="p">{</span>
<span class="s2">"name"</span><span class="p">:</span> <span class="n">JSONSChema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">String</span><span class="p">()),</span>
<span class="s2">"price"</span><span class="p">:</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">()),</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="p">)</span>
</pre></div>
<p>しかし、これではあまり幸せになった感じはしない上、タイプ数も増えてしまっています。
そこで以下のようにも定義することができます。</p>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">from</span> <span class="nn">jsmapper</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">JSONSchema</span><span class="p">,</span>
<span class="n">Mapping</span><span class="p">,</span>
<span class="n">Number</span><span class="p">,</span>
<span class="n">Object</span><span class="p">,</span>
<span class="n">String</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">class</span> <span class="nc">ObjectProperty</span><span class="p">(</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">String</span><span class="p">())</span>
<span class="n">price</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">())</span>
<span class="n">Schema</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span>
<span class="nb">type</span><span class="o">=</span><span class="n">Object</span><span class="p">(</span>
<span class="n">properties</span><span class="o">=</span><span class="n">ObjectProperty</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">Schema</span><span class="o">.</span><span class="n">validate</span><span class="p">({</span><span class="s2">"name"</span> <span class="p">:</span> <span class="s2">"Eggs"</span><span class="p">,</span> <span class="s2">"price"</span> <span class="p">:</span> <span class="mf">34.99</span><span class="p">})</span>
<span class="n">inst</span> <span class="o">=</span> <span class="n">Schema</span><span class="o">.</span><span class="n">bind</span><span class="p">({</span><span class="s2">"name"</span> <span class="p">:</span> <span class="s2">"Eggs"</span><span class="p">,</span> <span class="s2">"price"</span> <span class="p">:</span> <span class="mf">34.99</span><span class="p">})</span>
<span class="k">assert</span> <span class="n">inst</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s2">"Eggs"</span>
<span class="k">assert</span> <span class="n">inst</span><span class="o">.</span><span class="n">price</span> <span class="o">==</span> <span class="mf">34.99</span>
</pre></div>
<p>この方法の優れたところは、 API を提供するにあたって最も使われるであろう Object 型の properties をクラスを宣言することによって定義でき、また <tt class="docutils literal">bind</tt> メソッドを使うとバリデーションに成功した場合の返り値として properties
に渡したクラスのインスタンスが受け取れ、その値にインスタンス変数としてドット演算子でアクセスできることです。
もう <tt class="docutils literal">dict</tt> の添字としてアクセスする必要はありません。</p>
<p>また、定義したクラスを継承して派生クラスを作ることができるので、エンドポイントによってわずかにプロパティが違う場合なども <tt class="docutils literal">dict</tt> を一から宣言することなく異なるプロパティのクラス変数をオーバーライドするだけです。</p>
<p>最後に、少し大きめな jsmapper による JSONSchema の定義を示します。</p>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">from</span> <span class="nn">jsmapper</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">JSONSchema</span><span class="p">,</span>
<span class="n">Array</span><span class="p">,</span>
<span class="n">Mapping</span><span class="p">,</span>
<span class="n">Number</span><span class="p">,</span>
<span class="n">Object</span><span class="p">,</span>
<span class="n">String</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">jsmapper.defines</span> <span class="kn">import</span> <span class="n">JSONSchemaDraftV4</span>
<span class="k">class</span> <span class="nc">Product</span><span class="p">(</span><span class="n">Mapping</span><span class="p">):</span>
<span class="k">class</span> <span class="nc">Dimensions</span><span class="p">(</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">length</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">())</span>
<span class="n">width</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">())</span>
<span class="n">height</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">())</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">(),</span>
<span class="n">description</span><span class="o">=</span><span class="s2">"The unique identifier for a product"</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">String</span><span class="p">())</span>
<span class="n">price</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Number</span><span class="p">(</span><span class="n">minimum</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">exclusive_minimum</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
<span class="n">tags</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Array</span><span class="p">(</span><span class="n">items</span><span class="o">=</span><span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">String</span><span class="p">()),</span>
<span class="n">min_items</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">unique_items</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
<span class="n">dimensions</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">Object</span><span class="p">(</span>
<span class="n">properties</span><span class="o">=</span><span class="n">Dimensions</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="p">[</span><span class="n">Dimensions</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">Dimensions</span><span class="o">.</span><span class="n">width</span><span class="p">,</span> <span class="n">Dimensions</span><span class="o">.</span><span class="n">height</span><span class="p">]</span>
<span class="p">))</span>
<span class="n">warehouseLocation</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span>
<span class="n">ref</span><span class="o">=</span><span class="s2">"http://json-schema.org/geo"</span><span class="p">,</span>
<span class="n">description</span><span class="o">=</span><span class="s2">"Coordinates of the warehouse with the product"</span>
<span class="p">)</span>
<span class="n">ProductSchema</span> <span class="o">=</span> <span class="n">JSONSchema</span><span class="p">(</span>
<span class="n">schema</span><span class="o">=</span><span class="n">JSONSchemaDraftV4</span><span class="p">,</span>
<span class="n">title</span><span class="o">=</span><span class="s2">"Product set"</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="n">Array</span><span class="p">(</span>
<span class="n">items</span><span class="o">=</span><span class="n">JSONSchema</span><span class="p">(</span>
<span class="n">title</span><span class="o">=</span><span class="s2">"Product"</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="n">Object</span><span class="p">(</span>
<span class="n">properties</span><span class="o">=</span><span class="n">Product</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="p">[</span><span class="n">Product</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">Product</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">Product</span><span class="o">.</span><span class="n">price</span><span class="p">]</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">),</span>
<span class="p">)</span>
</pre></div>
<p>以上です。
最新バージョンである 0.1.7 のリリースは 2 週間以上前ですが、仕事が忙しく、また他のライブラリの開発もしていてブログエントリにすることを忘れていたことを思い出したので書いてみました。</p>
<p>ちなみにこのライブラリは Python 3 でしか動きません。
テストは Python 3.3 と Python 3.4 で行っています。
このライブラリに関係する Python 2 との違いは metaclass
の指定方法だけだと思いますので、 3to2 を使えば自動でコンバートできると思います。
ぼくはこのライブラリを Python 2 で使う予定はないので、 Python 2 に対応する予定もありません。</p>
</div>
<div class="section" id="section-2">
<h2>おわりに</h2>
<p>開発は <a class="reference external" href="https://github.com/yosida95/python-jsmapper">GitHub</a> 上で行っているので、不具合報告や改善案がある場合はそれぞれ Issue や Pull Request でおねがいします。</p>
<p>また、明日は私の誕生日です。
このライブラリによって救われる方や、純粋に私の誕生日を祝ってくださる方からの<a class="reference external" href="http://amzn.to/yosida95">誕生日プレゼントをお待ちしています</a>。</p>
</div>
見てるなう(仮)を早くした2014-06-01T00:00:00+09:002014-06-01T00:00:00+09:00yosida95tag:yosida95.com,2014-06-01:/2014/06/01/123403.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>おはようござ …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>おはようございます。
yosida95 です。</p>
<p><a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a> とは、閲覧中の Web サイトを Twitter で簡単に共有するためのブックマークレットです。
製作した経緯は<a class="reference external" href="https://yosida95.com/2012/04/28/235534.html">見てるなう(仮)を作った</a>というエントリにまとめてあります。</p>
<p>運営を始めて丸 2 年が経ちましたが、おかげさまでユーザーも大変増えました。
類似サービスの存在はいくつか認識していますが、 Twitter を <tt class="docutils literal">#miteru</tt> で検索すると、そのほとんどが私が製作した<a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a>を利用して投稿されたものであることがわかります。</p>
<p>本日、<a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a>をアップデートし、より快適にご利用いただけるようにしました。</p>
</div>
<div class="section" id="section-3">
<h2>アップデートの内容</h2>
<div class="section" id="section-4">
<h3>高速化</h3>
<p><a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a>は過去に指摘された<a class="reference external" href="https://yosida95.com/2012/06/25/021925.html">セキュリティ上の問題</a>から、ワンタイムトークンを発行した後に投稿フォームへと進む仕様でした。
今回のアップデートでは認証方法を変更し、ワンタイムトークンを発行することなく投稿フォームへと進むことができるようになりました。</p>
<p>ワンタイムトークンの代わりに、ブックマークレットに含まれた共有鍵を使ってリクエストパラメーターを署名することで、これまでと同程度のセキュリティを担保しています。</p>
</div>
<div class="section" id="section-5">
<h3>ブックマークレット毎の共有鍵</h3>
<p>これまでの仕様では共有鍵を Twitter アカウント毎に発行していたため、複数のデバイスで同じ Twitter アカウント用のブックマークレットをインストールした場合でも、共通の共有鍵が使われていました。
今回のアップデートは、ブックマークレット毎に共有鍵を生成するように変更しました。
そのため、万が一共有鍵が漏れた場合でも、個別の共有鍵を revoke することによって不正な投稿を防ぐことができます。</p>
</div>
<div class="section" id="section-6">
<h3>技術的なサムシング</h3>
<div class="section" id="python-3-4">
<h4>Python 3.4 へのアップデート</h4>
<p>これまでは Python 2.7 で動いていましたが、今回のアップデートに伴って Python 3.4 へと移行しました。
フレームワークはこれまでどおり Pyramid を利用し、 Twitter との連携は tweepy の利用をやめ、 OAuth 周りに<a class="reference external" href="https://github.com/idan/oauthlib">oauthlib</a>を採用、リクエスト周りは手書きしました。</p>
</div>
<div class="section" id="jquery">
<h4>jQuery の廃止</h4>
<p>投稿画面ではこれまで、プレースホルダーや、ウィンドウ表示時にコメントフィールドにフォーカスを合わすことを実現するために、 jQuery を用いてきました。
今回のアップデートは jQuery の利用を廃止し、 JavaScript の標準 API のみを用いて DOM の操作などを実現しています。</p>
</div>
<div class="section" id="section-7">
<h4>データストアの変更</h4>
<p>これまでは MongoDB を利用してきましたが、 MariaDB へ乗り換えました。</p>
</div>
<div class="section" id="section-8">
<h4>コンテナ化</h4>
<p>これまではサーバーの中で直にアプリケーションインスタンスを起動していましたが、今回のアップデートによって専用のコンテナの中で動かすようにしました。
ちなみに、今流行りの Docker ではなく、 LXC を生で叩いています。</p>
</div>
<div class="section" id="section-9">
<h4>テスト</h4>
<p>これまでは<a class="reference external" href="https://www.youtube.com/watch?v=tOWZB9tFgu8">よしだ VPS</a>に作った Jenkins インスタンスの上でテストを回していましたが、 Jenkins のアップデートやサーバーの更新、言語の実行環境の構築などから開放され、開発中のプロダクトのテストを実行することのみに集中できる点に惹かれ、先日 CircleCI を個人で契約しました。
そして、今回のアップデートの開発中はそのテストを CircleCI で回していました。
今後はクローズドソースのプロダクトは CircleCI でテストを回し、オープンソースのプロダクトは TravisCI でテストを回していく方針です。</p>
</div>
</div>
</div>
<div class="section" id="section-10">
<h2>終わりに</h2>
<p>これらのアップデートは、本日よりご利用いただくことができます。
今までご利用頂いていた方にも、いかなる手続きを必要とせずにアップデートが適用されます。</p>
<p>今回のアップデートに関して発生したと思われる問題、その他の問題がありましたら <a class="reference external" href="https://twitter.com/yosida95">Twitter</a> または <a class="reference external" href="https://www.google.com/recaptcha/mailhide/d?k=01zs72Bn9xjCrWFSVTR9iUNw==&c=twvYTxrQ6qscX7r-9ew6RfzB3wBg4QI5gXMjsh6DpUc=">EMail</a> にてご連絡ください。</p>
<p>今後とも、<a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a>をよろしくお願いします。</p>
</div>
TravisCI が Python 3.4 をサポートしたので tox を叩く .travis.yml を更新する2014-05-01T00:00:00+09:002014-05-01T00:00:00+09:00yosida95tag:yosida95.com,2014-05-01:/2014/05/01/063132.html<div class="section" id="section-1">
<h2>更新</h2>
<div class="section" id="t17-15-00z">
<h3>2014-05-05T17:15:00Z</h3>
<p><a class="reference external" href="https://github.com/GehirnInc/py3oauth2/pull/1">GehirnInc/py3oauth2#1</a> を頂 …</p></div></div><div class="section" id="section-1">
<h2>更新</h2>
<div class="section" id="t17-15-00z">
<h3>2014-05-05T17:15:00Z</h3>
<p><a class="reference external" href="https://github.com/GehirnInc/py3oauth2/pull/1">GehirnInc/py3oauth2#1</a> を頂いて気づいたのですが、 TravisCI がサポートしているすべてのバージョンの Python に PATH が通っているようです。
ぼくがこの記事を執筆した時点では通っていなかったのですが、アップデートがあったようです。
そのためこの記事の寿命は終わりました。
よりシンプルに以下のようにするだけで、執筆時点の <tt class="docutils literal">.travis.yml</tt> と同じようにビルドすることができます。</p>
<p>Python のバージョンを指定していないため、 TravisCI (Ubuntu 12.04) がデフォルトとしている Python 2.7 が使われますが、 <tt class="docutils literal">tox</tt> は Python 2.7 でも動作し、 <tt class="docutils literal">python3.x</tt> に <tt class="docutils literal">PATH</tt> が通っているため、これで問題なくビルドできます。</p>
<div class="highlight"><pre><span></span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python</span>
<span class="nt">env</span><span class="p">:</span>
<span class="w"> </span><span class="nt">matrix</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py33"</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py34"</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="coverage"</span>
<span class="nt">install</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pip install tox</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">if test "$TOXENV" = "coverage"; then pip install coveralls; fi</span>
<span class="nt">script</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">tox</span>
<span class="nt">after_success</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">if test "$TOXENV" = "coverage"; then coveralls; fi</span>
</pre></div>
</div>
</div>
<div class="section" id="section-2">
<h2>はじめに</h2>
<p>おはようございます、 yosida95 です。</p>
<p>さて、最近の私は <a class="reference external" href="http://www.gehirn.co.jp/">Gehirn</a> で人権活動と称して、自分の人権を確保するために進捗を作る毎日を送っています。
以下に私の人権活動の履歴を示します。</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/GehirnInc/py3oauth2">GehirnInc/py3oauth2</a></li>
<li><a class="reference external" href="https://github.com/GehirnInc/python-jwt">GehirnInc/python-jwt</a></li>
<li><a class="reference external" href="https://github.com/GehirnInc/python-oidc">GehirnInc/python-oidc</a></li>
<li><a class="reference external" href="https://github.com/yosida95/python-jsmapper">yosida95/python-jsmapper</a></li>
</ul>
<p>これらのプロジェクトの共通点は、 Python 3k 向けのライブラリで GitHub にリポジトリを置き、 TravisCI でテストを行っていることです。</p>
<p>これまで TravisCI は、 Python 3k では Python 3.2 と Python 3.3 しかサポートしておらず、 Python 3.4 でテストするために <tt class="docutils literal">sudo <span class="pre">apt-get</span> install python3.4 <span class="pre">python3.4-dev</span></tt> を実行していました。
しかし、昨日 (4 月 30 日 ) の 11 時 (JST) 、ついに <a class="reference external" href="http://blog.travis-ci.com/2014-04-28-upcoming-build-environment-updates/">Python 3.4 のサポートが入りしました</a>。</p>
<p>そこで、ネイティブの Python 3.4 を使ってテストを行うように <tt class="docutils literal">.travis.yml</tt> を更新してみます。</p>
</div>
<div class="section" id="travis-yml">
<h2>.travis.yml</h2>
<div class="highlight"><pre><span></span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python</span>
<span class="nt">python</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3.3</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3.4</span>
<span class="nt">env</span><span class="p">:</span>
<span class="w"> </span><span class="nt">matrix</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py33"</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py34"</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="coverage"</span>
<span class="nt">matrix</span><span class="p">:</span>
<span class="w"> </span><span class="nt">exclude</span><span class="p">:</span>
<span class="w"> </span><span class="c1"># exclude 3.3</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">python</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3.3</span>
<span class="w"> </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py34"</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">python</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3.3</span>
<span class="w"> </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="coverage"</span>
<span class="w"> </span><span class="c1"># exclude 3.4</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">python</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">3.4</span>
<span class="w"> </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">TOXENV="py33"</span>
<span class="nt">install</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pip install tox</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">if test "$TOXENV" = "coverage"; then pip install coveralls; fi</span>
<span class="nt">script</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">tox</span>
<span class="nt">after_success</span><span class="p">:</span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">if test "$TOXENV" = "coverage"; then coveralls; fi</span>
</pre></div>
<p>まず前提ですが、テストは <tt class="docutils literal">tox</tt> を使って蹴っています。
<tt class="docutils literal">tox</tt> はそのままでは <tt class="docutils literal">tox.ini</tt> の <tt class="docutils literal">envlist</tt> に並べた <tt class="docutils literal">env</tt> を全て実行するのですが、 <tt class="docutils literal">TOXENV</tt> という環境変数をセットしてやると、特定の <tt class="docutils literal">env</tt> のみを実行できます。</p>
<p><tt class="docutils literal">python</tt> にバージョンのリストを書いていますが、こうするとそれぞれのバージョンについて TravisCI がテストをとってくれます。
この場合では、 <tt class="docutils literal">3.3</tt> と <tt class="docutils literal">3.4</tt> のそれぞれでテストが実行されます。</p>
<p>次に、 <tt class="docutils literal">env.matrix</tt> に <tt class="docutils literal">TOXENV</tt> を複数並べていますが、こうすることで TravisCI は <tt class="docutils literal">python</tt> と <tt class="docutils literal">env.matrix</tt> の全ての組み合わせについてテストを実行してくれます。
つまり、以下の 6 通りのテストが実行されます。</p>
<ul class="simple">
<li>python: 3.3, TOXENV="3.3"</li>
<li>python: 3.3, TOXENV="3.4"</li>
<li>python: 3.3, TOXENV="coverage"</li>
<li>python: 3.4, TOXENV="3.3"</li>
<li>python: 3.4, TOXENV="3.4"</li>
<li>python: 3.4, TOXENV="coverage"</li>
</ul>
</div>
<div class="section" id="matrix-exclude">
<h2>matrix.exclude</h2>
<p>これまでの説明の通り 6 通りのテストが実行されるのですが、例えば python: 3.4 の時は <tt class="docutils literal">python3.3</tt> が見つからず、 python:3.4, TOXENV="3.3" のテストが落ちるという問題があります。</p>
<p>そもそも TravisCI は Python のバージョンごとに用意した <tt class="docutils literal">virtualenv</tt> を <tt class="docutils literal">activate</tt> してからテストを実行しており、 $VIRTHAL_ENV/bin とシステムデフォルトの Python にしか <tt class="docutils literal">PATH</tt> が通っていません。</p>
<p>この問題を解決するために、テストを実行しなくてよい環境の組み合わせを <tt class="docutils literal">.travis.yml</tt> の <tt class="docutils literal">matrix.exclude</tt> に羅列していきます。
上記の例では <tt class="docutils literal">TOXENV</tt> によるバージョンの指定と <tt class="docutils literal">python</tt> が一致しない場合に加え、 <tt class="docutils literal">python 3.4</tt> 以外での coverage の取得を exclude しています。</p>
</div>
ポートノッキングで SSH の authorized_keys を更新する2014-03-30T00:00:00+09:002014-03-30T00:00:00+09:00yosida95tag:yosida95.com,2014-03-30:/2014/03/30/115758.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。</p>
<p>先日、 3 年間共に闘ってきた iMac が逝去しました。
その結果 MacBook Air と共に闘うことを強いられたのですが、この MacBook Air も 3 年前に購入したもので、 C2D の超低電圧版を積んだ大変歴史を感じる非実用的なマシンです。</p>
<p>そこで、実用的なマシンを手に入れるために MacBook Air を購入しました。
マシンを新しく購入して真っ先にやることは SSH 用の RSA 鍵ペアの生成だと思います。
私もその例に漏れずに SSH 用に RSA 鍵ペアを生成しました。</p>
<p>いざ開発を始めようとリモートのサーバーにログインを試みると、認証に失敗して接続を拒まれました。
当たり前の話です。
そこで何をするかというと、リモートサーバーの authorized_keys に新しく生成した RSA 鍵ペアの公開鍵の方を追記するわけです。
しかし、 authorized_keys を追記するにはリモートサーバーにログインする必要があります。
このためにすでに認可された鍵を持っているマシンから接続するのは面倒臭いです。</p>
<p>そこで、リモートサーバーにログインせずに authorized_keys を更新する方法を考えるわけです。
今回は、リモートサーバーに対してポートノッキングをすることで authorized_keys を更新できるようにします。</p>
</div>
<div class="section" id="section-2">
<h2>ポートノッキング</h2>
<p>ポートノッキングとは、サーバーの特定のポートに対して特定のパターンでパケットを飛ばすことで事前に設定したコマンドを実行する仕組みのことを言います。</p>
<p>例えば、 sshd が 22 番ポートを listen しており、この 22 番ポートをポートスキャンから隠蔽したりブルートフォースから守ったりしたいという状況において、通常時は 22 番ポートに来たパケットは捨てるが、ポートノッキングをトリガーに一定時間だけ 22 番ポートを開けるという使い方をするわけです。</p>
<p>前述の例の場合では、 <a class="reference external" href="https://yosida95.com/2013/07/31/055159.html">iptables の ipt_recent モジュール</a>などを使えば簡単に実現できますが、今回は authorized_keys を更新するという操作を実行するために、 L7 でポートノッキングを待ち受けるデーモンを動かすことにします。</p>
<p>今回、ポートノッキングを受け取るために <a class="reference external" href="https://github.com/yosida95/recvknocking">recvknocking</a> という Go ライブラリを書きました。</p>
</div>
<div class="section" id="authorized-keys">
<h2>authorized_keys の更新</h2>
<p>authorized_keys を更新する方法をお話する前に、私の SSH 公開鍵の管理方法についてお話します。</p>
<p>私の公開鍵の管理方法は、 ssh-keys という Git リポジトリ (オリジナルは GitLab でホスティング) にすべての SSH 公開鍵を保存し、クライアントマシンの公開鍵などの、全てのリモートサーバーで認可されてほしい鍵を authorized_keys に追記するルールを同じリポジトリにある Makefile に記述するというものです。</p>
<p>そのため、 authorized_keys を更新するには、リモートサーバーにある ssh-keys を GitLab から <tt class="docutils literal">git pull</tt> してきて、そのあと <tt class="docutils literal">make</tt> すればよいという事になります。</p>
<p>これを行うデーモンプログラムを <a class="reference external" href="https://github.com/yosida95/gitpull">gitpull</a> として実装しました (リポジトリの名前や README 的には、ポートノッキングを受けて <tt class="docutils literal">git pull</tt> を実行するだけのはずですが、実際には <tt class="docutils literal">git pull</tt> 後 <tt class="docutils literal">make</tt> したうえで、挙句その結果をメールで送信するということまでしています)。
これも Go 製で、先ほどの <a class="reference external" href="https://github.com/yosida95/recvknocking">recvknocking</a> を使って実装しています。</p>
</div>
<div class="section" id="section-3">
<h2>まとめ</h2>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/zsh</span>
<span class="nv">port</span><span class="o">=</span>NNNN
<span class="k">for</span><span class="w"> </span>host<span class="w"> </span><span class="k">in</span><span class="w"> </span>akari<span class="w"> </span>kyoko<span class="w"> </span>yui<span class="w"> </span>chinatsu<span class="w"> </span>sakurako<span class="w"> </span>yuno<span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span>i<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="sb">`</span>seq<span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="m">3</span><span class="sb">`</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span>nc<span class="w"> </span><span class="s2">"</span><span class="si">${</span><span class="nv">host</span><span class="si">}</span><span class="s2">.yosida95.com"</span><span class="w"> </span><span class="nv">$port</span>
<span class="w"> </span><span class="k">done</span>
<span class="k">done</span>
</pre></div>
<p>とかすると authorized_keys が更新され、古い非実用的なマシンからわざわざリモートサーバーにログインせずとも新しい実用的なマシンの鍵が認可されるようになりました。</p>
</div>
<div class="section" id="section-4">
<h2>最後に</h2>
<p>OpenSSH 6.2 からは、接続してきたクライアントの公開鍵が認可されているか否かを調べるために、 sshd が AuthorizedKeysCommand に設定したコマンドを叩いてくれる仕組みが導入されました。
この仕組を使うことで、データベースに公開鍵を問い合わせるといったことも可能になり、コードを書かずとも、ポートノッキングをせずとも、 authorized_keys を更新できます。
大変素晴らしいですね。</p>
<p>ちなみに、 Ubuntu 12.04 の apt リポジトリにある OpenSSH は 5.9p1 、 Sceitntific Linux 6.2 の yum リポジトリにある OpenSSH は 5.3p1 、 Mac OS X 10.9 にバンドルされている OpenSSH は 6.2p2 です。</p>
<p>以上です。
ありがとうございました。</p>
</div>
新年2014-01-31T00:00:00+09:002014-01-31T00:00:00+09:00yosida95tag:yosida95.com,2014-01-31:/2014/01/31/122628.html<div class="section" id="section-2">
<h2>こんにちは</h2>
<p>こんにちは …</p></div><div class="section" id="section-2">
<h2>こんにちは</h2>
<p>こんにちは yosida95 です。
昨年書いた「:<a class="reference external" href="https://yosida95.com/2013/12/22/000222.html">情報科の授業は教養に過ぎないという話 - 東京工業大学附属科学技術高校編</a>」という記事にまつわるおもしろ事象を twitter にて観測したのでご紹介します。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">進路で後悔してる人は辛いんだろうなぁ</p>— †ハルカス†@子供たちに明るい未来を (@newworldhoge) <a href="https://twitter.com/newworldhoge/statuses/427435157419601920">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">あの教養に過ぎない〜の文章は在校生からすると腹立つんだよね</p>— †ハルカス†@子供たちに明るい未来を (@newworldhoge) <a href="https://twitter.com/newworldhoge/statuses/427435855867678720">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">自分たちがバカにされてる気がするし、責任を学校に転嫁してる感じ</p>— †ハルカス†@子供たちに明るい未来を (@newworldhoge) <a href="https://twitter.com/newworldhoge/statuses/427436154795728896">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">書いた人ってゲヒルン技術開発局にいる人だっけ?</p>— †ハルカス†@子供たちに明るい未来を (@newworldhoge) <a href="https://twitter.com/newworldhoge/statuses/427436495448727552">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">学校の正式名称でエゴサーチしてたら書いた人の垢わかるしね</p>— †ハルカス†@子供たちに明るい未来を (@newworldhoge) <a href="https://twitter.com/newworldhoge/statuses/427436995749494784">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">さっきの豆腐批判してるひとのブログ読んでみてるけど文章書くの下手</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427440304979857408">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">卒業生のブログなのか</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427436478872842240">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ゲヒルン株式会社でエンジニアとして正社員登用される事が決まっています。</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427436784230727680">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ってかいてあったわ</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427436825481732096">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">3年生</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427437545400455169">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">文句言いながらちゃんと全部読んだ</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427443030526668800">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">読点打てば読みやすくなると思うなよ</p>— いちげ (@ichige_jp) <a href="https://twitter.com/ichige_jp/status/427442176092434432">January 26, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">この人は頭いいけど馬鹿っていう類いだと思う すっげー視野狭い</p>— 辞書 (@easy397) <a href="https://twitter.com/easy397/status/428893909066870784">January 30, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">退学を薦めるってなんなの?馬鹿にしてんの?</p>— 辞書 (@easy397) <a href="https://twitter.com/easy397/status/428894387859255296">January 30, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">てめーとはちげーんだよくそが ぶっ殺</p>— 辞書 (@easy397) <a href="https://twitter.com/easy397/status/428894553622335489">January 30, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">死ねよ</p>— 辞書 (@easy397) <a href="https://twitter.com/easy397/status/428895881450905600">January 30, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">お前みたいなクズそうそうかいねーよクズ</p>— 辞書 (@easy397) <a href="https://twitter.com/easy397/status/428895820058877952">January 30, 2014</a></blockquote><p>なるほどね</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">特にその人に向けられたわけでもない正論を能動的に読んで、自分の欠点を指摘されているように解釈して憤慨しているの、すごく滑稽だし、哀れだ。</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/429086935009599490">January 31, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ぼくは、件のエントリでは「技術」という点についてフォーカスして、その点でのみ周囲を評価するように徹していたんだけど、こういう発言をする人間が後輩や先輩にいるという点を鑑みるに、この学校には人間性にも難がある人間が集まっているんだなぁって思う。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/429087793097093120">January 31, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/masawada">@masawada</a> 人間性ではなく性格です。ご確認ください。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/429088254562816000">January 31, 2014</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">こちらからは以上です。ありがとうございました。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/429087102307794944">January 31, 2014</a></blockquote></div>
yosida95 の2013年を振り返る2013-12-31T00:00:00+09:002013-12-31T00:00:00+09:00yosida95tag:yosida95.com,2013-12-31:/2013/12/31/111207.html<div class="section" id="section-1">
<h2>こんにちは</h2>
<p>2013年も早いもので最終日を迎えました。
今年も残 …</p></div><div class="section" id="section-1">
<h2>こんにちは</h2>
<p>2013年も早いもので最終日を迎えました。
今年も残すところあと12時間くらいになったので、そろそろ1年を振り返り、来年の展望を語る意識の高いエントリを書き初めてもよい頃合いだろうと思って筆をとりました。</p>
</div>
<div class="section" id="section-2">
<h2>活動まとめ</h2>
<div class="section" id="section-3">
<h3>勉強会・セッション系</h3>
<p>特に意識をしていたわけではないのですが、今年を振り返ってみると、2012年ほど頻繁に勉強会に参加していなかった事に気づきます。
特に、 LT やセッションは1度もやっておらず、2012年には <a class="reference external" href="http://www.youtube.com/watch?v=tOWZB9tFgu8">PyCon JP でのセッション</a>を始め、2月に1度くらいのペースで発表をやっていたことと対比すると、この差に驚きます。
インプットに徹していた、と言うと聞こえがよいので、そういうことにしておきます。</p>
<p>従って、まとめるような活動がありません。
2014年では、個人としても、 Gehirn の中の人としても、私が得た知見を多くの人と共有していければと思います。</p>
<p><a class="reference external" href="http://news.gehirn.jp/">Gehirn News</a> という情報共有の場をせっかく与えられているので、こちらも活用していかなければなりませんね。</p>
<p>勉強会の運営という面でも、やはり PyCon JP 2012 の運営と CombConf の主催に携わっていた2012年に対して2013年は何もしない1年でした。
一方、すでに <a class="reference external" href="http://2014.pycon.jp/">PyCon JP 2014</a> のメディアスタッフとして活動を始めた<a class="footnote-reference" href="#pycon-stuff" id="footnote-reference-1">[1]</a>ので、2014年は勉強会の運営に関わっていける1年になると思います。</p>
<table class="docutils footnote" frame="void" id="pycon-stuff" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td><a class="reference external" href="http://pyconjp.blogspot.jp/2013/12/pycon-jp-2014-logo.html">PyCon JP 2014 のロゴが決定しました!</a></td></tr>
</tbody>
</table>
</div>
<div class="section" id="section-4">
<h3>高校関連</h3>
<p>今年は課題研究によってソウルジェムが濁った1年でした。
生徒の授業時間外の自主的な活動を無くしては成り立たないカリキュラムであることに加え、複数の生徒による班づくりが強制されているため、班内の自主性の無い人間が逃げ得をし、自主性や責任感のある人間が損をする仕組みとなっています。
しかし、ここにそのことをつらつらと書いても何も生まれないので、とりあえずこの辺にしておきます。
<img alt="夏休み最終日ですね" src="https://yosida95.com/photos/MhcH1.raw.png" style="width: 100%;" /></p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">もうさ、ぼくが課題研究で開発して成績では5を取ってきたプロダクトのソースコード公開するから、各位はそれを自分の成果として持っていけばいいんじゃないんですかね。課題研究、"できる"人が損する仕組みになっているから、みんなが平等にサボれる用にするための協力ならしますよ。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/412600146115821568">December 16, 2013</a></blockquote><p>高校関連で今年最も特筆すべきことと言えば、やはり先週公開した「<a class="reference external" href="https://yosida95.com/2013/12/22/000222.html">情報科の授業は教養に過ぎないという話 - 東京工業大学附属科学技術高校編</a>」のことでしょう。
300を超えるはてブを獲得し、このブログエントリが基になった派生エントリや、このエントリに言及するエントリも幾つか公開されました。</p>
<p>ブログのコメント欄やブコメで、ぼくの考え方に賛同する意見やぼくを励ます意見、そしてアドバイスなど、多くの建設的な意見を頂きました。
このエントリを公開した反響は大きく、 twitter を眺めていたかぎりでは多くの人にリーチし、議論も提起できたようだったので、大変満足しました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">「そういうことじゃないんだよ」「とりあえずここで人格否定来て欲しい」「最後まで読まれてない。」「燃えろ!」現場からは以上です。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/414431415594266625">December 21, 2013</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">人格否定されたい人が隣にいる</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/414433141307105280">December 21, 2013</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">「筆者述べてない」</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/414461352439078912">December 21, 2013</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">「このコメントは作者の気持ちを考えている」</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/414559220122411009">December 22, 2013</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">はてブに「だからコメントするなら最後まで読むべきだよ。全く同じことが本文中に書かれてるから。」「本文を全部読めば、そのコメントをするに至らないから……。」って感じのコメントが散見されて、なるほどコレが燃料かという感じである。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/414572741258276864">December 22, 2013</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">これが「無責任な周囲による無責任な意見」です。ご確認ください。</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/414612376613171200">December 22, 2013</a></blockquote><p>このエントリの公開は12月22日に日付が変わった頃でしたが、エントリ自体は、実は公開する1ヶ月以上前に書いて、その後折にふれて細かな修正を加えながら温めて来たものでした。
エントリを公開した理由としては、「体験談を共有したい」「他の学校の体験談を知りたい」という事以上にいくつかの思惑がありましたが、それらについてはここには書かずにおきます。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">よしださんにんまりだろうな</p>— hinasssan (@hinasssan) <a href="http://twitter.com/hinasssan/status/414587593527795712">December 22, 2013</a></blockquote><p>( hinata くんには思惑その他について明かしていないのにも関わらずこのツイートがあったので、さとり世代の力を感じずにはいられません。 )</p>
</div>
</div>
<div class="section" id="section-5">
<h2>仕事関連</h2>
<p>8月に<a class="reference external" href="https://yosida95.com/2013/08/01/222538.html">ゲヒルン株式会社に転職した</a>ことは、ぼくにとって大きな転機となりました。
今までゲヒルンを含め3つの会社に所属したり、他の会社とも色々やってきたりしましたが、他のどこの会社で働いている時よりもゲヒルンで働いている時の方がクリエイティブな活動をして、ぼくの能力を活かせている実感があります。
また、どこの会社に居た時よりも強い帰属意識を持つことができています。</p>
<p>世の中に数多ある IT ベンチャーの1つですが、それでも日に日に会社が大きくなっているという事が目に見えているという事に、わくわくエンジニアとしてとてもわくわくさせられます。
実際、12月27日には SOHO オフィスの一室からビルの1フロアへとオフィス移転<a class="footnote-reference" href="#gehirn-moved" id="footnote-reference-2">[2]</a>を果たしました。</p>
<p>2014年4月からは正社員登用されることが決まっているので、さらにわくわくする毎日が待ち受けているのかと思うと、夜も寝られませんし、朝も起きられません。</p>
<table class="docutils footnote" frame="void" id="gehirn-moved" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td><a class="reference external" href="http://www.gehirn.co.jp/press/2013/12/27/239/">本社移転のご案内</a></td></tr>
</tbody>
</table>
</div>
<div class="section" id="section-6">
<h2>まとめ</h2>
<p>こんな感じで、2013年を振り返ってみると、大きなイベントはそれほど多くありませんでしたが、それでもぼくにとってはよい年でした。
2014年は学校から離れるということで、より多くの時間を手に入れ、公私ともに充実する1年になるのではないかと予想しています。
夏頃には実家を離れ、一人暮らしを始めようとも考えています。
勉強会などでの知見の共有も積極的にしていきたいと思っていますので、見かけた際にはぜひお声がけいただければ、と思います。</p>
<p>それではこの辺りで締めさせていただきます。
今年1年ありがとうございました。
よしだ先生の2014年にもご期待ください!</p>
</div>
情報科の授業は教養に過ぎないという話 - 東京工業大学附属科学技術高校編2013-12-22T00:00:00+09:002013-12-22T00:00:00+09:00yosida95tag:yosida95.com,2013-12-22:/2013/12/22/000222.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんにちは yosida95 です。
このエントリでは、以前から私が抱いてた高校に関するもやもやについて、ようやく日本語に落とし込める程度に整理できたので共有します。</p>
<div class="contents topic" id="topic-1">
<p class="topic-title">目次</p>
<ul class="simple">
<li><a class="reference internal" href="#section-2" id="toc-entry-1">はじめに</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-2">入学まで</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-3">違和感</a></li>
<li><a class="reference internal" href="#section-5" id="toc-entry-4">2年生進級と退学</a></li>
<li><a class="reference internal" href="#section-6" id="toc-entry-5">不満点</a></li>
<li><a class="reference internal" href="#section-7" id="toc-entry-6">結論</a></li>
<li><a class="reference internal" href="#section-8" id="toc-entry-7">申し送り</a><ul>
<li><a class="reference internal" href="#section-9" id="toc-entry-8">中学生向け</a></li>
<li><a class="reference internal" href="#section-10" id="toc-entry-9">高校生向け</a></li>
<li><a class="reference internal" href="#section-11" id="toc-entry-10">免責</a></li>
</ul>
</li>
<li><a class="reference internal" href="#section-12" id="toc-entry-11">最後に</a></li>
<li><a class="reference internal" href="#section-13" id="toc-entry-12">余談</a></li>
<li><a class="reference internal" href="#section-14" id="toc-entry-13">追記</a><ul>
<li><a class="reference internal" href="#section-15" id="toc-entry-14">他校の事例</a></li>
<li><a class="reference internal" href="#t15-31-26z" id="toc-entry-15">2013-12-21T15:31:26Z</a></li>
<li><a class="reference internal" href="#t18-20-18z" id="toc-entry-16">2013-12-21T18:20:18Z</a></li>
<li><a class="reference internal" href="#t08-18-09z" id="toc-entry-17">2013-12-22T08:18:09Z</a></li>
<li><a class="reference internal" href="#t08-19-32z" id="toc-entry-18">2013-12-23T08:19:32Z</a></li>
<li><a class="reference internal" href="#t07-18-00z" id="toc-entry-19">2013-12-26T07:18:00Z</a></li>
<li><a class="reference internal" href="#t07-00-00z" id="toc-entry-20">2018-12-31T07:00:00Z</a></li>
<li><a class="reference internal" href="#t05-00-00z" id="toc-entry-21">2019-10-11T05:00:00Z</a></li>
</ul>
</li>
</ul>
</div>
<p>私は2011年から<a class="reference external" href="http://www.hst.titech.ac.jp/">東京工業大学附属科学技術高校</a>の<a class="reference external" href="http://www.hst.titech.ac.jp/~ics/">情報・コンピュータサイエンス分野</a>というところで3年間学んできました。
というか、現在も在籍していて、後は3月末日の卒業を待っているところです。
卒業できたらいいな。</p>
<p>さて、私と交友のある方や、<a class="reference external" href="https://twitter.com/yosida95">私の twitter</a>
をご覧の方はご存知かと思いますが、私はこの高校に入学して以来ずっと違和感を感じてきました。
2年生の時には退学を考えた末親の説得に成功し、クラス担任・副担任・私の母・私で面談をしました。
最終的には、私の周囲の大人達になだめられたり、諌められたりしたことで思いとどまり、現在に至っています。
しかし退学の意思が雲散霧消したわけではなく、登校も惰性によるものです。</p>
</div>
<div class="section" id="section-3">
<h2>入学まで</h2>
<p>まずは、中学生の時の私は何を期待して東京工業大学附属科学技術高校を選択し、どうやって入学したかについてお話します。</p>
<p>中学生当時の私は他人より少しだけ記憶力が良いことを生かして、いわゆる学校の勉強を授業中に先生の話を聞くことだけで済ませ、常に学年トップクラスの成績を維持していました。
そのため、自宅学習の必要に迫られることは一切無く、有り余った放課後の時間のすべてを友人と遊ぶことやプログラミングをすること、生徒副会長として友達と自分の学校生活を充実させるための活動にあてました。
遊ぶ金欲しさに、当時陰りつつあったものの未だブームの中にあったドロップシッピングに乗って、 PHP でオンラインストアを作って物販をしていたことを覚えています。</p>
<p>いざ受験期に突入して周囲が受験勉強を始めている中でも、私はこのオンラインストアの運営の事に頭を使っていました。
進学先については、今まで独学でしかなかったプログラミングについて、体系的に学ぶことでその技能を向上させるべく、情報系の高校に進学したいと思っていました。</p>
<p>しかし、特定の高校に進学したいと考えていたわけではなく、都内にある情報系の高校でそこそこ偏差値が高い高校であればどこでも良いだろうと考えていました。
この候補に上がった高校が東京工業大学附属科学技術高校と、高校ではありませんが東京工業高等専門学校(東京高専)でした。
この2つしかなかった選択肢の中から、私は東京工業大学属科学技術高校を選択しました。
この選択が中学3年生の10月頃の話だったと思います。
入試には学校推薦入試と一般入試があり、模擬試験で偏差値が72あった私は一般受験でも十分合格できると思いましたが、より実施が早く、従ってより早く進路が確定する学校推薦入試によって合格を果たしました。</p>
<p>このような調子で進学先の高校を決定したため、高校の所在地を初めて知った日は、学校推薦入試のその日でした。</p>
</div>
<div class="section" id="section-4">
<h2>違和感</h2>
<p>ここで、東京工業大学附属科学技術高校の教育カリキュラムを簡単に説明します。
まず、東京工業大学附属科学技術高校には、私が所属している情報・コンピュータサイエンス分野の他に、応用化学分野や建築・デザイン分野など合わせて5つの分野があります。
1年生の時には学年の生徒全員が同じカリキュラムで学習をします。
このカリキュラムの中に「科学技術入門」という教科があり、この教科のなかでこれら5つすべての分野について導入学習を行います。
その後、2年生への進級に際して5つの分野の中からいずれか1つを選択し、2年生・3年生では選択した分野毎のカリキュラムに従って学習を進めていきます(ただし、学校推薦入試で入学した生徒は入学の時点で進む分野が決定しています。)。</p>
<p>さて、無事入学を果たした私でしたが、入学3日目くらいにまず些細な違和感を感じました。
それは、「私のクラスに私と匂いがする人間がいない」というものです。
願書の志望動機に「同じ領域に興味をもつ仲間と切磋琢磨したい」と書いて合格した私は、早速私以上のレベルで物を語れ、私以上のレベルでコードを書ける仲間を見つけようと思ったのですが、これでは幸先の悪いスタートです。</p>
<p>次に感じた違和感は授業のレベルについてです。
前述の科学技術入門で情報・コンピュータサイエンス分野に関する授業のレベルがあまりにも初歩的な物だったのです。
冗談抜きに「それ小学生の時にやったわーつれーわー」ってかんじでした。</p>
<p>このような経緯で入学して早々に志望動機を叶えることに絶望しかけた私でしたが、まだ1年生ということで分野が分かれていないこともあり、2年生になって分野が分かれればきっとより専門的な内容に進んで行くのだろう、その時には私の他に情報の推薦入試によって入学したレベルの高いクラスメートもできるのだろうと思うことで希望をつなげました。</p>
<p>希望をつなげたとは言え、少なくとも1年生の間に学校で何事かをなせるとは考えられなかったので、夏休みが明けた頃から私は積極的に勉強会やハッカソンなどに顔をだすようになりました。
その中で、職業でプログラマをやっている方々や、大学でコンピュータサイエンスを学んでいる方々などとの交流を持ちました。
私が作ったプロダクトについて発表をしたり、それについて賛辞やアドバイスを頂いたり、私にとって学校の外の世界は大変居心地がよく、わくわくさせられる世界でした。</p>
</div>
<div class="section" id="section-5">
<h2>2年生進級と退学</h2>
<p>そんな感じで2年生に進級し、ようやく情報・コンピュータサイエンス分野のカリキュラムに従った学習ができるようになったわけです。
しかし、抱いていた幾ばくかの期待は裏切られ、肝心の授業の内容と言えば1年生の時とさほど変わらず、またとてものんびりとしたスピードで進行していきました。
この件について、情報の定期テストの意見欄に書いたところ、担当の教諭から後日「あなたのレベルとペースに合わせていたら誰もついて来られなくなるから。点数さえ取れば授業中に別のことをしていてよいよ。」と言われてしまいます。
いよいよ私は危機感を募らせます。
これでは新しい事は一切学べないのではないか、一体私は何をしにこの高校に進学したのか、このままでは3年間を溝に捨てることになってしまうのではないか―――</p>
<p>ついに私は退学を考え始めました。
これと期を同じくして私の元へ IT 企業から、それも多くの人が名前を知っているような企業からも私の能力を買うメールが届き始め、退学をしたところで、高校を卒業しなかったところで、世の中を生きていけるのではないかと思ったことも退学を決意する後押しとなりました。</p>
<p>親を説得することに成功した私は、親を通じて退学の意思を学級担任へ伝えました。
すぐさま面談の場が持たれ、冒頭に書いた4者での面談が行われました。
面談の中では退学を決意した経緯や将来設計のことなどについて聞かれたと記憶しています。
学級担任(数学科)は「私には専門的なことや IT 業界のことは分からないので……」と終始聞く側に回っていました。
そんな感じで進行した面談でしたが、社会の厳しさを説かれたり、私とほぼ同様の理由で退学を考えたものの結局大学へ進学した卒業生を紹介されたりしている内に、話の流れと私の決意を有耶無耶にされ、とりあえず再度熟考するという形で退学は保留となりました。</p>
<p>このような経緯で退学の機を逃した私でしたが、学校に行くモチベーションは完全に失われ、ただ惰性で学校に通うようになりました。
そのことから遅刻や欠席もしだいに増えていきました。
学校をサボってひたすらコードを書いていた日はこれまでに1日や2日ではありません。</p>
</div>
<div class="section" id="section-6">
<span id="anchor-1"></span><h2>不満点</h2>
<p>このように、退学を考えるまでに至った3年間でしたが、私は一体東京工業大学附属科学技術高校の何が不満だったのか、その不満点を整理してみます。</p>
<ul class="simple">
<li>専門分野の授業に専門性がなかった<ul>
<li>独学で進めてきたコンピュータの学習を体系的に学び私の技能を向上させる事を期待して入学したものの、授業の内容は初歩的なもので、とても技能の向上につながらなかった</li>
<li>入学の時点で、私の技能はすでに学校のカリキュラムで身につく技能のレベルを超えていた</li>
</ul>
</li>
<li>クラスメートの専門性が低かった<ul>
<li>情報・コンピュータサイエンス分野を選択する生徒は例外なくコンピュータに興味を抱いているものと信じていたが、決してそうではなかった</li>
<li>特に学校推薦入試によって入学してきた生徒は、すでにある程度のスキルを持っているものと信じていたが、決してそうではなかった<ul>
<li>私が入学した翌年の学校推薦入試の面接を担当した教諭によれば、「単にゲームをプレイすることが好きだから」という志望動機を臆面もなく面接で発言する程度の受験生しか居なかったそうだ</li>
</ul>
</li>
<li>自分よりもスキルの高い生徒と切磋琢磨して私自身の技能を向上させる事を狙って入学したが、それは果たせなかった<ul>
<li>普通の学校でスキルの高さを持て囃されることに慢心してスキルの向上が妨げられてしまわないように、周囲のレベルの高さに叩きのめされて努力を怠れない環境が欲しかったが、それは叶わなかった</li>
</ul>
</li>
</ul>
</li>
<li>進学校であった<ul>
<li>そもそも生徒はコンピュータになんて興味がなかった</li>
<li>分野特有の授業に加えてセンター入試等に必要になる教科も履修する、時間的に無理があるカリキュラムが組まれている<ul>
<li>無理があるカリキュラムであるため自宅学習課題の量が多かった<ul>
<li>放課後の時間を使って課題を処理することが求められた</li>
</ul>
</li>
<li>無理があるカリキュラムであるため終業時刻は他の学校のそれと比べると遅い
= そもそも放課後にとれる時間が少ない<ul>
<li>わずかに確保できた放課後の時間は課題の処理に溶かされていく</li>
<li>スキル向上を図る独学のために確保できる時間は皆無だった</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-7">
<h2>結論</h2>
<p><strong>進学先を間違えた</strong></p>
<p>中学生時代に体験入学の制度などを活用し、東京工業大学附属科学技術高校の本質を見抜いておくべきだった</p>
</div>
<div class="section" id="section-8">
<h2>申し送り</h2>
<p>結論がでたのでこのエントリは終了しても良いのですが、それだと次に繋がるものが無いので、私と同じ境遇にある諸氏に申し送りをしておきます。</p>
<div class="section" id="section-9">
<h3>中学生向け</h3>
<ul class="simple">
<li>進学先高校についてよく調べましょう</li>
<li>高校で専門的な事を学ぶことは諦めましょう<ul>
<li>独学を進めるための時間や、学校外の世界で活動するための時間を最大限確保しましょう</li>
</ul>
</li>
<li>高校に行かないという手段もあります<ul>
<li>中学生時代の私はこの選択肢を知りませんでした</li>
<li>大学への進学には、高校卒業程度認定試験に合格して入試を受けるという経路もあります</li>
</ul>
</li>
<li>スクーリングが少ない通信高校に通うという選択肢もあります<ul>
<li>学校の学習に使う時間と専門的な学習に使う時間の配分を自分で決められます</li>
<li>終業や始業の時間が自由に設定できるため、 IT 企業で働くための時間も十分に取れます</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-10">
<h3>高校生向け</h3>
<ul class="simple">
<li>ご愁傷さまです</li>
<li>退学は手遅れになる前にした方がよいです<ul>
<li>一刻を争います</li>
<li>次の進路が見えているのなら、退学は立派な選択肢です</li>
<li>ずるずると決定を先延ばしにすると選択肢が少なくなっていきます</li>
</ul>
</li>
<li>外の世界を見ましょう<ul>
<li>今の時代は SNS を使うだけで本来なら接点がなかったような人とも簡単に繋がれます<ul>
<li>人と人との距離は飛躍的に近づきました</li>
</ul>
</li>
<li>勉強会での発表は良い経験になります<ul>
<li>あと1年早ければ <a class="reference external" href="http://combconf.com/">CombConf</a> というものがありました</li>
<li><a class="reference external" href="https://yosida95.com/2012/12/25/064109.html">CombConf という IT カンファレンスを開催してきました #combconf</a></li>
<li>第2回はありません</li>
</ul>
</li>
<li>技術系のバイトはよい経験になります</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-11">
<h3>免責</h3>
<p>なお、このブログエントリを真に受けた事によって生じた利益や不利益について私はもちろんあなたの周囲の誰も責任を取りません。
自分の進路における決定はすべて自分の責任の下に行なわれるべきです。
しかし、無責任な周囲による無責任な意見を積極的に聞いて自分自身で咀嚼した方がお得です。
あなたは自身が想像している以上に視野狭窄です。
周囲の意見を聞くことで、自分だけでは考えつかなかった選択肢がいくつも出現して裏ステージへ進める可能性が高まります。</p>
<p>私自身がひどい視野狭窄に陥っている可能性が高いので、周囲の意見を聞こうという自戒です。
よろしければ、このエントリや私の考え方についてご意見や反論などをください。</p>
</div>
</div>
<div class="section" id="section-12">
<h2>最後に</h2>
<p>こういうエントリを書くと、専門ではない授業の重要性を説かれることになります(例: <a class="reference external" href="https://yosida95.com/2012/05/15/082821.html">No Title (近況報告)</a>のコメント)。</p>
<p>私は、生涯学習の重要性や素晴らしさについては認識しているつもりですが、すでに自らの選択するべき職業について明確に自覚していて、手に職をつけるべきタイプの人間が義務教育を修了した後に専門的では無い事を意識的に、あるいは体系立てて学ぶ必要性やその重要性についてはいまいちピンときていません。
学びたいことや学ぶべきことについて、それを学ぶ必要が生じた時に生涯学習の一環として学べばよいと考えていることがその理由です。</p>
<p>そして、生涯学習を実践していくためには時間的な余裕や金銭的な余裕が必要だと思います。
それらの余裕を手に入れるには、一般にドカタのようなポジションではなく、専門的な技能を持った専門職である必要があり、またある程度の社会的地位が要るはずです。
つまり、社会人デビューする時にはすでに専門技能を有している必要があると考えます。</p>
<p>これまでに3つの会社で(アルバイトではありますが)エンジニアとして勤務してきた経験や、属するコミュニティで聞いてきた話、目の当たりにした出来事などによれば、技能を磨いていけばある程度の会社で専門職として勤務するところまでは到達できます。
従って、学生や生徒である期間に専門的では無い事を学ぶために自らの専門性を高めることを制限することは却ってよくないのでは無いでしょうか。</p>
</div>
<div class="section" id="section-13">
<h2>余談</h2>
<p>はてなブログのエントリエディタにある文字数カウンタによれば、このエントリは 6,271 文字によって構成されているそうです。
400字詰め原稿用紙にして16枚分。
久しぶりにこれほどの長文を書きましたが、こんな長文を書いている時間があるのなら卒業に必要なレポートを書けよという話です。</p>
</div>
<div class="section" id="section-14">
<h2>追記</h2>
<div class="section" id="section-15">
<h3>他校の事例</h3>
<p>わたしの記事に呼応して複数の方がご自身の情報系の学校における体験談を共有してくださいました。
この記事のタイトルを「情報科の授業は教養に過ぎないという話 - <strong>東京工業大学附属科学技術高校編</strong> 」としたように、他の学校でにおいてもわたしと似た体験やあるいは異なる体験があるだろうと思い、この記事は是非それらを伺いたくてまず自分の体験談を公開したという目論見もあったので、体験談が数年をかけて集まってきたことがとても嬉しいです。</p>
<p>ご自身の体験談を共有してくださった皆さまにお礼を申し上げます。</p>
<ul class="simple">
<li><a class="reference external" href="http://yukkurisinai.hatenablog.com/entry/2013/12/22/164847">情報科の授業は教養に過ぎないという話 - 木更津工業高等専門学校編</a> (2013.12.22)</li>
<li><a class="reference external" href="http://blog.monora.me/2013/12/%E6%83%85%E5%A0%B1%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%AB%E9%81%8E%E3%81%8E%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E5%88%A5%E3%81%AE%E8%A6%96%E7%82%B9/">情報科の授業は教養に過ぎないという話 - 別の視点から</a> (2013.12.22)</li>
<li><a class="reference external" href="http://masawada.hatenablog.jp/entry/2013/12/26/010357">情報科の授業は教養に過ぎないという話 - 国立大学法人 電気通信大学編</a> (2013.12.26)</li>
<li><a class="reference external" href="https://kcs1959.jp/archives/4491/general/%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%A7%E3%81%99%E3%82%89%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E6%85%B6">情報(工学)科の授業は教養ですらないという話 – 慶應義塾大学編 – KCS ComputerSociety</a> (2018.12.26)</li>
<li><a class="reference external" href="https://medium.com/@cddadr/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E6%83%85%E5%A0%B1%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%AB%E9%81%8E%E3%81%8E%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E5%B2%A9%E6%89%8B%E7%9C%8C%E7%AB%8B%E5%A4%A7%E5%AD%A6%E7%B7%A8-e261ca30c567">ソフトウェア情報学科の授業は教養に過ぎないという話 — 岩手県立大学編</a> (2019.03.03)</li>
</ul>
</div>
<div class="section" id="t15-31-26z">
<h3>2013-12-21T15:31:26Z</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">ホッテントリジェネレータで東京工業大学附属科学技術高等学校って入れたら東京工業大学附属科学技術高等学校は即刻滅亡すべきって出てきたから <a href="https://twitter.com/yosida95">@yosida95</a> はいますぐこれにタイトルを変えるべき</p>— DJ香風智乃 (@masawada) <a href="https://twitter.com/masawada/status/414416282985828352">December 21, 2013</a></blockquote></div>
<div class="section" id="t18-20-18z">
<h3>2013-12-21T18:20:18Z</h3>
<p>私の進路について、このエントリのコメントやはてなブックマークで言及されているようなので追記します。
来年の4月から、現在アルバイトしているゲヒルン株式会社でエンジニアとして正社員登用される事が決まっています。</p>
<p>高校に不満を抱いている一方で、アルバイト先には現在のところ大変恵まれています。
特に、正社員登用が決まっているゲヒルンでは、のびのびと自分の裁量で働ける環境を得られたことに加え、以前から親交があり、またよい刺激を受けてきた仲間と一緒に働く事ができています。</p>
<p>私の詳細な職歴については、以下のエントリもご覧ください。</p>
<ul class="simple">
<li><a class="reference external" href="https://yosida95.com/2012/09/03/211203.html">株式会社 Decoo に就職して、そして退職しました</a></li>
<li><a class="reference external" href="https://yosida95.com/2012/10/13/222109.html">株式会社ゼロスタートに入社しました!</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/07/31/223353.html">退職のご報告</a></li>
<li><a class="reference external" href="https://yosida95.com/2013/08/01/222538.html">ゲヒルン株式会社に入社しました</a></li>
</ul>
</div>
<div class="section" id="t08-18-09z">
<h3>2013-12-22T08:18:09Z</h3>
<p><a class="reference external" href="http://twitter.com/yukkuri_sinai">@yukkuri_sinai</a> さんが、本エントリの派生エントリを書いて下さりましたので共有します。</p>
<ul class="simple">
<li><a class="reference external" href="http://yukkurisinai.hatenablog.com/entry/2013/12/22/164847">情報科の授業は教養に過ぎないという話 - 木更津工業高等専門学校編</a></li>
</ul>
<p>本エントリのタイトルからもお察しかと思いますが、それぞれ色々な学校に所属する(していた)諸氏の<strong>体験談</strong>を知りたくて、まずは自分の体験談を語る本エントリを執筆しました。
そのため、思惑通り木更津高専での体験談を読むことができて幸いです。
他にも、体験談をお持ちの方はブログエントリとして共有していただければと存じます。</p>
</div>
<div class="section" id="t08-19-32z">
<h3>2013-12-23T08:19:32Z</h3>
<p>私の後輩で、直接の面識がある <a class="reference external" href="http://twitter.com/sukukyon">@sukukyon</a> が、同じ学校の同じ分野に所属する別視点のエントリとして、以下のエントリを書いてくれたので共有します。</p>
<ul class="simple">
<li><a class="reference external" href="http://blog.monora.me/2013/12/%E6%83%85%E5%A0%B1%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%AB%E9%81%8E%E3%81%8E%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E5%88%A5%E3%81%AE%E8%A6%96%E7%82%B9/">情報科の授業は教養に過ぎないという話 - 別の視点から</a></li>
</ul>
</div>
<div class="section" id="t07-18-00z">
<h3>2013-12-26T07:18:00Z</h3>
<p>電気通信大学の <a class="reference external" href="http://blog.hatena.ne.jp/masawada/">id:masawada</a> さんも本エントリの派生エントリを書いてくださったので共有します。</p>
<ul class="simple">
<li><a class="reference external" href="http://masawada.hatenablog.jp/entry/2013/12/26/010357">情報科の授業は教養に過ぎないという話 - 国立大学法人 電気通信大学編</a></li>
</ul>
</div>
<div class="section" id="t07-00-00z">
<h3>2018-12-31T07:00:00Z</h3>
<p>慶應義塾大学理工学部情報工学科の mt_caret さんが5年越しに派生記事を書いてくださいました。</p>
<ul class="simple">
<li><a class="reference external" href="https://kcs1959.jp/archives/4491/general/%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%A7%E3%81%99%E3%82%89%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E6%85%B6">情報(工学)科の授業は教養ですらないという話 – 慶應義塾大学編 – KCS ComputerSociety</a></li>
</ul>
</div>
<div class="section" id="t05-00-00z">
<h3>2019-10-11T05:00:00Z</h3>
<p>岩手県立大学の Eddie さんも本記事の派生記事を書いてくださっており、それを遅ればせながら発見したので追記します。</p>
<ul class="simple">
<li><a class="reference external" href="https://medium.com/@cddadr/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E6%83%85%E5%A0%B1%E7%A7%91%E3%81%AE%E6%8E%88%E6%A5%AD%E3%81%AF%E6%95%99%E9%A4%8A%E3%81%AB%E9%81%8E%E3%81%8E%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1-%E5%B2%A9%E6%89%8B%E7%9C%8C%E7%AB%8B%E5%A4%A7%E5%AD%A6%E7%B7%A8-e261ca30c567">ソフトウェア情報学科の授業は教養に過ぎないという話 — 岩手県立大学編</a></li>
</ul>
<p>自身が持つ選択肢それぞれについてしっかりと検討した上で、そこで行われる情報教育には(それほど)期待せずに、代わりに得られるものも総合的に勘案した上で進学先を選ぶことも立派な進路選択だと思います。
Eddie さんのように学校における情報教育のことは割り切った上で、代わりに自学に割ける自由な時間を得ることができれば、わたしでも「進学先を間違えた」とは結論付けなかったかもしれません。</p>
<p>この点はわたしがこの記事の「 <a class="reference external" href="#anchor-1">不満点</a> 」で書いた通りです。</p>
<blockquote>
<ul class="simple">
<li>分野特有の授業に加えてセンター入試等に必要になる教科も履修する、時間的に無理があるカリキュラムが組まれている<ul>
<li>無理があるカリキュラムであるため自宅学習課題の量が多かった<ul>
<li>放課後の時間を使って課題を処理することが求められた</li>
</ul>
</li>
<li>無理があるカリキュラムであるため終業時刻は他の学校のそれと比べると遅い
= そもそも放課後にとれる時間が少ない<ul>
<li>わずかに確保できた放課後の時間は課題の処理に溶かされていく</li>
<li>スキル向上を図る独学のために確保できる時間は皆無だった</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</div>
</div>
転職に伴って定期券を購入しにみどりの窓口に行ったら2区間定期というものの存在を知った話2013-09-01T00:00:00+09:002013-09-01T00:00:00+09:00yosida95tag:yosida95.com,2013-09-01:/2013/09/01/023814.html<div class="section" id="section-2">
<h2>こんばんは</h2>
<p>こんばんは …</p></div><div class="section" id="section-2">
<h2>こんばんは</h2>
<p>こんばんは yosida95 です。</p>
</div>
<div class="section" id="section-3">
<h2>2区間定期</h2>
<p>月曜日から夏休みが始まることに加え、8月の転職に伴って職場の最寄り駅が変わったため、みどりの窓口に定期券を購入しに行きました。</p>
<p>これまでは、自宅最寄り駅から学校の最寄り駅を経由して職場の最寄り駅までの区間の定期券を券売機で購入していました。
自宅の最寄り駅から学校の最寄り駅までの通学定期と、学校の最寄り駅から職場の最寄り駅までの通勤定期の2枚を買えば定期券代を最も安く抑えられますが、定期券が2枚になる(と思い込んでいた)ことと、そのために職場から自宅への帰り道にわざわざ学校の最寄り駅を経由することを嫌って、少し高くなりますが上記区間の通勤定期を購入していました。</p>
<p>今回もそのつもりでしたが、そもそも最安の方法で購入して本当に定期券が2枚になってしまうのか気になり、券売機ではなくみどりの窓口で購入し、その際に1枚にまとめられないかを尋ねました。
その結果、自宅最寄り駅から学校最寄り駅までの通学定期と、学校最寄り駅から職場最寄り駅までの通勤定期を"2区間定期"として購入すれば1枚の定期券にまとめられることが判明しました。</p>
<p>大変お便利ですね。
これまで自宅から学校最寄り駅までも通勤定期の値段で買っていたので、その差額が思いやられますね。
定期券に1ヶ月15,540円費やしていましたが、この購入方法だと15,280円になるので、1ヶ月あたり260円浮きます。
勤続10ヶ月だったので2,600円余分に払っていたことになります。
こうしてみると経済的な負担は大した事ないですが、それよりも根拠のない思い込みで損をしていたことに対する精神的なショックが大変大きいです。</p>
</div>
<div class="section" id="section-4">
<h2>定期券代最適化</h2>
<p>ここで自宅と学校と職場の位置関係を言うと、自宅最寄り駅が新小岩駅、学校最寄り駅が田町駅、職場最寄り駅が新宿駅です。</p>
<p>ここで、愚直に新小岩駅から田町駅の通学定期と田町駅から新宿駅の通勤定期の2区間定期を買っても良いのですが、この買い方だと山手線を半周以上することになります。
しかし、通勤定期の区間を通学区間に含まれる秋葉原から新宿駅にすることで、より一層お安くなるということをみどりの窓口の係員が親切にも教えてくれました。</p>
<p>実際には係員がしれっとよしなにしてくれていたのですが、これを見たぼくが「ぼくが欲しいのは田町から新宿までの通勤定期なのですが……。」と指摘したことで、このお得な買い方を教えてくれました。
ぼくは馬鹿ですね。
また損をするところでした。
計算すると、愚直な買い方と係員が教えてくれたスマートな買い方では1ヶ月辺り630円違います。</p>
<p>ということで、みどりの窓口の係員のお陰で定期券代を最適化したお話でした。
当初購入しようとしていた全区間を通勤定期で購入する方法と、2区間定期でさらに通勤区間の始まりを通学区間に含まれる駅からに変更する方法では、1ヶ月あたり2470円も差額がありました。</p>
</div>
ゲヒルン株式会社に入社しました2013-08-01T00:00:00+09:002013-08-01T00:00:00+09:00yosida95tag:yosida95.com,2013-08-01:/2013/08/01/222538.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。</p>
<p>本日、<a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社</a>に入社いたしましたのでご報告します。
入社と言っても雇用形態はアルバイトです(10ヶ月ぶり3度め)。</p>
</div>
<div class="section" id="section-3">
<h2>きっかけ</h2>
<p>きっかけは、<a class="reference external" href="https://yosida95.com/2012/11/22/033659.html">昨年の11月18日にさくらインターネット石狩データセンター見学ツアーに行った</a>帰り道、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> を連れ立って <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さんとお食事をご一緒した席で、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> と共に「来年(2013年)の4月からゲヒルンにおいでよ!」ってお誘いを受けたことです。</p>
<p>4月に入社する予定だったのに8月にずれ込んだのは、前の職場の居心地が良すぎてなかなか抜ける決心がつかなかった事などが挙げられます。
この間 <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さんには辛抱強くずっとお待ち頂いている状況が続き申し訳なく思っていましたが、今回前職で担当していたプロジェクトに一区切りがついた段階で転職できたので良いタイミングだったとも思っています。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> 待 っ て ま す ! ! </p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/332140395884584960">May 8, 2013</a></blockquote></div>
<div class="section" id="section-4">
<h2>感想・意気込み</h2>
<p>前述のとおり、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> や 社長の <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さん、それから取締役の <a class="reference external" href="http://twitter.com/N_taka">@N_taka</a> さんなど以前から面識が有った方々と一緒に働けるということや、従業員の平均年齢的にも設立年的にも若い会社の中で自分がどんな事を成せるのかということに、とてもわくわくしています。</p>
<p>特に、<a class="reference external" href="https://yosida95.com/2012/12/25/064109.html">一緒に70人規模の勉強会を企画・運営した</a>り、<a class="reference external" href="https://yosida95.com/2013/01/01/005050.html">ぼくの自宅で徹夜ハッカソンをした</a>りなど以前から親交があり、また、技術者としても一目置いている <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> とは以前から一緒に働きたいと思っていたので、これが実現できた事をとても嬉しく思っています。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> <a href="https://twitter.com/KOBA789">@KOBA789</a> 一度、こばくんとよしだくんをいっしょに働かせたいと思ってる。</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/332140876463742976">May 8, 2013</a></blockquote><p>また、<a class="reference external" href="https://yosida95.com/2011/05/27/215545.html">一昨年の5月27日に初めて @isidai さんとお会いした</a>ときは、まさかその2年後にこうして一緒に働くことになるとは露ほども思っていませんでしたので、人生って何が起こるかわかりませんね!</p>
</div>
<div class="section" id="section-5">
<h2>終わりに</h2>
<p>これ is よしだせんせー's 次回作.</p>
<p>以上、今後ともよろしくお願いします。</p>
</div>
iptables の ipt_recent モジュール2013-07-31T00:00:00+09:002013-07-31T00:00:00+09:00yosida95tag:yosida95.com,2013-07-31:/2013/07/31/055159.html<div class="section" id="section-1">
<h2>始めに</h2>
<p>iptables に ipt_recent というモ …</p></div><div class="section" id="section-1">
<h2>始めに</h2>
<p>iptables に ipt_recent というモジュールがあることを1週間くらい前に知ったので、メモがてらブログに残します。</p>
<p>このモジュールを使うとできることは、「ある条件に一致するパケットの Source/Destination IP を記録する」「あるパケットの Source/Destination IP が記録したリストの中に含まれるかを時間や出現回数を元に調べ、その結果によってルールを適用するかどうかを判断する」です。</p>
<p>同じような事をもっと手軽にできる iptables のモジュールとして ipt_limit がありますが、これはあくまでも流量制限しかできないので、 ipt_recent を使うと例えば以下のような、 ipt_limit よりももっと柔軟な事ができますね。</p>
<ul class="simple">
<li>1分間に6回以上 SSH への SYN フラグが立ったパケットを受け取ったら、以後10分間その SourceIP からの接続を拒否する( SSH ブルートフォース対策)</li>
<li>10秒以内に3回以上あるポートへのパケットを受け取ったら、そのパケットの SourceIP に限り SSH への接続を許可する (ポートノッキング)</li>
</ul>
</div>
<div class="section" id="section-2">
<h2>使い方</h2>
<p><tt class="docutils literal">iptables <span class="pre">-m</span> recent <span class="pre">--help</span></tt> を叩けば詳細な使い方が見られますので、そちらをご参照下さい。</p>
</div>
<div class="section" id="section-3">
<h2>終わりに</h2>
<p>大変便利ですね!</p>
<p>しかし、あくまでも L3 レベルでの制御なので、例えば認証が一定回数失敗するとなにかルールを適用したい場合など L3 より上のレイヤーの結果を伴う必要がある場合は、 DenyHosts や Fail2ban を使用するなど、用法用量を守って賢く使い分けられるとステキですね。</p>
</div>
退職のご報告2013-07-31T00:00:00+09:002013-07-31T00:00:00+09:00yosida95tag:yosida95.com,2013-07-31:/2013/07/31/223353.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは、 yosida95 です。</p>
<p>録画した「きんいろモザイク」を観ながらこの記事を書いているので、全体的にふわっとした文章になりますがご容赦下さい。</p>
</div>
<div class="section" id="section-3">
<h2>退職しました</h2>
<p>本日7月31日付で、昨年の10月から10ヶ月間に渡り勤務していた株式会社ゼロスタートを退職しました。
なお、在籍期間的に有給が付かなかったため、最終勤務日も本日でした。
入社時の意識の高い私については<a class="reference external" href="https://yosida95.com/2012/10/13/222109.html">入社時に書いたエントリ</a>をご覧ください。</p>
</div>
<div class="section" id="section-4">
<h2>ゼロスタートについて</h2>
<div class="section" id="section-5">
<h3>業務</h3>
<p>ゼロスタートでは、進行中のプロジェクトで使われる細々としたスクリプトを書くことは何度かあったのですが、基本的には入社以来ずっと1つのプロジェクトに1人で関わってきて、途中からこれを fork して納品物を作る過程で社内の人と共に開発に取り組みました。</p>
<p>そのプロジェクトの中で私は、これまでの私個人の活動では見たたことも触ったこともないような大きさのデータと格闘したり、悪名高き O から始まる赤い会社製のデータベースと格闘したり、メモリ使用量と実行速度との狭間で格闘したり、 ORM が吐くスロークエリと格闘したり、非モダンブラウザでもモダンブラウザでも意図したとおり動作する JavaScript コードを書くべく各ブラウザの仕様の狭間で格闘したり、その中で Firefox のバグを踏んだり、といったように格闘家として活動しました。</p>
<p>そんな感じで産み落としたプロダクトが、社会に疎い私でも名前はおろかその製品すら知っているような企業に採用されたり、その結果バグが見つかって何度か土曜日に会社に呼び出されたりと、その辺の学生をとっ捕まえても経験したことがないような経験をたくさんしました。
<a class="reference external" href="https://twitter.com/search?q=%23%E3%83%95%E3%82%A9%E3%83%AD%E3%83%AF%E3%83%BC%E3%81%8C%E4%BD%93%E9%A8%93%E3%81%97%E3%81%9F%E4%BA%8B%E3%81%8C%E7%84%A1%E3%81%95%E3%81%9D%E3%81%86%E3%81%AA%E4%BD%93%E9%A8%93">#フォロワーが体験した事が無さそうな体験</a></p>
</div>
<div class="section" id="section-6">
<h3>環境</h3>
<p>ゼロスタートでは、とても恵まれた環境で働かせていただきました。</p>
<p>私の本職は高校生なわけですが、そちらに影響が出ないようにと学校の定期テスト中と定期テストの前には毎回休みを取らせてもらえました。 <a class="footnote-reference" href="#test-leave" id="footnote-reference-1">[1]</a></p>
<p>ゼロスタートのステキポイントは技術書の蔵書が多いことです。
Facebook 上で個人的に「読みたい」と言った、私の業務とは直接関係がない Hadoop に関する本も、翌々日には社内の蔵書に加えられていました。</p>
<p>また、ある日 Facebook 上で「そろそろ MBA じゃ辛い。 個人 HHKB 持ち歩きワンチャンか……。 」と投稿したのですが、それを社長に捕捉され、翌週には私のデスクの上には HappyHackingKeyboard Professional2 無刻印モデル(墨) が積んでありました。</p>
<p>それから、社内に無料飲料自動販売機が有ったことも地味に嬉しいポイントでした。
ゼロスタートの前に働いていた会社にも無料飲料自動販売機はあったので当たり前の用に感じてしまいましたが、よく考えるとこれって全然当たり前のことじゃなくとても恵まれたことなんですよね。</p>
<p>そんな感じで、ゼロスタートには全体的に従業員を大切にしてくれる文化があるのだなと感じています。
それから、前述のように社内に多くの技術書があったり、(スケジュールの関係で私が参加することは無かったのですが)エンジニア合宿も高頻度で開催されていたりと、エンジニアが自力だけではなく会社の力も借りて成長できることもゼロスタートの特徴だと思います。</p>
</div>
<div class="section" id="section-7">
<h3>感想</h3>
<p>まず私の印象に強く残っていることは、初出社の日の契約書を交わした時、時給にいくら欲しいかという話になって、前職の時給を基準に考えていたので、「前職の時給がいくらだったので、」と言った所で社長が話を遮って「安い」と言ったことです。
結局、入社時に前職の1.5倍の時給を貰えることになり、その後の人事査定で昇給しさらに多くの時給を貰えることになりました。
これは大きな励みになったと同時に、「お時給の分はしっかり働かせていただきます。」(ドラマ「ハケンの品格」より)という意識にもつながりました。</p>
<p>前出の入社時のエントリに書いた「永久機関的な何か」を回しても余りあるくらいの給与でした。
AWS に毎月コンスタントに 100USD 以上を支出したり、さくらの VPS を5台契約したり、また色々な分野の技術書も購入して読みました。
自分の幅を広げる事ができたと思っています。</p>
<p>ゼロスタートでは毎月末にビアバストが開催されているのですが、その中で誕生日を祝っていただいたことも嬉しかった思い出です。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">うわーい♡ゼロスタートは毎月恒例のビアバストでルンルンモードでございます! <a href="https://twitter.com/yosida95">@yosida95</a> くん!お誕生日おめでとう(((o(*゚▽゚*)o))) <a href="http://t.co/MLaV5J0odH">pic.twitter.com/MLaV5J0odH</a></p>— 藤崎英恵 (@fujisakidesu) <a href="https://twitter.com/fujisakidesu/status/350179282171097088">June 27, 2013</a></blockquote>
<div id="fb-root"></div><script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v2.3"; fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><div class="fb-post" data-href="https://www.facebook.com/zerostart.inc/photos/a.173420562689002.39471.116174491746943/587741741256880/?type=3" data-width="500"><div class="fb-xfbml-parse-ignore"><blockquote cite="https://www.facebook.com/zerostart.inc/photos/a.173420562689002.39471.116174491746943/587741741256880/?type=3"><p>ゼロスタートはただいま毎月恒例のビアバスト開催中です♡今月は期待の超若手ルーキーのこうへい君がお誕生日!!!まだ未成年なんて・・・なんとも羨ましいです♪おめでとうございます(*´ω`*)</p>Posted by <a href="https://www.facebook.com/zerostart.inc/">株式会社ゼロスタート</a> on <a href="https://www.facebook.com/zerostart.inc/photos/a.173420562689002.39471.116174491746943/587741741256880/?type=3">2013年6月27日</a></blockquote></div></div></div>
</div>
<div class="section" id="section-8">
<h2>おわりに</h2>
<p>そんな感じで何ひとつ不満なく働いていたゼロスタートですが、この度退職する運びとなりました。</p>
<p>初めに私の Twitter からツイートを拾ってゼロスタートで働くきっかけを作ってくださった <a class="reference external" href="https://twitter.com/__hase__">@__hase__</a> さんを始め社内の方々には大変お世話になり、本当にありがとうございました。
この場を借りて再度お礼を申し上げます。</p>
<p>それから、入社したての頃に私のリクエストで製作されたゼロスタート製ステッカーですが、私の手元にもまだ数枚ありますので、欲しい方は私と会う際にリクエストして下さい。</p>
<p>なお、「きんいろモザイク」を観ながら書き始めたこの記事ですが、途中「きんいろモザイク」に観入って記事を書く手が止まるなどしたところ、今週放送分を観終わり現在は同じく録画した「井口裕香のむ〜〜〜ん ⊂( ^ω^)⊃」を観ています。</p>
<p>それでは、よしだせんせーの次回作にご期待ください!</p>
<table class="docutils footnote" frame="void" id="test-leave" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>というか、「定期テスト期間中は社内 Git サーバーへのアクセス権を剥奪して仕事が出来ないようにする」と脅されました</td></tr>
</tbody>
</table>
</div>
バックアップ戦略、しましょうか2013-07-29T00:00:00+09:002013-07-29T00:00:00+09:00yosida95tag:yosida95.com,2013-07-29:/2013/07/29/032151.html<div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 …</p></div><div class="section" id="section-2">
<h2>はじめに</h2>
<p>こんばんは yosida95 です。
生きています。</p>
<p>ぼくの自室環境では、仮想マシンのイメージや Mac の TimeMachine のバックアップイメージなどを RAID-Z2 on OpenIndiana (WD Red 使用)なストレージサーバーに保管しています。</p>
<p>そのためハードウェア障害程度には耐えられそうですが、何があるのか分からないのでさらにバックアップするに越したことはありません。
そこで、 Amazon Web Services が提供している <a class="reference external" href="http://aws.amazon.com/jp/glacier/">Amazon Glacier</a> に保管することにしました。</p>
</div>
<div class="section" id="section-3">
<h2>いつものアレ</h2>
<p>というわけで、バッチを書きました。
バックアップが存在しないものはバックアップを行い、すでにバックアップが存在するものは modify time と SHA-1 ハッシュを前回バックアップ時のものと比較して、変更があればバックアップを行い、変更がなければバックアップをスキップします。</p>
<div class="highlight"><pre><span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">import</span> <span class="nn">fcntl</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">unicodedata</span>
<span class="kn">from</span> <span class="nn">boto.glacier</span> <span class="kn">import</span> <span class="n">connect_to_region</span> <span class="k">as</span> <span class="n">connect_to_glacier</span>
<span class="kn">from</span> <span class="nn">boto.sdb</span> <span class="kn">import</span> <span class="n">connect_to_region</span> <span class="k">as</span> <span class="n">connect_to_sdb</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="n">handler</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">StreamHandler</span><span class="p">()</span>
<span class="n">handler</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="n">formatter</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">Formatter</span><span class="p">(</span><span class="sa">u</span><span class="s1">'[</span><span class="si">%(asctime)s</span><span class="s1">][</span><span class="si">%(levelname)s</span><span class="s1">] </span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">)</span>
<span class="n">handler</span><span class="o">.</span><span class="n">setFormatter</span><span class="p">(</span><span class="n">formatter</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">GlacierBackuper</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">aws_access_key_id</span><span class="p">,</span> <span class="n">aws_secret_access_key</span><span class="p">,</span>
<span class="n">region</span><span class="p">,</span> <span class="n">glacier_vault</span><span class="p">,</span> <span class="n">sdb_domain</span><span class="p">,</span>
<span class="n">pattern</span><span class="p">,</span> <span class="n">ignore_pattern</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">glacier</span> <span class="o">=</span> <span class="n">connect_to_glacier</span><span class="p">(</span>
<span class="n">region</span><span class="p">,</span> <span class="n">aws_access_key_id</span><span class="o">=</span><span class="n">aws_access_key_id</span><span class="p">,</span>
<span class="n">aws_secret_access_key</span><span class="o">=</span><span class="n">aws_secret_access_key</span>
<span class="p">)</span><span class="o">.</span><span class="n">get_vault</span><span class="p">(</span><span class="n">glacier_vault</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sdb</span> <span class="o">=</span> <span class="n">connect_to_sdb</span><span class="p">(</span>
<span class="n">region</span><span class="p">,</span> <span class="n">aws_access_key_id</span><span class="o">=</span><span class="n">aws_access_key_id</span><span class="p">,</span>
<span class="n">aws_secret_access_key</span><span class="o">=</span><span class="n">aws_secret_access_key</span>
<span class="p">)</span><span class="o">.</span><span class="n">get_domain</span><span class="p">(</span><span class="n">sdb_domain</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ignore_pattern</span> <span class="o">=</span> <span class="n">ignore_pattern</span>
<span class="k">def</span> <span class="nf">_compute_hash</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span>
<span class="n">seek_point</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">()</span>
<span class="n">fd</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">20</span><span class="p">)</span> <span class="c1"># 1MiB</span>
<span class="k">while</span> <span class="n">buf</span><span class="p">:</span>
<span class="n">result</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="mi">10</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">fd</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">seek_point</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">archive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
<span class="k">assert</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isabs</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ignore_pattern</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">ignore_pattern</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="ow">or</span>\
<span class="bp">self</span><span class="o">.</span><span class="n">pattern</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'skip archiving of </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">))</span>
<span class="k">return</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'start archiving of </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">))</span>
<span class="n">fd</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'a+b'</span><span class="p">)</span>
<span class="n">fd</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">fcntl</span><span class="o">.</span><span class="n">flock</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">LOCK_EX</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">u</span><span class="s1">'computing hash'</span><span class="p">)</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compute_hash</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">u</span><span class="s1">'getting modified time of file to archive'</span><span class="p">)</span>
<span class="n">mtime</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getmtime</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">query</span> <span class="o">=</span> <span class="sa">u</span><span class="s2">"select * from </span><span class="si">%s</span><span class="s2"> where `filepath` = '</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sdb</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\'</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\'\'</span><span class="s1">'</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">rows</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sdb</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">rows</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'archive not found'</span><span class="p">)</span>
<span class="n">is_archive_needed</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">float</span><span class="p">(</span><span class="n">metadata</span><span class="p">[</span><span class="sa">u</span><span class="s1">'mtime'</span><span class="p">])</span> <span class="o">==</span> <span class="n">mtime</span> <span class="ow">and</span>\
<span class="n">metadata</span><span class="p">[</span><span class="sa">u</span><span class="s1">'hash'</span><span class="p">]</span> <span class="o">==</span> <span class="nb">hash</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'archive has already exist and is up to date'</span><span class="p">)</span>
<span class="n">is_archive_needed</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'archive has already exist'</span>
<span class="sa">u</span><span class="s1">' but file has been modified'</span><span class="p">)</span>
<span class="n">is_archive_needed</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">glacier</span><span class="o">.</span><span class="n">delete_archive</span><span class="p">(</span><span class="n">metadata</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="n">metadata</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="k">if</span> <span class="n">is_archive_needed</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="n">writer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">glacier</span><span class="o">.</span><span class="n">create_archive_writer</span><span class="p">()</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">20</span><span class="p">)</span>
<span class="k">while</span> <span class="n">buf</span><span class="p">:</span>
<span class="n">writer</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">20</span><span class="p">)</span>
<span class="n">writer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sdb</span><span class="o">.</span><span class="n">new_item</span><span class="p">(</span><span class="n">writer</span><span class="o">.</span><span class="n">get_archive_id</span><span class="p">())</span>
<span class="n">metadata</span><span class="p">[</span><span class="sa">u</span><span class="s1">'filepath'</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span>
<span class="n">metadata</span><span class="p">[</span><span class="sa">u</span><span class="s1">'mtime'</span><span class="p">]</span> <span class="o">=</span> <span class="n">mtime</span>
<span class="n">metadata</span><span class="p">[</span><span class="sa">u</span><span class="s1">'hash'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">hash</span>
<span class="n">metadata</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">fcntl</span><span class="o">.</span><span class="n">flock</span><span class="p">(</span><span class="n">fd</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span> <span class="n">fcntl</span><span class="o">.</span><span class="n">LOCK_UN</span><span class="p">)</span>
<span class="n">fd</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">u</span><span class="s1">'archiving has finished: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="p">))</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">archive_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dirname</span><span class="p">,</span> <span class="n">archived</span><span class="o">=</span><span class="p">[]):</span>
<span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">dirname</span><span class="p">):</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">normalize</span><span class="p">(</span><span class="sa">u</span><span class="s1">'NFC'</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">filepath</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dirname</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">filepath</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">archive</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span> <span class="ow">and</span> <span class="n">archived</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">filepath</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">archive_dir</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">archived</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">archived</span>
<span class="k">def</span> <span class="nf">get_args</span><span class="p">():</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">()</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--access_id'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'AWS Access Key ID'</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--access_secret'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'AWS Secret Access Key'</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--aws_region'</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'Region Name'</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--glacier_vault'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'Glacier Vault Name'</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--sdb_domain'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'SimpleDB Domain Name'</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--pattern'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">ur</span><span class="s1">'.+'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'RegExp pattern which match filepath to upload'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--ignore-pattern'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="sa">u</span><span class="s1">''</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'RegExp pattern'</span>
<span class="sa">u</span><span class="s1">' which match filepath to skip uploading'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">()</span>
<span class="n">backuper</span> <span class="o">=</span> <span class="n">GlacierBackuper</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">access_id</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">access_secret</span><span class="p">,</span>
<span class="n">args</span><span class="o">.</span><span class="n">aws_region</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">glacier_vault</span><span class="p">,</span>
<span class="n">args</span><span class="o">.</span><span class="n">sdb_domain</span><span class="p">,</span>
<span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">unicode</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">pattern</span><span class="p">),</span>
<span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">),</span>
<span class="n">args</span><span class="o">.</span><span class="n">ignore_pattern</span> <span class="ow">and</span>
<span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">unicode</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">ignore_pattern</span><span class="p">),</span>
<span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">))</span>
<span class="n">backuper</span><span class="o">.</span><span class="n">archive_dir</span><span class="p">(</span><span class="n">unicode</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getcwd</span><span class="p">()))</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<div class="section" id="amazon-glacier">
<h2>Amazon Glacier</h2>
<p>Amazon Glacier は大容量なデータを低価格で保管できるストレージサービスです。
月額 0.01USD/GB で使えます。</p>
<p>1ファイルをアーカイブという1単位とし、そのアーカイブを Vault という容れ物に格納する仕組みです。
ただし、アーカイブや Vault は階層構造を持てない上、もともとのファイルパスや modify time といった付加情報を保持できません。
アーカイブには一意な ID が割り当てられ、この ID によって取り出しなどの操作を行います。</p>
<p>そこで、同じく Amazon Web Services が提供している Amazon SimpleDB に、バックアップ元のファイルパスと modify time 、そして SHA-1 ハッシュと、それに対応するアーカイブ ID を記録しています。</p>
<p>また、 Amazon Glacier には「アーカイブの更新」という概念がないため、このバッチでは変更があったアーカイブについては古いものを削除した上で新たにアーカイブを作っています。
ここで注意が必要なのは、 Amazon Glacier は長期間のファイル保存を前提として作られているサービスであるため、作られてから90日経過していないアーカイブを削除すると "Early Delete" として、アーカイブサイズに応じた料金を請求されます。</p>
<p>Amazon Glacier のもっと詳しい特徴などについては各々調べて下さい。</p>
</div>
<div class="section" id="section-4">
<h2>最後に</h2>
<p>夏休みに入ったし、 LeapMotion も手に入れたので、また近いうちに記事書きます。</p>
</div>
Solaris の IP Filter に詳しくなろう2013-06-23T00:00:00+09:002013-06-23T00:00:00+09:00yosida95tag:yosida95.com,2013-06-23:/2013/06/23/213654.html<div class="section" id="section-1">
<h2>とにかく</h2>
<p><a class="reference external" href="http://docs.oracle.com/cd/E19082-01/819-2251/6n4i7td97/index.html">man 4 ipf</a>を読め …</p></div><div class="section" id="section-1">
<h2>とにかく</h2>
<p><a class="reference external" href="http://docs.oracle.com/cd/E19082-01/819-2251/6n4i7td97/index.html">man 4 ipf</a>を読め</p>
</div>
Zabbix のメディアタイプに Growl を指定し、手元のマシンの Growl で障害情報を受け取る方法2013-05-27T00:00:00+09:002013-05-27T00:00:00+09:00yosida95tag:yosida95.com,2013-05-27:/2013/05/27/005303.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>「サーバー監視 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>「サーバー監視をしていなくて許されてるのは小学生までですよね〜キャハハ」</p>
<p>私感ですが、 Munin と Zabbix のハイブリッド監視がステキです。</p>
</div>
<div class="section" id="section-2">
<h2>手順</h2>
<p>Zabbix では、ある監視項目の値が閾値を超えるなどのイベントをトリガーに、その情報を監視者に通知することができます。
その通知方法として Zabbix にデフォルトで用意されている方法は、"メール", "Jabber", "SMS", そして"スクリプト"です。</p>
<p>Growl 通知を使うためには、この4つの通知方法のうち"スクリプト"を使用します。
つまり、"Growl で障害通知をするスクリプトを自分で書いて、ここに指定すればいいってワケ"です。</p>
<div class="section" id="section-3">
<h3>手順1. スクリプト</h3>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1"># -*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">gntp</span> <span class="kn">import</span> <span class="n">notifier</span> <span class="k">as</span> <span class="n">growl</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">user</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">hostname</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span>
<span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">,</span>
<span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">a</span><span class="p">:</span> <span class="n">a</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">u</span><span class="s1">':'</span><span class="p">),</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">u</span><span class="s1">'@'</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">notifier</span> <span class="o">=</span> <span class="n">growl</span><span class="o">.</span><span class="n">GrowlNotifier</span><span class="p">(</span>
<span class="n">applicationName</span><span class="o">=</span><span class="sa">u</span><span class="s1">'Zabbix'</span><span class="p">,</span>
<span class="n">notifications</span><span class="o">=</span><span class="p">[</span><span class="sa">u</span><span class="s1">'zabbix'</span><span class="p">],</span>
<span class="n">defaultNotifications</span><span class="o">=</span><span class="p">[</span><span class="sa">u</span><span class="s1">'zabbix'</span><span class="p">],</span>
<span class="n">hostname</span><span class="o">=</span><span class="n">hostname</span><span class="p">,</span>
<span class="n">port</span><span class="o">=</span><span class="n">port</span><span class="p">,</span>
<span class="n">password</span><span class="o">=</span><span class="n">password</span>
<span class="p">)</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">notifier</span><span class="o">.</span><span class="n">register</span><span class="p">()</span>
<span class="k">if</span> <span class="n">ret</span> <span class="ow">is</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">notifier</span><span class="o">.</span><span class="n">notify</span><span class="p">(</span>
<span class="n">noteType</span><span class="o">=</span><span class="sa">u</span><span class="s1">'zabbix'</span><span class="p">,</span>
<span class="n">title</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
<span class="n">description</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
<span class="c1"># icon=u'[URI of ICON]',</span>
<span class="n">sticky</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">priority</span><span class="o">=-</span><span class="mi">1</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">ret</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>こちらが予め用意した通知スクリプトです。</p>
<p>これを zabbix_server.conf の"AlertScriptsPath"に指定されているディレクトリに保存します。</p>
<p>なお、このスクリプトを動作させるためには gntp というライブラリが必要ですので、 pip または easy_install を使ってサクッとインストールしておいて下さい。
また、 virtualenv を使う場合は、適切に shebang を変更して下さい。</p>
<p>保存したら、 Zabbix の実行ユーザーが実行できるように、適切にオーナーやグループ, パーミッションを調整して下さい。</p>
</div>
<div class="section" id="section-4">
<h3>手順2. メディアタイプに追加する</h3>
<p>Zabbix にログインした状態で、「管理」-> 「メディアタイプ」 -> 「メディアタイプの作成」と進み、フォームに適切な情報を入力し、 Zabbix メディアタイプを作成して下さい。</p>
<p><img alt="create-media-type" src="https://blogmedia.yosida95.com/2013/05/27/005303/create-media-type.png" style="width: 100%;" /></p>
</div>
<div class="section" id="growl">
<h3>手順3. "Growl" メディアをユーザーに追加する</h3>
<p>Zabbix にログインした状態で、「管理」 -> 「ユーザー」と進み、 Growl 通知を受け取りたいユーザーの設定画面を開きます。
ユーザー設定画面の下方に「メディア」という項目があるので、この項目の「追加」ボタンを押し、開いたフォームに適切な情報を入力し、 "Growl" メディアをユーザーに追加します。</p>
<p><img alt="add-media" src="https://blogmedia.yosida95.com/2013/05/27/005303/add-media.png" style="width: 100%;" /></p>
<p>なお、「送信先」のフォーマットですが、 "user:password@hostname:port" を想定しています。
user は不使用ですので空を、 password は通知を受け取るマシンの Growl 環境設定のネットワークタブで設定したものを、 hostname は通知を受け取るマシンのホストネームまたは IP アドレスを、 port は通知を受け取るマシンの Growl がリッスンしているポート番号を、それぞれ入力して下さい。</p>
</div>
</div>
<div class="section" id="section-5">
<h2>できた!</h2>
<p><img alt="growl" src="https://blogmedia.yosida95.com/2013/05/27/005303/growl.png" style="width: 100%;" /></p>
<p>ね、簡単でしょ?</p>
</div>
Ubuntu のパッケージリポジトリのミラーをローカルに建てたら幸せになった話2013-05-19T00:00:00+09:002013-05-19T00:00:00+09:00yosida95tag:yosida95.com,2013-05-19:/2013/05/19/003744.html<blockquote class="twitter-tweet" data-cards="hidden" lang="en"><p lang="ja" dir="ltr">このやりかただと、これ …</p></blockquote><blockquote class="twitter-tweet" data-cards="hidden" lang="en"><p lang="ja" dir="ltr">このやりかただと、これに引っかかるみたいです。別の方法を考えないと <a href="http://t.co/W80Sl9Fj0C">http://t.co/W80Sl9Fj0C</a> / “Ubuntu のパッケージリポジトリのミラーをローカルに建てたら幸せになった話 - yosid…” <a href="http://t.co/Q2bQOlhxQ2">http://t.co/Q2bQOlhxQ2</a> <a href="https://twitter.com/hashtag/ubuntu?src=hash">#ubuntu</a></p>— ざるそば (@ytooyama123) <a href="https://twitter.com/ytooyama123/status/435752429745762304">February 18, 2014</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/ytooyama123">@ytooyama123</a> 突然失礼します著者です。 post mirror スクリプトが rsync コネクションを同接1本以上張ることは無いので BAN 対象になるとは思えないのですが、BAN 対象になると思われた根拠を伺ってよろしいでしょうか。必要ならエントリを修正します。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/435774488605503488">February 18, 2014</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> 著者様のサイトを参考にsyncをしようとしたところ、最後のスクリプトの実行で <a href="http://t.co/W80Sl9Wm2C">http://t.co/W80Sl9Wm2C</a> で述べられたアラートが出てしまいました。「i18n 対応する」までは想定通り動いていました。(続く)</p>— ざるそば (@ytooyama123) <a href="https://twitter.com/ytooyama123/status/435788398935031808">February 18, 2014</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/ytooyama123">@ytooyama123</a> アラートというのは motd (内容は BANNED IP のリスト)の事ですか? これは rsyncd が出している motd なので、接続してきた全てのクライアントに表示されるものです。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/435792797954621440">February 18, 2014</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> これはアラートではないんですね。勘違いしていました。Syncする毎にものすごい数の同じメッセージがでたので、<a href="http://t.co/E1XEM9L0qT">http://t.co/E1XEM9L0qT</a>に接続しすぎでbanされたのかと勘違いしてしまいました。お手数おかけしました。</p>— ざるそば (@ytooyama123) <a href="https://twitter.com/ytooyama123/status/435794177977106432">February 18, 2014</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/ytooyama123">@ytooyama123</a> jaist の BAN がどのレイヤーで行われているか分かりませんが、一般的には L3 で行われていると思うので、その場合 motd すら表示されないですね。表示された motd の中にご自身のクライアントの IP が含まれていない事をご確認ください。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/435795058990645248">February 18, 2014</a></blockquote><p>【修正 2013/08/04】 /etc/apt/mirror.list にミスが有りましたので修正しました。
修正前の記事では run_postmirror が 0 に設定されていましたが、これでは postmirror.sh が実行されません。</p>
<p>こんばんは yosida95 です</p>
<p>いきなりですが、ぼくの部屋では10台(物理・仮想あわせて)の Ubuntu Server が常に動いています。
また、実験用として使う一時的な仮想マシンにも大抵の場合、 Ubuntu Server をインストールしています。
なお、よしだ VPS では OS の選択肢として Ubuntu Server 12.04 LTS に対応しています。
(昔は RHEL クローンの Scientific Linux を愛用していたのですが、どうしても Linux Kernel のバージョンが古いので、そこそこ新しいバージョンに追随している Ubuntu Server を使っている状況です。)</p>
<p>さて、このように10台以上の Ubuntu をコンスタントに運用していてストレスを感じることの1つに パッケージのアップグレードやインストールの待ち時間があります。
アップグレードは自動でやっているのでそこまででも無いのですが、インストールの待ち時間はそこそこストレスが掛かります。</p>
<p>そこで一念発起して、ローカルにパッケージリポジトリのミラーを建てて、高速ダウンロードを可能にしてストレッサーを取り除こうとしたっていうワケです。</p>
<div class="section" id="section-1">
<h2>方法</h2>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>apt-mirror
$<span class="w"> </span>sudo<span class="w"> </span>apt-mirror
</pre></div>
<p>この2行だけです。
この2行を実行すると、パッケージのダウンロードが始まります。
ただし、 wget が20プロセス並列に。</p>
<p>大抵の場合、20スレッド並列に動くような CPU は自宅に無く、コンテキストスイッチが発生しまくりでオーバーヘッドが大きいし、ロードアベレージは上がりまくって良いこと無いです。
また、ダウンロード元は archive.ubuntu.com で、ただでさえスループット伸びないわけです。</p>
</div>
<div class="section" id="section-2">
<h2>設定を変える</h2>
<p>そこで、設定を変更する必要があります。
設定ファイルは /etc/apt/mirror.list にあります。
設定方法はみれば大体わかると思います。
以下にぼくが実際に使っている設定を載せます。</p>
<pre class="code literal-block">
############# config ##################
#
set base_path /var/spool/apt-mirror
#
set mirror_path $base_path/mirror
set skel_path $base_path/skel
set var_path $base_path/var
set cleanscript $var_path/clean.sh
set defaultarch i386
set postmirror_script $var_path/postmirror.sh
set run_postmirror 0
set nthreads 4
set _tilde 0
#
############# end config ##############
deb-i386 http://ftp.jaist.ac.jp/ubuntu precise main restricted universe multiverse
deb-i386 http://ftp.jaist.ac.jp/ubuntu precise-updates main restricted universe multiverse
deb-i386 http://ftp.jaist.ac.jp/ubuntu precise-backports main restricted universe multiverse
deb-i386 http://ftp.jaist.ac.jp/ubuntu precise-security main restricted universe multiverse
deb-i386 http://ftp.jaist.ac.jp/ubuntu precise-proposed main restricted universe multiverse
deb-amd64 http://ftp.jaist.ac.jp/ubuntu precise main restricted universe multiverse
deb-amd64 http://ftp.jaist.ac.jp/ubuntu precise-updates main restricted universe multiverse
deb-amd64 http://ftp.jaist.ac.jp/ubuntu precise-backports main restricted universe multiverse
deb-amd64 http://ftp.jaist.ac.jp/ubuntu precise-security main restricted universe multiverse
deb-amd64 http://ftp.jaist.ac.jp/ubuntu precise-proposed main restricted universe multiverse
deb-src http://ftp.jaist.ac.jp/ubuntu precise main restricted universe multiverse
deb-src http://ftp.jaist.ac.jp/ubuntu precise-updates main restricted universe multiverse
deb-src http://ftp.jaist.ac.jp/ubuntu precise-backports main restricted universe multiverse
deb-src http://ftp.jaist.ac.jp/ubuntu precise-security main restricted universe multiverse
deb-src http://ftp.jaist.ac.jp/ubuntu precise-proposed main restricted universe multiverse
clean http://ftp.jaist.ac.jp/ubuntu
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise/main/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise/restricted/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise/universe/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise/multiverse/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-updates/main/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-updates/restricted/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-updates/universe/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-updates/multiverse/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-backports/main/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-backports/restricted/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-backports/universe/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-backports/multiverse/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-security/main/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-security/restricted/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-security/universe/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-security/multiverse/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-proposed/main/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-proposed/restricted/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-proposed/universe/i18n/
skip-clean http://ftp.jaist.ac.jp/ubuntu/dists/precise-proposed/multiverse/i18n/
</pre>
<p>1つ特徴としては、 deb-i386 や deb-amd64 などと、デフォルトの設定と異なる設定をしています。
これは10台のサーバーにインストールしたアーキテクチャが統一されていなく、 i386 と amd64 両方のバージョンのパッケージが必要なためです。</p>
<p>また、ダウンロード元は、 jp.archive.ubuntu.com でも良いと思いますが、理研や jaist の方が多分スループットが伸びます。
<a class="reference external" href="http://www.ubuntulinux.jp/ubuntu/mirrors">日本国内のミラーサーバー一覧</a>からネットワーク的に近く、帯域の太いものを選べば幸せになると思います。</p>
</div>
<div class="section" id="section-3">
<h2>定期的にパッケージを更新する</h2>
<p>cron で apt-mirror を回すだけです。
apt-mirror をインストールすると、 /etc/cron.d/apt-mirror に毎日4時に cron をするための設定がコメントアウトされた状態で書かれているので、コメントアウトを外して、都合の良いタイミングで同期が取れるように設定を変更して下さい。</p>
</div>
<div class="section" id="http">
<h2>HTTP サーバーを建てる</h2>
<p>apt は HTTP でパッケージをダウンロードしてくるので、 HTTP サーバーを建てないと、 apt-mirror がダウンロードしてきたパッケージ達はただのストレージ潰しとなってしまいます。
そこで、 HTTP サーバーを建てて、他の Ubuntu がアクセスできるようにします。</p>
<p>なお、 HTTP サーバーは Apache でも Nginx でも Lighttpd でもよいと思いますが、ここではぼくの個人的な趣味で Nginx
を入れて設定したいと思います。
本当なら、ソースコードをダウンロードしてきて、必要な機能だけを持つ Nginx をビルドして使うところですが、その手順を紹介すると1本の独立した記事が出来そうなので、 apt-get で全部入りの Nginx を入れてしまいます。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>nginx
</pre></div>
<p>設定ファイルは /etc/nginx にあります。
まずは、 nginx.conf を開いて、 worker_processes や worker_rlimit_* や、 worker_connections を適切な値に変更します(この手順は省いても問題有りませんが、この設定をすることでよりパフォーマンスが伸びる場合があります)。</p>
<p>次に、 /etc/nginx/sites-available に apt-mirror などという分かりやすい名前で apt-mirror ようの設定ファイルを作り、最低以下の内容を記述します。</p>
<div class="highlight"><pre><span></span><span class="k">server</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kn">server_name</span><span class="w"> </span><span class="nv">${host_name}</span><span class="p">;</span>
<span class="w"> </span><span class="kn">listen</span><span class="w"> </span><span class="mi">80</span><span class="p">;</span>
<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/ubuntu</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kn">root</span><span class="w"> </span><span class="s">/var/spool/apt-mirror/mirror/</span><span class="nv">${ダウンロード元のホスト名}</span><span class="p">;</span>
<span class="w"> </span><span class="kn">autoindex</span><span class="w"> </span><span class="no">on</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>これができたら、 /etc/nginx/sites-enabled に、今作った設定ファイルへのシンボリックリンクを張って、 Nginx を起動します。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/etc/nginx/sites-available/apt-mirror<span class="w"> </span>/etc/nginx/sites-enabled
$<span class="w"> </span>sudo<span class="w"> </span>service<span class="w"> </span>nginx<span class="w"> </span>start
</pre></div>
</div>
<div class="section" id="ubuntu-apt">
<h2>Ubuntu の apt が、今回建てたミラーサーバーからパッケージを取得するようにする</h2>
<p>/etc/apt/sources.list に、パッケージの取得先の URI が記述されているので、これを今回建てたミラーサーバに変更します。</p>
<pre class="code literal-block">
deb http://ubuntu.mirror.yosida95.com/ubuntu/ precise main restricted universe multiverse
deb-src http://ubuntu.mirror.yosida95.com/ubuntu/ precise main restricted universe multiverse
deb http://ubuntu.mirror.yosida95.com/ubuntu/ precise-updates main restricted universe multiverse
deb-src http://ubuntu.mirror.yosida95.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://ubuntu.mirror.yosida95.com/ubuntu/ precise-backports main restricted universe multiverse
deb-src http://ubuntu.mirror.yosida95.com/ubuntu/ precise-backports main restricted universe multiverse
deb http://ubuntu.mirror.yosida95.com/ubuntu precise-security main restricted universe multiverse
deb-src http://ubuntu.mirror.yosida95.com/ubuntu precise-security main restricted universe multiverse
</pre>
<p>※なお、これらの URI は実際にぼくのサーバーで使っているものですが、外部からはアクセス出来ないようにしています。</p>
</div>
<div class="section" id="i18n">
<h2>i18n 対応する</h2>
<p>この状態で、 apt-get update をすると分かるのですが、以下の様なログが出力されます。</p>
<pre class="code literal-block">
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/main Translation-en
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/restricted Translation-en
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/universe Translation-en
(無視|Ign) http://ubuntu.mirror.yosida95.com precisemultiverse Translation-en
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/main Translation-ja
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/restricted Translation-ja
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/universe Translation-ja
(無視|Ign) http://ubuntu.mirror.yosida95.com precisemultiverse Translation-ja
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/main TranslationIndex
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/restricted TranslationIndex
(無視|Ign) http://ubuntu.mirror.yosida95.com precise/universe TranslationIndex
(無視|Ign) http://ubuntu.mirror.yosida95.com precisemultiverse TranslationIndex
</pre>
<p>これは、 i18n 系のパッケージが apt-mirror ではダウンロードされないため、 404 Not Found が返っているためです。
これを修正するためには、 i18n 系のパッケージを手動でダウンロードしてくれば良いわけです。</p>
<p>apt-mirror によるパッケージのダウンロードが終わった後に、/var/spool/apt-mirror/var/postmirror.sh というスクリプトが実行されます。
このフックスクリプトに i18n 系のパッケージをダウンロードするコードを書いてやればいいわけです。</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
<span class="nv">RSYNC</span><span class="o">=</span><span class="s2">"rsync --recursive --times --links --hard-links --delete --delete-after"</span>
<span class="nv">SOURCE</span><span class="o">=</span><span class="s2">"rsync://ftp.jaist.ac.jp/pub/Linux/ubuntu"</span>
<span class="nv">TARGET</span><span class="o">=</span><span class="s2">"/var/spool/apt-mirror/mirror/ftp.jaist.ac.jp/ubuntu"</span>
<span class="nv">dists</span><span class="o">=(</span>precise<span class="w"> </span>precise-updates<span class="w"> </span>precise-backports<span class="w"> </span>precise-security<span class="o">)</span>
<span class="k">for</span><span class="w"> </span>dist<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="s2">"</span><span class="si">${</span><span class="nv">dists</span><span class="p">[@]</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="si">${</span><span class="nv">RSYNC</span><span class="si">}</span><span class="w"> </span><span class="si">${</span><span class="nv">SOURCE</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/main/i18n/<span class="w"> </span><span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/main/i18n/
<span class="w"> </span><span class="si">${</span><span class="nv">RSYNC</span><span class="si">}</span><span class="w"> </span><span class="si">${</span><span class="nv">SOURCE</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/multiverse/i18n/<span class="w"> </span><span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/multiverse/i18n/
<span class="w"> </span><span class="si">${</span><span class="nv">RSYNC</span><span class="si">}</span><span class="w"> </span><span class="si">${</span><span class="nv">SOURCE</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/restricted/i18n/<span class="w"> </span><span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/restricted/i18n/
<span class="w"> </span><span class="si">${</span><span class="nv">RSYNC</span><span class="si">}</span><span class="w"> </span><span class="si">${</span><span class="nv">SOURCE</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/universe/i18n/<span class="w"> </span><span class="si">${</span><span class="nv">TARGET</span><span class="si">}</span>/dists/<span class="si">${</span><span class="nv">dist</span><span class="si">}</span>/universe/i18n/
<span class="k">done</span>
</pre></div>
<p>※ぼくがダウンロード元として使っている jaist は rsync でもアクセスできるようになっているので、ここでは rsync
で同期をとるようにします。
$SOURCE や $TARGET を選んだミラーサーバーに合わせて適切に変更して下さい。</p>
</div>
<div class="section" id="section-4">
<h2>以上です</h2>
<p>お疲れ様でした。</p>
<p>この設定により、パッケージのアップデートやインストールにかかる時間は劇的に短縮されてストレスが軽減しました。
ぼくはこのミラーサーバーのために、よしだ VPS 上に新しいインスタンスを切ったのですが、その OS のサイズとダウンロードしてきたパッケージのサイズ合わせてわずか 136GiB 程度のストレージを使うだけでこのように快適な環境を手に入れられたので、とても幸せになりました。</p>
</div>
Google Compute Engine を軽く使ってみた感想2013-05-17T00:00:00+09:002013-05-17T00:00:00+09:00yosida95tag:yosida95.com,2013-05-17:/2013/05/17/192921.html<div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 …</p></div><div class="section" id="section-1">
<h2>はじめに</h2>
<p>こんにちは、 yosida95 です。
2ヶ月ぶりのブログエントリです。
生存しています。</p>
</div>
<div class="section" id="google-compute-engine-1">
<h2>Google Compute Engine</h2>
<p>現在開催中の Google I/O で Google の IaaS 、 Google Compute Engine の Preview 版の一般公開が発表されました。
<a class="reference external" href="http://cloud.watch.impress.co.jp/docs/news/20130517_599836.html">関連記事:Google、IaaSの「Google Compute Engine」プレビュー版を一般公開</a></p>
<p>Amazon Web Services の EC2 の対抗馬として騒がれているので、どんなものか<span class="strike">学校の試験期間中の暇な時間を活かして</span>軽く触ってみました。</p>
</div>
<div class="section" id="web">
<h2>Web コンソール</h2>
<p>Google Compute Engine には Web コンソールが用意されていて、インスタンスの作成などの操作はこの Web コンソール上で行う事ができます。
しかし、この Web コンソールは必要最小限の説明や機能しかありません。
従って、 Amazon Web Services の EC2 の使い勝手に慣れていると、随分と見劣りします。</p>
<p>また、プルダウンメニューがページのスクロールと干渉して、目的のメニューを選ぶことが難しいく、使い勝手悪いです。</p>
<p>まぁ、「 REST API を用意したから開発者ならこれを使えや」という事なのでしょう。
ぼくにとってはそれで十分なので、特に文句ないです。</p>
</div>
<div class="section" id="rest-api">
<h2>REST API</h2>
<div class="section" id="section-2">
<h3>インスタンスの作り方</h3>
<p><span class="strike">REST API 操作の例として、インスタンスの作成方法を紹介します。</span>
REST API 操作例としてインスタンスの作成方法を紹介出来れば良いのですが、それを書くにはブログはあまりにも狭すぎるので、ある Zone(データセンター) で稼働中のインスタンスの一覧を取得してみます。</p>
<div class="section" id="oauth-2-0">
<h4>OAuth 2.0</h4>
<p>詳しくは <a class="reference external" href="https://developers.google.com/accounts/docs/OAuth2">Google のドキュメント</a>を読んで下さい。</p>
<p>Google の各種 API は、認可プロトコルとして OAuth 2.0 が採用されており、 Google Compute Engine も例外ではありません。</p>
<p>まずは、前準備として <a class="reference external" href="https://code.google.com/apis/console">Google API Console</a> から、 Google Compute Engine 用の ClientID と ClientSecret を取得してきます。</p>
<p>次に、 Google アカウントにログインした状態で、以下のルールで組み立てた認可用 URI を踏み、アクセスを許可して Verifier を入手します。</p>
<pre class="code literal-block">
https://accounts.google.com/o/oauth2/auth?client_id=${ClientID}&scope=https://www.googleapis.com/auth/compute&response_type=code&redirect_uri=${RedirectURI}
</pre>
<p>次の POST リクエストをしてアクセストークンを取得します。
(例として curl からリクエストしています。 )</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>curl<span class="w"> </span>-d<span class="w"> </span><span class="nv">client_id</span><span class="o">=</span><span class="si">${</span><span class="nv">ClientID</span><span class="si">}</span><span class="w"> </span>-d<span class="w"> </span><span class="nv">client_secret</span><span class="o">=</span><span class="si">${</span><span class="nv">ClientSecret</span><span class="si">}</span><span class="w"> </span>-d<span class="w"> </span><span class="nv">redirect_uri</span><span class="o">=</span><span class="si">${</span><span class="nv">RedirectURI</span><span class="si">}</span><span class="w"> </span>-d<span class="w"> </span><span class="nv">grant_type</span><span class="o">=</span>authorization_code<span class="w"> </span>-d<span class="w"> </span><span class="nv">code</span><span class="o">=</span><span class="si">${</span><span class="nv">Verifier</span><span class="si">}</span><span class="w"> </span>https://accounts.google.com/o/oauth2/token
</pre></div>
<p>成功すると、 JSON で access_token が返ってくるので、これを保存します。</p>
</div>
<div class="section" id="section-3">
<h4>インスタンスの一覧を取得する</h4>
<div class="highlight"><pre><span></span>curl<span class="w"> </span>-G<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: OAuth </span><span class="si">${</span><span class="nv">access_token</span><span class="si">}</span><span class="s2">"</span><span class="w"> </span>https://www.googleapis.com/compute/v1beta14/projects/<span class="o">{</span><span class="nv">$ProjectID</span><span class="o">}</span>/zones/<span class="si">${</span><span class="nv">Zone</span><span class="si">}</span>/instances
</pre></div>
<p>というように、 <tt class="docutils literal"><span class="pre">https://www.googleapis.com/compute/v1beta14/projects/{$ProjectID}/zones/${Zone}/instances</span></tt> に Authorization ヘッダ付きで GET することで、指定した Zone で稼働中の、指定したプロジェクト用のインスタンスの一覧が JSON で取得出来ます。</p>
<p>ここまでに書いた事柄のより詳しい内容は、 <a class="reference external" href="https://developers.google.com/compute/docs/reference/v1beta14/">Google Compute Engine の REST API ドキュメント</a>を見ればわかります。</p>
</div>
</div>
</div>
<div class="section" id="gcutil">
<h2>gcutil</h2>
<p>ここまで、苦労して REST API の操作方法を書いて来ましたが、なんと Google Compute Enigne には Google 謹製の REST
API クライアントがあります。
これは、 Python 製のコマンドラインツールで、 REST API を使った操作の全て(多分) を行えます。</p>
<p>プログラムで仮想マシンを操作する必要がないのであれば、この gcutil を使えばよいと思います。</p>
<p><a class="reference external" href="https://developers.google.com/compute/docs/gcutil/">gcutil Reference</a></p>
</div>
<div class="section" id="section-4">
<h2>思ったことなど</h2>
<ul class="simple">
<li>OS の選択肢が少ない<ul>
<li>現状選択可能な OS は CentOS と Debian Linux<ul>
<li>Ubuntu Server は以前は使えた痕跡が有ったが、削除されていた</li>
<li>個人的に Debian Linux は好きなので別に文句とかは無い</li>
</ul>
</li>
<li>Amazon Web Services の EC2 に見劣りする</li>
</ul>
</li>
<li>初めてのインスタンスを作ってから SSH 接続するまでが長い<ul>
<li>gcutil を使って ssh 接続をすると、認証用の鍵ペアの作成に始まり、(どうやら)インスタンス上に gcutil の実行ユーザーと同名のユーザーを作って、 ~/.ssh/authorization_keys に作った鍵を追加している<ul>
<li>Amazon Web Services の EC2 ではまず認証用の鍵ペアを生成して、その鍵がすでに ~/.ssh/authorization_keys に追加された状態でインスタンスが立ち上がってくる</li>
</ul>
</li>
<li>でも、 EC2 の場合は、ユーザー名が固定されているから、普段使っている愛着のある名前のユーザーをつくる手間が省けるのは良いかも</li>
</ul>
</li>
<li>よりハードウェアっぽい<ul>
<li>IaaS として VCPU の数やメモリの量が選べるのは当然のことだが、 Google Compute Engine では、小さなプランを選ぶと、 "Shares physical core" などと出て、ホストマシン上でインスタンスがどのように動くかの情報が分かるので、仮想化ボーイとしては面白い<ul>
<li>でも、 EC2 の方がちゃんと抽象化できている、とも言える。</li>
</ul>
</li>
</ul>
</li>
<li>まだまだベータ<ul>
<li>つくれるインスタンスの量(というか、 VCPU の数)が制限されている</li>
<li>今後正式版がローンチされる事が楽しみ<ul>
<li>だけど、ぼくはゆとり開発者なのでこのままの Google Compute Engine なら、 Amazon Web Services の EC2 に甘やかされ続けたい。</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="section-5">
<h2>以上です</h2>
<p>REST API の使い方説明しようと思ったら、分量の大半を OAuth 2.0 の認可ステップに費やされた。。。</p>
</div>
MongoDB の DBRef で参照先が削除された場合 ( mongoengine )2013-03-03T00:00:00+09:002013-03-03T00:00:00+09:00yosida95tag:yosida95.com,2013-03-03:/2013/03/03/154037.html<div class="section" id="mongodb-dbref-cascade">
<h2>MongoDB の DBRef に cascade が欲しい</h2>
<p>昔 …</p></div><div class="section" id="mongodb-dbref-cascade">
<h2>MongoDB の DBRef に cascade が欲しい</h2>
<p>昔から今においても RDB をいじってる人間として、欲しい気持ち感じて辛まるんですが無いんですかね。</p>
</div>
<div class="section" id="dbref">
<h2>参照切れが起きている DBRef を検出するクエリ</h2>
<p>SQL なら書けるのに、MongoDB では書けないんですかね。
書きたくて震えます。</p>
</div>
<div class="section" id="section-1">
<h2>参照切れの発生</h2>
<p>ゆとりデベロッパーなので、MongoDB を使うときに ODM(Object-Document Mapper) を使っています。
Python の開発では主に mongoengine を使っています。</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mongoengine</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">Document</span><span class="p">,</span>
<span class="n">ReferenceField</span>
<span class="p">)</span>
<span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="n">Document</span><span class="p">):</span>
<span class="c1"># some fields</span>
<span class="k">class</span> <span class="nc">Bar</span><span class="p">(</span><span class="n">Document</span><span class="p">):</span>
<span class="n">foreign</span> <span class="o">=</span> <span class="n">ReferenceField</span><span class="p">(</span><span class="n">Foo</span><span class="p">,</span> <span class="n">dbref</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
<p>上記のようにコレクションが定義されていると仮定して、例えば Foo のドキュメント foo を消してしまいます。
もし、Bar のドキュメントのうち、 foo を参照しているものが無ければ何の問題も無いのですが、もし Bar のドキュメント bar が foo を参照していると、参照切れが発生します。</p>
</div>
<div class="section" id="mongoengine">
<h2>mongoengine は参照切れが起きるとどういう挙動をするか</h2>
<p>参照切れが起きていない状態では、bar.foreign を参照すると foo が返ってきます。
当然ですね。</p>
<p>では、参照切れが起きた状態で bar.foreign を参照するとどうなるのか。
ぼく的には何らかの例外とかが発生すると嬉しいのですが、実際には bson.dbref.DBRef のインスタンスが返ってきます。</p>
<p>mongoengine は MongoDB を操作するために、pymongo を使用しているので、1つ下のレイヤーで扱われているデータをそのまま返してしまうわけですね。
気が利かないですね。</p>
<p>従って、例えば bar.foreign.get_some_filed() というメソッドを呼びだそうとすると、AttributeError 例外が発生します。
この例外は想定外なので、多くの場合ハンドリングされず、一番上まで昇ってきます。
ウェブアプリだと500 Internal Error を返します。
これは良くないですね。</p>
</div>
<div class="section" id="section-2">
<h2>検出する</h2>
<p>本当は参照切れを発生させないことが一番なんですが、仕方ない場面だって十分にあります。
そこで、どういう対策をするのかといえば、次の2つをやっておけば良いんじゃないでしょうか。</p>
<ol class="arabic simple">
<li>AttributeError をハンドリングする</li>
<li>定期的にバッチ処理をして参照切れをなくす</li>
</ol>
<p>1 の方法は、なるべく mongoengine.objects の参照を行なっている層の近くでやると良いですね。
あるいは、AttributeError の検出ではなく、bar.foreign にアクセスするときに、isinstance(bar.foreign, Foo) とかでチェックすると確実かも知れません。
そして、ただ検出/チェックするだけでなく、見つけたら参照切れを解消してしまうと良いですね。</p>
<p>まぁ、2 の方法は、データが大きくなればなるほど大変なので、1 で事足りるならそれで十分ですね。</p>
<p>なんかとてもに眠い上、定期考査期間中なので、よくわからないテンションで自分でも何言ってるか分からない記事ですが、とにかくそういうことです。</p>
</div>
PasteDeploy で、設定ファイルのセクションを指定してアプリケーションを立ち上げる2013-02-22T00:00:00+09:002013-02-22T00:00:00+09:00yosida95tag:yosida95.com,2013-02-22:/2013/02/22/015401.html<p>【2013/03/07 修正】 aodag さんより …</p><p>【2013/03/07 修正】 aodag さんよりご指摘を頂いたので、 gunicorn に関して修正しました。</p>
<p>メモです。
仕事の中で気になったので、調べてまとめてみました。</p>
<div class="section" id="section-1">
<h2>はじめに</h2>
<p>Pyramid の設定ファイル( development.ini とか production.ini とか)は、 PasteDeploy でパースされ、設定内容( SQLAlchemy が使う DB とか,テンプレートがあるディレクトリのパスとか)に従ってアプリケーションが起動します。</p>
<p>その設定ファイルは通常、以下の様な感じになっています。</p>
<div class="highlight"><pre><span></span><span class="k">[app:main]</span>
<span class="na">use</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">egg:myapp</span>
<span class="na">pyramid.reload_template</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<span class="na">pyramid.debug_authorization</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.debug_notfound</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid_debug_routematch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.default_locale_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">ja</span>
</pre></div>
<p>通常使用であればこれで不便しないのですが、環境によって設定を変えたいと思った場合に、次のように app セクションを追加することで、複数の設定を記述できます。</p>
<div class="highlight"><pre><span></span><span class="k">[app:main]</span>
<span class="na">use</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">egg:myapp</span>
<span class="na">pyramid.reload_template</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span>
<span class="na">pyramid.debug_authorization</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.debug_notfound</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid_debug_routematch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.default_locale_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">ja</span>
<span class="k">[app:sub]</span>
<span class="na">use</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">egg:myapp</span>
<span class="na">pyramid.reload_template</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.debug_authorization</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.debug_notfound</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid_debug_routematch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span>
<span class="na">pyramid.default_locale_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">en</span>
</pre></div>
<p>このエントリは app:sub に記述した設定でアプリケーションを立ち上げるにはどうすれば良いのか、という方法のメモです。</p>
</div>
<div class="section" id="pserve">
<h2>pserve の場合</h2>
<p><tt class="docutils literal">pserve <span class="pre">--help</span></tt> を実行すればわかりますが、-n, --app-name というオプションがあります。</p>
<p>これに sub を渡してやれば、 app:sub の設定でアプリケーションが立ち上がります。</p>
<p>また、 gunicorn を使う場合は、以下のようにして PasteDeploy 設定ファイルの server セクションに gunicorn を指定してやると、 pserve コマンド経由で gunicorn を立ち上げる事ができます。
(参考: <a class="reference external" href="http://docs.gunicorn.org/en/latest/run.html#paster-serve">Running Gunicorn</a> )</p>
<div class="highlight"><pre><span></span><span class="k">[server:main]</span>
<span class="na">use</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">egg:gunicorn</span><span class="c1">#main</span>
<span class="o">:</span>
<span class="o">:</span>
</pre></div>
</div>
<div class="section" id="uwsgi-gunicorn-wsgi">
<h2>uWSGI, <span class="strike">gunicorn</span> その他 WSGI サーバーの場合</h2>
<p>これが本題です。</p>
<div class="section" id="pastedeploy-1">
<h3>PasteDeploy への対応状況</h3>
<p>まずは uWSGI と <span class="strike">gunicorn</span> の PasteDeploy への対応状況から。</p>
<p><span class="strike">gunicorn の場合、 gunicorn_paster というコマンドがあって、これに PasteDeploy の設定ファイルを渡してやるとアプリが立ち上がります。
しかし、立ち上がるアプリケーションは app:main セクションに記述されたもの固定で、指定する方法がありません(調べた限り)。</span></p>
<p>uWSGI の場合は、--paste や --ini-paste というオプションに PasteDeploy の設定ファイルを渡してやれば良いですが、 app:main セクションを指定することはできません。</p>
</div>
<div class="section" id="section-2">
<h3>使用するセクションを指定する</h3>
<p>ということで、どうやって使用するセクションを指定するのか、という方法ですが、以下のスクリプトを app.py とか適当な名前でプロジェクトのトップディレクトリに置きます。</p>
<div class="highlight"><pre><span></span><span class="c1">#-*- coding: utf-8 -*-</span>
<span class="c1"># app.py</span>
<span class="kn">from</span> <span class="nn">paste.deploy</span> <span class="kn">import</span> <span class="n">loadapp</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">loadapp</span><span class="p">(</span><span class="sa">u</span><span class="s1">'config:/path/to/PasteDeployConfigureFile'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">SECTION_NAME</span><span class="p">)</span>
</pre></div>
<p>これによって app:app が純粋な WSGI アプリケーションのインスタンスになるので、あとは次のようなコマンドで起動できます。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>gunicorn<span class="w"> </span>app:app
$
$<span class="w"> </span>uwsgi<span class="w"> </span>--module<span class="w"> </span>app:app
</pre></div>
<p>SECTION_NAME を環境変数によって変えるとか、フロントエンドサーバーからのオプションで切り替えるとか、そういう使い方ができると思います。</p>
<p># 簡単なメモを書くつもりが30分くらい時間を奪われてて萎えぽよ</p>
</div>
</div>
Consistent Hashing の実装2013-02-22T00:00:00+09:002013-02-22T00:00:00+09:00yosida95tag:yosida95.com,2013-02-22:/2013/02/22/140829.html<p>最近、Consisten Hashing について調べ …</p><p>最近、Consisten Hashing について調べている。
日本語で解説してくれているページはいくつもあって、それが言っていることはわかるのだけれど、やっぱりコードを読んでみないとちゃんとわかっているかわからない。</p>
<p>そこで、Github を漁っていたら、<a class="reference external" href="https://github.com/dakatsuka/node-consistent-hashing">簡単なNode.js 実装</a>を発見した。
それを読んでスッキリ理解できたのだが、自分で実装してみないことには落ち着かない。
そこで、この Node.js の Consistent Hashing 実装を Python に移植してみた。</p>
<div class="highlight"><pre><span></span><span class="c1">#-*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">math</span>
<span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">sha1</span>
<span class="k">class</span> <span class="nc">ConsistentHashing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodes</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">replicas</span> <span class="o">=</span> <span class="mi">160</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ring</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_node</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">add_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">replicas</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">sha1</span><span class="p">(</span><span class="sa">u</span><span class="s1">'</span><span class="si">%s</span><span class="s1">:</span><span class="si">%d</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">x</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">node</span>
<span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">remove_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
<span class="k">while</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nodes</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nodes</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">replicas</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">sha1</span><span class="p">(</span><span class="sa">u</span><span class="s1">'</span><span class="si">%s</span><span class="s1">:</span><span class="si">%d</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">x</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">while</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">)</span> <span class="ow">is</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="n">key_hash</span> <span class="o">=</span> <span class="n">sha1</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">position</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_node_position</span><span class="p">(</span><span class="n">key_hash</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="p">[</span><span class="n">position</span><span class="p">]]</span>
<span class="k">def</span> <span class="nf">get_node_position</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key_hash</span><span class="p">):</span>
<span class="n">upper</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">lower</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">index</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">compare</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="n">upper</span> <span class="ow">is</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">lower</span> <span class="o"><=</span> <span class="n">upper</span><span class="p">:</span>
<span class="n">index</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">floor</span><span class="p">((</span><span class="n">lower</span> <span class="o">+</span> <span class="n">upper</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span>
<span class="n">compare</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keys</span><span class="p">[</span><span class="n">index</span><span class="p">],</span> <span class="n">key_hash</span><span class="p">)</span>
<span class="k">if</span> <span class="n">compare</span> <span class="ow">is</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">index</span>
<span class="k">elif</span> <span class="n">compare</span> <span class="ow">is</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">upper</span> <span class="o">=</span> <span class="n">index</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lower</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">upper</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">upper</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ring</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">return</span> <span class="n">upper</span>
<span class="k">def</span> <span class="nf">compare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">v1</span> <span class="o">></span> <span class="n">v2</span> <span class="k">else</span> <span class="o">-</span><span class="mi">1</span> <span class="k">if</span> <span class="n">v1</span> <span class="o"><</span> <span class="n">v2</span> <span class="k">else</span> <span class="mi">0</span>
</pre></div>
<ul class="simple">
<li><a class="reference external" href="https://github.com/dakatsuka/node-consistent-hashing">移植元:node-consistent-hashing</a></li>
<li><a class="reference external" href="https://github.com/dakatsuka/node-consistent-hashing/blob/master/LICENSE">移植元のライセンス:MIT LICENSE</a></li>
</ul>
Linux で NIC の bonding + bridge2013-02-17T00:00:00+09:002013-02-17T00:00:00+09:00yosida95tag:yosida95.com,2013-02-17:/2013/02/17/220930.html<div class="section" id="nic">
<h2>NIC 買いました</h2>
<p><a class="reference external" href="http://www.amazon.co.jp/dp/B000BMZHX2/">インテル …</a></p></div><div class="section" id="nic">
<h2>NIC 買いました</h2>
<p><a class="reference external" href="http://www.amazon.co.jp/dp/B000BMZHX2/">インテル PRO/1000 PT デュアルポート サーバ・アダプタ EXPI9402PT</a></p>
<p>これをとりあえず4枚。
中古で1枚辺り4000円くらいでした。</p>
</div>
<div class="section" id="nic-1">
<h2>NIC 取り付けました</h2>
<p>もともと Dual Port なサーバーにも取り付けたので、1台のサーバーから LAN ケーブルが4本生えてきて激しく L2 スイッチのポートを占領してきます。
つい先日16ポートの L2 スイッチを買ったばかりなのに、もうポートが埋まってしまいました。</p>
</div>
<div class="section" id="lan">
<h2>1台のサーバーに複数の LAN ケーブルをさせるようになった僕たちは</h2>
<p>bonding を試してみるしかない。</p>
</div>
<div class="section" id="vps">
<h2>よしだ VPS</h2>
<p>ホストマシンとして動かすために、 bonding したインターフェースをブリッジのポートとして使いたい。</p>
</div>
<div class="section" id="section-1">
<h2>やってみた</h2>
<div class="section" id="ubuntu-12-04-lts">
<h3>Ubuntu 12.04 LTS 編</h3>
<div class="section" id="bonding">
<h4>bonding をロード</h4>
<div class="highlight"><pre><span></span>modprobe<span class="w"> </span>bonding
<span class="nb">echo</span><span class="w"> </span><span class="s2">"bonding"</span><span class="w"> </span>>><span class="w"> </span>/etc/modules
</pre></div>
</div>
<div class="section" id="section-2">
<h4>インターフェースの設定</h4>
<div class="highlight"><pre><span></span>$<span class="w"> </span>cat<span class="w"> </span>/etc/network/interfaces
auto<span class="w"> </span>lo
iface<span class="w"> </span>lo<span class="w"> </span>inet<span class="w"> </span>loopback
auto<span class="w"> </span>eth0
iface<span class="w"> </span>eth0<span class="w"> </span>inet<span class="w"> </span>manual
<span class="w"> </span>bond-master<span class="w"> </span>bond0
auto<span class="w"> </span>eth1
iface<span class="w"> </span>eth1<span class="w"> </span>inet<span class="w"> </span>manual
<span class="w"> </span>bond-master<span class="w"> </span>bond0
auto<span class="w"> </span>eth2
iface<span class="w"> </span>eth2<span class="w"> </span>inet<span class="w"> </span>manual
<span class="w"> </span>bond-master<span class="w"> </span>bond0
auto<span class="w"> </span>eth3
iface<span class="w"> </span>eth3<span class="w"> </span>inet<span class="w"> </span>manual
<span class="w"> </span>bond-master<span class="w"> </span>bond0
auto<span class="w"> </span>bond0
iface<span class="w"> </span>bond0<span class="w"> </span>inet<span class="w"> </span>manual
<span class="w"> </span>bond-slaves<span class="w"> </span>none
<span class="w"> </span>bond-miimon<span class="w"> </span><span class="m">100</span>
<span class="w"> </span>bond-mode<span class="w"> </span><span class="m">1</span>
auto<span class="w"> </span>br0
iface<span class="w"> </span>br0<span class="w"> </span>inet<span class="w"> </span>static
<span class="w"> </span>bridge_ports<span class="w"> </span>bond0
<span class="w"> </span>address<span class="w"> </span><span class="m">192</span>.168.1.100
<span class="w"> </span>network<span class="w"> </span><span class="m">192</span>.168.1.0
<span class="w"> </span>netmask<span class="w"> </span><span class="m">255</span>.255.255.0
<span class="w"> </span>broadcast<span class="w"> </span><span class="m">192</span>.168.1.255
<span class="w"> </span>gateway<span class="w"> </span><span class="m">192</span>.168.1.1
<span class="w"> </span>dns-nameservers<span class="w"> </span><span class="m">192</span>.168.1.10
<span class="w"> </span>pre-up<span class="w"> </span>ifup<span class="w"> </span>bond0
<span class="w"> </span>post-down<span class="w"> </span>ifdown<span class="w"> </span>bond0
</pre></div>
</div>
<div class="section" id="section-3">
<h4>ネットワーク再起動</h4>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>/etc/init.d/networking<span class="w"> </span>restart
</pre></div>
</div>
</div>
<div class="section" id="scientific-linux-6-3">
<h3>Scientific Linux 6.3 編</h3>
<p>Redhat Enterprise Linux クローンなので、 Redhat Enterprise Linux やそのクローンなら変わらないと思う。
事実、 Redhat Enterprise Linux のドキュメント読んで設定した。</p>
<div class="section" id="bonding-1">
<h4>bonding をロード</h4>
<div class="highlight"><pre><span></span>$<span class="w"> </span>cat<span class="w"> </span>/etc/modprobe.d/bonding.conf
<span class="nb">alias</span><span class="w"> </span>bond0<span class="w"> </span>bonding
</pre></div>
</div>
<div class="section" id="section-4">
<h4>インターフェースの設定</h4>
<div class="highlight"><pre><span></span>$<span class="w"> </span>cat<span class="w"> </span>/etc/sysconfig/network-scripts/ifcfg-bond0
<span class="nv">DEVICE</span><span class="o">=</span>bond0
<span class="nv">ONBOOT</span><span class="o">=</span>yes
<span class="nv">BOOTPROTO</span><span class="o">=</span>none
<span class="nv">BONDING_OPTS</span><span class="o">=</span><span class="s2">"mode=1 miimon=100"</span>
<span class="nv">BRIDGE</span><span class="o">=</span>br0
$
$<span class="w"> </span>cat<span class="w"> </span>/etc/sysconfig/network-scripts/ifcfg-br0
<span class="nv">DEVICE</span><span class="o">=</span>br0
<span class="nv">ONBOOT</span><span class="o">=</span>yes
<span class="nv">TYPE</span><span class="o">=</span>Bridge
<span class="nv">BOOTPROTO</span><span class="o">=</span>none
<span class="nv">IPADDR</span><span class="o">=</span><span class="m">192</span>.168.1.200
<span class="nv">PREFIX</span><span class="o">=</span><span class="m">24</span>
<span class="nv">GATEWAY</span><span class="o">=</span><span class="m">192</span>.168.1.1
$
$<span class="w"> </span>cat<span class="w"> </span>/etc/sysconfig/network-scripts/ifcfg-eth0
<span class="nv">DEVICE</span><span class="o">=</span><span class="s2">"eth0"</span>
<span class="nv">BOOTPROTO</span><span class="o">=</span>none
<span class="nv">ONBOOT</span><span class="o">=</span>yes
<span class="nv">HWADDR</span><span class="o">=</span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="nv">MASTER</span><span class="o">=</span>bond0
<span class="nv">SLAVE</span><span class="o">=</span>yes
</pre></div>
<p>/etc/sysconfig/network-scripts/ifcfg-eth1 以降は、1行めと4行目が違うだけ。</p>
</div>
<div class="section" id="section-5">
<h4>ネットワーク再起動</h4>
<div class="highlight"><pre><span></span>$<span class="w"> </span>/etc/rc.d/network<span class="w"> </span>restart
</pre></div>
</div>
</div>
</div>
<div class="section" id="section-6">
<h2>結果</h2>
<div class="section" id="ifconfig">
<h3>ifconfig</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>ifconfig
bond0<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>MASTER<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:225061<span class="w"> </span>errors:0<span class="w"> </span>dropped:53618<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:83983<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:0
<span class="w"> </span>RX<span class="w"> </span>bytes:61269544<span class="w"> </span><span class="o">(</span><span class="m">61</span>.2<span class="w"> </span>MB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:16177865<span class="w"> </span><span class="o">(</span><span class="m">16</span>.1<span class="w"> </span>MB<span class="o">)</span>
br0<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>inet<span class="w"> </span>addr:192.168.1.100<span class="w"> </span>Bcast:192.168.1.255<span class="w"> </span>Mask:255.255.255.0
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:78075<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:61643<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:0
<span class="w"> </span>RX<span class="w"> </span>bytes:10268843<span class="w"> </span><span class="o">(</span><span class="m">10</span>.2<span class="w"> </span>MB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:10584226<span class="w"> </span><span class="o">(</span><span class="m">10</span>.5<span class="w"> </span>MB<span class="o">)</span>
eth0<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>SLAVE<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:162525<span class="w"> </span>errors:0<span class="w"> </span>dropped:228<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:79854<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:1000
<span class="w"> </span>RX<span class="w"> </span>bytes:45562722<span class="w"> </span><span class="o">(</span><span class="m">45</span>.5<span class="w"> </span>MB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:15420797<span class="w"> </span><span class="o">(</span><span class="m">15</span>.4<span class="w"> </span>MB<span class="o">)</span>
<span class="w"> </span>Interrupt:16<span class="w"> </span>Memory:fbde0000-fbe00000
eth1<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>PROMISC<span class="w"> </span>SLAVE<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:55268<span class="w"> </span>errors:0<span class="w"> </span>dropped:46114<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:4129<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:1000
<span class="w"> </span>RX<span class="w"> </span>bytes:15011606<span class="w"> </span><span class="o">(</span><span class="m">15</span>.0<span class="w"> </span>MB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:757068<span class="w"> </span><span class="o">(</span><span class="m">757</span>.0<span class="w"> </span>KB<span class="o">)</span>
<span class="w"> </span>Interrupt:17<span class="w"> </span>Memory:fbee0000-fbf00000
eth2<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>SLAVE<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:3636<span class="w"> </span>errors:0<span class="w"> </span>dropped:3640<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:0<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:1000
<span class="w"> </span>RX<span class="w"> </span>bytes:347749<span class="w"> </span><span class="o">(</span><span class="m">347</span>.7<span class="w"> </span>KB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:0<span class="w"> </span><span class="o">(</span><span class="m">0</span>.0<span class="w"> </span>B<span class="o">)</span>
<span class="w"> </span>Interrupt:18<span class="w"> </span>Memory:fbfe0000-fc000000
eth3<span class="w"> </span>Link<span class="w"> </span>encap:Ethernet<span class="w"> </span>HWaddr<span class="w"> </span><span class="m">00</span>:15:17:XX:YY:ZZ
<span class="w"> </span>UP<span class="w"> </span>BROADCAST<span class="w"> </span>RUNNING<span class="w"> </span>SLAVE<span class="w"> </span>MULTICAST<span class="w"> </span>MTU:1500<span class="w"> </span>Metric:1
<span class="w"> </span>RX<span class="w"> </span>packets:3632<span class="w"> </span>errors:0<span class="w"> </span>dropped:3636<span class="w"> </span>overruns:0<span class="w"> </span>frame:0
<span class="w"> </span>TX<span class="w"> </span>packets:0<span class="w"> </span>errors:0<span class="w"> </span>dropped:0<span class="w"> </span>overruns:0<span class="w"> </span>carrier:0
<span class="w"> </span>collisions:0<span class="w"> </span>txqueuelen:1000
<span class="w"> </span>RX<span class="w"> </span>bytes:347467<span class="w"> </span><span class="o">(</span><span class="m">347</span>.4<span class="w"> </span>KB<span class="o">)</span><span class="w"> </span>TX<span class="w"> </span>bytes:0<span class="w"> </span><span class="o">(</span><span class="m">0</span>.0<span class="w"> </span>B<span class="o">)</span>
<span class="w"> </span>Interrupt:19<span class="w"> </span>Memory:fbfa0000-fbfc0000
</pre></div>
</div>
<div class="section" id="ping">
<h3>ping 編</h3>
<ol class="arabic simple">
<li>適当なマシンから 192.168.1.100 に向けて ping を打つ</li>
<li>192.168.1.100 のマシンに繋がる LAN ケーブルを1本思い切って引っこ抜く</li>
<li>こいつ、 LAN ケーブル抜いても ping 返ってくるぞ……!!</li>
</ol>
</div>
</div>
<div class="section" id="section-7">
<h2>トラブルシューティング的な</h2>
<div class="section" id="ubuntu-12-04-lts-1">
<h3>Ubuntu 12.04 LTS 編</h3>
<div class="section" id="etc-network-interfaces">
<h4>/etc/network/interfaces の順番大切!!</h4>
<p>順番間違うと、ネットワーク再起動しても、 bonding インターフェースに ethernet port が attach しなくて使えなかったりする。
pre-up とか post-up とかのフックを設定してみたけれど、自分の場合うまく設定出来ず諦めたので、順番大切!!</p>
<p>下手すると、 bond0 がスレーブが立ち上がってくるのを待っていて、スレーブはマスターが立ち上がってくるのを待つような、デッドロック状態に陥る。</p>
</div>
<div class="section" id="section-8">
<h4>ネットワーク再起動時のデッドロック</h4>
<p>設定を変えた後、前述のマスターとスレーブが互いに待ち合うデッドロックに陥る場合がある。</p>
<p>そういう時は、手動でインターフェースを立ち上がらせてやる。
その時に、 ifup コマンドを使うと、設定を読みに行って結局デッドロックに陥るので、 ifconfig ethX up みたいな感じで、ただ単純にインターフェースを立ち上がらせると良い。</p>
</div>
</div>
</div>
<div class="section" id="section-9">
<h2>最後に</h2>
<p>トライアンドエラーとネット上の情報をかき集めてやってるので、用語とかが正しいのかよく分からない。
間違ってたら指摘して欲しい。
でも、なんとなく雰囲気は伝わると思う。</p>
</div>
<div class="section" id="section-10">
<h2>参考</h2>
<ul class="simple">
<li><a class="reference external" href="https://help.ubuntu.com/community/UbuntuBonding">UbuntuBonding - Community Help Wiki</a></li>
<li><a class="reference external" href="https://access.redhat.com/knowledge/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html">25.7.2. チャンネルボンディングの使用</a></li>
</ul>
</div>
Vyatta を導入した話2013-02-03T00:00:00+09:002013-02-03T00:00:00+09:00yosida95tag:yosida95.com,2013-02-03:/2013/02/03/081842.html<div class="section" id="l2">
<h2>L2 スイッチを買った</h2>
<p>今 …</p></div><div class="section" id="l2">
<h2>L2 スイッチを買った</h2>
<p>今まで使っていた L2 スイッチのポートをすべて使い切り、サーバーをこれ以上増やすことも、既存のサーバーに NIC をさすこともできなくなってしまったので、前から欲しいと思っていた NETGEAR の GS116v2 を買いました。
これで16ポート増やすことが出来ました。</p>
<p><a class="reference external" href="http://www.amazon.co.jp/dp/B002T0ISNU/">NETGEAR 【ライフタイム保証(無償永久保証)】ギガ16ポート アンマネージスイッチ GS116-200JPS</a></p>
</div>
<div class="section" id="section-1">
<h2>ネットワークの構成を変えたい</h2>
<p>これまで、サーバーと普段使う PC などの非サーバーマシンが同じネットワークにいました。
また、 WiFi ルーターもルーティング機能を切り、同じネットワークに居ました。</p>
<p>さすがにこれではセキュリティが気になる上、ファイアウォールの設定もサーバーや各マシンで個別に行っていたため面倒でした。
そこで、サーバーのネットワークと PC のネットワーク、そして WiFi のネットワークを分離して、ファイアウォールもそれぞれのルーターでまとめて行おうと前から思っていました。</p>
<p>L2 スイッチを導入したことをきっかけに、ここにも手を付けようと思いました。</p>
</div>
<div class="section" id="vyatta-1">
<h2>Vyatta</h2>
<p>サーバーのネットワークは ONU に繋がるルーター、 WiFi のネットワークは WiFi ルーターのルーティング機能を使えばよいですが、クライアント用のルーターはどうしようかと考えた時に、以前さくらの VPS に入れようとして失敗して以来触ってこなかった Vyatta を使う事が頭をよぎったので、これを使うことにしました。</p>
<p>早速、最新の Vyatta Core 6.5 を、 KVM を使った VPS である、よしだ VPS の対応 OS に加え、よしだ VPS で使えるようにしました。
よしだ VPS とは、 KVM の上で動くハンドメイド VPS です。
よしだ VPS について詳しくは、ぼくがよしだ VPS のアーキテクチャについて発表した PyCon JP 2012 の動画をご覧ください。</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/tOWZB9tFgu8" frameborder="0" allowfullscreen></iframe><p>余談ですが、ネットワークの分離を VLAN で L2 的にネットワークを切って、 L3 スイッチを使ってルーティングするとステキだと思ったのですが、 VLAN は甘えですし、 L3 スイッチは家庭ネットワークに導入するには価格的にハードルが高すぎます。。。</p>
</div>
<div class="section" id="section-2">
<h2>できた!</h2>
<p>あいだの手順をぶっ飛ばしていきなり完成です。
3分クッキングよりお手軽です。</p>
<p><img alt="network-graph" src="https://blogmedia.yosida95.com/2013/02/03/081842/network-graph.png" style="width: 100%;" />
※このネットワーク図は、 <a class="reference external" href="http://twitter.com/tk0miya">@tk0miya</a> さんが作っている <a class="reference external" href="http://blockdiag.com/ja/nwdiag/index.html">nwdiag</a> を使って作りました。</p>
<p>このようなネットワークを作りました。
ap, vyatta は NAT を切って、ローカルルータとして動かしています。</p>
</div>
<div class="section" id="section-3">
<h2>スループット</h2>
<p>ルーターを変えて気になることは、どれほどスループットがでるか、ということです。
Vyatta はソフトウェアルーター故、スループットがそれほど伸びないのでは無いか、という不安があります。
そこで、 ipref を使ってスループットの計測を行いました。</p>
<p>計測は kyoko と imac 間で、 Vyatta を挟まずにL2 で繋がっている状態と、 Vyatta を挟んだ(上のネットワーク図)場合の2つの場合で続けて7回行い、最大値と最小値の2回分を除いた値の相加平均を取りました。
有効桁数は3桁です。
以下の表には、この計測方法による結果と、参考までに最大値と最小値を掲載しました。</p>
<table border="1" class="docutils">
<colgroup>
<col width="27%" />
<col width="39%" />
<col width="34%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">種類</th>
<th class="head">Vyatta 不使用</th>
<th class="head">Vyatta 使用</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>測定結果</td>
<td>940Mbps</td>
<td>935Mbps</td>
</tr>
<tr><td>最大値</td>
<td>941Mbps</td>
<td>938Mbps</td>
</tr>
<tr><td>最小値</td>
<td>939Mbps</td>
<td>901Mbps</td>
</tr>
</tbody>
</table>
<p>Vyatta 不使用時の値については値にばらつきが無かったので、 Vyatta のホストマシンの NIC や L2 スイッチの物理的な性能限界な気がします。</p>
<p>Vyatta 使用時は、不使用時に比べて 5Mbps 程度スループットが落ちています。
これが仮想化やソフトウェア処理によるオーバーヘッドなのかなぁとおもいます。
物理マシンに Vyatta を入れるともう少しスループットが伸びるかもしれません。</p>
<p>余談ですが、Vyatta のVNIC のモデルを最初は e1000 に設定した状態でスループットを測定したところ、 420 Mbps 以上スループットが伸びませんでした。
この予想以上に低い測定結果に納得がいかず、まずは仮想マシンの性能不足を疑って、2コアだった vcpu を4コアにして、メモリも 1GiB から 2GiB にしてみたのですが、結果は変わりませんでした。
そもそも Vyatta 上で top を見ていても、 CPU 使用率は5%にも満たず、メモリはスッカスカでした。
そこで、 VNIC を virtio に設定して測定しなおしたところ上記のような結果がでました。
どうもこの 420Mbps という値は、 <a class="reference external" href="http://home.kendomo.net/diary.php/2009-09-30/1">e1000 の限界値らしい</a>です。</p>
<p>個人的には、この結果にはとても満足しています。
1000BASE-T のネットワークで、 1Gbps に近い値がでている事、ハードウェアの物理的限界値らしき値より 5Mbps 程度しか性能劣化が無いことに幸せ感があります。</p>
</div>
Vyatta のDNS Forwarding にハマった話2013-02-03T00:00:00+09:002013-02-03T00:00:00+09:00yosida95tag:yosida95.com,2013-02-03:/2013/02/03/093956.html<p><img alt="network-graph" src="https://blogmedia.yosida95.com/2013/02/03/081842/network-graph.png" style="width: 100%;" /></p>
<div class="section" id="dns-forwarding">
<h2>DNS Forwarding</h2>
<p>Vyatta には DNS Forwarging の機能 …</p></div><p><img alt="network-graph" src="https://blogmedia.yosida95.com/2013/02/03/081842/network-graph.png" style="width: 100%;" /></p>
<div class="section" id="dns-forwarding">
<h2>DNS Forwarding</h2>
<p>Vyatta には DNS Forwarging の機能があります。
これを使うと、 Vyatta に対して DNS リクエストを行うと、外部ネットワークの DNS を引いて、その結果を転送してくれます。</p>
<p>たとえば、上図のネットワークでは akari で DNS が動いているとして、 Vyatta でルーティングしている 192.168.2.0/24 で DNS Forwarding をon にすると、 imac から 192.168.2.1 に DNS リクエストをすると 192.168.1.10 に同じリクエストをした結果が返ってきます。</p>
<p>実際には、 Forwarding とは言ってもデフォルトでキャッシングが有効になっているので、一旦 Vyatta のキャッシュにレスポンスが貯められて、そのキャッシュから imac に対してレスポンスが返るようです(cash-size を0にすれば、言葉通りそのまま転送されてきます)。</p>
</div>
<div class="section" id="section-1">
<h2>127.0.1.1 が返ってくる</h2>
<p>DNS Forwarding をon にした状態で、 vyatta 自身のレコードを imac から引くと、なんと驚いたことに127.0.1.1 が返ってきます。
もちろん、akari のZone ファイルには vyatta が 192.168.3.1 で登録されています。
別のネットワークでレコードを引くと、ちゃんとこの値が返ってきます。</p>
<p>この問題には悩まされました。
vyatta にログインして <tt class="docutils literal">nslookup vyatta</tt> をすると 127.0.1.1 が返ってくるので、どうやらVyatta 内部のレコードが DNS Forwarding よりも優先されて返されているようです。</p>
</div>
<div class="section" id="section-2">
<h2>問題はタイミングだ</h2>
<p>色々調べてみると、 /etc/hosts にvyatta の値として 127.0.1.1 が設定されています。
どうやら、この値が返されているようです。
そこで、この行を削除してみたのですが、結果に変わりはありませんでした。</p>
<p>ここが原因では無いと判断して、 /etc/hosts の値をそのままに、Vyatta の DNS Forwarding の設定値をいじって commit して named が再起動してレコードを引いてみたら、今度はちゃんと期待する akari からのレスポンスが返ってきました。</p>
<p>この設定の変更が原因であると疑って、設定をもとに戻せば再現するかと思って設定を戻して commit してみたところ、それでも期待する akari からのレスポンスが返ってきました。</p>
<p>この結果から導かれた仮説は、 <strong>"named が起動するタイミングで /etc/hosts が読まれ、この結果が転送先の DNS のレコードよりも優先される"</strong> というものです。
そこで、 /etc/hosts を元に戻して、設定の変更をせずに named をリスタートした結果、再度 127.0.1.1 が返ってくるようになったので、この仮説が実証されました。</p>
</div>
<div class="section" id="etc-hosts">
<h2>リセットされる /etc/hosts</h2>
<p>通常運用ではルーターを再起動するような機会は滅多にないと思うのですが、その必要が生じたとします。
すると、 Vyatta は system host-name の値を見て /etc/hosts をリセットしてきます。
このリセットのタイミングは named の起動よりも先ですし、後だったとしても2回目の再起動で結局変更は元に戻ってしまいます。</p>
<p>解決策として以下の方法が考えられます</p>
<ol class="arabic simple">
<li>/etc/hosts を書き換えるシェルスクリプトを書いて、 Vyatta の機能を使って起動時に実行されるように設定する</li>
<li>Vyatta の system host-name に適当な値を設定して、 akari のレコードと被らないようにする</li>
<li>DNS Forwarding を使わない</li>
</ol>
<p>私が取った方法は3ですw最も楽な方法を取りました。
akari の named の設定とファイアウォールの設定を変えて、 192.168.2.0/24 からのクエリを許可したうえで、 DHCP を使ってネームサーバーとして 192.168.1.10 を配りました。</p>
</div>
mixslide というウェブサービス2013-01-03T00:00:00+09:002013-01-03T00:00:00+09:00yosida95tag:yosida95.com,2013-01-03:/2013/01/03/031344.html<div class="section" id="section-1">
<h2>こんばんは</h2>
<p>こんばんは …</p></div><div class="section" id="section-1">
<h2>こんばんは</h2>
<p>こんばんは</p>
<p>ジンギスカンキャラメル 、さくら石狩 DC 見学ツアーのおみやげで買ったので、人に配って歩くという厄介芸をしていたのですが、さすがに余りが目立つので自分で食べてみたところ、とても食べられたものじゃないですね!こんなに美味しくないものを久しぶりに食べました。</p>
</div>
<div class="section" id="mixslide-1">
<h2>mixslide</h2>
<p>今日、1月3日の0時0分ごろに <a class="reference external" href="http://mixslide.com/">mixslide</a> というウェブサービスをリリースしたので、お知らせします。</p>
</div>
<div class="section" id="mixslide-2">
<h2>mixslide ってなに</h2>
<p>みなさん、勉強会にはよく行きますか?
勉強会で行われた発表に使われたスライド、発表者それぞれが思い思いのサービスにアップロードしています。
スライドを公開してくれることはとても嬉しいのですが、複数の発表者がいる勉強会だと、あっちこっちにスライドが分散してしまって不便です。</p>
<p>そこで、 <a class="reference external" href="http://mixslide.com/">mixslide</a> です。</p>
<p>mixslide を使うと、あっちこっちに散らばってしまったスライドを1箇所に集めることができます。
それも、1ページに。</p>
<p>しかも、 mixslide の特徴として、ログインしているユーザーなら<strong>誰でもまとめを編集できる</strong>があります。
発表をされた方が、自分の分を追加していってまとめを作ることはもちろん、すでに作られているまとめに拾われなかったスライドに気づいたら自由に追加することができるのです。</p>
<p>だれもがまとめを編集できますが、"この時点でのまとめを見たい"、これも mixslide ならできます。
最初に作られた状態から、最新の状態、そこに来るまでの変遷も、すべて見ることができます。</p>
</div>
<div class="section" id="section-2">
<h2>ちょっとなにいってるか分からない</h2>
<p>試しに、ぼくが先日開催してきた勉強会、 "CombConf" のスライドまとめを見てみましょう。</p>
<p><a class="reference external" href="http://mixslide.com/2ddae07d-1048-43e3-b22a-4d9797d6bd5c">CombConf まとめ</a>。
ご覧のとおり、 CombConf で使われたスライドが1ページにまとめられています。</p>
<p><a class="reference external" href="http://mixslide.com/2ddae07d-1048-43e3-b22a-4d9797d6bd5c/changelog">CombConf まとめの編集履歴</a> を見ると、このまとめがどのように編集されてきたのかが手に取るようにわかります。</p>
<p><a class="reference external" href="http://mixslide.com/2ddae07d-1048-43e3-b22a-4d9797d6bd5c/changelog/1">CombConf まとめの最初の状態</a>。
こちらを見ると、現在4枚目に表示されているスライドが、最初の状態ではまとめに含められていなかったことが一目瞭然です。</p>
</div>
<div class="section" id="section-3">
<h2>だれが作ったの</h2>
<p>サーバーサイドはすべて、ぼくが作りました。
ページデザイン、マークアップは、 <a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> がすべてやりました。</p>
<p>したがって、 invalid な HTML についてのマサカリの投げ先は <a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> です。
サーバーサイドに関するものについてはぼくが甘んじてお受けします。</p>
</div>
<div class="section" id="section-4">
<h2>どうやって作ったの</h2>
<p>もともとは、夏に開催された「私立プログラミングキャンプ」というハッカソンイベントで、アイディアを思いつき開発を始めたことがきっかけでした。
しかし、イベント期間中にサービスをリリースすることができませんでした。
その場の勢いでドメインも取っていたので、どうせならリリースしたいと思いつつ開発をしない日々が4ヶ月くらい経って、いつの間にか年末になっていました。</p>
<p>せっかく年末年始は冬休みで時間があるからこれを使おう、ということで12月30日から開発に取り掛かりました。
年が明けると同時のリリースを目標にしていましたが、一つ前のエントリにある通り、ぼくが権威 DNS サーバーのアドレスを間違える、という大ポカをやらかしたので、デザイナーの <a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> の誕生日に併せてリリースしました。</p>
<ul class="simple">
<li>本日誕生日の、 <a class="reference external" href="http://amzn.to/oidong1">@oidong1 の wishlist</a></li>
<li>半年後に誕生日の、<a class="reference external" href="http://amzn.to/yosida95">ぼくの wishlist</a></li>
</ul>
</div>
<div class="section" id="section-5">
<h2>技術的なサムシング</h2>
<p>Web Application Framework には、例によって Python の Pyramid を採用しています。
DB には MongoDB 、 Message Queue には RabbitMQ 、非同期処理には Celery を使っています。</p>
<p>また、例によって、サーバーはぼくの自室にある、 akari と名付けられたサーバーです。</p>
</div>
<div class="section" id="section-6">
<h2>応援メッセージ・不具合報告</h2>
<p>基本的には、 Twitter で <a class="reference external" href="https://twitter.com/yosida95">@yosida95</a> までお願いします。
Twitter アカウントをお持ちでないなら、<a class="reference external" href="https://yosida95.com/">yosida95 の連絡先一覧</a>のうち、どれかご都合のよい物にお願いします。</p>
<ul class="simple">
<li>半年後に誕生日の、<a class="reference external" href="http://amzn.to/yosida95">ぼくの wishlist</a></li>
<li>本日誕生日の、 <a class="reference external" href="http://amzn.to/oidong1">@oidong1 の wishlist</a></li>
</ul>
</div>
<div class="section" id="section-7">
<h2>よろしくおねがいします</h2>
<p>よろしくお願いします。
はてブとかしておくと、いざというときに便利かもしれません(圧力)。</p>
</div>
2012 年にぼくがさせていただいたこと2013-01-01T00:00:00+09:002013-01-01T00:00:00+09:00yosida95tag:yosida95.com,2013-01-01:/2013/01/01/005050.html<div class="section" id="section-2">
<h2>こんばんは</h2>
<p>こんばんは …</p></div><div class="section" id="section-2">
<h2>こんばんは</h2>
<p>こんばんは。</p>
<p>年内リリースを目指していたサービスのリリースが、権威 DNS のアドレスを間違える、というぼくのミスにより延期になって余裕が出たので、このような記事を書いています。</p>
<p>あと15分で2013年ですね。
一昨日から昨日にかけて <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> と <a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> と一緒にぼくの家で徹夜ハッカソンしていたり、今日も1日中コード書いていたりで、全然大晦日感がしないです。
12月32日が始まりそうな予感。</p>
</div>
<div class="section" id="section-3">
<h2>勉強会での発表</h2>
<p>今年は、積極的に LT やセッションをさせて頂きました。</p>
<div class="section" id="section-4">
<h3>セッション</h3>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="5%" />
<col width="75%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">勉強会</th>
<th class="head">日付</th>
<th class="head">タイトル(スライドへのリンク)</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>PyConJP 2012</td>
<td>9月15日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/2012-dot-09-dot-15-pycon-jp-2012-%5Bnaudeyanguna17sui-falsevps-gou-zhu-ji-%5D">ナウでヤングな17歳の VPS 構築記</a></td>
</tr>
<tr><td>プログラミング生放送勉強会第19回@品川</td>
<td>12月22日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/purosheng-mian-qiang-hui-di-19hui-at-pin-chuan">libvirt で作るプライベート VPS</a></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="lt">
<h3>LT</h3>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="6%" />
<col width="74%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">勉強会</th>
<th class="head">日付</th>
<th class="head">タイトル(スライドへのリンク)</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>プログラミング生放送勉強会14@品川</td>
<td>4月7日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/14">Python meets MongoDB</a></td>
</tr>
<tr><td>私立プログラミングキャンプ</td>
<td>8月11日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/number-upcamp">鋭意製作中</a></td>
</tr>
<tr><td>私立プログラミングキャンプ</td>
<td>8月12日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/number-upcamp-1">僕らの#upcamp</a> (slideshow by <a class="reference external" href="http://twitter.com/oidong1">@oidong1</a>)</td>
</tr>
<tr><td>さくら石狩 DC 見学ツアー</td>
<td>11月27日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/2012-dot-11-dot-27-number-shi-shou-dctua">ナウでヤングな17歳の VPS 構築記 (LT size)</a></td>
</tr>
<tr><td>CombConf</td>
<td>12月23日</td>
<td><a class="reference external" href="https://speakerdeck.com/yosida95/2012-dot-12-dot-23-combconf">コミュニティ参加のススメ</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="section-5">
<h2>イベントの運営</h2>
<div class="section" id="pycon-jp-2012">
<h3>PyCon JP 2012</h3>
<p>今年の1月くらいに、 PyCon Organizers JP というコミュニティに加わって、およそ9ヶ月がかりで PyCon JP 2012 の運営に関わって来ました。</p>
<p>Pythonista として、国内最大の Pythonista の祭典の運営に関われたこと、そして、去年は一参加者でしか無かったイベントに、運営側として関われたことがとても嬉しかったです。</p>
</div>
<div class="section" id="combconf">
<h3>CombConf</h3>
<p>CombConf という、"中高生の、中高生による、中高生のためのカンファレンス"を開催しました。</p>
<p>この件については、先日の<a class="reference external" href="https://yosida95.com/2012/12/25/064109.html">CombConf という IT カンファレンスを開催してきました #combconf</a>というエントリに詳しいです。</p>
<p>リーダー(的立ち位置)として、1つのイベントを1から作り上げる、ということはぼくにとってとても大きい経験でした。</p>
</div>
</div>
<div class="section" id="dc">
<h2>さくら石狩 DC 見学ツアーに参加</h2>
<p>11月27日から28日に、抽選に当たって、さくら石狩 DC 見学ツアーに参加してきました。
自宅に VPS を持つ勢として、サーバーやルーターのアクセスランプに心踊らせる勢として、とても楽しかったです。</p>
<p>また、これをきっかけに、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> となんかよく分からん友情が芽生えたのが大きな収穫でした。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E7%9F%B3%E7%8B%A9DC%E3%83%84%E3%82%A2%E3%83%BC?src=hash">#石狩DCツアー</a> でよしだとよくわからん友情が芽生えた気がしている</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/270884243926810624">November 20, 2012</a></blockquote></div>
<div class="section" id="section-6">
<h2>アルバイト</h2>
<p>今年、会社に所属してプログラムを書く、という初体験を済ませました。
今まで、"中学生プログラマー"だの、"元中学生プログラマー"だの、"アマグラマー"だの名乗ったり、そう呼ばれたりしていましたが、これで自他共に"プログラマー"として認識されたのでは無いかと思います。</p>
<p>なお、最近は、"アフタースクールプログラマー"を名乗っています。</p>
<div class="section" id="decoo">
<h3>株式会社 Decoo</h3>
<p>8月の1ヶ月間だけでしたが、株式会社 Decoo というところでアルバイトをしてきました。
きっかけは、このブログを見た株式会社 Decoo の CTO からメールが届いたことでした。</p>
<p><a class="reference external" href="https://yosida95.com/2012/09/03/211203.html">株式会社 Decoo に就職して、そして退職しました</a>に詳しいです。</p>
</div>
<div class="section" id="section-7">
<h3>株式会社ゼロスタート</h3>
<p>10月から、現在に至るまで株式会社ゼロスタートでアルバイトをしています。
きっかけは、 Twitter で「@各社 雇ってください」的なふわっとしたツイートをしたところ、株式会社ゼロスタートの社員の方に声を掛けて頂いたことでした。</p>
<p><a class="reference external" href="https://yosida95.com/2012/10/13/222109.html">株式会社ゼロスタートに入社しました!</a>に詳しいです。</p>
</div>
</div>
<div class="section" id="section-8">
<h2>高校辞めたくなった</h2>
<p>高校入学後1ヶ月目くらいから高校辞めたい感をずっと感じてきていましたが、その気持ちが、今年の6月頃に爆発しました。
それで、親も巻き込んで、担任・副担任・母親・ぼくの4者で面談をしたり、 Twitter でさんざん呟いたり、ブログエントリ(参考: <a class="reference external" href="https://yosida95.com/2012/05/15/082821.html">No Title (近況報告)</a>)を書いたりして、勉強会でお会いした方からアドバイスを貰ったりもしました。</p>
<p>7月頃を振り返ると、完全にうつ病の一歩手前で、母にとても心配を掛けてしまったことを覚えています。
わずか1年ちょっとのために将来の数十年を失う事がないように、よく考えた結果として、休学なり、退学なりをするならそれでよいという話をされました。</p>
<p>現在もなお、辞めたいという気持ちを払拭できてはいませんが、やりたいことを実現するための行動が、その先のやりたいことの大きな障壁になる、という本末転倒な事態に陥らないように、と自分に言い聞かせて、なんとか通い続けています。</p>
<p>友人などからも、「最近、ちゃんと学校通ってるの?」とか、「お前からは、学校の匂いがしない(意訳)」とか、いろいろ言われますが、通っていることは通っています。</p>
<p>なお、余談ですが、最近の愛読書は校則になっています。
何日、何コマの欠席、何回の遅刻が許されるか、などに詳しいです。</p>
</div>
<div class="section" id="section-9">
<h2>年明けてました</h2>
<p>いつの間にか年明けてしまっていました。
おめでとうございます。
2013年も、よろしくお願いします。</p>
</div>
PQI Air Card が届いた2012-12-29T00:00:00+09:002012-12-29T00:00:00+09:00yosida95tag:yosida95.com,2012-12-29:/2012/12/29/030934.html<p>女の子と2人でとしまえんに遊びに行ってきた yosida95 です。
なん …</p><p>女の子と2人でとしまえんに遊びに行ってきた yosida95 です。
なんか、楽しかった反動で寝られそうにないので、ブログでも書きます。</p>
<p>さて、先日 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> から Amazon wishlist 経由で、 PQI Air Card と、 SD カードライターがセットで届きました。
なんでも、 <a class="reference external" href="https://yosida95.com/2012/12/25/064109.html">CombConf</a> 開催にあたり、ぼくが立て替えていた分をこれで返すそうです。
年末一杯遊べるおもちゃを与えてくれてありがとうございます!!</p>
<div class="section" id="pqi-air-card-1">
<h2>PQI Air Card とは</h2>
<p>Micro SD カードを SD カードとして使うためのアダプタです。
ただ、それだけではなくて、このアダプタには WiFi モジュールが組み込まれています。
本来は、写真や動画を WiFi で共有するための機能なのですが、中で Linux が動いていて、 telnet で接続できたり FTP や HTTP が使えたりできるので、 Geek のおもちゃになっています。</p>
<p>詳しくはググってください。
Let's google it!</p>
</div>
<div class="section" id="pqi-air-card-2">
<h2>PQI Air Card の準備</h2>
<p>PQI Air Card には 32GB の Micro SD カードが付属するので、これを PQI Air Card に挿入します。
自分で用意した Micro SD カードでも使えます。
これが PQI Air Card と他の類似品との大きな違いです。
次に、 Micro SD カードを挿入した PQI Air Card をそのへんに転がってるデジカメや SD カードライターに挿入します。</p>
</div>
<div class="section" id="pqi-air-card-3">
<h2>PQI Air Card に接続する</h2>
<p>PQI Air Card をデジカメや SD カードライターにセットしてから25秒くらい(マニュアル値)待つと、そのなも "PQI Air card" というアクセスポイントが立ちます。
これに、適当なマシンで接続してやります。
すると、 192.168.1.50-52 あたりの IP アドレスが降ってきます。</p>
</div>
<div class="section" id="telnet">
<h2>telnet で接続する</h2>
<p>まずは、昔なつかしの telnet で接続してやります。
telnet コマンド自体は、さくっと書いた HTTP サーバーのデバッグとかでまだご健在ですね。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>telnet<span class="w"> </span><span class="m">192</span>.168.1.1
</pre></div>
<p>これでサクッと root として接続できます。
デフォルトで telnetd が動いている辺り怖いですね。</p>
</div>
<div class="section" id="busybox">
<h2>BusyBox を強化する</h2>
<p>PQI Air Card の中で動くコマンドは BusyBox によって提供されています。
BusyBox とはご存じなければググってください。
PQI Air Card では、ストレージの容量を節約するために最低限のコマンドしか使えないようになっています。
これだと窮屈すぎるので BusyBox を強化します。</p>
<p><a class="reference external" href="http://ameblo.jp/tonsuke-usagi/entry-11212317428.html">FlucardでプログラムとかCGIとか|とんすけぶろぐ</a> このページにある <tt class="docutils literal">deploy\_20120420.zip</tt> を使います。
この中には、 PQI Air Card で使えるようにコンパイルされた BusyBox が入っています。
落としてきた ZIP を展開して中に入っている <tt class="docutils literal">deploy\_20120420/DCIM/122\_TREK</tt> を PQI Air Card で使う Micro SD カードの DCIM ディレクトリにコピーします。
PQI Air Card では SD カードは <tt class="docutils literal">/mnt/sd</tt> にマウントされているので、 <tt class="docutils literal">/mnt/sd/DCIM/122\_TREK/busybox</tt> を vi や top として、 <tt class="docutils literal">/bin</tt> にシンボリックリンクを張ります。</p>
<p>また、この <tt class="docutils literal">deploy\_20120420</tt> には BusyBox の他にも各種コマンドを PQI Air Card で使えるようにコンパイルされたものも入っているので、これも利用します。
<tt class="docutils literal">/mnt/sd/DCIM/122\_TREK</tt> 以下の <tt class="docutils literal">bin</tt> や <tt class="docutils literal">usr/bin</tt> なんかのシンボリックリンクを <tt class="docutils literal">/</tt> 以下に張ります。</p>
<p>併せて PQI Air Card に最初から含まれていて <tt class="docutils literal">deploy\_20120420</tt> にも含まれているは、後者のものを使うために最初からあるものを削除します。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/vi
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/top
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/awk
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/dd
$<span class="w"> </span>rm<span class="w"> </span>/usr/bin/hexdump
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/hexdump
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/killall
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/less
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/passwd
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/sed
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/tar
$<span class="w"> </span>rm<span class="w"> </span>/usr/bin/telnet
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/telnet
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/busybox<span class="w"> </span>/bin/whoami
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/bin/*<span class="w"> </span>/bin/
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/sbin/*<span class="w"> </span>/sbin/
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/lib/*<span class="w"> </span>/lib/
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/etc/*<span class="w"> </span>/etc/
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/usr/bin/*<span class="w"> </span>/usr/bin/
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/usr/lib<span class="w"> </span>/usr/lib
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/usr/include<span class="w"> </span>/usr/include
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/usr/libexec<span class="w"> </span>/usr/libexec
$<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span>/mnt/sd/DCIM/122_TREK/usr/local<span class="w"> </span>/usr/local
</pre></div>
<p>なぜコピーで無いかというと、 PQI Air Card のメモリが限られているためです。
なので、 Micro SD カードに実体を置いて、こっちにはシンボリックリンクを張っておきます。</p>
</div>
<div class="section" id="autorun-sh">
<h2>autorun.sh を書く</h2>
<p>"BusyBox を強化する" の項でシンボリックリンクを張って BusyBox が使えるようになりましたが、一度 PQI Air Card への通電を切ると作業前の状態に戻っているとおもいます。
これは PQI Air Card はストレージにある OS のイメージをすべてメモリに乗っけて、オンメモリで動作するためです。
まー、 SmartOS みたいなもんですね。</p>
<p>なので、起動するたびに上記のようなコマンドを打ってやらないといけないのですが、さすがにこれは骨です。
そこで、 <tt class="docutils literal">autorun.sh</tt> を使います。
<tt class="docutils literal">autorun.sh</tt> は、 PQI Air Card がイニシャライズするときに呼ばれるシェルスクリプトです。
このシェルスクリプトに上記のようなコマンドを列挙してやることで自動化できます。</p>
<p><tt class="docutils literal">autorun.sh</tt> を置く場所は、 Micro SD カードのルート、つまり <tt class="docutils literal">/mnt/sd/autorun.sh</tt> です。</p>
</div>
<div class="section" id="section-1">
<h2>おまけ</h2>
<div class="section" id="ssh">
<h3>公開鍵認証で SSH を使う</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>dropbear<span class="w"> </span>-A<span class="w"> </span>-N<span class="w"> </span>root<span class="w"> </span>-C<span class="w"> </span><span class="s1">'-'</span><span class="w"> </span>-U<span class="w"> </span><span class="m">0</span><span class="w"> </span>-G<span class="w"> </span><span class="m">0</span><span class="w"> </span>-R<span class="w"> </span><span class="o">[</span>authorized_keys<span class="w"> </span>へのパス<span class="o">]</span><span class="w"> </span>-s
</pre></div>
</div>
<div class="section" id="telnet-1">
<h3>telnet で接続できなくする</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>killall<span class="w"> </span>telnetd
</pre></div>
</div>
<div class="section" id="ftp">
<h3>FTP で接続できなくする</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>killall<span class="w"> </span>tcpsvd
</pre></div>
</div>
</div>
<div class="section" id="section-2">
<h2>参考ページ</h2>
<p><a class="reference external" href="http://hitoriblog.com/?p=12627">ひとりぶろぐ » デジカメ内部でRubyを動かす狂気!無線LAN内蔵SDカードアダプタPQI Air Cardの間違った使い方</a> - 大いに参考にさせていただきました。</p>
</div>
CombConf という IT カンファレンスを開催してきました #combconf2012-12-25T00:00:00+09:002012-12-25T00:00:00+09:00yosida95tag:yosida95.com,2012-12-25:/2012/12/25/064109.html<p>あけましておめでとう …</p><p>あけましておめでとうございまs……メリー・クリスマス!!24日中はほぼ一日中寝ていました。</p>
<p>去る12月23日、 CombConf という IT カンファレンスを開催してきたのでご報告します。</p>
<div class="section" id="combconf">
<h2>CombConf ってなに</h2>
<p>中学生・高校生を対象にした IT カンファレンスです。
運営スタッフも全員高校2年生なので、"中高生の、中高生による、中高生のための IT カンファレンス"といった感じです。</p>
<p>詳しくは、 <a class="reference external" href="http://combconf.com/">CombConf 公式サイト</a>や、ぼくが書いて <a class="reference external" href="http://gihyo.jp/news/info/2012/11/2701">gihyo に掲載していただいた告知記事</a> をご覧ください。</p>
</div>
<div class="section" id="section-1">
<h2>スタッフになったきっかけ</h2>
<p>ぼくが通う学校の文化祭の終了後ふらーっとカフェ(ルノアール)によったところ、チーフの <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> とエバンジェリストの <a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> がミーティングをしていて、それに対していろいろと口を出していたらいつの間にかスタッフになっていました。
その日のうちに combconf.com ドメインのメールアドレスが発行され、”わくわくエンジニア"という肩書きが決まりました。
それが10月14日のことです。
開催のおよそ2ヶ月前ですね。</p>
<p>ちなみにわくわくエンジニアの由来ですが、ぼくが"わくわく"という言葉が好きなこと、某出会い系サービス"ワクワク○ール"の広報が激アツだと感じていて、そのことを常々口癖の様に言っていたことから決まりました[要出典]。</p>
</div>
<div class="section" id="combconf-1">
<h2>ぼくが CombConf でやったこと</h2>
<p>ぼくが CombConf にジョインした時点では、会場は確定していないし、公式サイトも作られていませんでした。
メンバーの「あれをやりたい」「これをやりたい」「実現したい」という気持ちは強くてもそのための具体的方策が挙げられないようなので、やりたいことを吸い上げて、その方法を考えだして、タスクを全員に振り分ける層を担当していました。
ここには、 PyCon JP 2012 でスタッフをやっていた経験が活かせました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">好き放題言われたことを、実現させる方法を考えて、そのためのタスクを割り振る役回り的な何か。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/282113170175299586">December 21, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> そして実行効率の悪いワーカーの尻を叩き続ける</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/282114076602155008">December 21, 2012</a></blockquote><p>こういうこと作業をやっていたところ、 CombConf 運営チームには最も遅くにジョインしたくせに、いつの間にかリーダー的立ち位置になっていたようです。</p>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/KOBA789">@KOBA789</a> <a href="https://twitter.com/yosida95">@yosida95</a> 正しい</p>— おいどん (@oidong1) <a href="https://twitter.com/oidong1/status/281267819792965633">December 19, 2012</a></blockquote><div class="section" id="section-2">
<h3>個々の作業</h3>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">CombConf で俺がした仕事: メンバーのタスク管理, タスク管理システム製作, 一般参加枠募集, gihyo 広報記事執筆, 懇親会開催決定, 懇親会参加者募集, あとなんか色々やったけど忘れた。全体を通して、進まないことを前にすすめる役もやってた。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/282110862930616320">December 21, 2012</a></blockquote><p>ざっとこんなかんじです。
あとはタイムテーブル作ったりもしました。</p>
<p>ぼくがやった作業の中から3つを挙げると、タスク管理と懇親会の開催、そして広報です。</p>
<div class="section" id="section-3">
<h4>タスク管理</h4>
<p>前述のとおりな役割に居たので、タスク管理をすることは必然でした。
先日書いた<a class="reference external" href="https://yosida95.com/2012/12/02/100735.html">CombConf を支える技術 〜タスクリマインダー〜</a>もその一環です。
どんなタスクが必要で、それをいつまでにやる必要があるのか、というものを挙げていってその進捗を管理していました。</p>
</div>
<div class="section" id="section-4">
<h4>懇親会の開催</h4>
<p>懇親会は個人的にどうしてもやりたかったことなので、 CombConf 開催1週間前という慌ただしい時期でしたが、開催を決めて募集を始めました。</p>
<p>CombConf が中学生・高校生の部活が主体であることに対して、懇親会は個人色を強めようと思いました。
なので、懇親会で行った LT 大会の参加を無条件にしました。
できたら、コンピューターに関することを仕事にしてる人のお話とかも聞けたらよいなーって思っていました。</p>
<p>懇親会参加費を中学生以下は無料で中学生以外も500円という、懇親会で提供したピザや飲み物の実費すら大きく下回る設定にしたのは、とにかく誰にでも気軽に参加して欲しかったからです。</p>
<p>今でこそバイトをしていて収入があるぼくですが、その中学生時代を思い出すと、気軽に500円出せたかは怪しいです。
また、高校生でも今回集まって頂いた層だとバイトをしている人は少ないと思うので、1000円とかをいきなり出すのは厳しいかなーと思います。</p>
<p>せっかく、未知との交流が懇親会にはあるのに、それを参加費を理由に諦めてもらいたくなかったです。
ぼくは高校1年生の時に、プログラマーたちのコミュニティの懇親会に初参加したのですが、そこはとても刺激的な場でした。
参加してくれた中学生・高校生にもこのような場が存在することを知ってもらい、そして CombConf 以外の別のコミュニティに参加するきっかけになってくれれば、という思いがありました。</p>
<p>懇親会では(正確な計算は体調が悪くなりそうなのでしていませんが)2万円を超える赤字がありました。
しかし、スタッフを含め52名の参加があり、うち10名ほどは中学生でした。
この数はぼくの意図からすれば大成功でした。</p>
<p>ただ、心残りだったのは、 CombConf 本体が食い込んできたために、懇親会の時間を1時間ほどしか取れなかったことです。
せっかく LT に参加したくても時間の問題で参加できない方も数名いらっしゃいました。</p>
</div>
<div class="section" id="section-5">
<h4>広報</h4>
<p>広報といっていいのかはわかりませんが、前出の gihyo.jp の記事を書いたり、 <a class="reference external" href="https://www.facebook.com/CombConf">CombConf の Facebook ページ</a> を更新したり、ということをしていました。
広報と言うよりはライター的な立場だったかもしれません。
一般参加者の皆さんに送った懇親会のお知らせと前日案内のメッセージ、部活参加枠の方に送った前日案内メールは私の仕業でしたね。</p>
<p>また、開催1ヶ月くらい前に都内の中学校・高校にお送りした CombConf 開催案内も、文面・封筒印刷・封入・切手張りを含めて私の仕業でした。
文面の校正や3つ折り、送り先調べは他のメンバーも手伝ってくれました。
私を含めスタッフの3人が私の部屋に集まってわいわい作業をしていたので、この作業が事前準備の中では最も楽しかった気がします。
夜を徹した最も辛い作業でもありましたが。</p>
</div>
</div>
</div>
<div class="section" id="combconf-3">
<h2>CombConf 当日</h2>
<div class="section" id="combconf-4">
<h3>CombConf スタッフとして</h3>
<p>CombConf 開場後から開始までは受付をやっていました。
受付をやっていたところ、 <a class="reference external" href="http://twitter.com/nash_fs">@nash_fs</a> さんと <a class="reference external" href="http://twitter.com/wasao">@wasao</a> さんから ORANGINA の差し入れをいただきました!
ありがとうございました!!</p>
<p>それから、オープニングセレモニーとクロージングセレモニーでは、司会兼ご案内係をやっていました。</p>
<p>また、 <a class="reference external" href="https://twitter.com/oidong1">@oidong1</a> と一緒に、懇親会用の飲み物やお菓子を買い出しに行ったりもしました。</p>
<p>全体的に振り返ると、やたらと騒がしい落ち着きのないお兄さん、といった感じでしょうか。</p>
</div>
<div class="section" id="section-6">
<h3>発表者として</h3>
<p>CombConf では一般参加枠参加者として LT もしてきました。
本当は Talk 枠で10分がっつり喋りたかったのですが、何を隠そう CombConf 主催側なのに部活に参加していない人間なので、残念ながら LT しか出来ませんでした。</p>
<p>LT では当然技術の話をしても良かったし、楽しんでもらえるような話も出来たのですが、きっと技術の話は他の発表者の話としてお腹いっぱいだと思ったこと、そして懇親会の項でも述べたような、交流の場に参加して欲しい、という思いを伝えたかったことから、趣向を変えて「コミュニティ参加のススメ」というタイトルで LT をしました。</p>
<p>こちらが発表資料です。</p>
<script async class="speakerdeck-embed" data-id="0b9805302f410130f88012313d03008e" data-ratio="1.2994923857868" src="//speakerdeck.com/assets/embed.js"></script></div>
</div>
<div class="section" id="section-7">
<h2>次回開催について</h2>
<p>CombConf は個別には小さなトラブルもありましたが、全体を見ると大成功に終わったと個人的には思っています。</p>
<p>第2回開催を期待する声が聞こえてくるのですが、運営チーム全体の認識として、残念ながら難しいと思っています。
というのも、運営チームのメンバーは全員高校2年生で、進路のことを考えなければいけません。
そのため、今回のように CombConf 運営にコミットすることが難しいからです。</p>
<p>2年後の開催は可能かもしれませんが、その頃にぼくらは大学生ないし社会人になっています。
すると、"中高生の、中高生による、中高生のための IT カンファレンス"では無くなってしまいます。</p>
<p>そこで誰かに運営を引き継ぐことを考えるのですが、ぼくらでないと今回のような CombConf は開催できないという自負があるので、引き継いだ後同じクオリティ、またはこれ以上のクオリティで開催するのは無理なのではと思っています。
この点については、参加者の大学生の方からも「第1回がレジェンドになっているからねー」という同意ももらっています。</p>
<p>ただ、可能性を残しておくと来年の今頃の時期にメンバーの進路が確定していれば事実上は可能になるし、運営メンバーで行った打ち上げの中では「4月ごろになれば勉強に飽きて CombConf やりたくなるのでは」という話もありました。
とか言うと、チーフの <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> に怒られるので、やっぱり無いです。
無いです。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/combconf?src=hash">#combconf</a> 、マジで次回は考えてない。考えてない。考えてないよ! 考えてないったら考えてないんだからね!</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/282738001065439232">December 23, 2012</a></blockquote><p>最後に、 CombConf にご参加頂いた皆様、本当にありがとうございました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">CombConf 来てない人損してるというよりは、来てる人めっちゃ得してる <a href="https://twitter.com/hashtag/combconf?src=hash">#combconf</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/282740132300345344">December 23, 2012</a></blockquote></div>
田町アドベントカレンダー16日目 #tamachi2012-12-17T00:00:00+09:002012-12-17T00:00:00+09:00yosida95tag:yosida95.com,2012-12-17:/2012/12/17/002958.html<div class="section" id="section-1">
<h2>こんばんは</h2>
<p>こんばんは …</p></div><div class="section" id="section-1">
<h2>こんばんは</h2>
<p>こんばんは</p>
</div>
<div class="section" id="section-2">
<h2>アドベントカレンダーの季節ですね</h2>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">12/8とかいう微妙な日付を指定することにより<a href="https://twitter.com/mactkg">@mactkg</a>が途中で投げ出しにくくなるライフハック</p>— JA1TYE/Ryota Suzuki (@JA1TYE) <a href="https://twitter.com/JA1TYE/status/274886292452544512">December 1, 2012</a></blockquote><p>このつぶやきの趣旨に賛同して、16日の担当を申し出たがためにこんな時間にブログ記事を書いています。</p>
<p>このつぶやきにある目的を達成できたらよかったのですが、アドベントカレンダー参加時に「いつでもよいです」とコメントした人をぼくの前に持ってくるとかいう姑息な手段により、主催の <a class="reference external" href="https://twitter.com/mactkg">@mactkg</a> さんが楽をしているためこの目標は達成できませんでした。</p>
</div>
<div class="section" id="section-3">
<h2>田町ってなに</h2>
<p>港区芝浦にある山手線・京浜東北根岸線の駅名です。
地名です。
2年前までは縁もゆかりもない地域だったのですが、うっかりよくわからない工業高校に合格してしまったがために1日の大半の時間を田町で過ごすはめになっています。</p>
</div>
<div class="section" id="section-4">
<h2>なにを書こうか</h2>
<p><a class="reference external" href="https://twitter.com/mactkg">@mactkg</a> さんを始めとする他の参加者さんの記事をざーっと眺める限り、田町に関することならなんでもオッケーな感じがあるので余計ネタ選択が難しくなっていますね。</p>
<p>散々悩んだ挙句、田町駅周辺の私自身がよく利用するカフェ2軒を紹介することにします。</p>
</div>
<div class="section" id="section-5">
<h2>エクセルシオール カフェ 田町東口店</h2>
<p>なんてことは無い、そのへんにありふれたエクセルシオールです。
早く学校につく過ぎた時とか、中途半端な時間を潰したい時とかにさっと入ってさっと出てこれる感じなので重宝します。</p>
<p>場所は田町駅芝浦口を降りて、学校の正門を通り過ぎてそのまま真っすぐ行って、初めてぶつかる横断歩道を渡った場所にあります。
田町駅芝浦口の階段の上から見える位置で、学校からとても近い位置にあります。
そのため、学校からでてすぐにいけたりすぐに学校に戻れたりします。</p>
<p>なにか作業をするには向きませんが、落ち着いてコーヒーを飲んで時間を潰すときにはとても便利です。</p>
</div>
<div class="section" id="section-6">
<h2>ルノアール田町三田口駅前店</h2>
<p>なんてことは無い、普通のルノアールです。
そのへんにありふれていて、秋葉原にも3店舗くらいあるルノアールです。</p>
<p>こちらのカフェは、これはルノアール全般に言えることなのですが、落ち着いて作業をすることができます。
学校が終わったものの授業中や帰りのホームルーム中に書きかけになってしまったコードがあり、帰宅する時間が勿体無くてすぐさま作業の続きにとりかかりたい時などに学校から歩いてすぐの距離にあるのでとても重宝します。</p>
<p>なぜコードを書きたい時に重宝するのか、それはこちらのルノアールは申し出ると電源を貸してくれるからです。
つまり、電源が提供される上、ルノアールの、あのふかふかとした椅子を使って作業をすることができるのです。
また、ルノアールのサービスである、無限緑茶・無限お冷ももちろん提供されるので、ついつい3時間4時間居座ってしまうこともあります。
この居座りを許してくれる雰囲気があることも、ルノアールの素敵ポイントです。</p>
<p>ただ、一点、注意としては、こちらのルノアールは他店舗に比べて分煙がしっかりしていません。
電源を貸してくれる席は禁煙席だけなのですが、その禁煙席に喫煙席の煙が流れこんで来ています。
30分程度いただけで服がとてもタバコ臭くなってしまう程度の酷さです。
そのため、こちらのルノアールで作業をした後学校に戻ると喫煙疑惑をかけられる可能性も十分にあるのでお気をつけ下さい。</p>
<p>場所は駅ビルの中の1テナントで、サイゼリアやマクドナルドがある側の階段のほぼ真下にあります。</p>
</div>
<div class="section" id="section-7">
<h2>以上です</h2>
<p>お付き合い頂きありがとうございました!
素敵なカフェで Let's Happy Hacking !!!</p>
</div>
CombConf を支える技術 〜タスクリマインダー〜2012-12-02T00:00:00+09:002012-12-02T00:00:00+09:00yosida95tag:yosida95.com,2012-12-02:/2012/12/02/100735.html<div class="section" id="section-1">
<h2>こんにちは</h2>
<p>こんにちは …</p></div><div class="section" id="section-1">
<h2>こんにちは</h2>
<p>こんにちは!</p>
</div>
<div class="section" id="combconf-1">
<h2>CombConf</h2>
<p>ご存知の方も多いと思いますが、今ぼくは12月23日に開催する中学生・高校生向けのカンファレンス、 CombConf の運営をやっています。
CombConf での肩書きはわくわくエンジニアです!
わくわくしてます!</p>
<p>CombConf ってなによって方は、 <a class="reference external" href="http://combconf.com/">CombConf 公式サイト</a> や、 <a class="reference external" href="http://gihyo.jp/news/info/2012/11/2701">gihyo.jp の CombConf 紹介記事</a> をご覧ください!</p>
<p>中学生・高校生では無い方の参加も一般参加枠にてお待ちしています!
<a class="reference external" href="http://connpass.com/event/1205/">CombConf 一般参加枠参加登録フォーム</a>よりどしどし参加登録してください!</p>
</div>
<div class="section" id="google-apps-script">
<h2>Google Apps Script</h2>
<p>ふと思い立って Google Apps Script で遊びたくなったので遊んでみました。
Google Apps Script とは、 Google Spreadsheet なんかを JavaScript で操作できるイカした奴です。
Google Apps Script についての詳しい説明は面倒ですし、ぼくもいじりはじめてから5時間くらいしか経ってなくてよく知らないので、 <a class="reference external" href="https://developers.google.com/apps-script/">Google Apps Script - Google Developers</a> とか読んでください。</p>
<p>Google Apps Script はこいつ単体で Cron とかメールの送信とかできちゃうデキる子です。</p>
</div>
<div class="section" id="google-apps-script-editor">
<h2>Google Apps Script Editor</h2>
<p>Google Apps Script の開発環境として、 Google が公式に Web IDE を提供しているのですが、こいつは全くもって気が利きません。
こいつの気の利かない感じは、行頭でスペース1個打ってからタブ打ってみたり、タブ打ってから Backspace 打ってみたり、バグの無い関数に対してデバッガーを起動したりすれば実感していただけるのでは無いでしょうか。</p>
<p>そうそう、それから</p>
<div class="highlight"><pre><span></span><span class="kd">function</span><span class="w"> </span><span class="nx">foo</span><span class="p">(){</span>
<span class="p">}</span>
</pre></div>
<p>は関数として認識してくれるのに、</p>
<div class="highlight"><pre><span></span><span class="kd">var</span><span class="w"> </span><span class="nx">foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(){}</span>
</pre></div>
<p>を関数として認識してくれない辺りにはイラッとしました。
名前がついた関数か、無名関数を代入された変数かの違いがあることは認識していますが、 Google Apps Script Editor の補完の動きを見ていると変数に代入されたオブジェクトの型を追っているようなので、これくらいできてくれてもいいんじゃないか、って思いました。</p>
<p>というか、普段全く IDE を触らず、辛うじて ER Master を使うためだけに Eclips を使ったりする程度なので、 IDE ってこんなものなのか、、、って残念な気持ちになりました。
余談ですが、 Titanium でアプリを開発するときも Vim でコードを書いて、コンパイルもターミナルからコンパイラを叩いていました。</p>
</div>
<div class="section" id="section-2">
<h2>タスクリマインダー</h2>
<p>勉強会開催までには幾つものタスクがあるのですが、 CombConf 運営チームはなかなかタスクに手を付けられずに終わってるべきタスクが未着手とかいう事態が発生します。
そこでぼくが意識してタスクをバシバシ前に進める推進力になろうと意識しているのですが、ぼくも怠け者なのでタスクを発火させる役割の人間がタスクを発火していないというだめだこりゃ状態が発生する可能性があります。</p>
<p>そこで、わくわくエンジニアとして、タスクのリマインドを自動化しようと考えました。
そのタスクリマインダーに、触りたくてウズウズしていた Google Apps Script を組み合わせられないか考えました。
そうしたら、スタッフを務めていた PyCon JP 2012 では Google Spreadsheet と Google Apps Script を使って毎朝タスクリマインダーが送られてきていたことを思い出しました。</p>
<p>これだ、ということで、 Google Spreadsheet と Google Apps Script を使ったタスクリマインダーをCombConf にも導入することにしました!</p>
</div>
<div class="section" id="section-3">
<h2>書いた!</h2>
<div class="highlight"><pre><span></span><span class="kd">var</span><span class="w"> </span><span class="nx">USERS_SHEET_NAME</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'users'</span><span class="p">,</span>
<span class="w"> </span><span class="nx">TASKS_SHEET_NAME</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'tasks'</span><span class="p">,</span>
<span class="w"> </span><span class="nx">SPREADSHEET_URI</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'スプレッドシートのURI'</span><span class="p">;</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getEmailByNickname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">();</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">usersSheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="p">.</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">USERS_SHEET_NAME</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">userEmailTable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{};</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="nx">usersSheet</span><span class="p">.</span><span class="nx">getLastRow</span><span class="p">();</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="nx">userEmailTable</span><span class="p">[</span><span class="nx">usersSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">getValue</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">usersSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">).</span><span class="nx">getValue</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">nickname</span><span class="p">){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">userEmailTable</span><span class="p">[</span><span class="nx">nickname</span><span class="p">];</span>
<span class="w"> </span><span class="p">};</span>
<span class="p">})();</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getAllUserNicknames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">();</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">usersSheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="p">.</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">USERS_SHEET_NAME</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">users</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="nx">usersSheet</span><span class="p">.</span><span class="nx">getLastRow</span><span class="p">();</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">nickname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">usersSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">getValue</span><span class="p">();</span>
<span class="w"> </span><span class="k">if</span><span class="p">((</span><span class="nx">nickname</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="nx">users</span><span class="p">)</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">false</span><span class="p">){</span>
<span class="w"> </span><span class="nx">users</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">nickname</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">users</span><span class="p">;</span>
<span class="p">};</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getTasks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">();</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">tasksSheet</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">spreadsheet</span><span class="p">.</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">TASKS_SHEET_NAME</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">tasks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{};</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="nx">tasksSheet</span><span class="p">.</span><span class="nx">getLastRow</span><span class="p">();</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">task</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="nx">tasksSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">getValue</span><span class="p">(),</span>
<span class="w"> </span><span class="nx">limit</span><span class="o">:</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">tasksSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">).</span><span class="nx">getValue</span><span class="p">())),</span>
<span class="w"> </span><span class="nx">charge</span><span class="o">:</span><span class="w"> </span><span class="nx">tasksSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">3</span><span class="p">).</span><span class="nx">getValue</span><span class="p">(),</span>
<span class="w"> </span><span class="nx">progress</span><span class="o">:</span><span class="w"> </span><span class="nx">tasksSheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="mf">4</span><span class="p">).</span><span class="nx">getValue</span><span class="p">()</span>
<span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">progress</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="mf">100</span><span class="p">){</span>
<span class="w"> </span><span class="k">continue</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">charge</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="nx">tasks</span><span class="p">){</span>
<span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">task</span><span class="p">.</span><span class="nx">charge</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">task</span><span class="p">.</span><span class="nx">charge</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="nx">task</span><span class="p">];</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">tasks</span><span class="p">;</span>
<span class="p">};</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getTaskState</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// 1:超過, 2:今日まで, 3:進行中</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">today</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">();</span>
<span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">setHours</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
<span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">setMinutes</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
<span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">setSeconds</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
<span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">setMilliseconds</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">limit</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">limit</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">today</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">3</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">};</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getFormatedDate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">date</span><span class="p">){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">date</span><span class="p">.</span><span class="nx">getFullYear</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'/'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">date</span><span class="p">.</span><span class="nx">getMonth</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'/'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">date</span><span class="p">.</span><span class="nx">getDate</span><span class="p">();</span>
<span class="p">};</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="nx">embed_nickname</span><span class="p">){</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">embed_nickname</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">true</span><span class="p">){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">name</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">' [担当:'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">charge</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'][期日:'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">getFormatedDate</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">limit</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'][進捗:'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">progress</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'%]\n'</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">name</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">' [期日:'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">getFormatedDate</span><span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">limit</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'][進捗:'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">progress</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'%]\n'</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">};</span>
<span class="kd">function</span><span class="w"> </span><span class="nx">sendTaskReminderMail2Inviduas</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">tasks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">getTasks</span><span class="p">();</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">charge</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="nx">tasks</span><span class="p">){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">overdue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">,</span>
<span class="w"> </span><span class="nx">today</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">,</span>
<span class="w"> </span><span class="nx">fight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">;</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">charge</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">task</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">charge</span><span class="p">][</span><span class="nx">i</span><span class="p">];</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">task</span><span class="p">){</span>
<span class="w"> </span><span class="k">continue</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">switch</span><span class="p">(</span><span class="nx">getTaskState</span><span class="p">(</span><span class="nx">task</span><span class="p">)){</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">1</span><span class="o">:</span>
<span class="w"> </span><span class="nx">overdue</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">2</span><span class="o">:</span>
<span class="w"> </span><span class="nx">today</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">3</span><span class="o">:</span>
<span class="w"> </span><span class="nx">fight</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'タスクリマインダーメール\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'タスクの追加や進捗状況の変更は'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">SPREADSHEET_URI</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'から行なってください。\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========期限切れ==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">overdue</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========今日まで==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">today</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========頑張って==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">fight</span><span class="p">;</span>
<span class="w"> </span><span class="nx">sendEmail</span><span class="p">(</span>
<span class="w"> </span><span class="nx">getEmailByNickname</span><span class="p">(</span><span class="nx">charge</span><span class="p">),</span>
<span class="w"> </span><span class="s1">'タスクリマインダー for '</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">charge</span><span class="p">,</span>
<span class="w"> </span><span class="nx">body</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">};</span>
<span class="kd">function</span><span class="w"> </span><span class="nx">sendTaskReminderMail2All</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">tasks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">getTasks</span><span class="p">(),</span>
<span class="w"> </span><span class="nx">overdue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">,</span>
<span class="w"> </span><span class="nx">today</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">,</span>
<span class="w"> </span><span class="nx">fight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span><span class="p">;</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">charge</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="nx">tasks</span><span class="p">){</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">charge</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">task</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">tasks</span><span class="p">[</span><span class="nx">charge</span><span class="p">][</span><span class="nx">i</span><span class="p">];</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">task</span><span class="p">){</span>
<span class="w"> </span><span class="k">continue</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">switch</span><span class="p">(</span><span class="nx">getTaskState</span><span class="p">(</span><span class="nx">task</span><span class="p">)){</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">1</span><span class="o">:</span>
<span class="w"> </span><span class="nx">overdue</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">2</span><span class="o">:</span>
<span class="w"> </span><span class="nx">today</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mf">3</span><span class="o">:</span>
<span class="w"> </span><span class="nx">fight</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">getFormatedTask</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'タスクリマインダーメール\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'タスクの追加や進捗状況の変更は'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">SPREADSHEET_URI</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'から行なってください。\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========期限切れ==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">overdue</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========今日まで==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">today</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'\n==========頑張って==========\n'</span>
<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">fight</span><span class="p">;</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">nicknames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">getAllUserNicknames</span><span class="p">();</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">nicknames</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="nx">i</span><span class="p">){</span>
<span class="w"> </span><span class="nx">sendEmail</span><span class="p">(</span>
<span class="w"> </span><span class="nx">getEmailByNickname</span><span class="p">(</span><span class="nx">nicknames</span><span class="p">[</span><span class="nx">i</span><span class="p">]),</span>
<span class="w"> </span><span class="s1">'タスクリマインダー'</span><span class="p">,</span>
<span class="w"> </span><span class="nx">body</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">};</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">sendEmail</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">recipient</span><span class="p">,</span><span class="w"> </span><span class="nx">title</span><span class="p">,</span><span class="w"> </span><span class="nx">body</span><span class="p">){</span>
<span class="w"> </span><span class="nx">MailApp</span><span class="p">.</span><span class="nx">sendEmail</span><span class="p">(</span><span class="nx">recipient</span><span class="p">,</span><span class="w"> </span><span class="s1">'[自動送信メール]'</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">title</span><span class="p">,</span><span class="w"> </span><span class="nx">body</span><span class="p">);</span>
<span class="p">};</span>
</pre></div>
</div>
<div class="section" id="section-4">
<h2>使い方</h2>
<ol class="arabic simple">
<li>新しいスプレッドシートを作る</li>
<li>シートを追加する<ul>
<li>タスクを書いていくためのシートと、通知先のメールアドレスを書いていくためのシート、計2枚のシートが必要です</li>
</ul>
</li>
<li>わかりやすいようにシートの名前を適当に変更する(オプション)</li>
<li>ツール -> スクリプトエディタ -> スプレッドシート</li>
<li>上記のコードをペースト</li>
<li>タスクを書くシートの名前をTASKS_SHEET_NAME に設定する</li>
<li>ユーザーを書くシートの名前をUSERS_SHEET_NAME に設定する</li>
<li>タスク用のシートに以下のフォーマットでタスクを書く<ul>
<li>1列目: タスク名</li>
<li>2列目: 期日(YYYY/MM/DD)</li>
<li>3列目: 担当者</li>
<li>4列目: 進捗度(百分率)</li>
</ul>
</li>
<li>通知先メールアドレス用のシートに以下のフォーマットでニックネームとメールアドレスのペアを書いていく<ul>
<li>1列目: ニックネーム<ul>
<li>タスク用シートの担当者名と1:1 で対応する必要があります</li>
</ul>
</li>
<li>2列目: 通知先メールアドレス</li>
</ul>
</li>
</ol>
<p>※各シートの1行目は項目名として使われることを想定しているので、1行目に書いてあるタスクやメールアドレスは読まれません。</p>
</div>
<div class="section" id="section-5">
<h2>ありがとうございました!</h2>
<p>寝てないのでさくっと書くつもりでしたが、気づいたら2610文字の長文になってました。
お読み頂きありがとうございました。
Happy Hacking!!!</p>
</div>
さくらの石狩データセンターを見学してきたよ!2012-11-22T00:00:00+09:002012-11-22T00:00:00+09:00yosida95tag:yosida95.com,2012-11-22:/2012/11/22/033659.html<p><img alt="entrance" src="https://blogmedia.yosida95.com/2012/11/22/033659/entrance.jpg" style="width: 100%;" /></p>
<p>というわけで、17日, 18日の2日間飛行機に乗って北海道の石狩 DC を …</p><p><img alt="entrance" src="https://blogmedia.yosida95.com/2012/11/22/033659/entrance.jpg" style="width: 100%;" /></p>
<p>というわけで、17日, 18日の2日間飛行機に乗って北海道の石狩 DC を見学してきました。</p>
<div class="section" id="section-2">
<h2>きっかけ</h2>
<p><a class="reference external" href="http://b.hatena.ne.jp/articles/201210/10682">はてブで見かけたキャンペーン</a>を気になってブックマークしていました。
その後、ぼくの学校の文化祭が終わったあとで <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> と <a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> と3人でルノアールに入り、開催予定の勉強会 <a class="reference external" href="http://combconf.com/">CombConf</a> の打ち合わせをしていました。</p>
<p>その中で、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> に「こんなのがあるんだけど」って紹介したら「めっちゃいきたい!」って話になったので、データセンターに萌えるタイプの人間としてデータセンターに対する熱意を応募フォームに書き添えて、ほぼ同時に応募しました。</p>
</div>
<div class="section" id="section-3">
<h2>北海道グルメツアー</h2>
<p>応募した結果、一緒に応募した <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> と、ぼくと同じく高校生で以前から面識のあった <a class="reference external" href="http://blog.hatena.ne.jp/toriimiyukki/">id:toriimiyukki</a> も当選したことを知り、ツアー中ほぼこの3人で行動していました。</p>
<p>飛行機の遅延により50分遅れて新千歳空港についた後、バスに乗って石狩データセンターへ移動しました。
サーバーラックやチカチカ光るルーターがぼくらを待っているのかとおもいきや、待っていたのは海鮮丼でした。</p>
<p><img alt="sashimi-rice" src="https://blogmedia.yosida95.com/2012/11/22/033659/sashimi-rice.jpg" style="width: 100%;" /></p>
<p>海鮮丼を美味しく頂いた後、ようやく石狩 DC の中に入りました。
舘野副社長が丁寧に説明をしてくれながら、データセンターの各所を見て回りました。
監視センターにある PUE のモニターを見て「おー厨二病っぽい」って思ったり、中身の詰まったサーバーラックがズラーって並んでいる姿に感動したり、ラックの中で緑のアクセスランプがチカチカ光っている姿に心踊ったり、めっちゃ楽しかったです。
その中でも、最も感動したのは、頭上をケーブルが整然と並んで配線されていることでした。
よく見るデータセンター写真みたいにケーブルがグッチャグチャに張っているのではなく、本当に綺麗に交わることなく配線されていました。
<a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> も見学の後で感想を話していた時にいちばん感動したのはこの点だと言っていました。</p>
<p><img alt="rack" src="https://blogmedia.yosida95.com/2012/11/22/033659/rack.jpg" style="width: 100%;" /></p>
<p>石狩データセンターを見学した後はホテルに移動して懇親会が行なわれました。
懇親会の中で LT 大会が行なわれるとの事だったので、東京から新千歳空港に移動する飛行機の中で作ったスライドを使って LT をさせていただきました。
LT 大会は <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> によるターミナル共有システム liveterm に始まり、次がぼくの「ナウでヤングな17歳の自宅 VPS 構築記 (LT size)」、そして <a class="reference external" href="http://blog.hatena.ne.jp/toriimiyukki/">id:toriimiyukki</a> の"自己紹介 & いかにさくら VPS を使っているか" という内容の LT と、偶然にも冒頭から3人続けて高校生が LT をしました。</p>
<p>私の LT は9月15日の PyCon JP でのセッションを LT サイズに縮めたものでした。
さくらインターネットといえば「さくら VPS 」、さくら VPS のホストマシンは今日見学した石狩データセンターにもあるぞということでうってつけのネタだと思いこの内容で LT をしました。</p>
<p>LT のデモ中、ウェブコンパネと MySQL のコネクション切れにより 500 エラーが出て「これはずるい」と大いに笑って頂いたり、 LT 終了後には「ナウでヤング」というフレーズはさくらインターネット的に困るというツッコミをいただいたり、おおむねよい反応を得られました。</p>
<p>そしてなんと、 LT をした記念として石狩データセンター開局1周年記念Tシャツをいただきました!</p>
<p><img alt="sakura-t-shirt" src="https://blogmedia.yosida95.com/2012/11/22/033659/sakura-t-shirt.jpg" style="width: 100%;" /></p>
</div>
<div class="section" id="section-4">
<h2>ハッカソン</h2>
<p>宿泊するホテルはすすきのの中心にあり、参加者の多くは夜のすすきのに繰り出していたのですが、我々高校生3人は <a class="reference external" href="http://blog.hatena.ne.jp/toriimiyukki/">id:toriimiyukki</a> の部屋に集まってそこでハッカソンを始めました。</p>
<p>途中で大量の電子機器と高すぎた人口密集度によって部屋がとても暑くなってきたことと <a class="reference external" href="http://blog.hatena.ne.jp/toriimiyukki/">id:toriimiyukki</a> が寝落ちたことから涼を求めて隣のぼくの部屋に移動し、 <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> と2人でハッカソンを継続しました。
<a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> とは自宅に VPS があるもの同士として、ネットワークの話をしたり、ぼくが「 SLA100%を目指そう。 そのために Erlang をやろう」って呟いたことによって <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> が Erlang を始めたり、技術的素敵空間が出来上がっていました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">こばと話してると、絶対に学校とかその辺の奴とは話せないレベルの話をできで心が躍ってすんげー楽しい。今回のDC 見学ツアーに参加してる高校生が全員知り合いな辺り、やっぱりこの界隈である程度力ある人ぜんぜん少ないよ <a href="https://twitter.com/hashtag/%E7%9F%B3%E7%8B%A9DC%E3%83%84%E3%82%A2%E3%83%BC?src=hash">#石狩DCツアー</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/269849873698922496">November 17, 2012</a></blockquote></div>
<div class="section" id="section-5">
<h2>2日目</h2>
<p>2日目は飛行機が飛び立つまで完全自由行動でした。
ハッカソンにおける強烈な寝不足でぼくがカフェでコーヒーを飲みながら突然寝落ちたり、 <a class="reference external" href="http://blog.hatena.ne.jp/toriimiyukki/">id:toriimiyukki</a> が"いくらの量り売りをしてる店にいきたい"といいおみやげを買いにいったり、吹雪に見舞われたりぐだぐだと楽しい時間を過ごしました。
なんというか、北海道に来てまでビックカメラに入り、ガジェットを見て回ったりする辺りが本当に技術系高校生っぽいと思いました。</p>
<p>新千歳空港についてからは、会社や学校に持っていくおみやげを買いあさりました。
「北海道に来たからにはジンギスカンキャラメルを買いたい」ということで、ジンギスカンキャラメルを探しまわったりもしました。</p>
<p>いざ飛行機が出発する時間になったのですが、午前中から振り続ける雪、というか猛吹雪のせいで滑走路が1本を除いて使えなくなったり、ぼくらが乗る後の飛行機が欠航したりでだいぶ雲行きが怪しくなっていました。
飛行機に搭乗したあとも暴風で飛行機がぐわんぐわん揺れて滑走路で立ち往生していました。
しかし、なんとか30分遅れで飛行機は離陸することができ、無事に東京に帰ってきました。</p>
<p>東京に帰ってきた第一印象は東京暑い!でした。
成田空港で解散した後、ぼくと <a class="reference external" href="http://blog.hatena.ne.jp/koba789/">id:koba789</a> は秋葉原に直行しました。
というのも、ぼくが「 Gehirn ステッカー欲しい」と Twitter でぼそっと呟いたことをきっかけに Gehirn 社長の <a class="reference external" href="http://twitter.com/isidai">@isidai</a> さんを含む6人規模のオフ会が秋葉原で行なわれることになっていたためです。
和風ハンバーグをごちそうになりました。
美味しかったです><</p>
</div>
<div class="section" id="section-6">
<h2>まとめ</h2>
<p>記事が大分長くなった上、とてもまとまりの悪い記事になってきたので無理やり締めます。</p>
<p>参加者のみなさんお疲れ様でした。
とても楽しかったです!来年も開催されるならぜひ参加したいです!!</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E7%9F%B3%E7%8B%A9DC%E3%83%84%E3%82%A2%E3%83%BC?src=hash">#石狩DCツアー</a> でよしだとよくわからん友情が芽生えた気がしている</p>— 霧矢あおい (@KOBA789) <a href="https://twitter.com/KOBA789/status/270884243926810624">November 20, 2012</a></blockquote><p>ぼくも同じようなことを思っていました。
嬉しいです。</p>
</div>
Gehirn Web Services ファミリーの Gehirn RS2 に恋をして Pyramid を動かす2012-11-19T00:00:00+09:002012-11-19T00:00:00+09:00yosida95tag:yosida95.com,2012-11-19:/2012/11/19/011515.html<p>2012/11/22 記事の最後に追 …</p><p>2012/11/22 記事の最後に追記しました</p>
<div class="section" id="section-1">
<h2>ただいま</h2>
<p>ただいま!
さくらインターネットの石狩データセンター見学から先ほど帰って来ました。</p>
</div>
<div class="section" id="gehirn-rs2">
<h2>Gehirn RS2 とは</h2>
<p><a class="reference external" href="http://www.gehirn.co.jp/">ゲヒルン株式会社</a> が先日リリースした Gehirn Web Services というインフラプラットフォームファミリーのうちの1プロダクトで、平たく言うとレンタルサーバーサービスです。</p>
</div>
<div class="section" id="gehirn-rs2-1">
<h2>Gehirn RS2 のすごい話</h2>
<ul class="simple">
<li>安い<ul>
<li>315 円から借りられる</li>
</ul>
</li>
<li>WAF (Web Application Firewall) が標準搭載</li>
<li>定期的にスナップショットが作成され、データを自動でバックアップできる</li>
</ul>
<p>他にも、独自 SSL 証明書持ち込めて設定できたり、特定ホストへのアクセスをローカルのポートにリバースプロキシすることで Node.js とかで立てたサーバーに80番ポートでアクセスできたり、いろいろおもしろい機能がたくさん実装されています。
それなのに、1ヶ月315円で借りられます。</p>
<p>ご存知のように、ぼくの<a class="reference external" href="http://youtu.be/tOWZB9tFgu8">自室内に自分専用の VPS サービス</a>が構築されていて、運営してるサービスのほとんどを自宅サーバーから提供している程度にはサーバーに困らない生活を送っていますが、この中二心をくすぐる素敵なサーバーを使ってみたいということ、 Gehirn の社長と知り合いであることなどから、発表された日の夜にバイト帰りの電車の中で契約しました。
安価でいいおもちゃが手にはいりました。</p>
</div>
<div class="section" id="python">
<h2>Python を使う</h2>
<p>私といえば Python です。
なので、 Gehirn RS2 の特徴でもあるリバースプロキシ機能を使って Python で書いた WSGI アプリケーションをローカルでデーモンとして動かし、外から <a class="reference external" href="http://gehirn-rs2.yosida95.com">gehirn-rs2.yosida95.com</a> にアクセスすればローカルで動いているアプリケーションにアクセスできるようにしました。</p>
<div class="section" id="python-1">
<h3>Python のバージョンを調べる</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>python<span class="w"> </span>--version
Python<span class="w"> </span><span class="m">2</span>.6.6
</pre></div>
<p>あれ……?
Python 2 系の最新安定版って 2.7.3 だよな……?</p>
</div>
<div class="section" id="rs2">
<h3>rs2 コマンド</h3>
<p>Gehirn RS2 には rs2 コマンドというものがあって、例えば Node.js を使いたい場合は</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>rs2<span class="w"> </span>install<span class="w"> </span>node
</pre></div>
<p>として Node.js をインストールした後</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>rs2<span class="w"> </span>use<span class="w"> </span>node
</pre></div>
<p>とすれば、 Node.js が使えるようになります。</p>
<p>install の際は、最新バージョンのソースコードをダウンロードしてきてビルドしてくれます。</p>
<p>もしかして同じように Python もつかえるのではないか……?</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>rs2<span class="w"> </span>install<span class="w"> </span>python
Usage:
<span class="w"> </span>:
<span class="w"> </span>:
</pre></div>
<p>だめか……。</p>
</div>
<div class="section" id="section-2">
<h3>ソースからビルド</h3>
<p>しかたがないので、 <a class="reference external" href="http://www.python.org/">python.org</a> から Python 2.7.3 のソースコードをダウンロードしてきて自分のホームディレクトリの下でビルドしました。
この件について、 Gehirn の社長に「 Python 2.7.3 を使いたいんだけど」ってリプを送ったところ次のようにお答えをいただきました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">一段落。寝る。 - The Pyramid Web Application Development Framework: <a href="http://t.co/1ovhoFdC">http://t.co/1ovhoFdC</a> <a href="https://twitter.com/hashtag/miteru?src=hash">#miteru</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/268027945522712579">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> おおー!乙!!</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/268028542929993728">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/isidai">@isidai</a> Python2.7 ビルドして、A, AAAA レコード設定して、Pyramid 入れて走らせただけなんですけどねww</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/268028747247144961">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> それだけでも十分!</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/268028881485852672">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/isidai">@isidai</a> Python2.7.3 標準で入ってくれませんかね(/ω・\)チラッ</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/268029132166799360">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> virtualenv対応じゃダメですかね</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/268029496001695744">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/isidai">@isidai</a> それだと結局Python 2.7 系をビルドする手間がかかるのは同じなので、あってもなくても良くなっちゃうなーとは思います。</p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/268030042569854976">November 12, 2012</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> 2.6がいい、2.7がいい、3.1がいいっていう意見を全部聞いてると結局virtualenvに辿り着くのです…</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/268030260329730050">November 12, 2012</a></blockquote><p>ということで、 Gehirn RS2 には virtualenv と virtualenvwrapper を <tt class="docutils literal">/usr/local/bin</tt> 以下に入れていただけました。
この、 Twitter とかで要望出してカジュアルにレンタルサーバーが使いやすいものになっていくのってとってもステキだと思います><</p>
</div>
<div class="section" id="pyramid">
<h3>Pyramid アプリを起動</h3>
<p>ご存知とは思いますが、 Pyramid というのは Python の超素敵な WAF(Web Application Framework) で、家系図的に言うと Pylons2 に当たるプロダクトです。</p>
<p>早速 virtualenv を1個切って、</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pyramid
$<span class="w"> </span>pcreate<span class="w"> </span>-t<span class="w"> </span>starter<span class="w"> </span>testproj
$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>testproj
$<span class="w"> </span>python<span class="w"> </span>setup.py<span class="w"> </span>develop
</pre></div>
<p>を実行してさくっと Pyramid プロジェクトを作りました。
pcreate の時点で / にサンプルのビューが定義されているので、これを利用してサクッと動作を確認してしまします。</p>
<ol class="arabic simple">
<li>自分に割り当てられたポート番号を確認する</li>
<li>自分に割り当てられたポート番号を使用して WSGI サーバーを立ち上げる。</li>
</ol>
<p>以上の設定でリバースプロキシの設定が完了です。
外部からアクセスしてみてください。</p>
</div>
</div>
<div class="section" id="section-3">
<h2>最後に</h2>
<p>俺が Gehirn RS2 でもっとも最初に Python 2.7.3 を動かし、最初に Pyramid 製アプリケーションを動かし、最初に gunicorn
を起動し、最初に Python 3.3.0 を動かした人です!!!(よしだ調べ)</p>
</div>
<div class="section" id="section-4">
<h2>追記</h2>
<p>なんとこの記事を公開したその日、 <tt class="docutils literal">rs2 install python</tt> が実行できるようになりました!
これを実行すると、 pythonbrew がインストールされます!
やばい!
対応早い!
<span class="strike">pythonbrew ってどうよって話は置いといて</span></p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> rs2 install python でpythonbrew入るようになったので普通に使えるか見て欲しいです。</p>— isidai (@isidai) <a href="https://twitter.com/isidai/status/270425354726948864">November 19, 2012</a></blockquote><p><a class="reference external" href="http://support.gehirn.jp/information/news/2012/11/19/629/">rs2コマンドをアップデートしました</a></p>
</div>
Pyramid で Celery を使って非同期処理をする2012-11-04T00:00:00+09:002012-11-04T00:00:00+09:00yosida95tag:yosida95.com,2012-11-04:/2012/11/04/182244.html<div class="section" id="celery">
<h2>Celery</h2>
<p>Celery とは Python 製のタスク …</p></div><div class="section" id="celery">
<h2>Celery</h2>
<p>Celery とは Python 製のタスクキューです。
非同期処理をするのに使います。</p>
<p>情弱なのでこの前の PyconJP 2012 で Celery の存在を知りました。
存在を知る前は、 Kestrel と MongoDB を使ってオレオレタスクキューを作って使っていました。
それ以前はリクエスト毎にスレッドを生成してそいつを走らせつつレスポンスを返してしまうような実装をしていました。</p>
<p>Django からこの Celery を使う日本語解説記事は複数見かけましたが、 Pyramid から使う解説記事は見つけられなかったのでぼくが書いておきます。</p>
</div>
<div class="section" id="pyramid-celery-1">
<h2>pyramid_celery をインストールする</h2>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pyramid_celery
</pre></div>
<p>pip を使ってサクッと pyramid_celery をインストールします。</p>
</div>
<div class="section" id="section-1">
<h2>設定ファイルを編集する</h2>
<p>Pyramid から先ほどインストールした pyramid_celery を使えるように、 PasteDeploy 設定ファイル( development.ini や production.ini )を編集します。</p>
<p>具体的には、 pyramid.includes に pyramid_celery を追加し、[app:main] の中に BROKER_URL を追加します。
BROKER_URL には、タスクを保管するメッセージキューの URL を設定します。
今回は、 RabbitMQ を使う前提でサンプルの値を入れてあります。</p>
<div class="highlight"><pre><span></span><span class="k">[app:main]</span>
<span class="na">pyramid.includes</span><span class="w"> </span><span class="o">=</span>
<span class="w"> </span><span class="na">pyramid_celery</span>
<span class="na">BROKER_URL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">amqp://user:password@host:port//vhost</span>
<span class="na">CELERY_RESULT_BACKEND</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">amqp://user:password@host:port//vhost</span>
</pre></div>
<p>CELERY_RESULT_BACKEND の設定は Celery を使ってただ単に非同期処理をする上では必要のない設定ですが、これを設定してやることでタスクの状態(実行待ちか、実行後か)やタスクを実行した返り値などを取得することができます。</p>
<p>BROKER_URL や CELERY_RESULT_BACKEND としてデフォルトでは RabbitMQ を使うことになっていますが、 RabbitMQ 以外にも、 <a class="reference external" href="http://docs.celeryproject.org/en/latest/getting-started/brokers/redis.html">Redis</a> や <a class="reference external" href="http://docs.celeryproject.org/en/latest/getting-started/brokers/mongodb.html">MongoDB</a> 、 <a class="reference external" href="http://docs.celeryproject.org/en/latest/getting-started/brokers/sqs.html">Amazon Simple Queue Service</a> 、また <a class="reference external" href="http://docs.celeryproject.org/en/latest/getting-started/brokers/sqlalchemy.html">SQLAlchemy</a> や <a class="reference external" href="http://docs.celeryproject.org/en/latest/getting-started/brokers/django.html">Django のORM</a> を介して RDBMS を使うこともできるようです。
(それぞれのリンク先は Celery でこれらをストアとして使うための公式ドキュメント(英語)の該当する記事です)</p>
</div>
<div class="section" id="section-2">
<h2>タスクをプログラミングする</h2>
<p>既存の Pyramid アプリケーションの中にタスクを定義します。
ここでは、 myapp.tasks としてタスクを定義していく事にします。</p>
<p>タスクの内容として、メールを送信したり画像のサムネイルを生成したりなどが考えられると思うのですが、どこの解説記事を読んでも(公式ドキュメントでさえも)足し算をタスクの例としていたので、ここでもそれにならって足し算を例として取り上げます。</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">celery</span> <span class="kn">import</span> <span class="n">task</span>
<span class="nd">@task</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
</pre></div>
</div>
<div class="section" id="pceleryd">
<h2>pceleryd を実行する</h2>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pceleryd<span class="w"> </span>./development.ini
</pre></div>
<p>こいつがメッセージキューから実行すべきタスクを受け取ってタスクを実行し、その結果をストアに保存する役目を果たしてくれます。</p>
</div>
<div class="section" id="section-3">
<h2>タスクを呼び出す</h2>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pshell<span class="w"> </span>./development.ini
>>><span class="w"> </span>from<span class="w"> </span>myapp<span class="w"> </span>import<span class="w"> </span>tasks
>>><span class="w"> </span><span class="nv">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>tasks.add.delay<span class="o">(</span><span class="m">5</span>,<span class="w"> </span><span class="m">10</span><span class="o">)</span>
>>><span class="w"> </span>result.task_name
<span class="s1">'myapp.tasks.add'</span>
>>><span class="w"> </span>result.ready<span class="o">()</span>
True
>>><span class="w"> </span>result.successful<span class="o">()</span>
True
>>><span class="w"> </span>result.result
<span class="m">15</span>
</pre></div>
<p>このとおり、タスクが成功していることがわかります。
ここではインタラクティブシェルから直接タスクを呼び出していますが、実際に使うときはアプリケーションの任意の場所からリクエストに応じてタスクを実行します。</p>
</div>
<div class="section" id="section-4">
<h2>タスクを定期的に実行する</h2>
<p>タスクを定期的に実行する方法として、伝統的には cron を用いる方法があります。
しかし Celery でもタスクを定期的に実行することができます。
Celery を使うことで、タスクを実行するスケジュールをアプリケーションのコードに含められるという利点があります。</p>
<div class="section" id="section-5">
<h3>タスクをプログラミングする</h3>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">celery.task</span> <span class="kn">import</span> <span class="n">periodic_task</span>
<span class="kn">from</span> <span class="nn">celery.schedules</span> <span class="kn">import</span> <span class="n">crontab</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span>
<span class="c1"># 30秒おきに実行する</span>
<span class="nd">@periodic_task</span><span class="p">(</span><span class="n">run_every</span><span class="o">=</span><span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="mi">30</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">run_every_30seconds</span><span class="p">():</span>
<span class="c1"># 何かの処理</span>
<span class="c1"># 毎月1日の8時0分に実行する</span>
<span class="nd">@periodic_task</span><span class="p">(</span><span class="n">run_every</span><span class="o">=</span><span class="n">crontab</span><span class="p">(</span><span class="n">minute</span><span class="o">=</span><span class="s1">'0'</span><span class="p">,</span> <span class="n">hour</span><span class="o">=</span><span class="s1">'8'</span><span class="p">,</span> <span class="n">day_of_month</span><span class="o">=</span><span class="s1">'1'</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">run_first_of_every_month_at_8</span><span class="p">():</span>
<span class="c1"># 何かの処理</span>
</pre></div>
</div>
<div class="section" id="pceleryd-pcelerybeat">
<h3>pceleryd と pcelerybeat を実行する</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pceleryd<span class="w"> </span>./development.ini
$<span class="w"> </span>pcelerybeat<span class="w"> </span>/.development.ini
</pre></div>
<p>pceleryd の役目は上で説明したとおりです。
pcelerybeat の役目はタスクを実行すべき時刻になったら pceleryd にそのことを知らせるというものです。
従って、 pcelerybeat を実行しておきながら pceleryd を実行していない場合はそのタスクが実行されることはありません。</p>
<p>また、上記の2コマンドを実行する方法の他に、 pcelerybeat は実行せずに、 pceleryd に --beat オプションを追加することで1コマンドにまとめる方法もあります。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pceleryd<span class="w"> </span>./development.ini<span class="w"> </span>--beat
</pre></div>
</div>
<div class="section" id="section-6">
<h3>注意</h3>
<p>Celery 3.0 からは、 CELERY_ENABLE_UTC がデフォルトで True になっているため、 crontab に指定した時刻はすべて UTC
として扱われます。
他のタイムゾーンの時刻で指定したい場合には、設定ファイルの CELERY_TIMEZONE に使いたいタイムゾーンを指定してやるか、サーバーのローカル時刻を使いたい場合は CELERY_ENABLE_UTC を False にしてやります。</p>
<p>また、 CELERY_TIMEZONE を指定する方法の場合、 pytz モジュールが必要なるので、 pip などでインストールしてください。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pytz
</pre></div>
</div>
</div>
<div class="section" id="section-7">
<h2>最後に</h2>
<p>Celery では celery.task を古いモジュールとして、もうこれ以上使われるべきでないとして使用を推奨していません。</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">celery</span> <span class="kn">import</span> <span class="n">Celery</span>
<span class="n">celery</span> <span class="o">=</span> <span class="n">Celery</span><span class="p">()</span>
<span class="nd">@celery</span><span class="o">.</span><span class="n">task</span>
<span class="k">def</span> <span class="nf">some_task</span><span class="p">():</span>
<span class="c1"># 何らかの処理</span>
</pre></div>
<p>以上のようにすることが推奨されていますが、 pyramid_celery のドキュメントには celery.task を使ってタスクが定義されていること、 pceleryd は celeryd の config オプションを無効化しているために PasteDeploy 設定ファイルに CELERYBEAT_SCHEDULE を指定する必要があり、その場合1行に Python の dict を文字列として記述し timedelta や crontab を使うには eval を使う必要があるなどカオスになることから古いスタイルを使っています。</p>
<p>StackOverFlow に、「 pyramid_celeryd は非常に薄いラッパーで、これがなくて Celery 単体で十分に使えるから pyramid_celery は必要とされてないよね!」って書いてある記事がありましたが、タスクがデータベースを使った処理をするときには PasteDeploy 設定ファイルから SQLAlchemy の engine を作ってそれを session に bind する処理が必要になり、また開発用と製品用でデータベースを分けている場合にはさらに処理が複雑になるので、ここでは pyramid_celery を使う方法を書きました。</p>
</div>
<div class="section" id="url">
<h2>参考 URL</h2>
<ul class="simple">
<li><a class="reference external" href="http://docs.celeryproject.org/en/latest/index.html">Celery - Distributed Task Queue</a></li>
<li><a class="reference external" href="http://kk6.hateblo.jp/entry/2012/09/06/celery%E3%81%AEPeriodic_Task%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E3%83%A1%E3%83%A2">celeryのPeriodic Taskについてのメモ</a></li>
</ul>
</div>
株式会社ゼロスタートに入社しました!2012-10-13T00:00:00+09:002012-10-13T00:00:00+09:00yosida95tag:yosida95.com,2012-10-13:/2012/10/13/222109.html<p>タイトルで軽く釣りま …</p><p>タイトルで軽く釣りました。
入社と言ってもアルバイトです。
ごめんなさいごめんなさい。</p>
<p>報告が遅くなりましたが、10月9日から<a class="reference external" href="http://zero-start.jp/">株式会社ゼロスタート</a>でプログラマーとしアルバイトしています。</p>
<div class="section" id="section-2">
<h2>経緯</h2>
<p>きっかけは Twitter で仕事探してる的なツイートをしたら、 <a class="reference external" href="http://twitter.com/__hase__">@__hase__</a> さんから会社見学のお誘いを受けた事でした。
そのお誘いにほいほいついっていって会社見学に行ったところ社長が出迎えてくださり、「うちでバイトしたいの?全然いいけど」みたいな感じであっさりバイトすることになりました。</p>
<p>余談ですが、前出のツイートに対して Heroku の人からも反応があって超やべーとか思ってたのですが、それ以来音沙汰がなくちょっとへこんだ反面ほっとしてます。</p>
<p>ゼロスタートは <a class="reference external" href="http://blog.hatena.ne.jp/amachang/">id:amachang</a> さんの「<a class="reference external" href="http://d.hatena.ne.jp/amachang/20110112/1294841503">株式会社ゼロスタートコミュニケーションズに遊びに行ってきた! - IT戦記</a>」という記事で以前から知っていたことや、 PyCon JP 2012 で一緒にスタッフをした <a class="reference external" href="http://twitter.com/RicoImazu">@RicoImazu</a> さんが居る会社であること、なにより Python で開発をしているということからかねてから興味のある会社でした。</p>
</div>
<div class="section" id="section-3">
<h2>ぼくがアルバイトをする理由</h2>
<p>ぼくが放課後にアルバイトしたい理由として、常に継続してコードを書き続けたいというものがあります。
別に自宅でも努力すれば不可能ではないですが、様々な外部要因によりとても困難です。
また、自宅でコードを書くだけの時間をとれたとしても書くものが無いという問題があります。
大抵の場合、自分で作った問題は自分で簡単に解決できてしまいます。</p>
<p>仕事として会社に行ってコードを書くのであれば、ぼくを誘惑する外部要因から遮断され解決すべき問題が与えられます。
さらに、今まで自分が挑んだことも無いようなプロダクトを開発することがあり、今まで自分が解決したことの無い問題に思う存分取り組む事ができます。</p>
<p>ここまで偉そうなことを言いましたが、身も蓋もない話をすれば金を稼ぎたいという動機も少なからずあります。
休日に遊びに行くにも、サーバーを借りるにも、自宅サーバーを維持するにも、技術書を買って勉強するにもお金がかかり、高校生の資金力ではちょっとどころではなく厳しいものがあります。
これまでに勉強してきたことでお金を稼ぎ、休日にそのお金で勉強したり遊んだり色々して成長して、それを仕事にフィードバックしてさらにお金を稼ぐ、という永久機関的な何かが出来れば最強だなぁとおもいます。</p>
</div>
<div class="section" id="section-4">
<h2>感想</h2>
<p>夏休みにアルバイトしていた Decoo ではフルタイムで出勤できないとプロジェクトの進捗とかの問題上厳しいと言われ、ぼくが高校1年生くらいの時に、たしか BeProud の人だったと思うのですが、大学生くらい時間が自由にならないと厳しい的な感じのことを言われていたので、高校生のうちは放課後に IT 企業でプログラマーとして働くのは厳しいものと思っていました。
しかし、今回ゼロスタートでは放課後にアルバイトさせていただけたのでとても嬉しいです。</p>
<p>なにより Python で仕事が出来るということが嬉しいです。</p>
<p>よろしくお願いします。</p>
</div>
PyCon JP 2012 に参加してきました #pyconjp2012-10-02T00:00:00+09:002012-10-02T00:00:00+09:00yosida95tag:yosida95.com,2012-10-02:/2012/10/02/164054.html<p>報告いまさらかよって …</p><p>報告いまさらかよって気もしますが、去る9月15日から17日までの3日間、東京都品川区の産業技術大学院大学で行われた PyCon JP 2012 に参加してきました。</p>
<p>いつもなら、感想とかあった出来事とかをここに書いているのですが、今回はすべてこちらにまとめられているので省略します。
よろしくお願いします。</p>
<ul class="simple">
<li><a class="reference external" href="http://gihyo.jp/news/report/01/pyconjp2012/0001">第1回 複雑さは幸せを殺す ─初日/2日目キーノートと開発者向け注目セッションから:PyCon JP 2012参加レポート|gihyo.jp … 技術評論社</a></li>
<li><a class="reference external" href="http://gihyo.jp/news/report/01/pyconjp2012/0002">第2回 17歳のVPS構築記,Python3の最新情報からソーシャルゲーム,WebフレームワークとPythonの話:PyCon JP 2012参加レポート|gihyo.jp … 技術評論社</a></li>
<li><a class="reference external" href="http://gihyo.jp/news/report/01/pyconjp2012/0003">第3回 Open Spaces,ライトニングトーク,Sprints─PyConならではのセッションたち─そして来年は?:PyCon JP 2012参加レポート|gihyo.jp … 技術評論社</a></li>
</ul>
株式会社Decoo に就職して、そして退職しました2012-09-03T00:00:00+09:002012-09-03T00:00:00+09:00yosida95tag:yosida95.com,2012-09-03:/2012/09/03/211203.html<p>タイトル少し釣りまし …</p><p>タイトル少し釣りました。</p>
<p>夏季インターン扱いのアルバイトとして学校が夏休みである8月の1ヶ月間、<a class="reference external" href="http://www.decoo.co.jp/">株式会社 Decoo</a>にて働いていました。</p>
<p>Decoo とは今年の4月1日に<a class="reference external" href="http://megalodon.jp/2012-0401-1242-31/af2012.decoo.jp/">このような</a>若い世代に嬉しい採用活動を行い話題になった渋谷の IT 企業です。</p>
<div class="section" id="section-1">
<h2>きっかけ</h2>
<p>このブログを偶然読んで頂いた Decoo の CTO が私に興味を持ってくださり、 Decoo のエンジニアを交えたお食事のお誘いという形でメールを下さりました。
当時私はアルバイトを探しており、その件についても頂いたメールの中で触れて頂けていたので、これをチャンスだと思いお食事をご一緒させていただきました。
焼肉をごちそうになりました。</p>
<p>そのお食事とその後のメールのやりとりの中で、私の学校が夏休みでフルタイムで勤務できる期間について夏季インターンのアルバイトとして働いてみてはどうか、というお話を頂きました。</p>
</div>
<div class="section" id="section-2">
<h2>夏休み</h2>
<p>7月下旬に学校が夏休みを迎え、 CTO にインターンについてメールをお送りしたところトントン拍子に話が進み、8月の1ヶ月間 Decoo で働かせていただくことになりました。</p>
</div>
<div class="section" id="section-3">
<h2>入社初日</h2>
<p>天気はあいにくの豪雨でした。</p>
<p>ひと通り新入社員オリエンテーションを終えると、進めていくプロジェクトについてのミーティングがあり、その場で仕事が割り振られました。
他の学生のインターン報告エントリで、インターン用に特別に用意された課題をこなしていったという話をよく目にしていたので、これには驚きました。
それと同時に、お仕事として価値のあるものを創れ、それが形になって提供されることに対して喜びを感じました。</p>
<p>この日のお昼に焼肉をごちそうになりました。</p>
</div>
<div class="section" id="section-4">
<h2>最終勤務日</h2>
<p>朝から通常どおりの業務をしていました。
退勤時間が近くなると、退社についての手続きや人事の方との面談、社長への挨拶などをしました。</p>
<p>冬や春などのまとまった時間が取れる時にはまた連絡して欲しい、などと言われてとても幸せでした。</p>
<p>夜には私が配属されチームで私の送別会を開いて頂き、焼肉をごちそうになりました。</p>
</div>
<div class="section" id="section-5">
<h2>感想</h2>
<p>とても刺激的でエクサイティングな1ヶ月間でした。</p>
<p>ブログを読んでいただければお分かりになると思いますが、私が得意とすることは Web 系いわゆるろくろ回し分野ですが、今回のインターンではそれとは違う分野のお仕事をさせて頂きました。
慣れないことで少し戸惑うこともありましたが、しかしそれでも遺憾なく実力を発揮出来たと自負しています。</p>
<p>今回痛感したことがあって、それは「1つの言語を徹底的にやりこむことの大切さ」です。
1つの言語を徹底的にやりこんでおくと、プログラミング自体への理解が深くなって、つぶしが利くようになります。
もちろん、言語による構文や予約語、プログラミングパラダイムの差異などは出てきますが、それがさほど大きな問題ではなくなるとおもいます。</p>
<p>チーム開発の経験が一切なかった私にとって、チームでゴールを共有して、ゴールに向かって自分の力を出す、というのはとても新鮮な体験でした。</p>
<p>今までひとりきりで開発をしてきて、自分の実力がどの程度なのかということをわからずに居ましたが、チームで開発をしていく中で自分の実力の程度をおよそ計り知ることもできました。
また、 CTO にはスキルは既に社会人レベルであるとの評価を頂いた他にも、事あるごとにコーディングやテストなどの能力について褒めていただけました。
ただ、これに慢心すること無くこれからも精進していきます。</p>
<p>何より、自分が書いたコードや問題に対する解決方法が評価されるということが、中途半端なことはできないという意識につながり、それがモチベーションになりました。</p>
<p>他にも語り尽くせない程のことを体験し学び、とてもとても濃密な1ヶ月間でした。</p>
<p>本当にお世話になりました。
ありがとうございました。</p>
</div>
<div class="section" id="section-6">
<h2>最後に</h2>
<p>報告が遅くなりましたが、ダメ元で送った CfP がなんと採択され、来る9月15日 PyCon JP 2012 で45分間セッションをさせて頂く事になりました。
テーマは VPS に関するものです。</p>
<p>また、 PyCon JP 2012 では今年の初めからスタッフとして微力ながらもお手伝いをさせていただいています。</p>
<p>9月の15日と16日、そして Sprint の17日の計3日間、品川の産業技術大学院大学で行われる PyCon JP 2012 にお越しください><</p>
<ul class="simple">
<li><a class="reference external" href="http://2012.pycon.jp/">PyCon JP 2012 開催します! - PyCon JP 2012</a></li>
<li><a class="reference external" href="http://connpass.com/event/708/">PyCon JP 2012 参加登録ページ</a></li>
</ul>
</div>
私立・プログラミングキャンプ 2012 東京大会 - #upcamp に参加してきました。2012-08-13T00:00:00+09:002012-08-13T00:00:00+09:00yosida95tag:yosida95.com,2012-08-13:/2012/08/13/121435.html<div class="section" id="upcamp-1">
<h2>upcamp-ってなに</h2>
<p><a class="reference external" href="http://ya.spcamp.org/">#upcamp 2014</a> ここ見てね。</p>
</div>
<div class="section" id="lt">
<h2>LT 編 …</h2></div><div class="section" id="upcamp-1">
<h2>upcamp-ってなに</h2>
<p><a class="reference external" href="http://ya.spcamp.org/">#upcamp 2014</a> ここ見てね。</p>
</div>
<div class="section" id="lt">
<h2>LT 編</h2>
<p>ガチ迷子やって遅刻しました。
すみません。
すみません。
<a class="reference external" href="http://twitter.com/masawada">@masawada</a> さんに救出してもらいました。
ありがとうございました。</p>
<p>遅刻してきたのに飛び込みで LT させていただきました。
LT でデモ見せる予行演習してたら仮想マシンのホストサーバーがネットワーク的に死んでました。
自宅にいたコンピューターとかよくわからない母親にサーバーの再起動をお願いするために、会場の後ろのほうでぼそぼそ電話で話していました。
すみません。
すみません。</p>
<p>無事、ホストマシンの復帰を確認したので、 LT をしました。
その時のスライドはこちら。</p>
<script async class="speakerdeck-embed" data-id="502601229be99c000201eff3" data-ratio="1.299492385786802" src="http://speakerdeck.com/assets/embed.js"></script></div>
<div class="section" id="section-1">
<h2>夕食編</h2>
<p><a class="reference external" href="http://twitter.com/masawada">@masawada</a> さんと <a class="reference external" href="http://twitter.com/KOBA789">@KOBA789</a> と <a class="reference external" href="http://twitter.com/oidong1">@oidong1</a> で夕食を食べに行きました。
@oidong1 はとにかく終始惚気話をしたので、ぼくらアフター組は生暖かい目で見守っていました。
そんな最中生まれた名言がこちら。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">oid○ng1 「非リア充は死ねっ」 マジ名言過ぎて鳥肌モノ <a href="https://twitter.com/hashtag/upcamp?src=hash">#upcamp</a></p>— Kohei YOSHIDA (@yosida95) <a href="https://twitter.com/yosida95/status/234248352932446208">August 11, 2012</a></blockquote></div>
<div class="section" id="section-2">
<h2>ハッカソン編</h2>
<p>まず、12ダースの RedBull が提供され、ぼくらのエナジー供給には十分すぎるほどの体制が取られていました。
ありがとうございます。</p>
<p>もともと僕と @oidong1 が組んで一緒に開発をすることになっていましたが、そこにジョインしてきたのが <a class="reference external" href="http://twitter.com/i315">@i315</a> (いとおちゃん)氏。</p>
<p>作るものが大体固まって、さあ何で書くかとなった時に勃発したので宗教戦争「Python:Pyramid vs. Ruby:Rails」。</p>
<p>激論の末結末がつかず、決戦はじゃんけん3回戦にもつれ込んだ。
ぼく2 v.s. いとおちゃん:0 で決着がついたに思えましたが、激論に疲弊していたぼくらにまともな思考力は残されておらず、いつの間にかじゃんけん3回戦がじゃんけん3点先取性にすりかわって、ぼくの逆転負け。</p>
<p>大人げないぼくはそれでもゴネていたところに、 <a class="reference external" href="http://twitter.com/umisama">@umisama</a> の「なんでじゃんけん3回戦なのに5回戦ってるの?」の一言に目が覚め、宗教戦争がどんどん <tt class="docutils literal">git revert</tt> されていき、最終的に @oidong1 の手によっていとおちゃんがジョインする前の状態にまで <tt class="docutils literal">git revert</tt> された。</p>
<p>いとおちゃんは <tt class="docutils literal">git reflog</tt> すればこれまでのコミットがすべて見えるんだぞ、とか言いつつも大人気ないぼくに対して大人の行動。</p>
<p>ここまで来たのが1:30。
この間1行もコードを書かずに不毛な時間を過ごしてしまった。
ごめんなさい。
ごめんなさい。</p>
<p>一生懸命に開発を進めましたが、やはり開発始めが遅くタイムアップ。
それでも、本気で @oidong1 のサイトデザインをテンプレート言語にトランスレートしながら、ぼくの開発成果とマージしていったら、@oidong1 に「魔法使いみたい、本来の意味で」と言われたので満足。</p>
<p>そんなぼくらの成果発表スライドがこちら。
@oidong1 が作ってくれました。</p>
<script async class="speakerdeck-embed" data-id="50286f119697ed0002015fc2" data-ratio="1.3333333333333333" src="http://speakerdeck.com/assets/embed.js"></script></div>
【重要】見てるなう(仮)セキュリティ脆弱性について2012-06-25T00:00:00+09:002012-06-25T00:00:00+09:00yosida95tag:yosida95.com,2012-06-25:/2012/06/25/021925.html<p>公開から2ヶ月が経過し、多くの方に …</p><p>公開から2ヶ月が経過し、多くの方にご愛用いただいている「<a class="reference external" href="http://miteru.yosida95.com/">見てるなう(仮)</a>」にセキュリティ脆弱性があると、ユーザーである <a class="reference external" href="http://twitter.com/ww24">@ww24</a> 様より<a class="reference external" href="https://gist.github.com/2978257">攻撃コード</a>と共にご報告を受けました。</p>
<p>私の方で調査いたしましたところ、「見てるなう(仮)」ユーザーが悪意のあるページで見てるなうをした場合、ユーザーのアクセストークンが抜き取られ、<strong>ユーザーが意図しないツイートを攻撃者によって投稿されてしまう可能性がある</strong>ことが判明いたしました。</p>
<p>この攻撃は JavaScript の window.open 関数をオーバーライドして、 window.open 関数に渡った引数と生成された Window オブジェクトへの参照をコピーします。
挙動は通常の window.open と変わりがないため、 window.open がオーバーライドされていることの検出は難しいものと思います。</p>
<p>なお、この攻撃は投稿画面をブックマークレットによって直接表示している<strong>すべての「見てるなう(仮)」類似サードパーティ製サービス(閲覧中のウェブページを Twitter へ投稿するサービス)にも同様の影響</strong>を与えます。
私が調査した3種類の類似サービスでも投稿ページのアドレスを抜き取り、ウィルス配布ページやフィッシング詐欺ページなどの<strong>攻撃者の任意のページを Twitter に投稿できる</strong>ことを確認いたしました。</p>
<p>この度私が施した対策は以下の流れによって行われます。</p>
<ol class="arabic simple">
<li>window.open によってワンタイムトークン生成ページを開き、ワンタイムトークンを発行する。
有効期限は10分間。
トークンは、発行元のドメインに対してのみ有効である。</li>
<li>ワンタイムトークンの認証符号を HMAC-SHA1 によって計算する。
この際の鍵ブックマークレット生成時に発行した秘密鍵とする。</li>
<li>認証符号と共に投稿ページを呼び出す</li>
<li>投稿時、サーバーに保存されている秘密鍵によって計算された正しいワンタイムトークンの認証符号と送られてきた認証符号を照合する</li>
<li>照合の結果一致した場合にのみ Twitter への投稿をする</li>
<li>一致した場合でも一致しなかった場合でも発行されたワンタイムトークンを無効化する</li>
</ol>
<p>この修正の影響によって、すでにご利用いただいているユーザーには、<strong>ブックマークレットの交換</strong>をお願いしております。</p>
<p>交換の方法は、古いブックマークレットを破棄して頂いた後、<a class="reference external" href="https://miteru.yosida95.com/">「見てるなう(仮)」</a>にログインしていただき、表示されるブックマークレットをブックマークバーにドラッグアンドドロップしていただくことです。</p>
<p>この度はご迷惑をお掛けし誠に申し訳ありません。
何卒よろしくお願いいたします</p>
画像まとめてダウンローダー作った2012-06-18T00:00:00+09:002012-06-18T00:00:00+09:00yosida95tag:yosida95.com,2012-06-18:/2012/06/18/033304.html<p>ちょっと必要になった …</p><p>ちょっと必要になったから、ウェブページのアドレスを渡すとそのページ中にある画像をダウンロードしてくれるスクリプトを作った。
やっつけ仕事。</p>
<p>基本的に img タグを追ってるけど、 img タグが a タグの中にいて、かつその a タグの href 属性に指定されてる URL が画像の場合はそっちをダウンロードしてきてくれる( img タグにサムネイルを指定してクリックすると大きくなるページを想定)。</p>
<p>使ってるマシンの CPU コア数分だけプロセス作って、そいつらで並列に画像をダウンロードするからそれなりに速いと思う。
コアあたりスレッド2つで動くなら、 CPU の数 * 2でやるともっと速いかもね。</p>
<div class="highlight"><pre><span></span><span class="c1">#-*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">urllib</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">from</span> <span class="nn">urlparse</span> <span class="kn">import</span> <span class="n">urljoin</span>
<span class="kn">from</span> <span class="nn">BeautifulSoup</span> <span class="kn">import</span> <span class="n">BeautifulSoup</span>
<span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">Pool</span><span class="p">,</span>
<span class="n">cpu_count</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">IMAGE_EXTS</span> <span class="o">=</span> <span class="p">[</span><span class="sa">u</span><span class="s1">'jpg'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'jpeg'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'png'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'gif'</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">get_args</span><span class="p">():</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">()</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'url'</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'ダウンロードしたい画像があるウェブページのURL'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'directory'</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'ダウンロードした画像を入れるディレクトリ'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'-e'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'--ext'</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="sa">u</span><span class="s1">'append'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="p">[],</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'jpg, jpeg, png, gifの他にダウンロードしたい画像拡張子 [複数指定可能]'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'-d'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'--domain'</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="sa">u</span><span class="s1">'append'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="p">[],</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'ダウンロードする画像があるドメインを制限する [複数指定可能]'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">get_html_source</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="k">if</span> <span class="mi">200</span> <span class="o"><</span> <span class="n">entry</span><span class="o">.</span><span class="n">code</span> <span class="o"><</span> <span class="mi">300</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">()</span>
<span class="k">return</span> <span class="n">unicode</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">get_pictures_list</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">is_valid_img</span><span class="p">):</span>
<span class="n">pictures</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">soup</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">get_html_source</span><span class="p">(</span><span class="n">url</span><span class="p">))</span>
<span class="k">for</span> <span class="n">img</span> <span class="ow">in</span> <span class="n">soup</span><span class="o">.</span><span class="n">findAll</span><span class="p">(</span><span class="s1">'img'</span><span class="p">):</span>
<span class="k">if</span> <span class="n">is_valid_img</span><span class="p">(</span><span class="n">img</span><span class="p">[</span><span class="sa">u</span><span class="s1">'src'</span><span class="p">]):</span>
<span class="k">if</span> <span class="n">img</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'a'</span>\
<span class="ow">and</span> <span class="n">is_valid_img</span><span class="p">(</span><span class="n">img</span><span class="o">.</span><span class="n">parent</span><span class="p">[</span><span class="sa">u</span><span class="s1">'href'</span><span class="p">]):</span>
<span class="n">pictures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">urljoin</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">img</span><span class="o">.</span><span class="n">parent</span><span class="p">[</span><span class="sa">u</span><span class="s1">'href'</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">pictures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">urljoin</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">img</span><span class="p">[</span><span class="sa">u</span><span class="s1">'src'</span><span class="p">]))</span>
<span class="k">return</span> <span class="n">pictures</span>
<span class="k">def</span> <span class="nf">get_img_validator</span><span class="p">(</span><span class="n">exts</span><span class="o">=</span><span class="p">[],</span> <span class="n">domains</span><span class="o">=</span><span class="p">[]):</span>
<span class="n">patterns</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">exts</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="n">patterns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">ur</span><span class="s1">'\.(</span><span class="si">%s</span><span class="s1">)$'</span> <span class="o">%</span> <span class="n">ur</span><span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">exts</span><span class="p">),</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">))</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">domains</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="n">domains</span> <span class="o">=</span> <span class="p">[</span><span class="n">domain</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">u</span><span class="s1">'.'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'\.'</span><span class="p">)</span> <span class="k">for</span> <span class="n">domain</span> <span class="ow">in</span> <span class="n">domains</span><span class="p">]</span>
<span class="n">patterns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
<span class="n">ur</span><span class="s1">'^((https?://([^.]+\.)*</span><span class="si">%s</span><span class="s1">/)|(?!http))'</span> <span class="o">%</span> <span class="n">ur</span><span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">domains</span><span class="p">),</span>
<span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">is_valid_img</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
<span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">patterns</span><span class="p">:</span>
<span class="k">if</span> <span class="n">pattern</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">url</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">is_valid_img</span>
<span class="k">def</span> <span class="nf">downloader</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
<span class="n">url</span><span class="p">,</span> <span class="n">savepath</span> <span class="o">=</span> <span class="n">arg</span>
<span class="n">urllib</span><span class="o">.</span><span class="n">urlretrieve</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">savepath</span><span class="p">,</span> <span class="n">url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">u</span><span class="s1">'/'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">def</span> <span class="nf">save_pictures</span><span class="p">(</span><span class="n">pictures</span><span class="p">,</span> <span class="n">savepath</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">savepath</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">Exception</span>
<span class="n">pool</span> <span class="o">=</span> <span class="n">Pool</span><span class="p">(</span><span class="n">cpu_count</span><span class="p">())</span>
<span class="n">pool</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="n">downloader</span><span class="p">,</span> <span class="p">[(</span><span class="n">url</span><span class="p">,</span> <span class="n">savepath</span><span class="p">)</span> <span class="k">for</span> <span class="n">url</span> <span class="ow">in</span> <span class="n">pictures</span><span class="p">])</span>
<span class="n">pool</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">pool</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">()</span>
<span class="n">pictures</span> <span class="o">=</span> <span class="n">get_pictures_list</span><span class="p">(</span>
<span class="n">args</span><span class="o">.</span><span class="n">url</span><span class="p">,</span> <span class="n">get_img_validator</span><span class="p">(</span><span class="n">IMAGE_EXTS</span> <span class="o">+</span> <span class="n">args</span><span class="o">.</span><span class="n">ext</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">domain</span><span class="p">))</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">pictures</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="n">save_pictures</span><span class="p">(</span><span class="n">pictures</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">directory</span><span class="p">))</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
socket でサーバー - クライアント型のチャットソフト作った。2012-06-16T00:00:00+09:002012-06-16T00:00:00+09:00yosida95tag:yosida95.com,2012-06-16:/2012/06/16/210334.html<p>ぼくが Python 始めたての頃 …</p><p>ぼくが Python 始めたての頃にも socket でチャット作ろうとしていろんな人のブログ記事でコード読んでまわったんだけど、 1:1 でしかやり取りできなかったり、「サーバー側でも発言できるようにしてみました」とか言ってて混沌としてたために、実装できずじまいだった。</p>
<p>そのことを<a class="reference external" href="http://www.python.jp/doc/nightly/howto/sockets.html">ソケットプログラミング HOWTO — Python 2.7ja1 documentation</a> 読んでたら思い出したので作ってみた。
一日くらいかかったけど特に躓くことなく作れたので、 curses でちょっとビジュアライズなクライアント作ってみたらこいつが思いの外クセモノだった。</p>
<p>ソースコードはここに置いてある。
<a class="reference external" href="http://bitbucket.org/yosida95/socket-chat">yosida95 / Socket Chat / overview — Bitbucket</a>。
gist に貼り付けるにはちょっと頑張りすぎたので、リポジトリとして公開してある。</p>
<p>実験してないけど、理論的にはネットワーク帯域食いつぶすまでクライアント増やせるはず。
詳しいことはコード読んでね。</p>
Event Search をアップデートしました2012-06-15T00:00:00+09:002012-06-15T00:00:00+09:00yosida95tag:yosida95.com,2012-06-15:/2012/06/15/032549.html<p>昨6月14日に <a class="reference external" href="http://event.yosida95.com/">Event Search</a> (旧: ATND を検索す …</p><p>昨6月14日に <a class="reference external" href="http://event.yosida95.com/">Event Search</a> (旧: ATND を検索するアレ)をアップデートいたしました。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/yosida95">@yosida95</a> お待たせいたしました。connpassのイベント検索APIを公開いたしましたので、是非ご利用下さい。 <a href="http://t.co/YZZi1dqr">http://t.co/YZZi1dqr</a></p>— connpass (@connpass_jp) <a href="https://twitter.com/connpass_jp/status/192420486737707009">April 18, 2012</a></blockquote><p>従来は ATND BETA の API を JSONP で呼び出す事によって、 ATND BETA に登録されているイベントのみを検索していただくことが可能でした。</p>
<p>しかし、今回のアップデートによって主要イベント支援サービスである <a class="reference external" href="http://atnd.org/beta">ATND BETA</a> 、 <a class="reference external" href="http://connpass.com/">connpass</a> 、 <a class="reference external" href="http://zusaar.com">Zusaar</a> をまとめて一挙に検索することが可能になりました。</p>
<p>検索パラメータとしてご利用いただけるのはフリーワード(タイトル、キャッチコピー、説明文対象)、主催者のイベントサイト上でのニックネーム、 Twitter ID ( ATND のみ ) 、参加者のイベントサイト上でのニックネーム ( connpass 非対応 )、 Twitter ID ( ATND のみ、 connpass 非対応)、開催日(範囲さえも指定できます)の4つです。</p>
<p>さらに、これらの検索結果の RSS と Google Calendar ( iCalendar 形式 )による提供も行なっています。
例えば、気になるワード ( python hack-a-thon ) などの検索結果を RSS で受信していただくことにより、常に最新のイベント情報を受信して頂けます。
また、ご自身のニックネームによる検索結果を Google Calendar で受け取っていただくことにより、参加イベントが自動的に Google Calendar に追加されます。</p>
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">connpassを含めて頂き有難うございます! RT <a href="https://twitter.com/yosida95">@yosida95</a> ATNDを検索するアレは、ATND BETA, conpass, Zusaarをまとめて検索できるツールとして生まれかわりました。<a href="http://t.co/2PoLK33L">http://t.co/2PoLK33L</a></p>— connpass (@connpass_jp) <a href="https://twitter.com/connpass_jp/status/213084000296767488">June 14, 2012</a></blockquote>はてなキーワード、または Wikipedia のタイ卜ルから MeCab 用の CSV ファイルを生成するマン2012-06-10T00:00:00+09:002012-06-10T00:00:00+09:00yosida95tag:yosida95.com,2012-06-10:/2012/06/10/164239.html<div class="section" id="section-1">
<h2>データ入手元</h2>
<div class="section" id="wikipedia">
<h3>Wikipedia</h3>
<p><a class="reference external" href="http://dumps.wikimedia.org/jawiki/latest/">http://dumps.wikimedia …</a></p></div></div><div class="section" id="section-1">
<h2>データ入手元</h2>
<div class="section" id="wikipedia">
<h3>Wikipedia</h3>
<p><a class="reference external" href="http://dumps.wikimedia.org/jawiki/latest/">http://dumps.wikimedia.org/jawiki/latest/</a></p>
<p>jawiki-latest-all-titles-in-ns0</p>
</div>
<div class="section" id="section-2">
<h3>はてなキーワード</h3>
<p><a class="reference external" href="http://d.hatena.ne.jp/hatenadiary/20060922/1158908401">http://d.hatena.ne.jp/hatenadiary/20060922/1158908401</a></p>
<p>keywordlist_furigana.csv</p>
</div>
</div>
<div class="section" id="python">
<h2>Python スクリプト</h2>
<div class="highlight"><pre><span></span><span class="c1">#-*- coding: utf-8 -*-</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">csv</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">import</span> <span class="nn">htmlentitydefs</span>
<span class="kn">import</span> <span class="nn">unicodedata</span>
<span class="kn">from</span> <span class="nn">BeautifulSoup</span> <span class="kn">import</span> <span class="n">BeautifulSoup</span>
<span class="n">ignores</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">ur</span><span class="s1">'^[1-9][0-9]*年(代?の(オリンピックサッカー競技|スポーツ|メジャーリーグベースボール|ワールドシリーズ|航空|野球|バレーボール|美術|建築)|(全米テニス選手権|全米選手権_\(テニス\)|全豪テニス選手権|民主党全国大会|アメリカ合衆国大統領選挙|ウィンブルドン選手権|オーストラレーシアン選手権)|代)?$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^([1-9]|1[012])月([1-9]|[12][0-9]|3[01]日)?$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^[0-9]+$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^.{1,}記号$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^.+_\(.+\)$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^([a-zA-Z0-9-]+)(\.[a-zA-Z0-9-]+){1,}'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'^[^\w\d]+$'</span><span class="p">,</span>
<span class="n">ur</span><span class="s1">'[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">chr</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">32</span><span class="p">)]),</span>
<span class="p">]</span>
<span class="n">ignore_pattern</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">ur</span><span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">ignores</span><span class="p">),</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">arg_parse</span><span class="p">():</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span>
<span class="n">description</span><span class="o">=</span><span class="sa">u</span><span class="s1">'はてなキーワード, またはWikipediaのタイ卜ルからMeCab用のcsvファイルを生成するマン'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'--source'</span><span class="p">,</span> <span class="n">choices</span><span class="o">=</span><span class="p">(</span><span class="sa">u</span><span class="s1">'hatena'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'wikipedia'</span><span class="p">),</span>
<span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'inputの取得元'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'input'</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="n">argparse</span><span class="o">.</span><span class="n">FileType</span><span class="p">(</span><span class="sa">u</span><span class="s1">'r'</span><span class="p">),</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'配布元からダウンロードしてきたcsvファイル'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="sa">u</span><span class="s1">'output'</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="n">argparse</span><span class="o">.</span><span class="n">FileType</span><span class="p">(</span><span class="sa">u</span><span class="s1">'w+'</span><span class="p">),</span>
<span class="n">help</span><span class="o">=</span><span class="sa">u</span><span class="s1">'MeCab用に変換したcsvファイルの出力先'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">text_normalize</span><span class="p">(</span><span class="n">sentence</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sentence</span><span class="p">,</span> <span class="n">unicode</span><span class="p">)</span>
<span class="c1"># html remove</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">sentence</span><span class="p">)</span><span class="o">.</span><span class="n">text</span>
<span class="c1"># remove url</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">'https?(:\/\/[-_.!~*</span><span class="se">\'</span><span class="s1">()a-zA-Z0-9;\/?:\@&=+\$,%#]+)'</span><span class="p">,</span>
<span class="sa">u</span><span class="s1">''</span><span class="p">,</span> <span class="n">sentence</span><span class="p">)</span>
<span class="c1"># replace html entity</span>
<span class="n">matches</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">'(&#(x?)([0-9a-fA-F]+);?)'</span><span class="p">,</span> <span class="n">sentence</span><span class="p">)</span>
<span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">unichr</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">match</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="mi">16</span> <span class="k">if</span> <span class="n">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'x'</span> <span class="k">else</span> <span class="mi">10</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">sentence</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">match</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">result</span><span class="p">)</span>
<span class="n">matches</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s1">'(&([a-zA-Z]+);?)'</span><span class="p">,</span> <span class="n">sentence</span><span class="p">)</span>
<span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">htmlentitydefs</span><span class="o">.</span><span class="n">name2codepoint</span><span class="p">[</span><span class="n">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">sentence</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">match</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">unichr</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
<span class="c1"># replace wave tilde to long</span>
<span class="n">dashes</span> <span class="o">=</span> <span class="p">[</span><span class="sa">u</span><span class="s1">'</span><span class="se">\u2013</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2014</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2015</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2053</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2212</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2500</span><span class="s1">'</span><span class="p">,</span>
<span class="sa">u</span><span class="s1">'</span><span class="se">\u2501</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u254C</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u254D</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2574</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2576</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u2578</span><span class="s1">'</span><span class="p">,</span>
<span class="sa">u</span><span class="s1">'</span><span class="se">\u257A</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u301c</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u3030</span><span class="s1">'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\uff5e</span><span class="s1">'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">dash</span> <span class="ow">in</span> <span class="n">dashes</span><span class="p">:</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">sentence</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">dash</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u30fc</span><span class="s1">'</span><span class="p">)</span>
<span class="c1"># unitify long repeats</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">ur</span><span class="s1">'</span><span class="se">\u30fc</span><span class="s1">{2,}'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'</span><span class="se">\u30fc</span><span class="s1">'</span><span class="p">,</span> <span class="n">sentence</span><span class="p">)</span>
<span class="c1"># NFKC normalization</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">normalize</span><span class="p">(</span><span class="sa">u</span><span class="s1">'NFKC'</span><span class="p">,</span> <span class="n">sentence</span><span class="p">)</span>
<span class="c1"># Lower</span>
<span class="n">sentence</span> <span class="o">=</span> <span class="n">sentence</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">return</span> <span class="n">sentence</span>
<span class="k">def</span> <span class="nf">convert_hatena_keyword</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="n">output</span><span class="p">):</span>
<span class="n">csv_writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">input</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="sa">u</span><span class="s1">'euc-jp'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'replace'</span><span class="p">)</span>
<span class="n">keyword</span> <span class="o">=</span> <span class="n">text_normalize</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">u</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">elif</span> <span class="n">ignore_pattern</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">cost</span> <span class="o">=</span> <span class="n">unicode</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">36000</span><span class="p">,</span> <span class="o">-</span><span class="mi">400</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="o">**</span> <span class="mf">1.5</span><span class="p">)))</span>
<span class="n">csv_writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">([</span><span class="n">value</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="sa">u</span><span class="s1">'euc-jp'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'replace'</span><span class="p">)</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="p">[</span>
<span class="n">keyword</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'0'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'0'</span><span class="p">,</span> <span class="n">cost</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'名詞'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'一般'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span>
<span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="n">keyword</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'はてなキーワード'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">''</span><span class="p">]])</span>
<span class="k">def</span> <span class="nf">convert_wikipedia_titles</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="n">output</span><span class="p">):</span>
<span class="n">csv_writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">input</span><span class="p">:</span>
<span class="n">keyword</span> <span class="o">=</span> <span class="n">text_normalize</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="sa">u</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'replace'</span><span class="p">))</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">elif</span> <span class="n">ignore_pattern</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">cost</span> <span class="o">=</span> <span class="n">unicode</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">36000</span><span class="p">,</span> <span class="o">-</span><span class="mi">400</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">keyword</span><span class="p">)</span> <span class="o">**</span> <span class="mf">1.5</span><span class="p">)))</span>
<span class="n">csv_writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">([</span><span class="n">value</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="sa">u</span><span class="s1">'euc-jp'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'replace'</span><span class="p">)</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="p">[</span>
<span class="n">keyword</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'0'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'0'</span><span class="p">,</span> <span class="n">cost</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'名詞'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'一般'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span>
<span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="n">keyword</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'*'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'Wikipedia'</span><span class="p">,</span> <span class="sa">u</span><span class="s1">''</span><span class="p">]])</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">arg_parse</span><span class="p">()</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">source</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'hatena'</span><span class="p">:</span>
<span class="n">convert_hatena_keyword</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">input</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">args</span><span class="o">.</span><span class="n">source</span> <span class="o">==</span> <span class="sa">u</span><span class="s1">'wikipedia'</span><span class="p">:</span>
<span class="n">convert_wikipedia_titles</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">input</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<div class="section" id="section-3">
<h2>ごめんなさい</h2>
<p>生起コストの計算がちゃんとしてなくてごめんなさい。</p>
</div>
<div class="section" id="section-4">
<h2>参考</h2>
<p><a class="reference external" href="http://blog.livedoor.jp/techblog/archives/65828235.html">livedoor Techブログ : wikipediaのデータや顔文字辞書からmecabのユーザ辞書を作成するフレームワーク</a></p>
</div>
6月になりました2012-06-06T00:00:00+09:002012-06-06T00:00:00+09:00yosida95tag:yosida95.com,2012-06-06:/2012/06/06/170805.html<p>今日の10日後、6月16日は私の誕生日ですね。
いささか早 …</p><p>今日の10日後、6月16日は私の誕生日ですね。
いささか早くはありますが、なんと <a class="reference external" href="http://twitter.com/daisuke_nomura">@daisuke_nomura</a> さんと <a class="reference external" href="http://twitter.com/usaturn">@usaturn</a> さんから書籍を頂きました!</p>
<p>@daisuke_nomura さんからは「<a class="reference external" href="http://www.amazon.co.jp/dp/4894712741">達人プログラマー―システム開発の職人から名匠への道</a>」を、 @usaturn さんからは「 <a class="reference external" href="http://www.amazon.co.jp/dp/4798032948">Python プロフェッショナルプログラミング</a>」をいただきました。
いずれも私がとても読みたいと思っていた本です ( ウィッシュリストに載せてあったので当たり前ではありますが ) 。
本当にありがとうございます!</p>
<p>さて。
私の誕生日は先に述べたとおり6月16日です。
まだ10日あります。</p>
<p>なお、Amazon ウィッシュリストはこちらで公開しています。
<a class="reference external" href="http://amzn.to/yosida95">http://amzn.to/yosida95</a></p>
ご苦労さまでした2012-05-30T00:00:00+09:002012-05-30T00:00:00+09:00yosida95tag:yosida95.com,2012-05-30:/2012/05/30/170937.html<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1">#-*- coding: utf-8 -*-</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randrange …</span></pre></div><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1">#-*- coding: utf-8 -*-</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randrange</span>
<span class="n">LENGTH_OF_INT</span> <span class="o">=</span> <span class="mi">5</span>
<span class="k">def</span> <span class="nf">prime_list</span><span class="p">(</span><span class="n">limit</span><span class="p">):</span>
<span class="n">primes</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="p">[</span><span class="kc">True</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">limit</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">number</span><span class="p">,</span> <span class="n">is_prime</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">tmp</span><span class="p">):</span>
<span class="k">if</span> <span class="n">is_prime</span><span class="p">:</span>
<span class="n">primes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">number</span> <span class="o">*</span> <span class="mi">2</span><span class="p">,</span> <span class="n">limit</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
<span class="n">tmp</span><span class="p">[</span><span class="n">_</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">primes</span>
<span class="k">def</span> <span class="nf">prime_range</span><span class="p">(</span><span class="n">offset</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">_offset</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">limit</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">offset</span>
<span class="n">_limit</span> <span class="o">=</span> <span class="n">offset</span> <span class="k">if</span> <span class="n">limit</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">limit</span>
<span class="n">primes</span> <span class="o">=</span> <span class="n">prime_list</span><span class="p">(</span><span class="n">_limit</span><span class="p">)</span>
<span class="n">begin</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">primes</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">while</span> <span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">begin</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
<span class="n">middle</span> <span class="o">=</span> <span class="p">(</span><span class="n">begin</span> <span class="o">+</span> <span class="n">end</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span>
<span class="k">if</span> <span class="n">primes</span><span class="p">[</span><span class="n">middle</span><span class="p">]</span> <span class="o">></span> <span class="n">_offset</span><span class="p">:</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">middle</span>
<span class="k">elif</span> <span class="n">primes</span><span class="p">[</span><span class="n">middle</span><span class="p">]</span> <span class="o"><=</span> <span class="n">offset</span><span class="p">:</span>
<span class="n">begin</span> <span class="o">=</span> <span class="n">middle</span>
<span class="k">return</span> <span class="n">primes</span><span class="p">[</span><span class="n">end</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">primes</span><span class="p">[</span><span class="n">end</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">>=</span> <span class="n">offset</span> <span class="k">else</span> <span class="n">end</span><span class="p">:]</span>
<span class="k">def</span> <span class="nf">ex_euclid</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">x1</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="n">y0</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">b</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">a</span> <span class="o">//</span> <span class="n">b</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span> <span class="o">%</span> <span class="n">b</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">x1</span> <span class="o">=</span> <span class="n">x1</span> <span class="o">-</span> <span class="n">q</span> <span class="o">*</span> <span class="n">x0</span><span class="p">,</span> <span class="n">x0</span>
<span class="n">y0</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">y1</span> <span class="o">-</span> <span class="n">q</span> <span class="o">*</span> <span class="n">y0</span><span class="p">,</span> <span class="n">y0</span>
<span class="k">return</span> <span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">a</span>
<span class="k">def</span> <span class="nf">generate_key_pair</span><span class="p">(</span><span class="n">prime_table</span><span class="p">):</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">q</span> <span class="o">=</span> <span class="n">prime_table</span><span class="p">[</span><span class="n">randrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">prime_table</span><span class="p">))]</span>
<span class="k">while</span><span class="p">(</span><span class="n">p</span> <span class="o">==</span> <span class="n">q</span><span class="p">):</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">prime_table</span><span class="p">[</span><span class="n">randrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">prime_table</span><span class="p">))]</span>
<span class="n">n</span> <span class="o">=</span> <span class="n">p</span> <span class="o">*</span> <span class="n">q</span>
<span class="n">modulo</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">q</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">int_gen</span> <span class="o">=</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">randrange</span><span class="p">(</span><span class="mi">10</span> <span class="o">**</span> <span class="p">(</span><span class="n">LENGTH_OF_INT</span> <span class="o">-</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">LENGTH_OF_INT</span><span class="p">)</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">int_gen</span><span class="p">()</span>
<span class="n">d</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">gcd</span> <span class="o">=</span> <span class="n">ex_euclid</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">modulo</span><span class="p">)</span>
<span class="k">while</span> <span class="n">gcd</span> <span class="ow">is</span> <span class="ow">not</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">int_gen</span><span class="p">()</span>
<span class="n">d</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">gcd</span> <span class="o">=</span> <span class="n">ex_euclid</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">modulo</span><span class="p">)</span>
<span class="k">return</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">prime_table</span> <span class="o">=</span> <span class="n">prime_range</span><span class="p">(</span><span class="mi">10</span> <span class="o">**</span> <span class="p">(</span><span class="n">LENGTH_OF_INT</span> <span class="o">-</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">LENGTH_OF_INT</span><span class="p">)</span>
<span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="n">generate_key_pair</span><span class="p">(</span><span class="n">prime_table</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
No Title (近況報告)2012-05-15T00:00:00+09:002012-05-15T00:00:00+09:00yosida95tag:yosida95.com,2012-05-15:/2012/05/15/082821.html<p>例えば、お母さんに料理 …</p><p>例えば、お母さんに料理や手芸を習っていた子が、技術の更なる向上を望んで3年間でそれらを学ぶ教室に入った。</p>
<p>しかし初回の授業で入門以前の事をやられ違和感を持つ。
二回目以降もその状況に変わりはなかったが、二年目からは各自の希望と特性に応じてコース分けがされるのでそれに期待してモチベーションを保った。</p>
<p>いざ待ちに待った二年目が始まって彼女は自分が希望したコースで学べる事になったが、授業の内容は一年時と何ら変わりがなかった。
このままのペースで行くと卒業時までに何ら新しい事を学べない可能性が少なからずあることに気づく。
その事によりこれまで何とか繋いできた糸がプツンと切れてしまった。</p>
<p>自宅にいる自由な時間で技術の向上を図るが、通学にかかる時間や、進級に圧倒的影響を持つ絶対にやらなければならない課題をこなす時間がかかることと、そもそも授業自体の時間が長いことによって、取れた自由な時間は糞の足しにもならないことに彼女は絶望した。</p>
見てるなう(仮)を作った2012-04-28T00:00:00+09:002012-04-28T00:00:00+09:00yosida95tag:yosida95.com,2012-04-28:/2012/04/28/235534.html<p>先程のエントリでも触 …</p><p>先程のエントリでも触れられてるけど、改めて。</p>
<p>hinatter が運営していた「<a class="reference external" href="http://miteru.gkbr.me">見てるなう</a>」の後継サービスとしてリリースされた「<a class="reference external" href="http://miteru.odiak.net/">みてるなう</a>」が先程まで Bad Gateway エラーを吐いて使えなかったので、カフェに居たぼくはその場のノリで MacBook Air を取り出して、 hinatter オリジナルに近い「<a class="reference external" href="https://miteru.yosida95.com/">見てるなう(仮)</a>」を制作し、リリースしました。</p>
<p>2時間足らずで製作したものですが、従来の見てるなう同様ブックマークレットから簡単に投稿画面を呼べ、必要に応じてコメントを付加して Twitter に投稿することができます。</p>
<p>なお、 Twitter の OAuth Access Token をブックマークレットの中にハードコードして、投稿ページには GET で渡しています。
これもオリジナルと同じ仕様です。</p>
<p>ご承知だとは思いますが、投稿画面 URL 、あるいはブックマークレットを他人に見せてはいけません。
第三者にあなたのアカウントを使って勝手に見てるなうされます。</p>
<p>【見てるなう(仮) <a class="reference external" href="http://miteru.yosida95.com">http://miteru.yosida95.com</a>】よろしくお願いします。</p>
プログラミング生放送勉強会14@品川で LT をしてきました #pronama2012-04-08T00:00:00+09:002012-04-08T00:00:00+09:00yosida95tag:yosida95.com,2012-04-08:/2012/04/08/120455.html<p>昨7日に行われた<a class="reference external" href="http://atnd.org/events/26346">プログラミング生 …</a></p><p>昨7日に行われた<a class="reference external" href="http://atnd.org/events/26346">プログラミング生放送勉強会14@品川</a>に参加してきました。
そこで、プロ生ちゃんより年下のぼくが LT をさせて頂きました。</p>
<p>タイトルは「 Python meets MongoDB 」です。
仰々しいタイトルですが、内容は先日公開したサービス <a class="reference external" href="http://twit.yosida95.com/">#TwitActivity</a> のステマです。</p>
<p>スライドは Sperker Deck に公開してあります。</p>
<script src="http://speakerdeck.com/embed/4f7fd8dea38af3001f00162d.js"></script><p>最後のスライドに私からのメッセージを追加しておきました。
何卒よろしくおねがいします。</p>
<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/sm17501045"></script><p>17:28あたりから</p>
私はいかにして Web2.0 を極めたか2012-04-01T00:00:00+09:002012-04-01T00:00:00+09:00yosida95tag:yosida95.com,2012-04-01:/2012/04/01/222721.html<p>今日、私はここに Web2.0 を …</p><p>今日、私はここに Web2.0 を極めた事を宣言する。</p>
<div class="section" id="web2-0-1">
<h2>0 Web2.0 とは</h2>
<div class="line-block">
<div class="line">Web 2.0 (ウェブにいてんれい、ウェブにいてんゼロ、ウェブ・ツー・ポイント・オー)とは、2000年代中頃以降における、ウェブの新しい利用法。</div>
<div class="line">ティム・オライリーによって提唱された概念。狭義には、旧来は情報の送り手と受け手が固定され送り手から受け手への一方的な流れであった状態が、送り手と受け手が流動化し誰もがウェブを通して情報を発信できるように変化したwebの利用状態のこと。</div>
<div class="line">「<a class="reference external" href="http://ja.wikipedia.org/wiki/Web%202.0">Web 2.0</a> 」より引用</div>
</div>
<p>正直ナニを言っているのかとんと理解できないが、要するに従来の Web がバージョンアップした、今までよりもワンダフルでエクセレントな Web を Web2.0 とする。</p>
<p>例えば Gmail 、例えば Google Maps 。
Web そのものをプラットフォームとしてサービスを提供しリッチなユーザー体験がもたらされた頃、人々はこぞって Web2.0 という言葉を使用して持て囃した。</p>
</div>
<div class="section" id="web2-0-2">
<h2>1 なぜ今 Web2.0 なのか</h2>
<p>上記の Wikipedia からの引用の通り、 Web2.0 は2000年頃に騒がれたバズワードであり、近頃は耳にする機会も減少してきた。
それなのに、なぜ12年も経った今、 Web2.0 なのか。</p>
<p>それはここに紹介する1本のソフトウェアに端を発する。
これだ。
<img alt="Web 2.0 を極める" src="https://blogmedia.yosida95.com/2012/04/01/222721/package.jpg" style="width: 100%;" /></p>
<p>このキャッチーなタイトルに惹かれた。
「 Web2.0 を極める」。
このソフトウェアを、なんと初対面の <a class="reference external" href="http://twitter.com/grapswiz">@grapswiz</a> さんに買って頂けたのだ。</p>
<p>そのような経緯で入手した「 Web2.0 を極める」。
購入していただいた恩に報いるため、誠心誠意 Web2.0 を学び、ついに今日極めることに成功し、ここにペンを執った次第だ。</p>
</div>
<div class="section" id="section-1">
<h2>2 ソフトウェアの内容</h2>
<p><img alt="タイトル画面" src="https://blogmedia.yosida95.com/2012/04/01/222721/title.png" style="width: 100%;" />
このソフトウェアは以下のような構成で、いずれも綺麗なお姉さんにつきっきりで解説していただける。</p>
<dl class="docutils">
<dt>Google</dt>
<dd><ul class="first last simple">
<li>「キーワード検索」でネットを使いこなそう</li>
<li>グーグル検索の基本を覚えよう</li>
<li>複雑な検索を行なってみよう</li>
<li>特殊な情報を検索してみよう</li>
<li>検索オプションでより深く情報を探しだそう</li>
<li>キーワードを整理して、的確に検索してみよう</li>
</ul>
</dd>
<dt>Blog</dt>
<dd><ul class="first last simple">
<li>ブログって何だろう?</li>
<li>ブログを開設してみよう</li>
<li>ブログを書いてみよう</li>
<li>デザインを変えてみよう</li>
<li>おこづかいを稼いでみよう</li>
<li>読んでもらえる記事を書くコツ</li>
<li>トラブルに気をつけよう(ブログ編)</li>
</ul>
</dd>
<dt>Web2.0</dt>
<dd><ul class="first last simple">
<li>ウェブメールを活用しよう</li>
<li>流行しているページをチェックしよう</li>
<li>Web 百科事典を活用しよう</li>
<li>最新情報を手軽n入手しよう</li>
<li>情報付きの地図を利用しよう</li>
<li>ネットでみんなの動画を見よう</li>
<li>ネットでみんなとスケジュールを管理しよう</li>
<li>ネットでみんなと交流しよう</li>
<li>トラブルに気をつけよう(ネットマナー編)</li>
</ul>
</dd>
</dl>
<p>Google の項では検索の基本的なやり方に始まり、 Pagerank や I'm Feeling Lucky 、 Adwords などの Google 特有のサービス、 define 等の検索演算子、アスタリスクによる曖昧検索まで解説してくれる。</p>
<p>Blog の項ではそもそもブログとはなんぞやという所から始まって、 Libedoor ブログを例にブログ開設の仕方、ブログの書き方、そしてデザインのカスタマイズ、さらにはアフィリエイト、果てはトラブルに巻き込まれない利用方法まで幅広く解説してくれる。</p>
<p>ソフトウェアのタイトルにまで冠された Web2.0 の項では、 Gmail や Livedoor クリップ 、 Wikipedia 、 goo RSS リーダー、 Windows Live Search 、 goo 地図、 YouTube 、 Google Calendar 、 mixi を例に各サービスの利用方法や各種設定方法に触れ、実際に Web2.0 がもたらす便利なサービスを紹介している。
加えて、ここでも安心してネットを利用する方法も説明してくれる。</p>
<p>これだけ盛りだくさんの内容で、それを一貫して綺麗なお姉さんがつきっきりで教えてくれる、なんとも素晴らしいソフトウェアである。</p>
<p><img alt="お姉さん 2.0" src="https://blogmedia.yosida95.com/2012/04/01/222721/guide.png" style="width: 100%;" />
解説してくれるお姉さん</p>
</div>
<div class="section" id="section-2">
<h2>3 所感</h2>
<p>このソフトウェアはぼくに Web 2.0 がもたらす便利で明るい未来を教えてくれた。
そして、ぼくが Web 2.0 を極めるきっかけを与えてくれ、実際に Web 2.0 を極めることまでできた。</p>
<p>これまでただ情報を受取る側であった私達が、 Web 2.0 の普及により簡単に情報を発信する側になった。</p>
<p>それによって注意する必要が生じた事が、個人情報のより扱いや Web で発言することによって生じるであろう他人との衝突である。
このソフトウェアでは、そこも丁寧にサポートしてくれる。</p>
</div>
<div class="section" id="section-3">
<h2>4 まとめ</h2>
<p>2012年の今、改めて Web 2.0 に触れて極めることで、 Web の未来を考えて、開発者の立場として未来を作っていきたいものです。</p>
<p>みなさんも「 Web 2.0 を極める」を購入して Web 2.0 を極めましょう。</p>
<p>※今日はエイプリールフールです。</p>
</div>
プロセス監視ツール Supervisor を導入する2012-03-22T00:00:00+09:002012-03-22T00:00:00+09:00yosida95tag:yosida95.com,2012-03-22:/2012/03/22/030615.html<div class="section" id="section-1">
<h2>1 インストール</h2>
<p>PyPI に登 …</p></div><div class="section" id="section-1">
<h2>1 インストール</h2>
<p>PyPI に登録されているので pip でインストールできます。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>supervisor
</pre></div>
<p>pip がインストールされていない場合は、 pip を入れるなり Supervisor をソースから入れるなりして自力でがんばってください。
pip は大抵の場合 python-pip とかそんな雰囲気の名前で OS の標準リポジトリに登録されています。</p>
</div>
<div class="section" id="section-2">
<h2>2 設定ファイルを書き出す</h2>
<p>Supervisor のインストールが終わると <tt class="docutils literal">echo\_supervisord\_conf</tt> というコマンドが追加されます。
こいつは supervisord の設定ファイルの雛形を標準出力に書き出します。</p>
<p>従って、</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>echo_supervisord_conf<span class="w"> </span>><span class="w"> </span>/etc/supervisord.conf
</pre></div>
<p>とやれば設定ファイルが作成されます。</p>
</div>
<div class="section" id="section-3">
<h2>3 最低限の設定をする</h2>
<div class="highlight"><pre><span></span><span class="gu">0a1,2</span>
<span class="gi">> ; Sample supervisor config file.</span>
>
<span class="gu">3,6c5,8</span>
<span class="gd">< chmod=0700 ; ソケットファイルの権限</span>
<span class="gd">< chown=www-data:www-data ; ソケットファイルのオーナーユーザー, グループ。ウェブサーバーの実行ユーザーが望ましい。</span>
<span class="gd">< username=user ; ウェブコンパネにアクセスするためのユーザー名</span>
<span class="gd">< password=pass ; ウェブコンパネにアクセスするためのパスワード</span>
<span class="gd">-</span>
<span class="gi">> ;chmod=0700 ; socket file mode (default 0700)</span>
<span class="gi">> ;chown=nobody:nogroup ; socket file uid:gid owner</span>
<span class="gi">> ;username=user ; (default is no username (open server))</span>
<span class="gi">> ;password=123 ; (default is no password (open server))</span>
14c16
<span class="gd">< logfile=/var/log/supervisord.log ; supervisord自体のログファイルのパス</span>
<span class="gd">-</span>
<span class="gi">> logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)</span>
18c20
<span class="gd">< pidfile=/var/run/supervisord.pid ; supervisord自体のpidファイルのパス</span>
<span class="gd">-</span>
<span class="gi">> pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)</span>
40,41c42,43
<span class="gd">< username=user ; ウェブコンパネにアクセスするためのユーザー名, 5行目で指定したもの</span>
<span class="gd">< password=pass ;ウェブコンパネにアクセスするためのパスワード, 6行目で指定</span>
<span class="gd">-</span>
<span class="gi">> ;username=chris ; should be same as http_username if set</span>
<span class="gi">> ;password=123 ; should be same as http_password if set</span>
</pre></div>
<p>この例ではウェブコンパネへのアクセスを同一サーバー上に居るウェブサーバーが受付け、それを UNIX socket にリバースプロキシする想定で設定しています。
TCP socket を利用したい場合は [unix_http_server] ディレクティブをコメントアウトして、代わりに [inet_http_server] を設定してください。</p>
<p>参考までに <tt class="docutils literal"><span class="pre">http://[server]/supervisor/</span></tt> でアクセスできるようにする Nginx 設定ファイルの記述例を挙げておきます。</p>
<div class="highlight"><pre><span></span><span class="k">upstream</span><span class="w"> </span><span class="s">supervisor</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kn">server</span><span class="w"> </span><span class="s">unix:///tmp/supervisor.sock</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">server</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kn">listen</span><span class="w"> </span><span class="mi">80</span><span class="w"> </span><span class="s">default</span><span class="p">;</span>
<span class="w"> </span><span class="kn">server_name</span><span class="w"> </span><span class="s">[server]</span><span class="p">;</span>
<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kn">root</span><span class="w"> </span><span class="s">html</span><span class="p">;</span>
<span class="w"> </span><span class="kn">index</span><span class="w"> </span><span class="s">index.html</span><span class="w"> </span><span class="s">index.htm</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/supervisor/</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1"># 実運用では一般のユーザーにアクセスされないように、allow, denyを使ってアクセス制限するべきです</span>
<span class="w"> </span><span class="kn">rewrite</span><span class="w"> </span><span class="s">^/supervisor(/.*)</span>$<span class="w"> </span><span class="nv">$1</span><span class="w"> </span><span class="s">break</span><span class="p">;</span>
<span class="w"> </span><span class="kn">proxy_pass</span><span class="w"> </span><span class="s">http://supervisor/</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="section-4">
<h2>4 ここまでの動作を確認してみる</h2>
<p>設定ファイルが書き終わり、ウェブコンパネへのアクセス方法も確保できたら、</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>/usr/bin/supervisord<span class="w"> </span>-n
</pre></div>
<p>で起動してみてください。
-n オプションを指定することによりデーモン化されません。
エラーメッセージが出た場合は <tt class="docutils literal">/etc/supervisord.conf</tt> の該当箇所の記述を見直してください。</p>
<p>起動した場合は終了させずに <tt class="docutils literal"><span class="pre">http://[server]/supervisor/</span></tt> へアクセスしてみてください。</p>
<p><img alt="Supervisor" src="https://blogmedia.yosida95.com/2012/03/22/030615/supervisor.png" style="width: 100%;" /></p>
<p>このような画面が表示されたら成功です。
表示されない場合はサーバーの設定ファイルを見なおしてください。</p>
</div>
<div class="section" id="section-5">
<h2>5 監視するプロセスを設定する</h2>
<p>それではいよいよ Supervisor で監視するプロセスを設定してみます。</p>
<p>設定内容を <tt class="docutils literal">/etc/supervisord.conf</tt> にベタ書きしても問題ありませんが、プロセス単位でファイルを分けたほうが管理しやすいと思うので、専用のディレクトリ <tt class="docutils literal">/etc/supervisor.d</tt> を作ってそこに設定ファイルを置いていく形にします。</p>
<div class="section" id="etc-supervisord-conf-include">
<h3>/etc/supervisord.conf の include ディレクティブを設定</h3>
<div class="highlight"><pre><span></span>128,129c130,131
<span class="gd">< [include]</span>
<span class="gd">< files = /etc/supervisor.d/\*.ini</span>
<span class="gd">-</span>
<span class="gi">> ;[include]</span>
<span class="gi">> ;files = relative/directory/\*.ini</span>
</pre></div>
</div>
<div class="section" id="section-6">
<h3>ディレクトリを作成</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>mkdir<span class="w"> </span>/etc/supervisor.d
</pre></div>
</div>
<div class="section" id="section-7">
<h3>設定ファイルを記述</h3>
<div class="highlight"><pre><span></span><span class="c1"># 今回は TwitActivity のバックエンドに使われている uWSGI を Supervisor で管理する想定で書き進めてみます</span>
<span class="k">[program:uwsgi_twitactivity]</span>
<span class="na">command</span><span class="o">=</span><span class="s">/usr/bin/uwsgi --ini-paste /var/www/twit.yosida95.com/production.ini</span><span class="w"> </span><span class="c1">; 実行コマンド</span>
<span class="na">process_name</span><span class="o">=</span><span class="s">%(program_name)s</span><span class="w"> </span><span class="c1">; プロセスの名前, uwsgi_twitactivityに展開される</span>
<span class="na">numprocs</span><span class="o">=</span><span class="s">1</span><span class="w"> </span><span class="c1">; 実行するプロセスの数</span>
<span class="na">autostart</span><span class="o">=</span><span class="s">true</span><span class="w"> </span><span class="c1">; プロセスが死んだ場合自動で再起動するか</span>
<span class="na">user</span><span class="o">=</span><span class="s">www-data</span><span class="w"> </span><span class="c1">; プロセスを実行するユーザー</span>
<span class="na">redirect_stderr</span><span class="o">=</span><span class="s">true</span><span class="w"> </span><span class="c1">; stderrをstdoutにリダイレクトするか</span>
<span class="na">stdout_logfile</span><span class="o">=</span><span class="s">/var/www/twit.yosida95.com/uwsgi.log</span><span class="w"> </span><span class="c1">; stdoutを記録するファイル名</span>
<span class="na">stopsignal</span><span class="o">=</span><span class="s">INT</span><span class="w"> </span><span class="c1">; プロセスが停止するシグナル</span>
<span class="na">environment</span><span class="o">=</span><span class="s">PYTHON_EGG_CACHE=/var/www/twit.yosida95.com/.cache</span><span class="w"> </span><span class="c1">; 実行時に渡される環境変数</span>
</pre></div>
</div>
<div class="section" id="section-8">
<h3>!!注意!!</h3>
<p>監視するプロセスが自分自身でデーモン化しないようにしてください。
自分自身でデーモン化する場合 fork した後自分自身を kill します(参考: <a class="reference external" href="https://yosida95.com/2012/03/03/230238.html">Python のプロセスをデーモン化する</a>)ので、 Supervisor はプロセスが死んだとして起動をリトライします。
しかし、その全てに失敗するので起動に失敗したものとして認識されます。</p>
<p>大抵の自分自身をデーモン化できるサーバープログラムの場合、 daemonize や nodaemon と言ったそれっぽい名前のオプションがあるので、そいつを適切に指定してやってください。</p>
</div>
</div>
<div class="section" id="supervisor-1">
<h2>6 supervisor を起動してみる</h2>
<p>先程の4と同じ手順で起動します。
そして、 <tt class="docutils literal"><span class="pre">http://[server]/supervisor/</span></tt> にアクセスしてみましょう。</p>
<p><img alt="Supervisor uWSGI" src="https://blogmedia.yosida95.com/2012/03/22/030615/supervisor-uwsgi.png" style="width: 100%;" /></p>
<p>ご覧のとおり uwsgi_twitactivity が running として表示されています。
このメニューにある restart などをクリックすれば uWSGI が再起動したりします。</p>
<p>それでは試しに uWSGI をわざと殺して本当に生き返るのか実験してみます。
Supervisord を -n オプションをつけて起動したまま別の端末から次のコマンドを実行してみます。</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span><span class="nb">kill</span><span class="w"> </span>-KILL<span class="w"> </span><span class="nv">$UWSGI_PID</span>
$<span class="w"> </span><span class="c1"># supervisorを起動した端末</span>
<span class="m">2012</span>-03-23<span class="w"> </span><span class="m">01</span>:41:24,346<span class="w"> </span>INFO<span class="w"> </span>exited:<span class="w"> </span>uwsgi_twitactivity<span class="w"> </span><span class="o">(</span>terminated<span class="w"> </span>by<span class="w"> </span>SIGKILL<span class="p">;</span><span class="w"> </span>not<span class="w"> </span>expected<span class="o">)</span>
<span class="m">2012</span>-03-23<span class="w"> </span><span class="m">01</span>:41:25,353<span class="w"> </span>INFO<span class="w"> </span>spawned:<span class="w"> </span><span class="s1">'uwsgi_twitactivity'</span><span class="w"> </span>with<span class="w"> </span>pid<span class="w"> </span><span class="m">20864</span>
<span class="m">2012</span>-03-23<span class="w"> </span><span class="m">01</span>:41:26,895<span class="w"> </span>INFO<span class="w"> </span>success:<span class="w"> </span>uwsgi_twitactivity<span class="w"> </span>entered<span class="w"> </span>RUNNING<span class="w"> </span>state,<span class="w"> </span>process<span class="w"> </span>has<span class="w"> </span>stayed<span class="w"> </span>up<span class="w"> </span><span class="k">for</span><span class="w"> </span>><span class="w"> </span>than<span class="w"> </span><span class="m">1</span><span class="w"> </span>seconds<span class="w"> </span><span class="o">(</span>startsecs<span class="o">)</span>
</pre></div>
<p>こんな感じで生き返ってくれました。</p>
</div>
<div class="section" id="supervisord">
<h2>7 Supervisord を自動起動する</h2>
<p>Supervisor 用に chkconfig 対応起動シェルスクリプトをそれっぽく書いてみました。
※ RHEL 系の場合を想定しています</p>
<div class="section" id="etc-rc-d-init-d-supervisord">
<h3>/etc/rc.d/init.d/supervisord</h3>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span>
<span class="c1"># chkconfig: - 15 15</span>
<span class="c1"># description: Copyright (C) yosida95 All Right Reserved.</span>
.<span class="w"> </span>/etc/rc.d/init.d/functions
<span class="nv">SUPERVISORD</span><span class="o">=</span><span class="s2">"/usr/bin/supervisord"</span>
<span class="nv">PIDFILE</span><span class="o">=</span><span class="s2">"/var/run/supervisord.pid"</span>
start<span class="o">()</span><span class="w"> </span><span class="o">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-x<span class="w"> </span><span class="s2">"</span><span class="nv">$SUPERVISORD</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$SUPERVISORD</span><span class="s2"> is not executable."</span>
<span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
<span class="w"> </span><span class="k">fi</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Starting ..."</span>
<span class="w"> </span><span class="nv">$SUPERVISORD</span><span class="w"> </span>--pidfile<span class="w"> </span><span class="nv">$PIDFILE</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nv">$?</span>
<span class="o">}</span>
stop<span class="o">()</span><span class="w"> </span><span class="o">{</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Stopping ..."</span>
<span class="w"> </span><span class="nb">kill</span><span class="w"> </span>-QUIT<span class="w"> </span><span class="sb">`</span>cat<span class="w"> </span><span class="nv">$PIDFILE</span><span class="sb">`</span>
<span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="nv">$?</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">]</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span>rm<span class="w"> </span>-f<span class="w"> </span><span class="nv">$PIDFILE</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nv">$retval</span>
<span class="o">}</span>
<span class="k">case</span><span class="w"> </span><span class="nv">$1</span><span class="w"> </span><span class="k">in</span>
<span class="w"> </span>start<span class="o">)</span>
<span class="w"> </span>start
<span class="w"> </span><span class="p">;;</span>
<span class="w"> </span>stop<span class="o">)</span>
<span class="w"> </span>stop
<span class="w"> </span><span class="p">;;</span>
<span class="w"> </span>*<span class="o">)</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$0</span><span class="s2"> start|srop"</span>
<span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">2</span>
<span class="w"> </span><span class="p">;;</span>
<span class="k">esac</span>
</pre></div>
</div>
<div class="section" id="section-9">
<h3>自動起動</h3>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>chkconfig<span class="w"> </span>--add<span class="w"> </span>supervisord
$<span class="w"> </span>sudo<span class="w"> </span>chkconfig<span class="w"> </span>supervisord<span class="w"> </span>on
</pre></div>
<p>これで、 OS 起動時に supervisord が自動的に起動され、登録されているプロセスも自動で立ち上がるようになります。</p>
</div>
<div class="section" id="supervisorctl">
<h3>supervisorctl</h3>
<p>Supervisor には supervisorctl という便利なコマンドも用意されています。
これを解説する余力が今無いので解説は省きますが、 supervisorctl -h とすればヘルプが表示されるし、使い方はわかると思います。
基本的に、ウェブコンパネでできることがこのコマンドラインツールでできます。</p>
</div>
<div class="section" id="section-10">
<h3>参考</h3>
<ul class="simple">
<li><a class="reference external" href="http://d.hatena.ne.jp/anatoo/20120310/1331321778">適当なスクリプトをデーモン化するのにSupervisorが便利 - id:anatooのブログ</a></li>
<li><a class="reference external" href="http://prasinos.blog2.fc2.com/blog-entry-592.html">prasinos' work memo chkconfig 対応スタートアップスクリプトの書き方</a></li>
</ul>
</div>
</div>