2013年12月31日火曜日

Dartのドキュメントを適当に翻訳し始めました。

2月のGDG中国のイベントのためにDartを調べているのですが、
平行して英語の勉強も”ある程度”しないといけないような気がしたので、
適当にDartのDocumentを翻訳することにしました。

とりあえず、翻訳した後の文章を見ても何となく分かるようなわからんような…。
(Golang Cafeとか、Blogでも書いたけど、「プログラミング言語 Go フレーズブック」の日本語がおかしいとか、読みにくいとか言ってたけど、翻訳者の苦労がよく分かる…。)

https://github.com/tyokoyama/dartdoc

私は、中学校の頃までは英語の授業があったけど、高校以降は、工業高校だったので、英語の授業が
高校からガクッと減ってるんですね。大学も工学部だったし、(正直その頃には英語に全く興味なかったし)週1回の講義が1年と、週1回の英会話の講義が1年…?だったかな。まあ、とにかくよくわからんのですよ。

特に、","が何個もつながった文章とか、わけがわからないし(今のところ、","で区切って短い文章で読み進める作戦)
あと、圧倒的に単語の意味を覚えてない。
それから、慣れない言語で文脈を読み取るのは今は難しい。

「あの時、しっかり勉強しておけば良かった」とまでは思わないけど、ある程度、単語も覚えていかないとだめだね。
ということで、ぼちぼちやっていこうかと思っています。

2013年12月30日月曜日

Golang Cafe #10を開催しました。

Golang Cafe #10を開催しました。

今回は、imageパッケージを使ってみる会ということで画像処理のコードを書いていました。
サンプルコードはGithubにpushしてありますので、ご興味があればごらんください。

今回提示したサンプルは

  1. png画像をjpegに変換する(単純に読みだして、そのまま書き出す)
  2. png画像に「#」を書き加えてpng画像を出力する。(#golangとしたかったけど時間が足りなかった)
基本的に画像を読み込む場合は、os.Open("ファイル名")でファイルを開きます。書き出す時は、os.Create("ファイル名")でファイルを作成した後、os.Fileのポインタを介して画像データを書き出します。

Goのimageパッケージは、画像のピクセル情報をimage.Imageインターフェイスを実装した構造体が管理しており、画像の形式(gif/jpeg/png)にかかわらず、Imageインターフェイスを介して画像が生成されるようになっています。ImageインターフェイスはRectangleの取得、color.Modelの取得、ピクセルの色を取得しかありません。
したがって、直接編集することができないようになっています。

画像を編集しようと思うとどうするか。というと、元画像を読み取り、いちいち画像データをコピーする必要があります。今回はRGBAにコピーしています。RGBAは一般的なRGBA(Aは透明度?)に対応した型です。
(以下はwritesample.goの抜粋です)
rect := img.Bounds()
rgba := image.NewRGBA(rect)
size := rect.Size()

// 元画像のコピー
for x := 0; x < size.X; x++ {
 for y := 0; y < size.Y; y++ {
  rgba.Set(x, y, img.At(x, y))
 }
}

// #golangとか書きたいけど、今は時間がない。
for i := 0; i < 10; i++ {
 rgba.Set(60, (10 + i), image.Black.At(0, 0))
 rgba.Set(65, (10 + i), image.Black.At(0, 0))
 rgba.Set((58 + i), 13, image.Black.At(0, 0))
 rgba.Set((58 + i), 16, image.Black.At(0, 0))
}

outRect := image.Rect(0, 0, rect.Max.X, rect.Max.Y)
outImage := rgba.SubImage(outRect)

RGBAだけでなく、Gray16や、RGBA64にはSet()が用意されており、ピクセルデータを上書きする事ができます。今回は黒で上書きしたので、定数で定義されている、image.Blackを利用しました。用意されているのは、黒と白だけのようなので、他の色は作るしかないです。
Goには、JavaとかC#などのように、「線を引く」「円を描く」「画像を描画する」というAPIが用意されていないので、自分でピクセルの上書き処理を書かないといけません。
(あってもいいと思うけど何でないの?)

しかも、画像として書き出すためには、image.Imageを作らないといけないので、出力用のRectangleを用意して、SubImage()で取り出すという事をしなければいけないという、ちょっと面倒な感じになっています。(ただ、データ構造として、interfaceになっていて、画像形式に依存したコードがそれぞれの処理で分離されているのは良い設計だと思う)

ということで、便利なライブラリがないかと探してみると、draw2dというライブラリが存在しています。後半はこれを使ったコードを書いて、動かすという流れになりました。
サンプルコードはwritesamplewithdraw2d.goを見て下さい。

draw2dを使う場合は、"code.google.com/p/draw2d/draw2d"をimportします。
ライブラリ自体を取得する場合は、go getコマンドで取得して下さい。

使い方は、image.NewRGBA()までは同じですが、その後、戻り値のimage.Imageをdraw2d.NewGraphicContext()の引数にして、GraphicContextを取得します。
GraphicContextには、DrawImage()も、LineTo()もありますから、それぞれのAPIを呼び出せば、画像が描けたり、線が引けたりします。
(それでも、少し不便な感じがしなくはないですが…)

文字も描画できますが、事前にTrueTypeFontを読み取らないといけません。
初期値が"../resource/font/"になっていて、しかも、freetype-goというライブラリに依存しているため、そちらのソースコードを編集するか、draw2d.SetFontFolder("font/")という感じで、事前にフォントのディレクトリを指定しておく必要があります。
しかも、それだけではまだダメで、任意のフォント(例えば、システムフォントなど)を読み出そうと思ったら、内部でチェックがかかっていて、ファイル名を勝手に生成するようになっているので、”MS ゴシック"とか、"ヒラギノ角ゴ"というようなフォントを指定してもそのまま使えないという残念な結果になりました。
(元々この辺は使えないのだろうか?)

ということで、imageパッケージ周りはまだまだライブラリを作る余地があり、標準に用意されても良さそうな感じはしました。来年の1.3以降のリリースに期待ですね。

さて、次回は、archiveパッケージを使ってみる会になる予定です。

2013年12月28日土曜日

2013年を振り返る。

2013年も、あと少しですね。

ここ数年は毎年やっていますが、2013年を振り返ってみたいと思います。
自分のBlogを見返してみると、2013年の目標を定めていました。

GDG中国の活動について

GDG中国の活動として、決まっていたのは、

1/13(日)第16回勉強会@岡山
1/19(土)GDG四国 徳島テクニカルセッション
2/9(土)第17回勉強会@広島

の3つで

その後、5回イベントを開催しました。
4/13(土)第18回勉強会@岡山
6/22(土)第19回勉強会@岡山
6/29(土)第20回勉強会@福山
9/7(土)第21回勉強会@岡山
10/12(土)第22回勉強会@岡山

他にも、
5/25(土)、26(日)Devfest Japan 2013
6/8(土)htmldayへの参加

あとは、講師として
7/27(土)Google Apps Script勉強会
9/28(土)Go言語勉強会

そして、Golang Cafeの主催が10回。
講演回数などを確認していると、結構やってるなと思ったり思わなかったり。
AngularJS:3回
Google Apps Script:2回
Android:2回
Go:1回+Golang Cafe

回数からすると、今年はAngularJSを押してたのかな?と思ったりしています。
今は、Goを押していますけど、Googleのどのプロダクトも便利なもので、
使ってくれる人が増えるといいなーと思っています。

しかし、一時期、発表の質が落ちてしまって、参加者の方には非常に迷惑をおかけしてしまった部分も会ったのかなと思っていますので、今後はしっかり準備をしてから臨みたいと思います。

コミュニティとしては、スタッフが転職していなくなったり、プライベートが忙しくなったりと、スタッフがズタボロな状態なので、これを何とかしないとダメなのと、
いつも使わせて頂いていた会場が閉鎖になり、広島でのイベント開催が難しくなった事もあって、どうしても縮小傾向で考えないとダメなのかもしれない。
ただ、その前にもう少しスタッフにお願いするようにしてみようとも思ってたりしています。

それから、GDG中国で今後やってみたいなと思っているテーマは、

  • Google App Engineの言語はどれがいいのか?
  • Android 4.4の新機能について。
  • Dart(これは2/11(火祝)にやります)
  • AngularJSを岡山で。
  • Google Apps関係
    • 各種APIを叩くとか、サービスの連携とかをネタに。
  • Maps関係
と、考えています。発表が全て私である必要はないと思うのでもう少し、いろんな方に頼っていきたいと思います。

仕事関係

2013年は公務員になるという事があったので、目標を達成する事ができませんでしたが(というか、何もかもが変わってしまった)その振り返りをしてみたいと思います。
  1. 早朝の配達のバイト
  2. 専門学校の非常勤講師
  3. Google Appsのアドバイザー→データの移行プログラム(βバージョン)の作成案件(?)
  4. Androidアプリケーション/Chrome Extension/Google App Engineのアプリケーション開発
  5. その他突発の社会人講師とか。

3月までは、上記の仕事をしていました。特に専門学校の講師に関しては、一度やることになっていたのに急遽キャンセルをしてしまったというのが、申し訳なかったと思っています。
今思うと、「よくやっていたな」とも思えますし、「第二の人生」と思って活動してきました。
とはいえ、Androidの講師や、テクニカルレビューアを担当させていただき、それなりに、これまでと同様の活動ができたことにも感謝しないといけないと思います。

と、いうものの、Androidアプリケーション「今日のアドバイス」を作りましたし、
iPadとiPhoneで通信させるWebアプリ(実際にはAndroidも使える)を学校の仕事で作りました。その他にもExcel VBAマクロを駆使したものも幾つか…。

ということで、IT関連の事もある程度はできたかなと思っています。

技術関係

  1. Google Apps(無料版)をしっかり使う
  2. Google+も主力にする
  3. Go
  4. AngularJS(HTML5 + CSSも)
  5. blogをしっかり書く
  6. 書籍も読む
  7. なんか執筆(?)
ということを目標に掲げていましたが、執筆は立場上不可能になってしまったのでダメでしたが、1と7以外はしっかりできたかな?と思ったり思わなかったりしています。

実際、Pure + AngularJS + GAE/Gとか、Bootstrap + AngularJS + GAE/Gという構成でWebアプリケーションを作ってみましたし、本業の方には敵いませんが、ある程度勉強できたと思います。G+も主力になって、非常に便利に使っていますし、いい事づくめですね。書籍もしっかり読んで、Blogに感想を書き残すということもできたので良かったのかなと。(ただ、数がそんなに多くない気もしなくはない)

ただ、Google Appsを有効利用できなかった(ほぼ塩漬け状態だった)のと、ドメインをしっかり取り直そうかなとか思っていたりするので、いろいろ整理してから、来年に臨みたいですね。

ということで、今年もいろいろな方にお世話になりました。良いお年をお迎えください。
来年の目標はまた来年に投稿しようと思います。

はじめてのBootstrapを読みました。

はじめてのBootstrapを読みました。
Twitter Bootstrapの使い方が知りたかったので購入してみました。
全5章のうち、最後の5章は実際にWebサイトを構築するという章だったので、
また時間がある時に読むことにして今回はパスしています。

2章からの基本的なCSSを適用するというところで、ひと通りのUIを体験し、
3章で用意されているコンポーネントが紹介されます。
ここまでの内容だけでも、それなりにモバイルアプリケーションが作れました。
(生徒に文句を言われることもなく…。)

レスポンシブデザインについての記述もしっかりされており、読んで、サンプルを入力するだけでは、難しいかもしれませんが、実際に作る段階になれば、おもしろい事ができるようになっていると思います。

4章からはJavaScript APIを利用した、動きがあるもので、Webアプリケーションに導入するには非常に便利なものが紹介されていました。

ただ、(書籍を読んだからかもしれませんが)本家サイトにある、解説に書かれている事が書籍になったという感じにも受け取れるので、慣れた人にはこの書籍は向かないと思います。また、dotinstallなどにも解説があるそうなので、そちらを見たことがある方は、購入の前に立ち読みをしてみた方がいいかもしれません。

ということで、個人的には非常に有意義なものでした。
ぜひ初心者の方は、読んでみてください。

2013年12月23日月曜日

Golang Cafe #9を開催しました。

Golang Cafe #9を開催しました。

今回は、「Go言語でデザインパターン」ということで、結城浩さんの書籍「Java言語で学ぶデザインパターン入門 マルチスレッド編」を、2月頃にGoで書いたものがあったので、それを元に進めてみました。
githubのリポジトリにタイトルのままのディレクトリが作られているのでそちらをごらんください。

最初の「Single Threaded Execution」では、本来は、排他制御を行わないと、変数の値が正しく読み取れない(他のスレッドでの変更が中途半端に反映された)状態が発生して、「Broken」という出力がある想定だったのですが、Go on Mac OSXだと、何もしなくても、全く不整合が発生せず、その時の状況を忘れてしまっていたので、3人でハマってしまいました。(Windowsでは、不整合が発生したので排他制御を入れなければいけなかったが、Ubuntuでは全く発生しなかった)
恐らく、コンパイル時に最適化されてしまったのかな?と後になって考えるところです。
Goroutineの切り替わりが問題か?と思って、runtime.GOMAXPROCS(3)とかも適用してみたのですが、全く不整合が発生しませんでした。
該当コードはこちらです。(channelで排他制御のコードがありますが、全く無意味 http://play.golang.org/p/gz21HM20kv

本来、ここで言いたかった事は、「しっかり排他制御を行って、同時にアクセスできるのは1つのスレッドのみ」ということを実現しましょう。ということでした。

次の「Immutable」は、複数のスレッドで実行しても、値を変更するAPIを用意しなければ、変更したくても変更できないというパターンです。
特に問題が発生しなかったので素通りしました。

最後に、「Guarded Suspention」はchannelはスレッドの終わりを待つだけのものなので、特に注目するところではないのですが、今回は、sync.condを使って排他制御を行っています。(これが正しいかどうかは別として、書籍のコードと同じような事をしようと思うと恐らくこれだろうと思っています)
理由としては、C#でいうところの、Monitor.Wait()とMonitor.Pulse()を実現する方法がChannelでは不可能だからです。(でも、実際には同じような事はバッファリングすればできる…か?)
プログラムの内容としては、ClientスレッドがQueueにPutするまで、Serverスレッドは待ち続ける。という内容になっていて、スレッドの動作はバラバラですから、Queueにデータがある間はsync.cond.L.Lock()でロックし、値を取り出し、キューから削除してUnlock()しますが、データが無くなった時には、sync.cond.L.Wait()でキューにデータがセットされるのを待ちます。
Clientスレッドでは、キューにデータをセットしたら、sync.cond.L.Signal()を呼び出して、サーバ側にデータが入った事を伝えています。(その後は、CPUが勝手にスレッドを動かすはずなので、どのスレッドでもどうぞ。ということで)

ここで、問題になったのが、init()の呼び出しについて。
init()はパッケージが読み込まれた時に、1度だけ実行される特殊な関数ですが、構造体のメソッドとしてinit()を定義していても呼び出されるのか?という話になりました。
そこで、最初は「呼び出される」(static{}と同じ動き)と言っていたのですが、ドキュメントにそのような記載はないし、よくよくコードを確認すると、main()に呼び出しがあったので、メソッドにした場合は、呼び出される事はありません。(コメントアウトしてみると、panicになりました)

というところで、2時間が経過したので、ここまでとなりました。

次回は、12/29(日)に10回目を行います。
テーマは「imageパッケージと戯れる」にする予定です。



2013年12月16日月曜日

Golang Cafeを開いた結果

この記事は、Go Advent Calendar 2013の16日目の記事です。
内容が技術な感じではないので、Qiitaへの投稿は控えました。

2013/10/27(日)から、毎週日曜日の夜に、「Golang Cafe」というGo言語をみっちりやる会をやることにしました。
東京では、Go研というイベントが開催されており、標準パッケージを読み進めるスタイルになっています。(目的は標準パッケージを読み、Goでの設計方法を研究する)
これを自分でもやってみようと思ったのがきっかけです。

本来は、私自身が、Go言語を使うことが少なくなってしまったのと、転職したので、職業上コードを書く機会がかなり減ってしまったので、強制的に書く時間を作ろうと思って、イベントをやることにしました。毎回、「一人でもやります」と書いているものの、一人になったことはなく、毎週2人の猛者が参加して頂いています。

ということで、3人のメンバーで毎週、勉強会をやっています。

Golang Cafeのこれまでのテーマを挙げます。

  1. How to write Go Codeの内容
  2. encoding/jsonパッケージのソースコードを読む
  3. GoroutinesとChannelsで並列処理入門
  4. database/sqlパッケージを触る
  5. osパッケージを触る
  6. text/templateパッケージを使う
  7. Goのプレゼンのプレお披露目/Go1.2の概要
  8. プレGo年会
  9. 既存言語のデザインパターンをGoで書いたら?(12/22開催予定)
という流れですすめてきました。

結果、自分自身の知識が深められた。(職業上、仕事には生かせられないけどw)
参加者のレベルがあがった。(今後、GDG中国の戦力に…)

実際、当初の目的からは活動内容が変わってきていますが、特に問題ないと思っています。ただ、会のなかで、「他の言語で書くと…」という話題が出てくる事が多いので、
標準パッケージや、実際のGoのプロダクトを読みつつ、設計を研究していく必要はありそうです。

ただ、標準パッケージの読み方にもコツがあって、reflectパッケージから読み始めた方が、色々有利な事が多いと思いました。
理由は#2の時にencoding/jsonパッケージを読もうとしましたが、中でreflectパッケージがかなり使われていて、reflectパッケージを読んでおかないとencoding/jsonパッケージに集中できないという状況が発生したからです。
ということから、reflectパッケージは早めに読んでおく方が良さそうです。

それから、osパッケージは中でsyscallパッケージを使っているので、syscallパッケージを読み進めたほうがいいですが、Windows版に関しては中身が「return -1」が連発しているという、いわゆる「サポート外」のコードが散見されますので、Windows版でソースコードを読み進めるのは現時点では、おすすめしません。
(今後も改善の余地があるんだろうか?OSの仕組みから違うような…?)

といった所で、これまでに得た事をつらつらと書いてみました。

※#golangや#gdgchugokuでTwitterに投稿するので、気が向いたら反応してください。

Golang Cafe #8を開催しました。

Golang Cafe #8を開催しました。

今回は、東京で行われるGo年会に合わせて、岡山でも非公式でやってしまおうということで、勝手に「プレGo年会」というテーマで進めてみました。
(Go年会参加者は、参考にしてねw)

で、開催中にGo言語フレーズブックを開こうと思って、かばんを見ると…、かばんの中に書籍がないという事実が発覚して(日中に教員免許更新講習を受けてきた時に会場に置き忘れた?)ということで、書籍をその場でAmazonで購入するという事件がありました…。
正直、ショックです。。
が、正誤表が、以前の私の指摘した部分だけでなく、だいぶ増えていて、改めてみると驚きました。と同時に、コードを書いて動きをみていないなと思いました。
当時のBlog記事も見直しましたが、今日の発言と微妙な食い違いがありましたので
改めて読み進めようと思いました。

さて、内容は、質問の回答と今年1年のGoの振り返り、来年のGoの動向(というか希望?)について、雑談を交えて話をしてきました。

  1. 質問の回答
    1. 配列型引数の関数は呼び出し元に影響を与えるか?
      1. 呼び出し元に影響を与えない。(引数の値は編集されない)
      2. 引数がスライスの場合は、呼び出し元にも影響が出る。(編集される)
        1. ただし、引数が配列型の関数にスライスを指定するとコンパイルエラーになる。
        2. 基本的に実体はコピーされて、ポインタ、スライスなどは影響する。
      3. ソースコードはgithubをごらんください。
    2. Goにメソッドのオーバーロードは無いのか?
      1. ない。(コンパイルエラーになる)
      2. Goにオーバーロードはなぜないのか?
  2. 今年1年の振り返り
    1. Go1.1→Go1.2に
      1. Go1 and the Future of Go Programs」によると、1.2.1、1.3、1.4の記述があるから、今後もバージョンアップしそうだね。
      2. そういえば、AngularJSも1.3がでたとかなんとか…。リリースは早いなー。(1:03追記:リリースではなく、対応方針が発表されたの間違いでした。)
    2. Go関係のコミュニティ、イベントが増えた。
      1. 個人的には全く参加できてないけど、いつかは参加してみたいですね。
      2. 今後も増えてくるんじゃないだろうか。
    3. Lite IDE
      1. Ver18で止まっている…?
      2. Golang IDE Ver20がリリースされている。
        1. アイコンが同じ。
        2. どういうこと?
      3. GolangJPのG+コミュニティにあまり投稿がない。
        1. +Ryuji Iwataさんがんばって!
        2. 試しにGolangJPにGolang Cafeの告知流そうか。
      4. エディタ
        1. Sublime Text
        2. Vim
      5. 高級言語を使っているとGoは使い勝手が悪いんじゃないか?
        1. 速度を考えると実装されなさそうな機能が多い?
          1. Genericsとか、演算子のオーバーロードとか。
            1. Goにオーバーロードはなぜないのか?
      6. Go言語でできることはなんだろう?
        1. HTMLUnitがあるとうれしい!
        2. 既存のアプリケーションをGoで置き換えたい…。
          1. バッチ処理の部分ならいける!?
          2. 並列性を活かせるもの
          3. 1つの処理でも複数のGoroutineで回して最後に終わったGoroutineの後で、全てを出力する…。みたいな。
        3. GoでHTTPサーバとか?
          1. Apacheをリバースプロキシで使うとかして…。
      7. Goの互換性
        1. Ver1.0から互換性を保つということを謳っているので、バージョンアップしても大丈夫なはず!
        2. Go1互換のガイドラインに沿ってSub repositoryに分割されるのでは?
        3. よって、Ver1.0のコードをVer1.2のコンパイラでコンパイルしても落ちることはないはず。当然、挙動も変わらない。
      8. OAuth2ライブラリなどもある。
        1. https://code.google.com/p/goauth2/
      9. リコーのGoのプログラマ採用がでてきた!
        1. https://www.ricoh-careers.com/job.phtml?job_code=302
  3. 来年のGoの動向(予想)
    1. GAE/GのExperimentalが外れて欲しい!
    2. Goの案件が出てきて欲しい。
      1. Cのプログラムを置き換えるとか…。
        1. COBOLの案件も…。
          1. ファイル出力系は置き換えられそう?
    3. プロダクトへの導入
      1. リコーは採用があるくらいだから、そのうちリリースがありそう?
      2. GoogleはどんどんC/C++のコードをGoに置き換えるということが発表されているので、日本の企業もだんだんとバックエンドがGoで作られるという日がくるのでは?大規模なものの方が向いてそうな気がする。

といった所で、今年のGo言語の様子はいろいろありました。来年はGoが実戦投入されることを祈っています。というか、投入されてどういう結果になったかの報告が聞けそうです。

あとは、比較的近く、いつもお世話になっている+Yasutaka KawamotoさんともGolang Cafeやってみたいですね!

では、次回の
Golang Cafe #9は2013年最後の回になると思います。
次回は、私が個人的に進めていた、「Go言語でデザインパターン」の話をしてみることにします。

2013年12月11日水曜日

Golang Cafe #7を開催しました。

Golang Cafe #7を開催しました。

今回は、+Takanobu Haginoさんの疑問に答えた後、+Ryuji Iwataさんの発表資料のお披露目があったので見させて頂いたのと、Go1.2の変更点を幾つか紹介した流れとなりました。

+Takanobu Haginoさんの疑問
  1. C#のdecimalに対応するものは何か?
  2. 演算子のオーバーロードなどの機能は?
  3. 変数の型が何かを知る方法は?
私が知るかぎりでは、2は、Goには存在しません。理由は速度に影響があるのか、複雑になるからなのかはわかりませんが…。

1は、math.big.Intとか、math.big.Ratを利用するしかありませんが、これはJavaのBigDecimalのようにメソッドを呼び出さないと計算ができないので少々面倒なのですが、この問題を解決しているのがC#のdecimal型なんですよね…。

3は、Go1.2からfmtパッケージの書式が増えて、%Tが指定できるようになっています。これを使えば型の名前を出力する事ができます。Debugなどで使えば便利だと思います。プログラムで判定するなどしたい場合は、switch文の中で、変数名.(type)の記述をすることで判定が可能です。型を実際に取得する場合はreflectパッケージを利用する歯科なさそうです。

次に、+Ryuji Iwataさんのプレゼンですが…発表当日をお楽しみに!

最後に私からGo1.2の変更点について、nilの扱いとThree-Index-Slices、fmtパッケージの変更点について紹介しました。

最初のnilの扱いについて。

package main

import (
        "fmt"
)

type T struct {
        Field1 int32
        Field2 int32
}

type T2 struct {
        X [1<<24]byte
        Field int32
}

func main() {
        var x *T
        p1 := &x.Field1
        p2 := &x.Field2
        var x2 *T2
        p3 := &x2.Field

        fmt.Println(x2.X[0])        
        fmt.Println(p1, p2, p3)
}

上記のようにnilポインタの変数のメンバを参照した時に1.1の時はアクセスできていたようなのですが、1.2からはpanicになるように変更されました。ただ、実際に動かしてみるとどちらもpanicになったような…。
現時点では、nilポインタアクセスさせるということがないので、いまいちわかりませんでした。変な事はしないということが重要ですね。

次に、

        var arr [10]int

        for i := 0; i < len(arr); i++ {
                arr[i] = i + 1
        }

        slice := arr[2:4:7]
        //slice := arr[2:4:4]

        var slice2 []int = slice
        for i := 0; i < 5; i++ {
                slice2 = append(slice2, 11 + i)
        }

        fmt.Println(slice, len(slice), cap(slice), arr, slice2, cap(arr))

上記のように、sliceを取得する時に、3つ目の値を指定することで、容量を取得する事ができるようになりました。実際にappendしていくと、参照元のarrの値が容量いっぱいまで更新されるようになります。また、確保される容量は、7-2=5となります。7個確保されるわけではなく、2番目から7番目までの容量という意味で捉えるといいでしょう。
上記の結果だと、1 2 3 4 11 12 13 8 9 0という配列になります。slice側は容量よりも大きくなっても値は保持されます。
sliceなので、元の配列arrの容量には影響は与えませんでした。値のみ影響されるようです。
以前は、容量の指定がなかったので、まちがって編集すると元もすべて影響をうけていましたが、容量指定のおかげで、少なくとも、容量よりも大きな添字の値は守られるようになっています。

fmtパッケージの変更点は、型名が出力される%Tの他に、出力する引数の番号を指定できるようになりました。%[1]dという指定をします。開始番号は1です。
%[3]d %d %dとすると、2番目の省略した所は、4番目を参照しようとします。したがって、省略したら指定した番号の次を出力という動きをしています。

次回のGolang Cafe #8は、今年のGo言語の振り返りと来年以降の動向を聞いてみようと思います。4年もたった言語ですからそろそろ大きな飛躍があると思いますので…。



2013年12月5日木曜日

Golang Cafe #6を開催しました。

Golang Cafe #6を開催しました。

今回のテーマはtext/templateパッケージの使い方が主なテーマになりました。

リポジトリはgithubにありますので、作成したコードはそちらを参照して下さい。

始まる前に、「Goで複数行にわたって記述する方法」について話題になったので、
そのことを調べました。
Goの場合は、明示的に「次の行に続く」事を書いておけば大丈夫なようです。
以下の例だと、正しく動きますが、
 str :=  "Hello" +
 " World!" +
 " Hoge!"

 n := Name("hoge")

 n.
  Print()

以下の例だとコンパイルエラーになります。
 str :=  "Hello"
 + " World!"
 + " Hoge!"

 n := Name("hoge")

 n
 .Print()

最初に簡単な使い方を紹介しました。

templateに任意の値を追加する時は、{{.Name}}というようにテンプレートを追加します。
先頭の"."はtemplate.Execute()で指定した引数のオブジェクトを示しています。
したがって、構造体を指定した場合は、メンバを指定することも可能です。標準の型の変数を指定した場合は"."と指定することで値を表示させる事が可能になります。

次に{{range $index, $element := .}}{{end}}とすると、rangeキーワードを使ったfor文と同じことを実現できます。先頭に$が付いたものはテンプレート内変数でrange以外でも使うことができます。
要素が0件だった時に、0件の処理をしたい場合は{{else}}を記述しておくと、else側が処理されるようになります。

{{if .Flag}}{{else}}{{end}}などとすると、テンプレート内での条件分岐が実現できます。
.Flagは判定条件です。

{{len .}}とすると、引数で渡された値の長さが取得できます。len()を呼び出しているのと同じ意味になります。これを使って、「取得件数:XX件」という事が実現できます。

templateはファイルに記述しておき、ファイルの内容から生成することも可能になっています。
t := template.Must(template.ParseFiles("sample.txt"))
とすると、sample.txtに書かれたテンプレートを読み取り、正しく記述されていればTemplateオブジェクトが取得されます。しかし、記述に誤りがある時は、panicになります。template.Must()はtemplateが必ず生成できることをチェックする関数です。
テンプレートが動的に変わるなど、正誤があいまいな時はMust()は使わないほうがいいでしょう。

また、template.ParseFiles()は複数のファイルを指定して一括で読み込めるので、
以下のように、複数のファイルを読み込ませても構いません。
t := template.Must(template.ParseFiles("sample.txt", "sample2.txt"))

テンプレートには名前をつけるようになっていて、template.ParseFiles()で読み込ませた時のテンプレート名はファイル名がそのまま付きます。
特定のテンプレートを取得したい時は、t.Lookup("sample2.txt")などとテンプレート名を指定してオブジェクトを取得します。

特定のテンプレートを指定してテキストを出力する時は、
err := t.ExecuteTemplate(os.Stdout, "sample2.txt", members)
のように、ExecuteTemplate()を呼び出すと可能です。2番目の引数がテンプレートの名前です。

次回のGolang Cafe#7は先週(今週?)リリースされたGo1.2の変更点について扱う予定です。

2013年11月26日火曜日

Golang Cafe #5を開催しました。

Golang Cafe #5を開催しました。

今回は、osパッケージを利用するのをテーマに進めました。
githubのリポジトリにもpush済みですので、ソースコードはそちらをご覧ください。

私が動作させた関数は以下です。

  • Open
  • Getenv
  • IsExist
  • IsNotExist
  • Chdir
  • Remove
  • RemoveAll
  • Mkdir
  • MkdirAll
  • Environ
まず、注意点として、パスを指定する時に"~"の指定はできないので、ホームディレクトリを取得する場合は、Getenv("HOME")で環境変数から取得して下さい。
ちなみに、"~"を使うと、カレントディレクトリに"~"というディレクトリができて困ることになります。

ディレクトリの存在チェック
os.Open()を使います。ディレクトリが存在しない場合は、戻り値にerrorが返されるので、直接errorを判定してもいいですが、IsExist()とIsNotExist()を呼ぶと、true/falseで存在チェックができるようになっているので、そちらを利用する方が便利です。

RemoveAllとRemove、MkdirAllとMkdirの違いですが、複数階層のディレクトリを指定する場合は、RemoveAll()、MkdirAll()を呼び出さないと、ディレクトリの作成、削除はできません。(errorが返されます)存在するディレクトリに新たにディレクトリを作る/削除する場合は、Mkdir()、Remove()でも実行できます。

Chdir()はカレントディレクトリを移動します。

Environ()は環境変数名の一覧を取得する関数です。Getenv()の引数もEnviron()で取得できる文字列を指定すれば、環境変数の設定を取得する事ができます。

それから、今回はWindowsでの動作が「サポートされていない」という状況が多かったのでWindowsで動作を検証していた+Takanobu Haginoさんは、ちょっとお困りのようでした。
Windowsにはuidなどの属性が存在しないのでGetuid()などを呼び出しても-1しか返ってきません。実装がreturn -1になっています。(syscallパッケージのソースコードに書かれています)(これはWindowsの仕組み上、どうしようもないと思われる)

osパッケージは内部でsyscallパッケージの関数を呼び出すようになっている事が多いので、syscallパッケージを触ってみる方が良いのかもしれません。

ということで、今回はあまり動かせなかったので、また今度osパッケージを使う(2回目)が行われることでしょう。

次回の#6はtemplateパッケージ(私は最近使わなくなってしまった…)の使い方がテーマになる予定です。

2013年11月18日月曜日

Golang Cafe #4を開催しました。

Golang Cafe #4を開催しました。

今回のテーマは、「database/sqlパッケージを触る」ということで、
事前にPostgreSQL9.3.1をHomebrewでインストールしておきました。

リポジトリはGithubにあります。https://github.com/tyokoyama/golangcafe
ブランチCafe_#4を作成していますが、masterブランチにもマージしていますし、ディレクトリを変えているのでmasterからも参照できます。

PostgreSQLを使うので、ライブラリはPure Goのgithub.com/lib/pqを利用しました。
(他のデータベース、ライブラリを利用される方は、こちらを参照して下さい)

導入方法は、
go get github.com/lib/pq
で、インストールできます。

ここからは、lib/pqの前提で説明を続けます。

まず、クライアントの文字コードをUTF-8にしておく必要があります。(チェックロジックがpq/conn.goの113行目にあります。恐らく、新しいPostgreSQLならdefaultがUTF-8になっているので大丈夫だろうと思われます。

まず、pqのインポートを行って下さい。
import (
 _ "github.com/lib/pq"
 "database/sql"
)

import時に"_"をつけると、パッケージの読み込みは行うが、プログラムでは呼び出さない事を明示しています。今回は、database/sql/driverパッケージがinterfaceのかたまりで実装はpqにあります。したがって、database/sqlパッケージがdatabase/sql/driverのインターフェイスを呼び出すことで、pqで実装されたPostgreSQLへのクエリ実行のコードが呼び出される仕組みになっています。
要は、database/sqlがpqのドライバを呼び出すのでimportしておかないと、panicになると覚えておけば良いと思います。

データベースへの接続
db := sql.Open("postgres", "user=gdgchugoku dbname=sampledb sslmode=disable")
defer db.Close()

pqのドキュメント通りではないですが、PostgreSQL側のsslの設定を有効にしておかないとsslmode=verify-fullが動かないのと、省略時がsslmode=requiredらしいので、標準でsslを使った接続になるようです。したがって、サンプルで試す時はsslmode=disableにしてsslを使わないように指定しましょう。

Queryの実行
公式のサンプルだと、
row := db.QueryRow("select * from character where cost=?", param)
などと、記述できるようですが、
pqを利用する場合は、
row := db.QueryRow("select * from character where cost=$1", param)
というように、?ではなく、$1などという指定しか受け付けないようです。
http://godoc.org/github.com/lib/pqを見る限りでも、?のサンプルが見当たらないので、サポートしていないのかもしれません。コードを書く時は、Driver側のドキュメントを見た方がいいかもしれません。
ちなみに、RowもRowsもClose()が実装されていますが、自動的にクローズされるということなので、明示的に呼び出す必要はありません。
RowとRowsの違いですが、Rowの方は先頭1行のみで、全行取得はRowsを利用します。(中身の実装はRowもRowsを含んでいるので、同じものです。便利機能というところでしょうか?)

カーソルの制御
db.Query()の戻り値の*Rows.Next()を呼び出し、カーソルを次の行に移動させます。Golangの(pqの?)カーソルは最初の読み出しでもNextを呼び出さないと、行のデータが取得できません。
サンプル通りですが、以下の様なコードになります。
 if rows, err := db.Query("select * from character"); err == nil {
  if names, err := rows.Columns(); err != nil {
   t.Errorf("row.Columns error %v", err)
  } else {
   for name := range names {
    t.Logf("name = %s", name)
   }
  }

  for rows.Next() {
   // 行の中身を見る。
   var no int
   var name string
   var cost float64
   var typeId int
   var attack int
   var lead int
   var scheme string
   var morale int

   if err := rows.Scan(&no, &name, &cost, &typeId, &attack, &lead, &scheme, &morale); err != nil {
    t.Errorf("Scan Error %v", err)
   }
   t.Logf("Rows[%d, %s, %f, %d, %d, %d, %s, %d]", no, name, cost, typeId, attack, lead, scheme, morale)
  }
 } else if err == sql.ErrNoRows {
  t.Logf("Query NoRows")
 } else {
  t.Errorf("Query error %v", err)
 }

*Rows.Columns()は列の名前を取得するメソッドですが、PostgreSQLの仕様なのか、0,1,2・・・という数字(列番号)しか返してきませんでした。select * from ...のように全列取得だからかと列指定もしてみましたが、同様に0,1なので、他言語で列名が取得できるのは、何か別の工夫があるのか、pqの実装がショボイのかはわかりませんでした。(Driverの開発ノウハウが必要かも?)

更新系のクエリを実行する場合ですが、参照系と同様に、*DB.Query()を使えば実行できます。また、*DB.Exec()もあるので、そちらを利用してもいいかもしれません。ただ、pqの実装が甘いようで、Exec()だと、更新クエリにより影響を受けた行数はResult.RowsAffected()で取得できますが、最後に追加したIDはAPIとしては、Result.LastInsertId()が用意されていますが、pqではサポートしていません。(ドキュメントにも明記されています)

  if row, err := db.Query(fmt.Sprintf("insert into character values(%d, '羽柴秀吉', 2.5, 1, 8, 6, '撹乱貫通射撃', 4) RETURNING no", no)); err != nil {
   t.Errorf("Insert Query Error %v", err)
  } else {
   if names, err := row.Columns(); err != nil {
    t.Errorf("row.Columns error %v", err)
   } else {
    for name := range names {
     t.Logf("name = %s", name)
    }
   }

   row.Next()
   if names, err := row.Columns(); err != nil {
    t.Errorf("row.Columns error %v", err)
   } else {
    for name := range names {
     t.Logf("name = %s", name)
    }
   }

   if err := row.Scan(&no); err != nil {
    t.Errorf("Scan after insert Error %v", err)
   }
   t.Logf("no = %d", no)
  }

LastInsertId()がサポートされていないので、現状で更新したIDを取得するためには、PostgreSQLのクエリの機能であるRETURNINGをつける必要があります。これは、更新、削除の時も利用できますが、UPDATEの時に指定すると更新された行全てが返ってくるようになっています。(試していないけど、DELETEの時も複数行返ってくると思われる)

と、ここまでがトランザクションを使わずCRUDを実現する方法でした。
量が多いので、別の記事にしようと思っていますが、ひとまず、Golang Cafe #4のまとめとしてはこの辺で終わります。

#4で議論になったこと。
Q. GolangにORM無いの?
紹介がありました。
http://jmoiron.net/blog/golang-orms/


2013年11月11日月曜日

Mac OS X 10.9(Marvericks)にPostgresqlをインストールする。

Mac OS X 10.9にPostgresqlをインストールしようとしたら、かなり苦戦したのでメモしておく。

まず、homebrewを使ってインストール。

brew install postgresql

とすると、PostgreSQL 9.3.1をインストールしようとするが、tcl-tkがないと言われるので、

brew install tcl-tk

その後、

brew install postgresqlする。

それでも、以下のエラーになるので、

configure: error: file 'tclConfig.sh' is required for Tcl

issueの対策を施して
args << "--with-tcl" unless build.include? 'no-tcl'の行の次の行に
args << "--with-tclconfig=/usr/local/Cellar/tcl-tk/8.6.0/lib" unless build.include? 'no-tcl'を追加

brew install postgresql

でも、まだplperl.soのエラーがでるので、

xcode-select --install
で、コマンドラインツールをインストールして、

brew install postgresql

で、インストール完了!

psql -Vの結果が
psql (PostgreSQL) 9.3.1

となっていたので、大丈夫なんだろう。とりあえず、PostgreSQLをあまり使っていないので、そこからだな。

Golang Cafe #3 を開催しました。

Golang Cafe #3を開催しました。

今日のお題はGoroutinesとchannelを使った並列プログラミング(初級)という感じです。githubにコードを置いてあります。

ワーカースレッド(goroutine)を起動するには、呼び出し時にgoを記述する。

Channelを使って、簡単な排他制御ができる。
ch := make(chan int)でChannelを作る。
ch<-1だと、Channelに1を送る。<-chだと、Channelから値を受け取る。

ちょっと、サンプルコードのミスで、よくわからないコードができてしまったが、コンパイルエラーにならないのが不思議だった。該当のソースコードはこちら

break、continueの使い方
言語仕様を参照。基本的にラベルの次のfor、switch、selectを抜ける。
continueはラベルの次のforをもう一度実行。

selectについて。言語仕様を確認した感じ。
select文にdefaultを入れると、defaultを呼び出して抜けてしまう。ただし、defaultがなければ、caseのどれかが呼ばれるまで処理をブロックする。

select{}にすると、無限に待ち続ける。

time.Tick()とtime.After()を同時に呼び出して、selectで同時に待ち受けるとtime.After()が永久に戻ってこない?(ただし、time.TickでのChannelの応答の前に、time.After()のタイミングがあると、呼び出される)
バグ…?
と思っていたら、+Fumitoshi Ukaiさんから、正しい書き方を教えていただきました!ありがとうございました。

runtime.GOMAXPROCS(n)を呼び出すと、CPUの利用数が設定できる。(戻り値は前の設定なので注意!)これを呼び出すと、goroutinesが並列に処理されるようになる。
が、アクティビティモニタで確認したら、スレッド数は6だった。(2を期待したけど、Go言語ランタイム(?)の方のスレッドがいるんだろうか。)

関数の引数で、channelが「送信専用」か「受信専用」かを明示することができる。
送信専用=ch chan<- int
受信専用=ch <-chan int
間違いがあると、コンパイル時にエラーになる。

次回は、database/sqlパッケージを使って、DBにアクセスする回になりそうです。

2013年11月5日火曜日

MacOS X Marvericksはまだ早い!

無料でアップデートできるという、噂のMac OS X Marvericksですが、無料なので、私も早速アップデートしてみました。

が、いろいろなアプリケーションが動かなくなったり、動きが悪くなってきたりしているので、今後、アップデートを検討している方へのメモとして残しておこうと思います。

ちなみに、購入したのは2012/12/31で、Core i7 2.6GHz、メモリ8GBの比較的新しいモデルだと思います。

動かなくなったもの

  • Mercurial
動きがわるくなったもの
  • VirtualBox
  • Chrome(?)
  • homebrew
  • Mac OS自体の動作。ログインとか、ロック解除とかがもっさり…。
MercurialはMacのPythonのパスが変わったということで、動作しなくなったようですが、homebrewからのビルドが通らなくなってしまって(XCodeの利用規約の承認が必要だった?)結局、sudo easy_install -U mercurialで解決しました

VirtualBoxに至っては、一度起動したら、毎回セットアップからインストールしないと
まともに起動しないという状態に陥っていて、仕事でVirtualBoxをフル活用している私としてはかなり悩ましい問題になっています。最新バージョンの4.3.0なのに…。
早く改善して欲しいものです。

ということで、今のところ、問題となることが多いようなので、Mountain Lionで様子を見ている方はそのまま様子を見た方がいいと思います。

私だけが特別ならいいんだけど…。

2013年11月3日日曜日

Golang Cafe #2を開催しました。

先週に引き続き、Golang Cafe #2を開催しました。
今回は、encoding/jsonパッケージのMarshal()から読み始めました。

それまでに、前回のExampleの事を復習していたら、godocコマンドのハックに…。
(ですが、本題と違ったのでまた違う日にやることにしました)

色々出てきたのでメモ。
引数の型がinterface{}になる時は、「何でもOK」という意味。(他の言語で言う、Object、object、void *、variant…など。)

deferキーワード。呼び出した関数が終了した後に呼び出される、後処理用スタックに積む。(その場で処理は実行されないので、ファイルのクローズなどをまとめておくと良い。)

recover()はdeferキーワードを使って呼び出した関数内でしか利用できないので注意。

reflect.Valueは、今日は読まないが、「ポインタを持った構造体」
reflect.ValueOf()はポインタを持った構造体を返す関数ということにしておく。

読んだ所は、encoding/json#Marshalを掘り下げる感じで。

  1. encoding/json#Marshal
  2. e = &encodeState{}
  3. e.marshal()
    1. エラーチェック用defer関数を登録して、e.reflectValue()
    2. reflectValueQuoted(v, false)で呼び出す。(1.1.2だと267行目付近)
      1. IsValid()かどうかをチェック
      2. Marshalerインターフェイスを実装しているかどうかをチェック(TypeAssertionを使って、変換する)
      3. Marshalerインターフェイスではない場合、ポインタをもらっているという想定で、v.Addr().Interface().(Marshaler)で参照先の値を取り出してTypeAssertionする。
        1. TypeAssertionは変換できない場合もあるので、代入用変数と、チェック用の変数を2つ左辺に記述する形で使う。(i, ok := v.(int)…など)チェック用変数がfalseの場合は変換できなかった事を示す。(interfaceを実装していない、型が違うなど。)
        2. MarshalJSON()([]byte, error)を実装していれば、自分で実装したJSONエンコード処理が呼ばれる。
      4. それ以外は、reflect.Kind()で型の種類を取得して、それぞれの方法で出力する。
        1. 構造体はフィールドごとに再起呼び出し。
        2. fallthroughキーワードは次のcaseを実行する。
          1. Goのswitchはデフォルトbreak!
        3. reflect.Kind()はhttp://goo.gl/uDQOPOのconst値を返してくる。
        4. invalid、unsafePointer、channel、func、Mapのキーがstring以外のものは、変換できずerrorを返す。

それから、私が作成したサンプルコードとテストコードをまとめてgithubに置きました。
https://github.com/tyokoyama/golangcafe
次からはこのリポジトリにまとめてCommitしていくことにします。
(忘れてなかったら、各回ごとにbranchも作っておくようにします。)

次回は、goroutine & channels関連をやってみる予定です。

2013年10月27日日曜日

Golang Cafe #1を開催しました。

今日は、Golangをみっちりやるという目的で、Golang Cafe #1を開催しました。

内容は、最初なのでHow to Write Go Codeの内容を中心に進めました。

順番は、

  1. 今後のために、Workspaceの構築
  2. パッケージについて
  3. Your First Program
  4. Goコマンドについて
    1. go build
    2. go install
  5. go test
    1. TestXxx()
    2. BenchmarkXxx()
    3. ExampleXxx()
注目のポイントとしては、まず、パッケージについて。

  1. 基本的にソースコードのパッケージ名とディレクトリ名が一致している必要がある。
  2. mainが含まれるパッケージ(コマンドのプログラム)には、mainパッケージしか配置できない。
  3. mainから他のパッケージを参照する事は可能。
    1. したがって、自作の外部パッケージは別のディレクトリで作成する。
    2. 参照する時はWorkspaceのsrc以下のディレクトリ構成をフルパスで指定する感じの記述が必要
      1. ex) sample.com/firstlib/sublib
      2. ex) sample.com/firstlib
      3. など。
  4. サブディレクトリにパッケージを作成する事が可能。
  5. go buildでは自作パッケージ(≠コマンドのプログラム)は-oオプションがない限り、何も出力されない。
  6. go installで、pkgディレクトリにコンパイル後のライブラリファイルが出力される。
  7. go install は、パッケージを省略すると、カレントディレクトリのパッケージのビルドを行う。特定のパッケージをインストールする場合は、パッケージ名を絶対パス指定するか、相対パス指定する。
  8. go installはコマンドとライブラリで出力先が自動的に切り替わるのでコマンドの違いはない。
次に、go testについて

  1. go testコマンド
    1. ユニットテストを行う場合
      1. テストコードはtestingパッケージを利用する
      2. ファイルの置き場所はパッケージのソースコードと同じ場所に置く。
        1. ファイル名はXXX_test.goとする。(自動的にテストコードと認識される)
      3. テストコードの関数はTestXxx(t *testing.T)とする。
        1. 先頭はTestで始まる関数を自動的に読み取ってくれる。(JUnit3と同じ)
        2. Xxxの所はテスト対象の関数名にする。(任意ではあるがわかりやすい?)
    2. ベンチマークを取る場合
      1. テストコードと一緒に記述すれば良い。
      2. ベンチマークの関数名はBenchmarkXxx(b *testing.B)とする。
        1. 自動的に読み取ってくれる。
        2. Xxxの所は対象の関数名にする(ユニットテストと同じ)
      3. コマンドパラメータが必要。指定がなければ実行されない。
        1. go test -bench .
        2. go test -bench=".*"
    3. Exampleコードを作成する場合
      1. テストコードと一緒に記述する。
      2. Exampleの関数名はExampleXxx()とする。
        1. 自動的に読み取ってくれる。
        2. Xxxの所は対象の関数名にする(ユニットテストと同じ)
      3. 関数の最後に、特殊なコメントが必要。なければ実行されない。
        1. // Output: で始まる。(これが無いと実行されない)
        2. 以降、標準出力に出力される文字列をコメントで記述。
        3. 標準出力には、自分で出力するようにコードを書く必要がある。
        4. 用途が不明。(簡単なユニットテスト?)
    4. 複数のパッケージを一気にテストする場合。
      1. go test [パッケージ名を空白で区切って羅列する]
      2. 相対指定も使える。
      3. ちょっと面倒だけど、シェルなどを使って、文字列を作るしか無さそう。
      4. ディレクトリを指定するとかでは実行できなかった。
    5. go testのコマンドパラメータについては、ドキュメントを参照。
ということで、今回は3名で集まって、中身を進めました。
(本日のお題を用意していたので、Google Documentですが、URLを置いておきます。
http://goo.gl/iVLEXf
今後は、Go Playgroundにソースを貼って動かして動作を確認も良いのですが、
テストコードを書いて動作を確認して進めてみようと思っています。

それから、基本的には毎週日曜日に気が済むまでやってみたいと思います。

2013年10月13日日曜日

第22回GDG中国勉強会を開催しました。

10/12(土)の第22回GDG中国勉強会@岡山を開催しました。
今回は、Google Cloud Platformを使ってみるという会でしたので、参加者の皆さんもいろいろなサービス、APIを使われたことだろうと思っています。
見た限りでは、Google App Engineが多かったようです。
そのうち、Blogを書いてくれる事だろうと思うので待っていることにします。

私はGoogle Cloud SQLと、Google Compute Engineを動かしたので、その手順を書いておきます。

※事前にGoogle Cloud Consoleでプロジェクトを作っていること。

まず、Google Cloud SQLから。

  1. Cloud SDKをダウンロード、展開する。(Go版に萌えましたが、コマンドが少ないのでPython版か、Java版が無難です。もしかしたらPython版だと早い?)
  2. Google Cloud SQLに接続する場合は、
    1. ./gauth
    2. (プロジェクトIDなどを聞かれ、認証URLが出てくるのでブラウザで認証させる)
  3. ./google_sql.sh [インスタンス名]

とすると、Google Cloud SQLに接続できるので、これで、select version();とか実行すれば結果が取れます。
参考:G+の投稿

次に、Google Compute Engineの接続。ほぼ、Getting Startedの通りですが、Webのコンソールも利用しました。方法をメモしておきます。
  1. プロジェクトのメニューからAPIs&auth→APIsを選び、「Google Compute Engine」を探し、ONにする。
  2. メニューのCompute Engineを選択し、NEW INSTANCEボタンを押す。
    1. OSはDebian6、7とCentOS6が選べる。(私はCentOSにしました)。
    2. 以下の画像はDiskを再利用していますが、New Persistent Disk from Imageを選択すれば新規作成できます。
  3. ./gcutil auth --project=[プロジェクト名]
    1. 承認用のURLが表示されるので、ブラウザにコピペして承認する。
    2. 承認キーが表示されたら、コンソールにコピペ
  4. ./gcutil ssh [インスタンス名]
    1. sshで接続してCompute Engineのコンソールを利用する。
    2. 思ったより重たいので注意。
    3. ここからCompute Engine側でコマンド実行となる。
  5. sudo yum install httpdとかする。
    1. Apacheを動かすので。
  6. sudo /etc/rc.d/init.d/httpd startとかする。
    1. Apache起動。(service httpd startも可能ですが、私は上のコマンドを実行しました。)
  7. ここで、一旦Compute Engineからログアウト
  8. firewallを追加。
    1. ./gcutil addfirewall http2 --description="Incoming http allowed." --allowed="tcp:http"
    2. iptablesを書き換えても何も意味はありません。(Google側で管理されているそうです。)
  9. 適当にIPアドレスで接続。
  10. 表示されれば成功!
  11. 最後に、インスタンスを削除して終了。
    1. コンソール上で可能(削除とリブートしか無い)
    2. ./gcutil deleteinstance [インスタンス名]でも可能です。
    3. ちなみに、Compute Engineでshutdown -h nowしたら、削除するしかできなくなります。(REBOOT INSTANCEボタンはエラーになります)
私はスターターパックを使っていじり倒そうと思いましたが、多分プロジェクト名を間違って申し込んだので、$1000が設定されないと思うので、適当に払います…。

2013/10/27追記:
金額が表示されたのをG+に投稿したのですが、こちらにもリンクを張っておきます。
https://plus.google.com/114183076079015753160/posts/88dV7kCuTrL

よくある質問
Q1. お金…?
A. 今のところ、どれくらいかかっているか不明です。が、そこまで課金されない気がする。まだ、Cloud Console上には課金情報は出ていません。
https://cloud.google.com/resources/starterpack/から、$1000のスターターパックに申し込んでおくと吉…?(Promo Code「fuy-in」です)


2013年10月7日月曜日

OSC広島2013に参加してきました。

オープンソースカンファレンスHiroshima 2013に急遽参加してきました。

ここ2、3年はブース出展をしても来る人は皆無という状態が続いていたことと、私のスケジュール調整が難しい事もあって、今年は参加しない方針にしていました。
しかし、スタッフの高田さんから「LT参加」の依頼があったので、LTのみ参加という、久しぶりにバカな事をやってみました。(5分のために新幹線で往復しました)

会場の様子はTwitterの#osc2013hiを追いかけて頂くなどで知っていただけたらと思いますが、大盛況だったようで、当日の参加者も200人ということだったようです。

私が駆けつけた時はすでに撤収準備に入っていたりして、あまり会話ができませんでしたが、ある程度話ができたのでよかったかなと思っています。
(やっぱり、オンラインよりは直接会った方がいいなと思います)

で、LTの時にthinreportsの発表の時にGoogle Closure Toolsというのを目にして、ちょっと感動しました。(Google Closure Toolsは西日本で聞ける人がいるのか?という程度には誰も使ってなかった…)thinreportsは裏でGoogle Closure Toolsを使っているらしく、何か協力ができるかも。ということでした。

島根の方だったので、またOSC島根にも出展を考えてもいいかなー。と思ったりしていますが、今年のようにセッションが15分しかないとかだとちょっと厳しいかな…。という気もしたりしなかったり。
(島根はけっこう遠いからな…)

LT自体は、本来の内容は2分30秒ぐらいで終わってしまったように思いますが、すぐに終わってしまうのはもったいないと思ったので、少しだけフリートークをさせていただきました。が、やっぱりおとなしく終わっておくべきだったかなと思っています。
暗い話題だけを提供してしまったので、今後はもう少し明るい話題があっても良いかな?と思うのですが、どうだろう…。

2013年10月5日土曜日

Androidプログラミングレシピ増補改訂版が発売されました。

昨年のテクニカルレビューアを務めたことのつながりで、今年も2冊のテクニカルレビューを担当させて頂きました。

昨年担当した書籍のことは以下のリンクをごらんください。
(ブログに書いたと思っていたが、どうやら書いていなかったようなので、)
https://plus.google.com/114183076079015753160/posts/bzhS5X5CUw6
https://plus.google.com/114183076079015753160/posts/EqYR5iWKsca

今年の2冊は初版でAndroid2.3までの内容として、英語で書かれた書籍が改訂されたので、日本語に翻訳されたものを、技術的観点で、私がレビューを行いました。
幅広い内容になっているのと、Android4までの内容が書かれているので、前回は1冊でしたが、今回は2冊に分かれています。
(1版のことについては、http://takashi-yokoyama.blogspot.jp/2012/01/android.htmlへ。)

1冊目のAndroidプログラミングレシピ​増補改訂版 アーキテクチャ/UI/ネットワーク編は、環境構築、各種View、通信(ネットワーク、Bluetooth、NFC、USBホスト)について扱われています。

2冊目のAndroidプログラミングレシピ​増補改訂版 メディア/データ/システム/ライブラリ/NDK編は、マップ、カメラ、音声、動画、センサー、GPS、Preference、SQLite、
ライブラリプロジェクトについて、NDK、RenderScriptの事が書かれています。
こちらに関しては、少し残念だったのが、Google Map Android API v2ではなく、v1のMapViewに関する説明になっていることです。
(公式に非推奨になっていることもあり、MapViewを使った新規開発は不可能なため。)
ここは、翻訳本の制約でしょうか。どうすることもできないので、興味がある皆さんが購入して頂いて、次回作に期待するしか無さそうです。

2冊とも文字が多いので、書籍に書かれているソースコードを入力して動かしながら読んだ方が理解は早いと思います。
そして、あまり知られていない便利なクラスがあるということに気がつくこともあるかと思いますので、ぜひ一読いただければと思っています。

2013年9月30日月曜日

HTML+CSSデザイン|基本原則、これだけ。【HTML5 & CSS3対応版】を読みました。

HTML+CSSデザイン|基本原則、これだけ。【HTML5 & CSS3対応版】
HTML5のクライアント側の技術も知りたかったので読んでみました。

デザインの基礎知識、プランニングの話題が前半出てくるので
個人的に必要だったマークアップとCSSのレイアウトあたりなどの話題が
なかなか出てこないというのが気になりましたが、内容とサンプルコードが
しっかりしていたので、この本は良かったと思います。

マークアップの部分は、コンテンツの違いが説明されていますし、
スタイルの部分はレイアウトや、インターフェイスの話題が大半を占めています。
しかし、アニメーションやデザイン的な話も書かれているので
個人的に知らなかった事が書かれていて、十分でした。

少し、サンプルコードを触りましたが、物足りないので
もう一度触ってしっかり覚えたいと思います。

気になるのは、編集時のチェックが甘いのか、参考資料の番号が
なかったり、間違っていたりと、読みすすめれば分かる程度の
ことですが、ちょっと残念だったかもしれません。

2013年9月29日日曜日

Go言語勉強会に行ってきました。

ぷち勉強会としてGo言語をやるということで、講師を務めてきました。
http://atnd.org/events/43427

ぷち勉強会の様子はhttp://togetter.com/li/570097にまとめられています。

当日の資料:http://goo.gl/lpydda
同日に+Shingo Ishimuraさんが公開した資料http://slid.es/sinmetal/first-golang
東京と、香川で同時開催だったようです。
go wikiとかも紹介されたようです。(私は見たことがなかった…)

今回は「浅く広く」ということで、主に文法について話をしました。
プログラミングのスタイルは人それぞれだと思ったので、
「こう書くべき」とは言わず、「いろいろな書き方がある」という
ことにしました。

ただ、少し内容としては物足りない部分があったかもしれません。
(他の言語でプログラムを書いている人ばかりなので、見ればわかる)

ちょっと、tour of goとか見てたら、全て知っている内容になってしまいましたが
実際、「初心者向け」ってなるとこんな感じだろうなと思ったり思わなかったり。

思ったよりもコードを書かずにGo Playgroundと、読んで理解されていたので
進捗は、70ページぐらいのうち、60ページ弱まで進んだ所で
タイムアップしました。

並列処理のところや、パッケージのことについても話をしたかったのですが、
仕方がないということにします。

次は、並列処理、テスト、パッケージのあたりを中心にしたものがあれば良さそうです。
が、やっぱり実際に何らかのコードを作成した方が良さそうな気もするので
難しいところですね。

Go言語に興味がある人はいるようなので、今後のGDG中国のイベントで取り上げたいと
思っています。

2013年9月8日日曜日

Go言語で構造体のメンバを継承する

久しぶりにGo言語関係のトピックです。たまたまTwitterで質問されていたので試してみました。(私も実は知らなかった)ということで、メモしておきます。

Go言語には継承の考え方はないのですが、構造体に別の構造体のメンバを取り込むことができます。
interfaceでもできることは書いてありますが、構造体に関してはドキュメントに明記がないような気はするけど、以下のリンクあたりに構造体のメンバを使うコード例が書かれています。(※英語なので読むのに時間と体力が必要なので今回は軽めにしておきます。)
http://golang.org/ref/spec#Selectors

ちなみにこの辺りの記述なのかもしれません。
http://golang.org/ref/spec#Composite_literals

サンプルコードです。(リンク先は動作確認ができるようになっています)
http://play.golang.org/p/nNV-jUiygC

package main

import "fmt"

type a struct {
 A int
 B float32
}

type b struct {
 a
 C string
 D bool
}

func main() {
 val := b {C: "abcde", D: true}
 val.A = 1
 val.B = 2.5

 fmt.Printf("b.A = %d\n", val.A)
 fmt.Printf("b.B = %f\n", val.B)
 fmt.Printf("b.C = %s\n", val.C)
 fmt.Printf("b.D = %v\n", val.D)
}



第21回勉強会@岡山を開催しました。


昨日、第21回勉強会@岡山を開催してきました。

私のAndroidのカメラをテーマにしたセッションと、萩野さんが開催している「HTML5を業務アプリで使うための勉強会」で取り上げた内容を紹介するセッションの2つが行われました。

最初は私のセッションでしたが、やっぱり練習不足は否めないものでしたが、参加者の皆さんはいかがだったでしょうか。当日の資料は以下になります。

Androidのカメラを使う(Presentation)
当日ハンズオンで使ったサンプルプロジェクト(事前に練習=完成したもの)
CaptureSample http://goo.gl/v8IWz8
CameraSample http://goo.gl/K8oNlU

CaptureSampleは、外部のカメラアプリに対してIntentを飛ばして、結果を受け取る版
CameraSampleはCamera APIを利用して写真を取ったり、ズームしたり、顔検出したりします。

実際は、プレビュー表示でハマってしまって(資料の抜け+練習不足)残念な事になってしまいました。時間もかなりオーバーしてしまった事もあってHTML5に興味があった方には申し訳ないことをしたかもしれません。

で、当日言った事をいくつか残しておくと、

  • カメラは端末によって動作が違うから、気をつけること。
  • CameraInfoの値をチェックして、ズームや、オートフォーカス等が利用できるかどうかを確認してプログラムが動くようにすること。
    • isZoom = falseの時にはズームは使えない。
  • 某端末は、isZoom = trueだけど、setZoom()したら、例外発生!
いくつか、Togetterまとめにまとめられているようなので、ご興味があればどうぞ。

やっぱり、前回のぷち勉強会とどうように、資料に書いてない部分を補う程度の「練習」が必要でしたが、なかなかその時間が取れず、セッションを担当するのは難しい気もしてたりします。

次回は9/28(土)にまた、香川のぷち勉強会で「Go言語」が扱われるので参加します。

2013年8月9日金曜日

GASAPIドキュメント作成プロジェクト(?)

先日、GASのAPIを抽出できないかと思って、頑張ってみたのでBlogに残す。
githubとかには公開していませんが、そんなに行数も多くないのでいいでしょう。

今の所、これと同じようなことをしているサービスがあって
+keisuke oohashiさんが作成しているI hack meというサービスで
GASの更新検出が主な目的です。

私の場合は、出版した書籍「Google Apps Scriptクイックリファレンス」にAPIの説明を書き残したものの、公務員になってしまって、激務なので、なかなか執筆時間が取れず
(教員なので、兼業する事は、許可を貰えば可能です)
執筆作業は難しいので
書籍の賞味期限が切れる前に別途、どこかに残しておきたいなーと思っているわけです。
(Driveとか、FormAppとか書籍には載っていないので…)

ということで、今のところSpreadsheetにAPIを抽出して引数と説明と注意点を書き残せたら便利だろうということで、コツコツやっていこうかと思っています。

さて、プログラムですが、foreachでメンバを抽出してそのままシートに出力しているだけです。クラスごとにSheetを分けるほうがいいだろうと思ってクラスごとにSheetを作っています。

が、量が多いので、ScriptDbに出力する方向で考えようかと思っています。
その後、Google Siteに転記かなー。

乞うご期待(あまり期待せずに生暖かく見守って下さい)

var spreadsheet;

function myFunction() {
  spreadsheet = SpreadsheetApp.openById("YOUR_SHEET_ID");
  printObject(this, "top");
}

function printObject(obj, name) {
  var apis = [];
  var sheet = createsheet(spreadsheet, name); // var sheet = spreadsheet.getSheetByName("hoge");
  for(var i in obj) {
    var typ = typeof obj[i];
    
    // APIのリストを配列に追加
    apis.push([i]);
    Logger.log(i);
    
    if(typ == "object") {
      printObject(obj[i], i);
    }
  }
  // 一括でSpreadSheetに追加
  sheet.getRange(1, 1, apis.length).setValues(apis);
}

// Sheetを取得(無ければ、Sheet追加)
function createsheet(ss, name) {
  // ss = SpreadsheetApp.create("GASAPIドキュメント");
  var sheet = ss.getSheetByName(name);
  if(sheet == null) {
    sheet = ss.insertSheet(name);
  }
  
  return sheet;
}

2013年7月28日日曜日

ぷち勉強会に参加しました。

昨日、香川県の高松でぷち勉強会が開催されたので、講師として参加してきました。

その時の資料はこちら。
http://goo.gl/CS8k4L

勉強会の様子

今回の内容のポイントは「共通化」でした。

GASのAPIの使い方などは、私の著書などで調べることも可能ですし、ドキュメントも
以前に比べると充実してきていると思いましたので、敢えてそういう所は省いて、
MS Excelなどと比べた時に有利な点として、既存の資産の使い回しができるのは
良い事だと思ったので紹介しました。

結局、データの共有という事で、ScriptProperties、ScriptDbの使い方を
紹介することになったので、その辺りは紹介し、実際に動かして結果を確認して
いただきました。

今回の話として強くアピールしたのは、「複雑な仕様」「規模が大きくなる」という
事が発生するようなら、GAEなどのアプリケーションに移行することをおすすめする
というGoogle+などで投稿している事を話しておきました。
(実際、どうなんでしょうね。あまり大きくなってしまうとどうなるか…。は
確認していないのは現状だし…)

現時点ではGoogle Appsのユーザも少なく、「金の匂いがしない」ということで
本腰を入れて…というようには、なかなかいかないようですが、地道に広めていこうかと
思っています。

フィードバック


  1. Math.round()は「丸め」であって、「四捨五入」ではない。

http://msdn.microsoft.com/ja-jp/library/ie/5cza0web(v=vs.94).aspx

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FMath%2Fround

今回の発表のケースだと、「税込金額」を求めるというものを想定しました。
で、そこで出てきたのが、四捨五入は0.5を足して小数以下を切り捨てるのが
厳密な定義ということでした。
(この点については私も反対意見はない)
ただ、実行結果からして、挙動はほぼ四捨五入の挙動を示していること、
Google検索の結果の上位が全て四捨五入と書いている事を考えると、
四捨五入ということで問題はなさそうに思っています。
(恐らく、負の数を扱った時の結果が厳密なものと違うのか?)

重要なことではあるけど、後は、Wikipediaの「端数処理」を見てご判断下さい。

反省点

最近、発表した後、反省することがなかったので、しっかり反省点を挙げて
おきたいと思います。

大きく、1点目は、「少ししか使っていない」ということ。実運用をしていないと
いうのもあって、紹介する時に、使い方程度しか紹介できないのは痛い。
ScriptDbの質問でも、共通化した時の問題点として、「同時更新」の問題が
発生してくるので、そういう時にデッドロックの問題は…?
という質問に対して回答がしっかりできないなど、まだまだということでしょうか。

2点目は発表の事前準備の時間が少ない。今回はまだうまくやれた方だと思いますが、
福山のAngularJSの時は、薄っぺらさが出てしまっていたようにも思うので
もう少し時間を取らないと(取れるようにしないと)いけないですね。

コードを書くということ自体が少なくなってきているので、上手にやらないと。

2013年6月8日土曜日

htmlday2013に参加しました。

今日はhtmlday2013の活動の一環として、
午前中はヒーロー島のイベントでハンズオン。
午後はAngularJSで遊ぼうというイベント。

ハンズオンの資料はそのうち、ヒーロー島さんで公開されると思います。
(恐らく…。公開されなければ、第20回の勉強会でも、ほぼ同じ内容でハンズオンする予定なのでその時に公開します。)

ハンズオンの時はMicrosoftのイベントだったので、アウェイ感がとても強かったですが
また、何かの機会に一緒にやれたらいいですね。
実際、ハンズオンはどうだったかなと思ってます。
ASP.NETでも、AngularJSは動くので使ってみて下さい。)
チュートリアルのモジュール化以外の部分はこなしました。(※ユニットテストを除く)

午後は、AngularJS + PureでTodoサンプルを実装してみました。
ソースはまた今度公開します。

ng-bindを使った方が良いということもわかったり、angularJSを使う幅が
広がったかなーと思っています。

最後に、前回のDevfest2013の延長戦の時にやっていた、YouTubeサンプルを
もう一度眺めて終わり。
これもソースコードを公開します。


2013年3月29日金曜日

HTML5を業務アプリで使うための勉強会 #2を開催しました

HTML5を業務アプリで使うための勉強会 #2に参加してきました。

今回の内容はHTML5で新たに追加されたり、廃止されたり、意味が変わった要素の
確認が主な内容となりました。
これまで存在を知らなかった要素が廃止になっていたり意味が変わったものを改めて確認してみると、「可読性」がポイントになっているように思いました。

当日注意したポイント


  • 図や、本文の説明を補足するものはfigure要素を利用する
  • strongはネスト可能
  • aの中にブロック要素を含める事ができる
  • section要素の中には見出し(h1〜h6)が必要
    • 実際、業務アプリで利用する場合はdivを使うことになりそうよね…。
  • 日時を表す文言を明確にするためのtime要素



当日の資料からの抜粋



HTML5で廃止されたタグの確認


basefont, big, center, font, strike, tt
cssにて代用可
frame, frameset, noframes
ユーザビリティとアクセシビリティにダメージを与える
acronym, applet, isindex, dir
あまり使われない、混乱を招く、他で代用可
s, u については?

HTML5で追加されたタグの確認


section, article, aside, hgroup, header, footer, nav, figure, figurecaption
よりよい文書構成にするため
video, audio, track, embed, mark, progress, meter, time, data, dialog, ruby, rt, rp, bdi, wbr, canvas, command, details, datalist, keygen, output

HTML5で変更になったタグの確認


address, b, cite, dl, hr, i, label, menu, noscript, s, script, small, strong, u

togetterまとめ


+Toyoaki Okoさんがtogetterに内容をまとめてくださっています。
http://togetter.com/li/478715

ページビューが順調に伸びているようなので、注目されていることなのでしょうか。

次週以降は…。


次週はDrag and Drop APIや、File APIをテーマにする予定になっています。
http://www.zusaar.com/event/613003

私は残念ながら参加できませんが、週末に補習を行うことで対応する予定です。
(平日はどうがんばっても深夜にしか参加できないので…)
今後のイベントの舵取りは+Takanobu Hagnioさんに引き続き行っていただけます。

もしかしたらイベント化するかも?
(希望があれば、G+、Twitterなどで言っていただければイベント化します)

2013年3月21日木曜日

HTML5を業務アプリで使うための勉強会 #1を開催しました

昨日、
HTML5を業務アプリで使うための勉強会(仮)
http://www.zusaar.com/event/584004

を開催しました。

次回(2回)があるかどうかが不明だったのでzussarのタイトルは(仮)となっています。
しかし、次回の予定も立てて、開催することになったので、blogのタイトルは#1としています。

まず、第1回目の内容は

  1. 前提条件を決める
    1. 開催予定
    2. 公開するWebサービスではなく、いわゆる「業務アプリ」に適用するための勉強会であること。
    3. JavaScriptは利用する
      1. HTML5のAPIの使い方
      2. JavaScriptライブラリ(Jqueryなど)
    4. (できれば)GDG中国のイベントで成果を発表
    5. 私が4月から勤務時間的に平日開催では開催できなくなったことを話す。
  2. 参加者のHTML5の知識の確認
  3. HTML5 Formsの事を話したり、調べたり、動きを確認したり…。

最初に以下のサイトを紹介しました。

HTML5を導入する時にチェックをしておいた方が良いもの。

チェック関係

文法チェック

アウトラインチェック

各種ブラウザの対応状況を確認

HTML5 & CSS3 Support

HTML5 Test

今日のサンプル的なお題

HTML5Rocks HTML5 Forms

HTML&CSS標準デザイン講座(書籍)
http://goo.gl/BsxBD (Amazon)

参考サイト



HTML5でごく普通のWebページを作る

Eric Meyer’s Reset CSS(ブラウザの標準スタイルをリセットする)

テーマは入力フォームなので、HTML5の仕様でカバーできる部分はカバーしましょうという意味も込めて、以下の属性を紹介
autofocus属性(初期フォーカス位置)
required属性(必須入力)
placeholder属性(入力例の表示)

新しい入力タイプも紹介しました。
input type="range"(スライドバーで入力できる)
input type="date"(Opera/Chromeだと日付の入力でDatePickerが表示される)
input type="search"(検索文字列の入力)
input type="tel"(電話番号)
input type="color"(色入力、カラーピッカーが表示される)

CSS3の指定で
:invalid
:required
を使うと、それぞれ、不正な入力時と未入力時のスタイルを指定することも可能になっています。(サンプルはHTML5rocksを見て下さい)

HTML5の入力フォームは指定したタイプの書式に合わないものはブラウザで入力チェックをして間違った入力の時はエラーメッセージ(JavaScriptのsetCustomValidity()メソッドでカスタマイズも可能)も表示してくれる優れものです。
(当然、Submitされません。)

結論としては、それぞれの入力項目に対して属性を正しく指定して、「何を入力するか」を明確にしましょう。という感じになりました。
が、現時点ではブラウザによって対応状況がまちまちなので、HTML5Testなどで対応状況を確認して、使えるものはコーディング規約に規定するなどで運用できるのではないかという話もありました。

今後の活動に対して、いろいろな話題の広がりがありそうな回だったと思います。

次回の開催は、3/27(水) 19:00からです。場所は当日の参加者の様子から一番近そうな場所を選んで告知します。

HTML5を業務アプリで使うための勉強会 #2



2013年3月18日月曜日

4月から電気科の講師になります。

2月の初旬に高校の教員になることが決まったという記事を投稿したのですが、
やっと、どの高校に配属されるかというのが決まりました。
(校長先生から連絡がありました)

具体的な高校の名前を出すのはやめておきますが、
今の家からだとちょっと遠いかもしれないです。

ちなみに、電気科で、かつ定時制の担当になりました。

なので、就業時間が13:00〜21:30だそうです。

GDG中国の活動について


GDG中国に対する活動で平日に動かないといけないようなこと(例えば、会場を借りた時の銀行振込とか)は午前中が自由に動けるので今後も問題なく自分で活動できそうです。

いろいろ解決しないといけないですが、
平日の夜のイベントは参加(開催)不可能になりました。(深夜のジョイフルとかならいけるか?w)
スタッフの方にお願いする形であれば何とか開催も可能…か。
あ、前日移動という方法も取れないぞ…!?
ということは、遠隔地の活動が難しい感じだな…。ちょっと考えよう。

実際の仕事


については、しばらくすれば具体的に打ち合わせをしてから準備をすることになるかと思いますが
私は情報が専門なので、電気科の電気にどこまで太刀打ちできるかが非常に気になります。
ちょっと困ったねぇ。
(高校、大学で少しだけ電気基礎と電気回路、電子回路はやったけど、もう10年以上前の事だし…)

「素晴らしい経歴を持たれていて…」とお言葉をいただいたものの、適用できるのかどうかは
いろいろ挑戦ですね。

ということで、食品運送のトラック運転手の挑戦の次は電気の分野への挑戦となります。

どんどんITから遠ざかっているけど、ちゃんとやりますから!

2013年3月1日金曜日

GAE/G+AngularJSでGoogle+ SignInを利用する(1)

最近、公開されたGoogle+ SignInという、Google+アカウントを利用した認証
サービスを利用してみようと思ってがんばってみました。

Google+ SignInについては以下の記事をご覧ください。
http://googledevjp.blogspot.jp/2013/02/google-sns.html

で、本当は公開されているサンプルを動かせばいいのに、わざわざ苦戦する方向で
試してみました。

事前準備として、APIsConsoleで

  1. Google+ APIをONにする。
  2. ClientIDを作成する。(Web Applicationのものを作成してください。)

ClientIDは削除できないので選択を間違えると、無駄にIDが増えていくことになるので気をつけてください。(リダイレクト先は後でも変更可能です。)

ライブラリが提供されているので、実際にはHTMLだけ作成すればローカルのWebサーバを
経由するだけでGoogle+ SignInボタンは表示されます。

実際にSignInボタンを押すと、プロフィール情報が取得され、ブラウザで表示させる事が
できるようになります。

サンプルコードはgithubで公開しています。
https://github.com/tyokoyama/gplus-signin-sample

単純な例であれば、すぐ作れるようになりますが、私はAngularJSも一緒に使おうとして
だいぶはまりました。(SignIn直後にプロフィール情報を表示させる事は今も解決していません)

最初のSignIn後のリダイレクト先にAngularJSのコントローラの関数を指定できないので
以下のように強引に関数を呼び出すか、


var elem = document.getElementById('viewResult');
angular.element(elem).scope().signIn(authResult);

githubのサンプルコードのように、ボタンを配置してボタンを押した後で
プロフィール情報を取得しにいく。という事なら何とか可能でした。

実際の動きはPHPのQuickstartを見ると良いかもしれません。
(HTMLの部分はjQueryが使われています)
https://developers.google.com/+/quickstart/php

GAE/Gでも、PHPのプロジェクトからindex.htmlだけコピーするだけでも、
プロフィール情報が表示されるようになります。
(適当にAjaxでのリクエストが発生しますが、GAE/G側の実装がなければ404の応答になるだけ)

もうしばらく、いじり倒さないとだめだなと思ったのと、
生産性の低さに嘆く1日でした!

関連するGoogle+の投稿

https://plus.google.com/u/0/114183076079015753160/posts/CYgcSMk3GJN
https://plus.google.com/u/0/114183076079015753160/posts/eSMpESRHTRo

2013年2月19日火曜日

mavenを使ってAndroidアプリケーション開発(1)

mavenを使い倒したいので、Apache Maven 3 クックブックを読みながら、

Androidアプリケーション開発環境を構築していました。Maven自体のインストールは
無くても良いということでしたが、インストールしていても問題ありません。(私はインストールしてから環境を構築してみた)

コマンドは
$mvn archetype:generate -DarchetypeCatalog=http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml

とかでプロジェクトは作成できるのですが、
mvnコマンドを使うよりは、EclipseのMaven-Android-Pluginを利用した方が簡単に作成できるようになります。

Eclipse Marketplaceのインストール


このMaven-Android-Pluginを適用するためには、Eclipse Marketplaceをインストールする必要があって、メニューのHelp→Install New Softwareで、"http://download.eclipse.org/mpc/indigo/"を入力してインストールします。

Maven-Android-Pluginのインストール
メニューのHelp→Eclipse Marketplaceを選択して、"android m2e"で検索するとAndroid Connectorというのが出てくるので、それをインストールしてください。

実際に環境を構築して…

プロジェクトの作成はEclipseから作成できるようになるので、MavenProjectとして作成します。

プロジェクト作成後にEclipseからでもRun→Maven buildを選択してもコンパイルはできますが、実機にインストールされないことと、Goalの設定を"Compile"にする必要があります。

コマンドラインから
$ mvn clean install android:deploy

とすると、コンパイルされて、起動しているエミュレータか接続されている実機
(adb installができる状態にしておく)にインストールされます。

その後、アプリケーションを実行すると確かにHello Worldが見えるのですが…。

開発をする上で、色々問題がありました。

問題


  1. Eclipse上でAndroid関連(だけか?)のクラスが全て赤線(エラー)表示
  2. プロジェクトからアプリケーションの実行ができない
  3. 書籍にもAndroidアプリケーション開発の章があるが、内容が薄いし、役に立たない…。


これからも苦戦しながら、いろいろ理解が進むかな…。

Google+の投稿
https://plus.google.com/u/0/114183076079015753160/posts/eRQpXH9qDkQ



Jenkins実践入門を読みました。(1)

Jenkins実践入門を読みました。


ただし、途中(5章 JUnitでテストする)までで中断しています。

その理由は、「実際に使ってみないとイメージが沸かない」というのがあって、
(サンプルコードを使えば動きは見れるのでしょうが)
実際のプロジェクトで試してみたいと思って、ひとまず、テストを実行させる所で
中断して、別の書籍を読んでいます。

今回はほぼ環境構築で苦戦しましたが、
Scientific Linux上に構築する場合はパッケージのTomcatを使わずに、公式からダウンロードした物を
利用した方が良いと思います。(パッケージだとtomcatユーザで動作しますが、ログイン不可であるため、gitのコマンドを実行させる事が”そのままだと”できません。)

この書籍はSubversionで動作させる前提で説明していますが、
私はGit Pluginを導入して動作を確認しました。
操作は全く違いますが、書籍と大幅に違う表示になるという事は無いのと、
10章にGitとの連携についても記述があるので、困ることはないと思います。

後は、ant、またはmavenの使い方がわからないと自分のプロジェクトで動きを確認することは
難しいので(antのbuild.xmlや、mavenプロジェクトのpom.xmlあたりの記述がわからない)
同時にantやmavenの書籍を読み、ある程度知っておいた方が良いかもしれません。

という事で、今後もまた読むことになると思うのでタイトルは(1)としました。

関連したGoogle+の投稿

https://plus.google.com/u/0/114183076079015753160/posts/GtRGRr85aQT

https://plus.google.com/u/0/114183076079015753160/posts/AxLauhRC2CG

JenkinsにGit Pluginを導入した。
https://plus.google.com/u/0/114183076079015753160/posts/E8L5bT1Cb3E

Tomcatはパッケージのやつを入れない方がハマらない…。
https://plus.google.com/u/0/114183076079015753160/posts/1949ByXFohW

読み方がわからん…。
https://plus.google.com/u/0/114183076079015753160/posts/Tq5Cx3fHiwf

Antタスクでハマる
https://plus.google.com/u/0/114183076079015753160/posts/cqoQk5kB1JZ
https://plus.google.com/u/0/114183076079015753160/posts/AwsYPtijrVH
やっと解決
https://plus.google.com/u/0/114183076079015753160/posts/3zshn4H4ZSB

2013年2月16日土曜日

GDG Chugokuのマネージャの活動目的

年末に、私が思う勉強会についての記事を書いたのですが、
大体はその記事にも書いた通りなのですが、私が2年9ヶ月ぐらいの活動を通じて
ずっと一貫した考え方があります。

繰り返しになりますが、それは「身近な、まだ見ぬ技術者の発掘と参加者のレベルアップ」という事です。
実際、活動を始めた頃からその考え方で活動しようと決めていたのですが、
Google Developer Day 2010の基調講演でも同じようなコメントが発信され、
より強く考えるようになりました。


実際、目的が達成できているかどうかは私にはわかりませんが、
勉強会というのは、勉強をするのが目的なので、「人集めに奔走し始めたら終わりだ」とも
思っています。

参加者がいなくなったら、「需要がなかった」とあきらめるのも一つの考え方のようにも
思います。(これは、人から言われたことですが)

中国地方だとGoogle技術が仕事に結びつくというのが少ないようにも思えるので、
どうしても扱うプロダクトによっては、ほとんど人が来ないということもあるかもしれません。

ただ、マイペースでやらないと疲れるので、(特に最近は辞めたくなったりもしたので)
GDGのアピールやら、イベントの人集めやら、良いプロダクト生み出す事とかは他のマネージャ達に託して
今後は、まったりと告知をしながら、裏番組をぶつけられながら(笑)活動していきたいですね。
(長く続けると疲れてくる頃もあるんだろう…。恐らく)

という事で、なんとなく早朝のバイト中に思ったので記事にしてみました。

最後に、久しぶりにGDD 2010の事を思い出した(と言っても、私は京都会場でスタッフしてましたがw)ので


「ジュニアなエンジニアは、次の世代を支える存在かもしれないので、彼らを育てるような活動をしていただきたい」というセリフが印象的でした。

Google Developer Day 2010の基調講演

2013年2月11日月曜日

JUnit実践入門を読みました。


JUnit実践入門を読みました。
この書籍はJavaで動作するユニットテストフレームワークのJUnitを利用した
テストコードの書き方が書かれていて、私も途切れ途切れに読んだので
この書籍もまた読もうと思っていますが、サンプルコードも掲載されているので
実際に入力して動かした方がいいかもしれません。

特に個人的に発見だったのが、カテゴリ化テストとパラメータ化テストで、
書き方を知らなかったのもありますが、これまではいろいろなテストが混ざってしまって
読みにくく、メンテナンスもしにくかったのですが、この辺りの書き方を利用すれば
もう少しデータの種類も増やせそうだし、テストの分類もできるので
「どのような視点で」テストをするのかが明確にできそうな気がしました。

最後に演習問題のページがあり、そこで如何にJavaの力がないのかを
思い知るのも良いかもしれないです。
(私はJDK1.4あたりで止まってるっぽい感じがしました…)

他の使い方としては、リファレンス的に参照しても使えると思います。
(恐らく私はこの使い方になりそうな気がします)

やっぱり書籍は繰り返し読んだ方が良いですね。

Two-legged OAuthを利用してGoogle Appsにアクセスするには

Google Appsの業務をやり始めてから初めて知ったTwo-legged OAuthの認証について
あまりいい記事がなかったので、書き残しておきます。

結論からいうと、毎度のごとく、+keisuke oohashiさんの助けにより
うまく動作させることができました。(ありがとうございます!)

Two-legged OAuthがGoogle Apps無料版でも利用できるのかどうかを
確認した時の投稿(あまり参考になりません
https://plus.google.com/u/0/114183076079015753160/posts/j4sHzchyHWs

Two-legged OAuthを検証し始めた時のGoogle+の投稿(参考にするならこちら)
https://plus.google.com/u/0/114183076079015753160/posts/8NCiJghLapC

Two-legged OAuthのポイント


  • 認証用のオブジェクトと、各種APIにアクセスするためのオブジェクトを生成する。(以下の例はCalendar API)

OAuthHmacSigner signer = new OAuthHmacSigner();
signer.clientSharedSecret = "<クライアントシークレット>";
    
OAuthParameters param = new OAuthParameters();
param.version = "1";
param.consumerKey = "<コンシューマキー>";
param.signer = signer;
    
Calendar calendar = new Calendar.Builder(httpTransport, jsonFactory, null)
      .setHttpRequestInitializer(param)
      .setCalendarRequestInitializer(new CalendarRequestInitializer("<Simple API AccessにあるAPI KEY>"))
      .build();
    
service = new CalendarService(calendar);

コンシューマーキーはGoogle Appsだと、取得したドメイン名のスーパーキーが標準で用意されているのでそれを使うのが簡単ですが、実際に運用する場合は自分で作った方がいいでしょう。作成する場所はGoogle Appsの管理コントロールパネルから高度なツールを選択して「サードパーティのOAuthクライアントアクセスを管理する」から作成して下さい。コンシューマーシークレットも同じページの「管理」リンクをクリックすることで見ることができます。次にSimple API AccessにあるAPI KEYですが、これは、「Google APIs Console」を表示してAPI Accessメニューをクリックすると表示されるKEYを指定します。(Google Appsの管理者アカウントでアクセスした方が無難です)

  • 編集する対象のユーザを指定する。


ArrayMap<String, Object> customMap = new ArrayMap<String, Object>();
customMap.add("xoauth_requestor_id", "<対象のアカウント>");

com.google.api.services.calendar.Calendar api = service.getService();
com.google.api.services.calendar.Calendar.Events.List eventList = api.events().list(target_email)
               .setTimeMin(new DateTime(fmt.format(Calendar.getInstance().getTime()) + "T00:00:00+09:00"))
               .setFields("items(id,summary)")
               .setMaxResults(1000);
   
eventList.setUnknownKeys(customMap);
   
Events events = eventList.execute();

Two-legged OAuthは管理用途で利用される機能(?)なので、編集する対象のユーザを指定しないとどのユーザのデータを編集するのかがわからないので対象のユーザを指定して下さい。

以上で、Two-legged OAuthを使った管理作業が可能になると思います。

2013年2月2日土曜日

4月から高校教師になれそうです。

今日、岡山県の教職員課から「4月から常勤の講師としてお願いしたい」という旨の連絡をいただきました。そこで、以前からアプローチをしていただいていた事もあって快諾しました。
(私は教員免許(工業)をもっているので、以前、金に困っていた時に申請していたのが、今、効果が出たという感じで…)

なので、私は4月から高校教師になれそうです。契約期間はひとまず1年間みたいです。(とりあえず、電話連絡だけなので”なれそう”ということにしておきます。)

一応、公務員ということになるので「副業NG」という制約がついてしまうことになってしまいます。
なので、今携わっている以下の仕事は全てやめないといけなくなりました。

  • 朝の食品配達のパート
  • 専門学校の講師
  • 自営業(一応、個人事業主なので廃業届を出さないといけないですね)
とりあえず、朝のパートは「XX日に辞めます」で良いと思うのですが、
専門学校の講師は、来年度の依頼を受けていたので、代役を探さないといけません。(ある程度、お願いしてみようという候補はいますが…)

一番面倒なのは、自営業の部分ですね。「廃業届」を出せば、ひとまずなしにはなりますが、
ブログ、Androidアプリ、いろいろな所に貼りまくったアフィリンクとかどうしようかな…と考えています。

ブログの広告はひとまず非表示に設定を変えたのですが、アフィリエイトリンクはそこら中に貼ってしまったので、もうどうしようもないな…。G+のプロフィールのやつは変更できるか…。
(これまで、まともな収入になったことは無いのですが…)

ということで、広告系の収入はGDG中国の活動費として利用していこうと思います。
(交通費、設備の利用料などなど)

OKかどうかは、次に連絡があった時にでも聞いてみるか…。
(多分だめなんだろうな…)

何か、いいアイデアがあったら教えて下さい。

2013年1月27日日曜日

書籍「Google Apps Scriptクイックリファレンス」出版


書籍が出版されました!





ついに、私が執筆した書籍第3弾の「Google Apps Scriptクイックリファレンス」が出版されました。
この書籍は、Google Appsで動作するスクリプトのリファレンス本です。すべてのサービス(API)についてフォローできていませんが、ほぼすべてのサービスについて記述されています。Experimental(実験的)なサービスの一部がぬけてしまいましたが、面白いテーマのものは掲載できたのではないかと思います。

Amazonで一瞬「入荷時期未定」となった


Amazonの初回入荷が少なかったのか、一瞬「在庫切れ」となったようで、注文していただいた方の中には発送待ちになってしまったのではないかと思います。すみません。

https://plus.google.com/u/0/114183076079015753160/posts/GgwsPhx2QzH

電子版の出版は?

今の所、予定はありません。(少なくとも、私の耳には入っていません…)

いつ書いてたの?


書籍の書き始めは9月で、11月末脱稿でした。脱稿前の査読は11月の中旬頃にしていただきました。12月は出版社による査読と修正の繰り返しでした。
で、1月出版できてよかったです。

書籍で苦労した点


今回の書籍で苦労したのは幅広い範囲をフォローすることと、思ったよりもAPIが多くて、「数の暴力」ではないのですが、大量のAPIの検証に時間を取られたのが執筆時の苦労でした。
特に、「まともに動作しない」という状況も多々あり(使い方が間違っていたり、ドキュメントの記述がおかしいなど…)、+keisuke oohashiさんにはたくさん助けていただきました。
その様子はGoogle+で#gasjaを検索していただければ、見つけられると思います。
(その時のリンクもどこかにまとめたいのですが時間が無い…)

また、脱稿後の出版社での査読と修正の量も多く、修正作業が大変でした…。
(査読、修正で結局1ヶ月かかった(?))

査読に協力していただきありがとうございました


今回はこれまでの書籍と違って、2人の方に査読をお願いしました。
なので、事前に読んでいただいている分、少し安心しています。
謹呈見本が3冊届きましたが、協力していただいたお2人に送りました。
レイアウトされた書籍を見て、感動してくれてたらいいな…。

これから…


Developer Expertの方にも購入していただいたようで、これからのフィードバックが恐ろしいですが、いい反応と思って様子を伺おうと思っています。
そして、Google Apps Scriptの利用者が増えるきっかけになる事を祈っています。
(見た感じだと今の所、反応は良さそうだけど、どうだろう?)

ついでに、書籍が売れてくれたら喜びます。(増刷とかならないかな…)

2013年1月7日月曜日

プログラミング言語 Go フレーズブックを読みました。

プログラミング言語 Go フレーズブックを読みました。



この本はGo 1.0に対応した書籍で元々は英語の書籍だったものを+Yoshiki Shibataさんが翻訳して書籍を出版されました。

実際、読んでみた感想としては、「Goの初心者向けではない」です。内容も言語が得意としているからか、goroutineとchannelを使った例が多かったので、マルチスレッドプログラミングの知識(よりも経験、マルチスレッドのプログラムを動かしてみる程度には…かな?)があった方が良いと思います。
それから、ネットワークや、Webサーバの話題がありましたが、OSのシステムコールを呼び出すなどの話題はありませんでした。(ファイルのアクセスは少し出てきています)これも、言語の特性として得意ではないから(?)なのかもしれないですね。最近はGoでWebサービスを作る事例も増えているので、時代の流れには沿っている感じもしました。

したがって、ある程度Goでプログラミングをしてみてからの方が良いかもしれません。

私もよくわかっていなかった部分があったので、いい発見ができたのと、また読み返してみたいと思っています。
(本当はコードの写経とか、動かしながら確認するべきだったのですが、そこまでの余裕がなかったので今回はしていません)

個人的に気になった点は、文章が難しい感じがしました。日本語的におかしいという点はなかったのですが、私の知識が足りないだけなのかもしれません。

GDG中国のイベント等で、噛み砕いた内容のセッションができると良い気もしました。
(やるかどうかはわかりませんがw)

2013年1月3日木曜日

2013年の目標

2013年が始まって、すでに3日目に入りました。

久しぶりの3日間だったので、じっくり休みながら、2013年の目標を考えていました。

昨年同様に、GDG中国、仕事、技術面で目標を立ててみようと思います。

2011年も2012年も正直、目標のことなんて盆になるころには忘れていたのですが、
意外にも達成率が良かったみたいです。

という事で、今年も同じようにやってみようと思います。

GDG中国(勉強会関連)の活動


確定分を確実に消化していく




1/13のイベントではAngularJSを使ってみるということで、軽く紹介する予定です。

1/19のイベントの内容はまだ決めていないのですが、Androidのネタではないです。
Google Apps ScriptかGoで行くとは思いますが、AngularJSも面白いので
いいかな?なんて。他にもGoogle Cloud Storageとか、BigQuery、Google Cloud SQLあたりも
どこかで紹介したいものですが、いつになることやら。
(5月にGoogle I/O 2013も開催されるので、そこまでにはどうにか…と言いたいところだけど
タイミング的な問題もあって不可能でしょうね…。)

今後の開催予定について

今年も基本的には思いついたらやるという作戦でいくつもりですが、
新規の講師もお願いしたいものです。(特に今年は主力メンバー激減しそうなので…)
(ノルマみたいに「何人増やす!」みたいなのは宣言しません。そういうのではないと思うので)

あまり詰めすぎず、空けすぎずの2、3ヶ月間隔で進めたいですね。

1回は福山で開催する。
OSCは「スタッフの参加がなければ」回避して、単独開催でいきたいと思います。
(昨年も”無理して参加する必要はないのでは?”といった意見もあったので、さらに距離を置こうと思います)

仕事関係


  • 早朝の配達のバイト
  • 専門学校の非常勤講師
  • Google Appsのアドバイザー→データの移行プログラム(βバージョン)の作成案件(?)
  • Androidアプリケーション/Chrome Extension/Google App Engineのアプリケーション開発
  • その他突発の社会人講師とか。

早朝のアルバイト自体は、悪くないと思っているのですが、1日に複数の仕事をやるようだと作業時間が長くなってしまって、開発もできないし、疲労もたまるし、それぞれの業務のクオリティが下がってしまうという事が発生してしまいました。(特に最近の授業は本当に生徒に迷惑をかけてしまっていると思います。すみません。)

よって、目標は「早朝のバイトを辞めても大丈夫な生活を作る」か、「早朝のバイトともう一つぐらいの仕事の生活をする」事を目標にしたいと思っています。

ただし、常駐系の作業をやってしまうとフットワークが悪くなるので考えどころ。
2月、3月は専門学校の授業もなくなるので、少なくとも3月ぐらいまで続けないとだめだろうなと
思っていますが、4月以降で何か策が出てこなければ、後者の作戦になりそうです。

ちなみに、Google Appsのアドバイザーは1月末で終わりです。

技術関係


  • Google Apps(無料版)をしっかり使う
  • Google+も主力にする
  • Go
  • AngularJS(HTML5 + CSSも)
  • blogをしっかり書く
  • 書籍も読む
  • なんか執筆(?)

2013年もGoogle技術を主体に進める予定ですが、Googleの副社長が「Microsoft Officeのユーザの9割を獲得するのが目標」なんて言っているようなので、だんだんとGoogle Appsの導入が増えてくるのでしょう。中国地方だと(私が知らないだけですが)Google Appsの使い手があまりいないので将来の導入で困っている人がいたら、最低限の手助けができる程度には利用しておきたいと思っています。
(まあ、無料版でどこまでfor Businessの機能が使えるのかは未知数ですが…)

次に、Google+を主力で今年も使おうと思っています。2012年も使ってきたのですが、どんどん新機能が導入されてカオスなので、すでにやばいですが、上手に使っていきたいと思います。
Twitterは「イベント時」、「告知」、「MensionやDMへの反応」以外にはROMしかしないようにするつもりです。

あとは、私の本来の目的である「Webを勉強する」という目的を達成するために、今年はGo(GAE/G)とAngularJSでWebアプリケーションを構築してみたいと思っています。(今の所、アイデアはないのですが、何らかの形で)

そして、blogを書くこと。技術的なメモとかがGoogle+に投稿したり、単に忙しかったりで投稿がおろそかになってしまっていたので、繁忙期以外はしっかりまとめていきたいと思います。

最後に書籍を読むこと。興味を持って購入したものの、全く読んでいないという状況が目に余るのでしっかり読んでいくつもりです。(今は「プログラミング言語Goフレーズブック」を読んでいます)
他にも「JUnit実践入門」とか、「Jenkins実践入門」なんていうユニットテスト系の書籍も購入したまま読めていないので読みます。

生活面

生活面ですが、やっぱり「スポーツクラブ」を活用することでしょう。
2012年は週4回ぐらいのペースでは通えたので、2013年もしっかり「風呂」として活用したいと思っています。
ただ、早朝のアルバイトを始めてから、夜遅くになるのはまずいと思い始めたことと、
肉体労働+運動になるので、肉体の疲労が蓄積しやすいことがデメリットになり始めました。

2013年も「下の上」な生活をしながら生き延びることにします。
(Bloggerに見出し機能があることに、やっと気がついた…。)