Google Colaboratoryを知る

HAWAII

 今日も見に来てくださって、ありがとうございます。

 Google先生、これまでもいろいろなサービスを提供してくれていますが、この機能、昨日(ダジャレ)初めて知りました。Google Colaboratoryです。何かというと、Googleのアカウントを持っていれば、Jupyter notebookの機能がWebブラウザだけで使える、というサービスです。GPUも使えるそうです。そして、無料です!いや~、Google先生、ありがとうございます。

 知らない人に簡単に説明すると、Jupyter notebookは、対話的にPythonスクリプトを実行することができ、その結果を記録するドキュメントの機能を融合したWeb技術を基盤としたツールです。実行する前の状態をドキュメントにしておいて、説明するときに順番に実行して見せる、という使い方もできるし、説明ドキュメントをメインにして、実行結果を付けて見せる、という使い方もできます。再利用可能という点においても優れており、研究成果や教科書的な媒体としての位置づけを獲得しているそうです。

 ここで使い方の詳細を紹介しようかとも思ったのですけど、サービス上にすでに紹介がありますので、そのリンクを張り付けておきます。

https://colab.research.google.com/notebooks/welcome.ipynb

これで、誰でもJupyter notebookが使えますね。すばらしい。

Pythonでプログラミング キー入力を受け付ける

 今日も読みに来てくださって、ありがとうございます。今回は、Pythonのお話です。

 Pythonでファイルの更新とキー入力待ちを同時にチェックしたいという要望がありました。ファイルの更新チェックは、新しいデータが記録されたのを抜き出したい、ということで、更新確認は、前回タイムスタンプと今回タイムスタンプが異なっていれば、何らかの更新があった、という判断で対応できました。その更新チェックをしながら、キー入力待ちを同時にやりたい、という要望です。

 通常Pythonでキー入力を受け付けるというと、「input()」が思いつきます。こんな感じですね。

>>> a = input('Hit any key:')
Hit any key:aaa
>>> print(a)
aaa

 ただこれだと、「input()」が実行されると先に進まなくなって、待ち状態になってしまいます。そうすると、ファイルのタイムスタンプが更新されたらデータを読み込むという処理をしながらキー入力待ちができないのです。そう、やりたいのは、かつてBASICでINKEY$というコマンドで実装していたように、その関数が実行された時に入力されたキーを知りたい、ということです。調べてみるといろんなやり方があるようでしたが、中でも簡単に実装できたやつをメモしておきます。blessedというモジュールに入っている、Terminalを利用します。「input()」は標準モジュールに含まれていますが、blessedは標準モジュールではないのでpipでインストールする必要があります。

pip install blessed

 このblessedは、cursesモジュールという文字セル表示を扱うためのライブラリをより簡単に使えるようラップしたものだそうです。cursesは、Unix端末で主に利用されているcursesライブラリのインターフェースということでした。もっと簡単に言うと、CUIのインターフェースをうまく扱えるようにするために使えるライブラリですね。
 インストールできたので、さっそく使ってみます。

from blessed import Terminal

t = Terminal()

with t.cbreak():
    while True:
        k = t.inkey(timeout=0.001)
        if not k :
            pass
        elif k.is_sequence:
            if k.name == 'KEY_ESCAPE':
                break
            print(f'"{k.name}"が押されました。終了するには「ESC」キーを押してください。')
        else:
            print(f'"{k}"が押されました。終了するには「ESC」キーを押してください。')

 これでESCキーが押されるまでループを繰り返すようになりました。合間にファイルのタイムスタンプ更新チェックを入れれば要望通りのことができます。
 ただ、このスクリプトの実行に、ぼくの環境ではCPUの使用率が35%ほどかかっていました。もしこれが問題で、使用率を下げたいなら、timeモジュールのsleepを上記のpassのところに記載するとよいでしょう。試しにぼくの環境で入れてみましたが、sleep(0.1)と入れるだけで、CPU使用率が2.5~3%ほどに下がりました。単純にループしてるだけなのに、sleepしないとCPU使用率って意外とかかるのですね。

Pythonでは「クラスもオブジェクト」です

WIKI WIKI SHUTTLE

 今日も見にきてくださって、ありがとうございます。がんばって更新していきます。

 ずっとデータベースの論理設計の勉強会に参加しているのですけど、そちらでしばらくPythonの勉強会をすることになりました。メンバーのなかでは適任者ということで講師に任命されまして、それで先日、第一回目が開催されました。その講習の中でぼくが「Pythonでは、すべてがオブジェクトとして管理されています。」と説明してから、ふと、class作成後、class変更したら、以前のclassとは異なるオブジェクトになっているのだろうか、ということが自分でも気になったので、確認してみました。でも、このタイトルだと、なんのこっちゃ、という感じですねぇ♪

 まず、オブジェクトとはこんな感じのモノです、というイメージがわかりやすいように、listを作成してみます。ご覧のとおり、typeはlistになり、オブジェクトとして管理するためにidが採番されています。

>>> alist = [1,2,3,4,5]
>>> type(alist)
<class 'list'>
>>> id(alist)
3005538914888
>>>
http://pythontutor.com/visualize.html#mode=display
にてイメージ化。

 ちなみに、この中で使われている「1」などの数値もオブジェクトとして管理されています。調べていて面白かったのは、-5~256の範囲の数値はintのオブジェクトとしてあらかじめキャッシュされて使いまわされているそうです。この点は処理系によって実装は異なるのでしょうけど、ぼくの環境では以下のように確かに使いまわされているのが確認できました。

>>> type(1)
<class 'int'>
>>> id(1)
140729051148544
>>> id(alist[0])
140729051148544
>>> id(2)
140729051148576
>>> id(1+1)
140729051148576
>>> id(alist[1])
140729051148576

 では、本題のclassを定義して確認してみます。以下のようなスクリプトを実行してみます。poiクラスを作成してidを確認してから、内容を少し変更したpoiクラスを再作成してもう一度idを確認してみます。

class poi:
    pass

print(type(poi))
print(id(poi))

class poi:
    a = 1

print(type(poi))
print(id(poi)) 
一つ目のクラス
二つ目のクラス

printの実行結果は、以下の通りでした。やっぱり違うモノ(オブジェクト)になってますよね。

出力結果

 ちょっと意外に感じたのは、class定義されたもののtypeが「type」だったことです。やっぱり、<class ‘class’>はちょっとヘンだよねぇ、ということにでもなったのでしょうか?このあたりの呼び名は宗教観(?)の違いで争われそうですね。
 idは予想通り異なっていたので、class定義することで、以前のクラスが別のオブジェクトで上書きされた、という風に考えられますね。あ、、、でも、上書きではありませんでしたね。自分で説明しておいて間違えました。変数名は、オブジェクトに張り付けた付箋のようなイメージです、と説明したのでした。実際にはpoiクラスというクラスのオブジェクトができて、再度、別のpoiクラスというクラスのオブジェクトができる、というのが正しい考え方ですね。ちょっと変数にセットしてみてやってみます。

class poi:
     pass

poiA = poi

class poi:
    a = 1

poiB = poi
クラスが作成されるごとに変数へ格納

 予想通り、「poi class」というオブジェクトが二つできました。先ほどの例ではpoiAに代入しなかったので、最初の「poi class」オブジェクトがガベージコレクトされて捨てられてしまった、ということですね。

xdwlibでDocuworks9の中のテキストを出力

 今日も見にきてくれて、ありがとう。久しぶりの更新です。そのうちまた更新しますので、また見にきてくださいね。

 おしごとの関連で富士ゼロックスさんのドキュワークスでつくられた文書のテキストを抜き出す必要があったので、Pythonスクリプト作成してみました。帳票出力のプログラムを修正したときに、修正前後の差分をとって、チェックするのに便利です。
ご利用は自己責任でどうぞ。

利用するまでに必要な作業は以下の通りです。

1.Pythonのインストール
  これは、本家のサイトをご覧になってがんばってやってください。
  ぼくの環境は、実行時最新の3.7.4をインストールしました。

2.xdwlibのインストール
  「pip install xdwlib」で完了。3.8.2.0がインストールされました。なぜかインストール時にエラーがでましたけど、正常に利用できました。林秀樹さん、ありがとうございます。

from sys import argv, exit
from os.path import basename, isfile, splitext
from xdwlib import xdwopen

def export_xdwfulltext(input_file):

    BASE_FILENAME , ext = splitext(input_file)
    if ext.lower() != ".xdw":
        print("指定されたファイルの拡張子が.xdwではありません。["+ext+"]")
        input("Hit Enter key.")
        return

    if not isfile(input_file):
        print("指定されたファイルが存在しません。["+input_file+"]")
        input("Hit Enter key.")
        return

    OUTPUT_PATHNAME = BASE_FILENAME + ".txt"

    if isfile(OUTPUT_PATHNAME):
        print("出力先のファイルが既に存在します。["+OUTPUT_PATHNAME+"]")
        answer = input("上書きしますか?(Y/N):")
        if answer.upper()[0] != "Y":
            print("処理を中断しました。")
            return

    with open(OUTPUT_PATHNAME,"w",encoding="utf-8") as f,\
         xdwopen(input_file) as doc:
        for p in doc:
            f.write(p.fulltext())
            f.write("\n")


if __name__ == '__main__':

    if len(argv) < 2:
        print(basename(argv[0]),"は、ドキュワークスで出力されたxdwファイルの中のテキストを出力するプログラムです。")
        print("拡張子が.xdwのファイルのみ対象とし、同ファイル名の.txtファイルとして出力します。")
        print("使い方1:",basename(argv[0]),"hoge.xdw ...")
        print("使い方2:",basename(argv[0]),"に、ファイルをドラッグ&ドロップ")
        input("Hit Enter key.")
        exit

    for f in argv[1:]:
        export_xdwfulltext(f)

エンティティの種類

 今日も見に来てくれて、ありがとう。地道に書いていきますので、また見に来てくださいね。先週、700%にユーザー数がいきなり増えていて、びっくりしました。なぜかカナダから、同時期に34ユーザの訪問があったのでした。ま、そのひとたちは、二度と来ないと思いますけど。そう34ユーザーでも700%です♪

 さて、先日エンティティの定義について書きました。エンティティが定義できたら、次はエンティティの種類について検討します。システム設計では、データをマスタ系とトランザクション系というふうに分けて管理することが多いのですが、TM(T字形ER手法)では、エンティティをリソースとイベントの二種類に分けて考えます。リソースはその名の通り、その組織の中で管理されている資源にあたるものになります。イベントは基本的にはその組織の中で発生した出来事(実施した仕事)を記録したものになります。また、イベントはリソースから生成することができるので、全てのリソースを把握することがとても重要なことだと思います。なので、リソースとイベントの数を比べたときに、リソースの数が多ければ、その組織はまだまだ改善の余地(新たに仕事を生み出す可能性が残っている)があり、イベントの数が多ければ、打つ手が少ないのでは、という可能性が考えられます。

 TMでは、エンティティの種類の定義は以下の通りです。このように、明確に定義されているのがTMの特徴です。他の手法でもリソースとイベントを分ける場合はあるようですが、その場合でも例示(社員はリソース、受注はイベント等)のみで、定義は示されていないということだそうです。

イベント:日付(タイムスタンプ)によって並べられる
リソース:イベント以外

 例えば、認知番号が「受注番号」だとエンティティは「受注」になり、「受注日」という属性があれば、そのエンティティはイベント、ということになります。そう、とっても簡単ですね。これで世の中のエンティティをすべてイベントとリソースに分けることができるようになりました!

 めでたし、めでたし、と、なればよかったのですけど、現実世界はそんなに甘くありません。ある日、最初の悩みが生まれました。それは、イベントのふりをしているけれど、イベントではないエンティティがあるんじゃないか、という悩みです。基本的な考え方として、イベントは、取引の実績など、事実を記録していくもの、という特性があり、リソースは、仕事をしていく上で必要な資源、という特性があります。上記のルールどおりに考えると、資源にあたるものだけれどもイベントに分類されてしまうものが出てくるのです。例えば、契約番号に契約日があればイベントです。でも、「契約」エンティティが組織にとって重要な資源として扱われそこからさまざまな仕事が生まれてくるような場合、リソースになるような気がするのですよね。仕事とともに忘れ去られてしまってよい情報ではありませんのでどうしてもリソースとして扱いたくなったのでした。で、よくよく考えてみたところ、日付が表していることがらに違う意味があったのです。

日付の違い:
1.記録のためのタイムスタンプの日付(監査証跡)
2.開始、終了などの、範囲を表す日付(未来日付)

 そう、この「1.」の方がイベントのよりどころになる日付で、「2.」の方は違う、ということを発見したのでした。ぼくが悩んだ今回の「契約日」は、契約を交わしたイベントを記録した日付ではなくて、もうちょっとていねいに表現すると、この日から契約が始まりますよ、という「契約開始日」だった、というわけです。このように日付の意味を考慮した場合には、契約がリソースになることがあるので注意が必要です。契約をリソースとして正しく管理できれば、譲渡や継承の問題も解決しやすくなりそうですね。

 このリソースとイベントの分類、なにがうれしいの?というひともいるかも知れませんので、ちょっとだけ補足します。例えば、海外旅行保険契約やレンタカーの貸渡契約などは、ルール通りイベントで問題ないと思います。ただ、その時に契約したひとの情報をイベントの中に記録しておくだけだと、新たな仕事も生まれません。でも、これら契約者の情報をリソースとして管理できるような仕組みにした場合、新たな可能性が考えられるようになります。例えば、契約者に対して、他の類似商品の販売や、サービス向上の可能性を考えられます。イベントとして埋もれてしまったままだと、その可能性に気づくのはなかなか難しいと思います。システム設計上はもちろんですが、ビジネスとして考えた場合にも、リソースを把握して見える化する、ということがとても重要ですね。

エンティティ

 今日も見に来てくれて、ありがとう。励みになります♪

 先日「エンティティ」という単語を何となく使ってしまいましたが、それほど一般的なことばではないよねぇ、ということが気になっていて、ちょっと補足したいと思います。

 ぼくが初めてエンティティということばを聞いたのはいつでしょうかねぇ、たぶん、システム開発の中で必要だと言われていた、「ER図(Entity-Relationship-Diagram)」というドキュメントからでしょうか。日本語では実体関連図、と翻訳されています。ぼくはこの図を見たとき、リレーショナルデータベースのテーブルとその関係を表す図になっていたので、単純にこう思っていました。

エンティティ    = テーブル
リレーションシップ = テーブルとテーブルの関係

 システム開発の製造工程、プログラムを作成するうえでは、この理解で充分でした。画面や帳票があって、どのテーブルのどの項目が画面や帳票とマッピングされるのか、どんな条件で取り出せばいいのか、ということさえわかればプログラミングできたからです。当時はほとんどのひとがそんな認識だったんじゃないかなぁ。どうしてそんな風になっていたかというと、当時、リレーショナルデータベース(RDB)は新しく登場した概念だったし、システム開発においては、単なるファイルに替わるものとして利用されていたからだと思います。画面のプログラムを作るためにはそこに表示するデータを格納するためのテーブルが必要で、これがなかなか決まらなくて、苦労していたのをよく覚えています。

 TM(T字形ER手法)を習ったときには、エンティティは以下の通り定義されていました。あまりにも簡単で明快!でも、それまでモヤモヤしていたのがスッキリしました!

エンティティ:管理したい対象で、認知番号があるもの

 当時「認知番号」は、個体指定子と言われていました。英語では、entity-setterです。その前は、identifierと言っていました。日本語だと「識別子」という意味になるのですけど、あまり適切な訳ではないということで、当時はidentifierを英語のまま使っていたということでした。このあたり、佐藤正美先生(TM(T字形ER手法)の考案者)が考えられることですので、またちょっとしたら呼び名は変わるかもしれません。いずれにせよ、簡単に言うと、認知番号は、番号、No、ID、コードがついた項目で、これらをもとにエンティティを作る、ということになります。例えば、以下のようになります。

認知番号:顧客番号 → エンティティ:顧客
認知番号:商品No → エンティティ:商品
認知番号:店舗番号 → エンティティ:店舗
認知番号:取引ID → エンティティ:取引

 「エンティティ=テーブル」と思い込んでいて、テーブルって、何を基準に作るんだろうねぇ、と思っていたぼくにはかなりの衝撃でした。それまでぼくが知っていたエンティティは実体と訳されていて「業務におけるひとまとまりのモノ」みたいに言われていたのです。「モノ」ってなんなんだよ、誰がどうやって決めるんだよ!というぼくの疑問のような不満なような問題は、簡単に決着がついたわけです。

 この衝撃の事実を知ったことで、うれしくなったぼくは、ずっといろんなひとに説明して回っていたのですけど、あるときなんと、「そんなの当たり前のことでしょ。どうして大発見みたいな感じなのか、よく分からないんですけど?」というひとが現れました!ぼくにとってのこの大発見は、プログラムもテーブルも作ったことがないひとからすると、別に声を大にして言うようなことでもなんでもなくて、自然なことだったようです。む~、確かに!余計な前提知識があったために、ずいぶんと遠回りしちゃったようです。もうちょっと、素直になろう♪

日頃のトレーニング(日々妄想)

MJ BOOK CAFE

 今日も読みに来てくれてありがとう。来てもらってうれしくなったのでまた記事を書こうと思います。
 どうしてこんなことを書いたかというと、Facebookでつながっている方がブログアクセス数500を超えた、と、大喜びをしていたのです。ぼくのブログは完全に自己満足なものなので、ほとんどのひとが読んでいないだろうなぁ、と、思っていたのです。それでもまあ勉強になるよね、と思ってその方のまねをしてGoogle Analyticsを設定してみたところ、なんと、意外にも毎日ひとりとかふたりとか、ちょくちょくアクセスがあることが発覚しました。(予想通りアクセスのない日もありましたよ。)
 来てもらったひとにあんまりがっかりさせては申し訳ないので、もうちょっと記事を書いていこうかと思った次第です。今後とも、よろしくお願いしますね。

 さて、タイトルの「日頃のトレーニング」について、です。かれこれ20年ほど前、佐藤正美先生の「ビジネスの実態がわかるデータベースの作り方」という早稲田大学エクステンションセンターのセミナーで、衝撃を受けました。野球選手なら、日頃のトレーニングとして色んな練習をしてから、試合に臨みます。それに比べて、練習なしで、いきなり試合に参加してくるエンジニアが多すぎる、というお話をしていただきました。確かに!ぼくはエンジニアとしてということを意識した練習、何にもしてませんでしたね!でも、エンジニアの日頃のトレーニングって何だろうねぇ、というのが、今日のお話です。

 池袋ジュンク堂書店では、書籍などを1万円以上お買い上げの方には、4階にあるMJブックカフェ池袋店のブレンドコーヒー引換券がもらえます。今日はこの引換券を使ってただでコーヒーをいただきました。ただ券でも、レシートをもらったら、必ずトレーニング開始します。

 セミナーで教わったことは、データベースの論理設計をしながらビジネスの分析をする、というもので、まずは「番号、No、IDなどの管理するための番号を認知番号として、エンティティを作る」ということです。この認知番号が取られているモノは、その企業などの組織の中で、管理したいモノであるということが現れているので、まずは、そこを起点にします。

  • 端末番号 → 端末
  • 取引ID → 取引
  • ID → Wi-fi
  • No. → ?

 という感じです。このレシートに情報を出力するためには、店舗も管理しないとねぇ、とか、取引IDとNoはどちらもこのレシートを特定するために使えるけど、その違いは何かなぁ、とか、Noの桁数が多すぎるので、桁の上の方は他の何かを管理している番号かもねぇ、とか、Wi-fiはホントに管理されているかなぁ、管理するとしたらどんな管理方法になるかなぁ、とか、【IK】って何かなぁ、とか、引換券は「割引100%」として入力されているのかぁ、とか、他の割引方法はないのかなぁ、とか、取引IDが連番なら、いつからの連番なのかなぁ、いまお客さんが10人入っていて、一時間ごとに入れ替わるとしたら、一日10時間営業だとおよそ100人、取引IDの138130を100で割ると1381、365日で割ると、およそ4年分くらいなのかなぁ、とか、端末番号には47AEと書いてあるけど、この店舗に1個しかないのに、変な番号だなぁ、どういう付け方をしたらこうなるんだろう、とか、とか、とか、ずっと妄想、いや、これがトレーニングですね。
 こうやって、日々、思考力(妄想力)を鍛えておけば、試合で考えることを要求されたときにも、パッと答えが出せる、ということになりますね。そう考えると、コンサルタントって、妄想力が強いひとに向いた職業なのかなぁ。

帰ってまいりました!

 はい、帰ってまいりました。ぼくのパソコンです。買ってからそんなに経っていないのに、不調になりまして。もうどうしようもないよねぇ、ということで、入院してもらっていました。

 さて、どんなに不調だったかと申しますと、なんと、制御不能になりました。これが証拠の動画です。

 現象としては、画面中央の下部あたりを中心に、連続で高速タップしているようです。その証拠にタッチパネルモードを「タッチ」から「アクティブペン」に変更するとこの現象はおさまります。先週の水曜日辺りに少しずつ始まりまして、モードを切り替えてしばらく使い続けておりました。最近スマフォアプリを開発しようと決意しましたので、動作確認するにはやっぱり、タッチも使いたいよねぇ、と、切り替えてみるとごらんの通り頻度が半端ない感じになってきまして。で、入院してもらおうと。

 土曜日の夜に決意して、Panasonicのサイトからエントリーしましたところ、日曜日にもかかわらず翌日の朝いちばんにメールをいただきました。最速の月曜日集荷を申し込んでおいたら、月曜日の9時~12時にて手配しました、ということでした。メールに添付されてきた修理依頼書にサインして、ファイルのバックアップをとってパソコンのパスワードを解除して、集荷にきてもらいました。

 それからしばらくパソコンのない暮らしをしておりましたが、木曜日の朝、修理されたパソコンが届きました。思っていたよりスピーディな対応で、ちょっぴりうれしくなりました。ありがとう、パナソニックの神戸カスタマーセンターの人たち!

 でもねぇ、処置内容「LCD故障のため、交換いたしました。」というだけなのは、ちょっぴりそっけないよね。ぼくとしては、故障の原因とか理由を知りたいですね。買って半年もたっていないタイミングでの故障ですから、また壊れるんじゃないか、次に買うとき、パナソニックのタッチはやめた方がいいかな、という風になりますからねぇ。最低でも、この部品の故障率はこれくらいでめったにないことですよ~、とか、こんな風に使うと壊れやすいんですよ~、気を付けてね、って、言ってほしいなぁ。

 勝手にタッチされない、って、快適ですね♪

Flutterを使ってみよう[3/3]

 さて、今度こそ動かします。まずはプロジェクトの作成からです。

 「Start a new Flutter project」をクリックします。

 一般的なアプリケーションを作成するので、「Flutter Application」を選択します。「Next」をクリックします。

 ここでは、新しいFlutterアプリケーションの情報を入力します。今回はお試しなので、おすすめの設定のままで大丈夫でしょう。「Next」をクリックします。

 パッケージの名前を設定するようです。「Company domain」だけ、「ishikawasekkei.com」に変更してみます。「Package name」が変更されました。あと、「Sample Application」のところの「generate sample content」をチェックしてみましょう。きっとサンプルが作成されることでしょう。「Finish」をクリックします。

 しばらく待った後、プロジェクトが開かれました。Android Studioをインストールした後に作っておいた仮想デバイスで動かしてみたいと思います。

 この、デバイスを選ぶところで「Open Android Emulator: Pixel 3 API Q」を選択して、三角形をクリックしてみようと思います。

 デバイスを選択すると仮想端末が開きました。そして、実行の三角形をクリックすると、「Initializing gradle…」で結構長い時間待たされた後、「Resolving dependencies…」が出てきて、警告が出てきました。

 プライベートネットワークとパブリックネットワークの両方にチェックして、「アクセスを許可する」をクリック。許可しないと、使えませんからね。

 おっと、エラーがでました。。。今のところ原因はよく分かりませんが、仮想デバイスがいけないのかも知れません。ちょっと調べてみないとねぇ。。。

 と、言うことで調査完了いたしました。対応しまして、再度三角形をクリックして実行したところ、コンソールに以下のような出力が表示されまして、画面に最初のアプリケーションが表示されました。

 やっと動きました!

 さて、今回のエラーについて、どうやって対処したかというと、
1.http://dl-ssl.google.com/android/repository/platform-tools_r28.0.2-windows.zipをダウンロード。
2.解凍した「platform-tools」フォルダを、C:\Users\mitsu\AppData\Local\Android\Sdk配下のフォルダと置き換える。
 と、今回はただそれだけでした。ちなみに、解決方法については、ここに記載されていました。内容は根本解決にはなっておらず、このフォルダの内容を以前のものにダウングレードするだけ、というものでした。
 投稿はちょうど2日前のもので、このあたり、Flutterは現在進行形の開発環境で、かなり活発に利用されているなぁ、という感じがしました。Flutter開発をするなら、開発環境がまだ整備されていないのかも、という疑う姿勢と、英語で検索するスキルが絶対に必要だなぁ、と、思いました。
(追記:その2日後に、platform-toolsのバージョンが29.0.1と、リビジョンが一つ増えて根本解決していました。Flutter開発者集団は、優秀で仕事が早いですね!)

 では、仮想環境ではなくて、本当に端末で動くのか、確認したいと思います。まずは、動かしたい端末の設定です。USBケーブルで接続して動かしていくのですけど、「開発者向けオプション」の「USBデバッグ」を有効にする必要があります。「開発者向けオプション」を表示させるためには、スマフォの「設定」-「システム」-「端末情報」と進み、「端末情報」の中の「ビルド番号」を数回タップすると表示されますので確認してみてください。ケーブルをつなぐとスマフォに「USBデバッグが接続されました」と表示されました。
 ええと、Android Studioの上部に自動的に表示されると思っていたのですが、出てきませんねぇ。

 もしかしたら、仮想環境でアプリを実行中だからかも知れませんね。と、いうことで仮想環境のアプリを終了してみます。
 ダメですねぇ。。。
 メニューにそれらしいものがないか、探してみます。

「Tools」の中に「Connection Assistant」というのを見つけました。クリックして見ます。

 すると、右上に上記のようなウィンドウが開いて、スキャンが始まり、しばらくすると「SH-03K」という接続したぼくのスマフォが表示されました。「Next →」をクリックします。次の表示を見てみると、「USBデバッグ」を有効にせよ、と、書いてあって、手順も書いてありました(英語で)。「Next →」をクリックします。

 ADB(Android Debug Bridge)serverをリスタートせよ、ということですので「Restart ADB server」ボタンをクリックします。
 …全然表示は変わりませんねぇ。と、しばらくウロウロしていたのですけれど、ふと、スマフォの方を見てみると「USBデバッグを許可しますか?」と、聞いてきていました!ええと、もしかして、リスタートとか必要なかったのかも。スマフォの「OK」をクリックします。

 はい、ちゃんと表示されました。選択して、実行します。

 下の方のコンソールに実行中のメッセージがちゃんと出てきました。ここに選択した端末の名前が出てたのですね。

 実機にも出力されました!
 さて、噂のHot Reloadを試してみたくなりました。タイトル部分の「Flutter Demo Home Page」を修正してみます。

 ここですね。ここの部分を、「フラッターでもホームページ」に変えてみます。

 さすがに修正しただけでは変わりませんねぇ。ファイルを保存してみます。「Ctrl+S」を押してみます。

 すぐにコンソールに「Performing hot reload…」と出力されました。

 修正も、一瞬で反映されました。できました~!

Flutterを使ってみよう[2/3]

 前回の続きです。次にやらないといけないことは、PATHの設定です。

 ユーザー変数のPATHを設定するために、Windows画面左下の「ここに入力して検索」のところへ「env」とキー入力します。

 すると「システム環境変数の編集」が検索されてきますので、クリックします。

 「環境変数(N)…」をクリックします。

 「Path」を選んで「編集(E)…」をクリックします。

 「新規(N)」をクリックします。

 「C:\Flutter\bin」を追加して「OK」を次々とクリックしてPATHの追加は終了です。

次は、「flutter doctor」コマンドを実行せよ、ということですので、実行してみます。

 しばらくグルグルしていましたが、メッセージが出てまいりました。Flutterはちゃんとインストールされているようです。Android toolchainの中で、いくつかのライセンスが受け付けられてなくてダメ、と言われております。解決するためには「flutter doctor –android-licenses」を実行してね、と言われましたので、実行してみます。そういえば、フライイングして、AndroidStudioはインストールしておいたのでした。こちらは別途記事をアップしたいと思います。

 ここで初期値のままエンターキーを押すと終了しました。ま、当たり前ですけど。再度実行して、このタイミングで「y」を入力してからエンターキーを押すと、たくさんメッセージが出力されて、またしても、「y/N」を聞かれます。

  上の方に戻って見てみますと、「The Google TV Add-on for the Android Software Development Kit」のソフトウエア利用許諾契約が5個のうちのひとつ目ということで出力されていました。たぶんテレビのアドオンは使わないですねぇ。エラーじゃなくて警告ということだから、全部そのままでいいような気がしてきました。でも、後から問題になったときに問題を発見するのは難しいだろうなぁ。と、いうことで、今回はすべて許諾をよく読んでひとつずつ「y」を入れて許諾していくことにしようと思います。

  • The Google TV Add-on for the Android Software Development Kit License Agreement
  • The Android Software Development Kit License Agreement
  • The Glass Development Kit License Agreement
  • Intel (R) Hardware Accelerated Execution Manager End-User License Agreement
  • MIPS Technologies, Inc. (gMIPSh) Internal Evaluation License Agreement for MIPS Android

 以上、順番に許諾していきました。
 そして、次の2つに対応したいと思います。
[!] Android Studio (version 3.4)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.

 FlutterホームページのGet Started - Set up an editor に書いてありました。

まずは、Android Studioを起動します。

 しばらく待つと、「Welcome to Android Studio」画面が登場します。

 はて、Fileメニューがありませんね。プロジェクトを作成していないからでしょうか。ConfigureをクリックしたらSettingsとPluginsがありました。

 確認したところPluginsでも同じ画面にたどり着きましたので、Settingsの方がわかりやすいと思いますので、そちらの画面を採用します。

 Flutterの項目の「Install」をクリックします。

 サードパーティのプラグインが個人情報を扱う方法についてはJetBrains社は全く関知しないのでちゃんとチェックしてくださいね、というメッセージが表示されました。「Accept」をクリックします。

 「インストールしようとしているプラグインはDartのプラグインを必要としています。続けますか?」はい、当然、続けますよ。「Yes」をクリックします。

 しばらく待つと、上記のようにボタンが「Restart IDE」に変わります。これをクリックしてAndroid Studioを再起動します。

 はい、「Restart」ですよ~。

 おっ、Flutter用のメニューが増えていますね。もう一度「flutter doctor」コマンドを実行してみます。

 エラーは解決しました。Flutter入門には、「Flutter I18n」というプラグインもインストールしてね、と書いてありましたので、同様にインストールしておきました。日本語を扱うときに必要な国際化プラグインですね。
 あとは接続デバイスですが、現在接続されているデバイスを表しているだけ、ということで、つなげば解消するということですので気にしないことにします。これでセットアップは概ね完了ですね。次回、プロジェクトを作って実際に動かしてみたいと思います。やっと実行できる~!!!