Scratchから飛び出してSmalltalkを学ぼう(準備編)

先日書いた記事に返事を頂いて、そうか、Scratch 1.4 の中身は Smalltalk(Squeak)なのだからそっちで試してみることができるんだ。ということで、ちょっと Smalltalk を数日動かしてみる。

何処から手を付ければよいのか?

真面目にやるのであれば、教科書とかチュートリアルをやればいいんでしょうが、そもそも Smalltalk を今更まじめに見る気はないし(と思っておりましたよ)、オブジェクト指向のメッセージングのところだけ見ておきたいので、何かよい実例はないのかと思い探してみました。Google で初心者解説回りをさがしてもよいのですが、今だとアドベントカレンダーを見ていくとなんとなく実用がわかります。

Smalltalk Advent Calendar 2017 – Qiita
https://qiita.com/advent-calendar/2017/smalltalk

初心者なところと、難解で細かいいところと雑多な記事があつまっていますが、少なくと、

  • ほどよく、プログラム言語を使っている人が書いている
  • ほどよく、複数の人が書いている

ということで、アドベントカレンダーの各記事と各リンクはプログラム言語を学ぶときのとっかかりとして便利です。

テスト駆動開発でお試しする Pharo Smalltalk・第1回 はじめてのレッド、イエロー、グリーン – Qiita
https://qiita.com/sumim/items/fa41066c57d211814ff9

そんな中で、TDD を使った解説があったので試していきます。

Scratch 1.4 で Smalltalk を使う

ちなみに、Scratch 1.4 で Smalltalk の環境を開くには、以下の記事を参考にしてください。

SmalltalkからScratchをいじる(1) スプライトの大量生成 – Qiita
https://qiita.com/maeda_/items/7a525cae6b3c1ca45773

「画面右上のSCRATCHのロゴの”R”の部分をShiftキーを押しながらクリックするとメニューが開きます。」ってのがスタートです。

  • inspect morph がスクリプトを持つ変数表示と workspace/playground の表示
  • browse morph class でクラスのブラウジングの表示

image

このままでも色々できるはずなのですが、もうちょっときちんとして環境が欲しいので、Pharo ってのを入れます。

Pharo 6.1 を使う

Pharo  https://pharo.org/ ってのは、OSS な Smalltalk な環境で、Windows/macOS/Linux での動作環境が用意されています。先の TDD の解説も Pharo なので、これを使います。

Smalltalk は内部では VM で動いているので、Android シミュレータのようにイメージをダウンロードして実行します。で、最新の公開は 7.0 らしいのですが、stable なのは 6.1 のほうですね。7.0 と 6.1 はメニュー表示が微妙に違っていて、先の TDD の記事と違ってしまうので、6.1 のほうを入れます。

image

間違えて 7.0 のほうを入れて「メニューが違う」「リファクタリングがない」と思って苦労したのは内緒です。↓が 7.0 の画面

image

これが 6.1 の画面。ちょっと違う。

image

まず最初にやってことは、コードエディタの文字が小さいので大きくするところから、背景部分をクリックして「System」→「Setting」を開きます。

image

何処あるのかわからないので、Font で検索して、Default と Code の部分を変更します。大きめにしておくと老眼の私には優しくなります。

image

TDD のチュートリアルを進める

テスト駆動開発でお試しする Pharo Smalltalk・目次 – Qiita
https://qiita.com/sumim/items/3a36c03ab41519077b37

を地味に進めるわけですが、まったく Smalltalk の文法が分からないながらもいくつか面白い発見をしたので、以下、書き残しておきます。Smalltalk 自体は古い言語(メジャーなのは Smalltalk-80 位からだから、40年ぐらい前か)ので、そのあとに出てきた言語も含めてってことですが。

文末に「.」ピリオドを使う

C言語系では文の終わりに「;」セミコロンを使うわけですが(これが嫌われものであり、セミコロンあるなしで、関数言語とか Python とかに移る場合もあるわけで)、Smalltalk は「.」ピリオドで文章を終わらせます。なるほど、英文はピリオドで終わるから、Smalltalk もピリオドで終わるのですね(おそらく)。

image

関数の最後はピリオドが省略できるので、一文だけの関数はピリオドがあったりなかったりします。

戻り値を ^ で表す。

最初、この「^」はなんだ?と思ったのですが、return です。関数型言語だと、常に式を表すので関数の最後の行が価を返すことが決まっているのですが、Smalltalk の場合は、明示的に値を返します。

image

メソッドのパラメータを「:」コロンで区切る

Smalltalk でメソッド(関数)を呼び出すときに、括弧を書きません。引数の指定に「:」コロンを使うわけですが、なんか、この形式みたことがあるな?と思ったら Objective-C でした。

image

というか、Objective-C のルーツが Smalltalk であったことを今知りました。

  • Smalltalk の場合
    bank addXRate: 1 USD / 2 CHF .
  • Objective-C の場合
    [ bank addXRate: 1 USD / 2 CHF ] ;
  • C++ の場合
    bank.addXRate( 1 USD / 2 CHF ) ;

「1 USD / 2 CHF」は、まあ、ひとつの引数とみてください。Objective-C の場合、ひとつ目の引数の場合は名前(セレクタ)を省略することもできるのですが、ここではあえて使うパターンで。

2つのパラメータを持つときは、

  • Smalltalk の場合
    bank exchange: 10 CHF to: #USD .
  • Objective-C の場合
    [ bank exchange: 10 to: #USD ] ;
  • C++ の場合
    bank.exchange( 10, #USD );

こんな感じになりますね。C/C++ だと引数に名前がつかないので、型で判断するのでややこしくなるのですが、Smalltalk の場合は名前が使えます。この部分、C# では名前付きの記法もできるようになったので、似た形で書けます。

ちなみに self は自分自身のオブジェクトを示すので C++ の this と同じ。

  • self assert: ( bank exchange: 10 CHF  to: #USD ) equals: 5 USD
  • this->assert( bank.exchange( 10, #USD ), 5 USD );

この2つは同じ意味になります。

Smalltalk には型がない

実は Smalltalk には型がありません(と言い切っていいのだろうか?)。関数の後ろにある「|」パイプで囲まれたところが、内部変数の宣言です。えらい大雑把ですが、Smalltalk が VM で動いているからこれでいけるみたいです。

image

VB6 の Variant みたいな感じですかね。

  • Dim bank, result

と書くのと同じことになります。ちなみに、下記のように bank 変数に別の型を入れてもエラーになりません。あまり、やらないだろうけど。

image

既存クラスを拡張できる

たぶん、Smalltalk のオブジェクト指向プログラミングの肝になると思うのですが、Smalltalk では既存のクラスにメソッドを追加して拡張できます。Objective-C でいうカテゴリだったり、C# でいう拡張メソッドのような機能ですが、Smalltalk ではすでに定義されているクラスに対してメソッドが追加できます。

image

既存のクラスを弄ってしまうのだから、セキュリティやら隠蔽性やらはどこに行くの?という話なのですが、そこは Smalltalk が VM 上で動いている利点なのでしょう。動作環境が別々なのだから大丈夫…という思想だったのかもしれません。

ともかく、一番根っこになる Object クラスにもメソッドを追加できます。

image

Object クラスの testing のカテゴリ(これは分類なので、何処にあっても一緒(だと思う)には、isColor とかいうメソッドもあるわけで、所謂「神クラス」になります。Objective-C にもカテゴリ名を使って既存クラスを拡張する機能があってので、これと同じ機能を取り入れたものと思われます。

C++ がオブジェクト指向で GUI を作るときに継承を使い、そのあと深い継承が深くなりすぎて C# で委譲が使われることが多くなった、という経緯があるのですが、Smalltalk だと根っこに手を入れるという技があったのですね。まあ、このあたりは C++/Java/C# 等ではできないし、親クラスがいきなり変わってしまっても困るので(メソッド名の重複など)拡張という機能だけに留まるわけですが。

細かく保存し、細かくコンパイルする

Smalltalk では、ブロックという概念がない(らしい)ので、クラスのメソッド単位でコードを書いていきます。メソッドが細かく分かれるので、分かれた単位で保存&コンパイル(Accept)を繰り返します。これ、昔は相当重かったと思われるのですが、今の CPU ならば全然問題ありません。

image

記述するコードは十数行ぐらいなので、これで十分かもしれません。逆に言えば、ひとつのメソッドに数百行も書いてしまっていたら、Smalltalk としてはおかしいかもしれません。

if 文ってのは無い

これも Smalltalk の奇妙な文法だと思うのですが、Smalltalk には if 文がありません(たぶん)。じゃあ、条件分岐はどうなるのか?というと「ifTrue:」と「ifFalse:」というセレクタ(引数みたいなものか)を使います。

image

なので、C++ であれば

if ( a == true ) { b = 10 ; } else { b = 20 ; }

と書くところを、Smalltalk では、

a == true ifTrue: [b := 10] ifFalse: [b := 20] .

と書きます。不思議ですね。この書き方、実は利点があって、if 文(っぽいもの)が式として扱えるので、関数型言語っぽいことができます。

b := a == true ifTrue: 10 ifFalse: 20 .

な感じで、a が true/false かによって、10 か 20 を b に代入ができます。

~~~

そんな訳でひとまず、気づいたところはここまで。あともう少し TDD をぽちぽちと進めるつもり。

カテゴリー: 開発, Smalltalk | Scratchから飛び出してSmalltalkを学ぼう(準備編) はコメントを受け付けていません

System.Net.HttpListener が .NET Core の時だけメモリリークっぽい現象になる件の解決策

FireScratch を C# で作っていた時に発覚したメモリーリックっぽい現象に当たったので、珍しく issue https://github.com/dotnet/corefx/issues/32454 を立てました。

サーバーのほうで、.NET Core か .NET Framework を使って以下のような簡易 HTTP サーバーを作ります。

namespace CheckHttpListener
 {
     class Program
     {
         static void Main(string[] args)
         {
             Console.WriteLine("test server .net framework");
             var listener = new System.Net.HttpListener();
             listener.Prefixes.Add("http://127.0.0.1:5411/");
             listener.Start();
             while (true)
             {
                 var context = listener.GetContext();
                 var res = context.Response;
                 res.StatusCode = 200;
                 var sw = new System.IO.StreamWriter(res.OutputStream);
                 sw.Write(string.Format("text {0}", DateTime.Now.ToString()));
                 sw.Close();
             }
         }
     }
 }

これに対して、テスト用にアクセスするクライアントを作っておきます。

namespace CheckClient
{
    class Program
     {
         static void Main(string[] args)
         {
             HttpClient client = new HttpClient();
             int cnt = 0;
             while ( true )
             {
                 var res = client.GetAsync("http://localhost:5411").Result;
                 var text = res.Content.ReadAsStringAsync().Result;
                 Console.WriteLine($"{cnt} {text}");
                 cnt++;
                 System.Threading.Thread.Sleep(20);
             }
         }
     }
 }

これを動かしておくと、.NET Framework の時にはサーバーのメモリが程よい大きさで止まるのですが、.NET Core のほうは、がんがんとメモリを食い潰してしまって最後にサーバーが倒れます。だいたい1時間ぐらい放置しておくと落ちます。

image

同じコードで、.NET Framework と .NET Core の挙動が異なるので、.NET Core の HttpListener のバグか?とも思ったのですが、どうやら HttpListener.GetContext が HttpListnerContonet が持つ Response オブジェクトの挙動が異なるので、一概にバグとは言えないような感じです。

Response を明示的に Close するか using を使う

解決策としては、Response に対して明示的に Close メソッドを呼び出すか、using を使って暗黙に Response が閉じられるようにします。

var context = listener.GetContext();
var res = context.Response;
 res.StatusCode = 200;
var sw = new System.IO.StreamWriter(res.OutputStream);
 sw.Write(string.Format("text {0}", DateTime.Now.ToString()));
 sw.Close();
 res.Close(); // ★

あるいは、

var context = listener.GetContext();
using (var res = context.Response)  // ★
 {
     res.StatusCode = 200;
     using (var sw = new System.IO.StreamWriter(res.OutputStream))
     {
         sw.Write(string.Format("text {0}", DateTime.Now.ToString()));
     }
}

のように書きます。この Close 処理は .NET Framework でも有効なので、これで同じコードで .NET Core でも .NET Framework でもメモリリークが出ないようになります。

大抵のサンプルは HttpListener をたくさん回さないので、この問題にあたることはないのですが、実際に作ってサーバー化すると数時間後に落ちたりするので注意が必要ですね。これ、Windows + .NET Core だけの現象なのか、それとも Linux + .NET Core でも発生するのかはあとで調べておきます。

カテゴリー: C# | System.Net.HttpListener が .NET Core の時だけメモリリークっぽい現象になる件の解決策 はコメントを受け付けていません

いっせーのせで学ぶ Scratch のブロードキャストメッセージ

Scratch のメッセージングは、普通のオブジェクト指向言語と変わっていて(Scratch 自体はれっきとした「オブジェクト指向言語」、内部は Smalltalk だったわけだし)、メッセージをブロードキャストで投げます。ブロードキャストメッセージとは何か?そもそもブロードキャストってどういう動きをするのか?と言えば、

普通のメッセージは、送り手のクラスがあって、受け手のクラスがある。値を送る(参照でもいいけど)という1対1のイメージですね。いわゆる 受け手.method( 値 ) で、受け手のクラスに送るパターンです。

image

これがブロードキャストになると、1対多の関係になって、送り手.method( 値 ) のイメージになります。

image

この図だと、送り手が複数の受け手に対して送るので、1対1の関係を増やしたような感じになりますが、実際のところはメッセージをブロードキャストで送るってのは、中間的なクラスがあってブロードキャストの場合はそれぞれに送るというスタイルになります。

送り手からは1回のメッセージを送っただけで、複数の受け手にデータが流れるという感じですね。

image

これ、ちょうど UDP の配信と同じ仕組みで、双方向のコネクションをとらない UDP 通信ではブロードキャストが可能になります。TCP とは異なり一方的にデータを流します。

同じことは、映像配信にも言えて、いわゆる昔のテレビの電波だとか、地デジに配信も似た感じになります。ブロードキャストは一方向にしか流せないけど、非常に多い受け手に対して同時配信をするときの良い仕組みです。

物理的にブロードキャストを実現するならば、電気信号を分配してそのまま増幅させればよいし、光通信も光を分割して後から増幅すればいくらでも同じデータを増やせます。まあ、完全に同じではないことは量子的な解析になるわけですが、普通の範囲では分割してデータを流すことが可能です。

Scratch のブロードキャスト

Scratch には、メッセージを送るためのブロックがあって、

  • 受け手が、メッセージを受け取ったときのイベント処理
  • 送り手が、メッセージを送り、処理を待たない
  • 送り手が、メッセージを送り、処理を待つ

image

という3つのブロックがあります。「送って待つ」ブロックは、いわゆる処理を受け取るパターンになるのですが、実はこのメッセージは相手が複数あってもよい(ブロードキャストだから)、「送って待つ」というのは、ブロードキャストを送ったすべての相手の処理を待つという、all wait のパターンになります。なかなか複雑で、おもしろいですよね。

このメッセージングが複数持てるということは、メッセージ先の「受け手」はスレッドで動いているのでは?という想像ができます。おそらくScratch はラウンドロビン形式で動いているはずなので、メッセージの先(各スクリプト)が OS レベルでのスレッドで動いているとは思えませんが、少なくとも「スレッドもどき」で同時実行できるということになります。

マルチスレッドなので無限ループでブロッキングしない

猫弾幕3 https://scratch.mit.edu/projects/249352885/ のネズミのスクリプトを見るとわかるのですが、「旗をクリックされたとき」の処理が3つあります。これもそれぞれ同時実行しています。

image

image

左上のブロックで「ずっと」を使っていて無限ループになっているのは「怖い」感じがするのは C言語を想定するからで(実際、怖い感じがしますw)、Scratch の場合はこのような無限ループにしても適度に OS に処理を戻してくれるので問題ありません。ループはだいたい 20 msec 位で動いています。

猫弾幕3では、2つの変数(残りの数、秒数)同時に別々のループでチェックしています。ふつうにプログラミングをするならば、ひとつのループの中で2つの変数を2つの if 文を使ってチェックするところですが、Scratch の場合はこんな風にループ自体を分けてしまうことができます。2つのループが同時に実行されるために、2つの変数が同時にチェックされる、という仕組みですね。意外とこの仕組みは重宝します。

親指の数をどう勘定するか

さて、いっせーのせに戻ると、この上がっている親指の数をどうやって数えようか?と悩みます。

image

ひとつの方法としては、8つの右手と左手についてサムアップしているかどうかをひとつずつチェックします。

image

幸いにして、右手と左手はそれぞれ別のスプライトとなっているので、別々に勘定ができます。

image

まあ、これでもいいんですけどね。リストに入れて効率化してもいいですけど、さっきのブロードキャストメッセージを活用してみましょう。

「いっせーのせ」メッセージを送って待つことにします。ブロードキャストメッセージで送るので、メッセージが送る先の数は「送り手」にはわかりません。どこに送るかもわかりません。どれだけ多くの相手がいるかわからないけど、すべて相手が応答を返すまで待つのは確かなことです。

image

さて、受け取った右手や左手のスプライトは、「いっせーのせ」メッセージを受け取ったら、サムアップをしている(コスチューム番号が1になっている)場合は、合計を1だけ足して返します。これは、どの右手、左手のスプライトも同じです。

image

さて、「いっせーのせ」メッセージを送った送り手は、最終的に何を受け取るでしょうか?そう、サムアップしているが「合計」に入っているというわけです。ちょうど、ブロードキャストにメッセージを配信している形と同じになりますね。

image

この右手と左手のスプライトは、どの順番で実行されるかわかりません(実際は、スプライトの番号順になるだろうけど)。順番は問わないし、受け手となるスプライトの数も関係ありません。

例えば、人数を増やしたいと思ったとき先の「親指の数を数える」の定義では、if 文を追加していかないといけませんが、ブロードキャストメッセージを利用したパターンでは追加したスクリプトに「いっせーのせ」メッセージを受け取ったときの処理を追加しておくだけです。このあたりはオブジェクト指向のインターフェースという形になりますが、そのあたりも含めて Scratch は非常にオブジェクト指向言語として綺麗に動きます。

サンプル

UDPのブロードキャストはどうするのか?

参考までに、UDP通信のブロードキャストの例を晒しておきます。C#だとこんな感じ。ネットワーク内(ネットワークマスク内)にあるPCに一斉通信をすることができます。Wi-Fiは通らないので有線LANのみ有効な技ですが重宝します。

 public async Task<bool> Connect()
        {
            // ブロードキャスト送信
            var client = new UdpClient();
            client.EnableBroadcast = true;
            int n = await client.SendAsync(
                CMD_REQUEST_RESPONSE, CMD_REQUEST_RESPONSE.Length,
                new IPEndPoint(IPAddress.Parse(BROADCAST_ADDR), BROADCAST_PORT));
            var recv = await client.ReceiveAsync();
            _ep = recv.RemoteEndPoint;
            client.Dispose();

            return true;
        }
カテゴリー: Scratch | いっせーのせで学ぶ Scratch のブロードキャストメッセージ はコメントを受け付けていません

WPFで Web Speech API を使ってみよう!

クレウスさんの、

なところから、Web Speech API がブラウザ上で使えることが分かったので試してみるの巻です。

Web Speech APIの実装 – Speech Synthesis API | CodeGrid https://app.codegrid.net/entry/2016-web-speech-api-1

ブラウザ上で Web Speech API を使って文章の読み上げができる、って話は聞いてことはあったのですが、これ OS の機能をブラウザから呼び出している訳ではなくて、ブラウザの内部機能として実装されている、という話だったのですね。なので、Google Chrome で読み上げると Google の音声で喋るし、Edge で動かすと Microsoft の音声出力になります。おそらく Safari とかも違う音声になっているはず。

Javascript は簡単

読み上げするだけなら非常に簡単で、

var text = “hello world.”;
speechSynthesis.speak(new SpeechSynthesisUtterance(text));

と Javascript で書くだけです。text の部分は、文章を選択した場所でもよいし、何かを喋らせたい文章を書くもよし。声質も変えられるので、自前であれこれできます。

じゃあ、.NET から使ってみよう

ブラウザ上で音声を出せることは分かったけど、では、.NET からどう扱えばいいのか?ってことを考えると悩みどころなのですが、まあ、定番の WebBrowser か WebView を使えばなんとかなるでしょう?と考えました。

が、試してみると、意外と難関があることが判明。

  • WinForms や WPF で使われている WebBrowser は内部で IE を使っているので、Web Speech API の対象にならない。

なので、確か WPF などで Edge エンジンを使えるようになったような気がしたので、調べなおしてみると、

WPFやWindowsフォームでEdgeのWebViewを使うには?[Windows 10 1803以降]:.NET TIPS – @IT
http://www.atmarkit.co.jp/ait/articles/1807/04/news017.html

に、ありますね。

どうやら、NuGet で「Windows Community Toolkit v3.0」を落としてきて、その中にある WebView を使えばよいそうです。Microsoft.Toolkit.Win32.Controls を NuGet でダウンロードします。ちなみに、このコントロールは .NET Framework 4.6.2 以上なので、別途 .NET Framework をダウンロードする必要があります。開発者向けのをダウンロードしないといけないので、https://docs.microsoft.com/ja-jp/dotnet/framework/install/guide-for-developers から新しいものを入れてください。

image

ツールボックスに「WebView」コントロールが増えるので、これをウィンドウに貼り付けます。

image

読み上げるための TextBox と Button も貼り付けておきます。

image

グレーの WebView は、呼び出し用にあるだけなので見えなくても大丈夫なはず。大抵の例は、ブラウザ上で Web Speech API を動かすわけですが、ここでは WPF に貼り付けてある TextBox を読み上げるようにします。

 

InvokeScript で Javascript を実行する

ブラウザ内にある Javascript を実行するのに、WebView には InvokeScript というメソッドがあります。WebBrowser のときには、WebBrowser.Document.InvokeScript だったのですが、WebView では Document がなくなっていて、直接 InvokeScript メソッドが追加されていますね。Document がなくなったのでブラウザの DOM を直接見ることはできなくなったのですが、まあ、InvokeScript があればトリッキーなことをして DOM を探ることもできるので問題はありません。

以下、は動作コードですが、いつか試行錯誤の痕跡を残しておきます。

public partial class MainWindow : Window
 {
     public MainWindow()
     {
         InitializeComponent();
         this.Loaded += MainWindow_Loaded;
     }
     private void MainWindow_Loaded(object sender, RoutedEventArgs e)
     {
         // web.IsJavaScriptEnabled = true;
         // web.Navigate("http://moonmile.net/speech.html");
         // 非推奨だがローカルファイルから読み込む
        web.NavigateToLocal("speech.html");
     }

    private void clickGo(object sender, RoutedEventArgs e)
     {
         var text = @"
<body>
<script>
function hello(text){
  speechSynthesis.speak(new SpeechSynthesisUtterance(text));
}
</script>
</body>
 ";
         // 直接文字列を入れるとダメ
        // web.NavigateToString(text);
         this.web.InvokeScript("hello", new string[] { text1.Text } );
     }
 }

NavigateToString メソッドを使って、直接 HTML を入れることはできるのですが、なぜか InvokeScript メソッドを呼び出したときにアプリケーションごと落ちてしまいます。仕方がないので、Navigate メソッドで外部サイトから読み込むか、NavigateToLocal メソッドでローカルファイル(exeと同じフォルダ)から読み込みます。NavigateToLocal は非推奨ってことになっていますが、まあ、そのまま使えます。InvokeScript メソッドの呼び出しで落ちるのは、何かの初期化が足りていないんでしょう。

InvokeScript メソッドは、HTML 内にある Javascript の関数を直接呼び出せます。パラメータも渡すことができるので、これを TextBox から取り込みます。

ローカルファイルにある speech.html の内容は、以下のように hello 関数にひとつの引数を入れたものだけです。

<body>
<script>
function hello(text){
  speechSynthesis.speak(new SpeechSynthesisUtterance(text));
}
</script>
</body>

後は、ボタンを押して InvokeScript を呼び出せばふつうに Edge で喋ってくれます。

これは Unity で使えるのか?

さて、肝心のこの仕組みは Unity で使えるんでしょうか?って話なんですが、たぶん、ダメだと思うんですよね。UWP だと使えるんでしたっけ?

と思って、UWP で使ってみると…あっさりいけますね。UWP のほうはもともと内部的に Edge が使われているので大丈夫そうです。NavigateToString メソッドも普通に使えます。InvokeScript はダメで、InvokeScriptAsync だとうまく動きます。

public sealed partial class MainPage : Page
 {
     public MainPage()
     {
         this.InitializeComponent();
         this.Loaded += MainPage_Loaded;
     }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
     {
         // this.web.Navigate(new Uri( "http://moonmile.net/speech.html"));
         var text = @"
<body>
<script>
function hello(text){
  speechSynthesis.speak(new SpeechSynthesisUtterance(text));
}
</script>
</body>
 ";
         this.web.NavigateToString(text);
     }

    private async void clickGo(object sender, RoutedEventArgs e)
     {
         await web.InvokeScriptAsync("hello", new string[] { text1.Text });
     }
 }

ってことは、Unity でもいけるのかも。

~~~
追記 2018/10/01

Unity はやってないのでわからないのですが、Xamarin.Forms と Xamarin.Android の WebView で試してみました。結果は「ダメ」です。Android 上の Chrome では動くのですが、WebView の内部で使っている Chrome(Chroniumらしい)が対応していないらしく、AspeechSynthesis を認識できません。ちなみに音声を出すだけならば、TextToSpeech があるので、それを使えば ok. iOS の WebView の場合は AspeechSynthesis が使えるようです。

カテゴリー: C# | WPFで Web Speech API を使ってみよう! はコメントを受け付けていません

Firebaseを使い、Scratchで相互通信する

Google の Firebase には Realtime Database というものがあって、複数のアプリケーション(デスクトップPC、スマホ、M5Stack などなど)を使って同期ができます。って記事が、あちこちにあるので、ならば、Scratch でもできるのでは?と思って作ってみたのがこれ。

image

1画面にはなっていますが、デスクトップPCからノートPCにリモートデスクトップ表示しているところです。別のPCでスクラッチを起動しておいて(ひとつのPCでは複数起動できないので)、片方のオレンジ猫を動かすと、もうひとつのオレンジ猫が動きます。

直接通信させることもできるのですが、Google の Firebase を経由させます。

image

Scratch なところは、デスクトップアプリ(WPFとか)でもよいし、スマホアプリを Xamarin で作ることもできます。便利かどうか別として、まあ、こんなことができるということで。

Firebase の基本的なところは、

C#でFirebaseを使ってみよう!(1) FirebaseとEmail-Password認証 – こっちみないで(´・ω・`) http://kmycode.hatenablog.jp/entry/2017/02/09/205655

Firebase Realtime Database のデータ保存、取得、ストリーミング受信実験( ESP32 , M5Stack ) | mgo-tec電子工作
https://www.mgo-tec.com/blog-entry-firebase-realtime-database-sever-sent-events-esp32-m5stack.html

なところを参考にしています。Firebase は API KEY を取得してアクセスするのですが、そのままだと誰でもアクセスできてしまうので、一応ユーザー名(メールアドレス)とパスワードでガードを掛けます。

C# や F# から Firebase を扱うときは、NuGet で次の2つを追加します。

  • FirebaseAuthentication.net
  • FirebaseDatabase.net

内部で Rx が使われているらしく、System.Reactive や System.Reactive.Linq などが同時にインストールされます。

先の記事では、C# でサンプルが書かれているのですが、FireScratch の場合は都合上 F# で書いています。まあ、以前作った NetScrattino が F# だったので、それを踏襲したかっただけなんですけどね。

Firebase 自体は NoSql なので、JSON 形式でごっそりとデータを置きます。

image

こんな風に、/scratch/firecat というパス(フォルダーのようなものか)の下に、データが置かれます。謎な文字は識別子みたいなものですね。プロパティとして、From, To, Text, X, Y を置くためには、下記のようなクラスを作っておきます。

type Data() =
	let mutable _from : string = ""
	let mutable _to : string = ""
	let mutable _x : int = 0
	let mutable _y : int = 0
	let mutable _text = ""

	member x.From with get() = _from and set(v) = _from &<- v
	member x.To with get() = _to and set(v) = _to <- v
	member x.X with get() = _x and set(v) = _x <- v
	member x.Y with get() = _y and set(v) = _y <- v
	member x.Text with get() = _text and set(v) = _text <- v

C# だとこんな感じ

public class Data
{
	public string Text { get; set; }
	public string From { get; set; }
	public string To { get; set; }
	public int X { get; set; }
	public int Y { get; set; }
}

このデータクラスを、Firebase に対してアップロードします。F# で作る場合は、こんな風に、各種の関数を作っておくと便利です。詳しい中身は先の記事の C# コードを読んだほうがよいでしょう。

// ログイン
let singIn() =
     let auth = new FirebaseAuthProvider( new FirebaseConfig( apikey ))
     authLink <- auth.SignInWithEmailAndPasswordAsync( email, passwd ).Result
     printfn "サインインに成功しました"

// クエリを取得
let GetDatabaseQuery( path ) =
     let opt = new FirebaseOptions()
     opt.AuthTokenAsyncFactory <- fun () -> Task.FromResult( authLink.FirebaseToken )
     let client = new FirebaseClient( databaseURL, opt )
     client.Child( path )

// データをアップロード
let upload( data : Data ) =
     let query = GetDatabaseQuery( DatabasePath )
     query.PostAsync( data ) |> ignore
     ()
 // テキストを保存
let uploadText( text: string ) = upload( new Data( Text = text ))


 // テキストを取得
let downloadText() =
     let query = GetDatabaseQuery( DatabasePath )
     let results = query.OnceAsync<Data>().Result
     let items = results.Select( fun o -> o.Object )
     items.First().Text

// リアルタイムデータの監視
let startWatchingRealtime() =
     realtimeDatabaseWatcher <- 
         GetDatabaseQuery(DatabasePath)
             .AsObservable<Data>()
             .Subscribe( fun ev -> 
                 if ev <> null then
                     let text = ev.Object.Text
                     match ev.EventType with
                         | FirebaseEventType.InsertOrUpdate -> fireData <- ev.Object | FirebaseEventType.Delete -> ()
                         | _ -> ()
             )
     ()

これを、Scratch から呼び出せるように HTTP サーバーを作っておきます。スクラッチからは、/say/me/you/hello のようなスラッシュで区切られてデータが送られてくるので、これをパースして、Firebase に保存します。

もうひとつの PC では、リアルタイム監視(startWatchingRealtimeで登録)をしているので、これを fireData に保存しておいて、スクラッチのポーリング(/poll)に送られるようにします。

// Scratchから受信するためのHTTPサーバー
let Server( port ) =

    // firebase にログイン
     singIn()
     startWatchingRealtime()

    let listener = new System.Net.HttpListener()
     listener.Prefixes.Add("http://127.0.0.1:"+(port |> string)+"/" )
     listener.Start()
     while true do
         let context = listener.GetContext()
         let res = context.Response
         let mutable data = ""
         let path = context.Request.Url.PathAndQuery
         match path with 
             | "/poll" -> 
                 data <- data + String.Format("text {0}\n", fireData.Text )
                 data <- data + String.Format("from {0}\n", fireData.From )
                 data <- data + String.Format("to {0}\n", fireData.To )
                 data <- data + String.Format("x {0}\n", fireData.X )
                 data <- data + String.Format("y {0}\n", fireData.Y ) // printfn "%s" path // printfn "%s" debug | "/reset_all" ->
                 printfn "/reset_all"
                 data <- "ok" | _ ->
                 let pa = path.Split([|'/'|])
                 match pa.[1] with   
                 | "say" ->
                     let me = pa.[2]
                     let you = pa.[3]
                     let text = pa.[4]
                     printfn "say %s %s %s" me you text
                     upload( Data( From = me, To = you, Text = text ))
                 | "sayall" ->
                     let text = pa.[2]
                     printfn "sayall %s" text
                     uploadText( text )
                 | "movex" ->
                     let me = pa.[2]
                     let x = pa.[3] |> int
                     printfn "movex %s %d" me x
                     upload( Data( From = me, X = x ))
                 | "movey" ->
                     let me = pa.[2]
                     let y = pa.[3] |> int
                     printfn "movey %s %d" me y
                     upload( Data( From = me, Y = y ))
                 | "movexy" ->
                     let me = pa.[2]
                     let x = pa.[3] |> int
                     let y = pa.[4] |> int
                     printfn "movexy %s %d %d" me x y 
                     upload( Data( From = me, X = x, Y = y ))
                 | _ ->
                     data <- ""
                 printfn "%s" path
         res.StatusCode <- 200
         let sw = new System.IO.StreamWriter( res.OutputStream )
         sw.Write( data )
         sw.Close()
     ()

スクラッチから送られてくるコマンド(say, sayall, movex など)は自分で定義をします。スクラッチのメニューでシフトキーを押しながら「ファイル」を選択すると「実験的なHTTP拡張の読み込み」が出てくるので、ここで作成した firescratch.json を読み込ませます。

image

{
   "extensionName": "Firebase Scratch",
   "extensionPort": 5411,
   "url": "https://github.com/moonmile/firescratch",
   "blockSpecs": [
     [ " ", "%s と言う", "sayall", "hello world." ],
     [ " ", "%s が %s さんへ %s と言う", "say", "me", "you", "hello" ],
     [ " ", "%s を X座標 %d にする", "movex", "me", 0 ],
     [ " ", "%s を Y座標 %d にする", "movey", "me", 0 ],
     [ " ", "%s を X座標 %d、 Y座標 %d にする", "movexy", "me", 0, 0 ],

    [ "-" ],
     [ "r", "自分", "from" ],
     [ "r", "相手", "to" ],
     [ "r", "X座標", "x" ],
     [ "r", "Y座標", "y" ],
     [ "r", "メッセージ", "text" ],
     [ "-" ]
   ],
   "menus": {
     "OnOffValues": ["ON", "OFF"]
   }
 }

サーバーを立ち上げて、コマンド待ち状態になると「その他」のところがグリーンになります。

image

これを2つのPCで起動させて、スクラッチ同士で通信させたのが、https://twitter.com/moonmile/status/1044440471823478784 にある動画になります。

相互通信にしたいところだけど、ひとまず一方向だけのスクリプトを

送信元のスクリプト

送信先のスクリプト

サンプルコード

https://github.com/moonmile/FireScratch

カテゴリー: Scratch | Firebaseを使い、Scratchで相互通信する はコメントを受け付けていません

夏休みの宿題の読書感想文を星新一ショートショートで書いてみるテスト

中学生もすなる読書感想文というものを星新一ショートショートで記してみるなり、ということで、奥さんに「書けるわけない」言われたので原稿用紙5枚(2000字)ぐらい書いてみるテスト。この位だったら30分位でさっと書けないとアカンよ。

絵本 星新一ショートショート | 星 新一
https://www.amazon.co.jp//dp/4048544519

~~~

星新一といえばショートショートSF作家として有名だが、ショートショート以外のものでは「人民は弱し 官吏は強し」という自伝っぽい本がある。星新一の父親が経営していた星製薬の話なのだが、色々官僚に虐められたという話だ。小学校の頃にSF文庫を読み、中学になってからはアシモフやらディックやら翻訳モノを読んでいた自分にとって、筒井康隆と星新一はちょっと特殊な日本のSF作家という存在で、真面目な印象を受ける星新一とおちゃらけた筒井康隆の文体は対象を為していた訳だが、実像のほうは星新一ほうが波乱な人で筒井康隆のほうが常識人というのが面白いところでもある。作家が内面にあるものを「小説」として表層化するときに、どのようにねじれていくのか(中二病的な言い方をすれば、「コンプレックス」なんだけど)の体現者二人という感じで見ていた。そんな中で、ショートショートという軽めであり、一見思想的なものを含まない星新一のもうひとつの顔として「人民は~」をよみ、再び星新一のショートショートに戻ると、ちょっと違った皮肉が文章の中に込められていることが分かる。同時代的には小松左京、横田順弥、半村良がいるのだけど(ええと、「幻魔大戦」の平井和正はちょっと特殊だし、「グインサーガ」の栗本薫も特殊ではあるので)、あまり作家像がみえないところに星新一のショートショートがある。そういう作家性のないところは、日経の星新一賞にAIをぶつけてみようというアイデアにも表れている。文体というものが作家性の大切な要素ではあるものの、ショートショートという中ではアイデア重視とそぎ落とされた文体の中で、要素だけが残された面白さに焦点が合わされているところにある。加えて言えば、星新一のショートショートの挿絵が一貫して和田誠だったところに奇妙な一致を見ることができる。短い文章は短歌や俳句のようなものではあるけれど、それよりも長く、しかし長編よりは短く、作家性を思わせるところが少ない判明、まさしく「星新一の描く」ショートショートである、と匂わせるような断然とした雰囲気が其処にはある。だから、実は、絵本になったショートショートは奇異ではありつつ、一見して半身を失った星新一ショートショートのような気もしないでもないのだが、いや、それはどうなのだろうか。まだ見知らぬ小説、まだ見たことのない挿絵に対して初めて面するとき、昔の星新一&和田誠ペアのショートショートを知らないのであれば、絵本となったショートショートは、実は本来の星新一のショートショートを真面目に眺める機会なのかもしれない。
実はクレイアニメのような図柄、そして短い物語の組み合わせは、数々の教育テレビ(Eテレ)の10分アニメを思わせる。ニョッキだとかポルタだとかそういうショートアニメにはちょっとしたストーリーが含まれていてちょっとした感動(子供向きだから?)が含められている。実は、これらのショートアニメは10年前以上に作れたものが多く、今のEテレのものを見ると解るけど、サイズが4対3になっている。新作が作られてないのか、それても旧作を発信することでコストを抑えているのかどうかは分からないが、これも初見であればそれが旧作であろうと新作であろうとあまり関係ない。始めてみる子供(大人でも)からすれば、それは興味を引く面白いお話である。それと同じく、絵本として再構成された(文章も再構成されているような気がする)星新一のショートショートは、大人向けのちょぴりとした皮肉(政治的な皮肉とかブラックジョーク)がある。禁じ手がいくつかあって、性行為と殺人と時事風俗は扱わなかったはずだが、「おせっかいな神々」には禁じ手を破っているらしい。ちょっと覚えていないけど。とりあえず、その手の良く分からないブラックジョークは絵本のほうでは省かれている。子供向けだし、内情が分からないとおもしろくないジョークを書き連ねてたって子供には面白くない。いや、大人でも面白くないのである。
だから、いろいろなバックグラウンドを知らなくても面白いSFショートショートが成立するというのがはなかなか珍しいことでもあり、うまいぐらいに3本用意したなとうならせるところがある。そう、ネタバレをすれば毛の生えたタコの話は、前知識がなくても奇妙で面白いし、ちょっぴり怖い感じがする。それは心理学的に怖いのか、ヒトが進化した中で必ず奇妙なものとして見えるのか、そこまでは突き詰めないけど、そういう作風が絵本の中からも出て来るのが星新一ショートショートの普遍性というものだろう。

~~~

以上、これで30分ちょっと。40字50行で2,000文字です。

カテゴリー: 書籍 | 夏休みの宿題の読書感想文を星新一ショートショートで書いてみるテスト はコメントを受け付けていません

Surface RT を引っ張り出して性能を確認してみる

Surface Go が流行りそうですが、手元にある Surface RT を引っ張り出して電源を入れてみる。

Surface RT を購入して初日の所感を | Moonmile Solutions Blog にある通り、2013年3月に購入。直前に初代 iPad を購入しているので、散財といえば散財なのですが、いわゆる「Windows ストアアプリを自前で入れられる」ってのがキーポイントです。今でこそ、Xamarin が使えるようになって iPhone/iPad アプリが簡単に作れるようになっていますが、当時は Objective-C で作らないといけないので、「私にとっては」結構な苦痛だったんですよね。まあ、その分、iPad アプリの商機というものがあった訳ですが…iPad 専用の絵本とかが流行った頃の話です。

中身は ARM なので、通常の Intel x86系の実行ファイルは動きません。しかし、arm でコンパイル&ビルドして実行ファイルを入れれば動作する…ハズなのですが、当時 Surface RT は「安全」のために arm の実行ファイルを直接入れて実行させることを嫌ったのです。脱獄すれば実行はできるものの、通常の状態で arm のバイナリが動かないのは、かなりマイナスでしたね。実際マイナスなので、Surface RT は Microsoft イベントにとっては暗黒扱いになっているようです。

先の記事にも書いてある通り、業務用に使うのであれば Intel CPU が積んである Surface Pro を買ったほうがいいんですよ。Surface RT は Office が付いているとはいえ完全に廉価版扱いで、iPad の値段よりも安かった。おそらく原価割れではないかと思うのですが、定かではありません。

Windows Update が走る?

確か、最後の Windows Update(Windows 8.1のアップデート)をして、電源を落としたはずなのですが、何故か更新プログラムを延々と構成し始めます。

30%を構成しましたの後、リセットがかかって、再び30%構成したあとにリセットが掛かる、という無限ループに陥ってしまったのか?という状態なのですが…なんとか、6時間後位に起動しました。一時は工場出荷にリセットなのか?とも思って回復 USB を用意したりしたのですが、まあなんとか。

Excel 2013 が動くよ

Surface Go でも話題になっていますが、Surface RT は Office 2013 がバンドルされています。これ、MS 社員も「Office がバンドルされているから安い」と言っていた覚えがあるのですが…まあ、タブレットで Office は使わないですよね。メールとかで貰ったときに便利なのかもしれませんが。

当時は、Office 365 は無かったし、Google のスプレッドシートが出たばっかりで動作も鈍かったので、arm のデスクトップ上に Office を載せたのはそれなりに意味があったのですが。これ、Excel VBA が使えなくてですね、キーボードがないと使えないし、やっぱり閲覧オンリーでしかないんですよ。

VLC で動画が見れるよ

動画(mp4)を見るのに、VLC を使うわけですが、当時はストアアプリ版というのがなくてですね。標準装備の「ビデオ」しか使えませんでした。標準のビデオのほうは、コーディックが少ないののと、ストリーミングに対応していないので、いまいちだったんですよね。

今はストアアプリ版(Windows 8.1にもあった)の VLC があるので、ストリーミングを含めて NAS 経由で動画を表示できます。ただし、Surface RT の頃の Wi-Fi が 2.4GHz のほうにしか対応していなくて、帯域が足りなくて少しブロックノイズが発生します。実写のほうはそうでもないのですが、アニメ絵は mp4 の圧縮に不利なのでブロックノイズが走りがちです。

自前の Windows 8.1 アプリを入れる

大抵の人は、Windows 8 から Windows 10 にバージョンアップしてしまったでしょうが、Surface RT は Windows 10 のラインナップから外されてしまって 8.1 までしか動きません。ちなみに、

うちの家PCは、奥さんの希望により 8.1 で止まっています。まあ、普通に使っている分には 8.1 も 10 も変わらないんですよ。むしろ、10 にアップデートするときに中にあるソフトウェアが動かなくなる&個人データが一部消される、というリスクがあって 8.1 のままです(8 から 8.1 のとき結構消されたのよ)。

Windows 10 の UWP アプリ(ストアアプリ)は、別途ウィンドウを開けるようになったので、あまり覚えている人はいないかもしれませんが、8.1 の頃はこんな風に全画面オンリーでした。でもって、分割表示するため真ん中にバーがでるんですよ。

これ、フラットデザインとして UI デザインとしてどうなの?って気もしないでもないのですが、改めて使ってみると「タブレットならば、この全画面が使いやすい」ですね。デスクトップ PC の場合、全画面を占領される(正確にはモニタ1枚)のは、ちょっと…な気もしますが、Surface RT のように比較的狭い画面ではせいぜい左右に2分割するしか余裕はありません。

こんな風に、右画面で動画を流しながら、左画面で Redmine の障害報告を読んだりできます。当時、ツイッターを流し見しながら仕事をしていた人も多いはずです(今でもそうだけど)。当時、iPad はシングルタスクで画面を表示していたので、この Surface RT の並列性は結構な優位点だったハズなのですが、活かされなかったですね。

因みに、Windows 8.1 のストアアプリは、Visual Studio 2015 でビルドができます。これを arm 版でビルドをして Surface RT で動かすわけですが、リモートデバッグツールを Surface RT に入れないといけないんですよ。なのに、最新である Visual Studio 2015  Update 3 のリモートデバッグツールは、x64とx86しかなくて arm 版がありません。たぶん、入れ忘れだと思うんですけどね。仕方がないので、無印の Visual Studio 2015 環境を使ってリモートで Surface RT にアプリを送り込んでいます。

Scratch はちょっと重たい

Surface RT 当時、Scratch がどの程度だったのかは覚えていないのですが、今 Scratch を動かしてみると結構重たい感じです。arm & デスクトップ側のアプリ導入禁止により、ブラウザでのみ Scratch が動きます。ストアアプリ版の IE(Edgeとは違う)の Javascript が不足するのでは?と思ったのですが、そういえば普通に Flash が使われているので、元気に動作しています。

ただし、キーが打てないのと、ブロックの動かし方がタップでは微妙なので、Scratch プログラミングを Surface RT 上でできるか?というと難しいですね。普通に、無線マウスと無線キーボードを付けたほうが利用しやすいでしょう。

当時、iPad から Flash が排除される、Android のブラウザでは艦これが動かない、ということで唯一?艦これが動くタブレット端末だったハズですが、どうだったかな。Surface RT で「艦これ」始めた – だるろぐ を見る限り、遅くて駄目だったらしい。

野球ゲームでは重たい Scratch ですが、マリオフラッピーではするすると動きます。なので、プログラムによるのでしょう。

5年前の機種なのに、これだけ元気に動くのは結構優秀な機種ですよね。初代 iPad は液晶が駄目になり、2台目を買い、その2台目もバッテリーが切れて、Apple で3台目に変えて貰っています(1万円で)。

ノートPC も Windows 98 やら Windows XP が元気に10年以上も動いていたりするので、結構 Windows 機種は長持ちするほうなんですよ。まあ、Linux 機の場合は、30年前以上から使っている vi や emacs が今でも動くので、ソフトウェア互換は抜群です。そういう意味では、Slackware から Linux を使っている世代としては、Ubuntu も大差なく使えます(ターミナルレベルではw)。じゃあ、mac はどうなのかというと、以前からある apple script を地道に継承していたりして、そういう姿勢は各種独特です。

そういうところを踏まえて、Surface Go がどの層を狙っているのかあるいは狙っていないのか、が興味深いところですね :)

カテゴリー: 雑談 | Surface RT を引っ張り出して性能を確認してみる はコメントを受け付けていません

サブ開発環境を Ubuntu 18.04 で準備する

手元で使っている業務PC は、2013年に自作(他作でもあるけど)したもので、その記録が 最強.NET開発PCを作るよ(その1) | Moonmile Solutions Blog にある。かれこれ、5年になるけど、メモリ 64GB を積んだ .NET 開発マシンというのは伊達ではなくて、今でも十分可動している。途中で、2回ほど SSD が逝ったのは熱が籠ってしまったのか、Windows 10 にしてハードに使い過ぎたのかは分からないが、SSD を交換して(つまりは OS を再インストールして)現役状態である。

現時点では、主な稼働状況としては、

  • Windows 10 Pro
  • Visual Studio 2017 が3,4枚稼働
  • Word/Excel が3,4枚稼働
  • VMWare が 2つほど常時稼働
  • Amazon Video か VLC が常に動いている

状態で、なんというか、夏は熱暴走が気になるところで常にCPUは50度位。CPU 稼働はこんな感じで、面白いのは OS が乗っている C ドライブはほとんど稼働していない状態(おそらくキャッシュに乗っているのだと思う)という感じです。

image

Windows Update による再起動が困る

確か、Windows 8 の頃にはあまりなかったのですが、Windows 10 では PC がスリープした状態でも夜中に勝手に起動して勝手に Windows Update をして、勝手にシャットダウンしていうことが多々あります。たまに、朝まで電源が付いているときもあるのですが、最近は月一は PC 落ちている状態が多いですよね。

これ何が困るって、作業を途中にしてスリープしているのに、PC を再起動するものだから途中のアプリが勝手に落とされるんですよ。Excel や Word が途中で落ちて、自動修復状態になってしまったり、Visual Studio で大き目のものを開いているのにまた開き直さないといけない訳です。最近では、更に妙なことになって、再起動時に Visual Studio が 10個位勝手に起動したりします(たぶん、以前に画面を復活させようとして、デバッグ中に死んだ Visual Studio も立ち上げてようとしているのが原因)。

一番困るのは、VMWare へのシャットダウンが十分ではなくて、VMWare で仮想環境を立ち上げたままスリープをすると、Windows Update の再起動のおかげで、VMWare が強制終了されてしまうんですよ。これで、何回か VMWare 上の Linux マシンや Windows が修復起動になったりしてます。まあ、まめに仮想環境自体もスリープさせればよいのですが、そのあたりも手間だし忘れるし。

そんな訳で、仮想環境の VMWare 分を何処かに引っ越せないか?と考えていました。

じゃあ、Ubuntu + VMWare の組み合わせを考えよう

正攻法ならば、Windows サーバー機を用意するのがいいんですが、自宅が仕事場所でもあるし、サーバー機のファンがうるさいのも困るところなので、通常の静音型 PC を使いたい。

どうせなので、ベースは Ubuntu にして ROS とか React-Native あたりも試してたい。Android のビルドを VMWare 上でやると遅くて大変なので、実機 PC でやりたい。ということで、Ubuntu を入れる前提で PC の追加購入を考えました。

image

スペックとしては、

  • メモリ 32GB
  • SSD 512GB + HDD 1TB
  • CPU Intel i7-7700
  • グラボは無し
  • OS無し、Office無し
  • 静音ファンで少しだけプラス

ドスパラの Magnate GE(マグネイト GE)ミニタワーパソコン(PC) 7768|パソコン通販のドスパラ【公式】 をベースにして税込みで13万円也です。

ゲームや映像に使う訳ではないので、グラフィックボードはオンボードのみを使う。メモリは 64GB にしたいところだけど、結構な値段がプラスになってしまうので 32GB にしておく。これは、常時 VMWare を動かす予定なので、16GB だとちょっと足りない(仮想で、4GB x3 位動くので、ホスト OS が圧迫されてしまう)。

Ubuntu + VMware の時は UEFI を切る

Ubuntu 18.04 LTS の DVD を使ってインストールした訳ですが、結構すんなり入ります。ブラウザを使ったり、メールや Slack などを使うだけならば Windows じゃなくてもいい感じですね。Mac の場合、どうしてもスペックが制限されてしまうので、メモリを摘んだりして標準以上にしようとすると Windows PC の選択にならざえるを得ないのですが、初心者であっても Linux 機を使える感じにはなっているようです。

ただし、ハマりどころもあります。

image

Windows で VMWare や VirtualBox で仮想環境を作るときはすんなりといくのですが、Ubuntu でハマりました。何故か、VMWare Player をインストールしたあとに、起動しようとすると、/dev/vmmon が無いと云って起動できません。何度か、Ubuntu 自体をインストールし直して Virtualbox を入れたりしたのですが、こちらも起動できません。

要は、マシンが UEFI が有効になっていて、インストールする OS ( Ubuntu 18.04
LTS ) の署名とのずれがある(そもそも署名がない?)らしいのです。そういえば確かに、2,3年前に「もともと Windows が入っていたノート PC に Ubuntu を入れようとした入れられない問題」ってのがあって、それのことです。VMWare や Virtualbox が入れようとしているドライバーに署名が UEFI BIOS の署名と異なっているので駄目ってことですね…たぶん。

ネットを見るとあれこれ解決方法があるみたいなのですが、手っ取り早いのは BIOS の画面を開いて UTFI を使わないで起動することです。この画面ではデフォルトで「Windows UEFI mode」になっているので、「Other OS」に切り替えてしまいます。UEFI その1 – UEFIとセキュアブートについて・UEFI環境でOSを起動するOSローダー・UEFI対応PCとBIOS対応PC – kledgeb を参照してください。

そうすると、無事 VMWare Player が起動できるようになって、ゲスト OS に Windows 7 を使ったりできます。この画面は、もともと業務 PC のか仮想環境を Ubuntu のほうに引っ越して起動させています。

image

この仮想化された Windows 7 へは、業務 PC(Windows 10)からリモートデスクトップができるので、今までと同じように開発ができます。ネットワークを通す分だけちょっと遅くなるけど、Azure などで仮想環境を作るよりも操作は素早くなります。ファイル転送も楽ですからね。

VNC で接続する

Ubuntu + VMWare は基本モニタを使わずに作業をする予定です。業務 PC からリモートデスクトップで仮想環境にある Windows 7 に繋ぎに行くか、Ubuntu へ VNC で接続するかというところです。

Windows 10 から繋げられるように Screen Sharing の設定をしておきます。

image

クライアントは、VNC Viewer や TightVNC を使います。

React Native の環境を作る

さて、Ubuntu を使うもうひとつの目的である React Native の環境を作ります。React,Angular,Vue.js,React Nativeを使って学ぶ はじめてのフロントエンド開発 の第9章だけ見て分かったような気になっても仕方がないので、手を動かします。

ただ、素の環境から作るのは結構手間がかかるみたいですね。これも落とし穴が結構あります。

  • Java SDK のインストール
  • Android IDEのインストール
  • nodejs のインストール
  • react native のプロジェクトを作る
  • アプリを実機で動かす

基本は Getting Started · React Native にある手順に沿って行きます。nodejs は Installing Node.js via package manager | Node.js にあるらしい。

あれこれやって、エミュレータと実機 Android で動かすところまでできました。

$ react-native init aproj

aproj というプロジェクトを作る。

$ adb devices
$ adb reverse tcp:8081 tcp:8081

実機 Android で動かす場合は、adb reverse で 8081 を設定する。

$ react-native run-android

デバッグ実行する。

という手順です。このあたりは再び仮想環境で試してみる予定。

↓は参照先

ReactNative for Androidで実機をデバッグに使うには | Theoretical Cat https://www.yslibrary.net/2015/09/17/reactnative-for-android-debugging-on-real-device/

画面では、こんな感じでやると、実機 Android で React Native が動作します。

image

react native で実機を振ると menu が出るってことになっているんだけど、うちだと出ないですよね。なので画面の更新ができない(苦笑)。エミュレータのほうは R キーが効くので、実機の振動 API の問題ですかね?

“R” キーを2回送ればいいので、adb shell input  を使えばコマンドラインから更新ができます。

$ adb shell input keyevent KEYCODE_R KEYCODE_R

あとは、ラズパイの Android Things に接続するとか、ファイル共有のための samba の設定とかがあるので、それはまた今度。HDD 1TB を何処かにマウントしないといけないので。

カテゴリー: 雑談 | サブ開発環境を Ubuntu 18.04 で準備する はコメントを受け付けていません

高知風素麺とMicrosoft MVP

なんか、7月1日に続々と「Microsoft MVP に落ちました」報告がツイッターに上がっていて、「?」となって「Microsoft MVP bye」で検索するとあちこちで落ちたツイートが発生していしていました。どうやら、6月末に Microsoft から「落ちたよ」メールが届いていたらしいんですね。ちょうど 7月1日は日曜日だったので、合格したよメールが翌日の7/2に届くようになるので、妙な1日だったという。

ちなみに、私の場合は、

  • Visual Studio and Development Technologies を受賞
  • Windows Development は落選

ってんわけで1勝1敗です。Windows Development のほうは、Windows IoT Core じゃだめなんですかね?ホロレンズじゃないとだめ?…な感じもあるにはあるけど、まあ、Windows IoT Core と Android Things を Orange Pi とか Pine64 とかで使ってみようよ、ってなわけで引き続きこっちはこっちでやっていきます。碧蓝航线とAzureの組み合わせとか。

ところどころ「今回はなにもやっていなかったし、さすがに~」のコメントが散見するんですが、何もやってなかったら、受賞できないのは当たり前じゃん!ちゃんとアピールするような実務を積み重ねていた人が受賞するのが筋でしょ!と思うんですが、どうなんですかね?むしろ、やねうらおさんみたいに辞退するのが筋ってもんじゃないでしょうか?何もやっていない、という自覚があるんだったら。

とはいえ、個人でプログラミングやっている限りで MSDN 一式使えるのはありがたいところなので「ええ、20万円分(プロフェッショナル版の分しか使わないので)は働きますよ」気分でやってます。というか、最初の受賞目的がそれなので、8年経ってもそれなのです。その前は自腹で年間10万円以上払っていたし、今になってもその気分は変わらず。というか、それ位払えない現状が…というのもあるのですが、まあ、今年も 20万円分だけは Microsoft MVP のために働かせていただきます。ちなみに、単価で言えば20万円というと当社比で1週間ちょっと位なので、あしからず。つまりは、それぐらいやればいいんですよ。

ちなみに、Microsoft MVP を前面に出して仕事を取れたことは1回しかありません。これ非IT業界では知名度が低いので仕事には繋がらないかも(「営業」活動していないのは重々承知なんだけど)。けど、就職/転職には有利っぽいので、若手の方はどしどし応募して、ところてん形式に上のほうから押し出していくのがベターですね。今回 MVP の総人数もごっそり減ったことですし Microsoft としても「若返り」を図りたいでしょう。

高知風そうめんが美味い

それはさておき、久し振りに TV でケンミンショーという番組を見て「高知風そうめん」が簡単そうだったので作ってみました。

要は、素麺の上にちらし寿司の具をのせる感じなので、誰でもできそう。

高知風そうめん | お美津さんちの赤いサラダ
https://ameblo.jp/akai-salad/entry-11009761599.html

を参考にして「しいたけの甘辛煮」さえ作れば、大丈夫です。これが味のベースですね。あとは、錦糸卵ときゅうりがあれば3色揃うからこれで十分かと思います。ケンミンショーの番組では、レモンの薄切りにもみじおろしがあったけど、それは無くてもok. ゴマをまぶすのは忘れてしまいました。まあ、ちらし寿司なんだから何でもいい気もするけど。

結構、たくさん食べれるので、揖保乃糸一袋(300g)を全て茹でても4名(一人は小2だ)完食できます。お試しあれ。

カテゴリー: 雑談 | 高知風素麺とMicrosoft MVP はコメントを受け付けていません

プログラマの視点から「プログラム教育」騒ぎを見てみる

2年目のプログラミング教室 | Moonmile Solutions Blog を書いたときに思ったことを少し補足。

「プログラミングを何処で学びましたか?」と問われたとき、ほぼ100%「独学です」と答えるしかない世代(大学にはまだ情報科がなかったし、科目としてはIEEEの実数計算を学ぶ位なものだったから)から見れば、「とあるプログラム言語を学び、将来に備える」という発想で、プログラミング教育をしようとするならばナンセンスだろう。小学生時代に学んだプログラム言語そのものが就職する頃にも有利に働く、訳がない。いや、COBOL とか Fortran とかは長く続いている言語だし、そういう意味では Javascript だって C++ だって、将来的にレガシーな「古典言語」として読むことは必要になるかもしれないが、それは古典でしかなく、現代文ではない。

だから、プログラミング教室を請け負うときに考えたのは、将来的に役に立つあれこれの話ではなくて、

  • 今、情報が取り入れやすいプログラム言語を扱う
  • 今、何か実現しやすいプログラム言語を扱う

という同時代性に重きを置いて、Scratch、Python、C言語(Python はまだ取り込んでいないし、C 言語 + Arduino の組み合わせはまだなんだけど)という柱を考えた。ぼちぼちと始まるであろう学校の「プログラミング教育」は、教育要領としてプログラム言語に負うわけではなく「論理思考」に重きがあるので、実際にキーボードをぽちぽちと打つ時間は1,2時間程度でしかない。むしろ、とあるキーワードを Google を使って検索して何かの調べ物をするとか(既に、小中学生レベルでやっている)、マウスを使ってポチポチと学習ソフトを動かすとか(マウスは、4年生ぐらいだと動かせない子が多い)のほうが大切だったりする。スマホでゲームをダウンロード&遊んだり、任天堂DSで妖怪ウォッチのRPGを進めたりすることは、小学2年生でも軽くできることなのだが、「能動的に」パソコンやスマホを使って「調べる」ことはなかなか難しい。Youtube でマリオの動画を見たいときに「マリオ」で検索するとか、攻略で詰まってしまった Wii の毛糸のカービィを調べるために、スマホで「カービィ」と動画を見ていって、ちょっとずつ解いていくとか、そういう間接的な使い方は難しい。そう、昔小学校の頃に「辞書の引き方」という授業があったのだが(今は、何故か学校の辞書を使ってちょっとしかやらない。自分の辞書を買わない)、とある目的を達成するのには少しだけ回り道をして道具を揃えないといけない&道具を使いこなさないといけない、というのが重要になってくる。そう、RPG でいう道具集めみたいなものだ。

そういう「道具」としての「プログラム言語」の場合は、今昔に置いて古くなったりするものだから直接的に扱っても仕方がない。しかし、何かを実現しようとするときに、道具としてのプログラム言語を扱う(あるいは検索サイトを使う、将来的には音声を通じてAIに尋ねる)ための「組み合わせ」としての論理能力は重要である。いや、そもそもが、プログラム言語というものはロジックの合わせであり、とあることを実現するために引数を与えると、何らかの処理が行われて結果を返すという「関数」的な使い方に終始することになる。

なので、プログラム言語自体の選定にあれこれするのは無意味である。無意味ではあるもし、特殊過ぎる性能(とある手段をクリアするために作られた道具)を扱うためにプログラム言語を選定しようとするのも間違いである。直前(2年後に就職とか)ならば別なんだけど。

だから、教える側が馴染みに深いプログラム言語を扱って(この場合は「教師」となる)、生徒や児童のサポートができればよい。たとえば、プログラム言語の学習書のように「int x;」とは何かとか、宣言とは何かとか、for文とは何か、とかみたいな文法的なものはいらない。そのあたりは道具立てでしかない。同じことは Scratch の様々なブロックを扱うときにも言える。

それよりも、もっと目的となること、例えば「猫を端から端まで動かしてみよう」みたいなことが必要で、Scratch で言えば、繰り返しのブロックを使って端に触れたかどうかを判定するとか、C 言語で言えば width を設定しておいてfor文で最大値に達するまで繰り返すとか、Unity ならどうするとか、Python を使うとどうなるとか、というのが問いとして適切になる。つまり、教える側としては「繰り返しのブロックを使ってみましょう」というようなプログラム言語の文法から入るのではなく、「地球を太陽の周りを回らせてみましょう」という何かを達成させるために、道具としてのプログラムを使うというスタイルをとるのがベターであるし、それがプログラミング教育の本質であろうと私は思う。

ちょうど、数学の問題を解くのと同じなんだけど、異なるのは答え(正確には試行過程なんだけど)はひとつは限らない。例えば、Scratch で、

  • 猫がマウスカーソルを追うようにしてみよう

としたとき、正解ははひとつではなく、実際に3種類ぐらい皆(小学3-6年生)が作ってくる。ああ、なるほど、そういう方法もあるのかと感心するぐらい様々な方法がある。といういことを覚えておいて欲しい。だから、教科書通りの解き方をしてないからといって「×」にするのは、それこそ「×」だ。これを実施するためには、

  • 目的(達成条件、クリア条件)が明確になっていること
  • 道具立てを縛らないこと
  • でも、わからない場合は、ヒント(補助線のようなもの)を出しても良い

を教える側が念頭に置く必要がある。逆に言えば、児童/生徒の「何をすれば正解なの?」の意識を壊す必要があるということ。何をやっても、正解に至る≒目的を達成することは可能であるということに気付かせる必要がある。

カテゴリー: 雑談 | プログラマの視点から「プログラム教育」騒ぎを見てみる はコメントを受け付けていません