OmniAICreator/Qiita-1.07M huggingface dataset:
初心者🔰がAnacondaに挑む。

# はじめに
「え？そこから説明いる？」と思われるほどの本気の初心者です。

(個人的メモ)
[前回のRの環境構築時](https://qiita.com/drafts/2a6de08741bf5cafafde/edit)にmacOS 10.14.6を（未だに）使っていましたが、今は12.2.1を使ってます。(2022.11.25)
常に最新とは程遠いversionを使うタイプです。 


# Anacondaをインストール
https://www.anaconda.com/products/distribution

サイトに勧められるまま、現状のOSに対応する最新versionと思われるAnacondaを入手し、言われるがままにインストール。（あと1分と言われてからが長かった）


# シェルを変更する
PythonとAnacondaの関係は、RとRstudioの関係みたいなもの？と想像していたのだけれど、AnacondaをインストールしたらPythonもインストールされていて驚く。（そのことに気がつくまでにしばらくどうやってPythonをインストールするのかについてググっていた初心者的loss of time）

[このサイト](https://www.python.jp/install/anaconda/macos/install.html)を見て、pythonを使うには、眠れる蛇を起こす必要があることを知るが、その前にシェルって何？となり、ひとまずターミナルを起動してみたところ「今はdefaltのintaractive shellはzshなんだよ。」とアップデートを勧められる。どうやら、デフォルトのシェルがbashになっていたようだ。bashとかzshとかログインシェルとかインタラクティブシェルとか、ググっても貝の識別ができそうになかったので、[本家](https://support.apple.com/ja-jp/HT208050)の指示に従って、デフォルトのシェルをbashからzshへと変更した。

```$ chsh -s path```
の```path```の部分に、/bin/zsh、/bin/bash、/bin/csh、 などを入れるとシェルを変えられる。

ターミナルを再起動すると、デフォルトでAnacondaが起きていた（＝ターミナルの行の先頭に常に(base) と表記されていた）。Anacondaには、こちらのタイミングで起きていただきたいので、以下の呪文を唱える。

```$ conda config --set auto_activate_base false```

毎回、ターミナルを起動するたびに```% conda activate```と唱えてAnacondaを起こすことにする。

（続く）
カレントディレクトリにある全てのJSONをマージする

単純な方法
```
cat *.json | jq -s > all.json
```

ファイル名がIDになっていて、数値順でソートしたい場合は次の通りします。
```
cat `ls -1 *.json |sort -n` | jq -s > all.json
```
UnityのInvalid editor window エラーの解消方法

Unityを触っていると表示される「Invalid editor window」エラーの解消方法です。

# 環境
OS : Windows10
Unity バージョン : 2019.4.15f1

# 手順
1. Window > Layouts > Revert Factory Settings に進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368729/658b92b9-1762-d1d8-1c5d-e44b91a0b201.png)
2. 確認画面でContinueを選択 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368729/076811ee-8c80-7f19-c95d-dda7f044d530.png)
3. Faild to destroy editor windows エラーが表示されるが、再生ボタンを押すと消えるので問題ない
標準化＆正規化

## 標準化とは

標準化とは、特徴量を標準正規分布（平均を0，分散を1）のスケーリングに合わせる処理のことです。変換の式は、次式となります。

$$　x_{std, i} = \frac{x_i-\mu}{\sigma}　$$

$$　(x_i: 元データ, \mu:平均, \sigma:標準偏差)　$$

## 正規化とは

正規化とは、特徴量の値の範囲を一定の範囲に収める変換で、その範囲は主に[0, 1]、または [-1, 1]となります、範囲を[0, 1]にするときの変換式は、次式となります。

$$　x_{norm, i}=\frac{x_i - x_{min}}{x_{max}-x_{min}}　$$

$$　(x_i:元データ, x_{min}:最小値, x_{max}:最大値)　$$

## 標準化と正規化の使い分け

正規化は外れ値の影響が大きいので、基本は標準化を使います。以下が使い分けの例です。

### 標準化

- ロジスティック回帰、SVM、NNなど勾配法を用いたモデル
- kNN、k-meansなどの距離を用いるモデル
- PCA、LDA(潜在的ディリクレ配分法)、kernel PCAなどのfeature extractionの手法

### 正規化

- 画像処理における RGBの強さ [0, 255]
- sigmoid, tanhなどの活性化関数を用いる，NNのいくつかのモデル

### 使わない時

決定木，ランダムフォレスト
機械学習の評価方法

## 分類と回帰、両方に使える評価手法

* [ホールドアウト検証](#ホールドアウト検証)
モデルの汎化性能を評価する方法
* [交差検証（Cross-validation）](#交差検証(クロスバリデーション))
モデルの汎化性能を評価する手法

## 分類に使える評価手法

* [混同行列(Confusion matrix)](#混同行列)
* [正解率(Accuracy)](#正解率(Accuracy))
* [適合率(Precision)](#適合率(Precision))
* [再現率(Recall)](#再現率・感度(Recall))
* [特異度(Specificity)](#特異度(Specificity))
* [F値(F-measure)](#F値(F-measure))

# ホールドアウト検証

全てのデータセットを任意の割合で学習データ、検証データ、テストデータに分割して検証する方法。機械学習モデルの汎化性能評価に際して従来より使用されている一般的な検証方法です。

# 交差検証(クロスバリデーション)

交差検証（cross-validation）は、汎化性能を評価する統計的な手法で、分類でも回帰でも用いることができます。機械学習を行うとき、学習を行うための学習データと未知のデータに適用したときのモデルを評価するためのテストデータがあります。

交差検証の中でも、よく利用されるK-分割交差検証について説明します。K-分割交差検証は、データをK個に分割してそのうち1つをテストデータに残りのK-1個を学習データとして正解率の評価を行います。これをK個のデータすべてが1回ずつテストデータになるようにK回学習を行なってそれぞれでホールドアウト検証を行い精度の平均をとる手法です。

![](https://i.imgur.com/zyEkI67.png)

# 混同行列

![](https://i.imgur.com/xWKV3Sw.png)

# 正解率(Accuracy)

予測値が実際にそうである割合

$$
Accuracy=\frac{TP+TN}{TP+FP+TN+FN}
$$

# 適合率(Precision)

陽と予測したもののうち、実際に陽である割合

$$
Precision=\frac{TP}{TP+FP}
$$

# 再現率・感度(Recall)

実際に陽であるもののうち、陽と予測できた割合

$$
Recall=\frac{TP}{TP+FN}
$$

# 特異度(Specificity)

実際に陰であるもののうち, 陰と予測できた割合

$$
Specificity=\frac{TP}{FP+TN}
$$

# F値(F-measure)

再現率と適合率の調和平均

$$
\frac{2Recall⋅Precision}{Recall+Precision}
$$
コピーレフト対象

いつも忘れて調べるのでメモを残しておく。

## コピーレフト対象

|種類|ソースコード再利用|ライブラリ利用|ネットワーク経由利用|例|
|:-:|:-:|:-:|:-:|:-:|
|コピーレフト|対象|対象|対象|AGPL|
|コピーレフト|対象|対象|対象ではない|GPL|
|準コピーレフト|対象|対象ではない|対象ではない|LGPL|
|非コピーレフト|対象ではない|対象ではない|対象ではない|MIT Licence<br />Apache Licence|
バッチファイルが動作しないと思ったら文字コードが原因だったのでその対策

## 背景
CSVファイルを生成して、決まったディレクトリに出力するバッチファイルを一日一回実行するタスクスケジューラを設定したのに、うまく動作していなかったので原因を調べていたら文字コードのせいでした。

## 開発環境
- Windows10
- VSCode

## 問題が起こっていた部分

```.bat
REM こちらのバッチファイルはUTF-8で記述されていました
@echo off

set EXPORT_PATH=%~dp0日本語フォルダ\hoge.txt
echo %EXPORT_PATH% >> tmp.txt
...

```
上記のバッチファイルを実行して`tmp.txt`を確認すると…
```.txt
***\譌･譛ｬ隱槭ヵ繧ｩ繝ｫ繝蜷構hoge.txt
```

## 解決方法
原因としては出力先のフォルダ名が日本語で、記述されたバッチファイルのエンコードがUTF-8なのに対して、実行するコマンドプロンプトの文字コード設定がShift_JISだった、ということでした。
なので、バッチファイル内に文字コードの設定を変更するような一文を追記することで正しい出力先を設定できるようにしました。

```.bat
@echo off
chcp 65001 > nul
set EXPORT_PATH=%~dp0日本語フォルダ\hoge.txt
echo %EXPORT_PATH% >> tmp.txt
...
```
コマンドプロンプトの文字コードの設定は`CHCP`コマンドでできますので、今回の場合はUTF-8の65001に設定しています。
*バッチファイルの文字コードに合わせる

## まとめ
当たり前に思われたかもしれませんが、CMDと.batの文字コード設定が違うと化けます。環境によってはバッチファイルの先頭に`chcp`コマンドでエンコーディングの設定をしましょう。

今回はバッチファイルの処理内容が単純なものだったため、動くだろうと思ってテストもせずにスケジューラ設定してしまったのは失敗でした。
Educational DP Contest M

## 初めに

思考のアウトプット練習です。実装例も一応あるので誰かの参考になると嬉しいです。
今回はMについて解説したいと思います。

https://atcoder.jp/contests/dp/tasks/dp_m


## 方針
$i$人目(i$\leq n-1$)までに飴を$j$個配った状態を考えた時に、$i+1$人目には飴を$0 $から$ min(a_{i+1},k-j)$個まで配ることができます。よって$dp[i][j]=$i人目までにj個配る配り方の総数として$dp[n][k]$が分かれば良さそうです。遷移は以下のようになります。

$$
dp[i][j]=\sum_{l=0}^{a_i}dp[i-1][j-l]
$$
計算量について考えると、$i$人目までに飴玉を$j$個配った状態を全ての$j$に対して計算しなければならないので、$\sum$部分の計算には$O(k)$かかり、全体では計算量が$O(NK^2)$になってしまい`TLE`してしまいます。

そこで、$\sum$の部分を前もって計算してあげることで計算量を削減します。
具体的には$dp[i-1][j]$を全ての$j$について計算し終わった後、$sum[j]=\sum_{l=0}^{j} dp[i-1][l]$を計算しておきます。こうすることで次の$dp[i][j]$を$O(1)$で求めることができます。

これで$O(NK)$で解けました。
以下実装例です。

```c++:m.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll MOD = 1000000007;
int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n + 1);
  for (ll i = 1; i <= n; i++) {
    cin >> a[i];
  }
  vector<vector<ll> > dp(n + 1, vector<ll>(k + 1));
  vector<ll> sum(k + 1);
  for (ll i = 1; i <= n; i++) {
    if (i == 1) {
      for (ll j = 0; j <= a[i]; j++) {
        dp[i][j] = 1;
      }
    } else {
      for (ll j = 0; j <= k; j++) {
        // j-a[i] 〜 j の和が知りたい
        if (j - a[i] <= 0) {
          dp[i][j] += sum[j];
        } else {
          dp[i][j] += sum[j] - sum[j - a[i] - 1];
        }
        dp[i][j] = (dp[i][j] + MOD) %
                   MOD;  // dp[i][j]が負になってる可能性があるので注意
      }
    }
    // sumを計算しておくことでO(NK)になる
    for (ll j = 0; j <= k; j++) {
      if (j == 0) {
        sum[j] = dp[i][j];
      } else {
        sum[j] = sum[j - 1] + dp[i][j];
      }
      sum[j] = sum[j] % MOD;
    }
  }
  cout << dp[n][k] << endl;
}
```
Alteryxで項目ごとにグループ番号を付与する

# 1. はじめに
Alteryxで項目ごとにグループ番号を付与するフローを作りました。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/f5afeb1d-e892-686b-8273-5e3a2e54adee.png)



# 2. ワークフロー
まずは全体像です。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/adc1893e-2e7d-d9f8-3dfa-770fbc06570d.png)

マクロ（青い丸）のフローです。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/c91a0258-b096-4ec7-6236-6f3de2b03e41.png)



## 2.1 全体像の説明
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/bfa1c4af-ced0-223e-0745-c9c409d8c442.png)


①インプットデータ
今回は[ポケモンの新作ゲームに登場するポケモンのデータ](https://www.pokemon.co.jp/ex/sv/ja/)を使用

②インプットデータ
「名前、分類、タイプ、特性」の順に4項目を1グループとしたいので、グループの先頭となる「名前」を先頭カラム名としてセット

③マクロ
マクロで処理をすると「group_ID」という列が追加される

④クロスタブツール
クロスタブツールでデータを横持ちにする

⑤閲覧ツール
データ整形の完成！！！

## 2.2 マクロの説明
![画像9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/b51a9f32-c23f-c5dc-f1be-e74e0ab45219.png)



①マクロ入力ツール
[2.1 全体像の説明](#21-全体像の説明)の①インプットデータが入る

②セレクトツール
項目とデータの列は文字列なので、型は「V_Wstring」、サイズは「1073741823」にセット
![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/0bfe0931-b710-9b1f-dc0d-875c48d942f7.png)

③レコードIDツール
後の処理でデータの順番が混ざらないようにレコードIDを追加する

④フィルターツール
「項目」列から「名前」というレコードをTrueへ、それ以外のレコードをFalseへ分ける
![画像11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/6ed6b9fa-f93d-32bb-2a3c-1e043474faa7.png)

⑤コントロールパラメータとアクションツール
コントロールパラメータには[2.1 全体像の説明](#21-全体像の説明)の②インプットデータが入る
アクションツールを図のような設定にする
※インプットデータが④フィルターツールの「名前の欄」に設定することができる
※今回は「名前」をグループの先頭に指定しているが、他の項目でも対応可
![画像12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/b657b1c9-564e-2c06-b823-a4ea54070a2b.png)
[#1]はインプットデータの「名前」が入る
![画像15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/46390dc6-584c-dbc6-9e7e-1996cb31a2c8.png)

⑥フォーミュラツール
「名前」というレコードをグループの先頭にしたいので、dummy列を追加し「1」を設定する

⑦レコードIDツール
名前のレコードに1から番号を追加する

⑧フォーミュラツール
「名前以外」のレコードにdummy列を追加し「2」を設定する

⑨ユニオンツール
⑦と⑧のレコードを結合する

⑩ソートツール
RecordID列を昇順、dummy列を昇順に並び替える

⑪複数行フォーミュラツール
「group_ID」にデータがなければ、「1つ上のgroup_IDのデータ」を設定
「group_ID」にデータがあれば、そのまま
というif文を書く
![画像16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2618987/289e27da-b9be-30c8-f837-8a32babe899c.png)

⑫セレクトツール
必要のない列を消してマクロの処理は完了！！！


# おわりに
Alteryxで項目ごとにグループ番号を付与するフローをご紹介しました。
よく使うフローはマクロにすると呼び出すだけなので楽ちんですね。

# 参考
[ポケモンのデータ](https://www.pokemon.co.jp/ex/sv/ja/)
Keycloakのワンタイムパスワード認証(OTP)のリセット手順 

## はじめに
### 概要
Keycloakにおけるユーザの「ワンタイムパスワード認証(OTP)」のリセット手順を紹介します。
Keycloakでは「多要素認証(MFA)」の機能を提供しており、Google Authenticator等を使用してスマートフォンから追加認証のためのワンタイムパスワードを取得可能です。しかし、
- スマートフォンを紛失/故障してしまった
- Authenticator の移行作業をせずに端末変更をしてしまった

場合などには、MFA認証を利用できない状況となり、サービスにログイン不能となってしまいます。
このような場合、Keycloakの管理者により対象ユーザのOTP設定のリセットが必要となります。

本記事では、KeycloakのOTP設定のリセット手順を紹介します。Keycloakのインストールや初期設定、OTPの設定方法については記載しません。

### 想定読者
- Keycloak Admin

## 前提
- Keycloakの認証設定でOTPが有効化済みであること
- OTPでログイン済みのユーザが存在すること
## 手順
1. 管理者アカウントでKeycloak Admin Consoleにログインし、[対象のRealm] > 左メニューの [Manage][Users] から、OTP設定をリセットしたいユーザを選択し、[Credentials]タブを選択します。![Monosnap Keycloak Admin Console 2022-11-25 10-53-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/ca9e9038-7755-92dd-1fd9-406d37dea92c.png)

1. OTPでログイン済みの場合、`Manage Credential` に`otp` の行が追加されています。これを削除します。 ![Monosnap Monosnap Keycloak Admin Console 2022-11-25 10-53-26.png 2022-11-25 11-06-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/b5b405e4-2dc0-a2e0-552c-fbc2e189ef2b.png)![Monosnap Keycloak Admin Console 2022-11-25 11-09-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/b5ee4bf8-286e-0aca-2e8a-acd6c123c2e6.png)
1. ユーザの[Details] タブを表示します。![details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/74b7c32e-a8f0-ce5c-9774-3eedb657fad8.png)
1. [Required User Actions] に`Configure OTP` を選択し、保存します。 ![configureotp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/fb43bd9d-4805-8733-beb5-c08e9282ffc8.png)![configureotp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/55977250-7dc3-e6cf-ad2b-ad5caf66f0f8.png)
1. 該当ユーザにアプリケーションにログインしてもらいます。ユーザ名/パスワードを入力後、以下の画面に遷移しMFAデバイスの再設定が可能となります。![mfa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24487/13a406a0-a545-bc07-9f68-9df7445d48e3.png)


## おわりに
手順は以上です。
Authy等、複数端末で利用可能なAuthenticatorもありますが全てのサービスで使用できるとは限らず、Google Authenticatorの移行作業も簡単にはなりましたが故障や紛失等不意の事故もあり、このような作業は割と頻繁に発生するのではないでしょうか？

この記事がみなさんのお役に立てれば幸いです。
Django 3 JSONFieldの日本語をunicode化させない方法

開発環境：`django3.0.7`, `python3.7`, `mysql`

新しいバージョンの環境では別の設定方法があるかも知れませんが・・・。

### 
Djangoの`JSONField`で日本語が入った`dict`をDBに登録してみたら、日本語が`unicode`になってしまって人が読めない状態になりました。それで日本語が日本語のまま登録される方法があるか見てみました。

### これは試したが、失敗
`json.dumps`に`ensure_ascii=False`を指定すると日本語が`unicode`にならない`str`値を取得できます。
それで`dict`ではなくて`json.dumps`で変換した`str`を入れてみました。

```python
model.jsoncol = json.dumps({ "ほげほげ": "テスト" }, ensure_ascii=False)
```

ですが、結果は同じく日本語は`unicode`になっていました。

### これで解決！

`JSONField`の親クラスの`JSONFieldMixin`処理の中に`json.dumps`を呼び出す箇所がありました。
`JSONField`の引数の`dump_kwargs`を指定したら、`json.dumps`にまで渡される仕組みでした。
それで以下のように設定して解決！

```python
sample_filed = JSONField(dump_kwargs={ "ensure_ascii": False })
```

DBのレコードに日本語が日本語のままになって登録されて人が読めるようになりました。
Windows10 Pro で Guest 共有

MS-Windows の Guest 共有は、パスワード無しファイル共有を実現する場合によく使われていた。
便利な反面セキュリティ的に問題があり、現在の Windows ではデフォルトで無効になっている。

しかしながら安全が担保されているネットワーク内で、一時的にファイルをコピーしたいときなどでこの機能を使うと都合がいいときがある。なぜならば共有サーバ側でさくっと共有を設定するだけでコピーが実現できる。共有クライアント側で状況で設定方法を切り分けてめんどくさいことを考えなくても良くて Good ！



# 下準備

まず、この記事


「Windows 10 April 2018 Update の後に Guest 共有ができなくなった」
https://qiita.com/nanbuwks/items/ea179c07a4041f7496d5

のとおりグローバルポリシーエディタとユーザマネジャでゲストログオンを設定します。

# パスワード無し共有を有効にする

「ネットワークとインターネット」で「ネットワークと共有センター」で「共有の詳細設定の変更」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e352b277-ffb7-2e94-0493-d71760dde3b1.png)
すべてのネットワークで「パブリックフォルダーの共有」で共有を有効にして・・・と
「パスワード保護共有を無効にする」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5fa19cd0-657f-6a4f-e360-aa028844883a.png)


# 共有フォルダ作成

例として、ドライブCにshare フォルダを作ります。


プロパティで「詳細な共有」で「このフォルダーを共有する」にチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b128e5ef-23fe-8c42-6c41-7ceba2317ebd.png)

「アクセス許可」でGuestを追加、フルコントロールを許可します。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/767c3151-85c4-9995-6ec9-a09bbdaf5939.png)

プロパティの「セキュリティ」で Guest にフルコントロールを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4606a443-2d11-630c-cca3-b49fa8e3835d.png)

# クライアントからのアクセス

接続元から、「ファイル名を指定して実行」で「`\\192.168.0.18`」と打つと共有が見えるようになる。

# 作業が終わったら

サーバ側の設定を元に戻しておきます。
TerraformをインストールしてTerraformでAWS上にEC2作ってみる

# はじめに
Terraformの勉強を始めたので備忘録を兼ねて行ったことを投稿しようと思います。

# Terraformの実行環境構築
Terraformはtfenvでバージョン管理ができるようなので今回はtfenvでTerraformをインストールします。
 
### tfenvのインストール
macなのでbrewコマンドでインストールします。
```
brew install tfenv
```

### tfenvでTerraformをインストール
最新バージョンのterraformをインストールします。
```bash
tfenv install latest
```

### インストールしたTerraformのバージョンを確認します
```bash
❯ tfenv list
  1.3.5
No default set. Set with 'tfenv use <version>'
```

### インストールしたTerraformのバージョンがデフォルトバージョンとなるように設定します
```bash
❯ tfenv use 1.3.5
Switching default version to v1.3.5
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.3.5
```

### Terraformでもバージョンを確認します
```bash
❯ terraform version
Terraform v1.3.5
on darwin_arm64
```

### Terraformの作業用ディレクトリを作成
作業用ディレクトリを作成して、その中に移動します。
```bash
mkdir terraform
cd terraform
```

### Terraformの構成ファイルを作成
Terraformの構成ファイルの拡張子は`.tf`です。
`terraform.tf`ファイルを作成してTerraform自体の情報を定義します。
```terraform
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }

  required_version = ">= 1.0.0"
}
```

`provider.tf`ファイルを作成してAWS　Providerの情報を定義します。
```terraform
provider "aws" {
  region  = "ap-northeast-1"
  profile = "terraform"

  default_tags {
    tags = {
      Managed = "terraform"
    }
  }
}
```
`region`リソースを作成するリージョン
`profile`Terraformから利用するAWSのプロファイル名
※AWSプロファイルの設定は今回割愛
`default_tags`はTerraformで作成・管理するAWSリソース全てにタグを付与する設定
※この設定をすることでどのリソースがTerraformで作成・管理されたものか判別

`ec2.tf`ファイルを作成してEC2インスタンスの情報を定義します。
```terraform
resource "aws_instance" "test" {
  ami           = "ami-0404778e217f54308"
  instance_type = "t3.micro"

  tags = {
    Name = "tf_test"
  }
}
```
`ami`作成したいインスタンスAMI
`instance_type`作成したいインスタンスタイプ
※以上の2項目を最低限指定するとVPCやセキュリティグループはデフォルトで作成
`tags`作成したリソースを判別しやすくする


### 構成ファイルの整形
Terraformにはコードフォーマッターが用意されているので、これで整形します。
```bash
terraform fmt
```

## Terraformでリソースを作成
作成した構成ファイルをもとにTerraformでリソースを作成していきます。

### Terraformの初期化
以下のコマンドを実行して構成ファイルの定義内容で初期化を行います。
```bash
terraform init
```

### Terraformの実行計画
構成ファイルを実行した際の実行計画が確認できます。
具体的にどんなリソースが作成されるのか確認します。
※実環境には影響を与えないので安全に実行できます。
```bash
terraform plan
```

### Terraformの実行計画を反映
`terraform plan`で作成されるリソースに問題がなければその内容を実環境に反映させます。
```bash
terraform apply
```
※実環境に影響を与えるので実行前に確認のダイアログが表示されるので`yes`と入力

### 作成したインスタンスの確認
ここで作成したインスタンスを確認しましょう。
Nameタグに`tf_test`が設定されたインスタンスが作成されているはずです。
以下のコマンドでも確認できます
```bash
terraform show
```

## TerraformでEC2を削除
作成したインスタンスの確認ができたら削除を行います。

### Terraformの削除の実行計画
`terraform plan`コマンドにオプション`-destroy`を付与することで、削除の実行計画を確認することができます。
```bash
terraform plan -destroy
```

### Terraformの削除の実行計画を反映
削除の実行計画が問題なければ、反映させます。
```bash
terraform destroy
```
※`destroy`はTerraform管理下にあるリソースを全て削除します
意図しない環境で実行しないように十分注意してください

※確認のダイアログが表示されるので`yes`と入力

### 削除したインスタンスの確認
ここで削除したインスタンスを確認しましょう。

# さいごに
はじめてTerraform使ってAWS上にEC2を作ってみましたが、やはりコードで管理ができるようになると、どんな設定をしたのかが全てコードに残るので、それだけでもかなりの恩恵を感じられました。
次回は作ったEC2にアクセスするための設定をTerraformで行いたいと思います。
MacでProductIDからシリアルポートを特定する

最近Arduinoなどのデバイスを数種類接続して使うことが多いので、
MacBookProでProductIDからArduinoのシリアルポートの番号を特定したかった
**動作確認済みデバイスはArdinoUnoとLeonardoのみ** 

## Macの「システム情報」を取得する

system_profilerコマンドでシステム情報に載っているものが取得できる

    $ system_profiler SPUSBDataType
 
![スクリーンショット 2022-11-24 17.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45348/5772ac22-6c63-4b84-98d4-af1ee5466824.png)


## 「システム情報」からLocationIDを抜き出すシェルスクリプト

system_profilerコマンドで取得した情報を使ってProductIDからLocationIDを取得するシェルスクリプトを書く

``` port_search_pid.sh
#!/bin/sh
PID="$1"
if [ $# != 1 ] || [[ "$PID" != *0x* ]] || [ ${#PID} != 6 ]; then
    echo "Please enter your ProductID"
    exit 1
fi

ARDUINO_PORT=`system_profiler SPUSBDataType | grep -A 8 "Product ID: ${PID}" | grep -n "Location ID" | grep -o '0x....' | sed -e "s/0x//g"`
ARDUINO_PORT=`ls /dev | grep -e "${ARDUINO_PORT}" | head -n 1 | xargs printf '/dev/%s\n'`
echo $ARDUINO_PORT
```

## 使い方

引数にProductID（製品ID）を指定して実行するだけ

    $./port_search_pid.sh 0x0043 

![スクリーンショット 2022-11-24 17.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45348/7ccbd6c1-ad9b-f93b-3fed-8735a40a016b.png)


system_profilerのエラーみたいなものも出るけどよくわからない
MFC から SVG クラスの呼び出しコードサンプル

## MFC から SVG クラスの呼び出し方法
これまでの投稿で SvgImage クラスが出来上がりました。
一通りの基本的なコードは作成したので MFC(GDI+) での描画コードと SVG クラスへの出力コードを比較しながら、どのように実装していくかみていくこととします。
GDI+ の実装に合わせてカスタムが必要な個所は SvgImage クラスにコードを追加したり、サンプルコードを数種類用意します。

## MFC で GDI+ にて描画する際の準備と解放のサンプルコード

ウィンドウのサイズのビットマップ領域を用意し、書き込みを行う処理です。
本来であればここで作成したビットマップをウィンドウに対して BitBlt 関数などで書き込むのですがそちらのコードは省略しています。
```cpp
	CBitmap bmp;
	// ビットマップ形式
	CRect	rect;
	mdRect	rectClient;
	GetClientRect(&rect);
	CDC		dcMem;
	CClientDC dc(this);
	dcMem.CreateCompatibleDC(&dc);
	const int cx = rect.Width();
	const int cy = rect.Height();
	bmp.CreateCompatibleBitmap(&dc, cx, cy);
	CBitmap* pPrev = dcMem.SelectObject(&bmp);

	dcMem.PatBlt(0, 0, cx, cy, WHITENESS);
	dcMem.SetMapMode(MM_ANISOTROPIC);
	dcMem.SetViewportOrg((rect.right - rect.left) / 2,
		(rect.bottom - rect.top) / 2);
	dcMem.SetViewportExt(1, -1);
	dcMem.SetWindowOrg(0, 0);
	dcMem.SetWindowExt(1, 1);
	Gdiplus::Graphics graphics(dcMem.m_hDC);

// TODO: 書き込み処理 graphics に対して行う

    // メモリの解放
	dcMem.SelectObject(pPrev);
	dcMem.DeleteDC();
	bmp.Detach();
	bmp.DeleteObject();
```

## MFC の SvgImage オブジェクトの準備
MFC 側から SvgImage クラスを呼び出す際のコードサンプルは以下の通りです。

```cpp
    CRect rectAll(0, 0, 640, 480);
	SvgImage *pImage = new SvgImage();
	pImage->CreateSvgImage(rectAll);
```
SVG の defs タグを一つに統合して宣言したい場合は CreateSvgImage 関数の呼び出し直後に作成するのが良いでしょう。ファイルの可読性が向上します。

これまでの投稿にありましたように defs タグを必要になった際に逐次用意しても表示に問題は発生しません。必要とあれば一つの defs タグにまとめるよう書き換えを行ってください。

## SVG クラスのファイル出力
[SVG画像の ViewPort 設定と MFC でのファイル出力](https://qiita.com/frashell/private/3a239652c276421e5d9e)
にて実装したファイル出力関数を使用して SVG ファイルの書き出しを行うサンプルコードです。
あらかじめ public ユーザの Documents フォルダに image フォルダを作成しておいてください。

ファイル名は任意のものに変更してください。
ここでは GDI+ に描画する際にレイヤ別に出力することを考慮して "layer_0.svg" というファイル名にしてあります。
```cpp
    UINT uLayer = 0;
	CString strFile;
	strFile.Format(L"C:\\Users\\public\\Documents\\image\\layer_%d.svg", uLayer);
	pImage->OutputSVGImageFile(strFile);
```
オンボーディングで使う、システム概要資料を作る際に考えたこと

## はじめに

この記事は[エムスリーキャリア FY22 AdventCalendar](https://qiita.com/advent-calendar/2022/m3c)の2日目の記事です。

社内でオンボーディング用の資料を作成したら、思いのほか評判が良かったので、作成時に意識したことをまとめてみます。

下記のようなストーリーになるように気をつけました。

- ユーザとして見えるシステムの仕様・用語を説明する
- ルールがなぜそうなっているのかを伝える。あるいは不文律として伝わっているルールを資料に明文化して伝える
- 中心となるシステムの役割を伝え、全体のデータの流れを伝える
- それらが分かったら、システムの裏側を触ってもらう課題にチャレンジしてもらう。
    - たとえば、システムの管理画面を触りながら、ユーザデータを触ったりしながら、システムが参照するデータについて理解を深める。

なお、私の場合は、すでに社内でいろんな方がガイダンス資料を作成されていたので、今回はそれらをパッチワークのように組み合わせつつ、補足したり課題を追加したりして資料を作成しました。

## ストーリーの流れ

### ユーザとして見えるサービスの仕様・用語を説明する

まずはユーザ目線でサービスを概観するようにしました。また、社内用語やドメイン用語などについても説明するようにしました。

いきなり、システムの内部の話をしても、何をしているのかわからないと思うので。

また、自分たちが触るサービス以外にも、社内の中心となる他サービスについても説明するように心がけました。

### ルールがなぜそうなっているのかを伝える。あるいは不文律として伝わっているルールを資料に明文化して伝える

ルールについてきちんと伝えます。事故を発生させないためには、なぜそのルールが必要になったのかをきちんと理解してもらうことが必要です。

そこで、ルールを説明する際には、それが必要になった背景や経緯（過去の事故事例など）についても触れます。

例えば、社員が本番環境を触る際には少なからずルールが存在すると思いますが、その際のルールについて理由などを説明します。その際、サービスの仕様でルールに関連する仕様を説明しておくとより納得感が増します。


### 中心となるシステムの役割を伝え、全体のデータの流れを伝える

サービスの概要が掴めたら、内部のシステムの説明に移ります。

弊社の場合、マイクロサービスで連携する形構成されているため、どんな登場人物が出てくるのか、それらはどういう通信をしているのかというデータの流れについて中心に説明します。

その際、実際のサービスを動かしながら説明すると、理解が深まると思われます。

### それらが分かったら、システムの裏側を触ってもらう課題にチャレンジしてもらう。

理解度を確認してもらうため、なんらかのシナリオに基づいて操作を行ってもらいます。シナリオは課題として用意しておき、その課題を理解してもらうのに必要な情報を、前項までで説明するように資料をデザインするように心がけます。

例えば、「テスト環境で会員を登録→管理画面から操作→DBの会員情報を確認」といった操作をしてもらいます。

こうすることで、実際に手を動かせるので、なんとなく、どんなふうにデータが流れるのかが体感できると思われます。

ただ、実際に手を動かしてもらう際には、資料の説明以外にも接続情報など多数の環境固有の説明が必要かと思いますので、その点のフォローも忘れないようにします。

## 最後に

ストーリーを持って段階的に構成を説明し、課題を用意して手を動かしてもらうことで、理解を深めてもらうという流れがあると、理解がスムーズになるかと思います。

よろしければ参考にしてください。
ASP.NET Core3 namespaceとフォルダ名の一致によるエラー記録

<h1>.NETCore3で起こったエラー“名前空間ですが種類のように使用されています”の対処法</h1>  

こんにちは！見習いIOTエンジニアのめぐみです。
今回の記事ではASP.NET Core3の勉強中に遭遇したnamespaceに関するエラーとその対処法を記載していきます。
同じようなエラーから抜け出せない方の助けになれば幸いです。

まず、【エラー内容】はこちら↓<br>
<h2>CS0118:'Temperature'は名前空間ですが、種類のように使用されています</h2>
<br>
実際の画面がこちらです<br>

![temp01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984282/35cd4830-e336-51db-a6a4-5fc0d9822201.png)
<br>
OnGetAsyncメソッドで使いたいTemperature型のリストの宣言に赤線が引かれ、上記のようなエラー内容が表示されています。

.NETCoreの記事があまりないのか、私のようなエラーにはまる方が少ないのか、記事を検索してもなかなか対処法が見つかりませんでした。

原因としては、コード上の"namespace DBChart_Razor.Pages.Temperature"（つまりソリューションの"Pages"中のフォルダ名）と
私がclassとして定義した"Models"の中の"Temperature"の名前が同じだったこと。
Temperature型として認識される前に、名前空間（namespace）として捉えられてしまったようです。<br>
<br>
<h2>それなら名前空間となるフォルダ名を変えれば・・・！？</h2><br>
ということで以下のように修正しました。<br>

![temp00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984282/9771210f-1548-5bf7-7629-c9b2b198fbab.png)
フォルダ名を"Temp"に変え、コードも"namespace DBChart_Razor.Pages.Temp"に変更すると、エラーは消えました。<br>
<br>
今回のようにnamespaceとなるフォルダ名とclass名がかち合ってしまった時は、コード上のnamespace部分だけ変えても良いのですが、
.NETCore3ではフォルダ名から自動的にnamespaceを記載してくれるので、やはり初めからフォルダ名をclass名とかぶらないようにつけるのが得策ではないかと学んだ1日でした！
[React] export Context するのをやめた話

# 実装A

こういう実装よくあると思うのですが

```contexts/hoge.ts
export const HogeContext = React.createContext({}); 
```

```providers/HogeProvider.ts
import { HogeContext } from 'contexts/hoge';

export const HogeProvider: FunctionComponent<{ children: ReactNode }> = ({
  children
}) => {
  const value = ...; // ロジック
  
  return (
    <HogeContext.Provider value={value}>
      {children}
    </HogeContext.Provider>
  );
};
```

```components/Hoge.ts
import { HogeContext } from 'contexts/hoge';

export const Hoge = () => {
  const value = useContext(HogeContext);
  return (
    ...
  );
}
```

実装追いづらくないですか？

# 実装B

と言うことで自分は hooks、Provider とまとめて全部詰めちゃいます

``` libs/Hoge.tsx
// useHoge があれば必要ないので export しない
const HogeContext = React.createContext({});

export const HogeProvider: FunctionComponent<{ children: ReactNode }> = ({
  children
}) => {
  const value = ...; // ロジック
  
  return (
    <HogeContext.Provider value={value}>
      {children}
    </HogeContext.Provider>
  );
};

export const useHoge = () => {
  return useContext(HogeContext);
};
```

## メリット

- useHoge を利用しているコードから定義元にジャンプした時に実装が見れる
- HogeProvider を探さなくて済む
- 各所で HogeContext を import して useContext する手間が少し省ける
テストコードがローカルだと成功するのにBitrise上だと失敗する原因を特定する方法

これは [ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.7 の 1 日目の記事です。

なぜか、ローカルで走らせたテストだと上手くいくのに、Bitriseで実行すると失敗する時ってありますよね。

そんな時に限ってBitriseのログを見るとFailing testsと書かれているだけで、原因が出力されていない。。。

そんな時は、Bitrise CLIを使ってXcodeのxcresultを確認しましょう。

## 補足. Bitrise CLIとは
Bitrise CLIは、Bitriseのオープンソースランナー。 
Bitrise環境をローカルで再現・実行することが可能で、ローカルだと上手くいくけどBitriseだと失敗する場合の原因特定に便利です。
ちなみに実行にBitriseアカウントは不要です。

https://devcenter.bitrise.io/ja/bitrise-cli.html

## 1. Bitrise CLIをインストール

Bitrise CLIのインストールはとても簡単で以下のコマンドを二つ叩けば完了します。

`brew update && brew install bitrise`

`bitrise setup`

https://devcenter.bitrise.io/ja/bitrise-cli/installing-and-updating-the-bitrise-cli.html#homebrewでbitrisecliをインストールする

## 2. bitrise.ymlをルートに置く

Bitrise CLIでリモートの環境を再現させるため、bitrise.ymlを実行ディレクトリのルートに置いておきます。

## 3. Bitriseでテストワークフローを実行する

bitrise.ymlに定義しているテスト用ワークフローを以下のコマンドで実行してください。

`bitrise run [実行したいbitrise.ymlに定義しているテストワークフロー]`

## 4. Xcodeが吐くテストログを取得する

テストが失敗すると以下のようなログが吐かれます。

```
** TEST FAILED **
If you can't find the reason of the error in the log, please check the xcodebuild_test.log.
<中略>
Exporting test results
$ cp "-a" "/var/folders/xxxx/Test-XXXX.xcresult" "/var/folders/xxxx/XXXX/"
```

そのログ内に以下のようなコマンドが書かれているのでターミナル上で実行してコピーします。

`cp "-a" "/var/folders/xxxx/Test-XXXX.xcresult" "[保存したいディレクトリを指定]"`

## 5. xcresultを開いて原因を特定する

あとは上記でコピーしたxcresultを開いて、原因を特定しましょう。

![xcresult](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339601/9b3f04e7-f5d2-4b43-2b4e-b63c0a55b96d.png)

## 最後に

Bitrise CLI使えば、ローカルで実行できるので素早く確認できて嬉しいですね。
この記事が、テストコードがローカルだと成功するのにBitrise上だと失敗する人の一助になれば幸いです。
paiza.ioでelixir その100

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
c言語、コンパイルして、実行せよ。

# サンプルコード

```

File.write "hello.c", """
#include <stdio.h>

int main(int argc, char * args[]) {
    printf("Hello, World!");
    return 0;
}
"""

{result, 0} = System.shell("gcc hello.c")
IO.puts result

{result, 0} = System.shell("./a.out")
IO.puts result


```

# 実行結果

```

Hello, World!
```

# 成果物

https://paiza.io/projects/TFm5tcI0iUvU_7b_KeTFvg?language=elixir


以上。
Dockerfileで上の階層をCOPYできん

## 前提
- docker-composeを利用している

## やりたいこと
sampleディレクトリの内容をimageに入れたい

### NGパターン:sob:
```
.
├─ docker
│   └ app
│      └ Dockerfile
├─ sample
└ docker-compose.yml
```

```docker-compose.yml
version: '3'
services:
  app:
    container_name: 'sample_app'
    build:
      context: docker/app
      dockerfile: Dockerfile
```

```Dockerfile:Dockerfile
FROM php:8.0-fpm-alpine
COPY ./sample /app
```
これでビルドすると
```
$ docker-compose up --build
failed to compute cache key: "/sample" not found: not found
```
てっきりCOPYコマンドのpathの指定の仕方が間違っていると思っていたが、
そうではなかった。
docker-compose.ymlのcontextの指定の仕方が原因だった。

おそらくこの設定ではDockerfileはapp以下のファイルしか見れないのだろと思う。

### OKパターン:blush:

```
.
├─ docker
│   └ app
│      └ Dockerfile
├─ sample
└ docker-compose.yml
```

```diff_docker:docker-compose.yml
version: '3'
services:
  app:
    container_name: 'sample_app'
    build:
-      context: docker/app
-      dockerfile: Dockerfile
+      context: .
+      dockerfile: docker/app/Dockerfile
```

```Dockerfile:Dockerfile
FROM php:8.0-fpm-alpine
COPY ./sample /app
```

contextを上の階層にしてやることでDockerfileからも
上の階層を参照できるようになる。(ということだと認識している)
競技プログラミング歴と勉強法メモ


# 目次
[1.この記事について](#この記事について)
[2.プロフィール](#プロフィール)
[3.競技プログラミング歴](#競技プログラミング歴)
[4.勉強内容と感想](#勉強内容と感想)

# この記事について
メモとして競技プログラミング歴と勉強法などを記載していきます
色進化したらいい感じに更新予定
20221230 入茶したため少し更新！
![18803828-2E78-413A-8E75-999647216E3B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2972157/5e9745d0-c913-f838-9074-a1732299aeef.png)


# プロフィール
AtCoderアカウント：https://atcoder.jp/users/nampo2
twitterアカウント：https://twitter.com/nampo_aco
年齢：31歳(1991年生まれ)
大学：東京大学→東京大学大学院
専攻：化学
現職：化学メーカーにて研究開発

# 競技プログラミング歴
2022年8月　C++勉強開始
2022年9月　ABC初参加
2022年12月　入茶


# 勉強内容と感想
2022年8月～10月　[APG4b](https://atcoder.jp/contests/APG4b)
何をすればいいか分からない為、for beginnerと書いていたこのサイトから勉強開始
競技プログラミングを始めるにはちょうどいい感じ
2章の後半ぐらいから難易度が上がる為、適度にABCの過去問を解きながらの方がいいかも


2022年10月～ [競技プログラミングの鉄則](https://www.amazon.co.jp/競技プログラミングの鉄則-アルゴリズム力と思考力を高める77の技術-Compass-Booksシリーズ-米田/dp/483997750X/ref=nodl_?dplnkId=ba4bd9b2-64b1-4b73-99c4-7628d9c6b867)
体系的に競技プログラミングに必要な知識を学べている(まだ途中)
早くグラフアルゴリズムを学んでレートアップを図りたい
純粋関数について

# 純粋関数とは
純粋関数は処理の複雑度を決める鍵でもある。
一つのソフトウェアで純粋関数を割合が多ければ多いほど、システム全体の複雑度は下がる。
では何を純粋関数と言えるのか。
関数が以下の条件を満たす場合純粋関数と言える。

#### 純粋関数の条件
① 引数が同じの場合、常に同じ値を返す。
② 関数によってプログラムの状態が変化することはない。

以下のコードは純粋関数の例である。
```javascript:javascript
function add(a, b) {
  return a + b
}
```
関数に引数として1, 2を入れると、必ず３を返す関数である。
関数の外部の影響を受けず、想定できる値が保証できる。
しかし、以下の関数はどうだろう。

```javascript:javascript
let num = 2
function add(a) {
  return a + num
}
```
一見純粋関数に見えるが、よく見ると、関数外部の変数を参照していることがわかる。
number型の`num`は、現在`2`の状態であるが、これが`3`や`4`に変更されたら、関数`add`が返す値はその都度変わってしまう。
関数が外部の影響を受けて返す値が変わってしまうこのような関数は純粋関数とは言えない。

# なぜ純粋関数を使うのか。
純粋関数を使う理由としては以下の通りである。
① テストしやすい。
関数が返す値が想定できるため、テストコードを書くことが簡単になる。
② プログラムの複雑度を下げることができる。
１つの機能を持つ返り値が保証できる関数であるため、自然と得られる結果である。

では以下の例はどうだろう。

```javascript:javascript
function returnFn() {
  return function sample () {
      console.log("hello world")
  }
}
```
関数を返す関数で、高段関数である。
結論から言うと、このような高段関数も純粋関数に属する。
純粋関数は、外部の影響を受けないという条件があるとのことから、上記のreturnFn関数はこの条件に当てはまることがわかる。
paiza.ioでelixir その99

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
アセンブラ、コンパイルして、実行せよ。

# サンプルコード

```

File.write "hello.s", """
.code64
.text
.globl main

main:
	mov   $1, %rax;
	mov   $1, %rdi;
	mov   $msg, %rsi;
	mov   $12, %rdx;
	syscall;
	mov   $0, %rax;
	syscall;

.data
msg:
	.asciz "Hello world!"
"""

{result, 0} = System.shell("gcc -no-pie hello.s")
IO.puts result

{result, 0} = System.shell("./a.out")
IO.puts result


```

# 実行結果

```
Hello world!
```

# 成果物

https://paiza.io/projects/TcgIX2OBgOIAOAS0LhA3vg?language=elixir


以上。
Slackで自分が特定のリアクションを押した時にAsanaへタスク登録するように設定してみた。

この記事は [#AsanaTogetherJP Advent Calendar 2022](https://adventar.org/calendars/7467) にエントリーしています。

## やりたい事
仕事上、Slackで議論してタスクに落とし込んでAsanaに登録して進捗を共有するということをやっているのですが
転記するのって面倒ですよね。別にそれで仕事が進むわけではないし。
なので「SlackでリアクションをしただけでAsanaに登録されたら楽だよな」という動機で作りました。

## 使うツールの説明
Slack・Asana・Zapierの３つです。
この記事を見てるということはたぶんSlackとAsanaはもう知ってると思います。
(AsanaTogetherJP自体がSlackコミュニティなので)
残りのZapierですけどSaaSと連携して「〇〇をXXした時に△△する」という設定をしておけば自動でやってくれるツールです。
詳しくは![この辺](https://mag.sweeep.ai/topic/74611/)を見てアカウントを用意してください。


## 下準備
設定の![MyApps](https://zapier.com/app/connections)に入ってSlackとAsanaの接続を用意しておきましょう。
「Add connection」を押してポチポチやってれば出来るはずです。

## Zap作成
### Slackの処理
「Create Zap」を押してTriggerを設定していきます。
Slackを選んでEventを「New Reaction Added」にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/e4f09fe8-b524-5e85-51d7-8df860c74870.png)

Continueを選んで、アカウントを設定したあと、「Set up trigger」に移ります。
「Reaction」「Channel」「User」を設定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/fa9996fc-4dc6-3a5d-ff47-c9c67f3fce61.png)

今回やりたいのはSlackで自分が特定のリアクションを押した時なので下記を設定します。
| 項目 | 内容 |
| - | - |
| Reaction | 特定の絵文字（今回は事前に登録しておいたアイコン）|
| Channel | 空白（全てのチャンネルで動作させたい）|
| User |（自分）|

Test処理に移るのでTestして正常実行されるのを確認します。

### Asanaの処理
Asana側の処理に移ります。
appでAsanaを選んでEventを「Create Task」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/b5cdf1a6-b98a-2cd6-4246-29b16657b7fe.png)

Continueを選んで、アカウントを設定したあと、「Set up action」に移ります。
項目は色々ありますが今回は下記の設定にしてみました。
書かなくてもわかると思いますがNameが件名、Descriptionが詳細です。
Nameが長くなるのが嫌なら適当なタイトルを入れて置きましょう。

|項目|内容|
| - | - |
|Workspace / Organization(required) | 会社のワークスペース|
| Project | 個人Todo|
| Section |Asana|
| Name | Message Text |
| Description | Message TextとMessage Permalink |
| Tag(お好みで) | Asana |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/9947ef79-ebaa-7b07-66ab-3e2a5f3817cd.png)

「Test action」を実行して確認します。他にも入れたい項目があれば調整しましょう。
「publish Zap」をクリックして完成です。

他にもGoogleカレンダーと同期する方法などもありますので、色々試してみましょう。

## おまけ
フリープランだと上記までで終了ですが、有償プラン（StarterでもOK）であればタスクの多段実行ができるようになります。
なので「登録したタスクへのリンクを、Slack投稿の返信として投稿する」という処理も可能になります。
Asana設定を終わったあと「＋」をクリックしてアクションを追加します。
Slackを選択して「Send Channel Message」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/03bd7b7a-5e86-fe1b-4a9b-c1a49f7843bf.png)

Continueを選んで、アカウントを設定したあと、「Set up action」に移ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/2f89c6fc-8834-0e7b-099b-88ea88709da6.png)
今回は「Slack投稿の返信として投稿」したいので、1.Triggerに指定したSlackの内容を参照していきます。
「Custom」から「Message Channel Name」を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/882d0313-b3cd-a293-b2ab-1c5ff70b4cac.png)
設定例：
| 項目 | 内容 |
|-|-|
| Channel(required) | Message Channel ID|
| Message Text(required) | 投稿しました ＋ Pernalink Link|
| Thread | Message.TS |

結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91812/1edf5a85-8a1f-4d58-d36e-49376f3bcc29.png)
Figmaにおける Kindle for PC問題 ショートカットキーの衝突解消方法

# 解決方法
下記のURLの通りにする。
Kindle for PCをCtrl＋Alt＋Kのショートカットキーで立ち上がらなくする方法 | ノート100YEN.com
https://note100yen.com/en-180816.html

## 上記URLの内容は？
(上記URLでは違うアプリのショートカットキーと被っているがショートカットキー自体は同じもの。)
Kindle for PCはインストール時に強制的にこのショートカットキーを設定してしまう。
それに、kindle for PCのアプリ自体にはショートカットキーを設定する項目がない。

なので、自力でKindle for PCのショートカットキー見つけ、ショートカットキーのプロパティから設定を取り消さなければならない。
これはWindowsのグルーバルなショートカットキーの知識を知っている人でないと解決できない。
Kindle for PCの説明書にも載っていない隠し設定。
試しにヘルプからショートカットキーと入力しても「検索に一致する結果はありません。」と出る。
![ヘルプ文.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/6c66df87-c21e-edc0-78cc-3edc1d8ceba3.jpeg)

# 問題
KindleはPC版をインストールすると
Ctrl+Alt+Kのショートカットキーで起動してしまう。
これはFigmaではフレームをコンポーネント化するショートカットキーするキーとかぶっている。
Figmaでコンポーネント化しようとするとKindle for PCが立ち上がってしまう。
優先順位はKindeの方が高い。
これを解消するにはどうすればよいか？

# 要望
Figmaでのコンポーネント化は重要なキーなので、
Kindleはこのショートカットキーをインストール時に初期設定として設定しないで欲しい。
もしくはKinde自体にショートカットキーの設定項目を追加して欲しい。
Kibo-rpc 2022環境構築（自分用ごみ箱）

# はじめに
自分用メモです。
未完成です。

# 参考資料
[Programming Manual](https://jaxa.krpc.jp/download.html)←メインの資料

# セットアップ
## 2.1 スペック要件と本環境(OK)
・64-bit プロセッサ
・4 GB RAM (8 GB RAM を推奨）
・Ubuntu 20.04

## 2.2 Android Studio

### 2.2.1(OK)
問題なし

### 2.2.2(OK)
ダウンロードするバージョンは3.4.1であることに注意すること。
また、解凍したzipファイル（android-studio)の中にあるテキスト（~/android-studio/Install-Linux-tar.txt）を用いる事。この時点でAndroid Studioはインストールされていない。

### 2.2.3(OK)
1)
Android Studio の起動方法
```
$ cd android-studio/bin
$ ./studio.sh
```

2)OK
3)OK
4)
Android SDK Build-ToolsとAndroid SDK Platform-Toolsに[25.0.3]、[26.0.2]を選択する項目が各々あるかと思ったが、
```
・Android SDK Build-Tools
[25.0.3]check
[26.0.2]check
・CMake
[Android SDK Platform-Tools]check
```
のように選択するしかなかった。読解力が無かったのか。。。？
5)OK

## 3.1 Android プロジェクト作成(OK)
1)OK
2)OK
3)OK
4)OK
解凍後のフォルダ名は「Templates」であることに注意
5)
もしかしたらpathが以下のように表示されるときがあり謎
~/TemplateAPK/app/src/main/java/jp/jaxa/iss/kibo/rpc/defaultapk/YourService.java
6)OK
7)OK

# 3.2 アプリケーションの作成(OK)
「Sample APK」ではなく「Template　APK」を使用したところ、以下のエラーを確認
```
cannot resolve symbol Point
cannot resolve symbol Quaternion
cannot resolve symbol Mat
```

↓解決策↓

そもそもPoint, Quaternion, Mat型を定義してないからエラーが出て当たり前
以下をimport する必要がある。横着はよくない。
```
import gov.nasa.arc.astrobee.types.Point;
import gov.nasa.arc.astrobee.types.Quaternion;
import org.opencv.core.Mat;
```

## 3.3 アプリケーションのビルド(OK)
~~エラーが発生する可能性があるから、Android Studioからビルドしない方がいいんだって~~(2022/11/29 16:02)
ビルドの仕方が分からん。てか、
```
$ cd /app/build/outputs/apk/app-debug.apk
```
ファイルに移動は出来なくね？あとおそらく正しい場所はこう
```
$ cd SampleApk/app/build/outputs/apk/app-debug.apk
```
outputsの下にappが無い。。。

----------------------------------
Android Studioからbuildしないでと書いてあったけど、それ以外にbuildする方法が無かったので押したらappとapp-debug.apkができた！！
もしおかしくなったらやばい。。。
(2022/11/29 16:18)



## 4.6 自分のPCでシミュレーターを立てる
### 4.6.4 Docker インストール(OK)
問題なし

### 4.6.5 Docker を用いた Kibo-RPC シミュレータのビルド(OK)
[Link](https://jaxa.krpc.jp/download_ja.html)には複数のフォルダがあるが、「Modules for Local Simulation Environment」のこと、ちょい分かりずらいね。あと、ホントに数時間かかる。

ネットワーク設定のところの末尾は内容が近い物ではなく、本当の末尾に書いた。

### 4.6.6 APK 実行用の Android Simulator を設定する(NO)
1) OK
2) OK
3) OK
4) OK
5)
エラー発生
```
Your CPU does not support required features (VT-X or SVM).
```


6)
7)


### 4.6.7. Guest Science Manager APK のビルド(NO)
この部分はこうしないとスムーズにいかない。
gitわかる人前提で書かれてるのかな？優しくない
```
$ export ANDROID_PATH=${HOME}/astrobee_android
$ git clone https://github.com/nasa/astrobee_android.git
$ git checkout a8560ab0270ac281d8eadeb48645f4224582985e
```
↓正しくは
```
$ export ANDROID_PATH=${HOME}/astrobee_android
$ git clone https://github.com/nasa/astrobee_android.git
$ cd astrobee_android
$ git checkout a8560ab0270ac281d8eadeb48645f4224582985e
```

### 4.6.8. ネットワークの設定
1)OK
前に書いてたやつをコメントアウトしたけどまずかったかな？とりあえずすすむ
2)OK
この手順は新たにTerminalを開くときに実行する必要があるんだと。.bashrcファイルに書き込んでいると実行する必要が無いからあとでやろう（未完了）
3)ON
ターミナルは起動したけどAndroid Emulatorに接続できなかった。
Android EmulatorのWi-FiをOFFってどうやってやるんだ。

### 4.6.9. APK のインストール
### 4.6.10. プログラムの実行


以上
また何かあれば更新していきます。

更新履歴
2022/11/ - 更新中
ABC 275 C - Counting Squares を全探索して息切れした

[**問題**](https://atcoder.jp/contests/abc275/tasks/abc275_c)を一目見た時に、アプローチが分からず、
速攻でブラウザを閉じた(笑)

心を落ち着かせ、とりあえず、[**解説**](https://atcoder.jp/contests/abc275/editorial/5149) をチラ見して、
"**全探索**" という単語を見かけたので、なるほどと思いトライしてみることにした。

思考のアプローチ
<INS>**step1**.四隅の角を、それぞれ for 文で動かしてみる
**step2**."step1"の組み合わせが正方形であることを判断する、if so, count up.
**step3**.重複を除いて count up を続け、最終値を output.</INS>

**注意した点**：
&emsp;計算量。四隅を導くだけでも、ざっくり O(8^8 = 16777216) 必要。
&emsp;判定 + 重複を除いたカウント処理を軽く すれば間に合いそう。
&emsp;っと見立てながらコーディング。

```abc275c.cpp
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

//(h1,w1)-----(h3,w3)
// 
// 
//(h2,w2)-----(h4,w4)

bool judge(int w1, int w2, int w3, int w4, int h1, int h2, int h3, int h4) {

	bool flag = true;

	int side1 = pow(w1 - w3, 2) + pow(h1 - h3, 2);
	int side2 = pow(w1 - w2, 2) + pow(h1 - h2, 2);
	int side3 = pow(w4 - w2, 2) + pow(h4 - h2, 2);
	int side4 = pow(w4 - w3, 2) + pow(h4 - h3, 2);

	int diagonal1 = pow(w4 - w1, 2) + pow(h4 - h1, 2);
	int diagonal2 = pow(w3 - w2, 2) + pow(h3 - h2, 2);

	if (diagonal1 != 2 * side3 || diagonal1 != 2 * side2 || side3 != side2) flag = false;
	if (diagonal2 != 2 * side4 || diagonal2 != 2 * side3 || side3 != side4) flag = false;
	if (side1 != side3 || side2 != side4 || side1 != side2 || side1 != side4 ) flag = false;

	return flag;
}

int main() {
	vector<string>S(9);
	for (int i = 0; i < 9; i++)
		cin >> S[i];
	map<string, int>memo;
	int cnt = 0;
	for (int w1 = 0; w1 < 8; w1++) {
		for (int w2 = 0; w2 < 8; w2++) {
			for (int w3 = w1+1; w3 < 9; w3++) {
				for (int w4 = w2+1; w4 < 9; w4++) {


					for (int h1 = 0; h1 < 8; h1++) {
						for (int h2 = h1+1; h2 < 9; h2++) {
							for (int h3 = 0; h3 < 8; h3++) {
								for (int h4 = h3+1; h4 < 9; h4++) {

									if(S[h1][w1] == '#' && S[h2][w2] == '#'&& S[h3][w3] == '#'&& S[h4][w4] == '#'){

										if (judge(w1, w2, w3, w4, h1, h2, h3, h4)) { 
											vector<pair<int, int>>num{ {w1,h1},{w2,h2},{w3,h3},{w4,h4} };
											sort(num.begin(), num.end());
											string key = "[" + to_string(num[0].first) + "," + to_string(num[0].second) + "]," + \
												         "[" + to_string(num[1].first) + "," + to_string(num[1].second) + "]," + \
												         "[" + to_string(num[2].first) + "," + to_string(num[2].second) + "]," + \
												         "[" + to_string(num[3].first) + "," + to_string(num[3].second) + "]";
											memo[key]++;
										}
									}

								}
							}
						}
					}



				}
			}
		}
	}
	cout << memo.size();
	//while (1) {}
	return 0;
}
```
今話題の脆弱性について自社サイトは大丈夫ですか？


今某サイトの下記の脆弱性が話題です

最近弊社ではRuby on Railsなので自社での状況を確認しました


# 1. 認証CookieにSecure属性をつけていない

## どのような問題が？
HTTP通信でCookieが送られてしまうため、暗号化されていないため、信用できないWiFiを利用した場合などに、登録している情報ややり取りの履歴が盗まれる可能性がある。

## 参考情報

> Secure 属性がついた Cookie は HTTPS プロトコル上の暗号化されたリクエストでのみサーバーに送信され、安全でない HTTP では決して送信されないため、中間者攻撃者が簡単にアクセスすることはできません。(URL に http: を含む) 安全でないサイトは、 Secure 属性を使用して Cookie を設定することができません。
https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies

## 弊社での対策

### 1. Secure属性を付与する

```ruby:config/environments/production.rb
config.session_store(secure: true)
```

<追記>
ところが Secure 属性が付加されません

```ruby:action_dispatch/middleware/cookies.rb
def []=(name, options)
# name: _server_rails_session
# options: {:value=>"...=", :same_site=>nil, :path=>"/", :domain=>nil, :expire_after=>nil, 
# :secure=>false, :httponly=>true, 
# :defer=>false, :renew=>false, :id=>"..."}
```

```ruby:action_dispatch/middleware/session/cookie_store.rb
def set_cookie(request, session_id, cookie)
  cookie_jar(request)[@key] = cookie
end
```

```ruby:rack/session/abstract/id.rb
  def context(env, app = @app)
    req = make_request env
    prepare_session(req)
    status, headers, body = app.call(req.env)
    res = Rack::Response::Raw.new status, headers
    commit_session(req, res)
    [status, headers, body]
  end
:
def commit_session(req, res)
  session = req.get_header RACK_SESSION
  options = session.options
# options: {
#  :path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"..."
# }
:
set_cookie(req, res, cookie.merge!(options))
```

```ruby:action_dispatch/middleware/session/abstract_store.rb
    module SessionObject # :nodoc:
      def commit_session(req, res)
        req.commit_csrf_token
        super(req, res)
      end
      :
      def prepare_session(req)
        # @default_options: {
        #  :path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"..."
        # }
        Request::Session.create(self, req, @default_options)
      end
```

結局 `@default_options`が`secure: false`ままでした。

以下を書き換えると修正できました

```diff
- config.session_store secure: true
+ config.session_store :cookie_store, secure: true
```


### 2. CloudFrontのビヘイビアでHTTPS通信だけに限定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302078/a890b0f8-b450-8eae-803e-88535400edec.png)


# 2. 他人の情報を書き換え可能

ユーザAでログインしてユーザAの認証Cookieを使い、ユーザBの情報を入手したり書き換えることができる。

なぜ起きるのか？以下のように書き換えるユーザのIDをリクエストパラメータで参照している。

```ruby
user = User.find(params[:user_id])
user.update params[:user_name]
```

本来であれば以下のようにユーザIDはセッションから取得すること。またデータベースに渡すパラメーターは制限する必要がある。
```ruby
user = User.find(current_user.id)
user.update params.require[:user].permit[:name]
```

またユーザが投稿した記事のような場合は単純に`find`せずに事前に`where`句で対象となる記事を絞り込んでください

```ruby
article = Article.where(author: current_user).find(params[:id])
```

# さらに

RUNTEQ校長「[ひさじゅ](https://twitter.com/hisaju01)」さんより教えていただきました

BrakemanというGemを使うとよくある脆弱性を検知してくれるとのことです

https://brakemanscanner.org/
c++ explicit指定子

## 役割
C++ explicit暗黙の型変換を防ぐため

## 環境
Visual Studio 2019 (v142)

```c++
#include <iostream>
using namespace std;

class Point
{
public:
    int x, y;
    Point(int x = 0, int y = 0)
        : x(x), y(y)
    {
    }
};

void displayPoint(const Point& p)
{
    cout << "(" << p.x << ","
        << p.y << ")" << endl;
}

int main()
{
    displayPoint(1);// Ok
    Point p = 1; // OK
}
```
main関数のdisplayPoint(1)で暗黙の型変換が発生

```c++
#include <iostream>
using namespace std;

class Point
{
public:
    int x, y;
    explicit Point(int x = 0, int y = 0)
        : x(x), y(y)
    {
    }
};

void displayPoint(const Point& p)
{
    cout << "(" << p.x << ","
        << p.y << ")" << endl;
}

int main()
{
    displayPoint(1);
    Point p = 1;
}
```
ビルド時以下のエラーメッセージが表示され
```
error C2664: 'void displayPoint(const Point &)': 引数 1 を 'int' から 'const Point &' へ変換できません。
message : 理由: 'int' から 'const Point' へは変換できません。
message : class 'Point' のコンストラクターが 'explicit' と宣言されています。
message : 'displayPoint' の宣言を確認してください
error C2440: '初期化中': 'int' から 'Point' に変換できません。
message : class 'Point' のコンストラクターが 'explicit' と宣言されています。
```
## 変更
C++ 11前コンストラクタ一つ引数
C++ 11以後に2個以上引数を取るコンストラクタ
javascriptでじゃんけんゲーム

昔ながらのボタンを押して遊べるじゃんけんゲームを作ってみた。
⇒<a href="https://note.nonbiri3.com/jyanken.php">実際の動作はこちら</a>

ただこれだとリセットボタンが何回も押されるとre()が何度も実行されて動きが早くなってしまう。
もっとこうしたら良いよ！とアドバイスくれる方、おねがいしますm(_ _)m

```html
    <div style="text-align:center;">
    <div id="Rejan2">☆じゃんけんゲーム☆</div>
    <p><img id="jankenpon" src="images/jan0.png" style="width:100px;"></p>

<div style="margin:10px;">
    <button onclick="R_Click(0);"> グー</button>
    <button onclick="R_Click(1);"> チョキ</button>
    <button onclick="R_Click(2);"> パー</button>
</div>

<div style="margin:10px;">
    <button onclick="re();"> リセット</button>
</div>
<div id="Rejan1"></div>
</div>

<script>
function R_Click(p_janken_r) {
    clearTimeout(repeat);
    let janken = ['グー','チョキ','パー',];
        let janken_r = Math.floor( Math.random() * 3);
        let p_janken = ['グー','チョキ','パー'];
            if (janken_r === p_janken_r) {
                Result_end = "あいこ";
            } else if(p_janken_r === 0 && janken_r === 1) {
                Result_end = "勝ち！";
            }else if(p_janken_r === 1 && janken_r === 2) {
                Result_end = "勝ち！";
            }else if(p_janken_r === 2 && janken_r === 0) {
                Result_end = "勝ち！";
            }else {
                Result_end = "負け～";
            }

            document.getElementById("jankenpon").src="images/jan" + janken_r + ".png";
            document.getElementById("Rejan2").innerHTML = Result_end;
  document.getElementById("jankenpon2").src="images/jan" + p_janken_r + ".png";
        }
function re() {
    picChange();
    document.getElementById("Rejan2").innerHTML = "じゃんけんゲーム";
}

let img = ["images/jan0.png", "images/jan1.png", "images/jan2.png"];
let count = -1;
picChange();
function picChange() {
    count++;
    if (count == img.length) count = 0;    
    document.getElementById("jankenpon").src = img[count];
    repeat = setTimeout("picChange()", 100);
}
</script>
```
Cloud Run の CPU boost 機能を試してみた

# はじめに

こんにちは、京セラコミュニケーションシステム 福留（@kccs_kazuo_fukudome）です。

先日、Cloud Run の新機能 CPU boost が発表されました。
参考：https://cloud.google.com/blog/ja/products/serverless/announcing-startup-cpu-boost-for-cloud-run--cloud-functions

Cloud Functions、Cloud Run で CPU boost 機能を利用すると、コールドスタートからの起動が早くなる、とくに Java アプリケーションでの効果が高いという説明でした。今回は Spring Boot アプリケーションで、簡単な REST API のアプリケーションのコンテナを作成し、CPU boost を利用した時と利用しない時で、どのくらいレスポンスタイムに差が出るのかを検証してみました。

:::note info
本記事は 2022 年 11 月ごろに作成しております。
Google Cloud の機能を利用した場合は、利用料が発生します。
:::

## この記事の対象者

- Web アプリケーションでバックエンド処理に Java を利用している人
- Cloud Run で Java を利用したアプリケーションを作ってみたい人
- Cloud Run の機能に興味がある人

## Spring Boot アプリケーションの作成

今回は、Java + Spring Framework で、以下のようなメッセージのみ返却する REST API アプリケーションを作成しました。この REST API アプリケーションを Cloud Run へデプロイし、レスポンスタイムを計りました。Spring Boot を利用した Java アプリケーションの Cloud Run へのデプロイ方法については、参考となる HP が色々とありますので、そちらを見て頂ければと思います。

```
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin
public class HelloController {

	@GetMapping("/hello")
	@ResponseBody
	public String helloResponse() throws Exception {
		return "Hello World!! (GET METHOD)";
	}
}
```

## CPU boost 機能なしの結果

作成した Cloud Run が、コールドスタートになるようにリクエストタイミングを調整し、レスポンスタイムを 3 回計りました。結果は、次の通りで、レスポンスタイムの平均は、11.22 秒となりました。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/f91547e0-8152-e498-5c5a-c8b5f6dabad8.png)
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/6d548465-fbdc-affe-8823-b790f4378670.png)
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/0339031a-8ce7-889b-dbc7-d91274c2c532.png)

## CPU boost 機能ありの結果

次に、CPU boost 機能を使って、レスポンスタイムを計ります。CPU boost 機能の設定も簡単で、Cloud Run の設定画面で、次のオプションにチェックを入れるだけ。非常に簡単です。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/dacb01cc-784d-5ec3-6777-71d3fe3b20d4.png)

この状態で、CPU boost なしと同じ環境、タイミングでレスポンスタイムを計りました。結果は、次の通りで、レスポンスタイム平均は、5.53 秒となりました。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/58979d89-af53-0709-d408-45ba235d189f.png)
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/557e26c9-603e-2059-5a9d-2e98c15d35cb.png)
![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852633/b0a8646d-4155-cc85-a788-8c383487cfed.png)

# 料金について

CPU boost 機能を使うと、起動時に CPU の割り当てが 1 ～ 4 では 2 倍に、6 だと 8 になり、その起動時間に応じて課金が発生するようです。
参考：https://cloud.google.com/run/docs/configuring/cpu?&_ga=2.48985313.-635310204.1642555300#startup-boost

今回のような REST API アプリケーションだと、起動時間は 約 0.2 秒でした。アプリケーションの規模や利用するライブラリの数にもよりますが、CPU boost を使用した料金は、使用しない場合と、ほぼ変わらないと思います。

## まとめ

Spring Boot アプリケーションで、CPU boost を利用すると、レスポンスタイムが、約 49% 改善しました。CPU boost を利用しても、約 5 秒ほどかかるので、高いレスポンスタイムが要求されるシステムでは、もう少しのスピード改善が必用かもしれません。ですが、レスポンスタイムがそれほど必要でないシステムでは、十分な結果だと思います。Java で作成したアプリケーションがあるのであれば、リソースの再利用もできるため、CPU boost を利用したシステム構築を検討してみても良いかと思います。
Vagrantが立ち上がらない

# Vagrantとは？
簡単に言えば、仮想マシンを管理するツールである。

Virtual Boxと使おうとMacにインストールを試みた。
しかし以下コマンドをうった際エラーが出た。

```
// 以下を実行
vagrant -v
// 結果
fatal error: runtime: bsdthread_register error
```

# 環境
・MacOS Monterey
・バージョン12.6
・Virtual Box 6.1

# 試したこと
よく見たらVirtual Boxはもっと新しいバージョンが
あるではないか。。

そこで最新のVirtual Boxをインストール。

https://www.virtualbox.org/wiki/Downloads

よし、いけ！
```
// 以下を実行
vagrant -v
// 結果
fatal error: runtime: bsdthread_register error
```

まだダメか。。
そこでググったところ、vagrantを入れ直すとうまくいく
記事を見つけたので実行。。


```
// vagrantをアンインストール
sudo rm -rf /opt/vagrant
sudo rm -f /usr/local/bin/vagrant
sudo pkgutil --forget com.vagrant.vagrant
```

次はhomebrewを使用して、インストール
```	
brew install vagrant
```

今度こそは、、
```
// 以下を実行
vagrant -v
```

成功！
入れ直しかVirtual Boxのアップデートが原因だったぽいです！