OmniAICreator/Qiita-1.07M huggingface dataset:
TeXをコンパイルするShellScriptの作成


## 作成動機
TeXで文書を書く必要があった。が、コンパイル毎にコマンドを打つのが面倒だったから

## 構造
<img width="366" alt="edf78e47.png" src="https://qiita-image-store.s3.amazonaws.com/0/199478/66f00e51-6660-f4f5-daaf-647da23d04d0.png">


### 概要説明
1. ファイル情報を取得
2. 以降texファイルの場合のみ実行
3. ディレクトリに移動
4. pdfファイルの作成
5. 作業を続行するか尋ねる
6. 4に戻る(無限ループ),または終了する

## コード

```bash
#!/bin/bash#

echo "texファイルをドラッグ&ドロップ"
read -p "filepath: " filepath

base=`basename ${filepath}`
dir=`dirname ${filepath}`
filename=${base%.*}
expanded=${base##*.}

if [ ${expanded} = "tex" ];then
    ad=`pwd`
    cd; cd ${dir}
    
    while :
    do
		echo "コンパイルを開始します";echo
		platex ${filename}.tex;echo;echo

		dvips ${filename}.dvi;echo;echo
		ps2pdf ${filename}.ps;
		echo "コンパイルが完了しました"
		open ${filename}.pdf

	
		read -p "終了する場合はqを入力してください" res
		if [ $res = q ];then
	  	  break
		fi
    done
    
    cd; cd ${ad}
    
else
    echo "error: texファイルではありません"
fi
```

### 説明

#### ファイル情報を取得する部分

- fileのpathを取得


```bash
read -p "filepath: " filepath
```

- texファイル部分とpath部分の取得


```bash
# ファイル名(hoge.tex)
base=`basename ${filepath}`
# path(/user/name/huga/)
dir=`dirname ${filepath}`
```

- ファイル名と拡張子の取得


```bash
# ファイル名
filename=${base%.*}
# 拡張子
expanded=${base##*.}
```

#### ディレクトリの移動部分


```bash
# 現在のディレクトリパスを保存
ad=`pwd`
＃texファイルのディレクトリに移動
cd;cd ${dir}
・
・
・
# もとのディレクトリに戻る
cd;cd ${ad}

```

#### 無限ループ部分

```bash
while:
do
	・
	・
	・
	# ユーザーから入力を受け付け
	read -p "終了する場合はqを入力してください" res
	# 入力内容が"q"ならループを抜ける
	if [ $res = q ];then
		break
	fi
done
```

#### コンパイル部分


```bash
	# texファイルからdviファイルの作成
	platex ${filename}.tex

	# dviファイルからpostScriptファイルの作成
	dvips ${filename}.dvi
	#psファイルからpdfファイルの作成
	ps2pdf ${filename}.ps
```
VM setup on headless KVM

目標：GUI が使えない手元 KVM に ubuntu 仮想マシンをセットアップしたい。X を飛ばすとかは無しで。

`xenial-server-cloudimg-amd64-disk1.img` をダウンロードする。このイメージの `cloud-init` では複数の DataSource が利用できる。イメージの中では次のように設定されている。

```yaml:/etc/cloud/cloud.cfg.d/90_dpkg.cfg
datasource_list: [ NoCloud, ConfigDrive, OpenNebula, DigitalOcean, Azure, AltCloud, OVF, MAAS, GCE, OpenStack, CloudSigma, SmartOS, Bigstep, Scaleway, AliYun, Ec2, CloudStack, None ]
```

手元の KVM で使う分には、一番最初の `NoCloud` が[簡単](http://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html)だと思う。

default_user である `ubuntu` のパスワードを有効化するには、次の NoCloud `user-data` を使うのが簡単。

```yaml:user-data
#cloud-config
ssh_pwauth: True
password: password
lock_passwd: False
```

新規にユーザを作るならこんな感じにすると簡単だろう。

```yaml:user-data
#cloud-config
users:
  - name: adminuser
    groups: admin
    plain_text_passwd: password
    lock_passwd: false
```

# インストール
実際に起動させるには、例えば次のようにする。

```bash
cp xenial-server-cloudimg-amd64-disk1.img /var/lib/libvirt/images/test.img
```

`cloud-init` で何が起こってるのかわからない時など、`root` でログインしたい場合は次のようにしてパスワードを設定できる。これはデバッグ時のみ。

```bash
virt-sysprep --root-password password:hogehoge -a /var/lib/libvirt/images/test.img
```

`NoCloud` 用の補助ディスクを作る。先ほどの `user-data` を使う。必ず `user-data` と `meta-data` の両方のファイルを用意してコマンドを実行する。user-data だけでは NG

```bash
touch meta-data
genisoimage -output /var/lib/libvirt/images/udata.iso -volid cidata \
  -joliet -rock user-data meta-data
```

libvirt 環境に登録する。

```bash
virt-install --virt-type kvm --name test --ram 2048 \
  --disk path=/var/lib/libvirt/images/test.img,size=16 \
  --disk path=/var/lib/libvirt/images/udata.iso,device=cdrom \
  --graphics none --console pty,target_type=serial --import --network network=default
```

初期設定が終わったら無効化しておくのも手。

```bash
touch /etc/cloud/cloud-init.disabled
```

# 補足

`virt-sysprep` で全部設定してしまえばいいような気もしますが、`cloud-init` でユーザ作成などもおこなっているので、いい感じに順番に実行するのが難しかったです。

もっといい方法があるかなぁ…？

`^]` は、CTRL を押しながら ] キーを押す。
【Swift4.1】lazyプロパティの使い所


# はじめに

Swiftを学び始めてしばらく経ちますが、
lazyプロパティをまだ上手く使いこなせていません。
そこで、具体的にどんなところで使うことが出来るのかをまとめてみました。


# 基礎

**参照された時に初めて初期値が設定されるプロパティ**

```swift:lazyなし
var defaultPrice = 100

class Item {
    var price: Int = defaultPrice
}

let item = Item()

defaultPrice = 200
print(item.price) // 100
```

```swift:lazyあり
var defaultPrice = 100

class Item {
    lazy var price: Int = defaultPrice
}

let item = Item()

defaultPrice = 200
print(item.price) // 200

defaultPrice = 300
print(item.price) // 200
```

ImplicitlyUnwrappedOptionalに似ているが、
lazyでは宣言時に値の初期値を決めておくことが出来る。


## 初期化タイミングに合わせて初期値を決定したい時

初期化時点で計算メソッドを呼び出したい時に使える。
該当プロパティのみのためであればクロージャでも代用可能。

```swift
var defaultPrice: Double = 100

class Item {
    // lazyがないとコンパイルエラー
    lazy var price: Double = applyTax(price: defaultPrice)

    func applyTax(price: Double) -> Double {
        return price * 1.08
    }
}

let item = Item()

print(item.price) // 108
```


## 複数のイニシャライザで呼び出していた処理を一箇所にしたい時

今まで適当に初期化してイニシャライザで設定していたのをまとめられる。

```swift
class CustomView: UIView {
	// Before : var subView = SubView()
    lazy var subView: SubView = setupSubView()

    override init(frame: CGRect) {
  		super.init(frame: frame)
  		// Before : 初期化時にSubView()してViewの設定をしていたメソッド
  		// Before : setupSubView()
	}

	required init?(coder aDecoder: NSCoder) {
  		super.init(coder: aDecoder)
  		// Before : 初期化時にSubView()してViewの設定をしていたメソッド
  		// Before : setupSubView()
	}

	private func setupSubView() -> SubView {
		let view = SubView()
		view.frame = CGRect(...)
  		return view
	}
}
```


## 特定のオブジェクトを生成する静的なメソッドを特定のタイミングでのみ呼び出したい時

ファクトリーメソッドを初期化時点で記述出来る。

```swift
class ViewController: UIViewController {
    lazy var actionButton: UIButton = ViewFactory.makeActionButton()

    func present(infoView: InfoView) {
        view.addSubview(infoView)
        infoView.frame = view.bounds.offsetBy(dx: 0, dy: view.bounds.height)
        infoView.present(animated: true)

        // ここで初めてActionButtonが生成される
        actionButton.center = view.center
        view.addSubview(actionButton)
    }
}
```


## 非オプショナルを求めるプロトコルのプロパティに後から値を入れたい時

参照時には値が初期化されるため、非オプショナルに対応出来る。

```swift
protocol ItemProtocol {
    var price: Double { get }
}

class Item: ItemProtocol {
    lazy var price: Double = getPrice()
    
    func getPrice() -> Double {
        return 100.0
    }
}

let item = Item()

print(item.price) // 100
```


# 注意

便利なlazyですが、
初期化タイミングが不明瞭なため思わぬバグを引き起こすことがあります。

私見ではありますが、
プロジェクト内での利用タイミングの統一やコメントでの補足等しておく必要はあるかと思います。


# 参考

http://hajihaji-lemon.com/smartphone/swift/lazy/
https://medium.com/@johnsundell/using-lazy-properties-in-swift-592c777e0052
http://www.ssktm.info/entry/2017/11/28/093046
https://www.slideshare.net/tomohirokumagai54/lazy-var-cocoakansai-cswift
MITM対策にSwift4でCertificate Pinningをやってみた

#はじめに
iOSアプリケーションの安全性を上げるために、MITM対策をCertificate Pinningをやってみました。


MITMやSSLとは？という方は下記のWikipediaを参考にしてください。
[MITM](https://ja.wikipedia.org/wiki/%E4%B8%AD%E9%96%93%E8%80%85%E6%94%BB%E6%92%83)　[SSL/TLS](https://ja.wikipedia.org/wiki/Transport_Layer_Security)

#環境
・Xcode 9.3
・Swift 4.1
・macOS 10.3

#実装
通信を行うクラスにURLSessionDelegateを継承してください。

継承したクラスに下記のurlSessionメソッドを追加してください。

``` swift
func urlSession(_ session: URLSession, didReceive challenge:URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
      let serverTrust = challenge.protectionSpace.serverTrust
      let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)

      //ドメイン名を確認するpoliciesにSSLをセットする
      let policies = NSMutableArray()
      policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
      SecTrustSetPolicies(serverTrust!, policies)
           
      //SSL証明書をチェックする
      var result: SecTrustResultType = SecTrustResultType(rawValue: 0)!
      SecTrustEvaluate(serverTrust!, &result)
      let isServerTrusted:Bool = result == SecTrustResultType.unspecified || result ==  SecTrustResultType.proceed
            
      //ローカルとリモートの証明書データを取得する
      let remoteCertificateData:NSData = SecCertificateCopyData(certificate!)
      //○○○に証明書ファイル名、□□□に型名を入れる
      let pathToCert = Bundle.main.path(forResource: "○○○", ofType: "□□□")

      let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
            
      if (isServerTrusted && remoteCertificateData.isEqual(to: localCertificate as Data)) {
          let credential:URLCredential = URLCredential(trust: serverTrust!)
           completionHandler(.useCredential, credential)
      } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
      }
}
```

これで基本的な実装は終了です。

後はこのようにすれば完成です。

```swift
  let configuration = URLSessionConfiguration.default
  let session = URLSession(configuration: configuration, delegate: self, delegateQueue:OperationQueue.main)
  var request = URLRequest(url:url)
  let task = session.dataTask(with: request) { data, response, error in
      //処理を書く
   }
```

実行確認はこちら等を参考に
[Charlesで他社アプリの通信を覗く](https://qiita.com/hiragram/items/195c7117fb6ebd50653e)


#参考
[Certificate pinning technique on iOS](https://medium.com/@andersongusmao/certificate-pinning-technique-on-ios-af0f0813e88)
【Ruby】[ ]またはnewを使った配列の生成方法まとめ

配列クラスの生成には、Arrayクラスのクラスメソッドである`[]`メソッドや`new`メソッドの他に、[配列式](https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html#array)と呼ばれる記法もあるのですが、今回は`[ ]`または`new`を使った方法についてまとめてみました。勘違いしているところなどありましたらご教授お願いします。

# [ ]を使った生成 - 配列リテラル
## 配列の生成（その1）

```
a = [1, 2, 3]
=> [1, 2, 3]
```
**コメント欄より追記 18/05/02**
上でArrayクラスのクラスメソッドの紹介と書いたのですが、こちらはクラスメソッドではなく、[配列リテラル](https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html)でした。失礼いたしました(_ _)

# [ ]を使った生成
## 配列の生成（その2）
[ ] の引数に要素を指定。

```
Array[1, 2, 3]
=> [1, 2, 3]
```
**コメント欄より追記 18/05/02**
この書き方は、Arrayのサブクラスのインスタンスを作成しやすくするためのもの。
詳しくは[Ruby2.5のリファレンス](https://docs.ruby-lang.org/ja/2.5.0/method/Array/s/=5b=5d.html)か、下記のコメント欄をご覧ください。

# newを使った生成
## 配列の生成（その3）
引数に配列の長さと、初期値を指定。

```
Array.new(2, 'hello')
=> ['hello', 'hello']
```

## 配列の生成（その4）
引数に配列を指定。
引数で渡された配列を複製する。

```
a = [1, 2, 3]
=> [1, 2, 3]

a.object_id
=> 70347435534940


arr = Array.new([1, 2, 3])
=> [1, 2, 3]

arr.object_id
=> 70347435491080
```

## 配列の生成（その5）
引数に配列の長さと、ブロックを指定。

```
Array.new(2){|i| i * 2}
=> [0, 2]
```
Win10のWSLでRuby on Railsの環境構築したやつ

Ruby触るの初めてで環境構築つまったのでメモ書き

WSLのディストリビューションはDebianにしました。
基本ホームディレクトリで作業してます。
##rbenvを入れる

とりあえずGit入れる
```sudo apt-get install git```

そしたらrbenvをクローン

```bash
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
git clone https://github.com/rkh/rbenv-update.git ~/.rbenv/plugins/rbenv-update
```
パスを通す

```bash
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile 
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile 
```
これでrbenvは入るはず

##Rubyを入れる
まずインストールできるRubyのバージョンのリストを確認する
rbenv周りでsudoとかつかうとディレクトリの権限周りで辛くなります。

```bash
rbenv install --list
```

確認したら入れたいバージョンを入れる
ここでは例として2.5.1を入れる

```bash
rbenv install 2.5.1
```
インストールされたバージョンのリストを確認

```bash
rbenv versions
```

使いたいRubyのバージョンを指定

```bash
rbenv global 2.5.1
```

使用するRubyのバージョンを確認

```bash
rbenv version
```

ちゃんと指定したバージョンが表示されればおｋ

##railsとか入れる

まぁまずBundlerを入れる

```bash
rbenv exec gem install bundler
#rbenv rehash は不要
```
nodejsが必要なので入れる

```bash
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
```

yarn入れる

```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn
```

npmも入れる

```bash
sudo apt-get install npm
```

railsを入れる

```bash
gem install rails
```


これでとりあえずrailsの環境構築はできるはず。
あとは適宜データベースの環境入れたり、必要に応じて必要なものをインストールしたりする。
例```rails webpacker:install```とか


ちなみにRubyMineでWSL上のRubyを指定して書いてます。

## 追記
rbenv rehashは不要になったとのご指摘がありました｡  
確かにそうですね｡この記事を書いた時点でも不要だったかもです｡
指摘ありがとうございます｡
scanfに注意

# scanf を利用してデータを入力する際の注意

迷える子羊さんから、プログラムがちゃんと動かないと相談されたので、それをメモとして記述しておく

## 課題: 整数の入力値を2つ受け取り、処理Aを実行して結果を出力する

```c
#include <stdio.h>
int main(){
    int a, b;
    scanf("%d, %d", &a, &b);
    /* Procedure A */
}
```

## 発生した問題: Aの処理結果が期待しているものと違う

### 実行手順
```console
$ gcc test.c
$ ./a.out
1 2
<期待と異なる結果>
```
原因は入力データのフォーマットがscanfが要求しているものと違うからなのだけれど、ちょっと見ただけではわかりにくい
### 正しい入力データの場合
```console
$ ./a.out
1, 2
<期待通りの結果>
```

カンマ","が入力データに有るか無いかで結果が異なる
異なるのは当然として、scanf はフォーマット文字列と入力をどのように処理しているのか？

scanfの説明として[IBMのページ](https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/rtref/scanf.htm)を参照すると次のように記述されている

>The scanf() function reads format-string from left to right. Characters outside of format specifications are expected to match the sequence of characters in stdin; the matched characters in stdin are scanned but not stored. If a character in stdin conflicts with format-string, scanf() ends. The conflicting character is left in stdin as if it had not been read.

最後の行に注目!!
*If a character in stdin conflicts with format-string, scanf() ends.* **The conflicting character is left in stdin as if it had not been read.**

つまりscarfの文字列が"%d, %d"で入力が "1 2"の場合には

- **a** に"1"が入る
- "2"以降はカンマが一致しないので読み込まれない
  - 変数 **b** は不定
    - エラーも発生しない

そして、出力結果が誤ったものとなってしまう

この事を確かめるために、初期化前の値とscanf後の値を表示してみる

###プログラムを変更
```c
#include <stdio.h>
int main(){
    int a, b;
    printf("Before scanf: %d, %d\n", a, b);
    scanf("%d, %d", &a, &b);
    printf("After scanf: %d, %d\n", a, b);
    /* Procedure A */
}
```

### プログラムを再コンパイルして誤ったフォーマットでデータを入力

```console
$ gcc test.c
$ ./a.out
Before scanf: 137630162, 32766
1 2
After scanf: 1, 32766
<期待と異なる結果>
```

変数 **b** はscanf実行前の値がそのまま

### 正しいフォーマットでデータを入力

```console
$ ./a.out
Before scanf: 237597138, 32766
1, 2
After scanf: 1, 2
<期待通りの結果>
```

scanf はCの初学者には辛い仕様となっている

だから、何かの防衛策を取る方が良いだろう

- scanf で取得した値をユーザーに対するフィードバックとしてprintfで表示する
- 変数を絶対に利用しない数値で初期化しておいて、scanf後に変数が所定の値となっているか判定する
    - 例えば 正の整数が必要な変数を負の値で初期化しておく
- scanf の戻り値が適切な値(想定する入力データ数)となっているか確認する: [shiracamus](https://qiita.com/shiracamus)さんのアドバイス
    - 適切な値が読み取れるまでscanf をループする
    - ただし、bufferをクリアしないとループから抜けられないという事態が生じる場合がある（次のscanfで条件を満たさなかった位置から読み取りが開始されるので。)
    - bufferをクリアの例:　char c; while((c = getchar()) != '\n' && c != EOF);
    - 初心者向けではないかも

> scanf()の戻り値について
>> The scanf() function returns the number of fields that were successfully converted and assigned. The return value does not include fields that were read but not assigned.
>>The return value is EOF for an attempt to read at end-of-file if no conversion was performed. A return value of 0 means that no fields were assigned.

という事で、*scanf* を利用の際は慎重に:smile:
特定のタイトルが付いているウィンドウを閉じる

#概要
「Hey, Scripting Guy!」の確認。

[Scripting Guy さん、特定のタイトルが付いているコマンド ウィンドウを閉じる方法はありますか][1]
[Microsoft Word を使用した独自のタスク マネージャの構築 (うそでしょ。いいえ、本当です)][2]

タイトルと完全一致しなくても、最初が一致していたら消せるようです。
.htaのテスト用簡易アプリ、Word文書で消せることを確認しています。

#コード
以下をテキストエディタにコピペし、"close_target.vbs"として保存する。
テスト用簡易アプリを起動した後に実行する。
.vbs実行後、3秒程度あとにプロセスが閉じられる。

```vb:close_target.vbs
Set objWord = CreateObject("Word.Application") 
Set colTasks = objWord.Tasks 
 
If colTasks.Exists("消したいターゲット") Then 
    colTasks("消したいターゲット").Close 
End If 
objWord.Quit
```
```colTasks("消したいターゲット").Visible = False```にすると、そのままでウィンドウだけ見えない状態になります。


##テスト用簡易アプリ
以下をテキストエディタにコピペし、"target.hta"として保存し、実行する。

```html:target.hta
<html>
<head>
<title>消したいターゲットです。</title>
</head>
<body>
これを消します。
</body>
</html>
```

#備考
WMIやその他スクリプト関連オブジェクトにできないのに、なんでWordでできるようにしているのかよくわかりませんが・・・

[Microsoft Word を使用した独自のタスク マネージャの構築 (うそでしょ。いいえ、本当です)][2]
> Microsoft Word の Application オブジェクトには、コンピュータで実行中のすべてのプロセスのコレクションを返す Tasks プロパティが含まれています。このプロパティと Win32_Process の違いは、Tasks コレクションが、実行可能ファイル名ではなく、プロセスのフレンドリ名を返すことです。これによって、次のような情報を取得できます。

#参考
[Scripting Guy さん、特定のタイトルが付いているコマンド ウィンドウを閉じる方法はありますか][1]
[Microsoft Word を使用した独自のタスク マネージャの構築 (うそでしょ。いいえ、本当です)][2]

[1]:https://gallery.technet.microsoft.com/scriptcenter/34192ec6-aace-4cc5-b267-23708d5067db
[2]:https://gallery.technet.microsoft.com/office/29bde7e6-cd56-4925-8918-53295f15843d
PythonとK-meansを使ったFizzbuzz

誰かがやっていそうだと思っていたら、意外にもやっていなかったので、やってみる。

#環境
* Anakonda3
* JupyterNoteBook5.0.0

#コード
```python:FizzBuzz+with+KMeans.py
import numpy as np
from sklearn.cluster import KMeans
result=KMeans(n_clusters=4,n_jobs=-1).fit_predict(np.array([np.tile([0,0,1],30),np.tile([0,0,0,0,1],18)]).T)
print(['FizzBuzz' if t == result[14] else 'Fizz' if t == result[2] else 'Buzz' if t == result[4] else 0 for t in result])
```

#解説
###モジュールのインポート  
```python
import numpy as np
from sklearn.cluster import KMeans
```
K-means法で機械学習を行うために`skleran.cluster`を、行列を扱うために`numpy`をインポートしている。

###データの作成・準備
```python
palameter = 6
array_A=np.tile([0,0,1],palameter*5)
array_B=np.tile([0,0,0,0,1],palameter*3)
```
１～９０の範囲において、以下の配列を作成した。
* ３の倍数[Fizz]にフラグを立てた配列をarray_A
* ５の倍数[Buzz]にフラグを立てた配列をarray_B

配列のインデックスを利用しているため、実際の値から－１されていることに注意しておく。

###準備
```python
array_X=np.array([array_A,array_B])
array_Y=array_X.T
```
先ほど作成したデータを結合してから転置、そうしないとK-meansが行えない。

###実行
```python
array_V=KMeans(n_clusters=4,n_jobs=-1).fit_predict(array_Y) #KMeansを使用して４つのクラスターに分けた結果をarray_Vに代入。
```
４つのクラスター( [FizzBuzz] / [Fizz] / [Buzz] / [Other] )に分かれる。

###出力
```python
for temp in array_V:
    if temp == array_V[2]: print('Fizz')
    elif temp == array_V[4]: print('Buzz')
    elif temp == array_V[14]: print('FizzBuzz')
    else: print(0)
```
* ３（１５の倍数を除く）
* ５の倍数（１５の倍数を除く）
* １５の倍数
* それ以外

に事前に分かれているため、特に順番を気にする必要はない。

#リンク
###参考
[scikit-learn でクラスタ分析 (K-means 法)](https://pythondatascience.plavox.info/scikit-learn/%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E5%88%86%E6%9E%90-k-means)
[numpyの使い方](https://qiita.com/jyori112/items/a15658d1dd17c421e1e2)
[NumPy入門 サンプル集](https://algorithm.joho.info/programming/python/numpy-sample-code/)
[Pythonの数値計算ライブラリ NumPy入門](http://rest-term.com/archives/2999/)
###ソース
[github](https://github.com/Polaris1080/FizzBuzz-with-KMeans)
Jenkins

現場でJenkinsを使うので調べたまとめ
~~wikiはわけわからんのでググりました~~

#Jenkins(ジェンキンス)
- Javaで書かれたオープンソース = 無償
- ソフトウェアのビルド→検証→サーバインストールの一連を自動化
- 継続的インテグレーション（CI）ツール
- サーバへインストールして利用
- ジョブ単位の管理（多ジョブ↔︎1Jenkinsや、多プロジェクト↔︎1Jenkinsが可)
- プラグインで機能拡張（インストールでチョチョイと導入可）

…継続的・・何だって？

####**継続的インテグレーション（CI）ツール　とは**
- 継続的にテストやビルドなどの作業を繰り返すこと( = CI )を支援するツール
- 特定のイベントをトリガーにしてあらかじめ指定しておいた処理を実行する機能付き
- サーバへインストールするものや、GitやGitHubと連携するクラウド型、XcodeやVisualStudioなどの開発環境と連携するものなどがある。

ﾌﾑﾌﾑ。
つまりはテストツールってことかな。

インストールや設定は、参考リンクを参照すると良さそう。
とりあえずここまで。

>*参考*
Wikipedia
https://ja.wikipedia.org/wiki/Jenkins
Jenkinsを使った自動テスト環境を作る（前編）
https://knowledge.sakura.ad.jp/5293/
Macで作ったC++プログラムをVisual StudioとCMakeを使ってwindowsでビルドする

macで作ったC++プログラムをwindowsのvisual studioでビルドする際に色々手間取ったので備忘録
# visual studioでCMakeを通してビルドする方法

1. cmakeをダウンロード(https://cmake.org/download/   のBinary distributionsのWindows win64-x64 Installerを選択)
2. cmakeのpathを通しておく。（インストール途中で通しておくか聞かれるチェックボックスがあるのでそれにチェックするか、自分でC:\Program Files\CMake\binにpathを通す）
1. visual studio(visual studio community 2017)をダウンロードする。
1. インストール作業の途中で何の開発環境を入れるか選択する画面が出てくるので「C++によるデスクトップ開発」を選択。
![visual studio セットアップ.png](https://qiita-image-store.s3.amazonaws.com/0/245217/da15437c-90e2-5f68-2d41-dedc3511912a.png)
1. インストールが終わったら同時にインストールされているはずの「開発者コマンドプロンプト for VS.2017」を開く。
1. ビルドしたいプロジェクトのCMakeLists.txtのあるディレクトリに移動
2. 「mkdir build」をしてCMakeLists.txtと並列に新しいディレクトリ作成（ディレクトリ名はbuildじゃなくてもいいけどここではbuildにしておく）
3. 「cd build」で作った新しいディレクトリに移動
4. 「cmake ..」でcmake
5. buildファイルの中に「.sln」拡張子のものがあると思うのでそれをダブルクリックするとvisual studioで開ける

# ビルドしたときに出てくる各エラーの対処
## 「定数が2行目に続いています」や「構文エラー'in'」「プリプロセッサ ディレクティブのシャープ記号 (#) の前に、空白文字以外の文字があります。」など
- 原因 : macとwindows(visual studio?)の文字コードの違い
- 対処方法

1. エラーをダブルクリックでエラーの出ているファイルを開く
2. 画面上のタブの「ファイル」→「名前を付けて〇〇（ファイル名）を保存」→「上書き保存」ボタンの右にある▼を押して「エンコード付きで保存」を選択（既に存在するが上書き保存しますか？的なことを聞かれるのでOKを押す）
3. デフォルトでエンコードが【日本語（シフトJIS）】になっていた場合→エンコードは変えず、「行の終わり」を「Unix(LF)」に変更。その他の場合→「エンコード」を「Unicode(UTF-8 シグネチャつき)」に、「行の終わり」を「Unicode 行区切り記号(LS)」に変更

## sys/time.hが無いといわれる
- 対処方法
  - sys/time.h →time.hに書き換え
  
## arpa/inet.hが無いといわれる
- 対処方法
  - arpa/inet.h →winsock2.hに書き換え

## fftw3.hが無いといわれる
- 対処方法
  - http://blog.livedoor.jp/locked_empty_shell/archives/8968994.html 

## boost/〇〇が無いといわれる
- 対処方法
  - 画面右のプロジェクトが並んでいるところで、対象のプロジェクトの上で右クリック→「NuGetパッケージの管理」→boostを検索して取得
  
# 参考にしたサイト
- http://blog.livedoor.jp/locked_empty_shell/archives/8968994.html
 
- https://stackoverflow.com/questions/20543940/where-do-i-get-arpa-inet-h?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
 
- http://none53.hatenablog.com/entry/2017/04/29/QT_%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB_C2001_%E5%AE%9A%E6%95%B0%E3%81%8C_2_%E8%A1%8C%E7%9B%AE%E3%81%AB%E7%B6%9A%E3%81%84%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
- http://nekko1119.hatenablog.com/entry/2015/05/21/022037
アリババクラウドのVPCって？

# はじめに
今回はAlibabaクラウドの
Virtual Private Cloud （VPC）
に触れます。

# AlibabaクラウドのVPCとは
他のクラウドサービスと同じような感じの
仮想プライベートクラウドではありますが
アーキテクチャをみてみるととても面白いです。

## 論理アーキテクチャ

![](http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/pic/34221/intl_en/1505790128795/%E6%9E%B6%E6%9E%84%E5%9B%BE.png)

[技術的な原理 - VPC プロダクト紹介| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/doc-detail/34221.htm?spm=a21mg.p38356.b99.5.68b92dae8eaOWq)

こちらをもうすこし深掘りしてみます。

[VPCとは - VPC プロダクト紹介| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/doc-detail/34217.htm?spm=a21mg.p38356.b99.4.4f3c1312WNvYJH)

### Cider
作成するときは、拡張できるように
大きいレンジを選ぶようにこころがけましょう。

|CIDRブロック|使用可能な IP アドレスの数|
|:---|:---|:---|
|192.168.0.0/16|65,532|
|172.16.0.0/12|1,048,572|
|10.0.0.0/8|16,777,212|

### VSwitch
VPCに割り当てたIPレンジをサブネットに分ける(セグメント化)ものになります。

例えば、VPCを10.0.0.0/8にしたら
ECSを10.0.0.0/24, 10.0.1.0/24
RDSを10.0.2.0/24
のように分けるためものになります。

> VSwitch は、VPC の基本的なネットワークデバイスであり、異なるクラウド製品インスタンスを接続するために使用されます。VPC を作成した後、VSwitchesを作成して、仮想プライベートネットワークをさらに 1 つまたは複数のサブネットにセグメント化することができます。VPC 内の VS スイッチは相互接続されています。したがって、サービスの可用性を向上させるために、異なるゾーンの異なる VS スイッチに異なるアプリケーションを導入することができます。

### VRouter
一般的なネットワークのルートテーブルの設定を行います。

ユースケースとしては、
[VRouterとルートエントリ](https://jp.alibabacloud.com/help/doc-detail/49002.htm?spm=a21mg.p38356.a3.1.18802499LppmtT)

をご参考ください。
ここはまた別の機会に、詳しくお話しします。

> VRouter は VPC のハブです。VPC の重要なコンポーネントとして、VPC 内の VS スイッチを接続し、VPC と他のネットワークを接続するゲートウェイとして機能します。VPCを正常に作成すると、ルートテーブルに関連付けられた VRouter が自動的に作成されます。詳細は、Routes を参照してください。

# VPC対応のものは？
[VPC ネットワークタイプへの切替え - FAQ| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/faq-detail/38742.htm?spm=a21mg.p38356.b99.159.7cfe280ctK1SoP)
を読みますと、

- ECS(仮想クラウドサーバー)
- RDS(リレーショナルデータベースサービス)
- SLB(サーバーロードバランシング)

となります。

VPC対応のものは
アカウントの作成時期によって変わります。
**現在〜2017 年 2 月 15 日 13:00(日本時間)時点以前**
にアカウントを作成しましたので
**VPCのみ選択可能**
となります。


> Q： VPC ネットワークしか選択できなくなることで、プロダクトの使用方法に影響しますか。たとえば、他のプロダクトとの通信に影響するのでしょうか。
> A： ほぼ影響はありません。ほとんどの Alibaba Cloud プロダクトは既に VPC に対応しており、デフォルトのネットワークタイプの切り替えを開始したリージョンでは、すべてのプロダクトについて VPC 対応実施しております。

_クラシックネットワーク_ を使う機会がなくなっていきますので、今稼働させている人たちは切り替えていく計画が必要になるかもしれませんね。

# 設計でこまったら
こちらのドキュメントを読んで、ご自身の作成したい環境と照らし合わせて進めてみるとよいと思います。

- [ネットワーク環境の設計 - ベストプラクティス| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/doc-detail/54095.htm?spm=a21mg.o282931.b99.12.2f3649a8MGabh4#vswith)
- [適用シナリオ - VPC プロダクト紹介| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/faq-detail/45289.htm?spm=a21mg.p38356.b99.7.6d8d4f25stRP4o)

# まとめ
AlibabaクラウドのVPCは複雑なことを覚えることはなく、柔軟なネットワーク設計ができます。
その他のプロダクトもVPC対応しているようです。
グローバルなネットワーク上のサービス(プロダクト)しかない
クラウドサービスではないものもありますから
Alibabaクラウドはお客様のビジネス上で可能性を広げることができると考えられます。

# ちょっと覚えておきたいこと
管理コンソールで
_VPNを選ぶと東京にはないので_
リージョンが **青島** に変わります。

UI/UXの問題ですが、そのまま作ろうとすると
私は日本のリソースが見れなかったので
ご注意ください。
クロスサイトスクリプティングってなんだ

#魔法の言葉：クロスサイトスクリプティング
「クロスサイトのテストやって」との上司指示。
「承知しました！」・・・知らんけど。

ってことで、まとめサイトをググってみた。

##クロスサイトスクリプティング　とは
- セキュリティホールの一種
- HTTPレスポンスに埋め込まれたJavascriptやタグにより、ブラウザ側に誤動作を行わせる
- 略称：XSS

##具体例
- サイト利用者のCookie情報や入力情報が盗まれる

##ブラウザ仕様の注意点
- IEのデフォルト設定では拡張子ではなく、ファイルの内容によってファイルタイプを決定する。HTTPレスポンスのContent-Typeがimage/bmpであり、かつ拡張子がbmpであっても、ファイルの内容がHTMLであれば、HTMLと判断し、スクリプトが実行される。

##対策
- スクリプトを埋め込む必要がない箇所には、登録自体を禁止、または受け渡しを禁止する
- タグを無効化してから表示する
- aタグのリンクに入力データを使用したい場合、URLを絶対パスで記述する
- スクリプトのコード内には入力データをなるべく使用しない
- TMLで特別な意味を持つデータである「<」「>」「"」「'」「&」をそれぞれ、「<」「>」「"」「'」「&」に変換する
- IEはファイルアップロードが可能なアプリケーションの場合、ファイルの内容にHTMLタグが含まれていないことなどアップロードしても安全なファイルであことを確認する仕様にする

##テストをする前に
###何が不具合と認識されるのか調べる
サイトポリシーを参照して、何が不具合に当たるのかを確認する。
 - 例1. 入力OKだが表示は無効
 - 例2. 入力自体が禁止
 - 例3. 機能的にHTMLは入力OK

##テスト方法・其の１
*手段 1*
1. URLパラメータに、スクリプトを指定してアクセスしてみる
2. スクリプトが無効化されているか確認する

*手段 2*
1. 入力ホーム欄にスクリプトを入力して処理してみる
（例えば\<ahref=’http://attack’>attack<\/a>と入力して登録）
2. 入力内容を表示するページへ遷移し、スクリプトが無効化されているか確認する。
（例えば"attack"がリンク表示されていれば　NG)

##テストデータ例・其の１
```html
<!-- シングルクォートを利用したケース -->
　　　>>'<script>alert('Test')</script>

<!-- ダブルクォートを利用したケース -->
  >"><script>alert("Test")</script>

<!-- IMGタグのsrc属性にJavascriptを利用したケース -->
  >"><img src="javascript:alert('Test')">

<!-- IE限定でstyle属性を利用したケース -->
  " style = "background:url(javascript:alert('Test'))" OA="

<!-- Javascriptに入力データを動的に埋め込むケース -->
  '+ alert('Test') +'
```

##テスト方法・其の二
Hiddenフィールドやセレクトボッックス、ラジオボタンの脆弱性チェック
**→　HTTPリクエストを変更できるプロキシを利用**

1. ブラウザのプロキシ設定で以下を設定<br>
・ プロキシサーバ：localhost<br>
・ ポート番号：8080
2. HTTP Proxyが転送するHTTPリクエスト／レスポンス処理方法を「Manual」に設定<br>
 →　受け取ったHTTPリクエストをHTTP　Proxyで受け、内容を変更してサーバへ転送が可能になる
3. 受け取ったリクエスト／レスポンスを変更して送信<br>
 ・　入力するパラメータ値はテスト其の１を参照
 
> 参考
https://japan.zdnet.com/article/20360061/2/
wxPythonを使ってみる (2)

こんにちは．これからwxPythonを使ってみる(2)について始めたいと思います．
対象や動作環境などのはじめに必要な情報は[wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f) と同じになります．
また，今回の内容は[wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f) の続きとなります．是非読んで見てください．

## wx.Frameの基礎知識

前回では，wx.Frameについて少しさわれましたが，wx.Frameはアプリケーションの最上位ウィンドウとなる存在です．
wxPythonでは，基本的にすべてのウィジェットは親ウィジェットを指定してインスタンス化を行いますが，wx.Frameとwx.Dialogのみ例外となっています．
普通は，wx.Frameもしくはwx.Frameのサブクラスを用います．

### 「pos」を利用した表示位置設定

wx.Frameにおける表示位置がX軸とY軸を用いた座標で設定します．ディスプレイの左上隅をX=0,Y=0として開始点とし，X軸とY軸を調整します．wx.Pointというクラスを使って表現しまうす．

```python3:window_display04.py
import wx
app = wx.App()
coordinate = wx.Point(10,50)
frame = wx.Frame(None, -1, 'Hello,World!',size=(500,500),pos=coordinate)
frame.Show()
app.MainLoop()
```
サンプルコードを実行しますと，前回のwindow_display01.pyと変わらないウィンドウが表示しますが，ディスプレイ上で表示される位置が変わります．X=10（左から10）,Y=50(上から50)で設定を行いました結果は下の図となります．

<img width="523" alt="スクリーンショット 2018-04-12 11.23.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/179248/390e365f-cd7b-bc6e-dc91-3112b0791cf4.png">

また，サンプルコードの3行目を簡略化して，4行目の中に入れることが可能です．
```frame = wx.Frame(None, -1, 'Hello,World!',size=(500,500),pos=(10,50))```

### 「size」を利用した初期サイズ設定

wx．Sizeクラスを利用してサイズ設定を行います．実際サンプルコード01から04は毎回sizeを利用しています．
これの利用方法とwx.Pointとかなり似ています．それではもう一度wx.Sizeの利用方法を確認して見ます．

```python3:window_display05.py
import wx
app = wx.App()
window_size = wx.Size(400,100)
frame = wx.Frame(None, -1, 'Hello,World!',size=window_size,pos=(10,50))
frame.Show()
app.MainLoop()
```
サンプルコードを実行しますと，w=400（幅400）,h=100(高さ100)で設定を行いました結果は下の図となります．

<img width="410" alt="スクリーンショット 2018-04-12 11.33.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/179248/26e65e2d-604a-4dc5-96a9-f7fa84640fd9.png">

また，サンプルコードの3行目を簡略化して，4行目の中に入れることが可能です．
```frame = wx.Frame(None, -1, 'Hello,World!',size=(400,100),pos=(10,50))```

wz,Sizeもwz.Pointと同様，明示的にインスタンス化することなく設定できるので，数値を格納したタプルを渡すことで自動的にwx.Sizeが生成されます．

今回のwxPythonを使ってみる(２)は以上で終わります．
読んでいただいてありがとうございます．
また今度で会いましょ！

---
### 「wxpythonを使ってみる」目次
* [wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f)
StackBlitz その後 - Angula CLI リポジトリをダイレクトに実行

##　StackBlitz その後

前回の記事 [StackBlitz で Angular のオンラインデモ環境を爆速で用意する](https://qiita.com/tkiryu/items/46f64a09f23bed248e12) からしばらく経ちましたが、StackBlitz は着々と進化を続けています。

最近いろいろなところで目にするようになってきました。なんと　Angular Material のサイトでも使われています。今後も様々なところへ普及していくだろうと思っています。

## 新機能
少し前に追加された機能で **StackBlitz で　Angula CLI リポジトリをダイレクトに実行** できるようになりました。

何を言っているかというと、

``` :GitHub上のURL
https://github.com/{GH_USERNAME}/{REPO_NAME}
```
というリポジトリがあった場合に、URL を
　　1.`github.com` から　`.com` を削除し `github`　とし、
　　2.ドメイン部分に `stackblitz.com` を挿入する。

``` :StackBlitzで実行するためのURL
https://stackblitz.com/github/{GH_USERNAME}/{REPO_NAME}
```
と変更してアクセスすると、直接　StackBlitz 上で　Angular CLI プロジェクトが実行できるようになるということです！


## 実際にやってみる

1.　Github に移動
現在、自分の GitHub 上には Angular で作った ToDo アプリがあるので、ブラウザでアクセスします。
https://github.com/tkiryu/todo-app-complete

![image.png](https://qiita-image-store.s3.amazonaws.com/0/70618/7ce9e075-3ece-5721-3a9b-37f765b0fc9f.png)

2.　URLを変更
さきほどの手順にしたがって URL を変更します。
https://stackblitz.com/github/tkiryu/todo-app-complete
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70618/18e99012-1860-4ea5-ca42-6bab360331b1.png)
3. 変更後の URL に移動
右ペインに実行結果が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70618/89a6b0b3-7a8d-421d-b8cf-33dd606070b4.png)

## デモとして見せる、共有するのに最適
このように GitHub 上のリポジトリをダイレクトにブラウザ上で実行できるので、とても簡単にデモを見せることができます。URLを送れば、共有も簡単です。ブラウザ上で実行されるので、共有相手先の環境を一切気にする必要がないのも嬉しいですね。共有された側は、ブラウザ右上の `FORK` ボタンで簡自分のプロジェクトとしてフォークすることができます。これまた簡単ですね。

この機能がローンチされてからというもの、頻繁に利用しています。GitHub　上にプロジェクトをお持ちの方はぜひ試してみてください。

##　参照
StackBlitz のファウンダー Eric Simons 氏によるポスト [Run Angular CLI repos directly in your browser](https://blog.angular.io/run-angular-cli-repos-directly-in-your-browser-41332fd80901)　をあわせてチェックしてみてください。
調査系のIPアドレス

ShodanとShadowserverの一覧。蜂蜜壺にきたIPアドレスなので、全部ではありません。

#Shodan
```shodan.ip
185.163.109.66	goldfish.census.shodan.io
198.20.69.74	census1.shodan.io
198.20.69.98	census2.shodan.io
198.20.87.98	border.census.shodan.io
198.20.99.130	census4.shodan.io
198.20.70.114	census3.shodan.io
66.240.192.138	census8.shodan.io
66.240.205.34	malware-hunter.census.shodan.io
66.240.219.146	burger.census.shodan.io
66.240.236.119	census6.shodan.io
71.6.135.131	census7.shodan.io
71.6.146.185	pirate.census.shodan.io
71.6.146.186	inspire.census.shodan.io
71.6.158.166	ninja.census.shodan.io
71.6.165.200	census12.shodan.io
71.6.167.142	census9.shodan.io
80.82.77.139	dojo.census.shodan.io
80.82.77.33	sky.census.shodan.io
82.221.105.6	census10.shodan.io
82.221.105.7	census11.shodan.io
89.248.167.131	mason.census.shodan.io
89.248.172.16	house.census.shodan.io
93.120.27.62	census5.shodan.io
93.174.95.106	battery.census.shodan.io
94.102.49.190	flower.census.shodan.io
94.102.49.193	cloud.census.shodan.io
```

#Shadowserver
```Shadowserver.ip
184.105.139.67	scan-01.shadowserver.org.
184.105.139.68	scan-02.shadowserver.org.
184.105.139.69	scan-03.shadowserver.org.
184.105.139.70  scan-04.shadowserver.org.
184.105.247.194	scan-13.shadowserver.org.
184.105.247.195	scan-14.shadowserver.org.
184.105.247.196	scan-15.shadowserver.org.
184.105.247.252	scan-15n.shadowserver.org.
216.218.206.66	scan-05.shadowserver.org.
216.218.206.67	scan-06.shadowserver.org.
216.218.206.68	scan-07.shadowserver.org.
216.218.206.69	scan-08.shadowserver.org.
74.82.47.2	scan-09.shadowserver.org.
74.82.47.3	scan-10.shadowserver.org.
74.82.47.4	scan-11.shadowserver.org.
74.82.47.5	scan-12.shadowserver.org.
```
Wake-on-LAN のシェルスクリプト

Linux から、wol するときのシェルスクリプト　
自分用の備忘です。

```shell

#!/bin/sh

#  ＰＣ（サーバ）の説明
if [ $1 = "数字とか、ＰＣ，サーバ名" ]; then 
wakeonlan ＭＡＣアドレス
exit
fi
```
MacのComposerでタイムアウトになるのを解決。

Macのcomposerを使おうとしたらタイムアウトのエラーになった。
家のネット環境がwimax2になってからのエラー。

### エラー内容
- composerを使おうとしたら以下のエラーが出た。

```php
% composer require google/apiclient:^2.0

The "https://packagist.org/packages.json" file could not be downloaded: failed to open stream: Operation timed out
Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info
The "https://packagist.org/packages.json" file could not be downloaded: failed to open stream: Operation timed out
https://packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date

                                                                                                                                                                                              
  [Composer\Downloader\TransportException]                                                                                                                                                    
  The "https://packagist.org/p/google/apiclient%24cb2b69d70145ea262e3c394dd495e52ba16b27e3c157ac185d1c4777ba34f39b.json" file could not be downloaded: failed to open stream: Operation time  
  d out 
```

- composer自身のアップデートしようとしても同様のエラーが出た。

```php

% composer self-update

The "https://getcomposer.org/versions" file could not be downloaded: failed to open stream: Operation timed out
Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info

                                                                                                                   
  [Composer\Downloader\TransportException]                                                                         
  The "https://getcomposer.org/versions" file could not be downloaded: failed to open stream: Operation timed out  
                                                                                                                   
```

### networksetupコマンドで解決

- Wi-FiのIPV6をオフにして自動に設定し直す

```
% networksetup -setv6off Wi-Fi
% networksetup -setv6automatic Wi-Fi    
```

- 使えるようになった。

```php5

% composer self-update                
Updating to version 1.6.4 (stable channel).
   Downloading (100%)         
Use composer self-update --rollback to return to version 1.6.3

```

### wifiの状態確認コマンド

```
%  networksetup -getinfo Wi-Fi
DHCP Configuration
IP address: 192.168.●●●.●●●
Subnet mask: 255.255.255.0
Router: 192.168.100.1
Client ID: 
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: ●●:●●:●●:●●:●●:●●
```
File APIでJSONを取得、オブジェクトに変換してブラウザに表示する

JSONファイルをJavascript用にオブジェクト化してみました。
key、value毎に表示したり、for inを利用して両方一緒に表示したりできました。

複雑で読みづらいJSON形式ファイルでも、これを通せば見やすくなりました。

そういえばMIMEをtext/jsonだと思っていたらapp...だったんですね。

```html:html
<!DOCTYPE html>
<html>
<body>
	<form method="post" enctype="multipart/form-data">
		<input type="file" id="file" accept="application/json">
	</form>
	<p id='name'></p>
	<p id='value'></p>
	<p id='name_value'></p>
	<script>


	</script>
</body>
</html>
```
```js:javascript
window.onload = function() {
	const reader = new FileReader();
	//HTMLを初期化し、新たなファイルを文字列として読込む		
	file.addEventListener('change', function(e) {
		reader.readAsText(e.target.files[0]);
		name.innerHTML = value.innerHTML = name_value.innerHTML = "";
	});
    //ファイルをオブジェクト化して表示
	reader.onload = function(e) {
		var obj = JSON.parse(e.target.result);
		for (var i = 0; i < Object.keys(obj).length; i++) {
			name.innerHTML += Object.keys(obj)[i] + '<br>';
		}
		for (var i = 0; i < Object.values(obj).length; i++) {
			value.innerHTML += Object.values(obj)[i] + '<br>';
		}
		for (key in obj) {
			name_value.innerHTML += key + ' ' + obj[key] + '<br>';
		}
	};
};
```
OPCELの勉強の仕方(あまり期待しないでね)

#ググっても合格体験談っぽいのがないので・・
Qittaって資格情報なものでもないので投稿するか悩んだけど現実問題OPCELに関する情報が少なかったのでこれから受験する方に少しでも参考になってくれればと思い。。

#OPCELって
今、クラウド業界ではやりのOpen Stackに関する資格です。クラウドのミドルウェア的なものですね。昔は、CloudStackとかが台頭してましたが、いざこざがありOpenStackが最近の企業で導入しています。AWSとかAzureがパブリック(1リソース対大多数利用)に対してプライベート(1リソース対1企業)なクラウドを構築するのがOpenStackというイメージで自分は持っています(もし違ったらスミマセン)
NFSとかSDNとかにも関係してくる話であり、今、ITインフラ部門にとっては切っても切り離せない技術テーマでないかと思います。

OpenStackの認定資格はかつてもあったそうですが、個々のベンダーごとに(富士通とかNEC??)資格を設けており、レベルの物差しが図れなかったためLPI-Japanがこの資格を作ったそうです。詳しいところはWebとかで見れば出てくると思いますー

　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　
#難易度は？
正直難しいです。LPICの30xの上位？に屈する資格らしく範囲も膨大です。
そして受験費用が高すぎる！！！！！合格点は公式には6割とありますが、自分が受けたときは6割五分が合格点でした。

#対策
一番いいのは、実際OpenStackを構築するのがベストですね。といっても困りますよね・・・
まず全体のコンポーネントがイメージできるかがポイントです。できれば図式化されている資料とかがネットに転がっているので
それを利用するといいかと。後、公式の例題は絶対しておくとよいです。ここから数問出ているのでよほど重要なのかなと感じられました。
公式参考書は全く使い物にならないので買わないことを強くお勧めします。

以上です。何か聞きたいことありましたらコメントお願いします。
rails dbコマンド　まとめ

rails　dbコマンドについてまとめて置こうと思います。
初めてだと間違えて実行して困ってしまうこととかが結構あったので役に立てばいいなと思います！
では行きましょう！

未実行のマイグレーションファイルを実行する

```
rails db:migrate
```

実行されていないマイグレーションを表示

```
rails db:abort_if_pending_migrations
```

マイグレーションをrollbackさせる（間違えてmigrateしてしまった人はとりあえずこれ）

```
rails db:rollback
```

STEP=nをつけることもできる(n回分マイグレーションをrollbackする)

```
rails db:rollback STEP=n
```

現在のマイグレーションのバージョンを表示

```
rails db:version
```
Rubyでセリをする問題を解いてみた[プログラミング問題]

友達に問題を出されて考えたのでメモとして残しておきます

AとBが交互に取引をして行く。
Aは200円ずつ、Bは300円ずつ取引をして行く。
片方が値段をあげることができなくなったらセリは終了し、最後に値段をあげたほうが購入する。

標準出力から商品の値段、Aの予算、Bの予算を受け取る

```ruby

loop do
    price += 200
    if A_budget >= price && B_budget < price + 1000
        puts "A #{price}"
        return
    end
    price += 300
    if B_budget >= price && A_budget < price + 10
        puts "B #{price}"
        return
    end
end
```

プログラミング問題を解いたらオファーがもらえたりするサービスもあるみたいだし本格的にやってみようかな〜

おすすめのサービスとかがあれば教えてもらいたい

それと実行スピードとかあるみたいだけど早くするためにはどうしたらいいんだろう？？
誰か教えて〜
Infura の JSON RPC API で Ethereum アドレスの残高を取得

# はじめに
- Geth と呼ばれる Ethreum クライアントは、JSON RPC API を提供することができます。
- JSON RPC API を使用することで、Geth を実行せずに、外部のサーバ（ノード）を使用して、Ether の残高を取得したり、トランザクションを投げたりすることができます。
- ただし、JSON RPC API を提供しているサーバが返す値を読む形になるので、そのサーバを信用する必要があります。
- 通常は、自らが所有するサーバの JSON RPC API を使用することが望ましいと思いますが、この記事では [Infura](https://infura.io) というサービスが提供する JSON RPC API を使用します。
- Infura のサーバ上で動いている Geth に、API 経由でアクセスするといった形になります。

# Infura に登録して API Key 取得
- Infura を使用するために、API Key を取得する必要があります。
- https://infura.io/ でメールアドレスを登録すると、次のようなフォーマットで API Key つきの URL がメールで送られてきます。
- https://mainnet.infura.io/xxxxxxxxxx

# curl で JSON RPC API にアクセス
- 今回は Ethereum アドレスの残高を知りたいので、Geth の JSON RPC API `eth_getBalance` を使用します。
- [API ドキュメント](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getbalance) 

## API に渡すパラメータ
- `DATA`: 残高を取得したい Ethereum アドレス 
- `QUANTITY|TAG`: ブロックの番号または、`"latest"` つまり最新のブロックを指定

```
"params" : [
  "0xF02c1c8e6114b1Dbe8937a39260b5b0a374432bB",
  "latest"
]
```

## リクエストのサンプル
- 実際に使用する際は、次の箇所を変更してください
 - `YOUR_API_KEY` の部分を、自分の API Key に変更してください。
 - アドレス `0xF02c1c8e6114b1Dbe8937a39260b5b0a374432bB` を、残高を調べたいアドレスに変更してください。

```
curl -i -X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xF02c1c8e6114b1Dbe8937a39260b5b0a374432bB","latest"],"id":1}' \
"https://mainnet.infura.io/YOUR_API_KEY"
```

## レスポンスのサンプル

```
HTTP/2 200 
date: Mon, 30 Apr 2018 18:21:08 GMT
content-type: application/json
content-length: 55
server: nginx/1.10.3 (Ubuntu)
vary: Origin

{"jsonrpc":"2.0","id":1,"result":"0x2453625cffc4f000"}
```

- この `result` の値が Ethereum アドレスの残高になります。
- この値は16進数なので、次のようなコマンド等で10進数に直すと wei の値になります。

```
echo $((16#2453625cffc4f000))
# => 2617543960000000000
```

- 1 Ether = 1000000000000000000 Wei なので、今回は `2617543960000000000` を `1000000000000000000` で割った値 `2.61754396` が残高になります。

# 参考
- http://blog.playground.io/entry/2018/05/01/035823
- https://scrapbox.io/playground/Infura_%E3%81%AE_JSON_RPC_API_%E3%81%A7_Ethereum_%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%AE%8B%E9%AB%98%E3%82%92%E5%8F%96%E5%BE%97
- https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getbalance
- https://infura.io/docs/gettingStarted/makeRequests

# sushiether
- Ethereum 関連の情報は https://scrapbox.io/sushiether/ に集約することにしました。
- この記事の内容に変更・更新がある場合は、[Infura の JSON RPC API で Ethereum アドレスの残高を取得 - sushiether](https://scrapbox.io/sushiether/Infura_%E3%81%AE_JSON_RPC_API_%E3%81%A7_Ethereum_%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%AE%8B%E9%AB%98%E3%82%92%E5%8F%96%E5%BE%97) を更新します。
Omise決算額変更

#こういう使い方は特殊なのか？
自分が公開しているWebサービスp4matchではポイントを買ってもらい、そのポイントを使ってイベント（大会）参加の申し込みを行う形をとっています。

このポイントとは1000円チャージしたら1000ポイント、5000円チャージしたら5000ポイント
というようにSUICA等の電子マネーと同じように扱うものです。

そのポイント購入にあたってOmiseの導入に取り組み始めたのですが

1. ページに複数の購入ボタンが設置できない
 - 指定のスクリプトを複数置いても決済ボタンは1つしか作られない
- 一度設置したボタンの購入金額を変更することが出来ない
 - 決済ボタンが自動生成されるもので事後変更等動作が保証できかねる

この仕様って通常の決済は**１商品１ページで決済ボタンも１つ**が当たり前ってことなのでしょうか？

でもチャージ金額のボタンを押したらそれぞれの決済ページに遷移するというのは避けたい（そのページで決済を終了にしたい）


#参考記事
@Hi_Noguchisさんの
[Omise.jsのdata-amount値を可変にする](https://qiita.com/Hi_Noguchi/items/14a3d4e16afcf6fb35ed)

#過程
１はどうしても解決できなかったので
参考記事によりボタンは一つで2.の対応で問題が解決できると思い、金額をラジオボタンで選んでもらい、その時上記の対応を行いました。
しかし一度この対応後にラジオボタンの再選択（再設置し直し）すると決済ボタンは表示されなくなってしまいました。
(jQueryのキャッシュの関係なのかな？)

#対応策

1. ラジオボタンでの選択時には何も行わず、”選択したポイントをチャージする”というボタンを用意する
- ”選択したポイントをチャージする”ボタンを押した時にダイアログを作成
- ダイアログオープン時に決済ボタン作成
- ダイアログを閉じる時にページリロード

強引ですがこれで金額選択ができる決済ページが出来ました。

#つぶやき
決済サービスはなにが正解？
まだしっかり収益が出ていないサービスなので固定出費は避けたいので使用料は決済手数料（さらに安い）というサービスで探してみると

- PayPal
 - お客さんがID作らないといけない？
- SPIKE
 - 手数料が独特でいいかもと思ったのですが売上１０万超えると高くなったり、JCB対応には月額費が発生と考えることが増えたので次
- STRIPE
 - 導入しやすそうで検索にもよく出てくるのでこれでいいと思ったのにこれがJCB未対応ということで断念
- Omise
 - ちゃんとJCB対応している。導入が簡単て書いてあった！（が、今苦労してます＾＾；）
- PAY.jp
 - こちらを選ばない理由は特にないのですが、今の所サービスが日本だけということくらいか

Omise情報ほんと少ないですね。
まだ導入途中なので導入終了したらあらためてまとめてみたいと思います。

このサービスなら苦労無いのにとかあったらぜひコメントください
ivy-modeで、現在の入力を削除し、候補リストをリセットする。

例えば、find-file時の入力を削除するには、

    Shift-Space

を入力。

これで入力が消えて、候補リストがリセットされる。

## 参考
- [5.2.4 Key bindings that alter the minibuffer input](http://oremacs.com/swiper/#key-bindings-that-alter-the-minibuffer-input)
pecoでsshするやつ in fish shell

元ネタ: [pecoでsshするやつ](https://qiita.com/d6rkaiz/items/46e9c61c412c89e84c38)

fish-shellでsが使えなくて焦ったので、
備忘録として公開しておきます。

## 作り方

元ネタの記事から`$()`を`()`にするだけ。

```fish
~> alias s='ssh (grep -iE "^host[[:space:]]+[^*]" ~/.ssh/config|peco|awk "{print \$2}")'

~> functions s
# Defined in /Users/miyabi/.config/fish/functions/s.fish @ line 2
function s --description alias\ s=ssh\ \(grep\ -iE\ \"\^host\[\[:space:\]\]+\[\^\*\]\"\ \~/.ssh/config\|peco\|awk\ \"\{print\ \\\$2\}\"\)
	ssh (grep -iE "^host[[:space:]]+[^*]" ~/.ssh/config|peco|awk "{print \$2}") $argv;
end

~> s
# pecoが立ち上がってSSH接続出来る

~> funcsave s
# これでsコマンドが保存されて常に使えるようになった
```

## おまけ: moshも登録

mでいいかな？
moshは`mosh host`で接続できるのでsshのほぼ丸コピーで使える

```fish
~> m
fish: Unknown command 'm'

~> alias m='mosh (grep -iE "^host[[:space:]]+[^*]" ~/.ssh/config|peco|awk "{print \$2}")'

~> functions m
# Defined in - @ line 0
function m --description alias\ m=mosh\ \(grep\ -iE\ \"\^host\[\[:space:\]\]+\[\^\*\]\"\ \~/.ssh/config\|peco\|awk\ \"\{print\ \\\$2\}\"\)
	mosh (grep -iE "^host[[:space:]]+[^*]" ~/.ssh/config|peco|awk "{print \$2}") $argv;
end

~> funcsave m
```
Excelの薄い本(2)

# SUMの再定義
ワークシート関数SUMは、引数に長さ０の文字列が入るとエラーになるので、
ユーザ定義関数として再定義します。

```vb
Function TSUM(ParamArray AR())
    Dim S: S = 0
    Dim I: For I = 0 To UBound(AR)
        S = S + IFSJ(AR(I))
    Next I
    TSUM = S
End Function

Function IFSJ(V, Optional J = 0)        ' IF SPACE J
    IFSJ = IFNC(V = "", V, J)
End Function

Function IFC(C, V, Optional S = "")     ' IF C THEN V ELSE S
    If C Then IFC = V Else IFC = S
End Function

Function IFNC(C, V, Optional S = "")    ' IF NOT C THEN V ELSE S
    IFNC = IFC(Not (C), V, S)
End Function
```

# 複雑な計算式の畳み込み
例として、在庫 =（計画、CNTがあればCNT) - 減耗 - 出庫 + 前回在庫 + 繰越
といった計算式があるとすると、

```vb
=TSUM(IFSJ([@CNT],[@計画]),-[@減耗],-[@出庫],[@前回在庫],[@繰越])
```
これでも充分複雑なので、RANGEと構造化参照を使って畳み込みます。


```vb
Function 在庫(A, Optional S = "")
   On Error Resume Next   
   Dim M: M = MM(Range(A))
   S = TSUM(IFSJ(DIA(A, "CNT", M), DIA(A, "計画", M)), _
                -DIA(A, "減耗", M), -DIA(A, "出庫", M), _
                 DIA(A, "前回在庫", M), DIA(A, "繰越", M))
   在庫 = S
End Function

Function DIA(A, T, Optional I = 0, Optional S = "")
   On Error Resume Next
   If I = 0 Then I = MM(Range(A))
   S = DI(Range(CC(A, "[", T, "]")), I)
   DIA = S
End Function
```
Aには、テーブル名の文字列が入るので、これをキーワードにして、
別のテーブルの在庫関数を定義することも出来ます。
neosnippetで使い捨てのsnippetを登録する

私は昔はemacsを使っていて今はvimを使うことが多いのですが、emacsで重宝していた機能の一つに
[yasnippet](https://github.com/joaotavora/yasnippet)を使った[oneshot-snippet](http://d.hatena.ne.jp/rubikitch/20090702/1246477577)がありました。
これはsnippetの機能を使って使い捨てのsnippetを作成し、さっと使えるようにしたものです。
登録するほどの汎用性はないけど、ファイル編集の際に何回か同じパターンを入力しなきゃならないときが
結構あるので、この関数が好きで大分お世話になりました。

しかし、vimでは[neosnippet](https://github.com/Shougo/neosnippet.vim)という同じようなスクリプトはあるものの、oneshot snippetのようなものは見つけられなかったので
Vim script勉強して何とか作らなきゃなぁ、と思っていたのですが、今日改めてneosnippetのコードを見ていたら
`neosnippet_register_oneshot_snippet`という関数を発見したのでメモしておきます。
試したところ、これを使えば使い捨てのsnippetを作れたので、使い方を残しておきます。

## 使い方

前提: neosnippetは既に使える状態であるとします。

`.vimrc`に以下のコードを追記します。(キーバインドは自分の好きなものに変えてください)

```vim
vmap <C-u>     <Plug>(neosnippet_register_oneshot_snippet)
```

後は、編集ファイル内でsnippetの元を作り、visual modeでsnippetを範囲選択した状態で
ctrl-uを押すことで`neosnippet_register_oneshot_snippet`が起動され、使い捨てのsnippetを登録できます。
登録の際にトリガーを聞かれるので、好きなトリガーを登録すれば、そのファイル内でのみ使えるsnippetを起動できるようになります。

## 例

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/133841/10baf4fe-adad-2aba-e22d-01c6b5eb4ec0.gif)


`foo.py`ファイル内で以下のようなsnippetを書きます。

```
self.${1} = $1
```

で、visual modeで上の行を選択しctrl-uを押すことでoneshot snippetを登録できます。

登録時に、snippet呼び出しのキーワードを指定します (デフォルトだと"oneshot"。ちょっと長い気がしますが。)。

後はinsert modeでoneshotと入力をしてctrl kなどでsnippetを起動すればいつも通りのsnippetが簡単に使えるようになります！
初音ミクV4X macOS High Sierra バージョン10.13.4で読み込めない問題について

初音ミクV4X Mac OSの最新バージョンによる不具合

公式HPの不具合記述
http://piaprostudio.com/?p=3922


こちらを修正するために必要な手順

1.updaterをDLする
https://ec.crypton.co.jp/support/engine/26

Piapro Studio VSTi / AU v2.0.4.7 (Mac) アップデータからDL

2.updaterをMac純正のアーカイブユーティリティで解凍する
※純正でないと解凍した際にエラーが出ました。

3.Logic Pro Xの環境設定→プラグインマネージャ→選択項目をリセットして再スキャン
![スクリーンショット 2018-05-01 02.26.28.png](https://qiita-image-store.s3.amazonaws.com/0/247810/64ff54f9-34b6-24f2-2a28-74b50a351e7a.png)

4.新規トラック作成→ソフトウェア→AU音源→クリプトン→ステレオ
pippro studioが立ち上がります
![スクリーンショット 2018-05-01 02.27.51.png](https://qiita-image-store.s3.amazonaws.com/0/247810/b14e9509-fef1-f708-b239-45c95544a703.png)


自分はV4Xをとりあえず試してみるために落とした際不具合が起こり、AppleCareに連絡してクリプトン側にアップデータがないか確認するようにというところまで行き着きました。割と情報が散乱しているので（V3でも同じようなエラーが起こって居た模様でぐぐるとその記事が引っかかる）、この記事で正確な情報をお伝えできればと思います。

その後上記で試して何か不具合などありましたらコメントでご連絡ください。（あくまで一般ユーザーですので、試す際は自己責任でお願いいたします）
世界一シンプルなReact-native + Reduxチュートリアル３

前回までのチュートリアル
[世界一シンプルなReactNativeチュートリアル１](https://qiita.com/loverails/items/8c46767413a3c8d15f00)
[世界一シンプルなReactNativeチュートリアル２](https://qiita.com/loverails/items/8418e2a51a3aed462805
)

さあ前回作ったメモアプリはアプリを閉じるとメモが消えてしまう欠陥品だった。
今回はredux-persistでstoreを永続化（データベースに保存）してみよう。

## redux-persistがあると何が嬉しいか？

今までは、データベースにデータを保存するには

```
1.reduxのstoreに保存する 
2.storeから値を呼び出す
3.データベースに保存
```

と言う3ステップが必要だった。
しかしredux-persistを使うことで、

```
1.reduxのstoreに保存する＝同時にデータベースに保存される
```
になる！！！

つまりdatabaseへの読み書きの記述を一切しなくてよくなる。
このredux-persistがあるから私はreduxをreact nativeで使っている。
mobx-persistなどもあるが、starが少ない(泣)...
結局2018年のreact nativeはreduxを使わざるを得ないw


## 導入
redux-persistの導入ははとても簡単だ。まず
yarn add redux-persist
// npm i redux-persist
そして以下のように記述するだけだ。

```js
// store.js
import { createStore } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import rootReducer from "./rootReducer";
import storage from "redux-persist/lib/storage";

const persistConfig = {    
  key: "root",             
  storage                  
};
  
const persistedReducer = persistReducer(persistConfig, rootReducer);
   
export const store = createStore(persistedReducer);
export const persistor = persistStore(store);
```

...終了だ。

なんと言う手軽さだろう。
もうメモアプリを閉じてもメモは消えないよ。やったね。

このredux-persist設定をすることで、保存先のDBを選べたり、保存しないstateをreducer単位で選ぶことも可能だ。
実は今回redux-persistを使ったことによりスマホのDBからstateの呼び出しがあるので、アプリの起動が遅くなっている。
がーん。
react native 標準のデータベースのasync storageは遅いことで有名だ。
工数を取れる人は、他のデータベースへと乗り換えよう。

redux-persistのREADMEを読めば大抵のことは出来るようになる。
（dbを低速なasyncStrageから変更したい。一部のstateだけdbに保存したいなど。）

これできみもReactNativeマスターだ。
PowerShell の配列は添え字に配列が使える

```powershell
> $a = 'abcdef'

> $b = 0,2,4
> $a[$b]
a
c
e

> $b = 0..2
> $a[$b]
a
b
c

> $b = 0..2 + 4..6
> $a[$b]
a
b
c
e
f
g

```
ESP32とAWSIoTとAlexaを繋げてみた(AWSIoTとDynamoDB編)

#Lambdaからデータを取得するのにはデータベースが必要だ
ということに気づきましたのでAWSIoTからAWSのサービスの一つである
DynamoDBにデータをあげててみます
AWSIoTから直接あげられるのです
AWSIoTにACTルールを作りましょう
<img width="727" alt="スクリーンショット 2018-05-01 1.06.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/1cf60821-ed6a-56a7-6481-278d665bb25e.png">
属性を

```
clientid() AS client_id, parse_time("yyyyMMddHHmmssz", timestamp() ,"Asia/Tokyo" ) AS timestamp, *
```

トピックフィルタを

```
BME280/+/
```

とします
BME280/のどっかにあがったデータからモノのIDとタイムスタンプをyyyyMMddHHmmssz形式で取得します

このアクションを追加しましょう

<img width="912" alt="スクリーンショット 2018-05-01 1.11.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/2e12e94f-84c9-1453-e300-f8e62f947234.png">

DBがないので作っちゃいましょう

<img width="525" alt="スクリーンショット 2018-05-01 1.11.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/de583aa1-4e12-dd74-f7dd-41e8d6bded75.png">


ロールもないので作っちゃいましょう名前をつけるだけで自動で作ってくれます

<img width="965" alt="スクリーンショット 2018-05-01 1.12.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/5a583377-b2e2-0d60-71e2-31e8f0edbac5.png">

AWSIoT内のテストでBME280/data/にパブリッシュしてみました
<img width="675" alt="スクリーンショット 2018-05-01 1.18.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/24394dac-d63e-4022-b593-d6d1cc5a3e6c.png">

DBにデータが追加されています！！
次回こそLambdaからESP32のデータを取得します