OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby 2.7 で in 演算子が使えるようになる

[ブログ記事](http://secret-garden.hatenablog.com/entry/2019/09/26/192045)からの転載になります。

Ruby 2.7 で `in` 演算子が使えるようになります。
そもそも `in` 演算子ってなんやねんって話なんですが、同じく Ruby 2.7 で入る予定のパターンマッチ構文の `in` になります。
例えばパターンマッチを使用することで次のような判定を行うことが出来ます。

```ruby
def check user
  # name に m が含まれていて age が 14以下
  case user
  in { name: /m/, age: (..14) }
    "OK"
  else
    "NG"
  end
end

p check(id: 1, name: "Homu", age: 13)
# => OK
p check(id: 2, name: "mami", age: 15)
# => NG
```

このようにパターンマッチを使用する事でより細かく条件を指定する事が出来ます。


## `in` 演算子を使う

上記の例だと `case <expr>; in <pattern>; ... end` みたいな構文を書く必要があるのでやや冗長に見えますね。
そこで `in` 演算子です。
`in` 演算子を使うことでパターンマッチ式を1行で書くことが出来ます。

```ruby
def check user
  # name に m が含まれていて age が 14以下
  # in 演算子は true / false を返す
  (user in { name: /m/, age: (..14) }) ? "OK" : "NG"
end

p check(id: 1, name: "Homu", age: 13)
# => OK
p check(id: 2, name: "mami", age: 15)
# => NG
```

`in` 演算子はパターンマッチと同様に `<expr> in <pattern>` と書くことが出来ます。
また戻り値は `true / false` になります。
これは次のような `select` などと組み合わせるとより強力になります。

```ruby
users = [
    { id: 1, name: "Homu", age: 13 },
    { id: 2, name: "mami", age: 14 },
    { id: 3, name: "Mado", age: 21 },
    { id: 4, name: "saya", age: 14 },
]

# @1 から _1 に変わったナンパラを使うとより簡潔にかける
p users.select { _1 in { name: /m/, age: (..14) } }
# => [{:id=>1, :name=>"Homu", :age=>13}, {:id=>2, :name=>"mami", :age=>14}]
```

これめっちゃ便利そうですね！！！  
ちなみに `in` 演算子なのか `in` 式なのかどっちが正しいんですかね？  
[matz が `in` operaetor と書いていた](https://bugs.ruby-lang.org/issues/15865#note-14)ので `in` 演算子と明記しましたが `in` 式のほうが正しいのかな。
python リストの中の数字を文字列に変換する方法

こんな感じで、リストの中にINTEGERの要素があり、文字列に変換したい時がある。

```sample.py
user_list = [1, 2, 3]
```

その場合はmapメソッドを使うと簡単に変換できる

```sample.py
user_list_str = list(map(str,user_list))
```

出力結果

```sample.py
user_list = [1, 2, 3]
user_list_str = list(map(str,user_list))
print(user_list_str)

# 出力結果
['1', '2', '3']
```

反対に文字列から数値にしたい場合はstrの部分をintにすればok
Re:dashで取得したデータをSlackに投稿する（とRe:dash内pythonを書くときの注意点）

## やりたい
- Re:dashで取得したデータを、pythonデータソースを使って、Slackに投稿したい
- Re:dashのalert機能は便利だが、条件が解消しないとずっと出続けてしまう問題があった

## 準備
- Slack AdminでIncoming Webhooksを設定し、`Webhook URL`を取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861/c895256d-5f39-36af-d769-56c6e911a703.png)
- Re:dashには、既にpythonデータソースが用意されている前提。ググればいっぱい出てくる

### Slack投稿用のサンプル
```
import requests
import json

SLACK_URL = "[WEBHOOK_URL]"
content = "`Daijin` は `Hentai`"
payload = {
    "text": content
}
data = json.dumps(payload)
response = requests.post(SLACK_URL, data)
```

## 実際にやったこと
- Re:dashで取得したある条件に合ったデータをSlackに投稿する
    - Re:dash上で定期実行するが、その時間を秒単位では指定できず、ほっとくと重複したデータを投稿してしまう。そこをSlack APIを使って既に投稿したデータは投稿しない処理を加えた。
    - 結果75行の割と大きめのソースとなった

## その際ハマった注意点
- python側で使うライブラリは、`Data Source`の画面で追加できる。但し、標準ライブラリのみで、`pip install`が必要なものはGUIだけではできなそうだった  
<img width="279" alt="スクリーンショット 2019-09-27 18.51.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861/ae089264-8efd-01cd-3927-dd3be2887b2f.png">  
ここでsaveするだけでimportできるようにはなった
- なぜか関数を作れない。関数を作って実行すると関数内からglobal変数にアクセスできない
- 引数付きのクエリは実行できなそうである
- get_query_resultではクエリは実行されない
- redashの定期実行は割とブレる。1minute毎のやつでも30秒くらいずれる。弊社の環境だと、なぜか90秒サイクルで実行されてた。1秒以内で実行されるクエリなんだが

```
13:32:20
13:33:50
13:35:20
13:36:50
13:38:20
```

## 参考
&raquo; [Re:Dashでpythonデータソースを使ってクエリ結果をごにょごにょしたい](
https://qiita.com/axm-aoki/items/4982cf8999aebc46b3d4)
Movable Type 6.5 for AWS を利用する前にやっておくべきこと

Movable Type 6.5 for AWS が先日リリースされています。この AMI イメージは、Movable Type 6 for AWS と違い、Amazon Linux 2 がベースになっているので細かいところが変わってます。とはいえ、やることはそうそう変わらないけど。

*Movable Type for AWS を利用するまでは、[これ](http://www.sixapart.jp/movabletype/aws/how-to-use.html)を見ればいいと思う。*
*Movable Type 6 for AWS を利用するときにやっておくことは、[これ](https://qiita.com/swordbreaker/items/fb97696c9fac5c7b27f1)を見ればいいと思う。*
*Movable Type 7 for AWS は、ここに書いてあることと同じでいいと思う*


# 作業用ユーザーの登録

ec2-user として SSH でログイン後に root ユーザーになります。

```console
$ sudo su -
````

新しいユーザーを登録して、sudo が使えるように wheel グループに加入させます。

```console
# useradd NEW-USER-NAME
# usermod -G wheel NEW-USER-NAME
```

パスワードなしで sudo できるようにもできますが、個人的には毎度入れるほうが好きなのでパスワードを設定します。

```console
# passwd NEW-USER-NAME
```

セキュリティを考えると新しい公開鍵を用意したほうが良いですけど、ここでは既存の公開鍵を登録します。

```console
# sudo su - NEW-USER-NAME
$ mkdir .ssh
$ chmod 700 .ssh/
$ vi .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
```

ログアウトして、作成したユーザーで SSH でログインし直します。

# モジュール類のアップデート
AWS Marketplace から起動した直後でもモジュールのアップデートが存在するので、更新します。定期的に実行するようにしても良いですが、動かなくなるとか怖いので都度実行してます。

```console
$ sudo yum update -y
```

# タイムゾーンの設定
AWS Marketplace から起動した直後は、UTC なタイムゾーンになっているため、JST に合わせます。

```console
sudo timedatectl set-timezone Asia/Tokyo
```

# 日本語ロケールの追加
ついでにローケールも日本語対応にして、キーボードも対応させます。

```console
$ sudo localectl set-locale LANG=ja_JP.UTF-8
$ sudo localectl set-keymap jp106
```

# mt-config.cgi の編集
mt-config.cgi は、インスタンス起動直後にすでに作成されていますが、こちらも US モード全開なので、日本向けに変更します。

任意のエディタでファイルを開いて書き換えます。

```console
$ sudo vi /app/movabletype/mt-config.cgi
```

以下の内容を追記（場所はどこでも。まあ、一番最後にでも）

```mt-config.cgi
DefaultLanguage ja
```

保存後に movabletype サービスを再起動します。

```console
sudo systemctl restart movabletype
```

# Movable Type のセットアップ
http:// *your-host* /mt/admin にアクセスすると見慣れた画面から Movable Type のセットアップが開始します。

# それ以外にやっておくと良いこと
セキュリティを高めるためには、他にも色々やっておいたほうがいいことあるよね。

* ssh のポート番号を変える
* 無用なサービスを停止する（ダイナミック／パブリッシング使わないなら php 止めるとか）
* ssh できるソース IP を限定する

とか。
とりあえず、こんなところで。
PermissionsDispatcherでRuntime Permissionをちょっとだけ楽にする


# 背景
プロジェクトにPermissionsDispatcherが導入されていたので色々触ってみる

# PermissionsDispatcherとは
Android 6.0(M) 以降から導入されたruntime permissionの実装を楽にしてくれるライブラリ。
https://github.com/permissions-dispatcher/PermissionsDispatcher

runtime permissionについて
https://developer.android.com/training/permissions/requesting

# 導入方法
build.gradleに以下を記載。

```groovy

apply plugin: 'kotlin-kapt'

dependencies {
  implementation "org.permissionsdispatcher:permissionsdispatcher:${latest.version}"
  kapt "org.permissionsdispatcher:permissionsdispatcher-processor:${latest.version}"
}
```
自動生成なのでkotlin-kaptプラグインを忘れないように。

# 使い方

順番に使い方を記載してく。

## 1. Activity / FragmentにRuntimePermissionsアノテーションをつける
以下のような形。

```MainActivity.kt

@RuntimePermissions
class MainActivity : AppCompatActivity() {
```

```MainFragment.kt
@RuntimePermissions
class MainFragment : DaggerFragment() {
```

## ２. 欲しいパーミッションの取得に成功している or 失敗した後に実行される関数を実装

```MainActivity.kt
    fun readDeviceData() {
       getIMEI()
    }
```

## ３. 2.で作成した関数にNeedPermissionアノテーションをつける

NeedPermissionの中には欲しい権限情報を記載する

```MainActivity.kt
    @NeedsPermission(Manifest.permission.READ_PHONE_STATE)
    fun readDeviceData() {
       getIMEI()
    }
```

## ４. ビルドする
自動的にコードが生成される

## 5. 関数名 + WithPermissionCheck()という名で拡張関数ができているので呼ぶ。

```MainActivity.kt
   override fun onCreate(savedInstanceState: Bundle?) {
       readDeviceDataWithPermissionCheck()
   }
```

## ６. onRequestPermissionsResultをoverrideし、生成された拡張関数onRequestPermissionsResultを呼ぶ

```MainActivity.kt
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        onRequestPermissionsResult(requestCode, grantResults)
    }
```

以上。

# 自動生成されたコード

こんな感じ。ほぼほぼルーチン作業だったパーミッションコードが自動生成されている。
すでにパーミッションが設定されている場合でも呼び出してくれる形なので便利。

```MainActivityPermissionsDispatcher.kt

private const val REQUEST_READDEVICEDATA: Int = 2

private val PERMISSION_READDEVICEDATA: Array<String> =
    arrayOf("android.permission.READ_PHONE_STATE")

fun MainActivity.readDeviceDataWithPermissionCheck() {
  if (PermissionUtils.hasSelfPermissions(this, *PERMISSION_READDEVICEDATA)) {
    readDeviceData()
  } else {
    ActivityCompat.requestPermissions(this, PERMISSION_READDEVICEDATA,
        REQUEST_READDEVICEDATA)
  }
}

fun MainActivity.onRequestPermissionsResult(requestCode: Int, grantResults: IntArray) {
  when (requestCode) {
    REQUEST_STARTLOCATIONSAMPLING ->
     {
      if (PermissionUtils.verifyPermissions(*grantResults)) {
        readDeviceData()
      }
    }
  }
}
```

# 二つ同時にパーミッションを取得したい場合

連続してパーミッションを取得したい場合は@NeedPermissionに二つ設定する。

```kotlin
@NeedsPermission(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE)
```

# まとめ
他にもユーザーがアクセス許可を付与しない場合に呼び出されるメソッドやなぜ許可が必要なのかを表示するためのメソッドなども指定できるので、ちょっとだけ楽になる。
kotlin List Set Mapの特徴

# List Setの違い
## List
- 重複要素を許可
- 要素の順番を保持

```kotlin
fun main() {
    val intList = listOf(1,1,2) // 重複要素も許可
    println(intList) //[1, 1, 2]
}
```

## Set
- 重複要素を持てない
- 要素の順番を保証しない

```kotlin
fun main() {
    val intList = setOf(1,1,2) //重複は自動で削除
    println(intList) //[1, 2]
}
```
重複は自動で削除される

# ミュータブルとイミュータブル
List, Set, Mapはイミュータブル(読み取り専用)になります。
ミュータブルな型を使用する場合は、MutableList,MutableSet,MutableMapを使用します。

## 使用方法

```kotlin
val intList = listOf(1, 2, 3)
val intSet = setOf(1, 2, 3)
val intMap = mapOf(1 to 10, 2 to 20, 3 to 30)

val intMutableList = mutableListOf(1, 2, 3)
val intMutableSet = mutableSetOf(1, 2, 3)
val intMutableMap = mutableMapOf(1 to 10, 2 to 20, 3 to 30)
//Mutableな型は要素の追加が可能
intMutableList.add(4) //[1, 2, 3, 4]
intMutableSet.add(4) //[1, 2, 3, 4]
intMutableMap[4] = 40 //{1=10, 2=20, 3=30, 4=40}
```

値を入れずに宣言だけする場合

```kotlin
val intMutableList: MutableList<Int> = mutableListOf()
val intMutableSet: MutableSet<Int> = mutableSetOf()
val intMutableMap: MutableMap<Int, Int> = mutableMapOf()
```
URLSession系の優良記事まとめ

# JSON
**・[非エンジニアに贈る「具体例でさらっと学ぶJSON」 ｜ DevelopersIO](https://dev.classmethod.jp/etc/concrete-example-of-json/#return-note-0-2)**
→`オブジェクト`, `配列`, `キー`, `値`らへんがごっちゃな方はこの記事から
**・[[Swift3] JSON文字列の作成 ｜ DevelopersIO](https://dev.classmethod.jp/smartphone/swift3-json/)**
**・[Swift3でJSONパースを行う - Qiita](https://qiita.com/suzuki_y/items/1b64a116ee3c6c9c2805)**

# URLSession
**・[Swiftで遊ぼう！ - 482 - URLSessionの基礎 - Swiftで遊ぼう! on Hatena](http://yataiblue.hatenablog.com/entry/2015/11/07/000000)**
→サンプルなどを用いた説明
**・[【Swift】URLSessionまとめ - Qiita](https://qiita.com/shiz/items/09523baf7d1cd37f6dee)**
→関数などのまとめ
【Laravel】LengthAwarePaginatorで1つのページに複数ページネーションを実装 -Laravel5


LengthAwarePaginatorを使って1つのページに複数ページネーションを実装。

> 参考
> Laravel5で1ページに複数のPaginationを実装する
> https://qiita.com/sano1202/items/371a59ea46cb66993b8b


基本的にはこちらを参考にさせていただきました！

が、LengthAwarePaginatorを使用して複数ページネーションを実装しようとした際に詰まったので備忘録。

## Paginationのパラメータ名を変更する

パラメータ名が変更できずに随分困りましたが第５引数に 
> ['pageName' => 'hogehoge']

を入れるだけでした。。


```php

$users = new LengthAwarePaginator($users , $count, $per_page, $page, ['pageName' => 'hogehoge']);

$users->setPath(url('/users'));
```


これで、`/users?hogehoge=2`
のようになります。



初心者なので、、こんなのもわからないの？！と言わずお手柔らかにmm
備忘です。
Unityでチーム開発 流れやルールなど

#はじめに

株式会社テクロスでエンジニアとしてアルバイトしてる大学生です。

アルバイトでUnityでのチーム開発を何度か行ったのですが、知見を文書化してなかったのでまとめてみようと思います。
似たような記事もあったけど全体的にまとまってはなかったりしたので、全体感持ちやすいように今回簡単にまとめてみました。

今回はUnityとGitHubを使ってチーム開発を行います。(この記事は初心者の方向けです)

#チーム開発の流れ
簡単にざっくり言うと
Unityでプロジェクト作成→GitHubにレポジトリを作る→皆でcloneして開発
って流れになると思います。(当たり前か)

以下で各フェーズでの具体的な手法とルールについて確認していきます。

#Unityでプロジェクト作成してGithubにレポジトリを作る

これは[こちらのサイト](https://blog.naichilab.com/entry/unity-github#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%AB%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8B)がまとまってて非常に良い。
この記事の流れ通りに設定すればオーケーだと思う。
Unityプロジェクトだと.gitignoreも自動で作ってくれるので便利ですね、UnityとGitHub親和性高い。


レポジトリができたらREADMEにチーム開発のルール等まとめておくといいかと思います。具体的には、

 - Unityのバージョン
 - 最初の環境構築の流れを簡単にまとめる
 - コードの書き方でルール等あればまとめる

ぐらいですかね

>1. このリポジトリを各々forkする
2. forkしたリポジトリをcloneする
(clone したいディレクトリまでローカルで移動して"git clone http~")
3. ローカルで作業用branchを作成
(git checkout -b (適当なブランチ名))
4. 編集したらcommitしておく
(git add ファイル名)
(git commit -m "コメント")
5. GitHubにpushする
(git push (先) (元))
6. pushしたらプルリク送る
https://qiita.com/syougun360/items/013229aeddec08121474

これはUnityじゃない別のプロジェクトですけどこんな感じで書いてます。(Git初心者が多かったのでだいぶ分かりやすく書いてるけど)

コーディング規約は基本的にリーダブルコード様に従ってます。https://qiita.com/Kenya/items/faec4cc374edd5ffbba6
細かいですけど関数はスネークケース、グローバル変数はキャメルケースにするとかいうルールも決めてました。
コーディングルールはその程度決めておけばいいと思います。基本的にはリーダブルコードに則って、キャメルケース等の使い方を統一する程度で。

#いざ開発
ここまできたらあとは開発するだけなんですが、複数人で同じプロジェクトをいじる時は絶対に図を作る必要があります。
完成のイメージ図、画面遷移図、シーケンス図、クラス図等必要です。皆の頭の中のイメージを統一させるためと、誰がどの作業をしているのか見やすいようにです。

どの図がどんなものかは[こちらのページ](http://objectclub.jp/technicaldoc/uml/umlintro2)によくまとまってるのでご覧ください。

そもそもクラスが何かとかよく分かってない人は[ドラゴンボールで学ぶオブジェクト指向 改](https://ryoasai.hatenadiary.org/entry/20110317/1300380540)が分かりやすいです。

この図を作るのは難しいので何回も作って慣れるしかないと思います。図の作り方まとめてくれてるサイトいっぱいあるので、頑張りましょう！！

図も完成したらいよいよコードを書いて開発していくだけです！！
誰がコードレビューするのか等もルール決めしておくといいかもしれないですね。

#おわりに

エンジニア初心者なので上手くまとめられてるか、間違ってないか不安です。間違ってたら教えてください。
また何か思い出したら追記します。
Go の -race option は内部で何をしているのか。何を検知しないのか。

```-race``` をつけてCIを通しているのにAPIがデータ競合で落ちてしまいました。調べていたら```-race```がそもそも何をしているかに行き着いたので簡単に共有します。

## -race とは

```-race```はコンパイラフラッグの一種で競合を検知するのに便利です。例えば下記のコードはmapへの読み書きが同時に起こってパニックするコードです。これを```go run main.go -race```のように実行するとwarningを出してくれます。

```go
package main

import (
	"fmt"
	"strconv"
	"time"
)

func main() {

	m := make(map[string]int)

	go func() {
		for i := 0; i < 1000; i++ {
			m[strconv.Itoa(i)] = i // write
		}
	}()

	go func() {
		for i := 0; i < 1000; i++ {
			fmt.Println(i, m[strconv.Itoa(i)]) // read
		}
	}()

	time.Sleep(time.Second * 5)

}
```

下記のように実行するとWarningを出します。

```
$ go run -race main.go
```

## -race はそもそも何をしているのか

内部では```C/C++```用の競合検出ライブラリが使われています。簡単に言うと、競合を実行時に検出するコードを出力することができるライブラリです。
https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual

もちろん```Go```のコンパイラはこれをサポートしており、実際に```runtime/race```の```README.md```には```ThreadSanitizer```が使われていることが明記されています。

https://github.com/golang/go/tree/master/src/runtime/race

> untime/race package contains the data race detector runtime library. It is based on ThreadSanitizer race detector, that is currently a part of the LLVM project (http://llvm.org/git/compiler-rt.git).

コンパイル時に実際にどのようなコードが仕込まれているかを見てみましょう。例えば下記のコードをビルドした場合をみてみます。

```go
package main

func Inc(x *int) {
    *x++
}
```

普通にビルドすると下記のようにコンパイルされます。

```
...

pcdata  $2, $1
pcdata  $0, $1
movq    "".x+8(SP), AX
pcdata  $2, $0
incq    (AX)

...
```

```-race``` をつけると下記のようにコンパイルされます。

```
...

pcdata  $2, $1
movq    "".x+32(SP), AX
testb   AL, (AX)
pcdata  $2, $0
movq    AX, (SP)
call    runtime.raceread(SB)
pcdata  $2, $1
movq    "".x+32(SP), AX
movq    (AX), CX
movq    CX, ""..autotmp_4+8(SP)
pcdata  $2, $0
movq    AX, (SP)
call    runtime.racewrite(SB)
movq    ""..autotmp_4+8(SP), AX
incq    AX
pcdata  $2, $2
pcdata  $0, $1
movq    "".x+32(SP), CX

...
```

コンパイラーが```call runtime.raceread(SB)```のように同時に到達可能な各メモリー位置に読み取りおよび書き込みを検知する命令を追加しています。ご覧の通り、```-race```をつけると命令が増えてパフォーマンスが落ちるのでビルドしたバイナリを本番に乗っけるのはやめましょう。[go build -race でプログラムが遅くなってた話](https://qiita.com/smith-30/items/be4d92c251d2b2b39bd3)

ちなみにGoコンパイラが吐き出すアセンブリは```Compiler Explorer```というサービスで簡単に確認できて便利です。

[Compiler Explorer](https://go.godbolt.org/z/IWw4hk)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186028/e2f279ed-b7db-28c3-acbb-210d6472c05e.png" wifth="70%">


## -raceを使ってるのに競合が起きる理由

-raceでは競合を検知するための命令を追加しているので、そこに到達しないと競合を検知しません。つまりテスト時に-raceをつけてPASSしたからと言って競合が発生しないとは言えません。

Goのドキュメントにも明示されていました。
https://golang.org/doc/articles/race_detector.html#How_To_Use

> To start, run your tests using the race detector (go test -race). The race detector only finds races that happen at runtime, so it can't find races in code paths that are not executed. If your tests have incomplete coverage, you may find more races by running a binary built with -race under a realistic workload.

テストカバレッジが低い場合はテストだけで全ての競合が消せたと判断せずに、実際に```-race``` をつけてビルドしてみて動かしてみることが大切です。

## Referece

Golang race detection
https://krakensystems.co/blog/2019/golang-race-detection
ONNXで eliminate_unused_initializer 最適化

ONNXがサポートしている最適化 eliminate_unused_initializer  を調べてみました。

最適化をしているソースはこれ。

https://github.com/onnx/onnx/blob/master/onnx/optimizer/passes/eliminate_unused_initializer.h

ソースよりもコメントがわかりやすい。

```python
// Before:
//   A, B, C are in the initializer list
//   D = Add(B, C)
// After:
//   B, C are in the initializer list and A is removed
//   D = Add(B, C)
//
```

グラフのどこにも使っていない initializer があれば削除されます。

ダミーの initializer を定義してグラフに加えます。

```python
dummy_init = numpy_helper.from_array(numpy.zeros((190, 100), dtype=numpy.int64))
dummy_init.name = 'dummy_init'
```

最適化前のグラフ。
![eliminate_unused_initializer.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/c57b1888-1b4e-b005-dbc4-66fdefc77f66.png)


passにeliminate_unused_initializerを指定して最適化。

```python
passes = ['eliminate_unused_initializer']

optimized_model = optimizer.optimize(model_def, passes)
```

最適化後のグラフ。
![eliminate_unused_initializer_optimized.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/00a77ff3-e903-e770-9fc6-416460e33983.png)

グラフを修正するのではないので、グラフの表示は同じです。モデルのファイルサイズが148 KBから148 バイトへ1/1000になりました。

全ソース。

```python
import numpy
import onnx
from onnx import helper, numpy_helper
from onnx import TensorProto
from onnx import optimizer

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 4])

dummy_init = numpy_helper.from_array(numpy.zeros((190, 100), dtype=numpy.int64))
dummy_init.name = 'dummy_init'

pad = helper.make_node(
    'Pad',
    ['X'],
    ['Y'],
    mode = 'constant',
    value = 1.5,
    pads = [0, 1, 0, 1]
)

graph_def = helper.make_graph(
    [pad],
    'test-model',
    [X],
    [Y],
    initializer = [dummy_init]
)

model_def = helper.make_model(
    graph_def,
    producer_name='onnx_example'
)

onnx.save(model_def, 'onnx/eliminate_unused_initializer.onnx')

# 最適化パスを指定
passes = ['eliminate_unused_initializer']

optimized_model = optimizer.optimize(model_def, passes)
onnx.save(optimized_model, 'onnx/eliminate_unused_initializer_optimized.onnx')
```
BigQueryのコスト最適化のベストプラクティス(要約)

**[Cost optimization best practices for BigQuery](https://cloud.google.com/blog/products/data-analytics/cost-optimization-best-practices-for-bigquery?fbclid=IwAR3YQiGr0Y2ntYi5gJrBR6jNSDgPq8BeCgpd-otyzfXSg8Zok3ENenNzL30)**

↑の記事が参考になったので簡単に要約しました。
詳細は元記事を読んでください。

# コスト最適化(ストレージ編)

#### 1. 必要なデータだけ残しとく
適切にexpirationを設定する。
datasetのexpirationを変えても既存のテーブルには反映されないから気をつける。

#### 2. データの編集には注意する
90日間テーブルを編集しなければ、自動的に long-term storageに移行されて、storage金額は50%になる。streaming, copy, loadingとかすると、また active storage になって90日間は long-term storage にならないからそのあたりを考えて運用する。

1年に一回以上編集しないならば、BigQeuryのデータをGCSの Coldline class のGCSに移したほうがいい。

#### 3. データの重複コピーは避ける
[federated data access model](https://cloud.google.com/bigquery/external-data-sources) 機能があるから、BigTableとか、GCSとか、CloudSQLのデータをBQにコピーするのは避ける。

#### 4. Streaming Insertを使ってないかチェックする
Streaming Insert 使ってたら、ほんとにこの処理はリアルタイムである必要があるのかを考える。
例えば1時間ごとのloadでもよければbatch loadingに切り替える。

#### 5. バックアップとデータリカバリについて理解しておく
BQは7日間のテーブル変更履歴を持つ。つまり、リカバリーバックアップなしにリバートできる。テーブルが消えても、履歴が消えるのはその2日後。

# コスト最適化(クエリ編)
#### 1. 必要なクエリだけ投げる
カラムナーテーブルだから必要なカラムだけ宣言する。 `*` とか使わない。

#### 2. 事故的なニューマンエラー用の設定しておく
[課金されるバイト数を制限してクエリ費用を抑える](https://cloud.google.com/bigquery/docs/best-practices-costs#limit_query_costs_by_restricting_the_number_of_bytes_billed)

#### 3. キャッシュを賢く使う
デフォルトでキャッシュ設定はONになってて24時間有効

#### 4. テーブルを分割する
[分割テーブルの概要](https://cloud.google.com/bigquery/docs/partitioned-tables)

#### 5. クラスタリングでさらに節約
パーティションあと、最大4カラム指定してクラスタリングできる

[クラスタテーブルの概要](https://cloud.google.com/bigquery/docs/clustered-tables)

# flat-rate vs on-demand

月の請求が$10,000(約100万円)を超えたら、flat-rateに移行することを考えよう。
一定slotを購入し、あとは料金を気にせず好きなだけqueryを実行できる。
Raspberry Pi3 セットアップ& NFSサーバ設定 メモ


# Environment
Raspberry Pi 3
NOOBS_V3_2_0

# Set up
Choose Raspbian Full install


Setting root password

```:bash
sudo passwd root
sudo apt update
sudo apt dist-upgrade
sudo apt dist-upgrade --fix-missing
```

Add user

```:bash
sudo useradd user
sudo passwd user

sudo mkdit /home/user
sudo chown user:user /home/user
```

Change autologin-user

```/etc/lightdm/lightdm.conf
autologin-user=user
```

```:/etc/systemd/system/autologin@.service
#ExecStart=-/sbin/agetty --autologin tmp --noclear %I $TERM
ExecStart=-/sbin/agetty --autologin user --noclear %I $TERM
```



sudo権限付与

```
usermod -aG sudo user
```


NFSサーバインストール

```
sudo apt install nfs-kernel-server
mkdir /home/user/nfs
```

```:/etc/export
/home/user/nfs *(ro,sync,no_subtree_check)
```

IPアドレスの静的設定

```:/etc/dhcpcd.conf
interface eth0
static ip_address=192.168.1.1/24
static routers=192.168.1.1
static domain_name_servers=
```

MACからのマウント確認

```:bash
sudo mount_nfs -o resvport 192.168.1.1:/home/user/nfs ./mnt
```
JMeter5.2でShift-JISの文字化け問題を修正した件


## はじめに
JMeterには長年Shift-JISの文字化けの問題があり、Proxyを使ってHTTP Requestを記録する際に、フォームから入力した値などが文字化けして記録されることがあります。

そのため、これまで独自にソースコードを修正したり、以下のような手段で回避されてきたと思います。

 - [JMeter の Request パラメータの文字化けをソースコードを修正せずに解消する方法](https://qiita.com/t_okumura/items/7e326ebd2331f64dd2bd)
 - [JMeter の Proxy で Shift_JIS が化ける場合は delegate で文字コード変換リバースプロキシを構成する](http://dechnostick.hatenablog.com/entry/2015/01/24/001446)

今回Shift-JISの問題をJMeterコミュニティに報告し、Shift-JISの文字化けの修正パッチがJMeter5.2としてリリースされます。

![release.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495725/23225e26-7f33-a7c1-b7dc-fd783e078390.png)

## Shift-JISの文字化けの問題

次のように、テキストフォームに入力した文字列をサーバ内で処理して返すアプリケーションで、ブラウザでアクセスすると正しく文字列を返すことができるページが、JMeterのプロキシを介すと次のように文字化けすることがあります。

![problem01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495725/ef9e2076-cc0c-c7ec-f444-98b215196226.png)


## 修正内容

今回の修正では、HTTP Request記録時のデフォルトの文字コードを設定画面から指定できるようになりました。

「Recording's default encoding」の欄に、文字コードを設定するとデフォルトのエンコーディングを指定できます。

![GUI_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495725/766dd055-38dd-6f2e-5c5f-381004b25d69.png)

今回、デフォルトエンコーディングに Shift-JIS を指定すると、初回アクセスから文字化けをしなくなることが確認できます。

## JMeterのHTTP Requestの文字コード解釈の仕様

JMeterの HTTP Requestの文字コードの解釈は以下の通りです。

![reason01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495725/0ad7e0da-3deb-5f82-ea20-ae557da065ac.png)


 1. フォーム中の文字列は、ターゲットページの文字コードでエンコードしようとします。
 2. ターゲットページの文字コードの判別は、JMeterのプロキシで一度レスポンスのファイルを読み込む必要があり、最初にアクセスした段階ではターゲットページの文字コードを取得することができません。
 3. このためデフォルトの文字コード(V5.1まではUTF-8に固定）が使われ、Shift-JISの文字列が文字化けします。
 4. JMeter Proxyがレスポンスとしてターゲットページを読み込むことで、page1の文字コードを判別することができます。
    JMeter内部ではMap構造でターゲットページとエンコーディングの組み合わせ情報を保持します。
 5. 2回目以降、同ページにアクセスした場合は、正しく文字コードを取得でき、文字化けが発生しなくなります。

以上の理由から、初回アクセス時には文字コードが正しく設定されていても、文字化けを起こすことがあります。



##  残課題

今回の修正では、デフォルトのエンコーディングを指定することができるようになりましたが、ページごとに文字コードが異なる場合には対応できていません。

HTTP Proxyの仕組みを使う限り、文字コードの解釈には一度ファイルを読み込む必要があり、初回アクセス時に文字コードが判別できない問題は残っています。

あらかじめページごとに文字コードを指定する、または、記録時に動的に文字コードを設定する仕組みが必要かもしれません。
Elasticsearch7系がmaster not discoveredで起動できなかった時の話

7系とかドヤ顔で書いてるけど7系以外で確認してません。ﾌﾌ。

## 前提
Amazon linux 2
Elasticsearch 7.0.0
openjdk 1.8.0

## 何があったの
開発環境で元気に動いてるES設定の99%を本番環境に持ってきて、生まれたてのEC2で起動しようとしたら

```
master not discovered yet, this node has not previously joined a bootstrapped (v7+) cluster, and [cluster.initial_master_nodes] is empty on this node: have discovered [];
```

こんなんが出て起動できず。
なお残りの1%はリージョンとかの設定でございます。

## で？
`cluster.initial_master_nodes` 設定すりゃいいだけじゃねえの？って思ったけど、
開発環境からもってきた設定ファイル `elasticsearch.yml` だと `cluster.initial_master_nodes` の設定はコメントアウトされている。でも開発環境のESはバリバリ動いてるし、restartしてもstop/startしてもなんの問題もなかった。

## 結論
`cluster.initial_master_nodes` を設定して正常起動見届けた後にstopしてコメントアウトして起動すると正常に起動します。
masterの情報をキャッシュしてるのかな？
EC2をstop/startして試しても起動したので、ファイルとかに持ってんだろうか…？


「エラーメッセージちゃんと読め」って話なんですけどね。
ちゃんと動いてる設定ファイル持ってきたのになんでよ！！ってなったので、自分と同じハマり方をする人を減らせればと思い…
BrightFuturesのレスポンス結果を表示するのはonSuccessのスコープ内でやろう


BrightFuturesを使用した非同期処理の場合、
APIから取得した結果を表示するためにUILable等に設定するのは、```onSuccess```のスコープ内でやること。
そうしないと非同期処理のため、値がまだ帰ってきていない内に描画処理が走り、想定通りに反映されない。

普段JavaScriptで書いてるときは自然としてそうだが失念してた。
Async/Awaitほしい、、


```swift

class SomeViewController: AutoLayoutViewController {

  private var someObj:SomeObject = SomeObject()
  private var someLabel: UILabel

   override func viewDidLoad() {

   [BrightFuturesを使った非同期処理]
     .onSuccess { success in
       someObj = success
       
       // ここが正解
       self.someLabel.text = success.text
     }

   // ここでやると反映されない
   // self.someLabel.text = success.text

  }

}

```
ONNXで eliminate_nop_transpose 最適化

ONNXがサポートしている最適化 eliminate_nop_transpose を調べてみました。

最適化をしているソースはここ。
https://github.com/onnx/onnx/blob/master/onnx/optimizer/passes/eliminate_nop_transpose.h

```c++
static bool is_nop_transpose(const std::vector<int64_t>& perm) {
    for (size_t i = 0; i < perm.size(); i++)
      if (perm[i] != (int)i)
        return false;
    return true;
  }

  bool patternMatchPredicate(Node* node) override {
    return (node->kind() == kTranspose && node->hasAttribute(kperm)) &&
        is_nop_transpose(node->is(kperm));
  }
```

transpose の転置を決める行列(perm)が、[0, 1, 2, ・・] となる場合は、何も転置しないのでnopと同じ扱いで削除します。

こういう転置のNodeを定義して、最適化をかけてみます。

```python
transpose = helper.make_node(
    'Transpose',
    ['pad_out'],
    ['Y'],
    perm=[0,1]
)
```

最適化前のグラフがこれ。
![eliminate_nop_transpose.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/da749440-c96d-ce1e-7a75-be7e6a2473f1.png)


passにeliminate_nop_transposeを指定し、optimizer.optimizeを呼び出します。

```
passes = ['eliminate_nop_transpose']

optimized_model = optimizer.optimize(model_def, passes)
```

![eliminate_nop_transpose_optimized.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/16b2bb78-6fea-a1cf-6759-7f29bf4939bb.png)


不要な転置が削除されました。


全ソースはこちら。

```python
import onnx
from onnx import helper
from onnx import TensorProto
from onnx import optimizer

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 4])

pad = helper.make_node(
    'Pad',
    ['X'],
    ['pad_out'],
    mode = 'constant',
    value = 1.5,
    pads = [0, 1, 0, 1]
)

transpose = helper.make_node(
    'Transpose',
    ['pad_out'],
    ['Y'],
    perm=[0,1]
)

graph_def = helper.make_graph(
    [pad, transpose],
    'test-model',
    [X],
    [Y]
)

model_def = helper.make_model(
    graph_def,
    producer_name='onnx_example'
)

onnx.save(model_def, 'onnx/eliminate_nop_transpose.onnx')

# 最適化パスを指定
passes = ['eliminate_nop_transpose']

optimized_model = optimizer.optimize(model_def, passes)
onnx.save(optimized_model, 'onnx/eliminate_nop_transpose_optimized.onnx')
```
トレイリングスラッシュの有無とディレクトリについて

#トレイリングスラッシュって？

URL末尾の/のことです。通常あまり気にかかける必要はありませんが、場合によっては
サイトの挙動に影響が出ることがあります。
正しく理解した上で運用することが望ましいでしょう。


##トレイリングスラッシュの有無について

例えば、以下のようなURLがあったとします。
①http://sample.com/test
②http://sample.com/test/

①の場合、「sample.comというディレクトリにあるtestというファイル（ドキュメント）をリクエストする」という意味になります。testと名前のついたHTMLや画像、スクリプトなどの何らかのリソースを要求します。この結果、testというファイルが存在しない場合には404エラーが発生することになります。
しかし、実際にはそうはならないケースがほとんどです。
一般的には末尾に/を付けて301リダイレクトされ、②のときと同じ結果となるためです。

②の場合、「sample.comというディレクトリにあるtestというディレクトリをリクエストする」という意味になります。この場合、testというディレクトリにある決まったファイル（index.htmlが一般的）を表示する形になります。


##ファイルとは？

コンピュータ上の情報は意味のある単位でデータとして記録・管理されています。この単位のことを「ファイル」と呼びます。Wikipediaによれば、1952年、パンチカード（厚手の紙に穴を開けて位置や有無でデータを記録する記録媒体）に格納された情報を指した言葉と記述されています。

以下Wikiより引用
初期のころは格納されている中身の情報よりも、装置自体をファイルと呼ぶことが多かった。例えば、IBM 350 のディスク装置は「ディスクファイル」と呼ばれていた。

1962年のCTSSではファイルシステム機能があり、1つの補助記憶装置上に複数の「ファイル」が存在するという形態が登場した。これが現代的な意味でのファイルの始まりである。CTSSではファイル名が2つの部分で構成されていた。1つはユーザーが読めるプライマリ名で、セカンダリ名はファイルの種類を表していた。このようなファイル名の構成方法は Microsoft Windows などの現代のオペレーティングシステムにも受け継がれている。

古い用法（情報を格納するものを「ファイル」と呼ぶ使い方）はほとんど見られなくなったが、例えばレジスタの集まりをレジスタファイルと呼ぶのは古い用法の名残である。

##ディレクトリとは？
「ファイルをグループ化するための特殊なファイル」とWikipedeiaでは紹介されています。
複数のファイルを格納し、ファイルを分類・整理することができる保管場所（入れ物）と捉えるのがわかりやすそうです。Mac　OSでは「フォルダ」と呼ばれます。

Unixでは最上位にルートディレクトリがあり、全てはそこにマウント（接木）されるモデルとなっています。一方で、MS-DOSおよびWindowsでは、最上位は「ドライブ」であり、そこに各々のメディアのルートディレクトリがあり、ツリーがあるモデルとなっています。


##おわりに

大体の場合問題ないとは言え、URLを記述する際は一貫させるべきです。（ありが良いとされています。）リダイレクトを挟む分だけ多少表示速度が落ちます。
また、/がなかった場合に301リダイレクトを設定されるか調べておきましょう。
リダイレクトが使えない時はrel=”canonical”タグを設定するなどの対策が必要です。

なんとなく捉えていた方も多いかもしれませんが、（自分もそうでした）調べてみると使い分けは
大事だと気づかされます。バンチカードなど、昔の技術やコンピュータの起源について詳しく調べてみるのも面白そうです。


参考：
・[海外SEO情報ブログ　URLの最後に付ける「トレイリング スラッシュ」ありなしの違いはSEOに影響するのか？](https://www.suzukikenichi.com/blog/differences-between-trailing-slash-and-non-trailing-slash/)
・[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 トレイリングスラッシュ](https://wa3.i-3-i.info/word11910.html)
・[Apacheドキュメント](https://httpd.apache.org/docs/current/en/mod/mod_dir.html#directoryslash)
・[ファイルとディレクトリの概念](http://www.cc.kyoto-su.ac.jp/~hirai/text/files.html)
・[ファイル (コンピュータ)Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB_%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)
・[ディレクトリWikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA)
Linux上で文字バケして指定できないディレクトリを消したい

# 文字バケして削除できないディレクトリが・・・！
```
[root@Dev01 xxxx]# ls -la
合計 0
drwxr-xr-x 2 nobody nobody 32  9月 26 23:32 ??
drwxr-xr-x 3 nobody nobody 17  9月 27 15:41 .
drwxr-xr-x 3 nobody nobody 20  9月 27 15:41 ..

[root@mobileDev01 mission]# rm -r ??
rm: cannot lstat `??': そのようなファイルやディレクトリはありません
```

# ノード番号を調べる
```
[root@Dev01 mission]# ls -i
978522588 ??
```

# ノード番号を使ってファイルを削除する
```
find . -inum 978522588  -exec rm -rf {} \;
```

参考
https://sakura86.com/linux-mojibake-del/
TeraTermについての個人的まとめ

#この記事について#
自分の備忘録として、自分の考えや調べたことを記載していきます。
ほぼリンク集として使用。
経験が浅いので、間違っていることもあると思いますがご容赦ください。

#マクロ

| 事項       |       説明|       参照|
|:-----------------|:------------------|:------------------|
|[Teratermマクロ(鍵認証接続)](https://qiita.com/KisaragiZin/items/2ad586db5dcf1c608e75)|-|-|
|[メッセージボックスを扱う](http://teraterm.feasible-lab.com/category/10-various-boxes/10-1-how-to-use-messagebox/)|-|-|
Javaにおけるtransient修飾子とシリアライズに関して

初めて```transient```というフィールド修飾子に遭遇したのでメモ。

```
private transient long originalTime;
```

### 一般的な説明
transientを付与すると該当のフィールドは直列化の対象外となる。
該当の変数を持つクラスを直列化しようとして、```NotSerilizabaleException```が発生した際にこの修飾子を付与するととりあえず例外は発生しなくなる。

### 直列化ってなに？
直列化以外にも、シリアライズ、シリアル化などと呼ばれる。
オブジェクトと直列化することは```オブジェクトの情報をストリーム化し、ファイルとして保存 or ネットワークを介してやり取りする```ことが可能になるっぽい。要するにJavaのオブジェクトをバイト列として出力するということ。

### どういう時に直列化できないの？
そもそもオブジェクトによっては直列化できる・できないが決まっている。そのようなオブジェクトを持っているクラス自体を直列化しようとすると前述の例外が発生すると思われる。

### 直列化する方法
あるクラスを直列化するには```java.io.Serializable```を実装すればいい。 シリアライズ化可能ですよー、という証でこのinterfaceを実装すると良い。

### 個人的なまとめ
- Javaオブジェクトをファイルに保存したり、ネットワーク経由で伝達する場合は直列化（シリアライズ）が必要。
- 特定のクラスを直列化するには```Serializable```を実装する必要がある。
- クラスを直列化した時に```NotSerilizabaleException```が発生することがある。
- 直列化の対象外にするために```transient```を使う。
KotlinのPairとTriple

出典 : "[Pair and Triple in Kotlin](https://medium.com/@agrawalsuneet/pair-and-triple-in-kotlin-c76c1d23c0ea)"

一般的に2つの値を返すメソッドの返り値は同一のデータの型で構成されたり異なるデータの型で組み合うことができます。

利用するメソッドが同じクラス内にある場合には一般的にクラスで利用する変数を一つ作ってメソッドで該当の変数の値を設定して必要なところでその変数を利用します。

また、2つの変数を持つデータクラスを作成後、データクラスのオブジェクトを返す方法として利用します。

2つの値を返すメソッドがいくつかあると仮定しましょう。そしてそのメソッドたちが変換する値を成す二つのデータの型は全部違います。

こういう場合は各メソッドに利用するデータクラスをすべての別のものとして定義して作るのでしょうか。

もちろん違います。

Kotlinはそういう用途で利用できるすでに定義されているクラス`Pair`を提供しています。`Pair`は同一であるか違うデータ型の2つの値を保存したり返す時に利用されます。

2つの値は関係性があるかもしれないし、ないかもしれません。同一であるか異なるデータの型にもなれます。

# どう使うか
保存する2つの値を`Pair`のコンストラクタに伝えると簡単に`Pair`クラスのオブジェクトが作られます。

```kotlin
Pair ("Hello", "How are you")
Pair ("First", 1)
Pair (10, null)
Pair (1.5, listOf(null))

var variable1 = "I am a String"
var variable2 = 10
    
Pair (variable1, variable2)
```

# 保存された値はどうやって使うか
`first`と`second`プロパティや`componetN`メソッドを利用してそれぞれ別の変数に保存して使用するか、またはすでに`componetN`メソッドが定義されているため、分離宣言して2つの変数に分けて受け取ることもできます。

```kotlin
var pair = Pair("Hello", "How are you")

println(pair.first)
println(pair.second)

println(pair.component1())
println(pair.component2())

// or

var (firstName, lastName) = Pair("Suneet", "Agrawal")
println(firstName)
println(lastName)
```

`Pair`オブジェクトにも`toString()`のような一般的なメソッドを使用することもできます。

```kotlin
val pair = Pair("I am a String", listOf(1,2,3))
print(pair.toString())
```

`Pair`オブジェクトに`copy`メソッドを利用する際に値を変更することもできますが、変更されるデータの型は既存と同一である必要があります。

```kotlin
val pair = Pair("I am a String", listOf(1,2,3))
print(pair)
    
val anotherPair = pair.copy(first = "I am new String")
print(anotherPair)
```

`toList`メソッドを使用して`Pair`オブジェクトを`List`に変換した後、`List`のインデックスを使用して値を持ってきたり他の作業を行うこともできます。

```kotlin
val pair = Pair("I am a String", 10)
val list = pair.toList()
    
println(list[0])
println(list.get(1))
```

# メソッドに3つの値を返すためにどうすればいいか
`Triple`クラスを使用すれば良いです。3つ目の値は`third`プロパティや`component3`メソッドを使用して検索することができます。

```kotlin
val triple = Triple("I am a String", listOf(1,2,3) , 10)
println(triple.third)
println(triple.component3())
```

`Pair`と同じように`copy`や`toList`メソッドも利用できます。

# 最後に4つ以上の値を返すにはどうすればいいか
この場合は、データクラスを作ってそのクラスのオブジェクトを返した方が良いでしょう。

[Pair](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/)と[Triple](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-triple/index.html)のKotlinの公式ドキュメントはそれぞれのリンクを参考にしてください。
デフォルトシェルをzshからfishに変更したときの作業ログ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110571/84f7b3fe-382c-b4af-b71b-857ecf68d2d6.png)

# 前提
- デフォルトシェルにzshを使用していた
- ターミナルはiTerm2

# 作業ログ
## fishのインストール→デフォルトシェルの変更
```shell
# 実行するとfishがインストールされる
$ brew install fish 

# versionを確認
$ fish -v 
fish, version 3.0.2

# デフォルトシェルにfishを指定
$ sudo vi /etc/shells 
 -> /usr/local/bin/fish を末尾に追加
$ chsh -s /usr/local/bin/fish
```
このタイミングで再起動すると、fishが読み込まれます。

`chsh: /usr/local/bin/fish: non-standard shell` 的なエラーが出る方は、 `/etc/shells` に `/usr/local/bin/fish` がちゃんと追加されているか（typo等）を確認してください。

https://fishshell.com/

## プラグイン『fisherman』のインストール
```shell

# fishermanをインストール
$ curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher

#こんな感じのやつが出る
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
 0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
 100 15372  100 15372    0     0   9801      0  0:00:01  0:00:01 --:--:--  9801

# fishermanのversionを確認
$ fisher -v
fisher version 3.2.9 ~/.config/fish/functions/fisher.fish
```

https://github.com/jorgebucaran/fisher

## fishermanの各種プラグインをインストール

```shell
# fishの設定ファイルを作成
$ touch ~/.config/fish/config.fish

# gitステータスをわかりやすくするtheme-bobthefishを追加
$ fisher add oh-my-fish/theme-bobthefish
fetching https://codeload.github.com/oh-my-fish/theme-bobthefish/tar.gz/master
linking ~/.config/fish/functions/__bobthefish_colors.fish
linking ~/.config/fish/functions/__bobthefish_display_colors.fish
linking ~/.config/fish/functions/__bobthefish_glyphs.fish
linking ~/.config/fish/functions/bobthefish_display_colors.fish
linking ~/.config/fish/functions/fish_greeting.fish
linking ~/.config/fish/functions/fish_mode_prompt.fish
linking ~/.config/fish/functions/fish_prompt.fish
linking ~/.config/fish/functions/fish_right_prompt.fish
linking ~/.config/fish/functions/fish_title.fish
added 1 package in 0.83s

# theme-bobthefishを上手く表示させるためのpowerlineフォントをインストール
$ git clone git@github.com:powerline/fonts.git
$ cd fonts
$  ./install.sh

# fontsインストールツールを削除
$ cd ../
$ rm -rf fonts
```

## iTermのfont設定を変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110571/a54860e2-77f3-77fc-0e10-d77a65d788cf.png)
- Preference -> Profiles -> TextのFontから、Powerline系のFontを指定する
- その後、iTermを再起動

- すると、shellが例のかっこいい見た目に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110571/8316300b-b523-d366-5a6a-60520d5cf9f0.png)
OneSignalをXcode11でビルドするなら最新じゃないと動かない

##はじめに
Xcode11にしたら、OneSignalでプッシュ通知が届かなくなった！
OneSignalのダッシュボードにも端末が表示されなくなった！

##環境
mac
Xcode11
Swift4.2

##やったこと
OneSignal最新版2.11.1を入れてビルド
Swift4.2でもOneSignal最新版2.11.1はビルド通った！

９月頭にOneSignalチームからその旨のメールが来ていたのに無視していたのが悪かった。
TerraformでModuleを使おう

# Moduleとは

特定のリソースをModuleにすることで、設定の使い回しや共通化を図る事ができます

# どんなときに使うか

同一の設定のEC2インスタンスを複数起動する場合、Moduleを使うと簡単です。
workspaceの機能を使わずに、環境ごとにディレクトリを分けている構成をした場合は、Moduleを使用することで複数環境で同一の設定をすることができます。

# ここでやること

簡単に試すことを目的にProviderはDockerを指定します。ImageとContainerをModuleにし、異なる環境でImageのタグやコンテナ名、ホストポートへのマッピングを変更する例を上げたいと思います。


# 実行環境
## ツール
| Tool      | Version |
| --------- | ------- |
| Terraform | 0.12.8  |

## ディレクトリ構成

以下の構成で考えます。

```bash
$ tree .
.
├── env
│   ├── A
│   │   └── main.tf
│   └── B
│       └── main.tf
└── modules
    ├── image
    │   ├── main.tf
    │   ├── output.tf
    │   └── variable.tf
    └── container
        ├── main.tf
        ├── output.tf
        └── variable.tf
```

# Moduleの定義

以下のファイルをそれぞれ定義します。

| ファイル    | 説明                                     |
| ----------- | ---------------------------------------- |
| main.tf     | resourceを定義します                     |
| output.tf   | 他のModuleで利用する値を定義します       |
| variable.tf | Moduleへの入力するための変数を定義します |

## Image

imageはnginxを指定しますが、imageのタグは変更できるようにvariableとして定義します。
container側でimageのIDを利用するためにoutputを定義しています。

```main.tf
resource "docker_image" "nginx" {
  name = "nginx:${var.nginx_image_version}"
}
```
```output.tf
output "nginx_image_id" {
  value = "${docker_image.nginx.latest}"
}
```
```variable.tf
variable "nginx_image_version" {
  default = "latest"
}
```
## Container

containerではコンテナ名とホストのポートを指定できるようにvariableで定義します。

```main.tf
resource "docker_container" "nginx" {
  image = "${var.nginx_image_id}"
  name  = "${var.nginx_container_name}"
  ports {
    internal = 80
    external = "${var.nginx_host_port}"
  }
}
```

```output.tf
```
    

```variable.tf
variable "nginx_image_id" {}
variable "nginx_container_name" {}
variable "nginx_host_port" {
  default = 8080
}
```

# Terraformの実行

Moduleを作成した後は必ず `$ terraform init`を実行します。
環境ごとに以下の設定になるようにmain.tfファイルを編集します。

| 環境 | nginxのimageタグ | コンテナ名      | ホストポート |
| ---- | ---------------- | --------------- | ------------ |
| A    | 1.17             | env_A_container | 8081         |
| B    | 1.16             | env_B_container | 8082         |


```env/A/main.tf
provider "docker" {
}
module "image" {
  source = "../../modules/image"
  nginx_image_version = "1.17"
}
module "container" {
  source               = "../../modules/container"
  nginx_image_id       = "${module.image.nginx_image_id}"
  nginx_container_name = "env_A_container"
  nginx_host_port      = "8081"
}
```

```env/B/main.tf
provider "docker" {
}
module "image" {
  source = "../../modules/image"
  nginx_image_version = "1.16"
}
module "container" {
  source               = "../../modules/container"
  nginx_image_id       = "${module.image.nginx_image_id}"
  nginx_container_name = "env_B_container"
  nginx_host_port      = "8082"
}
```

`env/A`と`env/B`のディレクトリで`$ terraform apply`を実行すると、2つのimageとcontainerが作成されているはずです。

# 最後に
Moduleへのインプットをvariableでアウトプットをoutputを用いることがわかれば、難しい話ではないはずです。
今回のように環境をディレクトリで分けるときには有効な方法かと思います。

# 参考
- https://www.terraform.io/docs/providers/docker/index.html
Laravelでフォーム保存後のフィードバックにSessionのフラッシュデータを使うのと、そのテスト方法

Webページでは何らかのフォームで保存ボタンを押した後に次のページにリダイレクトすることがあり、
リダイレクトされた次のページでフィードバックしたいということがよくあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/6edbb88b-c180-c711-3e79-d8adef917fbd.png)
※画像はイメージです

Laravelにおいてこのフィードバックを出す方法と、そのテスト方法について説明します。

## バックエンドでセッションのフラッシュデータに値を入れる

Controller で以下のようにwithでフラッシュデータに値を入れておきます。

```php

 public function add() {
   // 保存とか色々する
   // 最後に次のページへリダイレクトさせる
   return redirect()->route('/')->with('success', '保存が成功しました');
 } 
```

公式ドキュメントでいうと https://readouble.com/laravel/5.8/ja/responses.html

> フラッシュデータを保存するリダイレクト

あたりの章です。


## フィードバックの HTML と SCSS


Laravelのヘルパ関数でsession()というのがあるので、それで値をとります。


LaravelのBladeファイルで書くとHTMLは以下のようになります。

```html
@if(session('success'))
    <div class="feedback-wrapper">
        <div class="feedback success">
            {{ session('success') }}
        </div>
    </div>
@endif

```

対応するSCSS

```scss
.feedback-wrapper {
  .feedback {
    margin: auto;
    padding: 12px;
    border-radius: 4px;
    text-align: center;

    &.success {
      border: 1px solid green;
      color: green;
      font-weight: bold
    }
  }
}
```

## テスト方法
Featureテストを書く時に、フラッシュデータが何が入っているかというのをテストに書きます。

```php

    public function testAdd()
    {
        $this->post('/test/add', [
            'text' => '入力したテキストです',
        ])->assertRedirect('/text')->assertSessionHas('success');
    }

```

assertSessionHas() を使えば、仮にリダイレクト先が同じでも、入っているフラッシュデータが違う 'success' と 'warning' であっても区別することができます。
Azkaban

Azkaban is a batch workflow job scheduler created at LinkedIn to run Hadoop jobs. Azkaban resolves the ordering through job dependencies and provides an easy to use web user interface to maintain and track your workflows.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80683/1f4b97f3-883d-ac78-4f2f-18489011733c.png)
Reactorのtransform内でPublishSubjectをマップした挙動をテストした際にハマったこと

# `transform(mutation:)`内の処理

以下のように`event`をマップしたReactor内のtransformの挙動をテストする際につまづいたポイントを書き残しておきます。

```swift
import ReactorKit
import RxSwift

final class HogeReactor: Reactor {
    ...
    func transform(mutation: Observable<Mutation>) -> Observable<Mutation> {
        return .merge(
            mutation,
            provider.accountService.event.flatMap { event -> Observable<Mutation> in
                switch event {
                case let .updateProfile(user):
                    return .just(.setUser(user))
                }
            }
        )
    }
    ...
}
```

# `event`の実装

ちなみに`provider.accountService.event`は以下のように`PublishSubject`で実装されています。

```swift
enum AccountEvent {
    case updateProfile(user: User)
}

protocol AccountServiceType {
    var event: PublishSubject<AccountEvent> { get }
    ...
}

final class AccountService: AccountServiceType {
    let event = PublishSubject<AccountEvent>()
    ...
}
```

# テスト失敗

これをテストする際に単純にstreamを流しただけだとテストがうまくいきませんでした。

```swift
@testable import Hoge
import Nimble
import Quick

class HogeReactorSpec: QuickSpec {
    ...
    describe("state.user") {
        context("when receives updateProfile event", closure: {
            it("is updated user", closure: {
                let updatedUser = TestData.testUser()
                stubServiceProvider.accountService.event.onNext(.updateProfile(user: updatedUser))

                // Failed：stateにupdatedUserがセットされず
                expect(hogeReactor.currentState.user) == updatedUser  
            })
        })
    }
}
```

一度も`transform(mutation:)`が呼ばれてないため、`event`のマップがそもそもできていないのが原因ぽいです。

# テスト通過

`transform(mutation:)`を呼ぶために適当にactionを呼んでやるとうまくいきました。

```swift
@testable import Hoge
import Nimble
import Quick

class HogeReactorSpec: QuickSpec {
    ...
    describe("state.user") {
        context("when receives updateProfile event", closure: {
            it("is updated user", closure: {
                // NOTE: Call any action to set up transformed mutation
                hogeReactor.action.onNext(.load)

                let updatedUser = TestData.testUser()
                stubServiceProvider.accountService.event.onNext(.updateProfile(user: updatedUser))

                // Pass：stateにupdatedUserがセットされる
                expect(hogeReactor.currentState.user) == updatedUser
            })
        })
    }
}
```

本当にこれが正しいのかわかりませんが、とりあえず動いたので良しとしてます。
知見ある方いましたらコメントで教えていただけると嬉しいです。
Laravel EloquentのwhereHasメソッドが重いのでその代替案

みなさんこんにちは [tyamahori](https://twitter.com/tyamahori)です。
仕事でちょっとしたシステムをLaravelで作成する機会がありました。その中で注意しなければいけない点があったのでここに書き残したいともいます。


# whereHasメソッドは重くて辛いょ。。
やっまりwhereHasメソッドを使うと重くて辛いんですよ。。ネットでググるとこんな感じで記事が出てきます

- [EloquentのwhereHasメソッドは辛い](https://qiita.com/hisash/items/40532808e61ed3210a6a)
- [WhereHas query is too slow](https://github.com/laravel/framework/issues/18415)

# 代替案ありました！
GitHubのissueを読み込んでみるとなんと解決策があるではないですか！！！
[WhereHas query is too slow のコメント](https://github.com/laravel/framework/issues/18415#issuecomment-371662299)
> Laravel is creating a temporary column on literally every row in the database, in which it fills with true or false. If any indexes can be used, they are probably used after this. Any query that uses whereHas is probably going to be a full table scan.
> 
> Here is a similar query, except it does not induce full table scans.
> 
> ```
> Profile::whereIn('profiles.id', function($query) use ($mac_address) {
>     $query->from('devices')
>         ->select('devices.profile_id')
>         ->where('devices.mac_address', $mac_address);
> })
> ```

なんと`whereIn`を使えばいいんですね。勉強になりました。issueに乗っているコードを必要に応じて読み替える必要はあります。実際、案件にてwhereHasとwhereInを比較してみたら、驚くくらいに挙動が軽くなりました！。whereHasを使っている方はぜひともwhereInを使ってみてくださいね！！
なんにもしてないのにt2.nanoなインスタンスのステータスチェックがいつの間にか落ちてるしSSH繋がんなくなったら

# はじめに

t2.nanoなインスタンスが「なにもしてない」のにヘルスチェックが落ちてSSHでつなげなくなりました。

「なにもしてないのに壊れた」というよりも
「なんにもしてないから壊れた」の方が正しいかもしれません。

貧弱なインスタンスは面倒見てあげる必要があるんですね。

# 現象

t2.nanoなAmazon Linuxを立ち上げて１週間くらいたったとき、
SSHでインスタンスに接続できなくなり、AWSコンソールで確認するとインスタンスのステータスチェックでエラーが発生していました。

このインスタンスにはアプリケーションなどをほとんど入れていない状態なので、
インストールしたアプリケーションが何か悪さをしたわけではないさそうです。

システムログを見た感じだとsshdがメモリ不足で殺されていたので、それが原因だと考えられます。
(sshdとは、sshで接続を受けるために必要なサーバ側のプログラムです。)

t2.nanoのメモリは0.5GBであり、
普通にしてると空メモリは100MBくらいありますが、
EC2のインスタンスのSSHはブルートフォースアタックを受けるので、それでSSHのメモリ使用量が増えたのかな？ と予想。

```text:sshdがkillされてる悲しいログ
[1705026.349903] Out of memory: Kill process 11606 (sshd) score 3 or sacrifice child
```


そんなわけで、再発防止案としては以下の4つを思いつきました。

- スワップ領域を追加し、メモリ不足を緩和する
- インスタンスタイプを上げる
- （メモリ使用量増加がSSHブルートフォースアタックが原因だとしたら）SSHのポートを変更する
- IPアドレス制限をする

など考えられましたが、基本的なところとして、スワップ追加を実施しました。
お金に余裕があるなら、インスタンスタイプをあげればいいと思います。

スワップ追加で本当にsshdが落ちないか、（それによってヘルスチェックが落ちないか）は、まだ未検証です。

まあ、設定してから4日くらい経ってますが、いまのところは大丈夫なかんじです。


# システムログの見方


あれ？なんかSSH繋がんないし、インスタンスのステータスチェックでエラーになってるなと思ったら、システムログを見ましょう

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstances.html#troubleshooting-retrieve-system-logs

![スクリーンショット 2019-09-27 15.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/8ccf055d-b4b3-3e9e-5e32-6788b234b570.png)

```
[1705026.349903] Out of memory: Kill process 11606 (sshd) score 3 or sacrifice child
```
こんなエラーがあれば、それはsshdがシステムによってkillされてます。

# 設定の仕方

AWSのリファレンスを参考に設定しました。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-memory-swap-file/

## EC2のインスタンスにログインする

SSH繋がんない状態だとSSHでログインできないので、
インスタンスの再起動をしましょう。多分、SSHできるようになります。
再起動してSSHが繋がらないようであれば、きっとメモリ不足とかではなく別の問題です。

## SWAP領域を作成する

スワップ領域のサイズですが、もとのメモリ容量が0.5GBなので、
１GB程度あれば十分かなと思います。

####  dd コマンドを使用してルートファイルシステムにスワップファイルを作成します。

「bs」はブロックサイズ、「count」はブロック数です。この例で、スワップファイルは 1 GB です。

```bash
$ sudo dd if=/dev/zero of=/swapfile bs=100MB count=10
```
※bsがデカすぎるとメモリ不足になるので、メモリ不足なら、bsを小さくしてcountの数を増やしましょう

####  スワップファイルの読み書きのアクセス許可を更新します。 

```bash
$ chmod 600 /swapfile
```

####  Linux スワップ領域のセットアップ: 

```bash
$ mkswap /swapfile
```

####   スワップ領域にスワップファイルを追加して、スワップファイルを即座に使用できるようにします。 

```bash
$ swapon /swapfile
```

####  手順が正常に完了したことを確認します。 
```
$ swapon -s
```

こんな感じに表示されるはず

```
ファイル名				タイプ		サイズ	使用済み	優先順位
/swapfile                              	file    	976556	512	-2
```

####   /etc/fstab ファイルを編集して、起動時にスワップファイルを有効にします。

```
$ vi /etc/fstab
$ /swapfile swap swap defaults 0 0
```

#### メモリが増えてることを確認する。
```
$ free -h
```
`-h` はちょうどいい感じで数字の表示をギガとかメガとかにしてくれるオプション

```
              total        used        free      shared  buff/cache   available
Mem:           479M         56M        100M        144K        322M        398M
Swap:          953M        512K        953M
```

はい、Swapに953MB追加されてますね。
なぜ1000MBじゃないかって？ 
たぶんメガバイト表示であってメビバイト表示ではないからです。

# まとめ

t2.nanoなインスタンスのステータスチェックがいつの間にか落ちてるしSSHが繋がらなかったら

システムログみてメモリ不足が発生していることを確認して

もしそうだったら

スワップ領域を追加する。

以上です。
Digital Signature Certificate


![dsm....jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423705/8862462b-8202-bf83-7426-f679fcefdf41.jpeg)

Digital Signature Mart is an authorized partner of Capricorn CA and best digital signature provider in Delhi and the other states of India. it deals in all types of digital signature certificate like class2, class3, and DGFT. It gives the best service and on-time delivery. For digital signature and any quarry visit on our website.

https://www.digitalsignaturemart.com/
python 勉強 plot

#plotの勉強

pivotの勉強の際に作成したpythonでplotをしてみる。
データの可視化への試みです。
ざっくりしています。。。


<pre>
import numpy as np
import pandas as pd

df = pd.read_csv(r'インプットファイル', index_col=0).drop(['日時','企業名','支払','返金'], axis=1)

df["日時"] = df["日時"].str.split(":").str[0]
print(c_nitiji)
data = pd.pivot_table(df, index='日時',  columns='種別',  values='金額', aggfunc=[sum])

data2 = data.fillna(0)

fig, ax = plt.subplots()
ax.plot(data2)
plt.savefig(r"アウトプット")

</pre>

以下の図ができた。
みづらい。。。
もうちょっと改良予定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395963/bf4dc589-cfa4-ea77-8726-61f05ed48078.png)