OmniAICreator/Qiita-1.07M huggingface dataset:
Promiseのメソッドチェーンに潜む罠

[引用元](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)
> Promise.prototype.then() メソッドと Promise.prototype.catch() メソッドもまた Promise を返すので、これらをチェーン (連鎖) させることができます。

なるほど確かにメソッドチェーンで書くことはできる。
じゃあメソッドチェーンをしなくても当然書けるよね、と思ってたら足元をすくわれた、という話。

# おさらい

Promiseの基礎は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)

# やってみる

## 例

```javascript

const t = Date.now();

function doneAsync(v) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const n = v + 1;
			console.log(`${Date.now() - t}: ${v}, ${n}`);
			resolve(n);
		}, 1000);
	});
}
```

- 1秒後に
- 経過時間・引数・引数に`1`足したものを表示して
- 引数に`1`足したもので解決する

という`Promise`を返す関数があったとして、これを使用した直列的な処理を考えてみる。

期待する結果は

```

1000: 0, 1
2000: 1, 2
3000: 2, 3
```

こんな感じ。[^1]


### ①メソッドチェーン型
```javascript

doneAsync(0)
.then(doneAsync)
.then(doneAsync);
```

### ②非メソッドチェーン型
```javascript

const p = doneAsync(0);
p.then(doneAsync);
p.then(doneAsync);
```

## 実行結果

```:①

1005: 0, 1
2019: 1, 2
3021: 2, 3
```

```:②

1002: 0, 1
2019: 1, 2
2021: 1, 2
```

②のコードの3つ目のthenの実行タイミング・結果がおかしい。
一見等価に思える2つのコード、**実は等価ではなかった**。

## なんで？

`then`の戻り値の認識ズレ。

[引用元](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#Methods_2)
> プロミスに成功ハンドラと失敗ハンドラを付加します。呼ばれたハンドラの戻り値によって解決している新しいプロミスを返します。

この**新しいプロミスを返します**というのが曲者で
メソッドチェーンをした場合、一般的にはメソッドを持つオブジェクト自体が返っているパターンが多く
`then`でも実行した`Promise`オブジェクトが返ってくると認識してしまいがちだが
実は`then`が返すのは**全く別の新しい`Promise`オブジェクト**になっている。

その前提で考えると、
①のコードでは、それぞれの`then`の対象が**それぞれ別の`Promise`オブジェクト**なのに対し、
②のコードでは、全ての`then`の対象が**最初に作成した`Promise`オブジェクト**になっていた。

`Promise`は、解決されたタイミングで自身に対して`then`で登録された`callback`を全て実行している[^2]だけで
単一の`Promise`オブジェクトそのものが直列的な処理フローを持っているわけではない。

解決した結果新たな`Promise`オブジェクトの処理が動き出し、その結果また新たな・・・という実装をしていれば
それが結果的に直列的な処理になっているというだけの話。
この辺、概念としては`callback`の入れ子と何ら変わらないように思う。

なので、②のような場合は

```javascript

const p = doneAsync(0);
const p2 = p.then(doneAsync);
p2.then(doneAsync);
```

のように、前に実行したい処理を持っている`Promise`オブジェクトに対して`then`しなければならない。

## どうしてもメソッドチェーンができない

~~宗教的な理由で~~ある処理を規定回数、`for`文で繰り返させたいなどのシーンで
メソッドチェーンができないということもあるでしょう。

そんな場合であっても、**直前に返された`Promise`に`then`すればいい**ということが分かっていれば

```javascript

let p = doneAsync(0);
for (let i = 0; i < 2; i++) {
	p = p.then(doneAsync);
}
```

みたいな感じで書き換えは大丈夫。


## 悪い事ばかりでもない・・・か？

②のコード、やりたいこととは違っていたものの
逆にこれを**並列処理的なもの**として扱うこともできそう。

```javascript

const p = doneAsync(0);
p.then(v => {
	console.log(v + 123); // 124
});
p.then(v => {
	console.log(v * 200); // 200
});
```

みたいな感じにすると、`doneAsync`の結果(この場合は`1`)を用いて
それぞれ別々の処理を記述する事ができる。

ただ、並列処理とは言っても**複数のブロックを同時に処理しているわけではなく**て
1つ目の`callback`処理を同期的に終わらせたあと、次の`callback`処理をする・・・ってだけなので
処理時間の短縮ができる、なんてことにはなりません。

独立した処理を`then`ブロックで分けると見やすいかもね～程度で。

# まとめ

- 単一の`Promise`オブジェクトに複数`then`しても、想像している直列処理にはならないよ
- 基本的にはメソッドチェーンで`then`した方がいいよ
- どうしてもメソッドチェーンできない場合は、`then`する対象をよく確認してね
- `catch`も`then`と同じだよ




[^1]: 実行時間に数msの差は出る。

[^2]: 厳密には、解決後に登録された`callback`も実行するなどのいい感じの処理もしてくれる。
[MySQL]コマンドラインからMySQLに接続した後、用意したSQLファイルを実行する方法

## 本記事の説明
コマンドラインからMySQLに接続して、接続中に用意したSQLファイルを実行する手順を記載します。
本記事では、SQLファイルの用意から、MySQLの接続、SQLファイルの実行までの手順まで説明します。

## SQLファイルの用意
実行したいSQLファイルを用意します。

```
vi hoge.sql
```

## MySQLに接続
```
mysql -u ユーザー名 -D データベース名 -p
```

## SQLファイルの実行
以下のコマンドで実行します。
結果がコマンドラインに出力されます。

```
mysql> source hoge.sql
```

SQLファイルはMySQLログインしたディレクトリに配置すれば実行されます。
10K SAS RAID5と7.2k SATA RAID1 x4を比べる その2

前回
https://qiita.com/tsurun/items/7680c574ba4486b8780f

前回の続きです。

意図的にキャッシュミスを増やすため、テストサイズを32GBにしてDataCoreのキャッシュサイズ20GBを上回る大きさにして試してみた。


##SAS RAID5 32GB 1回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115778/de380948-e319-e889-0c2d-219d353d3403.png)


   Sequential Read (Q= 32,T= 1) :   205.407 MB/s
  Sequential Write (Q= 32,T= 1) :  2529.667 MB/s
  Random Read 4KiB (Q=  8,T= 8) :    36.274 MB/s [   8856.0 IOPS]
 Random Write 4KiB (Q=  8,T= 8) :   391.043 MB/s [  95469.5 IOPS]
  Random Read 4KiB (Q= 32,T= 1) :    65.623 MB/s [  16021.2 IOPS]
 Random Write 4KiB (Q= 32,T= 1) :   141.713 MB/s [  34597.9 IOPS]
  Random Read 4KiB (Q=  1,T= 1) :    67.559 MB/s [  16493.9 IOPS]
 Random Write 4KiB (Q=  1,T= 1) :    29.484 MB/s [   7198.2 IOPS]

  Test : 32768 MiB [H: 2.3% (0.8/35.0 GiB)] (x1)  [Interval=5 sec]
  
##SATA RAID1 32GB 1回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115778/0f71b05b-3ed9-f229-c75e-1561fb71b8f1.png)

   Sequential Read (Q= 32,T= 1) :   118.054 MB/s
  Sequential Write (Q= 32,T= 1) :  2271.629 MB/s
  Random Read 4KiB (Q=  8,T= 8) :     4.300 MB/s [   1049.8 IOPS]
 Random Write 4KiB (Q=  8,T= 8) :   419.732 MB/s [ 102473.6 IOPS]
  Random Read 4KiB (Q= 32,T= 1) :     5.787 MB/s [   1412.8 IOPS]
 Random Write 4KiB (Q= 32,T= 1) :   192.944 MB/s [  47105.5 IOPS]
  Random Read 4KiB (Q=  1,T= 1) :     7.722 MB/s [   1885.3 IOPS]
 Random Write 4KiB (Q=  1,T= 1) :    47.188 MB/s [  11520.5 IOPS]

  Test : 32768 MiB [G: 2.3% (0.8/35.0 GiB)] (x1)  [Interval=5 sec]

#ライトスルーにして、インターバルも60秒にして、GUIからバックエンドへのIOが無くなったことを確認してからやってみることにした。
##SAS RAID5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115778/5af1421e-aabb-ffbe-64ee-b6f3efdef6ac.png)

   Sequential Read (Q= 32,T= 1) :  1061.049 MB/s
  Sequential Write (Q= 32,T= 1) :   869.983 MB/s
  Random Read 4KiB (Q=  8,T= 8) :    57.141 MB/s [  13950.4 IOPS]
 Random Write 4KiB (Q=  8,T= 8) :    47.587 MB/s [  11617.9 IOPS]
  Random Read 4KiB (Q= 32,T= 1) :    64.960 MB/s [  15859.4 IOPS]
 Random Write 4KiB (Q= 32,T= 1) :    43.677 MB/s [  10663.3 IOPS]
  Random Read 4KiB (Q=  1,T= 1) :    67.027 MB/s [  16364.0 IOPS]
 Random Write 4KiB (Q=  1,T= 1) :    35.346 MB/s [   8629.4 IOPS]

  Test : 32768 MiB [H: 2.3% (0.8/35.0 GiB)] (x1)  [Interval=60 sec]
  
##SATA RAID1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115778/80e47f66-f949-cbc9-ed3a-f649d999c2e6.png)


   Sequential Read (Q= 32,T= 1) :   240.465 MB/s
  Sequential Write (Q= 32,T= 1) :   369.747 MB/s
  Random Read 4KiB (Q=  8,T= 8) :    14.551 MB/s [   3552.5 IOPS]
 Random Write 4KiB (Q=  8,T= 8) :    27.487 MB/s [   6710.7 IOPS]
  Random Read 4KiB (Q= 32,T= 1) :    19.420 MB/s [   4741.2 IOPS]
 Random Write 4KiB (Q= 32,T= 1) :    31.779 MB/s [   7758.5 IOPS]
  Random Read 4KiB (Q=  1,T= 1) :    20.383 MB/s [   4976.3 IOPS]
 Random Write 4KiB (Q=  1,T= 1) :    35.053 MB/s [   8557.9 IOPS]

  Test : 32768 MiB [G: 2.3% (0.8/35.0 GiB)] (x1)  [Interval=60 sec]


前回の結果と合わせて見てみると、キャッシュヒット率が落ちてくるとやっぱりSAS RAID5の方が早いみたいだけど、致命的な差ではなさそう。むしろメモリさえたくさん積んでおけばSATAでも構わないからRAID1複数個を束ねる方がよさそう。
ionicで開発を始めた1ヶ月前の自分に伝えておきたい事

一先ずios版のリリースまで漕ぎ着けたので反省と雑感。

## バージョンを確認する
ionic-cli とionic本体のバージョンは別物です。
`ionic --version` という何気ないコマンドで返ってくるのはionic-cliのバージョンです。
ionic4だと思ってしばらく開発を進めていたのですが実はionic3という事態で、ドキュメント(ionic4の)通りに実装しても動かない事が多々あり、ドキュメント適当すぎるだろ！と思っていたら馬鹿は自分でした。
正しくは `ionic info` でバージョンを確認することが出来ます

## 一旦tslintを切る
ionic-cliで`run`や`emulate`を行うと、自動的にtslintがソースをチェックをしてくれます。
くれるんですが、えらい時間が掛かります。
package.jsonの中に以下の設定を追加するとtslintが走りません。

```javascript:package.json

  "config": {
    "ionic_enable_lint": false
  },
```

## Cordovaを使う機能は後回しに
開発を始めた当初は `ionic serve` コマンドを使い、ブラウザでリアルタイムに確認していたのですが
googlemap用のプラグインをインポートしたところ、ionic serve is not supported という事で表示が出来なくなりました。
そんなものかと `ionic cordova run browser` で開発を続けたんですが、圧倒的に `ionic serve` の方が早です。
今やり直すならcordova使うプラグインの実装は後回しにします。

## xcodeを思ったより使う
リリースまでの全てをionicで完結出来る訳ではない事はなんとなく想像していましたが思っていたよりxcodeが開きっぱなしです。
`ionic cordova run ios` で出てくるエラーとはionic上で戦わず、早々にxcodeを開いて対処した方が解決が早いです。

## スペックがものを言う
アプリ開発にionicを選ぶという事は、Webエンジニアでスクリプト言語に慣れ親しんでいるみたいなタイプの人が多いのだと思います。
自分もそうなのですが、そうなると普段のWeb開発にさほどマシンスペックを必要としていません。
なんですが、ビルドが存在する世界線に入るとスペックの違いが露骨に出ます、数秒の差が積み重なって中々のストレスです。
いま新しいMacBookProを買うなら6コアか8コアを選びます。

## 学習コストはそれほど高くない
AngularやReactなど選択するプラットフォームでの開発経験があれば改めて勉強しないといけない内容は然程ないと思います。

## 完成後が面倒
DeveloperAcountの登録やAppSroreConnectでの作業、xcode通してのアップロードなど、Appstoreに関わる雑務が諸々あります。
会社の情報登録したりDUNSNumber発行したり、2FA様に一台端末用意して管理方法決めたり。
自分で行った一連の作業を再現出来る気がしません。
スクリーンショットや紹介文など用意しないといけないコンテンツも多く、開発以外の部分で結構な面倒を感じました。
気軽に始めてしまったのですが必要な能力も別物なので、エンジニアは開発に専念した方が幸せかもしれません。

## Slackチャンネル
日本語のチャンネルがあって情報が集まっています。
https://ionic-jp.herokuapp.com/

## 結論
今後もionicで開発を進めていこうと思います。
Picassoで円形に切り取った画像に枠線を付ける

## はじめに
Picassoで画像を円形に切り取るのは [Picasso で角丸なImageを描画する](https://qiita.com/tanukiti1987/items/df313f499768369e5adf)などで紹介されていますが、更に切り取った画像に枠線を付けたいことがあったので調べたメモです。

今回使ったライブラリのバージョンは下記です、適宜読み替えて下さい。

 * com.squareup.picasso:picasso:2.71828

## 実装
巷に出回っているCircleTransformにもう少し手を加える形で実現できました。

```kotlin:BorderedCircleTransform.kt
import android.graphics.*
import com.squareup.picasso.Transformation

class BorderedCircleTransform(
    private val borderColor: Int,
    private val borderSize: Int
) : Transformation {

    override fun transform(source: Bitmap?): Bitmap? {
        source ?: return null

        val size = Math.min(
            source.width,
            source.height
        )

        val x = (source.width - size) / 2
        val y = (source.height - size) / 2

        val squaredBitmap = Bitmap.createBitmap(
            source,
            x,
            y,
            size,
            size
        )

        if (squaredBitmap != source) {
            source.recycle()
        }

        val bitmap = Bitmap.createBitmap(
            size,
            size,
            source.config
        )

        val canvas = Canvas(bitmap)
        val paint = Paint().apply {
            shader = BitmapShader(
                squaredBitmap,
                Shader.TileMode.CLAMP,
                Shader.TileMode.CLAMP
            )
            isAntiAlias = true
        }

        val r = size / 2f
        Canvas(bitmap).drawCircle(
            r,
            r,
            r,
            paint
        )

        val paintBg = Paint().apply {
            color = borderColor
            isAntiAlias = true
        }

        canvas.drawCircle(
            r,
            r,
            r,
            paintBg
        )

        canvas.drawCircle(
            r,
            r,
            r - borderSize,
            paint
        )

        squaredBitmap.recycle()

        return bitmap
    }

    override fun key(): String = "bordered_circle"
}
```
呼び出し時にborderの色と太さを指定できます。

```kotlin
        Picasso.get()
            .load(URL)
            .transform(
                BorderedCircleTransform(
                    borderColor = Color.RED,
                    borderSize = 4
                )
            )
            .into(image_view_bordered_circle)
```

文字色を赤、太さを4で指定するとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68671/bb7456bd-f0ce-7e5f-02ce-977c2485b6cf.png)


## おわりに
早くImageViewのプロパティでサクッと円形や枠線をつけることが出来る時代が来て欲しいですね。
USE case: 場合分け

職業訓練
https://qiita.com/kaizen_nagoya/items/95368b63fa21d64271ec

Day2, UML
https://qiita.com/kaizen_nagoya/items/bf1ac474aae48b27ef57

# Use case図を描こうとしている。

猫中心設計で、猫と車について、衝突して死亡したという図の描きかけ。

![cat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/1f909c6c-05ec-0548-2e90-98df5e057c62.png)

車は無人運転者でなければ、人が乗っている。

無人運転車と、友人運転車の２つの場合に分けて書くと良い。

車をActorとするか、Objectとするかで２つの選択肢がある。

死亡事故と死亡事故以外で場合分けができる。

Sequence図の場合分けの仕方はわかりやすい。
UseCase図は、場合分けの仕方はあるのだろうか。
Flutter シミュレータデバッグバーを隠す

#Ios Simulator Remove Debug Bar 

###Demands

1 We have a Flutter project. 
2 We achieve the flutter project at Xcode
3 We want to submit the app from App Store Connect
4 When we click the submit button. Apple tells us to fulfill the screenshot of 6.5 inch 5.5inch 12.9inch

<img width="500" alt="スクリーンショット 2019-06-13 16.39.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/33c7e319-1a8c-2653-d8fd-60b05d8abab4.png">


5 We only have an iPhone X device which is in 5.7inch
6 We come up with the idea to use the simulator
7 We get the following simulator. There is a red debug mark on the right top side of the simulator.

<img width="210" alt="スクリーンショット 2019-06-13 16.43.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/9331eccf-cc7d-9b82-8e58-3ed3a575d4f8.png">
8 We are worried about the result of the review from apple inc. So how to remove it?
9 We tried to modify the scheme of the build from Xcode
![スクリーンショット 2019-06-13 16.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/208746b4-84e8-846f-8322-dd9e2b842f33.png)
10 But we get the error below

```
========================================================================
ERROR: Flutter does not support running in profile or release mode on
the Simulator (this build was: 'release').
You can ensure Flutter runs in Debug mode with your host app in release
mode by setting FLUTTER_BUILD_MODE=debug in the .xcconfig associated
with the Release build configuration.
========================================================================
Command PhaseScriptExecution failed with a nonzero exit code
```

11 Yes, the project is generated by the flutter framework. And the flutter ios project cannot run release mode on the simulator.

12 But there is another way

13 Open the project with IntelliJ IDEA
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/05631502-0018-8878-cff4-8f80ebf89de5.png"/>

14 Run the project on IntelliJ IDEA

15 After the simulator is launched by IntelliJ IDEA. Open the Flutter Inspector. The Window view is like this
![スクリーンショット 2019-06-13 17.11.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/3f6e616f-92b6-09cd-29ec-a488d3f595af.png)

16 In the list of More Actions, there is Hide Debug Mode Banner
![スクリーンショット 2019-06-13 17.12.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/cafb2c6b-c7a8-174e-78cb-21b054e4ade4.png)

17.After click on it. The debug bar will be hidden immediately.
<img width="200" alt="スクリーンショット 2019-06-13 17.13.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/7b9613ce-ebc6-0d49-b446-3d599aab99b6.png">

###Summary
1. By using the Flutter Inspector at IntelliJ IDEA
2. There is no necessary to modify build scheme on Xcode
Nginxで504 Gateway Time-out

重いページ開こうとすると504エラーが出ていたときにしたこと。
nginxの設定で色々いじったので備忘録。

まず以下を変更してみたが変わらず。

```
  fastcgi_connect_timeout 600s;
  fastcgi_send_timeout 600s;
  fastcgi_read_timeout 600s;
```

次に以下。これでもダメ。

```
  keepalive_timeout 600;
```

最終的に以下を変更でうまくいきました！

```
  send_timeout 180;
  proxy_connect_timeout 600;
  proxy_read_timeout    600;
  proxy_send_timeout    600;

```

そもそもページ開くだけでタイムアウトになるほど重いのが根本的に良くないんですけどね...
tensorflow-gpuで libcublas.so.10.0のImportError

tensorflow 1.13からcuda10がデフォルで利用されるようになり、

そこで下記のようなエラーが出された

```
ImportError: libcublas.so.10.0: cannot open shared object file: 
No such file or directory
```

cuda9.0を利用していたのでまずは10にアップデート。

しかし、まだ上記エラーは消えない。　

ちなみに、PATHは下記のように通している

```
# CUDA
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```

/usr/local/cuda/lib64配下に確かにlibcublas.so.10.0はない。
どうやら, 下記にあるよう。

```
/usr/lib/x86_64-linux-gnu
```
したがって
LD_LIBRARY_PATHに上記を追加する。

```
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
```

以上で、OK. 

参考: 
https://github.com/tensorflow/tensorflow/issues/26182#issuecomment-472674508
[docker]コンテナの動作確認・起動・停止の方法（コマンド）

# 本記事ではどんな事を説明するのか？
dockerで稼働しているコンテナに対しての動作のコマンドを記載します。


# コマンド一覧
下記コマンドはどのディレクトリにいても、dockerが起動していれば実行可能です。
## コンテナの動作確認
### 動作しているコンテナのみ表示
```
docker  ps
```
### 動作・停止しているコンテナを表示
```
docker ps -a
```

上記を実行すると、コンテナの様々な状態が表示されます。
コンテナの起動・停止に使用する`CONTAINER ID`や、動作状況が分かる`STATUS`が表示されます。

```
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
```

## コンテナの起動
下記の[コンテナID]は、上記`docker ps -a`にて確認可能です。

```
docker start [コンテナID]
```

## コンテナの停止
```
docker stop [コンテナID]
```

## コンテナの再起動
```
docker restart [コンテナID]
```

## コンテナの削除
```
docker rm [コンテナID]
```
HTML ３つのリンクについて

こんにちは職業です。

今回は「３つのリンク」について扱っていきます。

「URLのリンク」
「別のファイルへのリンク」
「ページ内リンク」

一括でまとめましたのでご参照ください。

「URLのリンク」
例として職業のリンクを指定していきます。
また、target属性を指定すると、別タブでリンクすることが出来ます。

「別ファイルのリンク」
まず、初めに別ファイルを用意します。
ファイル名の指定の仕方は、herfで指定してあげます。
リンク先はnext.htmlとしています。

「ページ内リンク」
リンクしたいところにidを指定します。
指定したいものと同じものを記入します。

![リンク４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/64ef58b8-4a58-200b-6149-053de00153e0.png)

![リンク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/a7da6a9d-17b7-3164-3d9c-fb2d313aa6c7.png)
![リンク１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/29798c21-cc48-bfe1-1fed-d0f50e293e93.png)
![リンク２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/0fd10002-ffbc-f011-05a1-74f4d5756681.png)
![リンク３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/3745e7a4-cc1c-343c-edfc-282d317f0da0.png)



**感想**
命令が上手くいくと非常に楽しくできます。


それではまた！
brewでインストールしたパッケージをアップデートする方法

## 背景
vimとneovimに脆弱性があるとのこと↓
https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md

対象は `Vim < 8.1.1365, Neovim < 0.3.6`とのこと

おもむろにターミナルを確認

```
$ nvim -v
NVIM v0.3.4
```

アップグレードは以下のようにします。

```
### まずはbrewをアップデート。これをしないと最新のパッケージのバージョンを取得できない
$ brew update

### アップグレード対象のパッケージを指定
$ brew upgrade neovim

### 実行後確認
$ nvim -v
NVIM v0.3.7
```
Splunk 選択されたフィールドに追加したい

検索するときの細かい話ですが、選択されたフィールド selected field に追加する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394817/7de0abfe-8af4-bb90-5e2c-f91ce4813b47.png)

デフォルトではhost,source,sourcetypeが設定されている

#１．GUIから設定
「すべてのフィールド」を押下
例えば、forksを追加したい場合は左側のチェックボックスを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394817/84db5caa-8115-428b-7ed0-c52db9379bd7.png)

#２．confファイルで設定
splunk/etc/app/配下の ui-prefs.conf を設定
例えば、サーチアップにforksを追加したい場合は

[search]
display.events.fields = ["host","source","sourcetype","forks"]

を追加

以下answersリンク
https://answers.splunk.com/answers/185864/selected-fields-in-fields-side-bar.html

結果はどちらの手順でもこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394817/e9bce04a-2a93-d2cf-4795-0a07218c68c5.png)



以上です。
icloudとのファイル共有

jekyllとgithub pagesを使ってblogを共有することは可能になったんですが，privateにはできないことが判明．したがって，他人に見られたくないhtmlはやはり違う管理が必要．そこで，icloudを使うことにする．初めからそうすればよかったやん．

ところがね．．．
# finderやterminalから見えない
1. システム環境設定のiCloudでiCloud Driveをオンにしてなくてどこからも見れなかった．
2. onにすれば，~/Library/Mobile\ Documentsからいくつも見える．
3. com~apple~CloudDocsが良さそう

# iPhoneに反映されない
でも，iphoneではファイルが反映されない．なんで？と思ってたのですが，loginができていませんでした．
1. 設定->パスワードとアカウント->iCloud
2. アカウント名を選択
3. そこでpass wordを聞かれます．

# iPhoneでの表示
うまくiCloudに入ると
1. 「ファイル」アプリを選んで，
2. ブラウズを選択して，
3. iCloud Driveを選択
すると共有ファイルにアクセスできます．
リストにNULLが含まれるとtibbleにできないので、NAに強制変換する


# TL;DR

NULLが含まれるリストは```as_tibble()```が使えないので、先にNULLをNAに置換するといいよ

# リストをtibbleにしたいが、エラーが出る

スクレイピングなどで取得したリスト形式のデータは、tidyverse的に```as_tibble()```を使って```data.frame```に変換すると、扱いやすいです。
ですが、リストの要素にNULLが含まれていると、エラーがでます。

```list_to_tibble.r

library(magrittr)
library(tibble)

data <- list(lm_id = "LMFA0000001", name = "2-methoxy-12-methyloctadec-17-en-5-ynoyl anhydride", main_class = "Other Fatty Acyls [FA00]", sub_class = NULL)
data

$lm_id
[1] "LMFA0000001"

$name
[1] "2-methoxy-12-methyloctadec-17-en-5-ynoyl anhydride"

$main_class
[1] "Other Fatty Acyls [FA00]"

$sub_class
NULL # <- NULLなのでエラーになる
```

```list_to_tibble.r
data %>% as_tibble
Error: All columns in a tibble must be 1d or 2d objects:
* Column `sub_class` is NULL
Call `rlang::last_error()` to see a backtrace
```

# リストに含まれるNULLをNAに置換する

NULL値があるといけないので、```lapply()```を使って、NULLをNAに置換してます。

```list_to_tibble.r
data %<>% lapply(function(x) if(is.null(x)) {NA} else {x})
data
$lm_id
[1] "LMFA0000001"

$name
[1] "2-methoxy-12-methyloctadec-17-en-5-ynoyl anhydride"

$main_class
[1] "Other Fatty Acyls [FA00]"

$sub_class
[1] NA # NULLからNAに置換
```

NAにすれば、```as_tibble()```で```data.frame```に変換できます。

```list_to_tibble.r
data %<>% as_tibble
data
# A tibble: 1 x 4
  lm_id      name                                  main_class          sub_class
  <chr>      <chr>                                 <chr>               <lgl>
1 LMFA00000~ 2-methoxy-12-methyloctadec-17-en-5-y~ Other Fatty Acyls ~ NA
```
EA

アドインの有効化　BPMNを選択したら

```
C:\Program Files (x86)\SparxSystems Japan\EA>reg add "HKCU\Software\Sparx Systems\EAAddins\BPMNサポート" /ve /d "BPMN20.MainClass"
値  は存在します。上書きしますか? (Yes/No) y
この操作を正しく終了しました。

C:\Program Files (x86)\SparxSystems Japan\EA>pause
続行するには何かキーを押してください . . .
```
Windows 上の Python で UTF-8 をデフォルトにする

TL;DR: UTF-8をデフォルトで使いたい人は環境変数に `PYTHONUTF8=1` を設定しよう

Python は文字列が unicode なので、あちこちで「適切」なエンコーディングを選択する必要があります。残念ながら後方互換性やWindows固有の事情によりまだ ANSI Code Page (日本語なら cp932) がデフォルトで使われる場面があります。

ざっと Python と外の世界との入出力をあげてみます。

* テキストファイルを読み書きする時のデフォルトのエンコーディング = ACP
* 標準入出力のエンコーディング
    * 標準入出力がコンソールのとき = UTF-16 で WriteConsoleW 等を呼ぶ
    * 標準入出力がコンソールでない時 = ACP
* 子プロセスとのPIPE = ACP

最近 `chcp 65001` を使って UTF-8 を使う方法が広まっているように思います。これはコンソールのエンコーディングを指定する (SetConsoleCP(), SetConsoleOutputCP()) ものなので、標準出力がリダイレクトされた場合には関係ありません。

```
# Power Shell 6
PS C:¥> python3 -c "print('おはよう')" > ps.txt

# cmd.exe
C:¥> chcp 65001
C:¥> python3 -c "print('おはよう')" > cmd.txt
```

同じコマンドに見えますが、 Power Shell 6 で出力した ps.txt は UTF-8 で書かれていて、 cmd.exe で出力した cmd.txt は cp932 で出力されました。 Power Shell は python3 の標準出力を一旦受け取り、 cp932 から UTF-8 に変換してリダイレクト先に書き込んでいるからです。

さて、 Python 3.7 からは最終兵器である [UTF-8 mode (PEP 540)](https://www.python.org/dev/peps/pep-0540/) があります。このモードは Python を起動する時にコマンドラインオプションで `-X utf8` を追加するか環境変数で `PYTHONUTF8=1` を設定しておくと有効になります。このモードではエンコーディングは次のようになります。

* テキストファイルを読み書きする時のデフォルトのエンコーディング = UTF-8
* 標準入出力のエンコーディング
    * 標準入出力がコンソールのとき = UTF-16 で WriteConsoleW 等を呼ぶ
    * 標準入出力がコンソールでない時 = UTF-8
* 子プロセスとのPIPE = UTF-8

これで一貫して UTF-8 を使うことができます。

この状態では子プロセスとのパイプもデフォルトではUTF-8になってしまうので、cp932を使うコマンドを利用する＆パイプをテキストモードで開くときにはエンコーディングに "mbcs" か "cp932" を指定する必要があります。

cp932 のままのコンソールを使う場合も、コンソール自体への入出力は WriteConsoleW が使われるので文字化けしないはずです。テキストファイルのエンコーディングがUTF-8に切り替わるのも多くの人にとってはメリットでしょう。 (type コマンドでそのファイルを表示すると文字化けしますが)

一方 PowerShell を使う場合、 python3.exe が標準出力に UTF-8 を書いているよと簡単に伝える手段が不明です。（[この記事](https://aquasoftware.net/blog/?p=378) を見つけたのですが、コマンドを実行するたびにこれをするのは...）

Python を Windows 上で使ってなるべく UTF-8 を使いたい人は次のような装備を揃えると良いでしょう。

* デフォルトで UTF-8 を利用するテキストエディタ (VS Code, Atom, Windows 10 1903 以降のメモ帳)
* cp65001 を利用するように設定した cmd.exe (あるいは勝手に cp932 -> UTF-8 変換しないシェル)
* 環境変数 `PYTHONUTF8=1` を設定した Python 3.7 以降
Windows の Aero Shake （エアロシェイク）を無効にする

#Windows で ウィンドウをもってマウスを振ると・・・
他のウィンドウが全部閉じる！

**これがまたうっとおしい！**

#無効にする
大体、レジストリをいじる方法や、コンパネからスナップごと無効化する方法があるが、それはあったほうがいいので、エアロシェイクのみ無効化します。

レジストリをいじる方法もありますが、いじらなくてもできるっぽいので紹介。

**（Windows 10 Pro での方法なので Home の人は他の方法でよろしくどうぞ）**

１．Win + R で gpedit.msc と入力し、グループポリシーエディタを開く（他の方法でもよい）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136398/23f4d35f-24c4-eaa7-00b8-190e79a616a1.png)

２．ユーザーの構成 > 管理用テンプレート > デスクトップ にある「Aero Shake のウィンドウ最小化のマウス ジェスチャをオフにする」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136398/5c110432-4b0a-7a03-03e8-f58dac27ad35.png)

３．これを有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136398/566292f1-96a4-9b05-4044-daddc4316c34.png)

すると・・・

**振っても閉じない！**やったぜ。

#参考
https://www.haruru29.net/blog/windows10-move-window/
（こちらの情報に写真を追加しただけです）

参考元の方に感謝です。
googleドキュメント系の文字装飾ショートカット

# はじめに
覚書レベルのメモです。
いろいろ不備があると思いますが、ご容赦くださいませ。

# googleドキュメント系の文字装飾ショートカット
プレゼン直前に状況が変わって、**急いでgoogleスライドの資料修正！**
古い情報を取り消し線で消して最新の情報を記載して反映！

という超できるプレゼンターをしようとしたが、**取り消し線のアイコンが見つからない！**

![gdrive-fonteffect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435600/91647351-3ab0-acc3-d5e3-473af986cfe5.png)


そのときの教訓から以下のショートカットをメモ

### Windowsの場合

| 装飾 | ショートカットキー |
|:-- | :-- |
| 太字 | Ctrl+B |
| 斜体 | Ctrl+I |
| 下線 | Ctrl+U |
| 取り消し線 | Alt+Shift+5 |

### Macの場合
| 装飾 | ショートカットキー |
|:--|:--|
| 太字 | ⌘+B |
| 斜体 | ⌘+I |
| 下線 | ⌘+U |
| 取り消し線 | ⌘+Shift+X |

・・・って、取り消し線、MacとWindowsで異なるのデスネ。
複数プロジェクトを開発している時に jupyter を使う

※この記事は試行錯誤している現状をメモしたものです。ベストプラクティスとは限りません。

世の中の Jupyter Notebook（以下jupyter）の記事は、公式のチュートリアルも含めて、Pythonインタープリタを1個だけインストールしていることを前提にしています。

しかし、私は pyenv で複数のPythonインタープリタをインストールし、pipenvでプロジェクトごとに仮想環境を作って開発しているので、ちょっと困ることがあります。

# jupyterが1個しかないと困ること

jupyterで「Python3」のノートブックを実行する時は、jupyterを起動したPythonインタープリタを使用します。`pandas`などのパッケージを使いたい時は、そのPythonインタープリタにインストールする必要があります。

しかし、プロジェクトごとに、パッケージのバージョンが違ったり、独自パッケージがあったりするので、1つのPythonインタープリタに全パッケージを共存させることはできません。

# 作戦A: プロジェクトごとに jupyter をインストールする

各プロジェクトでjupyterをインストールします

```shell
$ ( cd ~/path/to/foo; pipenv install --dev jupyter )
$ ( cd ~/path/to/bar; pipenv install --dev jupyter )
$ cd ~/path/to/foo; pipenv run jupyter # 開発したいプロジェクトでjupyterを起動する
```

この方法の**メリット**は、

- とにかく分かりやすい: pipenv install するだけ
- 各プロジェクトのjupyterが完全に分離されるので、トラブル時に直すのも簡単

一方**デメリット**は、

- jupyter のインストール先が複数になるため、jupyterをアップデートしたりプラグインを追加したりするのが煩雑になること
- あるプロジェクトから別のプロジェクトに移る時には、jupyterを起動し直す必要がある。プロジェクトを並行開発している場合（レビュー待ち中に別プロジェクトをコーディングするなど）は起動が面倒

# 作戦B： jupyterを --user でインストールし、プロジェクトごとに kernel を作る

まずjupyterは、各プロジェクトとは無関係な場所にインストールします。簡単なのは `--user` を使うことです。こうすると、pipenvやpyenvに関係なく、`jupyter`コマンドを特定のPythonインタープリタで使えるようになります。

```
$ ~/.pyenv/versions/3.7.3/bin/pip install --user jupyter
$ export PATH="$PATH:$HOME/.local/bin" # これを ~/.bash_profile に追加
$ which jupyter
/Users/foo/.local/bin/jupyter
```

そして、各プロジェクトで`ipykernel`というパッケージをインストールし、プロジェクトの仮想環境を「Kernel」としてjupyterに登録します。

```
$ pipenv run pip install ipykernel
$ pipenv run python -m ipykernel install --name="$(basename $(pwd))" --user
```

すると、Notebookを新規作成する時に、「Python3」の他にプロジェクト名が表示され、実行時にプロジェクトの仮想環境で実行できるようになります。
Segwitにおける改善点

LNを勉強したいけど、Segwitが何なのかよくわかっていないので、改善点とメリットを個人的にまとめました。
#ロック・アンロックスクリプト
---
###ScriptPubkey
before :   OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG
after  :   0 <公開鍵のハッシュ>
###scriptSig
before :   <署名> <公開鍵>
after  :   空→witnessに<署名> <公開鍵>を格納

**メリット**
この結果、前述のmereability問題が解消される
#アドレスフォーマット
---
Segwitでは従来のBase58チェックエンコードとは違いBech32が導入されている。
###変更点
Base58のアドレス→version byte + payload + checksum
Bech32のアドレス→human-readable + separator + data
###メリット
・大文字/小文字の区別がない→音声読み上げ可能に！
・QRコードがコンパクトになる
・アドレスの打ち間違えを検出できる(dataの最後6文字はチェックサムが用いられている為)

#ブロックサイズ
---
###変更点
before : 1MBまで
after  : 4MBまで
###サイズの計算方法
Segwitののブロックサイズは以下の式から求められる。

**ベースサイズ　×　３　＋　トータルサイズ**

ベースサイズ : witnessを含まないトランザクションデータのサイズ
トータルサイズ: witnessを含むトランザクションデータのサイズ


**メリット**
witnessに移したデータの分だけデータスペースを効率よく使用できる!!

##最後に##
署名に使われるデータの種類の変更点や拡張機能の話はいつかまとめたいと思います。
次回はLNについて理解していこうと思います。
参照
https://docs.google.com/presentation/d/14GzGI-pcT86r8Vrh_kQmtzGybEOp-biVX1mG2xdvShA/edit#slide=id.g2be4e68226_0_2
AWS + EC2 + Amazon Linux 2 + docker 構築までの手順書

dockerを使い始めて数ヶ月経ちましたが、dockerを開発した方は天才ですね。

今では、dockerを使わずに環境構築やアプリケーション開発は考えられないほどです。

さらにAWSとDockerの相性がとてもいい。

必要な仮想環境を一瞬で構築・破棄する手軽さ。
ネットワークセキュリティを瞬時に構築できる簡単さ。
WEB・プログラムの世界の進化はすごいですね。（笑）

さて、AWSを最近使い始めたばかりなので、AWSの操作に悪戦苦闘していましたが、
だんだん掴んできたので、備忘録をどんどん残して行きたいと思います。

今回は、EC2のメインAMI「Amazon Linux 2」にdockerをインストールして、便利な設定を記録しておきたいと思います。

#docker インストール
今までは、ubuntuでDockerを構築していたので、
公式サイトからダウンロードしてDocker環境を構築していましたが、
Amazon Linux 2 では、最初からリポジトリに登録してあるので、yumで一発です。

```bash
# yum更新
$ sudo yum update -y
# docker インストール
$ sudo yum install -y docker
# docker 起動
$ sudo service docker start
```

これだけでdockerが立ち上がります。
ついでにsudo付きでコマンドを実行するのがめんどくさいので、
docker group　にユーザーを追加しておきます。

```bash
# ec2-user を docker グループに追加する
$ sudo usermod -a -G docker ec2-user
```
#docker-compose インストール

docker-compose はyumからインストールできないので、
Githubからダウンロードしてインストールします。

```bash
# root ユーザーに切り替える
$ sudo su -

$ curl -L "https://github.com/docker/compose/releases/download/1.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# docker-compose コマンドに実行権限付与
$ chmod +x /usr/local/bin/docker-compose

# root ユーザーを抜ける
$ exit

# docker-compose コマンドの実行確認
$ docker-compose --version
docker-compose version 1.11.2, build dfed245
```

#作業をしやすくするためにエイリアスを設定する
```bash
# エイリアスを書き込む
$ cat << EOF >> ~/.bashrc
alias d='docker'
alias dc='docker-compose'
EOF

# bashを更新する
$ source ~/.bashrc

$ d --version
Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136

$ ds --version
docker-compose version 1.11.2, build dfed245
```
ちるとしふと　に　学ぶ計算機工学

【ちるとしふと (新鋭短歌シリーズ39)/千原 こはぎ】
https://www.amazon.co.jp/dp/product/4863853106/
　CTRL+Z アンドゥ　p.16 

保存していないイラレと凍りつくわたし一瞬で失くす四時間

この短歌を題材に計算機工学を開設します。
　

#時間

計算機の処理には時間がかかります。
有限の時間内に処理が終わるかどうかは、計算機にとって致命的です。
有限の時間ないに処理が終わらないのであれば、処理を中止した方がよいからです。


### CPU　
2.6GHz 
### メモリ
1600MHz DDR3

### Graphics
Intel Iris 

### Disk
APPLE SSD SM0256F   

#空間
メインメモリ、Graphicsメモリに比べて、Diskなどは処理時間が遅いです。
処理時間が速い空間だけで処理が終わるかどうかは、実用的に大事です。


### CPU
64bit core i5
### memory

### Graphics


### Disk


#処理

## 保存
MS-DOSでは、consoleからの入力で、CTRL+ZがEnd of Fileです。
CTRL+Zを入力するとファイルとして保存します。

## Undo
WindowsのAdobe illustratorでは、CTRL+ZがUndoです。

Undoの処理をできるようにするためには、その前の状態を保存しておき、その次の処理を取り消せば、Undoになるようにすることがあります。



## 凍りつく
無限ループに陥っているか、書き込み禁止の場所に書き込もうとして止まっているか、凍りつく理由と状態にはいろいろな場合があります。










#ソフトウェア
###Illustrator
https://www.adobe.com/jp/products/illustrator.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/9287866b-cbf2-cbf8-ba2a-538529c6ffdf.png)

Adobe iLLustratorの略でAi


###PhotoShop
https://www.adobe.com/jp/products/photoshopfamily.html
Google Announced Android Q: Top Features You Need To Know About

Android Q- the successor of Android 9 Pie released into the wild in different beta version in the series. Beta 1 and improved beta 2 version is launched in succession for the developers to start experimenting with new features and enhancements. Finally, in Google I/O 2019 event, the beta 3 version made available to download on an increased range of devices and beta 4 is expected to land in the coming fall.

The string of updates and new features come with the Android Q seems as if Google has finished much finesse in the OS, which was started with Android Pie.

Read more.. https://www.prismetric.com/google-announced-android-q-top-features-you-need-to-know-about/
C# と Java の列挙型の違い

# C# と Java の列挙型の違い

## はじめに
某イベントで Effective Java の訳者として有名な柴田さんとお話する機会があり、長年の疑問が解決したのでメモ。


## それぞれの列挙型

### C# の場合
C# の列挙型はとてもシンプルです。C 言語の `enum` と同じです。

```csharp
public enum Gender
{
    NotKnown = 0,
    Male = 1,
    Female = 2,
    NotApplicable = 9
}
```

こんなかんじで使えます。

```csharp
if (customer.Gender == Gender.Female)
{
    // 女性の場合は割引金額
    return 1500;
}

return 1800;
```

整数で書くと `if (customer.Gender == 2)` のようになるので、仕様書をひっくり返して `2` ってなんだっけ? ってなりますね。列挙型のおかげでいろいろ助かるわけです。


### Java の場合
Java の列挙型は C# のそれと比較して強力です。後発の C# の方が Java より強力であることのほうが多いのですが、列挙型は Java の方が強力な機能の一つです。

```java
public enum Gender {
    NotKnown(0, "不明"),
    Male(1, "男性"),
    Female(2, "女性"),
    NotApplicable(9, "判別不能");

    private final int id;
    private final String name;

    private Gender(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getFee() {
        if (this.equals(Gender.Female)) {
            // 女性の場合は割引
            return 1500;
        }
        return 1800;
    }

    @Override
    public String toString() {
        return this.name;
    }
}
```

C# と違い、Java の列挙型はクラスそのものです。C# では料金を性別で切り替えるのを列挙型の外に書きましたが、Java では列挙型の中に書けます。

こういう区分で処理を切り替えることはよくありますが、C# のような単純な列挙型の場合は、処理の切り替えを探すのが一苦労です。Java の用に列挙型に書ければ、すぐに見つかるわけですね。


## なんで C# の列挙型はしょぼいの?
できないものはしょうがないのであまり調べたことはなかったんですが、柴田さんから納得できる理由をもらいました。

C# は 1.0 (2002) の時点で列挙型は組み込まれていました。対する Java はと言うと... その時点では列挙型がなかったんですね。つまり列挙型に関しては Java の方が後発で、C# よりいい仕様を取り入れることができたってことのようです。

ちなみに、Java への列挙型の導入は Java 5.0 (2004) からです。

よくよく考えると、高機能な列挙型があるのにもかかわらず、よく使われる `Calendar.DAY_OF_MONTH` などは全て整数で列挙型ではありません。その頃にはなかったんですね。全く気が付きませんでした。


## おまけ
### C# でも対抗はできる
C# の (厳密には .NET の) 列挙型はオブジェクトではないので、Java と同じにはなりません。しかし、拡張メソッドを使うと同じようなことはできます。

```csharp
public static class GenderExtensions
{
    public int GetFee(this Gender gender)
    {
         if (gender == Gender.Female)
         {
             return 1500;
         }
         return 1800;
    }
}
```

このクラスを `Gender` 列挙型と同じ名前空間で同じファイルに書けば Java とあんまりかわりません!

ただ、`ToString()` メソッドとかはこの方法が使えないんですよね...


### そもそも必要なの?
確かに Java の列挙型は便利なんですけど、ないならないでっていうお話も。

処理が複雑な場合はストラテジーパターン (もしくはステートパターン) を利用したほうがすっきりするのはよく知られています。

また、金額をデータベースから読み込みたいとなると列挙型には書きづらくなります。

ないならないでなんとかなるんです。

でも、ちょっとした列挙型とか書くときは Java が羨ましくなるのでした!
RaspberryPiにて「sh: can't access tty; job control turned off」と出たとき

# 環境
RaspberryPi 3G
(SDHCカード)TOSHIBA製 32GB


# 状況
Noobsのエラーが出たと表示してから、以下のようなエラーが表示する

```

sh: can't access tty; job control turned off
```

# 解決方法1
調べるといくつか解決方法があり、自分は試しましたがうまくいかなかったパターンを先に紹介します。

RaspberryPiのSDカードをPCで開き、config.txtを開く。
それから`avoid_safe_mode=1`という一文を最後の行に付け加える。
RaspberryPiにSDカードを戻して起動。
これでOKな人はOKなようです。

ただ自分の場合はこの方法ではエラーが残りKernel Panic云々と表示されるだけでした。

# 解決方法2
別の解決方法です。
同様にSDカードをPCで開き、recovery.cmdlineというファイルがあると思います。
このファイルを開くと一行だけのファイルで、いろいろと(引数)が羅列されています。
その行末に(半角スペースを挟んで)`disablesafemode`と書き足します。
あとはSDカードをRaspberryPiに戻して起動

# 解決方法3
もうマイクロSDHCカードを変える。

# 終わりに
僕はマイクロSDHCカードを交換しました。
Azure Media Services のライブ配信のテストに使える、テスト用映像を ffmpeg で生成する。

#やりたいこと
- Azure Media Services の Live Channel の機能をテストしたい

#面倒なこと
- RTMP を喋れるようなエンコーダーを用意するのが結構めんどくさい
- テスト用映像を用意するのがめんどくさい
- PC のライブカメラを使うと、自分の顔がずーっと流れてて残念な気持ちになる
- 何秒くらい遅延しているかをテストするために、映像に時計の情報を入れたいがそれが結構めんどくさい

#それ、ffmpeg で解決出来ました！
下記コマンドにて ffmpeg を起動するだけ！

```testsignal-rtmpingest.bat
ffmpeg.exe -v verbose -re -f lavfi -i testsrc -f lavfi -i "sine=frequency=440:sample_rate=44100:beep_factor=8" -strict -2 -c:a aac -b:a 128k -ar 44100 -r 30 -g 60 -keyint_min 60 -b:v 400000 -c:v libx264 -preset medium -bufsize 800k -maxrate 400k -f flv rtmp://ライブチャンネル名.channel.media.azure.net:1935/live/自動生成されるパラメーター/mystream1
```

#何をやっているか
- ffmpeg のフィルターで testsrc を使って時計付きテストパターンを生成
- 同じく、音声側は 440Hz のビープ音と、1 秒ごとの 3520Hz の短いビープ音の生成
- x264 でエンコードして rtmp で指定したライブチャンネルにインジェスト

#こんな感じ
![ffmpegtest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/ebca0a3d-aad9-887f-38e5-2d93ff080324.png)

#ffmpeg ダウンロード先
こちらから！
https://ffmpeg.org/
[python] macOS mojaveでtheanoを使うモジュールでエラーが出る問題を解決する

Pythonでpymc3などを使うときにtheanoが内部でインポートされるが，その際にmacOS mojave以降で以下のようなエラーがimport時に出ることがある．

```python
import pymc3 as pm
```

```sh
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/pymc3/__init__.py", line 5, in <module>
    from .distributions import *
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/pymc3/distributions/__init__.py", line 1, in <module>
    from . import timeseries
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/pymc3/distributions/timeseries.py", line 1, in <module>
    import theano.tensor as tt
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/__init__.py", line 110, in <module>
    from theano.compile import (
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/compile/__init__.py", line 12, in <module>
    from theano.compile.mode import *
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/compile/mode.py", line 11, in <module>
    import theano.gof.vm
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/gof/vm.py", line 674, in <module>
    from . import lazylinker_c
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/gof/lazylinker_c.py", line 140, in <module>
    preargs=args)
  File "/Users/jotaro/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/theano/gof/cmodule.py", line 2391, in compile_str
    (status, compile_stderr.replace('\n', '. ')))
Exception: Compilation failed (return status=1): In file included from /Users/jotaro/.theano/compiledir_Darwin-18.2.0-x86_64-i386-64bit-i386-3.6.8-64/lazylinker_ext/mod.cpp:1:. In file included from /Users/jotaro/.pyenv/versions/anaconda3-5.0.1/include/python3.6m/Python.h:25:. /Users/jotaro/.pyenv/versions/anaconda3-5.0.1/bin/../include/c++/v1/stdio.h:108:15: fatal error: 'stdio.h' file not found. #include_next <stdio.h>.
```

## 原因・解決法
macOS　mojaveからヘッダファイルがデフォルトで`/usr/include`に置かれていないのが原因．
以下のスクリプトを実行すると，.pkgをインストールするダイアログとともにヘッダファイルが当該ディレクトリに配置されるようになる．

```sh

open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```
webpackでモジュール間で共通変数を持ちたい


## 2020/05/10追記

**うまくいかず、、**

hoge.jsでの変更が huga.jsに反映されませんでした。
定数の扱いになってしまうみたいで、 
huga.jsの glogals.a は、10のまま。。

これを試しても、やはり同じ感じです。
https://webpack.js.org/plugins/provide-plugin/

webpackの仕様が変わったのか。
とりあえず、windowオブジェクトに名前空間用意するしかないかなぁ。。

誰か知っているかた、おしえてください！


## jsファイル間で変数を共有したい時

その昔は、、、

```javascript:globals.js
(function(){}(
 window.common = {
  a:10,
  b:12
}
))();
```

```javascript:a.js
(function(){}(
 window.common = window.common || {}
 window.common.a++;
 console.log(window.common.a); // 11
))();

```
```javascript:b.js
(function(){}(
 window.common = window.common || {}
 window.common.a++;
 console.log(window.common.a); // 12
))();
```

```html:index.html
<html>
<title>バンドルツール出る前の旧石器時代</title>
<head>
</head>
<body>
<script src="./globals.js">
<script src="./a.js">
<script src="./b.js">
</body>
```

こんなことしてた

## webpack使った時
~~同じ事したい時、どうすればいいのか。~~
~~この記事を見て、実験してみたらうまいこといった。~~
[ES6 Modules 間では export/import された変数（？）は同期される](https://qiita.com/shuhei/items/f74e1f7478839e829b16)

```javascript:globals.js
export default {
  a:10,
  b:15
};
```

```javascript:module_hoge.js
import globals from './globals';
console.log(globals.a) // 10
globals.a++;
console.log(globals.a) // 11
```
```javascript:module_huga.js
import globals from './globals';
console.log(globals.a) // 11
```

:relaxed:

~~この方法は正しいのだろうか。~~
~~他にも色々ありそう。~~
https://stackoverflow.com/questions/37656592/define-global-variable-with-webpack
Androidデバイスroot取れるか早見表(magisk)

個人で調べた範囲のまとめ。
Magiskを使ってAndroidのrootを取る事が前提

次の条件のいずれかが揃っていればRoot化可能なはず。
`adb`と`fastboot`はAndroidをいじるなら何かと必要なので入れておきましょう。
Ubuntuなら`sudo apt install android-tools-adb android-tools-fastboot`で入ります

1.と2.の方法についてはMagisk公式にも記載あり: https://github.com/topjohnwu/Magisk/blob/master/docs/install.md

## 1.fastboot で カスタムリカバリー を焼く方法

*条件*

- Bootloader Unlock 済 (fastboot flashできる状態)
- Root化したい端末向けのTWRPバイナリが手に入る
    -  TWRP公式 https://twrp.me/ で希望の端末のTWRPバイナリがあるか検索
    -  もしTWRP公式に載ってなくても[ 端末名 TWRP ]などでググると誰かが移植して公開してるのが落ちてるかも。
    -  誰かが移植して適当に公開しているTWRPバイナリは危険な気がするけど、度胸

*方法*

 1. `fastboot flash recovery [twrp_img]`でTWRPを焼く
 2. 端末でTWRPを起動し、TWRP上でmagiskをFlash
 3. Android上でMagiskManagerを起動し、magisk本体をDirect Installする



*ポイント*

- Android上で動くMagiskが自身のROMを書き換えるので、**Stock ROMが不要**
- 発売して間もない端末や、マイナーすぎる端末はTWRPバイナリがまだ存在しない事が多い


## 2.fastbootでMagiskインストール済みのboot ROMを焼く

*条件*

- Bootloader Unlock済み(fastboot flashできる状態)
- Stock ROM(boot.img)が手に入る
 - メーカーのウェブサイトから入手できれば最善
 - 野良ROMサイト https://www.needrom.com/ から落とせる場合もあるが、怪しいので自己責任で。
 - [端末名 Stock ROM]とかでググるとヒットするかもしれないが、更に怪しいのでこれも自己責任で。

*方法*

1. root化したい端末のboot.imgを予め転送しておく
2. MagiskManager.apkをインストールする
3. MagiskManagerを起動し、`Install Magisk`→ `Select and Patch a File` → (1.)で転送しておいたboot.imgを選択
4. `/sdcard/Download/magisk_patched.img`に Magisk インストール済の bootバイナリ(パッチ済ROM)が出来上がります
5. `adb pull /sdcard/Download/magisk_patched.img`で吸い出しましょう
6. 端末をfastbootモードにして、`fastboot flash boot magisk_patched.img`でパッチ済みROMを焼きましょう

*ポイント*
 - 対象端末のTWRPバイナリがなくてもMagiskを導入できる


## 3.SP Flash Toolで Magiskインストール済みのboot ROMを焼く(MediaTek端末)

*条件*

 - MediaTekのSoCを使った端末
 - SP Flash Toolが使える状態 (ほとんどのMediaTek端末は使えると思いますが要確認)
 - Stock ROMが手に入る

*方法*

 パッチ済みROMを作るまでは _fastbootでMagiskインストール済みのboot ROMを焼く_ の 1~5と同じです

6. SP Flash ToolでStock ROMのScatterファイルを指定する
7. Stock ROMのboot.imgをパッチ済みに入れ替える
8. SP Flash Toolでダウンロードボタンを押してから、電源を切った状態の端末をUSB接続する

*ポイント*

 - Bootloader Unlockする必要なし
    - そもそもMediaTek端末はBootloaderがUnlockできないものは少ないかも


## 4.EDLモードで Magiskインストール済みのboot ROMを焼く(Snapdragon端末)
(原理的にはできるはずだが、よくわかってない)

*SnapdragonのEDLモードでFlashするツールが`Mi Flash Tool`しか見つからなかったが、`SP Flash Tool`でいうところのScatterファイルがどうなっているのかよくわからない*
sshでCentOSにログインし、firefoxを起動すると"Channel error: cannot send/recv"のエラー

sshで接続した先のサーバでfirefoxを使いたかったが、アドレスバーにアドレスを入力して開こうとすると、
コンソールに「接続が相手からリセットされました」のメッセージが表示されて開けない。
このサーバに繋いだNASの管理画面を参照したかったので、取り急ぎの対応を行った。



```
$ ssh -X -p 2222 hogehoge.jp
$ firefox
```

```
[Parent 6744] WARNING: pipe error (68): 接続が相手からリセットされました: file /builddir/build/BUILD/firefox-52.5.1/firefox-52.5.1esr/ipc/chromium/src/chrome/common/ipc_channel_posix.cc, line 322

###!!! [Parent][MessageChannel] Error: (msgtype=0x2C0002,name=PBrowser::Msg_PRenderFrameConstructor) Channel error: cannot send/recv
```


- Firefoxのアドレスバーにabout:support入力し、現在のMultiProcessの設定を確認する
- 「マルチプロセスウィンドウ（1/2既定で有効）」と表示された
- Firefoxでアドレスバーにabout:config入力すると、以下のような警告が出たが、
「危険性を承知の上で使用する」をクリック。
- 検索窓に「browser.tabs.remote.autostart」と入力すると、<br>
「browser.tabs.remote.autostart」<br>
「browser.tabs.remote.autostart.2」<br>
のみ表示される。
- browser.tabs.remote.autostart.2」の値がTrueだったので右クリックで「切り替え」をクリックするとfalseとなる

参考：https://support.mozilla.org/ja/questions/1167673


マルチプロセス化のメリットとして以下が挙げられていた。
- レンダリングスピードの高速化
- クラッシュの減少
- メモリ消費が少なく
ROCm 3.x から RCCL が普通に動き始め, 複数 GPU 間通信ができるようになってきました

ROCm 2.5 から, GPU 間の corrective 通信 RCCL(NCCL の ROCm バージョン)が動き始めました.

ROCm 3.x あたりから, API は NCCL そのままになりました(ややこしいが, NVIDIA の NCCL そのままのインターフェイスで, 実装だけ ROCm? で置き換えたもの)

https://github.com/ROCmSoftwarePlatform/rccl

RCCL により, GPU 間でのデータ転送や集約が高速に行える... はず.
たとえば StyleGAN https://github.com/NVlabs/stylegan では複数 GPU での training に NCCL を利用していますが, RCCL により StyleGAN の AMD GPU での複数 GPU 学習が可能になる気配があります.

4 x VEGAs で動作確認しました.

https://github.com/ROCmSoftwarePlatform/rccl/issues/59

## 利用方法

ROCm 2.10 あたりから, rccl も apt パッケージで提供されるようになりました.

自前でビルドしたい場合, ROCm のバージョンに合わせた brach を引き(`master-rocm-2.5` など), README にしたがってビルドします.

test を走らせたい場合, ベンチマークにも使える `rccl-tests` があります. 

https://github.com/ROCmSoftwarePlatform/rccl-tests

こちらは OpenMP を使っていませんので問題なくビルドできます.
 
x299 + 4 x VEGAs で all_gather をためしたところ, 1.97 GB/s くらいでした.

```
$ LD_LIBRARY_PATH=/opt/rocm/rccl/lib ./all_gather_perf -g 4
# nThread 1 nGpus 4 minBytes 33554432 maxBytes 33554432 step: 1048576(bytes) warmup iters: 5 iters: 20 validation: 1 
#
# Using devices
#   Rank  0 Pid  23147 on        wwk device  0 [0x0c] Vega 10 XT [Radeon RX Vega 64]
#   Rank  1 Pid  23147 on        wwk device  1 [0x19] Vega 10 XT [Radeon RX Vega 64]
#   Rank  2 Pid  23147 on        wwk device  2 [0x67] Vega 10 XT [Radeon RX Vega 64]
#   Rank  3 Pid  23147 on        wwk device  3 [0x6a] Vega 10 XT [Radeon RX Vega 64]
#
#                                             out-of-place                       in-place          
#       size         count    type     time   algbw   busbw  error     time   algbw   busbw  error
#        (B)    (elements)             (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)       
    33554432       2097152   float    13115    1.92    1.92  0e+00    12802    1.97    1.97  0e+00
# Out of bounds values : 0 OK
# Avg bus bandwidth    : 1.94233 
```

少なくとも PCIe Gen3 x4 では接続されているはずなので 3.94 GB/s くらいは理論上出るはずですが(https://en.wikipedia.org/wiki/PCI_Express), 半分の性能になっています. はて?

https://github.com/ROCmSoftwarePlatform/rccl/issues/80

## 問題点

rccl の repo に昔あったサンプルコード

https://github.com/ROCmSoftwarePlatform/rccl/tree/master-rocm-2.4/samples

を最新 RCCL でビルドして動かすと

https://github.com/ROCmSoftwarePlatform/rccl/blob/master-rocm-2.4/samples/allreduce.cpp#L110

あたりでとまります. API 呼び出しかなにか変わったのかもしれません.
rccl 最新の unit test コードあたりなどを参考にして, RCCL 利用プログラムを作成するのがよさそうです.

## Debug

`NCCL_DEBUG=INFO` と環境変数を指定します.
Bitbucket（オンプレ）のREADME.mdに画像を付ける


GitHubやクラウドサービスのBitbucketならIssue機能があるのですが弊社の環境では無かったので備忘録。
# 画像のアップ
1. JIRAにREADME.mdを作る課題を作成する（もうこの時点で分かったと思いますが:relaxed:）
2. システムキャプチャ画像をチケットに添付する
3. 添付した画像のURLを取得し、下記のようにマークダウンを記述する。

#### マークダウン
```
![代替テキスト](画像URL, "画像タイトル")
```
Squirrel.Windowsについてのメモ

#はじめに

Windowsデスクトップアプリを配布する技術として比較的最近登場したSquirrel.Windowsを
https://github.com/Squirrel/Squirrel.Windows
を参考に簡単にまとめた。


#Squirrel.Windowsとは
- Windowsアプリをアップデート・配布するためのフレームワーク
- Nugetパッケージを使ってインストールとアップデートパッケージを作成
 - Nuget ・・・Microsoftがサポートする.NETのコード共有メカニズム

- .Netで作られていないアプリケーションでも使用可能
- ClickOnceから移行可能
 
##ClickOnceとの比較

Windowsアプリの配布方法として一般的なClickOnceとSquirrel.Windowsを比較すると次のようになる

|        |    ClickOnce |    Squirrel.Windows    |
|:-----------------:|:------------------:|:------------------:|
| 新しさ             |         古い      |        新しい        |
|     ライセンス       |            MS製 |       OSS       |
| アップデート時の問い合わせ             |              あり |        なし        
| 実装作業量             |             比較的軽い |       比較的重い       |
| バグの修正          |           今後行われないかも |      随時修正(するはず)       |

メモ

1. Squirrel.WindowsはNugetでパッケージングする部分が若干手間がかかるためClickOnceと比べると手間がかかるそう。
2. Squirrel.Windowsもアップデート時の問い合わせを発生させることは可能



#Squirrel.Windowsの機能について
Squirrel.WindowsはGoogle Chromeのように簡単で早く、自動でインストールとアップデートを実現するために以下の機能を提供することを目指している。

 - 設定
  - 既存の.NETアプリケーション用のインストーラを容易に統合する
  - クライアントAPIは更新をチェックし、（できればHTMLで）更新履歴を受け取ることができる。
  - 開発者は、インストールとアップデート中にイベントとカスタムアクションの制御が可能
  - アンインストール時にアプリケーションのクリーンを行うことが可能

 - パッケージング
   - 既存の.NETアプリケーションを指定してインストーラを生成するのが、非常に簡単
   - アプリケーションのアップデートの作成が、簡単に自動化できる
   - デルタファイルをサポートしているので、更新パッケージのサイズが削減可能
 - アプリケーションの配布中の動作
  - アップデートサーバのホスティングが単純なHTTPを通して行われる
 - インストール
  - UACダイアログがない
  - ローカルのユーザーアカウントにインストール
  - 再起動を行わない 
 - アップデート中の動作
  - アプリケーションの実行中にアップデートが適用可能
  - 再起動しない 
  - 現在作動中の動作を中断しない

# 最後に
ひとまず現状の更新はここまで。
作業ステップについては随時更新予定。
virtualbox(centos)でnginx+phpの環境を作る

#内容
タイトル通り。今更apacheとかだせーよって人のために。
#下ごしらえ
公式手順書
http://nginx.org/en/linux_packages.html#stable

epalも使うかもしれないからいれておく
```sudo yum install epel-release```

nginxは標準のリポジトリに追加されているのでリポジトリをアップデートする。
```sudo yum update```

#nginx php php-fpmのインストール
```yum install nginx```
```yum install php5```
```yum install php5-fpm```

#nginx
nginxを起動
```sudo systemctl start nginx```

ステータスを確認
```sudo systemctl status nginx```

エラーログの在り処
```/var/log/nginx/error.log```
#通信の設定
php-fpm側

```/etc/php5/fpm/pool.d/www.conf
+ listen = 127.0.0.1:9000
```

nginx側

```/etc/nginx/nginx.conf
fastcgi_pass 127.0.0.1:9000;
```

php-fpmを再起動させる
```sudo service php-fpm restart```

nginxも
```sudo nginx -s reload```

#参考にさせていただいたサイト

https://qiita.com/jshimazu/items/01f6abc2c3f3e1667d45
http://zemuriya.hatenablog.com/entry/2015/08/02/131133
【Java】標準ライブラリでAES暗号で暗号化する方法

# やりたいこと
- Javaの標準ライブラリを使ってtokenを暗号化して保存したい
- token情報を取得する際は復号化した状態で使いたい
- 暗号化と復号化するときの鍵が同じAES暗号を使いたい

# 暗号化/復号化処理のサンプル
- 暗号化＆復号化で使用する鍵は128bit(=16byte/英数字16文字)
- 暗号利用モードがCBCの場合は鍵と同じ長さの初期ベクトルが必要

## 実装例
```java:CryptSample.java
package com.tamorieeeen.sample

import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * 暗号化/復号化処理サンプル
 * @author tamorieeeen
 */
public class CryptSample {

  // アルゴリズム/ブロックモード/パディング方式
  private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  // 暗号化＆復号化で使用する鍵
  private static final String ENCRYPT_KEY = "yourEncryptKey01";
  // 初期ベクトル
  private static final String INIT_VECTOR = "yourInitVector01";

  private final IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes());
  private final SecretKeySpec key = new SecretKeySpec(ENCRYPT_KEY.getBytes(), "AES");

  /**
   * tokenを保存
   */
  public void saveToken(String token) {

    String encryptedToken = this.encryptToken(token);
    // encryptedTokenをDBに保存
    this.saveTokenToDb(encryptedToken);
  }

  /**
   * 暗号化処理
   */
  private String encryptToken(String token) throws Exception {

    Cipher encrypter = Cipher.getInstance(ALGORITHM);
    encrypter.init(Cipher.ENCRYPT_MODE, this.key, this.iv);
    byte[] byteToken = encrypter.doFinal(token.getBytes());

    return new String(Base64.getEncoder().encode(byteToken));
  }

  /**
   * tokenを取得
   */
  public String getToken() {

    // DBからtokenを取得
    String encryptedToken = this.getEncryptedTokenFromDb();

    return this.decryptToken(encryptedToken);
  }

  /**
   * 復号化処理
   */
  private String decryptToken(String encryptedToken) throws Exception {

    Cipher decrypter = Cipher.getInstance(ALGORITHM);
    decrypter.init(Cipher.DECRYPT_MODE, this.key, this.iv);
    byte[] byteToken = Base64.getDecoder().decode(encryptedToken);

    return new String(decrypter.doFinal(byteToken));
  }

  /** ここから下は各自必要なメソッドを作成してください **/

  /**
   * tokenをDBに保存
   */
  private void saveTokenToDb(String encryptedToken) throws Exception {

    // encryptedTokenをDBに保存する処理
  }

  /**
   * DBからtokenを取得
   */
  private String getEncryptedTokenFromDb() throws Exception {

    // DBからtokenを取得する処理
  }
}
```

# 参考
[【Java】標準ライブラリで暗号技術を使う](https://qiita.com/Qui/items/6aa46d428e5bfe9b8d37)
[暗号処理をやってみよう！](https://qiita.com/tkxlab/items/8c802b018afa138640f1)