話題のflutterを使って見ました

Flutter - Beautiful native apps in record timeは、Googleが開発しているスマホアプリ開発環境(UIフレームワーク)です。同じコードでiOSアプリ、Androidアプリを開発することができます。開発言語はGoogleが開発しているDart programming language | Dartです。

React Native, Xamarinなど同じ環境でiPhone/Androidアプリを開発できるものはすでにありますが、選択肢が増えるのは良いことだと思います。 また、Android StudioVisual Studio Codeがサポートされているのも取っつきやすいかもしれません。

今回は、iPhoneアプリをシミュレータで動かすところまで実行しましたが、iPhoneアプリ開発環境(Xcode、cocoapod)のインストールは別サイトを参考にする必要があります。

以下、macOS XGet Started: Install on macOS - Flutterを試してみました。

Flutter SDKを取得

Clone the repo

git clone -b beta https://github.com/flutter/flutter.git
export PATH=`pwd`/flutter/bin:$PATH

環境チェック

flutter doctorを実行します。

$ flutter doctor
Downloading Dart SDK from Flutter engine ead227f118077d1f2b57842a32abaf105b573b8a...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 43.3M  100 43.3M    0     0  4290k      0  0:00:10  0:00:10 --:--:-- 5273k
Building flutter tool...

  ╔════════════════════════════════════════════════════════════════════════════╗
  ║                 Welcome to Flutter! - https://flutter.io                   ║
  ║                                                                            ║
  ║ The Flutter tool anonymously reports feature usage statistics and crash    ║
  ║ reports to Google in order to help Google contribute improvements to       ║
  ║ Flutter over time.                                                         ║
  ║                                                                            ║
  ║ Read about data we send with crash reports:                                ║
  ║ https://github.com/flutter/flutter/wiki/Flutter-CLI-crash-reporting        ║
  ║                                                                            ║
  ║ See Google's privacy policy:                                               ║
  ║ https://www.google.com/intl/en/policies/privacy/                           ║
  ║                                                                            ║
  ║ Use "flutter config --no-analytics" to disable analytics and crash         ║
  ║ reporting.                                                                 ║
  ╚════════════════════════════════════════════════════════════════════════════╝

Downloading Material fonts...                         0.6s
Downloading package sky_engine...                     0.6s
Downloading common tools...                           0.8s
Downloading darwin-x64 tools...                       3.8s
Downloading android-arm-profile/darwin-x64 tools...   0.7s
Downloading android-arm-release/darwin-x64 tools...   0.7s
Downloading android-arm64-profile/darwin-x64 tools...  0.7s
Downloading android-arm64-release/darwin-x64 tools...  0.5s
Downloading android-x86 tools...                      1.9s
Downloading android-x64 tools...                      2.2s
Downloading android-arm tools...                      1.0s
Downloading android-arm-profile tools...              0.7s
Downloading android-arm-release tools...              0.7s
Downloading android-arm64 tools...                    0.9s
Downloading android-arm64-profile tools...            1.2s
Downloading android-arm64-release tools...            0.9s
Downloading ios tools...                              4.9s
Downloading ios-profile tools...                      4.1s
Downloading ios-release tools...                      2.5s
Downloading Gradle Wrapper...                         0.3s
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.1.5, on Mac OS X 10.13.3 17D102, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK 25.0.2)
[!] iOS toolchain - develop for iOS devices (Xcode 9.2)
    ✗ libimobiledevice and ideviceinstaller are not installed. To install, run:
        brew install --HEAD libimobiledevice
        brew install ideviceinstaller
    ✗ ios-deploy not installed. To install:
        brew install ios-deploy
[✓] Android Studio (version 3.0)
[!] IntelliJ IDEA Community Edition (version 2017.3.4)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.20.1)
[!] Connected devices
    ! No devices available

! Doctor found issues in 4 categories.

×が問題点ですね。Editor plugin(IntelliJ IDEA)は後回しにします。

$ brew install --HEAD libimobiledevice
以下の依存モジュールをインストールします。
==> Installing dependencies for libimobiledevice: automake, libxml2, libtasn1, libplist, libusb, usbmuxd, openssl

$ brew install ideviceinstaller
以下の依存モジュールをインストールします。
==> Installing dependencies for ideviceinstaller: libzip

$ brew install ios-deploy
$ brew install

Update your path

以下の内容を.bash_profileに追加。使っているshに依存します。

export PATH=[PATH_TO_FLUTTER_GIT_DIRECTORY]/flutter/bin:$PATH”

確認。

$ echo $PATH

iOS Setup

Install Xcode

$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
$ sudo xcodebuild -license

Set up the iOS simulator

$ open -a Simulator

Deploy to iOS devices

iOS開発環境をセットアップしていない人は、以下の処理が必要ですが、知らないと少し難しいかもしれません。

外部ライブラリ追加

$ install cocoapods

$ cd flutter/examples/hello_world/ios
$ pod setup

example実行

$ cd flutter/examples/hello_world
$ flutter run

f:id:unokun3:20180311104921p:plain

TypeScriptで始めるJavascript再入門(1)

Javaなどのクラスベースオブジェクト指向言語を知っている人が最新のJavascriptを知る場合、Typescriptを使うのが良い方法です。

TypeScript - JavaScript that scales.は、マイクロソフトが開発しているaltJSの一つです。 TypeScriptはJavaScriptに対して、省略も可能な静的型付けとクラスベースオブジェクト指向を加えた厳密なスーパーセットとなっています。

使い方

Typescriptは、.tsという拡張子を持つファイルに記述し、tscというコマンドでjavascriptコンパイルします。コンパイルオプションは、tsconfig.jsonファイルに記述します。

$ cat age.ts
let age: number = 10;
console.log(age + ‘歳です。’);

$ cat ./tsconfig,json
{
    "buildOnSave": true,
    "compileOnSave": false,
    "compilerOptions": {
        "target": "es5",
        "sourceMap": true,
        "module": "commonjs",
        "charset": "utf8"
    }
}

$ tsc -p ./tsconfig,json

$ cat age.js
let age = 10;
console.log(age + '歳です。');

静的型付け

Typescriptは、静的型付け可能な言語のため、次のコードはコンパイルエラーになります。javascriptの暗黙型変換によるバグを未然に防ぐことができます。

let age: number = 10;
age += '1';
$ tsc -p ./tsconfig,json
error TS2322: Type 'string' is not assignable to type 'number'.

クラス

クラスは、javascriptのバージョンに応じてコンパイルしてくれます。javascriptのバージョンごとの記述方法を調べる方法としてTypescriptを使うのも良さそうです。

class car {
    speed:number;
    private _ownerName:string;

    accelarator(accelarateSpeed:number)
    {
        this.speed += accelarateSpeed;
    }

    public get ownerName():string {
        return this._ownerName;
    }
    public set ownerName(name:string) {
        this._ownerName = name;
    }
}

このクラスをes5準拠でコンパイルすると以下のjavascriptファイル(car.js)が生成されます。

var car = /** @class */ (function () {
    function car() {
    }
    car.prototype.accelarator = function (accelarateSpeed) {
        this.speed += accelarateSpeed;
    };
    Object.defineProperty(car.prototype, "ownerName", {
        get: function () {
            return this._ownerName;
        },
        set: function (name) {
            this._ownerName = name;
        },
        enumerable: true,
        configurable: true
    });
    return car;
}());

es2015(es6)準拠でコンパイルすると以下のjavascriptファイル(car.js)が生成されます。

class car {
    accelarator(accelarateSpeed) {
        this.speed += accelarateSpeed;
    }
    get ownerName() {
        return this._ownerName;
    }
    set ownerName(name) {
        this._ownerName = name;
    }
}

インタフェース

microsoft独自仕様としてTypescriptはinterfaceを使うことができる。コンパイル時に必須メソッドチェックなどを行ってくれます。

interface vehicle
{
    speed:number;
    accelarator(accelarateSpeed:number);
}
class car implements vehicle {
    speed:number;
    private _ownerName:string;

    accelarator(accelarateSpeed:number)
    {
        this.speed += accelarateSpeed;
    }

    public get ownerName():string {
        return this._ownerName;
    }
    public set ownerName(name:string) {
        this._ownerName = name;
    }
}
class motorcycle implements vehicle {
    speed:number;

    accelarator(accelarateSpeed:number)
    {
        this.speed += accelarateSpeed;
    }
}

リンク

Webアプリのコンポーネント化

vue, reactなどを使ってWebアプリを作成する時、どのようにコンポーネント化していくのが良いのでしょうか? 今、その設計方法(ベストプラクティス)に関心を持っています。

以下の記事は参考になりそうです。

iOSのStoryboard的なツールは便利かもしれない。

nodebrewでnodeインストール

フロントエンド実行環境の最初の一歩、nodeのインストール。今までは、homebrewを使ってインストールしていました。

brew install node

しかし、これだと複数バージョンを混在させることができないので、nodebrewに変更しました。

brew uninstall node
brew install nodebrew

パッケージ管理はyarnを使いたいので、brewでインストールしました。nodeなしでインストールします。

brew install yarn --without-node
Updating Homebrew...
==> Downloading https://yarnpkg.com/downloads/1.3.2/yarn-v1.3.2.tar.gz
Already downloaded: /Users/unokun/Library/Caches/Homebrew/yarn-1.3.2.tar.gz
🍺  /usr/local/Cellar/yarn/1.3.2: 14 files, 3.9MB, built in 2 seconds

たまにしか使わないとどのようにしてインストールしたか忘れてしまいます…

リンク

wikipediaのデータでdoc2vec

doc2vecでWikipediaを学習する - TadaoYamaokaの日記

を参考に、wikipediaのデータをdoc2vecでトレーニングし、類似単語を調べてみました。

総単語数 2,890,010
頻度10以下 2,364,440
残り単語数 525,570

doc2vecは、トレーニングした単語をmodel.wv.vocabで参照することができます。 単語数が、残り単語数の約半分になっているのは、出現頻度が少ない単語が出現している文を削除した時に別の単語も削除しているからでしょう。

>>> len(model.wv.vocab)
266732

トレーニングした単語は、word_vector(keyedvectors)に辞書形式で保存されます。

>>> model.wv.vocab
'カウンダ': <gensim.models.keyedvectors.Vocab object at 0x1143776d8>,
'持ち場': <gensim.models.keyedvectors.Vocab object at 0x10d97e208>,

結果は、(当然ですが)参考にした記事とほぼ同じになりました。

>>> model.most_similar('リンゴ')
[('花', 0.6139837503433228),
 ('トマト', 0.6134904623031616),
 ('ワイン', 0.6084833145141602),
 ('酒', 0.5981301665306091),
 ('果物', 0.5930838584899902),
 ('コーヒー', 0.5895085334777832),
 ('子供', 0.5830855965614319),
 ('果実', 0.5804908275604248),
 ('ビール', 0.5784652233123779),
 ('食べ物', 0.5778894424438477)]

>>> model.most_similar(positive=["ザク", "ガンダム"])
[('ms', 0.7442907094955444),
 ('モビルスーツ', 0.6582286357879639),
 ('モンスター', 0.652472734451294),
 ('x', 0.6502348184585571),
 ('機体', 0.6486747860908508),
 ('マシン', 0.6468290090560913),
 ('ロボット', 0.6423962712287903),
 ('cpu', 0.6389658451080322),
 ('戦闘機', 0.6290717124938965),
 ('ゲーム', 0.6265822649002075)]

>>> model.most_similar(positive=["猫"], negative=["フレンズ"])
[('動物', 0.6338815689086914),
 ('子供', 0.6299443244934082),
 ('人間', 0.6273439526557922),
 ('親', 0.6224128007888794),
 ('ネズミ', 0.6112015247344971),
 ('犬', 0.6050996780395508),
 ('自分', 0.598896324634552),
 ('魚', 0.5975416302680969),
 ('家族', 0.5973026752471924),
 ('が', 0.5970552563667297)]

ひらがなにすると結果が異なるもが興味深いです。リンゴの場合、カタカナ表記する語彙(トマト、ワイン、コーヒー、ビール)を使うコンテキストで用いられるのでしょうか?

>>> model.most_similar('りんご')
[('みかん', 0.5127906203269958), 
 ('桃', 0.479043573141098), 
 ('さくら', 0.45111995935440063), 
 ('リンゴ', 0.44701433181762695), 
 ('ラーメン', 0.42265254259109497), 
 ('梅', 0.4148010015487671), 
 ('ひまわり', 0.41388049721717834), 
 ('夏祭り', 0.3995071053504944), 
 ('弥生', 0.396240234375), 
 ('祭り', 0.3920435905456543)]

リンク

collection型のソート(Python)

Pythonでcollection型のソートにはOrderedDicを使う。

>>> from collections import OrderedDict
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

リンク

wikipediaのデータでdoc2vec(UnicodeDecodeError)

doc2vecを使ってとあるコーパスのドキュメント類似度を取得してみましたが、思ったような結果が得られませんでした。

そこで、doc2vecの記事が同じように検証できるのか調べてみました。 まずは、これです。

doc2vecでWikipediaを学習する - TadaoYamaokaの日記

手順「頻度の少ない単語を除外する」でUnicodeDecodeErrorが発生しました。

Mecab分かち書きしたwikipediaのデータをpythonで読み込む時に、UnicodeDecodeErrorが発生しました。

$ python ../../../../extract_low_freq_terms.py wiki_wakati.error wiki_lf_terms.1
Traceback (most recent call last):
  File "../../../../extract_low_freq_terms.py", line 12, in <module>
    for line in open(args.input, "r", encoding="utf-8"):
  File "/Users/unokun/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 5844: invalid continuation byte

python、UnicodeDecodeErrorで検索しましたが、それらしい記事は見つかりませんでした。

原因は、mecabによる分かち書きで、バッファサイズが足らなかったことが原因でした。バッファサイズを多くとるとそれ以降の処理を問題なく実行することができました。

mecabはバッファサイズを越えた時点で処理をするため、1文字分のデータを出力していないのだと思います。

変更前
$ mecab -O wakati wiki -o wiki_wakati.error
input-buffer overflow. The line is split. use -b #SIZE option.

変更後
$ mecab -b 100000 -O wakati wiki -o wiki_wakati.error

同じくwikipediaのデータを使っている

word2vecで遊ぶ – Eyepod touch

が参考になりました。

リンク