OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby技術者認定試験】ポイントまとめ


##Ruby Silver 試験ポイントまとめ(自分用)
自分用メモで汚いですが間違えやすいところをまとめてますぜひ

- Ruby 2.0以降では、デフォルトのスクリプトエンコーディングはUTF-8
- Hash#eachのブロックパラメータはArray。
- Hash#size はhashの要素の数を返す
- Enumerable#select	selfからブロックの条件に該当する要素を集めて返す。
- Enumerable#find	selfからブロックの条件に該当する最初の要素を返す。
- Array#delete	selfから引数の要素を削除。削除した要素を返す。破壊的メソッド。

- 例外処理について
    - Rescue 節で省略するとstandard error とそのサブクラスを拾う
    - Ensure節は必ず実行される
    - raiseメソッドは引数を指定していなければ、RuntimeError例外を発生

- 八進数表記
    - 0から始まるもの
    - Puts 090 などでエラー

- 演算子の優先順位は\*よりも\**が高い

- Ruby定数は大文字で始める
    - 変更可能だが警告が出る

- Ruby変数名
    - １文字目はアルファベット小文字か_で始める必要がある。
    - ２文字目以降はアルファベットもしくは数字を使用


- 可変長変数
    - *a などで宣言
    - 任意の数の引数が取れ、aに配列が格納される

- Initializeメソッドは何回でも読み出され書き直される
- Super の記述場所は任意の位置でおｋ

- 外部モジュール読み込みについて
    - 数学PIなどをしようする場合Mathモジュールを読みこむ必要がある
    - 読み込み方法例
        - Include Math
        - Math::PI

- クラス拡張のメソッドより特異メソッドが優先して実行される

- .. , … 演算子について
    - a = [1,2,3,4]
    - a[0..3] => [1,2,3,4]
    - a[0..-1] => [1,2,3,4]
    - a[0,3] => [1,2,3]

- find_all == select
- map == collect

- 正規表現記号
    - *は直前の文字列の０回以上の繰り返しを表す
    - Iオプションで大文字と小文字の区別しない
    - . は任意の文字を表す
    - {m}は直前の正規表現のm回の繰り返しを意味
    - Mオプションで.が改行にもマッチする
    - \d+などの+は連続を表す
    - Matchは一度しか行わない
    - Scanは繰り返し行われる
    - \wは単語構成文字の省略記号

- 65を”A”にしたい時
    - 65.chr
    - 逆は”A”.ord

- ヒアドキュメント
    - <<-識別子' のように-' を付けて書くことで終端行をインデントすることは可能
    - 通常は空白を開けるとエラー

- Chompメソッドで\r\n全て消す
- chopメソッドで末尾の文字を消す
- IO#rewindはファイルポインターを先頭に移動する

- Splitメソッドは引数で特定の文字列を区切り文字として指定できる。また第二引数で生成される配列の個数を指定することができる。

- “0-5”は範囲指定になるが、”8-”では範囲指定にならず8と-を削除します

- eql は 文字列が同じ場合true
- equal は　オブジェクトが同じかどうかを見る

- inject はブロックに要素を割り当てる…|i,j|

- IO
    - IO#getsとIO#readlineはファイルオブジェクトから一行読み込んで、読み込みに成功した時にはその文字列を返す。
    - IO#getsとIO#readlineの違いはEOFに到達した時の振る舞いのみ。IO#getsはnil, IO#readlineはEOFErrorを返す 

```
foo = [1,2,3]
bar = foo
p foo === bar # => true
```

```
Module Foo
  def foo			//インスタンスメソッドとして定義
    puts("foo")
  end
end

Class Bar
  extend Foo		//FooモジュールのインスタンスメソッドをBarクラスの特異メソッドとして定義
end

Bar.foo  #=> foo  という使い方ができる
```
- ::Fooのような::演算子から始まる定数は、トップレベルで定義されている定数

- slice!はスライス後を参照している

- ファイルの末尾(EOF)への反応の仕方
    - getsの場合、nilが帰る
    - Readlineの場合、EOFError例外が発生する

- File#mtimeメソッドは更新が保存されるがFile::Stat#mtimeメソッドは更新が保存されない
    - File::Statクラスはnewメソッドのみクラスメソッド

- ファイル名と拡張子が".“で区切られているファイル名から任意の拡張子を取り除く時に、第2引数として”.*"を指定してFile.basenameを呼び出します
- "%2d%s"の"%2d"は出力したい数値が2桁より少なければ、空白スペースを入れるようにする指定

```
(1..5).each_cons(3) {|arr| p arr }
# <実行結果>
# [1, 2, 3]
# [2, 3, 4]
# [3, 4, 5]

(1..10).each_slice(3) {|arr| p arr }
# <実行結果>
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# [10]
```
```
arr = [1,2].zip([3,4])
p arr
# <実行結果>
[[1, 3], [2, 4]]
```
```
a1 = [1,2,3]
a2 = [4,2,3]
p a1 - a2
# <実行結果>
[1]
```
```
p ({a: 100, b: 100}).invert

# <実行結果>
# {100 => :b}
```
```
1: s = ["one", "two", "three"]
2: s.shift
3: s.shift
4: s.unshift
5: s.push "four"
6: p s

# <実行結果>
# 1: ["one", "two", "three"]
# 2: ["two", "three"]
# 3: ["three"]
# 4: ["three"]
# 5: ["three", "four"]
```
```
p "Ruby on Rails".delete("Rails")
# <実行結果>
# "uby on "
```
```
a, b = 0    # a => 0, b => nil
c, a = 1    # c => 1, a => nil
a, d = 1, 2 # a => 1, d => 2
b, c = 3    # b => 3, c => nil
```
Rubyの超基礎:ハッシュとeachメソッド

Rubyのハッシュとeachメソッドでの使用例をメモする。

#ハッシュについて
ハッシュ名={要素}として宣言する

```Ruby
user = { 要素1, 要素2､.. }
```

# ハッシュの要素の書き方
・キーと値がセット
　(キーとはラベル名=配列でいうインデックスだが､自分で決められる)
・書き方は3種類ある

```Ruby

 “key” => 値　#・・・①
 :key => 値　 #・・・②
 key: 値      #・・・③
#補足:②､③はキーがシンボル(=一意性のある整数ー>メモリが節約できる)
```

#取り出し
宣言に合わせて､2種類

```ruby
ハッシュ名["key"]  #・・・①
ハッシュ名[:key]   #・・・②､③
```

#宣言例(ハッシュの入れ子)

```Ruby
users = {
  hoge: { id: 1, name: "hoge"},
  fuga: {id: 2, name: "fuga"}
}
```
#ハッシュ.eachメソッド
キーと値の2つの変数を設定できる｡
ハッシュの要素を順番に|変数|に格納して､処理をする｡

```Ruby
users.each do |key, value|
  p "#{key} ID is #{value[:id]} and name is #{value[:name]}"
end

###　実行結果
#"hoge ID is 1 and name is hoge"
#"fuga ID is 2 and name is fuga"
```
(メモ)
ハッシュ名は､users
キーは､hoge と fuga
ハッシュの入れ子なので､値もハッシュ名[:キー]で取り出している｡
[Swift]古いiOSバージョンでアーカイブしたデータを読み出す方法

アーカイブする古いコードの例。

```swift
let url = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("com.example").URLByAppendingPathComponent("data")

// 保存時
let archivingData: [OldClass] = [...]
let data = NSKeyedArchiver.archivedDataWithRootObject(archivingData)
do {
    try data.writeToURL(url, options: NSDataWritingOptions.AtomicWrite)
} catch let err {
    print(err)
    return
}

// 取得時
let data: NSData?
do {
    data = try NSData(contentsOfFile: url.path!, options: .DataReadingUncached)
} catch let err {
    print(err)
    return
}
let unarchivedData: [OldClass]! = NSKeyedUnarchiver.unarchiveObjectWithData(data!) as! Array
```

これで圧縮されたデータをiOS 13以降で読み込もうとすると、そもそもメソッドが存在しない。
それを解凍するには、iOS 11以降で利用可能な`NSKeyedUnarchiver(forReadingFrom:)`と`decodeObject(forKey:)`などを利用する。

```swift
if FileManager.default.fileExists(atPath: fileURL.path) {
    do {
        let newObjects: [NewClass] = []
        let data = try Data.init(contentsOf: fileURL)
        if #available(iOS 11.0, *) {
            let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
            // セキュアコーディングをfalseにする（しないとセキュアでないと言われて読み込まれない
            unarchiver.requiresSecureCoding = false
            // 必要に応じて旧クラス→新クラスへデータを読み替えるよう登録
            // もちろん新クラスはアプリに実装されていなければならない
            unarchiver.setClass(NewClass.self, forClassName: "OldFramework.OldClass")
            // rootキーを読み込む
            newObjects = unarchiver.decodeObject(forKey: "root") as? [NewClass]
        } else {
            NSKeyedUnarchiver.setClass(NewClass.self, forClassName: "OldFramework.OldClass")
            newObjects = NSKeyedUnarchiver.unarchiveObject(with: data) as? [NewClass]
        }
    } catch let err {
        print(err)
    }
}
```

# 参考

- [NSKeyedUnarchiver - Foundation | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/nskeyedunarchiver)
- 勘
リンク集

# ありがたいWebサイト様々
情報公開されている皆様に感謝です。
有効的に活用させていただきましょう！

## １．MarkLogic
#### ■ MarkLogic9の新機能TDEを使ってみた
[★Linkはこちらから★](https://qiita.com/JucoML/items/45a4d446218e215d6c7c)
XMLやjsonのドキュメントから抽出したデータを、Query Consoleで表形式にして表示できます。Corb2を使えばCSVファイルでエクスポートできますが、定義ファイルを結構作成する必要があったりツールを使う必要があったりで手間がかかるため、Query Consoleだけで簡単に表示できるのはいいですね。
慣れるまで結構大変かもしれませんが、習得すべきテクニックかと！

#### ■ MarkLogic Dockerコンテナの構築
[★Linkはこちらから★](https://jp.marklogic.com/blog/building-a-marklogic-docker-container/)
DockerでMarkLogic環境を構築可能なんですね。これは便利。
いちいちOSから作らなくて済むので、時間も手間も効率が良くていいです。

#### ■ MarkLogic XQueryサンプル
[★Linkはこちらから★](http://aiden-style.com/article/marklogic-xquery-samples/)
XQueryの実行サンプル集。
ドキュメントのINSERT、LOAD、DELETE、などなど。ちょっとした時に使える簡単なソースが書かれており助かります。
JAWS DAYS 2019 レポート

拝聴させていただいたEKS&ECS関連のセッションです。

⑴[新卒一年目のSREがコンテナをデプロイできるようになるまでの道のり](https://speakerdeck.com/dharada1/xin-zu-1nian-mu-falsesregakontenawodepuroidekiruyouninarumadefalsedao-falseri-jaws-days-2019)
マッチングアプリをサービス提供しているそうです。Golang、マルチクラウド、スマホアプリ。自分のTech領域では通用しないな。

⑵[AWS環境のセキュリティ運用(設計)をはじめてみよう](https://dev.classmethod.jp/cloud/aws/jaws-days-2019-a-security/)
役に立ちそうな情報量がぎっしり。他にもたくさんの情報をQiitaで発信してくれてます。

⑶[GitHub Actionsを使って、ワークフローもプルリクベースで開発しよう！](https://jawsdays2019.jaws-ug.jp/session/1044/)

⑷[自社基盤で運用していた事業用サービスをAWS Fargate/Lambda等を活用しAWS上で再構築！苦労話もあるよ](https://jawsdays2019.jaws-ug.jp/session/1941/)
エンタープライズ系の話でしたので、そうそう！あるある！、的な話が散りばめられていました。m系インスタンスは起動しない時があるとか。
「Managed Cloud with AWS」は初めて知りました。AWSの標準機能だけでは対応ができない運用面を支援するツールは必要だな。

⑸[EC2からECSへ移行を始めたお話](https://speakerdeck.com/yoshiokacb/ec2karaecsheyi-xing-woshi-metaohua)

⑹[Kubernetes を使ってエンジニア組織の生産性を上げよう](https://speakerdeck.com/manabusakai/kubernetes-and-engineer-productivity)
会計ソフト（SaaS）で有名なfreeeの方の講演でした。先に進んでいる方のお話は参考になります。

⑺[Kubernetes on AWS/EKSベストプラクティス](https://speakerdeck.com/mumoshu/eksbesutopurakuteisu2019-dot-2-number-jawsdays)
AWSへの依存やAWSの進化が進むことで、AWS側がなんでもやってくれちゃうのでk8sの中身を理解してもあまり意味がなくなり、遂には自分の仕事がなくなるといった話は怖いですね。ビジネス側の視点に立つことは重要ですね。
mapメソッドについての基礎

# まえがき
mapメソッドの基礎を実例を通してまとめます。
# 簡単な例
```javascript

var numbers = [1,2,3,4]
numbers.map(
	function(){
		console.log("OK");
	}
)
// OKと4回出る
```

配列に.mapとつけて、中に関数を入れる。
4個入った配列なので、中の関数は4回実行されました。
# アロー関数で書いてみよう
アロー関数で書いた方がきれいです。
アロー関数の解説→https://qiita.com/NNNiNiNNN/items/c19405345d8751ceb178

``` javascript
var numbers = [1,2,3,4]
numbers.map(()=>{
	console.log("OK");
	}
)
// OKと4回出る
```
ここからはアロー関数で説明していきます。
#引数をつけてみよう
まず、引数を一つ付けてみます。

``` javascript
var numbers = ["あ","い","う","え"]
numbers.map((value)=>{ // 引数を一つ付けます。
		console.log(value);// valueの中には・・・？
	}
)
// あ
// い
// う
// え
```
第一引数は配列の値を取得しています。
次に、二つ目の引数をつけます。

```javascript
var numbers = ["あ","い","う","え"]
numbers.map((value, index)=>{// 引数を二つ付けます。
		console.log(index);// indexの中には・・・？
	}
)
// 0
// 1
// 2
// 3
```
第二引数では、配列のインデックス番号を取得しています。
もう一つ付けます。

```javascript
var numbers = ["あ","い","う","え"]
numbers.map((value, index,array)=>{// 引数を三つ付けます。
		console.log(array);// arrayの中には・・・？
	}
)
// ["あ", "い", "う", "え"]
// ["あ", "い", "う", "え"]
// ["あ", "い", "う", "え"]
// ["あ", "い", "う", "え"]
```
配列そのものを取得しています。
これは例えば

```javascript

var numbers = ["あ","い","う","え"]
numbers.map((value, index,array)=>{
    array.push(value);// valueあいうえを順番にpush
    console.log(array);// pushされるごとに表示してみます。
	}
)
// ["あ", "い", "う", "え","あ"]
// ["あ", "い", "う", "え","あ", "い"]
// ["あ", "い", "う", "え","あ", "い", "う"]
// ["あ", "い", "う", "え","あ", "い", "う", "え"]
```
こんな感じで、対象の配列を操作することができます。

# 返り値を利用してみよう
mapの最大の特徴は返り値を利用できることです。
以下の例を見てみましょう。

```javascript
var numbers = [1,2,3,4]
var double = numbers.map(value=>{
	return(value * 2); 
	}
)
console.log(double);// [2,4,6,8]
```
mapで得た値をそのままreturnすることで新しい配列を得ることができました。
# まとめ
配列の要素に対して一つ一つ関数を実行できる。
引数として要素の値、番号、配列そのものを使うことができる。
返り値を出力できる。

以下はおまけ

# オブジェクトを引数にしてみよう
mapの側に第二引数としてオブジェクトを用意してみます。

```javascript
var move = {
	  "name": "だいもんじ",
  	"damage": 110,
    "accuracy": 85
  }// こんなオブジェクトを作ってみる
var properties = ["damage","accuracy"];// mapを使う配列はこっち
properties.map(function(value){ // アロー関数「ではない」ことに注意
	console.log(this[value])
}, move )// 第二引数にオブジェクトmoveを設定
// 110
// 85
```
thisで第二引数であるmapを参照できました。
thisの挙動の違いがあるため、アロー関数では同じ動きをしないので注意。
EclipseにてGradleのJAVA_HOME設定

EclipseにてGradleのタスクを実行する際に、下記のようなエラーになってしまう場合があります。

>What went wrong:
>Execution failed for task ':modules:user.rest:compileJava'.
> Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_161 contains a valid JDK installation

原因はGradleのJAVA_HOMEが設定していないため、JREでビルドするからです。

Eclipse⇒Windowメニュー⇒Preference⇒Gradleにて「JAVA HOME」をJDKのパスを選択して設定すると解決となります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/7b808232-99a2-656f-2e21-5674d1c4787e.png)


全般ではなく、プロジェクトのタスクを実行する際にJAVA_HOMEを変更したい場合は下記にように操作できます。
タスク（例：deploy）に右クリック⇒Open Gradle Run Configuration...
![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/e4a8caaf-1547-dbd2-1e1a-f1873d43fd16.png)

以上
Monaca クラウド IDE のプロジェクト起動モードについて

現在、Monaca クラウド IDE では、次の 3 つのモードでプロジェクトを開くことができるようになっています。

- クラウドIDEで開く
- セーフモードで開く
- ライトモードで開く

# クラウドIDEで開く

`クラウドIDEで開く` でプロジェクトを開いた場合は、ターミナル機能を含む Monaca クラウド IDE の全ての機能を利用できます。

ターミナル機能は、有料プランから利用できます。

このモードでは、プロジェクトを開いた際にプレビューサーバーでプロジェクトを処理するために、`package.json` の `dependencies` や `devDependencies` に設定されているパッケージがインストールされます。

そのため、package.json の設定内容によっては、プロジェクトの容量が非常に大きくなる場合がありますが、Monaca クラウド IDE でもローカル環境と同じような開発を行うことが可能になります。


# セーフモードで開く

`セーフモードで開く` でプロジェクトを開いた場合は、Monaca クラウド IDE のプレビュー画面が利用できなくなります。

Monaca クラウド IDE では、通常プレビュー画面が表示されている状態でプロジェクトが開きます。

プレビュー画面が表示されている場合は、プロジェクトを開いた際に起動ファイルに記述されている JavaScript が実行されるため、JavaScript の処理が無限ループ等になっている場合は、ブラウザー自体がフリーズし、操作できない状態になる場合があります。

セーフモードでは、プレビュー画面が利用できない状態でプロジェクトが起動するため、プロジェクトを開いた際に起動ファイルは実行されません。

そのため、JavaScript に記述されている無限ループ等の処理でブラウザーの操作ができなくなる状態を回避することができます。

セーフモードは、JavaScript の無限ループ等の処理でブラウザーが操作できない状態になった場合に、問題の処理を修正するために使用します。


# ライトモードで開く
`ライトモードで開く` でプロジェクトを開いた場合は、ターミナル機能を利用することはできなくなります。

ライトモードでは、`package.json` の `dependencies` や `devDependencies` に設定されているパッケージは、インストールされません。

プレビュー画面には、プロジェクトの `www` 配下にある起動ファイルの実行結果が表示されるようになります。

ライトモードでは、`package.json` に設定されているパッケージはインストールされないため、プロジェクトの容量を抑えることができます。また、ターミナル機能は利用できなくなりますが、`クラウドIDEで開く` でプロジェクトを開いた場合より、動作が軽くなる利点もあります。

`Vue.js` のようなトランスパイルが必要なフレームワークプロジェクトの場合は、プレビューサーバーでプロジェクトを処理する必要があるため、`package.json` に設定されているパッケージをインストールする必要がありますが、`最小限のテンプレート` やトランスパイルが不要なプロジェクトを利用する場合は、ライトモードでプロジェクト開発を行うことができます。


# プロジェクトの再構成について

新規にプロジェクトを作成し `クラウドIDEで開く` でプロジェクトを開いた場合は、`package.json` に設定されているパッケージがインストールされます。

対象のプロジェクトがトランスパイル不要なプロジェクトだった場合は、インストールされたパッケージは利用しないため、プロジェクトに無駄な容量が発生します。

一度、 `クラウドIDEで開く` からプロジェクトを開いた後に、ライトモードに切り替えたい場合は、`プロジェクトの再構成` を実行することで、プロジェクトにインストールされたパッケージを削除することができます。

`プロジェクトの再構成` は、Monaca Dashboard に表示されているプロジェクトを選択し、`設定` > `プロジェクトの再構成` 項目にある `再構成` ボタンをクリックすることで実行することができます。


# おわりに
開発するプロジェクトによっては、`ライトモード` で開発を行うことができます。ライトモードを利用することでの利点もありますので、一度、プロジェクトで利用する起動モードを確認してみてはいかがでしょうか。
React Hooks時代のContext

Reactの進化に合わせて、Contextの使いやすさも上がってきている、と感じました。

## `Context`とは

`Context`は、React 16.3で正式導入された[^1]仕組みで、`props`を経由せずに親から子孫へ値を渡せる仕組みです。

### 使い方（渡す側）

まずは、`const SomeContext = React.createContext(デフォルト値);`のようにして、コンテキストを作成します。そして、コンテキストへ値を供給したい側では、`<SomeContext.Provider value={値}>...</SomeContext.Provider>`で囲むことで、これに囲まれた子孫コンポーネントから`値`を取り出し可能となります。

### 使い方（使う側）

このコンテキスト値を取り出そうとする場合、取り方が3通りあります。

#### `Context.Consumer`（React >= 16.3）

コンテキストの正式導入と同時に入った方法が`Context.Consumer`で、これは`children`としてRender prop的な関数を取って、その関数に値が入ってくる、という流れになっています。

```jsx
<SomeContext.Consumer>
  {
    value => (
      <SomeChildren value={value} />
    )
  }
</SomeContext.Consumer>
```

#### `Component.contextType`（React >= 16.6）

「クラスコンポーネントにRender propは合わせづらい」ということもあってか、React 16.6では[クラスコンポーネントでコンテキストを使う機能が導入されました](https://qiita.com/jkr_2255/items/45079573e0691878eb54#%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%B8%E3%81%AEcontext%E9%81%A9%E7%94%A8componentcontexttype)。詳しくは以前に書きましたが、大きな制約として**1つしか設定できない**ということがあります。

#### `React.useContext`（React >= 16.8）

そして、React Hooksの一つとしてもコンテキストが使えるようになっています。見た目的には`const value = React.useContext(SomeContext);`と、単なる関数であるかのように書けるのですが、実態としては別物なので、使うに当たって[ルールがあります](https://qiita.com/jkr_2255/items/40203693aa8a60bbd9ef)。

## コンテキストの動作とメリット・デメリット

コンテキストを使うメリットとしては、まず「propsを介さず、目的の場所で必要な値を使える」ということがありますが、もう1つのメリットとして「Reactの管理内にある」ということがあります。React外で値を共有してしまうと、値を更新した際にReactの更新がうまくついていかないことが考えられますが、コンテキストはReactの管理内なので、もちろんそんな心配はありません。

一方で、コンテキストが書き換わればコンポーネントが全面的に書き換わるので、クラスコンポーネントの`state`のような、「大きな構造を持っていて、その一部分だけが書き換わることが多い」オブジェクトを入れてしまうと、不必要な更新が増える危険があります。また、かつては「Render propが読み書きしづらい」という問題もあったのですが、React 16.8ではクラスコンポーネントで複数のコンテキストが必要になる場合を除いて問題は解消しています。

## 便利な利用例

### 全体に及ぶ環境設定

言語・ユーザーなど、アプリケーション全体に影響が及ぶ環境をハンドリングするのに、コンテキストはぴったりです。これらは子孫のどこで使うか把握するのも難しいですし、更新する機会も（プログラムの動作というスケールで考えれば）ほとんど来ないので、更新時の弊害もあまりありません。

### stateの更新用関数の引き回し

React Hooksを使った場合、コンテキストの取り出しがごく簡単に行なえます。ということで、`setStateValue`のような、stateの更新用関数をコンテキストで引き回して下位から使う、ということの実用性がかなり上がっています。さらに、React Hooksでは複数の`state`がバラバラに存在する状態となるので、`useState`で生成したセット用の関数をそのまま流用することもできてしまいます。


[^1]: それ以前にも別なコンテキストAPIがありましたが、本稿では扱いません。
ttyとは？

## ttyとは？

>どうやら、標準出力の接続先デバイス事のらしい。一般的にはpts、RS232C経由などはttyS0が標準出力の接続先になっていて、中継しているプログラムがmgetty。

???

> ttyは`仮想ファイルで出入力を扱うデバイス`らしい

どういうことや???

> ttyとは、標準入出力となっている端末デバイス(制御端末、controlling terminal)の名前を表示するUnix系のコマンドである。元来ttyとはteletypewriter（テレタイプライター）のことを指す。(Wikipeadia)

ターミナルを立ち上げるとそれぞれに名前がついてるってことかな？


## ttyコマンド

UNIXのttyコマンドは
標準入力、標準出力となっている端末デバイスを表示する

```
$ tty
/dev/ttys02
```

ちなみにターミナルで新しいウィンドウを作るごとに違う数字になるからウィンドウを開くごとに新しいttyが割り当てられるっぽいな

```
# ログイン中のユーザーを表示
$ w
21:11  up 16 days, 19:43, 21 users, load averages: 3.59 7.09 8.63
USER     TTY      FROM              LOGIN@  IDLE WHAT
hoge    console  -                07 219  16days -
hoge    s000     -                07 219      7 -bash
hoge    s001     -                07 219      7 -bash
hoge    s002     -                07 219      7 -bash
hoge    s003     -                07 219      7 -bash
```

## echoで遊んで見る

いろんな記事見るとやってるのでやってみた。

/dev/ttys015の方からechoすると/dev/ttys022の方で出力できた！！

でも使い道があるのかは全くわからない（笑）

<img width="1114" alt="スクリーンショット 2019-02-23 21.24.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/222453/5049f818-ccaf-3744-752b-7e834099db70.png">


## 参考記事
http://takuya-1st.hatenablog.jp/entry/20101024/1287947368
https://qiita.com/toshihirock/items/22de12f99b5c40365369
mysqlへExcelVBAから接続する。64bit Winに32bit Excelをインストールしている場合。

# はじめに。
Excelからmysqlへ接続するためのodbcドライバの設定で少しつまずいたのでその時のメモです。
Excelからドライバを使う場合は、Excelに合わせて32/64bitを選択しインストールする必要があります。この点を理解しておらず、OSが64bit、Excelが32bit版だったため、エラーを繰り返しました。わたしの環境の場合、「mysql installer」からODBCをインストールしようとしても64bit版しか選択できず、個別インストーラーを利用する必要がありました。

# odbcドライバのDL/Install
以下のどちらかからインストールする。
- mysql installer（mysql製品の追加削除更新を管理するツール）
- mysqlの公式サイトから個別インストーラをDL
    - https://dev.mysql.com/downloads/connector/odbc/

# インストール
Visual studio 2005 C++ redistなんたらが必要と英文msgが表示されたらマイクロソフトのサイトから探してインストールする必要があります。再配布なんたらというやつ。

# ドライバを登録する。
インストール完了後、コンピュータにドライバを登録する。

- コントロールパネル⇒管理ツール⇒以下のいずれかを開く
    - 64bit Excel
        - 「ODBC データ ソース (64 ビット)」
    - 32bit Excel
        - ODBC Data Sources (32-bit)

- ユーザDNSタブ選択し追加
- Mysql ODBC 8.0 ANSI driver　を選択。
    - ここにmysqlドライバがない場合、インストールに失敗している。
- 接続情報を入力。
![odbc.png](https://qiita-image-store.s3.amazonaws.com/0/342467/74cf5a3b-0a9f-208d-cc28-79b60eacd386.png)
- Data source name :適当
- Description:任意
- tcp/ip：IPaddress　or　hostname
- user：mysqlのユーザ
- password：上記ユーザのパスワード
- database:接続データベース
    - 上記の情報に誤りがなければここに利用可能データベースがリストされる。
    - 表示されない場合、認証情報かIPアドレスに誤りがある。


#Excel 設定
## 参照設定
- Microsoft ActiveX Direct Data objects ##.## Library
- Microsoft scripting runtime（必要かどうか未確認）

## コネクションストリング（接続識別子）

```vb:Driverで接続する
Sub mysqltest()
    'MySQL 接続
    Dim con As New ADODB.Connection
        con.ConnectionString = "Driver={MySQL ODBC 8.0 ANSI Driver};" & _
                               "Server=localhost;" & _
                               "Port=3306;" & _
                               "Stmt=SET NAMES SJIS;" & _
                               "Database=testdb;" & _
                               "Uid=root;" & _
                               "Pwd=1111;"

```

```vb:DSNで接続する。
'Driver名ではなく下記のようにDSNを使っても接続できる。
        con.ConnectionString = "DSN=mysql32driver;" & _
                               "Server=localhost;" & _
                               "Port=3306;" & _
                               "Stmt=SET NAMES SJIS;" & _
                               "Database=testdb;" & _
                               "Uid=root;" & _
                               "Pwd=1111;"
```



#Excel VBAでエラーメッセージが表示される場合
>[Microsoft][ODBC Driver Manager] 指定された DSN には、ドライバーとアプリケーションとのアーキテクチャの不一致が含まれています

⇒ドライバの32/64と、Excelの32/64の不一致。

>ERROR [IM002] [Microsoft][ODBC Driver Manager] データ ソース名および指定された既定のドライバーが見つかりません。

⇒上記と同様か、あるいはドライバー名などが間違っているか。
Flutterで起動時に一度だけ処理を実行したい

Flutterでアプリを開発していると、アプリが起動し画面が読み込まれる前の段階で一度だけ処理を実行したいことがあると思います。
Androidで言う`onCreate`と同じような動作をFlutterで実現したいです。
こんなことを実現したい
-
- アプリ起動時に保存された文字列を取得してTextに表示したい
- <del>ネット上から非同期で画像を取得して表示したい</del>

→WEBから取得した画像を表示するための超簡単な方法があるようです。
https://qiita.com/superman9387/items/e7a669dbd7354894c860

<br>
アプリの起動時に実行したい処理は、`State`クラスの`initState`をオーバーライドして、その中に処理を書くことで実現できます。
Flutterプロジェクトの作成時にデフォルトで生成されるサンプルコードを基に説明します。

```dart:main.dart
import 'package:flutter/material.dart';
//データ保存に必要なShared preferencesをインポートする
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
    _saveCounter(_counter);
  }

  // 今のカウントを保存する
  _saveCounter(int count) async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    await pref.setInt("myCount", count);
  }

  // 保存したカウントを読み込んでTextに反映させる
  _readCounter() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      var data = pref.getInt("myCount");
      if (data != null) {
        _counter = data;
      }
    });
  }

  //ここが重要
  @override
  void initState(){
    //アプリ起動時に一度だけ実行される
    _readCounter();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

```

`initState()`の中でアプリ起動時に一度だけ実行したい、任意の処理を実行することができます。

```dart:
@override
void initState(){
  //アプリ起動時に一度だけ実行される
  _readCounter();
}
```
<img src="https://qiita-image-store.s3.amazonaws.com/0/366412/49861421-ee88-c4f7-1fa8-efc926791093.jpeg" width=40% />

フローティングボタンを押すとカウンターが1ずつ増え、アプリを閉じても数字を保存できるようになりました。
Angular で markdown で書いた記事を Github Pages で表示するまで

これ :arrow_down: を見て、 GitHub Pages って React 使えるんだ！
[create-react-appとTypeScriptでサラッと作ったSPAをgh-pagesにスルッとデプロイすっぞ！](https://qiita.com/rhirayamaaan/items/cdbda70670157a8fb705)

と思って、じゃあ Angular もできるよね！というところから、 markdown で書いたものを表示したいよね！と思って調べて試してたらできたので :pencil: 

### 動機
最近、勉強したこととか調べたことをどこかに集約したいなと思いつつ、
- 簡単にメモ気分で書きたい
- 勉強した内容とかが自分の中で更新されたら書いた内容も更新していきたい
- Qiita とかだと若干の公式感が出て(個人的な感覚だけど)、ちゃんと書かないとみたいな意識が出てしまうのでちょっとな...(実際この記事もちゃんと書いてる...つもり)
- 非公開にする必要はない
とかいろいろ考えて、どっかに置きたいな〜というので調べてて Github Pages もありだな〜みたいな感じでサンプルを作ってみた。

### 環境
```
Angular CLI: 7.2.4
Node: 8.11.3
Angular: 7.2.6
```

### 作ったもの
https://ikepon.github.io/angular-wiki/
https://github.com/ikepon/angular-wiki

### 手順
`assets` に `blog/abc.md` みたいな記事の markdown を入れておいて、それを表示する感じにしました。

```console
ng new angular-wiki
cd angular-wiki 
yarn add ngx-markdown
```
markdown はこの辺 :arrow_down: を見ながら設定。
https://www.npmjs.com/package/ngx-markdown

適当なコンポーネントを作って

```console
ng g component blog
```
route をこんな感じにして `id` で markdown のファイル名を指定して設定するようにしました。

```ts
const routes: Routes = [
  { path: 'blog/:id', component: BlogComponent }
];
```
コンポーネントは以下のような感じで設定。

```html
<p>
  blog works!
  {{post}}
  <markdown [src]="post"></markdown>
</p>
```

```ts
export class BlogComponent implements OnInit {
  post: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.post = 'assets/blog/' + params['id'];
    });
  }
}
```
各ページに遷移できるように `app.component.html` にリンクを追加して

```html
<ul>
  <li>
    <a routerLink="/">TOP</a>
  </li>
  <li>
    <a routerLink="/blog/article_1.md">Article 1</a>
  </li>
  <li>
    <a routerLink="/blog/article_2.md">Article 2</a>
  </li>
</ul>
<router-outlet></router-outlet>
```
あとは `assets/blog/article_1.md` `assets/blog/article_2.md` みたいな適当なファイルを置いてブログ部分は完成。

デプロイは `angular-cli-ghpages` を使って
https://www.npmjs.com/package/angular-cli-ghpages

```console
yarn add -D angular-cli-ghpages
```
ビルドしてデプロイしました。

```console
ng build --prod --base-href "https://ikepon.github.io/angular-wiki/"
npx angular-cli-ghpages --dir="dist/angular-wiki"
```

フロントに強くなると、もっといろいろできるんだろうな〜と思って、小さいことからコツコツやっていこうかと思ってます。
[Swift]UserDefaultsが設定されているか確認する方法

`UserDefaults`の`bool(forKey:)`や`integer(forKey:)`などはnullableでない値を返してくるため、設定されていなくても`false`や`0`が返って来てしまう。
そういった場合に値が設定されているかを確認する場合は、`object(forKey:)`を調べると良い。

```swift
let isEnabled: Bool?
if UserDefaults.standard.object(forKey: "isEnabled") == nil {
    print("isEnabled is not set")
} else {
    isEnabled = defaults.bool(forKey: "isEnabled")
}
```
gulpでSSIを利用する

ちょっとハマったのでメモ。

- MAMPでSSIを使えるようにしていた
- MAMP内にgulpを入れている
- そのgulp内でSSIを使用したい

こんな時に、陥るかもしれない。

そもそも**MAMPのサーバとgulpで立ち上げたサーバは異なる**ので、
gulpの中にSSIを入れてあげないと動作しない。
（MAMPでSSI有効にしていたので、普通にOKだろうと思ってた）

```terminal
npm install connect-ssi --save-dev
```

### 参考ページ
[gruntやgulpでSSIを利用する](http://cly7796.net/wp/other/use-ssi-with-browser-sync/)
[connect-ssi](https://www.npmjs.com/package/connect-ssi)


### 前提条件
- browser-syncが入っていること。入っていなければインストールする
html5  カメラ起動  capture属性について

# カメラ起動

input要素のtype属性がファイル・アップロード状態になっていて、そのaccept属性が指定されている場合に、capture属性 の項の規則が適用されます。

## ユーザ向きカメラを用いて写真を撮影し、撮影された写真をHTMLフォームでアップロードする場合
```html 
<form action="server.cgi" method="post" enctype="multipart/form-data">
  <input type="file" name="image" accept="image/*" capture="user">
  <input type="submit" value="Upload">
</form>
```

## 周囲向きビデオ・カメラを用いて、動画をキャプチャーする場合
```html
<form action="server.cgi" method="post" enctype="multipart/form-data">
  <input type="file" name="video" accept="video/*" capture="environment">
  <input type="submit" value="Upload">
</form>
```

## より高度なユースケースの場合は、マークアップでcapture属性を指定
```html
<input type="file" accept="image/*" capture>
<canvas></canvas>
```

## XMLHttpRequestのスクリプトでファイル・アップロードを処理します
```js
var input = document.querySelector('input[type=file]'); 

input.onchange = function () {
  var file = input.files[0];

  upload(file);
  drawOnCanvas(file);   
  displayAsImage(file); 
};

function upload(file) {
  var form = new FormData(),
      xhr = new XMLHttpRequest();

  form.append('image', file);
  xhr.open('post', 'server.php', true);
  xhr.send(form);
}
```

## クライアント・サイドで画像編集を行うことを目的としている場合などには、画像をアップロードせずにクライアント・サイドに表示ができる
```js
unction drawOnCanvas(file) {
  var reader = new FileReader();

  reader.onload = function (e) {
    var dataURL = e.target.result,
        c = document.querySelector('canvas'), 
        ctx = c.getContext('2d'),
        img = new Image();

    img.onload = function() {
      c.width = img.width;
      c.height = img.height;
      ctx.drawImage(img, 0, 0);
    };

    img.src = dataURL;
  };

  reader.readAsDataURL(file);
}
```

## img要素を用いて画像の表示のみ
```js
function displayAsImage(file) {
  var imgURL = URL.createObjectURL(file),
      img = document.createElement('img');

  img.onload = function() {
    URL.revokeObjectURL(imgURL);
  };

  img.src = imgURL;
  document.body.appendChild(img);
}
```
slick.js マウススクロールでスライドを送れるようにする

# 概要
カルーセルを簡単に作れるライブラリ、slick.jsをマウスホイール/トラックパッドのスクロールに対応させたのでメモ。

# 実装
``` app.js
var $carousel = $('.js-carousel');

// slickの初期化
$carousel.slick({
        arrows: false,
        centerMode: true,
        centerPadding: '40px',
        slidesToShow: 3
      });

// スクロールイベントの監視
$carousel.on('wheel', function(e) {
  e.preventDefault();

  if (!$carousel.hasClass('js-slick-moving')) {
    if (e.originalEvent.deltaY < 0) {
      $(this).slick('slickNext');
    } else {
      $(this).slick('slickPrev');
    }
  }
})

// スライド送り中を判定するためにクラスを付与する
$carousel.on('beforeChange', function(){
  $carousel.addClass('js-slick-moving');
});

$carousel.on('afterChange', function(){
  $carousel.removeClass('js-slick-moving');
});
```
JAWS DAYS 2019 - Serverless/Container/k8s/IaC/SRE/Security + ML 資料リンク集

## はじめに

[JAWS DAYS 2019](https://jawsdays2019.jaws-ug.jp/) のインフラ周りのセッションの資料リンク集を作りました。
twitterで私が見つけたものについてはリンクを載せていますが、
漏れているものがありましたら編集リクエストを送っていただくか、コメントでリンクとセッションのタイトルを教えていただければこちらで追加します(後日上がってきたものについては随時更新していきます)。

なお、あまり広げると編集作業が大変になると想定されます。
著者に技術スタックに関連した分野で恐縮ですが、このページではコンテナ関連技術とAWS運用周り(IaC/SRE/Security) (+ ML) 関連のセッションに限らせていただきます。
ほかのジャンルについては、別のページにまとめていただけますと幸いです。

注: @hayao_k さんがなんと[全セッションの資料リンク集](https://qiita.com/hayao_k/items/91c19480948f26b71705)をつくってくれてますので、こちらも合わせてご確認ください。

## Serverless

* [サーバレスで動かすトークン発行プラットフォーム, 小池 駿平さん](https://speakerdeck.com/shunp/sabaresudedong-kasutokunfa-xing-puratutohuomu)
* [AWS Serverlessを活用したサービス監視, 清家 史郎さん](https://slide.seike460.com/#/)
* [AWS x JAMStack で構築・運用するサーバーレスなWeb Front, 江藤 武司さん](https://riotz.works/slides/?2019-jaws-days#1)
* [見せてやろう…Serverlessの本当の力を…!!, 照井 将士さん](https://speakerdeck.com/marcyterui/lets-show-you-the-real-power-of-serverless-dot-dot-dot)
* [Build and Scale SaaS product by Serverless technologies., Okamoto Hidetakaさん](https://speakerdeck.com/hideokamoto/jaws-days-2019)
* [Node.jsでのAWSサーバレスアプリプログラミングを簡単にする技術の研究紹介, 木村 功作さん](https://speakerdeck.com/kimusaku/node-dot-jsdefalseawssabaresuapuripuroguraminguwo-jian-dan-nisuruji-shu-falseyan-jiu-shao-jie-an-introduction-of-a-technology-for-simplifying-serverless-application-programming-in-aws-with-node-dot-js)

## Container/k8s

* [新卒一年目のSREがコンテナをデプロイできるようになるまでの道のり, 原田 大地さん, 坂田 純さん](https://speakerdeck.com/dharada1/xin-zu-1nian-mu-falsesregakontenawodepuroidekiruyouninarumadefalsedao-falseri-jaws-days-2019)
* [GitHub Actionsを使って、ワークフローもプルリクベースで開発しよう！, 池田 尚史さん]
* [EC2からECSへ移行を始めたお話, 吉岡 隆行さん]
* [Kubernetes を使ってエンジニア組織の生産性を上げよう, 坂井 学さん](https://speakerdeck.com/manabusakai/kubernetes-and-engineer-productivity)
* [Kubernetes on AWS/EKSベストプラクティス, Yusuke Kuokaさん](https://speakerdeck.com/mumoshu/eksbesutopurakuteisu2019-dot-2-number-jawsdays)
* [EC2からKubernetesへの移行をセキュリティ/モニタリングから考える, 杉浦 英史さん, 河村 篤志さん](https://speakerdeck.com/atk/freeeniokeru-kubernetesjian-shi-ji-pan)

## IaC/SRE

* [至高の CI/CD パイプラインを実現する5つの約束, ポジティブな Toriさん, 小西 宏樹さん](https://speakerdeck.com/toricls/the-five-principles-to-spark-joy-in-your-pipelines)
* [Infrastructure as Codeに疲れたので、僕たちが本来やりたかったことを整理する, 村主 壮悟さん](https://speakerdeck.com/shogomuranushi/infrastructure-as-code-is-very-tired)

## Security

* [1日でSSHをやめることができた話 ~AWS Systems Manager Session Manager 導入と運用Tips~](https://speakerdeck.com/3utama/1ri-tesshwoyamerukotokatekitahua)
* [AppStream 2.0を活用してユーザ端末に依存しない運用にしよう]
* [[初心者向け]AWS環境のセキュリティ運用(設計)をはじめてみよう, 臼田 佳祐さん](https://speakerdeck.com/cmusudakeisuke/chu-xin-zhe-xiang-ke-awshuan-jing-falsesekiyuriteiyun-yong-she-ji-wohasimetemiyou)
* [PenTesterが知っている危ないAWS環境の共通点 ~攻撃者視点よりお届けする狙われやすいAWSの穴~, 洲崎 俊さん, 一ノ瀬 太樹さん, 北原 憲さん](https://www.slideshare.net/zaki4649/pentesteraws)

## ML

* [PythonとSageMakerで始める MLチームのみで完結するAPIの構築事例, 虻川 勝彦さん](https://speakerdeck.com/ababa893/jaws-days-2019-pythontosagemakerteshi-merumltimufalsemitewan-jie-suruapifalsegou-zhu-shi-li)
* [機械学習における AWS を用いたマイクロサービスアーキテクチャ, 中川 裕太さん](https://www.slideshare.net/yutanakagawa2/aiml-aws)
* [AI/MLシステムにおけるビッグデータとの付き合い方, 鈴木 翔太さん]
私も画像が投稿できるWebアプリを作りたい。その2(カラムの追加)

#1.もうできてるテーブルにカラムを追加する
↓を一緒に投稿したい。
タイトル＋内容＋画像
↓
もうできてるpostテーブルに
imageカラムを追加する。
（imageカラムは写真用）


```
$ rails g migration AddImageToPosts image:text
                    ①　　　　　　　　　②
```
①クラス名
　後々「なんじゃこりゃ」状態になりたくないので、
ーーーーーーーーーーーーー
1.Add
 「付け足しましたよ。」
2.Image
 「Imageカラムを」
3.To
 「↓の所へ」
4.Posts
 「postsテーブルの所へ」

ーーーーーーーーーーーーー
②
1.image:
  カラム名
2.text
　データ型
ーーーーーーーーーーーーー

```
$ rails db:migrate
```
つづく
[React Native]undefined is not an object (evaluating 'this.state...')と言われた時

だいたい`<Button onClick={this.addData()}>Add data</Button>`などした時。
`bind`すると良い。

```jsx
<Button onPress={this.addData.bind(this)}>Add data</Button>
```

## 参考
- [javascript - Undefined is not an object evaluating this.state.* - Stack Overflow](https://stackoverflow.com/questions/40445631/undefined-is-not-an-object-evaluating-this-state)
import androidx.appcompat.app.AppCompatActivity でエラー。

自分の為の覚書きとして残しておきます。

Android Studioにて 既存のプロジェクトを　androidX に移行しようとrefactorしたけれど、

import androidx.appcompat.app.AppCompatActivity がうまく読み込めていないのか、

class MainActivity : AppCompatActivity() {　のAppCompatActivityが赤字になる。（幼稚な表現で申し訳ない）

おかしいなぁ、と思ってググってみたところ、

Build →　Clean Project でエラー解消しました。

今までもいろんなトラブルシーンでこの「Build →　Clean Project」で救われたことがあったような気がする。
東プレRealForceがMacのSleep復帰時に認識されない。


#はじめに
- 東プレの高級キーボードの素晴らしさを知り、自宅のMac環境にRealForceのUSキーボードを導入した。
 - これは「Realforce87USW 英語配列 【静音仕様・白モデル】 SE070S」というモデル。
- タイピングがこんなにも心地いいなんて。。。なんでもっと早く買わなかったんだ！

![IMG_1775.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/215a7747-c87b-dc87-ccc9-6e6eef824738.jpeg)

# キーマップ変更

- [karabiner Elements](https://pqrs.org/osx/karabiner/)でキーマップを設定。
 - iMac (21.5-inch, Mid 2011)
 - macOS High Sierra 
 - karabiner Elements 12.2.0

![スクリーンショット 2019-02-24 0.33.56.png](https://qiita-image-store.s3.amazonaws.com/0/283854/bbe78236-e909-9e6e-6181-37746a98f98f.png)

- と言ってもUSキー配列なので、あんまり変える必要がない。
 - しかもこのキーボード、DIPスイッチで左のCtrlキーとCaps Lockが切り替えられるのが良い。
 -  (キーボードの写真は購入時のもので、実際はCaps Lockと左のCtrlキーを交換してます。)

- ただ、、使っているうちにめんどくさい問題に遭遇。。。
 
# スリープ復帰時にUSBケーブルを抜き差ししないとキーボード入力が認識されない。

- 問題点
 - Macがスリープ状態から復帰する際、マウスでログイン画面を表示するまでは出来るが、何故かキーボード入力が受け付けられない。
 - 一度USBケーブルを抜き差しすれば、再びキーボード入力を受け付けるようになるが、毎回メンドくさい。
 - せっかく超快適な環境が手に入ったのに、これどうにかならないのか？
 - いくつかググってみた所、解決方法を編み出した方を発見。
- 解決方法 
 - 1.マウスでスリープ復帰させる。
 - ~~**2.キーボードの「Caps Lock」を押す。**~~ --> 何度か試した所、実はマウス復帰のみでOKでした。

![IMG_1776.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/678bb2cd-3dee-69ec-484b-b042d25537f7.jpeg)

- memo 
 - **スリープ復帰トリガーは必ず最初にマウス側でやること!!** 
 - この順番が極めて重要！！
 - 先にキーボードで復帰しちゃうと、その後のキーボード入力は認識されない。
 - RealForceのDIPスイッチで「Ctrl」と「Caps Lock」を入れ替えてもこれは有効である。

# 見事に解決！！
- これでUSB抜き差し問題は解決した。
 - 本来、どんなキーでも反応しないとダメだけど、この程度の回避でUSB抜き差ししなくて済むなら別にいいや。
- これでMacでも最高のタイピングが楽しめますよ！！
最高の仕事術「タイムボックス」を実践する為のカレンダーアプリを作った話

## とりあえず試してみたい方向け

▼ダウンロードはこちら(mac向け/dmg形式)▼
<https://s3-ap-northeast-1.amazonaws.com/watari/downloads/darwin/Watari-0.0.5.dmg>

## Googleカレンダーの"現在の予定だけ・デスクトップ最前面に"表示したい人生だった

[もっとも生産性を高める仕事術はタイムボックス。 そのやり方とメリットとは？ | ライフハッカー［日本版］](https://www.lifehacker.jp/2019/02/make-your-days-more-productive-by-timeboxing.html) という記事が最近公開されました。

消化できもしない肥大化したTodoリストなんかより、カレンダーに直接予定をぶち込んだ方が確実にこなすよね、うまく取捨選択できるよね、という話です。

私もそんなタイムボックス的な管理をしてましたが**「いちいちカレンダーを開かないと現在の予定が確認できない」**という問題に直面しました。

そこで

- **デスクトップで一番手前にGoogleカレンダーの現在の予定出したらよくね？**
- **残り時間のカウントダウンとカレンダーのメモも出せたらよくね？**
- **ついでに予定ごとにURLのレコメンドしてもらえたら嬉しくね？**

という思考回路で作ったmac向けアプリがWatariです。

## デモ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【最高の仕事術に選ばれた&quot;タイムボックス&quot;の相棒に】<br>〜GoogleカレンダーでTodo管理してる、生産性に拘る方へ〜<br><br>Googleカレンダーの「現在の予定」をデスクトップに常時表示するアプリ「Watari」を公開しました。<br><br>▼ダウンロードはこちら（Mac向け/dmgファイル）▼<a href="https://t.co/n2PeCv1hKR">https://t.co/n2PeCv1hKR</a> <a href="https://t.co/ceQXHvMEyf">pic.twitter.com/ceQXHvMEyf</a></p>&mdash; ながみ@新しいmacアプリ出しました (@nagaminenot) <a href="https://twitter.com/nagaminenot/status/1099265041809825792?ref_src=twsrc%5Etfw">2019年2月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 技術的なおはなし
- ベースには[electron-vue](https://github.com/SimulatedGREG/electron-vue)を使用
- 現在の予定名を使ってGoogleカレンダーAPIを検索、同じ予定の過去の時間に見ていたURLを探し、レコメンド
- URLの探し方はアプリにsqlite３を内蔵させて、Chromeの履歴（sqlite3で読める）を検索（もちろんChromeの履歴をサーバーで収集はしてないのでご安心ください。ユーザーのPCとGoogleカレンダーAPI間で完結したレコメンドです。）

### 技術的にしんどかったこと
- sqlite3を内蔵しようとすると、ビルドで一苦労する。そしてWindowsでビルドできない。[このへん](https://stackoverflow.com/questions/32504307/how-to-use-sqlite3-module-with-electron)を参考に解決した。
- 自動起動機能の実装が少し大変だった。権限もらえないと `AutoLaunch.isEnabled()` で `false` ではなく `error` を `catch` しないといけなかったり。sqlite3よりはだいぶマシ。

個人的には重宝していて、毎日仕事で使っているのですが他のタイムボックスで予定管理している人に使ってもらえるか気になるので、ぜひ試してみて、感想をいただきたいです。

▼ダウンロードはこちら(mac向け/dmg形式)▼
<https://s3-ap-northeast-1.amazonaws.com/watari/downloads/darwin/Watari-0.0.5.dmg>

▼感想・バグ報告はこちら▼
<https://twitter.com/nagaminenot>

※会社制作ではなく個人制作のアプリです
Arduino IDE コンフィグレーションメモ

# はじめに
- Arduino IDEで複数種類のボードを使い出したので、環境設定を元に戻せるようにメモ。

# 開発環境

- iMac 2011
- Arduino IDE 1.8.5
- 使用ボード 
 - ESP8266
 - Arduino nano互換ボード

#「ツール」メニューのボード設定

## EPS8266
- [Amazon ESP8266開発ボード](https://www.amazon.co.jp/gp/product/B07DDD3TCD/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)
- USBケーブル: MicroUSB
 
|項目|値|
|:---:|:---:|
|ボード|Generic ESP8266 Module|
|Flash Mode|QIO|
|Flash Size|4M(3M SFIFFS)|
|Reset Method|nodemcu|
|Crystal Frequency|26MHz|
|Flash Frequency|80MHz|
|CPU Frequency|160MHz|
|Upload Speed|115200|
|シリアルポート|/dev/cu.wchusbserialfa120|

## Arduino nano 互換ボード
- USBケーブル: MiniUSB

|項目|値|
|:---:|:---:|
|ボード|Arduino Nano|
|プロセッサ|ATMega328P|
|シリアルポート|/dev/cu.wchusbserialfa140|
Railsのrenderの書き方多すぎ問題について

新人エンジニアです。
コードを見ていく中で色んなrenderの書き方を見つけて、こんがらがってきたのでこちらにまとめようと思います。

##renderの色々な書き方
[RAILSGUIDE](https://railsguides.jp/layouts_and_rendering.html)のものを紹介します。これ全部同じ意味ですからね。。。

>BooksControllerクラスのupdateアクション内で、本の更新に失敗したらeditテンプレートを出力したいとすると、以下のどのレンダリング呼び出しを行っても最終的には必ずviews/booksディレクトリのedit.html.erbを使用して出力が行われます。

```

render :edit
render action: :edit
render "edit"
render "edit.html.erb"
render action: "edit"
render action: "edit.html.erb"
render "books/edit"
render "books/edit.html.erb"
render template: "books/edit"
render template: "books/edit.html.erb"
render "/path/to/rails/app/views/books/edit"
render "/path/to/rails/app/views/books/edit.html.erb"
render file: "/path/to/rails/app/views/books/edit"
render file: "/path/to/rails/app/views/books/edit.html.erb"
```
No.040【Python】無限大を表す" inf "について①

![python-logo-master-v3-TM-flattened.png](https://qiita-image-store.s3.amazonaws.com/0/336067/8fb9f6aa-57f7-dc4b-b4bf-a648969d315c.png)

####今回は、無限大を表す「inf」について書いていきます。
I'll write about "inf()",which indicates infinity.

###■ 浮動小数点数 float型のinf
&emsp;Floating-point number float-type, "inf"

```
>>> # コンストラクタ float()の引数に、文字列"inf" を指定
>>> 
>>> f_inf = float("inf")
>>> 
>>> print(f_inf)
inf
>>> 
>>> print(type(f_inf))
<class 'float'>
```

###■ 負の無限
&emsp;Negative "inf"

``` 
>>> # infにマイナスをつける
>>> 
>>> f_inf_minus = -float("inf")
>>> 
>>> print(f_inf_minus)
-inf
>>> 
>>> print(type(f_inf_minus))
<class 'float'>
```
###■ 他の型への変換方法
&emsp;How to change to another type

``` 
>>> # infは、int型に変換できない
>>> 
>>> print(int(f_inf))
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    print(int(f_inf))
OverflowError: cannot convert float infinity to integer
``` 

``` 
>>> # ただし、文字列str型は、変換可能
>>> 
>>> print(str(f_inf))
inf
>>> print(type(str(f_inf)))
<class 'str'>
``` 
###■ infの作成方法
&emsp;How to create inf

```   
>>> # ① float( )で作成
>>> 
>>> print(float("inf"))
inf
>>> 
>>> print(float("infinity"))
inf
>>> 
>>> print(float('INF'))
inf
>>> 
>>> print(float('INFinity'))
inf
>>> # ↑小文字・大文字混ざっていても問題なし
``` 
``` 
>>> # ② sysモジュールによる作成
>>> 
>>> import sys
>>> 
>>> f_inf_num = sys.float_info.max * 2
>>> 
>>> print(f_inf_num)
inf
``` 
```
>>> # ③ mathモジュールによる作成
>>> 
>>> import math
>>> 
>>> print(math.inf)
inf
>>> print(type(math.inf))
<class 'float'>
>>> 
>>> print(float("inf") == math.inf)
True
```

``` 
>>> # ④ Numpyによる作成
>>> 
>>> import numpy as np
>>> 
>>> print(np.inf)
inf
>>> 
>>> print(type(np.inf))
<class 'float'>
>>> 
>>> print(float("inf") == np.inf)
True
```
###■ infを含んだ演算
&emsp;Calculation with "inf"

```
>>> # 和
>>> 
>>> print(float("inf") + 50)
inf
>>> 
>>> print(float("inf") + float("inf"))
inf
```

```
>>> # 差
>>> 
>>> print(float("inf") - 50)
inf
>>> 
>>> print(float("inf") - float("inf"))
nan
>>> # ↑ nanは、非数を表す
>>> 
>>> print(type(float("inf") - float("inf")))
<class 'float'>
```
```
>>> # 積
>>> # infに0を掛ける → nan
>>> 
>>> print(float("inf") * 2)
inf
>>> 
>>> print(float("inf") * float("inf"))
inf
>>> print(float("inf") * 0)
nan
```

```
>>> # 商
>>> 
>>> # inf を inf で割る → nan
>>> # 0 を inf で割る → 0
>>> # 0 で割る → error
>>> 
>>> print(float("inf") / 2)
inf
>>> 
>>> print(float("inf") / float("inf"))
nan
>>> 
>>> print(float("inf") / 0)
Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    print(float("inf") / 0)
ZeroDivisionError: float division by zero
```
```
>>> # べき乗
>>> # inf の 0乗 → 0
>>> # 1 の inf乗 → 1
>>> # 0 の inf乗 → 0
>>> 
>>> print(float("inf") ** 2)
inf
>>> 
>>> print(float("inf") ** float("inf"))
inf
>>> 
>>> print(float("inf") ** 0)
1.0
>>> 
>>> print(0 ** float("inf"))
0.0
>>> print(2 ** float("inf"))
inf
>>> print(1 ** float("inf"))
1.0
```

随時に更新していきますので、<br>定期的な購読をよろしくお願いします。
I'll update my article at all times.
So, please subscribe my articles from now on.

本記事について、<br>何か要望等ありましたら、気軽にメッセージをください！
If you have some requests, please leave some messages! by You-Tarin
Python3 : dict配列をとあるキーでグループ化する

このような表形式のデータを、 `group_id` ごとに `name` でまとめたい場合です。

| group_id   | name                              |
|------------|-----------------------------------|
| monogatari | 化物語                             |
| monogatari | 傷物語                             |
| monogatari | 偽物語                             |
| monogatari | 猫物語                             |
| monogatari | 傾物語                             |
| monogatari | 花物語                             |
| monogatari | 囮物語                             |
| monogatari | 鬼物語                             |
| monogatari | 恋物語                             |
| monogatari | 憑物語                             |
| monogatari | 暦物語                             |
| monogatari | 終物語                             |
| monogatari | 続・終物語                         |
| toaru      | とある魔術の禁書目録                 |
| toaru      | 新約 とある魔術の禁書目録             |
| toaru      | とある魔術の禁書目録SP               |
| toaru      | とある科学の超電磁砲                 |
| toaru      | とある科学の超電磁砲 アストラル・バディ |

`itertools` の `groupby` と、`operator` の `itemgetter` を利用すれば1行で実現できます。

```python
from itertools import groupby
from operator import itemgetter

items = [
    {'group_id': 'monogatari', 'name': '化物語'},
    {'group_id': 'monogatari', 'name': '傷物語'},
    {'group_id': 'monogatari', 'name': '偽物語'},
    {'group_id': 'monogatari', 'name': '猫物語'},
    {'group_id': 'monogatari', 'name': '傾物語'},
    {'group_id': 'monogatari', 'name': '花物語'},
    {'group_id': 'monogatari', 'name': '囮物語'},
    {'group_id': 'monogatari', 'name': '鬼物語'},
    {'group_id': 'monogatari', 'name': '恋物語'},
    {'group_id': 'monogatari', 'name': '憑物語'},
    {'group_id': 'monogatari', 'name': '暦物語'},
    {'group_id': 'monogatari', 'name': '終物語'},
    {'group_id': 'monogatari', 'name': '続・終物語'},
    {'group_id': 'toaru',      'name': 'とある魔術の禁書目録'},
    {'group_id': 'toaru',      'name': '新約 とある魔術の禁書目録'},
    {'group_id': 'toaru',      'name': 'とある魔術の禁書目録SP'},
    {'group_id': 'toaru',      'name': 'とある科学の超電磁砲'},
    {'group_id': 'toaru',      'name': 'とある科学の超電磁砲 アストラル・バディ'},
]

lists = {g: [x['name'] for x in list(n)] for (g, n) in groupby(items, key=itemgetter('group_id'))}
```

`lists` には以下のようにデータが入ります。

```json
{
  "monogatari": [
    "化物語",
    "傷物語",
    "偽物語",
    "猫物語",
    "傾物語",
    "花物語",
    "囮物語",
    "鬼物語",
    "恋物語",
    "憑物語",
    "暦物語",
    "終物語",
    "続・終物語"
  ],
  "toaru": [
    "とある魔術の禁書目録",
    "新約 とある魔術の禁書目録",
    "とある魔術の禁書目録SP",
    "とある科学の超電磁砲",
    "とある科学の超電磁砲 アストラル・バディ"
  ]
}
```

注意点としては、 `items` はグループ化に使うキー（ここでは `group_id` ）でソートされている必要があります。
無料でできるPHPのWEBサイト公開（テスト用）

# はじめに
PHPで作ったサイトを割と手軽に公開できたので方法をメモ。

今回は無料の[XFREEサーバー](https://www.xfree.ne.jp/)を使いましたが、本格的に運用していく場合は有料プランのXserverとか使った方がいいと思います。

とりあえず作ってみて公開してみたいっていう場合に割と機能（PHP、MySQL対応）も充実していて無料だしお試しでやるにはいい感じだと思います。

# 環境
macOS High Sierra バージョン 10.13.2

# 登録方法
[このページ](https://template-party.com/manual/server1.html)に詳しい登録方法が記載されているので、ここを参考に登録します。

# ファイルアップ
登録が完了したらPHP・MySQLサーバーの利用を開始するから管理パネルにログインする。

下記のFTPアカウント設定画面を開く。

<img width="1021" alt="ftp" src="https://user-images.githubusercontent.com/34936885/53285605-cbcf4200-37a5-11e9-9cf5-77b6bd20daf1.png">

ファイルマネージャーでブラウザ上からファイルのアップもできますが、ここからだとファイルを1つずつしかアップできないので今回は[FileZilla](https://filezilla-project.org/)を利用してファイルをアップしました。

FileZiilaを起動し上記画面に表示されているホスト、ユーザー名、パスワードを入力し、クイック接続をクリック。初回は証明書の確認メッセージが表示されると思いますが、とりあえずOKをクリック。

<img width="1195" alt="fz" src="https://user-images.githubusercontent.com/34936885/53285588-975b8600-37a5-11e9-949f-062b7075f811.png">

これで接続が完了しFileZillaの右下の部分にアップしたいファイルをドラッグすればサーバーにファイルがアップできます。

ファイルをアップする前にすでにdefault_page.png、htaccess、index.htmlの3つのファイルがあると思いますがdefault_page.png、index.htmlは削除しましょう。htaccessはサーバーの設定ファイルなので残しておきます。

これでFTPアカウント設定画面のアカウント名のURLにアクセスすればサイトが表示されるはずです。

# MySQLの利用
<img width="1009" alt="db" src="https://user-images.githubusercontent.com/34936885/53285598-be19bc80-37a5-11e9-87ea-9c4100a70e3e.png">
## DB追加
MySQLの設定画面を開きMySQL追加タブでデータベース名を入力しデータベースを追加する。
## ユーザー追加
MySQLの設定画面を開きMySQLユーザ設定タブでユーザー名とパスワードを入力しユーザーを追加する。
## 権限設定
MySQLの設定画面を開きMySQL一覧タブで追加したデータベースが表示されているはずなのでそこに先ほどのユーザーを追加する。
## phpmyadminにログイン
MySQLの設定画面を開きphpmyadminタブをクリックすればユーザー名とパスワードを求められるので先ほど設定したものを入力しログイン。（めちゃくちゃレスポンスが悪いので注意）

これでMySQLを使えるようになります。
PHPでDBにアクセスする際はMySQL設定画面に表示されているデータベース名、MySQLホスト名、ユーザー名、ユーザーパスワードを設定してやればアクセスできるはずです。

# ローカルでの作業
ローカルで作業する場合は[MAMP](https://www.mamp.info/en/)を利用するとお手軽だと思います。こいつもMySQLが使えるので便利です。

アプリケーション/MAMP/htdocsのフォルダにファイルを置いてMAMPを起動すればローカル環境でサイトの確認ができます。
詳しくは割愛させていただきます。[この辺](https://techacademy.jp/magazine/5102)を参考にどうぞ。

# さいごに
無料でWebサイトを公開する方法を記載しましたが、本格的に運用していく場合は別サービスを利用することをお勧めします。SSL化などに（おそらく）対応していないので有料のXserverとかを利用する方がいいと思います。

勉強用やテスト用にとりあえず公開したい！！タブレットやスマホで確認したい！！ていう場合は非常に便利だと思います。

とりあえず無料だったのでXFREEサーバーを利用しましたが、Webサイト公開する際にオススメのサービスとかあったらぜひ教えて下さい。
覚えたいVim操作集

よく使うものや覚えたいもの書き出しつつチートシートにする
障害調査とか本当に少しだけ書き換えたい時など、vimerではない人用

# 数字何桁検索
/[0-9]\{桁数\}

# 文字列を含む行削除
:g/文字列/d

# 文字列を含まない行削除
:v/文字列/d

# ファイル内一括置換
: :%s/古い文字列/新しい文字列/g
(/が含まれる文字列を置換したい場合は/を;に置き換える)

# ウインドウを縦分割
:vs ファイル名

# ウインドウを横分割
:sp ファイル名

# 空の縦ウィンドウを開く 
:vnew

# 空の横ウィンドウを開く 
:new

# ファイル差分
:vert diffsplit ファイル名

# 矩形選択モード
ctrl + v

# 矩形選択->一括入力
ctrl + v, 範囲選択, shift + i, esc

# 一番上
g

# 一番下
shift + g

# 画面半分下
ctrl + d

# 画面半分上
ctrl + u

# 行ジャンプ
:数字

# 単語移動(前)
e

# 単語移動(後)
b

# コピペ
ctrl + vのあとに範囲指定
y
p

# 行カット
dd

# 1文字カット
x

# アンドゥ
u

# リドゥ
ctrl + r


### 参考URL
viコマンド（vimコマンド）一覧（検索・置換）
http://uguisu.skr.jp/Windows/vi.html
Visual Studio CodeとXdebugでPHPのデバッグ環境を構築する

いろいろとやり方があると思いますが、備忘のため書き留めておきます。

## 環境

* macOS Mojave
* brewをインストール済み

## PHPとXdebugをインストール

```bash
brew install php@7.2
pecl install xdebug
```

## php.ini設定

```bash
vim /usr/local/etc/php/7.2/php.ini
```

`php.ini` の先頭行付近を下記のように編集。
参考：https://xdebug.org/docs/all_settings

```plain
zend_extension="xdebug.so"
xdebug.remote_enable=1
xdebug.remote_autostart=1
[PHP]
```

## Visual Studio Codeの拡張機能「PHP Debug」のセットアップ

1. 拡張機能で `PHP Debug` をインストール
2. 左のサイドメニューからデバッグ（虫のマーク）を選んで、上部の歯車マークをクリック
3. `PHP` を選択
4. 下記のような設定ファイルが現れるので、適宜修正してください（そのままでもOK）

```plain
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000
    },
    {
      "name": "Launch currently open script",
      "type": "php",
      "request": "launch",
      "program": "${file}",
      "cwd": "${fileDirname}",
      "port": 9000
    }
  ]
}
```

## デバッグ実行

デバッグメニューにおいて、`Listen for XDebug`を選んだ状態で、緑の再生ボタンをクリック。
あとはブレイクポイントを設定後に、ブラウザからアクセスしたり、スクリプトを実行したりすれば、デバッグできます。
AWS Configの通知内容をLambdaで整形

# AWS Config概要

触れる機会がありましたので忘備録的に記載致します。

- AWSの各サービスの設定変更を検知
  作業者が複数いる状況やAWSリソースが多数ある場合でも管理者が設定変更を簡単に把握できる。

- AWSが準備したルールに準拠しているかを評価
  誤った設定を行った際に通知され把握できる。

■ 公式リンク
[公式ページ](https://aws.amazon.com/jp/config/)
[ブラックベルト](https://d1.awsstatic.com/webinars/jp/pdf/services/20160831-AWS_BlackBelt-CloudTrail-Config-public.pdf)

# 構築


## 構成
AWS Configから直でSNSだと件名が固定になってしまい、本文のjsonを見ないと何のメールか判らない為、
Lambdaを経由してメール通知します。Lambda連携の為にCloudWatch Eventsも出てきます。

![Config.png](https://qiita-image-store.s3.amazonaws.com/0/316662/f0630c70-0b38-3901-c07f-11595af45b28.png)


## AWS Config

■ 設定

| 設定項目 | 値 |
| --- | --- |
| 記録するリソースタイプ | グローバルリソース (AWS IAM リソースなど) を含める |
|Amazon S3 バケット|バケットの作成|
|バケット名|任意|
|Amazon SNS トピック|※チェックなし|
|AWS Config ロール|既存の AWS Config サービスにリンクされたロールを使用|

■ ルール
52項目から通知したいルールを選択
[AWS Config マネージドルールのリスト](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html)


## CloudWatch Events

###　設定変更検知

| 設定項目 | 値 |
| --- | --- |
|イベントソース|イベントパターン|
|サービス名|Config|
|イベントタイプ|Config Configuration Item Change|
|※1|Any message type|
|※2|Any resource type|
|※3|任意のリソース ID|

※1 選べるタイプが１つの為、anyを選択 
※2 通知のAWSサービスを選択したい場合に使用。
　　下記URLから監視対象のリソースタイプの値を入力することで通知内容を限定できる。
　　[AWS Config でサポートされている AWS リソースタイプとリソース関係](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/resource-config-reference.html)
※3 EC2でいうインスタンスIDを入力することで、通知内容をインスタンス単位で制限ができるはず
   　　☆未検証!

###　ルール準拠・非準拠検知

| 設定項目 | 値 |
| --- | --- |
|イベントソース|イベントパターン|
|サービス名|Config|
|イベントタイプ|Config Rules Compliance Change|
|※1|Any rule name|
|※2|Any resource type|
|※3|任意のリソース ID|

※1 Configのルール設定で検知対象を絞っている為、Any
※2 設定変更検知と同様
※3 設定変更検知と同様

## Lambda

タイトルがAWS Config起因かつ、設定変更検知なのかルール準拠・非準拠検知なのかを把握できるようにします。
本文はConfigが出力するjsonをそのまま載せるLambdaのコードになっています。

| 設定項目 | 値 |
| --- | --- |
|関数の作成|一から作成|
|名前|任意|
|ランタイム|Python3.6|
|ロール|1つ以上のテンプレートから|
|ロール名|任意|
|ポリシーテンプレート|Amazon SNS 発行ポリシー|
|トリガーの追加| CloudWatch Events|
|ルール|上記で作成したルール|



###　コード

``` 
   
import json   
import boto3
 
def lambda_handler(event, context):   
        type = event['detail-type']  
        Msg=json.dumps(event)
        sub = '[AWS Config]' + str(type)
            
        client = boto3.client('sns')
        response = client.publish(
            TopicArn='SNS TopicのArn',
            Message=text,
            MessageStructure='context',
            Subject=sub
        )  
        return

```

## SNS

トピックの設定で「メッセージの発行の許可」を「全員」にすることで
Lambdaからメールを送付できました。
もっと適切な設定があると思いますが、省略します。

# まとめ

ここまで完了したら監視対象の設定を変更し、メールが通知されるか確認してください。
CloudWatch EventsのターゲットにSNS Topicを追加することでLambda起因のトラブルか否かを
切り分けすることができます。
CloudWatch　LogsのLambdaを見るとエラー要因がわかったりします。

公式ドキュメントや調べた内容の継ぎ接ぎな内容なので、間違いがありましたら
ご指摘いただけると幸いです。