OmniAICreator/Qiita-1.07M huggingface dataset:
スマートコントラクトでどんなデータを保存できる

アカウント毎の残高ぐらいは全然良いけど、URLとか、ファイルとか、画像とか、どこまで保存できるかを確認したい

## 環境
- ganache を使って、プライベートネットワークを作る
- browser-solidity アプリでコントラクトを操作する

## 確認したいこと
- 文字列を保存する際、長さの制限はどのぐらい？

```javascript
pragma solidity ^0.4.0;

contract StringSaver {
    string storedData;
    
    function set(string newString) public {
        storedData = newString;
    }
    
    function get() public constant returns (string data) {
        return storedData;
    }
}
```

## 手順
- https://ethereum.github.io/browser-solidity/ を使って、上記 ganache で起動しているネットワークに接続する
    - ganache デフォルトは 7545 ポートを起動しているので、browser-solidity の Environment から `Web3 provider` を選択し、Endoint を`127.0.0.1:7545`設定し接続しておく

![スクリーンショット 2017-12-12 19.34.24.png](https://qiita-image-store.s3.amazonaws.com/0/4777/a39b6521-25db-31ac-81dd-55565579f275.png)
![スクリーンショット 2017-12-12 19.35.08.png](https://qiita-image-store.s3.amazonaws.com/0/4777/a13a5a10-73e6-5ebc-fc2f-05758f01ca3c.png)
![スクリーンショット 2017-12-12 19.35.41.png](https://qiita-image-store.s3.amazonaws.com/0/4777/ff19a34c-201c-0116-4dcf-c73edef8bcaf.png)

- 上記コントラクトをbrowser-solidityの編集エリアに入力し、右側の'create'ボタンをクリックし、デプロイする

![スクリーンショット 2017-12-12 19.38.56.png](https://qiita-image-store.s3.amazonaws.com/0/4777/e6ab0d26-6ba0-71c3-e258-27ae00805baa.png)

- プライベートネットワークなので、すぐデプロイされ、下記画像のように関数を操作できるようになります。

![スクリーンショット 2017-12-12 19.40.04.png](https://qiita-image-store.s3.amazonaws.com/0/4777/ff9bc9bd-cfd7-806a-e2fd-60f5446407d6.png)

- `set`の右側のフィールドに設定したい値を入力して`set`をクリックすれば、`set`関数が呼び出されて、最終的にブロックチェーンに書き込まれる

## 試してみた結果
ganache でトランザクションなどを確認すると下記のようになっています。長い文字列を保存できますが、`gas`は結構かかります。

![スクリーンショット 2017-12-12 19.43.31.png](https://qiita-image-store.s3.amazonaws.com/0/4777/274f010b-9d09-08d1-6069-1739f9dbc99e.png)

一番上のトランザクションは関係ないです。

| 文字列            |       gas |
| ----------------- | ---------:|
| 'あいうえお'      |    43,615 |
| 'あいうえお' 10回 |   138,174 |
| 'あ' 2,000回      | 4,135,042 | 

`あ`を 10,000 回すると、`out of gas`エラーになりましたが、アカウントの残高が足りなかっただけでした

## まとめ
- 長い文字列などのデータでも保存できますが、その分の gas が掛かるので、今までの普通のシステムのように使うのは、あんまり現実的ではない
- アカウントの残高制限ではなく、トランザクションまたはブロック単位の上限を確認できなかったが、調べてみたら、下記の回答がありました。
    - [gas - Is there a limit for transaction size? - Ethereum Stack Exchange](https://ethereum.stackexchange.com/questions/1106/is-there-a-limit-for-transaction-size/1110#1110)
    - ブロックとトランザクション単位の gas 制限は固定値ではなく、直近のブロックデータによって調整されるのおで、上記記事は 2016/2/7 の時 3,141,592 でしたが、いま時点（2017/12/13 05:13）の https://ethstats.net 確認したら、block gas limit はなんと、**7,992,222** になっています！！！

<img width="1255" alt="スクリーンショット 2017-12-13 05.01.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/4777/6083a41e-44a7-0fac-22c0-4c0e91f0987d.png">

## 参考記事
- [Ganache で始める Ðapp 開発 · m0t0k1ch1st0ry](https://m0t0k1ch1st0ry.com/blog/2017/12/05/ganache/)
- [Ethereum ＜超初心者の方向け＞Mistを用いたコントラクト開発入門 - ぴんく開発テスト工房](http://pinkworks.hatenablog.com/entry/2017/12/12/004815)
artisan dusk コマンドではなく phpunit コマンドでLaravelDuskを実行してしまうと挙動がおかしくなる

実行前にdusk用の設定ファイルを読み込んだりしているだけで、`php artisan dusk`で最終的に実行されるのは`phpunit`です。

なので、以下のコマンドどちらでもテストが実行されてしまいます。
ただ設定ファイルを読み込んでくれないので、テスト用DBを向いてくれなかったりと挙動がおかしくなってしまいます。

```sh
# 正しいコマンド
$ php artisan dusk tests/Browser/Hoge/HogeTest.php
# 間違ったコマンド、でもExceptionなどは発生しない
$ ./vendor/bin/phpunit tests/Browser/Hoge/HogeTest.php
```
この打ち間違いに気が付かないで、しばらくハマってしまうことが何度かありました。。。
もう同じことを繰り返したくないのでチェック処理を組み込みます。

`php artisan dusk`の実体はDuskCommand.phpです。
DuskCommand.phpから`phpunit`を実行する直前に既存`.env`を`.env.backup`に退避するという処理が動くのでこのファイルの存在有無を判定します。


LaravelDusk用のTestCaseクラスを作成していると思うので、そちらのsetUpに以下を組み込みます。

```php:DuskTestCase.php
namespace Tests\Browser;

use Laravel\Dusk\TestCase as BaseTestCase;

class DuskTestCase extends BaseTestCase
    public function setUp()
    {
        parent::setUp();
        // artisan dusk ではなく phpunit コマンドで実行してしまうことを防止。少々乱暴だが.env.backupが作成されているかどうかで判定する
        // 現在の.envと.env.dusk.XXXが完全一致する場合は.env.backupが作成されないがそのような状況はまず起こらない
        if (!file_exists(base_path('.env.backup'))) {
            $this->fail('phpunitコマンドではなくartisan duskコマンドで実行してください。');
        }
    }
```

# 注意点

ソースコード中のコメントにも書いてありますが、LaravelDusk実行時に使用するenvファイル`.env.dusk.xxx`と`.env`の内容が一致する場合は`.env.backup`は作成されませんので、この判定はうまく動かなくなります。
ただし、テスト用DBを使用したり、各種ドライバをテスト用のものに変更するなどしてテストを書くことがほとんどなのでこの一致するという状況はまず起こらないと考えます。
jupyterhub で ユーザーローカルの Python 環境を利用するには

# jupyterhub とは

[jupyterhub](https://github.com/jupyterhub/jupyterhub) は jupyter のマルチユーザでの利用を可能にするパッケージです。
「jupyterhub でのユーザ認証を通過すると各ユーザ毎の jupyter notebook 環境が利用できる」というわけです。

# 各ユーザのローカルのPython環境を利用するには

「ユーザ毎の jupyter notebook 環境が利用できる」わけですから

1. ユーザの環境はユーザが自由に構築したい
2. 管理者がユーザの要望を受けて共通のPython環境を作るのではなく，ユーザが自分のローカルの環境を使えるように設定したい

という要望が出ることは容易に想像できます。

`1.`に関しては `pip install 何か --user` などで対応するとして `2.`はどう行うとよいでしょうか。

これは `/home/ユーザ名/.jupyter/jupyter_notebook_config.py` に下記のような行を追記することで実現できます。

```Python
import os

# この例では : で複数のPYTHONPATHを設定しています。
os.environ['PYTHONPATH'] = "/home/ユーザ名/foo/bar/lib/python3.5/site-packages:/home/ユーザ名/.local/lib/python3.5/site-packages"

# もし C++ 拡張などをwhlを使わず自分でビルドしてユーザローカルにinstallしている場合は下記のような環境変数設定も
#os.environ['LD_LIBRARY_PATH'] = "/home/ユーザ名/.local/lib"
```

# まとめ

jupyter notebook を一人で使っている場合あまり設定を気にすることは無いかもしれません。
一方 jupyterhub のような共用環境では何か独自の設定したいという場面が出てくるかと思います。
そういった場合にこの記事が一助となればと思います。

以上

# 追記

すみません。昔全く同じこと書いてたことに気がつきました。

https://qiita.com/kozo2/items/1a22ca4b9da6e0364c4c
SwiftとSwift愛好会と出会って１年



Swiftを愛する皆様、お疲さまです。[Swift愛好会 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/love_swift) 13日目を担当します@mizukoA です。
ガチな技術記事を書きたいところですが、Swiftを触り始めて１年くらいで、自分の現在地確認のようなゆる〜い記事を書きます。←Qiitaさんに怒られませんように

####Swift以前に
私は派遣社員で事務職しています。プログラミング云々とは程遠い業務で、Excelの関数・データ集計・ピボット・簡単なマクロを組む等のことをしています。
2011年頃Webデザインの仕事がしたくて職業訓練講座に1年くらい通ってました（HTML,CSS,JavaScriptをさらっと。Adobe PsやAiの使い方に時間を取られました）。
自分は昔からAppleが好きで、受講期間中にSteve Jobsが亡くなって悲しんでいました...。いくつか資格も取ったけど、Web系の仕事には就けず、いつしか諦めていました。

####Swiftとの出会い

そして昨年2016年の秋冬、iPhone7を予約しに行ったらiPad Air2が付いてきました←何か違う。
読んでいた本の中に、初心者がプログラミング学習を始めるのに適した言語は「特にこだわりがなければPythonかSwift」と書かれていました。iPadでプログラミングの学習が手軽にできるApple純正のiPad apps『Swift Playgrounds』が紹介されていたのでDLしました。これが私とSwiftの出会いでした！

####プログラミングまるで初心者がやってみたら、超難しかった😭 

本当に子供向けなの？いやいや負けられない！　
`for loop`が楽しい。自分で`func`を組んだり、`if`、 `switch`で削られました。
いくつか課題が解けるようになってくると、全然わからないけれど、自分が書いたコードでロボットやアニメーションが動くってすごい！楽しい！もっと理解したい！！
今後、ただなんとなく事務職していても面白くないから、アプリを作る人になってみるか！
と、2017年の年始に決めました。


####そして2017年１月、Swift愛好会と出会った！
乾杯🍺から始まる勉強会、最高過ぎる。
みなさんとても親切な方ばかりで、質問しやすくて、たくさん助けてもらっています。
愛好会に参加したことがきっかけで、たくさんのiOSエンジニアと知り合うことができました。国際カンファレンスやミートアップにお邪魔するようになりました。英語もっとできるようになりたい！

初心者向け書籍を3冊読みながらサンプルアプリを作って、私がつまづいたところを書いておきます。
①　Xcodeあるある。
AutoLayoutで制約の付け方。

UserDefaultsに保存する独自のクラス用に「Swift File」を作成した後、エラーにならないはずなのにエラーが出てパニックになる　→　入力し直すと、何事もなかったようにエラーが消える。謎すぎる...
出たエラー　"Editor placeholder in source file"

```
override init() {

} 
```

②　計算機で使った`enum`

```
import UIKit

enum Operator {
    case undefined
    case addition
    case subtraction
    case multiplication
    case division
}
```
をもとにして、列挙型はこのあとswitch文にも使われるのですが、演算記号の半角全角が本当の原因でした...←

③　写真ギャラリーで誤植だらけ
`ViewController`のクラスで`func collectionView`に余分なものがあり、ビルドが通らなかった。自分で調べる癖がついたのでよかったです。


##年内に審査に出すぞ！！自作の個人アプリを鋭意製作中です＼(^o^)／
色々予定が遅れがちではありますが、作っています。
また改めてお知らせします。
年明けの愛好会の合宿でアプリ製作に付いて成果発表ができるように頑張ります。

※参考にした書籍類は後ほど追記いたします。



[Swift愛好会 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/love_swift)  、明日は @yoching さんです！
テーブル駆動テスト in C++

この記事は[Altplus Advent Calendar 2017](https://qiita.com/advent-calendar/2017/altplus)の13日目のエントリです。

最近なぜかJava関連のアカウントにTwitterでフォローされることが多い、JavaマスコットのDukeを愛してやまない竹田です。

# テーブル駆動テスト

今回は、[Go wiki](https://github.com/golang/go/wiki/TableDrivenTests)で紹介されて、Goコミュニティでよく使われている（？）テーブル駆動開発をC++でやってみたいと思います。

テーブル駆動テストとは、テストの入力と期待値をテーブルの行に記載し、テーブルを走査しながら実行していくテストのことです。

例えば、int型の入力を受け取って、2倍する関数`int twice(int x)`のテスト・テーブルは以下のようになります。

| in(入力) | out(出力) |
|:---------|-----------|
| 0        | 0         |
| 1        | 2         |
| 2        | 4         |

このテーブルを使って、テーブル駆動テストを書くと以下のようになります。

```cpp
#include <cassert>

int twice(int x){
    return x * 2;
}

int main()
{
   struct { int in; int out; } table[]{
       {0, 0},
       {1, 2},
       {2, 4}
   };
    
   for(auto [in, out]: table){
    assert(twice(in) == out);
   }
}
```

テスト・ケース毎にAssertを書く必要がなくなり、テーブルに入出力がまとめられているため、関数の入出力仕様に集中することができます。入出力で仕様が決定される純粋な関数のテストに役立ちます。

関数の引数が増えてもテーブルの列を追加するだけで対応できます。文字列とインデックスを取って、インデックス番目の文字を返すat関数のテーブルは、

| 文字列(in1) | インデックス(in2) | 文字(out) |
|:------------|-----------------|-----------|
| "abc"       | 0               | 'a'       |
| "Hello"     | 3               | 'l'       |
| "Hello world!" | 7            | 'r'       |

```cpp
#include <cassert>
#include <string_view>

char at(std::string_view s, int index){
    return s[index];
}

int main()
{
   struct { char const* str; int index; char out; } table[]{
       {"abc", 0, 'a'},
       {"Hello", 3, 'l'},
       {"Hello world!", 7, 'o' }
   };
    
   for(auto [s, i, out]: table){
    assert(at(s, i) == out);
   }
}
```

# 最後に

テーブル駆動テストを利用すると、関数の入出力仕様にフォーカスしたテスト・ケースを見通しよく記載することができます。

C++の"unnamed struct"(テーブルの定義に利用している名前なしのstruct)、"range-based for"、"structured bindings"を利用して、快適なテーブル駆動テストにしましょう！
tcpdumpを長時間取得したい

# やりたいこと：tcpdumpを長時間取得したい

IP 192.168.56.100の25番portのパケットキャプチャーを1日分取得したい。
※OSはRedHat7,キャプチャを取りたいNICはenp0s8


## コマンドの準備
コマンドを実行する前に考慮したこと
- 出力されるファイルのサイズ
- サーバーと通信していなくても(ログアウトしても)、キャプチャが取得できること

どれくらいのファイルが出力されるかを/tmpで確認した。

```ruby:/tmp
tcpdump -w test25 -i enp0s8 port 25 and host 192.168.56.100
```
コマンドを実行した5分後にctrl + Cを打鍵

ファイル(test25)の大きさを確認したが200KBほどだったため、単純計算で 

`200KB * 12 * 24 = 57.6MB`

ファイルサイズは問題ない。
## コマンド実行

```ruby:/tmp
nohup tcpdump -w tcpdump25 -i enp0s8 port 25 and host 192.168.56.100 &
```

## コマンドの説明
- nohup
サーバーからログアウトしてもプロセスが落ちない(job)

- -w tcpdump25
パケットキャプチャをtcpdump25というファイルに出力する

- -i enp0s8
パケットキャプチャを取得するNICはenp0s8

- tcpdump XXX &
tcpdumpのプロセスをバックグラウンドで実行

## コマンド実行後
特に必要な処理はない。
私の場合はexitして1日後にサーバーにログインして
`ps aux`　で`tcpdump`のプロセスが存在することを確認した。

## コマンド(プロセス)終了方法
```ruby:
kill [PID]
```

## 確認
出力したファイルをWireSharkで確認した。
Easy PureScript bundling with Parcel

Recently, there's been a lot of buzz about a new bundling tool "that could replace/kill Webpack" called Parcel. Well, put shortly, it already works well enough to replace Webpack for my own uses, and you may find you don't need Webpack to build any PureScript projects anymore either.

I installed Parcel Bundler by using `npm i -D parcel-bundler`. You might choose to install it globally if you want.

## Building JS that requires PureScript builds from /output: Done

In my [Bismuth-Example](https://github.com/justinwoo/bismuth-example/tree/ae50fa45e8b38e2fed83248cf408a31d08e76b93) project, I have a index.js file that imports PureScript builds from output like so:

```js
import * as Main from '../output/Main';
```

This then builds in Parcel by using the CLI by running `parcel build ./flow-src/index.js` and outputs to dist/index.js.

The convenient thing about using the output directly is that while file size suffers from Parcel not being able to efficiently compact and remove dead code from the PureScript output, the normal watch operation works instantly. And so if you are using an editor plugin for PureScript IDE, then you will see Parcel rebuild your bundles almost instantly, in my case being 120-140ms.

This is what you would want to work with most of the time anyway, so it's convenient that setup really doesn't require anything.

## Building JS from --optimize built Pulp: Done

Building an optimized PureScript bundle is easy: you specify a output file and use the `-O` flag. Note that you often don't even need this unless you're a real pilkunnussija, and even then you might not care. Either way, if you really do, the easiest solution is to build to a folder *not* named dist as that's where Parcel will want to build to.

So in my [Web-Audio-Player](https://github.com/justinwoo/purescript-web-audio-player-demo/tree/5eeb729806bfc915297974cb693f0fff0e7bd0f7), I run `pulp browserify -O --to build/app.js && parcel build build/app.js` to build my app. Done.

In my [Vidtracker](https://github.com/justinwoo/vidtracker/tree/693e2b6ece5b2b59308c47c69d7beaa3a8b10df8) front end, I also use a similar method by running `pulp build -O -m FrontEnd --to build/index.js && parcel build build/index.js`.

## Conclusion

For my own uses, I will continue using Parcel unless I run into situations where I really need some specific configurations. And really, considering how PureScript can output a normal bundle and can be consumed from the /output files, I will probably not be reaching for Webpack again anytime soon.

## Links

* Parcel https://parceljs.org/
Ionicで画像をWebから取得＆内部ディレクトリに保存してから表示する

この記事は [Ionic Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ionic) の13日目の記事です

## はじめに

画像などのリソースの追加/更新ペースを高くする場合、毎回アップデートの申請をするのはめんどいので、Webにアップした画像を引っ張ってきて表示してみたいと思います
また毎回だとWebのオーバーヘッドが馬鹿にならないので一度取得した画像は内部ディレクトリに保存して再利用します

## インストールとか

今回は画像のアップロード先としてFirebase Storageを使いますので`firebase`と`angularfire2`をインストールします

```bash
$ npm install firebase angularfire2
```

またIonicの内部ディレクトリに書き込むために[Ionic Native - File](https://ionicframework.com/docs/native/file/)もインストールします

```bash
$ ionic cordova plugin add cordova-plugin-file
$ npm install @ionic-native/file
```

これで準備は完了

## 実装

コードだけ

```src/pages/hoge/hoge.ts
import { Component } from '@angular/core';
import { IonicPage } from 'ionic-angular';
import { File } from '@ionic-native/file';
import * as firebase from 'firebase/app';
import 'firebase/storage';

@IonicPage()
@Component({
  selector: 'page-hoge',
  templateUrl: 'hoge.html',
})
export class HogePage {

  imagePath: string;

  setImagePath() {
    const image = this.getImage();
    const saveDirectory = this.file.dataDirectory;

    // `file://`スキーマがAndroid7以上だと参照できないので取る
    const imagePath = (saveDirectory + image).replace(/file:\/\//, '');

    this.file.checkFile(saveDirectory, image)
      // ファイルが存在すればそのまま使用
      .then(() => this.imagePath = imagePath)

      // なければ
      .catch(error => {

        // Firebase storageからURLを取得して
        const imgRef = firebase.storage().ref('path/to/' + image);
        imgRef.getDownloadURL()
          .then(url => {

            // URLからデータを取得して
            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.responseType = 'arraybuffer';
            xhr.onload = (event) => {
              const data = xhr.response;
              const contentType = xhr.getResponseHeader('Content-Type');
              const blob = new Blob([data], { type: contentType });

              // 保存
              this.file.writeFile(saveDirectory, image, blob)
                .then(() => this.imagePath = imagePath)

                // 失敗してもURLをそのまま渡せば表示はできる
                .catch(() => this.imagePath = url);
            };

            xhr.send();
          });
      });
  }

  private getImage(): string {
    // APIで取ってくるなりなんなり
    return 'hoge.png';
  }

}
```

```src/pages/hoge/hoge.html
<ion-content padding>
  <img [src]="imagePath" />
</ion-content>
```

これで画像の取得表示ができました
やったね
ガンガン画像を追加しましょう

## まとめ

Ionic最高！！ :octopus:
C#でWebServerを０から作ってみる話 編集

# 初めに

こちらはC# Advent Calender2017の15日目の記事になります。

# まずは リポジトリ 
https://github.com/wotakuro/Kotori

# これは何？
スマートフォンゲーム向けのAPIサーバーをC#で作れないかなぁと思い、作成中のものです。
ゲーム向けAPIサーバーなので、HTTP経由でJsonでデータを受け取り、Jsonで返す形を想定しています。

個人的な野望のために作っていたんですが、最近は放置プレイモードになってしまってます…。
(今回Qiitaのカレンダーに投稿して思い出そうキャンペーン中です。)

# 0から作ってみる？
特に何らかのフレームワークを殆どつかわず、Main関数から書いている＋下記部分を自作してるので、「0から」と言い張っています。
 - HttpServerクラスなどを一切使わず、TCP/IPのSocketを読み書きして実装じゃ
 - Jsonも自前で実装じゃ
 - O/R マッパー？そんなものReflection使って自前で SQLからC#のObjectを引っ張るのじゃ！

# とりあえず０ベースで作ってみての感想。

「車輪の再開発なんて無駄なことは辞めるべき」という意見もあるかと思いますが、勉強には非常になるので、一度は無駄な車輪の再開発をするべきじゃないかなぁと思いました。

今回、Httpのサーバーを自前で書くと決めたことで、色々調べました。知らなかったHttpコードがあったりといろいろな発見があって楽しかったです。

あとは自分で書き起こしているので、色々と好きなような仕組み入れたい放題で楽しいですね！
例えば、Httpサーバーとして立ち上がる前に何らかのデータを読んで置いてから起動するみたいな事も仕込み放題です。

# あとは雑に作ってるものの紹介をします。

## 基本的な構造
大きく三つに分けた形で構成をしています。
 - kotori.exe：メインループのプログラムです。Application.dllを動的に読み込み処理します。
 - Application.dll:ユーザーが作成するアプリ本体です。
 - KotoriCore.dll：Httpの機能本体です。kotori.exe・Application.dllから参照されます

この辺りは、Javaのtomcatのwarファイルを配置したら実行するような構造を真似しようと思ってこうなりました。
 

## 簡単なコード例
下記はHttpで受けるAPIを簡単に書いてみたサンプルです

```csharp:LoginModule.cs
/// <summary>
///  http://localhost:8080/login
/// というアドレスにアクセスが来たらこのモジュールが実行されます
/// </summary>
[WebModule("/login")]
class LoginModule : Kotori.Module.IWebModule
{
    /// <summary>
    /// 実行処理を行います
    /// </summary>
    /// <param name="request">クライアントから来たデータをここから取得してください</param>
    /// <param name="response">クライアントへの応答をこちらへ書き込んでください</param>
    public virtual void Exec( Kotori.Http.HttpRequest request , Kotori.Http.HttpResponse response)
    {
        string str = "login user_id:" + request.getParam["user_id"];
        response.Write(System.Text.Encoding.UTF8.GetBytes(str));
    }
}
```
IWebModuleを継承したクラスを自動的に列挙し、そこについている[WebModule]Attributeに指定された名前でURLを決定するようになっています。

そして、各モジュールごとに 下記Exec関数をオーバーライドして挙動を書いていく形になっています
`virtual void Exec( Kotori.Http.HttpRequest request , Kotori.Http.HttpResponse response)
`
「responseにHttp経由で渡されたパラメーターが入るので、それを元に処理し、responseに書いていく」
という流れになっています。

このModuleで、ログイン・ガチャを引いた・ゲーム開始等々を用意していくことでゲームのサーバーを作ってしまおうという魂胆です。

## 現在の課題とか…
### そもそも色々作成中で未整備…
す、すみません。。。
### "multipart/form-data"未対応…
べ、勉強して実装します。。。
### Https対応はどうするつもりなの？ 
nginxでリバースプロキシすれば…ｒｙ
### Http 2.0というのがあってですね・・・
まあ後から考えます…。Http 2.0はリソース先読みのプロトコルなど、Webページ向けに有利な設計で、単なるAPIサーバーだと、そこまで大きな利益もないはず…。( Http Headerのパースコストが下がるくらいでは？)
必要になったら勉強します。。。
### 名前どうしよう・・・・。
「南ことり」さんから、Kotoriっていう名前を付けたんですが…。
うーん。Kotlinと若干被るしなー。などとどうでもよい事に思案していますｗ


雑多な感じでしたが、以上です。
ラズパイ上のNode.jsで音楽再生するときにハマった


## 環境

* Raspberry Pi 3
* Node.js 

```
$ uname -a

Linux raspberrypi 4.4.21-v7+ #911 SMP Thu Sep 15 14:22:38 BST 2016 armv7l GNU/Linux
```

## play-soundモジュール

https://www.npmjs.com/package/play-sound

Node.jsで音声ファイルの再生ができます。

```bash
$ npm i --save play-sound
```

```app.js
'use strict';

const player = require('play-sound')();

player.play('./audiofile/opening.mp3', err => {
    if (err) throw err
});
```

こんな感じで使えて簡単です。

## ハマった所

Raspberry Pi上でインストールしようとして`npm install`したときにはまりました。

```
"alsa/asoundlib.h : No such file or directory"
・
・
・
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/n0bisuke/.nodebrew/node/v9.2.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:258:23)
gyp ERR! stack     at ChildProcess.emit (events.js:159:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:209:12)
gyp ERR! System Linux 4.4.0-78-generic
gyp ERR! command "/home/n0bisuke/.nodebrew/node/v9.2.0/bin/node" "/home/n0bisuke/.nodebrew/node/v9.2.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/n0bisuke/audio/node_modules/lame
gyp ERR! node -v v9.2.0
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
npm WARN audio@1.0.0 No description
npm WARN audio@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! lame@1.2.4 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the lame@1.2.4 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/n0bisuke/.npm/_logs/2017-12-12T16_39_37_274Z-debug.log
```

などが表示されmake errorが出ました。

`asoundlib.h`が無いよってエラーみたいですが、[この辺](https://raspberrypi.stackexchange.com/questions/15018/sound-recording-program-using-nano)を参考に以下を実行してから再度npm installを実行するとうまくいきました。

この`asoundlib.h`のファイルは[こちらの記事](https://users.atmark-techno.com/node/2652)によると`ビルドしているlinuxのルートファイルシステム内(/usr/arm-linux-gnueabi以下)から供給`されているものらしいです。

```
$ sudo apt-get update
$ sudo apt-get install libasound2-dev
```

これで再インストールするとうまくいきました。
UnityでiOS向けのETC2 Textureを作る

# Unity2017.3 でCrunch Texture対応
これに伴いiOSでもETC2のTextureを作成できるようになりました。
[https://blogs.unity3d.com/jp/2017/11/15/updated-crunch-texture-compression-library/](https://blogs.unity3d.com/jp/2017/11/15/updated-crunch-texture-compression-library/)

メモリ使用量は増えますが、PVRTCをこねくり回して綺麗にする作業から解放され、
さらにファイルサイズも大幅に減るためダウンロード時間も短縮されます。



## PVRTC
### メリット
4/2bpp対応なのでメモリ使用量が少ない。
すべてのiPhoneで利用可能

### デメリット
半透明の境界で汚くなる(ディザやClear PVRTCで軽減可)
綺麗にするのに作業/開発コストやお金がかかる

## Crunch ETC2 8bpp
### メリット
PVRTC汚い問題から解放される
ファイル容量が大幅に削減


### デメリット
PVRTC 4bppと比べてメモリ使用量が二倍
iPhone5S 以降のみ対応

## 比較一覧
|               | PVRTC | ETC2 | Crunch ETC2 |
| -------------- | ----- | ---- | ----------- |
| Bit Per Pixel  | 4/2   | 8    | 8           |
| ファイルサイズ | 〇    | 〇   | ◎           |
| メモリ効率     | ◎     | 〇   | 〇          |
| 綺麗さ         | △     | 〇   | 〇          |

# まとめ
メモリ使用量が増えるデメリットはありますが、それを上回るメリットはあるのではないかと感じています。
まだβ版ですが今後の進化に期待です。
シミュレーションゲームにおけるゲームオブジェクトの更新順依存バグについて

この記事は [Tekka Advent Calendar 2017](https://adventar.org/calendars/2330) 12日目の記事です。


シミュレーションゲームにおけるゲームオブジェクトの更新（Update）は、
更新の順序により挙動が大きく変わるケースがあります。

例えばゲームオブジェクトAがゲームオブジェクトBに「電力」を渡し、
ゲームオブジェクトBが「電力」を消費して資源を生産する、という場合。
・Aが1フレームでBに渡す電力：20
・Bが資源の生産に消費する電力：100
であれば、順当に考えればBの資源生産には5フレームかかることになります。

ゲームオブジェクトの更新順が、A・Bの順であれば想定通り10フレームで資源生産が行われます。

1フレーム目：Aの電力受け渡し→Bの電力量20
2フレーム目：Aの電力受け渡し→Bの電力量40
3フレーム目：Aの電力受け渡し→Bの電力量60
4フレーム目：Aの電力受け渡し→Bの電力量80
5フレーム目：Aの電力受け渡し→Bの電力量100→資源生産

しかし、更新順がB・Aの場合。資源生産には1フレーム余分に必要となります。

1フレーム目：Bの電力量0→Aの電力受け渡し
2フレーム目：Bの電力量20→Aの電力受け渡し
3フレーム目：Bの電力量40→Aの電力受け渡し
4フレーム目：Bの電力量60→Aの電力受け渡し
5フレーム目：Bの電力量80→Aの電力受け渡し
6フレーム目：Bの電力量100→資源生産→Aの電力受け渡し

これがいわゆる更新順バグとなります。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ぬわあああこういう処理順依存バグを極力なくしたいから色々頭ひねってたのにィィィ…でもこういうバグも更に頭ひねることで解決できるのも独自エンジンのいいところ。 <a href="https://twitter.com/hashtag/Siv3D?src=hash&amp;ref_src=twsrc%5Etfw">#Siv3D</a> <a href="https://twitter.com/hashtag/gamedev?src=hash&amp;ref_src=twsrc%5Etfw">#gamedev</a> <a href="https://t.co/1imkPem6wP">pic.twitter.com/1imkPem6wP</a></p>&mdash; AiNI＠1日目金曜コ－39b (@aini_bellwood) <a href="https://twitter.com/aini_bellwood/status/927118042244440075?ref_src=twsrc%5Etfw">2017年11月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
更新順バグの実例。
画面中央のギヤのマークのブロックについて、左側2個のブロックは資源を2個続けて受け取りますが、
右側2個のブロックは1個ずつしか受け取れません。

このような処理順依存バグは、更新処理を1フレーム内に複数回行うことで解消できます。

オブジェクトAのPreUpdate：電力受け渡し
オブジェクトAのPostUpdate：制御なし

オブジェクトBのPreUpdate：制御なし
オブジェクトBのPostUpdate：資源生産

とした場合、

1フレーム目のPreUpdate：A:電力受け渡し→B：制御なし
1フレーム目のPostUpdate：A:制御なし→B：資源生産

となり、AとBの更新順が入れ替わった場合でも、

1フレーム目のPreUpdate：B：制御なし→A:電力受け渡し
1フレーム目のPostUpdate：B：資源生産→A:制御なし

このように想定した順序を維持することができます。

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ところでこのゲームですが、コミケで頒布します。<br>1日目金曜日コ－39b。 <a href="https://twitter.com/hashtag/Siv3D?src=hash&amp;ref_src=twsrc%5Etfw">#Siv3D</a> <a href="https://twitter.com/hashtag/gamedev?src=hash&amp;ref_src=twsrc%5Etfw">#gamedev</a> <a href="https://t.co/Pfo0cAyr92">pic.twitter.com/Pfo0cAyr92</a></p>&mdash; AiNI＠1日目金曜コ－39b (@aini_bellwood) <a href="https://twitter.com/aini_bellwood/status/931140646756171776?ref_src=twsrc%5Etfw">2017年11月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

このような複数回の更新を導入したゲームをコミケで頒布します。
1日目コ－39b「Tekka」でお待ちしています。
Rで単換字式暗号(ROT13)

# はじめに
特殊なコーディングでも、特殊なパッケージを使用しているわけでもありません。
仕事で文字列を処理することは少ないため普段使用しない関数などの発見があったため記事として残したいと考えました。
今回はシンプルな内容ですが、段階を踏んで有用な関数作成にも挑戦したいと思います。

# ROT13(rotate by 13 places)とは
単換字式暗号(シーザー暗号)の一つで、アルファベットを一文字毎に13文字後のアルファベットに置き換えます。
例： Hello →　Uryyb
アルファベットは26文字のため、2度暗号化することで元の文字列に戻ることが特徴です。

# Rでコーディング
以下が作成したROT13暗号化関数です。

```ROT13
ROT13 <- function(x) {
  chr.old <- paste(c(LETTERS, letters), collapse="")
  chr.new <- paste(substr(chr.old, 14, 26), substr(chr.old, 1, 13), 
                  substr(chr.old, 40, 52), substr(chr.old, 27, 39), 
                  collapse="", sep="")
  return(chartr(chr.old, chr.new, x))
}
```

## 関数内での処理内容
まず、変換する前の大文字小文字の2*26文字を格納した変数`chr.old`を作成します。
`LETTERS`はデフォルトで用意されている大文字A~Zを一文字ずつ格納しているベクトルで、`letters`は`LETTERS`を小文字にしたベクトルです。
後述しますが、関数`chartr()`で使用するためにベクトル内の各要素を`paste(, collapse="")`で結合します。
変数`chr.new`は`chr.old`の大文字と小文字をそれぞれ13文字ずらした並びにした文字列を格納します。
最後に、関数`chartr()`で引数の文字列を置換した結果を返します。
`chartr(old, new, x)`は`old`と一致する`x`の文字を`new`に変換します。
`old`と`new`は同じ位置の文字が対応します。つまり、`old`の1文字目が`new`の1文字目に、`old`の2文字目が`new`の2文字目に変換されます。

今回の場合だと以下のようになります。
old: ABC・・・NML・・XYZabc・・・nml・・・xyz
new: NOP・・・ABC・・KLMnop・・・abc・・・klm
A→N, X→K, n→a, z→m

## 実行結果
上記関数をテストデータで実行。
![ss_ROT13result.png](https://qiita-image-store.s3.amazonaws.com/0/199826/7330c6c2-7dee-4bc9-f038-2de2abd5a4ab.png)


# 参考文献
https://ja.wikipedia.org/wiki/ROT13
AzureStorage(RA-GRS)のセカンダリからPowerShellでblob複製(リージョン障害時の対処方法)

## 概要
[Azure Storage の停止が発生した場合の対処方法](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-disaster-recovery-guidance)の「オプション 2: セカンダリ リージョンからデータをコピーする」をPowerShellで実現する。

## 前提条件
- 複製元ストレージアカウントがRA-GRS構成
- 複製先ストレージアカウントは事前に作成

## 動作確認環境
| 項目       |バージョン |
|:-----------------|:------------------|
| PowerShell|5.1.14409.1005 |
| AzurePowerShell|5.1.1|

## スクリプト
``` Powershell
# 変数定義
$SrcStorageName = "複製元ストレージアカウント名"
$SrcStorageSubName = "複製元ストレージアカウントが所属するサブスクリプション名"
$SrcStorageRgName = "複製元ストレージアカウントが所属するリソースグループ名"

$DestStorageName = "複製先ストレージアカウント名"
$DestStorageSubName = "複製先ストレージアカウントが所属するサブスクリプション名"
$DestStorageRgName = "複製先ストレージアカウントが所属するリソースグループ名"

# Azure ログイン
Login-AzureRmAccount

# 複製元(セカンダリ)コンテキスト作成
Select-AzureRmSubscription -SubscriptionName $SrcStorageSubName | Out-Null
$SrcStorageKey = (Get-AzureRmStorageAccountKey -storageaccountname $SrcStorageName -ResourceGroupName $SrcStorageRgName).Value[0]
$SrcContextString = "AccountName=" + $SrcStorageName + ";AccountKey=" + $SrcStorageKey + ";BlobEndpoint=https://" + $SrcStorageName + "-secondary.blob.core.windows.net;"
$SrcContext = New-AzureStorageContext -ConnectionString $SrcContextString

# 複製先コンテキスト作成
Select-AzureRmSubscription -SubscriptionName $DestStorageSubName | Out-Null
$DestStorageKey = (Get-AzureRmStorageAccountKey -storageaccountname $DestStorageName -ResourceGroupName $DestStorageRgName).Value[0]
$DestContext = New-AzureStorageContext -StorageAccountName $DestStorageName -StorageAccountKey $DestStorageKey

# 複製元と同名のコンテナを複製先ストレージに作成 
Get-AzureStorageContainer -Context $SrcContext | New-AzureStorageContainer -Context $DestContext | Out-Null

# データ複製
$Containar = Get-AzureStorageContainer -Context $SrcContext
foreach($c in $Containar.name){
  Get-AzureStorageBlob -Container $c -Context $SrcContext | Start-AzureStorageBlobCopy -DestContainer $c -DestContext $DestContext | Get-AzureStorageBlobCopyState -WaitForComplete | Out-Null
}
```

## 参考

[Azure Storage：概要](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-introduction#replication)
[Azure Storage：リージョン障害が発生した場合の対処方法](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-disaster-recovery-guidance)
[Azure Storage：地理冗長 (GRS) のリージョン障害時の挙動について](https://blogs.technet.microsoft.com/jpaztech/2016/08/09/storage-service-grs-failover/)
[Azure Storage での AzurePowerShell の使用](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-powershell-guide-full)
【Ruby】エラトステネスさんの篩にかければ素数が振ってくる

# エラトステネスの篩
素数を求めるためのアルゴリズムです．
以下のステップ（[wiki](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9)参照）を踏むことで簡単に素数を求めることができます．

```
1. 探索リストに2から*x*までの整数を昇順で格納

2. 探索リストの先頭の数を素数リストに移動し，その倍数を探索リストから篩い落とす

3. 上記の篩い落とし操作を探索リストの先頭値が*x*の平方根に達するまで行う

4. 探索リストに残った数を素数リストに移動して処理終了
```

# 実際のコード
```Ruby
def sieve_of_eratosthenes(until_number)
  prime_num_list = (2..until_number).to_a
  0.upto(prime_num_list.size - 1) do |i| 
    break if prime_num_list[i] >= Math.sqrt(until_number)    
    prime_num_list = prime_num_list.reject{ |num| num % prime_num_list[i] == 0 && num != prime_num_list[i] }
  end
  prime_num_list
end
```

# おわりに
プロコンって，アルゴリズムを知っているか知らないかで本当に差が出ますよね
Ruby技術者認定試験Silverを受けたｖ・。・ｖ

本日、Ruby技術者認定試験のSilverを受験し合格しました。
Gold受験へのモチベーション上げと、これから受験する同期のために綴ります。
初投稿で読みづらい内容かもしれませんが、何卒よろしくお願い致します。

<h2>受験した理由</h2>
　島根県に生まれたからです。

<h2>試験の問題について</h2>
　試験の問題について知りたくて読まれていると思いますので、上部に記述します。
　基本的に、公式サイトに記載された出題範囲がまんべんなく出題されました。

<ul><li>Stringクラス、Hashクラス、Arrayクラスのメソッド(いっぱいでた)</li>
　各サイトや書籍の演習問題に出てくる問題に近いものが出た(10問ぐらい)
　別名のあるメソッドは必ず把握しておくこと
　破壊的メソッド,非破壊的メソッドの引っかけ問題が油断した頃に来る

<li>Fileクラス</li>

　ファイルを開く際のオプションとか、読み書き関連のメソッド、ファイルポインタ

<li>クラス定義、メソッド定義、継承</li>

　initializeメソッドとかインスタンス変数とか

<li>例外処理</li>

　どの例外が実行されるかといったものや、exit 1 など

<li>その他</li>

　正規表現
　moduleのinclude
　Rubyのfalse　
　String型へのto_iメソッド
　2,8,10,16進数
　変数のスコープ
　エンコーディング</ul>

<h2>勉強時間</h2>
だいたい3週間程度だったと思います。
少し前に新入社員研修でRuby on Railsを勉強していたので、少し繋がりました。

<h2>勉強に利用したもの</h2>
<b>メイン</b>
<ul><li><a href="http://www.minituku.net/">ミニツク</a></li>
　Rubyのe-ランニング学習サービスです。
　問題を解きながら、分からない問題をぐぐって調査した。
　正直、解答時間よりも検索結果を見ていた時間の方が長かった気がします。
　その際、ブラウザのブックマークからSNSを消しましょう。
　意志が弱いと呑まれてしまう.....

<li>Ruby 公式資格教科書</li>
　模擬問題を解きながら、これまたぐぐって調査した。
　ミニツクの問題に近いものや、模擬問題で出たようなことを本書内で確認</ul>
<b>サブウェポン</b>
<ul><li>模擬問題集(PDF形式でDLできる)</li>
<li><a href="https://rex.libertyfish.co.jp/">REx - Ruby Examination</a> (Rubyのe-ランニング、出来立てほやほや)</li>
<li>Ruby silver合格談を読む(モチベーションアップに繋がる)</li></ul>

<h2>最後に</h2>
　初投稿でドキドキしながら記述しました。
　Qiitaへの投稿にも慣れることができるよう、技術的な面でも資格的な面でも
　脳が腐るまで、ガシガシ学習バシバシ吸収ドシドシ投稿したいと思います。
【Java】ソースを書く際に…徒然覚書①

　▼変数の宣言は、ループの中でするべきか外でするべきかよく考える
　　　⇒スコープが短い方が、機械の処理時間が短くて済む

　▼同じ事を言ってしまっている箇所に注意
 　　　int i = a + b;
          　　　int sum += i;
          
          　　　　　⇒　int sum += a+b;
               
               　　　　同じ事を言ってる箇所はまとめよう！
 
 　▼配列にするべきか否かをよく考える
  　　　⇒　後から「○番目」等と指定して取り出す必要がある場合のみ
     
    　▼繰り返し処理に使われているものは変数にする
    
    　▼
やはりお前らの助っ人は間違っている。

<p>Swift、それはプログラマに残された最後の開拓地である。そこにはプログラマの想像を絶する新しい文法、新しいフレームワークが待ち受けているに違いない。<br />
これはプログラマ最初の試みとしてn年間の調査プログラミングに飛び立った、宇宙船Xcode号の驚異に満ちた物語である。</p>

<p>プログラマ35年定年説というのがあるが、それを超えて働いていると、様々な炎上プロジェクトに遭遇する。そこで知った興味深い事象について報告する。</p>

<p>プロジェクトが炎上すると、人を投入してなんとかするというのは常套手段である。そうやって間に合わない部分、足りない部分を助っ人達に作らせるのだが、炎上がなんとか収まると助っ人達は撤退する。その後は、元のチームのメンバーが助っ人達が作ったコードを保守することになる。</p>

<p>面白いのは、元のチームのメンバーに助っ人のコードのことを聞くと、酷い、というより、知らない、という反応を示すことだ。一切関わりたくないことのようだ。助っ人のコードが本当に酷いのかは分からないが、その後、元のチームのメンバーが、俺には関係ない！という態度で扱えば、そこからバグは発生する者だ。このコードはチームのお荷物となる。</p>

<p>興味深いのは、プロジェクトが長期の場合、元のチームのメンバーが殆ど入れ替わることは驚くべきことではない。でも、元も助っ人も関係ない彼らに助っ人コードのことを聞くと、俺には関係ない！という反応を示すことだ。</p>

<p>助っ人を投入する場合、チームの関係に気を使わないと、そのツケは長期にわたって払わないといけなくなるという、良い教訓だと思う。</p>

<p>今回、新たなスタイルに挑戦してみたが、自分にマサカリが飛んでこないことを願っている。</p>

関連情報
<a href="https://qiita.com/advent-calendar/2017/cocoa">Cocoa Advent Calendar 2017</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
Angular POSTでXSRFに引っかからないようにするには

## Angular4 + Django Rest Framework

DjangoからAngularが提供されている場合。

app.module.tsに

```ts:app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {HttpModule , XSRFStrategy , CookieXSRFStrategy } from '@angular/http'
                  // ^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^ この2つのモジュールを追加
import { AppComponent } from './app.component';

import { AppService } from './app.service'
...
省略
...

@NgModule({
  
...省略

  providers: [AppService , 
      { provide : XSRFStrategy, useValue: new CookieXSRFStrategy('CSRF-TOKEN' , 'X-CSRF-TOKEN')}
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^これ追加^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      ],

...省略

```

でPostリクエストが通りました！

Angular勉強するには、この本最高です。
[Angularアプリケーションプログラミング](https://goo.gl/cfPWXx)
【Java】ソースを書く際の心得


写経…という言葉。
お寺で心静かに向き合うものもあれば…
本に書かれたコードをただeclipsに打って「動いた～」ってするものもあるｗ

タイピングに問題がなければ、写経は全く造作がなく…それ故に覚えないorz
medamayakiはまさにこのタイプで、始めはめちゃくちゃ身に付きませんでした。

良い先輩に逢い。目から鱗のあたたかな指導を受け。自己学習も重ね…。
それでも、まだまだ道の途中です（数年後この覚書をニヤニヤ眺めるのを楽しみに）

ついつい。思いつきや、手で覚えてソースを書いてしまうのですが…

【初めて知るメソッド。知る機能。知る動き。】
　⇒これらは動かしてみないと理解できないものである
 
 という事を心に刻み。ソースを書く際は
 
 【一つの動き】を綴る度に、必ず動作確認をするようにする！
 
 長く書いてしまうと、どこに問題があるかわからなくなってしまうものである。
 まだ不慣れな間は特に、一つずつ。一歩ずつ。の動作確認を大切にしよう。
 
 理解して、初めて身に着くのだから…。
他の職種の人と一緒に仕事をし、信頼度を高めるために、心がけていること

# はじめに

この記事は、[Leveragesアドベントカレンダー](https://qiita.com/advent-calendar/2017/engineer)13日目の記事になります。

今回はポエミーな感じでお送りします。

---

弊社は営業からプロダクトをアウトプットするところまで、ほぼすべてを社内で行っているため、他職種のメンバーと話したり、議論をしたりする場面がかなり多いです。

なので他職種から信頼されている状態を作ることは仕事上割と重要で、エンジニアがやりたいことや、将来的に起きそうな、エンジニアしか理解していないことに割く工数を確保するためには「◯◯さんが言うならやっとくべきなんでしょう」と思われる状態を作るとスムーズです。

そのために、僕が他の職種の人と一緒に仕事をするときに心がけていることをまとめておこうかと思います。
あくまで僕がやっていることで、かつ、意識してやっているもの（普通にやれることではなく）であって、みんなやるべきということではありませんし、向き不向きもあると思います。ただ、誰かの何かの気付きになればいいかなと思って書いておきます。

あと、前提として、

<font color="red">**何事もほどほどに!**</font>

の精神を持っていないと死んでしまうので、注意してください。



## 10分以内にできる仕事は最初に済ませる

日常的に信頼を高めるためには、なるべく早くレスポンスをし、簡単な作業はすぐさまやってしまうのがいいと思っています。信頼の積み重ねには、大小より数のほうが効果が強いと感じることが多いのと、ちょっとした仕事だからこそ、依頼した仕事がすぐに返ってくると、「この人に頼めばすぐにやってくれる」と認識され、まれにちょっと時間がかかりますよと言えば、「この人が時間がかかるというのだから、時間がかかるに違いない。なぜなら、いつもすぐにやってくれる人だからだ」と、理由を説明するまでもなく納得してくる確率があがります。


## 相手の技術的な知識量を知る

当然といえば当然のことですが、わかっていてもエンジニアは自分の知識をベースにした会話を展開しがちだと思っています。
なので相手の知識量を知ることは重要で、バージョン管理の概念がない人に、gitは便利だと説いても始まりません。そういう場合はexcelで共同編集して事故ったみたいな、相手が経験的に理解している話をするべきで、gitとsvnやcvsとの違いについての話をするべきではありません。これを見極めることは、相手を説得する上で重要です。
また、相手の知識量を知ることは、相手の興味の深さを知ることにもなると思っています。
つまり、相手の知識量が少ないということは、その人に技術的な価値の高さを説明しても効果が薄く、もっと直接的に利益になることを訴えるべきという判断ができます。


## 相手の意見が正しい、あるいは、自分が間違っていると仮定する

相手の意見の背景やプロセスを理解することは、相手に納得してもらう上では重要ですが、それを引き出すことは難しいです。僕の経験上では、そもそもしっかりそれをロジックに落とし込めている人はあまりいない印象です。
なので、相手の意見を一旦正しいものとして、自分自身がその意見を正しいと言うためには、どういうロジックが必要かを考えるようにしています。
たいていの場合は、相手の意見が正しいという結論を導き出すことができるロジックはいくつか見つかります。そうすると、相手が正しいと信じている根拠がある程度明確になり、自分の意見を通したい場合、ただ自分の正しさを押し付けるより、そのポイントを突いた説得をした方が相手は納得しますし、引っかかりがあった場合に、どこに相手が引っかかっているかがわかりやすくなります。また、意外と自分が思いもつかなかった考え方を知るきっかけにもなります。


## 自責で考える

僕が考えている自責とは、「私が悪いです」と認めるということではありません。
問題が発生したり、発生しそうな場面に気づいたら、「自分のせいでこの事象が発生したのだとしたら、どのタイミングで何をしていれば未然に防げただろう」と考えることです。
この繰り返しが、他のメンバーやリーダーが気づいていないリスクに気づくことができる下地になっていて、それをもとに事前に相談することで、「この人がいると安心感がある」と感じてもらうことにつながっていると考えています。
また、これを考えることは、何もしないよりも経験速度を遥かに高めてくれるので、自身の成長のためにも価値が高いはずです。

---

なんだかんだで10以上の案件、会社で仕事をしてきて、セクショナリズムによる殺伐とした空気も結構経験してきた身としては、それぞれの職種がお互いの仕事に関心を持って、歩み寄れる現場を作りたいものです。
Re:VIEWで書いた原稿に隠しノンブルとタチキリ分の余白を挿入する

Re:VIEW(latex)で吐き出したpdfをそのまま同人誌の本文として入稿しようとすると怒られる可能性大です。大体

* ノンブルに(i, ii)とか入っている、そもそもない、順番違う
* タチキリ分の余白がない

とか言われます。こういうのは同人誌印刷所のホームページを漁るとけっこう情報が出てきます。具体的な方法についてみてみましょう。

## 隠しノンブルを入れる & タチキリ分の余白を入れる

解決方法は簡単で、ページごとに隠しノンブルとタチキリ分の余白を入れればOKです。

隠しノンブルについては([ノンブルの入れ方　～隠しノンブル～](http://manga.jp.net/knowhow/151203nombre/)
)が詳しいです。要するに隠しノンブルを使えば人が見えるところのノンブルを自由に作って、実際のページ番号は見えないところに入れるということが可能です(**一応、入稿時に説明したほうがよい**)。

タチキリについては[同人誌初心者のための しまねぇ＆まやちゃん はじめての同人誌](http://www.shimaya.net/hajimete-no-doujinshi/analog04.html)が詳しいです。つまり裁断するとき用に余白入れろってことです。

以上を踏まえて[cpdf](http://community.coherentpdf.com/)というコマンドラインツールでpdfを加工します。ただcpdfだけだと辛い部分があるので、雑にnode.jsでスクリプトを書きます。

```js:release.js
#!/usr/bin/env node

const { execSync } = require("child_process");
const fs = require("fs");

// 環境に合わせて設定を変更する
// B5は WIDTH = 182; HEIGHT = 257;
const PAGE_START = 3;
const WIDTH = 182;
const HEIGHT = 257;
const MARGIN = 3;

execSync("mkdir -p tmp");
// バラして
execSync("cpdf -split book.pdf -o tmp/%%%.pdf");
// 隠しノンブル入れて
const files = fs.readdirSync("tmp").sort();
files.forEach((file, i) => {
  const page = file.split(".").shift();
  const nombre = ((+page + PAGE_START - 1) + "").split("").join("\\n");
  const pos = ["0mm 15mm", `${WIDTH - 1.3}mm 15mm`][i % 2];
  execSync(`cpdf -add-text "${nombre}" -pos-left "${pos}" -font "Courier" -font-size "6" tmp/${file} -o tmp/${page}-nombre.pdf`);
});
// マージし直して
execSync(`cpdf -merge ${files.map(f => f.replace(/(\d{3})/, "tmp/$1-nombre")).join(" ")} -o tmp/merged.pdf`);
// 余白を入れる
execSync(`cpdf -mediabox "-${MARGIN}mm -${MARGIN}mm ${WIDTH + MARGIN * 2}mm ${HEIGHT + MARGIN * 2}mm" tmp/merged.pdf -o book-release.pdf`);
execSync("rm -rf tmp");
```

Re:VIEWのプロジェクトのルートで実行すると、以下のようにbook-release.pdfに結果が出力されます。簡単ですね!

<img width="535" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/380/cfec3c82-28ee-6faf-4c10-da50ef09883f.png">


※ページ番号の開始(`PAGE_START`)、タチキリの余白(`MARGIN`)等は各印刷所の指示に従ってください。このケースではページサイズは同人誌ではポピュラーだと思われるB5サイズ用に設定されています(Re:VIEWの設定例は以下)。ページサイズに合わせて修正してください。

```yaml:config.yml
texdocumentclass: ["jsbook", "10pt,b5j,uplatex,oneside"]
```
180度以上の角度(へこみ)が存在している多角形の角度計算プログラム

# はじめに
この記事は，[某アドベントカレンダー](https://qiita.com/advent-calendar/2017/sp2lc)の繋ぎ用にひねり出した記事ですが，それなりに参考になる事柄かもしれません．そのときは参考にしていただければ幸いです．

# やること
以下のような，へこみが存在している多角形の全ての内角の角度をプログラムで算出する．
※座標の数字は適当です．特に意味はありません．
![polygon.png](https://qiita-image-store.s3.amazonaws.com/0/183396/2f25cf89-180c-62d2-c66c-ae18f5e159f8.png)

# 理論
## 角度計算式
座標平面上において，3点 $A(x\_0, y\_0), B(x\_1, y\_1), C(x\_2, y\_2)$ が与えられたとき，ベクトルの内積の式より，
$$ cos\theta = \frac{(x\_0-x\_1)(x\_2-x\_1)+(y\_0-y\_1)(y\_2-y\_1)}{\sqrt{(x\_0-x\_1)^2+(y\_0-y\_1)^2} \times \sqrt{(x\_2-x\_1)^2+(y\_2-y\_1)^2}}$$
と，$\angle ABC$による$cos\theta$を求めることができます．
この値よりアークコサインを計算すると，$\angle ABC$の角度$\theta$を求めることができます．
しかしそれは，**角度が全て180度以下だった場合の話**に限ります．例えば上の図のようなケースでは，$\angle DEA$を計算すると，算出される角度の値は外角のものとなります．人間ならば見ればわかりますが，プログラムに実装する場合は，当然なす角が180度以上か否かを判定する必要があります．
そこで使用されるのが，「**三角形の符号付き面積**」という概念です．
## 三角形の符号付き面積
3点$A(x\_0, y\_0), B(x\_1, y\_1), C(x\_2, y\_2)$で構成される三角形において，
$$S=\frac{1}{2}(x\_0y\_1+x\_1y\_2+x\_2y\_0-y\_0x\_1-y\_1x\_2-y\_2x\_0)$$
で与えられる値$S$を，三角形の符号付き面積と言います．
三点$A, B, C$を与えたとき，

- 求めたい内角が必ず2番目(この場合は$B$)にある．
- 点$A, B, C$が必ず反時計回りの順で与えられている．

これら二つの条件を満たしている場合，この符号付き面積$S$の値が**正ならば180度以下**，**負ならば180度を超える**角度となります．

# 実装
理論を踏まえてプログラム(C言語)に起こします．
なお，プログラム上でも三点$A(x\_0, y\_0), B(x\_1, y\_1), C(x\_2, y\_2)$を与えて角度を計算しますが，プログラム中では点$B(x\_1, y\_1)が(0, 0)$になるように三点の値を設定し直しています．理論での式で$x\_1=0, y\_1=0$となっているものが実装されています．
プログラムの解説に関しては，コメントを参照してください．

```c

#include <stdio.h>
#include <math.h>

//x,y座標型
typedef struct point{
    double x;
    double y;
}Point;

//弧度法の角度から度数法へ
double rad2deg(double rad){
    return rad * (180 / M_PI);
}

//角度計算関数
double angle(Point a, Point b, Point c){
    int i;
    double ang;
    
    Point poly[3] = {a, b, c};
    //2番目の点bを(0, 0)にし，両端点の値もそれに揃える
    double tmpx = poly[1].x;
    double tmpy = poly[1].y;
    for(i = 0; i < 3; ++i){
        poly[i].x -= tmpx;
        poly[i].y -= tmpy;
    }
    
    //ベクトルの内積よりcosθを計算し，角度(0 < θ < 180)を算出
    ang = acos((poly[0].x * poly[2].x + poly[0].y * poly[2].y) 
/ (sqrt(pow(poly[0].x, 2) + pow(poly[0].y, 2)) * sqrt(pow(poly[2].x, 2) + pow(poly[2].y, 2))));
    ang = rad2deg(ang);
    
    //符号付き面積を計算し，符号により実際の角度が180度以下か以上かを判定
    if(poly[2].x * poly[0].y - poly[0].x * poly[2].y < 0){
        return 360 - ang;
    }
    else{
        return ang;
    }
}


```

例の図の多角形での実行結果は以下のようになりました．

```
∠ABC: 81.869898
∠BCD: 113.198591
∠CDE: 21.801409
∠DEA: 270.000000
∠EAB: 53.130102

```

# 参考文献

- [3点からなる角度を求める](http://imagingsolution.blog107.fc2.com/blog-entry-50.html)
- [三角形の面積](http://kyoushien.kyokyo-u.ac.jp/tango/sankakumen2a.html)
Cloud Functions for Firebase のログをコマンドラインで確認する

@mono0926 さんから Stackdriver についてコメントをいただき、それを見るのが一番良さそうです :pray:

* [Stackdriver](https://console.cloud.google.com/projectselector/logs?service=cloudfunctions.googleapis.com)
* [ログの書き込みと表示  \|  Firebase](https://firebase.google.com/docs/functions/writing-and-viewing-logs#using_the_stackdriver_logging_ui)


---

Cloud Functions のログを見るのに一番手っ取り早いのは、管理画面から直でログをみる方法です。

![ezgif-4-34ea461a5b.gif](https://qiita-image-store.s3.amazonaws.com/0/5678/b5559bda-3165-af12-a3a0-c6daab6409bf.gif)

リアルタイムにログも流すことができて、ログレベルも見やすいですね。

しかし欠点があって、1行が長いログを開いてスクロールすると下まで見切れずに次のログが表示されてしまったり、ログをコピーしようと思ってもうまくコピーできません。

Developer Tools で要素の検証からアクセスすればみれますが、面倒ですね。

## firebase functions:log

そんな時はコマンドラインからログを参照しましょう。

`firebase functions:log` のコマンドでログを取得して表示できます。
`--only functionName`, `--lines 10` のように引数をつけてログの取得もできます。

実際にやってみると

```bash
$ firebase functions:log --only addMessage --lines 5
2017-12-12T13:32:41.096Z N addMessage: undefined
2017-12-12T13:34:30.832550500Z D addMessage: Function execution started
2017-12-12T13:34:30.832615922Z D addMessage: Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
2017-12-12T13:34:31.411Z I addMessage: IncomingMessage {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,

..中略..

        finished: false,
        _head
2017-12-12T13:34:32.053563601Z D addMessage: Function execution took 1222 ms, finished with status code: 303
```

という感じでコマンドラインでログを取得できました。これならコピペもできますね。

しかし長すぎるログは途中でカットされてしまうようです。 :cry: 
カットされたログは2500文字程度だったので、その程度が目安かもしれません。

## コマンドラインでもログを Streaming したかった

コマンドだとログを1発取得しかできずに Streaming することができません、対して管理画面ではログが Stream で流れてきます。

10秒に1回 `firebase functions:log` を叩いて、新しいログがあればそれを表示する仕組みを作ればコマンドラインでも Streaming になるのではと思い、やってみました。

![Screen.gif](https://qiita-image-store.s3.amazonaws.com/0/5678/e363cba0-6113-2ea1-f82a-6dae36934ec8.gif)

Gif の再生時間が長くてわかりにくいですが、コマンド実行後は待っているだけで最新のログが取得されていきます。

しかしこのやり方は **失敗** で、理由は以下です。

* `firebase functions:log` の取得が遅くログが出てくるまで結構ラグが生まれてしまう
* ログの取得は重いようで、連続してアクセスすると 500 エラーが返ってきてしまう
    * サーバに負荷をかけてしまうようなのでログのポーリングはすべきでない

ソースコードは以下に公開していますが、使用は非推奨です。
https://github.com/starhoshi/firebase-log-tailer

## 結論

* リアルタイムのログを眺めたいときは管理画面からログを眺めましょう
* ログをコピーしたいとき、長いログをみたいときは `firebase functions:log` で確認しましょう
RPGツクールMVのタッチ操作を改善する2017

この記事は [RPGツクールMV Advent Calendar 2017](https://adventar.org/calendars/2288) 13日目の記事です。

RPGツクールはPCやコンシューマーで発達してきた背景からか、UIがコントローラーのある端末に向けたものになっていて、タッチ操作で完結させようと思うとユーザビリティ（使いやすさ）がガタ落ちしてしまいます。

もちろん、この3年で対策のためのプラグインやノウハウも積み重なってきましたが、個人的に残っていた不満点が

- **キャンセルが2本指タップって！**
- 「目的地をタッチして待つ」移動方法がちょっと…なんとなく歩き回りたいときはどうすればいいの？

#キャンセル操作について

ツクールMVの「キャンセル」ボタンは、タッチ操作では「2本指タップ」に割り当てられています。しかし、覚えにくいし直感的ではないし、キャンセルのたびに（2本の指を空けるために）スマホを持ち直さなければなりません。
対策したいのですが、全ての入力ウインドウを改造して「戻る」選択肢を逐一追加するのは現実的ではありません。
そこで、[uchuzineさんの仮想ボタンプラグイン](https://qiita.com/uchuzine/items/045f5bf87c331528daae)を参考に、キャンセルだけのボタンを常時設置するプラグインを書いてみました。

http://shinnoji.main.jp/jimen75th/game/js/plugins/SNZ_CancelButton.js

自分用なので至らない点もあるかもしれませんが、ご自由にお使いください。

<img width="687" alt="スクリーンショット 2017-12-01 20.54.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/27911/223e375b-f43b-6d2a-54e2-31a097c894b2.png">
<img width="687" alt="スクリーンショット 2017-12-01 20.56.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/27911/6f5ccb7b-1cef-9fc4-fb61-2166a588f1fc.png">
画面右下が、今回のプラグインで追加されたボタンです。

- マップ画面では「メニュー」ボタンを表示
- その他では「戻る」ボタンを表示

どちらを押しても、二本指タップと同じ挙動になります。
プラグインコマンドでこのボタンを隠すこともできます。

ただ、「メニュー不可」設定の間はメニューボタンを隠す処理が必要になることは　おととい気づいたので、その処理はまだ入れていませんごめんなさい。自分のためにも、後日追加しておきます。

##仕組み

###canvasを追加しました

ちょっと反則技です。
ゲーム画面全てに同じボタンを配置する手っ取り早い方法として、小さなcanvasを追加してそこにボタンを配置しています。全シーンにまたがってオーバーライドするのは無理だと判断しまして…。プラグインでシーンが追加されることもよくあるし。
ただ、描画レイヤーが増えた分、アニメーションがもっさりする場合があります。

###ボタンを配置するだけのためにcanvas要素を追加したのはなんで？

imgタグで良くね？…いえ、理由があります。
ダブルタップによるズーム対策です。
スマホのブラウザから画像をダブルタップすると「これが見たいんでしょ？」と画像だけをズームしてくれます。ふだんは便利な機能ですが、インタラクティブな操作には邪魔になるので、canvasに置き換えることで回避しているのです。


#移動操作について

かくいう私はスマホゲーには疎いので、マップ移動操作の最適解は模索中なのですが、最近ポケ森をやって使いやすかったので、挙動を真似したくなりました。

- 一点を短くタップすると、その位置に移動して調べる。これはツクールMVデフォルトの挙動と同じ
- 長くタップし続けると、タップしている方向に移動を続ける。指を離すと歩くのをやめる

デフォルトでもタップし続けると似た感じにはなりますが、指を離しても「直前に指を置いていた位置まで歩き続けるのをやめない」ので、立ち止まってほしいのに通り過ぎてしまってイラッとする結果になります。
これを改善するためにプラグインをクラフトしてみました。
トリアコンタンさんの[マップタッチ仕様変更プラグイン](https://triacontane.blogspot.jp/2015/11/blog-post_16.html)を改変させていただいたものです。

http://shinnoji.main.jp/jimen75th/game/js/plugins/SNZ_ChangeMapTouchPolicy.js

こちらもご自由にお使いください。改変元のライセンスに基づいてMITライセンスとします。
さらに別途導入した方がよさそうなプラグインを挙げておきます。

- ダッシュを常時禁止にできるプラグイン[SlowandSlow](https://tm.lucky-duet.com/viewtopic.php?t=2350)
- タップした時のハイライト表示を変えたり隠したりできるプラグイン[Destination Sprite](https://forums.rpgmakerweb.com/index.php?threads/destination-sprite.50602/)

*ダッシュの常時禁止を勧める理由は、ダッシュ可になっていると「目的地まで移動する」速度が速すぎて、タップ長押しの際に操作しづらくなってしまうからです

##手で操作キャラを隠さないために

「指を置きっぱなしで歩かせる」という操作体系にすると、操作する手と反対方向の斜め上側（右手操作のときは左斜め上）に歩かせたときに、とても使いづらいです。手でプレイヤーキャラクターが隠れてしまううえに、指が一番届きにくい箇所を押し続ける必要があるためです。対策は2つありそうです。

###あまり斜め上方向に歩かなくていいマップにする
手でキャラが隠れる方向には極力操作させないように、マップの構造を見直す必要があります。上移動を全廃することは難しいですが、せめて「斜め上」ではなく「真上」に動けばいいようにするとか。
ポケ森の場合は「奥から手前に移動して、メニューボタンで他のマップに遷移」という動線にしていることで「使いづらい方向に歩かせない」工夫をしているようですね。

###自キャラを大きく表示させる
指で隠れてもなんとかなるようにキャラを大きめに表示できると、さらに使いやすくなりそうです。
とりあえず、上記のサンプル画面では、マップ画面だけズームさせるプラグイン[DP_MapZoom.js](https://github.com/drowsepost/rpgmaker-mv-plugins/blob/master/DP_MapZoom.js)を採用していますが、もっと思い切って大きくしたほうが良さそうですね。ただ、あまりズームすると今度は周りが見渡せなくなってしまうので悩みどころです。
Google Homeが日本昔話を朗読してくれました。

ちきさんです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「OK グーグル、娘を泣き止まして」がしたい。</p>&mdash; Yosuke Kurami (@Quramy) <a href="https://twitter.com/Quramy/status/940453024400531456?ref_src=twsrc%5Etfw">2017年12月12日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

そんなことができたら最高ですね。

さて、**Google Homeが日本昔話を朗読してくれるようになったので共有します。**

Google Homeが朗読してくれるんですよ、小さいお子さんのいる家庭には朗報じゃないですか？

しかもIFTTTみたいな小難しいことは一切必要ありません。とても簡単です。

## おとえほん

まずは [おとえほん](http://www.otoehon.com/01/index.html) というCDが売られているので手に入れます。Amazonでさくっと買えます。

おとえほん がどういうものかと言うと、上記サイトでは

> おとえほんは、名前のとおり、聴く絵本。オーケストラアレンジされた音楽をバックに、女優の南果歩、鶴田真由がやさしく昔話を語ります。その音楽は単にBGMではなく、映画のサントラのように、物語の背景を艶やかに彩ります。心あたたまる語りと叙情豊かな音楽が相まったおとえほん。おとえほんを聴いて、想像力を育み、感受性豊かなお子さまに育ってほしいと切に思っています。

と解説されています。
お子さんの知育にぴったりですね！

まだ買っていませんが日本昔話だけじゃなく世界昔話もあります。

**実はこれをCDプレーヤーで再生すれば要件は達成できます。**が、それでは夢がないですよね？

## iTunesに取り込む

CDをiTunesに取り込みます。

別にiTunesじゃなくてもいいです。MP3とかにできるならなんでも良いです。

以下Q&Aです。

- PCを持っていない。
    - → 買いましょう。
- PCに光学ドライブがない。
    - → 買いましょう
- 買うお金がない。
    - → 職場や学校のPCでこっそり取り込んでアップロードしましょう。
    
## Google Play ミュージックにアップロードする

[Google Play Musicに音楽をアップロード（追加）してGoogle Homeで再生する方法](https://yuki-no-yabo.com/how-to-add-music-to-googleplaymusic/) が参考になりました。

**適当な名前のプレイリストを作ってアップロードした曲を登録するのを忘れないようにしましょう。**
僕は「日本昔話」というプレイリストを作りました。

## Google Homeに朗読してもらう

あとは **「おっけーグーグル、日本昔話の曲を再生して」** と言えば朗読が始まります。まあ実際には音源を再生しているだけですが。

セットで使うと便利なフレーズを挙げておきます。

- 「おっけーグーグル、{プレイリストの名前}の曲を再生して」
- 「おっけーグーグル、音量を3にして」(10段階？)
- 「おっけーグーグル、30分後に止めて」(オフタイマー)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Google Homeが日本昔話を朗読してくれました。 <a href="https://t.co/3bc7UNQzfl">https://t.co/3bc7UNQzfl</a></p>&mdash; ちきさん (@ovrmrw) <a href="https://twitter.com/ovrmrw/status/940615953364140032?ref_src=twsrc%5Etfw">2017年12月12日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

とても心温まる朗読で感動します。これならお子さんの寝落ちも期待できるというものですね。

真面目な話、子供が小さいうちに読み聞かせをすることは発育にとても良い影響を及ぼします。「読み聞かせ 効果」とかでググれば色々調べられます。親が直接読み聞かせをできるならそれが一番良いのですが、実際にはとても大変なのでそういうときはGoogle Homeに手伝ってもらうのもいいかなと思った次第です。

---

以上です。

もうお気付きかもしれませんが、自分で録音したファイルをGoogle Play ミュージックにアップロードしてプレイリストに登録すれば音源をどんどん拡張することもできますね！

それでは良いGoogle Homeライフを。
【Java】定数化する


ソースを書いていて、何度も使うものは変数にするとして。
”固定”の「文字列」で何度も使うものは定数化しましょう。
【定数とは…値を変更できない変数です。final修飾子を指定する事で定数になります】

理由：後から修正がかかった際、一か所を直せば済むから
　　　ソースの可読性が高まるから
   　　変更されたくない値を変更されない様にするから
   
   
定数化の方法：
  final定数は、宣言するときに値を代入する事も、先に宣言しておいて
  後から値を代入する事もできるけれど…代入した後は値は変更できません
  
 定数を宣言する再は【変数名は…全て大文字】
 (複数の単語を繋げる再は＿（アンダースコア）を使います)

　　String inputWords = "あいうえお";
 
　　 　⇒　final String INPUT_WORDS = "あいうえお";
   
   　　　　　⇒　 static final String INPUT_WORDS ="あいうえお";
    
メモ：　定数を定義するとメモリを割り当ててしまうので
　　　　for内には入れない（何度も呼び出されてしまう）
    
    　　定数はメソッドの外に定義する（mainはメソッドですよ☆）
      
      　staticと付ける事により、VMに書き込んでそこから呼び出せるので
        よりメモリを使わないで済むので、static finalで定義しましょう♪
        
        定数化するのは固定のもののみ。値が変化するものはダメ！