OmniAICreator/Qiita-1.07M huggingface dataset:
データサイエンスのための線形代数 第11回 行列の累乗と転置

:::note info
本記事は数学講座[3.4 行列の累乗と転置](https://www.matongxue.com/lessons/521/parts/3073)を勉強して投稿したメモです。詳細は元の素晴らしい講座のページをチェックしてください。
:::

:::note info
**累乗:**
数 同じ数または文字を何度か掛け合わせること。また，その積。a×a×a＝a3 のように掛け合わせた個数を右肩に小さく書き，これを累乗の指数（冪指数べきしすう）と呼ぶ。乗冪（じょうべき）。。
:::

# 行列のべき乗演算

行列は乗法と加法以外に、他の演算もあります。こちらで紹介するのは、行列のべき乗です。

$A$が正方行列で、$A^1=A,\quad A^2=A^1A^1,\quad\cdots,\quad A^{k+1}=A^kA^1$、$k$が正整数です。

:::note info
Q: なぜべき乗をする際に、行列が正方行列にする必要か？
A: $AA$をする際に、$A$が$m×n$とすると、$AA$が$(m×n)(m×n)$になるので、$m=n$の必要があります。だから、$A$が正方行列です。
:::

# 対角行列のべき乗演算

例え以下のような対角行列があります。

```math  
\Lambda=\left(\begin{array}{ccccc}{\lambda_{1}} \\ {} & {\lambda_{2}} \\ {} & {} & {} \\ {} & {} & {} & {\ddots} \\ {} & {} & {} & {} & {\lambda_{m}}\end{array}\right)
```
[対角行列の乗法規則](https://qiita.com/Junlee/items/6972ef25b53d9119b133#%E5%AF%BE%E8%A7%92%E8%A1%8C%E5%88%97%E3%81%AE%E4%B9%97%E7%AE%97)によると、$\Lambda$のべき乗が：

```math  
\Lambda^n=\left(\begin{array}{ccccc}{\lambda_{1}^n} \\ {} & {\lambda_{2}^n} \\ {} & {} & {} \\ {} & {} & {} & {\ddots} \\ {} & {} & {} & {} & {\lambda_{m}^n}\end{array}\right)
```

# 行列の転置演算

転置行列とは、$m 行 n 列$の行列 $A$ に対して $A の (i, j)$ 要素と $(j, i)$ 要素を入れ替えてできる $n 行 m 列$の行列のことである。$A=(a_{ij}),\quad A^\mathrm{T}=(a_{ji})$と記します。

例え、$m 行 n 列の行列A$：

```math 
{\displaystyle A={\begin{bmatrix}a_{1,1}&\cdots &a_{1,n}\\\vdots &\ddots &\vdots \\a_{m,1}&\cdots &a_{m,n}\end{bmatrix}}}

```
転置行列$A^\mathrm{T}$
```math 
{\displaystyle {}^{t}A={\begin{bmatrix}a_{1,1}&\cdots &a_{m,1}\\\vdots &\ddots &\vdots \\a_{1,n}&\cdots &a_{m,n}\end{bmatrix}}}
```

実際の例を見てみると：
![Matrix_transpose.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/4d7141b1-6c5a-20f8-eccb-7cc49a83ccdb.gif)

# 行ベクトルと列ベクトル

ベクトルにとって、行ベクトルと列ベクトルが同じものです。
```math 
\boldsymbol{x}=\begin{pmatrix}a_1\\a_2\\\vdots\\a_n\end{pmatrix}=(a_1,a_2,...,a_n)
```

行列の乗法では、行ベクトルと列ベクトルが違います。

```math 
\boldsymbol{x}=\begin{pmatrix}a_1\\a_2\\\vdots\\a_n\end{pmatrix},\quad\boldsymbol{x}^\mathrm{T}=(a_1,a_2,...,a_n)
```

同じ次元数のベクトルにとって、$\boldsymbol{x}^\mathrm{T}\boldsymbol{y}=\boldsymbol{x}\cdot\boldsymbol{y}$になります。$\boldsymbol{x}^\mathrm{T}\boldsymbol{y}$の結果が$1×1$の行列ですので、即ち実数です。

:::note info
$\boldsymbol{x}\cdot\boldsymbol{y}$の詳細は[ベクトルのドット積](https://qiita.com/Junlee/items/0c0f9d8a85bfb5c6db66#%E3%83%89%E3%83%83%E3%83%88%E7%A9%8D)を参照ください。
:::

# 転置演算の性質

行列の転置演算は以下の性質を持っています：
- $(A^\mathrm{T})^\mathrm{T}=A$
- $(AB)^\mathrm{T}=B^\mathrm{T}A^\mathrm{T}$
- $(A^\mathrm{T})^n=(A^n)^\mathrm{T}$
- $(A+B)^\mathrm{T}=A^\mathrm{T}+B^\mathrm{T}$

$(AB)^\mathrm{T}=B^\mathrm{T}A^\mathrm{T}$がよく使われいます。

# 対称行列と反対称行列

- 対称行列：$A^T=A$

```math  
\begin{pmatrix}
1 & 2 & 3\\
2 & 4 & -5\\
3 & -5 & 6\end{pmatrix}^\mathrm{T}
=
\begin{pmatrix}
1 & 2 & 3\\
2 & 4 & -5\\
3 & -5 & 6\end{pmatrix}
```

- 反対称行列：$A^T=-A$

```math  
\begin{pmatrix}
0 & 2 & -1 \\
-2 & 0 & -4 \\
1 & 4 & 0\end{pmatrix}^\mathrm{T}
=
-\begin{pmatrix}
0 & 2 & -1 \\
-2 & 0 & -4 \\
1 & 4 & 0\end{pmatrix}
```


# 参考情報

https://ja.wikipedia.org/wiki/%E3%81%B9%E3%81%8D%E4%B9%97%E6%B3%95

https://ja.wikipedia.org/wiki/%E8%BB%A2%E7%BD%AE%E8%A1%8C%E5%88%97

https://ja.wikipedia.org/wiki/%E5%AF%BE%E7%A7%B0%E8%A1%8C%E5%88%97
Failed to execute goal org.apache.maven.plugins:maven-surefire-pluginというエラーがでる

# はじめに

いままで動いていたmavenがなぜかコケるようになっていたので対処したときの記録です。
根本的になぜ解決したのかはわかっていないですが、参考になればと思います

# 問題

`./mvnw`を実行すると以下のエラーがでました

```
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M7:test (default-test) on project test-project: 
[ERROR] 
[ERROR] Please refer to /home/watanabejin/workspace/test-project/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] There was an error in the forked process
```

いままでうまくいっていたのに、、、

# 解決方法

Quarkusを起動しようとしているのでうまくバージョンが合わなくなったのかという予想は付きました

Javaを17から19に変更しました

```
$ asdf install java corretto-19.0.2.7.1
$ asdf global java corretto-19.0.2.7.1
```

するとうまく動かすことができました
昨日まで動いていたのに！！謎です
しかし、Quarkusが19でしか動かないのは納得がいきます

# おわりに

JVMを仕事で使い始めて2ヶ月経ちましたが、いまだにバージョン起因に悩まされます
Dockerが私は好きです、、

# 参考

https://ja.quarkus.io/guides/container-image
Salesforce動的フォームを有効化しよう

こんにちは
本橋孝昭です

今回は動的フォームの有効について試してみました

## 設定1

まずは動的フォームを有効にしたいオブジェクトのレコードページから「編集ページ」をクリックしましょう


![設定０１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5f3ea976-317c-158d-baf5-ba96ae65cfc8.png)


### 設定1 おまけ 画像１

このような画面が表示されればOKです

![ケースおまけ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/53158881-bb8c-8cc0-55e3-06628a11bcc7.png)


### 設定1 おまけ 画像2

赤の矢印あたりをクリックしてみてください。クリックをすれば「「アップグレードに関するお問い合わせ」」が表示されると思います

![ケースおまけ画像２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d4e8c700-0d06-bedb-3d2d-7d017393f293.png)



## 設定2
~~ページ＞レコードの詳細をクリックし~~

「アップグレードに関するお問い合わせ」をクリックしましょう
![設定２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2aed638b-6d95-3bb4-ab6c-e99ab190a205.png)

## 設定３
「次へ」をクリックしましょう
![次へ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a2c3166d-87e8-3e72-160a-4980681cf175.png)


## 設定4

[完了]をクリックしましょう


![設定４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2517627b-b1e5-00b0-9aab-4eea62ab1132.png)

以上で動的フォームの設定準備完了です！
お疲れさまでした！
mvn(Maven)コマンドがターミナルによって挙動が違う

# はじめに

ターミナルによって挙動が違う、さっきまで動いていたのに動かなくなったという減少が起きたので、先輩に助けていただきました
そこでの調査についてメモ程度にまとめていきます

# 問題

`./mvnw`を実行したところ以下のエラーがでました

```
 org.junit.jupiter.api.extension.TestInstantiationException: Failed to create test instance
        at io.quarkus.test.junit.QuarkusTestExtension.initTestState(QuarkusTestExtension.java:773)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:737)
```

しかし、別のターミナルで実行したところ何故かうまく動いていました

Javaのバージョンを調べたところどちらも同じで不思議でした

# 解決方法

先輩に聞いたところそれは環境変数が悪さしているんじゃないかと検討をつけて以下のコマンドを実行しました

動いていない方は以下

```
$ echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64/
```

動いている方は

```
$ echo $JAVA_HOME
# 何も表示されない
```

ここに違いがありました。`etc/environment`に試行錯誤の過程で`JAVA_HOME`を設定してしまっていたのが悪さをしていました

そこで消したところ問題なく動くようになりました。Java11で動いていたので17に変わったことで動きました

# おわりに

すごい人が回りにいると解決するまでの手順もスマートで本当にすごいなと感じます
早くそんな人になりたいです
G検定向けキーワードまとめ AI/人工知能界隈CEOまとめ

AI/人工知能開発のCEOまとめです。（2023年5月現在）
G検定対策に役立ててください。
※日進月歩で進化してますので、情報更新予定です。

Adobe：シャンタヌ・ナラヤン
Apple：ティム・クック（スティーブ・ジョブズ、スティーブ・ウォズニアック じゃないよ）
Amazon：アンディ・ジャシー（ジェフ・ペゾス じゃないよ）
DeepL：ヤロスワフ・クロテフスキー
Google：サンダー・ピチャイ （ラリー・ペイジ、セルゲイ・ブリン じゃないよ）
Meta(Facebook)：マーク・ザッカーバーグ
Microsoft：サティア・ナデラ（ビル・ゲイツ じゃないよ）
NVIDIA：ジェン・スン・ファン
OpenAI：サム・アルトマン
Tesla：イーロンマスク（OpenAI共同設立者、Twitter社CEO）
git clone []の保存先てどこ？

気になったので調べました。
# git とは？

git とは分散型バージョン管理システム


わかりやすく説明すると大きなプロジェクトを作成するときに複数人で作るとなると、統合時にプログラムがこんがらがったり、バグがおきたときに修復が難しかったりする。


gitというシステムは特定のサーバーにプログラムを構成する。特定のサーバー上にプログラムを追加する際には追加時期が記録される。プログラムが追加された時系列が確認しやすく、プログラムが混乱することも少ない、バグが置きたときは追加時期の記録をたどって修正しやすい。


https://tcd-theme.com/2019/12/what-is-git.html


# リポジトリとは？

リポジトリはファイルやディレクトリを保存する場所
リポジトリは主に２種類ある

### リモートリポジトリ
githubなどの特定のサーバー上に設置し、複数人で作業するための場所
### ローカルリポジトリ
個人のパソコン内にある、ユーザーが作業するための場所

# git clone とは？
リモートリポジトリからローカルリポジトリにファイルやカレントディレクトリをダウンロードすること


# git clone []の保存先はどこ？
本題
カレントディレクトリ下に作成されます


```sh
hoge@hogeMacBook-Pro ~ % 

```
だったらhoge@hogeMacBook-Pro~ % がダウンロード先です
TypeScriptでnamespaceは非推奨、でもモジュール化したい。

# はじめに

皆さん、大規模開発やってますか？私は多分やってません。その筈なのになんか滅茶苦茶ややこしいことになって、「この〇〇って何の〇〇だ…？」みたいなことになっています。
そういうわけで、自作モジュールを作って使いたかったのですが、そこで若干嵌ったので書いていきます。

# `namespace`を使いたかった

「TypeScriptでモジュールってどうやって作るんだっけ？」と思って一番最初に行き着いたのが、`namespace`を使う方法でした。

```hoge.ts
namespace Hoge {
    export type Fuga = {/*...*/}

    export class Piyo {
        public fuga: Fuga;
        // ...
    }
}
```

```main.ts
import * from './hoge.ts';
```

こうしてみたのですが、警告が出てきました。どうも`namespace`を使うのは非推奨のようでした。
どうしたものか……。

# 解決策

そう思って調べたところ、この方法でできることが分かりました。

```hoge.ts
export type Fuga = {/*...*/}

export class Piyo {
    public fuga: Fuga;
    // ...
}
```

え、名前空間無かったら読み込み先で名前の衝突とか諸々起こすんじゃないの？！……と思いましたが、そうでは無いようでした。恐らく、`import`文が肝です。

```main.ts
import * as Hoge from './hoge.ts'
```

モジュール側で名前を付けるのではなく、読み込み側で名前を付けることができるようでした。
PytorchのResnet50 modelで複数画像の特徴量を取得しファイルに保存

### 概要
Resnet50で、画像の特徴量をlistに格納し、別プログラムで類似画像の検索で使用したくファイルに保存。

### バージョン
Python 3.8
torch 2.0.0
torchvision 0.15.1

### プログラムについて
指定フォルダ配下の画像ファイル(jpg)を1枚づつ取り出し、特徴量を計算してListに格納し、全ファイル処理した後にファイルに保存する。
また、画像ファイルの一覧もファイルに保存する。
```Python
import torch
from torchvision.models import ResNet50_Weights
import torchvision.models as models
import torchvision.transforms as transforms
from PIL import Image
import os
import pickle

def get_device():
    if torch.cuda.is_available():
        return torch.device('cuda')
    else:
        return torch.device('cpu')

device= get_device()
model = models.resnet50(weights=ResNet50_Weights.IMAGENET1K_V1).to(device)
model.eval()

# Define the image preprocessing steps
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])
])

def getFeature(imgFile):
    image = Image.open(imgFile)
    image = preprocess(image)
    image = image.unsqueeze(0).to(device)
    with torch.no_grad():
        features = model(image)

    return features
#
#
IMAGE_DIR = "c:/temp/images/"
FILE_LIST = "c:/temp/filelist"
FEATURE_LIST = "c:/temp/features.pt"
filelist = os.listdir(IMAGE_DIR)
#
#  画像ファイルの特徴量をリストに格納
#
file_list=[]
feature_list = []
for file in filelist:
    #print(file)
    features = getFeature(IMAGE_DIR + file)
    feature_list.append(features)
    file_list.append(file)

#ファイルにリストを保存
torch.save(feature_list, FEATURE_LIST)
with open(FILE_LIST,'wb') as f:
    pickle.dump(file_list, f)
```

### 保存したデータはこっちで使用

https://qiita.com/tthogho1/items/0164c426246e2c446dd3
ラムダ式にif文を使用する

## ラムダ式の基本
ラムダ式の中でif文は使用できないと思っていたのですが、実際には使用することができました。
（はじめは「使用できない」という記事を投稿しましたが、親切な方からのご指摘により内容を180°修正いたしました）

まずは基本を確認。
ラムダ式は下の２つの形式を取ることができる。
```C#:式形式
() => expression
```
```C#:ステートメント形式
() => { sequence-of-statements }
```
<dl>
  <dt>式(expresssion)</dt>
  <dd>評価されて値を返す。評価の結果を持つため、他の式の中で使用したり、文の一部として使用できる。</dd>
  <dt>文(statement)</dt>
  <dd>実行されるのみで値を返さない。変数の宣言・代入、制御構文(if、for、while)が文に当たる。</dd>
</dl>

:::note info
式は値を返す。
文は値を返さない。
:::

## ラムダ式にif文を使用する 
```C#:if文
List<int> list = new List
List<int> result = list.Where( x =>
{
    if (x % 2 == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}).ToList();
```
## 3項演算子を使用する方法もある
```C#:3項演算子を使用する
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
List<int> result = list.Where( x => x % 2 == 0 ? true : false ).ToList();
// 上の例は単純な例であり、通常は下のように書く。(良い例が思いつかず...)
List<int> result2 = list.Where( x => x % 2 == 0 ).ToList();
```
ChatGPT搭載の文書チャットボット、LightPDFとChatPDFを比較してみた

ChatGPTのAPIがリリースされて以来、さまざまなソフトウェアやウェブサイトにChatGPT搭載の機能が実装されるようになりましたね。PDF界隈では、PDFをAIチャットボットに取り入れて、PDF内容について質問して情報をすばやく入手できる「ChatPDF」が話題になっています。ChatPDFの後、「mapdeduce」、「humata」や「pandagpt」なども似たサービスが続々と登場しました。今回はさらに最新リリースの「LightPDF」という文書チャットツールを利用し、ChatPDFと比較していきます。

<b>ChatPDFの公式サイト：</b>
https://www.chatpdf.com/
<b>LightPDFの公式サイト：</b>
https://lightpdf.com/jp/chatdoc

<h3>まずは利用前の比較：</h3>

LightPDFは<b>日本語対応</b>で、日本人ユーザーに対してよりフレンドリーで分かりやすいです。
![lightpdf-ai-chat-bot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/70ddb5bd-51ac-5809-8f10-e2f56193ef0f.png)

それにたいして、ChatPDFの方は英語しかありませんが、画面がよりシンプルです。
![chatpdf-ai-tool.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/a8f6755f-b33b-5c99-a38d-a724215deae1.png)

<b>対応する文書形式</b>について、ChatPDFはPDFしか対応しませんが、URLからのPDFの読み込みも可能です。一方、LightPDFはPDFだけでなく、doc、docx、pptx、xlsx、epubもサポートしますが、ローカルPCからファイルをアップロードしかできず、インターネット上のURLからの読み込みはできません。

<h3>実際同じPDFファイルで検証して比較：</h3>

今回使うのはソニーの「第105回定時株主総会招集ご通知」というPDFファイルです。参考にリンクも置いておきます：
https://www.sony.com/ja/SonyInfo/IR/stock/shareholders_meeting/Meeting105/105_ogm_J.pdf

ChatPDFにアップロードした後、ご覧のとおり、画面こそ英語ばかりですが、日本語のファイルを読み込んだら、日本語のまとめと質問のサンプルが表示されます。まとめは簡単ですが、問題はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/153d6a47-56d7-edc9-33f9-0fb17ea4d76e.png)

続いてはLightPDFの方をみます。同じ内容を日本語で要約し、質問のサンプルを3つ提供してくれます。内容も間違いはなく、ChatPDFより少し詳しいです。さらに機能の違いですが、上の「閲覧」をクリックすれば、アップロードしたファイルの閲覧もできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/cab78d67-9f86-5d18-0a69-d37f8c0cd648.png)

提供される質問をクリックして投げつけると、ChatPDFとLightPDFはどれも正確かつ詳細に答えてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/6651df74-c82e-15a3-7ee3-199b954c9ae8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/b432742b-76dc-8d97-195e-824febfcde34.png)

では、自分で考えた「ソニーの取締役候補者を教えてください」という質問を問いかけてみます。正解は下記の画像にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/9decd857-4d7e-0533-0b90-287bfe2f9e1e.png)


ChatPDFの方は慎重で、候補者は複数いるため、その情報のあるページを教えるだけですが、再度要求すれば教えてくれますが、人数も情報のページ数もあっていませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/d24be3ab-1996-3e86-24c4-4cc5cb9a28b1.png)

さらに確認すると、人名も間違っています。最初の吉田と十時だけが合っていて、その後はすべてデタラメで、試しに伊藤博之さんを検索してみましたが、ぜんぜんソニーと関係のない人物でした。こういうのはChatGPTがよく犯す過ちの一つですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/f06f462a-9a7c-b89d-9877-3d74394ea3c6.png)

一方、LightPDFの方は一回の質問だけで正しく返答できています。えらいえらいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/e7dc0280-f1a9-1d89-bf12-d03e8863b819.png)

<h3>結論</h3>

このファイルはスキャンしたものなので、情報のページソースは表示されていませんが、スキャンしたものではない場合は、ChatPDFもLightPDFも回答の情報がのっているページを教えてくれるはずです。さらに、LightPDFはほぼ制限がなく無料で利用できます。

以上のように比較してみた場合は、日本語対応でより正確な答えを出してくれるLightPDFの方はなんと勝ちましたね。ChatPDFも今後英語圏以外の市場に進出する場合は、日本語の対応や日本語ファイルの解析なども改善されるといいですね。
Kibanaをソースからビルドする

Elasticのコンサルタントの杉森です。[前回](https://qiita.com/daixque/items/9b7632ebfa9f7712852e)Elasticsearchをビルドしたので、今回はKibanaをビルドしたいと思います。

ElasticsearchはJavaのプロダクトでしたが、KibanaはNode.js / Typescriptで実装されていますので、ビルドのツールキットが違ってきます。とはいえひとまずビルドしてみましょうという記事ですので気張らずに行きましょう。

## 前提

この記事の前提は以下とします。

- Macのローカルでビルド（IntelMac, macOS Montereyで確認しています）
- Homebrewインストール済み


## Kibanaのチェックアウト

何はともあれコードをチェックアウトします。Kibanaはまた巨大なリポジトリなので結構時間かかります。

```
$ git clone git@github.com:elastic/kibana.git
```

本記事執筆時点でのHEADは 84db06c15d04bcaa011c41daf13ad1521deba604 でした。


## ビルドツールのインストールとビルド

まずはNodeをインストールするためにnvmをインストールしましょう。すでにnodebrewなどを使っているようでしたらそちらでもおそらく問題ありません。homebrewは入ってる前提で：

```
$ brew install nvm
$ source $(brew --prefix nvm)/nvm.sh
$ echo 'source $(brew --prefix nvm)/nvm.sh' >> ~/.bash_profile
```

こちら参考にさせて頂きました。 > https://qiita.com/ffggss/items/94f1c4c5d311db2ec71a#hombrew%E3%81%AE%E5%A0%B4%E5%90%88

Kibanaのソースコードに含まれている`.node-version`で、必要なバージョンを確認します。

```
$ cat .node-version 
16.16.0
```

ということなので、16.16.0をインストールしましょう。

```
$ nvm install v16.16.0
$ nvm alias default v16.16.0
```

確認します。

```
$ node --version
v16.16.0
```

インストールできました。
そうしたらNodeのパッケージマネージャーであるところのyarnをインストールします。

```
$ npm install -g yarn
```

で、yarnで依存のライブラリをとってきてビルドします。

```
$ yarn kbn bootstrap
```

コーヒーを淹れてしばらく待ちます。そういえばCoffeeScriptってありましたけどすっかり聞かなくなりましたよね。実はまだ使われている現場もあるのでしょうか。Rails3くらいにバンドルされていた気がするので、その辺りで作られた社内システムがまだ生きていたり？　Google Trendsでは2012年がピークのようです。現在ではTypeScript一択でしょうか。そういえばyarnのレイヤーにもgruntとかgulpとかwebpackとか色々ありましたよね。その辺が出てきた頃から私はフロントエンドを触る機会が少なくなって、現在に至る勢力争いについてはよく把握してませんが……

お、ビルドがようやく終わりました。

```
...
✨  Done in 445.66s.
```


## 起動

ではKibanaを起動しますがその前にElasticsearchが動いていないといけません。この時、以下のコマンドでこのKibanaのディレクトリからテスト用のElasticsearchを起動することができます。Elasticsearch側の設定に特に関心がなければこれで大丈夫でしょう。

```
yarn es snapshot
```

ではKibanaを起動します。別のターミナルから以下を実行して下さい。

```
yarn start
```

これまた初回はそれなりに時間がかかりますが、以下のログが出るまで待ちましょう。

```
 np bld    log   [18:53:09.696] [success][@kbn/optimizer] 133 bundles compiled successfully after 102.1 sec, watching for changes
```

めでたく起動しましたので、[http://localhost:5601/](http://localhost:5601/)にアクセスします。ログイン画面になりますが、以下のユーザーとパスワードで入れます。

- User: elastic
- Password: changeme

お疲れ様でした。

もちろん`config/kibana.yml`の書き換えることでElasticsearchの接続情報などの設定を変更できます。必要に応じて変更して下さい。
Elmer GUI tutorial (平板コンデンサの静電容量)

# Elmer チュートリアル（Fringe Capacitance）

[このページ](http://www.nic.funet.fi/pub/sci/physics/elmer/doc/ElmerTutorials.pdf)にあるElmer GUIチュートリアルの１１，Fringe Capacitance というのをやってみる．  
有限長さの平板コンデンサ（２次元）の計算．上記ドキュメントだとポテンシャルを計算するところで終わっていて，静電容量計算については詳しく書かれていないので，そっちもやってみる．  

## 入力ファイル

チュートリアル用の入力ファイルは公式ページで配布されているのでプロジェクトごとElmerから読み込んでRunすれば良い．   

読み込むと図のような感じでメッシュが表示される．真空中に完全導体の平板があるという状況．周囲のボックスの下辺がグラウンドになっている．  
境界条件は導体表面で電位１，グラウンドで０になっている． 

![geom1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672130/14a5d066-cd19-dc70-3e8d-ade861608c7c.png)


そのまま走らせるとチュートリアル通りの図ができるはず．ただ，その下に

    From the output of the simulation one may see that the capacitance in this case was 13.697 
    compared to the analytical estimate of 10. Hence the fringe capacitance in this case increases 
    the capacitance by 37 %.

と書いてあるが，この静電容量 "13.697" の計算の仕方が書いてないので以下のように設定るる．  

## 静電容量計算の設定  

やることは１．ソルバに静電容量計算の設定をする，２．各導体の境界条件に静電容量計算の設定を追加．[ここ](http://www.nic.funet.fi/pub/sci/physics/elmer/doc/ElmerModelsManual.pdf)のModel16 Electrostaticの部分を参照．キャパシタンス行列計算の設定について説明がある．  

１．ソルバの設定を開いて  
- Calculate Capacitance Matrix -> True
- Capacitance bodies -> 1 
- Capacitance Matrix Filename -> "cap.txt"    
  
と設定．
Capacitance bodies はキャパシタンスに寄与する導体の数．今の場合，平板１とグラウンドの２つだが，"not acounting the ground" と書かれているので１で良い（と思う）．出力ファイル名は適当につける．    

２．境界条件設定を開き，
- Capacitance Body -> Int

のように整数でナンバリングする．今の場合はグラウンドに０，平板に１と割り振ればおｋ．今の場合は要素が平板とグラウンドの２つしかないので，行列ではなくスカラーになる．    

## 実行 → ParaViewで表示 

結果をパラビューで表示する．まず電位分布は以下のような感じ．  

![potential01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672130/0939bf30-bae8-4a13-b478-159e8c1f6f1c.png)


出力された静電容量行列は以下のようになり，確かに "13.697" となった．  

![cap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672130/beb9d43d-2153-2ae3-b4f6-5b1e93a2724a.png)
WITH句を使ったデータの結合

## 1.WITH句とは？
![question_man_01_simple.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/3c050d62-5b45-c60d-f10e-f5d01b1ca0d3.png)

 SQLクエリ内に一時的な名前付きサブクエリを作成する方法です。WITH句を使用すると、サブクエリを一度だけ定義し、その後、同じクエリ内で何度も参照できます。

WITH句は、複雑なクエリを分割し、読みやすく、メンテナンスしやすいものにすることができます。また、WITH句を使用すると、クエリのパフォーマンスも向上する場合があります。

## 2.今回のモチベーション
今回のモチベーションは、
ある宿泊施設に訪れた人に対して、他の宿泊施設をおすすめする
そんな感じにしております

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/b1facc58-f3af-4917-dfe7-58b393ffe252.png)

そのため、最終的には
HotelIDとそれ以外のhotelID（小地域か大地域かは所属している小地域による）を与えることにします。


## 2.使い方
下が実際に、WITH句を用いたサブクエリの書き方になってます。
以前に、CASE句を使ったクエリの書き方を紹介しているので、よかったらみて見てください。

https://qiita.com/yusaku-pon/items/a63cb5bcf68f7e9dba29

```sql
WITH small_area_mst AS (
SELECT
small_area_name,
--20件以上あれば join_area_idをsmall_area_nameとして設定
--20件未満であれば　join_area_idをbig_area_nameとして設定
-- -1は、自ホテルを引いている

CASE WHEN COUNT(hotel_id)-1 >=20
THEN small_area_name ELSE big_area_name END AS join_area_id

FROM hotel.hotel
GROUP BY big_area_name , small_area_name
)
```
こんな感じで、あたかもテーブルがあるかのようにFROM句を使えるようになります。
```sql
SELECT *
FROM small_area_mst
```
WITH句はコロンで複数作成することが可能です。

```sql
WITH small_area_mst AS (
SELECT
small_area_name,
--20件以上あれば join_area_idをsmall_area_nameとして設定
--20件未満であれば　join_area_idをbig_area_nameとして設定
-- -1は、自ホテルを引いている

CASE WHEN COUNT(hotel_id)-1 >=20
THEN small_area_name ELSE big_area_name END AS join_area_id

FROM hotel.hotel
GROUP BY big_area_name , small_area_name
),

--どのホテルがどこのareaに含まれているかをまとめている。
recommend_hotel_mst AS(
SELECT
big_area_name AS join_area_id,
hotel_id AS rec_hotel_id
FROM hotel.hotel
--unionでテーブル同士を連結UNION
UNION ALL

SELECT
small_area_name AS join_area_id,
hotel_id AS rec_hotel_id

FROM hotel.hotel
)
```
UNION_ALL を使うことで、複数のテーブルを結合することができます。
詳しい説明はこちらがわかりやすいかと思います。

https://medium-company.com/sql-union/


## 3.WITH句の真骨頂
WITH句は以下のように使うことができます。

```sql
--どのホテルがどこのareaに含まれているかをまとめている。

--目的、small_area_nameが20以上の場合はsmall_area_nameを推薦して
-- それ以外の場合は、big_area_nameとして付与する。

SELECT 
hotels.hotel_id,
r_hotel_mst.rec_hotel_id
--レコメンド元のhotel_tbを読み込み
FROM hotel.hotel hotels

INNER JOIN 
small_area_mst s_area_mst
ON hotels.small_area_name = s_area_mst.small_area_name

--対象エリアのレコメンド候補を結合する
INNER JOIN recommend_hotel_mst r_hotel_mst
ON s_area_mst.join_area_id = r_hotel_mst.join_area_id

--レコメンド候補から自分ホテルを除く
AND hotels.hotel_id != r_hotel_mst.rec_hotel_id
```

INNER JOINで元のテーブルとWITH句で作成したテーブルを順番にJOINしております。

作成したデータセットがこちらになります。

![スクリーンショット 2023-04-18 18.41.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/32cf429a-bf6c-4e8c-c901-83742a84c7b3.png)

## ４.まとめ

複雑なクエリはWITH句を使って解決しましょう。

とは言いつつ、自分もスラスラとコーディングできるようになりたいなぁ

それではまた。
EC2に構築したNginx の設定を初期化する方法

## はじめに
EC2インスタンス上でNginxを構築していて、Errorの切り分けでNginxを最初からやり直したかった。ぴったしの記事がなかったので、一応、備忘録として残しておきます。
以下、EC2インスタンス上のNginxを初期化する方法です。

## 1. EC2へSSHログインする
```console:
ssh [アプリ名]
```
具体的な方法は、[こちら](https://qiita.com/takuma-jpn/items/b2c04b7a271a4472a900)を参考


## 2. Nginxを停止する
```console:
$ sudo systemctl stop nginx
```

## 3. Nginxの設定ファイルを削除する。
Nginxの設定ファイルは通常、以下のパスにあります。
```console:
$ cd /etc/nginx/
$ sudo rm nginx.conf
```

## 4. デフォルトの設定（nginx.conf.default）に戻す
```console:
$ sudo cp nginx.conf.default nginx.conf
```

## 5. Nginxを再起動する
```console:
$ sudo systemctl start nginx
```

## 6. ステータス確認
```console:
$ sudo systemctl status nginx
```

active(running)を確認できたら初期状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238056/36ed767a-bbdf-9fee-9acc-90f66a93c0e6.png)
C言語のprintf関数とnull文字を含む文字列

C言語の課題でハマったので備忘録

<h1>TL; DR</h1>
 printf関数にnull文字を含む文字列を与えると、その文字列はnull文字以降の文字を表示しなくなるよ。
例) {0x41, 0x00, 0x42}をprintf関数に与えると、A(0x41)だけ出力される。2つ目以降は表示しない。

<h1>環境</h1>
OS windows 10<br>
コンパイラ MinGW 5.4<br>
CLI PowerShell


<h1>本題</h1>
詳しく見ていきましょう。問題が起こったコードはこちらです。誤って文字列の範囲外の要素を指定して、代入してしまいました。

```
#include <stdio.h>

int main(void){
    char str[4] = "xyz";
    str[0] = str[5];
    printf("str: %s", str);
    return 0;
}

// 出力
// str:
```


文字列が消えた…？！

本当に文字列が消えたのでしょうか？strのそれぞれのASCIIコードを確認しましょう。

```
#include <stdio.h>

int main(void){
    char str[4] = "xyz";
    
    str[0] = str[5];
    printf("str[0]: %c, str[1]: %c, str[2]: %c", str[1], str[2], str[3]);
    return 0;
}

// 出力
str[0]: 0, str[1]: 0x79, str[2]: 0x7A

```

最初の文字が置き換わっただけで、ほかは初期値のままですね(0x79: y, 0x7A: z)。これだけでは、null文字があるとすべての文字が出力できないのか、それ以降が出力できないのか切り分けができません。別のindexで試してみましょう。

```
#include <stdio.h>

int main(void){
    char str[4] = "xyz";
    
    str[1] = str[5];
    printf("str: %s\n", str);
    printf("str[0]: %c, str[1]: %c, str[2]: %c", str[1], str[2], str[3]);
    return 0;
}

// 出力
str: x
str[0]: 0x78, str[1]: 0, str[2]: 0x7A

```

null文字以降の部分が表示できないようですね。

<h1>まとめ</h1>
 null文字を含む文字列をprintf関数に渡すと、null文字以降が表示されないということがわかりました。そもそも範囲外を指定するのがおかしなことですが、トラブルシューティングの助けになると幸いです。
node fibers arm64が入ってなかった

ubuntuARMイメージに、
コピってきたnode_moduleにはfibersのArm64環境用がなくてwebpackが立ち上げられなかった

```
## There is an issue with `node-fibers` ##
`/var/www/subsystem/bo/oej_robotics_cms/ejs/projectroot/node_modules/fibers/bin/linux-arm64-72-glibc/fibers.node` is missing.

Try running this to fix the issue: /usr/bin/node /hogehoge/node_modules/fibers/build
Error: Cannot find module '/hogehoge/node_modules/fibers/bin/linux-arm64-72-glibc/fibers'
Require stack:
〜〜〜
```

```
$ ll /node_modules/fibers/bin/
total 4
drwxr-xr-x 13 aaa bbb  416 Apr  5 17:49 ./
drwxr-xr-x 17 aaa bbb  544 Apr  5 17:49 ../
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 darwin-arm64-108/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 darwin-x64-72/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 darwin-x64-83/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 linux-x64-64-glibc/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 linux-x64-72-glibc/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 linux-x64-72-musl/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 linux-x64-83-glibc/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 linux-x64-83-musl/
-rwxr-xr-x  1 aaa bbb 1175 Mar  8 15:32 repl*
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 win32-x64-72/
drwxr-xr-x  3 aaa bbb   96 Apr  5 17:49 win32-x64-83/
```

たしかに無い・・

npm rebuildを実行
```
$ npm rebuild fibers
rebuilt dependencies successfully
```

```
drwxr-xr-x  3 aaaa bbb   96 Apr 18 18:14 linux-arm64-72-glibc/
```
キターーーーー

無事なんとかなりました
（M1 Mac Dockerなので、ARM Ubuntu使いたかったが、上記の問題でたから、Rosetta 2でIntelUbuntu動かそうとしたが、Apache起動せずで、トホホしてたが、命拾いした・・）

ちなみにnodeのバージョンは
```
$ node -v
v12.22.9
```

node v16だとまた厳しそうみたいだけどどうなんだろう・・
warning C4239 : conversion from 'A' to 'A &' の警告


```c++
#include <utility>

struct A {};
void fn(A&);

void f()
{
  fn(std::move(A()));
}
```

上記のようなコードを書いたところ、以下の警告が出た。(コンパイラは VS2012)

```Console
warning C4239: nonstandard extension used : 'initializing' : conversion from 'A' to 'A &'
          A non-const reference may only be bound to an lvalue
```

C4239 は、以下。(2023/4/18 現在)

https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4239?view=msvc-170

理由は引数の型が `non-const reference` であるのに、std::move で rvalue を渡そうとしているため。
rvalue を渡しているのだから関数の引数の型を A&& にしてやるのが良い。
[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第1章-5(Todoリスト削除編)

## 前回のあらすじ
ここまでみていただきありがとうございます！
前回はTodoリスト一覧表示編でTodoリストの一覧表示ができるようになりました。
[[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第1章-4(Todoリスト編集編)](https://qiita.com/streasure0426/items/ca2c8b71cf106922558c)

今回は作成したtodoリストを削除できるようにします。

## 事前準備
Dockerを一度止めている方はこちらのコマンドでDockerを起動し、コンテナに入りましょう。
``` bash
docker-compose up -d
docker-compose exec app bash
```

## ビューの編集
まずは一覧画面に削除ボタンを付けます

```diff_slim: app/views/todos/index.html.slim
h1 Todo一覧

= link_to  "Todo追加", new_todo_path, class: "btn btn-primary"

table.table
  thead
    tr
      th scope="col" 題名
      th scope="col" 詳細
      th scope="col"
+     th scope="col"
  tbody
    - @todos.each do |todo|
      tr
        td = todo.title
        td = todo.description
        td = link_to "編集", edit_todo_path(todo), class: "btn btn-sm btn-success"
+       td = button_to "削除", todo, method: :delete, class: "btn btn-sm btn-danger"
```

コードの説明します。
`method: :delete`：HTTPリクエストのメソッドをDELETEに設定しています。

これで削除ボタンを実装することができました。
画面は以下のようになっています。
![スクリーンショット 2023-04-18 18.16.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982962/ff1059d0-025e-65ec-eefb-6b074d083761.png)

## コントローラーの編集
ボタンを押したらtodoをデータベースから削除して一覧画面を更新できるようにコントローラーを編集します。

``` diff_ruby: app/controllers/todos_controller.rb
class TodosController < ApplicationController
  def index
    @todos = Todo.all
  end

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.create(todo_params)
    redirect_to todos_path
  end

  def edit
    @todo = Todo.find(params[:id])
  end

+ def destroy
+   @todo = Todo.find(params[:id])
+   @todo.destroy
+   redirect_to todos_path
+ end

  private
    def todo_params
      params.require(:todo).permit(:title, :description)
    end
end
```
コードの説明をします。
`@todo.destroy`：Todoデータベースから特定したtodoデータを削除します。

これで削除機能の実装が終わりました。
実際に削除できているか検証してみましょう。

## 検証
- 適当なtodoの削除ボタンを押して実際に削除できるか確認します。
![スクリーンショット 2023-04-18 18.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982962/2ac477c2-2f75-2ef3-8256-b4c5b7a22f9a.png)

上の画像のようにtodoが削除されていれば成功です。
何度か実際に試してみましょう。

## 総括
こちらで基本的なTodoリストの開発が完了しました！
お疲れ様です！
次回からはこれまで開発したTodoリストにTurboの要素を取り入れてより利用しやすくしたいと思います。

今回はここまで！

続けて読んでいただけるとありがたいです。

[[有料級]　Rails7(Turbo), Docker, Bootstrap5を使ったtodoリストの作り方第2章-1(モーダル画面作成編)](https://qiita.com/streasure0426/items/ff1ac3c98050e60bc06d)
OAuthを2秒で理解したので覚書をしようと思う

# 読むべき人
OAuth？なんかあれでしょ？
認証の時の、。

なんかフロー的な、あれでしょ？

という人。

# OAuthとはずばり何

サービス間連携する時のフレームワークのようなものです。


そう、フレームワークのようなものなのです。

OAuthを理解しようとするとやたら詳しく細かく説明してある図ばっかりが検索に引っかかって、小難しい言葉の羅列に理解する気を削がれた人は多いのではないかと思います。

まずはこのことを頭に叩き込んでください。
OAuthは認証処理をする上での「こんな感じでやることにしようぜ」っていうガイドラインに過ぎないのです。



# どんな時に使うものなの？

本質は簡単です。

Googleのスプレッドシートに保存してある情報を、別のアプリケーションが利用したいとします。
普通ならそのアプリケーションがユーザーのID・パスワードを把握すれば簡単に実現できると思いますよね。

でもID・パスワードを把握するってことは何処の馬の骨かもわからん謎のアプリが、
やろうと思えば

GoogleDriveに保存してある大事な資料を全て消したのち、
密かに想いを寄せていた取引先のかわいい女性にGmailで勝手に愛の告白をし、
YouTubeで知りもしないYouTuberのライブ配信に巨額のスパチャを送ることだってできてしまうわけです。

それはいかんということで、そのアプリケーションにスプレッドシートの閲覧の権限のみを渡したい！
そんな願いを叶えるのがOAuthの仕組みです。

![Screenshot 2023-04-18 at 18.14.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2373655/3b207064-56d9-ca6f-ed3f-c7d4fba58a3a.png)



ちまたの図には何やら難しい単語が羅列されていますが、今回は概要の概要を理解するため、テクニカルな用語は最小限で説明します。

①　アプリケーション「スプレッドシートにアクセスさせてくださーい！という要求」

②　Googleの認可サーバー「アプリケーションがあんたのスプレッドシートのデータ使いたいって言ってるぞ」

③ ユーザー「じゃあIDとパスワード渡しとくわ」

④ Googleの認可サーバー「使っていいらしいよ。でもお前のことそこまで信用できないからスプレッドシートだけ見れるための許可証だけ渡しておくわ。」

⑤ アプリケーション「スプレッドシートさーん、データ見せてー！あ、IDとパスワードはないけど専用の許可証はあるっすー。」


と言った流れになっています。

# 何がそんなにいいの？

上の流れでなんとなくは伝わったと思いますが、つまりは
・サードパーティのアプリケーションにユーザーのIDとパスワードが伝わっていない
・サードパーティのアプリケーションはユーザーのIDとパスワードを保存していない
・許可証となる専用のアクセストークンを発行することで権限を最小限に絞ることができる

ってわけです。

こうすることでサードパーティのアプリが暴走しようとしてもせいぜいスプレッドシートのデータをばら撒くくらいしかできないわけです。
ChatGPTにOutlookの日報メールを自動化させてみた

```
「chatGPTにoutlookの日報メールを自動化させてみた」　ってテーマでQiitaを書いて

以下条件
・pythonを使用する
・pythonを実行するとoutlookのメール新規作成が開かれて宛先・タイトル・本文を自動で入力する
・タイトルに日付が入るようにして YYYY/MM/DD方式
・段落は前提条件、手順、所管で記載
・回答はマークダウン方式で記載して
```

# chatGPTより
本記事では、Pythonを使用してOutlookの日報メールを自動化する方法について説明します。

## 前提条件
Python 3.xがインストールされていること
Microsoft Outlookがインストールされていること
Outlookの設定で「Outlookのプログラムによるアクセスを許可する」が有効になっていること

## 手順
1. ライブラリのインストール
PythonでOutlookを制御するためには、pywin32というライブラリが必要です。以下のコマンドでインストールしてください。

```py
pip install pywin32
```

2. コードの作成
以下のPythonコードを作成します。

```py
import win32com.client
import datetime
```

## Outlookオブジェクトの生成
```py
outlook = win32com.client.Dispatch("Outlook.Application")
```

## 新しいメールを作成
```py
mail = outlook.CreateItem(0)
```

## 宛先、件名、本文を設定
```py
mail.To = "送信先メールアドレス"
mail.Subject = datetime.date.today().strftime("%Y/%m/%d") + "の日報"
mail.Body = "日報の本文をここに入力する"
```

## メールを表示
```py
mail.Display(True)
```

3. コードの実行
コードを実行すると、Outlookの新しいメール作成画面が開き、宛先、件名、本文が自動的に入力されます。日付は、datetime.date.today().strftime("%Y/%m/%d")によって現在の日付をYYYY/MM/DDの形式で取得しています。

4. コードのカスタマイズ
コード中の以下の部分を変更することで、自分の環境に合わせた設定に変更できます。

```py
mail.To = "送信先メールアドレス" : 送信先メールアドレスを指定してください。
mail.Subject = datetime.date.today().strftime("%Y/%m/%d") + "の日報" : 件名のフォーマットを変更したい場合は、ここの文字列を変更してください。
mail.Body = "日報の本文をここに入力する" : 日報の本文を自分で入力する場合は、ここにテキストを入力してください。
```

## 所管
以上でOutlookの日報メールを自動化する方法を説明しました。この方法を使えば、日々の業務で必要となるメールを簡単に作成することができます。是非、試してみてください。


# ここから本題
驚くことは上記内容は少しの修正を加えた以外、すべてchatGPTが出力したものです。
実際に僕もこのコードを使用してoutlookの日報メールを自動化することが出来ました。

chatGPTに質問した内容は少しコツがありますが、数回質問をやり直した程度です。
　※ちなみにマークダウンでは返ってきませんでした。。


chatGPTの回答の精度やクオリティは、予想以上に素晴らしいものであり、今後のAIの活用方法をより注目する必要があると感じました。

今後はこのような生産性の向上はもちろん、意思決定支援や、新サービスの創生に関してにもAIを利用してみようと思う。
テストエンジニア資格「JSTQB」って知っていますか？

## JSTQBとテストエンジニア
皆さん「JSTQB」、「テストエンジニア」といった言葉を聞いたことはあるでしょうか？
現在の私たちの生活の中ではアプリケーション、Webサービスといったものが切り離せなくなっています。
それらのサービスをいざ使ってみようとしたらバグだらけだった・・・なんてことになったら困りますよね？
そんな事態を防ぐため、サービスリリース前にバグを発見する技術者が「テストエンジニア」、テストエンジニア向けの資格が「JSTQB認定テスト技術者資格」なのです！
今回はテストエンジニアにおすすめの資格「JSTQB」についてご紹介いたします！
また、今回の内容は新人プログラマの方にも必見の内容となっております！

## JSTQBの3つのレベル
JSTQB認定テスト技術者資格(以下JSTQB)はJSTQB(Japan Software Testing Qualification Board)によって2006年より開始された資格認定制度です。
この資格は初級レベルであるFoundation Level、そしてより上級であるAdvanced Level、Expert Levelの3つのレベルに分かれています。
この内Advanced LevelはFoundation Levelの合格と3年以上の業務経験が必要など受験資格が設定されており、Expert Levelは試験自体まだ実施されたことがありません。
そのため今回はFoundation Level(以下FL)に焦点を当ててご紹介いたします！

## FLの試験概要と難易度
**試験実施日**：予約可能であればいつでも
**試験実施地**：全国のテストセンター
**受験資格**：誰でも受けられます
**受験料**：22,000円(税込)

上記の通りFLは「受験してみたい！」という方であれば誰でも受験が可能です。
また、以前は年2回(2月、8月)の筆記試験でしたが2022年10月よりコンピューター試験に移行し、テストセンターの予約可能日であればいつでも受けられるようになりました。
また、難易度に関しては合格率が大体40%台～60%台となっておりさほど高くはありません。
きちんと勉強すれば誰でも取得可能な資格と言えるでしょう。
しかし、上記の通り受験料は決して安くはないので、できれば1回で合格したいところです。

## 勉強方法と参考書
FLに限らず「よし！受験してみよう！」となった時にまず考えるのは「どう勉強したらいいの？」ですよね？
FLの場合非常にシンプル！参考書を読むだけでOKです！
では次に「どの参考書を読めばいいの？」ですがこれも単純で、『ソフトウェア教科書』というJSTQB公認テキストがあるのでそれ一択です。
というより割とマイナーな資格だからか他に良い参考書や過去問集がないんですよね・・・。
内容的には公認テキストという事もあり、テストとは何か？という概念的なことから具体的なテスト技法までわかりやすくシンプルにまとめられており非常に読みやすい参考書となっております。
ページ数としても模擬試験込みで400ページほどでちょうどよい文章量です。
こちらに[Amazonのリンク](https://amzn.asia/d/3ypREHI)を貼っておくので参考にしてみてください。
購入の際の注意点としては必ず最新のものを購入するようにしましょう。
こちらのテキストはJSTQB公式が公開しているシラバスの更新に合わせて改訂されるため、古本屋等での購入は避けた方がよいと言えるでしょう。
シラバスに興味のある方は[公式Webサイト](http://jstqb.jp/)をご参照ください。

## 勉強時間について
FLの勉強時間としては30時間程度が目安と言われています。
1日1時間ほど勉強すれば1ヶ月で取得できますので、時間の確保に関しては社会人の方にも難しくないと思います。
私自身は約1ヶ月かけてテキストを3周ほど読み込み、割とすんなり合格できました。
この資格に限ったことではないですが少しずつコツコツが大事ですね！

## 最後に
技術者にとって資格取得は必ずしも必要とはされないと思います。
しかし、資格取得を通して勉強することで体系的に学ぶことができ、特に基礎知識を固めるには大いに役立つのではないでしょうか？
今現在テストエンジニアのプロジェクトで働いている方、今後配属予定の方、もしくはソフトウェアテストに少しでも興味のある方には是非おすすめです。
決して難しくはないのでコツコツ勉強してJSTQB Foundation Levelに合格しましょう！
Windowsのパッケージ管理システム「Chocolatey」について

## はじめに

#### 対象読者
本記事は、以下の方を対象としています。

+ Windowsのパッケージ管理システムを利用したい方
+ Chocolateyの概要を知りたい方
+ Chocolateyを利用したパッケージのインストール方法を知りたい方
#### パッケージ管理システムについて

その名の通り、複数のパッケージを管理してくれる頼もしいツールです。

パッケージ管理システムを使用することで、複数のライブラリやツールを簡単にインストール、アップグレード、アンインストールできるようになります。
また、依存関係を解決することができるため、手動でライブラリを探したり、バージョンを調整したりする手間が省けます。


## Chocolateyとは

ChocolateyはWindowsで使えるパッケージ管理システムで、コマンドプロンプトやPowerShellからソフトウェアをインストール・アンインストール・アップデートすることができます。

Macの```Homebrew```に該当します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124182/c1b4aea4-0891-e143-3b7f-d5f12d801a5d.png)


#### インストール手順

①管理者権限でPowerShellを開きます。
以下のコマンドを入力して、Chocolateyのインストーラーをダウンロードします。


```
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```


②インストールが完了したら、PowerShellを再起動します。
③インストールが正常に行われているか確認するために、以下のコマンドを実行します。

```
choco -v
```

バージョン情報が表示されたら、Chocolateyのインストールは完了です。


## Chocolateyを使ってパッケージをインストールする

パッケージをインストールするには下記のコマンドを実行します。

```
choco install パッケージ名
```
たとえば、openSSLをインストールする場合は、以下のようになります。

```
choco install openssl
```

また、インストール時には必要に応じて .light サフィックスを付けることができます。

```
choco install openssl.light
```

".light"はChocolateyパッケージのサフィックスで、そのパッケージが軽量版であることを示しています。
軽量版は、必要な機能だけを含むように構成されており、ダウンロードとインストールにかかる時間が短くなる場合があります。

ただし、すべてのパッケージに対して .light バージョンが用意されているわけではないようです。
確認方法は以下の通りです。


①[Chocolateyの公式サイト](https://chocolatey.org/packages)で検索バーにパッケージ名を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124182/b6222507-c6d8-b415-83e1-15129908c015.png)


②検索結果ページには、各パッケージのバージョンやインストールのためのコマンドが記載してあります。
「Tags」やコマンドの部分を見ると、.lightバージョンかどうかがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124182/722f7473-3803-6b53-5e6f-8dd2f1e6a32b.png)

以上が、Chocolateyを使ってWindowsにパッケージをインストールする手順になります。

## Chocolateyにインストールされているパッケージの一覧を表示

インストールしたパッケージを確認するには下記のコマンドを実行します。

```
choco list -lo
```
このコマンドを実行すると、ローカルにインストールされたパッケージのリストが表示されます。







## おわりに

#### まとめ
本記事では、Windowsのパッケージ管理システムである「Chocolatey」について、
下記の内容を説明いたしました。

・インストール方法
・Chocolateyを使用したパッケージのインストール方法
・lightバージョンのパッケージのインストール方法
・インストールしたパッケージの確認方法


MacにHomebrewがあるように、Windowsにも同様にパッケージ管理システムは存在します。
けれども私は知りませんでしたが。。。。（あまりメジャーではない？）

これで少しでもインストールしたツールにまとまりがでることを祈ります。


閲覧ありがとうございました。
vuetifyのカスタムカラーをvarで利用する

<b>version</b>
vue@3.2
vuetify@3.1

vuetifyでカスタムテーマを定義することありますよね。
特に色なんかはclassに埋めれば使えるようにしてほしいですが反映されない時があります~~いまだに仕様が謎~~。

そんな時は最終手段としてvarで呼び出しましょう。
vuetifyのカスタムテーマはcssのルートに変数で定義されるのでvarで呼び出せるみたいです

# Let's Go
カスタムカラー
```vuetify.ts
 theme: {
      defaultTheme: 'light',
      themes: {
        light: {
          colors: {
            'aka': '#FF98BD',
          },
        },
      },
  }
```

:::note 
ポイントはrgbに入れることです
:::
```hoge.vue
<style>
.aka {
  color: rgb(var(--v-theme-aka))
}
</style>
```
【Terraform】EC2の毎回変わるインスタンスidに発狂して対策を考えました。

:::note alert
セキュリティ上よろしくないやり方ですので参考程度で
:::

# 毎回マネジメントコンソールからインスタンスidを拾ってssh_configを書き直すのがめんどくさい！！

## であれば自動化したらいいよね

### やりかた
- EC2モジュールのmain.tfに以下を記述
```main.tf

resource "null_resource" "output_instance_id" {
  triggers = {
    xxx_id = aws_instance.xxx.id //xxxは環境に合わせたec2インスタンス名
  }

  provisioner "local-exec" {
    command = "echo yyyy ${aws_instance.xxx.id} >> ec2_id.txt" //yyyはインスタンスの固有名を設定するとわかりやすい例 EC2-AP-1aなど
  }
}
```
ec2_id.txtにインスタンスidが出力されます。 >> で追記しているのはEC2複数インスタンスがあるからそうしてます。

- ec2_id.txtを書き換える
``` ini_convert.sh
#!/bin/bash

file_path="./ec2_id.txt"

# 変数でEC2のIDを取得する
ec2_id_x=$(grep 'xxx' ./ec2_id.txt | awk '{print $2}')
ec2_id_y=$(grep 'yyy' ./ec2_id.txt | awk '{print $2}')


# 挿入するテキストを指定する
new_text="[SSHコンフィグのホスト名]\n hostname = xxx ${ec2_id_x}\n[SSHコンフィグのホスト名]\n hostname = yyy ${ec2_id_y}"

# 挿入するテキストを含めた新しいファイルを作成する
awk -v text="$new_text" '
  {
    if (NR > 2) {
      print
    }
    if (NR == 1) {
      print text
    }
  }
' "$file_path" > /tmp/file.txt

```
#この方法だとできませんでした。(ssh configは外部の変数を使えません。)一応configごと置き換えられるようにするpythonコードを置いておきます。

```  sshconfig_rewrite.py
import configparser
import shutil

class sshconfig_rewrite():

    def __init__(self):
        source_file = "./sshconfig.template"
        destination_file = "~/.ssh/config"
        shutil.copyfile(source_file, destination_file)
        self.input_file = "~/.ssh/config"
        config = configparser.ConfigParser()
        config.read('./ec2_id.ini')
        self.replace_text1 = '@@@hostname1@@@'
        self.replace_text2 = '@@@hostname2@@@'
        self.new_text1 = config.get('EC21A-aws-dev','hostname')
        self.new_text2 = config.get('EC21C-aws-dev','hostname')

    def ec2id_add_sshconfig(self):
        with open(self.input_file, 'r') as file:
            content = file.read()
            content = content.replace(self.replace_text1, self.new_text1)

        with open(self.input_file, 'w') as file:
            file.write(content)

        with open(self.input_file, 'r') as file:
            content = file.read()
            content = content.replace(self.replace_text2, self.new_text2)

        with open(self.input_file, 'w') as file:
            file.write(content)

if __name__ == "__main__":
    main = sshconfig_rewrite()
    main.ec2id_add_sshconfig()
    print("Text replacement is complete.")

```

``` ./sshconfig.temlate

host EC21A-aws-dev
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
    User xxxxx
    Port xx
    HostName @@@hostname1@@@
    IdentityFile xxxx

host EC21C-aws-dev
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
    User xx-xxxx
    Port xx
    HostName @@@hostname2@@@
    IdentityFile xxxx
```

# このコードを実行するには.sshとssh configのパーミッションを変えなきゃいけません。最悪のやりかたですね。
セールスフォースのデバッグログ（ユーザ追跡フラグ）作成エラーの対策

エラー：
有効な追跡フラグがあると、デバッグログがトリガされます。最大 1,000 MB のデバッグログのうち 1,241 MB を保持しています。追跡フラグを編集する前に、いくつかのデバッグログを削除してください。

対策：
デバッグログの削除

1.開発者コンソールを開きます。
2.コンソールの下部で、[Query Editor (クエリエディタ)] タブを選択します。
3.[Use Tooling API (Tooling API を使用)] を選択します。
4.次の SOQL クエリを入力します。
  SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog
5.[Execute (実行)] をクリックします。
6.削除するログを選択します。列で並び替えるには、そのヘッダーをクリックします。個々のログを選択するには、Ctrl キー (Windows または Linux 場合) または Command キー (Mac OS の場合) を押します。ログのブロックを選択するには、Shift キーを押します。
7.[Delete Row (行を削除)] をクリックします。
8.ログの削除を確定するには、[Yes (はい)] をクリックします。
SQLによる、CASE句

## 参考にした教材
https://www.amazon.co.jp/%E5%89%8D%E5%87%A6%E7%90%86%E5%A4%A7%E5%85%A8-%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AESQL-Python%E5%AE%9F%E8%B7%B5%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-%E6%9C%AC%E6%A9%8B-%E6%99%BA%E5%85%89/dp/4774196479

## 1.CASE句とは
SQL CASE文は、条件に基づいて結果を返すようにSQLクエリを制御するための構文です。 CASE文は、IF-THEN-ELSE文に似た機能を提供します。

## 2.実例
例えば、A,B,Cという地方があったとします。
その中でA-1,A-2,A-3のようにさらに地区が分割されているとします。

ホテル会社がA-1に泊まった人にはA-1の他のホテルを案内したいなとします。
ただ、A-1の地区があまりにも規模が小さいせいで、おすすめする場所が少なかったとします。
その場合は、もっと規模を増やして、A地方全体の店舗を含めてレコメンドしようとします。

その場合、CASE句が役に立ちます。

```sql
WITH small_area_mst AS (
SELECT
small_area_name,
--20件以上あれば join_area_idをsmall_area_nameとして設定
--20件未満であれば　join_area_idをbig_area_nameとして設定
-- -1は、自ホテルを引いている

CASE WHEN COUNT(hotel_id)-1 >=20
THEN small_area_name ELSE big_area_name END AS join_area_id

FROM hotel.hotel
GROUP BY big_area_name , small_area_name
)
```

ここでのCASE WHEN THENは先ほど説明した通り、if文のような役割を持っており
IF A THEN B
Aの場合は、Bを返す
といったような処理になります。
ELSEでそうでない場合は、Cを返すみたいな感じですね。

この場合、最初のカラムにはsmall_areaの名前が表示され
CASE句に沿ってjoin_area_idというカラムが追加され、
合計で2つのカラムが追加されます。

-1にしているのは、自らのホテルの数を引いているからです。

### 2.1 GROUP BYが必要な理由

逆に、GROUP BY がない状態を考えてみてみましょう。
そうすると、全てのhotel_idのカウントになってしまいますね。
知りたいのは、small_area_nameごとのhotel_idの数なので、GROUP　BYを使っております。

#### big_area_nameでもGROUP BYする理由は？

small_area_nameだけでグループ化すると、同じbig_area_nameに属する異なるsmall_area_nameの値を区別することができなくなります。例えば、同じbig_area_nameに属するが、名前が異なる2つのsmall_area_name値がある場合、small_area_nameだけでグループ化すると、1つのグループにまとめられ、結果的に両者の区別がつかなくなってしまいます。

今回の場合、CASE句でsmall_area_nameが20より小さい場合は、big_area_nameをおすすめしたいので、
big_area_nameの情報も必要ってわけです。

## 3.実行するとこんな感じになる
A-1は20以上ホテルの数があるので、A-1になってますね
逆にB-1は20より少ないので、Bになってますね。
![スクリーンショット 2023-04-18 17.25.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/1792c2f0-e833-91d2-6cda-a7a3e4de8b5d.png)

CASE句使うと、場合分けができるのでとても便利です。
【Pythonのデコレータを使ってみる: より効率的なコードを書くためのテクニック】

# はじめに

Python を勉強中の筆者がデコレータを理解するための基本概念や実践的な使用例をまとめてみました。デコレータを理解し、活用することで効率的なコードを書くための一助となれば幸いです。

# デコレータの概要

デコレータは、関数やメソッドの振る舞いを変更するための特殊な機能です。既存のコードを変更せずに機能を追加したり、コードの実行前後に特定の処理を行ったりできます。

### クロージャの概要

クロージャの理解が必要なため、先にクロージャを軽く説明します。  
クロージャは、関数の内部で定義された別の関数です。クロージャは、親関数のスコープ内の変数にアクセスできます。また、この関数の処理結果はクロージャの結果を返します。

```python
def make_multiplier(x):
    def multiplier(n):
        return x * n
    return multiplier

times_two = make_multiplier(2)
print(times_two(3))  # 6
```

### デコレータの基本構造

デコレータは、関数を引数に取り、別の関数を返す関数です。以下は、デコレータの基本的な構造です。

```python
def my_decorator(func):
    def wrapper():
        # 関数実行前にやりたいこと
        result = func()
        # 関数実行後にやりたいこと
        return result
    return wrapper
```

デコレータは、関数の定義の前に`@`記号とともに記述することで適用できます。

```python
@my_decorator
def greet():
    return "Hello, World!"

print(greet())  # デコレートされたgreet関数が実行される
```

## デコレータを使う理由

### コードの再利用

デコレータを使うことで、同じ機能を持つコードを複数の関数に適用することができます。これにより、コードの重複を減らし、保守性を向上させることができます。

### コードの読みやすさ

デコレータを使うことで、関数の本質的な機能と、その周辺的な機能（例: ロギング、認証など）を分離できます。これにより、コードの可読性が向上し、理解しやすくなります。

# デコレータの具体的な使用例

## タイミング測定デコレータ

関数の実行時間を計測するデコレータです。関数のパフォーマンスを簡単に確認できます。

```python
import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} は実行に {end_time - start_time:.2f} 秒かかりました")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)
    return "終了"

print(slow_function())

#slow_function は実行に 2.00 秒かかりました
#終了
```

## ロギングデコレータ

関数の呼び出しと結果をログに記録するデコレータです。

```python
import logging

def logging_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Calling {func.__name__} with arguments {args} and {kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"{func.__name__} returned {result}")
        return result
    return wrapper

@logging_decorator
def greet(name):
    return f"Hello, {name}!"

print(greet("Alice"))
```

## アクセス制御デコレータ

特定の条件を満たしている場合にのみ、関数を実行できるようにするデコレータです。

```python
def admin_required(func):
    def wrapper(*args, **kwargs):
        user = kwargs.get("user")
        if user and user.get("is_admin"):
            return func(*args, **kwargs)
        else:
            return "アクセスは拒否されました"

    return wrapper

@admin_required
def view_secret_data(user):
    return f"ユーザー {user['name']} は秘密情報を閲覧しています"

admin_user = {"name": "Alice", "is_admin": True}
regular_user = {"name": "Bob", "is_admin": False}

print(view_secret_data(user=admin_user))
print(view_secret_data(user=regular_user))

#ユーザー Alice は秘密情報を閲覧しています
#アクセスは拒否されました

```

# まとめ

デコレータを使うことで、コードの再利用性や可読性を向上させ、効率的なコードを書くことができます。また、複数のデコレータを組み合わせることで、さまざまな機能を簡単に追加できます。
論文まとめ：RandECG: Data Augmentation for Deep Neural Network based ECG classification

# はじめに
第３５回人工知能学会全国大会で発表された以下の論文
[1] Naoki Nonaka, Jun Seita, RandECG: Data Augmentation for Deep Neural Network based ECG . The 35th Annual Conference of the Japanese Society for Artificial Intelligence, 2021.
https://www.jstage.jst.go.jp/article/pjsai/JSAI2021/0/JSAI2021_2N1IS2a02/_pdf/-char/ja
のまとめ

# 概要
- ECG dataに対するaugmentationの研究
- 種々の data augmentation を加えた結果、心房細動の分類タスクでaccuracyが3.51%改善した

# 背景
- Deep Learningを使う場合、データセットが足りてなければdata augmentationが重要だが、ECG data に対するdata augmentationはこれまで研究されてなかった
- vsion系はもちろん、speech recognition 系の augmentation もそのままでは使えないので、今回種々のaugmentation手法を実験して効果を検証した


# 実験の設定
## dataset
1. PhysioNet / Computing in Cardiology Challenge 2017 dataset
https://physionet.org/content/challenge-2017/1.0.0/
（下の方にdatasetのリンクがある）

2. The China Physiological Signal Challenge 2018 dataset
http://2018.icbeb.org/Challenge.html
（入手方法は未調査）

## ネットワークのアーキテクチャ
以下のような1dの単純なResNet構造。

![スクリーンショット 2023-04-15 21.49.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/a74c989a-23b2-2aae-3ce2-43aeb187a936.png)

## メトリクス
- macro F1

# 試した data augmentation 手法
以下の図は今回試したdata augmentation 手法とそのハイパーパラメータの値（の最大値？）。

![スクリーンショット 2023-04-15 21.53.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/ba966910-2750-3e48-d5fb-be6a30e15261.png)

ここで出てくる range of magnitude 値・・・例えばscaleの[0.25,4]・・・は下記での結果図のmagnitude=20に相当するということか？<font color="blue">（このあたり詳しく書かれてないが、参照としている[2]の論文では「magnitude=10 ・・・ 角度30度に対応」などとなっていることを考えると、range of magnitudeがM=10か20だろう）</font>

# 実験結果
## PhysioNet17を用いて、各手法単独の精度を検証

以下の図で各列はaugmentationの手法、各行はmagnitude（magnitude=20が上記range of magnitudeか？）


![スクリーンショット 2023-04-15 22.27.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/8308bdc7-2601-6d36-96c8-0b655438129c.png)

本文中にも書いているが、統計的に有意なくらいに精度が改善しているのは、shiftのみとのこと。他のaugmentation単体では精度改善が微小か、あるいは悪化している。

## PhysioNet17を用いて、各手法の組み合わせで精度を検証

以下の図で、各列は採用したaugmentation手法の数、各行はmagnitude。<font color="blue">どのような組み合わせなのか、あるいはランダムに組み合わせたものを何度も試行しているのか、等不明</font>

![スクリーンショット 2023-04-18 16.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/7c1b61dc-aa57-7065-0550-6ba084df4529.png)

小さい範囲で多数のaugmentationを用いるとそれないの成果があるようだ。


# まとめと感想
## 結果を概観してのまとめ

この論文読んだだけでは不明点が多いが、以下のような点は言えるか。

1. augmentation単独ではshiftが最も効く
1. augmentationを組み合わせれば、適切な強度において精度が上がる
1. 組み合わせの数や、用いるaugmentationの中身、あるいはその強度によっては精度が悪化する

## 感想
- shiftに効果があるのは、training dataとtest dataのピーク取得法が異なる等が関係しているのだろうか？
- 本論文では行なっていないが、単独で精度の良いもので組み合わせを作れば、より精度のよいものが得られる気がする
- 精度の改善が良くても3%程度なのは、元々データが豊富にあるためか？つまりデータが少なければより大きな改善が期待できるだろうか


# reference
[2] Cubuk, E.D., Zoph, B., Shlens, J., Le, Q.V.: Ran- daugment: Practical automated data augmentation with a reduced search space. In: Proceedings of the IEEE/CVF Conference on Computer Vision and Pat- tern Recognition Workshops. pp. 702–703 (2020)
Googleデータアナリティクス：ピボットテーブルを分析に活用する

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/21a12cb1-a49a-802f-d903-6f68758eca0c.png" width="800">

# ピボットテーブルの構成要素

ピボットテーブルは、インサイトや傾向を把握するためにさまざまな方法でデータを表示できます。また、測定指標の比較や計算の実行、レポートの作成など、大規模なデータセットの分析を効率的に行い、データに関する問いの答えを見つける上でも役立ちます。 

ピボットテーブルは行、列、値、およびフィルタの 4 つの基本的な要素で構成されています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a44ffacf-a6bf-93b0-335c-7493c26ddb12.png" width="６00">

行は、選択したデータを横方向に整理、グループ化するものです。ピボットテーブルを使うの動画では、公開日のデータを用いて、年別にグループ化した行を作成しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/37b8c7db-755f-063e-6b4b-ceb655fce30f.png" width="４00">

列はデータ内の値を縦方向に整理して表示するものです。値は、データの計算や数値のカウントに使用されます。また、値の項目の中には計算フィールドがあります。計算フィールドは数式を指定し、列や行に基づいて独自の集計列を表示します。今回は、計算フィールドを作成し、測定したい変数を入力します。

前回の映画データの例では、値を使用して、興行収入の SUM、AVERAGE、および COUNT などのピボットテーブルの列を作成しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/744e0a59-0924-5e38-74b2-573a95b74792.png" width="６00">

最後に、ピボットテーブルのフィルタでは、通常のスプレッドシートと同様に、特定の条件に基 づいてフィルタを適用できます。以下では、 映画データのピボットテーブルに興行収入が1,000 万ドル未満の映画だけを表示するようにフィルタを適用しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/119b314d-ebdc-2217-cd88-9a33414293d8.png" width="６00">

ピボットテーブルエディタの 4 つの要素をすべて使用できるようになると、データからさまざまな指標を比較しながら計算を実行できるようになり、貴重なインサイトを得ることができます。

# 分析にピボットテーブルを使用する

ピボットテーブルは、データセットに関する問いに答え、その回答をステークホルダーと迅速に共有できる便利なツールです。たとえば、ある百貨店に勤務するデータアナリストが、各部門の総売上高と、それぞれの部門が販売する商品数を把握するよう依頼されたとします。また、依頼者はどの部門が最も収益を上げているかを正確に把握したいとも考えているようです。

ピボットテーブルを使用すれば、表計算ソフトの元データを変更せずに、各部門の売上高と販売した商品数を簡単に比較し、依頼主の問いに答えることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c5041107-d8b5-b81e-69bf-5d0e512b9e69.png" width="６00">

このピボットテーブルでは、部門を行として指定し、売上をグループ化して整理しています。値では、売上を SUM で集計した合計と、商品 ID を COUNTA で集計した合計を指定し、どの部門が最も収益を上げているかを判断するために、行の並べ替えを降順にしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c9a35ade-02dc-d397-1b32-6d78bc8e3a76.png" width="６00">

これで、玩具部門が最も収益を上げていることが分かりました。