OmniAICreator/Qiita-1.07M huggingface dataset:
PennyLane v0.16.0 の新機能を試す。

# PennyLane v0.16.0

PennyLaneの最新versionがリリースされました。

https://pennylane.ai/blog/2021/06/pennylane-v016-released/

色々機能が入っていますが、今回は量子回路の実行回数が見積もれるspec機能を使ってみます。

# コード

```python
dev = qml.device('default.qubit', wires=4)

@qml.qnode(dev, diff_method='parameter-shift')
def circuit(x, y):
    qml.RX(x[0], wires=0)
    qml.Toffoli(wires=(0, 1, 2))
    qml.CRY(x[1], wires=(0, 1))
    qml.Rot(x[2], x[3], y, wires=0)
    return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1))

x = np.array([0.05, 0.1, 0.2, 0.3], requires_grad=True)
y = np.array(0.4, requires_grad=False)

specs_func = qml.specs(circuit)
info = specs_func(x, y)
```

`qml.specs` は、qnodeを受け取って、その情報を返す関数のようです。

ここではqnodeがパラメータxとyを持っています。
ただしyについては　`requires_grad=False` となっているので、定数として扱います。
結局、変分パラメータとして動的に動くのはx(4要素ベクトル)だけです。
回路全体のパラメータは4個あることになります。

これをパラメータシフトルールで勾配計算しながら最適化することを考えます。
まず今のパラメータにおけるコストを知るために、回路を1度実行します。
次にパラメータを動かすための勾配情報をパラメータシフトルールで得ますので、
パラメータx2　回の回路実行が必要となります。
合計で 1 + 4 x 2 = 9 回の回路実行・・・と思われるのですが？

specの結果を見てみます。

`info
{'gate_sizes': defaultdict(int, {1: 2, 3: 1, 2: 1}),
'gate_types': defaultdict(int, {'RX': 1, 'Toffoli': 1, 'CRY': 1, 'Rot': 1}),
'num_operations': 4,
'num_observables': 2,
'num_diagonalizing_gates': 1,
'num_used_wires': 3,
'depth': 4,
'num_trainable_params': 4,
'num_parameter_shift_executions': 11, 
'num_device_wires': 4,
'device_name': 'default.qubit',
'diff_method': 'parameter-shift'}`

注目するのは
**num_parameter_shift_executions': 11**
です。9回ではないようです。

なぜ？と思い、質問したところ、回答がありました。
https://discuss.pennylane.ai/t/the-number-of-circuit-execution-in-parameter-shift/1144/3

**実は制御ゲート（今回だとCRYがあります）の場合は、パラメータシフトルールは2回ではなく4回の回路実行が必要となるそうです。**
今回、
RXは1パラメータなので、2回
CRYは1パラメータだが、制御ゲートなので4回
ROTは2パラメータなので4回
となり、これにコスト計算のための1回を加えると 2+4+4+1 = 11 となるわけです。
計算が合いました。

制御ゲート＋変分パラメータ　を多用すると、計算が重くなってしまいますね。注意しましょう！
spec機能での見積もりはなかなか重要そうです。
例えば有料のQPUやシミュレータを使う場合、この実行回数におよそ比例して料金がかかります。（計算時間も）


# まとめ

PennyLane v0.16.0を使ってみた。
spec機能はなかなか便利そう。
UICollectionViewFlowLayoutとIGListCollectionViewLayoutのsectionInsetの違い

## 前述
[UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview)のみで実装してあった機能をリファクタリングして、[IGListKit](https://github.com/Instagram/IGListKit)を使った実装に変更したときに`sectionInset`が想定とは異なるところに反映されて少し詰まったので覚書を残しておく
## 違い
[IGListKit](https://github.com/Instagram/IGListKit)を使った実装に変更したときに[UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview)の[collectionviewlayout](https://developer.apple.com/documentation/uikit/uicollectionview/1618047-collectionviewlayout)プロパティに[IGListCollectionViewLayout](https://instagram.github.io/IGListKit/Classes/IGListCollectionViewLayout.html)をサンプルのとおりにセットして違いが発生しました

左は[UICollectionViewDelegateFlowLayout#sectionInset](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617714-sectioninset)で設定
右は[IGListSectionController#inset](https://instagram.github.io/IGListKit/Classes/IGListSectionController.html#/c:objc(cs)IGListSectionController(py)inset)で設定

|[UICollectionViewFlowLayout](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout)|[IGListCollectionViewLayout](https://instagram.github.io/IGListKit/Classes/IGListCollectionViewLayout.html)|
|-|-|
|![スクリーンショット 2021-06-24 22.49.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/2aa921ae-9067-4aff-8e6e-e7de3681b9d8.png)|![スクリーンショット 2021-06-24 23.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/5825f2f6-6dd6-d757-1cdb-fd87e4aee366.png)|
残プロ　第-23回　~Bootstrapを導入する~

# インストール無しで導入

公式のドキュメントに従い，layout.htmlを作成します．


~~~
<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    {% block content %}
    {% endblock %}

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>
~~~


### ブロックを作成

\<body>内に{% block content %}{% endblock %}を作成しています．
テンプレートとして使用できるのでBootstrapの導入が楽になりますね．
Laravelで画像をアップロードする際にエラーになった時の解決方法

##エラー画面
[![Image from Gyazo](https://i.gyazo.com/bb52c10ed4c8667d7c1c1b96b46fdbb4.png)](https://gyazo.com/bb52c10ed4c8667d7c1c1b96b46fdbb4)

ファイル選択はjpgを指定しているにもかかわらず、バリデーションが発動しアップロードができなかった。

##解決方法

formタグに``enctype="multipart/form-data"``を挿入

```
<form method="POST" action="{{ route('products.store') }}" enctype="multipart/form-data">
    @include('products.form')
    <button type="submit" class="btn btn-block btn-warning">投稿する</button>
</form>
```

``enctype="multipart/form-data"``を
指定しないと、添付ファイルの情報を送信できていないので、サーバー側では添付ファイルを扱えないようです。

簡単ではありますが以上です！
Pythonによるディレクトリ・ファイル操作まとめ


## ディレクトリ構成を出力
treeコマンドを用いるとディレクトリ構成を以下のように出力できます。
.
├── dir2
│   ├── dir3
│   ├── file1
│   └── file2
├── dir4
├── file1
├── file2
├── file3
└── file4

treeコマンドは以下のようにインストールできます。

```zsh
brew install tree
```

試しにpythonで適当なディレクトリやファイルを作成します。`os.makedirs`の引数に`exist_ok=True`を入れると、既にディレクトリが存在する場合はスキップされてエラーが出ないので便利です。

```python
import os

# ディレクトリを作成
os.makedirs('dir1/dir2/dir3', exist_ok=True)
os.makedirs('dir1/dir4', exist_ok=True)

# 空のファイルを作成
for i in range(1, 5):
    with open(f'dir1/file{i}', 'w') as f:
        f.write('')

for i in range(1, 3):
    with open(f'dir1/dir2/file{i}', 'w') as f:
        f.write('')
```

treeコマンドを入力すると、作成したディレクトリ構成が出力されます。

```
cd dir1
tree
```
.
├── dir2
│   ├── dir3
│   ├── file1
│   └── file2
├── dir4
├── file1
├── file2
├── file3
└── file4



## 再帰的な検索
`glob.glob('**', recursive=True)`の構文を用いると、カレントディレクトリ以下すべてのファイルやディレクトリからキーワードに一致するものを取得できます。

```python
import glob

keyword = 'file'
path_list = [path for path in glob.glob('dir1/**', recursive=True) if keyword in path]
print(path_list)

# 出力結果
# ['dir1/file3', 'dir1/file4', 'dir1/file2', 'dir1/dir2/file2', 'dir1/dir2/file1', 'dir1/file1']
```

## ファイルの削除
`os.remove`を用いることでファイルを削除することができます。

```python
import os
os.remove('dir1/file1')
```

## ファイルやディレクトリのコピー・移動
shutilを用いることでファイルやディレクトリのコピー・移動を行えます。

```python
import shutil

# shutil.move('source', 'destination')
shutil.copy('dir1/file2', 'dir1/dir3')
shutil.move('dir1/file2', 'dir1/dir3')
```

## ディレクトリの削除
`shutil.rmtree`を用いることでディレクトリを削除できます。

```python
import shutil

shutil.rmtree('dir1')
```
高階関数 ― J 言語入門

J は、verb に対する操作、つまり高階関数の機能も幅広く備えています。高階関数にあたるものには、**adverb** と **conjunction** の 2 種類があります [^1]。

# 被演算子

adverb と conjunction を合わせて、**modifier** (修飾語) と呼びます。adverb は被演算子が 1 つ (**左側**)、conjunction は被演算子が 2 つ (両側) です。verb の場合は**引数** (argument) という言葉を使いましたが、modifier の場合は**被演算子** (operand) と呼び分けられています。

被演算子の名前は、被演算子が verb のときと noun のときで異なります。verb の被演算子は左側なら `u`、右側なら `v` です。一方 noun の被演算子は左側は `m`、右側は `n` です。

# 引数の反転

`~` という adverb は、verb の左右の引数を入れ替えます。

```j
   NB. 5 , 3 と同じ
   3 ,~ 5
5 3
```

`x u~ y` は `y u x` と同じです。

`~` の被演算子 (`-`) が**左側**にあることに注意してください。これは verb (monad) と adverb の大きな違いの一つです。

`~` を使うと、複雑な式の括弧を減らせることがあります。

```j
   (7 - 1) % 3
2
   3 %~ 7 - 1
2
```

# 引数の複製

`~` には他にも使い方があります。上の例では `~` が作った verb を dyad として使いました。これを monad として使うと、また違った働きをします。

```j
   NB. 3 , 3 と同じ
   ,~3
3 3
```

`u~ y` は、`y u y` として動作します。同じ引数を 2 回書かなくて済むので便利です [^2]。

# verb の合成

J には関数 (verb) の合成を行う conjunction が いくつか あります。ここでは代表的な 2 つを説明します。

## monad - monad / monad - dyad

`@` は、`u@v` の形で使います。`x u@v y` は `u (x v y)` を意味します [^3]。

```j
   NB. - (3 % 2)
   3 -@% 2
_1.5
```

また、`u@v y` は `u (v y)` を意味します [^3]。

```j
   NB. - (% 2)
   -@%2
_0.5
```

`u@v` は、`v` を適用した後に `u` を適用する、という一般的な関数合成と同じ動作です。

`u` は必ず monad として実行されます。`v` は使い方に応じて monad または dyad になります。

```
   u
   |
   v
 [/]\
[x]  y
```

## dyad - monad

`&` も、`u&v` の形で使います。`x u&v y` は `(v x) u (v y)` を意味します [^3]。

```j
   NB. (% 3) - (% 2)
   3 -&% 2
_0.166667
```

`u&v` は、**それぞれの引数に** `v` を適用し、その結果を `u` に与える、という動作をします。`@` と違って monad として使うことはできません [^4]。

`u` は必ず dyad として実行されます。`v` は、`x` と `y` それぞれについて monad として実行されます。

```
  u
 / \
v   v
|   |
x   y
```

# 引数の束縛 (部分適用)

`&` は、`m&v` や `u&n` の形で使うと、引数 (`m` / `n`) を verb (`v` / `u`) に束縛する働きをします。

```j
   3&- 5
_2
   -&3 (5)
2
```

---

\[ 前 : [verb と引数](https://qiita.com/unsigned-wrong-wrong-int/items/4357829e274c302cfe64) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [adverb と conjunction](https://qiita.com/unsigned-wrong-wrong-int/items/b61c2f03af3096be044f) \]

[^1]: adverb と conjunction の詳細は、次の記事で説明しようと思います。
[^2]: 計算途中の値を一時変数に入れる必要性も無くなります。
[^3]: 実は厳密には違いがあるのですが、説明の都合上割愛します。
[^4]: 執筆時点 (J9.02) では非推奨ですが、将来的には削除されると思われます。
新しいLinuxの教科書C3

##はじめに
これ以外でも入力はできるが、ホームポジションを崩さない効率的なキーボード操作ができる。

##コマンドラインの編集
プロンプト記号(%)の後ろのコマンド入力部分を**コマンドライン**という。

`○基本のカーソルの移動`
・**Ctrl + b**
後ろに一文字移動
・**Ctrl + f**
前に一文字移動

( bは「Backward」、fは「Foward」)

・**Ctrl + a**
行頭に移動
・**Ctrl + e**
行末に移動

`○単語単位のカーソルの移動`

・**Meta(Escキー) + b**
後ろに単語一つ分移動

・**Meta(Escキー) + f**
前に単語一つ分移動

`○文字の削除`
・**Ctrl + h** (またはBackspaceキー)
 前の一文字削除
・**Ctrl + w**
前の一単語(スペース区切り)削除

`○カットとヤンク(ペースト)`
・**Ctrl + u**
カット
・**Ctrl + k**
ペースト

```
% echo hello　#Ctrl + uを押す
%　　　　　　　 #削除される。Ctrl + kを押す
% echo hello　#ペーストされる
```
##トラブル時には
`○操作を受け付けない`
画面がロックされている可能性がある。

・**Ctrl + s**
画面のロック
・**Ctrl + q**
画面のロック解除

`○コマンドが終了しない`
誤操作や終了しない場合は強制終了する。

・**Ctrl + c**
コマンド終了

`○プロンプトが文字化け`
画像ファイルを表示させた後など、文字化けをする場合がある。

・**Ctrl + l**
画面を消去する

##補完機能

・**Tabキー**で予測変換
また、複数ある場合は2回押すことで候補の一覧表示ができる。

##コマンド履歴
・**Ctrl + P** (または↑キー)
一つ前のコマンド履歴へ移動

・**Ctrl + n** (または↓キー)
次のコマンド履歴へ移動

(　pは「Previous(前)」、nは「Next(次)」)

・**Ctrl + r**
履歴を遡ってインクリメンタル検索
Gitでシェルの設定ファイル(.zshrc)を管理してみた

# 概要

- `.zshrc`の設定を見直そうと思ったが、前にどういう設定をしていたか残したい
- gitで管理すればいいじゃないと思い立ち、そうすることにした
- また、GitHubにリモートリポジトリを作成してGitHubで共有することにした

# 流れ

## 1. .zshrcがあるディレクトリでgit init

```
$ git init
```

## 2. .zshrcファイルをadd

- このとき、他にも管理したいファイルがある場合は追加するといい
- リモートリポジトリを「.zshrc」としたのでこれだけ管理する

```
$ git add .zshrc
```

## 3. コミットする

```
$ git commit -m 'first commit'
```

## 4. GitHubでリモートリポジトリを作成

- 最初に設定したきりなので汚いですが。。。

https://github.com/Islanders-Treasure0969/.zshrc/blob/master/.zshrc

## 5. ローカルリポジトリと作成したリモートリポジトリを紐付け

```
$ git remote add origin https://github.com/Islanders-Treasure0969/.zshrc/blob/master/.zshrc
```

## 6. リモートリポジトリにプッシュする

```
$ git push origin master
```

# まとめ

- .zshrcの設定ファイルを見直す際に変更が怖かったが、これで心置きなく変えることができるのでよかった
- ついでにgitの確認もできたのでよかった
Kudu 上で使えるダンプ採取ツール SmartDump

App Service や Logic Apps などのトラブルシュート時に使う機会のある Kudu (高度なツール) にて、コンソールから簡単にダンプを取得できるツールが紹介されていました。

[microsoft/SmartDump: SmartDump - an exception and memory dump capture utility](https://github.com/microsoft/SmartDump)

exe ファイルなので、環境的には Windows のみが対象のようですね。

# インストール方法

GitHub 上にある `SmartDump.exe` または `SmartDump64.exe` を Kudu 上からドラッグ＆ドロップ等の方法でアップロードすれば OK。

![](https://user-images.githubusercontent.com/32285008/122495908-775acb00-d01d-11eb-8e95-7c1bbef34290.gif)

# 使い方

上記、[GitHub リポジトリ](https://github.com/microsoft/SmartDump) を見ていただければと思います。Usage とかもあるので、そんなに迷わないんじゃないかと思います。

* 手動での `w3wp.exe` プロセスのダンプ取得
* 例外ログの取得
* 特定の例外発生時、または対象以外の例外発生時ににダンプを取得する
* x 回目以降の例外発生時にダンプを取得する
* ブレークポイントに到達したらダンプを取得する

といったことができます。

-----

実際、Kudu 上でダンプを見るかというと微妙かもしれないですが、特定の例外発生時にダンプを取得するよう "仕掛け" ておくのは使いどころありそうな気がします。
TCPのことちゃんと調べてみた

## 勉強前イメージ

コネクション型のプロトコル

## 調査

### TCP とは

Transmission Control Protocol の略で、トランスポート層で伝送を管理するプロトコルです。
1対1の通信で、相手に都度確認を取りながら行う信頼性のある通信です。

### TCPの特徴

#### コネクション管理

- コネクションの確立

TCPは全二重の通信のプロトコルなので、
送信・受信の双方から接続の確立を行う必要があります。

コネクションの確立としては以下になります。

1. 送信側→受信側 に コネクションの確立要求(SYN) を送ります。
2. 受信側→送信側 に コネクションの確立要求(SYN) と 確認応答(ACK) を送ります。
3. 送信側→受信側 に 確認応答(ACK) を送ります。

この流れを `3ウェイハンドシェイク` と呼びます。

![1# TCPのことちゃんと調べてみた - diagrams.net - Google Chrome 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/fa457927-edda-cad6-34b7-06eb3ade2b46.png)


- コネクションの切断

接続の時同様、送信側・受信側の双方から切断を行うことが必要です。

コネクションの切断は以下になります。

1. 送信側→受信側 に コネクションの終了要求(FIN) を送ります。
2. 受信側→送信側 に 確認応答(ACK) を送ります。
3. 受信側→送信側 に コネクションの終了要求(FIN) を送ります。
4. 送信側→受信側 に 確認応答(ACK) を送ります。

![2# TCPのことちゃんと調べてみた - diagrams.net - Google Chrome 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/27fed085-34a3-e11e-db8c-e4cc9dc03464.png)


片方ずつコネクションを切断するということで `ハーフクローズ` と呼ばれます。

#### フロー制御・ウィンドウ制御

- フロー制御

フローとは流量という意味で、流量の制御になります。
データはバッファに一旦置いてからアプリケーションに渡しますが、
多い量を渡しすぎると取りこぼすので、
受信側は送信側に受信できるデータサイズを通知することで、送信側が送信量を調整できます。

- ウィンドウ制御

TCPの送信側で、1回で転送できるデータ量を表す `ウィンドウサイズ` が定義されています。
ウィンドウの範囲内にあるセグメントは受信側のACKを待たずに送信できます。
ウィンドウサイズは輻輳の状態でアルゴリズムで決められます。
ただ、ウィンドウサイズが受信側より多い場合は受信側の容量を優先します。


#### 輻輳制御・再送制御

- 輻輳制御

大量のデータを送り続けるとパンク状態になってしまいます。
それが輻輳状態になります。
セグメントがなくなったら基本的にはパンク状態と判断し、制御がされます。

- 再送制御

受信側は送信側にデータが到着するとACKします。
しかし、データが到着しないと受信側は送信側にACKを送らないので、パケットが破棄されたと判断して
送信側は再度同様のデータを送ります。
これが再送制御と言います。

## 勉強後イメージ

コネクションの切断あんまり知らなかった。
お互いにおわりね、って言い合うのか。
あと輻輳制御おもあまり知らなかった。
結構送る量は変化しながら送ってるのか・・・まぁそうか・・・・
行けるとこまで行ってあかんかったら減らすね！ってことかな？

## 参考

- [TCP/IPをわかりやすく - 通信プロトコルの基礎知識を図解で学ぼう](https://eh-career.com/engineerhub/entry/2020/02/13/103000/?PK=7AD555&isLoginAfter)
- [TCP/IP - TCP sequence control / Retransmission Control](https://www.infraexpert.com/study/tcpip10.html)
C言語（Windows API）を使って7以降のWindowsで音付きのアイコンのないダイアログを表示したい

Windows Vistaまではアイコンのないダイアログで一般の警告音が鳴っていました。
Windows 7以降は鳴らなくなりました。
それでも、音付きのアイコンのないダイアログをC言語（Windows API）で表示させてみます。

非常に単純ですが、MessageBox関数を呼ぶ前にMessageBeep関数で一般の警告音を鳴らすだけです。
音にこだわる人の自己満足ですが…

```c:NoIconDialogWithSound.c
#include <Windows.h>

int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC)
{
	MessageBeep(MB_OK);
	MessageBox(NULL, "一般の警告音が鳴ります。", "音付きのアイコンのないダイアログ", MB_OK);

	return 0;
}
```
CocoaPodsでrealmを入れようとして失敗したときに試したこと


#お題

realmを使ったtodoアプリを作る際にデータの永続化をしたかったので

swiftRealmを使うことにしました。

※realmとは、クラスで管理できる簡易データベースのようなものです。

viewController内で読み書きができ、手軽にデータベースを扱える点は

SQLiteを彷彿とさせます。このrealmに関する記事は別途で書きますので、

今回はインストール方法とその際に遭遇したエラーの解決法をメインに

進めます。

1.まず、CocoaPodsが使えないと先に進めないのでpod initでpodFileを作成

2.app（仮名）内直下にpodFileが生成されるのでファイルを以下のように修正

```swift:Podfile
target 'CheckList' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  //pod 'RealmSwift'を追加してRealmSwiftを入れるよう指示する
  pod 'RealmSwift'
end
```
その後に
3.pod repo updateでcocoaPodsのリポジトリを更新

4.pod install

ここまではok、だがpod Installをした段階で下記のエラーが発生

Realm` requires CocoaPods version `>= 1.10`, which is not satisfied by your current version, `1.9.3`.

これは、今のcocoapodsのバージョンが1.9.3であり、relamが求める

バージョン「1.10」に達していないために弾かれています。

pod updateコマンドでcocoaPodsをアップデートを試みると

以下のようなアナウンスが出てくる

```swift:Podfile
Update all pods
Updating local specs repositories

CocoaPods 1.10.1 is available.
To update use: `sudo gem install cocoapods`
```

どうやら、CocoaPods 1.10.1は「sudo gem install cocoapods」

コマンドでcocoaPodsをアップデートできるみたいなので

sudo gem install cocoapodsコマンドを入力する。

すると、色々なフレームワークが更新され、最後には緑文字で

Installing Realm (10.8.0)
Installing RealmSwift (10.8.0)

と出てくる。どうやら無事にインストールできたみたいです。

その後にpod installをすると、先ほどpodFile内に書いた

RealmSwiftがインストールできるようになります。

ひとまずこれでrealmをインストールするまでは上手くいきました。

次の記事では、realmの使い方を書きます。
Laravelの初期設定

# config/app.php

- アプリケーションの設定ファイル
 
```php
'timezone' => 'Asia/Tokyo',

'locale' => 'ja',
```

# app/Http/MiddleWare/TrustProxies.php
AWS上で正しく動作させるファイル

```php
protected $proxies = '*'; // 全てのプロクシを信頼する。
```

# データベースの作成

```
phpMyAdminからlaravel_diary_developmentを作成。
作成の際の照合順序はutf8mb4_unicode_ciを選択する。
```

# データベースの動作確認

```php
php artisan migrate
```

# エラーメッセージの日本語化

インストーラをダウンロード

```php
php -r "copy('https://readouble.com/laravel/6.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
```

resources/langフォルダにjaフォルダを追加

```php
php -f install-ja-lang.php
```

# ルーティング

```php

<?php

Route::get('/model_sample', 'SampleController@modelSample');

Route::get('/messages', 'MessageController@index');

Route::post('/messages', 'MessageController@store');
```

# コントローラー

```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

// Messageモデルをインポート
use App\Message;

class SampleController extends Controller{
  
      public function modelSample(){
      // Messageモデルを利用してid:1のmessageを取得
      $message = Message::find(2);
      return view('samples.model_sample', [
        'title' => 'モデルの使いかた',
        'message' => $message,
      ]);
    }
｝
```
Amazon DLMを使ってみた

#はじめに
本記事は、Amazon Data Lifecycle Manager(DLM)を使用した際の備忘録として記載したものである。

#Amazon Data Lifecycle Manager(DLM)とは

##■概要/特徴
* EBS スナップショットや  AMI の作成といったバックアップスケジュールを設定できるAWSサービスである。
* Amazon DLMを使用することで、バックアップの作成、保持、削除を自動化することができる。
* Amazon DLMで指定することができる最大世代数は1000である。
* 2020年3月のアップデートにより、1時間間隔のバックアップスケジュールを作成することが可能になりました。<br>https://aws.amazon.com/jp/about-aws/whats-new/2020/03/amazon-data-lifecycle-manager-adds-support-for-1-hour-backup-interval/

##■使用する上での注意点
* バックアップスケジュールで指定した時刻から1時間以内にバックアップ処理が実行される仕組みである為、 **バックアップで正確な時刻の指定はできない** 。<br>※【例】毎日12時にバックアップするようにスケジュールしても、12時半に取得されることがある。
* 指定する際の時刻はUTCの為、利用者側で日本時刻に修正して設定をする必要がある。
* Amazon DLMは、タグで対象を判別している為、タグが変更された際に検知するソリューションを別途用意する必要がある。<br>※ターゲットタグを削除または変更してポリシーを変更すると、それらのタグを持つ EBS ボリュームまたはインスタンスはポリシーの管理を受けなくなります。


#作業の実施手順

##(0)前提条件

* 実施環境はAWS CloudShellを使用するものとする。
* Amazon DLM用のIAMロールが既に作成済みであること。※無い場合は以下のコマンドで作成する。

```
# aws dlm create-default-role
```

* 本検証で使用するサーバー情報は以下となる。


|バックアップボリュームのNameタグ|バックアップ間隔|保管世代数|備考|
|:---|:---|:--|:--|
|TestServer_ｈ|00時00分|60世代|TestServerのHドライブのボリュームを毎日00時に取得するバックアップスケジュール|

##(1)バックアップスクリプトを作成

以下のバックアップスクリプトファイルを作成する。


```TestServer_HVolumeDailySnapshot.json
{
  "ResourceTypes": ["VOLUME"],
  "TargetTags": 
  [
    {
      "Key": "Name",
      "Value": "TestServer_ｈ"
    }
  ],
  "Schedules":
  [
    {
      "Name": "HVolume Daily backup",
      "CopyTags": true,
      "CreateRule": {
        "CronExpression": "cron(00 15 * * ? *)"
      },
      "RetainRule": {
        "Count":60
      }
    }
  ]
}
```

##(2)バックアップスケジュール(ライフサイクルポリシー)を作成

AWS CloudShellで、以下のコマンドを実行する。
※コマンド実行後、「Elastic Block Store > ライフサイクルマネージャー」にバックアップスケジュールが作成される。

```
aws dlm create-lifecycle-policy \
    --description "TestServer-HVolumeDailySnapshot" \
    --state ENABLED \
    --execution-role-arn arn:aws:iam::××××××××××××:role/service-role/AWSDataLifecycleManagerDefaultRole \
    --policy-details "file://TestServer_HVolumeDailySnapshot.json"
```

上記コマンドで指定した各種オプション

|オプション|説明|
|:---|:---|
|--description|ライフサイクルポリシー(バックアップスケジュール)の説明を記載|
|--state|ライフサイクルポリシーを有効/無効を指定。(ENABLED or DISABLED)|
|--execution-role-arn|対象のarnを指定|
|--policy-details|ライフサイクルポリシーの構成を設定|


#最後に

**■所感**

* バックアップスケジュールを作成する際に、タグ名の指定を間違えるとバックアップの処理に失敗するのだが、エラーメッセージなどは特に表示されなかったので、実施後は目視確認が必要だと感じた。
* 今回は、CLI(AWS CloudShell)で実施したが、コンソールでの設定に比べると汎用性が高く、複数台のバックアップスケジュールを作成するのに適していると感じた。
* 気軽にバックアップスケジュールを作成できるので、実用的だと感じた。
【Swift】APIを使って情報を取得するコードの詳細

#はじめに
この記事では、QiitaのAPIを使用した実装を例に挙げてそこで使用したメソッドの詳細を解説していきます。
⚠️当方初学のため認識違いがある可能性大です
誤りを見つけた際はコメントにて指摘していただけると幸いです🙇‍♀️🙇‍♂️


#参考記事
- [【Swift】Codableについて備忘録](https://qiita.com/s_emoto/items/deda5abcb0adc2217e86)
- [Codableについて色々まとめた[Swift4.x]](https://qiita.com/_ha1f/items/bf1aad5ea3e927f59f9d)
- [developer](https://developer.apple.com/)


#サンプルコード
以下のコードではQiitaのAPIから情報を取得しコンソールに出力しています。

```
import UIKit

struct Qiita: Codable　-①　{　

    let title: String
    let createdAt: String
    let user: User 
    
    enum CodingKeys: String, CodingKey　{ -②

        case title = "title"
        case createdAt = "created_at"
        case user = "user"
    }
}

struct User: Codable {

    let name: String
    
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
}

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        getQiitaAPI()
    }
    
    func getQiitaAPI() {
        guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=5")　 else {　 return }　-③
        
        var request = URLRequest(url: url) -④
        request.httpMethod = "GET"　-⑤
        
        let task = URLSession.shared.dataTask(with: url) {(data, response, err) in　-⑥
            if let err = err {
                print("情報の取得に失敗しました。：", err)
                return
            }
            
            if let data = data {
                do {
                    let qiita = try JSONDecoder().decode([Qiita].self, from: data) -⑦
                    for qiita in qiita {
                        print("タイトル：\(qiita.title)\n作成日：\(qiita.createdAt)\n\(qiita.user.name)")
                    }
                    
                } catch(let err) {
                    print("情報の取得に失敗しました", err)
                }
            }
        }
        task.resume() -⑧
    }
}
```

#目次
① Codable
② CodingKey
③ URL(string: )
④ URLRequest(url: )
⑤ .httpMethod
⑥ URLSession.shared.dataTask(with: url) { data, response, error in }
⑦ try JSONDecoder().decode()
⑧ .resume()


#① Codable
Codableとは、API通信等で取得したJSONやプロパティリストを任意のデータ型に変換するプロトコル。

```
typealias Codable = Decodable & Encodable
```
DecodableとEncodableどっちもにconformしたのがCodable。


#② CodingKey
CoodingKeyは、EncodeとDecodeでキー名が異なる時に一対一対応させる時に使用する。
case名をプロパティ名、rawValueをエンコード結果のフィールド名として定義する。


#③ URL(string: )
String型をURL型に変換している。


#④ URLRequest(url: )
URL型をURLRequest型に変換している。


#⑤ .httpMethod
URLRequest型のメンバ変数。
これを"Get"とすることで情報を要求している側という指定ができる（曖昧な理解）


#⑥ URLSession.shared.dataTask(with: url) { data, response, error in }
- URLSessionとは、関連するネットワーク上のデータ転送処理群をまとめるクラス。
- sharedとは、シングルトンのURLSessionインスタンス。
基本的なリクエストはこれを使えばデータの取得が可能となる。

この関数では、Dataオプジェクトを経由してデータの送受信を行い、無事値が帰ってきたらdataにそのレスポンスが渡され、エラーが発生した場合errorにエラーの詳細が渡される。


#⑦ try JSONDecoder().decode()
- JSONDecoderクラスとは、JSONオブジェクトからデータ型のインスタンスをデコードするオブジェクト。
- decode()は、第一引数に準備した型（Codableプロトコルに準拠した型）を指定し、第二引数には受け取ったJSONデータを指定する。
第一引数の型で指定したプロパティにJSONデータをデコードする。


#⑧ .resume()
処理を開始させるメソッド。
vscodeでxdebugでブレークポイントがうまく止まってくれない

#はじめに

MAMPを使用して環境構築しました。
バージョン
PHP: 7.4.12

vscodeでソースコードを読み込んで実行しています。


#xdebugを使うための設定

PHPのデバックツールにxdebugというものがあります。
MAMPをインストールした時点でxdebugもインストール済みという記事もありましたが、自分の場合はxdebugが入っていなかったので、手動でインストールしました。xdebugのインストールについては今回は割愛いたします。


xdebugはインストールしただけでは正常に動作しません。

まず、phpiniというPHPの設定ファイルに次のような追記が必要です。

```
[XDebug]
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_port = 9001
zend_extension = /Applications/MAMP/bin/php/php7.4.12/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so

```

もしかしたら、いらない設定も入っているかもしれませんが、　念の為自分が成功した設定状況をそのまま記載しています。

以下は補足説明になります。

```
xdebug.remote_port = 9001　
```
この箇所は、9000がいいという意見や、9001の方がいいという意見がありました。自分は９００１でやりましたが、9000でも大丈夫かもしれません。

```
zend_extension = /Applications/MAMP/bin/php/php7.4.12/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so
```

この箇所は、MAMP内のxdebug.soというファイルまでのパスを入力します。
私が使っている時点（2021/6/24）では、上記のパスにありました。
パス中の php7.4.12　の部分は、自分が使うPHPのバージョンを確認して入力します。

本来はこの設定で動くはずなのですが、自分の場合はこれだけではブレークポイントで止まってくれませんでした。

#ブレークポイントで止まってくれない問題

自分の場合、以下の方法で正常に作動しました。

launch.jsonに

```
"stopOnEntry": true
```
という一文を入れます。これだけでした。

最終的にlaunch.jsonの中身はこうなりました。

```
"version": "0.2.0",
  "configurations": [
  
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9001,
      "stopOnEntry": true
    }
  ]
```

xdebugで同じような点で躓いている方の参考になれば幸いです。
【Selenium】PythonでSeleniumを使う際に役に立つ(かも)Tips

# 概要
この記事ではPythonでSeleniumを使う際に役に立つ(かもしれない)Tipsを紹介していきます。

# webdriver-managerで最新のwebdriverを自動取得
Seleniumを運用する際に必要となるwebdriver、定期的に更新する必要があったりと面倒です。

そんな時に`webdriver-manager`を使用することで自動で対応したバージョンのwebdriverを取得してくれます！
使い方も非常にシンプルでdriverを定義する際に指定するだけ。

```python
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

# chromedriverのパスを指定する代わりにwebdriver_managerを呼び出す
driver = webdriver.Chrome(ChromeDriverManager().install())
```

また、Firefoxの場合は、

```python
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager

driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
```

シンプルですがめちゃくちゃ便利です。
保存先も邪魔にならない場所に置いてくれるのでディレクトリも散らかりません。

# 要素が存在するかチェックする
普通に`find_element`メソッドを使用すると要素が存在しない場合にエラーが返ってきます。

try exceptでも対応出来なくは無いですが、綺麗なやり方とは言えないので私は`find_elements`で要素の有無をチェックします。

```python
# 要素をリストで取得する(存在しない場合はリストの長さが0になる)
elements = driver.find_elements_by_xpath('有無を確認したい要素')

# 要素が存在しない場合
if len(elements) == 0:
    # 要素が存在しない場合の処理
else:
    # 要素が存在する場合の処理
```

# ファイルの保存先を指定する
Seleniumを使用してデータを保存したい場合に使用します。

```python
from selenium import webdriver

download_dir = "ファイルを保存したいディレクト"
options = webdriver.ChromeOptions()

# 保存先をchromeに適用
prefs = {"download.default_directory": download_dir}
options.add_experimental_option("prefs", prefs)

driver = webdriver.Chrome(options=options)
```

# 要素が読み込まれるまで待機する
サイトによっては要素の読み込みに時間がかかる場合があります。

そんな場合には`expected_conditions`を使用します。よくECと略されます。

```python
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

# 15秒まで待機するよう設定
wait = WebDriverWait(driver, 15)

# 要素を読み込むまで15秒待機(15秒経過しても読み込めない場合、Exception出力)
element = wait.until(EC.visibility_of_element_located((By.XPATH, "読み込みたい要素")))
```

# 操作するタブを切り替える
稀に別タブに切り替えて操作を行いたいというケースがあると思います。

そんな場合には`switch_to`を使用します。

```python
# 新しいタブに切り替える
driver.switch_to.window(driver.window_handles[1])

# 元のタブに切り替える
driver.switch_to.window(driver.window_handles[0])
```


また、新しいタブを閉じたい場合は以下のように行います。

```python
# 新しいタブに切り替える
driver.switch_to.window(driver.window_handles[1])

# 新しいタブを閉じる
driver.close()

# 元のタブに切り替える(これをしないと後の処理でエラー出ます)
driver.switch_to.window(driver.window_handles[0])
```

`driver.quit()`だとウィンドウごと閉じてしまうので間違えないように気を付けましょう。

# Tor Proxyを使用してwebdriverを動かす
<font color="Red">※悪用厳禁です。使用は自己責任でお願いします。</font>

まずTorブラウザを立ち上げ、右上の設定ボタン → Options → Tor → Advanced という順番に進み、下記のように設定します。
![tor_proxy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268562/332d1265-3499-430e-d11c-a7367bc92561.png)

次にTorブラウザを起動させた状態のまま、下記プログラムを実行します。

```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
 
options = Options()
# Torで設定したプロキシを指定する
options.add_argument("--proxy-server=socks5://127.0.0.1:9150")

# Tor Proxyを使用したchromedriverを起動
driver = webdriver.Chrome(options=options)
```

私は開発したwebアプリのアクセス制御の検証の際に使用しています。
Tor Proxyを使用する際は自分の管理下にあるサイトでのみ行うようにした方が良いかもしれません。

# 最後に
他にも便利な機能等ありましたら随時追加致します。

皆さんのオススメの機能がありましたらコメント欄で共有頂けますと幸いです！
日本語名のディレクトリ内でdocker-compose buildすると失敗する

## 概要
docker-compose buildを使用して、imageのビルドを行おうとしたら以下のエラーがでた。

```terminal
$ docker-compose build

Building web
invalid argument "_web" for "-t, --tag" flag: invalid reference format
See 'docker build --help'.
```

## 環境
mac OS Mojave バージョン10.14.6
Docker version 20.10.5
docker-compose version 1.29.0

## 解決方法
Dockerfileのあるディレクトリが「自動化」という名前であったので、「automation」に変更し、再度buildした。

```terminal
$ pwd
/Users/xxx/自動化
```

アルファベットのディレクトリではbuildが成功した。

```terminal
$ pwd
/Users/xxx/automation

$ docker-compose build
Building web
[+] Building 3.8s (6/6) FINISHED                                                                                                 
 => [internal] load build definition from Dockerfile                                                                        

~　省略 ~

Successfully built e63xxxxxxxxxxx
```

## いくつかのパターンで試してみた
ディレクトリ名を「自動化automation」とした場合は、buildが成功した。
ディレクトリ名を「じどうか」とした場合は、buildが失敗した。
ディレクトリ名を「❤️🌟」とした場合は、buildが失敗した。
ディレクトリ名を「ΨΩ」とした場合は、buildが失敗した。

ディレクトリ名がマルチバイト文字のみの場合失敗するのかもしれない。

## 使用したファイル

```dockerfile:Dockerfile
FROM python:3.7-slim-buster
WORKDIR /usr/src
```

```yml:docker-compose.yml
services:
  web:
    build:
      context: .
    volumes:
      - ./:/usr/src
    ports:
      - "3000:3000"
    tty: true```
Python Psd-Tools

今回は趣味で製作しているNscripterを使ったゲーム制作をする際に立ち絵が必要だったので
立ち絵を用意するためにいろいろ調べたので備忘録として残しておきます

使用するファイルは事前にPhotshopで開き名前を付けて保存
この際に互換性を優先するのチェックを外した状態で上書きします
こうしないとナゼカうまくいきませんでした（調査中）

ファイルの準備ができたら早速

```
'''モジュールをインストール'''
pip install psd-tools
```



環境の使用準備がこちら

```python:psdexporter.py
#’’’必要モジュールをインポート’’’
#’’’画像出力するファイルをオープン’’’
from psd_tools import PSDImage

file_path = '任意のファイル.psd'
psd = PSDImage.open(file_path)
```
以上で画像出力の準備が完了しました。

今回のモジュールは少々癖がありほどほどに苦戦させられました。

ひとまずテストで画像を出力します。

```python:psdexporter.py
from psd_tools import PSDImage

file_path = '任意のファイル.psd'
psd = PSDImage.open(file_path)

#’’’表示状態になっているレイヤーを統合した画像を出力’’’
psd.compose().save('任意パス.png')
```
今回は透過画像が欲しかったのでpngで出力
画像を出力する際にパスに書き込んだ拡張子を自動識別してファイルフォーマットを自動出力するようです
この時に出力される画像の状態についてですが、表示状態になっているレイヤーをすべてを統合して１枚の画像として出力します
ですが、いちいちペイントツールを立ち上げレイヤーを操作して保存してプログラムから出力していたら効率が悪すぎます
なのでペイントツールで編集などせずにプログラム上でレイヤーを操作してしまいましょう


PSDImageオブジェクトはレイヤー情報コレクションに持っていますのでこのようにFor文を使って設定していきます

```python:
from psd_tools import PSDImage

file_path = '任意のファイル.psd'
psd = PSDImage.open(file_path)

#’’’レイヤーをグループ（フォルダ）分けしている場合はグループ（フォルダ）を表示状態にしたうえで’’’
for rootlayer in psd:
    if rootlayer.name == '表示状態にするグループ（フォルダ）名'
        rootlayer.visible = True/False
　　    #’’’グループ（フォルダ）内のレイヤーを表示状態にします
        if layer.name == '表示状態にするレイヤー名'
            for layer in rootlayer:
                layer.visible = True/False
#’’’出力したい状態になるまで上記の条件分岐を書き込んでください’’’
#’’’絵師様が提供しているpsdを使う場合は一度ペイントツールでレイヤー構成やレイヤー名を確認しておくのが吉です’’’

#’’’作成したレイヤー構成でPILオブジェクトを発行して格納’’’
image = psd.compose()
#’’’PILオブジェクトが格納されていますのでこのままPILLOWで編集も可能ですが今回はそのまま画像をファイル出力します’’’
#’’’PILオブジェクトについてはほかの記事を参照されるほうがいいでしょう’’’

#’’’表示状態のレイヤーを画像として出力’’’
image.save('任意パス.png')
```

公式ドキュメントによればcomposeメソッドは実験段階のメソッドでありファイルの内容を完全に再現できない可能性がある旨の記事がありました
compose実行時に警告が表示されますが無視して実行してしまっても画像は出力されます

今回のスクリプトを描くにあたってこんなもの提供されている立ち絵を全パターン出力する以外での使用用途が見出せませんがまぁよしとしましょう
fanPressureによる出口境界条件の設定

# はじめに
OpenFOAM v8にて``fanPressure``を使った境界条件を設定しようとした際に、[公式ページ](https://cpp.openfoam.org/v8/classFoam_1_1fanPressureFvPatchScalarField.html)にある設定では動かなかったことから、ここに修正箇所を記録しておこうと思います。

# fanPressureとは

    This boundary condition can be applied to assign either a pressure inlet
    or outlet total pressure condition for a fan.

この境界条件をつかうと、圧力入り口条件、出口全圧条件を割り当てることができます。

# 設定方法: 0/p
```c++
    outlet
    {
        type            fanPressure;
        fanCurve        tableFile;
        facCurveCoeffs
        {
            file            "$FOAM_CASE/constant/pressureVsQ";
            format          csv;
            nHeaderLine     1;
            refColumn       0;
            componentColumns 1(1);
            separator       ",";
            mergeSeparators no;
            outOfBounds     clamp;
            interpolationScheme linear;
        }
        direction       out;
        p0              uniform 0;
        value           uniform 0;
    }
```
ここで気をつけなければいけないのは、公式ページでは``tableFileCoeffs``と記述されているところを、``fanCurveCoeffs``でないと設定を正しく読み込んでくれません。

これは[tableFile](https://cpp.openfoam.org/v8/classFoam_1_1Function1s_1_1TableFile.html)
のページにあるように、

```c++:tableFile
    <entryName> tableFile;
    <entryName>Coeffs
    {
        file                dataFile;    // name of data file
        format              foam;        // data format (optional)
        outOfBounds         clamp;       // optional out-of-bounds handling
        interpolationScheme linear;      // optional interpolation method
    }
```

となっており、``Coeffs``の設定は``<entryName>``を入れなければならないためです。

# fanCurveFileについて
`constant`以下に流量-圧力の関係を記述した設定ファイルを置きます。
上の設定では、`constant/pressureVsQ`というファイルを`csv`形式で、ヘッダー1行、カンマ区切り記述することになっています。

```c++:constant/pressureVsQ
pressureVsQ
1, 0.3
5, 0.1
```

などのように圧力と流量との関係を記述します。


# まとめ
OpenFOAM v8での`fanPressure`の設定方法をまとめました。
誤り等がありましたら、ご指定いただけると助かります。
DAX で新しいテーブルを作るときは、Generate のほうが分かりやすい

# 元ネタ
[Using GENERATE and ROW instead of ADDCOLUMNS in DAX](https://www.sqlbi.com/articles/using-generate-and-row-instead-of-addcolumns-in-dax/)

詳細はここを読んでもらうとして・・

# 自分がいいなと思ったところ
- Generate を使った方が変数で整理できて見やすく、後々修正するときにもわかりやすいかな、と
- わかる人にとっては、AddColumnsの方がSimpleに感じるのかもしれませんね。

```datastudio:generateSample
Calendar 5 = 
VAR BaseCalendar =
    CALENDAR ( DATE ( 2016, 1, 1 ), DATE ( 2018, 12, 31 ) )
RETURN
    GENERATE (
        BaseCalendar,
        VAR BaseDate = [Date]
        VAR YearDate = YEAR ( BaseDate )
        VAR MonthNumber = MONTH ( BaseDate )
        VAR MonthName = FORMAT ( BaseDate, "mmmm" )
        VAR YearMonthName = FORMAT ( BaseDate, "mmm yy" )
        VAR YearMonthNumber = YearDate * 12 + MonthNumber - 1
        RETURN ROW (
            "Day", BaseDate,
            "Year", YearDate,
            "Month Number", MonthNumber,
            "Month", MonthName,
            "Year Month Number", YearMonthNumber,
            "Year Month", YearMonthName
        )
    )
```
[generateSample](https://www.sqlbi.com/articles/using-generate-and-row-instead-of-addcolumns-in-dax/#code5)

```datastudio:addColumnsSample
Calendar 2 =
ADDCOLUMNS (
    ADDCOLUMNS (
        CALENDAR ( DATE ( 2016, 1, 1 ), DATE ( 2018, 12, 31 ) ),
        "Year", YEAR ( [Date] ),
        "Month Number", MONTH ( [Date] ),
        "Month", FORMAT ( [Date], "mmmm" ),
        "Year Month", FORMAT ( [Date], "mmm yy" )
    ),
    "Year Month Number", [Year] * 12 + [Month Number] - 1
)
```
[addColumnsSample](https://www.sqlbi.com/articles/using-generate-and-row-instead-of-addcolumns-in-dax/#code2)

# 背景
カレンダーテーブルを作ってた時、作り方が二種類あるのに気付いて、どういう違いがあるんだろう？と思って調べてみたら、英語サイトで解説があったので備忘録
bulk_insertより高速！？postgres-copyで大量データinsertしてみた

# はじめに

本記事では、postgres-copyの使い方とRails6から追加されたinsert_allのパフォーマンスの比較を行います。

# 環境
Ruby 2.6.6
Rails 6.0.3
Docker for Mac

# 前提

下記のテーブルを作成済みとします。

- postsテーブル

|name|type|description|
| --- | --- | --- |
|id|bigint|主キー|
|title|string|投稿タイトル|
|body|text|本文|
|created_at|datetime|作成日時|
|updated_at|datetime|更新日時|

# postgres-copyの導入

https://github.com/diogob/postgres-copy

まずはGemfileにpostgres-copyを追加します。

```ruby
gem 'postgres-copy'
```

その後bundle install(Dockerを使っています)

```
$ docker-compose run web bundle
```

次に、Postモデルにacts_as_copy_targetを追記します。

```ruby
class Post < ApplicationRecord
  acts_as_copy_target # 追加
end
```

これで、以下4つのメソッドがPostモデルに追加されます。

- copy_to
- copy_to_string
- copy_to_enumerator
- copy_from

今回使うのは`copy_from`のみになります。


# パフォーマンス比較

結論から申し上げると、copy_fromの方が早かったです。

10万行のCSVをinsertしてパフォーマンスを比較してみます。

## insert_all

```ruby
$ require 'csv'

$ now = Time.zone.now

$ rows = CSV.read('/app/tmp/test.csv', headers: true).map do |row|
  {
    id: row[0],
    title: row[1],
    body: row[2],
    created_at: now,
    updated_at: now
  }
  end

$ Benchmark.realtime do
    Post.insert_all(rows)
  end
=> 8.32
```

約8秒でインサートできました。

## copy_from

```ruby
$ Benchmark.realtime do
    Post.copy_from('/app/tmp/posts.csv')
  end
=> 4.33
```

こちらは約4秒ですね。

## 結果

|メソッド|実行時間(秒)|
| --- | --- |
|insert_all|8.32|
|copy_from|4.33|

ということで、copy_fromの方がおよそ2倍早いという結果になりました。

# 考慮すべきポイント

## created_at, updated_atが自動で挿入されない

これはinsert_allもcopy_fromも同じなのですが、ActiveRecordで普通にcreateする際に挿入されるcreated_atとupdated_atが自動で挿入されないので、insert_allであれば、ハッシュの値に入れる必要があります。
copy_fromでは、created_atとupdated_atの列と値を用意する必要があります。

## 不正データのバリデーション

### 重複データ

insert_allは重複データがあった場合に無視します。なので、実務ではinsert_all!の方を使うことになるかと思います。(insert_all!の場合、レコードの重複があったら、ActiveRecord::RecordNotUniqueの例外がraiseされます)

copy_fromも同様に、重複データがあっても例外は上がりません。

### 値が不正なデータ

insert_allもcopy_fromも、Railsのモデルにvalidationを設定していてもバリデーションがスキップされます。

そのため、取り込むデータを作成する段階で、正しい値のみを入れておく必要があります。

https://railsdoc.com/page/insert_all

## 子レコードの同時インサート

### activerecord-importだとrecursiveオプションがある

insert_allもcopy_fromも、子レコードの同時インサートには対応していません。なので、同時インサートが必要なテーブル構成の場合は、activerecord-importを使わざるを得ないのかなと思っています。。。

MySQLにはrecursiveオプションはありませんのでご注意ください。

https://patorash.hatenablog.com/entry/2020/07/10/111139

# まとめ

実用的には大量seedデータ投入の高速化に用いるくらいかなとは思いました。

そのseedデータ作成もカラム追加するごとにメンテが必要になるので、運用面も考えると少々面倒かなとか思ったり、、、

ともあれ、insertそのものが早いのは事実なので、活躍の場を与えてあげたいものです。

# icare開発者ブログもよろしくね！

https://dev.icare.jpn.com/dev_cat/
コンテナとコレクション

# これは何？

C++ の vector とかは「コンテナ」。
Java の List とかは「コレクション」。

こういう言葉遣いって他はどうなってるのかなと思って、軽く調べて列挙してみた。

## コンテナ

* C++ の STL コンテナ
* go の heap, list, ring のパッケージ名が container

こうしてみると、コンテナは少数派っぽい。

## コレクション

* Java のコレクションクラス
* .NET Framework のコレクションクラス
* Rust の `std::collections`
* go の [sort](https://golang.org/pkg/sort/) の説明が「Package sort provides primitives for sorting slices and user-defined **collections**.」となっている。
* [Swift Standard Library](https://developer.apple.com/documentation/swift/swift_standard_library) を見ると、配列や辞書のことを collection と呼んでいる。
* Dart の Deque とか List は collection ライブラリに入っている。

だいたいみんなこっちなんだなと思った。

## コレクションとコンテナ

* [Python で deque とかが入っているライブラリを説明する資料](https://docs.python.org/3/library/collections.html) の冒頭に「collections — Container datatypes」とある。
* Julia で、[append!](https://docs.julialang.org/en/v1/base/collections/#Base.append!) の説明に「For an ordered container collection, add the elements of each collections to the end of it.」とある。

この例を見ると、英語ネイティブの方々はわりとどうでもいいと思っているのかな、と思うけどどうなんだろ。

## アグリゲート

* C/C++ で、配列・構造体・共用体 の総称。日本語だと「集成体」。

## まとめ

コンテナは少数派、だいたいみんなコレクションっぽい。

新しくそういう構造を作る場合、その言語などの文化圏にあった名前を使うのが良いと思う。

そういう意味で、C言語は困る。C言語で（事実上）標準となっているそういうものはたぶんないので、良さげな名前を勝手に決める必要がある。
Buefy placeholderが効かない件



# 概要


![SS_ 2021-06-24 21.44.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646901/55570f39-df55-1ce9-4755-0a50b49891af.png)


上記のようなデザインを実装するために
[Buefy公式ドキュメント](https://buefy.org/documentation/datepicker/)を参考に実装。(コピペ)



```js:pug
b-datepicker(
  ref="datepicker"
  expanded
  placeholder="Select a date"
)
```

しかし、実際に表示されたのは以下のデザインで、
公式ドキュメントのような実装にならない。


![SS_ 2021-06-24 21.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646901/1615bb13-be3e-ebba-d467-66f1285bf5fb.png)


何よりplaceholderがが効いていないのが一番気になる。
なぜか`年/月/日`と表示されている。
(なぜか右端にカレンダーアイコンも表示されている)

期待する動きは`placeholder="Select a date"`と設定しているので`Select a date`が表示されていて欲しい。


# 解決策



```js:pug
b-datepicker(
  ref="datepicker"
  expanded
  placeholder="Select a date"
　　:mobile-native="false"
)
```
上記のコードのように`　:mobile-native="false"`を追加すると期待するデザインになりました

![SS_ 2021-06-24 21.53.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646901/b28b22a5-b130-64cd-14b0-a7d9c605b682.png)



# 参考文献

https://github.com/buefy/buefy/issues/1183
https://github.com/buefy/buefy/issues/889
vscode + wsl2 + docker での作業

最近のvscodeはリモートに接続していろいろできるらしいと聞いてお試ししてみる

## wsl2 インストール

この記事の記述に従ってwsl2をインストール
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

最後に適当なディストリインストールする。この記事では Ubuntu 20.04を使用する。

## docker for windows インストール

この記事の記述に従って docker for windows をインストールする
https://docs.docker.jp/docker-for-windows/install.html

wsl2 も docker for windows 基本的にはデフォルトのオプションでOK

## wsl2 設定

一部のコンテナでは メモリが足らないと起動しなかったり起動後動作がおかしかったりするのでその設定。

%UserProfile% に `.wslconfig` ファイルを作成する。

```
[wsl2]
memory=4GB
swap=0
```

## vscode でリモートのディレクトリを開く

wsl2マシンからvscodeを開く。

ubuntu コンソールを開き以下のコマンドを実行する
(ホスト名、ユーザー名はubuntu初回実行時に決定されている)

```
okada@BETA:~$ mkdir sample
okada@BETA:~$ cd sample
okada@BETA:~/sample$ code .
okada@BETA:~/sample$
```

これでリモートwslに接続したvscode が開く。

## container 設定

お試し用の nginx を実行してみる

### ディレクトリ構成

単純に index.html を表示するだけの構成。

```
sample/
    nginx/
        config/
            default.conf
        public/
            index.html
    docker-compose.yml
```

### docker-config.ymlを書く

```yml
version: '3'

services:

  web:
    image: nginx:latest 
    ports:
        - "80:80"
    volumes:
        - ./nginx/public:/var/www/html
        - ./nginx/config/default.conf:/etc/nginx/conf.d/default.conf
```

config と表示用htmlを準備する。

### container 設定を生成する

ネットに転がってる解説では  ".devcontainer を作って config書きましょう" が主流だけど vscode で作れる。

vscode と wsl を接続した時点で、vscodeウインドウの左下に  "wslでの編集" リンクがあるのでクリックすると関連メニューが表示される。

![vscode-sample.png](/knowledge/open.file/download?fileNo=447)

メニューから "Add Development Container Configuration File..." > "From docker-compose.yml"  を選択すると関連ファイルができる。

この時「devcontainerがあるけど実行する？」みたいなメッセージが表示されるけどいったん無視

### dev container 内にできた docker-compose.ymlを変更する

nginx はデーモンモードで起動する必要があるけど、生成されたファイルだと勝手に終わるとか待ちすぎるとかで サイトにつながらない。
なので生成された docker-compose.yml を調整する

.devcontainer/docker-compose.yml を編集。

```yml
 # Overrides default command so things don't shut down after the process ends.
 # この行を削除する
 #  command: /bin/sh -c "while sleep 1000; do :; done"
```

## コンテナ実行

wsl メニューから "Reopen in Container" を選択する。

## 確認

http://localhost/index.html をブラウザで表示する

## その他の記述

### ファイル共有関連

windows ファイルシステムでcontainer 作ると "共有ファイルは遅いけどいいの？"みたいなメッセージが表示されるけど、このやり方だとそういうのはない。
windowsから実行するよりは wsl経由で実行したほうが良いのかも。

### windows から関連ファイルを直接参照する

wsl がスペシャルなファイルシステムでマウントされているようで、 c:\... ではなく `\\wsl$\Ubuntu-20.04\home\okada\sample` みたいな場所にファイルが存在する。vscode でなくほかのエディタ等を使いたいならそっちから触ることになるのかも。
【HTML＆CSS】アンカータグについてまとめてみた

○アンカータグについて

アンカーとはそもそも錨のこと
同じページ内のリンクの飛び先を指定するもの

hrefリンクの飛び先を指定し、
id属性にてページの中にある特定部分について名前をつける


**`<li>`タグのPortfolioから`<h3>`タグのPortfolioに飛ばしたい!!**


手順は以下の通り
①リンクをつけたい場所に`<a href="#title名">title名</a>`を入力
②リンクを飛ばしたい箇所のタイトルに`<a　id ="title名">title名</a>`を入力


上記の例でいうと
BEFORE

``````````<header>
   <div class="logo">
　　　　　　　　　　<img src="no_image.png" alt="#"></div>
   　　<div class="nav">
   　　<ul>
   　　 **<li>Portfolio</li>**
  　　 </ul>
   </div>
   </div>
   </header>
````````
AFTER

``````````<header>
   <div class="logo">
　　　　　　　　　　<img src="no_image.png" alt="#"></div>
   　　<div class="nav">
   　　<ul>
   　　 **<li><a href="#Portfolio">Portfolio</a></li>**
  　　 </ul>
   </div>
   </div>
   </header>
````````


BEFORE 

      <div class = "box1">
        ＊＊<h3>Portfolio</h3>＊＊
        <p>It is a long established ~~~~~</p>
      </div>



AFTER

      <div class = "box1">
        ＊＊<h3><a id ="Portfolio">Portfolio</a></h3>＊＊
        <p>It is a long established ~~~~~</p>
      </div>


これでページ内でリンク先に飛ばせるようになりました！！
Rials いいね・コメント・フォロー・メール・チャットのテーブル設計


#ユーザーと投稿物（book）

```.rb
  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.string "name"
    t.text "introduction"
    t.string "profile_image_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

  create_table "books", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.integer "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

```

# いいね機能


```.rb

  create_table "favorites", force: :cascade do |t|
    t.integer "user_id"
    t.integer "book_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

```

# コメント機能

```.rb

  create_table "book_comments", force: :cascade do |t|
    t.text "comment"
    t.integer "user_id"
    t.integer "book_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

```

# フォロー機能

```.rb 

  create_table "relationships", force: :cascade do |t|
    t.integer "follower_id"
    t.integer "followed_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

```

#　メール機能（+アドレス機能）

```.rb

  create_table "mail", force: :cascade do |t|
    t.integer "user_id"
    t.integer "target_user_id"
    t.integer "target_user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "adrresses", force: :cascade do |t|
    t.integer "from_user_id"
    t.integer "to_user_id"
    t.string "title"
    t.text "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

```

# チャット機能
LINEのように相互に、時系列も分かるようなビューを搭載するなら、chat_roomという概念を入れたほうがわかりやすい。
メールは、誰々からのメッセージを見ると言った感じで、受信履歴（相手からのみ）を見る。
対して、チャットルームを導入すれば、そのチャットルームを上から順に出力すれば、勝手に相互時系列になる。

```.rb

  create_table "caht_rooms", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "chat_room_users", force: :cascade do |t|
    t.integer "chat_room_id"  # どこで
    t.integer "user_id"     # 誰が（いる）
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "chat_messages", force: :cascade do |t|
    t.integer "chat_room_id" #　どこで
    t.integer "user_id" # 誰が
    t.text "body"     # 何言った
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end


```
サーバーのストレージがマッハだと思ったらlogだった件

# はじめに
linuxサーバーでnodeで作ったsiteを公開していたら、pm2のlogが溜まっててストレージを食いつぶしていたのでこれをなんとかしたくなりました。

## サーバースペック
OS: Ubuntu18.04
あとの情報は今回の記事には関係なさそうなので割愛

# サーバーのストレージがやばい！
ある日、サーバーを監視していると、どうやらファイルの変更などができなくなっていました。
ファイルを変更しようとしたりすると、以下のようなメッセージが。

```terminal
Can not change file: No space left on device
```

というわけで、対処していきます。

## 状態の確認
とりあえず、状態を確認します。

```nginx
df -aTh
```

あたりで実行します。

## 原因ファイルの特定
ストレージがやばいことは分かったので、原因ファイルを探します。`du`コマンドをいじってみます。

```nginx
du -sh * | sort -nr
```

とか

```nginx
du -d1 -h <ディレクトリ>
```

あたりを確認しました。

```terminal
user: $ du -d1 -h ~/
XM    /home/user/hoge
XK    /home/user/fuga
：
：
：
X0G   /home/user/.pm2
XXG   /home/user

user: $ du -d1 -h ~/.pm2
X0G   /home/user/logs
（略）
```
ろぐ。。。？？？
もう少し詳しく確認したところ、あるnodeアプリケーションの起動中のエラーログが溜まりに溜まって、何十GBにも膨れ上がっていました。

## 原因の撲滅
とりあえず当該ファイルを削除します。
あと、この際にdbとかが停止していることがあるので、その場合は再起動しておきましょう。

## 再発防止
エラーが出ないようなコーディングをすることは当然として……
pm2のログが必要以上に溜まらないようにしましょう。

そこで登場するのが**pm2-logrotate**です。こいつを使って、一定以上の容量を超えたログファイルを削除するようにします。

# pm2-logrotateの導入
## pm2-logrotateって
[https://www.npmjs.com/package/pm2-logrotate](https://www.npmjs.com/package/pm2-logrotate)

## とりあえず全部止めておこう
```nginx
pm2 stop all
```

## インストールします
```nginx
pm2 install pm2-logrotate
```

## 起動
rootじゃないとだめならsudoしましょう。

```nginx
sudo pm2 logrotate -u user
```

## 確認
ここで起動できているはずなので確認します。

```nginx
pm2 report
```

なんか動いていたら成功です。

## 設定
とりあえず以下のコマンドで確認できるはずです。

```nginx
pm2 get pm2-logrotate
```

### 最大ファイルサイズ
```nginx
pm2 set pm2-logrotate:max_size 1G
```
単位は何も書かなければBとなり、K/M/Gまで設定できます。

### retain数
```nginx
pm2 set pm2-logrotate:retain 50
```

デフォだと20になっています。ここで指定した数だけログファイルが生成されると思っておけばよいでしょう。
この数を超えると更新が古いものから順に消えていきます。
`all`としておけばアプリケーションの分だけ残るはずです。

### その他の設定
```terminal
┌────────────────┬─────────────────────┐
│ key            │ value               │
├────────────────┼─────────────────────┤
│ max_size       │ 10M                 │
│ retain         │ all                 │
│ compress       │ false               │
│ dateFormat     │ YYYY-MM-DD_HH-mm-ss │
│ workerInterval │ 30                  │
│ rotateInterval │ 0 0 * * *           │
│ rotateModule   │ true                │
└────────────────┴─────────────────────┘
```

この左の部分が設定内容になります。
上のような感じで設定できます。
詳しくは公式ドキュメントを読みましょう（英語ですが）。

## pm2の再起動
最初に止めたものはこの段階で再起動しましょう。
なんか消えていれば、以下を実行すれば何とかなるかもしれません。
たいてい何とかなります。

```nginx
pm2 resurrect
```

# まとめ
logファイルだと思って油断していると、思わぬほど容量を食うことがあります。
それを防ぐためには、logrotateが有効です。