OmniAICreator/Qiita-1.07M huggingface dataset:
Unity でOVRLipsync を使い作った BlendShape のアニメーションをクリップに変換する方法

#要約
UnityでOVRLipsyncを使い作ったBlendShapeのアニメーションをアニメーションクリップに変換するには、GameObjectRecorderクラスを使えばできます。
[Unity - Scripting API: GameObjectRecorder](https://docs.unity3d.com/2018.3/Documentation/ScriptReference/Animations.GameObjectRecorder.html?fbclid=IwAR0xn-83ekBpecq0W1TLkmCfrTbUfrcyQN1Gayw3f5qLw6_wdFCu9qh398k)

#はじめに
Unityでアニメーション作ろうと思った際に、口パク面倒だなーと思っていたら、OVRLipsyncという神ツールを見つけました。ですが、ほとんどインタラクティブに使う用途ばっかりで、そのアニメーションをアセットにしたくても方法が見つからない...と、そこに現れた救世主！
[Unityユーザー助け合い所](https://www.facebook.com/groups/unityuserj/)
質問したらソッコーで回答をくれました。本当にありがとうございます！

#方法
Unityちゃんを使います。
![キャプ01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/7853b380-a9a1-5989-d44d-6b28e741958a.png)

OVRLipsyncをunityに入れて音声データに合わせてBlendShapeの値が動く（口パクする）ように設定します。ここまでは他の記事を参考にしてみてください。

[Unity - Scripting API: GameObjectRecorder](https://docs.unity3d.com/2018.3/Documentation/ScriptReference/Animations.GameObjectRecorder.html?fbclid=IwAR0xn-83ekBpecq0W1TLkmCfrTbUfrcyQN1Gayw3f5qLw6_wdFCu9qh398k)
のページを参考にして下記のようにしたスクリプトを作ります。

```
using UnityEngine;
using UnityEditor.Animations;

public class RecordTransformHierarchy : MonoBehaviour {
	public AnimationClip clip;

	private GameObjectRecorder m_Recorder;

	void Start()
	{
		// Create recorder and record the script GameObject.
		m_Recorder = new GameObjectRecorder(gameObject);

		// Bind all the Transforms on the GameObject and all its children.
		m_Recorder.BindComponentsOfType<SkinnedMeshRenderer>(gameObject, false);
	}

	void LateUpdate()
	{
		if (clip == null)
			return;

		// Take a snapshot and record all the bindings values for this frame.
		m_Recorder.TakeSnapshot(Time.deltaTime);
	}

	void OnDisable()
	{
		if (clip == null)
			return;

		if (m_Recorder.isRecording)
		{
			// Save the recorded session to the clip.
			m_Recorder.SaveToClip(clip);
		}
	}
}
```

これをunityちゃんの表情のblendshapeがあるMTH_DEFに割り当てます。
また、空のクリップを作り、スクリプトのclipの欄に割り当てます。
![キャプ02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/6d3be7f2-1950-9e39-9dea-581ea6c44413.png)

次に、UnityちゃんにデフォルトでついているAnimator, Idle Changer, Face Updata, Auto Blinkのチェックを外してUnableにします。
![キャプ05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/d4d8eab4-f9c0-781c-d479-db554e25938f.png)

この後、Playを押してStopすると、割り当てられたクリップにキーフレームがうたれます。この時、Pauseを押してからPlayを押して、Pauseを外して再生したほうがうまくいくと思います。下の図は失敗例。
![キャプ03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/c8a71168-53a4-620e-cd97-29200a4b02c2.png)


しかし、アニメーションのキーフレームが打たれているところのプロパティが黄色くなって、このままでは使えません。
ので、新しいクリップを作り、手動でプロパティを追加して、先のクリップから対応するプロパティにキーフレームをコピペします。日本語の場合は、_A,_I,_U,_E,_Oのプロパティのキーフレームを移せばいいと思います。（先の画像と今回の画像で使っているアニメーションが違うのでキーフレームが対応していないです。）
![キャプ04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/2843dd8b-3902-1ce4-c20a-48e903fc3d27.png)

その後、Animatorなどに今度はチェックをいれてableにして、音声と共に再生してみると口パクしているのがわかります。もし音声と口パクがずれていたら、Timelineなどを使い調節すると便利です。
![キャプ06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362049/b0d9cbbf-c6b4-4df6-69bc-6532d1198720.png)

#まとめ
面倒な部分を簡略化できると思いますが、現時点で私が口パクを作る頻度が高くないので更新はしないと思います。
もし、もっといい方法を思いついた方がいたら記事作ってください。私のためにもお願いします！（めんどくさがり）
npmでよく使うコマンド

## 環境構築

### npm init

Node.jsプロジェクトを新規作成します。
具体的には `package.json` が作成されます。

### npm install

`package-lock.json` を見てパッケージをインストールします。
`package.json` や `package-lock.json` は書き換えません。

`package-lock.json` が存在しない場合、 `package.json` を見てパッケージをインストールします。
インストール後、 `package-lock.json` が作成されます。

### npm install {パッケージ名}

指定したパッケージをインストールします。
インストール後、`package.json` と `package-lock.json` を書き換えます。

`npm i {パッケージ名}` と省略できます。
`-g` オプションを付けるとグローバルにインストールします。（他のコマンドも同様）

`--save-dev` オプションを付けると `dependencies` でなく `devDependencies` に追記され、開発時のみ使われます。
eslintやjestなどは開発時のみ使うので、こちらのオプションを付けることで製品に冗長なパッケージを含めずに済みます。

### npm uninstall {パッケージ名}

指定したパッケージをアンインストールします。
アンインストール後、`package.json` と `package-lock.json` を書き換えます。

### npm update

`package.json` を見てパッケージを更新します。
更新後、 `package-lock.json` を書き換えます。

### npm update {パッケージ名}

`package.json` を見て指定したパッケージを更新します。
更新後、 `package-lock.json` を書き換えます。

## 確認

### npm ls

インストールされているパッケージを表示します。
依存パッケージも含めて全て表示しますが、 `--depth=0` を付けると依存パッケージを含めずに表示します。

### npm version

Node.jsプロジェクトで使われているライブラリなどのバージョンを表示します。

### npm --version

`npm -v` と省略できます。
npmのバージョンを表示します。

## 実行

### npm run {コマンド}

`npm run-script {コマンド}` の省略形です。
`package.json` の `scripts` で指定したコマンドを実行します。

### npm test

テストを実行します。
実体は `package.json` 内にある `scripts` の `test` で指定したコマンドを実行します。

### npm start

プログラムを実行します。
実体は `package.json` 内にある `scripts` の `start` で指定したコマンドを実行します。

## 参考リンク

- [よく使うnpmコマンド - Qiita](https://qiita.com/yuch_i/items/3d5f562ac49e81705010)
- [【初心者向け】NPMとpackage.jsonを概念的に理解する - Qiita](https://qiita.com/righteous/items/e5448cb2e7e11ab7d477)
Overflow: hiddenではみ出した部分を隠す


## CSS の overflow

`overflow`とはCSSのプロパティの１つで「**要素のボックスからはみ出た部分をどう扱うか」を指定する。**

```example.css

セレクタ {
  overflow: 値;
}
```

**`visible`**：初期値。はみ出た部分が、はみ出たままの状態で表示される場合あり
**`hidden`**：はみ出た部分が隠れる
**`scroll`**：はみ出た部分が隠れてスクロールできる状態に
**`auto`**：ブラウザにより表示が変わる（基本的にはスクロールできる状態に）

### overflow: visibleでそのまま表示

```index.html
<p class="example">あいうえおあいうえおあいうえお</p>
```

```app.css
.example {
  width: 50px;
  height: 50px;
  overflow: visible;
  background: skyblue;
}
```

![スクリーンショット 2019-12-19 12.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/7038a45f-abab-9e92-0b11-cf2f2aa1a616.png)

### overflow: hiddenで非表示に

```app.css

.example {
  width: 50px;
  height: 50px;
  overflow: hidden;
  background: skyblue;
}

```

![スクリーンショット 2019-12-19 12.29.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/446210/ccf2e7fd-2f9e-bba5-e7a8-46b38ef52382.png)
【AOSP】Androidが文鎮化しそうな時に工場出荷時状態に戻す方法

ビルドしたAndroidOSを実機に入れようとして、謎のエラーを吐いて完全に詰んだ時などに役立ちます。
工場出荷時状態に戻すので、当然ですがデータは全て消えます。

### その前に...(追記2021/06/04)
もし、OEMのロック解除と、USBデバッグを有効にしてない場合、既に詰み状態の可能性が高いです。
多分Android Appの開発者や、OSをいじる人なら大丈夫だと思います。
https://source.android.google.cn/setup/build/running?hl=ja#unlocking-recent-devices


#事前準備
###fastbootモードに入る
- 実機をPCに接続します
- fastbootモードに入るために次のコマンドを打ちます

```
$ adb reboot bootloader
```
adbコマンドが使えない方はググるか、こちらの記事を参照してください
- [【AOSP】ビルドしたAndroidOSを実機に入れる](https://qiita.com/yamakentoc/items/564108cd5ad207193f0e)

###ブートローダーをアンロックする
fastbootモードで次のコマンドを叩いて、ブートローダーをアンロックします

```
$ fastboot flashing unlock
```
- 音量ボタン押して`Do not unlock the bootloader`を`Unlock the bootloader`に変更し、電源ボタンを押します
- `Device state`が`unlocked`になっていればOKです
<img width="500" alt="unlock_yazirushi.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/78856519-49a5-64fa-fbb9-abb088a51923.png">

#工場出荷時状態に戻す
- [こちらのサイト](https://developers.google.com/android/images)から各端末の工場出荷時イメージをダウンロードします
- 自分の端末の名前の欄を見つけます
- 本記事ではPixel 3aを使うため、`"sargo" for Pixel 3a`の欄を見つけます
![スクリーンショット 2019-12-18 23.17.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237700/7b06ad40-4871-694f-93d7-49c71a76e6ad.png)
- 好みのバージョンをダウンロードすると、`sargo-qq1a.191205.011`のようなフォルダがダウンロードされます
- ターミナルで、ダウンロードしたフォルダのpathに移動し、次のコマンドを叩きます

```
$ ./flash-all.sh
```
これでしばらく待つとAndroidが正常に起動します

#これでも治らない場合
おそらく詰みです🙏🙏🙏
端末の問い合わせフォームや、コミュニティに質問したりなどでどうにか解決or修理になると思います。
Pixelの場合は以下のリンクからお問い合わせできます
https://support.google.com/pixelphone/gethelp
JavaScriptのCallback関数って...何？

#はじめに

以前はPHPでシステム開発を行っていたので、その感覚でJavaScriptを触っていると
なかなか慣れることが出来ないそんな中、とあるデザインフレームワークのエラーハンドリングの解説に、
こんな感じ（下記）でAPIを使用してねと書いてありました。

```
rules: [{validator: function(value, callback)}]
```

これを見たとき、callback、、、んっ？となり、少し調べてロジック組んでみたけど動かない、、、。
どうやって使ったらよいの？とハマってしまった経験があるので、今回はコールバック関数について
記載しようと思います！（結果的にはコールバックでない箇所にハマっていたのですけど...）

#コールバック関数とは？

ウィキペディアによると、

>コールバック（英: Callback）とは、プログラミングにおいて、
他のコードの引数として渡されるサブルーチンである。


他のコードのひきすうとしてワタサレるサブルーチン......ほほぅ..何？


もう1回ちゃんと調べてみたところ、コールバック関数とは、
「他の関数に渡して実行してもらうための関数」のことをコールバック関数とよびます。

例えば、
「ある関数Aに、この関数Bを渡しておくから、Aの処理が終わったら渡しておいた関数Bを実行してね」
というように使います。この関数Bがコールバック関数でした。

```js
// コールバック関数B
const weather = () => {
    console.log("晴れ");
}

// コールバック関数を渡される関数A
const today = (callback) => {
    console.log('今日の天気は');
    callback();
}

today(weather);

// コンソールに「今日の天気は」「晴れ」と表示される
```

こう考えると、普段使っている「arr.map(callback)」や「arr.findIndex(callback)」
「arr.filter(callback)」など、callback関数を使っているのが分かりますね。


では、なぜ私がハマったのかというと...。

#そもそもJavaScriptの関数って...

JavaScriptをよく分かっていないがためにハマったのは実はココでして、、。
**「JavaScriptの関数は、関数であり、変数に代入できるオブジェクトでもある」**
ということをちゃんと理解していませんでした。

例えば下記のような関数の使い方であれば、PHPをやっていたのですんなり受け入れることが
出来ましたが、

```js
function hoge() {
    console.log("hoge");
}

hoge();
// コンソールに「hoge」と表示される
```

JavaScriptでは関数はオブジェクトでもあったので、他の変数に入れることも出来ます。
（この感覚がなかった...）

```js
function hoge() {
    console.log("hoge");
}
const hogehoge = hoge;

hogehoge();
// コンソールに「hoge」と表示される
```

結果はどちらも同じで「hoge」と表示されますが、ここで**重要**だったのが、

* 関数として実行する際は呼び出し側に「()」を付ける
* オブジェクトとして渡したりする際は「()」を付けない

ということでした。

# 私がハマったところ

私がハマったのはもうおわかりかもしれませんが、callback関数として値を渡さなければいけないところに、
下記のように()を付けてしまい、関数として実行していたため動かなかったというオチでした。。

```js
 // 使い方
 // rules: [{validator: function(value, callback)}]

 // 下記の定義をした際に、
 rules: [{validator: checkValidate()}]  // ←この()が原因！！

 // エラーチェック関数
 const checkValidate = (value, callback) => {
    if (value === 'xxxx') {
        callback('エラーですよ！');
    } else {
        callback();
    }
 }
```


#おわりに

JavaScript...慣れてしまえばフロントエンドを自在に操作できるようになるので、
とっても便利な言語ですね。早く覚えていかなくては。

この記事が何かのお役に立てれば幸いです。
Rubyチートシート(一部)

※この記事は https://kunosu.qrunch.io/entries/LaeGAOAE0Ijc9CzH に移動しました。

---

徐々に増やしていく予定。

## 実行時の引数を取得

```ruby
# 引数の数が2以外ならNG
if ARGV.size == 2
	folder_pass = ARGV[0]
	str = ARGV[1]
else
	puts "ruby #{__FILE__} フォルダパス 検索条件 の形式で実行"
	exit 1
end
```

## 文字列

### 文字列が含まれているか
真偽を返す

```ruby
str.include?("r")
```

### 正規表現に一致するか

```ruby
str =~ /<(\w+)>/
```

### 一致した部分を置換

```ruby
# "\"(円マーク)を"/"に変換
folder_pass = ARGV[0].gsub("\\", "/")
```

正規表現も可能

```ruby
# 第2引数が空の場合は、一致した部分の削除になる
str.gsub(/<(\w+)>/, "")
```

## ディレクトリ

### 指定パスにディレクトリが存在するかチェック

```ruby
if FileTest.directory?(folder_pass)
	func(folder_pass)
else
	puts("フォルダパスが正しくありません")
	raise ArgumentError
end
```

### ディレクトリ配下のファイルをすべて検索

- パスが存在しない場合はループに入らない(エラーも出ない)
- フォルダの区切り文字は"`/`(スラッシュ)"。"`\`(円マーク)" だと検索できない

```ruby
# testフォルダ以下のすべてのファイルを検索
Dir.glob("#{test}/**/*") do |pass|
	next if FileTest.directory?(pass)	# ディレクトリは無視
	puts pass
end
```

### ディレクトリ配下のファイル数を数える
ディレクトリはカウントしない

```ruby
file_num = Dir.glob("#{test}/**/*.*").count
```

## ファイル

### ファイルを1行ずつ読み込む

```ruby
# test.txt はUTF-8 で書かれている
File.foreach("test.txt", :external_encoding => "UTF-8") do |line|
	line.chomp!	# 改行削除
	next if (line == "")	# 空行を無視

	puts line
end
```

## 例外

### 例外を発生させる

```ruby
raise ArgumentError
```
Capistranoで自動デプロイ時に起きるエラーについて〜AWS〜

# はじめに
Capistranoを使って、AWSに自動デプロイをかけた時に出るエラーのお話
本件は主に再起動時に起きるエラーです
最後にデプロイ時に確認する事項をまとめていますので、そちらも軽くご参照いただければと思います

## Erroe内容
bundle exec cap production deploy実行後

```terminal:terminal
Mac_ikuy:"hogehoge" User$ bundle exec cap production deploy
#<Thread:0x00007f8b2b50bb18@/Users/mac_ikuy/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
        1: from /Users/mac_ikuy/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/mac_ikuy/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as ec2-user@18.177.78.202: Authentication failed for user ec2-user@xx.xxx.xxx.xxx (SSHKit::Runner::ExecuteError)
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@xx.xxx.xxx.xxx: Authentication failed for user ec2-user@xx.xxx.xxx.xxx


Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user ec2-user@xx.xxx.xxx.xxx

Tasks: TOP => rbenv:validate
(See full trace by running task with --trace)
```
こんな感じのエラーが出ます
今回の話の結論からいうと、SSHキーが消えてしまっているので、.sshにて下記コマンドを入力します

```terminal:terminal
$ cd ~/.ssh
.ssh $ ssh-add ~/.ssh/hoge.pem
```

hoge.pemにはインスタンスに対応したpemキーを入力してください

## Error解決しないときは

エラー文に慣れない方はなんかいっぱい書いてあってうわぁって思うかもしれませんが、ポイントは"Caused by"です
これのせいで、ってことですね
"Exception while executing"を直訳すると「実行中の例外」です
何か例外が起きてしまったんだなってことですね
AWSへのデプロイ時の基本注意点としては、

- mysql/nginexの再起動
- unicorn killの確認

です
前者は

```
[ec2-user@ip-xxx ~]$ sudo service nginx restart
[ec2-user@ip-xxx ~]$ sudo service mysqld restart
```

後者は

```
[ec2-user@ip-xxx ~]$ ps aux | grep unicorn
ec2-user  4223  0.0  0.0 11xxxx   master
ec2-user  4175  0.0  0.0 11xxxx   ~~~~省略~~~~
ec2-user  4236  0.0  0.0 11xxxx   ~~~~省略~~~~
[ec2-user@ip-xxx ~]$ kill 4223 #masterのNO.
```

上記ができているにも関わらずデプロイできないときは、インスタンスを一度停止しましょう
<img width="1236" alt="スクリーンショット 2019-12-19 11.36.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522204/bcd57435-8e0d-0125-ece6-60076d61f5d4.png">
"停止"が完了したら"開始"をしましょう
大概のエラーはこれでで解決できます。


# まとめ
解決方法のまとめです

- "Net::SSH::AuthenticationFailed: Authentication failed"が出たときはsshキーが消えている可能性があるので、addしてやる
- mysql/nginexの再起動
- unicornのkill
- インスタンスの再起動
【Access】既存テーブルへのCSVの取込みでデータ型変換エラー

#はじめに
まさか初めての記事がAccessになるとは思ってませんでしたぴーなっつです
Qita書くのに慣れてないのでお見苦しい点はご勘弁

##概要
Accessなんてあんまり使わないので、界隈では常識なのかもしれませんが（情報出てこなかったし）
2回目のCSVがインポートできないんですって問合せを頂きましたので、そのあたりのことをかきます

##問題点
長い数値列はAccessで普通に数値型になってしまうので
テーブル定義とか1回目の取込みでテキスト型とかにしますよね
で、一旦レコードを消して同じファイルを取り込もうとすると
「データ型の変換エラー」ってのが出てしまうことがあるようです

#解決
大した話ではないので手短にいきますが
インポート時の「設定」を開いてそのままOKするなり定義を読みこむなりすれば
エラー無く取り込めるようです
「設定」しないと、テーブル定義無視でAccessデフォルトの定義で取り込んでしまう的な？
そのくらいデフォでもうまいことやってくれたらいいのにとも思いますが
色んなパターンがあるからしょうがない・・・かな

・・・C#とかCoreの話が書きたい(ﾉД`)
1.3テキストの検索

#1.3テキストの検索

text1.concordance("")の""内に単語を入れることにより文全体から括弧内の単語が使用された分をを検索することができる。

```
>>> text1.concordance("monstrous")
Displaying 11 of 11 matches:
ong the former , one was of a most monstrous size . ... This came towards us ,
ON OF THE PSALMS . " Touching that monstrous bulk of the whale or ork we have r
ll over with a heathenish array of monstrous clubs and spears . Some were thick
d as you gazed , and wondered what monstrous cannibal and savage could ever hav
that has survived the flood ; most monstrous and most mountainous ! That Himmal
they might scout at Moby Dick as a monstrous fable , or still worse and more de
th of Radney .'" CHAPTER 55 Of the monstrous Pictures of Whales . I shall ere l
ing Scenes . In connexion with the monstrous pictures of whales , I am strongly
ere to enter upon those still more monstrous stories of them which are to be fo
ght have been rummaged out of this monstrous cabinet there is no telling . But
of Whale - Bones ; for Whales of a monstrous size are oftentimes cast up dead u
>>>
```

.similer("")で""内の単語に似ている単語を検索できる。

```
>>> text1.similar("monstrous")
mean part maddens doleful gamesome subtly uncommon careful untoward
exasperate loving passing mouldy christian few true mystifying
imperial modifies contemptible
>>> text2.similar("monstrous")
very heartily so exceedingly remarkably as vast a great amazingly
extremely good sweet
>>>
```


.common_contexts("","")で""内に単語を入れるとAND検索ができる！

```
>>> text2.common_contexts(["monstrous", "very"])
a_pretty is_pretty am_glad be_glad a_lucky
>>>
```



.dispersion_plot([""])で""内の単語の文全体における位置情報をプロットできる！

```
>>> text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])
>>>
```


.generate()で文を作れる!!

```
>>> text3.generate()
In the beginning of his brother is a hairy man , whose top may reach
unto heaven ; and ye shall sow the land of Egypt there was no bread in
all that he was taken out of the month , upon the earth . So shall thy
wages be ? And they made their father ; and Isaac was old , and kissed
him : and Laban with his cattle in the midst of the hands of Esau thy
first born , and Phichol the chief butler unto his son Isaac , she
>>>
```
AzureDevOpsでマージしたブランチを元に戻す(Revert)


まだ merge するつもりじゃなかったのに、Pull Request(以下PR) を Completeして merge してしまった！  
どうしよう・・・  

そんな時、どうすれば戻せるのかってときに役立てるかと思いメモします。（あとはConflict：競合が発生したときにこのPR一旦戻したいときとか）  

(実際に戻したわけではないので戻した後、ちゃんと変更履歴とかが残ってるのかはわかりません。戻るだろうなって確信を得ているので記事にします。)

それと初めて Revert という機能を使用したのでメモします。  

## やったこと

PRをCompleteすると上のほうに、緑の四角形が出てると思います。  
その右端に[Revert]ってボタンがあります。

- Revert：日本語訳 元も戻す  

その名の通り、Completeした内容を元に戻せます。  
押したらあっという間に魔法のように戻ると思ってました。  
そんなわけあるわけないんですけど。  

[Revert]ボタンを押すと以下のDialogが出てくると思います。  
![Revert1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467168/65a3fcaa-45f6-26e3-3c8d-d20ca8fdce4c.png)

「Revert pull request <プルリクエスト番号>」

- Target：このPR先ブランチ名
- Topic branch name：新規ブランチ名  

項目ごとにみるとデフォルトでこんな感じのことが書いてあります。  
  
Revertを押すと、このPRを打ち消すブランチ(Topic branch name)を作成してくれるようです。  
つまり、このブランチから間違えてmergeしてしまったブランチに対してPull Requestを送り、それをCompleteすることでようやく元に戻せるようです。  
実際にPRだけ作成して、対象Fileをみると間違えてマージした内容を打ち消すような変更がありましたので、安心しました。
Mackerelのアラート回数をモニター別に集計しようとしてみたが失敗した 



## 序

こんにちは、これは[Mackerel Advent Calendar 2019](https://qiita.com/advent-calendar/2019/mackerel) の19日目のエントリです。

日々サービス運用に携わっている中である特定のアラートが多く発生したり、
また逆に、何かしらの対策を講じることで今まで頻発していたアラートが減ることがあるかと思います。

そのような時、感覚的には増えたな、減ったなと思うんですが、
じゃあ具体的にどのくらい増減してるんだ、ということが分からない状態でした。

そこで定量的にアラートの増減を把握するために、アラート回数の集計を試みることにしました。

## 破

Mackerelではアラートの通知もwebhookで飛ばすことができるので、
エンドポイントをAPI+Lambdaにして、
その結果をMackerelのサービスメトリックに投稿して集計できないかと考えました。

大まかな流れは下記の通りです。
※こちらは [cohalzさんの記事](https://core.cohalz.co/entry/2019/12/02/120000)を参考にしました。

1. アラートが発生するとMackerelのwebhookからAPI Gatewayのエンドポイントにリクエストが飛ぶ
2. API GatewayからLambdaを呼び出す
3. LambdaからMackerelのサービスメトリック投稿のAPIにPOSTする


![スクリーンショット 2019-12-19 5.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205006/a4860e70-ca78-c2f6-57d9-c2478ac487db.png)


サービスメトリック投稿のためにはMackerelのAPIに下記のようなJSONをPOSTします。

```
[{"name": string, "time": number, "value": number}]
```

<br>

MackerelからAPI Gatewayに通知されるJSONには以下のような内容を含んでいるため、
nameをmonitorName、timeを日付+固定時刻(00:00)にしてサービスメトリックに投稿すれば、
日×モニター名別にアラート回数をグラフ化できそうだと考えました。
[参考](https://mackerel.io/ja/docs/entry/howto/alerts/webhook)

```
  "alert": {
    "openedAt": 1473129912,
    "closedAt": 1473130092,
    "createdAt": 1473129912693, 
    "criticalThreshold": 1.9588528112516932, 
    "duration": 5, 
    "isOpen": true, 
    "metricLabel": "MetricName", 
    "metricValue": 2.255356387321597, 
    "monitorName": "MonitorName", 
    "monitorOperator": ">", 
    "status": "critical", 
    "trigger": "monitor", 
    "url": "https://mackerel.io/orgs/.../alerts/2bj...",
    "warningThreshold": 1.4665636369580741

```
<br>

実際にアラート発火させサービスメトリックに投稿した結果がこちらになります。
![スクリーンショット 2019-12-19 7.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205006/b6b4725a-1c93-c600-6ce0-f43569fe5132.png)



countAlert*のサービスメトリックに対して、alertA、alertBの結果が投稿されています。

しかし、これだと意図通りに集計できません。
同一nameで同一時刻にサービスメトリックを投稿すればvalueは増加していくと何故か思い込んでいたのですが、
もちろんそんなことはなく、valueは新しい投稿で上書きされます。
(最初に気づけよという話なのですが、メトリック投稿するまで気づきませんでした…)


## 急
思ったようにアラートを集計できなかったというまとめになってしまったのですが、
Mackerelがwebhookで飛ばせる情報には、有益な項目が多々含まれていることがわかったので、
アラート集計に限らず試していければと思います。
[selenium]chromedriverのバージョンエラーが出たときの対処法

## 背景
seleniumを実行しようとしたら突然以下のエラーが表示されchromeが起動しない。
起動しないというかブラウザウィンドウは一瞬起動しようとするけど即落ちてエラーになる。

```
session not created: This version of ChromeDriver only supports Chrome version 77 (Selenium::WebDriver::Error::SessionNotCreatedError)
```

chromedriverがChromeのバージョンに対応していませんよとのこと。
対処してみた

## 環境（ざっくり）
* Mac Mojave
* chrome(79.xxxxxxx)
* selenium + ruby
* chromedriver


## 対処
#### 1. 以下のコマンドでchromedriverの在り処を把握しておく

```
$ which chromedriver
```
(多分 `/usr/local/bin/chromedriver` にあると思います )



#### 2. インストールされているchromeのバージョンを確認
chrome > 環境設定 > chromeについて で確認できます
<img width="1492" alt="スクリーンショット 2019-12-19 11.06.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499809/5479b650-dad4-6f7d-8860-5da797204c56.png">



#### 3. chromeのバージョンに対応したchromedriverをダウンロード
以下のサイトでchromeのバージョンにあったchromedriverをダウンロードしましょう
http://chromedriver.chromium.org/downloads

マスターバージョンがあっていれば大丈夫です。多分(自分はそれで動きました)。


#### 4. ダウンロードしたバイナリを設定する
zipファイルがダウンロードされるので解凍。
解凍するとchromedriverが表示されるので、それを手順1で確認した既存のchromedriverに上書きしましょう。
(※解凍先のディレクトリがDownloadディレクトリである想定)

```
$ mv ~/Downloads/chromedriver /usr/local/bin/
```
上書き完了！

これで動くはず。

## その他
当方の環境では selenium + ruby でやっていますが別にrubyじゃなくても同じような手順で解決できるんじゃね？と素人目に思っている次第です。はい。

## 参考にした記事
https://qiita.com/H2O_HoriHori/items/ad7f9855cfc20b995c42
https://qiita.com/y-agatsuma/items/ea2c9845ee0a931d5c9c
令和元年！活発なテキストエディタはどれだ！！

おはようございます、こんにちは、こんばんわ。

今回はテキストエディタについて書きます。
きっかけはテキストエディタを変えようかなと思っていて、どうせなら活発なものがいいなと思ったからです。
この記事は特定のテキストエディタの**有用性や機能は考慮せず**、ただ活発かどうかを見比べる記事で、フロントエンドエンジニア向けの記事となります。
ちなみに自分が使っているテキストエディタは**Brackets**です。

#フロントエンドエンジニアがよく使いそうなテキストエディタ
有名なエンジニア御用達の**vim**や**Emacs**といったテキストエディタはソフトウェア開発をしているつよつよエンジニアが使っているイメージです。
国でいうとアメリカとロシアのような大国、今回のテキストエディタ比較に出すのは恐れ多いので、一旦存在を忘れましょう。
以下が比較するテキストエディタ達です。

- VSCode
- Brackets
- Atom
- Sublime text3

王道中の王道（macOSでも使えるやつ）のラインナップとなりました。
フロントエンドエンジニアといえばキャッチアップ、キャッチアップといえばフロントエンドエンジニア（**偏見です**）
そんな我々が活発さを見比べず、誰が見比べますか。

という訳で、全てのフォーラムや拡張機能の数、直近のアップデートの数などを適当に見比べていきます。
**※全て２０１９年12月19日時点での数値になります。**

##VSCode
昨年ぐらいからシェアのトップに躍り出たらしいテキストエディタ。
実力の程は・・・！！

###2019年アップデート回数
11回
GitHubのissueの反映がほとんどでした。
かなり活発です。
###拡張機能の数
15134
対応しているプログラミング言語の数が他のテキストエディタに比べて多いので、その分多いのかな？
**vim**や**Emacs**のキーバインド機能を追加する拡張機能もありました。
###今年のフォーラムの投稿数
19,189
圧倒的に多い、活発。
※VSCodeのgithubに質問はstackoverflowと書かれていたのでそこを参照。
※stackoverflowで今年アクティブな質問のみの数になります。

##Brackets
ライブプレビューやpsdが表示できたりと驚きを与えてくれたテキストエディタ。

###2019年アップデート回数
1回
約2年ぶりのアップデート。
既に完成しきっていると見るか活発ではないと見るか・・・
アップデート内容はセキュリティー更新でした。
###拡張機能の数
約5,000
標準の機能で十分と見るか活発ではないと見るか・・・
使っているテキストエディタだからってフォローしている訳では決してありませんよ...??
※githubのbracketsが含まれているリポジトリの数で、C言語などが使われているのは関係のないリポジトリのため、それらを引いてざっくり約5,000としました。
###今年のフォーラムの投稿数
1,313
googleのgroupがありましたが、今年の投稿は20数件でした。
（もうフォローできない・・・）
※フォーラムやコミュニティーが見当たらなかったためstackoverflowを参照
※投稿数はbracketsとadobe-bracketsのタグの検索結果の合計値

##Atom
Microsoftに買収されたGitHubが開発元ですが、Atom君の立場は・・・

###2019年アップデート回数
6回
ちゃんとElectronを最新にしたりと精力的にアップデートがされている印象でした。
###拡張機能の数
8,623
もうすぐ10,000の大台。
公式サイトではトレンドや新着などでカテゴリ分けをして表示していたりと取っつきやすそうでした。
###今年のフォーラムの投稿数
1,908
あまり数は多くないですが、AtomのSlackがあるみたいので、そっちで済んでるのかもしれないですね。

##Sublime text3
誰もが一度は触ったことがあるんじゃないかと思うぐらい有名。
期待大です。

###2019年アップデート回数
3回
数は少ないですが、OSSではないことや前バージョンの存在を考えると少なくないのかなとも思えます。
※アプリケーションのSublimeText < changelogに記載されています。
###拡張機能の数
14,708
やはり、歴史が長いだけあって拡張機能も多いですね！！
あとは他のテキストエディタに比べると標準機能は強力ではないも関係しているかもしれませんね...!!
###今年のフォーラムの投稿数
2,177
VSCodeの前では霞んでしまいますが、2,000を超えてくるのはsublimeだけです。

#評価方法と結果
各方向からの見比べが終了したので、評価をしていきたいと思います。
評価方法は各比較項目で1位から4位に4点から1点を与え、合計点が多い方がより活発とします。
以下結果となります

- VSCode - 12点
- Brackets - 3点
- Atom - 7点
- Sublime text3 - 8点

VSCodeがぶっちぎりの1位でBracketsがぶっちぎりの最下位でした。
VSCode触ってみようかなぁ・・・

#感想
見比べみたいなことをしましたが、あくまで活発さを比べただけですので、これを使った方がいいとかこれが一番とかではありません。
どれも特徴があって素晴らしいテキストエディタですので、できれば全部触ってみて自分にあったテキストエディタを見つけてみてください。
ちなみに自分がBracketsを使い始めた理由は機能もありますが、なんかエンジニアっぽくておしゃれと思ったからです。

ツッコミどころ満載の比較でしたか、ゆるくやっているので大目にみてください。
こういう見比べ方あるよ！とかこのテキストエディタ入ってねーぞってのがありましたら、お気軽にコメントしてください。
気が向いたらアップデートします。

**参考**
各テキストエディタの公式サイト
各テキストエディタのGitHub
各テキストエディタのstackoverflow
RustでRc<RefCell<T>>する


# 目的
RustではRc\<RefCell\<T\>\>が使われることが多い。
３段活用みたいなRustコードを1段ずつ書いてみる。

なお、Outputはすべて`[1, 2, 3, 4, 5]`である。


## コード

### T

```rust:main.cpp
fn append(data:&mut Vec<i32>){
    data.push(4);
}

fn main(){

    let mut data = vec![1,2,3];
    
    append(&mut data);
    
    data.push(5);
    println!("{:?}", data);

}
```


### RefCell\<T\>


```rust:main.cpp
use std::cell::RefCell;

fn append(data:&RefCell<Vec<i32>>){
    data.borrow_mut().push(4);
}

fn main(){

    let data = RefCell::new(vec![1,2,3]);
    
    append(&data);
    
    data.borrow_mut().push(5);
    println!("{:?}", data.borrow());

}
```

### RC\<RefCell\<T\>\>


```rust:main.cpp
use std::cell::RefCell;
use std::rc::Rc;

fn append(data:Rc<RefCell<Vec<i32>>>){
    data.borrow_mut().push(4);
}

fn main(){

    let data = Rc::new(RefCell::new(vec![1,2,3]));
    
    append(Rc::clone(&data));
    
    data.borrow_mut().push(5);
    println!("{:?}", data.borrow());

}
```



## こういうことはできない
**コンパイル通らない例**
RcはRead-onlyで使うためのもので、上記RC\<RefCell\<T\>\>を使わなければならない

```rust:main.rs
use std::rc::Rc;

fn append(Rc<Vec<i32>>){
    data.push(4);
}

fn main(){

    let mut data = Rc::new(vec![1,2,3]);

    append(Rc::clone(&data));

    data.push(5);
    println!("{:?}", data);

}
```


## make_mutはおすすめしない

```rust:main.rs
use std::rc::Rc;

fn append(mut data:Rc<Vec<i32>>){
    Rc::make_mut(&mut data).push(4);
    println!("append: {:?}", data);
}

fn main(){

    let mut data = Rc::new(vec![1,2,3]);

    append(Rc::clone(&data));
    println!("main@1 {:?}", data);

    Rc::make_mut(&mut data).push(5);
    println!("main@2 {:?}", data);
    
    Rc::make_mut(&mut data).push(5);
    println!("main@3 {:?}", data);

}
```


Output

```
append: [1, 2, 3, 4]
main@1 [1, 2, 3]
main@2 [1, 2, 3, 5]
main@3 [1, 2, 3, 5, 5]
```

参照カウンタの値で挙動が変わるらしい。
ChromeのデベロッパーツールのコンソールでJavaScriptのライブラリをちょこっと使いたいとき

# はじめに
CDNがあるライブラリ限定となります。
環境作るのめんどくさいときに役立つかと思います。

## 例
試しにmoment.jsをコンソールで使えるようにします。

```.js
const script = document.createElement('script')
// scriptタグを作る

script.src = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.0/moment-with-locales.js'
// srcにCDNのURLを入れる

document.getElementsByTagName('head')[0].appendChild(script)
// headタグにscriptタグを入れる

const now = moment()
now.toDate()
// Thu Dec 19 2019 11:00:54 GMT+0900 (日本標準時)
```
エンジニア未経験者が、メンティとして意識して良かった３つの事

この記事は ZOZOテクノロジーズ [#5 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech5) 19日目の記事です。
昨日は、@hmsnakrさんの[VSCodeでのSQL Server(MSSQL)の開発](https://qiita.com/hmsnakr/items/0e9ccc94eeb3eb7f2e08)でした。

# 前書き

エンジニア未経験でサーバーサイドの担当部署に異動し、現在２年目になります。
未経験時にメンターを付けて頂き、OJTで業務をしてきた中で、「メンティとして意識すると、開発・相談・質問がしやすくなった事」を３点にまとめました。
個人的な経験がベースの内容となっていますが、以下のような方の参考になればと思います。

・エンジニア未経験で入社／部署異動した方
・OJTでエンジニア業務をスタートした方


# ①書きたい処理を日本語で書く

![book_sakubun_kodomo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442135/d213cdb0-246c-a0e8-776c-c130363f0e0a.png)


コードを書くこと自体に慣れていないうちは、「こういう処理を書きたい→そのままコードとして書く」というやり方自体に手間を取られます。初めは処理の型や定型文の蓄積がないので、頭の中だけでは「想定の処理→コードに落とし込んだ記述」への変換がしにくいためです。
なので、【コードを書くこと】に慣れない間は、**「まず書きたい処理を日本語で書く→それをコードに翻訳する」**という意識で書き方を分解すると、コーディングへの心理的な抵抗が少なくなり、手を動かしやすくなると思います。

イメージとしては、下記のような形です。このベタの日本語を、コードに置き換えていくイメージです。

```
もし、明日晴れだったら
    自転車で行く
もし、明日雨だったら
    傘をさして徒歩で行く
上記以外
    徒歩で行く
```



上記のようなやり方をすることで、自分の理解を日本語でアウトプット出来ているため、開発に詰まった時も、**自分の理解レベルを可視化した状態** でメンターへの相談・質問をする事ができます。「一体どこでつまっているのか？」が見える化されているので、メンターとのコミュニケーションも円滑になります。自分にとっても、「いま何が分からないのか分からない」という混乱した状態を避けやすくなります。


# ②質問は選択式にする

![wakaremichi_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442135/24b9877b-8fe7-93d8-9e5b-7cf66b7a1632.png)


開発や仕様調査に詰まった際に、「～が分からない」という【状態】をそのまま相談すると、「どこまで分かっていて、どこからが分かっていないのか？」という理解レベルの共有が難しくなります。

そのため、「AとBという処理を考えたが、どちらがベターか？」「この仕様はAという理解、Bという理解、どちらの方が正しいか？」「～という課題があるので、～を対策をしたいと思うが、良いか？（Yes or NO）」という選択式の質問として疑問を分解できていると、「自分の理解レベルを共有」＋「メンター側の考えや選択時の基準」を引き出しやすくなります。
また当たり前ですが、メンターはメンティの質問や相談の他にも、並行で業務をしています。そのため、メンターの思考のリソース＋時間を余計に奪わないという意味でも、質問を整理→選択式にするメリットはあると思います。

# ③素直に分からないと伝える（自力の調査時間を設定の上）

![kyosyu_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442135/c33230b6-6881-b87b-5dca-15cf6eb3cef7.png)


３つの中で、この点が一番大事だと思います。
開発や調査内容によっては「そもそも何がなんだか分からない。。」という状態になる場合もあります。その場合、①のように理解を日本語で書き出すこと、②のように選択式に洗い出すことが難しくなります。今まで全く触ったことのない機能の改修や、新規案件で要件の作成から関わる場合、上記のような ***「理解のスタートとなる地点が分からない」*** という状態になりやすいです。

そういった際は、自力で調査・理解する時間に **30分** の制限を設けます。この時間をオーバーしても分からない時は、それ以上調査しても、自力では理解できない可能性が高いです。そもそもの調査のスタート地点が間違っていたり、押さえるべき要件が抜けていたりします。そういった時は、メンターなど他人の目を一度借り、軌道修正をした方が良い場合が多いです。

仮に自分が大規模プロジェクトの一部ファイルの開発にアサインされた際、上記のような修正を挟まなかったとすると、
・プロジェクト全体に関する理解不足を解消しないまま進む
・終盤で理解不足による開発不足が発見される
・関わっている人の開発タスクにマイナスの影響を及ぼす
という、避けたい事態に陥ります。

上のような状況を防ぐ意味でも、
1：制限時間を設けた上で理解（分解）する
2：理解できない時は、メンター（場合によってはプロジェクの責任者）に素直に分からない状況を伝える
3：メンターから貰ったフィードバックを、理解できるレベルまでテキストベースに落とし込み、共有・内容確認して貰う
という流れが効率的だと思います（蛇足ですが、テキストに落とし込むのは、①と同じく自分の理解を可視化・共有しやすくするためです）。
「そもそも～という事が分からなくて困っている」と素直に伝える勇気も、エンジニア経験の浅いメンティには、大事な意識だと思います。ちなみにメンターと朝会や夜会を設定→その日の疑問点等をまとめて話す時間があると、上記のような相談もしやすくなると思います



# 参考サイト

・イラスト
https://www.irasutoya.com/
TA-Libをdockerコンテナにインストールする

AnacondaにTA-Libをインストールする
https://mrjbq7.github.io/ta-lib/index.html


DockerfileのTA-Libの部分を抜粋

```
FROM continuumio/anaconda3:2019.03
～～～
update等
～～～
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
  tar -xvzf ta-lib-0.4.0-src.tar.gz && \
  cd ta-lib/ && \
  ./configure --prefix=/usr && \
  make && \
  make install
RUN pip install TA-Lib
RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz
```
Javascript 文字列検索  indexOf() のちょっとした罠

## 公開後追記
「JS 文字列 存在確認」　とかで検索すると `indexOf()` を使う方法がたくさん紹介されてますが、もっといい方法がありました。

@ttatsf さんよりコメントで 

>可能なら、[String.prototype.includes()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/includes) を使ったらいいですね。
>


というご指摘をいただきました。

```javascript
"abcdefg".includes("abc") // true
```

単純な文字列の有無、存在するかどうかを知りたいときには `String.includes()` を使う方が、より明確であり適切。

追記おしまい

## ちょっとした罠

気軽に文字列検索したいとき、正規表現使ったりするほどでもないなというとき、indexOf()を使いたい。

ただそんなとき、

```javascript
Var string = "abcdefg";
if( string.indexOf('abc') ){
	// true
	console.log('true')
}else{
	// false
	console.log("false")
}

```


みたいに書いたとしたら


```zsh

false
```

とでてくる。

## なんでfalseになるのか？

これはindexOfの返り値は「True/False ではなく ヒットした文字列の出現位置」であり、なおかつ「1文字目は0番目」という仕様が関係している。  
つまり、「0番目にヒットした」という意味で `string.indexOf('abc')` の返り値は `0` となり暗黙変換によって `0 = false` として処理されることによる。。  

厳密にfalseを取るためには、マッチしなかったときの返り値である -1 と比較してあげないといけない。


```js

Var string = "abcdefg";
if( string.indexOf("abc") !== -1 ){
	// true
	console.log("true");
}else{
	// false
	console.log("false");
}

```

こうしてあげると正常。
決して条件式をそのまま突っ込んではいけない。

## ビット反転演算子 `~` を使うケース

たまにビット否定演算子 `~` を使って

```js

Var string = "abcdefg";
if( ~string.indexOf("abc") ){
	// true
	console.log("true");
}else{
	// false
	console.log("false");
}

```

としているソースコードがあるが、これは見落としたり直感的・一般的ではないと思うのでよっぽど軽量コーディングを心がけているチームでなければ導入しないほうが無難だと思う。

ちなみにこれが成立する理由は

> 任意の数値 x のビットごとの NOT 演算は、-(x + 1) を出力します。例えば、~5 で -6 を出力します。

[ビット演算子 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(Bitwise_NOT))


とある通り。つまり以下のような変換を行なっていることになる。

```js
~( -1) => 0  // 暗黙変換によりfalse
~ 2    =>  -3 // 暗黙変換によりtrue 
```

これはjsにおける「数値において0はfalse、0以外はtrueとする暗黙型変換」を利用したものだが、実質的には T/F で判定しているわけではないため、筆者はちょっと不安を覚えてしまう。

余談にはなりますが、ビット変換がなぜ1ずれるのかは2進数の性質上「正の数の最小値は0」であり、「負の数の最小値が-1」というのが理由。
気になる人は、符号付の2進数について調べてみると良いと思います。
Reactで親から子のメソッドを実行するサンプル

# はじめに
Reactにおいてコンポーネント間のメソッド実行はReduxなど使ってやるのが一般的ですが、
さくっとつくりたいアプリケーションにReduxは荷が重いです。

また、子が親のメソッドを実行するのはpropsで受け取った関数を呼べば良いだけですが、
親が子のメソッドを実行するのは意外と面倒みたいです。(なかなか調べても出てこない)

# サンプル
今回のサンプルはuseRef, useImperativeHandle, forwardRefを使って子メソッドの実行を実現しています。
codesandboxにコピペしてmaterial-uiをADDすればすぐ動きます

```jsx

import React, { useState, useRef, useImperativeHandle, forwardRef } from "react";
import Button from "@material-ui/core/Button";

export default function Parent() {
  const parentAdd = () => {
    Children.current.plus()
    console.log('親です')
  }
  return (
    <div>
      <Children parentAdd={parentAdd} ref={Children}/>
      <Button onClick={parentAdd}>親add</Button>
    </div>
  );
}

let Children = (props, ref) => {
  const [state, setState] = useState(1);
  const inputRef = useRef()
useImperativeHandle(ref, () => ({
  plus: () => {
    plus()
  }

}))

  const plus = () => {
    setState(state + 1);
  };
  return (
    <div ref={inputRef}>
      <div>{state}</div>
      <Button onClick={plus}>子add</Button>
    </div>
  );
};
Children = forwardRef(Children)

```

# 動き
親と子どちらのボタンを押しても数字が反応します。
### 親の持ち物
　・子のplus()を実行する「親addボタン」←これがやりたいこと
　・子

### 子の持ち物
　・数字の描画
　・数字をインクリメントする関数plus()を実行する「子addボタン」


# 注意
コンソールに以下のWarningが出るのでご注意ください。

```
Warning: Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: an object with keys {$$typeof, render}.
```
構成管理を覚えた新卒SREがdotfileを自動化させる

## はじめに

Leverages Advent Calendar20日目を飾ります、SREの @t-kusakabe です。
毎日yamlを書いてたりします。

## 構成管理について

レバレジーズではansibleを使って構成管理をしています。
インフラ未経験だった僕は、それまで名前こそ知っていましたがまったく使ったことがありませんでした。
IaC。素晴らしいですね。
ということで今回は覚えたてのansibleを使ってみたいと思います！


## dotfile

皆さんdotfile育ててますか？
普段から自分が愛用してるツールは自分用にカスタマイズして使うことで生産性が向上します。
しかし定期的にメンテナンスをしてあげないとすぐに冗長になってしまいますよね。
とりあえず適当にファイル作ってみたりvimrcとかに追記しまくったりなど。。。


僕のdotfileも2年ほど育ててきましたがかなり扱いづらい感じになっていました。。。


```shell:2年ほど運用してきたdotfile
.
├── emacs
├── emacs.d
│   └── init.el
├── gitconfig
├── myclirc
├── nvim
│   ├── ctags
│   ├── init.vim
│   └── userautoload
│       ├── basic.vim
│       ├── plug.vim
│       └── statusline.vim
├── plantuml
├── sh
│   ├── apt.sh
│   ├── ather.sh
│   ├── brew.sh
│   └── symbolic-link.sh
├── tigrc
├── tmux.conf
├── tmux.conf.debian
├── tmux.conf.osx
├── vscode
│   ├── keybindings.json
│   └── settings.json
└── zshrc
```

`sh` 以下にShellScriptを置いてShell芸で各種ファイルをばら撒いたりしていました。
中には何をしているのかわからないものがあったり、手作業でなんとかしているものもあって自動化からは程遠い状態でした。。。
また、PCを買い替えたりクリーンインストールをする度にどうやって環境作っていたっけ？と思いながら設定していました。
非常に効率が悪いですし不便ですね。つらい。。。

## ansibleでどうやった？

というわけでちょっと早めの大掃除も兼ねてdotfileをansible化してみました。
ひとまず以下のような形に落ち着いています。

```shell:ansibleにしてみたやつ
.
├── ansible.cnf
├── inventories
├── roles
│   ├── brew
│   ├── common
│   ├── desktop_app
│   ├── emacs
│   ├── git
│   ├── ideavim
│   ├── macos
│   ├── mycli
│   ├── npm
│   ├── nvim
│   ├── plantuml
│   ├── tig
│   ├── tmux
│   ├── vscode
│   └── zsh
└── site.yml
```

各Taskでしていることは単純で、Installする必要があるものはInstallする。
その後にsymlinkを貼る、といったことくらいしかしていないです。

Vim周りだけみてみます。

```shell:Vim周り
roles/nvim/files
├── ctags
├── init.vim
└── userautoload
    ├── basic.vim
    ├── plug.vim
    └── statusline.vim
```

大体こんな感じです(ややこしいので細かいのは省きましたw)
`basic.vim` にキーバインド等の設定、 `plug.vim` にプラグイン関係、 `statusline.vim` にはステータスラインに関する設定みたいな感じに分けてファイルを置いています。


Taskの中身はこんな感じです。

```yaml:roles/nvim/tasks~
# 必要なものをInstallする
- name: Install vim-plug
  get_url:
    url: "{{ vim_plug_url }}"
    dest: $HOME/.config/nvim/autoload/plug.vim

# 設定ファイルばら撒く
- name: Create symbolic link init.vim
  file:
    src: "{{ansible_env.PWD}}/roles/nvim/files/init.vim"
    dest: $HOME/.config/nvim/init.vim
    state: link
```

たったこれだけでもVimを使い始めるところまでを自動でしてくれるのでとても便利です！

HomebrewでInstallしているものなどは、YAMLで一覧に出来るのでとても便利でした。(別にansibleじゃななくても出来ますが。。。)
`brew install` しているもの、 `brew cask install` しているもので分けたりすることで管理しやすくしています。

```
└── defaults
    └── main
        ├── brew.yml
        └── brew_cask.yml

```

それぞれRole単位でディレクトリを分けて管理出来るのでとても使いやすくなりました。
実際実行するときは `ansible-playbook -i inventories site.yml` とするだけで、Homebrewで普段使っているものをInstallしてきて、VimやZsh、Tigなどの設定ファイルを自動で配置出来るようになりました。

## 最後に

いかがでしたでしょうか？
dotfileをansibleで管理することで自分のPCがどういう風に構成されているのかがわかるようになりました。
またいつでも自分のPCを気軽にCleanInstallすることも出来るようになりました。
また拡張する時もRoleごとに別れているので見通しがよくなったと思っています。

是非皆さんも年末の大掃除を兼ねてdotfileの整理をして気持ちよく新年を迎えていただければなと思います。
(クリスマスよりお正月が楽しみ)

明日は @kilig さんです！楽しみ！
はじめまして、自己紹介です。

苫小牧高専1年の上山龍人です。今回は、アドベントカレンダーのためにブログを開設しました。
>[アドベントカレンダー - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC)
アドベントカレンダー (Advent calendar) は、クリスマスまでの期間に日数を数えるために使用されるカレンダーである。待降節の期間（イエス・キリストの降誕を待ち望む期間）に窓を毎日ひとつずつ開けていくカレンダーである。**すべての窓を開け終わるとクリスマスを迎えたことになる。**

つまり、全員がこのブログを書き終わらないとクリスマスは迎えられないわけですね()。

さて、僕はいまPython3の勉強をしていますが、classやメソッドについての理解が曖昧で、開発を始めるには、まだまだ勉強が必要です。数学も勉強しました。微分係数と導関数は求められるようになりましたが、微分はまだ難しそうです。


最後に、Qiitaでブログを書いていて思ったのですが、Markdown式はHTMLも使えるとのことなので、やはりHTMLは勉強すべきなのかなと思いました。
Excelで文字が自動変換されるのを止める方法

- 環境
    - Windows 10 Pro 64bit
    - Microsoft Excel for Office 365 MSO 32ビット

# 文字を入れていると勝手に変換されてイライラする
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/fa51d7bc-053f-06f3-7cab-4e20293cc815.gif)

# 自動変換を止める方法
1. [ファイル] > [オプション] > [文章校正] > [オートコレクトのオプション]ボタンでダイアログを開く
2. [入力中に自動修正する]をOFF > [OK]ボタンでダイアログを閉じる
3. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/bf339567-6faf-4f52-d1ce-b9122cff4366.png)

参考 : [自動変換が勝手にされてしまう～自動変換を止める方法～ - Excel (エクセル) コーヒー ブレイク](https://www.newcom07.jp/EXCEL-database/blog/excel_coffee_break/2014/03/post-253.html)

# 自動変換が止まる
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/9f77e4ce-2ae4-ce3c-68df-1028cc84bf88.gif)
OSSに関するコンプライアンス体制構築の際の留意点

本日は弁護士の[野中さん] (https://www.mofo.jp/attorneys/mofolo/_takahiro_nonaka.html) に登場頂きます！（諸事情により遠藤が投稿してます）

#はじめに
はじめまして。弁護士の野中高広です。最近は、バッティングセンターにはまっています。空振りが約２割ですが（笑）。
ところで皆さんの会社では、OSSのリスクの問題について、どの程度のかたが認識しておられるでしょうか？コンプライアンス体制についても最低限整っているといえますでしょうか？
本日は、OSSに関してコンプライアンス体制の構築をするうえでの留意事項について、すでに皆さんご存知のことがほとんどであるとは思いますが、簡単に検討してみたいと思います。

#どうして体制を構築する必要があるのか？
これまでにOSSに関して問題となってきたいろいろな事例を見てみますと、第三者によるリバースエンジニアリングなどによって、OSSの利用が発覚し、OSSライセンス違反を指摘されるような場合があります。OSSのライセンス違反の指摘を受けた場合、謝罪やソフトウェアの差し替えを行なったり、ソースコードの公開などについて**迅速かつ適切な対応をとる**ことが重要と言われています。しかも、すばやく適切な対応を行なえば、すぐに訴訟に発展するわけではありませんし、欧米の事例を検討していますと、こうした対応の遅れが係争へと発展しているケースが多いともいえます。

#留意すべき事項は？
そのため、いろいろな事態あるいはリスクに事前に備えておくことが必要になるといえそうですが、実際にコンプライアンス体制を構築する際には、どのような点について特に留意する必要があるのでしょうか。会社によって進捗状況は様々だと思いますが、以下で、いくつか基本的な事項について触れてみたいと思います。

·        まず、OSSライセンスの利用にあたってのコンプライアンス強化を図るために、OSS利用についての**内部規程の作成**や、**内部規程遵守のための社内体制と仕組みの構築**が求められるといえます。その際に、社員の方への内部規程の周知・教育に加えて、社内・社外向けにOSS利用についての問い合わせ窓口を設置することなどもセットで検討しておくことが有効といえるでしょう。

·        その前提として、例えばGPLのソースコードの公開範囲についてなど、様々な解釈があり得るケースについては、この分野の有識者や専門家を交えて十分に検討を重ねて、自社の**見解を統一**しておくことが必要となります。その過程で社内で議論を積み重ねて、各種事例や先例についての知識や理解を深めつつ、多くの人が問題意識を共有することこそが有益ともいえるでしょう。

·        また、最近では様々な有用なソフトもありますが、**ソフトウェアの検査**を行なうことも肝といえます。ソフトウェア開発の初期段階、委託先からソフトウェアが納入される時、あるいは製品の出荷前などに、OSS検出ツールなどを利用して、意図しないOSSが混入していないかを十分に検査する必要があります。特に、**ソフトウェア開発の委託をする際**には、利用するOSSとその利用条件の開示を求めたり、あるいはOSSライセンス違反をした場合の責任分担やソースコードの調査義務などについても念のため盛り込んでおくことも検討するとよいでしょう。ここらあたりの話については、個人情報の取扱いが第三者に委託される場合の留意事項とパラレルに考えることができるかもしれません。

·        さらに最近では、**法務デューデリジェンス**による確認も重要となってきております。例えば、M&Aにおいて、買収した会社がOSSライセンス違反をしている場合もあり得るため、法務デューデリジェンスで、OSSに関する問題をレビューしていくことも、今後は一般的になっていくものと思われます。

#おわりに
以上、ごくごく簡単に見てきましたが、実際にいろいろな措置を導入していくに当たっては様々なハードルも考えられます。なかなか理解が難しい分野でもあり、問題意識を共有すること自体に苦労することも多々あるかと思います。
本日のテーマが、皆さんの会社のコンプライアンス体制構築がさらに進むうえで少しでもお役に立てれば幸いです。

#明日のテーマは…
明日は、Japan WGの設立当初から中心的な活躍をされているパナソニックの加藤さんから「OpenChain Japan WGの活動で集まった事例」についてご紹介いただく予定です。
自社の体制を構築する上で一番気になる「他社はどうしているのか」がわかる貴重な情報ですので、ぜひご期待ください。
.nill , .empty, .blank, .present？の違い

Ruby on Railsで値の存在またはオブジェクトの状態を確認するために使用できるメソッドがいくつかあります。 Rubyには.nilと.empty ? があります。Rails ActiveSupportには.blankと.present？があります。
#nil?
.nil? ObjectクラスのRubyメソッドです。 すべてのクラスを受け継ぐかのオブジェクトのクラス#nil? 任意のオブジェクトで使用できます。 Nilの場合はtrue、それ以外の場合はfalseを返します。 これは、空の文字列がnilではなく、空の配列がnilではないことを意味します。

```
nil.nil?
=> true
"".nil?
=> false
[].nil?
=>false
```
#empty?
.emptyは、オブジェクトの長さ== 0を意味します。このメソッドは、文字列、配列、ハッシュで使用できます。

```
"".empty?
=> true
```
ただし、空白の場合、改行またはタブ.emptyはfalseを返します。 空白、改行またはタブも文字としてカウントされます。

```
" ".empty?
=> false
"\t\n".empty?
=> false
```
Array ,hashes, set の場合、要素がない場合はtrueを返します。

```
[].empty?
=> true
{}.empty?
=> true
```
#blank?
.blank？ ActiveSupportのRails method です。
これは、nil、false、empty、empty stringに対してtrueを返します。

```
nil.blank?
=> true
false.blank?
=> true
"".blank?
=> true
" ".blank?
=> true 
[].blank?
=> true
{}.blank?
=> true
```
#present?
.present？も  Rails method です。 .blank?の反対です.

```
[].present?
=> false
" ".present?
=> false
false.present?
=> false
[1, 2, 3, 4, 5].present?
=> true
```
これがお役に立てば幸いです :)
PHP7.4対応版Laradockを、ビルドしただけの話（2019/12/17時点）

この内容は2019/12/17時点の話です。
あなたがこの記事をご覧になっているころには、LaraDockが対策済みになっているかもしれません。
（きっとこの記事を書いている最中にでも修正されているに違いない。）

# 始めに
本記事はDocker ComposeのプロジェクトであるLaradockのPHP7.4対応版の、以下のサービスを動作させることを目的としています。

1. workspace
2. nginx
3. php-fpm
4. php-worker
5. mysql

他のコンテナの動作については言及しません。

# 各コンテナをビルドする際に変更したファイルと変更箇所
## 1. mysql/my.cnf
MySQL8を使いたいのでデフォルトに認証方式を変更する。

```text:mysql/my.cnfの最終行に追記
+ default_authentication_plugin=mysql_native_password
```

## 2. php-fpm/Dockerfile
--with-libzipオプションがなくなったから削除。

```dockerfile:php-fpm/Dockerfileの54行目付近
-     docker-php-ext-configure zip --with-libzip && \
+     docker-php-ext-configure zip && \ 
```

## 3. php-worker/Dockerfile
oniguruma-devが必要らしい。

```dockerfile:php-worker/Dockerfileの32行目付近
-  supervisor
+  supervisor \
+  oniguruma-dev
```

--with-libzipオプションがなくなったから削除。

```dockerfile:php-worker/Dockerfileの70行目付近
-    docker-php-ext-configure zip --with-libzip && \
+    docker-php-ext-configure zip && \
```

# 追伸1
LaradockはPHPのiniファイルで、`error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT`と指定されているため、`array`か`string`以外の型に対して配列スタイルでアクセルするとNotice警告でエラー扱いになります。
依存関係のライブラリが対応していないケースがあるため、しっかり動作検証を行う必要がありそうです。
（実際に手元の開発環境で発生しました…。）

# 追伸2
[php本家ドキュメント(https://www.php.net/)](https://www.php.net/)の調子が悪いように感じる…。
📶【HTML】廃止になったXHTMLからHTML5への移行

## 内容

古いテンプレートファイルを確認したらいろいろと修正すべき部分があったので
まずはXHTML 1.0をHTML5に移行させる


🔴XHTML 1.0は正式に廃止されている模様
https://www.marguerite.jp/Nihongo/WWW/RefHTML/Appendix/About_XHTML_1.0.html

🔴これもSEO的に無意味

```hoge.html
<html lang="ja">
```
https://seopack.jp/seoblog/20161111-use-hreflang/

## やったこと

宣言等のタグをHTML5の記述に変更
以上！！

```hoge_xhtml.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
```

↓

```hoge_html5.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
```
[MySQL][utf8mb4][寿司ビール問題対応]既存のutf8データベース内容をutf8mb4に置きかえる手順

頻繁に実施したのでメモ。utf8で作成されていたデータベースをutf8mb4に置きかえる作業手順です。
もっと簡単にできるといいなぁ。

# 前提

- データベースインスタンスの文字セットは`utf8mb4`になっていること。`mysql utf8mb4`で検索すれば多数の記事あり

# 以下の手順を実行した環境

- RDS for MySQL 
- 移行元のMySQLサーババージョン(`mysql> select version();`) => `5.6.41-log`
- 移行先のMySQLサーババージョン(`mysql> select version();`) => `5.7.26-log`
- mysql client / mysqldumpのバージョン => `5.6.46`
- Amazon Linux2 上で実行

# 手順

## 概要手順

+ 既存データベース内容をダンプ
+ ダンプしたファイル内の`utf8`を`utf8mb4`に置き換え
+ データベース再作成(削除・作成)
+ `utf8mb4`化したダンプファイルをインポート

## 詳細手順

まずはデータベースをダンプします。

```bash
$ mysqldump -h <dbhost> -u<dbuser> -p<dbpassword> <dbname> > dump.sql
```

`utf8` を `utf8mb4` に置き換えます。下記では`sed`使ってますがもちろんどういう方法でもOKです。

```bash
$ sed -e 's/utf8 /utf8mb4 /g' ./dump.sql > ./dump_utf8mb4.sql
```

DB作成権限のあるユーザでmysqlクライアントに接続します。

```bash
$ mysql -u<user> -p -h <host>;
```

【オプション】データベースを削除。

すでに当該データベースを利用するアプリケーションが稼働していて、一時的にでも削除できない場合は、別データベースを作成・移行して、アプリケーションからの接続先を変更しても問題ありません。むしろダンプ失敗していたりして復元できない可能性も考慮するとそのほうが安全です。(上記で出力したダンプファイルは特定のデータベースには依存していません(`use database`も`create database`もない))

```bash
mysql> ★注意★ drop database <dbname>;
```

データベースを作成

```bash
mysql> create database <dbname> DEFAULT CHARACTER SET utf8mb4;
```

作成したデータベースに移動

```bash
mysql> use <dbname>;
```

`utf8mb4`化したダンプファイルをインポート

```bash
mysql> source dump_utf8mb4.sql;
```

# 動作確認

任意の文字列カラムにビール(🍺)、寿司(🍣)を入力してエラーがでなければOKです。

`utf8mb4`になっていなければ以下のエラーが発生します。🍣の場合。

```
SQL Error [1366] [HY000]: Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'カラム名' at row 1
  Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'カラム名' at row 1
```
iPad Proで遺伝研スパコン上で起動したJupyter notebookを使ってみた


@nigytaさんの記事[「遺伝研スパコンで Jupyter Notebook を利用する方法」]
(https://qiita.com/nigyta/items/6cb321735dba0a6215b2)で
iPad Pro(11インチ)でもできるかどうか試してみた。

## 使用ソフト
iOS 13.2.3
Terminus(遺伝研スパコン[^1]にssh接続できるよう設定済み)
Safari
[^1]: 遺伝研のスーパーコンピュータは国内の研究機関や大学に所属していれば利用できます（要申請、研究用途での利用）。

## やりかた
1. SafariとTerminusをSplit viewで立ち上げておく[^2]
[^2]: Terminusは画面上に常時表示しておく（バックグラウンドにしない）
1. Terminusでスパコンに接続、qloginしてノードを記録
1. Jupyter notebookの起動
上記記事の設定通り、
    - `netstat`で開いているポートを確認してから（この場合58888が空いていることを確認する）
    - Jupyter notebookのオプション```--ip=`hostname` --port=58888 --no-browser```をつけて起動
    - トークンをコピーしておく
    
1. TerminusでPort forwardingの設定
    - Port Forwardingを選択<br>
![IMG_0044 2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207005/32c95fbc-86ed-5999-63be-f6e9ac2823ed.png)
    - 設定画面<br>
![IMG_0046_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207005/855ef930-df82-7858-b6b4-83ac77c165d2.png)
    - qloginしているインタラクティブノードat029、ポート58888でJupyter notebook起動した場合
        - Label：表示名。自分がわかるように
        - Host：Terminusで接続している遺伝研スパコンのHost（terminusに設定しているものを選ぶ）
        - Port from：Jupyter notebookの起動時に設定したポート（この例では58888）
        - Destination：at029[^3]
        - Port to：8888(iPad側のポート)
[^3]: qloginするたびにノードがかわるので、毎回editする

1. Safariで　http://localhost:8888 を開く
1. トークンをペースト

## 追記
- Split viewにするのに苦労する時がある（不器用なので）
- ログインするたびにPort forwarding設定を書き換えないといけない

などでわりとめんどくさいので、よっぽどのことでなければ素直にPCから入った方が楽。
Terminusは、一度Hostの設定をしてしまえば使用感はPC経由と特に変わらないので、これからも使うんじゃないかと思う。
Nuxt.js に後から ESLint と Prettier を入れて困った時の解決策


[Nuxt の公式ドキュメント](https://ja.nuxtjs.org/guide/development-tools/#eslint-%E3%81%A8-prettier)通りに ESLint と Prettier を入れたら、ファイルの保存時に lintfix が走った後に formatter が走っているような挙動をした。結局 fix されていない。以下の json ファイルを `.vscode/settings.json` に書いて解決。

```.vscode/settings.json

{
  "eslint.validate": [
    {
      "language": "vue",
      "autoFix": true
    },
    {
      "language": "javascript",
      "autoFix": true
    }
  ],
  "eslint.autoFixOnSave": true,
  "editor.formatOnSave": false,
}
```

個人的なメモでした。

## 追記

「ESLint/Prettier併用で `<img />` が怒られる問題」
https://qiita.com/yoshinbo/items/3436face1a1b02f2542f

それでも解決しなかったら、以下を入れてみると良い。

 `yarn add -D eslint-config-prettier`

`yarn add -D eslint-plugin-prettier`
Nutanix Xi IoTを試してみよう(3) 関連リソース集


# はじめに
この記事は、[[2枚目]Nutanix Advent Calendar 2019](https://adventar.org/calendars/4014) 12月18日の分として作成しました。本記事の内容はこの日付の情報に基づいています。

これまでにXi IoTのトライアルの始め方、サンプルアプリを使った動作確認の方法をご紹介しました。
本記事では、Xi IoTに関連するリソースをご紹介します。

# Xi IoTのサイト、ドキュメント (ほぼ英語)
Xi IoTのサービス提供サイトや公式ドキュメントです。
- [Xi IoT日本語製品サイト](https://www.nutanix.jp/products/iot/)
- [Xi IoTサイト](https://iot.nutanix.com/)
- [Xi IoT Release Note](https://portal.nutanix.com/#/page/docs/details?targetId=Release-Notes-NTNX-IoT:Release-Notes-NTNX-IoT) ※
- [Xi IoT管理者ガイド](https://portal.nutanix.com/#/page/docs/details?targetId=Xi-IoT-Infra-Admin-Guide:Xi-IoT-Infra-Admin-Guide) ※

※印はmy.nutanix.comのログインが必要です。

# ハンズオンワークショップの資料(英語)
Xi IoTのハンズオンワークショップの資料が公開されています。ほとんどのワークショップはトライアルで提供される環境で実施することができます。

- [XI IOT - DATA PIPELINES - GETTING STARTED GUIDE](https://nutanix.handsonworkshops.com/workshops/64d8da4f-cdeb-49f6-9722-581e446f6a96/p/)
- [Xi IoT - Quick Start for MQTT Data Pipelines](https://nutanix.handsonworkshops.com/workshops/e64c519d-8f6a-438e-a0eb-3ba92046966d/p/)
- [XI IOT - QUICK START FOR AI INFERENCE](https://nutanix.handsonworkshops.com/workshops/2470db21-2e9a-47a3-bc25-be8eb7521a68/p/)
- [XI IOT - FACEFEED APPLICATION DEPLOYMENT GUIDE](https://nutanix.handsonworkshops.com/workshops/e1c32f92-1de8-4642-9d88-31a4159d0431/p/)
- [Xi IoT - Deepomatic Demo Application Guide](https://nutanix.handsonworkshops.com/workshops/0d137fc2-8fde-4210-a6cc-5300c693916e/p/)

# YouTubeの動画(英語)
Xi IoTのサービス概要やNutanixの年次イベントの.NextカンファレンスなどでのXi IoT関連のキーノートセッションがYouTubeで公開されています。英語ですが字幕を出すことができます。ビジョンやコンセプトなどを知るには一番の方法かもしれません。

- [製品概要](https://www.youtube.com/watch?v=4oQFNHKaKeM)
- [IoT Solutions World Congressのキーノート](https://www.youtube.com/watch?v=ctxrFZWAbWo)
- [.Next 2019 コペンハーゲンのキーノート](https://youtu.be/CLQLRgbV38s?t=2872)
- [.Next 2019 アナハイムのキーノート](https://www.youtube.com/watch?v=HhHFwJEtC7M)
- [.Next 2018ロンドンのキーノート](https://www.youtube.com/watch?v=I7ruBu0kj78)

# BLOGの記事(英語・日本語)

- [Xi IoT Blog](https://medium.com/nutanix-iot)(英語)
Nutanix Xi IoTチームが記事を投稿しているBLOGです。
- [konchangakita](https://konchangakita.hatenablog.com/)(日本語)
Kon-chanさんのBLOGです。展示会などで大人気の「映える」デモの製作について、詳細に解説されています。
- [p-iwaさんのBLOG](https://kanwa.blog/)（日本語）
別の記事でも紹介したBLOGです。Xi IoTのコンセプトやサービス概要が紹介されています。

# 終わりに
XiIoTの各種リソースをご紹介しました。まだまだ情報が少ないですが、ちょっとずつ増えてきています。こんなリソースもあるよという情報がありましたら、追記しますのでぜひお知らせください。