「プログラミング未経験のタワレコ店員がエンジニアになって思ったこと」というスライドを書いてみた

最近、〜歳からプログラマーになってとかキャリア論とかの話を見たりするのですが、
みんなすごい人ばっかりだなぁ思ったので何にもスゴくないド素人がエンジニアになったときに何を考えたのかを書いてみました。


http://koba04.com/slide/become_a_programmer/


正月でこれまでを少し振り返ってみたのとreveal.jsを試してみたかったのが書いた大きな理由ですが、書いてみるとやっぱりたいしたことしてないのでたいした内容にならないですね。


今年も頑張るぞー

軽く2012年振り返りと2013年やること

振り返り

  • 2012年はブログのエントリを22個書いていたので大体1ヶ月に2個書いてたみたいで、内容はJS周りが多かったのでJSに色々苦しんでいたようです。

2013年は

  • 色々掲げるとグダグダになることわかったので、今年はJSをもっと勉強していっぱい書いていく事をメインにしつつ、今年こそはiPhoneアプリを作ってリリースします!(Titaniumで作ろうかなと考え中)
    • 2012年中に作るもののイメージを決めたかったのですが、これっていうのに決まらなかったので早く決めないと。。。
  • 勉強しなければいけないこともしたいことも山ほどあるので、色々触れたりしつつピンポイントで深めていきたいと思ってます。
  • あとブログもそろそろ移転したいなぁ。。
  • 今年もよろしくお願いします。

MacアプリのDashでのドキュメント検索が便利な気がする

前から入れていたもののあまり活用してなかったのですが、最近また使いだしたMacアプリの紹介です。
「Dash」というドキュメントを検索したりSnippetを登録したり出来るアプリがあります。

https://itunes.apple.com/jp/app/dash-docs-snippets/id458034879



ネコもカワイイですね。


これの便利なところは、Snippetの保存先をDropboxにしておくと複数環境でSnippetを共有できるとか、オフラインでもドキュメントを検索できるとか色々あるのですが、なにより便利なのは1つのインターフェイスで様々なドキュメントを検索出来るところだと思います。


VimとかEmacsなどのEditorで頑張って全部検索出来るようにするという方法もあるかもしれないですが、
Dashを使うとMDNのJavaScriptのドキュメントも、jQueryのドキュメントもMan PageもPerlのドキュメントもNode.jsのドキュメントも同じように「option」+「space」で起動して検索できるでとても簡単で楽です。




ドキュメントの種類も

iOS, OS X, Man Pages, ActionScript, Akka, Android, Arduino, Backbone.js, C, C++, CakePHP, Cappuccino, Clojure, Cocos2D, Cocos2D-X, Cocos3D, CodeIgniter, CoffeeScript, Common Lisp, Corona, CSS, Django, Drupal, Emacs Lisp, Erlang, GLib, Groovy, Haskell, HTML, Java, JavaFX, JavaScript, Joomla, jQuery, jQuery UI, Kobold2D, Lua, MongoDB, Node.js, Mono, MySQL, Perl, PHP, Play, PostgreSQL, Python, Qt, Redis, Ruby, Ruby on Rails, Scala, Sparrow, SQLite, Symfony, Tcl/Tk, Twisted, TYPO3, Underscore.js, Unity 3D, Vim, VMware vSphere, WordPress, XSLT, XUL, Yii, YUI, Zend.

と本当にたくさんの種類があります。
あと何気にGoogleで検索したりStackOverflowで検索したりも出来ます。


無料版のままだと時々検索で待たされることがあるのですが、今だと850円払うとそれもなくなります。
細かい操作性でアレだなと思うこともあるのですが、Dash内のブラウザでもSafariとかChromeとかと同じように二本指のスワイプで戻ったり進んだり出来るようになるとさらに嬉しいです。



JS系のAPIを確認するのに、今まではブラウザで検索することが多かったのですがDashでまとめて出来るようになったのは個人的にはうれしいです。
あと、今までSnippetってあまり使わなかったのですが少しずつ使うようになってきました。会社で使う定型文とかを登録したり。


以上、ちょっとした小ネタでした。

jQuery1.8.2のanimation系メソッドをAndroid2.3.4のブラウザで使うと落ちる件

ゆとりなのでjQueryのtoggle()を使おうかなと思って、Android2.3.4のブラウザで確認していると何度やってもそこでブラウザが落ちるということがあったので調べてみたところ、下記のissueが原因のようでした。

上記のcommitでfixされていたので、このpatchあてるか1.7に落とすかどうしようかなと思っていたのですが、先日このfixを含む1.8.3がリリースされたので1.8.2(1)でshow()とかhide()とかtoggle()とかのanimation系のメソッド使っている場合は1.8.3にアップデートするといいんじゃないかと思います。


http://blog.jquery.com/2012/11/13/jquery-1-8-3-released/

gitのmerge-commitをrevertする

これまでtopic branchをmergeするときはrebaseしてfast-forwardな状態でmergeするか、merge --squashして何かあった時にすぐに戻せるようにと考えていたのですが、そもそもmergeを簡単にrevert出来れば問題ないしどうやるのかなぁと思って調べたところ、revert -mオプションで出来るんですね。
http://qiita.com/items/41b724a1c3569044372c


(mergeした記録を残す必要がないときはfast-forwardなmergeでもいいと思いますがその辺りの議論は http://togetter.com/li/407277 を)

mergeコミットを取り消したい場合

% git revert -m 1 mergeコミットのSHA1

という感じでやれば出来るのですが-mの後の数値ってなんだということで色々試してみました。
オプションを見ると-mの--mainlineの省略形でmainlineのparent-numberを指定するようです。

Usually you cannot revert a merge because you do not know which
side of the merge should be considered the mainline. This option
specifies the parent number (starting from 1) of the mainline and
allows revert to reverse the change relative to the specified
parent.

テストするブランチの状態
  • masterのREADME
initial commit!!!
from master1
from master2
  • developのREADME
initial commit!!!
from develop1
from develop2
  • mergeする
% git co master
% git merge --no-ff develop
# confrictの解消
% merge後のREADME
initial commit!!!
from master1
from master2
from develop1
from develop2
  • logの確認 ( commit log == READMEの行)
% git log --oneline --graph
* 375895c Revert "Merge branch 'develop'"
*   4c03b80 Merge branch 'develop'
|\  
| * 975a3b2 from develop2
| * 9732b33 from develop1
* | 4225ab1 from master2
* | 2d07f6d from master1
|/  
* be9b1b4 initial commit

「-m 1」でrevertする

  • この場合developのmergeを取り消すことが出来ます
% git revert -m 1 4c03b80
[master ba46e36] Revert "Merge branch 'develop'"
 1 file changed, 2 deletions(-)
  • diff
% git diff 4c03b80
diff --git a/README b/README
index d761f86..73735d7 100644
--- a/README
+++ b/README
@@ -2,5 +2,3 @@ initial commit!!!
 from master1
 from master2
-from develop1
-from develop2

「-m 2」でrevertする

  • この場合、masterがdevelopブランチと同じ状態になります
% git revert -m 2 4c03b80
[master 4eb3086] Revert "Merge branch 'develop'"
 1 file changed, 2 deletions(-)
  • diff
% git diff 4c03b80
diff --git a/README b/README
index d761f86..73735d7 100644
--- a/README
+++ b/README
@@ -1,6 +1,4 @@
 initial commit!!!
-from master1
-from master2
 from develop1
 from develop2

「-m 3」でrevertする

% git revert -m 3 4c03b80
error: Commit 4c03b801057726d4429337a9c76befa7a24c9b6d does not have parent 3
fatal: revert failed

ということでmainlineのparent_numberというのは1が「mergeされたブランチ(今のブランチ)」、2が「mergeしたブランチ(develop)」という感じになっているようです。「-m 2」を使う状況がイマイチ思いつかないので多くの場合は「-m 1」を指定することになるのかなと思います。


といいながらもやっとしている部分もまだ残ってたりしてgitむずい。。
間違いがあれば指摘してもらえると嬉しいです。

YouTubeの動画を簡単に連続再生させてみる(iPhone対応とcuePlaylist)

以前に書いたYouTubeJavaScriptから連続再生させる方法について書いた記事が今でも時々見られているようだし、PetaTube作るときに調べたこともあるので改めて書いてみます。

前回のはこちら
http://d.hatena.ne.jp/koba04/20110227/1298736386

iframeAPIでiPhone対応

埋め込み方法
  • 方法は簡単でサンプルにある通りこんな感じで簡単です。
  <div id="video"></div>が定義してあるとする。(ここがYouTubePlayerに置き換えられる)

  var w = window, player;

  // ここはドキュメントにある通り
  var tag = document.createElement('script');
  tag.src = "//www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  w.onYouTubeIframeAPIReady = function() {
    player = new YT.Player('video', { // 置き換えるHTML要素のid
      height: '450',
      width: '800',
      videoId: 'cfOa1a8hYP8',  // 再生したいvideoのid
      events: {
        // プレイヤーの準備が出来た時に何かしたい場合
        onReady: function() {
        },
        // プレイヤーの状態が変わった時に何かしたい場合
        onStateChange: function(e) {
          // 再生が終わった時に何かしたい場合
          if ( e.date == YT.PlayerState.ENDED ) {
          }
        },
        // エラーが起きた時(埋め込めない動画を指定したときなど)
        onError: function() {
        }
      }
    });
  };

PetaTubeの場合は、すでに削除された動画や埋め込みが許可されてない動画あった場合、onErrorで受け取ってSkipさせています。

cuePlayListで簡単連続再生

  • これのドキュメントを読んでいたところcuePlayListというものがあることを知って、これ使えば簡単に動画のリストを再生出来るんじゃないかと思って試してみました。
  • これだけで検索した結果の動画を連続再生することが出来ます。こちらでindexの管理もしなくていいので簡単ですね。
 <!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>YouTubeを連続再生してみる(iframe api)</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
</head>
<body>
<h1>YouTubeを連続再生してみる(iframe api)</h1>
<input type="text" id="query" size="50" placeholder="検索ワードを入力してね" />
<input type="button" id="search" value="検索" /><br />
<div id="video"></div>
<script>
jQuery(function($) {
  var w = window, player;

  // 最初は隠しておく
  $('#video').hide();

  // https://developers.google.com/youtube/iframe_api_reference
  var tag = document.createElement('script');
  tag.src = "//www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  w.onYouTubeIframeAPIReady = function() {
    player = new YT.Player('video', {
      height: '450',
      width: '800',
     // videoIdはこの段階ではセットしていない
      events: {
        onReady: function() {
          // 最後まで終わったらまた最初から再生されるように
          player.setLoop(true);
        }
      }
    });
  };

  // ここからは動画の検索
  $("#search").click(function() {
    var query = $("#query").attr("value");
    if ( !query ) {
      return;
    }

    $.ajax({
      url: 'http://gdata.youtube.com/feeds/api/videos?',
      dataType: 'jsonp',
      data: {
        'q': query,
        'alt': 'jsonc',
        'v': 2,
        'max-results': 50,
        'format': 5,
        'orderby': "viewCount",
        'start-index': 1
      }
    }).done(function(data) {
      // 再生中の動画があれば止めて消す
      player.stopVideo(); 
      player.clearVideo(); 
      $('#video').fadeIn();
      var videos = [];
      $.each(data.data.items, function() {
        videos.push(this.id);
      });
      // sort by favorite
      videos = videos.sort(function(a, b) {
        return b.favoriteCount - a.favoriteCount;
      });
      // ここでキューに動画のIDを突っ込むだけ
      player.cuePlaylist(videos);
    });
  });
});
</script>
</body>
</html>

これで検索した結果を連続再生することが出来るようになります。
こんな感じ。


画像を見てもらうとわかるのですが、再生/停止ボタンの隣に次の動画への▷のボタンが、さらに再生リストもプレイヤーの中に表示されるようになってユーザーがサムネイルから動画を選べるようになっています。


PetaTubeの場合は、こちらで管理したかったのでcuePlaylistは使わなかったのですが、ただ動画を連続再生させたい場合はとても簡単に出来るので便利です。


また前回のサンプルでは動画の数が残り少なくなってきたら裏でリクエスト投げてさらに動画を追加するということをやっていたのですが、そういう事やる場合は、自分でリストを管理する方法がいいとおもいます。

http://koba04.com/youtube/index.html


https://github.com/koba04/YouTube-Continuous-Player

Webサービスを作るときに考えたこと(PetaTube)

PetaTubeをリリースしてみて感じたことや考えていたことを自分のためにメモしておきます。


http://d.hatena.ne.jp/koba04/20121002/1349103920


長いので先に結論だけ書いてしまうと、多くの人に使ってもらうサービスを作るためにはyusukebeさんによるYAPC::ASIA2012のベストトーク「「新しい」を生み出すためのWebアプリ開発とその周辺」で語られているようなことをしっかりやっておかないとダメだなと思いました。

書籍も楽しみです!


考える

イデア
  • イデアはいつも考えています。
    • 自分は音楽が好きでいい音楽に出会うと人に勧めたくなるので、そういった思考がサービスを考える際にも大きく影響しています。
  • 基本的には「自分が欲しいサービス」という点で考えています。自分の他に数人でも欲しいと思っている人がいるんじゃないかと思った時にサービスに出来ないかを考えます。つまり基本的には自己満足です。もっと多くの人に使ってもらうためにはここでもっとしっかりと考えないとダメなんじゃないかと思っています。
    • 今回のPetaTubeでは、あるNaverまとめの動画が全部見たいと思ったけどこれ再生終わるたびに埋め込まれている動画をクリックして再生させるの面倒だなぁと思い、これIDだけ抽出できればJavaScriptで連続再生させられるんじゃないかと思ったのがきっかけです。
機能
  • 基本的には「最低限の機能」は何か、「あったらいい機能」は何かを分けて考えます。そして基本的には最低限の機能だけの実装を目指します。理由としては仕様が膨らむと途中で投げ出す可能性が高くなるからです。また、出来ることを単純な形で見せたいということがあります。
    • PetaTubeの場合はURLから動画を抽出して連続再生することが最低限の機能だと考えていました。あとブックマークレットも使われるかわかりませんが、あると相当便利なので最低限の機能として考えていました。
運用
  • ここでリリースした後の運用のイメージについても考えています。コンテンツを運営者が追加し続ける必要があるモデルを選択する場合はそれが実際に可能なのかということや、ユーザーが集まらないと成り立たないサービスの場合どうやって最低限の人数を集めて運用が可能なところまで持っていくかということです。
  • 個人的には、放置していても更新性があるようなサービスにしたいなと思っています。
    • LastFMが毎週作ってくれるランキングを活用しているCountDown LastFM Rankingもそうなっています
    • PetaTubeの場合は、ユーザーが動画がいっぱい貼ってあるウェブページを探して来てくれることを想定しているのでここは心配していませんでした。

名前

  • これはとても大事だと思っていて、後々のモチベーションにも関わってくるので作る前の段階で決めておくのがいいと思っています。(途中で変更してもいいとおもいますが)
    • PetaTubeという名前は正直これだ!という感じではないのですが、コンセプトを考えた時に「ペタ」っと簡単にYou「Tube」の動画を楽しめるということでこの名前にしました。YouTubeの動画ということをわかりやすくしたいなぁと思うとどうしても「〜Tube」なサービス名になるんですよね。。。

実装

技術の選択
  • ここは人それぞれだと思いますが、自分は「早く実装出来る」ことか「使いたい技術」であることを基準に考えています。どちらも楽しく開発をするためということが目的で、早く実装出来たほうが早く形に出来て楽しいですし使いたい技術だと実装自体を楽しむことが出来ます。そこまで大規模なアプリは想定していないので仕事の時のような基準では選択しません。ここは個人でサービスを作る醍醐味の一つかなと思っています。
    • 注意点としては、考え過ぎないということでしょうか。無駄にアクセスがいっぱい来る時のこととか色々考えすぎて大きなシステムにしないことは重要だと思います。そこはヒットしてから悩めばいいと思っています。
    • PetaTubeの場合は、早く実装出来るものとして「Amon2::Lite」、使いたい技術ということで「Backbone.js」と「Compass」を使っています。
デザイン(PC)
  • レイアウトだけは最初に考えて、色の調整などは機能の実装後に行いました。ホントはよくないのですが確認はChromeだけで行なっていました。変なことをしなければこれでまぁFirefoxSafariはなんとかなるかなと思い。I.Eは...対象ユーザーの中に少ないかなと思ったので気にしていませんでした。I.E10だとマシなんじゃないかという期待も込めて...
    • PetaTubeのデザインはとあるサイトを参考にさせてもらいました。分かる人には分かると思いますが。。色は自分で色々試して決めました。
    • 細かい点ですが、オススメなどをモーダルで実装したのはビデオの再生を止めないためという意図があったりします。
  • 実装については、Compassを使っていたので楽しく出来ました。
    • ネスト出来るのでプログラマブルに書けたりするのは気持ちいいし、変数にベースになる色を設定できるので色の調整などはかなり簡単に出来ました。
    • CSSをresetした状態からはじめたので最初はちょっと途方に暮れましたが、シンプルなデザインなのでなんとかなりました。(なってない?)
  • favicon.icoはあったほうがいいと指摘をもらったので、それはGIMPでなんとか作ってみました。。
デザイン(スマートフォン)
  • 正直そこまでは気にしなかったです。想定している使い方としてはPCで作業している時のBGM(V)だし3Gだとツラいだろうなということもあって。
    • ただiPadは使われるシーンがあるかなと思ったのでちょっと気にしました。
    • Androidはなかったのでリリースまで確認はしてませんでした。リリース後ちらっと借りて見てみましたが。
    • まぁでもiPhone使っているのですがサービス作るならAndroidも持っておかないとなぁとは思いました。今ならNexus7とか?スマートフォンで使われることを想定するサービスならスマートフォン用のデザインをどうするかは時間を掛けるべきだとは思います。
開発
  • ここでの最大の注意点は無理しないということでしょうか。個人でウェブサービスを作るときはどうしてもムラが出てしまうので、のらないときはやらないほうがいいと思います。逆にのってくるととにかく実装したくてたまらない状態になったりするので、そのときにガッとやったほうが進みも早いしいいものが出来ると思います。無理してヤル気が0になって放置というのが一番避けたいというところです。誰もがそんな放置されたリポジトリを持っているのではないでしょうか。
  • あとはとにかくプロトタイプを早く作ることを心掛けていました。デザインが全くされていない状態で動作を試すことでイメージ通り使いたいサービスになりそうかを考えていました。この段階で動いたのでしばらく自分だけで遊んでましたw。
作業する時間
  • 私事ですが、家族がいて休日は家族のためにほとんど時間を使うのでなかなかまとまった時間が取れません。これに対する自分の答えは寝る時間を削るしかないということです。といっても最低限の睡眠時間は確保すべきですが。これは他の方がどうやっているのか是非教えて欲しいです。
    • PetaTubeも基本的には仕事帰ってきてから寝るまでのちょっとした時間で実装していました。タスクの管理などはしていなくて、今日はここまでやりたいなぁという目安を作ってそこまで実装して寝るという感じでやってました。ハッカソンとかでまとまった時間とれたらよかったんですが。。ただその分考える時間は多かったのはいい部分でもあったなと思いました。
  • Web Application Framework(WAF)
    • 最近のWAFはよくできているので、setupするだけでデザインもそこそこされている状態になります。この段階で満足してちょっといじって放置ということがよくあるので注意。
    • あと、無駄にWAFの機能の拡張を始めたり、どういうアーキテクチャにするかを複雑に考え過ぎるとサービスを作るという目的を見失ったりしがちです。素直にWAFに従うといいんじゃないかなと思います。
  • Twitter Bootstrap
    • これホント便利なんですが、ツールや管理画面などでないなら使う際は注意が必要かなと思います。というのもBootstrapっぽいサイトになってしまいそこをカスタマイズしていくのは結構面倒だなという印象があるからです。まぁBootstrapっぽい感じでいいなら問題無いですが違うデザインにしたい場合は使わないという選択肢も考えていいいのかなと思います。便利なんですけどね。

環境の準備

  • よっぽど自信のあるサービスならサービス用のドメインを取得することも考えたのですが、今回はサブドメインで設定しました。
  • ミドルウェアの設定については、考えだすとそれだけでかなり時間を取られるので、最低限しか設定しません。ここまで来ると早くリリースしたくなるのと、これもヒットしてから考えればいいと思っているからです。
    • ちなみに環境構築はYAPCの間にやってましたw

リリース

  • Twitterとかブログ使って公開しましたと書いただけなのでもうちょっと色々出来たかなと思います。
  • リリース後はTwitterはてブなどで反応を見て改善できる点はなるべくするように心掛けています。便利とか欲しかったみたいなことを言ってもらえると本当リリースしてよかったなと思いますし、もっとよくしていこうと思いました。
    • とりあえず動画が表示されていない場合のトップページによく見られているサイトを表示しようかなとは思っています。
  • あと、可能ならソースは公開するといいんじゃないかなと思います。見られるという意識があるかないかでコードの質が変わる部分もあると思いますので。

ウェブサービスを作るのは楽しい

  • とまぁ色々書きましたが、ウェブサービスを作るのは楽しいです。
  • 自分は面白いものを作りたくてウェブの勉強を始めたので、簡単に自分の作ったものをみんなに見てもらえてTwitterなどでリアクションをもらえる今の環境はとても素晴らしいなと思っています。
  • とりあえず最低限のところまで作って後々機能追加していく方法は、モチベーションを高めるという意味でも効果的だなと思います。
  • リリースすると色々意見をもらえるのでとても勉強になります。Petatubeでも途中からtitleに再生中のビデオのタイトルを表示するようにした方が便利だと教えてもらい実装しました。これをすることでタブを選択して開かなくても再生中のビデオが何か確認することが出来るようになり便利になりました。この発想は自分にはなかったものなのでとても勉強になりました。

おまけ

  • 自分がウェブの世界面白いなと思ったきっかけはPerlのコミュニティに出会ったのがきっかけなので、何かPerlに恩返し出来ないかなと考えています。
  • その時に自分が出来るのは便利なモジュール作ったりなどというよりは、Perlを使って面白いものを作りアピールしていくことかなと思っていたりします。なのでAmon2::Liteで作っているというのをfooterに入れていたりブログでPerlで作っていると書いたりしています。
  • それでPerlで何か作ってみようと思ったり*.pmに参加してみようと思う人が1人でも増えればいいなと思っています。

というわけで自分用のメモですが、最後まで読んでくださりありがとうございました。
まぁ個人でウェブサービスを作るのは、好きに出来るしリアクションももらえて楽しいという話でした。