Data Scientistになりたかったアプリエンジニアのブログ

技術的な諸々を書き留めていきます

SIMフリースマホと世界の携帯電話会社のバンドの関係

今度旅行で香港・深センに行くことになったので、私が持ってる端末で4Gが使える携帯電話会社があるのか調べてみました。

周波数 B1 B2 B3 B4 B5 B6 B7 B8 B13 B17
ZenFone 3 Laser(ZC551KL) × × ×
iPad mini 2 ×
iPhone 7 ×
ドコモ × × × × × × × ×
中国移動香港 × × × × × × × × × ×
中国联通香港 × × × × × × × ×
周波数 B18 B19 B20 B21 B25 B26 B28 B38 B39 B40 B41 B42
ZenFone 3 Laser(ZC551KL) × × × × × × ×
iPad mini 2 × × × × × × ×
iPhone 7 ×
ドコモ × × × × × × × × ×
中国移動香港 × × × × × × × ×
中国联通香港 × × × × × × × × × ×

ElasticSearchのSaaSサービス比較

Elastic Cloud Searchly(small) Bonsai Amazon Elastic
メモリ 1GB 不明 0.5GB 1GB
ストレージ(SSD) 24GB 1GB 2GB 24GB
indices 不明 5 不明 不明
値段 $45/月 $19/月 $20/月 約$16/月

Azureにはマネージドサービスがない。 IBM cloudにもあったが高すぎたで表からは外した。

月2000円出すなら、IaaS上にElasticSearchを構築するのもありかな。

Node.js Design Pattern 2nd Editionの目次訳と感想

1. Node.jsのプラットフォームにようこそ

  • Node.jsの哲学
  • Node.js 6とES2015への導入
  • reactorパターン

    2. Node.jsの必須パターン

  • callbackパターン
  • モジュールシステムとそれらのパターン
  • observerパターン 「callbackパターンとobserverパターンの大きな違いは、観察されてる対象が通知するときにリスナーが単一なのか複数なのかが違う」と書いてあって当たり前といえばそうなんだけど、こういう捉え方をしたことがなかったので、メモしておきます。

    3. コールバックを用いた非同期制御フローパターン

  • 非同期プログラミングの難しさ
  • 素のJavascriptを使う方法
  • 非同期ライブラリ

    4. ES2015以降の非同期制御フローパターン

  • Promise
  • Generators
  • Babelを使ったAsync await

    5. streamを使ったコーディング

  • streamsの重要性を確認する
  • streamsの導入
  • streamsを使った非同期制御フロー
  • Pipingパターン

    6. デザインパターン

  • Factory
  • Revealingコンストラクター
  • Proxy
  • Decorator
  • Adapter
  • Strategy
  • State
  • Template
  • Middleware
  • Command

    7. モジュールを書く

  • モジュールと依存性
  • モジュールを書くときのパターン
  • 繋がれたプラグイン

    8. WebアプリのためのユニバーサルJavascript

  • ブラウザとコードを共有する
  • Webpackの導入
  • クロスプラットフォーム開発の基礎
  • Reactの導入
  • ユニバーサルJavascriptアプリを作る

    9. 先進的な非同期レシピ

  • 非同期的に初期化するモジュールの必要性
  • 非同期のバッチとキャッシュ
  • CPU負荷が高い処理をする

    10. スケーラビリティと設計パターン

  • スケーリングの導入
  • クローニングとロードバランス
  • 複雑なアプリを分解する

    11. メッセージングとインテグレーションパターン

  • メッセージングシステムの基礎
  • Pub/Subパターン
  • パイプラインとタスク分配パターン
  • Request/replyパターン

React+MaterialUI+Expressでスケルトンプロジェクトを作る

まずはexpressプロジェクトを作る

まずはexpressプロジェクトをつくるために、express-generatorをインストールする

$ npm install -g express-generator

インストールできたらexpressアプリを作成。

$ express app_name

app_nameのところは皆さんの好きなアプリ名を入れて下さい。

$ cd app_name
$ npm install

これで必要なnode_modulesがインストールされます。

次に、app_name/routes/user.jsを以下のように編集します。

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.json([{
    id: 1,
    username: "Kiriyama"
  }, {
    id: 2,
    username: "Nikaido"
  }]);
});

module.exports = router;

さらにport:3001でexpressサーバーが起動するように、package.jsonを以下のように書き換えます。

{
  "name": "app_name",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "PORT=3001 node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.18.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "express": "~4.15.5",
    "jade": "~1.11.0",
    "morgan": "~1.9.0",
    "serve-favicon": "~2.4.5"
  }
}

書き換えたら、下記のコマンドを打って、expressサーバーが起動することを確認する。

$ npm start

expressサーバーが起動したら、ブラウザで

http://localhost:3001/users

にアクセスし、

[{"id":1,"username":"Kiriyama"},{"id":2,"username":"Nikaido"}]

が表示されることを確認する。

Reactプロジェクトを作る

まずはReactプロジェクトを作る便利なツールのcreate-react-appをインストールします。

$ npm install -g create-react-app

インストールできたら、app_name直下で、下記のコマンドを実行して、Reactのスケルトンプロジェクトを作ります。

$ create-react-app client

インストールが長いですが、終わったらapp_name/client/package.jsonを開き、以下のようにproxyを追加します。

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "react-scripts": "1.0.14"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy":"http://localhost:3001"
}

これは、create-react-appでスケルトンプロジェクトを作るとデフォルトでは、create-react-appの開発サーバーが立ち上がり、前の段落で作ったExpressサーバーと通信しません。 これでは、開発がしにくいので、port:3001で立ち上がるように設定したExpressサーバーに通信するようにproxy設定をしています。

次に、create-react-appで作ったReactのコードがExpressサーバーからのデータを受け取れるか確認します。

app_name/client/App.jsを開き、以下のように編集します。

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  state = {users: []}

  componentDidMount() {
    fetch('/users')
      .then(res => res.json())
      .then(users => this.setState({ users }));
  }

  render() {
    return (
      <div className="App">
        <h1>Users</h1>
        {this.state.users.map(user =>
          <div key={user.id}>{user.username}</div>
        )}
      </div>
    );
  }
}

export default App;

編集が終わったら、app_name直下npm startをして、expressサーバーを起動した後、app_name/client直下でnpm startを実行します。 実行したら、ブラウザが自動で開きますので、ユーザーの情報がブラウザに表示されて入れば完了です。

Material-UIを導入する

最後に、Reactと一緒に使われることが多いCSSフレームワークMaterial-UIを導入します。

app_name/client直下で次のコマンドを実行します。

$ npm install material-ui@next --save

次にapp_name/client/App.jsを下記のように編集します。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Button from 'material-ui/Button';

class App extends Component {
  state = {users: []}
  
    componentDidMount() {
      fetch('/users')
        .then(res => res.json())
        .then(users => this.setState({ users }));
    }
  
    render() {
      return (
        <div className="App">
          <h1>Users</h1>
          {this.state.users.map(user =>
            <div key={user.id}>{user.username}</div>
          )}
          <Button raised color="primary">
            Hello World
          </Button>
        </div>
      );
    }
}

export default App;

編集を終えたら、再度npm startを実行し、ユーザー名の下にボタンが出て入ればMaterial-UIの導入は完了です。

Homebrewでインストールされるソフトのバージョンを確認する方法

タイトルそのままですが、以下のコマンドで確認できます。

$ brew info "インストールしたいソフトの名前"

丁度、elasticsearchをインストールしようとしたので、試してみると

$ brew info elasticsearch
elasticsearch: stable 5.6.3, HEAD
Distributed search & analytics engine
https://www.elastic.co/products/elasticsearch
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/elasticsearch.rb
==> Requirements
Required: java >= 1.8
以下略

とこんな感じで表示されます。

ES6でのfor...in文とfor...of文の違いについて

ES6(ES2015)を勉強していて衝撃だったのがfor...in文という仕様。すいません、今まで明確に仕様を知りませんでした・・・。

ソースはMozzilaからの引用です。

[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of#for...offor...in_との違い:embed:cite]

Object.prototype.objCustom = function () {}; 
Array.prototype.arrCustom = function () {};

let iterable = [3, 5, 7];
iterable.foo = "hello";

for (let i in iterable) {
  console.log(i); 
}

皆さん、これ何が出力されると思います? 私は、

3
5
7

と出力されると思いました。

違うんです。

0
1
2
"foo"
"arrCustom"
"objCustom"

と出力されるんです。 for...in文は、

オブジェクトの列挙可能なプロパティに対し任意の順番で反復処理を行います。それぞれ個別のプロパティに対し、文を実行できます。

というものなので、プロパティが列挙される出力になります。

ちなみに3, 5, 7と表示させたければ、for...of文を使います。

for (let i of iterable) {
  console.log(i);
}

間違いが多くなりそうなので、今後はfor...of文を基本に、私は使っていきたいと思います。

Quoineから残高情報をAPI経由で取得する

QuoineはJWT(Json Web Token)を使って認証を通して残高情報を取得できます。

今回はnode.jsを使って取得するためのサンプルプログラムを作ってみました。

var request = require('request');
var jwt = require('jsonwebtoken');

var host = "https://api.quoine.com";
var token_id = 'token_id';
var user_secret = 'user_secret';
var path = '/fiat_accounts';
var timestamp = new Date().getTime();
var payload = {
  path: path,
  nonce: timestamp,
  token_id: token_id
};

var signature = jwt.sign(payload, user_secret);

var options = {
  url: host + path,
  method: "GET",
  headers: {
    'X-Quoine-API-Version': '2',
    'X-Quoine-Auth': signature,
    'Content-Type': 'application/json'
  }
};

request(options, function(error, response, body){
  if (!error && response.statusCode == 200){
    var json = JSON.parse(body);
    console.log(json);
  } else {
    console.log(error);
  }
});

jsonwebtokenパッケージを使えば、簡単に認証付きのrequestが作れました。