OmniAICreator/Qiita-1.07M huggingface dataset:
[XCTest] 非同期処理のテストについて備忘録

# 背景
URLSessionで作ったApiClientクラスのfetch処理をAlamofireを使った実装にリプレイスすることになり、
今回はテストにも慣れてきたのでTDDで進めようと試みました。

# 第1段階
元の関数でAPIのレスポンスをパースしてItemを10個拾うテストを書きます。
これは「テストがうまく動作するかどうか」のテストのような段階です。

```swift:ApiClientTests.swift
class ApiClientTests: XCTestCase {
  func testFetchItems() throws {
    var tenItems: [Item]?
    
    // URLSessionを使った
    // fetchItems(url: String, completion: @escaping ([Item]?) -> Void)
    ApiClient.fetchItems(url: "http://...10個返ってくるAPI...") { items in
      tenItems = items
    }
    sleep(4)
    XCTAssertEqual(tenItems.count, 10)
  }
}
// テスト成功♪
```

# 第2段階
Apiclient.fetchItems2という関数名でAlmofire版を実装する前にテスト側を書き直します。

```swift:ApiClientTests.swift
class ApiClientTests: XCTestCase {
  func testFetchItems() throws {
    var tenItems: [Item]?
    
    // Alamofireを使った
    // fetchItems2(url: String, completion: @escaping ([Item]?) -> Void)
    ApiClient.fetchItems2(url: "http://...10個返ってくるAPI...") { items in
      tenItems = items
    }
    sleep(4)
    XCTAssertEqual(tenItems.count, 10)
  }
}
// まだfetchItems2は実装していないのでテストは失敗
```

# 第３段階ここで問題発生
Apiclient.fetchItems2という関数名でAlmofire版を実装したのにテストがうまくいきません。

```swift:ApiClientTests.swift
class ApiClientTests: XCTestCase {
  func testFetchItems() throws {...}
}
// tenItemsがnilでエラーになる。
```
テストではなく実際にアプリを動かすと問題なく動くのですが、テストだけ失敗してしまう。
調査すると非同期がうまく動作していないようで、```testFetchItems()```の処理後に```tenItems = items```の処理がされているようです。


# 非同期処理のテストには```XCTestExpectation```
[XCTestExpectation](https://developer.apple.com/documentation/xctest/xctestexpectation)とはXCTestにおいて処理を一旦止めて非同期で走っている処理の**完了のお知らせ**```fulfill()```を待ってまた走り出すという動きができます。
これでテストもうまく動作するようになりました。

```swift:ApiClientTests.swift
class ApiClientTests: XCTestCase {
  func testFetchItems() throws {
    var tenItems: [Item]?
    
    // 待ち合わせ用
    let expectation = expectation(description: "非同期待ち")

    // Alamofireを使った
    // fetchItems2(url: String, completion: @escaping ([Item]?) -> Void)
    ApiClient.fetchItems2(url: "http://...10個返ってくるAPI...") { items in
      tenItems = items
      expectation.fulfill() // ここで完了のお知らせ
    }

    // ここで完了のお知らせを待ちます。
    // timeout: 4 とすると4秒待ってお知らせがなければテスト失敗として処理してくれます。
    waitForExpectations(timeout: 4) 

    XCTAssertEqual(tenItems.count, 10)
  }
}
// 無事テスト成功♪
```

# リプレイス自体は完了したが、一部の矛盾が解決しませんでした。
無事にリプレイスは完了して、非同期のテストについても問題なく実装できるようになったことにウキウキしていました。
しかし今度は第一段階のテストがなぜ成功していたのかが不明です。
これはまだ解決していないのですが、優先順位が低いので一旦後回しにします。
この記事書いた目的は**「忘れ去ってしまいそうなので備忘録」**として残したのもあるのですが、**「あわよくば通りすがりの優しいつよつよエンジニアさんが知見をこぼしてくれたりしないだろうか」**なんて期待もしてたりします。

### 参考にした記事や書籍

- [iOSアプリ開発自動テストの教科書](https://www.amazon.co.jp/dp/B07TF46F7T)
- [【Swift】URLSessionまとめ](https://qiita.com/shiz/items/09523baf7d1cd37f6dee)
- [Swift の HTTP ライブラリで苦しまないための自作 API クライアント設計]
(https://qiita.com/Kuniwak/items/a972ff2ade643799d1fe)
- [iOSで非同期処理のテスト: XCTestExpectationの設定値と使い方まとめ]
(https://qiita.com/ktanaka117/items/e452e5ca58545c303dc2)


 
@takehito-koshimizu
ありがとうございました🙏
今回の解決には至りませんでしたが、URLSessionのキャッシュ機能について知見が広がりました🤗

もし今後解決したら追記予定とします。

# 以上！！
JLCPCBで実装　KICAD

こちらの記事にすべて書かれている
https://junkbox.wicurio.com/index.php?JLCPCB%E3%81%AE%E5%AE%9F%E8%A3%85%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%28PCBA%29%E3%81%AB%E5%87%BA%E3%81%99%E6%96%B9%E6%B3%95

※BOM生成時のエラー対策
全角を含むパスは利用不可、半角でもスペースは使えない
https://make.kosakalab.com/eda/kicad5_bom-error/

※KiCADで「posファイル」に部品の位置情報が反映されない場合の対処法
http://www.kicad.xyz/pos-file/#st-toc-h-3
Oracle Analytics Cloudことはじめ

皆さんこんにちは。オラクルの分析ソリューションをご存知ですか？
オンプレミス環境以外にもクラウド環境が用意されています。
Oracle Analytics Cloud：分析ツール
Autonomous Database：自律型データベース
これらについてわかりやすく解説をしていきます。

まず初めに、分析ソリューションの顔である分析ツールのご紹介です。

１．ダッシュボード
様々な情報が一目でわかります。
![Dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/474ea4a9-d91f-c0db-5463-f3868d93a3ce.png)

２．セルフサービスAnalytics
自分のアイデアで情報を自由に分析できます。
![セルフサービスBI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251127/e5a20369-e27f-6ae5-266e-2ffde5950d3a.png)

オラクルっぽくないきれいな分析ツールです（笑）
次回以降でより詳細に何ができるのかについてお話していこうと思います。
Git MbedStudio mbed-os CodeCommit を使う

準備するものは以下。
### Git
Git-2.31.1-64-bit.exe
TortoiseGit-2.12.0.0-64bit.msi
TortoiseGit-LanguagePack-2.12.0.0-64bit-ja.msi
### Mbed
MbedStudio-1.4.1.exe
https://github.com/ARMmbed/mbed-os
mbed-os-example-blinkyを選択してビルド
mbed-os-example-blinky.binをボードのドライブにドラック＆ドロップ
### AWS
IAMのユーザー名とパスワード
CodeCommitのユーザ名とパスワード
Couchbase Server コンパクション解説 （付. 他のNoSQL~MongoDB, HBase~の場合）

# はじめに

本稿では、Couchbase Serverにおけるコンパクションについて解説します。

# コンパクション入門

## コンパクションのメカニズム
Couchbase のすべての挿入、更新、削除は、ディスク上のデータファイルに「追加」されます。
Couchbaseの追加専用エンジンは、最終的にはデータファイル内のギャップ(特にデータが削除された場合)につながり、コンパクションと呼ばれるプロセスを使用して再利用できます。


コンパクションの際には、新しいファイルが作成されます。その間、既存のデータベースファイルはそのまま残り、情報の格納やインデックスデータの更新に引き続き使用されます。このプロセスにより、コンパクションが行われている間もデータベースが引き続き使用可能になります。
コンパクションが完了すると、古いデータベースファイルが無効になります。その後、新しく作成されたデータベースファイルで受信更新が続行されます。その後、古いデータベースファイルがシステムから削除されます。

コンパクションは、Couchbaseサーバーの実行中にバックグラウンドプロセスとして実行されます。  データベース操作をシャットダウンまたは一時停止する必要はありません。

## 運用における留意点

コンパクションの運用にあたり、下記の要因に注意を払う必要があります。


### 余裕のあるリソース状況
コンパクションプロセスはディスクとCPUの両方を集中的に使用します。

### 十分なディスク領域
コンパクションは新しいファイルを作成するため、コンパクションを行うために現在のデータベースファイルのディスク領域の2倍が必要になる場合があります。 コンパクションが実行される前に、ディスク領域がチェックされます。使用可能なディスクスペースが現在のデータベース・サイズの2倍未満の場合、コンパクション処理は行われず、ログに警告が出されます。

# オート・コンパクション

## オート・コンパクションのトリガー

オート・コンパクションのトリガーには、下記の２つの要素があります。

### データベースの断片化
これがプライマリ設定です。この数値を 10%に設定すると、データ ファイルが 10% 断片化された時点でオート・コンパクションがトリガーされます(オート・コンパクションの時間帯制限がない限り)

### 時間帯
データベースが多用されているときにオート・コンパクションが行われないようにするには、オート・コンパクションが許可される時間帯を設定します。 これは、時・分の単位で設定できます（たとえば、01:00 から 06:00 の間に実行）。  デフォルトでは、コンパクションは順次実行されます。 

## メタデータのパージ間隔
オート・コンパクションに関連深い、別の設定項目として、メタデータのパージ間隔があります。期限切れアイテムおよび削除済みアイテムのTombstones（削除済みアイテムと期限切れアイテムのキーとメタデータを含むレコード）は、オート・コンパクションプロセスの一部として削除されます。 

## オート・コンパクション設定

オート・コンパクションの設定は、クラスター単位とバケット単位で行うことができます。
下記は、設定画面のイメージです。上記解説の内容を参考に、ご覧になってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/55624032-28c2-e888-8b62-d7e7bcb72c83.png)

# コンパクションのマニュアル実行

REST APIコールを用いて、コンパクションをマニュアルで実行することも可能です。

# 他のNoSQLの場合

## MongoDB

確認した限り、MongoDBは、オート・コンパクションには対応していないように見受けられました。マニュアルのコンパクションは、repairコマンドで実行するようです。

## HBase

HBaseには、オート・コンパクションに関する様々なチューニング要素があり、オフピーク時に積極的にコンパクションを発生させ、それ以外の時間帯になるべくコンパクションが発生しないようにする設定が可能です。また、メジャーコンパクションとマイナーコンパクションという二つの機構が用意されているのに加え、スロットルというコンパクションの負荷を全体として最適化するための設定項目もあります。

# 参考情報

[Compaction API](https://docs.couchbase.com/server/current/rest-api/compaction-rest-api.html)

[Performing Compaction Manually](https://docs.couchbase.com/server/current/rest-api/rest-compact-post.html)
Ruby ドリル③ eachの入れ子について

##はじめに

furimaアプリ制作を終わり、現在はオリジナルアプリ制作のためアプリのペルソナなどを考えており、コードを記述しておりません。。。
本日はエラー文と戦ってないのでまたrubyドリルの復習をしたいと思います。

##問題

以下のように、生徒の名前と生徒の所持金が入った配列があります。
この配列を用いて、生徒の名前とそれぞれの合計額が出力されるコードを記述して下さい。

```.rb
student = [["Arakagaki", [500, 500, 122]], ["Hoshino", [1000, 1000, 1150]], ["Gen", [4040, 4040]]]
```

##ヒント

・昨日結婚しました

・合計金額は語呂合わせです

・~~each文を使います。~~
・eachメソッドを使います。

・少しづつ取り出す事を考えます


##解答・解説

```.rb
students = [["Arakagaki", [500, 500, 122]], ["Hoshino", [1000, 1000, 1150]], ["Gen", [4040, 4040]]]

students.each do |student|
    sum = 0
  student[1].each do |price|
    sum += price
  end
  puts "#{student[0]}さんの合計金額は#{sum}円です"
end

#出力
#Arakagakiさんの合計金額は1122円です
#Hoshinoさんの合計金額は3150円です
#Genさんの合計金額は8080円です
```

eachメソッドの入れ子を記述しました。
少しづつ解説していきます。

まずは生徒の配列の取り出します。

```.rb
students = [["Arakagaki", [500, 500, 122]], ["Hoshino", [1000, 1000, 1150]], ["Gen", [4040, 4040]]]

students.each do |student|
 puts student
end

#出力
#Arakagaki
#500
#500
#122
#Hoshino
#1000
#1000
#31150
#Gen
#4040
#4040

```

続いて、今度はお金だけを取り出します。お金も配列に格納されていますので再びeach文で取り出します。
ここで今回のポイントとなるeachの入れ子が出てきます。

```.rb
students = [["Arakagaki", [500, 500, 122]], ["Hoshino", [1000, 1000, 1150]], ["Gen", [4040, 4040]]]

students.each do |student|
  student[1].each do |price|
    puts price
  end
end

#出力
#500
#500
#122
#1000
#1000
#1150
#4040
#4040
```

今回は合計金額を出さなければなりません。
sum = o 
を使って自己代入をしてみます。

```.rb

students = [["Arakagaki", [500, 500, 122]], ["Hoshino", [1000, 1000, 1150]], ["Gen", [4040, 4040]]]

students.each do |student|
    sum = 0
  student[1].each do |price|
    sum += price
  end
end


#1回目
sum = 0
sum += price #500が入っている

#2回目
sum = 500 #1回目で入っている
sum += price #５００ += 500の計算式

#3回目
sum = 1000 #すでに2回計算されて１０００が入っている
sum += price #1000 += 122の計算式
```

この結果"Aragakiさんの合計人数は37人です。"
と出力されるようになります。
この作業を残り2つ
Hoshinoさん,Genさんでも繰り返し行います。
Node.jsのインストールと「Hello world」を表示するまで

##Node.jsとは
サーバー側で動くJavaScript。
もともとJavaScriptってやつはクライアント側、つまり簡単に言えばPC側で動くプログラム言語だけど、それをサーバ側で動くようしたものがNode.jsというもの。<br>

特徴としては大量の処理に対応するために、ノンブロッキングI/Oという機能があり、データベースへのアクセスとWebページの表示を別々におこなってくれて、ストレスなくページの表示ができる。そのためスマゲーム界隈で使われているとか。
あとはチャットなどのリアルタイムに動的な挙動をさせるのに用いられている。
###前提条件
環境はAmazon Linux 2
Node.jsを導入するにあたり、Gitも必要になるのでこちらも導入しておく必要がある。
無い場合はインストール。

```
# yum install git
```
###導入手順
インストールしたgitでリポジトリからnvmをインストールする

```
# git clone https://github.com/creationix/nvm.git ~/.nvm
# source ~/.nvm/nvm.sh
```
ちゃんとインストールされているか確認。nvmコマンドで以下のように出れば成功。

```
# nvm help
Node Version Manager
Usage:
nvm help Show this message
以下省略
```
nvmコマンドからNode.jsをインストールする。今回は安定版と言われているバージョン0.12.7をインストール

```
# nvm ls-remote
v0.1.14
v0.1.15
v0.1.16
・
・
・
v0.12.5
v0.12.6
v0.12.7

# nvm install 0.12.7
########################################################################
Now using node v0.12.7
```
ちゃんとインストールできたか確認

```
# node -v
v0.12.7
```
デフォルトで使用するNode.jsのバージョンを指定する。

```
# nvm alias default v0.12.7
default -> v0.12.7
```
nodeコマンドにパスが通っていないので、パスを通す

```
# vim ~/.bash_profile

※末尾に↓を書き加える
if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi
```
これでターミナルを再起動してnodeコマンドが使えたら成功。
### コマンドライン上で"Hello world"を表示させよう。

nodeコマンドを使用して、main.jsを通して、hello.jsに記述された"Hello World"をコマンドに出力する。
そのため、main.jsとHello.jsの２つのjsファイルを作成する必要がある。
このファイルは、nodeコマンドで呼び出すためのファイルになる。

```
$ vim main.js
var hello = require('./hello.js');
console.log(hello.sayHello());
```

次にhello.jsを作成する。

```
$ vim hello.js
exports.sayHello = function(){ return "Hello World !" }

$ node main.js
Hello World !
```
Node.jsでwebサーバ"Hello world"
ポートは10000番を使う。

```
$ vim example.js

var http = require('http');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(10000); ←ここにポート番号を指定する


console.log('Server running at http://1270.0.0.1:10000/'); ←ここにサーバーのグローバルIPとポートを指定してURLとする
```
ブラウザからアクセスしてみる。
http://127.0.01:10000
これで"'Hello World"と表示されていれば成功。
ADX2のLEからPro版へ移行するとビルドした音がUnityでガビガビになるときの対処法

自分が今（2021/5/20）製作に携わっているインディーホラーゲームをコンシューマーでパブリッシングしていただくことが決まりまして、それに伴い、ADX2のPro版に移行しなければならなくなったんですよね。

移行するの、中々手こずりました。
マニュアル読むのヘタクソすぎて。目的の記事見つけるのにも一苦労...

ADX2君、出来ることがUnity並みに多すぎじゃぁありません？
流石、現場で多くのプロの方が使用されているだけはあるなあと思います。

## 今回起きた問題
Cri Atom Craft をアップグレードし、UnityにPluginをインポートし直して、さあ動くかな！？とエディターを実行してみたところ、実装していた音がすべて**ガビガビな宇宙交信音みたいな音**に入れ替わっていたんですね...しかも音圧も高めで鼓膜が五枚は破けました（？）。

折角ADX2をアップグレードしたのに音がすんごいことになってて流石に困惑...。

なんとか原因を突き止めることは出来たので、同じ状況に遭遇した方へ共有したいと思います。

# ビルドターゲットを確認せよ！！！
LE版でADX2をいじっていると触るタイミングのない**ビルドターゲット**。
こいつさえ切り替えることが出来れば全てが解決します（自分は解決した）。

##　まずビルドターゲット「PC」を追加
### 早速やり方 ↓
1. プロジェクトツリーを開き、ターゲットコンフィグまで行く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714568/1fb03212-5561-ae22-720d-5d51b303254c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714568/dca2f8c4-a77d-353a-eaf8-7b641866bea9.png)


1. 新規オブジェクト → 『ターゲットコンフィグ「PC」の追加』
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714568/c1edd16e-94f6-18b6-c60a-20436af61981.png)
ポップアップが出てくるので、そのままOKしちゃって大丈夫です。
1. これで準備は完了

## 実際にビルドしましょう
#### 「Atomキューシートバイナリのビルド」からターゲット名を「PC」に変更
ターゲット名を**PC**以外に変更した場合はその名前のターゲット名を選びましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714568/9c2ff392-430e-d32d-6323-48dcb9c55057.png)

さあ、ビルドしたファイルを`StreamingAssets`に入れちゃいましょう。
（ここの作業を自動でインポートする設定があるみたいですが、自分はうまく出来なかったので、アナログ的に手動で入れ替えてます。別に大した作業じゃないし...）


**そしたらUnityで実際にPreviewしてみてください。**
ガビガビ宇宙交信音から、元の音へと戻っているはずです！！

ああ、嬉しい！！



## LEからProへの移行
~~LEでプロジェクトを作っていたけど、途中からProを使うことになったという方向けに、移行の仕方を簡単にまとめ......たかったのですが、参考にするマニュアルがCRIに申請したサポートアカウントにログインしないと見られない情報であり、Qiitaでの投稿は情報漏洩にあたる可能性があるため、まとめられませんでした。申し訳ありません。~~

LEからProへの移行手順は、**Unityに関連するマニュアル内できちんと記載がある**ので、そちらを探して参考にしてください。
DockerをWindows10 Homeで動かしてみた

今まではWindows10 ProのHyper-Vの環境でしか動かなかった**DockerがWindows10 Home 64bitで動かせる**みたいなので試してみた。
* * *
#1. まずはDockerダウンロード！とインストール
[Docker for Windows](https://www.docker.com/get-started)
ここからDockerのWindows版をダウンロード。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/25b7f67b-7d6b-2f81-a0d8-7926d7ef267c.png)
インストールは誘導されるがままに**チェックボックスいじらずOK押下**！

#2. 起動時にエラー！
Dockerをインストールし、起動したときにこんなエラーが出ました。
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_256859_ce786b54-c161-bfb6-c9d0-b3e23dbb4e3d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/c564ee3a-e9a8-9bd7-7530-74d54ccc0f7d.png)
<br>
ここで諦めずLinux カーネル更新プログラム パッケージをダウンロードしてみよう！
[Linux カーネル更新プログラム パッケージ](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package)
![fsdfsdfew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/9914cd94-64f2-f1bf-7767-c874dcd524d3.png)
ダウンロードし終えたらインストール。
Next押せばFinishします。

#3. これで完了！
先程のエラー画面のRestartを押下。
これで起動できなかった場合、
[コントロールパネル]→[プログラムのアンインストール]→左側の[Windowsの機能有効化または無効化]で下の項目にチェックがいっているか確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/6142cca6-41ed-59ee-8b02-949d7f1aa57b.png)

#4. 動作確認
先程のRestartボタン押した後のDockerの2分間のチュートリアルのターミナルで動かしてもいいし、コマンドプロンプトで確認してもいい。

```shell
docker version
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/79d484b6-816f-4b78-7b12-3d369952952c.png)

バージョン内容が表示されたら正常に動いてます。
コンポーズのバージョン確認はこれ

```
docker-compose version
```

# まとめ
Dockerさえ導入してしまえばどんな環境にも参画できてしまうので、ゲームするからWindows派！みたいな人でもあらゆる開発環境に対応できる時代ですね。筆者の人はMac使ってますがゲームするからWindows派ですﾎﾞｿｯ。。。
[勉強メモ]マイクロサービスを理解 Vol2

Vol1：マイクロサービスの概要->https://qiita.com/get-latest-information/items/e959d12a54a378ffceb2
Vol2: DDD(ドメイン駆動設計)を用いいたマイクロソフトサービス設計アプローチ

##今回のフォーカス
MicrosoftのAzure Docsで色々な機能やアーキテクチャなどがまとまっているので、
今回は、マイクロサービス関連で下記ページをサマリーします。**`なるべく短い言葉を使って。`**
◆ドメイン分析を使用したマイクロサービスのモデル化
https://docs.microsoft.com/ja-jp/azure/architecture/microservices/model/domain-analysis

##ドメイン駆動設計(DDD)とは・・・
- DDDは、MSなアプリを開発するためのフレームワークを提供。どのような順序でやればいいのかを教えてくれる。
- DDDはすごい簡単に言えば、ビジネスの観点(技術ではなく)から高品質のソフトウェアを設計する手法。    
＊DDDに関しては別途勉強予定。

##DDDのアプローチをドローン配送アプリに適用
以下の手順。今回は、下記の１と２のみ。３と４はVol3で。
全体の流れ：ドメイン分析→境界づけられたコンテキストを定義→Entity/Aggregates/Serviceを定義→マイクロサービスの識別
1. ドメイン分析
　-> ビジネス用ドメインを分析して、アプリの機能的な要件を理解。ドメインを分割して、コアドメイン、サブドメイン化する。
2. 境界づけられたコンテキストを定義
　-> コンテキストはソリューション、１つのサービスのこと。ドメインに対して解決する機能を提供するもの。
　-> １コンテキスト=1アプリ(+1DB)
3. Entity/Aggregates/Serviceを定義：
　->コンテキスト内でEntity/Aggregates/Serviceを定義。
4. マイクロサービスの識別

#ドメイン分析
以下は、ドローン配送においてドメインを分析したもの。
ドメインの中で、コアドメイン、サブドメインに分けていく。
コアドメイン：Shipping(出荷)とDron Mgmt(ドローン管理)
サブドメイン：アカウント、Invoicing、コールセンター　→他の部分は何になるんだ？サブドメインじゃないのか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284059/7cec11df-a3f3-4ed1-bb78-bf6b376b5a19.png)

##境界づけられたコンテキストを定義
簡単にいうと、機能をグループ化して、アプリケーションを開発する単位を分割すること。
各ドメイン間を結んでいる線は、コンテキスト同士がやりとりする場所。つまり、サービス同士が連携する。
＊ドメイン分析でのそれぞれのドメインの数と下記とでドメイン数が違う(LoyaltyやUserRatingがない)のは、グループ化されたからということでいいのかな。
＊なんでDrone Sharingが急にAccountsとやりとりするようになるのだろうか。アカウントに紐づくのは理解できるが。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284059/6e1deb54-8607-d344-57d6-f492e7768c83.png)

##感想
流れはなんとなく理解できるが、正直難しくてよくわからない。
実際にDDDの進め方をためしているものがGithubに上がっていたりするので、挑戦してみようかなと。
Git リモートリポジトリを指定してfetchを行う

# 目的

- リモートリポジトリを指定して`$ git fetch`を行う方法をメモ的にまとめる

# 方法

- 下記コマンドを実行することでリモートリポジトリを指定してfetchを行う。

    ```terminal
    $ git fetch リモートリポジトリ名
    ```
【環境構築】fzfを活用してTerminalの作業効率を高める


##fzfをクローンする。

```
git clone https://github.com/junegunn/fzf.git ~/.fzf
```


##fzfをインストールする。

```
~/.fzf/install
```


##現在使っているbash , zsh等の確認

```
echo $SHELL
```


###bashの場合

```bash
vim ~/.bashrc
```

###zshの場合

```zsh
vim ~/.zshrc
```

##簡単にbranch切り替えるやつ

```bash
## fbr - checkout git branch

fbr() {
  local branches branch
  branches=$(git branch -vv) &&
  branch=$(echo "$branches" | fzf +m) &&
  git checkout $(echo "$branch" | awk '{print $1}' | sed "s/.* //")
}
```

###簡単にディレクトリに移動するやつ

```bash
# fd - cd to selected directory
fd() {
  local dir
  dir=$(find ${1:-.} -path '*/\.*' -prune \
                  -o -type d -print 2> /dev/null | fzf +m) &&
  cd "$dir"
}
```

###線を入れるやつ(多分zshしか入れられないかも)

```bash
# 線を引く処理
function line() {
 # print -P '${(r:COLUMNS::-:)}'
 printf '\033[38;5;27m%s\033[m\n' ${(r:COLUMNS::-:)}
}
```

###記述したら反映させる

####bashの場合

```bash
source ~/.bashrc
```

####zshの場合

```zsh
source ~/.zshrc
```

##コマンド一覧

- ファイル検索 ⇒  control ＋ T   もしくは fd
- history検索  ⇒  control ＋ R
- git 切り替え  ⇒  fbr
コードリーディングの履歴を残しながら調査したい

# これはなに?

コードリーディングを行う時、GitHubやVSCodeの定義ジャンプの機能を使って動作を追いかけることをすると思いますが、実際に追いかけている時は、わかった気になっていても、後からその記録を辿り直すことは難しいです。

# よくやるやり方
ということで、メモを残しながらコードリーディングするのですが、このメモが見づらい。

```
https://github.com/spiffe/spire/blob/88debf14a4e5f262bcb7aa0ef9b29dfb5531863d/pkg/agent/client/client.go#L314

GetAuthorizedEntries
でtrust bundle とそのAgentが担当するRegistrationEntriesを取得しているようだ。
期限の更新はどこで行われるのだろうか？

agentが署名しているのかな。そんな気がするな

https://github.com/spiffe/spire/blob/88debf14a4e5f262bcb7aa0ef9b29dfb5531863d/pkg/agent/manager/sync.go#L143

ここだ
CSRを作って再度要求を出している。
```

まぁこんな風になる。

リンクをクリックすればコードを見ることができるが、多くのコード片のタブがブラウザやエディタに散らばってしまい、ごちゃごちゃしてしまう。

# 今回考えた方法

Markdown風に上記のメモを書くことで、プレビューとして該当するコードを文書内に埋め込むようにする。

時間もないので、ローカルのHTMLファイルの、特定のdiv要素の中に、メモを書くことで、ブラウザ上でプレビューが表示できるような仕組みで作ってみることにした。

良さそうなら既存のマークダウンエディタに組み込むなどを考えても良いかもしれない。

# 例

こんな風にメモを書くと

```
:code https://github.com/spiffe/spire/blob/88debf14a4e5f262bcb7aa0ef9b29dfb5531863d/pkg/agent/client/client.go#L314

GetAuthorizedEntries
でtrust bundle とそのAgentが担当するRegistrationEntriesを取得しているようだ。
期限の更新はどこで行われるのだろうか？

agentが署名しているのかな。そんな気がするな

:code https://github.com/spiffe/spire/blob/88debf14a4e5f262bcb7aa0ef9b29dfb5531863d/pkg/agent/manager/sync.go#L143

ここだ
CSRを作って再度要求を出している。
```

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100375/b1c374ac-d313-1437-a737-c5571de796b7.png)|
|:--|
こんな風にプレビューされる。
ファイル名をクリックするとGitHubに飛ぶ。

パースしやすいように今回は `:code <GitHubのURL>`という記法にしている。

# 例2

周辺コードも見たいことがあるので、対応してみる。

雑に `:code <GitHubのURL> <ハイライトしたい行>` という記法にした。

```
# spire-agentの起動の流れ

## cliのRun

:code https://github.com/spiffe/spire/blob/aba18a09e7591207699d5bda01b4b95b8c12e5eb/cmd/spire-agent/cli/run/run.go#L151-L197 189


## agent の Run

89行目でattestを呼んでいる。ここにはcatも引数についている。

:code https://github.com/spiffe/spire/blob/aba18a09e7591207699d5bda01b4b95b8c12e5eb/pkg/agent/agent.go#L39-L122 89

## agentのattest

:code https://github.com/spiffe/spire/blob/aba18a09e7591207699d5bda01b4b95b8c12e5eb/pkg/agent/agent.go#L180-L194 193

## pluginの場合はここ

:code https://github.com/spiffe/spire/blob/aba18a09e7591207699d5bda01b4b95b8c12e5eb/pkg/agent/plugin/nodeattestor/v0.go#L18-L82
```

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100375/a3877b12-ce42-59f0-0591-862c0989b45b.png)|
|:--|

こんな風に範囲＋行ハイライトの形でプレビューが残せる。

# 実際に試してみたい！

こちらからどうぞ

https://inajob.github.io/code-reading-editor/code-reading.html

# 感想

意外と良さそうに思う。

皆さんはコードリーディングの時はどうやってメモを残していますか？

# 参考

- https://emgithub.com/
  - 仕組みはこれと同じ
  - これだとコードの埋め込みはできるが、行ハイライトができなかった
  - http://raw.githubusercontent.com/ のコンテンツに`access-control-allow-origin: *`がついており、任意のWebページからクライアントのJavaScriptだけでfetchができるという状況を利用している。
- VSCode用の拡張機能CodeTourが似たような目的で利用できることを聞きました。
  - https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour
windows10上でanaconda GPU tensorflow2.4.0の環境構築

windows10 GTX1050

cuda cudadnn tensorflowのバージョンを小数1桁まで厳密に合わせないとはまります。
https://www.tensorflow.org/install/source_windows#gpu
https://www.tensorflow.org/install/source#linux

##GPUドライバのバージョンの確認
GPUを導入した際にインストールしたGPU自体のドライバを確認　GEFORCE EXPERIENCE というアプリ
この作業を行ったときは、バージョン456.71　GeForce Game Readyドライバーと記載されている。
これから使いたいCudaとの互換性は以下で確認できる。
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

（うまく行っている場合はアップデートしない方が安全だが、sony NNC210で評価時にGPUが使われないため、466.63へのアップデートを試みる。-> tensorflow2の動作確認は、、nvidia-smi で確認したところNVIDIA-SMI 466.63       Driver Version: 466.63       CUDA Version: 11.3 cuda更新されちゃったの！！？
nvcc -V で確認するとCuda compilation tools, release 11.0, V11.0.221 と変化無し。とりあえず、簡単なGPU使うプログラムは動いたので一安心）

##アナコンダのインストール
アナコンダのサイトで最新2020.11版をDL（2021.2時点）
pathを通すをチェックアウト　デフォルトpthonにするをチェックアウト
アナコンダプロンプト　ver確認　python -V   -> python３．８．５

##nvccのセッティング
vs_buildtoolsをインストール。win10sdkだけ外す。
参考HP
https://www.kkaneko.jp/tools/win/cuda.html#S1
https://www.kkaneko.jp/tools/win/buildtool.html
先にnvccを動かす。vs_bupildtools__1152964415.1607687786.exeを実行した。

##cudaのセッティング　

cudaの１１．０をDL　cuda_11.0.3_451.82_win10.exe
https://developer.nvidia.com/cuda-toolkit-archive
cmdコマンドプロンプトで以下を確認。anacondaプロンプトでも同様にOK
nvcc -Vでcuda確認OK
cd C:\Program Files\NVIDIA Corporation\NVSMI
nvidia-smiで認識していた(pathが通っていないので移動して実行）
C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi

##cudnnのインストール
nvidiaでログインしてDownload cuDNN v8.0.5 (November 9th, 2020), for CUDA 11.0を選び、さらにcuDNN Library for Windows (x86)を選択。x64は選択にない。
ダウンロードして解凍、C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0にコピー。すでに同名のフォルダはあるので中身を選択してコピーする。
pathはC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0にすでに通っているよう。マイコンピュータ右クリック、システムのプロパティ環境変数で念のため確認。

##tensorflow2.4のインストール（アナコンダプロンプトから）



アナコンダプロンプト管理者でconda install -y tensorflow=2.4.0通らないpipでもだめ。（時間がたてば大丈夫？）
pypiのサイトでwhl python3.8GPU対応 をDLして　
https://pypi.org/project/tensorflow-gpu/2.4.0/#files

```
pip install tensorflow_gpu-2.4.0-cp38-cp38-win_amd64.whl
```

が通る。別フォルダならpath指定。jupyterでtensorflowのimport可能になった。
##tensorflowの確認





ここまでやって、GPU稼働が確認できた。jupyter notebookで
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
AWS Lambda


#Lambda　サーバレス

EC2インスタンスの代わりにコードを実行することで、効率的なアーキテクチャを実現する。
利用者は、ソースコードだけを準備すればすぐに実行できるようになり、自動的にスケール等をおこなてくれる。

##Lambdaの特徴
・実行基盤は全てAWSが管理
・AWSサービスと連携させることで簡単にイベントドリブンなアプリケーションを実行可能
・Node.js/javaで書かれたコードを実行可能
・１００ミリ秒単位でコード実行時間に対しての課金でありコスト効率が非常に高い
・オートスケール

##Lambdaがサポートしている言語
・Node.js
・Ruby
・PowerShell
・Python
・C#
・Java
・Go

##Lambda関数
Lambdaを利用するには、Lambda関数という単位で、実行プログラムとその実行トリガーとなるイベントを事前に定義します。

実行数に応じて支払いが発生するため、 Lambda関数が無期限に実行されないようにタイムアウト設定がなされています。 指定されたタイムアウトに達するとLambda関数は実行を終了します。そのため、予想される実行時間に基づいてタイムアウト時間を設定することが必要となります。 **デフォルトのタイムアウトは3秒で、AWS Lambdaのリクエストあたりの最大実行時間は900秒。これは15分に相当します。よって、15分を超過した処理が発生すると計算処理が途中で終了してしまいます。**

**Lambda関数は最大512MBまでのデータ容量を扱うことができます。**

##Lambdaの仕組み
・画像のアップロードをトリガー
・アピりケーション内の実行処理をトリガー
・ウェブサイトのクリックをトリガー
・接続デバイスからの出力をトリガー　　など

##lambdaの起動

**・Pushモデル**
S3/Cognito/SNSなどのAWSサービスとカスタムが直接実行することにより起動するLambdaファンクション
　ーサービスもしくはアプリが直接実行する
　ー順不同
　ー3回までリトライ

**・Pullモデル**
DynamoDBとKinesisなどのデータ処理は、Lambdaに対して直接的にイベント発行を行われないため、Lambdaがそれらへポーリングを行い自らイベントを取得
　ーストリームに入ってきた順に処理される
　ーイベントソースとして登録したストリー ムに対してLambdaが自動的にデータ取 得などのファンクションを実行する
　ーイベントごとに複数レコードを取得可能
　ーデータが期限切れになるまでリトライ


##APIゲートウェイ　（API Gateway）
APIを介してバックエンドサービスへのHTTPからのアクセスを提供します。APIゲートウェイはLambdaと一体となって利用できるサービスであり、**APIゲートウェイをLambdaファンクションと統合する設定を実施することで、HTTPからLambdaファンクションへのアクセスが可能となります。**

グローバルおよびサービスコールを含むさまざまなレベルでスロットルを提供します。スロットリング制限設定はリクエストが多すぎるために バックエンドサービスが処理しきれなくなることを防ぎます。たとえば、API所有者は自分のREST APIの特定のメソッドに対して毎秒1,000リクエストのレート制限を設定し、数秒間で毎秒2,000リクエストのバーストを処理するようにAmazon API Gatewayを設定することもできます。 Amazon API Gatewayは1秒あたりのリクエスト数を追跡 し、制限を超えたリクエストは429 HTTPレスポンスを受け取ります。

####API Gatewayキャッシュ
プロビジョニングして、そのサイズをギガバイトで指定することで、API呼び出しにキャッシュを追加できます。キャッシュは、APIの特定の段階用にプロビジョニングされています。これによりパフォーマンスが向上し、バックエンドに送信されるトラフィックが減少します。キャッシュ設定を使用すると、キャッシュキーの作成方法と各メソッドに保存されるデータの有効期間（TTL）を制御できます。

##DynamoDBとの連携
DynamoDBへのデータ登録後、自動でLambda関数を起動してメタデータを登録することが望ましい構成です。そのためには、DynamoDBストリームという仕組みを使うことで、DynamoDBテーブルへのデータ登録をトリガーにしてLambda関数を起動することができます。

##RDSプロキシ
**アプリケーションとRDSデータベースの間の仲介役として機能します。RDSプロキシは必要となるデータベースへのコネクションプールを確立および管理し、アプリケーションからのデータベース接続を少なく抑える機能です。**
Lambda関数はRDSエンドポイントではなく、RDSプロキシを利用して接続することが求められます。RDSプロキシはLambda関数の同時実行によって作成された大量の同時接続をスケーリングするために必要なコネクションをプーリングします。これにより、Lambdaアプリケーションは、Lambda関数呼び出しごとに新しいコネクションを作成するのではなく、既存のコネクションを再利用できます。 RDSプロキシを利用せず、エンドポイントを利用するとLambda関数によってコネクションが多数発生して処理が上手くいかなくなってしまいます。


##AWS SAM
サーバーレスアプリケーション構築用のデプロイツールです。YAMLを使用して、サーバレスアプリケーションのLambda関数、API、データベース、イベントソースマッピングをモデリングします。**AWS SAMはCloudFormationと連携してサーバレスアプリケーションを展開します。その際は、SAM が SAM 構文を AWS CloudFormation 構文に変換および拡張することで、サーバーレスアプリケーションの構築を高速化することができます。**
[Ruby]instance_evalとclass_evalについて知っていても損はないはず。

# instance_evalとは
instance_evalは、任意のオブジェクトの特異メソッドを定義したり、そのオブジェクト自身が参照できるインスタンス変数を定義、更新をすることができる。

## 使用例

```ruby
# Fooクラスの定義
class Foo
  def initialize
    @foo = 'foo'
  end
end

# Fooクラスのインスタンスを作成
foo = Foo.new

foo.instance_eval do
  # fooにインスタンス変数を定義
  @bar = 'bar'

  # fooの特異メソッドを定義
  def baz
    puts 'baz'
  end
end

puts foo.baz #=> 'baz'
```

# instance_execとは
これもinstance_evalメソッドと似ていて、レシーバのインスタンス元でブロックを実行します。
引数を渡すと、それがブロックの引数として渡されます。

```ruby
# Fooクラスの定義
class Foo
  def initialize
    @foo = 'foo'
  end
end

# Fooクラスのインスタンスを作成
foo = Foo.new

puts foo.instance_exec(5) {|x| @foo * x } #=> => "foofoofoofoofoo"

hello = proc {
    "Hello! #{@name}"
}

puts x.instance_exec(&hello) #=> "Hello! foo"
```

## instance_evalとinstance_execの違い
instance_evalだと、インスタンス変数にしかアクセス出来ないが、
instance_exec を使えばブロックに引数を渡せます。

# class_evalとは
class_evalは、クラスに特異メソッドを追加したり、そのクラス自身のインスタンス変数（orクラスインスタンス変数）やクラス変数を定義、更新することが出来る。
このように、class_evalの中で、インスタンス変数を定義しようとすると、それはクラスのクラスインスタンス変数になる。

## 使用例

```ruby
# Fooクラスの定義
class Foo
  def initialize
    @foo = 'foo'
  end
end

Foo.class_eval do
  # クラスインスタンス変数の定義
  @bar = 'bar'

  # クラス変数の定義
  @@baz = 'baz'

  # 特異メソッドの定義
  def hello
    puts 'Hello!'
  end
end

# Fooクラスのインスタンスを作成
foo = Foo.new

# fooオブジェクトが持っているインスタンス変数を参照
puts foo.instance_variables #=> @foo

# Fooクラスが持っているインスタンス変数を参照
puts Foo.instance_variables #=> @bar

# Fooクラスが持っているクラス変数を参照
puts Sample.class_variables #=> @@baz

# fooオブジェクトの特異メソッドhelloを実行
puts foo.hello #=> "Hello!"
```

# まとめ
下記のポイントを押さえておけば間違い無いです！

## instance_eval
- レシーバーであるインスタンスのインスタンス変数を定義、更新することが出来る。
- 任意のオブジェクトの特異メソッドを定義、更新することが出来る。

## instance_eval
- instance_evalメソッドと大まかな動作は変わらないが、引数を渡すと、それがブロックの引数として渡されます。

## class_eval
- クラスに特異メソッドを追加したり、そのクラス自身のインスタンス変数（orクラスインスタンス変数）やクラス変数を定義、更新することが出来る。
- class_eval内でのインスタンス変数定義は、そのクラスのクラスインスタンス変数となる。
離職防止に有効な人事のデータ分析

我々が毎日思い掛けないところで出会いがあって、思い掛けない人の影響によって考え方が変わることがあります。よって、当然、離職のような心移りは簡単にデータで予測や分析することができません。

しかし、日本の企業は離職は仕方がない、新しいステージを登っていくことを祈ってあげるべきなど、現実から目をそらして、データによる離職分析の必要性を低く見ているのではないかと思います。

##人事分析の重要性
企業調査では、人員不足のアンケートで“雇用人員の過不足”と回答したのは66.5％、そのうち「従業員の自発的な離職の増加」が45.3％も占めています。一番驚くべきなのは、“人材不足が職場の環境へ影響がある”と答えているうち、75.9％が「離職者の増加」に影響があると答えていることです。

（参考：『「人手不足等をめぐる現状と働き方等に関する調査（企業調査・労働者調査）」結果』 （2019年9月18日））



すなわち、離職の増加が企業の人員不足の大きい原因のひとつ、さらに、離職者を増やす原因ともなっていることがわかります。



また、離職者の増加は実際どれくらい企業のコストへの影響があるかに関して、大体、一人当たりは年収の半分以上ともいわれています。たとえば800万円の年収の方が一人辞めると少なくとも400万以上の損失になります。金額以外でも思い当たるコストの損失も多いにあるでしょう。



優秀な社員が一人の退職による膨大な損失分、残ったメンバーがどのくらいの労働力をかけて、どのくらいの商品を販売し、どのくらい細かいコスト削減をすれば挽回できるか、もっと真剣に考える必要があります。


紙印刷代の節約、コミュニケーションコストを削減することを考える前に、実は人材を失う前に止める対策は何倍も効率的なコスト削減になります。



##人事データ分析ツールの現状
人事データの分析が近年注目されるようになったことは、日々テレビやタクシーの広告など、よく耳にするような人事分析ツールが出回ることからでも、需要がそれなりに増えていることがわかるかと思います。軽く検索すると驚くほど多種多様なツールが出てきます。



ただし、良くみると下記のような2種類に留まっているツールがまだ多いことがわかります。



・人事の事務業務の簡略化
・現状把握のためのグラフなどによる可視化


人事の業務を減らし、データ化できることで社内における現状の可視化ができることも非常に重要ですので、このような人事ツールの導入はたくさんメリットがあると思います。しかし、肝心の”なにが本当の原因で退職者が増えていくの？”といったような分析が出来ないことです。



##人事分析の流れと課題点
人事データ分析に限らず、基本的にデータ分析の流れは下記のようになっています。

![original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295824/c0ca9001-77e9-6ab4-6b4b-351731d33b78.png)






一度だけしっかりと分析すれば終わるのではなく、これをサイクルとして続けていくことが大事です。また、データ分析の前の課題設定から、最終結果をすべてそのまま受け入れるのではなく、しっかりと考えたうえ、議論と検討を重ねて対策など実施すべきです。



人事データの分析を実現するために、人事職が今の業務を続行の上でこの分析作業をする時間の余裕、データを収集・加工し、さらに分析や解読するスキルも人事職の皆さんが備えないとできないことになります。また、今の分析の流れでは、多くの人事分析ツールもできないことは理解いただけるかと思います。



ツールはあくまでも「道具」に過ぎないですので、データ分析に関して、AIや機械学習のツールを導入しても下記二つの条件が揃っていないと、大体の人事データの分析はEXCELのほうが実用性が高いです。



利用するシーン、解決したい問題がある　→　ターゲット
活用できるスキルがある　→　データハンドリングと統計の知識

具体的に解決したい課題がなければ、ツールはただ安心感のためのものになります。



##拡張分析による人事データの分析
実は機械学習のアルゴリズムを導入された「拡張分析」は人事データ分析の分野でも多く活用されています。特に離職分析において大変わかりやすい結果で評価されております。

サンプルデータを使った簡単な”離職分析”一例をご紹介いたします。



課題：離職者が増える原因を探るために、離職に影響する要因を見つけたい

仮説：高学歴、評価が低い、残業が多いと離職されやすい

データ：

・入社の際の学歴を含めた履歴書の情報
・入社後の勤怠、残業状況
・人事評価の結果

![original (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295824/3bdb82f6-5430-7dd7-6277-78efbc7a713d.png)


※上記サンプルデータのようなイメージでデータ（エクセル等）を用意する。



２、３ステップの簡単な操作で瞬時に下記のような結果とビジュアルを出すことができます。
![original (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295824/69bbcf77-b7ff-921c-318a-b343aa797d60.png)


上記機械学習によるサンプルデータの分析結果からでは、こちらの企業は”残業が高い”、”エンゲージメントが低い”、”コミュニケーションスコアが高い”といったような特徴を持っている方が一番離職されやすいことがわかります。



最初の仮説の”残業”は裏付けされましたが、”エンゲージメント”と”コミュニケーション”に関しては新しい気づきとなりました。この結論から、特別なケアを検討のうえで、該当の対象者や部門への対策を考えていくことがもっとも効率かつ効果的でしょう。部門別で傾向が異なることも多いので、部門別のデータに絞った分析も可能です。



実は離職分析だけではなく、ハイパフォーマー分析、昇進のための候補者選出のための分析、組織分析のためのアンケートデータもあれば、部門別の組織特徴の分析も可能です。



人事データの分析においての課題となる、作業時間確保とスキルに関してはツール導入だけでは解決が難しいので、導入初期ではデータ分析の経験が豊富なコンサルトとアナリストがサポートいたします。2か月ほどで人事担当の皆様でもできるようになります。



##まとめ
　人事データの分析は大変価値のある分析です。これからより一層、機械学習やAIを組み込んだツールが普及していくことでしょう。ただ、ツールはあくまでも道具ですので、使わないと価値が発揮できないし、使うのにそれなりのスキルを身に着ける必要があります。



データ分析ツールも価値を最大化ができる需要が増えていくと思います。拡張分析ツールは”人事データの分析”という一つの分析テーマのツールではないため、導入された場合社内の多くの分野のデータ分析に活用できるので、ツール導入のハードルも下がります。今後拡張分析や拡張分析ツールは人事職のデータ分析の力になると思います。
Nextjsでnext/imageコンポーネントが動作しない時の対処法

#はじめに

Nextjsでnext/imageコンポーネントを使用していた時に、上手く動作しないことが発生したので、その解決方法を紹介したいと思います。
#next/imageとは

next/imageはNextjs10からサポートが開始された画像最適化の機能を有したコンポーネントで、画像形式を自動的にWebPにしてくれたり、遅延ローディングに対応していたりと画像を扱う上で便利な機能が揃っています。
使い方もシンプルで、既存の`<img>`タグを`<Image />`に置き換えるだけで簡単に使用することができます。

````jsx
import Image from 'next/image'

function Home() {
  return (
    <>    
      <Image
        src="/sample.png"
        alt="Picture of the author"
        width={500}
        height={500}
      />
    </>
  )
}

export default Home
````

[公式ドキュメント](https://nextjs.org/docs/basic-features/image-optimization)

#next/imageが動作しない時の対処法
##１・外部から画像を取り込んでいる場合

ローカルではなく外部から画像を取り込んでいる場合は、プロジェクトに`next.config.js`ファイルを作成し、画像取り込み先のドメインを指定する必要があります。

````javascript:next.config.js
module.exports = {
  images: {
    domain: ['http://sample.com']//指定しなければエラーが発生する
  },
}
````

##２・ローカルから画像を取り込んでいる場合

私はこれでハマったのですが、Nextjsがローカルから画像を参照する際は`public`フォルダから画像を参照します。
**そして`public`フォルダは必ずプロジェクトのルートに配置するようにしましょう。**私の場合は`public`フォルダを`src`フォルダ内に配置していたため、エラーが発生しました。

↓公式ドキュメントにもしっかり記載されていました・・・
[公式ドキュメント](https://nextjs.org/docs/basic-features/static-file-serving)


#まとめ

以上です。Nextjsでnext/imageを上手く動作できない方の助けになれば幸いです。
AudioManager作ってみた

unityの音(特にSE)めんどくさいですよね。

テキスト通りの流れだと
ゲームオブジェクトに効果音入れる
オブジェクトに効果音を鳴らすプログラムを入れる

```
AudioSource audio;
AudioClip se;
audio = GetComponent<AudioSource>();
audio.PlayOneShot(se);
↑こんなかんじのやつ
```

これを鳴らしたいオブジェクトにすべて入れてたらめんどくさくてしょうがない

なのでAudioManagerというものを作って、すべての効果音をここからならせばいいと思って作ってみました

メリット
・AudioManagerにすべての効果音を入れているので管理しやすい
・上記のプログラムをいちいち、鳴らしたいオブジェクトごとに書かなくて済む
デメリット
・AudioManagerからすべての音を鳴らしているので、3dSoundが使えない(AudioManagerを鳴らしたい位置に動かせばできなくはないけどめんどい)

それではメインのプログラム

```AudioManger.cs
    static AudioSource g_Audio; //AudioSourceコンポーネント

    [SerializeField,Header("音データ")] AudioClip[] audioClips; //音データ
    [SerializeField, Header("音名前(添え字)")] string[] SEName; //音の名前,配列の添え字用

    static Dictionary<string, AudioClip> SEs = new Dictionary<string, AudioClip>(); //SEディクショナリリスト
  
    private void Awake()
    {
        g_Audio = GetComponent<AudioSource>(); //AudioSourceを手に入れる

        for (int i = 0; i < audioClips.Length; i++) //音データの要素分だけループ
        {
            SEs.Add(SEName[i], audioClips[i]); //SEディクショナリリストに音データと音の名前を入れる
        }
    }

/// <summary>
/// 音を鳴らすプログラム
/// </summary>
/// <param name="name">鳴らしたい音の名前</param>
    static public void PlaySE(string name)
   {
        g_Audio.PlayOneShot(SEs[name]);
   }

```

プログラム解説
Dictionaryという超便利なものがあります。(連想配列で検索)
keyとvalueが結びついている特性を生かして、効果音の名前と効果音本体を結びつけて手軽にインスペクター上から編集できる
効果音リスト作ってみました。

![スクリーンショット (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788590/8fa7e7fa-da86-c8e6-5374-01e97bdc5692.png)


こんな感じで音のデータと音の名前を入れます(順番は一致させる必要あり)

後は鳴らしたいところで以下のようなプログラムをうつと音が鳴ります

```
 private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Field")&& g_PlayerCS.GetVelocity().y==0)
        {
            //()のなかに鳴らしたい音の名前を入れる
            AudioManger.PlaySE("着地音");
        }
    }
```

ゲームデザイナーに音をAudioManagerに入れてもらって、プログラマーがseならせばいいだけなので簡単＠
添え字の名前が食い違う事故起こりそうだからここをいい感じに事故らない方法募集してます。
正規表現でバリデーション

#はじめに
今回はログインやユーザー新規登録でのバリデーションについて記事を書きたいと思います。
言語は`swift`で書きますが他の言語とあまり変わらない（少しは変わる）です。
また、正規表現をある程度学習していることを前提にしていますので正規表現の勉強をされていないかたは以下の記事を参考に勉強してから本記事を閲覧ください。
[正規表現を勉強しよう！](https://qiita.com/apapapa/items/32395a75fcf898f73fe3)

[今回のコードはこちら](https://github.com/ryotatanks9981/Regulation)

#Validatorクラス
validationを行なってくれるクラスを作ってメールアドレスとパスワードが想定した形になっているかチェックしてもらいます。

```swift:Validator.swift
class Validator {
    static func isEmail(_ email: String) -> Bool {
        let pattern = "^[\\w\\.\\-_]+@[\\w\\.\\-_]+\\.[a-zA-Z]+$"
        let matches = validate(str: email, pattern: pattern)
        return matches.count > 0
    }
    
    static func isPassword(_ password: String) -> Bool {
        let pattern = "^(?=.*?[^\\w])(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\\d])[!-~]{8!,20}$"
        let matches = validate(str: password, pattern: pattern)
        return matches.count > 0
    }
    
    private static func validate(str: String, pattern: String) -> [NSTextCheckingResult] {
        guard let regex = try? NSRegularExpression(pattern: pattern) else { return [] }
        return regex.matches(in: str, range: NSRange(location: 0, length: str.count))
    }
}

```

`pattern`でメールアドレスやパスワードの構成を指定してvalidate関数に渡してあげます。
`validate(str: ,pattern: )`はマッチした数の`NSTextCheckingResult `を配列でかえしてくれます。
なので呼び出し先ではマッチした数が0より多かったら`true`を返すという処理にしています。

上記のパターンが想定通りの判定をしてくれるか確認します。

###メールアドレス
```swift
//想定通りの形
let email1 = "test@test.com"
//最後が英字がない
let email2 = "test@test."
//@の後に英数字がない
let email3 = "test@.com"
//先頭が英数字から始まらない
let email4 = "@test.com"
//@がない
let email5 = "test-test."
```

結果は...

```
email1: true
email2: false
email3: false
email4: false
email5: false
```

###パスワード

```swift
//想定通りの形
let password1 = "Test@123"
//大文字がない
let password2 = "test@123"
//記号がない
let password3 = "test123"
//数字がない
let password4 = "test@test"
//文字数が足りていない
let password5 = "test@1"
```

結果は...

```
password1: true
password2: false
password3: false
password4: false
password5: false
```

上記のようになりました。
想定通りになっていますね。

#最後に
今回swiftで正規表現を書いたのですが、本来`\d`で表現できるところを`\\d`と表現しないといけませんでした。
`\d`と書くと

>Invalid escape sequence in literal

と怒られるのでゆうとおりにしましょう。

また、メールアドレスの正規表現については厳密なメールアドレスの定義通りではないので実際利用しているメールアドレスでも`false`になる場合があります。完璧な正規表現は難しいとのことなので今回はある程度の形を保証できるパターンで妥協しました。

わかりずらいところやもっとこうした方がいいなどのご意見がありましたらコメントお待ちしております。

#参考
[大文字小文字数字記号を最低１文字以上含む正規表現
](https://qiita.com/nori4k/items/567c0e141ac8511543c5)
M5Stack-CoreInkにBLE経由で文字列を表示する(その2)

[その1](https://qiita.com/sushisushiBoo/items/19f01bab110a8bcbc783)の続き

 - 2021.5.27 追記：efontによる日本語対応、リファクタリング、Battery Service追加
   - [ソースコード(github)](https://github.com/sushisushiboo/M5CoreInk_BLEServer)
 - 2021.5.20 追記: アドバタイズにUUIDを追加

```
pAdvertising->addServiceUUID(SERVICE_UUID);
```


![IMG_0750.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92080/bcc45660-7c2a-b332-0396-d5911b880359.jpeg)

# やりたいこと

### step2（この記事）
   step1に以下を加える

 1. 1時間に一回バッテリー電圧を確認して表示する
 1. 起動時にRTCがリセットされていたら、または月が変わったらWiFi経由でNTPで時刻合わせする

### step3（別記事にする予定）
 - M5StickCをBLEClient（セントラル）として動作させる(1)
   - 置く向きよってCoreInkに送る文字列を選択させる
   - ボタン押下でscan、connect、write実行
 - M5StickCをBLEClient(セントラル）として動作させる(2)
   - CoreInkのボタン状態がオンならば、表示、ブザー鳴動させる

# 参考
 - [ESP32の設定管理ライブラリの紹介](https://www.kerislab.jp/posts/2017-06-16-esp32-preferences/)
 - [M5 CoreInk RTCのコト＋NTPから時刻ゲット](https://note.com/rasen/n/nfe2b5a67eaa9)
 - [efont](https://github.com/tanakamasayuki/efont)

# 困ったこと
 - そのままだとWiFiとBLEServerがROMに収まらない
   - こちらを参考にして解決
   -  [ESP32-WROOM-32のプログラム領域が足りなくなった時に、パーティションの設定を変更（OTAを無効化）して領域を増やす方法](https://asukiaaa.blogspot.com/2019/03/esp32-wroom032ota.html)
   -  NO OTAを選択

# iPhoneから操作(Lightblueを使う)
### アプリ起動すると見つかる
![0FCC159B-8FBD-4818-B7AC-9FA8A9436C16.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92080/3e5a8718-b0e2-001a-a7ce-2f8561401ca7.jpeg)
### 接続
![80E3443B-B4DC-4074-9E63-3531293DCE12.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92080/cbbe4e92-86e3-a66f-4509-6aa02595b4d1.jpeg)
### サービス一覧
![ED5DEB4E-0BB5-4A17-A348-977588928530.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92080/2b47d31a-eec1-b556-930a-41b03a25a0c1.jpeg)
### サービス選択
![1C0C5BEE-7AFB-47AB-902D-B5624FB4C18D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92080/06151d50-4e08-b85a-e881-32f3c2f1cc80.jpeg)
vue-routerのmode: 'abstract'とは？

## 動機

vue-routerの公式ページによると、下記のように説明されている。

>abstract: 全ての JavaScript の環境で動作します。 e.g. Node.js を使ったサーバーサイド。 もしブラウザの API が存在しない場合、ルーターは自動的にこのモードに強制されます。

んーでも、どんな挙動になるのか、もうちょっと書いてくれていてもいいんじゃないかな・・・


## で、どんな挙動になるのか

URLを一切変更せず、ページ遷移するようになる。
hashやhistoryのときにURLを使って表現していた現在ページの情報をメモリ上で保持して、どこにも表示はしないイメージ。
vue-routerの機能は普通に使える。
&lt;router-link&gt;とか、router.push()とか、各種ナビゲーションガードとか、普通に動く。
ただし、ブラウザのAPIが存在しない環境が前提なので、historyAPIに依存した機能は無効になっている。
だから、戻るボタンを押したらSPA内でのナビゲーションに関係なく、前のページに戻る。
その辺を制御したければ自分でhistoryAPIをいじることになる。

あとひとつ罠があって、vue-routerに初期状態を手動で与えないといけない。なぜかは知らない。

```js:App.vue
  mounted() {
    this.$router.replace('/');
  }
```
TablePlusのPostgreSQLのレコードの削除方法

消したいカラムで右クリックすると下記画像となる。

Deleteをクリック。

(添付画像はレコードされていないので、Deleteが有効になっていません)

カラムのカラーが赤になるが、まだ未削除。

comand + s  をするとレコードが削除されます。

![スクリーンショット 2021-05-20 14.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468139/040c67d4-c8a1-1257-012b-c41c228e2b08.png)
[勉強メモ]マイクロサービスを理解 Vol1

マイクロサービスがふわっとしか分かってないので、改めて勉強。
ドメイン駆動設計やら、APIやら、ソフトウェア設計(ヘキサゴナル、クリーン、レイヤード、オブジェクト指向etc)なども
関わってくるので、追々勉強する、というか、関連したページをサマっていこうかと思います。

##今回のフォーカス
MicrosoftのAzure Docsで色々な機能やアーキテクチャなどがまとまっているので、
今回は、マイクロサービス関連で下記ページをサマリーします。**`なるべく短い言葉を使って。`**
◆マイクロサービス アーキテクチャ スタイル
https://docs.microsoft.com/ja-jp/azure/architecture/guide/architecture-styles/microservices

##マイクロサービス(MS)とは・・・
- MSは、**`小さく、独立、疎結合`**である。
- 各サービスは個別のコードを持つ。小規模なチームが開発。
- サービスは、サービスのデータや外部の状態を保持する役割。
- **`APIで相互の通信`**
    - マイクローサービス内の通信でAPI利用。
    - **`クライアントからの通信の場合もAPI Gatewayを置く。`**
        - メリット：
            - サービスからクライアントの切り離し
            - AMQPなどのWebフレンドリでないメッセージングプロトコルをサポート
            - 調整、キャッシュ、変換、検証などすぐに使用できるポリシー　⇨どういうこと？
- **`polyglotプログラミグ(多言語プログラミング)`**：簡単に言えば、個々のサービスが別の言語(Python,C#,Java etc)を使ってOK

##メリット
- 機敏性：MSは個別にデプロイされるため、バグ修正や機能リリースなどの**`更新をアプリ全体の停止なく実施`**できる。
- 小規模チームで実施可能。大規模になるとコミュニケーションに時間がかかり、管理オーバーヘッドが増大し、生産性が低下する。
- 小さなコードベース：モノリスの場合、依存関係が複雑のため多くの場所でコード変更が必要。**`MSでは、コードやデータストアは共有されないので、新しい機能を簡単に追加`**。
- 障害の分離：個々のマイクロサービスが停止しても、**`アプリ全体が停止することない仕組みにすることができる`**。
- スケーラビリティ：個々のサービスが**`独立して拡大縮小が可能`**。
- データの分離：サービスが独立しているので、スキーマの変更が実行しやすい。

##課題
- 複雑：MSはモノリスよりも多くの動的パーツで構成されるため、各サービスは単純だが、全体では複雑。
- 開発およびテストにおいて、モノリシックとはアプローチが異なる。
- ガバナンスの欠如：多くの異なる言語やフレームワークを使用するため、維持が難しくなる。
- サービスの依存関係のチェーンが長すぎる(サービスAがBを呼び出し、BがCを呼び出す)問題がおこる
- データ整合性をとることが難しい。
- 成熟したDevOpsカルチャーが必要。
- スキルと経験が必要。

##ベストプラクティス
- 全てを**`分散化`**する。
- **`データストレージは、データを所有するサービス専用とする。`**
- **`API通信`**
- 認証やSSL終了などの横断的な懸念事項は**`ゲートウェイにオフロード`**する。
- **`ドメインのナレッジは、ゲートウェイの外部で保持する。`**
- サービスには**`疎結合と高い凝集度(ぎょうしゅうど)`**が必要。｀
- 障害の分離。

##感想
- MSは、アプリを開発することだけでなく、リリース後の機能追加、更新を意識している。
- 分散化(独立)、疎結合、凝集度、API通信というのは、大事なキーワードである。
ESP32へmicropythonをインストールする

# はじめに
ESP32へmicropythonをインストールする手順を備忘録的な感じで書きます

なおインストールを行う際に接続するPCのOSはMacであり同様の手順ではWindowsでは動作しない可能性があります．

# 目次
1. ESP32をPCへ接続する
1. esptoolのインストール
1. micropythonをダウンロード
1. ESP32を初期化
1. ESP32へmicropythonをインストール
1. ESP32へ接続する(確認)

## 1. ESP32をPCへ接続する
![DSC_0243.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/218093ca-566b-4bcf-6503-53b912a1b110.jpeg)

写真のように接続します．

## 2.esptoolのインストール
macにてターミナルを起動し,下記コマンドを実行

```sh
pip install esptool
```

## 3.micropythonをダウンロード
https://micropython.org/download/esp32/
こちらからダウンロードする

なおダウンロードするのは**Firmware with ESP-IDF v4.x**である．
Micropythonはウィークリーで更新を行っているため最新版が異なる可能性がある．執筆時点での最新版かつStable版は**GENERIC : esp32-20210418-v1.15.bin**である．

![スクリーンショット 2021-05-20 14.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/9387d417-9fe9-b83a-7ea0-98fb7377a2b3.png)

(unstable版はおそらくバグも含まれていると思われるため個人的にはおすすめしない)


## 4. ESP32を初期化
下記コマンドを実行

```sh
esptool.py --port /dev/tty.usbserial-0001 erase_flash
```

なお私の場合portが **/dev/tty.usbserial-0001**であったが，人によりここは違うため, /dev/tty.まで打ってタブキーを押して候補を確認してから実行する

```sh
$ esptool.py --port /dev/tty.usbserial-0001 erase_flash
esptool.py v3.0
Serial port /dev/tty.usbserial-0001
Connecting........_____.....___
Detecting chip type... ESP32
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: fc:f5:c4:21:0c:dc
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 8.2s
Hard resetting via RTS pin...
```

⏫実行が成功するとこのようになる

## 5.ESP32へmicropythonをインストール
下記コマンドを実行

```sh
esptool.py --chip esp32 --port /dev/tty.usbserial-0001 write_flash -z 0x1000 /Users/[USERNAME]/Downloads/esp32-20210418-v1.15.bin
```

先ほどダウンロードしたmicropythonのbinファイルをインストールする．
原則ダウンロードしたファイルはダウンロードフォルダへ配置されるためそこへパスを指定する．
任意にダウンロードフォルダを変更している場合はそちらへ変更する．

```sh
esptool.py v3.0
Serial port /dev/tty.usbserial-0001
Connecting........___
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
WARNING: Detected crystal freq 41.01MHz is quite different to normalized freq 40MHz. Unsupported crystal in use?
Crystal is 40MHz
MAC: fc:f5:c4:21:0c:dc
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 1469216 bytes to 953244...
Wrote 1469216 bytes (953244 compressed) at 0x00001000 in 84.3 seconds (effective 139.5 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
```

⏫実行が成功するとこのようになる


## 6.ESP32へ接続する

下記コマンドを実行

```sh
screen /dev/tty.usbserial-0001 115200
```

スクリプトが下記のように出力されれば成功．

```sh
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:5636
load:0x40078000,len:12696
load:0x40080400,len:4292
entry 0x400806b0
MicroPython v1.15 on 2021-04-18; ESP32 module with ESP32
Type "help()" for more information.
>>>
```

なおscreenコマンドの終了の仕方は
**control + A + K**

無事接続できたらインストール成功です．
お疲れ様でした．
kintone 開発環境構築メモ2021

Surface Laptop 4 を購入したので、kintone 開発環境の設定をメモ。

# Surface Laptop 4

Surface Laptop, Surface Laptop 2 の次は、3 を飛ばして、Surface Laptop 4 を購入しました。
外観やキーボード配置などは、初代Surface Laptopから変わらず、性能が上がった感じ。
顔認証が精度よく早くなったようだ。
あとバッテリー駆動時間が、最大17時間と長持ちであまり電源コードを持ち歩く必要なし。
今回も US キーボードの関係で、Amazon US から購入して、約5日で届いた。

|  |Surface Laptop|Surface Laptop2|Surface Laptop4|
|:--|:--|:--|:--|
|OS|Windows 10S|Windows 10 Home|Windows 10 Home|
|CPU|i5-7200U|i5-8250U|i5-1135G7|
|コア数/スレッド数|2 / 4|4 / 8|4 / 8|
|ベースクロック|2.5GHz|1.6GHz|2.4GHz|
|最大動作クロック|3.1GHz|3.4GHz|4.2GHz|
|キャッシュ|3MB|6MB|8MB|
|CPU Mark|4601|7492|9822|
|Screen|2256x1504|2256x1504|2256x1504|
|バッテリー駆動時間|14.5時間|14.5時間|17時間|


# kintone 開発環境再構築手順

- Windows 10 Home セットアップ
- Windows 10 Pro アップグレード
- Windows 10 Pro 日本語化
- Windows Update
- セキュリティソフトインストール
- git for windows
- Powershell プロンプトカスタマイズ
    - posh-git
- Visual Studio Code
- node 関連
- kintone プラグイン開発環境

# Windows 10 Home セットアップ

既定のOSは、Windows 10 Home で、言語の選択に日本語が無いので、英語を選択して進めます。
Cortana がいろいろ英語で喋ってきますが、聞き流しながらセットアップを進めます。

# Windows 10 Pro アップグレード
Microsoft Store でアップグレード購入。
前回（Suraface Laptop2）の時は、Microsoft Storeで購入できなかったが、今回は購入できた。
英語環境のままだとMicrosoft Storeで購入できるのか？

# Windows 10 Home 日本語化
日本語ローカル　エクスペリエンス　パックを導入し、Windowsの表示言語を日本語に選択。

# Windows Update
とりあえず「Feature update to Windows 10, version 21H1」まで更新。

# Powershell Ver.5.1

Windows 10 のデフォルトバージョンですが、少し古いのでアップデートします。

- Powershell の規定値フォントを日本語表示できるものに変更
- PowerShellGet のアップデート

[PowerShellGetをアップデートしよう](https://blog.shibata.tech/entry/2017/12/18/004105)を参照して、PowerShellGet をアップデートします。

# posh-git

posh-git は、カレントディレクトリの git のサマリ情報をコンソール上に表示してくれます。
[posh-git](https://github.com/dahlbyk/posh-git) の手順に従って、インストール。

# Powershell プロンプトカスタマイズ

VSCode のコンソール出力で、プロンプトの表示をカレントディレクトリだけにします。
posh-git の設定だけで出来るようです。
Microsoft.PowerShell_profile.ps1 に設定。

```Microsoft.PowerShell_profile.ps1
# プロンプトの表示をカレントディレクトリだけにする
Import-Module posh-git
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory = $true
$GitPromptSettings.DefaultPromptAbbreviateGitDirectory = $true
```

VSCode のターミナル表示
![2021-05-20_13h09_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/452a212a-a2fd-bb9c-a409-2058c9c5d74e.png)


# git for windows
[git for windows](https://gitforwindows.org/) で、ダウンロードしてインストール

# nodist

[GitHub nodist](https://github.com/nullivex/nodist/releases) からダウンロード＆インストール
必要な node バージョンのインストール・切り替えが簡単。

# kintone プラグイン開発環境

create-plugin 等の kintone プラグイン開発に必要なものをインストール。
手順は、下記のとおり。

[kintone create-plugin を使ってみた](https://qiita.com/rex0220/items/ec21b526442951bf70d9)

2021/05/20 時点では、plugin-uploader でタイムアウトする問題があり、下記の暫定対応を行った。
[kintone plugin-uploader でタイムアウトの暫定対策メモ](https://qiita.com/rex0220/items/55338be91c2a420e7d1a)
【分子動力学】MDのトラジェクトリー解析ライブラリ「MDTraj」はじめの一歩

# はじめに
この記事では、pythonで使えるトラジェクトリー解析ライブラリであるMDTrajのインストールや簡単な解析方法を解説します。

# 前提
Anacondaを導入済み

# 実行環境
CentOS7

# 参考
https://mdtraj.org/1.9.3/index.html

# インストール
以下を実行するだけでOK

```bash
conda install -c conda-forge mdtraj
```

# トラジェクトリーを読み込む、原子を指定するなど

適当なトラジェクトリーファイルを用意してください。
トラジェクトリーの読み込みは

```python
import mdtraj as md
t = md.load('md.xtc', top='md.gro')
```
のように行います。

座標データはt.xyzで取得できて、

```python
>>>print(t.xyz.shape)
(101, 1960, 3)
```
これは全部で101フレーム、1960原子、3次元(x,y,z)の座標のリストになっているということ。

各フレームの時間もこのように取得できます。単位はピコセカンドですね。

```python
#最初の10フレームの時間を取得
>>>print(t.time[0:10])
[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90.]
```

また、セルの長さも取得できます。

```python
>>>print(t.unitcell_lengths[-1])
[6.9593244 6.9593244 6.9593244]
```





# トラジェクトリーを解析する

## RMSDを計算する

```python
import mdtraj as md
import numpy as np
import matplotlib.pyplot as plt
import csv

# トラジェクトリーの読み込み
t = md.load('md.xtc', top='md.gro')

# 各フレームの時間のリストを取得
time = t.time
# トラジェクトリーの最初のフレームを参照構造としてtのRMSDを計算する
rmsds = md.rmsd(t,t,0)

# 時間とRMSDをCSVファイルに書き込む
with open('rmsd.csv', 'w') as f:
        writer = csv.writer(f)
        for i in range(len(time)):
                writer.writerow([time[i], rmsds[i]])

# 時間vsRMSDでグラフを描画する
plt.plot(t.time, rmsds, label="rmsd")
plt.xlabel('time [ps]')
plt.ylabel('rmsd [nm]')
plt.show()

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788299/d49b2dac-8bc9-8dd1-c59c-7e22671ae5af.png)


もしgroファイルを参照構造としたいなら、下記のように書けばよいです。

```python
t = md.load('md.xtc', top='md.gro')
r = md.load('md.gro')

rmsds = md.rmsd(t,r,0)
```

↓でもう少し突っ込んだ内容も書きました

https://qiita.com/tacoma/items/6bed95a8657b6d249718
Node.jsのメモリリーク調査の備忘録

# はじめに

Node.jsのアプリケーションサーバーがメモリリークしているようで、数日おきにクラッシュしていたので原因を調べました。
ひと昔前はクラッシュしたらサービス停止して大変だったりしますが、最近はセルフヒーリングで立ち上がってくるのでクリティカルにならないのは進歩を感じます（老人会）

3点ヒープダンプ法も試しましたが、原因特定に至らなかったので地道に仮説検証を繰り返しました。


# 使用メモリ量を出力する

以下のコードでファイルに出力して、Excelに貼り付けてグラフにすれば十分です。
起動時には```--expose-gc```オプションをつけます。

```js
import * as fs from 'fs';
function logHeapUsage() {
  try {
    global.gc();
  } catch (e) {
    console.log("You must run program with '--expose-gc'");
    process.exit();
  }

  const heapUsed = process.memoryUsage().heapUsed;
  console.log('Program is using ' + heapUsed + ' bytes of Heap.');
  fs.appendFile('heapUsed.log', heapUsed + '\n', (error) => {
    if (error) {
      console.log(error);
    }
  });
}
setInterval(logHeapUsage, 2000);
```

# Gatlingを使って大量のリクエストを送る

以下のスクリプトで、ローカル環境でエラーが出ない程度に調整してリクエストを送ります。

```scala
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class MemoryLeak extends Simulation {
  val httpProtocol = http.baseUrl("http://localhost:3030")

  val memoryLeak = scenario("MemoryLeak")
    .repeat(100){exec(http("TopPage").get("/"))}

  setUp(
    memoryLeak.inject(
      rampUsers(200) during (100 seconds),
      nothingFor(30 seconds),
      rampUsers(200) during (100 seconds),
      nothingFor(30 seconds),
      rampUsers(200) during (100 seconds),
    ).protocols(httpProtocol)
  )
}
```

# 仮説・検証サイクルを回す

問題を再現できたら半分解決したようなものなので、あとは問題箇所を絞り込みながら検証を繰り返します。
まずはHello Worldのようなシンプルなエンドポイトを用意すると、アプリケーションコードに問題があるのか、フレームワークに問題があるのか切り分けできて良いかと思います。

# 今回の原因

Node.jsのv12.13.0が原因だったので、v14.17.0にバージョンアップして解決しました。
参考URL: https://bleepcoder.com/ja/node/613342361/node-v12-16-2-memory-issues-after-upgrade-from-v8-last-few


以上です。