<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Web　酒　肴</title>
    <link>http://blog.garden-place.jp/oborobeer/</link>
    <description>Flex, ActionScript, CMS, Ruby on Rails, Java, NetBeansなどの技術情報その他</description>
    <language>ja</language>
    <generator>Nucleus CMS v3.31SP1</generator>
    <copyright>&#169;</copyright>
    <category>Weblog</category>
    <docs>http://backend.userland.com/rss</docs>
    <image>
      <url>http://blog.garden-place.jp/nucleus/nucleus2.gif</url>
      <title>Web　酒　肴</title>
      <link>http://blog.garden-place.jp/oborobeer/</link>
    </image>
    <item>
 <title>サーバ移転</title>
 <link>http://blog.garden-place.jp/oborobeer/item_301.html</link>
<description><![CDATA[<p>このブログは会社のサーバを使っているので、個人サーバに移転します。
新しいサーバではWordpressにしました。</p>

<p><a href="http://blog.obanet.jp/">http://blog.obanet.jp/</a></p>

<p>過去の記事も移行しましたが、ソースコードの表示など、いくつか崩れている部分があるので、
サーバがある限りはこちらの記事も残しておきます。</p>
]]></description>
 <category>その他</category>
<comments>http://blog.garden-place.jp/oborobeer/item_301.html</comments>
 <pubDate>Mon, 9 Jan 2012 18:58:49 +0900</pubDate>
</item><item>
 <title>[Android]ドラッグ、ピンチイン/アウトできるMatrixImageView ver0.1</title>
 <link>http://blog.garden-place.jp/oborobeer/matrix_image_view.html</link>
<description><![CDATA[<p>Androidでちょっとやりたいことがあって、拡大した画像を自由にスクロール表示させる必要があった。
で、そういうViewがあるのだと思って探していたら、意外にも見つからない。</p>

<p>よくピンチイン/アウトしたりドラッグしたりする画像ビューアあるけど、あれみんな自力で実装してるということ？
そんなバカな、と思ったけど探しても見つからないし、とりあえず必要最低限のものはすぐできそうだったので作ってみた。</p>

<p><a href="http://typea.info/blg/glob/2010/08/androidx06ht-desire-3.html">こちら</a>のプログラムをかなり参考に、ベースにさせていただきました。
利用イメージはこんな感じ。</p>

<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Lk9kLlWHjvA?hl=ja&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Lk9kLlWHjvA?hl=ja&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>

<p>使い方は以下のようになります。
最後に記載しているMatrixImageView.javaのソースコードを貼っつけて、xmlファイル内でImageViewと同じように使用します。（もちろんソースコード内で直接MatrixImageViewを扱ってもOK）</p>

<pre><code>    &lt;jp.obanet.android.MatrixImageView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/img_view"
            android:src="@drawable/sample"

            interval="20"
            inertial="true"
            speedDecRatio="0.85"
            angleSpeedDecRatio="0.85" /&gt;
</code></pre>

<p>上4行はImageViewに指定するものと全く同じ。画像ファイルの指定や表示方法など。
下4行がMatrixImageView独自のパラメータです。省略したらデフォルト値が使用されます。</p>

<table>
<thead>
<tr>
  <th>パラメータ名</th>
  <th>意味</th>
  <th>タイプ</th>
  <th>デフォルト値</th>
</tr>
</thead>
<tbody>
<tr>
  <td>inertial</td>
  <td>（指を離した後）慣性動作させるかどうか</td>
  <td>boolean</td>
  <td>true</td>
</tr>
<tr>
  <td>interval</td>
  <td>慣性のアニメーションの更新間隔（ミリ秒）。小さい値ほど綺麗に動いて見えます。もちろんその分処理コストはかかります。</td>
  <td>int</td>
  <td>20</td>
</tr>
<tr>
  <td>speedDecRatio</td>
  <td>ドラッグ移動の慣性の減衰率。つまり摩擦。1に近いほどツルツルすべる。氷に近いイメージ。</td>
  <td>float</td>
  <td>0.85</td>
</tr>
<tr>
  <td>angleSpeedDecRatio</td>
  <td>回転の慣性の減衰率。同じく1に近いほどツルツル回る。</td>
  <td>float</td>
  <td>0.85</td>
</tr>
</tbody>
</table>

<p>今後の改良点としては以下を一応考えてますが、僕の目的は現状でも十分達せられるため、実装するかどうかはわかりません。</p>

<ul>
<li>画像が外に飛び出していかないようにする機能</li>
<li>内部の処理効率化、リファクタリング</li>
<li>その他Androidアプリ一般に必要なことの考慮（今回が初めてのAndroid開発なので色々足りないことがあると思ってる）</li>
</ul>

<p>ちなみにMatrixImageViewにはインナークラスLineがあり、これは以前ActionScript用に作成したもの(<a href="http://blog.garden-place.jp/oborobeer/actionscript/item_261.html">[ActionScript]２直線の交点を求める</a>)を移植、取り入れました。
直線同士の交点を出すためのものだったのですが、今回の必要に応じて2直線の角度を算出する機能をつけました。ここで配布するのに便利なようにインナークラスとして使っています。</p>

<p>ソースコードは続きに記載します。
利用、改変に関しては、僕が勝手に作った「猿ロッキングライセンス」を適用します。
一番最後の猿ロッキングライセンスに関する注意事項をよく読んでください。</p>
<p><b>MatrixImageView.java</b></p>

<pre><code>package jp.obanet.android;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MatrixImageView extends ImageView implements OnTouchListener{

    //繰り返し処理関連
    private int interval = 20;
    private Handler handler = new Handler();
    private Runnable runnable;

    // 移動、回転、ズーム用の変換行列
    private Matrix matrix      = new Matrix();

    //ズーム関連
    private float oldDist      = 0f;
    private PointF mid         = new PointF();
    private float curRatio     = 1f;

    //慣性移動に関するもの
    private boolean inertial = true;
    private float speedDecRatio = 0.8f;
    private float angleSpeedDecRatio = 0.8f;
    private PointF previous =new PointF();
    private PointF speed = new PointF();
    private float angleSpeed = 0;

    //回転に関するもの
    private Line previousLine;

    //モード判別（NONE: 未操作状態, ONE_POINT: ドラッグ中, TWO_POINT: 拡大縮小、回転中）
    enum Mode{
        NONE,
        ONE_POINT,
        TWO_POINT
    }
    private Mode mode = Mode.NONE;

    public MatrixImageView(Context context) {
        this(context, null);
    }

    public MatrixImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MatrixImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView(context, attrs, defStyle);
    }

    private void initView(Context context, AttributeSet attrs, int defStyle){
        //ScaleTypeは必ずMATRIXを設定
        setScaleType(ScaleType.MATRIX);

        if( attrs != null){
            interval = attrs.getAttributeIntValue(null, "interval", 20);
            speedDecRatio = attrs.getAttributeFloatValue(null, "speedDecRatio", 0.8f);
            angleSpeedDecRatio = attrs.getAttributeFloatValue(null, "angleSpeedDecRatio", 0.8f);
            inertial = attrs.getAttributeBooleanValue(null, "inertial", true);
        }

        setOnTouchListener(this);
        if(inertial){
            runnable = new Runnable() {
                @Override
                public void run() {
                 redraw();
                    handler.postDelayed(this, interval);
                }
            };
            handler.postDelayed(runnable, interval);
        }
    }

    /**
     * 慣性効果の処理
     */
    private void redraw(){
        if(mode == Mode.NONE){
            //移動、回転の慣性反映
            previous.set(previous.x + speed.x, previous.y + speed.y);
            matrix.postTranslate(speed.x, speed.y);
            matrix.postRotate(angleSpeed, previous.x, previous.y);

            //以下、次回の慣性のための移動スピード、回転スピード軽減処理

            //移動による慣性
            speed.set(speed.x * speedDecRatio, speed.y * speedDecRatio);
            //慣性の移動量が十分に小さくなったときは停止
            if(-1 &lt; speed.x &amp;&amp; speed.x &lt; 1){
                speed.x = 0;
            }
            if(-1 &lt; speed.y &amp;&amp; speed.y &lt; 1){
                speed.y = 0;
            }

            //回転による慣性
            angleSpeed = angleSpeed * angleSpeedDecRatio;
            //慣性による回転量が十分に小さくなったときは停止
            if(-1 &lt; angleSpeed &amp;&amp; angleSpeed &lt; 1){
                angleSpeed = 0;
            }

            setImageMatrix(matrix);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView view = (ImageView)v;

        switch(event.getAction() &amp; MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            //現在の慣性をリセット
            speed.set(0, 0);
            angleSpeed = 0;

            //移動（ズームは無し）開始
            previous.set(event.getX(), event.getY());
            mode = Mode.ONE_POINT;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            //移動・回転・ズーム開始
            previous.set(event.getX(), event.getY());
            oldDist = spacing(event);

            // Android のポジション誤検知を無視
            if (oldDist &gt; 10f) {
                midPoint(previous, event);
                mode = Mode.TWO_POINT;

                previousLine = new Line(
                 new PointF(event.getX(0), event.getY(0)),
                 new PointF(event.getX(1), event.getY(1))
               );
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = Mode.NONE;
            break;
        case MotionEvent.ACTION_MOVE:
            PointF current = null;

            if (mode == Mode.ONE_POINT) {
                current = new PointF(event.getX(), event.getY());
            }else if (mode == Mode.TWO_POINT) {
                current = new PointF();
                midPoint(current, event);
            }else{
                return false;
            }

            //移動処理
            float distanceX = current.x - previous.x;
            float distanceY = current.y - previous.y;
            matrix.postTranslate(distanceX, distanceY);

            if (mode == Mode.TWO_POINT) {
                //ズーム処理
                float newDist = spacing(event);
                midPoint(mid, event);
                float scale = newDist / oldDist;
                float tempRatio = curRatio * scale;
                oldDist = newDist;

                //倍率が上限値下限値の範囲外なら補正する
                curRatio = Math.min(Math.max(0.1f, curRatio), 20f);

                if (0.1f &lt; tempRatio &amp;&amp; tempRatio &lt; 20f) {
                    curRatio = tempRatio;
                    matrix.postScale(scale, scale, mid.x, mid.y);
                }

                //回転処理
                Line line = new Line(
                        new PointF(event.getX(0), event.getY(0)),
                        new PointF(event.getX(1), event.getY(1))
                );

                float angle = (float) (previousLine.getAngle(line) * 180 / Math.PI);
                matrix.postRotate(angle, current.x, current.y);

                //次回の準備
                angleSpeed = angle;
                previousLine = line;
            }


            //次回の準備
            speed = new PointF(current.x - previous.x, current.y - previous.y);
            previous.set(current.x, current.y);
        }

        // 変換の実行
        view.setImageMatrix(matrix);

        return true; // イベントがハンドリングされたことを示す
    }

    /**
     * 2点間の距離を計算
     */
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    /**
     * 2点間の中間点を計算
     */
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    static class Line{

        enum LineType{
            /** 第1引数の点と第2引数の点を通る直線（終端はない） */
            STRAIGHT,
            /** 第1引数の点から第2引数のほうに伸びる半直線 */
            HALF,
            /** 第1引数の点と第2引数の点の間の線分 */
            SEGMENT
        }

        public PointF p1;
        public PointF p2;
        public LineType type;

        /**
         * @param p1
         * @param p2
         */
        public Line(PointF p1, PointF p2){
            this(p1, p2, null);
        }

        /**
         * @param p1
         * @param p2
         * @param type
         */
        public Line(PointF p1, PointF p2, LineType type){
            this.p1 = p1;
            this.p2 = p2;
            this.type = (type == null) ? LineType.STRAIGHT : type;
        }

        /**
         * 2つのLineインスタンスの交点を表わすPointインスタンスを取得する
         * 交点がない場合はnullを返す
         * @param line
         * @return
         *
         */
        public PointF getIntersectionPoint(Line line){
            PointF vector1 = this.getVector();
            PointF vector2 = line.getVector();

            if(cross(vector1, vector2) == 0.0){
                //2直線が並行の場合はnullを返す
                return null;
            }

            // 交点を this.p1 + s * vector1 としたとき
            float s = cross(vector2, subtract(line.p1, this.p1)) / cross(vector2, vector1);
            // 交点を line.p1 + t * vector2 としたとき
            float t = cross(vector1, subtract(this.p1, line.p1)) / cross(vector1, vector2);

            if(this.validateIntersect(s) &amp;&amp; line.validateIntersect(t)){
                vector1.x *= s;
                vector1.y *= s;
                this.p1.set(p1.x + vector1.x, p1.y + vector1.y);
                return p1;
            }else{
                return null;
            }
        }

        /**
         * 2つのLineインスタンスが作る角度のラジアン値を返す
         * @param line
         * @return
         */
        public float getAngle(Line line){
            PointF vector1 = this.getVector();
            PointF vector2 = line.getVector();

            return (float)Math.atan2(vector1.x * vector2.y - vector1.y * vector2.x, vector1.x * vector2.x + vector1.y * vector2.y);
        }

        public PointF getVector(){
            return new PointF(p2.x - p1.x, p2.y - p1.y);
        }

        public PointF subtract(PointF p1, PointF p2){
            return new PointF(p1.x - p2.x, p1.y - p2.y);
        }

        /**
         * 交点までのベクトルを p1 + n * (p2 - p1) であらわしたとき、
         * nが適切な値の範囲内かどうかを判定する。
         *
         * 直線の場合：nはどの値でもよい
         * 半直線の場合：nは0以上である必要がある
         * 線分の場合：nは0以上1以下である必要がある
         * @param n
         * @return
         *
         */
        private boolean validateIntersect(float n){
            if(LineType.HALF.equals(this.type)){
                return (0 &lt;= n);
            }else if(LineType.SEGMENT.equals(this.type)){
                return ((0 &lt;= n) &amp;&amp; (n &lt;= 1));
            }else{
                return true;
            }
        }

        /**
         * 2つの2次元ベクトルの外積を返す
         * @param vector1 2次ベクトルを表わすPointインスタンス
         * @param vector2 2次ベクトルを表わすPointインスタンス
         * @return
         *
         */
        private float cross(PointF vector1, PointF vector2){
            return (vector1.x * vector2.y - vector1.y * vector2.x);
        }

        public String toString(){
            String str = "";
            if(LineType.STRAIGHT.equals(type)){
                str += "---&gt; ";
            }
            str += "(" + p1.x + ", " + p1.y + ") ---&gt; (" + p2.x + ", " + p2.y + ")";
            if(LineType.STRAIGHT.equals(type) || LineType.HALF.equals(type)){
                str += " ---&gt;";
            }

            return str;
        }
    }
}
</code></pre>

<p><b>猿ロッキングライセンスとは</b></p>

<p>以下の動画を再生、閲覧し猿ロッキングキャンペーンへの貢献をしてくれたらプログラムの利用、改変すべて自由となるライセンスです。
（2011年6月4日（土）以降は再生せずとも自由に利用できます）</p>

<p>１００万円ほしいっ！！<br />
（猿ロッキングについては<a href="http://www.stride-s.com/index.html">こちら</a> ）</p>

<p><object style="height: 390px; width: 640px"><param name="movie" value="http://www.youtube.com/v/itAD0sARR6g?version=3"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://www.youtube.com/v/itAD0sARR6g?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"></object></p>
]]></description>
 <category>android</category>
<comments>http://blog.garden-place.jp/oborobeer/matrix_image_view.html</comments>
 <pubDate>Sun, 8 May 2011 12:24:45 +0900</pubDate>
</item><item>
 <title>「おや！」ってなんやねん→ツイッター</title>
 <link>http://blog.garden-place.jp/oborobeer/item_292.html</link>
<description><![CDATA[<p>ツイッターで画面操作しているとたまにでるこのポップアップ。
今日はマキシマムザホルモンのアカウントをフォローした時に出た。</p>

<p><a href="http://blog.garden-place.jp/media/2/20100504-oya2.jpg">おや！</a></p>

<hr />

<p><b>> おや！ページを更新して、もう一度試してください。</b></p>

<p>「おや！」って・・・</p>
]]></description>
 <category>その他</category>
<comments>http://blog.garden-place.jp/oborobeer/item_292.html</comments>
 <pubDate>Tue, 4 May 2010 23:44:15 +0900</pubDate>
</item><item>
 <title>復帰</title>
 <link>http://blog.garden-place.jp/oborobeer/item_290.html</link>
<description><![CDATA[<p>なが～くブログを書いてなかった。
年度末が忙しすぎて家でPCを起動することが全くなくなってしまったから。いかんなぁと思います。適度なゆとりが発想を豊かにし、人生を楽しくするのだと実感しました。</p>

<p>少しゆとりができたので、これからいろんなことに精力的に取り組みます。
まずは・・・</p>

<ul>
<li>放送局の開始</li>
<li>バンド活動</li>
</ul>

<p>このブログと何の関係が？というツッコミはなしで。</p>
]]></description>
 <category>その他</category>
<comments>http://blog.garden-place.jp/oborobeer/item_290.html</comments>
 <pubDate>Sat, 10 Apr 2010 10:44:22 +0900</pubDate>
</item><item>
 <title>Flex/AIRハンズオン勉強会 in 京都　報告</title>
 <link>http://blog.garden-place.jp/oborobeer/item_288.html</link>
<description><![CDATA[<p>２１日（土）に開催した勉強会の後、急に忙しくなって報告やフィードバックなど遅くなっております。
来てくれた皆さん、どうもありがとうございました。
簡単に報告をしつつ、次への改善点を整理しておきます。</p>

<h3>参加者</h3>

<p>約２０人でした。正確な数は受付表を確認すればわかります。（今会社にある）<br />
そして一番の収穫は、ほぼ全員がPC持参したこと。
もともと自分の手を動かすハンズオン形式を取っていたので、PC持参できる人が集まったと言えばそうですが、この形式は今後も続けられそうだと感じました。<br />
また、ざっと見渡したところ未経験者の方がかなり多く見受けられました。詳細はアンケート集計しなければわかりませんが、参加者の構成に合わせた企画を実施していくつもりです。</p>

<h3>通信、インフラ</h3>

<p>コンセントの数、ギリギリでした。もう１つ２つタップを用意する必要があったと反省。<br />
さらに、この日のために<a href="http://www.uqwimax.jp/service/trywimax/" title="UQ WiMAX | Try WiMAX">WiMAXの試用版</a>を用意して社内LANを経由しないインターネットアクセスを提供したのですが、通信できない人が続出。事前準備の至らなさ、WiMAXルータの性能の限界など、色々と要因はありそうに思います。これも反省点。</p>

<h3>Flex最初の一歩</h3>

<p>Flexの未経験者向けハンズオンセミナー。<br />
とりあえず時間が足りなかった。初めての講師という大役を任されたT-2の経験不足もあるけど、そもそも30分で意味のある内容を詰め込むことに無理があったか。結果としてはT-2が時間延長してでも丁寧に教えてくれたので、未経験者の人にとっては価値あるものになったんじゃないかと思う。結果はアンケート集計してのお楽しみ。</p>

<h3>Flex/AIRのお仕事事情</h3>

<p>hirossyさん、lecheさんに登壇いただく。<br />
まずは、登壇といっても前で話すスペースが無かった、移動やモニターの切り替えが頻繁に起こって不便、という準備・企画不足は反省点。
内容はFlex/AIRにある程度取り組んでいる人、もしくは他の技術でバリバリやっている人にとってはかなり興味深い話が聞けたと思います。
お二人ともありがとうございました。</p>

<p>課題としては完全な未経験者の人やFlashでデザインはやったけどFlexも触ってみよう、という人にとっては、まだよくわからない話だったかもしれません。
この辺は他の企画にも共通する問題で、ターゲットを明確にすればするほど、それに合わない人をどうするかということを考えていこうと思います。</p>

<h3>ライブコーディング</h3>

<p>先述の２コーナーで登壇した３名（hirossyさん、lecheさん、T-2）が、その場で明かされた仕様のFlex/AIRアプリケーションを即興で作る、という作らされるほうにしたら鬼のような企画。しかもhirossyさんはコーディング経過をプロジェクターで公開。まさにライブコーディング。いきなりお願いして、よく引き受けてくれたと思います。</p>

<p>結果は見事にhirossyさんが完成させたという、企画者としては胸を撫で下ろす展開！面白かったのはhirossyさんの情報検索術がそのまま見れたこと。ネット上の色んな情報ソースが頭の中で整理されていれば、一つ一つの技術の詳細な中身までは憶えておく必要がないということを見事に体現してくれました。hirossyさんは懇親会に来れなかったのですが、来てたらヒーロー扱い間違いないというほど、この時の話題がよく出ました。</p>

<h3>最後に</h3>

<p>上記に色々と出てきた反省点・改善点は次回、次々回と回を重ねながら修正していきたいと思います。
言い忘れてましたけど、今後は毎月開催していくつもりです。１２月は皆忙しいと聞いていたのですが、少人数型の企画に変更してでも開催します。よろしければぜひ＾＾</p>
]]></description>
 <category>Flash/Flex</category>
<comments>http://blog.garden-place.jp/oborobeer/item_288.html</comments>
 <pubDate>Sun, 29 Nov 2009 11:50:04 +0900</pubDate>
</item><item>
 <title>Flex/AIRハンズオン勉強会 in 京都　のお知らせ</title>
 <link>http://blog.garden-place.jp/oborobeer/item_286.html</link>
<description><![CDATA[<p>勉強会について、ここでいろいろと思案の過程を書いてきたけども、まずは実施することになりました。
こういうのって考えすぎてその思考に縛られると動けなくなるから、考えた事はそれとして多少の矛盾を抱えても動いちゃったほうがいいと思うわけです。</p>

<p>つーわけで、京都でこれからFlex/AIRを覚えたいって方はぜひ参加してください。
うちの会社で行います。</p>

<p><a href="http://www.fxug.net/modules/bwiki/index.php?Flex%CA%D9%B6%AF%B2%F1%C2%E892%B2%F3%40%B5%FE%C5%D4" title="B-Wiki - Flex勉強会第92回@京都 - Flex User Group">Flex勉強会第92回@京都 - Flex User Group</a></p>

<p>前半は比較的初級者向けだけど、ライブコーディングはバリバリとこなしてる人にも参加してもらいたいですね。
集まった人のレベルに合わせてできるように、いくつかの準備はしておこうと思ってますけど。</p>

<p>もちろん興味のあるところだけ参加してもらって結構ですよ。</p>
]]></description>
 <category>Flash/Flex</category>
<comments>http://blog.garden-place.jp/oborobeer/item_286.html</comments>
 <pubDate>Sat, 7 Nov 2009 13:54:18 +0900</pubDate>
</item><item>
 <title>京都の地より、ＩＴ勉強会を再考してみる #4</title>
 <link>http://blog.garden-place.jp/oborobeer/item_283.html</link>
<description><![CDATA[<p>今度は中級者に対して何ができるか考える。
これがけっこう難しい。中級者ともなれば、求めるものは人により様々で多様性が生まれているだろうからだ。</p>

<p>また、中級者に上級者が教える、という形式は現実的に困難かと思う。
毎回、上級者が来てくれるかわからないし、そもそも上級者にとってメリットが少ない。
つまり以前にも書いた、「教える側（上級者）が成長しない」というジレンマに陥るだろう。</p>

<p>色々難しそうだが、とりあえず考えてみた。</p>

<h3><b>「コーディング比較・検討」形式</b></h3>

<p>最近うちの社内で<a href="http://d.hatena.ne.jp/guccyon/20091008" title="2009-10-08 - guccyonikki">guccyonが企画</a>して上々の滑り出しをしたので、それを使わせてもらおうかと思う。
あるプログラミング課題を全員で作成し、それぞれの実装方法などを発表しよりよい方法を学ぶ、というものだ。
guccyonの企画では色々なプログラミング言語で実装することを前提としているが、それをあえてFlex/AIR, ActionScriptに限定した課題にすることで、特有の言語やフレームワークに依存した突っ込んだ議論も盛り上がりそうに思う。</p>

<p>何より僕のように業務でFlex/AIRに携わっていない、そういう機会に恵まれない人は、現場の経験者がどのようにアプリケーションを作るのか知りたい。なぜかというとFlex/AIRを勉強するには書籍やＷＥＢのサンプルに頼るケースが多い状態なのだが、そのようなものは本来必要なエラーハンドリングやMVCの分離などは紙面の都合上省略している。だから自分が見よう見まねで作ったものが経験豊富な人の作り方とどう違うのかぜひ知りたいと思う。</p>

<h3><b>「オンエアバトル」 形式</b></h3>

<p>職場のダル（ダルビッシュの皮を十分に伸ばして被ったヲタク）のアイデア。普通の講演形式ではあるが、事前に発表内容を公開し投票を受け付ける。そして一定数以上の希望者がいた講演のみ発表してもらうというもの。これマジ立候補したくないんですけどｗ落選するの怖すぎるしｗ</p>

<p>でも皆が落選に馴れてきたら盛り上がりそう。落ちて当たり前、受かればラッキーくらいのスタンスでできれば楽しいかな。
聴衆も自分たちが必要とする講演をたくさん聞けてハッピー。</p>

<h3><b>「オンエアバトル（改）」 形式</b></h3>

<p>これも上のと似てるけど、少し違う。たとえばFlexハック集のような細かいテクニックをたくさん紹介する。紹介ってのは「こんなことができますよ～」という触りだけで、どうやるかまでは喋らない。そして、希望者が多かったいくつかのハックのみ、手法も含めて解説する、と。</p>

<p>上のアイデアと合わせて、基本理念は聴衆が求めていないものは解説しなくてよろしい、という非常に冷血感あふれる企画なのでした。怖い怖いｗ</p>

<hr />

<p>う～ん、中級者向けは難しいなぁ。とりあえず一回実施したときにアンケートや聞き込み調査で、みんなが何を求めているのか探るしかない。
あれこれ頭の中で考えるのは一回おいといて、次は実施に向けて実際に行動を起こしていきます。</p>

<p>１１月２１日（土）を予定。京都にいるFlex/AIRに興味のある人はまず一度覗きに来てください。貴方と僕のための勉強会を目指します。</p>
]]></description>
 <category>勉強会</category>
<comments>http://blog.garden-place.jp/oborobeer/item_283.html</comments>
 <pubDate>Thu, 29 Oct 2009 23:28:48 +0900</pubDate>
</item><item>
 <title>京都の地より、ＩＴ勉強会を再考してみる #3</title>
 <link>http://blog.garden-place.jp/oborobeer/item_279.html</link>
<description><![CDATA[<p>前回あげた懸念点をうまく回避すべく、色々な勉強会の形式を模索してみる。</p>

<h3><b>「ハンズオン + 講演」形式</b></h3>

<p>やはりどうしてもハンズオンはやりたい。しかし、前回も書いたように環境の問題がまず大きい。全員がノートPC持ってくるわけじゃないので、みんなのPC準備できんのかってこと。ノートPCを持ってくる人だけを対象に開催するのも一つだろうと思う。だけど、もう一つ考えてみたのがこの形式だ。</p>

<p>どういうことか端的に言うと。</p>

<p><b>PC持参のグループ</b>：　与えられた課題作成に一人で取り組む。<br />
<b>PCを持ってないグループ</b>：　グループ内で代わる代わる一台のPCを操作して課題作成。その模様はプロジェクタで共有。</p>

<p>PCを持参していない人はライトユーザ、つまりより初級者の割合が高いのだろうという予測に基づいている。
なのでPCを持っていない人には講師のPCを操作させてあげて、講師の指導のもとに課題作成を進める。他の人、PC持参している人もその内容を見ながら参考にできる。</p>

<p>PCを持っていない人数に応じて、共有するPCは複数台準備したほうがいいかもしれない。その場合は一台の共有PCごとに一人のサポーターが付いて指導する形。課題をうまく準備できればひょっとしたらきれいに回るかもしれない。もちろん、最適な課題ができた場合は以後使いまわして利用する。そうすると、講師さえ準備できればいつでも特定テーマについてのハンズオン学習ができるカリキュラムが徐々に完成していく。そのデータベースは公開して自由に利用してもらう。</p>

<h3><b>「読書会 + 講演」形式</b></h3>

<p>これも発想は上と同じ。つまり全員をひとまとめにできない事情があるのなら２つに分けてしまえ、というもの。
ズバリ書籍を<b>読む人</b>と<b>読まない人</b>だ。
手順は以下。</p>

<ol>
<li>参加者のニーズに応じて、今読むのに一番ふさわしい書籍を一つ選択する</li>
<li>その書籍を読んで成長したい、読書会に継続して参加したいと思う人を数人募る</li>
<li>次の勉強会までにどこまで読んでくるか決める</li>
<li>家で読む</li>
<li>次回の勉強会で、自分が詰まったところ、理解できたところ、簡単なまとめなど分担して発表する</li>
<li>理解できなかったところのQ&amp;Aコーナーもあり</li>
<li>次の勉強会までにどこまで読んでくるか決める（読む人はずっと同じ）</li>
<li>以下読み終わるまでループ</li>
</ol>

<p>Flex勉強会@大阪の活動にヒントを得て、それをもうひとひねりしたいのだが、このままではほとんど変化がない。
違いがあるとすれば全員で書籍を読むのでなく、誰が読むかを固定的に決めているところくらいだ。</p>

<p>なぜ固定化したかというと、読む書籍を５冊程度に増やして<b>「電波少年的　人は半年でFlexの達人になれるか？」</b>みたいな実験まで広げたいと思っている。むしろ自分が実験台になりたい。これなら書籍を読まずに聞いている人も楽しめるだろうか。</p>

<p>そして、本当に１人でもこれでFlexの達人が生まれれば、次回からは希望者殺到だったりして。３０過ぎても夢見がちな自分。</p>

<p>このアイデアはもう少しブラッシュアップが必要・・・と。</p>

<h3><b>「質問会」 形式</b></h3>

<p>今抱えている開発上の課題やQ&amp;Aなどを、経験豊富な先輩たちに自由に質問できる場を作る。
教える人のレベルに応じて初級者向けのサポーター、中・上級者向けのサポーターに分かれて各自のレベルに応じた課題に取り組むことで教える人も成長する。</p>

<p>質問者は質問するために必要な材料、開発環境やエラー画面などを持って来てもいいが、「こんな感じの処理はどうすれば実現可能か？」というようなアバウトな質問でもOK。
それが初級者向けの質問か、中・上級者向けの質問かの切り分けをした上で必要なサポーターに割り振る。サポーターが解決できなければより上位のサポーターに質問する。
また、その場で解決しそうにない課題であれば次回以降の勉強会の場で、それに取り組むハンズオンなどを企画する。</p>

<p>これを実施するには恐らく当日に質問を募集するよりも、勉強会実施前からメールなどで質問を集めたほうがいいだろう。そうすれば準備もできるし、参加者のニーズもより詳しく把握できる。</p>

<hr />

<p>初級者向けのアイデアは今のところこんなもん。もう２、３個アイデアが欲しいところだなぁ。引き続き中級者向けのアイデアを考えてみる。</p>
]]></description>
 <category>勉強会</category>
<comments>http://blog.garden-place.jp/oborobeer/item_279.html</comments>
 <pubDate>Thu, 22 Oct 2009 12:49:33 +0900</pubDate>
</item><item>
 <title>京都の地より、ＩＴ勉強会を再考してみる #2</title>
 <link>http://blog.garden-place.jp/oborobeer/item_277.html</link>
<description><![CDATA[<p>前回、自分らしい勉強会の目標設定をしたところ、コメントやメールなど意外に反響があったので驚いている。
今回は前回決めた目標である<b>成長と教育の有機的サイクル</b>を実現するために、どのような方針が必要かもう少しブレークダウンした具体策を考えていきたい。</p>

<p>最初に、僕が一番難しい問題と認識していることを書いておかなければいけない。
それは</p>

<p><b>月に１度、数時間の勉強をした程度で人は成長しない</b></p>

<p>ということ。だって年間４０時間程度でしょ？５年頑張ったとしても２００時間。大体１ヶ月の勤務時間に等しいけど、１ヶ月の勤務時間で得られるものってそんなに多くない。僕たち開発者は技術を身に付けた<b>後に</b>何を作るかが大切なわけで、必要な技術を身につけるだけで５年や１０年かかってたら意味がないと感じてしまう。技術は常に進化するということもあるし。</p>

<p>では勉強会そのものが無駄かというとそうではない。勉強会に出席するために事前準備として勉強しておくとか、勉強会に出席したことで自分の実力の無さを痛感し家で勉強に励むとか、そういう行動を促す契機としての機能を備えればいいと思っている。</p>

<p>そして、勉強会の事前に準備として勉強するのと、事後に触発されて勉強するのでは前者が好ましいと考える。期限付きで自分を追い込めるからだ。後者の頑張ろうという気持は大抵長続きしない。</p>

<p><b>まとめ</b></p>

<p>勉強会に向けて多くの参加者が何らかの準備をしていて、当日にその結果を確認し、また次の勉強会のためのレールが準備される、というようなサイクルを生み出せれば理想だ。</p>

<p>これらの前提を元に色々と考えてみよう。</p>

<hr />

<p>まず、今一般的に開催されている勉強会とは、どのようなものがあるかを分析したい。
こちらを参考にした。</p>

<p><a href="http://jibun.atmarkit.co.jp/lcom01/cs/200908/02/01.html" title="読書会からBoFまで。IT勉強会を5つに分類 － ＠IT自分戦略研究所">読書会からBoFまで。IT勉強会を5つに分類 － ＠IT自分戦略研究所</a></p>

<p>これに自分なりに内容や対象者のレベルなどを追加してみた。</p>

<p><b>勉強会の分類</b></p>

<table>
<thead>
<tr>
  <th>分類</th>
  <th>内容</th>
  <th>講師</th>
  <th>対象者のレベル</th>
</tr>
</thead>
<tbody>
<tr>
  <td>講師講演（LT)</td>
  <td>講師と聴衆に分かれて発表や説明をする（ＬＴは５分程度）</td>
  <td>要</td>
  <td>初級者～上級者</td>
</tr>
<tr>
  <td>ハンズオン</td>
  <td>参加者が実際に手を動かして実践する</td>
  <td>要</td>
  <td>初級者～中級者</td>
</tr>
<tr>
  <td>ハッカソン</td>
  <td>参加者が実際に手を動かして実践する</td>
  <td>不要</td>
  <td>中級者～上級者</td>
</tr>
<tr>
  <td>読書会（コードリーディング）</td>
  <td>全員で同じ書籍を読みながら討論、もしくは誰かが読んだ結果を報告する。コードリーディングはソースコードを読む</td>
  <td>不要</td>
  <td>中級者～上級者</td>
</tr>
<tr>
  <td>BoF、パネルディスカッション</td>
  <td>複数の登壇者が意見交換や発表を行う</td>
  <td>要</td>
  <td>初級者～上級者</td>
</tr>
</tbody>
</table>

<p>ハンズオンとハッカソンは違いがよくわからなかったので、指導者としての講師がいるかいないかという違いで解釈した。ハッカソンは講師もいないのでより上級者向けとなる。</p>

<p>今回の勉強会企画の中で一番大事だと考えていることは、初級者に向けて何ができるか。
まずはそこをメインに考えてみる。初級者向けとなりそうなものは</p>

<ul>
<li>講師講演（LT)</li>
<li>ハンズオン</li>
<li>BoF,パネルディスカッション</li>
</ul>

<p>一つずつ検討してみよう。</p>

<h3><b>講師講演（LT)</b></h3>

<p>これは実は講師にとって非常にメリットの多い方法だと思っている。前で喋るためにはそれなりの準備が必要だし勉強もする。一度喋るとまた次回も発表したくなる。という風に上で述べていた成長のサイクルを描ける。問題点を挙げるなら聴衆の成長が少ないと思えるケースが多いことだ。事前にどんな講演がなされるのか予備知識が足りない。だから自分も講演を聞くための準備をしようと思えない。また、一方的に聞くだけなのでそもそも準備の必要性を感じない、というところも問題だ。</p>

<p>勉強会はそれを主催する人、講演する人、聞く人、全員のためのものだ。大多数である聞く人のメリットが少なくなるような問題点は何とか排除したい。対策としては以下のようなところだろうか。</p>

<ul>
<li><p>発表内容の資料を事前に公開する</p>

<p>これにより聴衆側も何らかの準備ができるかもしれない。また、自分にとって必要の無い講演だと判断できれば参加すらしないだろう。効率的に成長してもらうためには、不必要なことに時間を割かず、その間に別のことをしたほうがいい。必然的に当日のタイムスケジュールも明確に提示する必要がある、と結論付けられる。大学の授業のように出たいコマだけ出る、という感じになるだろうか。</p>

<p>この案の問題点は講師側の負担が高まってしまうことだ。資料を事前に用意する労力もさながら、自分の発表内容が魅力的でなければ聴衆も集まらないというダブルパンチ。正直自分でもやりたいと思うかどうかは微妙・・・。</p></li>
</ul>

<h3><b>ハンズオン</b></h3>

<p>実はこれが一番僕の理想に近い。手を動かしている間は少なくとも参加者は成長しているはずだ（もちろん参加するテーマによるので、そこはまた事前情報により選択してもらう）。</p>

<p>ただし、だからといって簡単にいかない事情がある。ここがクリアできれば僕が考える勉強会の半分以上はこのハンズオンでいいのではないかと思える。事情というのは</p>

<ul>
<li>全員分のPCなどの環境準備が必要</li>
<li><p>（今度は）講師側の成長が少ない</p>

<p>講師の成長の件は、その講師がやや背伸びして対応できる内容にうまくあてがうことができればいいと思っている。つまり、最初はハンズオンで学ぶ立場の人が、ある程度マスターしたら今度はそれを教える側に立つ。そうしながら自分はよりレベルの高いハンズオンで学ぶ、というようなローテーションがうまく組めればいいと思う。</p>

<p>実はこの形は、僕がこの勉強会で実現したい形でもある。僕が今、勉強会の発展形を考えているのは自分がその勉強会をうまく回していくことだけを考えているわけじゃない。勉強会フレームワークを作ることを目指している。そのフレームワークにならえば主催者の負担も低く、参加者も講師も成長できるような勉強会を簡単に開催できる、というようなものだ。</p>

<p>「勉強会フレームワーク」という製品を作るオープンソース活動と言ってもいいのではないか。そしてたくさんの人がそれにならって勉強会を企画し、京都の、関西の、全国のいたるところで毎日色んな勉強会が開催されれば嬉しい。その時僕は、一参加者として「今日はどれに出ようかな？」と日々自分の成長を楽しめるようになるのだ。</p>

<p>話がそれた。とにかく環境の準備が大変。ノートＰＣを皆が持参した場合、どの程度人が集まるのだろうか？そういうこと。</p></li>
</ul>

<h3><b>BoF,パネルディスカッション</b></h3>

<p>これは今回は却下。これで聴衆が成長すると思えない。全員参加型にするにも初級者にはハードルが高い。てことで却下。</p>

<hr />

<p>次回はこれらの問題点を踏まえて、その全てを同時に解決するようなウルトラＦ難度のアイデアが出たら嬉しい。
そんな期待を持ちながらＢ難度くらいでもないよりはマシ、というスタンスで色々考えてここで書こうと思う。</p>
]]></description>
 <category>勉強会</category>
<comments>http://blog.garden-place.jp/oborobeer/item_277.html</comments>
 <pubDate>Mon, 19 Oct 2009 18:29:26 +0900</pubDate>
</item><item>
 <title>京都の地より、ＩＴ勉強会を再考してみる #1</title>
 <link>http://blog.garden-place.jp/oborobeer/item_274.html</link>
<description><![CDATA[<p>僕は<a href="http://www.fxug.net/" title="Flex User Group">Flex User Group</a>でFlex勉強会の開催に参加しているわけだけど、あらためて勉強会というものを考えてみる機会に恵まれた。
自分にとって勉強会ってなんだろう？何を求めているのだろう？また、他の人はどうなんだろう？そんな疑問に自問自答しつつ、自分らしい勉強会の形を探ってみようと思う。</p>

<p>で、探るだけじゃなくてどんな勉強会を目指すかを決定する。
そして決定するだけじゃなくてその勉強会を開催する。
まあ確かにそれは失敗に終わるかもしれない。でももちろん、成功する可能性もなくはない。</p>

<p>失敗する時は２パターンあって、それは</p>

<ul>
<li>頭の中で考えて、無理だと判断し<b>実行しなかった</b></li>
<li><b>実行した</b>がうまくいかなかった</li>
</ul>

<p>これに対して成功するパターンは一通りだけ、それは</p>

<ul>
<li><b>実行して</b>、成功した</li>
</ul>

<p>つまり当たり前だが、実行せずに成功することはない。成功させるためには少なくとも実行する必要がある。思い立った時に行動しなければ情熱も冷めるので、今回は最速で実行に持っていくことを最優先しようと思う。そのために多少の品質低下や不整合は気にしない。</p>

<hr />

<p>さて、ではIT勉強会の目的から考える。
僕はもともと主催がしたかったわけじゃないので、あくまで参加者として何が欲しいかを考える。</p>

<ol>
<li>自分の知らない情報の収集</li>
<li>自分の技術的成長</li>
<li>同業種、自分と興味分野が近い人との繋がりを作る</li>
<li>他業種、自分と興味分野が遠い人との繋がりを作る</li>
<li>モチベーションアップ</li>
<li>etc</li>
</ol>

<p>こうやって挙げると上記の中で、僕が今ＩＴ勉強会に一番求めているのは「2. 自分の技術的成長」となる。あとは3や5もある。でも一番強いのは2。圧倒的に2。</p>

<p>なぜだろうかと考えた。それは恐らく自分の仕事に直結するからだ。
僕は今、開発者としての自分から徐々に経営者としての自分を意識せざるを得ない状況になっている。それはある部分で誇らしくもあるが、ある部分では非常に嘆かわしい。</p>

<p>日々の新規事業の考案であったり、組織の統制であったり、部下の育成であったり、それらはとても大切なことでそれに取り組む自分を間違っていると思ったことはない。でも、そんなこと大して気にせずとも開発のことさえ考えておけばある程度うまく回っていくような、そんな環境もあるんじゃないか？と思ってしまう。残念ながら今、僕はその環境にはいない。</p>

<p>僕は経営者である前に開発者でいたかった。じゃあその道は断たれたのだろうか？
う～ん・・・もう断たれたのかもしれない。でもどこかに突破口はあるのかもしれない。</p>

<p>僕はそれを勉強会に期待した。自分の開発者としての成長サイクルを、勉強会を軸に回していけるのではないか。長い長いマラソンの42Kmの道のりの中で、まずはあそこまで走ろうと思える一本の電信柱にできるのではないか。
僕と同じようなことを考えている人、もしもたくさんいるのなら、そんな人たちとともに成長したい。</p>

<p>キーワードは<b>成長</b>だ。</p>

<p>そしてもう一つ。</p>

<p>僕は「教育」が好きだ。
教育するのもされるのも好きだ。
ここで僕がいう教育とはただ単に知識を詰め込むことを指すのではない。相手の立場になり、相手に何が必要かを考え、相手より少し経験の多い人が親身になって、より正しく効率的な方向を指し示してやるというものだ。
これからFlexやAIRを学ぼうという人に、先輩たちの通ってきた道のりを正しく示してやることができたら嬉しい。</p>

<p>僕が目指す勉強会、そのキーワードは<b>成長</b>と<b>教育</b>。</p>

<p>目標設定はまだ終わらない。
僕が上に挙げた２つのキーワードは、実はかなり両立困難なことだと知っているからだ。</p>

<p>教育には多くの場合教師が必要だ。その教師が一生懸命教えたらどうなるか？多分、教師自身の成長は止まる。
もちろん教えることで「教えるという技術」は向上するし、教えたことで初めて自分の中で知識が整理されるということもある。
だけど野球のコーチがどれだけバッティングフォームの指導をしようと、自分でバットを振らなきゃそのうちヒットは打てなくなるだろう。</p>

<p>つまり一生けん命教えれば教えるほど、教える側の人が損をするという考え方もできてしまうのだ。
「成長」と「教育」を高いレベルで両立するのは無理ということか？</p>

<p>いや、そんなはずはない。</p>

<p>そんなところで思考停止してどうする。人間は他の動物にはできないマネをさんざん実現してきた。言葉を操って複雑なコミュニケーションを取ったり、何十階もあるようなビルを建てたり、鉄の塊を空に飛ばしたりしてきた。</p>

<p>その人間が、「成長と教育の両立はできません」だと？あほか。</p>

<p>絶対にできる。いや、恐らくすでにどこかでできている。試行錯誤を繰り返せば自分にもできるはずだ。そう信じることくらいは許されるはずだ。</p>

<p>僕の勉強会の目標は<b>成長と教育の有機的サイクル</b>を実現することに決定した。</p>
]]></description>
 <category>勉強会</category>
<comments>http://blog.garden-place.jp/oborobeer/item_274.html</comments>
 <pubDate>Thu, 15 Oct 2009 20:52:39 +0900</pubDate>
</item>
  </channel>
</rss>
