OmniAICreator/Qiita-1.07M huggingface dataset:
データサイエンティスト検定リテラシーレベルの合格の流れ

## 概要

先日受験したデータサイエンティスト検定に無事合格できたことが分かったのでその時の流れをまとめていきます。
(前回までのDockerなどとは流れを変えてます)

## 前提条件など

* 経歴などは[こちら](https://qiita.com/dmikita/items/93a3d93ac91fb3c58641)の記事を参照
* [こちら](https://www.oreilly.co.jp/books/9784873117584/)の本などは読んでましたが実務的なところは実施していません。(大学などでは化学を専攻していたため計算等は一部やったことはありますが・・・)

## 資格取得のきっかけ
* [こちら](https://www.youtube.com/watch?v=J8yZ0YCKCn4)のAlciaさんの生放送を視聴してせっかくだから受けてみようかなと
* データサイエンティストの仕事には興味があったけどまだ実務的なところはやれていないから能力を試すのにもいいかなと

## 勉強方法

1. ↑のAlciaさんの放送でまとめていた[ページ](https://note.com/aicia_solid/n/n8df1b1ff04fc)を参考に必要な情報を確認。
1. [公式ページ](https://www.datascientist.or.jp/dskentei/)の問題を確認
1. [公式リファレンスブック](https://gihyo.jp/book/2021/978-4-297-12261-4)を勉強
    * 本の中で紹介されている[こちら](http://www.mi.u-tokyo.ac.jp/consortium/e-learning.html)はなかなかボリュームが多くすべては見切れませんでした

* 以上の内容を1か月ほど(8/30に受験した AWS ソリューションアーキテクトプロフェッショナルの試験の後から)実施しました。
* 元から機械学習について勉強をしていたのである程度は知っている内容でしたが、計算の部分などは参考書を参考に再確認を行いました。
* またデータの見方(グラフのスケールなど)も問題として出てくるのでここでの内容をもとにテレビなどでグラフを見るとなかなか面白いことになります

## 最後に
* リテラシーレベルなので問題はそれほど難しくなく参考書+αを少しで何とかなりそうです。
* 私の場合数学の部分が15年以上やっていない部分だったのでそこの計算のやり方などを思い出すのにてこずりました。
* 逆にエンジニアリングの部分は普通にSQLを使っている人なら問題なくとける問題でした。
* 9月のが初だったので今後変わっていくかもしれませんが興味のある方は受けてみることをお勧めします。
メールのエンコード/デコード方式

### はじめに

先日メールファイルの読み込みと処理を行うプログラムのソースコードを読む機会がありました。
その際、メールのエンコード方式について学ぶ必要があったので、今回まとめてみました。

### 8bitから7bitへ
人間にとって読み取り可能なテキストを通信機器でやりとりできるようにするためには、データ形式の変換を行う必要があります。

エンコードといえば、文字化けの対処法としてエンコード方式や文字コードを変更する、というのは一般的に馴染みがあると思います。

代表的な文字コードであるutf-8やISO-2022-JPは、それぞれ膨大な文字集合に含まれるコードポイントという番号を使って特定の文字を暗号化し、コンピューターでの処理を可能にするための変換方式です。

それとは別に、メールにはメール特有のエンコードが行われています。

メールはSMTPという専用のプロトコルでやりとりされていますが、
デフォルトでサポートされているのは7bitで表現できるASCII文字（半角ローマ字や数字等）のみとなっています。
電子メールは当初、主に英語で書かれたテキストのやりとりを想定していたからです。

日本語や中国語のようにローマ字と比較にならないほど情報量が多く、7bitでは表現できないような文字集合を使って書かれたテキストデータを損なうことなく着実に通信を行うためには、7bitへ変換する必要があります。

こうしたエンコードの情報は、メールヘッダー内で以下のように表示されます。

```
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
```
それぞれ順に見ていきます。
#### Content-Type
テキストメール、HTMLメール、添付ファイルのあるメール等の種類を指定します。
今回の例のようにtext/plainとなっている場合は、文字化けが起きないように、テキストがどのような文字集合で記述されているのか明示する必要があります。
上の例では、文字セットにutf-8が指定されています。
#### Content-Transfer-Encoding
メールのデータをSMTPプロトコルで送信できるような形に変換する際のエンコード方式を指定します。
よく使われるものには、quoted-printableや、画像や音声データをSMTP用に変換するbase64等があります。
### Pythonライブラリを使ったencode/decode
quoted-printableは非ASCII文字で表現されたテキストデータを7bitすなわちASCII文字で表現するためのエンコード方式です。
テキストに含まれる文字の、指定されたエンコード方式におけるコードポイントの16進数表記の前に半角イコール「=」をつけます。
例えば、

```
=E3=81=8F=E3=82=8D=E3=82=8A=E3=81=AF=E5=A4=A7=E3=81=8D=E3=81=AA=E7=8C=AB=
=E3=81=A7=E3=81=99=E3=80=82
```
こんなふうになります。
何と書いてあるでしょうか？Pythonのquopriモジュールを使ってutf-8に変換してみましょう。

```python
import quopri

# quoted-printableでエンコードされたASCII文字列
encoded_bytes = "=E3=81=8F=E3=82=8D=E3=82=8A=E3=81=AF=E5=A4=A7=E3=81=8D=E3=81=AA=E7=8C=AB=\
=E3=81=A7=E3=81=99=E3=80=82"

# quoted-printableでデコードし、Bytes型オブジェクトを出力
decoded_bytes = quopri.decodestring(encoded_bytes)
print(decoded_bytes)

# '\x'は16進数のエスケープ表現
# b'\xe3\x81\x8f\xe3\x82\x8d\xe3\x82\x8a\xe3\x81\xaf\xe5\xa4\xa7\xe3\x81\x8d\xe3\x81\xaa\xe7\x8c\xab\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82'

# 出力したBytes型オブジェクトをutf-8でデコードし、文字列を出力
decoded_str = decoded_bytes.decode('utf-8')
print(decoded_str)

# くろりは大きな猫です。
```

ちなみにASCII文字は元々7bitで表現されるため、変換されません。
ローマ字で構成される言語の場合、アクセントがついた母音等の特殊文字のみ変換が行われます。

```python
import quopri

# フランス語の文字列
str = "Les chaussettes de l’archiduchesse, sont-elles sèches? Archi-sèches."

# utf-8でエンコードし、Bytes型オブジェクトを出力
encoded_str = str.encode('utf-8')
print(encoded_str)

# b'Les chaussettes de l\xe2\x80\x99archiduchesse, sont-elles s\xc3\xa8ches? Archi-s\xc3\xa8ches.'

# quoted-printableでエンコードし、Bytes型オブジェクトを出力
encoded_bytes = quopri.encodestring(encoded_str)
print(encoded_bytes)

# b'Les chaussettes de l=E2=80=99archiduchesse, sont-elles s=C3=A8ches? Archi-s=\n=C3=A8ches.'
```

16進数の「e3」や「80」を、「=E3」や「=80」のような形に変換しているのがわかると思います。

以下、参考になりました。

https://stackoverflow.com/questions/25710599/content-transfer-encoding-7bit-or-8-bit
PHPで配列を使ってみましょう！

#配列について
<br>
PHPの配列を操作していきます！

以下の $scores に 1, 2, 3 の値を代入したいとします。

配列は[ ]で囲って、 , で区切ります。
<br>

```php:index.php

<?php
$scores = [1, 2, 3];

echo $scores[2] . PHP_EOL;
```

<br>
以下をターミナルで実行します！
<br>

```
~$ php index.php
```

<br>
$scores の [ 2 ] の要素が出力されました！
<br>

```
~ $ php index.php
3
~ $ 
```
<br>
インデックス番号は 0 から始まるので、

0番目→1
1番目→2
2番目→3

と表示されます！
なので $scores [ 2 ] は 3 が表示されました！


<br>
配列を置き換える時にもインデックス番号を使います。
$scores[ 2 ] を８に置き換えてみます。
<br>

```php:index.php
<?php
$scores = [1, 2, 3];

$scores[2] = 8;
echo $scores[2] . PHP_EOL;
```

<br>
ターミナルで以下を実行します...
<br>

```
~$ php index.php
```

<br>
置き換わりました！
<br>

```
~ $ php index.php
8
~ $ 
```
Java 文字列を1文字ずつ表示


#文字列を1文字ずつ表示

charAtを使うことで一文字ずつ表示することができます。

```
変数名.charAt(index)
```

```java:Test.java
public class Test{
     
    public static void main(String[] args) {
        String s = "ありがとう";
        for(int i=0; i<s.length(); i++) {
	        System.out.print(s.charAt(i) + "/");
        }
    }
}
```

＊for文の条件について
　i=0　　　　　　　　番号が0スタート
　i<変数名.length　　　lengthは文字の数
　　　　　　　　　　　ありがとうは５文字なので5未満の間ループする
　i++　　　　　　　　 ループするときに番号が１ずつ増える


```:出力
あ/り/が/と/う/
```

#指定した文字だけ表示

indexの部分に取得したい文字の番号を入力することで表示できます。
＊番号は０から始まるので注意する。

```java:Test.java
public class Test {
   
    public static void main(String[] args) {
		String s = "ありがとう";
        System.out.print(s.charAt(3));
	}
}
```

```:出力
と
```
【Windows10】Cドライブを別のSSDへ移行

Windows10のOSの入ったSSD（120GB）の残容量がひっ迫してきたため、500GBのSSDへ移行（クローン/マイグレーション）しました。今回使用したツールは「Acronis True Image WD Edition」（無料）です。特に詰まることもなくすんなり移行できましたが、このツールに関する記事があまり見当たらず、せっかくなので備忘録として手順などを簡単に記載しておきます。

# はじめに
### 使用したツール
- ツール名：　Acronis True Image WD Edition
- ダウンロードサイト：　https://kb-jp.sandisk.com/app/answers/detail/a_id/21567/kw/クローン  ※左記のサイトから「ATI2020WD_28080.zip」をダウンロード
- 使用条件：　上記サイトによれば、このツールのクローン機能を使用するためには、コピー元またはコピー先のSSD/HDDの少なくとも1つはWD製またはSanDisk製である必要があるとのことです。
- 選定理由：　無料で使えるため。（同様の有名どころのツールとしては「EaseUS Todo Backup」等がありますが、最近のバージョンからクローン機能は有料版でしか使えなくなったようです）

### 試した環境
●PCストレージ構成：
　デスクトップPC
　　├ ①SSD（Transcend/120GB/TS120GSSD220S）
　　│　 ⇒ ストレージ内の全て（Cドライブ/OS）がクローン対象
　　├ ②HDD（Western Digital/WD10EZEX）　※データ用ストレージとして使用
　　│　 ⇒ 今回のクローン作業の対象外
　　└ ③SSD（Western Digital/500GB/WDS500G2B0A）
　　　 ⇒ ①のクローン先のストレージ
●OS：　Windows 10 Pro（21H1）

### 参考元
SSDやHDDのデータを無料で移行できるツールが下記サイトに色々記載されており、今回使用した「Acronis True Image WD Edition」もこちらで存在を知りました。
https://fortune-ongakko.com/ssd-hdd-clonedrive/

# やったこと
1. クローン先のSSDをマザーボードにSATAケーブルで接続し、PCの電源をON
1. デスクトップ画面起動後、スタートメニューの「Windows システムツール」⇒「PC」を右クリック⇒「管理」からコンピュータの管理画面を開く
1. 管理画面の左側のツリーから「記憶域」⇒「ディスクの管理」をクリックし、手順1で接続したSSDにボリュームを割り当て、ドライブとして使用できるようにする（確か画面下の当該SSD上で右クリックしてフォーマットすればいけたかと）。完了後、管理画面を閉じる。
1. 「Acronis True Image WD Edition」を起動し、「ディスクのクローン作成」をクリック
1. 「自動」を選択した状態で「次へ」をクリック
1. ドライブの一覧の中から、クローン元のSSDを選択し、「次へ」をクリック
1. 　　　　　　〃　　　　　　　　　先　　　　〃　　　「次へ」をクリック
1. クローン元と先のドライブが正しく選択されているのを確認した上で「実行」をクリックし、クローン開始（20分程度でコピー完了したかと思います）。完了後、Cドライブのデータが正しくコピーされているかどうかをエクスプローラー上で確認する。
1. PCの電源をOFF
1. クローン"元"のSSDのSATAケーブルをマザーボードから外した後、再度PCの電源をON（このタイミングでクローン先のSSDがCドライブとして自動的に割り当てられる）
1. クローン先のSSD内のOSが無事起動したら、作業完了　

 ※OSが起動しない場合は、BIOS画面を開き、クローン先のSSDがブート用ドライブ（Windows Boot Manager）として正しく設定されているかどうかを確認しましょう。
[Tips] エクスプローラーからWindows Terminalを立ち上げる方法

# はじめに
いつもWindows Terminalを使う際に、
「スタートメニューからWindows Terminalを立ち上げる」⇒「作業する場所に移動する」
という作業が面倒くさかったので、エクスプローラーから直で立ち上げる方法を調べました

# エクスプローラーからWindows Terminalを立ち上げる方法
## 事前設定
- 【方法】Windows Terminal内の各シェルの設定で開始ディレクトリの項目の[親プロセスディレクトリの仕様]に✅を入れる(この作業はシェル毎に設定してください） 
    - これを行うことで、開く場所が上書きされるのを防ぎます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/887a4e29-27a1-37ee-6114-18a7e2efecf2.png)


## 基本編
- 【方法】開きたい場所に移動後、エクスプローラーのアドレスバーで **`wt`** を実行

1. まずエクスプローラーで開きたい場所に移動します（今回は`C:\tmp`）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/f6237425-6205-32ae-e098-22bd2164ddc4.png)

1. アドレスバーにコマンドを入力してエンターを押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/c4d86266-dc8e-45b5-e43a-8d9d663db7c2.png)
3. デフォルトのシェルでWindows Terminalが立ち上がります（私はCore版PowerShellを既定にしているのでそれが立ち上がりました）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/90fa7d00-c99b-cd89-f88e-7910845e6a3e.png)



## wsl編
- 【方法】開きたい場所に移動後、エクスプローラーのアドレスバーで **`wt wsl`** を実行

```
wt wsl
```

- 事前にwslの有効化とディストリビューションのインストールを行う必要があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/df6568cf-c504-8ba7-e13c-4de333e2ba18.png)


## Core版PowerShell編
- 【方法】開きたい場所に移動後、エクスプローラーのアドレスバーで **`wt pwsh`** を実行
    - Core版PowerShellは事前にインストールしておく必要があります

## Desktop版PowerShell編
- 【方法】開きたい場所に移動後、エクスプローラーのアドレスバーで **`wt powershell`** を実行


## コマンドプロンプト編
- 【方法】開きたい場所に移動後、エクスプローラーのアドレスバーで **`wt cmd`** を実行

# もっと簡単に立ち上げる方法
デフォルトのターミナルをWindows Terminalにしてしまえば`wt`を入力しなくても（`pwsh`や`wsl`だけ等）Windows Terminalでシェルを立ち上げることができます

1. Windows Terminalの[設定]->[スタートメニュー]を開き[既定のターミナルアプリケーション]を確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/645ecd8c-9641-03c7-2665-feb2930d8eb9.png)

2. [既定のターミナルアプリケーション]をWindows Terminalに変更し、ウィンドウ下の[保存]ボタンをクリックしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/fd53caaf-b831-ca25-fe35-26e4fa813ec5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/5496a5e3-17cb-481b-3245-9b55744f907a.png)

この場合、エクスプローラーだけでなくスタートメニューなどからpwshやwsl等を立ち上げてもちゃんとWindows Terminalで開くようになるので、完全にWindows Terminalに移行したい人向けの設定です

# まとめ
エクスプローラーからpwshやcmdを立ち上げる方法は知っていたのですが、Windowws Terminalだけが分かっていなかったので今回分かってすっきりしました。

また、これを機にデフォルトのターミナルをWindows Terminalに移行したので、これからはかなり快適に使えそうです

同じようにターミナルの立ち上げを面倒くさいと感じている方がいらっしゃったら
参考にしてもらえれば幸いです
サクラエディタの置き換えで使える正規表現

サクラエディタは、フリーソフトなこともあり、多くの現場で使用されています。
私もログ解析やExcel資料作成時にサクラエディタを使うことがあります。
今回は、より実務で使えるように、具体的に「置換前」「置換後」で指定する文字を明記して、コピペで使えるようにまとめました。
改行コードは「\r\n」で表現していますが、必要に応じて読み替えてください。

## Eから始まる5桁のエラーコードがない行を削除（エラー行だけ残す）
:::note info
ログのうちエラー文だけを抜き出せるので、エラー件数とエラー概要の取得に重宝します。
:::
| 置換前 | 置換後 |
|:-:|:-:|
|^(?!.*E¥d¥d¥d¥d¥d).\*\r\n||
### 置換前テキスト
>2024-01-01 10:00:00 [I00001] 情報：あああああ
2024-01-01 12:00:00 [E20001] エラー：いいいいい

### 置換後テキスト
>2024-01-01 12:00:00 [E20001] エラー：いいいいい

# 複数のタブを１つのタブに置換
:::note info
Excel方眼紙の資料をコピペで利用する際に重宝します。
:::
| 置換前 | 置換後 |
|:-:|:-:|
|\t+|\t|
### 置換前テキスト
>ああ	　　　　　いい	　　　　うう

### 置換後テキスト
>ああ	いい	うう

# キーワードが含まれる行を削除

| 置換前 | 置換後 |
|:-:|:-:|
|^.\*キーワード.\*\r\n|   |

### 置換前テキスト
>ああああああああああ
いいキーワードいいい
うううううううううう

### 置換後テキスト
>ああああああああああ
うううううううううう

# キーワードが含まれない行を削除
:::note info
ログから特定のキーワードのみを抜き出す場合に重宝します。
:::
| 置換前 | 置換後 |
|:-:|:-:|
|^(?!.\*キーワード).\*\r\n|   |

### 置換前テキスト
>ああああああああああ
いいキーワードいいい
うううううううううう

### 置換後テキスト
>いいキーワードいいい

# 空白行を削除
:::note info
空白行を詰めたい場合に、空白行を削除できます。
:::
| 置換前 | 置換後 |
|:-:|:-:|
|^\r\n|   |

### 置換前テキスト
>あああ
>いいい
>
>ううう

### 置換後テキスト
>あああ
>いいい
>ううう

# キーワードの文字以降を削除
| 置換前 | 置換後 |
|:-:|:-:|
|キーワード.*|   |

### 置換前テキスト
>ああああああああああああ
>いいいいキーワードううう

### 置換後テキスト
>ああああああああああああ
いいいい

# タブ区切りの1行に変換
:::note info
改行で区切られているデータを、Excelやcsvに都合のよい形式に変換する際に重宝します。
:::
| 置換前 | 置換後 |
|:-:|:-:|
|\r\n|\t|
### 置換前テキスト
>あああ
いいい
ううう

### 置換後テキスト
>あああ  いいい  ううう
【Vuetifly：Dialog】オーバーレイを押してモーダルを非表示

# オーバーレイを押してモーダルを非表示にする
VuetiflyでOverlayを押した時にモーダルを削除する方法

## 発生したエラー
dialogをtrueにしてモーダルを表示してオーバーレイを押すとエラーが発生する
![スクリーンショット 2021-11-14 19.16.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/6187684e-a1cd-ff5b-c759-7d854e1fffd6.png)

## 解決策
リファレンスに書いてある
https://vuetifyjs.com/ja/api/v-dialog/#events-click:outside

**click:outside　：　**アクティブなダイアログの外側をクリックしたときに発生するイベント

### 使い方
```
子
<v-dialog v-model="this.dialog" @click:outside="dailogStateChange">
     ~~~~~~~~~~~~~~
</v-dialog>
methods: {
  dailogStateChange() {
    this.$emit('dailogStateChange');
  },
}

親
methods: {
  dailogStateChange() {
    this.dialog = !this.dialog;
  },
}
```
または

```
<v-dialog v-model="this.dialog" @click:outside="!this.dialog">
     ~~~~~~~~~~~~~~
</v-dialog>
```
後者の方が楽ちんだけど
子では親のデータを更新できないので臨機応変に対応する
React Nativeでライトモードを強制する

# はじめに
スマートフォンがダークモードに対応してから、今ではスマホアプリでもウェブサイトでもダークモードに対応しているのが珍しくなくなりました。
私の周りではダークモードを使っている人がほとんどで、私も常時ダークモードにしています。

ただ、開発者の視点ではダークモード対応は機能として必須ではないため、個人アプリの開発や後回しにしがちだと思います。
そんなときは、端末のダークモード設定を無視し、アプリ上では常にライトモードにすることができます。

# 実装

## iOS

```objective_c
/* AppRoot/ios/AppName/AppDelegate.m */

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif

  ...

  /**
   * この3行を追加
   * iOS13以降でライトモードを強制する
   */
  if (@available(iOS 13, *)) {
    self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
  }

  return YES;
}
```

## Android

```java
/* AppRoot/android/app/src/main/java/com/AppName/MainApplication.java */

package com.AppName

// この行を追加
import androidx.appcompat.app.AppCompatDelegate;
import android.app.Application;
  ...

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
     // この行を追加
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
  }
```

## Expoの場合

app.json

```json
{
  "expo": {
    "userInterfaceStyle": "light",
  }
}
```

expo.userInterfaceStyleは一括設定なので、
下記のように個別に設定することも可能

```json
{
  "expo": {
    "userInterfaceStyle": "automatic",
    "ios": {
      "userInterfaceStyle": "light",
    }
  }
}
```
PHP関数の型の指定方法について...

#PHP型付けについて
<br>
引数や返り値に、文字列、整数値しか受け付けないように型を指定していきます！

以下の関数があったとします。
<br>

```php:index.php
<?php
function show($name, $score) {
  echo $name . ': ' . $score . PHP_EOL;
}

show('kana', 'kana');
```
<br>
 $name と $score の引数の前に型を指定していきます！

string は文字列で、

int は整数値を指定します！
<br>

```php:index.php
<?php
function show(string $name, int $score) {
  echo $name . ': ' . $score . PHP_EOL;
}

show('kana', 'kana');
```

<br>
ターミナルで以下を実行すると...
<br>

```
~$ php index.php
```

<br>
show( 'kana',  'kana' ) ; の2番目の引数に文字列が入っているのでエラーになります！

2番目の引数を整数値に変えてみます。
<br>

```php:index.php
<?php
function show(string $name, int $score) {
  echo $name . ': ' . $score . PHP_EOL;
}

show('kana', 2);
```

<br>
ターミナルで以下を実行すると...
<br>

 ```
~$ php index.php
```
<br>
ちゃんと出力されました！
<br>

```
~ $ php index.php
kana: 2
~ $ 
```


<br>
さらに強い型付けを指定するには、

declare ( strict_types = 1 ); を最初につけます。
<br>

```php:index.php
<?php

declare(strict_types=1);

function show(string $name, int $score) {
  echo $name . ': ' . $score . PHP_EOL;
}

show('kana', 2);

```

<br>
declare ( strict_types = 1 ); をつける事で厳密に型のチェックができます。
<br>
ネーミングセンスに惹かれた言葉

## はじめに

　これまでプログラミングに触れてきて、ネーミングセンスに惹かれた言葉をリストアップします。意味はググればいくらでも出てくるのでここには書きません。網羅性も無視です。

## 好きな言葉

### ヨーダ記法

　STAR WARSが生まれなかったら何になってたんだろう。

### YAML Ain't a Markup Language

　再帰性が好きです。

### パンくずリスト

　童話から持ってくるなんて惹かれちゃいます。

### ハンバーガーメニュー

　とにかくイメージしやすい。

### camelCase / snake_case

　これもイメージしやすい。動物が好きなので他のcaseよりもこの2つが特に好きです。

### EC2 / S3

　いつ見ても声に出したくなっちゃいます。

### i18n
　
　これ系好きです。_numeronym_ っていうんですね。

### DRY原則

　違反したら _"WET"_ というセンスに痺れました。


## おわりに

　よく使うもの、目にするもので挙げました。ググると他にも面白いのたくさん出てきますね。私もいつか生み出せるようにセンスを磨いていきたいです。
再現率？適合率？　混同行例を使った評価指標

機械学習の勉強をしていて、2値分類タスクを行う際の評価指標で混乱したので
備忘録として自分でまとめてみました。

##混合行列（confusion matrix）とは
　学習アルゴリズムの性能を明らかにする行列。
　以下の4パターンがあり、図にすると分かりやすい。

- TP（True Positive）：
<br>
実際のクラス：Positive、予測したクラス：Positive
- FP（False Positive）：
<br>
実際のクラス：Negative、予測したクラス：Positive
- TN（True Negative）：
<br>
実際のクラス：Negative、予測したクラス：Negative
- FN（False Negative）：
<br>
実際のクラス：Positive、予測したクラス：Negative

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/798953/906c09aa-c4da-d1eb-4d55-d530b39d08fb.png" width="480">


##様々な評価指標
- 正答率（accuracy）
正確に予測したものを全てのサンプルで割ったもの。精度ともいう。
$$
accuracy = \frac{TP + TN}{TP + TN + FP + FN}
$$

- 適合率（precision）
陽性であると予測されたもののうち、実際に陽性であったものの割合。
陽性的中率（positive predictive value）ともいう。
$$
precision = \frac{TP}{TP + FP}
$$ 

- 再現率（recall）
実際の陽性サンプルのうち、陽性と予測できたものの割合。
感度（sensitivity）、ヒット率（hit rete）、真陽性率（true positive rate）ともいう。
$$
recall = \frac{TP}{TP + FN}
$$ 

- f-値（f-measure）
適合率を上げるためには、真であることが最も確信できる1つのデータのみ陽性と予測し、その他を全て陰性とすればよい。
その場合、適合率は100%となってしまう。<br>
また、再現率を上げるためには、全てのサンプルを陽性と予測すればよい。
その場合、再現率は100%となる。<br>
このように、適合率と再現率はトレードオフの関係にある。
これら2つをまとめたものがf-値（f-measure）であり、適合率と再現率のバランスをとった評価指標である。
f-値は適合率と再現率の調和平均である。
F1スコア（F1-score）ともいう。

$$
F = 2 \div (\frac{1}{precision} + \frac{1}{recall}) \\\
= 2 \times \frac{precision \times recall}{precision + recall}
$$

###参考書籍
- [Pythonではじめる機械学習――scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎](https://www.oreilly.co.jp/books/9784873117980/)
- [［第3版］Python機械学習プログラミング 達人データサイエンティストによる理論と実践](https://book.impress.co.jp/books/1120101017)
イージング(Easing)を自由に比較できるものを作った話

#初めに
DOTweenでUIアニメーションの勉強をやり始めようとしたときにEasingで躓いたため、ネットで探したところGifや動画などにまとまっているだけでもっと詳細に比較したいと思い、これを作りました。自分と同じようなDOTweenをやり始めた人に使ってほしいと思ってます。
#コンテンツ
![easingicon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/56558ec5-49dc-59b5-2c8a-013511d94073.png)
リンク
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

[EasingComparison (UnityRoom)](https://unityroom.com/games/easingcomparison)

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

#操作説明
右にあるドロップダウンから好きなEasingを選択して比較して下さい。
右下のスライダーで時間を遅くできます。
ボタンを押すことで実際に押したときのアニメーションの比較もできます。

#紹介文
Easing(イージング)をパッと比較できるものです！
イージングが最初よくわからなくてこんなのあったら便利だなっていう思いつきで作りました！
TypeScriptでSpeechRecognitionの型をきちんと書く

TypeScript初心者の@akkadaskaです。
Web Speech APIというものを知り、これを使えば手軽に音声認識が使える！と思い触ってみましたが、TypeScriptでSpeechRecognition(webkitSpeechRecognition)の型が定義されていませんでした。
少し調べると`any`で解決する方法はいくつか出てきましたが、せっかくなのでTypeScriptの練習も兼ねてきちんとSpeechRecognitionの型定義を書いてみることにしました。
当方初心者ですので、間違いがあれば指摘していただけるとうれしいです！
#SpeechRecognitionの型定義を書く
まずは[MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/SpeechRecognition)を参考に、SpeechRecognition(webkitSpeechRecognition)のプロパティ、イベントハンドラ、メソッドの型を、インターフェース`ISpeechRecognition`に定義しました。
`grammars`や`lang`の型は、ここでは`string`にしましたが、もうすこし厳格に定義可能かもしれません。
`ISpeechRecognitionEvent`はどうも仕様書(MDN Docs)とGoogle Chromeでの結果が異なるようなので、使いそうなもののみ記載しています。別途必要な定義がある場合は追加するか、`any`を使う必要があるかもしれません。

```typescript:i-speech-recognition.ts
interface ISpeechRecognitionEvent {
  isTrusted?: boolean;
  results: {
    isFinal: boolean;
    [key: number]:
      | undefined
      | {
          transcript: string;
        };
  }[];
}

interface ISpeechRecognition extends EventTarget {
  // properties
  grammars: string;
  lang: string;
  continuous: boolean;
  interimResults: boolean;
  maxAlternatives: number;
  serviceURI: string;

  // event handlers
  onaudiostart: () => void;
  onaudioend: () => void;
  onend: () => void;
  onerror: () => void;
  onnomatch: () => void;
  onresult: (event: ISpeechRecognitionEvent) => void;
  onsoundstart: () => void;
  onsoundend: () => void;
  onspeechstart: () => void;
  onspeechend: () => void;
  onstart: () => void;

  // methods
  abort(): void;
  start(): void;
  stop(): void;
}

export default ISpeechRecognition;
```

#windowの型にSpeechRecognitionを追加する
デフォルトのTypeScriptでは`window`の型に`SpeechRecognition`や`webkitSpeechRecognition`が定義されてないので、これらを追加した新しい`window`の型定義`IWindow`を書きました。

```typescript:i-window.ts
import ISpeechRecognition from './i-speech-recognition';

// ISpeechRecognitionConstructorはコンストラクト可能でコンストラクトするとISpeechRecognitionの型定義を持つ
interface ISpeechRecognitionConstructor {
  new (): ISpeechRecognition;
}

//windowにISpeechRecognitionConstructorを定義にもつSpeechRecognitionとwebkitSpeechRecognitionを追加
interface IWindow extends Window {
  SpeechRecognition: ISpeechRecognitionConstructor;
  webkitSpeechRecognition: ISpeechRecognitionConstructor;
}

export default IWindow;
```

#作った型定義を使ってSpeechRecognitionを利用する
実際にSpeechRecognitionを使う場面では、`window`の型定義を先程作成した新しい定義である`IWindow`にしてあげます。

```typescript:sample.ts
import IWindow from './i-window';

// windowの型定義にIWindowを使う
declare const window: IWindow;

// 型定義はISpeechRecognitionConstructor
const Recognition = window.webkitSpeechRecognition || window.SpeechRecognition;

// 型定義はISpeechRecognition
const recognition = new Recognition();

// 補完・型チェックができる！
recognition.lang = 'ja-JP';
recognition.interimResults = true;
recognition.continuous = true;

```
これで、無事にTypeScript環境でSpeechRecognitionが使えるようになりました。
しかも、`any`を使っていないので、TypeScriptのメリットを生かすことができます！
#まとめ
このように、SpeechRecognitionの型定義を書いて、それを含む新しい`window`の定義を適用することで、TypeScript環境下でもSpeechRecognitionを利用することができるようになります。
余談ですが、`ISpeechRecognition`のコードを書いているときにGitHub Copilotがものすごく適切なサジェストをしてくれたので、もっとよく調べれば、もしかしたら偉い人が書いたもっと良いコードが出てきたのかもしれません。ですが、ここでは練習のために自作してみました。
間違い、改善点などがあればぜひ指摘してください！
Qiitaを始めた理由



#はじめに
Qiitaの初投稿の記事です。自分自身のスキルアップや研究の中で疑問となった事柄を調べるために散々お世話になってきたQiitaですが、この度引き続き自己研鑽に励むためにこのQiitaのアカウント登録に踏み込みました。

この投稿は初回ということで、何故Qiitaの初投稿に至ったのかその理由を書いていきたいと思います。

###1.情報のインプットに使える
記事の検索のためだけにQiitaを用いるのであれば特にアカウント登録は必要ありませんが、アカウントの登録を行うことで以下のような機能を使えるメリットがあります。

- 限定共有投稿 : URLを知っているユーザーのみアクセスでき、Googleの検索でも表示されなくなる機能
-  フォロー機能 : 気になるユーザーをフォローすることで簡単に興味を持つ内容の分野の情報を収集できる機能
-  トレンド・マイルストーン : 人気の記事や話題の記事を一覧として閲覧できる機能
-  ストック機能 : 気に入った記事や後に読みたい記事を一覧として表示できる機能

このほかにもアカウントの登録を行うことで使える機能が多々あります。このようにQiitaでは様々な便利な機能がありますので、情報のインプットを行うために効率が良く、役に立つと考えます。


###2.情報のアウトプットに使える
情報のアウトプットを行うことで以下のようなメリットがあると考えられます。

- 知識の定着化 : 自分が日常的に得た知識をアウトプットするためにはまずその知識を整理して書きます。その情報がしっかりと正しいものであるか、また情報を他者にも分かりやすく伝えることができるのかを考えることができますので、その過程の中で効率よく知識の定着ができると考えられます。
- アウトプットのスピード向上 : アウトプットを重ねていく中で情報の整理が早くなり、また他者に情報を正しく伝えられるようになります。結果としてアウトプットのスピードの向上に役に立つことが考えられます。
- 他者のフィードバックを得ることができる : 他者からフィードバックを得られることでまず新たな発見をすることができ、また自らの間違いにも気づくことができると考えられます。

このように日々インプットしたものを定期的にアウトプットすることで自身の糧にしていきたいと思っています。


###3.単純に備忘録として使える
クラウドに保存でき、記事として公開できるために強力な備忘録置き場として使えます。自分が昔書いた記事を振り返ってみて「ここあんまり良くない」と評価してもいいですし、自らに対する新しい発見のきっかけになればと思っています。

#最後に
拙い文章ではありますが、Qiitaの最初の記事として書かせていただきました。こうやって記事を書く中で、そもそもQiitaの方式であるMarkdown記法についてまだまだ分からないところもありますので、次回あたりは記事の書き方についてと注意点についてまとめてみようと思います。
Adobe Reader の MSI インストーラを作ってみる(作成中)

#イントロダクション
Adobe Reader は、現在 msi ファイル形式で配布されていません。しかし、Intune で Windows PC にアプリケーションを展開するには、msi 形式が一番簡単であることから最新版のパッチが含まれる msi ファイルを作れないか検討してみました。

#作成方針
Adobe Reader の exe ファイルを展開すると msi ファイルと パッチファイルである msp ファイルが入っていますので、このファイルと Windows 開発者ツールにある展開ツールを活用して msi ファイルを作成します。

#参考サイト
* https://stealthpuppy.com/deploy-adobe-reader-dc-microsoft-intune-part1/
* http://rogersau.blogspot.com/2012/03/msp-to-msi-office-communicator.html
* https://malinaservices.com/blog/merging-cab-inside-msi/
* https://docs.microsoft.com/en-us/windows/win32/msi/windows-installer-development-tools

#作成手順(作成中)
1. Adobe Reader の実行ファイルをダウンロード https://get.adobe.com/jp/reader/enterprise/
+ exe ファイルを 7zip などで解凍(c:\data) 
+ msi ファイルを展開 msiexec /a "AcroRead.msi" TARGETDIR="C:\out"
+ パッチファイルを展開 msiexec /a "C:\out\AcroRead.msi" /p "AcroRdrDCUpd2100720099.msp" TARGETDIR="C:\out" /qb
+ cab ファイルを作成 wimakcab.vbs "C:\out\AcroRead.msi" Data1 /R /L /C /U /E /S
+ cab ファイルを msi にマージ msidb.exe" -d "C:\out\AcroRead.msi" -a "Data1.cab"
+ orca で msi ファイルのMedia Table Cabinet属性が #Data1.cab になっていることを確認
+ Adobe Customization Wizard DC で msi をカスタマイズ

#確認済み事項
* Intune 指示による展開

#未確認事項
* アプリの更新が可能か
* Intune 指示によるアプリのアンインストール
uWSGIで.envの値をまとめて環境変数として渡す方法とハマリポイント

# 概要

[uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/index.html)は、例えばWebサーバであるNginxとアプリケーションであるFlaskの仲立ちをしてくれるサーバです。
.envはいろいろな用途がありますが、ここではその環境に必要な環境変数を記載しておくファイルとして扱います。

そこで2つを合わせて、**uWSGIから.envを読み込んでアプリケーションに環境変数をまとめて渡したい！**というシチュエーションがありえます。もちろん、アプリケーション側から直接.envを読み込む方法もあるでしょう。今回は、前者のやり方と自分がハマったポイントを紹介します。

# 環境

- uWSGI 2.0.20

# .envを使わない場合

```ini:hoge.ini
[uwsgi]
env = MY_SECRET_KEY_1=mysecretkey1
env = MY_SECRET_KEY_2=mysecretkey2
```

[env](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#env)を使うことで、アプリケーションに環境変数`MY_SECRET_KEY_1`と`MY_SECRET_KEY_2`を渡せます。

しかし、たくさんあるときは1つ1つ書くのは大変です。


# .envを使ってまとめて読み込む

```sh:.env
MY_SECRET_KEY_1=mysecretkey1
MY_SECRET_KEY_2=mysecretkey2
```


```ini:hoge.ini
[uwsgi]
for-readline = path/to/.env
  env = %(_)
endfor = 
```

.envには、アプリケーションに読み込ませたい環境変数を記述しておきます。そして、[for-readline](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#for-readline)で.envファイルを読み込み、1行ずつenvします。`path/to/.env`のところにはワーキングディレクトリからの相対パスか絶対パスを指定します。

# .envの場所を変数として渡したい

ここからがハマリポイント。結論は、**for-readlineにプレースホルダを使ってはいけない**、です。

プレースホルダとはuWSGIにおける変数で、プレースホルダを介してfor-readlineに.envのパスを渡したいと考えるわけです。自分もそうでした。


```ini:hoge.ini
[uwsgi]
project_root = /path/to/project

for-readline = %(project_root)/.env
  env = %(_)
endfor = 
```

プレースホルダはコマンドライン引数からも指定できます。

```sh
sudo uwsgi  --set-placeholder project_root=/path/to/project --ini hoge.ini
```

残念ながら、これはうまく動きません。.envファイルが存在しないというエラーが出てしまいます。

```
[uWSGI] getting INI configuration from /path/to/hoge.ini
open("%(project_root)/.env"): No such file or directory [core/config.c line 96]
```

githubにissueが立っており、おそらくバグのようです。長らく放置気味です。自分は諦めて相対パスを使いました。

https://github.com/unbit/uwsgi/issues/1046


githubの全体検索で、他の方達がどうfor-readlineをつかっているかがわかります。
https://github.com/search?p=2&q=for-readline&type=Code



# 参考

https://github.com/unbit/uwsgi/issues/629#issuecomment-43303330
Splunk: statsとevalの使い分け

時々微妙に迷うのでメモ。

###### 実施環境： Splunk Free 8.2.2

Splunkには eval と stats という2つのコマンドがあり、 eval は[評価関数(Evaluation functions)] (https://docs.splunk.com/Documentation/Splunk/8.2.2/SearchReference/CommonEvalFunctions)、 stats は[統計関数(Statistical and charting functions)] (https://docs.splunk.com/Documentation/Splunk/8.2.2/SearchReference/CommonStatsFunctions)を使用することができます。
この2つは全く別物ではありますが、一見似たような処理を行う関数も多いため、どちらを使用すればよいか迷うこともあります。
さて、ではどのように使い分けるべきか。
結論から言いますと、「横に処理(単一のイベント内に閉じて処理)」する場合は eval 、「縦に処理(複数のイベントにまたがって処理)」する場合は stats を使用します。

以下のダミーデータを例にしてみます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Test1
| eval Test2 = Test1 + 3, Test3 = Test1 + 6
| fields - _time, Test
```

![スクリーンショット 2021-10-04 21.58.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/9f1b1eab-8750-cc49-9d87-3fa43c445a92.png "対象")

 stats を使用した場合、処理は「縦に」行われ、結果のみが表示されます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Test1
| eval Test2 = Test1 + 3, Test3 = Test1 + 6
| fields - _time, Test
| stats sum(Test1), sum(Test2), sum(Test3)
```

![スクリーンショット 2021-10-04 21.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/bccf2f0a-0f71-88f2-d44f-e7159d742bb0.png "stats")

 eval を使用した場合、処理は「横に」行われ、結果は既存項目に追加する形で表示されます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS Test1
| eval Test2 = Test1 + 3, Test3 = Test1 + 6
| fields - _time, Test
| eval TestSum = sum(Test1, Test2, Test3)
```

![スクリーンショット 2021-10-04 22.00.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/c009f97e-a3be-a294-b023-90bc3e7e9134.png "eval")
【個人アプリ開発メモ】Reactでsvgファイルを使う方法

例えばtest.svgを取得して以下のディレクトリに配置

```ts
src/assets/svg/test.svg
```
あとは利用したいコンポーネントでsvgをimport

```ts
import testImg from 'src/assets/svg/test.svg';
```

img要素に以下の様に渡せば完了

```ts
<img src={testImg} alt="Icon" />
```

ちなみにimg要素を利用するときはaltを必ずつけること。通信が上手くいかず画像が読み込まれないときは
代わりにaltのフィールドが出力される。SEO的にも良いらしい。

以上。
VScodeでROOT(CERN)の自動補完を使う

# 1.環境
macOS : Big Sur 11.6.1
ROOT (CERN) : 6.24.06
VScode : 1.62.2 (Universal)

2024/04/01 追記 著者は2022年に上記の環境で作りましたが、最新のmac OS, Linux 環境でも動きます。というか、基本OS等のバージョンによることはないと考えています。
ただし、後述のC/C++ 拡張機能のバージョンには依存する可能性があります。ver1.19.9では動くことを確認しました。

# 2.この記事の対象
ROOT（CERN）をVScodeでよく書く方向け。

# 3.症状
VScodeってそのままだと、ROOTにインテリセンスが働かないんですよね。だから![スクリーンショット 2021-11-14 14.44.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2087702/cb4e01d7-5ac5-07c3-8e34-7e6e35f5e397.png)
こんなエラーがめちゃくちゃでてくると。不快だっっっっっ！！！！！！
しかも、インテリセンスが使えないと、自動補完できないのでVScodeの強みも半減なんですよね。
ということで、設定をいじってROOTに対してもインテリセンスが動くようにします。

# 4.解決策
## 4.1 C/C++の拡張機能のインストール（インストール済みなら飛ばすこと）
1. `shift+command+X`またはサイドバーから「拡張機能」メニューを開く
2. 検索窓（Marketplaceで拡張機能を検索する）に「C/C++」と打ち込む
3. C/C++の欄の「インストール」を押す

インストールした後の写真を添付します。写真一番上の拡張機能だけをインストールすれば大丈夫です。インストール前であれば、写真の歯車の部分が「インストール」となっているのでそこを押します。
![スクリーンショット 2021-11-14 16.21.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2087702/99821288-a054-7d22-409a-6eaabb41de7d.png)

## 4.2 設定の編集
1. `command+,`または左下の「管理」から設定を開く
2. 右上の「設定（json）を開く」から`settings.json`を開く
![スクリーンショット 2021-11-14 16.30.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2087702/c5ad5848-cf07-b2c3-eb4a-39d179b6c0b5.png)

3. `settings.json`に以下の内容を書き加える

```json:settings.json 
"C_Cpp.default.includePath": [
    "${default}",
    "（ROOTの入っているディレクトリ）/**"
  ]
```
(ROOTの入っているディレクトリ)は各自の環境に合わせてください。自分はHomebrewでrootをインストールしたのですが、自分は`C_Cpp.default.includePath`の２文目のところを

```
usr/local/Cellar/root/6.24.06/**
```
としています。

これで設定は完了です。

ちなみに、**をつけないと含まれるファイルを下のディレクトリまで（再帰的に）参照してくれないので注意しましょう。

## 4.3 マクロを書く
他の言語と同じように各クラスに対応するヘッダファイルをインクルードします。すると、TFile等のクラスが読み込まれ、インテリセンスが働いていることがわかると思います。
![スクリーンショット 2021-11-14 17.17.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2087702/71d214e7-a70a-9ead-836a-4bc646f6a79c.png)

# 5. おまけ 作業ファイルごとにインテライセンスを設定する
今までは、VScodeで読み込むファイル全体にインテリセンスがはたらくようにしました。
しかし、作業するディレクトリ毎に設定を変えたいこともあると思います。
この場合は作業ディレクトリにある`.vscode/c_cpp_properties.json`内の
`includepath`を編集しましょう。編集方法は4.2節の方法と同じです。

# 6. 解説
拡張機能C/C++はヘッダファイルを読み込むことで、自動補完などを行います。しかし、デフォルトでは、ROOTのヘッダファイルはC/C++が読み込む対象にはなっていないので、インテリセンスが働きません。そこで`C_Cpp.default.includePath`の設定で、ROOTヘッダファイルのディレクトリへPATHを通し、C/C++がROOTのヘッダファイルを認識できるようにしています。

最後に、間違い、改善点、やってもうまく行かない等ありましたら、コメントいただけると幸いです。

# 7.参考
https://root.cern/blog/root-on-vscode/
こちらも記事と合わせて読むことをおすすめします。（英語ですが）windowsやlinux環境の方はまずこちらを読むほうが良いかもしれません。著者のAlberto氏が制作された拡張機能[ROOT File Viewer](https://marketplace.visualstudio.com/items?itemName=albertopdrf.root-file-viewer)もぱっと図を確認するのに便利です。

https://root-forum.cern.ch/t/autocompletion-with-vs-code/38188/2
こちらも。少し説明不足ではありますが、設定について書かれています。

https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference
C/C++拡張機能の設定についても読んでおくとよいです。
WordPressのメニューのli要素、a要素を現実的なHTMLに補正する

WordPressの「メニュー」はウィジェットやブロックエディタでも呼び出すことができて便利ですが、きっちりした案件に使用する際は以下の難点があります。

* li要素に無駄なクラスが付与される
* a要素にクラスが付与されていない

CSSフレームワークを利用するなど、コーディングが完成してから着手する案件では困ります。

また、li要素に付与されるクラスは、びっくりするほど冗長です。

```
menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-9999 current_page_item menu-item-has-children menu-item-8888
```

これだけ長いと、ページ全体のファイルサイズに少なからず影響があります。
最小限のコードで、現実的なHTMLに補正する方法を紹介します。li要素のみのTIPSはよく見るのですが、a要素が少なかったので書いておきます。

## li要素の補正

li要素のクラス名を上書きするフックは「nav_menu_css_class」です。配列 `$classes` に、各クラス名が渡されています。

functions.php に以下のコードを追加すると、li要素のクラスが「menu-item」と「current-menu-item」だけになります。
もちろん、配列 `$output` に渡すクラス名を変えることもできます。

```php:custom_nav_menu_css_class.php
function echo_nav_menu_css_class($classes){
  $output = array(
    'menu-item'
  );
  if(in_array('current-menu-item', $classes)) {
    $output[] = 'current-menu-item';
  }
  return $output;
}
add_filter('nav_menu_css_class', 'custom_nav_menu_css_class', 10, 1);
```

## a要素の補正

a要素のクラス名を上書きするフックは「nav_menu_link_attributes」です。変数 `$atts` に、属性名がキー、属性値が値として渡されています。

functions.php に以下のコードを追加すると、a要素にもクラス「menu-label」を追加できます。
もちろん `$atts['class']` に渡すクラス名は自由です。

```php:custom_nav_menu_link_attributes.php
function custom_nav_menu_link_attributes($atts){
  $atts['class'] = 'menu-label';
  return $atts;
}
add_filter('nav_menu_link_attributes', 'custom_nav_menu_link_attributes', 10, 1);
```

### a要素にカレントクラスを付与しなければならないとき

支給されたコーディングデータによっては、**現在ページを示すクラス＝カレントクラスが、リンクを包括するli要素ではなく、a要素に付与する前提となっている**ことがあります。この場合、CSSを修正してもらうか、WordPressにフックを追加するかということになります。

```html
<a href="https://example.com/about/" aria-current="page" class="menu-label is-current">このサイトについて</a>
```

フック「nav_menu_link_attributes」は、各リンク先の投稿情報を保持しているオブジェクト `$item` も使用できます。
`$item->current` が `true` であればそのリンクは現在のページです。
functions.php に以下のコードを追加します。

```php:custom_nav_menu_link_attributes_current.php
function custom_nav_menu_link_attributes($atts, $item){
  $atts['class'] = 'menu-label';
  if($item->current) {
    $atts['class'] .= ' is-current';
  }
  return $atts;
}
add_filter('nav_menu_link_attributes', 'custom_nav_menu_link_attributes_current', 10, 2);
```

フックによるコード書き換えは多用したくないところなので、CSSの修正ができないときだけ利用してください。

私が公開しているCSSフレームワークがこの仕様になっていたのは内緒です。すみません直します…
シェルスクリプトでGUIアプリを作ってみた


##動機
Ubuntuで動くGUIツールが作りたかった
で、筆頭に上がったのが、シェルスクリプト。

##掘り下げると..
ターミナルへのコマンドを**クリック一発**で投げられるツールが欲しかった
当然、GUIがほしく、かつ、**Linuxで確実に動くものとしてシェルスクリプトが。**
他にも、pythonとかあり、ほとんどのLinuxでは標準でインストールされていることが多いことは知っていたが、**今後Ubuntuの仕様変更への対応を考えて、依存関係を極力少なくするためにシェルスクリプトを。**


##処理フロー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284147/08c31d15-9a9f-58ae-7012-b4798ce90046.png" width=90%>

##上記の処理フローの理由
**入力値の受付のためだけにGUIを使いたいため。**
上記のフローだと、INDEX画面で５つの入力のいずれかを行い、各所の入力受付画面に遷移し、終了以外はIMDEX画面に戻るが、
これだと、**遷移しかなく、メインループ等の実装は必要がない。**
また、そもそも**シェルスクリプトでメインループの実装の話を聞いたことがない。**
以上の理由により、終了以外はすべてINDEX画面に戻るループを組むだけの単純なフローに落ち着いた。

##使用したGUIライブラリ
・YAD（Zenityフォークライブラリ）
主に、[こちら](https://www.kabipan.com/densan/yad.html)を元に作成

## そして、作ってみた。
コードは[リンク](https://drive.google.com/drive/folders/1OjKlSyNMku0gUbJ5iNceNSDeZeXfK6JX?usp=sharing)にて。
※exec_cmdclick.shが実行ファイル
※アプリ説明は[こちら](https://docs.google.com/document/d/19KFUA_DxuWPMMtEZLaBMDIBlX8SB6xPwuQlLiEqaaNs/edit)


##感想
・シェルスクリプトでGUIは**メインループに相当する処理がなければさほど難しくない**
・ここまでしなくとも、**簡単なログアウトセッション程度は自作はさほど時間がかからない****（自作Linuxを作る際、GUIアプリがなくとも、「仕込む」という選択肢が。）**
・シェルスクリプトだと、**異様にグローバル変数が増える**（筆者の知識不足の可能性大）
・**シェルでウィンドウ最大化表示は止めたほうがいい**（後述参考）

##余談 〜　シェルでウィンドウ最大化表示は止めたほうがいい　〜
結論から言うと、**すごく間延びした感じがしてしまう**

###理由
まず、下記が今回作成したアプリのINDEX画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284147/317e37bb-612b-25b9-f783-312d14c55e59.png" width=40%>

そして、下記のウィンドウ最大化画面を
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284147/b78fbeeb-a40f-2c52-c9ee-e9dfcf2f2c6c.png" width=90%>

これ、**非常に余白の大きさが気になってしまう。**
両方共それなりにあるが、後者の最大化画像の方が、余白が伸びていて、しつこさまで感じてしまう。
ログアウトセッションのように、Linuxのアプリには最大化しないものがある理由がわかった気がする。
JavaScriptのコールスタックを理解する

JavaScriptエンジンは**コールスタック**という仕組みを通して、JavaScriptがどのように実行されたか追跡しています。

## コールスタックとは
**実行中のコードが辿ってきたコンテキストの積み重ねのこと**

言い換えると、JavaScriptエンジンがどのような経路を辿ってコードに辿り着いたのか記録しているものです。

## コード例
```javascript
function a() {}
function b() {
  a();
}
function c() {
  b();
}
c();
```

上記コードは、まず関数`c(　)`が実行されて、その中で関数`b(　)`が実行されます。さらに関数`b(　)`の中で関数`a(　)`が実行されます。

この時、生成されるコンテキストの順番は以下のようになります。

**1. グローバルコンテキストが生成される。**
**2. cの関数がよばれる際に、cのコンテキストが生成される。**
**3. cの関数の中でbの関数がよばれ、bのコンテキストが生成される。**
**4. bの関数の中でaの関数がよばれ、aのコンテキストが生成される。**

このようなコンテキストの積み重ねのことを**コールスタック**と呼びます。

## コールスタックの特徴
コールスタックの特徴として、**LIFO(Last In, First Out)**があります。
LIFOとは**「後入れ先出し」**のことで、**後から入ったコンテキストが先に実行されて消滅します。**

#### コンテキストを積む順番
グローバルコンテキスト ⇨ cのコンテキスト ⇨ bのコンテキスト ⇨ aのコンテキスト

#### 実行する順番：
aのコンテキスト ⇨ bのコンテキスト ⇨ cのコンテキスト ⇨ グローバルコンテキスト

## まとめ
JavaScriptエンジンは**コールスタック**という仕組みを通して、JavaScriptがどのように実行されたか追跡しています。

コンテキストが積まれた際、最初に実行されるのはaのコンテキストであり、常に**コールスタックの一番上に積まれているコンテキストが実行中のコンテキスト**になります。

そして、aの処理が終わるとaのコンテキストが消滅し、bの関数へと移ります。そして、bの処理が終わるとbのコンテキストが消滅し、cの関数へと移ります。

最終的にグローバルの処理が全て完了した時点でグローバルコンテキストが消滅します。

## 参考資料
https://www.udemy.com/course/javascript-essence/
ArgoCDにKustomized-Helmプラグインを設定する方法

ArgoCDがHelmを処理した後にKustomizeで部分できに上書きできるようにするための`Kustomized-Helm`プラグインを設定する方法です。

## ArgoCDのConfigMapで設定する方法

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  configManagementPlugins: |
    - name: kustomized-helm
      init:
        command: ["/bin/sh", "-c"]
        args: ["helm dependency build || true"]
      generate:
        command: ["/bin/sh", "-c"]
        args: ["helm template ../../helm_base -f $values --name-template $ARGOCD_APP_NAME --include-crds > ../../helm_base/all.yml && kustomize build"]        
```

## ArgoCDをHelmfileでインストールしている場合の設定方法

```yaml
releases:
  - name: argocd
    namespace: argocd
    createNamespace: true
    chart: argo/argo-cd
    version: 3.26.8
    values:
      - server:
          configManagementPlugins: |
            - name: kustomized-helm
              init:
                command: ["/bin/sh", "-c"]
                args: ["helm dependency build || true"]
              generate:
                command: ["/bin/sh", "-c"]
                args: ["helm template ../../helm_base -f $values --name-template $ARGOCD_APP_NAME --include-crds > ../../helm_base/all.yml && kustomize build"]
```
2021年共通テスト 数学II 第１問 ［１］

> (１) 次の問題Aについて考えてみよう。
> 問題A 
関数 $y=\sin \theta + \sqrt{3} \cos \theta (0 \leqq \theta \leqq \dfrac{\pi}{2} )$ の最大値を求めよ。

> ---
> $$ \sin \dfrac{\pi}{\fbox{ア}} = \dfrac{√3}{2}, \cos \dfrac{\pi}{\fbox{ア}} = \dfrac{1}{2} $$
>
> であるから、三角関数の合成により、
> 
> $$y = \fbox{イ} \sin(θ + \dfrac{π}{\fbox{ア}}) $$ と変形できる。

[ア]
$ \sin \frac{\pi}{3} が \frac{\sqrt3}{2} $  なので、「$ \sin \frac{\pi}{\fbox{ア}} = \frac{√3}{2}$」 の**アは3**。

[イ]
「三角関数の合成により」といっているけれど、sinの加法定理でも同じ意味だよね。

```math
加法定理：
\sin(a+b)=\sin(a)・\cos(b) + \sin(b)・\cos(a)
```

これをつかって「$y =\sin \theta + \sqrt{3} \cos \theta $」を sinだけの式に変形しよう。そうすれば、最大値も求められる。

```math

\begin{align}
y &=\sin \theta + \sqrt{3} \cos \theta \\
\\
&=\sin \theta \cdot 1 + \sqrt{3} \cos \theta \\
\\ 
&=2(\sin \theta \cdot \underline{\frac{1}{2}} + \underline{\frac{\sqrt{3}}{2}} \cdot \cos \theta)
\end{align}
```

$ \underline{\frac{1}{2}}=\cos \frac{\pi}{3}$、$ \underline{\frac{\sqrt3}{2}} = \sin \frac{\pi}{3} $ なので、

```math
=2(\sin \theta \cdot \cos \frac{\pi}{3} + \sin \frac{\pi}{3} \cdot \cos \theta)
```
加法定理 「$\sin(a+b)=\sin(a)・\cos(b) + \sin(b)・\cos(a)$」より、

```math
= 2\sin (\theta + \frac{\pi}{3})
```

したがって、**イは2**。

> よって、yは $ θ= \dfrac{\pi}{\fbox{ウ}}$ で最大値 $\fbox{エ}$ をとる。

[ウ]
sinは、sin π/2で最大値1になる。つまり「θ + π/3」が π/2 のときに最大になる。
したがって、 θ = π/2 - π/3 = π/6。**ウは6**。

[エ]
sin π/2で最大値1になるので、yは2になる。**エは2**。


> (２) pを定数とし、次の問題Bについて考えよう。
> 問題B
> $ 関数 y= \sin \theta + p \cos \theta (0 ≦ θ ≦ \dfrac{π}{2}) の最大値を求めよ。$
(i) p=0のとき、yはθ=$\dfrac{π}{\fbox{オ}}$で最大値$\fbox{カ}$をとる。

[オ][カ]
p=0ということは、y=sinθとなる。sinはsin(π/2)で最大値１になるので、
**オは２**、**カは１**。
【Nuxt.js】アプリテンプレート（カスタマイズ）

#はじめに
こんにちは！
今回は【Vue.js】についてアウトプットしていきます！

#アプリテンプレートとは

まずデフォルトのテンプレートを確認します。隠しフォルダ内にあるので、通常は閲覧しなくてOKです。今回は、`.nuxt⏩views⏩app.template.html`と見ていき、`app.template.html`がデフォルトのアプリテンプレートになります。

```app.template.html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>
```
※簡単にいうとHTMLページの一番ベースとなる雛形です。

この雛形を編集したいときは、直接`app.template.html`に書き込むのではなくて、新しく`app.html`というファイルを作成し編集を行ってください。ファイル名は必ず`app.html`にしてください。

例を出すと、Google ChromeのJavaScriptを無効とする設定になっていたら、ユーザーに警告する処理を`app.html`に記載し、実行させることなどができます。


#まとめ
HTMLドキュメントのベース（`app.template.html`）をカスタマイズしたいときは、新しく`app.html`ファイルを作成し、そっちでカスタマイズを行う。

#最後に
今回はアプリテンプレート（カスタマイズ）についてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
CocoaPodsで"pod install"した時にエラーが出たら(M1 Mac環境)

#概要
CocoaPodsによるライブラリのインストール

```terminal
$ pod install
```

M1 Mac環境でやるとエラーが出てしまいます。
色々解決の仕方があるようですが、シンプルに解決できた方法を共有します:grinning:

※ なお、Terminalからコマンドを実行します。
内容が理解できて、ご自身の環境に合っている場合だけお試しください:bangbang:
#本文

まずはffiをインストールしておく

```terminal
$ sudo arch -x86_64 gem install ffi
```

ライブラリをインストールする時はこのコマンド

```terminal
$ arch -x86_64 pod install
```

ライブラリを更新する時はこのコマンド

```terminal
$ arch -x86_64 pod update
```

#補足
この[stackoverflow](https://stackoverflow.com/questions/64901180/running-cocoapods-on-apple-silicon-m1)を参考にしました。
ArgoCDでkindやminikubeでingressのHelathcheck通らず、ずっとprogressingになる問題のワークアラウンド

ローカル環境でHealthcheckが通らなくてArgoCDがずっとクルクルして目障りなので無効化します。

ArgoCDのConfigMapで`resource.customizations`を指定することで挙動をカスタマイズすることができるのでここで無効にします。

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  resource.customizations: |
    networking.k8s.io/Ingress:
      health.lua: |
        hs = {}
        hs.status = "Healthy"
        return hs
```

## 参照


- [Deployment is still progressing since Ingress resource is not considered as synced · Issue #1704 · argoproj/argo-cd](https://github.com/argoproj/argo-cd/issues/1704)
フォームと同じページでデータを受け取りたい

##その手段
こたえはここにありました。

https://shiba-sub.sakuraweb.com/?p=5398

##やってみる
上記リンクを見てプログラム作成

```php
<form method="post" action="">
  <input type="text" name="name0">
  <input type="submit" value="送信">
</form>

<?php
  $data = $_POST["name0"];
  print $data;
?>
```

すると、動作するもののワーニングメッセージがでる。
PHPを読み込んだ際に$_POSTに何もないのが原因とおもわれました。
##対策

```php
$data = $_POST["name0"];
```
を

```php
$data = @$_POST["name0"];
```
にする。@はエラーメッセージ表示を無視する演算子のだそう。

##その他対策
https://teratail.com/questions/57739

にも対策がのっていた。
@をつけるよりも複雑そうなので試してないのでメモ程度にのせておく。

##失敗対策
読み込んだときにあらかじめフォームになにか入っていればワーニングは出ないのではと考え、

```php
<input type="text" name="name0">
```

を

```php
<input type="text" name="name0" value="0">
```

にして予めフォーム内に値をいれてみたが全く意味がなかった。

##その他
actionに直接$_SERVERってやると危険らしいのでやらないほうがいいそう。
こちらも複雑そうなので試してないでメモ程度にのせておく。

https://www.webdesignleaves.com/pr/html/form.html
一般化固有値問題

#一般化固有値問題　part1
###固有値＆固有ベクトル

正方行列$A$, ベクトル$\vec{v}$，スカラー$λ$として，以下の(1)式が成り立つと考えた時,

```math
A\vec{v} = λ\vec{v}・・・(1)
```

$\vec{v}$は$A$の固有ベクトル，$λ$は$A$の固有値といえる．
>例：

>```math
\begin{pmatrix}
3 & 7 \\4 & 6
\end{pmatrix}
×
\begin{pmatrix}
1 \\1
\end{pmatrix}
=10×
\begin{pmatrix}
1 \\1
\end{pmatrix}
```

***
###固有値の求め方
正方行列$A$が与えられた時，固有値$λ$は次のように求めていく．

```math
A\vec{v} = λ\vec{v}　\rightarrow　(A-λI)\vec{v}=0 
```

右辺を移行し，$\vec{v}$で括る．$λ$はスカラーのため，正方行列$A$に対して引けない．よって，単位行列$I$をかけてから引く．

```math
A\vec{v} = λ\vec{v}　\rightarrow　(A-λI)\vec{v}=0 
\rightarrow|A-λI|=0
```
$\vec{v}=0$　または　$(A-λI)=0$の時に式が成り立つ．今回は固有値と固有ベクトルを求めたいため，$\vec{v}≠0$とする．よって，今回は$|A-λI|=0$となる$λ$を求める．

>例：

>```math
A-λI=\begin{pmatrix}
3 & 7 \\
4 & 6
\end{pmatrix}
-λ\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}
```
```math
|A-λI|=\begin{vmatrix}
3-λ & 7 \\
4 & 6-λ
\end{vmatrix}
```
```math
(3-λ)(6-λ)-4×7=0・・・(2)
```

>(2)式から$λ＝-1,10$と求まる．

固有ベクトルの数と固有値の数は必ず同じになる．
***
###固有ベクトルの求め方
固有値と固有ベクトルはペアになっているため，固有値がわかれば固有ベクトルも求まる．

>例：(1)式に上記で求めた$λ＝-1$を代入すると，

>```math
\begin{pmatrix}
3 & 7 \\
4 & 6
\end{pmatrix}\begin{pmatrix}
\vec{v_1} \\\vec{v_2}
\end{pmatrix} = -1\begin{pmatrix}
\vec{v_1} \\\vec{v_2}
\end{pmatrix}\\\
\begin{cases}
  3\vec{v_1}+7\vec{v_2}=-\vec{v_1} \\\
  4\vec{v_1}+6\vec{v_2}=-\vec{v_2}
\end{cases}
```
連立方程式を解き，

>```math
\vec{v_1}=-\frac{7}{4}\vec{v_2}
```
よって，固有値$λ=-1$の時，固有ベクトルは$\begin{pmatrix}7\\\\-4\end{pmatrix}$の定数倍となる．

***
###余談
$A$が正方行列でない場合は，今回の方法では求められない．
helm-diffをM1のmacOSにインストールする

# 概要

[helm-diff](https://github.com/databus23/helm-diff)は2021年11月14日現在ではARM向けのバイナリは提供されていません。そのためM1のようなARMアーキテクチャ向けには自分でコンパイルしてインストールする必要があります。

# 事前に必要なパッケージ

## Go言語

```bash
brew install go
```

## golint

```bash
go get -u golang.org/x/lint/golint
```

`$GOPATH/bin`にPATHが通っているか確認しておきましょう。

# helm-diffプラグイン

```bash
https://github.com/databus23/helm-diff.git
cd helm-diff
make install/helm3
```
Docker環境でJupyterNotebookのセキュリティトークンを無効にする方法

ubuntu18.04上でdocker環境を作ってJupyterNotebookを起動するときに、セキュリティトークンの入力を省略したかったので試行錯誤してみました。

こちらの記事のコメントの部分でうまく回避できたようです。セキュリティ的にはまずいので、問題ない環境でのみ行ってください。
https://stackoverflow.com/questions/41159797/how-to-disable-password-request-for-a-jupyter-notebook-session

custom-start.sh というファイルを作成

```sh:custom-start.sh
jupyter notebook  --allow-root --no-browser --ip=0.0.0.0 --port=8886 --NotebookApp.token='' --NotebookApp.password=''
```


Dockerfileの最後で以下のようにしてcustom-start.shを起動

```sh:Dockerfile
WORKDIR /root
COPY custom-start.sh /root
RUN chmod +x /root/custom-start.sh
CMD /root/custom-start.sh
```
Google Chromeで画面全体のスクリーンキャプチャをChrome拡張なしで撮る方法

# macOSの場合

1. `⌘ + alt + i` でDeveloperToolsを表示。
1. `⌘ + p` でコマンドドロワを表示
1. `> full` と入力しエンター

# Linuxの場合

1. `ctrl + alt + i` でDeveloperToolsを表示。
1. `ctrl + p` でコマンドドロワを表示
1. `> full` と入力しエンター

# Windowsの場合

1. Delveloper Tools(開発者ツール)を開く。
1. `ctrl + shift + p` でコマンドドロワを表示
1. screenshotと入力する
1. 「フルサイズのスクリーンショットをキャプチャ」を選択する
Rの設定コマンドをシェルから直接実行したい

# はじめに
DockerでRのコンテナたてようと思ったが、Rコマンドから実行する設定系をDockerfileのRunに書きたいなというところで調べた

# ざっくり内容
Rをインストールしたあと、ミラーサイトを設定するときは

```shell
sudo R
```

から

```shell
chooseCRANmirror()
```
みたいに実行して、53とか入力しないといけないが、直接シェルから実行できた話

# 方法

```shell
sudo R -e 'chooseCRANmirror(ind=53)'
```

みたいに書けばうまくいく。なのでＤockerfileに書くときは

```Dockerfile
RUN R -e 'chooseCRANmirror(ind=53)'
RUN R -e 'install.packages("ggplot2")'
```

のように記載すればよい
※indみたいな引数は仕様を調べる必要がある

# 最後に
Dockerを再学習中…
FastAPI+Rをdocker-composeで組み立てて画像返ってきますみたいなのを作る予定。
SQLでループ文を作成する方法

##概要
私はSQLでデータ抽出をする際にはLOOP処理ができたらいいなと思うことも多々ある。

例えばカラムを日付毎に先頭一行ある状態でcsvファイルをエクスポートしたいなどという場合である。

そのような場合に検討することは
データベース言語のSQLでLOOP処理が実現可能なのかということである。

結論：SQLでLOOP処理は使用可能

###１ヶ月分毎に指定した日付をエクスポート処理するクエリ
BigqueryでSQLをたたいてGCSにエクスポートする




```sql:sql
DECLARE x INT64 DEFAULT 初期月
SET stores = ;
--setでLOOP処理を終了させる条件の変数を作成する

WHILE x <= stores
 DO
  EXPORT DATA OPTIONS(
  uri='gs://xxxxxxxxxxx-gcs-bucket-tokyo/export_sample/*.csv.gz', -- ファイルパスを指定。uriにはワイルドカード表記とする必要がある(ファイル名個別指定は出来ない)
  compression='GZIP',  -- 圧縮形式を指定(GZIP, DEFLATE, SNAPPY)。未指定の場合は圧縮無し
  format='CSV',        -- ファイルフォーマットを指定。CSV, JSON, AVROが選択可能
  overwrite=true,      -- ファイルが存在していた場合の上書き有無。未指定の場合はfalse
  header=true,         -- ヘッダ行の有無。未指定の場合はfalse
  field_delimiter=','  -- 区切り文字を文字列として指定
  ) AS
  SELECT *
  FROM データセット.テーブル名
  WHERE 日付 = x;
  SET x = ADD_MONTHS(x, 1);
END WHILE;
```
### まとめ
上記を定期スケジュールで実行させることで
定期的にファイルをGCSに抽出することが可能となる。
Pearson OnVUE の試験監督の言語は英語を選ぼう

# 前提
この情報は2021年11月13日時点の情報です。今後Pearson社の対応変化によって、変わる可能性があります。

MicrosoftのAZ-900などの認定試験は Pearson OnVUE で自宅で受験することができる。多くの試験の言語は英語だけでなく、日本語などの言語も選択可能。
一方で、その自宅での受験の際のリモート「試験監督」の言語 (プロクター言語)は日本語と英語を選択可能である。


# 結論

リモート試験監督の言語は英語を選んだほうがメリットが多い



# 試験監督が日本語の場合

### メリット
* チャットや電話が日本語になる。ただし、日本語が話せる外国人がほとんどで、ネイティブ日本人ではない。

### デメリット
* 試験時間として選べる時間帯が少ない。
   原則、月曜から土曜の 0930 - 1430。また一つのスロットあたりの人数が少ないようですぐに埋まってしまう。



### 日本語を選択した場合の試験の流れ

1. チェックインする
1. リモート試験官から机の周りを360度カメラで見せろとチャットで指示される
1. もし、メガネを掛けている場合は、メガネをカメラで見せろとチャットで指示される
1. 時計などしていないか確認するため両腕をカメラで見せろとチャットで指示される
1. 注意事項を告げられて、問題ない場合はカメラに腕でジェスチャーでマルを示すことを指示される
1. 問題文が表示される


# 試験監督が英語の場合

### メリット
* 試験時間として選べる時間帯が多い
   平日、土日、どちらも選べて、平日は 24h 選べるっぽい。
* 試験の時の試験監督の対応が簡素

### デメリット
* チャットや電話が英語になる

### 英語を選択した場合の試験の流れ

1. チェックインする
1. 問題文が表示される

全くチャット無し。



## リモート試験官からのチャットについて

カンニングが疑われるような変な動きをしない限り、通常、試験を受けている間に何か試験官からチャット、電話が来ることはない。なので、英語が不得意でもほぼ問題ない。




# 自分の経験

試験監督が英語で試験を受けている時に、緊急地震速報が大音量で部屋で鳴り響いたことがあった。
> Are you OK? Can you continue the exam?

とチャットで質問があったが、
> This is emergency earthquake call. Don't mind.

ぐらいの英語で切り抜けられました。
Nokogiriを使った基礎的なWebスクレイピングを学びました

Webスクレイピングについて基礎的な学習をしたので、アウトプットさせていただきます。

# Nokogiriとは
Nokogoriとはgemで提供されているWebスクレイピングライブラリのことで、gemを使ってライブラリをインストールすると使えるようになります。

```
$ gem install nokogiri
```
#### Webスクレイピングとは
Webサイトから情報を取得して、その情報に加工を加えて新たな情報を生み出すことです。
APIとの違いとして、APIはサービス側が開発者向けに一定の条件のもと、公式に機能の一部を使用できるようにしていますが、Webスクレイピングは公式のサービスとは言えず、無作為に使用していると利用規約に引っかかる可能性があり、その点の注意が必要になります。

#### Webスクレイピングの活用方法

例えば、価格.comから好きな家電の価格を取得して、一覧表をCSVで記録するといった具合に必要な情報を自動化して取得し、業務の効率化やAPIにはないデータの取得に役立つ等のメリットがあります。
逆にデメリットとしては、DOM構造が変わったりすると、それまで正常に機能していたコードが機能しなくなり、修正を加えないといけない等のデメリットがあります。


# DOMとは〜Webスクレイピングの前提知識
DOMとはJavaScript等のプログラミング言語でhtmlの要素を操作するための仕組みのことで、**「Document Object Model」**の略です。
分かりやすい日本語に直すと、**プログラムからHTMLやXMLを自由に操作するための仕組み**のことで、ファイル（HTML）の任意の部分に目印を付けて「この部分にこういう事をしたい」という処理を可能にするための仕組みがDOMです。

特徴としては、

- ツリー構造という階層構造である
- 各要素のことを**「ノード」**という
- WEBページとプログラミング言語とを繋ぐ仕組み

といった特徴があります。
この仕組みを使って例えばJavaScriptはWebサイトに動きをつけることができるようになります。
WebスクレイピングではDOMを理解した上で、要素を指定します。

次に、RubyでWebスクレイピングを行う際に使用する組み込みライブラリを説明します。

## open-uri
Rubyの組み込みライブラリで、URLからサイトにアクセス(サイト情報をファイルのように扱うことができる)して、様々なメタ情報を取得する際に使用します。
このライブラリを使用して、スクレイピングを行うURLをファイルとして開き、Nokogiriを使って分析していくイメージです。

```json:open-uriサンプル　公式より
require 'open-uri'
URI.open("http://www.ruby-lang.org/en") {|f|
  f.each_line {|line| p line}
  p f.base_uri         # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
  p f.content_type     # "text/html"
  p f.charset          # "iso-8859-1"
  p f.content_encoding # []
  p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002
}
```
[公式リファレンス](https://docs.ruby-lang.org/ja/2.7.0/library/open=2duri.html)

## Nokogiriを使ったWebスクレイピングの流れ
スクレイピングの簡単な流れは

- 求めるデータがどのノードにあるのか探す
- 見つけたデータを取得
- 取得したデータを自由な形に整形して利用する

という流れで行います。


## Nokogiriの要素指定方法

Nokogiriの要素の指定方法にはXPathによる指定とCSSセレクタによる指定の2パターンがあり、Webスクレイピング目的であればCSSセレクタの使用が推奨されているようです。

**以下の記事でNokogiriの使い方をざっくり理解できます**
[Nokogiriでスクレイピング - Qiita](https://qiita.com/w650/items/e663fa2430145c456c4d)

## Webスクレイピングをやってみる
これから[こちら](https://scraping-for-beginner.herokuapp.com/ranking/)のスクレイピング用の練習サイトを利用させてもらって、とにかくスクレイピングをやってみて、イメージを掴みます。
さきほどの流れに沿って進めていくと、まずは「求めるデータがどのノードにあるのか探す」をやっていきます。
先ほどのWebサイトの「タイトルタグ」を取得していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/938100/7e7f9985-115e-c5f9-18d1-e7de39d4bbcf.png)

欲しいデータを決めたので、次に「見つけたデータを取得」します。

```ruby:scraping_test.rb
require 'open-uri'
require 'nokogiri'

# Webスクレイピングを行うサイトのURL
url = 'https://scraping-for-beginner.herokuapp.com/ranking/'

html = URI.open(url).read
document = Nokogiri::HTML.parse(html)

# 指定した要素からテキストを取得して表示する
element_title = document.title 
puts element_title
```

```shell
xxx@MacBook-Pro ruby_test % ruby scraping_test.rb 
Webスクレイピング入門者のためのサイト
```
タイトルタグを取得することができました。
今回は、取得した情報を加工等はせずに、そのまま表示させていますが、スクレイピングのイメージを掴むことはできたと思います。

このような感じでWebスクレイピングは、Webサイトから欲しい情報を取得して、データを使うことができます。
Webスクレイピングを学習していく中で、いろんな利用方法が想像できて、とても面白く感じました。
今回は、基礎的な部分をアウトプットしましたが、学習を深めて、もっと応用的なアウトプットもしていきたいと思います。
ご覧いただきありがとうございました。

参照
[RubyでWebスクレイピング](https://zenn.dev/arao99/articles/5541a9bd74fd05)