OmniAICreator/Qiita-1.07M huggingface dataset:
RaspberryPi経由でNAS(NFS)にあるファイルをAWS S3へ転送する

#はじめに

　チョット古いNAS(NetGear ReadyNas 4000 Ultra 4, RNDU4000-100JPS)を使っているのですが、ハードウェア保証がすでに期限切れてしまっているので、動いているうちにバックアップをしたい！でも、8TBのデータ量をどこに保存するかのも問題があり、HDD単発やRAID1環境にコピーするにも安全性に不安が残る。

どうせバックアップに手間がかかるなら、NASからAWS S3に移動してしまおう！

## RaspberryPi経由ではなくNAS上で実行すればいいのでは？

　ReadyNasはsshでも接続できるけど、今使っているNASとしての機能が使えなくなるのは困る。また、NAS用にカスタマイズされているので追加のパッケージを簡単に導入することができないため、Raspberry Piを踏み台にしてNAS → RaspberryPi → AWS S3にデータコピーしてしまおうというのが目的です。

※Raspberry Piでgoogysを使おうとしたところ、ARM環境ではコンパイルできず断念(2018/09/28時点)。

# 設定
## Raspberry Pi インストール

1. アップデート

```shell
$ sudo apt update
$ sudo apt upgrade
$ reboot
```

1. s3fs関連のインストール

```shell
$ sudo apt install git fuse
$ sudo apt install s3fs
```

## AWS設定
1. S3バケットを作成 (リージョンをメモること)
2. IAMユーザーの作成、作成したS3バケットへの権限設定

## s3fs設定

AWSのユーザー・パスワードを保存

```
$ sudo echo AKIxxxxx:password > /etc/passwd-s3fs
$ chmod 640 /etc/passwd-s3fs
```

## mount先 作成

```
sudo mkdir /mnt/s3.bucket
```

# 実行してみる
## テスト

パーミッションのタグが設定されていないファイルは、piユーザーの権限で見れるようにする。

```
$ sudo s3fs s3bucketname /mnt/s3.bucket/ \
-o passwd_file=/etc/passwd-s3fs -o use_path_request_style \
-o rw,allow_other,use_cache=/tmp,uid=1000,gid=1000 \
-o endpoint=ap-northeast-1 -o url=http://s3.ap-northeast-1.amazonaws.com/ \
-o enable_content_md5 \
--debug -f
```

/mnt/s3.bucket/にファイルを作ったり消したりしてみる。そのとき、画面上に[CRT][ERR]などが表示されていないことを確認。

## 起動時にマウントされるように設定

`/etc/fstab`に追加。

```
s3fs#s3bucketname /mnt/s3.bucket fuse _netdev,allow_other,uid=1000,gid=1000,passwd_file=/etc/passwd-s3fs,endpoint=ap-northeast-1,url=http://s3.ap-northeast-1.amazonaws.com/ 0 0
```

`sudo mount -a`でfstabをテスト。`df`で`s3fs`が追加されていればOK。

## ファイルコピー

古いNetgearのReadyNasにログインするとき、鍵認証でsshログオンしても、必ずパスワードを聞かれてしまうので`sshpass`などを使用してログイン時のパスワードを自動入力させる。そして、`sshpass`を使うことでバックグラウンド実行可能。

あとは、rsyncでもscpでもお好みのコマンドでファイルを`/mnt/s3.bucket/`にコピーしてください。

```
$ sshpass -p "netgear1" rsync -av rn4000:/c/document /mnt/s3.bucket/ > /home/pi
/rsync.log &
```

# その他

## パフォーマンス
Raspberry Pi 3Bで動かしてみましたがCPU使用率 2%程度なので、他のアプリと共存させても大丈夫そうです。

## 転送量

8TBをS3に転送するためにかかる時間を大まかに計算

```
 eth0  /  traffic statistics

                           rx         |       tx
--------------------------------------+------------------
  bytes                     3.13 GiB  |        3.15 GiB
--------------------------------------+------------------
          max           93.72 Mbit/s  |    96.87 Mbit/s
      average           15.82 Mbit/s  |    15.89 Mbit/s
          min               0 kbit/s  |        0 kbit/s
--------------------------------------+------------------
  packets                    3301274  |         2928216
--------------------------------------+------------------
          max               7998 p/s  |        8378 p/s
      average               1986 p/s  |        1761 p/s
          min                  0 p/s  |           0 p/s
--------------------------------------+------------------
  time                 27.70 minutes
```

- 約30分で3GBでした。10分あたり1GB。1分で100MB
- 1日＝1440分、1440 * 100MB = 144GB/日
- 8TB = 8192GB. 8192GB / 144GB = 56.8日

プロバイダから警告が来ないことを祈りたい。
【Android】Kotlinのfuel内でのポップアップ表示処理でつまった件について【Kotlin】

# はじめに
Android初心者です。
最近、Androidアプリを開発できる途中に詰まった部分があり、それについて投稿しようと思います。
**※初心者であるため、間違いがあればご指摘お願いします。**

# 環境
- OS:Windows 10
- PC: HP HP Spectre x360
- Android studio 3.1.4
- Emulator : API 26

# fuel(HTTPクライアントライブラリ)内でのポップアップ表示
まず実現したかったことは、
1. fuelを使用して、APIをたたき、各種情報を取り出す
2. そして、取り出した情報をポップアップ表示で表示させる
といったことを実現させます

# プログラム例

```kotlin

 Fuel.post(" APIのURL ", listOf("number" to 【入力情報】, "usr" to 【入力情報】)).responseString { request, response, result ->
                when (result) {
                    is Result.Success -> {
                        if (res_code == 0) {
                                    runOnUiThread { alert(表示させる情報) {
                                    title = "タイトル名"
                                    yesButton {}
                                    noButton {}
                                    }.show()

                            } else {
                                Log.d("error", "undefined")
                            }
                        } else {
                            Log.d("Result", "Error")
                        }

                    }
                }

            }

```

重要なのは、fuel内でポップアップ表示する部分を

```kotlin

runOnUiThread { 
}.show()

```
の中に処理を書きます。
別のスレッドでUIを表示させるようにすると上手くいきました。
lubuntuにtrema-edgeをインストールしてみる

# はじめに
OpenFlow1.3を試してみようと、Lubuntu16.04 LTS にtrema-Edgeをインストールしようとしたら躓いたので、まとめてみる。

#やったこと
Lubuntu16.04だと、trema-Edgeにbundle installして、rakeを実行するときに、どうしてもエラーが出てしまった。
そのため、Lubuntu14.04で環境構築できるか試してみた。

#作業環境
今回は以下の環境で構築する。
・Lubuntu14.04 LTS

#環境構築
まず、以下のコマンドを実行し、環境構築に必要なパッケージリストの更新とインストールを行う。

```
$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get install -y build-essential git gcc g++ make libpcap-dev 
```

次に、rubyをインストールする。今回はソースからビルドを行った。
rubyのバージョンは2.0.0以上であればいいようなので、ruby-2.5.1をインストールしてみる。

```
$ sudo wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz
$ sudo tar xzvf ruby-2.5.1.tar.gz
$ cd ruby-2.5.1/
$ sudo ./configure --prefix=/usr
$ sudo make
$ sudo make install
$ cd
$ ruby -v
```

ここでbundlerをインストールしておくが、ただbundlerをインストールしただけだとエラーが出たので、少し古いバージョンをインストールする。
また、同時にtrema-edgeをgit cloneする。

```
$ sudo gem install bundler -v 1.10.6
$ git clone https://github.com/trema/trema-edge.git
```

ここで、git cloneしたtrema-edgeにbundle installしてみたが、rake実行時にエラーが出たため、Gemfileを編集しておく。

```
$ cd trema-edge/
$ vi Gemfile 
```

また、Gemfileは以下のように変更した。

```
source 'https://rubygems.org'

gem 'gli', '~> 2.11.0'
gem 'paper_house', '~> 0.6.2'
gem 'pio' ,'0.30.0'

group :development, :test do
  gem 'rubocop', '~> 0.27.1'
end

group :development do
  gem 'aruba', '~> 0.6.0'
  gem 'coveralls', '~> 0.7.0', require: false
  gem 'cucumber', '~> 1.3.15'
  gem 'flay', '~> 2.5.0'
  gem 'flog', '~> 4.2.1'
  gem 'reek', '~> 1.3.7'
  gem 'rspec', '~> 3.0.0'
  gem 'yard', '~> 0.8.7.4'
  gem 'rake', '< 11.0'
end

### Local variables:
### mode: Ruby
### coding: utf-8-unix
### indent-tabs-mode: nil
### End:

```
編集を終えたら、bundle installを実行し、rake のバージョンを指定して実行する。
最後にtrema-edgeのバージョンが確認できたら、環境構築の完了。

```
$ bundle install
$ rake _10.5.0_
$ ./trema -v
```

#おまけ
Lubuntu14.04は2017年4月にサポート期限が切れている。
そのため、せっかくなのでLubuntuのバージョンを上げてみる。
Lubuntuのバージョンを上げるために、以下のコマンドを実行した。

```
$ do-release-upgrade -c
# osのリリース情報の確認
$ sudo do-release-upgrade
# osのupgrade
```

＊Lubuntu16.04へアップグレード後も、trema-edgeの動作することを確認できました。

#まとめ
Lubuntu16.04 LTS にtrema-Edgeをインストールしようとして躓いたが、とても回りくどい方法でインストールできた。
自分の技術力ではLubuntu16.04に直接trema-edgeをインストールできなかったので、できた方にはやり方をまとめていただけるとありがたいです。
Firebaseの管理画面からプッシュ通知を送る方法

こちら↓の記事でFirebaseの設定をしたので、今回は管理画面からプッシュ通知を送る方法を紹介します。

[Firebase Cloud MessagingをつかってiOSアプリにプッシュ通知を送ろう（前編）](https://qiita.com/toshi586014/items/5dea32faab94828fae75)

[Firebase Cloud MessagingをつかってiOSアプリにプッシュ通知を送ろう（後編）](https://qiita.com/toshi586014/items/627176dcf461365b2c31#_reference-f6fa2dff7f89cd6df8f3)

## Firebaseにログイン

まず、こちら↓のリンクからFirebaseにアクセスして、Googleアカウントでログインします。

[Firebasse](https://console.firebase.google.com)

![001.png](https://qiita-image-store.s3.amazonaws.com/0/38924/97cc10d7-49d5-84ee-098d-5429064f409b.png)

Firebaseへようこそ画面が表示されるので、プッシュ通知を送りたいプロジェクトをクリックします。

## プッシュ通知を送信

Firebaseにログインしたら、プッシュ通知を送信します。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/38924/c0b2543a-9023-917b-2fea-98513494158d.png)

画面左下の「拡大」にある「Cloud Messaging」をクリックします。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/38924/c09a9065-1667-cddd-1d71-c4363652257c.png)

Cloud Messaging画面が表示されるので、「最初のメッセージを送信」ボタンをクリックします（2回目以降は、「新しいメッセージ」ボタンをクリックします）。

![004.png](https://qiita-image-store.s3.amazonaws.com/0/38924/b0b7969a-728f-4cbc-069a-287d567611a2.png)

メッセージ作成画面が表示されるので、プッシュ通知の内容を入力して、設定をします。

- メッセージ文は、プッシュ通知で送信したい文章を入力します。
- メッセージラベルは、Firebaseの管理画面でメッセージを見分けるための名前を入力します。この内容はユーザーには送られません。
- 配信日は、とくに指定がなければ、今すぐ送信を選択します。
- ターゲットは、ユーザーセグメントを選択します。
- ターゲットとするユーザーは、アプリを選択して、iOSもしくはAndroidを選択します。iOSとAndroidの両方に送る場合は、「別のアプリをターゲットにする」ボタンをクリックします。

![005.png](https://qiita-image-store.s3.amazonaws.com/0/38924/7b996a49-f888-930b-f940-c3266b2eeed2.png)

すると、ターゲット選択欄が追加されるので、もう一つのターゲット（iOSかAndroid）を選択してください。

![006.png](https://qiita-image-store.s3.amazonaws.com/0/38924/c0cd461d-e289-a152-4628-4aa1e61b35d6.png)

コンバージョンイベントと詳細オプションは省略できるので、そのままにします。
最後に、「メッセージを送信」ボタンをクリックします。

![007.png](https://qiita-image-store.s3.amazonaws.com/0/38924/86152e07-9630-f2d8-9828-fdead843877a.png)

メッセージの再確認画面が表示されるので、内容を確認してから「送信」ボタンをクリックします。

![008.png](https://qiita-image-store.s3.amazonaws.com/0/38924/c7218ee5-3e3e-4785-46eb-c038c83bd9e8.png)

Cloud Messaging画面に戻って、メッセージが送信されます。

## 送信結果を確認

![009.png](https://qiita-image-store.s3.amazonaws.com/0/38924/4ed18c1d-5ab2-2f0f-9166-75ac92bf6715.png)

送信したメッセージをクリックすると、メッセージの詳細を確認できます（閉じるときは、もう一度メッセージの行をクリックします）。

![010.png](https://qiita-image-store.s3.amazonaws.com/0/38924/c252848a-ed9a-18cd-5e80-7e0b1dba62af.png)

「Reports」タブをクリックすると、プッシュ通知のレポートを見ることができます。
非IT系で高齢な職場だけどがんばってslack導入してみてる

バリバリIT系じゃないけど、slackやってみようかな、という人達に向けて参考になればいいいなと思い、書いてみる。自分の考えの整理と発散のためでもある。


こんな環境でトライ中です。


◆人数と年齢構成
正社員 8
派遣 1
継続雇用　2

だいたいの年齢構成。そういえば年齢よくわからない人もいるので、実際ちがうかもしんないけど、だいたいってことで。

60代　3人
50代　3人
40代　2人
30代　3人（筆者含む
20代　0人

※筆者の立場：
主担当業務は別にあるが、職場ではメールの設定やHPの更新や社内サーバのメンテをなんとなく任されてる。社内SEや情シスというほどでもないが「パソコンの調子がへんだ。何もしてないのに」という問い合わせは私のところにくる。何もしていない、って言うけど、アラート出てクリックしたでしょ。そんな感じ。

slackとかgoogleスプレッドシートとかトレロはingressで覚えた。
（ingress以外でも使ってました）


◆導入交渉

キーワード
「無料」「試験的」「情報共有」

職場のキーパーソンやえらいひとに
slack導入しませんか～
とりあえずワークスペース作ってみたんですけど、試験的にやりませんか～と吹聴する。

slackってこういうやつです、と言って参考記事URLを送り付ける。
ビジネスに特化したLINEみたいなものですよ～、
情報の共有化にもいいし、リモートワークにも適しているし、いいですよ！と勧める。
かねてから仕事の属人化、抱え込みを解消していこう話をしていたこともあり、いいんじゃない？ってことで無料プランで即日スタート。
理解が早くて助かる。

ここの記事がたいへん有用だった↓
絵でわかるSlackの使い方！第1回:そもそもどんなもの？メリットは？
https://jimon.info/series-slack-1st/



◆導入
ワークスペースにみんなを招待する。
よくわかんないという人は、対面でサポートする。
社内の連絡伝達事項はslackで！と伝える。


◆予想される反応、その傾向と対策
・slackに書いたらメールで通知してほしい
・メールでいいじゃん

→
メール通知は却下。
システム、仕組み、メリット説明する。
まあまあまずはやってみましょうよとなだめる。
新しいことに対してとりあえず反発したい、ひとこと言いたいだけの人もいるので発散させてあげる。


◆導入開始～導入から1週間の目標、心掛け
まだ2～3日目だけど、こんな気持ちでやってる。

▼slack便利だよ～楽しいよ～という雰囲気つくり
・カスタム絵文字の登録
・みんなの発言に対して積極的にリアクション
・ゆるめの言葉遣いを意識「XXですー」「はーい」
・メンション飛ばして、相手に通知がいくようにする。


▼チャンネル警察になる
・チャンネルというもの、場所を意識してもらうため、そういう話題はこっちでやってね～とやんわり伝える。


◆今後の野望
社外の人でよくやりとりする人も巻き込んで（チャンネルゲスト。有料プランにしないといけないが）情報をまとめたい。


*****

slackが日本語対応して一年たって、ネット上に記事が増えたし、日経とかにも記事になったし、ぼちぼち導入できるかな～ってことで、軽い気持ちでやってみたら、とりあえずなんとかなってる、と思う。

引き続き不安と葛藤があるけど、ぼちぼちやっていきたい。
qiitaじゃなくて個人ブログでやれよっていう内容だったらごめんなさい。
【Zenject】ZenjectのUnitTestでIInitializableは走らない

# 概要
`IInitializable`、`ITickable`、`IDisposable`は`ZenjectUnitTestFixture`を継承したテストクラスでバインドしても実行されないっぽい。
[Zenjectのテスト作成ドキュメント](https://github.com/svermeulen/Zenject/blob/master/Documentation/WritingAutomatedTests.md)内、`IntegrationTest`の項目にそれっぽい事が書いてある。
以下は軽い解説。

# Zenject.IInitializable
Zenjectは`IInitializable`を実装する事で、よしなにインスタンスの初期化を行う事が出来る。

```c#:Hoge.cs
public class Hoge : IInitializable
{
    private int fuga = 0;

    void IInitializable.Initialize()
    {
        Debug.Log("初期化");
        fuga = 100;
    }

    public int GetFuga()
    {
        Debug.Log(fuga);
    }
}
```

以上の`Hogeクラス`を`MonoInstaller`でバインドし...

```c#:HogeInstaller.cs
public class HogeInstaller : MonoInstaller<HogeInstaller>
{
    public override void InstallBindings()
    {
        Container.BindInterfacesTo<Hoge>().AsSingle();
    }
}
```

実行すればコンソールに`初期化`と出力され、`fuga`には100が代入される。

# UnitTestで問題は起きた
上記の`Hoge`クラスにZenjectのUnitTestを実装する場合はこんなコードが書かれるでしょう。

```c#:HogeTst.cs
[TestFixture]
public class HogeTest : ZenjectUnitTestFixture
{
    [SetUp]
    public void CommonInstall()
    {
        Container.BindInterfacesTo<Hoge>().AsSingle();
    }

    [Test]
    public void FugaTest()
    {
        var hoge = Container.Resolve<Hoge>();
        var fuga = Hoge.GetFuga();
        //初期化が実行されて値が代入されているという想定
        Assert.AreEqual(100, fuga);
    }
}
```

残念ながら概要にも書いたように`Initialize`関数が実行されない為`FugaTest`は失敗してしまいます。

# 対策
`Hoge.Initializable`の内容をコンストラクタで実行するとテストは通るようになります。
`コンストラクタ`で実行すべき初期化と`IInitializable`で実行すべき初期化は見極めるべき。
`IInitializable.Initialize`関数はオブジェクトグラフの構築後（すべてのコンストラクタが実行された）に実行されるものであり

 - インスタンスに必要な初期化はコンストラクタで行う
 - DIされるクラスを触る初期化は`IInitializable.Initialize`で行う

みたいな感じでやっておくとテストを書く時にも困らなさそうです。
Transform Moving Least Squareを利用した画像補正のためのpython3.6コード(Windows)（工事中）

「Image Deformation Using Moving Least Squares」というタイトルの次の論文を
もとに画像補正コードを作成します

http://faculty.cs.tamu.edu/schaefer/research/mls.pdf

![Image Deformation Using Moving Least Squares.png](https://qiita-image-store.s3.amazonaws.com/0/293513/a44d197d-44c6-16c1-fa93-9655cdc9ce25.png)
ImageMagick の convert コマンドで市松模様（Checker Board）画像を作成する


```
convert -size 320x320 pattern:checkerboard -auto-level cb.png
```

![cb.png](https://qiita-image-store.s3.amazonaws.com/0/41095/cc7687cd-a787-fc23-fd90-a2a819898ba6.png)


なぜか分からないが -auto-level を付けないと出力に失敗する

```
convert -size 320x320 pattern:checkerboard cb.png
```

![bar.png](https://qiita-image-store.s3.amazonaws.com/0/41095/a3687591-19c6-833a-c7ef-5f79d76c0d45.png)
日頃の作業を効率化するツール３選 [windows版]

PCを使用する仕事であれば、業種を問わず行う作業を効率化してくれるツールで
使いやすかったものをまとめました。

##コピペを効率化
### Clibor
クリップボードの履歴を管理、表示できるソフトです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213957/f326a33e-55dd-3a3d-ef94-e97e5a63ed93.png)
【こんな時に便利】
　・コピペを繰り返す
　・少し前にコピーした文字をまた使いたい

「Ctrl + v」を押すつもりが間違えて「Ctrl + c」を押してクリップボードが上書きされても
履歴からすぐに取り出せるのが地味にありがたい。

- クリップボードの履歴は最大10,000件まで保存可能。
- クリップボードの編集が可能
- ホットキーを登録することで必要な時だけ表示できる。(「ctrlキーを2回」などで起動できる。)
- 定型文の登録が可能。

DL&詳細はこちら↓
[シンプルで高機能なクリップボード履歴フリーソフト「Clibor」](https://www.amunsnet.com/)

##ショートカットを効率化
### Claunch
...ファイル、フォルダ、アプリなんでもショートカット化してまとめられるツール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213957/102b5b52-b72c-8e97-f32e-22444c098a41.png)

【こんな時に便利】
　・ショートカットまでたどり着くのを簡単にしたい
　・特定のプロジェクトに関連するショートカットをまとめておきたい

Claunchによく使うサイトをまとめることで、ブックマークバーを簡潔にできます。

- ホットキー登録可能

DLはこちら↓
http://hp.vector.co.jp/authors/VA018351/claunch.html

##ファイル検索を効率化
### Everything
...ローカルのファイル検索を行うソフト
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213957/6b27f0a1-de5c-5a00-85f6-7a227e18534c.png)
【こんなときに便利】
・名前はわかるけどどこに置いたか忘れてしまったファイルを探す

エクスプローラーでもいいんですが、それより検索がとにかく速いです。
ファイルのみ、フォルダのみの検索も可能です。

DLはこちら↓
http://www.voidtools.com/

##(おまけの4選目)翻訳を効率化
###Google翻訳(chrome拡張機能)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/213957/188102ab-b972-3179-a388-3c927de2fc35.png)
単語や英文を選択するだけで翻訳結果を表示してくれます。
ElectronでUDP通信する

ElectronでUDP通信（送受信）を実装する必要だったので実装内容のメモ。


### 開発環境
Windows 10
Electron 3.0.2


### 実装内容
1. UDP通信には、[dgram](https://nodejs.org/api/dgram.html)を使用。
2. UDP通信行うには、メインプロセス側で通信を行う必要がある。（レンダープロセスから直接UDP通信はできない）
3. レンダープロセスでUDP信号を受け渡しするには、メインプロセスとレンダープラセス間を通信するIPC通信を利用する必要がある。
4. IPC通信とUDP通信を値の橋渡しは、メインプロセスでおこなう。


### 通信の流れ

```
Electron ( メインプロセス ← IPC通信 → レンダープロセス )
    ↑
UDP通信 
    ↓　
外部アプリ
```


### 実装サンプル
ElectronでUDP通信を行うサンプル。
サンプルコード [Github](https://github.com/yoshihitofujiwara/Sample_Electron_UDP)
アプリの使い方 [README](https://github.com/yoshihitofujiwara/Sample_Electron_UDP/blob/master/README.md)
[windows版](https://github.com/yoshihitofujiwara/Sample_Electron_UDP/tree/master/package/UDP-win32-x64) / [mac版](https://github.com/yoshihitofujiwara/Sample_Electron_UDP/tree/master/package/UDP-darwin-x64)

1. 上記のアプリのpackageフォルダ内にアプリデータあるので、OSに合わせたアプリを設置。
2. IP/Portの設定ファイルの更新
3. アプリを立ち上げると、最初に受信ログ部分に設定ファイル内容が出力されます。
4. あとは、IP/PORTがつながっていれば、相互にメッセージが送受信できます。




### 実装コード概要
#### メインプロセス
###### 送信
レンダープロセスから受け取った値を、 文字列をバッファに変換して送信しています。

##### 受信
最初にレンダープロセスからIPC通信を行い、
レンダープロセスとメインプロセスが相互に通信できるように設定する。
UDP通信で送られてきた、バッファオブジェクトを文字列に変換し、
IPC通信でそのままレンダープロセスに送る。


#### レンダープロセス
レンダープロセスでは、IPC通信を介してUDP通信を送受信しています。

###### 送信メッセージ
テキストエリアに入力した文字列をICP通信でメインプロセスに送られます。

###### UDP受信ログ
メインプロセス側で行ったUDP通信のメッセージを
IPC通信を介して受け取りテキストエリアに出力しています。


### その他
今回はUDP通信で扱う値は、文字列のみですがアプリに応じて値を変えたり、
json,osc等のフォーマットで最適化すれば扱いやすくなります。
UnityのStreamingAssets内のファイル一括取得にビルド後、ファイル取得に失敗してしまう

ビルド後にStreamingAssets内にある、指定ディレクトリのファイル一括取得がうまくいかなかったのでメモ。
[StreamingAssetsについてはこちら](https://docs.unity3d.com/ja/current/Manual/StreamingAssets.html)

うまくいかなかった内容は、開発環境で絶対パスでファイルを取得していたが、ビルド後は相対パスに書き変わってしまっていたのでファイル取得が失敗してしまっていた。

### 動作環境 
Windows10
Unity 2018.2.6f1

### 失敗例 : StreamingAssets内の指定ディレクトリのファイルリストの取得
sampleディレクトリ内のpng画像を一括取得

```c#
string [] files = System.IO.Directory.GetFiles (Application.streamingAssetsPath + "/sample", "*.png"
, System.IO.SearchOption.TopDirectoryOnly);

/// 又は
DirectoryInfo dir = new DirectoryInfo(Application.streamingAssetsPath + "/sample");
FileInfo[] files = dir.GetFiles("*.png");
```

上記の場合だと、開発時は絶対パスのファイルリストを返すが、
ビルド後、相対パスのファイルパスを返すのでファイルの取得に失敗してしまう。

なので、ビルド前、ビルド後の環境に依存しないようにファイルパスを取得できるように、
メソッドを用意する必要があった。


### 環境に依存しない、StreamingAssets配下のファイルリストを取得するメソッド

```c#
/// @method GetStreamingAssetFiles
/// @param string dir StreamingAssets配下にある取得したいディレクトリパス
/// @param string ext 取得したいファイル拡張子 (例: *.png, *.mp4, *.ogg, *.* 等)
/// @param bool isFullPath ファイルパスをフルパスで取得するか（デフォルトはフルパス）

static public string[] GetStreamingAssetFiles(string dir, string ext, bool isFullPath = true)
{
  if (dir.IndexOf("/") != 0)
  {
    dir = "/" + dir;
  }
  if (dir.LastIndexOf("/") != dir.Length - 1)
  {
    dir = dir + "/";
  }

  string basePath = Application.streamingAssetsPath + dir;
  string[] files = System.IO.Directory.GetFiles(basePath, ext, System.IO.SearchOption.TopDirectoryOnly);

  if (isFullPath && -1 == files[0].IndexOf(basePath))
  {
    for (int i = 0; i < files.Length; i++)
    {
      files[i] = basePath + files[i];
    }
  }
  else if (!isFullPath && -1 < files[0].IndexOf(basePath))
  {
    for (int i = 0; i < files.Length; i++)
    {
      files[i] = files[i].Replace(basePath, "");
    }
  }

  return files;
}
```


### 使用例
sampleディレクトリ内のpng画像を一括取得

```c#
// ファイルリストの取得
string [] files = GetStreamingAssetFiles("sample", "*.png");

// リスト一覧
for (int i = 0; i < files.Length; i++)
{
  files[i] = files[i].Replace(basePath, "");
  Debug.Log(files[i]);
  // C:/App/Assets/StreamingAssets/sample/hoge.png
}
```


これでひとまず、無事フルパスでファイルリストが取得することができました。
Face Tracking 「Augmented Face Image」

おはようございます！
僕は最近AR技術をずっと研究しています、で今日僕はすごく面白い技術を見つけました。皆さんに共有したいと思います。皆さんはSnapChatとかInstagramアプリ知っていますか？どんな特徴がありますか？
![333.jpg](https://qiita-image-store.s3.amazonaws.com/0/286745/5fd5b6b9-87bf-59c6-0e15-b5125fc26d4d.jpeg)
```Image source : https://www.wikihow.com/Get-Effects-on-Snapchat```
英語でFacial Recognition技術と言います。この技術は人の顔を認識し、それをエフェクトでモーフィングします。多分みんなさんは子供の頃からスーパヒーローになりたいそいう考え方あるんと思うています（僕もそうです、笑）で今回のイデアはFacial Recognition技術使ってMarvelのスーパーヒーロー顔を僕たちの顔にFilterしたいと思います。ま取り扱う僕たちがスーパーヒーローになるように感じるでしょう >.<
![444.png](https://qiita-image-store.s3.amazonaws.com/0/286745/f5bc29c6-178e-5444-bb4f-36c67ea6611e.png)
```Documentation : https://www.xzimg.com/Docs```

今回のぷろとは僕がUNITYとXZIMG技術を使えます、XZIMGはComputer Vision Recognitionサービスで、XZIMG中にたくさんComputer Visionのサービスがあります、例えば Magic Face, Augmented, Vision, Augmented Face,　で今回僕たちがAugmented Faceを使います。もっと詳しくXZIMGの情報やどうやって設定するを知りたいだったら、以上のリンクをご覧ください。

開発前に僕たちが注意する必要があることは3D Objectを探す時に僕たちの顔の周りに収まる 3D Objectほうがいいです。
![5555.png](https://qiita-image-store.s3.amazonaws.com/0/286745/01b633ec-e2c4-720c-6f0a-353c54281189.png)
```source : https://www.researchgate.net/figure/ ```

僕は前と同じインターネットのソースからを2つ例の3D Object選びました、スパイダーマンと黒パンサーです。
![6666.png](https://qiita-image-store.s3.amazonaws.com/0/286745/16f0298e-de29-c0c2-683d-c98f08996b91.png)
```source : https://www.models-resource.com/ ```

Unityに簡単な画面をデサインできました。その画面は4つボタンがあります、３つ左側のボタンはFilter変更することで、で下の１つボタンは写真を撮って保存することです。
![7777.png](https://qiita-image-store.s3.amazonaws.com/0/286745/f7ef250e-e1a2-0eec-e3fa-a2d20bc264de.png)
で最後3D Objectをインポートして、ボタンとつながって、ウェブカメラを開きて、顔ウェブカメラにみて見ましょう！
![screenshot3.png](https://qiita-image-store.s3.amazonaws.com/0/286745/294d3688-34f7-873d-1683-42fa855bd201.png)
![screenshot10.png](https://qiita-image-store.s3.amazonaws.com/0/286745/22656352-948d-81f3-cc21-2d3cb9193e4d.png)
```Video : https://youtu.be/3lRmQLV9v-Y```
できました！

で写真を撮って保存するコードとFilter変更するコード皆さんに共有したいと思います。それがみんなに役立つことを願っています。頑張ろう！
![888.png](https://qiita-image-store.s3.amazonaws.com/0/286745/31d7f605-c3d9-710a-286a-e618eba9f045.png)
![8888.png](https://qiita-image-store.s3.amazonaws.com/0/286745/7e672689-a43a-46fc-f35f-d92eb248283d.png)
カードでカウントを桁区切り表示する(小ネタ)

例えば，このようなデータがあったとして，
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/46127ac4-d3e6-49e6-78ca-9fb359be5248.png)
(Aが1000行)

値のカウントをカードで表示すると・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/f0d1c6b9-b2c0-1e1c-3138-4a27ce95cfab.png)
桁区切りされていない状態で表示されます。
桁区切りしたいのですが，それらしい設定が見当たりません。

しかし， [書式] > [データラベル] > [小数点以下の桁数の値] を「1」にして「0」に戻すと・・・
![pb.gif](https://qiita-image-store.s3.amazonaws.com/0/205972/7d7a370e-cfaf-12da-4057-cf5933a638c5.gif)

で，できた。。。

ちなみに，[表示単位] を「自動」にすると元の表示に戻ります。


上司がたまたま見つけてくださった小ネタですが，重宝しています。
Androidで画像の縦横比を保ったまま画面幅いっぱいに表示する

よく忘れてその度にググるのでメモ。

# 条件

* 画像はバナー系の、横幅が長いもの
* ImageViewで表示
* LinerLayout (vertical) > ImageView という構造

# 問題

```xml
<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/banner">
```

だいたいこんな感じのImageViewがあるとき、ImageView自体は画面幅いっぱいに広がるけれど、表示される画像はちんまりしている。

おそらく、バナー画像の高さが小さいため、それに合わせてImageViewの高さが決定し、バナー画像のアスペクト比を保ったまま表示するためにバナー画像の横幅を縮小されてしまったのが原因。

# 解決

```xml
<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/banner"
    android:adjustViewBounds="true">
```

`android:adjustViewBounds` を `true` にします。
ImageViewの境界が、表示内容（バナー画像）のアスペクト比に比例するようになります。


# あわせて読みたい

* [TextViewの文字列が中央揃えになってくれなくて悲しい](https://qiita.com/kikuchy/items/b2d7215df4d6f60fdefe)
* [Androidで独自Viewを作るときの4つのTips +3](https://qiita.com/kikuchy/items/0fa6bd232930bb12e187)
scp protocol error: mtime.sec not delimited

scpしたら
``protocol error: mtime.sec not delimited``
というエラーメッセージが出て、うまくいかないとの相談を受けました。

確かにググってもよくわからない・・
でも、正解はなくても、どこかにヒントはあるはず・・とみていたら

scp - protocol error: mtime.sec not delimited
https://cweiske.de/tagebuch/scp%20-%20protocol%20error%3A%20mtime.sec%20not%20delimited.htm

という記事中に``using "-v" as parameter for scp to get more info``と書かれていて
ゲットモアインフォ！もっと情報を取ろう！と直訳し()、
再度scp -vで試してみたところ

``Sink: This service allows sftp connections only.
protocol error: mtime.sec not delimited``
なる追加情報が！！
sftpしかサポートしてないですよ・・とのことでした。

・
・

今回は``protocol error: mtime.sec not delimited``が出てた原因はscpではなくsftpでの対応でってことでしたが
情報を得られるパターンはたぶん様々用意されているので(logなども)
そういうのをみるとお宝眠ってますよというお話でした
Laravelでscssを書くときにstylelintで自動シンタックスチェック

# これは何

###概要
laravel-mix に stylelint-webpack-plugin を組み込むことで mix でのアセットコンパイル時にSCSSのシンタックスチェックを出来るようにしたい。これによりSCSSの記述方法がチーム内で揃えられることにより保守性を高めたい。
lintを組み込むメリットについては他の記事に任せるとして、この記事ではインストール方法、設定方法について書いていきたいと思います。

### 私は誰
M&Aクラウドという会社でエンジニアをやっています。入社してまだ２ヶ月ほどです。
もともと専門はインフラでしたが、幅広い分野を触るようになりました。新しく覚えることが多いので四苦八苦しています。　

# 前提 
### バージョンとか
```
# artisan --version
Laravel Framework 5.5.39
```

以下は package.json の抜粋

```
        "laravel-mix": "^2.1.14",
        "stylelint": "^9.5.0",
        "stylelint-config-standard": "^18.2.0",
        "stylelint-webpack-plugin": "^0.10.5",
```



# 諸々インストール

```
npm install laravel-mix stylelint stylelint-webpack-plugin　--save-dev
```


# 設定

### webpack.mix.js 設定
だいたい以下のように書きました。

```
const mix = require('laravel-mix');

# このブロックが今回のミソです
const styleLintPlugin = require('stylelint-webpack-plugin');
mix.webpackConfig({
  plugins: [
    new styleLintPlugin({
      files: ['**/*.scss'],
      configFile: path.join(__dirname, '.stylelintrc'),
      syntax: 'scss',
    }),
  ],
});

mix.js('resources/assets/js/index.js', 'public/js').
    sass('resources/assets/sass/index.scss', 'public/css').
    version();
```

webpackConfig を使ってカスタム設定をやっています。
内部の書き方については[stylelint-webpack-pluginのページ](https://github.com/webpack-contrib/stylelint-webpack-plugin)を参考にできます。
以下抜粋

```
const StyleLintPlugin = require('stylelint-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new StyleLintPlugin(options),
  ],
  // ...
}
```


### .stylelint 設定
ルールはデフォルトでは「無し」で、自分で追加していく形になっています。

例としてcatしたものを貼っておきます。

```
$ cat .stylelintrc
{
  "extends": "stylelint-config-standard",
  "rules": {
      // 説明のために適当なルールを書いてあるだけです。
      "declaration-block-trailing-semicolon": "always"
  }
}
```

extends と rules について以下に説明します。

##### extends で Standardのルールを適用する。
以下のパッケージを入れて、.stylelintファイルで読み込みます。

`npm install stylelint-config-standard --save-dev`

新規プロジェクトの場合には、最初からスタンダードルールを適用してしまうのが良いと思います。
我々の場合、しばらく開発が進んでからこれを導入しているので、結構lintに怒られる箇所があり、直していくのは骨が折れそうです。

##### rules で個別のルールを適用する
rulesは個別のルールを書いていくところです。
以下のConfigGeneratorを使うと追加ルールどれにするかというのが簡単に決められそうです。
https://maximgatilin.github.io/stylelint-config/

# その他
### laravel-mix-styleline という npm パッケージがあるみたいなのだけど
https://github.com/tyler36/laravel-mix-stylelint

便利そうです。
以下のようにwebpack.mix.jsファイルで設定をすれば動きました

```
require( 'laravel-mix-stylelint' );

mix.stylelint({
  configFile: path.join(__dirname, '.stylelintrc'),
  files: ['**/*.scss'],
  syntax: 'scss',
});
```

しかし以下の理由で採用を見送りました

* スター数が少ないので、今後メンテナンスされていくか不透明
* stylelint-webpack-plugin を直接使えば入れる必要があるパッケージは少なくてよく、それで大して記述が増えるわけではない

### ハマりどころ
laravel-mix のバージョンが低いことにより mix.extend() メソッドがないよという問題がありました。単に最新版にアップデートすることで解決しました。

### fix（自動修正）について
stylelintのCLIで　`--fix`オプションをつけると多くの簡単なルールは自動修正してくれます。

```
node_modules/stylelint/bin/stylelint.js  **/*.scss --fix
```


# 今後の課題
ESLintには自動で直せるところは直してくれる`--fix`オプションみたいなのがあったと思います。stylelintで同様のことをうまくできないか調査してみたいと思います。
SAS ViyaのデモでJupyter Notebookが表示されなかったら

SAS ViyaはAIプラットフォームです。[SAS for Developers | SAS](https://developer.sas.com/home.html)から申し込んでトライアルが使えます。このデモなのですが、SAS Viyaに限らず、SASのプロダクトを試せるようになっています。

そのためなのか、初期表示がSAS ViyaではなくReport Viewerになることがあるようです。今回はそこからSAS ViyaのJupyter Notebookに戻る方法を紹介します。

## ウィンドウ下部にあるインフォメーションアイコン

Report Viewerなどを表示した際に、最下部にツールバーが出ています。ここで、iアイコンをクリックします。

<img width="2404" alt="Screenshot_ 2018-09-28 9.46.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/d2615202-df05-9762-065d-33b336248141.png">

そうするとモーダルウィンドウが表示されますので、その中のMore Productをクリックします。

<img width="2404" alt="Screenshot_ 2018-09-28 9.46.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/324206c0-7fab-b7d0-0e3f-df22754670b3.png">

製品がラインナップされますので、Jupyter Notebookの場合は SAS Viya Programmingを選択します。

![Screenshot_ 2018-09-28 9.46.41.png](https://qiita-image-store.s3.amazonaws.com/0/274479/4b65c7a4-4c5f-f295-1f0d-13800edc429e.png)

そして一番下にある Open Source Programをクリックします。

<img width="2404" alt="Screenshot_ 2018-09-28 9.46.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/9e3edea1-86b4-f08e-186e-1b7976be36b4.png">

そうすればJupyter Notebookが表示されるはずです。

![Screenshot_ 2018-09-28 9.47.24.png](https://qiita-image-store.s3.amazonaws.com/0/274479/eaf496e9-4dba-3c03-3e8e-4d3f880ce0dd.png)

## 他の機能

SAS Viyaのトライアルでは他にもプロダクトが多数あります。例えば SAS Studioではプログラミング言語としてのSASを使った開発ができます。

![Screenshot_ 2018-09-28 9.49.56.png](https://qiita-image-store.s3.amazonaws.com/0/274479/889e8989-3c3d-c8d8-a336-09b35634f491.png)

SAS Data Preparationを選ぶと、Data Studioにアクセスできます。

![Screenshot_ 2018-09-28 9.51.50.png](https://qiita-image-store.s3.amazonaws.com/0/274479/9ff22322-5cfc-fb14-19db-cacd211b49d1.png)


ここでさらにデータの管理を選びます。

![Screenshot_ 2018-09-28 9.51.54.png](https://qiita-image-store.s3.amazonaws.com/0/274479/425b6ff7-4e33-9817-6bb3-5420636ec536.png)


データ管理では共有データはもちろん、独自のデータをアップロードできます。アップロードしたデータはJupyter Notebookからアクセスできます。

![Screenshot_ 2018-09-28 10.07.47.png](https://qiita-image-store.s3.amazonaws.com/0/274479/9ea9124c-4281-4917-b6ac-55980e435e0f.png)


----

SAS Viyaには関連製品が多数あり、必要に応じて組み合わせられるようになっています。プロダクトを切り替える際には、ツールバーからアクセスしてください。

[SAS for Developers | SAS](https://developer.sas.com/home.html)
JupyterでPySparkが立ち上がらない時の対処方法

## 本記事について
JupyterからNotebookを開き、PySparkカーネルをスタートさせてもカーネルが起動しない時の対処方法について記載します。

## 症状
Notebookを開いてPySparkカーネルをスタートしても起動中のマークが出たまま止まる。
![Art000.png](https://qiita-image-store.s3.amazonaws.com/0/100574/15a7727e-e363-2c0d-3832-bdf1af71ac0b.png)

## 原因
PySparkカーネルを立ち上げると、新たにSparkアプリケーションが作成されます。

設定にもよりますが、Sparkアプリケーションは１度に１つしか実行できません。

なので、既に他のNotebookを開いてPySparkカーネルが起動していると、そのPySparkカーネルのSparkアプリケーションが実行中なため、後から開いたNotebookがPySparkカーネルをスタートさせてもSparkアプリケーションは止まったままで、PySparkを立ち上げることができなくなってしまいます。

また、Notebookを開く度に新しくSparkアプリケーションが作成され、そのNotebookを閉じても、それに紐付いていたSparkアプリケーションは削除されず残り続けるため、Notebookを開いたり閉じたりしていると、Sparkアプリケーションが溜まっていってしまいます。

## 対処方法
一旦全てのSparkアプリケーションを削除してから、再度Notebookを立ち上げ直します。

1. 開いている全てのNotebookを閉じる
1. Jupyterの「Running」タブで、全てのNotebookを「Shutdown」する
1. ``http://localhost:8088/``で「YARN UI」を開く
1. [Applications]でSparkアプリケーション一覧を表示し、削除するSparkアプリケーションの「Tracking UI」を選択<br>
   （下記図では３つのPySprakカーネルのSparkアプリケーションがWait状態で残っていますのでこれらを削除します）
    ![Art001.png](https://qiita-image-store.s3.amazonaws.com/0/100574/1611916d-fb2c-dd3b-0105-c772986a21c7.png)
1. Sparkアプリケーションの詳細ページの左上の「Kill Application」をクリックてSparkアプリケーションを削除する
   ![Art000.png](https://qiita-image-store.s3.amazonaws.com/0/100574/9f27b746-3be9-2428-35c9-63d6eb0fcd6d.png)
1. PySparkカーネルを立ち上げたいNotebookを開いてPySparkカーネルをスタートさせる
アドサーバーについて

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/19729221-05f3-fb01-3311-f77b89616b2c.png)


DSP/RTBオーディエンスターゲティング入門を読んだまとめ。
DSP/RTBだけといわず広告システムについて体系的に記されていたので小分け。
DSP・RTB・SSPになどの前に純広告からアドサーバーの登場まで。

##総論
「枠」から「人」への大きなパラダイムシフトを理解する

##変遷
特定のメディアの「枠」を買う(**ディスプレイ広告**)から、多様なメディアを横断して「人」(**オーディエンス**)への配信を買うことへと転換していく

##広告の出し方
###初期
####純広告を出す
サイト(以降**メディア**と呼ぶ)に直接広告原稿(以降**クリエイティブ**と呼ぶ)を出すこと

**1つのメディア枠**に**1つのクリエイティブ**を見せるだけ

- ベタ貼り
  - 例：Yahooホームページのメディア枠を〇〇〇万で買い、1枚のクリエイティブ画像を置く

**->**メディアへのアクセスログがそのまま広告掲載レポートとなる

###その次
####メディア ⇄ アドサーバーで出す
**メディアに広告配信タグを貼る**ことで、**1つのメディア枠**に**複数のクリエイティブ**を見せられるようになる

コンテンツを読み込むと**アドサーバー**に広告を読み込みに行く。
メディア(コンテンツのサーバー)と広告画像を配信するサーバー(アドサーバー)が分離している。

**->**アドサーバーはメディア用のサーバーとは別の、広告用のサーバーであることを指すので広義。


ブラウザ ⇒ メディアへのアクセス時に、メディアのサーバーにブラウザの情報を渡すのと同様、メディア ⇒ アドサーバーへのアクセス時も渡す。つまりユーザーの情報をアドサーバー上で取得できるようになる。こうなると広告関連情報を単に管理する以外のこともできるようになるので進化し、たくさんの種類のアドサーバーが登場する

##アドサーバー
主に3つ(本の中では)
実際にはアドサーバーと呼べるものは他にもある。

###媒体社アドサーバー
**メディア枠を管理**するためのもの。
クリエイティブ在庫・受発注、配信、レポート出力、売上などを管理する。
業務管理システムのイメージ。

###アドネットワークアドサーバー
一般にいうアドネットワークのこと。
クリエイティブ在庫・受発注、配信、レポート出力、売上などを管理・**代行**する。
**複数のメディア**の**メディア枠**に**複数のクリエイティブ**を見せられるようになる。
単体メディア向けに最適化というよりは、全体最適に強みをもつもの。
アドネットワークの規模自体は営業力に依存する。
アドネットワーク事業者がメディアを集めてジャンル毎に分類。
ジャンルを商品として広告主を集める。
マッチングするようなコミュニティを作り経済回すイメージ。

###第三者配信アドサーバー
**複数のメディア**への**宣伝活動**(以降**キャンペーン**)を**1つのアドサーバー**で管理できるようにしたもの。
配信コントロール設定や、間接コンバージョンまで含めた効果測定、見込み顧客データを活用した広告配信などのデータマネジメントを行うことに特化。
キャンペーンが一元管理できるため、キャンペーンに紐づくクリエイティブのパフォーマンス評価もし易い。
メディアには第三者配信サーバーの広告配信タグを貼るが、クリエイティブのメディア枠への配信は媒体社アドサーバーから行われる。
つまり媒体社アドサーバーが担っているメディア枠管理や、放っておいてもある程度売上を得られるようなアドネットワークの販売能力のような機能はない。
効果測定をし易くするために媒体社アドサーバーとの間に入っているイメージ。

##アドサーバー登場後
それから、主要アドサーバーの動向、新しい活用データによるターゲティング機会の創出、技術の進化による開発コストの低減などの様々な影響により、**クリエイティブを最適化して、ユーザーによって広告素材差し替えて表示できるようにしよう**という試みが出てくる。

こうして、DSP・RTB・SSPなどが登場してくる
[DSP/RTB/SSPについて](https://qiita.com/dich1/items/104ab37c4b70d22dcef3)

## 書籍情報
横山 隆治, 菅原 健一, 楳田 良輝　DSP/RTBオーディエンスターゲティング入門
https://amzn.to/2xUJEQ5
スプレッドシートに仕込んだメール下書き用gasのGoogleアカウントとは異なるアカウントでメールの下書きを作成したい

Googleスプレッドシートにスクリプトを埋め込んで、複数のユーザーでシートを共有しています。

スクリプトには、スプレッドシートの内容を本文等にセットしたメールの下書きを作成する、というものを書き、正しく機能しました。そこで、スプレッドシートを共有している別のユーザー（スクリプトを設置したGoogleアカウントとは別のアカウント）でログインしてそのスクリプトを実行すると、メールの下書きが作成できませんでした。

質問は、スクリプトの実行者のアカウントでメールの下書きが作成されるようなGASを設置するにはどうしたらいいのかを知りたいです。

どうぞよろしくお願いいたします。
初心者が Elixir の魅力を語ってみる

# はじめに

2週間ほど Elixir を触ってみて感じた魅力について語ってみます。
他にパフォーマンス面の魅力も多々あるのですが、まだ踏み込めていないので表面的な部分にとどまってます。

# パイプライン演算子

```elixir
d(c(b(a(1234))))
```

他の言語でこのようなコードを見かけることは多いのではないでしょうか。
見慣れてはいますが、処理の順番が「内→外」となっており、わかりづらいです。

```elixir
1234 |> a() |> b() |> c() |> d()
```

Elixir ならこう書けます。
順番が「左→右」になりわかりやすくなりましたね。
Elixir では標準ライブラリの多くがパイプライン演算子を使いやすいように設計されています。
私にとっては新鮮でしたが、 bash に精通している方はイメージしやすいのでしょうか？（私はあまり詳しくありません）

# 全ての値渡しがパターンマッチ

```elixir
{a, b} = {1, 2}
```

Elixir ではこういったコードが書けます。
ですが、ここまでだと Ruby などの言語にも似たような構文がありますね。
Elixir では他の値渡し、つまり関数の呼び出しでも全く同じことができます。
2次元上の2点間の距離をもとめるコードを書いてみます。

```elixir
defmodule F do

  def distance({x1, y1}, {x2, y2}) do
    :math.sqrt(:math.pow(x1 - x2, 2) + :math.pow(y1 - y2, 2))
  end

end
```

受け取った引数をいちいちバラバラに代入しなおしたりする必要がありませんね。
ここでは紹介しませんが、上記の Tuple の他に List や Map でも同じことができます。

# 動的なオーバーロード

一般的なオーバーロードと言えば、「引数のシグネチャによって呼び出す関数が変わる」といった仕組みです。
動的型言語である Elixir にオーバーロードはできないのでは？と思うかもしれませんが、**できます**。
ユークリッドの互除法で最大公約数を求めるコードを書いてみます。

```elixir
defmodule F do

  def gcd(a, 0), do: a
  def gcd(a, b) when a < b, do: gcd(b, a)
  def gcd(a, b), do: gcd(b, rem(a, b))

end
```

アルゴリズムについては Wikipedia あたりを参照していただければと思います。
おもしろいのは、一般的なオーバーロードと違い、実行時に呼び出す関数が決められるという点です。
動的型言語ならではの魅力と言えます。
`when` という節がありますが、これはガードと呼ばれます。
関数を呼び出すかを決める `if` のようなもの、と考えていただければ間違いないです。

# おわりに

Elixir の魅力を紹介させていただきました。
どうでしょう、素晴らしくないですか？
拙い記事ながら、誰かが Elixir に触れるきっかけになれば幸いです。
tbls と grom を使ってCI環境内でDBテーブル設計書を自動作成する

# やりたいこと

* CIでDBのテーブル設計書を自動で作成したい

# 実現方法

 [tbls](https://github.com/k1LoW/tbls) という対象のDBにアクセスしてMarkdownのドキュメントを自動で生成するツールを使います。

実際の流れとしては、以下のようになります。

1. CI環境でDBのコンテナを起動
2. golang ORM  [gorm](https://github.com/jinzhu/gorm)の オートマイグレート機能で、golangのstructから、自動でテーブルを作成
3. tbls でDBのコンテナにアクセスし、ドキュメントを自動生成

# 実際の構成

プロダクトコードのリポジトリ内に以下のようなソースファイルを用意します。
このコードは、プロダクトコードの中で普通に利用されるModelでもあります。

```golang:github.com/xxxx/product/models/user.go
package models

import (
    "github.com/jinzhu/gorm"
)

type User struct {
    gorm.Model
    
    Name         string `gorm:"type:varchar(32)"`
    MailAddress  string `gorm:"type:varchar(255)"`
    Age          int    `gorm:"type:int(11)"`
}
```

ドキュメントを管理するリポジトリ内に以下のようなソースファイルを用意します。
今回はMySQLを利用してますが、 tbls はPostgreSQLやsqliteにも対応しています。

```golang:github.com/xxxx/product/main.go
package main

import (
	"fmt"
	"os"

	"github.com/jinzhu/gorm"
	// MySQL driver
	_ "github.com/go-sql-driver/mysql"

	"github.com/xxxx/product/models"
)

func main() {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8",
		os.Getenv("MYSQL_USER"),
		os.Getenv("MYSQL_PASSWORD"),
		"mysql",
		"3306",
		os.Getenv("MYSQL_DATABASE"),
	)

	dbCon, err := gorm.Open("mysql", dsn)
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}

	dbCon.AutoMigrate(&models.User{})
	println("Done.")
	return
}
```

CI環境内で上記の `main.go` を実行してあげるだけでDBコンテナに自動でテーブルが作成されるので、
以下のように CI環境内で `tbls` を実行するだけでドキュメントが自動生成されます。
生成されたドキュメントは、マークダウンなのでそのままgithubにコミットして管理することができます。

```yaml
script:
  - go run main.go
  - tbls doc --force mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql/${MYSQL_DATABASE} ./docs
```

# まとめ

これだけの設定で、実際のプロダクトコードで管理しているgolangのModelが変更されると自動でテーブル設計書も更新するということができました。
tbls については、以下のページに更に詳しく書かれています。

https://k1low.hatenablog.com/entry/2018/05/22/083000
【Larval 5.5】＜メモ＞ SQL ロガー

SQLログを取るのに、
***mnabialek/laravel-sql-logger***
を使ったらドハマリした…orz
クエリの実効速度は大幅に落ちるし、メモリーを尋常じゃ無く食うので要注意！

LaravelでSQLログを取りたいなら、
***feyman/laravel-sql-logger***
の方が軽くて良い。

```
composer require feyman/laravel-sql-logger --dev
```
DockerプロセスとDockerイメージを掃除するワンライナー

Dockerを使っててひとつひとつ消すのが面倒だったので

### Dockerプロセス全員殺すマン
```docker ps -a | awk '{print $1}' | tail -n +2 | xargs docker rm```

### Dockerイメージの最終行以外を消すマン
```docker images | awk '{print $3}' | sed '$d' | xargs docker rmi```

※間違えているかもしれないのでご利用は計画的に
Slackで3ヶ月以前にアップロードされたファイルを全部消すシェルスクリプト

Slack を無料で使っているとファイル容量がすぐ満杯になってファイルアップロードができなくなるので cron に登録して毎日掃除していきたいと思います。

`SLACK_TOKEN` は、ここから発行 https://api.slack.com/custom-integrations/legacy-tokens

```sh
SLACK_TOKEN=xoxp-0000000000-0000000000-00000000000-0000000000
curl -sS "https://slack.com/api/files.list?token=${SLACK_TOKEN}&count=1000&ts_to=$(( `date +\%s` - (60 * 60 * 24 * 90) ))&pretty=1" | awk -F'"' '/"id":/{print $4}' | while read FILE_ID; do echo -n "${FILE_ID} "; curl -sS "https://slack.com/api/files.delete?token=${SLACK_TOKEN}&file=${FILE_ID}"; echo; sleep 1; done
```
Ubuntu 18.04でDNSサーバを切り替える方法

UbuntuのDNSサーバを変更で思いの他手間取ったのでメモ

# 経緯
-  ubuntuにDNSサーバ用ソフトウェアであるNSDを導入しようと試行するも失敗
-  デフォルトでインストールされているbind9-hostがポートの競合を起こしている事が原因と判明
-  bind9-host抜く
-  下記のように名前解できなくなった

```
$ dig google.com
;; reply from unexpected source: 127.0.0.1#53, expected 127.0.0.53#53
```

# 解決方法
`sudo vi /etc/resolvconf/resolv.conf.d/head`

```
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 9.9.9.9
```

`sudo service resolvconf restart`

`cat /etc/resolv.conf`
nameserverが変更されていることを確認

# ハマりポイント
## /etc/resolv.conf書き換えても元に戻る

/etc/resolv.conf自体がresolvconfのシンボリックリンクだった。
OSとしては/etc/resolv.confを読みに行くが、設定自体はresolvconfが管理してるっぽい。
ネットサーフィンならぬ、Qiitaサーフィンのすゝめ。

## 対象者
- プログラミングに関する知識を広げたいエンジニア全般（初心者上級者問わず）
- 独自の勉強を確立できていない人

## Qiitaサーフィンとは？
Qiitaという世界の中で完結するネットサーフィンのこと。言葉自体は僕の創作です。

> ネットサーフィン (Net Surfing、ネットサーフ) とは、ウェブページの閲覧において、各ページを興味の赴くまま次々に表示して閲覧していく行動のこと。この様子を波から波へと渡るサーフィンに見立てた造語で、電子掲示板についても言える。インターネットが普及し始めた1990年代から一般的な用語となった。
> [ネットサーフィン - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%82%B5%E3%83%BC%E3%83%95%E3%82%A3%E3%83%B3)

## How to Qiita surfing?

- トレンド記事で気になる記事を開いて読んでみる
「ん、Dockerって何だろう？Go言語？知らないけど面白そう！」という感覚でリンクを開けばおk。
この時時間に余裕があれば気になった記事は全て「新しいタブ」で開いておく。

- 記事を読んでいて分からなかった専門用語はgoogleを新しいタブで開いて検索だけしておく（ここでは読み進めない）
- 開いた記事を読み進め、コメントまで読み込んで複数の観点から記事トピックに関する考えを取り入れる
- 面白かった記事はストックし、気になった技術タグがあれば積極的にフォローしておく
- 可能ならここで何らかのアウトプットをする
コーディングでもよし、ツイッターでもよし、ノートに単語をメモする程度でもOK。

- Qiitaサーフィンで得た知識を自分の好きな方法で使っていく
手に入れた知識を同僚や後輩にひけらかすもよし、
知識を使ってより効率的に業務を進めるもよし、
気になった知識を使って新しい技術を試してみるもよし。

## Qiitaサーフィンのメリット
- 関連リンクが記事下にあるのでどんどん関連知識を追っていける
PHP、PDO、MySQL、CRUD、RDB、NoSQL、Redis...という感じでマジカルバナナ的に様々な知識を追っていける。

- 実行可能なコードがあるので自分でどんどん試していける
- 一人の意見ではない色々な視点から学べる

## Qiitaサーフィンのデメリット
- 全ての分野についての体系的な知識は手に入らない
- 上記の裏返しで、情報がどうしても断片的になってしまう
- 一度読み出すと止まらないため自制心が必要になる
- 偏った考え方の記事に当たると将来的にバイアスがかかってしまう可能性がある
とはいえこれに関してはコメントにおいて建設的なクリティサイズが行われている記事が多くあるので、コメント欄までしっかりと読み込むことで回避できる


## 個人的にQiitaサーフィンで得られたと思っている恩恵

### プログラミング界隈でのトレンドのキャッチアップ
とはいえWEBDBやSoftware Designを読むのにはもちろん叶わないので、ある程度の知識が身についた時点で雑誌などを読む必要はあり。

### トレンド記事を読むことによる、自分が興味を持っている分野以外の情報の収集
- Atomicデザイン
- ブロックチェーン
- 関数型プログラミング言語
- ログ設計に関する方針

等々、書ききれないほどいっぱいあります。

## まとめ

Qiitaサーフィン、おすすめです。
ラズパイで赤外線リモコン作ってみた 忘却録

# 作ったもの
ラズパイでコマンド叩いたら、CDプレイヤーが再生される（だけ）。

とりあえず、とりあえず、、、動くデモを作ってみたかったので、
見た目とか操作性とか特にこだわっていません。
次はWebページとかアレクサなどから制御できるようにしたい。
手を動かさずできるだけ楽に家電を操作したい。。。

# 必要なもの
* LED赤外線
* 赤外線受信機
* トランジスタ
* ブレットボード
* ジャンパワイヤ オスメス
* ラズパイとラズパイ動かすのに必要なもの（ラズパイ、MicroSD、AC電源）

# 手順
ラズパイの初期設定なんかは終わっているものとします。
初期設定は簡単なのでサクッと終わると思います！

* LED赤外線、赤外線受信機のデータシートから回路を考える
* 受信機を使って赤外線の信号を学習
* 学習した信号をコマンドラインから送信

# 回路
![kairo2.jpg](https://qiita-image-store.s3.amazonaws.com/0/220839/ab2aa4a8-2880-6b5a-f813-8ab60144b6d2.jpeg)


データシートの見方から抵抗の求め方、電圧電流とかわからないことだらけで知り合いの方にお世話になりながら（ほぼ作ってもらいましたが）作りました。

## 赤外線の学習
このデモを作るまで赤外線ってどのような仕組みで動いているのかよく知らなかったのですが、今回の学習ですこしわかってきました。
当初のイメージでは、赤外線に記号みたいな情報が乗っていて、それをピッっと一回で送信できるものだと思っていました。
それは違っていて、赤外線自体は記号や情報を飛ばしているだけではなく、0か1かの情報だけで、
それを一定の間隔で点滅して色々な機器を制御しているらしいです。
もちろん機器ごとに点滅の間隔は変わります。モールス信号的なイメージじです。

脱線しましたが、話を赤外線の学習に戻します。

学習には LIRC というツールを使います。

まずラズパイに LIRC を入れます。

```
sudo apt-get install lirc
```

インストールが終わったら  `/boot/config.txt` を編集します。 gpio ピンの情報を書き足します。

```
# IR-Remote controller
dtoverlay=lirc-rpi
dtparam=gpio_in_pin=4
dtparam=gpio_out_pin=17
```

編集が終わったら ラズパイ を リスタート します！

```
sudo shutdown -r now 
```

lire が自動起動すると GPIO をへんなところにわりあててしまうらしいので、下記コマンドで自動起動をOFFにします！

```
sudo systemctl disable lirc.service
```

続いて下記コマンド実行

```
sudo modprobe lirc-rpi gpio_in_pin=4 gpio_out_pin=17
sudo systemctl stop lircd.socket
sudo systemctl stop lircd.service
sudo /etc/init.d/lircd stop
sudo /etc/init.d/lircd start
sudo systemctl restart lircd.service
```

続いて赤外線学習していきます！
/etc/lirc/lirc_options.conf ファイルに↓を記入

```
[lircd]
nodaemon = False
driver = default
device = /dev/lirc0
```

設定を反映

```
sudo systemctl restart lircd.service
```

mode2コマンドをたたきます。

```
mode2 -d /dev/lirc0 —driver default
```

ついに学習コマンドです！

```
irrecord --disable-namespace -f -d /dev/lirc0 --driver default ~/lircd.conf
```

色々出てきます。。

```
irrecord -  application for recording IR-codes for usage with lirc
中略...
Press RETURN to continue.　←ここでENTER
中略...
Press RETURN now to start recording.　←ここでENTER
...............................................................................
```

ここまできたら、学習させたいボタンをひたすら押します。

学習が終わったら↓のメッセージが出るので、学習させたボタンの名前を適当につけてENTER

```
Please enter the name for the next button (press <ENTER> to finish recording)
```

次に「さっき学習した＊＊＊ってボタンを押して！」っていう↓のようなメッセージが出るので、ボタンを押します。

```
Now hold down button “on”.
Got it.
Signal length is 67
```

これで一つのボタン学習が完了しました。
次々学習させたい場合はメッセージに従って同じように登録していってください。

学習したファイルを適用するには、学習したファイルをコピーして、LIRC サービスを再起動します。

```
sudo cp ~/foobar.lirc.conf /etc/lirc/lircd.conf.d
sudo systemctl restart lircd.service
```

次に学習したボタンをコマンドラインから実行してみます！

```
irsend SEND_ONCE "cd" "on"
```

赤外線は角度結構シビアなので、そのへん調整が必要でした。

# 参考
[LIRC の赤外線データについて拙くまとめる](https://qiita.com/isann_tech/items/b765bf179f48c8cff616)
[Raspberry Pi Zero で赤外線リモコンを作る](https://qiita.com/ww24/items/32d2a78c20e6dcc2e68c)
golang context 簡単な使い方

メモです

```go
type tokenKey int

const (
	ctxTest tokenKey = 0
)


type App struct {
   Cache *cache.Cache
}

// uuidでtoken作成
func makeCsrfToken() string {
	h := md5.New()
	io.WriteString(h, uuid.New().String())
	token := fmt.Sprintf("%x", h.Sum(nil))
	return token
}

func (a *App) csrf(r *http.Request) {
	token := makeCsrfToken()
	ctx := context.WithValue(r.Context(), ctxTest, token)
	r.WithContext(ctx)
	a.Cache.Set(token, struct{}{}, cache.DefaultExpiration)
}
```

```go
func (a *App) Authorize(w http.ResponseWriter, r *http.Request) {
    ...
    ...
    a.csrf(r)
    // 取り出す
    csrfToken := r.Context().Value(ctxTest).(string)
}
```
picameraで顔認識してみた

OpenCVを使って顔認識をしたい時にはUSBカメラを使って顔認識をしますが、Raspberry Piのカメラモジュールを使う場合にはUSBカメラを使う時の設定とはかなり違ったので、まとめていきます。

# 環境設定
今回はpython2.7で環境構築していきます。python3系を使いたい場合は別途設定をしておきます。~~(機会があれば設定方法を書きます…)~~ *一番下の追記でpipを使ったOpen CVのセットアップ方法を紹介していますので、python3を使いたい場合はそちらを参考にしてみてください。*
まずはOpenCVをインストールします。次のコマンドでインストールしていきます。

```
$ sudo apt-get install libopencv-dev
$ sudo apt-get install python-opencv
```
そして画像をOpenCVで処理出来るように、pycameraの拡張モジュールでpicamera.arrayをインストールします。

```
$ pip install "picamera[array]"
```

# ソースコード
参考文献の本で紹介されていたカメラの画像を表示するプログラムに以前書いた[こちらの記事](https://qiita.com/K_M95/items/f1a3e7c47800adb94095)の顔認識を合わせてこちらのコードを書きました。

```python

# coding: utf-8
import picamera
import picamera.array
import cv2

cascade_file = "haarcascade_frontalface_default.xml"
with picamera.PiCamera() as camera:
	with picamera.array.PiRGBArray(camera) as stream:
		camera.resolution = (320, 240)
		while True:
			# stream.arrayにRGBの順で映像データを格納
			camera.capture(stream, 'bgr', use_video_port=True)
			
			# グレースケールに変換
			gray = cv2.cvtColor(stream.array, cv2.COLOR_BGR2GRAY)

			# カスケードファイルを利用して顔の位置を見つける
			cascade = cv2.CascadeClassifier(cascade_file)
			face_list = cascade.detectMultiScale(gray, minSize=(100, 100))

			for (x, y, w, h) in face_list:
				print("face_position:",x, y, w, h)
				color = (0, 0, 255)
				pen_w = 5
				cv2.rectangle(stream.array, (x, y), (x+w, y+h), color, thickness = pen_w)
			# system.arrayをウィンドウに表示
			cv2.imshow('frame', stream.array)

			# "q"でウィンドウを閉じる
			if cv2.waitKey(1) & 0xFF == ord("q"):
				break

			# streamをリセット
			stream.seek(0)
			stream.truncate()
		cv2.destroyAllWindows()

```
顔認識するカスケードファイルは[こちら](https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml)からダウンロードします。
以下のような実行結果になります。フレーム内で顔を認識したら赤い四角で囲まれるようになります。そしてコンソールには顔の位置と高さと幅を表示させています。

![alt](https://media.giphy.com/media/1etpYPCk56PROz8DKp/giphy.gif)

このコード中の「stream.array」でカメラモジュールからフレームを取り込んでOpenCVで処理を行います。このコードをアレンジすれば物体認識などのプログラムを作成することも出来るはずです。

# 追記：pipを使ってOpen CVをセットアップする(python3のみ)
python3でopencvを使うときはpipをつかってかんたんにセットアップできるそうです。
[こちら](http://asukiaaa.blogspot.com/2018/07/pythonopencvraspi.html)を参考にOpenCVを手動でインストールする時に必要な関連プログラムをインストールします。

```
 sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
```
OpenCVをインストールします。

```
sudo pip3 install opencv-python
sudo pip3 install opencv-contrib-python
```
OpenCVを動かすために必要なプログラムをインストールします。

```
sudo apt-get install libcblas-dev libatlas3-base libilmbase12 libopenexr22 libgstreamer1.0-0 libqtgui4 libqttest4-perl
```

# 参考文献
[実例で学ぶRaspberry Pi電子工作 作りながら応用力を身につける ](https://www.amazon.co.jp/%E5%AE%9F%E4%BE%8B%E3%81%A7%E5%AD%A6%E3%81%B6Raspberry-Pi%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C-%E4%BD%9C%E3%82%8A%E3%81%AA%E3%81%8C%E3%82%89%E5%BF%9C%E7%94%A8%E5%8A%9B%E3%82%92%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%82%8B-%E3%83%96%E3%83%AB%E3%83%BC%E3%83%90%E3%83%83%E3%82%AF%E3%82%B9-%E9%87%91%E4%B8%B8/dp/4062579502)
CentOS7でカーネルをアップデートしたらGUIが動かなくなって焦った

CentOS7でカーネルをアップデートしたら、GUIがフリーズして進行不能になったのでメモ。

# 何をしたらGUIが動かなくなったのか

GUIで起動して、シャットダウンする時に「更新プログラムをインストールしてシャットダウン」みたいなのにチェックを入れてシャットダウンしました。

その後から、ログインしてデスクトップが表示されたと同時にGUIがフリーズし、コマンドラインにも切り替えられず電源ガチャ切りするしかなくなりました。。。

# どう解決したのか

電源を入れるとすぐにカーネル選択画面が表示されるので、1つ前のカーネルを選択して起動したところ、GUIが問題なく操作できるようになりました。

# 1つ前のカーネルを毎回選択するのはめんどい

デフォルトのカーネルを設定することができるようです。

[CentOS 7でデフォルトのカーネルを変更・指定する](https://qiita.com/kjtanaka/items/9b5c18f399642a0679e9)

## カーネルのリストを表示する
```
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2-efi.cfg
```

※私の環境では「grub2.cfg」のファイル名が違っていました。

## 問題なく動作するカーネルの番号を設定する
```
grub2-set-default 1
```

カーネルが選択できなくなるわけではなく、デフォルトで選択状態になっているカーネルを変更するだけなのでご安心を。
AppStoreに「評価とレビュー」が表示されるタイミング

iOSアプリをリリースした際にわかったことを記しておきます。

![IMG_8099.PNG](https://qiita-image-store.s3.amazonaws.com/0/112818/0c5d2c8b-2b82-ca07-547b-6dca1a62ac64.png)
※アニメ好きの方ぜひ使ってくださいませ(^q^)  [Anilog - アニメ記録はアニログ](https://itunes.apple.com/jp/app/anilog-%E3%82%A2%E3%83%8B%E3%83%A1%E8%A8%98%E9%8C%B2%E3%81%AF%E3%82%A2%E3%83%8B%E3%83%AD%E3%82%B0/id1433207679?mt=8)

# 「評価とレビュー」の確認方法
App Store Connectの
マイApp＞アクティビティ＞評価とレビュー
から確認できます。ここから各レビューへ返信することも可能です。
<img width="224" alt="スクリーンショット 2018-09-27 16.49.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/f29360e8-86b5-b1aa-1701-f16f23fff3f8.png">


# 表示されたタイミング（2018年9月時点）
**評価（星での5段階評価）が5件集まった時点**で表示されました。
ちなみに、その時のレビュー（コメント数）は2件でした。コメント数が関係あるのかは不明ですが、下記記事にも同様の記述がありましたので、**評価5件が表示の条件になっている**のは堅いのではないでしょうか。

[iPhoneアプリにレビューの平均値が表示されるまで » さくさく日記 | さくさく日記](http://iphonework.biz/2010/08/22/iphone%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AB%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%AE%E5%B9%B3%E5%9D%87%E5%80%A4%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E3%81%BE%E3%81%A7/)

# おまけ：Appleによるレビューの削除
一度App Store Connectでレビューが表示されたにもかかわらず、次見たときには消えている（件数が減っている）という謎の現象が起こりました。これについてApple様に問い合わせてみたところ、下記の返信をいただきました。

>レビューはケースバイケースで評価され、Appleの裁量で削除される可能性があります。
今回評価したレビューがApp Storeのガイドラインに違反しており、復元できないと判断しました。
Appleは、利用規約に基づき、レビューを監視する権利を有し、迷惑メール、冒涜、憎悪、明示的/ポルノコンテンツを含むレビューを削除・編集することができます。ごめんね。

なんらかの問題がありAppleに削除されたようです。
【PhpStorm】Find in Path とかの検索結果を100件以上表示する

PhpStorm の小ネタです。
おそらく IntelliJ も同じです。

PhpStorm で `Find in Path` 検索とかすると、`１００　+ matches ~ ` ってなって、100件以上表示されません。

今まで右下の `Open in Find Window` で開いて頑張って探していたのですが、100件以上表示する設定がありました。

（参考）https://stackoverflow.com/questions/44803519/can-i-adjust-the-100-matches-in-x-files-from-intellijs-find-in-path

Registry触るので自己責任で。。

1. Help 
2. Find Action
3. Registryと入力
4. Registry… を選択
5. ide.usages.page.size を探して値を変更

あんまり大きな数値にすると検索が遅くなると思うんでほどほどに。
ReactNativeのScrollView+Keyboardで二回タップを防ぐ

この記事は、`ReactNative`で以下の条件を満たしたい場合の対処法を書いています。

- `ScrollView`を使っている
- ScrollViewの子要素に、 `TextInut`と`Button`(あるいは`TouchableOpacity`)が含まれている
- TextInputに入力するためにソフトキーボードが立ち上がり、入力後に送信ボタンなどを押したいが、 **ボタンを2回タップしないといけない** (1回目のボタンタップでソフトキーボードが消え、2回目のボタンタップでボタンタップ時のアクションが実行される)


解決法はとても簡単で、**ScrollViewの [keyboardShouldPersistTaps
](https://facebook.github.io/react-native/docs/scrollview#keyboardshouldpersisttaps)プロパティの値を `"always" `にするだけ**です。

```
<ScrollView keyboardShouldPersistTaps='always'>
//
</ScrollView>
```
これによって、最初にボタンタップした時にキーボードが隠れるのを防ぎ、そのままボタンタップのイベントを発火させることができます。

もちろん、[KeyboardAwareScrollView ](https://github.com/APSL/react-native-keyboard-aware-scroll-view)などでも使用可能です。

参考： [Today’s React Native Tip: Keyboard issues in ScrollView](https://medium.com/react-native-training/todays-react-native-tip-keyboard-issues-in-scrollview-8cfbeb92995b)