まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2020/04

知る人ぞ知るクイズ!脳ベルSHOW内「シャッフル人名」クイズの、クイズ問題を生成する AI で通称「シャッフル人名マシーン」を Windows10 環境で動かすための手順を紹介します。
20200416


大きく4つの段階に分かれています。最後の1つがシャッフル人名マシーン本体のインストールで、最初の3つはシャッフル人名マシーン・インストール前の前提条件となる部分のインストール作業です。



1. Linux/UNIX 環境の用意

「シャッフル人名マシーン」は Linux/UNIX 環境で動作します。Linux, macOS, ラズベリーパイなどを使っている場合、この 1 はすでに条件を満たしていることになるので飛ばして頂いて構いません。Windows 環境をお使いの場合はこの 1 を行う必要があります。

手順としては VirtualBox や VMWare などといった、いわゆる仮想マシン環境を構築して Linux をインストールしてもいいのですが、Windows 10 であれば WSL(Windows Subsystem for Linux) を使った方が(Linux 本体のインストールが不要で、初期設定も少ないので)楽だと思われ、おすすめです。

WSL を使って Ubuntu をインストールする手順については以下を参照してください:
http://www.aise.ics.saitama-u.ac.jp/~gotoh/HowToInstallUbuntu1804OnWSL.html#toc3


加えて2以降の作業を進める上での準備として、WSL を開いて以下の2つのコマンドを実行しておいてください:
$ sudo apt-get update -y

$ sudo apt install build-essential -y


なお、これ以降(2以降)の作業はすべて1で導入した Linux/UNIX 環境のターミナル画面を使って行います。


2. Node.js のインストール

「シャッフル人名マシーン」は Node.js(JavaScript) で記述されたプログラムです。というわけで、「シャッフル人名マシーン」を動かすには 1. で用意した Linux/UNIX 環境に Node.js をインストールする必要があります。これも済んでいる方は飛ばしていただいて構いません。

1. で用意した環境向けに Node.js をインストールしてください。なお Ubuntu に Node.js をインストールする手順については以下が詳しいので、こちらを参照してください:
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea


3. Mecab のインストール

前提準備としては最後の段階です。ここから先の部分はプログラマーであっても既に準備済み、という方はかなり少ないと思っています。「シャッフル人名マシーン」はその内部で Mecab という日本語形態素解析エンジンを使います。したがって Mecab も事前に(UTF-8 エンコーディングで動くように)インストールしておく必要があります。

WSL の Ubuntu に Mecab をインストールする場合の手順は以下を参照ください:
https://qiita.com/ekzemplaro/items/c98c7f6698f130b55d53

なおラズベリーパイ環境に Mecab を UTF-8 エンコーディングでインストールする場合の手順は以下を参照してください:
http://dotnsf.blog.jp/archives/2019-01-25.html


この 1 ~ 3 までの準備が完了すると、いよいよ「シャッフル人名マシーン」をインストールして動かすことができるようになります。


4. 「シャッフル人名マシーン」の導入と動作確認

ではいよいよシャッフル人名マシーンをインストールします。

まずターミナルを開き、git コマンドで「シャッフル人名マシーン」をダウンロードします:
$ git clone https://github.com/dotnsf/shuffle_jinmei

続いて「シャッフル人名マシーン」のソースコードがあるフォルダへ移動します:
$ cd shuffle_jinmei

2. の Node.js 導入時に同時にインストールした npm コマンドを使って「シャッフル人名マシーン」の動作に必要な依存ライブラリを導入します(この操作は一度だけ行う必要があります):
$ npm install

これで「シャッフル人名マシーン」実行前のすべての準備が完了しました。


いよいよ「シャッフル人名マシーン」を Node.js で実行してみます。シャッフル人名マシーンの実行には「シャッフル人名マシーン」の解答となる人物名をひらがなで指定して、以下のように実行します(以下は「かわばたやすなり」さんを指定した実行例です):
$ node shuffle_jinmei かわばたやすなり

※なお、ここで指定する人物名の名前が長いほど実行に時間がかかります。実行マシンの性能によっても異なりますが、9文字以上になるあたりから相当な時間を要するようになります。

最後まで完了すると、同じフォルダ内に (実行した人物名).txt というファイルが出来ているはずです(上記例であれば かわばたやすなり.txt というファイルが出来ています)。この中に実行結果が格納されています。ここでの「実行結果」とはシャッフル人名マシーンが「ある程度意味をなす日本語としてシャッフルできた」と判断した文章です。

内容を確認するには
$ nano かわばたやすなり.txt

などと実行してください。以下、実行結果例の一部を紹介します:
[
  {
    "kanji": "や",
    "original": "や",
    "lexical": "名詞"
  },
  {
    "kanji": "なり",
    "original": "なり",
    "lexical": "助動詞"
  },
  {
    "kanji": "た",
    "original": "た",
    "lexical": "助動詞"
  },
  {
    "kanji": "ば",
    "original": "ば",
    "lexical": "助詞"
  },
  {
    "kanji": "わかす",
    "original": "わかす",
    "lexical": "動詞"
  }
]
[
  {
    "kanji": "ば",
    "original": "ば",
    "lexical": "名詞"
  },
  {
    "kanji": "や",
    "original": "や",
    "lexical": "助詞"
  },
  {
    "kanji": "たす",
    "original": "たす",
    "lexical": "動詞"
  },
  {
    "kanji": "わ",
    "original": "わ",
    "lexical": "助詞"
  },
  {
    "kanji": "かなり",
    "original": "かなり",
    "lexical": "名詞"
  }
]
   :
   :

"[" から "]" までが1つの答になっていて、ある程度意味を成すを判断されたシャッフル結果が複数表示されていると思われます。例えば上記青字例では
  場や足すわ、かなり
という文章が「かわばたやすなり」のシャッフル結果として得られたことを意味しています。


といった具合にシャッフル人名マシーンをある俳優さんの名前を指定して動かして、
$ node shuffle_jinmei ???????

この問題が生まれた、という経緯だったのでした。
20200416



かなり自分向けですが、タイトル通りのウェブサービスを作ってみました。


【背景】
まずこのサービスを作った背景です。COVID-19 による在宅勤務やリモート会議が主流となる中で、ZOOM や WebEx などのウェブ会議サービスが多く使われるようになりました。このウェブ会議、サービスによって機能の違いはありますが、概ね以下のような機能を持っています:
・PC やスマホを使い、インターネット経由で仮想的な会議室に入って会議する
・音声は全員でリアルタイムに共有する
フロントカメラを使うことで参加者全員の表情を確認しながら進めることができる
ホスト役の PC 画面を全員で共有しながら会議できる(画面を共有する PC は後から変更可)

video_kaigi


これらの特徴によって、情報共有や伝達事項など「通知」目的のリモート会議であれば目的はほぼ達成できると思っています。通知したい人の画面を使ってプレゼンテーションを行い、その様子を他の参加者が音声と一緒にリアルタイムに確認し、質問なども行うことができるからです。
2020042601


一方、この形式ではまだリモート開催が難しい会議形態もあります。情報共有や伝達事項ではなく、ハンズオントレーニングなど「参加型」目的の場合です。ホスト役の人の画面を使ってハンズオン資料や作業内容を共有するところまでは何も変わりませんし、その様子を見ながら参加者が何の問題もなく作業を進めていける場合や、問題が発生しても自身で解決できる場合は問題になることもありません。Google Drive や Visual Studio Code Live Share のような仕組みを使うことで、全員で1つのファイルを同時に編集することはできます。この形がとれる場合においては音声と併用することでリモートサポートも可能になる範囲だと思っています。

ただローカル PC を使って作業する場合、特に参加者のスキルが必ずしも充分でない場合や、そうでなくても想定外のエラーが発生してしまった場合など、ウェブ会議では解決が途端に難しくなってしまいます。オンラインのウェブ会議ではなく、一箇所に(物理的に)集まって行う形式であれば、その場で本人の画面を覗き込めばエラー内容を確認できます。そのエラー内容が入力ミスなどのケアレスミスであれば正しい入力内容を指摘してあげるだけで解決できます。一方、入力内容が正しいのに想定外のエラーが発生しているようであれば、エラーメッセージやログ内容を参考にググったりして調べることになると思うのですが、画面が見えない限り、その場合分けすらも難しいという問題があります。また「エラーメッセージやログ内容を参考にググったり・・」と書きましたが、ウェブ会議で参加者のエラーメッセージやログ内容を正確に知るのは(その参加者のスキルレベルにもよりますが)かなり面倒です。実際にはエラー画面を共有してもらえればいいのですが、参加者がその手順を理解しているとは限りませんし、PC 画面を参加者全員に知られることに抵抗を感じる人もいると思われます。またその作業中は自分の(ホストの)画面を共有できなくなるので他の参加者の作業が止まってしまう可能性も危惧する必要があります。

更には、そもそもまったくセミナーに付いてこれない人がいて、序盤で躓いたまま全然進められていなかったりした場合でも、ウェブ会議のホスト側ではそのような人が存在していることに気付くことすらかなり困難です。
2020042602


比較的初心者を対象とするようなハンズオン勉強会を行うケースなど、上述のようなケースが想定されるオンライン会議をスムーズに行うには既存のウェブ会議システムだけでは難しいのではないか、、と考えていました。


【解決策の仮説】
上述のようなケースを解決するにはどうすればよいか? この問に対する明確な解答ではないのですが、1つ仮説を考えました:
従来のウェブ会議の逆を行うシステムがあれば解決するのではないか?

つまりホストの画面を参加者全員で共有するのではなく、参加者全員の画面の様子をホストが見れるようになっていれば、参加者側の操作でエラーが起こってもホストからエラーメッセージを確認できるし、作業についていけなくなったとしてもその様子をホスト側が確認できるのではないか?

この内容はあくまで仮説ですが、理屈の上では問題が解決しそうな気もしています。 この仮説を検証するための仕組みとして、ウェブ会議の逆(ホスト以外の参加者全員の画面をホストと共有する)を実現できる検証サービスを作ってみました。まだ使い勝手に難があることも理解していますが、仮説を検証するための機能までは実装できていると思っていて、特別なアプリケーションのインストールも必要としない形で実現できているので検証用に公開します。


【作ったサービス】
公開している URL は以下で紹介しますが、オープンソースとしても公開しています。ソースコードはこちらです:
https://github.com/dotnsf/screen_collect

また、このサービスを利用するには Windows または macOS で比較的最近の Chrome ブラウザを利用している必要があります。後述する MediaDevices インターフェースを使って実装している関係で、このインターフェースをサポートしていないスマホやタブレットのブラウザでは動きません。また他のブラウザでは未検証です。

以下、使い方を紹介します。


【使い方】
最初に、このサービスは実行順を守って動かす必要があります。最初にホスト側が会議室を準備し、その準備後にゲストが参加用 URL にアクセスすることで正しく実行されます(ホストが会議室を準備する前にゲストが URL にアクセスしてもその画面は共有対象になりません)。

まずホスト役の人が対応ブラウザを使って以下の URL にアクセスします(なおこのデモ用サービスでは Basic 認証は ID: admin, PW: password です):
https://screen-collect.mybluemix.net/view?room=XXXXXXXX

XXXXXXXX 部分は会議 ID のようなもので、ユニークな文字列を指定する必要があります(他の人と同じ値を使うと挙動がおかしくなります)。例えば日付や自分の名前を使って、以下の例のような URL を指定してください:
https://screen-collect.mybluemix.net/view?room=dotnsf-20200426

この時点では正しくアクセスできていても画面には何も表示されません(こんな感じの画面になれば正しくアクセスできています):
2020042601


この画面を使ってゲストの画面を共有することになるので、この画面を消さずに残しておいてください。またホストはこの画面をリロードしないよう気をつけてください(上述の順序の都合で、ホスト側ウィンドウをリロードした場合はゲスト側ウィンドウもリロードしてもらう必要があります):

最後にホストからゲストに参加用の URL を(メールやメッセンジャー等で)知らせる必要があります。ゲストへは上記 URL から "view" を除いた文字列を指定して通知してください。上記例の場合だと、この URL を教えることになります:
https://screen-collect.mybluemix.net/?room=dotnsf-20200426


ゲスト全員へ参加用 URL を通知し終わったらホスト側の準備は完了です。

ホスト側の準備が完了後にゲストが通知された URL にアクセスします(ゲストは Basic 認証なしでアクセス可能です)。なお試験的に一台の PC でホストとゲスト両方の画面をテストしたい場合は MediaDevice インターフェースのサポートの都合もあり、ホスト画面を FireFox で、ゲスト画面を Chrome で表示するようにしてください。

するとゲストには以下のような画面が表示されます:
2020042601


Room には URL で指定された会議 ID が表示されています。もしホストが URL を間違えて通知していても、ここで会議 ID を正しく修正して続行することで以下正しく実行されます。

そして Your name .. と書かれたフィールドに参加者の名前(本名でもニックネームでも可。ホストの人がわかる名前)を入力して Start ボタンをクリックします。
2020042602


すると画面には入力した名前が表示されますが、同時に別ウィンドウで画面共有ダイアログが表示されます。ここでゲストは共有範囲を選択します。共有範囲はアプリケーションウィンドウの単位でも、Chrome ブラウザのタブの単位でも、また全画面を選択することも可能です(以下の例では全画面を選択しています):
2020042603


共有範囲を選択したら「共有」ボタンをクリックします:
2020042604


するとゲスト画面では画面共有ダイアログが消え、代わりに小さな共有ウィンドウが表示されます(ゲストはこのウィンドウ画面を消さないよう注意してください):
2020042605


これでゲスト側の準備も完了しました。この後、ゲストは自由にアプリケーションを使ってください(下図ではゲストが Visual Studio Code を起動してプログラミングしている様子にしています):
2020042606


(実際のオンライン勉強会などではホストとゲストが事前にここまで行った上で実際のハンズオン作業に入ってもらう想定です)


ここで改めてホスト側の画面を確認します。さっきまで何も表示されていなかったホスト画面でしたが、ゲストが共有設定を完了すると、ゲストの名前とその画面がパネル表示されているはずです。またゲストの画面は(このデモサービスでは)5秒おきに更新されます:
2020042602


更に別のゲストが共有設定を完了するとパネルが追加され、以下のような感じになります。ホストの1画面内にゲストの画面が追加されて一覧できるようになり、(5秒おきですが)そこで行われているオペレーションの内容も確認できます。パネルはゲストの人数に応じて(共有設定が完了するたびに)追加されていきます:
2020042603


パネル内画面は縮小表示されていますが、画像を選択してクリックするとゲストのスクリーンと同じ縦横比率で拡大して表示されます。これでゲスト側でエラーメッセージなどが表示されていてもホスト側から視認することができるようになりますし、オンラインセミナーに付いてこれなくなって遅れ気味の人もホスト側から確認できるようになる、と思っています:
2020042604


ゲスト側は Chrome のゲストウィンドウを消すか、以下のダイアログの「共有を停止」をクリックすることで画面共有を停止できます:
2020042607


以上がサービスの使い方です。特別なアプリケーションをインストールすることなく、ブラウザだけで複数ユーザーのスクリーン内容をホストに共有する、という「ありそうでなかった※」サービスだと思っています。

※参加者の表情をカメラで映して同時に共有する、という機能は多くのウェブ会議システムに装備されていますが、参加者のスクリーンを共有する機能はなぜか付属していない機能だと思っています。

今後リモート勉強会などであらかじめこの準備をしておくことで、トラブルシューティングやリモートサポートに活用できないかと考えています。また上述のようにソースコードも公開しているので、興味ある方は専用環境を構築してお使いいただいても構いません。

以下、実現方法に関する技術的な補足説明です。興味ある方は引き続きどうぞ。


【どうやって実現しているか】
まず、このサービスはホストもゲストもウェブブラウザだけで(アプリケーションのインストールなしで)実現しています。また HTTP(s) 以外のプロトコルは使っていません。したがって比較的多くの環境で利用できるようになっていると思っています。

で、これを実現している鍵というかキーワードが何度か上述されている MediaDevices インターフェースです。簡単にいうと HTML と JavaScript だけで画面共有とそのために必要な UI を実現する技術です。ただ比較的新しい技術である上に対応している OS やブラウザはかなり少なく、スマホ・タブレット系は 2020/04/26 時点では全滅といっていい状況です(まあスマホでハンズオンセミナーに参加する人も少ないとは思うけど・・・)。MediaDevices インターフェースについては過去にこれをテーマにブログで紹介したこともあるので、詳しくはそちらも参照してください(この時はホスト・ゲストに分けず、1つの HTML 画面内で画面ストリームを取得してそのまま表示する、という内容でした):
MediaDevices インターフェースを使った画面共有

今回上記で紹介したデモはこの応用といえるもので「ゲストで取得した画面ストリームの内容を使い、バックグラウンドで5秒おきにスクリーンショットを撮ってホストに画像をポストし、ホストで受け取った画像を表示する」ということをゲストブラウザ内の JavaScript とホストサーバーの WebSocket を使って実現しています。機能的にはわざわざスクリーンショット(画像)に変換せず、ストリームのまま(動画のまま)ホストに送信する選択肢もあるのですが、さすがに帯域的にもホストの処理内容的にも(そしてデモサーバーの処理能力的にも)厳しそうな感触があったので、意図的に5秒おきにスクリーンショットを送受信する形にしています(5秒という部分は別途専用環境を作る際には変更可能です)。ただこの結果、ネットワーク上のすべてのやり取りを HTTP(s) と(HTTP を拡張した)WebSocket に集約することができ、帯域問題に加えてファイアウォール的な制約をすり抜けやすい形で実現できたという副産物もあります。

もう少し詳しく2点説明します。まずゲスト側で(JavaScript だけで)共有範囲のスクリーンショットを撮る、という操作ですが、これは上述の MediaDevices インターフェースを使って共有アプリケーション画面のストリームを取得した後に、以下のような処理を行っています。

"Your name .." で指定した名前だけが表示されているように見える HTML 画面には、実は非表示属性の付いた <video> 要素と、同じく非表示属性の付いた <canvas> が存在しています:
<body>
  <h3 id="name"><%= name %></h3>

  <!-- Video element (live stream) -->
  <div class="hidetop">
    <video autoplay playsinline id="video" width="640" height="480"></video>
  </div>

  <!-- Canvas element (screenshot) -->
  <div class="hide">
    <canvas id="canvas" width="640" height="480"></canvas>
  </div>
</body>

↑(hidetop クラスと hide クラスでブロックごと非表示指定されているので、ゲストユーザーからは何も見えません)

そして5秒おきに以下の JavaScript 関数 : video2image() が実行されます:
function video2image(){
  if( localStream ){
    var canvas = document.getElementById( 'canvas' );
    var ctx = canvas.getContext( '2d' );

    var video = document.getElementById( 'video' );
    var w = video.offsetWidth;
    var h = video.offsetHeight;

    canvas.setAttribute( "width", w );
    canvas.setAttribute( "height", h );

    ctx.drawImage( video, 0, 0, w, h );
    var png = canvas.toDataURL( 'image/png' );

    //. 画像を通知
    var msg = {
      uuid: uuid,
      room: '<%= room %>',
      image_src: png
    };
    socketio.json.emit( 'image_client', msg );
  }
}

localStream がスクリーン画面のストリームです。このストリームは <video> 要素と接続しています(この辺りは上記のブログの内容を参照ください)。そして <video> の画面を(非表示の) <canvas> にコピーすることでスクリーンショットを取得し、その内容を canvas.toDataURL() で画像データに変換した上で、Socket.IO を使い、ゲストの ID と一緒に WebSocket でホストの image_client イベントに送信しています。これによりバックグラウンド処理で5秒おきにスクリーンショット画像をホストに送る、という処理が実現できています。

そしてホスト側にはスクリーンショット画像を WebSocket で受け取った後(image_client イベント発生時の)の処理が記述されています:
  socketio.on( 'image_client_view', function( msg ){
    var socket_id = msg.uuid; //msg.socket_id;
    if( socket_ids.indexOf( socket_id ) > -1 ){  //. socket_ids == [];
      $('#image_'+socket_id).prop( 'src', msg.image_src );
      $('#image_'+socket_id).prop( 'title', msg.comment );
    }
  });

メッセージの ID でどのゲストからのイベントであるかを識別した上で、その中の image_src を使って画像情報(=スクリーンショット)を取り出し、ホスト画面内の適切な箇所の画像(=対象ゲストのパネル内の画像)を動的に再描画しています。

実際にはこれらの抜粋処理以外にも、これらをつなぐための処理や初期化などをアプリケーション・サーバー側で行ったりしています。詳しい内容については公開しているソースコードを参照ください。大規模な実験を行うようなケースでは別途独自の環境を準備した上で行っていただけると助かります:
https://github.com/dotnsf/screen_collect


【最後に】
こういったサービスを作って試すことで「こういうケースでは使えそう、こういうケースだとまだ○○の問題がある」みたいな形で次のステップが見えてくると思っています。自分的にはある程度のスキルを持った参加者による「もくもく会」のような内容であれば使えそうだという感触を持っていますが、より初心者参加型に近い内容だと、これだけで充分なサポートができるかどうかは不安もあります。

ただそれらが見えてくることで改良点のヒントにもなるだろうし、用途や条件によっては実践で使うこともできるかもしれないと考えています。またこのデモサービスを使ってみていただいた感想や「こういうケースではOKだった/NGだった」のようなフィードバックもいただけると嬉しいです。いずれにせよオンライン勉強会の体験改善は自分にとっても無視できないテーマなので、こういった形で解決できることがあれば引き続き取り組んでいきたいと思っています。


このエントリの続きです:
Visual Studio Code Live Share でモブプログラミング(1)


前回 VSCode LiveShare を使うまでの準備段階とその手順を紹介しました。今回は実際に VSCode LiveShare を使ってモブプログラミングを行うまでの手順と、使っている時の様子を紹介します。

なお VSCode LiveShare を使う場合、開発画面を提供する人(ホスト、1名)と、ホストの開発画面を使って開発に参加する人(ゲスト、1名以上)それぞれで手順が異なります。以下順を追って紹介しますが、ホスト側の手順はこの色で、そしてゲスト側の手順はこの色でそれぞれ紹介していきます。


【ゲストの招待】
まずはホストとなる人からゲストとなる人へ、Live Share に参加するための URL を送信する必要があります。このホストとなる人の VSCode の環境(ファイルシステム、ファイル)を共有することになる点にご注意ください。この手順は前回紹介した準備手順が全て完了している状態から続けて以下を行います。


まず VSCode を開き共有するプロジェクトを1つ作成して開きます。ここで開いている画面を共有することになる点に注意してください。したがって関係のないプロジェクトフォルダが含まれるような画面ではなく、共有するプロジェクトフォルダだけが開いているような画面にしておくのがよろしいと思います:
2020042008


なお、この例ではフォルダの中に README.md ファイル1つだけが入っている状態からスタートする例を紹介します:
2020042105



プロジェクトの準備ができたら VSCode 画面左下の、ログインしている自分のアカウント名をクリックします:
2020042006


メニューが表示されたら一番上の Invite Others(Copy Link) と書かれた部分をクリックします。これで招待用 URL がクリップボードにコピーされた状態になります:
2020042007


そのままメールやメッセンジャーなどを使って、招待するゲストの人達全員に先程コピーした内容をペーストして共有 URL を送信します:
2020042009


ホスト役の人の作業はいったんこれで完了です。次はゲスト役の人達の作業となります。


【ゲストとしてプロジェクトに参加】
ゲスト役の人達は上述の最後の手順で送信された共有 URL 付きのメッセージを受け取ったら、そのリンクをクリックします:
VSCLS00



ゲストのログインが環境していない場合、ウェブブラウザで VSCode LiveShare を使うためのアカウントログインを行います。以下は GitHub を使って OAuth ログインする場合の画面です。必要であればアカウントにログインします:
VSCLS01


そして OAuth を行うため、内容を確認して Authorize ボタンをクリックします:
VSCLS02


ログインが完了すると以下のようなダイアログが表示され、Visual Studio Code が選択されていることを確認して「リンクを開く」ボタンをクリックします:
VSCLS03


この際に Live Share プラグインがこの URI を開くことを許可するか?と聞かれたら、OK をクリックして許可してください:
VSCLS04


またゲストが Windows を使っている場合、初回だけは Visual Studio Live Share Agent の実行をファイアウォールに許可する必要があります。以下の画面が出たら「アクセスを許可する」を選択してください:
VSCLS05


ここまで成功すると、ゲストの VSCode でホストの VSCode プロジェクトが共有されている状態になります。ホストが共有したプロジェクトをゲストの VSCode 内でも開いていることを確認してください:
20200421001


【ゲストがプロジェクトを編集】
ここから先の作業はホストでもゲストでもいいのですが、今回はゲストがプロジェクトを中心的に作っていくものとして紹介します。というわけで引き続きゲスト側の作業となります。

ゲストの VSCode 内で新規にファイルをプロジェクトに追加したり、そのファイルを編集したり保存したりすることができます。これらの変更はあくまでホストのファイルシステムに対する変更ですが、その作業はゲスト側から行うことができるようになっています:
20200421002


なお、このゲストが行った変更はホスト側の VSCode でもリアルタイムに変更が反映されます:
2020042101


更に同時にホストも、また他のゲストもプロジェクトの同じソースコードに対して変更を行うことが可能です。Google Drive の同時編集機能を使ったことがある人であれば、あれのソースコードプロジェクト版だと理解いただくとわかりやすいかもしれません。また他のファイルを編集することも可能ですが、共有される画面はあくまで1つ(ホストのもの)であることに注意してください。

このような共同作業を通じてプロジェクトを作っていきます。


【ターミナルの共有】
ある程度プロジェクトができあがると動作確認をしたくなります。VSCode LiveShare ではホストのターミナル(Shell や PowerShell)を共有してコマンドを実行することで動作確認作業を共有することが可能となっています。

実際にターミナルを共有するにはホスト側で再度画面左下の自分の名前をクリックし、表示されるメニューから Share Terminal を選択します:
2020042102


ターミナルに対するゲストの権限を指定します。"Read-only" はターミナル自体はホストだけが作業をして、ゲストはターミナルの様子を見ることができる、というモードです。一方 "Read/write" はゲストもターミナルに対してコマンドを実行することができるモードです。ターミナルはかなり強い権限で実行され、想定外のコマンドを指定されてもそのままホストのPC上で実行してしまうので、よほど信頼できる相手と共有している場合のみ後者を選ぶべきだと思います:
2020042103


ターミナルを共有すると、ホストの PC が Windows であれば PowerShell、それ以外であれば Shell 画面が VSCode 画面内に表示されます(ターミナルアプリを WSL などにを変更することも可能です 参照):
2020042104


同時にゲストの VSCode 画面内にも同じターミナルが表示されます。モードによってはゲストからこのターミナルにコマンドを指定して実行することも可能です:
20200421003


このターミナルから Node.js などのコマンドを実行するなどしてテストや動作確認を行い、その結果を全員が共有することが可能です。



と、このような形で VSCode LiveShare を使うことができます。実際にはこの機能とウェブ会議システムを併用して、ホスト役の人が行う内容をプレゼンテーションと音声で共有しつつ、実際のプログラミング時には VSCode LiveShare の画面を共有する形でモブプログラミングを進める、といったことができそうです。

この方法であれば、従来の画面共有だけを使ったモブプログラミングと比較して、エラーが発生した時の内容を共有しやすいという大きなメリットが挙げられます。ホスト役でない人の PC で発生したエラーの内容をホストやサポート役の人が把握するのが難しいのですが、VSCode LiveShare を使っていると、エラーの様子も共有されることになり、その内容からどこをどう直せばよいか、というアドバイスもしやすくなると考えられます。


普段のエディタは Vi(m) か ATOM(+vi プラグイン)を気に入って使ってます。軽量で使いやすく、vi の慣れたキーバインドで使えるという点にメリットを感じています。 が、最近になって Visual Studio Code(以下 VSCode)を vi キーバインドで使うという選択肢も気になっています。特に後述する Visual Code Live Share(以下 VSCode LiveShare)は、今日のようなオンライン中心のイベントや勉強会で使える共同開発ツールとしてポテンシャルを感じています。そんなわけで、このブログでも VSCode LiveShare を使ったモブプログラミング(共同開発作業)を紹介しようと思いました。まず今回は環境準備の説明です。


【前提条件】
Windows 7 以上、64 bit Linux、 または macOS 10.13 以上 を使っている必要があります。VSCode 自体は Raspberry Pi などの他環境向けにも提供されていますが、後述する VSCode LiveShare プラグインは動作環境が限られているようで、現時点(2020/04/20)では Windows, Linux または macOS を使う必要があるようです。


【VSCode のインストール】
VSCode の公式サイトから VSCode をダウンロードして(普通に)インストールしてください。なお、VSCode LiveShare を使う場合はバージョン 1.22 以上が必要です。


【VSCode LiveShare プラグインのインストール】
VSCode LiveShare は VSCode を使ったコーディングの共同作業を行うツールです。それを実現するための拡張機能が VSCode LiveShare プラグインです。このプラグインは共同作業におけるホスト役の人(自分のコードを他の人に編集させる人)だけでなく、ゲスト役の人(他の人のコードを編集する人)の環境にも両方にインストールが必要です。

インターネットに接続された状態で VSCode を起動し、画面左のメニューから Extension タブを選び、検索フィールドに Live Share と入力して検索します。その名の通りの Live Share プラグインが見つかるのでこれをインストールします:
2020042001


プラグインのインストールの最後にリロードを促されるのでリロードします。この後バックグラウンドで依存ライブラリのインストールが始まり、完了まで少し待ちます。

プラグインのインストールが完了すると画面左下が以下のようになり、Live Share が利用可能になっていることがわかるようになります:
2020042002


なお、VSCode に(日本語化パックや VIM など)他のプラグインを使う場合はこのタイミングで必要なものを導入しておいてください。


【ログイン】
VSCode LiveShare で共同作業する際、「誰が」コードを編集しているのかがわかりやすいようにログインする必要があります。VSCode LiveShare の場合、Microsoft アカウントまたは GitHub アカウントで OAuth 認証を行う必要があります。以下は GitHub アカウントを使ってログインする例を紹介します。

上述画面の Live Share と白抜きで表示されている部分をクリックしてログインします。下図のような表示になるのでログインに利用するアカウントを選んで進めます(以下は "Sign in with GitHub" を選んだものとして説明を続けます):
2020042003


選択したアカウントの OAuth 認証の画面が表示されます。内容を確認して、許可(Authorize)するボタンをクリックします:
2020042004


プログラムを起動するダイアログが表示されたら、"Visual Studio Code" が洗濯されていることを確認して「リンクを開く」をクリックします:
2020042005


再び VSCode の画面に戻ります。この時点で画面左下にログインしたアカウントのユーザー名が表示され、VSCode LiveShare を利用するための準備も完了しています:
2020042006


これで VSCode LiveShare を使う準備ができました。次回はこの続きで実際に VSCode LiveShare を使う様子を紹介する予定です。


(2020/04/23 追記 続きはこちら)
http://dotnsf.blog.jp/archives/1077356596.html


突然ですが、以下の間違った式からマッチ棒を一本だけ動かして正しい式にしてください。なお ≠ (not equal)記号は使えないものとします:



正解は下にスクロールして確認してください:

 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓

模範解答はこちらです:



いかがですか? 意外と難しかったでしょうか? 「一本だけ」動かして成立させる、というルールが絶妙で、また色々なマッチ棒の使い方や可能性があったりして、時間制限によっては僕も解けなかったりします。結構盛り上がる遊びです。 ちなみに BSフジで放送中の「クイズ!脳ベル SHOW」の中のミニクイズの1つでもあったりします。

で、今回のブログエントリで紹介するのは、このマッチ棒クイズを自動的に解くプログラムです。デモサイトはこちらです(スマホで見る場合は画面を横長にしてください):
https://dotnsf.github.io/matchbo/

2020041200


赤字で「問題」と書かれたフィールドに初期状態の(問題文となる正しくない)式を入力します(掛け算は * 、割り算は /)。するとそのすぐ下に入力式がマッチ棒に変換されて表示されます:
2020041201


これが出題です。この 4+3=5+9 は解くのにトリッキーなワザが必要な出題例ですが、答はわかりますか? 答がわかったか、或いはギブアップする場合は次に進んでください。

ここで入力した問題の答をコンピュータに解かせることで答の一例を確認できます。コンピュータに解かせるには、問題フィールドが入力状態になっている時に Enter を押します(要は Submit します)。するとクイズの答となりえるものを探して下部に表示してくれます。

 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓
 ↓

2020041203

※わかりますか? 4から一本動かして 11 にして式を成立させています。こういう所に気づかないといけなかったりして、意外と奥の深いクイズだったりします。

なお、問題や解答として識別可能な文字はクイズ!脳ベル SHOW のルールに従って以下の通りとします(記号も掛け算割り算以外は変更が加わる可能性があることに注意が必要です):
2020041202


上記以外の文字表記は使えないものとします。また掛け算・割り算は足し算・引き算よりも優先されます。また最終的に成立していればですが、イコール記号は2つ以上使っても構いません、という番組ルールにのっとって判断されます。

また解がない(一本動かしただけでは成立しない)とコンピュータが判断した場合はその旨のメッセージが表示されます。本当は解が存在しているのにこのメッセージが出た場合は僕の作ったアルゴリズムが未熟なせい、ということにしてください:
2020041204



クイズとしても面白いのですが、解いていくうちに、自分の頭の中よりも効率的な解法アルゴリズムを思いついて、試しに実装してみたらなかなかの出来だったので公開します。なおソースコードも公開するので、興味ある方は中身も御覧ください。僕の独自アルゴリズムなので、もっと効率的な方法が存在している可能性大ですけど:
https://github.com/dotnsf/matchbo



このページのトップヘ