OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue】Vuexを使って無限スクロールのデータをキャッシュする

## やったこと
- Vuexに無限スクロールのデータをキャッシュする
- データ描画後にスクロール位置を戻す

## 実装例
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vYjjdjY" data-user="matsuura77" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/matsuura77/pen/vYjjdjY">
  qiita_vuex</a> by matsuura77 (<a href="https://codepen.io/matsuura77">@matsuura77</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
vuexに複数引数でコミットする際は連想配列で渡す必要がありました。

## 思ったこと
- scrollBehaviorが使えなかった
VueRouterがやってくれるスクロール位置保存があるのですがそれがうまく動いてくれなかったです。結局なぜ動かなかったのかわからなく、今回はjsで実装しました。

- キャッシュデータをいつリセットするべきか
実際の実装ではページごとにデータをキャッシュしているのですが、どのタイミングでキャッシュをリセットすべきか悩みました。結局はアプリケーションが破棄されるタイミングでいいと思いっています。

- Vuex便利
今回初めてvuexを使ったのですが、アプリ内のグローバルな変数があるのはとても便利だと思いました。

- スクロール位置を戻した時のちらつき
描画されてからスクロール位置を戻すため、最初の画面が一瞬チラつきます。これはscrollBehaviorを使ったとしても同じことで、scrollBehaviorはこれを誤魔化すためにアニメーションでスクロール位置を戻しています。チラつきをなくす方法があればコメントでお願いします。
Go言語 : インターフェース(&循環参照の分離)

## インターフェース
インターフェイスは、実装と使用を分離することが出来る。
また、Go言語のインターフェースは「循環参照」を解決するためにも使われる。 

#### 循環参照
Go言語ではパッケージの循環参照が禁止されている。 
循環参照というのは、パッケージAとBがお互いに参照しあってるということ。
循環参照の禁止は、レイヤードアーキテクチャを実現することに寄与する。
しかし、時に、循環参照の禁止は厳しすぎる制約となり、プログラム作成の障害となってしまう。
そこで、インターフェースを用いてパッケージを循環参照から切り離し、循環参照可能な仕組みを作ることもある。

## ファイル構造
dog/  
&ensp;&ensp;Dog.go  
&ensp;&ensp;DogLoar.go  
cat/  
&ensp;&ensp;Cat.go  
&ensp;&ensp;DogInterface.go  
main.go  

## ポイント
Dog.go  
 
```Go
func (d *Dog) GetDog() string {  
  cat := &cat.Cat{ CatObj: NewDogRoar() }  
  // GetCat -> DogInterface -> GetDogRoar
  return cat.GetCat()   
} 
```
※ GetDog関数の中でGetCat関数を呼び出しているが、結果は「Bow Wow !」になる。 

## 出力例
/Go_Interface $ go build  
/Go_Interface $ ./Go_Interface   
Bow Wow !  

## GitHub
https://github.com/GL-Kageyama/Go_Interface
デジタル エクスペリエンスの有効化は既に行われているようです


[チャレンジの手順と画面の内容が一致しません](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JdLaD)

これらの手順では、ドメイン名が既に入力されているため、ドメイン名を作成する方法がないことがわかります。デジタル エクスペリエンスの有効化は既に行われているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c839bede-7aa7-df48-eb7b-01d066eaa5fe.png)


チャレンジの功績を認められるためにドメインを変更したのではない、とアドバイスしました。バッジ全体を完成させた後、彼女は同じ手順を使用して自分用のカスタム ポートフォリオを作成しました。 

[Salesforce で個人ポートフォリオを構築 | ポートフォリオ サイトの作成が正しく機能しない](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000IRUJnSAP)

フィーロ、チャレンジをパスするには、ドメイン名を変更できないようです。そのままにして、モジュールの指示に従ってポートフォリオを作成し、バッジを取得しました。それから私はすべてを削除しました。 

次に、新しいプレイグラウンドでやり直し、MyDomain (セットアップ) でドメイン名を変更しました。デプロイすると、ドメイン名が変更され、デジタル エクスペリエンスに移動して有効にすることができます。これにより、ドメインに自分の名前でポートフォリオを作成できるようになります。

**結局バグあるいは、トレイルヘッドの手順の記述の誤り？**

いつものごとく意味が分からん。


# 同様の質問

+ [【未解決】Create a Portfolio Site - Unable to create Domain name](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JeErS)
+ [【未解決】(Create a Portfolio Site - Unable to create Domain name](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JeErS)
+ [Help to Enable Digital Experiences and Set Permissions](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PeFNA)
BukkitAPIとNMSのパーティクル名が所々異なる件について

# プラグイン開発あるある
コマンドでいい感じのパーティクルを見つけ、いざプラグインに組み込もうとした時です。

**「なんかパーティクル見つかんねえなあ...」**

こんな経験ありませんか？

# 例
## Bukkit
```
EXPLOSION_NORMAL
```
## NMS
```
"poof"
```

# BukkitAPIの内部実装を確認

これらの対応表はCraftBukkitのソースを見れば確認することが出来ます。

## Spigot (v1.19.2)
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/CraftParticle.java

# その他
サウンドidは全く同じぽい？
ポーションエフェクトとかも違ったような
enebularでnlp その2

# 概要
enebularでnlpやってみた。
練習問題やってみた。

# 練習問題
api作ってplunkerから、叩け。


# 方針
- getでjsonを表示する。

# フロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f9839c05-b1cd-416a-6ec8-6ef8c60a0c5e.png)


# サンプルコード

```

var endpoint = "https://ohiapp0.herokuapp.com/nlp?token=";
var src = document.getElementById('src');

function send(msg) {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			//alert(xhr.responseText);
    	document.body.appendChild(document.createTextNode(xhr.responseText));	
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
			//alert(xhr.responseText);
		}
	};
  var uri = endpoint + msg;
	xhr.open("GET", uri, true);
	xhr.send();
	//alert("ok");
}

function run() {
  send(src.value);
  src.value = '';  
};




```

# 成果物

https://embed.plnkr.co/plunk/962iX9sdmSZYLb4p


以上。
enebularでnlp

# 概要
enebularでnlpやってみた。

# インストール
ハンバーガーメニュー>パレットの管理>ノードを追加でnode-red-contrib-nlpノードを検索して追加

# フロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/db9823f8-782b-5a4d-5439-0674acd515e4.png)




以上。
引数の数が不定なメソッドの書き方

## 引数の数が不定なメソッドの書き方
メソッドの定義時の引数に 「*変数名」 で定義し、メソッド実行後は、与えられた引数をまとめて「配列」として出力することができる。
書き方は下記の通り。
```
（fooメソッドを定義）
def foo(*args)
  args
end

p foo(1, 2, 3)     #=> [1, 2, 3]
```
また、設定した引数の数でない時にメソッドを実行した時は下記のようになる。
```
(Methメソッドに通常の引数と引数の数が不定な引数を設定し、値を配列で返す処理を設定)
def meth (arg, *args)
  [arg, args]
end

（メソッド実行）
p meth(1)     #=> [1, []]    (*argsの方には引数を入れメソッドを実行していないので、[]が出力される)   

p meth(1, 2, 3)   #=> [1, [2, 3]]   (最初の1つ目の引数は、argへ、残りの引数は*argsの方に「配列」として出力される)
```
*また、この時p meth(1, 2, 3).flattenのように、
flattenメソッドを実行することで、上記の二次元配列[1, [2, 3]]を一次元配列[1, 2, 3]とすることもできる。
```
p meth([], 1)   #=> [[], [1]]    
p meth(0, 1)   #=> [0, [1]]　（複数の引数を設定すると、2つ目は必ず、「配列」で返ってくる）
```

さらに、引数不定の引数を途中で定義したときは、下記のような結果になる。
```
(Aメソッドを定義し、引数不定の引数を定義)
def a(a, *b, c)
  [a, b, c]
end

p a(1, 2, 3, 4, 5)     #=> [1, [2, 3, 4], 5]
p a(1, 2)        #=> [1, [], 2]
```

### まとめ
引数の数が不定の時は、「*変数名」で定義し、出力時は配列として出力される。
2022/10/3主にITとかセキュリティの記事

クラウド関連のセキュリティインシデントに見舞われた組織は80％超(10/1)
https://news.mynavi.jp/techplus/article/20221001-2466375/

政府、サイバー防衛強化へ　積極的防御案は専守防衛に抵触も(10/1)
https://news.goo.ne.jp/article/kyodo_nor/politics/kyodo_nor-2022100101000749.html

政府、サイバー防衛強化へ　積極的防御案は専守防衛に抵触も(10/1)
https://www.nnn.co.jp/dainichi/knews/221001/20221001081.html

ネットスカウトの2022年上半期DDoS脅威インテリジェンス報告書によれば、攻撃者は精度の向上と革新的な攻撃手法によってサイバー攻撃の猛攻を継続(9/30)
https://jp.acrofan.com/detail.php?number=100897

英情報局にサイバー攻撃　親露ハッカーか(10/1)
https://www.sankei.com/article/20221001-EVGFQEWBDBJCVCHHEHV2W2NOFQ/

英情報機関「MI5」のサイトがサイバー攻撃受ける＝BBC(10/1)
https://sputniknews.jp/20221001/mi5bbc-13155826.html

サイバー攻撃、十数件以上捜査　「国際共同」にも参加―摘発はゼロ、特捜隊発足半年・警察庁(10/1)
https://www.jiji.com/jc/article?g=soc&k=2022093000672

デジタル化が進む韓国の詐欺事情 被害額700億円を突破した「ボイスフィッシング」の手口(10/1)
https://www.nikkan-gendai.com/articles/view/life/312189

都水道局の偽アプリに注意　「詐欺被害につながる恐れ」(9/30)
https://www.itmedia.co.jp/news/articles/2209/30/news117.html

ECB、デジタルユーロの検証やプライバシーについて報告 調査段階から1年(9/30)
https://jp.cointelegraph.com/news/ecb-reports-on-digital-euro-validation-privacy-one-year-into-investigative-phase

今月の用語解説「中間者攻撃」(9/30)
https://japan.cnet.com/release/30784682/?ref=rss

インターネットの未来にかかわる投票、米国がロシアに圧勝　国際電気通信連合事務総局選(9/30)
https://www.cnn.co.jp/tech/35193978.html?ref=rss

島津製作所子会社の不正「タイマー」問題、別の医療機関でも発覚　計5件に(9/30)
https://www.tokyo-np.co.jp/article/205659

AWS WAF のログ分析に関する考慮事項(9/30)
https://aws.amazon.com/jp/blogs/news/aws-waf-log-analysis-considerations/

9月のWordPressプラグイン脆弱性まとめ、ただちに確認と対応を(10/1)
https://news.mynavi.jp/techplus/article/20221001-2467545/

NotionとGitHubとの連携機能とは？そのメリットや方法を解説！(10/1)
https://and-engineer.com/articles/Yylq5xEAACMA-qkt

ランサムウエア(10/1)
https://www.jiji.com/jc/article?k=2022093000677&g=tha

Googleフォトの写真が「水浸し」？ 異常報告で騒然(10/1)
https://forbesjapan.com/articles/detail/50793
importmap-railsでvue.jsの開発用ビルドと本番用ビルドの切り替えを行う

vue.js (vue.esm-browser.js) には、開発用ビルドと、本番用ビルドが用意されています。
Railsの環境に合わせて、vue.jsの環境を切り替える方法を簡単にまとめたいと思います。

vue.jsのビルドについては公式サイトをご確認下さい。

https://v3.ja.vuejs.org/guide/installation.html#%E3%81%95%E3%81%BE%E3%81%95%E3%82%99%E3%81%BE%E3%81%AA%E3%83%92%E3%82%99%E3%83%AB%E3%83%88%E3%82%99%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6


## 開発用ビルドと本番用ビルドの切り替え

`config/importmap.rb` 内で、Rails.envで環境を判定して、pinの切り替えを行います。

### CDNを利用する場合
```importmap.rb
if Rails.env.development?
  pin "vue", to: "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
else
  pin "vue", to: "https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js"
end
```
※ 実際に利用される際は、バージョンを明示的に指定して頂く方が安全です。`例)vue@3.2.40`


### ダウンロードしたファイルを利用する場合

各環境のファイルをダウンロードします。
##### 開発用
```
https://unpkg.com/vue@3/dist/vue.esm-browser.js
```
##### 本番用
```
https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js
```

ダウンロードした各ファイルを `vendor/javascript` フォルダに保存します。

「CDNを利用する場合の設定」の importmap.rb 設定から「to:」をファイル指定に変更して完了となります。

```importmap.rb
if Rails.env.development?
  pin "vue", to: "vue.esm-browser.js"
else
  pin "vue", to: "vue.esm-browser.prod.js"
end
```
Azure DevOpsのパイプラインからWebAppの環境変数を設定する

今回はWebAppの環境変数を管理をAzure DevOpsで行う方法を検証しました。
DevOpsのパイプラインで管理するメリットとしてはワークフローのyamlに環境変数を記載することでコード化され、実際のリソースで確認したり、別途ドキュメントなどで管理する必要がなくなることが挙げられます。
また、ビルド時にアプリケーションに対して設定する動的な変数と同じ運用ができるわかりやすさもあります。

### Libraryに変数を登録
LibraryにはPipelineやReleasesから利用できるシークレットなどKeyとValueの形式で登録することができます。
今回はDBへの接続情報を登録しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/d10b8d8a-4475-495c-962f-828a12b4131a.png)
※登録した変数の右側にある鍵のアイコンをクリックすることでValueがマスクされ、ログに平文が流れることを防げます。


### ワークフローにTaskを追加
AzureAppServiceSettings@1のTaskを使うことでAppServiseの設定を管理することができます。
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-app-service-settings?view=azure-devops
※variablesで参照するLibraryグループを宣言しておく

今回はappSettings（環境変数）の値を更新します。

```yaml

variables:
  - group: DB_Valiables

steps:
- task: AzureAppServiceSettings@1
  displayName: 'Azure App Service Settings'
  inputs:
    azureSubscription: '<azureSubscription>'
    appName: '<appName>'
    resourceGroupName: '<resourceGroupName>'
    appSettings: |
     [
        {
         "name": "DB_URL",
         "value": "$(DB_URL)",
         "slotSetting": false
        },
        {
         "name": "DB_USER_NAME",
         "value": "$(DB_USER_NAME)",
         "slotSetting": false
        },
        {
         "name": "DB_PASSWORD",
         "value": "$(DB_PASSWORD)",
         "slotSetting": false
        }
     ]
```

## おまけ
Releasesからも同様のTaskが実行可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/9f7e2120-1310-dab2-9f7d-e44dd35faca2.png)
注意点としてはLibraryの「Pipeline permissions」をOpen AccessにしておかないとReleasesからLibraryを参照できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/bfb5539a-8c55-5a4d-fdbb-c36c08c8c986.png)

以上、参考になれば幸いです。
自分用 git チートシート

## コミットをまとめる
```
git rebase -i HEAD~5
```
- p: 残すコミット
- s: 使うが前のコミットに溶かす

## 未追跡ファイルを消す
```
git clean -df
```

 -  [git clean](https://git-scm.com/docs/git-clean) は未追跡のファイルを操作するコマンド
 - 危険な操作なため、 `-i`, `-n`, `-f` のいずれかを使わないと実行できない
 - `-f` : 強制実行
 - `-n` : ドライラン、対象の確認
 - `-d` : ディレクトリを含む

## 直前のコミットを取り消す
```
git reset --soft HEAD^
```

||git commit|git add|ファイルの変更|どうなる？|
|---|---|---|---|---|
|--hard|取消|取消|取消|全部無かったことになる|
|--mixed|取消|取消|-|git addする前になる|
|--soft|取消|-|-|git addした後になる|
内部コンストラクタについて理解を深める。

### 内部コンストラクターと外部コンストラクターについて


Affine変換のコードを参考にしつつ、内部コンストラクタと外部コンストラクタについて理解を深める

```julia
module My

struct Affine
    W
    b
end

function (a::Affine)(x)
    a.W * x + a.b
end

end

using .My

Affine = My.Affine
W = rand(2,3)
b = rand(2)
x = rand(3)
a = Affine(W, b);
@assert a(x) ≈ keisan(W, b, x)
```


ここで、a = Affine()の引数を制限したいような時でも、関数が動くようにしたい。
この時、外部コンストラクターと内部コンストラクターで二通り考えられる。

### 1 外部コンストラクターについて

```julia
module My

struct Affine
    W
    b
end

function Affine(W::Matrix)
    r, c = size(W)
    b = zeros(r)
    Affine(W, b)
end

function (a::Affine)(x)
    a.W * x + a.b
end

end

using .My

keisan(W, b, x) = W * x + b
W = rand(2, 3)
x = rand(3)
a = Affine(W) # 引数をWに制限した
@assert a(x) ≈ keisan(W, zeros(2), x)
```

もちろん、引数がW,bの場合でも実行可能である。


```julia
W = rand(2,3)
b = rand(2)
x = rand(3)
a = Affine(W, b);
@assert a(x) ≈ keisan(W, b, x)
```


### 2 内部コンストラクターについて
structの内部で関数を定義しても上とほぼ同様の振る舞いができる。

```julia

module My

struct Affine
    W
    b
    function Affine(W::Matrix)
        r, c = size(W)
        b = zeros(r)
        new(W, b)
    end
    #Affine(W, b) = new(W, b) #これを入れないと、引数にW,bを入れた時にエラーが出る。
end

function (a::Affine)(x)
    a.W * x + a.b
end

end

using .My

Affine = My.Affine
keisan(W, b, x) = W * x + b
W = rand(2, 3)
x = rand(3)
a = Affine(W)
@assert a(x) ≈ keisan(W, zeros(2), x)
```

先ほどの外部コンストラクタの例とは異なる点として、W,bが引数の場合は実行できない。
内部コンストラクタによって、structのAffineのフィールドW,bが強く制限される。そのため、決められた引数(この場合W)以外は受け付けないようにすることができる。

```julia
W = rand(2,3)
b = rand(2)
x = rand(3)
a = Affine(W, b);
@assert a(x) ≈ keisan(W, b, x)
```


上を実行したい場合は、structの中に`Affine(W, b) = new(W, b)`を含ませる必要がある。
歪んだサイコロのgif動画




# 歪んだサイコロ


```julia
import Pkg; Pkg.add("StatsBase")
using StatsBase
import Pkg; Pkg.add("Distributions")
using Distributions


using Plots
const n6d = Dict(
        1 => "⚀", #\dicei
        2 => "⚁",
        3 => "⚂",
        4 => "⚃",
        5 => "⚄",
        6 => "⚅",
    )
const ntrial = 10000

means = Float64[]
sizehint!(means, ntrial)

anim = @animate for t in 1:ntrial
    #n1, n2, n3, n4, n5, n6 = rand(1:6, 6) 
    a = []
    for i in 1:6  
        push!(a, sample(1:6, StatsBase.ProbabilityWeights([0.5, 0.01, 0.01, 0.08, 0.4])))
    end
    
    n1 , n2 , n3 , n4 , n5 , n6 = a
    m = (n1 + n2 + n3 + n4 + n5 + n6)/6
    title = "$t times\n"
    title *= "($(n6d[n1]) + $(n6d[n2]) + $(n6d[n3]) + $(n6d[n4]) + $(n6d[n5]) + $(n6d[n6]))/6"
    push!(means, m)
    histogram(means, title=title, xticks=0:7, norm=:pdf, ylim=[0, 0.8], xlim=[0, 7], bins=10, legend=false)
end

gif(anim, "result6.gif")
```

![result6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224085/f4ef604f-e5a5-295e-279e-236abd012d9f.gif)




# 通常のサイコロ

```julia
using Plots

const n2d = Dict(
        1 => "⚀", #\dicei
        2 => "⚁",
        3 => "⚂",
        4 => "⚃",
        5 => "⚄",
        6 => "⚅",
    )
const ntrial = 1000

means = Float64[]
sizehint!(means, ntrial)

anim = @animate for t in 1:ntrial
    n1, n2, n3, n4, n5, n6 = rand(1:6, 6)
    m = (n1 + n2 + n3 + n4 + n5 + n6)/6
    title = "$t times\n"
    title *= "($(n2d[n1]) + $(n2d[n2]) + $(n2d[n3]) + $(n2d[n4]) + $(n2d[n5]) + $(n2d[n6]))/6"
    push!(means, m)
    histogram(means, title=title, xticks=0:7, norm=:pdf, ylim=[0, 0.8], xlim=[0, 7], bins=10, legend=false)
end

gif(anim, "result.gif")

```

![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224085/99307d79-5315-5fd7-ddd2-39acd7990e39.gif)


## コイン

https://zenn.dev/takilog/articles/c5d29ecbce7565


# others

歪んだコイン
https://zenn.dev/takilog/articles/c5d29ecbce7565

- 100daysofmakie 
- Makie.jlギャラリー

https://twitter.com/PG12345678/status/1454832104538181632
wsl2でvagrantを実行すると、「The host path of the shared folder is not supported from WSL」と出る


## メッセージ
```
 yuta  ~  vagrant_study  vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

vm:
* The host path of the shared folder is not supported from WSL. Host
path of the shared folder must be located on a file system with
DrvFs type. Host path: .
```

## 対処方法
以下を設定する

```
  config.vm.synced_folder '.', '/vagrant', disabled: true
```

## 参考
https://github.com/hashicorp/vagrant/issues/10576
DMM英会話とレアジョブ英会話で予約をした時に自動で予定をGoogleカレンダーに追加するGAS

DMM英会話とレアジョブ英会話で，予約したら自動でカレンダーに追加できないかなーと思い調べたところ[こちらの記事(2022/10/3アクセス)](https://designoma.com/dmm-eikaiwa-google-calendar/)を見つけました．レアジョブ英会話用のコードは1分探して見つからなかったので筆者が適当に変更したものを共有したいと思います．

## DMM英会話用(カレンダーの予定の色が変わるように参考元から少し変更）
```
var CRITERIA = "from:noreply@eikaiwa.dmm.com subject:レッスン予約 is:unread ";

function main() {
  eachMessage(CRITERIA, function (message) {
    var cal = CalendarApp.getDefaultCalendar();
    var body = message.getBody();    
    var [phrase] = /様、.*とのレッスン予約が完了しました/.exec(body);
    var [str] = phrase.match(/\d{4}\/\d{2}\/\d{2}\ \d{2}\:\d{2}/g);

    var title = "DMM英会話";
    var startTime = new Date(str);
    var endTime = new Date(startTime.getTime() + 25 * 60000);

    var event = cal.createEvent(title, startTime, endTime);
    event.setColor(CalendarApp.EventColor.PALE_RED)
  });
}

function eachMessage(CRITERIA, callback) {
  GmailApp.search(CRITERIA).forEach(function(thread) {
    thread.getMessages().forEach(function(message) {
      callback(message);
      message.markRead(); 
    });
  });
}
```
## レアジョブ英会話用
```
var CRITERIA = "from:donotreply@rarejob.com subject:レッスン予約完了 is:unread ";

function main() {
  eachMessage(CRITERIA, function (message) {
    var cal = CalendarApp.getDefaultCalendar();
    var body = message.getBody();    
    var [phrase] = /予約日時.*表記/.exec(body);
    var [str1] = phrase.match(/\d{4}\/\d{2}\/\d{2}/g);
    var [str2] = phrase.match(/\ \d{2}\:\d{2}/g);
    var str = str1 + str2;

    var title = "レアジョブ英会話";
    var startTime = new Date(str);
    var endTime = new Date(startTime.getTime() + 25 * 60000);

    var event = cal.createEvent(title, startTime, endTime);
    event.setColor(CalendarApp.EventColor.PALE_RED)
  });
}

function eachMessage(CRITERIA, callback) {
  GmailApp.search(CRITERIA).forEach(function(thread) {
    thread.getMessages().forEach(function(message) {
      callback(message);
      message.markRead(); 
    });
  });
}
```
二地点の座標（緯度経度）距離の早見表

# 概要

センシンロボティクスのテクノロジーグループのスウです。
会社に入って三年目になり、ドローン周りを開発し、経度、緯度関連のロジックに毎日に関わっている。
この文書は計算ツールがない場合、二点の座標の距離はどのぐらい単位の差があるかすぐ判断できる早見表。

# この記事を読む対象の人
- 測距カメラ（例：レーザー距離計）などで測距できた座標の小数点の桁数により、どのぐらい誤差があるか知りたい人。
- 二点座標の経度と緯度の中の一つが同じで、残る一つだけ違う場合、二点の距離はどのぐらいあるか知りたい人。

# カメラ測距できる小数点桁数により、誤差の早見表

## 説明

例えば、測距した座標の小数点は6桁の場合、例：`(35.111111,139.111111)`。
その際に、6桁以後の部分は0から9の数字である可能性があり、例えば
座標は`(35.1111110000,139.1111110000)`や`(35.1111119999,139.111111999)`などの可能性もある。
仮の想定座標は`(35.1111110000,139.1111110000)`を使って、実際の正しい座標は`(35.1111119999,139.111111999)`の場合、誤差が出ている。

下記の表はその可能誤差の早見表。
Aは仮の想定座標で、Bは実際の正しい座標。


|測距できる小数点桁数|ポイント|緯度(10桁)|経度(10桁)|AとBの距離<br>(可能誤差)|
|--|--|--|--|--|
|9|A|35.1111111110|139.1111111110||
||B|35.1111111119|139.1111111119|<0.1cm|
|8|A|35.1111111100|139.1111111100| |
||B|35.1111111199|139.1111111199|≈0.1cm|
|7|A|35.1111111000|139.1111111000| |
||B|35.1111111999|139.1111111999|≈1cm|
|6|A|35.1111110000|139.1111110000| |
||B|35.1111119999|139.1111119999|≈14cm|
|5|A|35.1111100000|139.1111100000| |
||B|35.1111199999|139.1111199999|≈1.4m|
|4|A|35.1111000000|139.1111000000| |
||B|35.1111999999|139.1111999999|≈14m|

## 結論

利用の目的によるが、細かい測量場合、測距できる小数点桁数は7桁以上の方が安全かと考える。


# 二点座標の経度と緯度の中の一つが同じで、残る一つだけ違う場合、二点の距離の早見表

## 説明

経度が同じく、緯度だけ変わる場合、大体の距離を知りたい場合、この早見表が役に立つ。

例えば、ポイントAとポイントBの経度は同じで、緯度が違う。

ポイントAの座標：`(35.111111111,139.111111111)`
ポイントBの座標：`(xx.xxxxxxxxx,139.111111111)`

|ポイントB<br>桁が違う箇所|緯度|Aとの距離|Aとの緯度差|
|--|--|--|--|
|9桁目|35.11111111`2`|<0.1cm|0.000000001|
|8桁目|35.1111111`2`1|≈0.1cm|0.00000001|
|7桁目|35.111111`2`11|≈1cm|0.0000001|
|6桁目|35.11111`2`111|≈11cm|0.000001|
|5桁目|35.1111`2`1111|≈1m|0.00001|
|4桁目|35.111`2`11111|≈10m|0.0001|
|3桁目|35.11`2`111111|≈110m|0.001|
|2桁目|35.1`2`1111111|≈1km|0.01|
|1桁目|35.`2`11111111|≈11km|0.1|

## 実際計算してみる
渋谷駅：`(35.6589047,139.7000822)`
恵比寿駅：`(35.6580808,139.6857737)`

渋谷駅と恵比寿駅の経度の差は緯度の差より大きいので、経度だけ見る。
経度の差は大体小数点以下1、2桁目の差があるので、距離は11kmより小さく、1kmより大きい。
もう少し細かく考えると、経度の差は大体0.015(0.1より0.01の方に近い)ぐらいで、距離は1kmの近くかと考えられる。

実際計算してみたら、距離は≈1.3km

## 結論

早見表は概算のため、精度を求める場合は計算ツールが必要。

簡単に言うと、
6桁目以降にだけ差がある場合、大体cm単位の距離
3~5桁目に差がある場合、大体m単位の距離
1~2桁目に差がある場合、大体km単位の距離


## 参考URL
- keisanサービス：https://keisan.casio.jp/exec/system/1257670779
- 国土地理院：https://vldb.gsi.go.jp/sokuchi/surveycalc/surveycalc/bl2stf.html
【Azure】約25時間の勉強でAZ900を取得したので、勉強方法やコツを共有してみる

# 1.はじめに
どうも、ARIの名古屋支社に勤務している愛知県民です♪
(/・ω・)/

先日、うちのベビー（1歳1か月）から「AZ900とれよ」と言われた気がしたので、
早速勉強して資格を取得してきました！

**そこで今回はAZ900を取得した勉強方法やコツについて記事にしたいと思います。**
AzureやAZ900を勉強中の方の参考になれば幸いです。
(*^^)v

:::note info
ちなみに、自分のスコアは850点でした♪

|![000_スコアレポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/85c186e5-23ff-37bd-80bd-7b3e051425c2.png)|
|:--|
:::


# 2.自分のスペック
まず初めに受験当時の自分のスペックを箇条書きで紹介します。
見ての通り、多少AWSの知見はありますが**Azureの知見は0**です。

:::note info
所持している資格

* ITパスポート
* AWS認定クラウドプラクティショナー
* AWS認定ソリューションアーキテクトアソシエイト
:::

:::note info
実務経験
* AmazonConnectを中心としたAWSに関する実務経験は約1年半
* Azureの実務経験はなし
:::

# 3.勉強方法について
では、いよいよ勉強方法についてです！

## 3.1.使用した問題集
自分は以下のUdemyで買える問題集を中心とした勉強をしました。
**解説が分かりやすく、知識の深堀りに必要な参考URLも付いているので、おすすめです♪**

https://www.udemy.com/course/microsoft-azure-az900-exam/

## 3.2.具体的な勉強方法と勉強時間の内訳

先ほどのUdemyの講座には全5回(+旧試験範囲1回)分の問題が付いています。
**自分は旧試験範囲の分は解かずに、以下の10時間を1セットとして、2回繰り返しました。**
（解くときのポイントは後述します）

|内容|時間|
|---|---|
|問題演習（第1回） | 30分|
|上記演習の解説を読んで知識を深める | 1.5時間 |
|問題演習（第2回） | 30分 |
|上記演習の解説を読んで知識を深める | 1.5時間 |
|・・・ | ・・・ |
|問題演習（第5回） | 30分 |
|上記演習の解説を読んで知識を深める | 1.5時間 |
|合計 | 10時間 |

各回で正答率が表示されるため、**正答率が80%未満の問題演習については3回目も解きました。**
自分は半分くらいを解くことになったので、5時間ほど使いました。

以上より、自分が費やした時間は「10時間×2 + 5時間」で合計25時間となります。

また、2,3回目の「演習の解説を読んで知識を深める」時間は1回目よりも短くなると思うので、
**人によっては15~20時間くらいで完走できる**と思います。

:::note info
ちなみに、自分は試験勉強開始から受験までが約15日で、週5回、2~2.5時間勉強する短期集中型でしたが、
3ヵ月間で、週1回、2時間の勉強を3ヵ月続ける長期的なプランも良いと思います♪
:::

## 3.3.勉強する際のコツ

:::note warn
個人的にはこのセクションが一番大切な気がしています・・・！
:::
### 3.3.1.正答率は80%を目標にする
実際の試験は70%以上で合格ですが、
**70%を目標にすると当日知らない問題が出て、
ギリギリ不合格になる可能性があると考えたため、**
試験勉強の段階では80%を目標にするのがおすすめです♪

### 3.3.2.自信がない問題にはすべて「★」をつける
Udemyの問題集では、各問題に「★」をつけることができます。
自分は自信がない問題にはすべて「★」をつけ、
回答の正解・不正解に応じて、以下の見直しをしていました。

||「★」あり|「★」なし|
|---|---|---|
|正解 | 回答を読み、サービス名をGoogle検索し、<br>参考URLがあればそれも確認して知識を深める。 |特に問題ないので次に進む。|
|不正解 | 回答を読み、サービス名をGoogle検索し、<br>参考URLがあればそれも確認して知識を深める。 |**自信があったのに間違えた**ということなので、<br>知識が足りなかったのか、<br>問題文を読み間違えたのか等、<br>なぜ間違えたのかを細かく確認する。<br><br>その後、回答や参考URLを確認して知識を深める。|

また、**Makoto Okadaさんのブログ**がとても分かりやすかったので、
こちらも確認しつつ、AZ900に必要な知識を身に付けました。

https://az-start.com/


### 3.3.3.不正解の回答についても調べる

先ほど紹介した問題集では、不正解の理由が分からない問題が何問かあるので、
自分はなぜそれが不正解なのかまで調べて、次に出た時に備えていました。

:::note info
例えば、「Azure Function」が不正解だったときに調べておくと、
他の問題で出た時に正解を絞り込むことができるため、おすすめです♪
:::

### 3.3.4.試験日をあらかじめ決めておく
こちらは他の方の体験記にも多く記載がありましたが、
自分も試験日を決めておき、そこから逆算して勉強するのをおすすめします。

**終わりを決めておかないと頓挫する可能性や、「来週はやる」みたいな感じのさぼりが出やすいと考えています。**

# 4.テストセンターか、自宅か
受験に際してはテストセンターか自宅かを選択できると思いますが、
**個人的にはテストセンターでの受験をおすすめします。**

理由としては以下の2点ですので、この辺りが気にならない方は自宅でもOKかなと考えています。

* 自宅だとWi-Fi等の不具合でつながらない可能性がある
* 本棚はタオルで隠す、カメラで全方位を写す等、準備が少し大変

# 5.AZ900を無料で受験する方法
今回、自分は使用しなかったのですが、
Microsoftのセミナーを受けるとAZ900を無料で受験できるクーポンがもらえるみたいです。
**普通に受験すると13500円くらいかかるのでお得ですね・・・！**

具体的には以下のURLに接続し「Microsoft Azure Virtual Training Day: Azureの基礎」
を受講するとクーポンがもらえます。

https://www.microsoft.com/ja-jp/events/top/training-days/

# 6.おわりに
ここまで読んで下さり、ありがとうございます！！！
(^^)

今回は問題集ベースの勉強法でしたが、どうにか合格することができました！
Azure関連の資格は他にもDP900やAI900があるので、もしそちらも取得できれば報告したいと思います♪
(:3_ヽ)_
【TypeScript】多次元オブジェクトの末端の値を簡単に取り出したい


# やりたいこと

こんなオブジェクトがあったら

```js
const hoge = {
  aaa: 'A',
  bbb: {
    ccc: 'BC',
    ddd: {
      eee: 'BDE',
      fff: 'BDF',
    },
  },
};
```

こんな感じで取り出したい

```js
pick(hoge, 'aaa') // 'A'
pick(hoge, 'bbb-ccc') // 'BC'
pick(hoge, 'bbb-ddd-eee') // 'BDE'
```

TypeScriptで動的に取り出す部分を変えたい場合、`hoge[key1][key2]`のように取り出すと型エラーが出るため。

# TypeScriptのコード

単純化のためにキーもバリューもstring型とする。

--- 2022/10/03更新 ---
@shiracamusさん @akebi_mhさん のアドバイスを受けてコード更新。
JavaScriptの場合の書き方はお二方のコメントをご参照ください。

```ts
type Input = { [x: string]: string | Input };

function pick(obj: Input, key: string) {
  return key
    .split('/')
    .reduce<string | Input>(
      (o, c) => (typeof o === 'object' ? o[c] ?? '' : o),
      obj,
    );
}
```
gitの復習

# はじめに
webアプリ開発について、学んでいる中、gitの学習をすっかり忘れていたので、ざっと復習。

# gitの概要
今までは、githubというサービスにファイルなどを保存している気でいたが、githubは、リモートサーバーの状態を、ブラウザで表示するツールのことだった。理解不足でした。

## 流れ
1. gitのインストール（済でした）
1. 新規リポジトリーの作成（または、既存のリモートリポジトリ―をコピー）
1. ステージング（リポジトリ内のファイル(の変更点）を、管理対象に加える）
1. ステージングの変更分を、「ローカルリポジトリに」反映させる
1. ローカルリポジトリの変更分をリモートリポジトリに反映させる



## コマンド

1. webページからダウンロードしていました
1. git init （リモートリポジトリからコピーする時は、git clone コピーしたurl)
1. git add ファイル名 (リポジトリ内のすべてのファイルを管理対象にするなら、 git add . )
1. git commit -m "残したいメッセージ"
1. git push origin

## 困ったこと　知らなかったこと
・始めに、git clone リポジトリ名で、githubからコピーしてきたとき、
```
warning: 'You appear to have cloned an empty repository'
```
　と表示されて焦ったが、単にリポジトリの中にファイルがないだけだった模様。

・vscodeで編集中に、pushをしていなかったせいで、こんがらがって、git pull を使って、画面でマージするようなことになった。感覚で動かしていたら思うようにはなったが、検索すると、git pullは初心者は使わない方がいいと出てきたこともあり、ここも復習が必要になった。
## 最後に
tutorialなどにそって、コマンドを入力しているだけだと、その場で理解していても、日にちがたつと、何のためのコマンドだったか忘れてしまうので、触れる前にざっと概念を理解しておくと、覚えやすいと感じた。
これからも、調べものをするときなどは、２度手間にならないように、考えて整理しながら学習したい。
Hoverすると画像が拡大するJSライブラリ「magnify.js」を作ってみた

ふと、「css で `transform: scale(x)` したいけど、他の JS ライブラリが transform プロパティをいじっていて併用できないよー」なシチュエーションに出くわしたので、バッティングしないように同じく js で transform プロパティを丁寧にいじるコードを書きました。

そんなニッチな需要がどれくらいあるかわからないけど、興味本位で（初めて）ライブラリ化して公開してみたのでそのご紹介です。

## 概要

画像をはじめとして任意の要素をマウスオーバー時に拡大することができるライブラリです。

* ソースコード

https://github.com/SogoKato/magnify.js

* デモページ（雑ですみません）

https://sogo.dev/magnify.js/

## つかいかた

```html
<div class="magnify">
    I will be 1.5x big (the default).
</div>
<div class="magnify" data-magnify-scale="2">
    I will be 2x big.
</div>

<script src="https://cdn.jsdelivr.net/gh/SogoKato/magnify.js@main/magnify.min.js"></script>
<script>
    // Apply for each element with `magnify` class (default behavior).
    const magnify = new Magnify(".magnify");
</script>
```

1. CDN 経由またはファイルをダウンロード & 配置で `magnify.min.js` を読み込みます
1. 拡大したい要素に `magnify` クラスを付与します
1. 必要な場合は任意の拡大率を `data-magnify-scale` 属性に設定します
1. `new Magnify()` !

詳しい設定内容については [README.md](https://github.com/SogoKato/magnify.js/blob/main/README.md) をご覧ください。

## 作ってみた感想

* 初めて js のライブラリを作ってみて、こういうふうに作るのね、と発見が多かった
  * 構造についてはパララックスのライブラリ [Rellax](https://github.com/dixonandmoe/rellax) を参考にさせてもらいました :pray: 
* CDN 配信ってどうやるんだろうと思ったら、何も設定しなくても jsdelivr 君が GitHub から取ってきてくれた
  * ルールに従ったリンクを書くだけ！
* 現状はささっと作っただけなので拡大するとオーバーフローしちゃう場合がある
  * 細かいオプションは今後増やしていきたいかも

ご意見・ご感想がありましたら、ぜひコメントや GitHub issue に書いていただけるととても喜びます！  
それでは！
TypeScriptの型の省略と抜粋　OmitとPickを使ったまとめ

# はじめに
TypeScriptを書いてるとTypeで型を定義して書くことがあると思いますが、
PickとOmitを使うと、既に定義してある型を利用して、効率よく開発することができます。
PickとOmitの使い方を学んだ内容を簡単にまとめました。

# 型の省略
```Omit```を使うと、、TypeScriptの型の省略ができます。

下記のTodoTypeが既に定義してあり、userIdとidとtitleを型定義したい時があるとします。
```react
export type TodoType = {
  userId: number;
  id: number; // idいらない
  title: string;
  completed: boolean; 
};
```

Omitを使うと、指定した型を省略できます。
```react
export const Todo = (
  props: Omit<TodoType, "id"> // // Omitを使ってidを省略する
) => {
  const { title, userId, completed } = props;
  const completeMark = completed ? "[完]" : "[未]";
  return <p>{`${completeMark}${title}(ユーザー:${userId})`}</p>;
};
```

# 型の抜粋
```Pick```を使うと、TypeScriptの型の抜粋ができます。


下記のTodoTypeが既に定義してあり、userIdとtitleとcompletedだけを型定義したい時があるとします。
```react
export type TodoType = {
  userId: number; // 欲しい
  id: number;
  title: string; // 欲しい
  completed: boolean; // 欲しい
};
```

Pickを使って、利用したい型のみを抜粋することができます。
```react
export const Todo = (
  props: Pick<TodoType, "userId" | "title" | "completed"> // Pickを使ってuserIdとtitleとcompletedを抜粋する
) => {
  const { title, userId, completed } = props;
  const completeMark = completed ? "[完]" : "[未]";
  return <p>{`${completeMark}${title}(ユーザー:${userId})`}</p>;
};
```

# 使い方まとめ
```react
/* 型の抜粋 */
Pick<元の型定義,抜粋したい型>

/* 型の省略 */
Omit<元の型定義, 省略したい型>
//　複数ある場合、|でつなぐ
Omit<元の型定義, 省略したい型|省略したい型>
```
[Unity]PC(Windows)でビルド(.exe)したときに全画面表示になる問題

Unity:2021.3.5f1
Windows11
解決したのでメモ。
# 経緯
タイトルのまま。
Windowsでビルドして、実行ファイル(.exe)を実行したら全画面表示になった。
本当は下図（右側→）みたいに、ウィンドウ内にゲーム画面を表示したかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/ac116c69-d8bb-1545-ca50-21ae63e3eb8c.png)

## まずは結論
１．Edit>ProjectSetting>Player>Resolution and Presentationを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/18b2ec6f-80a2-bcf9-e7f3-12143369877f.png)
２．Resolution and Presentation内にて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/ce3ee2d9-68e7-1d05-b83a-eb738ab392ca.png)
* 「Fullscreen Mode」はWindowed
* 「Resizable Window」にチェック☑
* 「Allow Fullscreen Switch」にチェック☑

これでビルドしたら、理想通りにウインドウにゲーム画面を表示できました。

## 各種設定の内容
（とりあえず動けばいいやって方はここからは見なくても大丈夫）

↓　上で設定した内容の中身について　↓
| 設定のなまえ |  内容 |
|:-|:-|
|Fullscreen Mode          |起動時、全画面表示にするかどうか。   <br>  |
|Resizable Window         |ウィンドウサイズを変更できるようにするか。<br>※このチェックを外すと、全画面表示は使用できなくなる。 |
|Allow Fullscreen Switch  |これにチェックすると、PCの全画面キー(※)で全画面モードと<br>ウインドウ表示を切り替えられる。 |

※全画面表示はwindowsならF11キー

↓　Fullscreenのドロップダウンにある選択肢について　↓　
| 選択肢 | 内容 |
|:-|:-|
| Fullscreen Window 　　 | 全画面表示。デフォルトではこれになってる。<br>解像度は自動で画面に合わせてくれる。 |
| Exclusive Fullscreen <br>(Windows専用)  | 全画面表示。<br>解像度は自分が選択した解像度（※）になる。  |
| Maximized Window  <br>(Mac専用)  | 上に同じ。  |
| Windowed |  ウインドウ表示。ウィンドウの大きさを変えられる。<br>※ウインドウの大きさを固定したいときは「Resizable Window」にチェック。 |

※自分が選択した解像度とは：上記「Exclusive Fullscreen」または「Maximized Window」を選択してビルド→アプリ実行すると、最初に「解像度を選択する画面（[参考](https://nakamura001.hatenablog.com/entry/2019/04/18/Unity%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AE%E8%A7%A3%E5%83%8F%E5%BA%A6%E9%81%B8%E6%8A%9E%E3%81%AE%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AD%E3%82%B0%E8%A1%A8%E7%A4%BA)）」が出る。そこで設定した解像度のこと。

参考：
[Windows PlayerSetting -Unityマニュアル](https://docs.unity3d.com/ja/current/Manual/playersettings-windows.html#Configuration)
[Unity：固定ウィンドウ、可変ウィンドウ、フルスクリーンにする設定](http://www.fast-system.jp/unity-fullscreen-windowed-fixed-resizable/)
SHARP Brain に Linux を入れて遊ぶ(5) - シリアル通信

[目次](https://qiita.com/nekopro2/items/7eff2eb5e1c4480d3b30)

# 概要
SHARP Brain で何しようと思った時に、シリアル通信できると他のデバイスをつなげて遊べそうだと思ったので試してみました。

## 前提
普通にUSBシリアルを繋げたら /dev/ttyUSB で認識するかなーと思ったけどダメっぽい。
ならば libusb か FTDI のライブラリを入れるまでよ。

## FTDI ライブラリ
FTDI ライブラリが動くんなら Windows でも Mac OS X でも Linux でもデバグしやすいので、確認してみる。
FTDI の [D2XX DirectDrivers](https://ftdichip.com/drivers/d2xx-drivers/) を見ると、下のほうに Linux 1.4.22 ARMv5 soft-float があるので、これを入れる。
![ftdi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821068/61b13961-2374-1a98-8db2-a3cf73ba4479.png)

libftd2xx-arm-v5-sf-1.4.22.gz がダウンロードできるが、中身はどうみても .tar なので tar xf で解凍。
~~~
user@brain:~$ tar xf libftd2xx-arm-v5-sf-1.4.22.gz
~~~

続いて release/ReadMe.txt に従ってインストール。
~~~
user@brain:~$ cd release/build/
user@brain:~/release/build$ sudo -s
[sudo] password for user:
root@brain:/home/user/release/build# cp libftd2xx.* /usr/local/lib/
root@brain:/home/user/release/build# chmod 0755 /usr/local/lib/libftd2xx.so.1.4.22
root@brain:/home/user/release/build# ln -sf /usr/local/lib/libftd2xx.so.1.4.22 /usr/local/lib/libftd2xx.so
root@brain:/home/user/release/build# cd ..
root@brain:/home/user/release# cp ftd2xx.h /usr/local/include/
root@brain:/home/user/release# cp WinTypes.h /usr/local/include/
root@brain:/home/user/release# ldconfig -v
root@brain:/home/user/release# exit
exit
~~~

これで ftdxx.h をインクルード、 -lftdxx すれば使える。
ただ、Brainux のアプリからシリアル アクセスするには root が必要なので、実行時には sudo しよう。


## 通信クラス
ざっくり作成。
https://gitlab.com/nekodevteam/brainux/-/tree/main/ft2xx

WindowsでもLinuxでも動作するので、まずはそっちでテストしよう。

## テスト
テスト コードでは、とりあえず最初のデバイスを開いて A～Z を送信 / 受信をします。

1. 秋月の [FT234X](https://akizukidenshi.com/catalog/g/gM-08461/) を接続する。
1. TxD と RxD をショートさせて ループバックさせる。
![ft.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821068/ab995497-4fea-b0ed-2cef-ca705df6f0d5.jpeg)
1. make する
1. sudo ./ft2xxtest
~~~
user@brain:~$ cd ft2xxtest/
user@brain:~/ft2xxtest$ make
gcc -Wall -O3 -c -o ft2xxtest.o ft2xxtest.cpp
gcc  -g -o ft2xxtest ./ft2xxtest.o -lftd2xx -lstdc++
strip ft2xxtest
user@brain:~/ft2xxtest$ sudo ./ft2xxtest
[sudo] password for user:
Devices
 - DM01P46D
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ...
~~~
コンテナ内のNext.js（Webpack）でHMRが動作しなくて困った

別の記事[（MacでDockerの代わりにpodmanを使ってみた）](https://qiita.com/ckbys/items/b56b8cf2f73a603588d3)の動作検証中に、Dockerコンテナでfrourioを動かしていたのですがコードを編集してもHMRが動作しなくて変更が反映されず困りました。
以下、その時の解決手順メモ。

# 環境

Mac
Next.js 12
frourio
podman 4.2.1

# next.config.jsにWebpackのpollを設定

こちらの記事[（next.jsでホットリロードされないときの対処法）](https://laby-tech.com/column/94/)を参考にwebpack.config.jsを以下のように設定しました。

```js
module.exports = {
  reactStrictMode: true,
  webpackDevMiddleware: config => {
    config.watchOptions = {
      poll: 800,
      aggregateTimeout: 300,
    }
    return config
  },
}
```

で、変更は反映されるようになったのですがコンテナ側のCPU使用率が死ぬほど高くなってしまいました。
pollの間隔とかの問題ですかね。ディスクアクセスが多くなるとどうしても負荷が高くなります…

# docker-compose.ymlに環境変数を設定

## CHOKIDAR_USEPOLLING=true

こちらの記事[（Docker環境でNextjsのHot Reloadが効かない場合の対策）](https://zenn.dev/jpn_asane/articles/4b774619daa8a7)を参考に環境変数を設定してみました。

```compose.yml
  environment:
    - CHOKIDAR_USEPOLLING=true
```

が、これは特に効果がありませんでした。環境が違うのかな？

## WATCHPACK_POLLING=true

こちらの記事[（Next.jsでwebpack5使うとHotReloadが動かなかった件）](https://jws.work/blog/Next.js%E3%81%A7webpack5%E4%BD%BF%E3%81%86%E3%81%A8HotReload%E3%81%8C%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E4%BB%B6/)を参考に環境変数を設定してみました。

```compose.yml
  environment:
    - WATCHPACK_POLLING=true
```

変更が反映されるようになり、コンテナ側のCPU使用率も変更前とさほど変わらない状態になりました。
ファイルをwatchする仕組みが違うのでしょうか。詳しくは調べてないですがこちらの環境ではこの設定が適していました。
【2022年10月版】 スピードテストサイトリスト

# 【2022年10月版】 スピードテストサイトリスト

- [ブロードバンドスピードテスト](https://www.bspeedtest.jp/)
- [BNRスピードテスト](https://www.musen-lan.com/speed/)
- [fast.com](https://fast.com/ja/)
- [Google スピードテスト](https://www.google.com/search?q=%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%86%E3%82%B9%E3%83%88)
- [みんなのネット回線速度](https://minsoku.net/)
- [SPEEDCHECK](https://www.speedcheck.org/ja/)
- [SPEEDTEST](https://www.speedtest.net/ja)
- [スピードテスト.jp](https://xn--zcka2bjc9dzp.jp/)
- [USEN GATE 02 インターネット回線スピードテスト](https://speedtest.gate02.ne.jp/)
- [Wild Speed](http://wild-speed.jp/netspeed/index.html)
C#のawaitがよくわからないのでいろいろ試してみた

```
        static async Task Main(string[] args)
        {
            var sw = new Stopwatch();
            TimeSpan ts;

            sw.Start();

            var result1 = await WaitProcess(5).ConfigureAwait(false);
            var result2 = await WaitProcess(3).ConfigureAwait(false);
            var result3 = await WaitProcess(1).ConfigureAwait(false);

            var sum = result1 + result2 + result3;

            sw.Stop();
            ts = sw.Elapsed;

            Console.WriteLine($"sum process took {ts.TotalMilliseconds} milli sec.");

            sw.Restart();

            var result4 = WaitProcess(5);
            var result5 = WaitProcess(3);
            var result6 = WaitProcess(1);

            var res4Result = await result4.ConfigureAwait(false);
            var res5Result = await result5.ConfigureAwait(false);
            var res6Result = await result6.ConfigureAwait(false);

            sum = res4Result + res5Result + res6Result;

            sw.Stop();
            ts = sw.Elapsed;

            Console.WriteLine($"sum process took {ts.TotalMilliseconds} milli sec.");

            sw.Restart();

            var result7 = WaitProcess(5);

            await WaitProcess(7);

            var result8 = WaitProcess(3);
            var result9 = WaitProcess(1);

            var res7Result = await result7;
            var res8Result = await result8;
            var res9Result = await result9;

            sum = res7Result + res8Result + res9Result;

            sw.Stop();
            ts = sw.Elapsed;

            Console.WriteLine($"sum process took {ts.TotalMilliseconds} milli sec.");

            sw.Restart();

            var result10 = WaitProcess(5);
            var result11 = WaitProcess(3);
            var result12 = WaitProcess(1);

            var res10Result = await result10;
            var res11Result = await result11;

            await WaitProcess(7);

            var res12Result = await result12;

            sum = res10Result + res11Result + res12Result;

            sw.Stop();
            ts = sw.Elapsed;

            Console.WriteLine($"sum={sum} sum process took {ts.TotalMilliseconds} milli sec.");
        }
```

```
5 sec task Start!
5 sec task Complete!
3 sec task Start!
3 sec task Complete!
1 sec task Start!
1 sec task Complete!
sum process took 9485.2903 milli sec.
5 sec task Start!
3 sec task Start!
1 sec task Start!
1 sec task Complete!
3 sec task Complete!
5 sec task Complete!
sum process took 5013.1635 milli sec.
5 sec task Start!
7 sec task Start!
5 sec task Complete!
7 sec task Complete!
3 sec task Start!
1 sec task Start!
1 sec task Complete!
3 sec task Complete!
sum process took 10035.8225 milli sec.
5 sec task Start!
3 sec task Start!
1 sec task Start!
1 sec task Complete!
3 sec task Complete!
5 sec task Complete!
7 sec task Start!
7 sec task Complete!
sum=9 sum process took 12004.8536 milli sec.
```

awaitいれると同期的処理になるっていうけど、この実験でだいたい理解できた気がする｡｡｡
というか、やってみると大したことないというか、こういうことかぁって感じ｡｡｡｡

以上
Rails7 APIモード device エラー「verify_authenticity_token has not been define」

# 結論
ApplicationControllerで継承元をAPIからBaseに変更する。
```ruby
class ApplicationController < ActionController::Base
        include DeviseTokenAuth::Concerns::SetUserByToken

        skip_before_action :verify_authenticity_token
        helper_method :current_user, :user_signed_in?
end
```
Linux キャパシティプランニング

# 【Linux キャパシティプランニング】
備忘録です。

## コマンド
- メモリやスワップの情報
    - top
    - free
    - vmstat
- プロセス情報
    - top
    - ps
    - pstree
- CPUの平均負荷（直近1分、5分、15分）
    - top
    - uptime
- メモリ、仮想メモリの詳細状態を継続的に監視
    - vmstat
- CPUの利用状況、ディスクの入出力情報を継続的に監視
    - iostat
    - （NFS：nfsiostat、CIFS：Pcifsiostat）
- さまざまなシステム統計情報
    - sar 
- ログイン中のユーザーとそのプロセス
    - w
- ネットワークの統計情報
    - netstat
- 開いているファイルとポート確認
    - lsof
IntelliJで「11は無効なソース・リリースです」

最近、Intellij を使用するようになりました。
しかし、Intellij を使用している際、「11は無効なソース・リリースです」というエラーが発生しました。
Java のバージョンに問題がある事までは、わかったのですが、具体的にどうしたらいいかという事が分かりませんでした。

このエラーの原因を調整していく中で、Intellij の以下部分を修正する必要が分りました。

- Project SDK
`プロジェクトを右クリック→Open Module Settings→Project→Project SDK` 
上記の順に進んでいくと、Project SDK があります。
このProject SDK を該当のバージョンに修正する必要があります。

- Language level
`プロジェクトを右クリック→Open Module Settings→Module→Source→Language level`
Language level のバージョンを該当のバージョンに修正する必要があります。

- Module SDK
`Modules→Dependencies→Module SDK`
Module SDK のバージョンが異なっている場合もあるので、該当バージョンに修正する必要があります。

- Gradle JVM
`Preferences→Build, Execution, Deployment→Build Tools→Gradle→Gradle JVM`
Gradle JVM も同様に、該当のバージョンに修正する必要があります。

上記の4点を修正した結果、このエラーを解決することができました。
0の0乗は何か？

0の0乗は何かを検索するといろいろな意見が出てきます。

「1だ」「いや0だ」「いやそもそも定義できない」など。

そこでpythonでy=0^xのグラフを描いて検証しました。

指数関数のグラフを描くのに下の記事を参考にしました。

https://qiita.com/Cesaroshun/items/8dd2321f909ae6ec7566?fbclid=IwAR0KZ0LEwvo83bI-ffrDceNvY_DoOR32qbNYUq27Jn-Dqw5A_nsfSR7bdIo

コードは以下です。

```python:o^o
import matplotlib.pyplot as plt
import numpy as np
import math
x = np.arange(0, 10, 0.1)
y = 0**x
plt.plot(x, y)
plt.ylim(-1.5, 1.5)
plt.show()
```

出力結果は下になりました。

![0power0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1210818/c3c00989-ea00-0bd1-4ce7-9e1a08656294.png)

pythonによると0の0乗は1らしいですね。

信じるか信じないかはあなた次第です(ｷﾘｯ
【TypeScript】多次元オブジェクトの1次元化


# やりたいこと

こんなオブジェクトがあったら

```js
const hoge = {
  aaa: 'A',
  bbb: {
    ccc: 'BC',
    ddd: {
      eee: 'BDE',
      fff: 'BDF',
    },
  },
};
```

こんな感じに変換したい

```js
{
  'aaa': 'A',
  'bbb-ccc': 'BC',
  'bbb-ddd-eee': 'BDE',
  'bbb-ddd-fff': 'BDF',
};
```

単純化のためにキーもバリューもstring型とする。

# TypeScriptのコード

JavaScriptなら単に型情報を省けばOK

```ts
type Input = { [x: string]: string | Input };
type Output = Record<string, string>;

/** 多次元オブジェクトの1次元化 */
function flattenObject(obj: Input, sep: string): Output {
  const entries = Object.entries(obj)
    .map(([k1, v1]) => {
      if (typeof v1 === 'string') {
        return [[k1, v1]];
      } else {
        const childObj = flattenObject(v1, sep);
        return Object.entries(childObj).map(([k2, v2]) => [k1 + sep + k2, v2]);
      }
    })
    .flat();
  return Object.fromEntries(entries) as Output;
}

// こんな感じで使う
flattenObject(hoge, '-')
```
（Unity）Joystick PackのFloating Joystickを使う場合の注意

## 0.0 はじめに
UnityのAsset（アセットストア）のJoystick Packを使うと3D、2D問わずゲームにバーチャルスティックを簡単に実装できます。
バーチャルスティックの種類もFixed（スティックは常に表示され、位置が固定されている）、Floating（スティックはタップされるまで非表示だが、タップされたらその場にスティックが表示される）とDynamic（スティックはタップされるまで非表示だが、タップされたらその場にスティックが表示され、ドラッグすると追従する）という3種類のモードがあります。
ただCanvasのRender Modeの設定がScreen Space - Camera（RenderMode==ScreenSpaceCamera）の状態で、Floatingモードをつかうと1回目だけコントローラーが表示されない、動作が変な感じになります。

対策を見つけるのにかなり時間がかかったので忘れないうちに記事にしておきます。
もちろん、CanvasのRender Modeの設定をScreen Space - Overlayを変えればこの問題は起きなくなります。












## 1.0 スクリプトの変更
ScriptsフォルダのBaseフォルダにあるJoystickを変更します。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352037/4c5e93f3-2e13-4860-6cdd-e23661386f13.png)
















ScreenPointToAnchoredPosition関数（138行目あたり?）の頭 、Vector2 localPoint = Vector2.zero;の前、（もしくはすぐ後）に下記の記述を挿入する


```C# Test.cs
if (cam == null && canvas.renderMode == RenderMode.ScreenSpaceCamera)
    cam = canvas.worldCamera;
```



この記述がないとcam変数にcanvas.worldCameraが設定されないので、canvasの大きさが考慮されずJoystickの位置が意図しない場所に表示されてしまいます。
ちなみにこの関数を呼んでいるFloatingJoystickクラス（Joystickクラスの継承先）ではScreenPointToAnchoredPosition関数の後にOnPointerDown関数を呼んでいますが、こちらの関数にはこの記述が含まれている、、、、なぜだろう？
 




## 2.0 その他、このアセットについて
###### FloatingモードとDynamicモードでは、デフォルトだとRect Transformが画面左下側に偏っているので画面左下側のみでしか反応しません。画面全体でJoystickつかうのであれば幅Widthと高さHightを画面サイズに変更しましょう（このときAnchorsやAnchor Presetsは変更せず左下基準のままとする）。
###### このアセットはUIなのでCanvasに入れる必要があります。
pythonで前月の最終日からNヶ月前の初日にデータを区切る

# 最初に

機械学習やデータ分析で、特定の期間にデータを絞りたいなという時があると思います。

アドホックに絞る場合はPySparkや素のSQLで簡単に絞れますが、これを自動で、動的に絞りたいときはどうするか？

ということで、コーディングしてみました。

# ゴール
「プログラムを実行する日」を起点として、「その前月の最終日」から「3ヶ月前の月の初日」の2つを取得したいと思います。

# 流れ
## 「プログラムを実行する日」を取得する
つまり本日のdatetimeを取得します。
```python
from datetime import date

current_datetime = date.today()
print(current_datetime)
>>> 2022-10-02
```
## 「その前月の最終日」を取得する
### プログラム実行日の前月データ
relativedeltaメソッドを使います。
```python
from dateutil.relativedelta import relativedelta

one_month_ago_datetime = current_datetime - relativedelta(months=1)
print(one_month_ago_datetime)
>>> 2022-09-02
```
### 前月の最終日
月の最終日とは、その月の日数に等しいので、それから取ります。
```python
import calendar

target_end_datetime = get_last_date(one_month_ago)
print(target_end_date)
>>> 2022-09-30
```
参考にさせていただきました。

https://note.nkmk.me/python-datetime-first-last-date-last-week/

##「3ヶ月前の月の初日」を取得する
### まともにやるとダメ
まともに考えると、上のtarget_end_datetimeから、relativedeltaで3を引けばいいのですが、これをすると
```python
three_month_ago_datetime = target_end_datetime - relativedelta(months=3)
print(three_month_ago_datetime)
>>> 2022-06-30
```
となるので、欲しい「2022-07-01」とは若干異なりますね。
確実性を保つために、別の方法を試します。

### 「2ヶ月前の月の初日」を取ることにする
まず2ヶ月前のdatetimeを取って、
```python
two_month_ago_datetime = target_end_datetime - relativedelta(months=2)
print(two_month_ago_datetime)
>>> 2022-07-30
```
この月の初日を取ることにします。
```python
target_first_datetime = two_month_ago_datetime.replace(day=1)
print(target_first_datetime)
>>> 2022-07-01
```
これで出来ました。


# 元データがただの文字列だったら？
元データがただの文字列（yyyyMMdd）であれば、これを一旦datetime型に直して上のコードを使う必要があります。

https://pg-chain.com/python-datetime-strptime
AWS自主学習 ハンズオン コンテナ・SQS・Lambda・S3

AWSのお勉強。EC2、SQS、Lambda、S3をハンズオンで使ってみる。

やりたいこと
1. 自PC→コンテナ(docker on EC2)にテキストデータを送信
自PCでcurlをたたいてテキストデータを送信、
docker on EC2の自作goプログラムでデータ受信

2. コンテナ→SQS
 コンテナ(自作goプログラム)からSQS標準キューにテキストデータを連携。

3. SQS→Lambda
 SQSをイベントソースにしてLambdaをキック。

4. Lambda→S3
 LambdaからS3にテキストファイルを作成。


## チャレンジその１
まずは簡単な構成で作ってみる。
![HandsOn.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/f36ae2cc-b7d8-b472-21a6-b07b19bde9b3.png)

## チャレンジその２
もう少し現実的な構成にしてみる。
何でもパブリックサブネットはやめてALBだけとし、
docker on EC2 は ECS on Fargate に変更してプライベートに配置、
SQSに抜けるところはPrivatelink、S3に抜けるところはGateway型VPCエンドポイントに変更
![HandsOnのコピー.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/592efd7e-a745-bd69-3d6b-fb043dc088d7.png)


## 進捗
次回からひとつひとつやっていく
（できたところまで随時リンクを貼っていきます）

### [進捗]事前準備
- [x] [0-1. Windows10からcurlをたたくには](https://qiita.com/simis/items/2164e19a728a61570db4)
- [x] [0-2. 開発環境(Cloud9)を準備する](https://qiita.com/simis/items/6a1298cb8a0c45daf367)


### [進捗]チャレンジその１
- [ ] 1-1. VPC/subnet/EC2をterraformで作る
- [ ] 1-2. (事前学習)docker
- [ ] 1-3. (事前学習)go言語
- [ ] 1-5. (事前学習)Gin ※go言語のWebフレームワーク
- [ ] 1-6. EC2にdockerを入れてgo言語 & Ginで200 OKを返すだけの簡易WebAPIを作る
- [ ] 1-7. SQSをterraformで作る
- [ ] 1-8. WebAPIを拡張しSQSエンキュー処理を追加する
- [ ] 1-8. (事前学習)Lambda
- [ ] 1-9. SQSをイベントソースとしたLambdaを作る(SQSから呼ばれて起動するだけの処理)
- [ ] 1-10. LambdaからS3にファイル作成する

### [進捗]チャレンジその２
- [ ] 2-1. VPC/subnet/EC2をterraformで作る
- [ ] 2-2. EC2にdockerを入れてECS上で動かす業務APコンテナイメージを作成する
- [ ] 2-3. ECRにプッシュする
- [ ] 2-4. ALB/ECSをterraformで作成する
- [ ] 2-5. Privatelink、SQSをterraformで作る
- [ ] 2-6. SQSをイベントソースとしたLambdaを作る(SQSから呼ばれて起動するだけの処理)
- [ ] 2-7. LambdaからVPCエンドポイント経由でS3にファイル作成する
docker-compose up -d実行時にエラー発生  "ERROR: In file './docker-compose.yml', volume must be a mapping, not a string."


Docker,Vagrantの学習をメインに続けています。その過程で、DockerfileをビルドしてからRuby,Postgresqlのイメージをpullしてきて簡易的なwebサイトの構築を実施していますが、コンテナが立ち上がらないエラーが発生しました...（泣）

# 1.エラー
Dockerfileをビルドさせた後に、docker-compose.ymlファイルを作成してdocker-compose up -dをしたら下記のエラーが発生しました。
````
$ docker-compose up -d
ERROR: In file './docker-compose.yml', volume must be a mapping, not a string.

````

# 2.原因
これは、間違いなくdocker-compose.ymlファイルの記述が間違ってますね！でも、どこが間違っているのでしょうか？
"volume must be a mapping"と出力されているので、おそらくホストとコンテナをマウントさせる記述のところですかね？

````docker-compose.yml
db:
    image: postgres
    volumes: 
      - 'db-data': '/var/lib/postgresql/data'
````
見つけました！一番下の " - 'db-data': '/var/lib/postgresql/data' "の部分が間違ってます！


# 解決
では、修正していきましょう。

````docker-compose.yml（修正前）
db:
    image: postgres
    volumes: 
      - 'db-data': '/var/lib/postgresql/data'
````

````docker-compose.yml（修正後）
db:
    image: postgres
    volumes: 
      - 'db-data:/var/lib/postgresql/data'
````

一番下記述のシングルクォーテーションが余分に多かったですね。
その後、docker-compose up -dを実行するとうまくいきました！

# 3.最後に
docker-compose.ymlファイルは、正しくインデントや空白をつけないとうまく読み込んでくれません。また、コロンやシングルクォーテーションのつけ忘れ等の記述ミスをしやすい特性があります。（ただ単に私が間違えやすいだけｗｗ）なので、最初にdocker-composeでエラーが生じたらdocker-compose.ymlファイルに原因がある可能性が大きいので参考にしてみてください。
VSCodeでGraphQLのシンタックスハイライトが効くようにする

## TLDR
以下のVSCode extensionを使いましょう
https://marketplace.visualstudio.com/items?itemName=apollographql.vscode-apollo

## 調べたこと
公式のドキュメントに情報がありました。「syntax highlight site:www.apollographql.com」でgoogleのサイト内検索の機能を使いました。(有名かもしれないです、このサイト内検索の方法は覚えておいて損はないです)
https://www.apollographql.com/docs/devtools/editor-plugins/#syntax-highlighting

## できるようになること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672529/164ce89f-fd51-185b-dcf2-a8209ddb0dcb.png)
を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672529/0921434e-85a6-daa4-b17a-bcaa55518ad4.png)
のように表示できるようになります。
シンタックスハイライトが欲しくて導入しましたが、他にもGraphQLでの開発に便利な機能があるので、graphqlを使った開発をする方は導入しておくと良さそうです。
AWS　クロスアカウントアクセス

# 前提条件
この記事は、最初の一歩用となっております。
わかりやすくするため、説明不足な点がありますので、
詳しくは、他の記事を参照してください。
# クロスアカウントの概要
複数のアカウントがあり、それぞれにユーザがあると管理が面倒。（下記参照）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883811/e26b4288-8ab0-9944-4568-ef94e1c5c0d4.png)

管理を統一するために、ユーザは１アカウントで管理する。
他のアカウントへは、上記アカウント認証を経由してアクセスする。
これが**クロスアカウントアクセス**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883811/fa4d5ff7-639d-2752-9395-ee7536d5f6ec.png)
　①管理アカウントにログイン
　②各アカウントにログイン（スイッチロールという）
　　※各アカウント側には、ユーザは作成しない。IAMロールを作成して利用。
エンジニアリングマネージャーにオススメの、人材マネジメントについての本

# TL;DR

- [図解 人材マネジメント入門　人事の基礎をゼロからおさえておきたい人のための「理論と実践」100のツボ](https://www.amazon.co.jp/dp/B088BBW2GN)を読もう

![図解 人材マネジメント入門](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/c69cd395-667a-a7c7-178f-003a3de63185.jpeg)


# エンジニアリングマネージャー（以下EM）の悩み
- EMとして働いていると、いろいろな悩みを抱える
    - そのうち悩みを抱えやすいのは、ヒト・モノ・カネのうち **ヒト**
        - EMとしてメンバーとどう接すればいいのか
        - パフォーマンスを発揮できないメンバーをどう支援するのか
        - 人事評価や給与査定はどうあるべきか
        - 等
    - 相談や自己解決も多いが、体系的にヒトについて学ぶために、どういう手段があるか？
        - 読書

# EM関連の書籍
- エンジニアは、学びをエンジニア領域内に求めがち
    - EMとしてのあり方について学ぶ本なら、このあたり
    - [エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド](https://www.amazon.co.jp/dp/4873118484)
    - [エンジニアリングマネージャーのしごと ―チームが必要とするマネージャーになる方法](https://www.amazon.co.jp/dp/4873119944)
        - 良書ではあるが、どちらも海外著書の翻訳オライリー本
        - ジョブ型雇用の色が強く、日本のメンバーシップ型雇用と相容れない表現も多い
    - [ITエンジニア採用とマネジメントのすべて 「採用・定着・活躍」のポイントと内製化への道筋が1冊でわかる](https://www.amazon.co.jp/dp/4761276215)
        - コロナ禍を経て変化した日本のIT業界を知れる良書
        - ただし、マネジメントの基礎知識を学ぶ本ではない印象

# そもそもこの悩みや必要な知識は、EMに限らない
- そこで今日紹介したい本
- [図解 人材マネジメント入門　人事の基礎をゼロからおさえておきたい人のための「理論と実践」100のツボ](https://www.amazon.co.jp/dp/B088BBW2GN)
    - 人材マネジメントについて、図解で計100個ポイントが書かれている

![図解 人材マネジメント入門](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/c69cd395-667a-a7c7-178f-003a3de63185.jpeg)

## 章立て

- Chapter 1. 人材マネジメント
- Chapter 2. 人事評価
- Chapter 3. 賃金・退職金(外的報酬)
- Chapter 4. 働きがい(内的報酬)
- Chapter 5. 等級
- Chapter 6. 採用
- Chapter 7. 異動・代謝
- Chapter 8. 人材開発
- Chapter 9. 組織開発
- Chapter 10. 働く人

## 100のツボ一部ピックアップ

- 001. マネジメントとは何か？
- 005. マネジャーはどのような役割を果たすべきか？
- 013. 人事評価に公平感をもたらすために重要なことは？
- 027. 賃金に納得してもらうために必要なことは？
- 037. やりがいのある仕事のために必要なことは？
- 048. 役割等級とは何か？
- 058. 面接を行ううえでのポイントは？
- 065. どんな性格の人が管理職に選ばれやすいのか？
- 071. 人材開発とは何か？
- 087. 組織を活性化させるには？
- 093. プロフェッショナルとは何か？

こういったものが100項目、見開きで片側文章・片側図解でわかりやすく説明されている

# 最後に
- いちWeb系エンジニアである前にいちビジネスパーソンであるように、
- いちエンジニアリングマネージャーである前にいちマネージャーである
- となると、EMに必要な知識だけ集めるだけでは不足
    - マネジメントとは？マネージャーとは？をまずは学ぶ
    - そのためにこの本は強く推奨したい