OmniAICreator/Qiita-1.07M huggingface dataset:
kubernetesでファイルシステムのグループを指定する


## yaml

```fsgroup.yaml
apiVersion: v1
kind: Pod
metadata:
  name: fsgroup
spec:
  securityContext:
    fsGroup: 101
  containers:
  - image: nginx:1.19
    name: nginx-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
```

## fsgroupを付けた場合
- グループはnginx(GIDが101)

```
~ ❯ kubectl-iexec fsgroup                                       Tue Jun  8 10:01:53 2021
# ls -ld /cache
drwxrwsrwx 2 root nginx 6 Jun  8 01:01 /cache
#
```

## fsgroupをつけなかった場合
- グループはrootに

```
~ ❯ kubectl-iexec fsgroup                               655ms  Tue Jun  8 10:03:08 2021
# ls -ld /cache
drwxrwxrwx 2 root root 6 Jun  8 01:03 /cache
#
```

ぼくがはまったのは、PVCをマウントしようとしたときに、SecurityContextをつけずにやっていたのだけど、そうするとアプリケーションがマウントしたファイルシステムへの書き込みができずに、PodがRunnnigとErrorをひたすら繰り替えずという事象になった。
JavaScriptの読み込まれる・実行されるタイミング

#リクエスト→レスポンス→レンダリングまで

[ブラウザのネットワークレイヤー]
①ブラウザがサーバーにリクエスト(HTMLとCSSとJSをおくれ)
②サーバーがHTMLファイルを生成(作るから待って)
③レスポンスが返ってくる(HTMLとCSSとJSファイルをダウンロード)
[レンダリングエンジン]
④最初にhtmlを読み込むと、windowオブジェクトが生成される(widowオブジェクトは各ページごとにあるお)
⑤windowオブジェクトのプロパティとしてDocumentオブジェクトがある。DocumentオブジェクトがhtmlをパースしてDOMツリーを作っていこうとする
読み込み状況を示す文字列を返すreadyStateプロパティがあり、この時の文字列はloading
⑥パースはhtmlの上から順に行われていく。div, h1, ul, liなどの各要素はNodeと呼ばれる。レンダリングエンジンはNodeをDOMツリーに追加していく(documentオブジェクトが根Node)
⑦この時、script要素があるとそのコードをパースし、エラーがなければ同期的に実行する。つまり、JavaScriptの実行が終わるまで、htmlのパースが一時停止される。ここのJSの実行はJavaScriptエンジンで行われる。
⑧htmlが全てパースされ、DOMツリーが完成すると、readyStateプロパティはinteractiveになる
⑨ブラウザはDocumentオブジェクトに対して、DOMツリーの構築完了を告げるDOMContentLoadedイベントを発生させる
⑩imgなどの外部ソースを読み込み、すべての読み込みが完了した時点でdocument.readyStateプロパティはcomplateになる

最後にブラウザは、Windowオブジェクトに対してloadイベントを発生させる

[JavaScriptエンジン]
JavaScriptの実行は同期的に行われると言ったが、非同期に行う方法も存在する。
①ASYNC、DEFERこの辺りがよく使われるんじゃないか
非同期に実行するため、HTMLのレンダリングが一時停止せずに、ユーザーに少しずつ画面を表示(線画)できる
二項分布を正規分布の形で近似する

## はじめに
二項分布と正規分布が一致する条件を調べる。

## 二項分布

```math
P(X=k)={ }_{n} \mathrm{C}_{k} p^{k}(1-p)^{n-k} \quad(k=0,1,2, \cdots, n)
```

について`p=1/2`、`n=100`とすると

```math
P(X=k)= \frac{{ }_{100} \mathrm{C}_{k}}{2^{100}} \quad(k=0,1,2, \cdots, n)
```

## 正規分布

```math
p(x)=\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{(x-\mu)^{2}}{2 \sigma^{2}}}
```

について`μ=50`、`σ=5`とすると

```math
p(x)=\frac{1}{5\sqrt{2 \pi }} e^{-\frac{(x-50)^{2}}{50}}
```

## プロットしてみる
```python
from numpy import random
import matplotlib.pyplot as plt
import seaborn as sns

sns.set()
sns.kdeplot(random.normal(loc=50, scale=5, size=100000), label='normal')
sns.kdeplot(random.binomial(n=100, p=0.5, size=100000), label='binomial')

plt.legend()
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/996549c3-dc41-bd8b-9d82-34aebae8d623.png)

## 二項分布を正規分布の形に近似する
[スターリングの公式](https://k-san.link/binomial-normal/#Stirling8217s_formula)を使うと次の近似が成り立つ。

```math
\frac{n !}{k !(n-k) !} p^{k}(1-p)^{n-k} \approx \frac{1}{\sqrt{2 \pi n p(1-p)}} \exp \left\{-\frac{(k-n p)^{2}}{2 n p(1-p)}\right\}
```
[基礎]rebase(リベース)したときのコンフリクトの解消方法

#はじめに
git mergeと違ってリベースをしたときのコンフリクトは各コミットごとに起こるため若干厄介です。
その対処法を見様見真似でやってみたので、こちらでまとめます

#準備

まずは準備です。
ブランチを用意して、それぞれで作業していきます

```:terminal
% git br
* master
 % git br test
 % git br
* master
  test 
```
<masterブランチ側での処理>

```index.html
<p>master側の処理です</p>
```

```:terminal
% git add index.html
% git commit -m "masterでの処理"
```

<testブランチ側での処理>

```index.html
<p>test側の処理です</p>
```

```:terminal
% git add index.html
% git commit -m "testでの処理"
```

#リベースしていく

さっそくリベースしていきます。まずtestブランチで以下を叩きます

```:terminal
git rebase master
```

すると以下のような表示が出ます。

```
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
error: could not apply c2657f6... test側での処理
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply c2657f6... test側での処理
```

コンフリクトですね。さっそく手元のコードを見てやります。

```index.html
<<<<<<< HEAD
<p>masterでの処理です</p>
=======
<p>test側での処理</p>
>>>>>>> c2657f6 (test側での処理)

```

今回はあえて次のように処理してやります。

```index.html
<p>喧嘩両成敗！！</p>
```

そして、コミットします。

```:terminal
git add index.html
git commit -m "リベースのコンフリクト解消1"
```

git statusして状態を見てやリましょう

```:terminal
interactive rebase in progress; onto 6d9705c
Last command done (1 command done):
   pick c2657f6 test側での処理
No commands remaining.
You are currently editing a commit while rebasing branch 'test' on '6d9705c'.
  (use "git commit --amend" to amend the current commit)
  (use "git rebase --continue" once you are satisfied with your changes)

nothing to commit, working tree clean
```

ご丁寧に次にないすべきか書いてあります。
今回はコンフリクトを解消したので、続行させます。

```:terminal
% git rebase --continue
Successfully rebased and updated refs/heads/test.
```

よし！！成功！

次にmasterブランチに行きます。

masterブランチでマージしてやります

```:terminal
git merge test
```

#おわり

コンフリクトは怖いですが絶対にわけわからん！ということはないはずなので落ち着いて対応しましょう！
ウェブサイトにおけるマイクロインタラクション 

# 1）定義
マイクロインタラクションとは、直訳すれば「小さなやりとり」という意味になります。
Dan Saffer氏の著書「マイクロインタラクション ー UI/UXデザインの神が宿る細部」によれば
>「単一のシナリオに基づいてひとつの作業だけをこなす最小単位のインタラクションのこと」のことであり、
ユーザーのアクションに対するフィードバックやステータスの変化を正しく伝えるための細かなデザインのこと

とのことです。

https://www.amazon.co.jp/dp/4873116597?tag=check_amazon-22&linkCode=ogi&th=1&psc=1

# 2）目的
マイクロインタラクションの目的は**「ユーザーのアクションに対するフィードバックや、現在のステータスを正しく伝える」**ということです。
具体的には
　①アクションに対するフィードバックを伝える
　②タスクの進行状況を伝える
　③現在のステータスを伝える
　④新着情報を伝える
　⑤エラーの発生を伝える
などがあげられます。

# 3）マイクロインタラクションとUX
マイクロインタラクションを採用することによりユーザーにいい印象を与えられれば、ユーザーのエンゲージメントが上がり、離脱率の低下を期待できます。
したがっって、いかにわかりやすくユーザーの目的を達成できるようにするかがマイクロインタラクションにとって重要になります。

#4）実装
CTAボタンにマイクロインタラクションを追加する例を説明します。
（これは「①アクションに対するフィードバックを伝える」の例です）
![animationBtn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1555848/79abdaa6-b0a7-1d4d-b6d5-3d7c7af26235.gif)
cssは以下の通りです。

```ruby:CSS
.btn a {
    color:#fff;
    background-color: blue;
    transition:all .3s ease-out;
}
.btn a:hover {
    color:blue;
    background-color: #fff;
}

```
マウスが乗っていない時には背景色が青、文字色が白
マウスが乗ったら背景色が白、文字色が青に変化していきます。
同時に、マウスオーバーする前のa要素に対して、transitionプロパティを記載することで
変化にアニメーションを加えることができます。


**transition : [変化対象のプロパティ] [変化時間] [変化の仕方];**

変化対象のプロパティ：all（transitonプロパティの全てのプロパティ）
変化の始まりから終わりまでの時間：.3s（0.3秒）
アニメーションの変化の仕方：ease-out（開始が速く終了がゆっくり）

ボタンの上にカーソルを持ってきた時、ボタンと文字色が変化することで、このボタンがクリック可能な要素であるということをユーザーに示しています。
php-jwtを使って認証付きAPIの実装方法

# php-jwtを使って認証付きAPIの実装方法

# 概要

ホストAからホストBへの通信で勝手アクセスを防ぐため
アクセスキーを持つプログラムだけが実行できるようにする。

# php-jwt導入

php-jwtをcomposerを使いダウンロード

```bash
$ composer require firebase/php-jwt
```

[firebase/php-jwt](https://github.com/firebase/php-jwt)

# サンプルコード

サンプルは最近案件で使っているのでCodeigniterベース🙇‍♂️

*JWT_Test.php*

JWT::encodeでAPP_SECRET_KEYを使いエンコードを行う
JWT::decodeでAPP_SECRET_KEYを使いデコードを行う

```php
use Firebase\JWT\JWT;

const APP_SECRET_KEY = "xxxxxxxxxx";

class JWT_Test
{
    /**
     * APP_SECRET_KEYを使い暗号化を行う
     */
    function encode()
    {
        $payload = array(
            "iss" => "xxx",
            "aud" => "xxx/xxx",
            "iat" => time(),
            "exp" => time() + 3600
        );

        $jwt = JWT::encode($payload, APP_SECRET_KEY);

        return $jwt;
    }

    /**
     * APP_SECRET_KEYを使い復号化を行う
     */
    function decode($jwt)
    {
        $decoded = JWT::decode($jwt, APP_SECRET_KEY, ['HS256']);

        return $decoded;
    }
}
```

*Welcome.php*

Guzzleを使いAPIリクエストを行うSSL認証のサイトにアクセスする場合、
`'verify' => FCPATH.'cacert.pem'` が必要、cacert.pemは以下
Authorizationヘッダーにエンコードしたtokenを付けてアクセス
リクエスト先はAuthorizationヘッダーを取得デコード可能な場合のみ処理を継続
[curl - Extract CA Certs from Mozilla](https://curl.se/docs/caextract.html)

```php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->model('JWT_Test');
    }

    /**
     * 本体側 Guzzleを使いヘッダーにトークン付きリクエストを行う
     */
    public function jwt_request()
    {
        $token = $this->JWT_Test->encode();
        $client = new GuzzleHttp\Client([
            'base_uri' => 'https://xxx.xxx.xxx/',
            'verify' => FCPATH.'cacert.pem'
        ]);
        $headers = [
            'Authorization' => $token,
            'Accept' => 'application/json',
        ];

        $response = $client->request('GET', '/sample-acc/welcome/jwt_request_decode', [
            'headers' => $headers
        ]);

        var_dump($response->getBody()->getContents());
    }

    /**
     * レスポンス側 ヘッダーのトークンが復号化可能な場合に処理を継続
     */
    public function jwt_request_decode()
    {
        $headers = apache_request_headers();
        $token = $headers['Authorization'];

        try {
            $result = $this->JWT_Test->decode($token);
            echo json_encode($result);
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
}
```

---

いいね！と思ったら LGTM お願いします :clap::clap::clap:

【PR】週末ハッカソンというイベントやってます！ → https://weekend-hackathon.toyscreation.jp/about/
バックエンドとフロントエンドでREST APIスキーマを簡単に共有する。【OpenAPI】

かなり今更感が強いですがOpenAPIについて薄い記事を書きます。

OpenAPIはRest APIのスキーマを定義する規格ですが、それをもとに自動でAPIのドキュメントを生成したり
API ClientのSDKを自動生成することができます。（APIリクエストするコードを描く必要はありません。）

REST APIのスキーマを開発前から定義しておくことでバックエンドの開発を待たずに
フロントエンドの開発を進めることも可能です。
フロントエンドのAPI Client SDKはAxios、Fetch、Redux-queryなどメジャーなものはほぼサポートされています。

また、バックエンド側でStubを利用してOpenAPIのスキーマを自動生成することも可能です。
サーバー側のStubが利用可能なフレームワークは以下の通りです。
 
自動生成されたAPIのドキュメント（Swagger）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181998/1259cfae-c6a3-a643-346d-0b4280691830.png)
 

公式Ebookたち
https://drive.google.com/drive/folders/1noArns8WacpJM7TG5ojkiii6BLMWNqVN

公式Github
https://github.com/OpenAPITools/openapi-generator#overview

よさげなQiita
https://qiita.com/amuyikam/items/e8a45daae59c68be0fc8#openapi
敬意(Respect)のあるスクラム

スクラム開発において互いのメンバーへの敬意は大切とされます。

しかしながら
必ずそうなるとは限りません。
逆に言えば、そうなることを他のメンバーに期待してはいけないとも言えます。

「敬意は先に示す」ものとも思いますが
なかなか難しいですね

それでも
お互いの敬意が感じられない場合は

それもまた
1つのチームなのではないでしょうか。

大切なのは
「必ずそうなるとは限らない」
ことを(いつまでも)受け入れられないことをやめる

ではないかと思っています

お互いが敬意のあるスクラムをやっているに越した頃はありませんが
現代はVUCA(変動の大きい)時代と言われています

いつまでも
同じ(健全であれ健全であれ)チームに属していることの方が
稀なのではないでしょうか

そういった渦中にあって
相手に何かを期待するスタンスは
とても各人の依存度が高く(危険であるように私は思いました
最近Swift書いている時に気をつけている基本的なこと

## 初めに
人によっては当たり前すぎとなるようなことかもしれませんが書き記しておきます。
今後自分が成長するにつれてどんどんこの記事が膨れ上がっていくかもしれません
## 共通化
これはまじで当たり前かもしれませんが、コードを何かたす際や修正する際に常に他の所でも使えるように共通化できないか考えます。
例えば最近だとAPIを叩いている時に薄暗い画面にローディングインジケーターを出すタスクをしたのですが、その場合はViewControllerに直接書くのではなく、Utilフォルダなどにローディングインジケーターをスタートさせたり、ストップさせたりするクラスやプロトコルを作っておくみたいな感じです。
他にも色々な画面で使いそうなalertだったりサインインやサインアップで使用するvalidationなど共通化できるものは様々です。

## 文字列をハードコードしない
これも当たり前なのですが、rswiftなどを駆使して文字列は直接書き込まないようにしています。おそらく企業が運営しているアプリなどではほとんど文字列を直接書き込んだりしないでしょう。
ただrswiftなどを使わずに定数などを使って管理する文字列もあったりとそこはプロジェクトによりけりだと思います。

## swiftの関数について理解しておく
これは自分の最近あったことで言うと
```pushViewController```など画面遷移で使う関数のcompletion引数はdefaultでnilが設定されているので何もしない場合省略でいいのですが、そうとは知らずにnilを毎回わざわざ代入してしまってました。
恥ずかしい笑
このようにいつも使用している関数などもっと簡潔に書けるかもしれないなど気をつけて行こうと思いました。
## 後日増えていきます
ここからはおそらく今後どんどん増えていきます
VS Code 1.45 の新機能 - ワークベンチ内のフォーカス移動コマンドの追加

https://code.visualstudio.com/updates/v1_45#_accessibility

ワークベンチ内のフォーカスを移動するコマンドが追加された。

**表示: 次の部分にフォーカス(View: Focus Next Part)**（`F6`）
**表示: 前の部分にフォーカス(View: Focus Previous Part)**（`Shift`+`F6`）

`F6`を押す度にフォーカスが `エディタ`->`パネル`->`ステータスバー`->`アクティビティバー`->`サイドバー` と切り替わる。`Shift`を押しながらだとその逆向き。
ただしサイドバーやパネルを閉じている時はそれらへのフォーカス移動はスキップされる。
同様に、設定でステータスバーやアクティビティバーを非表示にしている時もそれらへのフォーカス移動はスキップされる。

各エリア内のフォーカス移動は矢印キーで行う。
現場で役立つシステム設計の原則　まとめ

備忘のためのメモです。

## １.小さくまとめてわかりやすくする

- オブジェクト指向設計は変更を楽で安全にする工夫
- コード整理の基本は名前と段落
- 短いメゾット、小さなクラスを使ってコードを整理する
- 値オブジェクトでわかりやすく安全にする
- コレクションオブジェクトで、複雑なロジックを集約して整理する
- クラス名やメゾット名と業務の用語が一致する程、プログラムの意図がわかりやすくなり、変更が楽で安全になる。


## ２.場合分けのロジックを整理する

- 早期リターンやガード節を使うと区分ごとのロジックをわかりやすく整理できる
- 区分ごとに別クラスに分けると独立性を高めることができる
- 多態を使うと、区分ごとのロジックをif文/switch文を使わずに記述できる
- 列挙型(enum)は、叩いをシンプルに記述する仕組み
- 列挙型を活用すると、区分ごとの業務ロジックをわかりやすく整理して記述できる

## 3.業務ロジックをわかりやすく整理

- 変更が大変になるのは、データクラスと昨日クラスを分けるから
- データクラスを使うと、業務ロジックの重複が増える
- アプリケーション全体のコードの見通しを良くするためには、データとロジックを一体にする設計を徹底する
- 業務ロジックは業務データの近くに集める(=ドメインオブジェクト)
- ドメイン(業務アプリケーションの対象領域)をオブジェクトのモデルとして整理したもの　＝　ドメインモデル
- ドメインモデルに業務ロジックを集める
- ドメインモデルは画面やDBの都合から独立させる
- 他の層では業務的な判断/加工/計算のロジックをドメインモデルに任せることでシンプルでわかりやすい構造になる

## 4.ドメインモデルの考え方で設計

- ドメインモデルは業務ロジックをオブジェクト指向で整理する技法
- データの整理ではなく、業務ロジックの整理
- 業務の関心事は、ヒト/モノ/コトで整理できる
- コトを整理の軸にする
- 起きてよいこと/起きてはいけないことの判断と対応が業務ルール
- 業務ルールをオブジェクトで表現する一般的なパターンを覚えておくとドメインモデルの設計がやりやすくなる
- ドメインモデル設計のインプットは業務の言葉の正しい理解
- 業務の言葉を正しく覚え、正しく使えるようになることが、良いドメインモデル設計に直結する
- 業務知識をプログラミング言語で体系的に表現したドメインモデルを中核にした業務アプリケーションは、変更が楽で安全になる

## 5.アプリケーション機能を組み立てる

- アプリケーション層は、業務処理の進行役であり調整役
- アプリケーション層のサービスクラスをシンプルに保つことが、システム全体の見通しの良さと、変更のやりやすさにつながる
- サービスクラスは、様々な関心ごとの交差点になり、ごちゃごちゃしやすい
- サービスクラスはシンプルに保つための設計の徹底が重要
- 全体を段階的に組み立てながら設計の改善を続ける
- 業務的な判断/加工/計算の詳細はドメインモデルに集約する
- 画面の複合した関心事を持ち込まない
- そのためにサービスクラスのメゾットを基本処理単位に分解する
- 必要に応じて複合サービスを提供する
- データベースのデータ操作を意識しないように分離し隠蔽する

## 6.データベースの設計とドメインオブジェクト

- 制約のないデータベースがプロがラムを複雑にする
- 制約を撤退するとデータ管理がうまくいき、プログラムがわかりやすくなる
- テーブル設計の基本は3つの制約(NOT NULL制約、一意性制約、外部キー制約)
- 良いテーブル設計のコツは「コトの記録」の徹底
- 状態の更新はコトの記録とは独立させる
- オブジェクトとテーブルは設計の動機ややり方が基本的に異なる
- オブジェクトとテーブルの設計を独立させやすい仕組みを活用する

## 7.画面とドメインオブジェクトの設計を連携させる

- 画面はアプリケーションに複雑さを持ち込む
- 「何でも画面」は分かりにくい
- タスクごとの画面に分けて考える
- 画面とドメインオブジェクトは「利用者の関心事」として一致する
- 画面とドメインオブジェクトを一致させる改善が、ドメインオブジェクトの設計を洗練させる
- リリースノート、利用者ガイドなど、多くの関係者が理解し確認できる内容とソフトフェアの設計を一致させることがソフトウェアの変更を楽で安全にする

## 8.アプリケーション間の連携

- アプリケーション間の連携が、アプリケーションの価値を高める
- 連携方法はファイル転送/データベース共有/Web API/非同期メッセージングがある
- Web APIの利用が広まっている
- 肥大化したWeb APIは使う側も提供する側も負担が大きい
- APIの変更を楽で安全にするには、小さなAPIに分ける
- APIも進化することで価値を生む
- アプリケーション間を疎結合に連携する非同期メッセージングは今後の有力な選択肢

## 9.オブジェクト指向の開発プロセス

- オブジェクト指向の良さを活かすには分析と設計を一体にした開発のやり方が必要
- 分析工程と設計工程を分割しない
- 分析と設計を同じ人間が担当する
- 分析設計の成果はコードで表現する(自己文書化)
- 更新すべきドキュメントは利用者ガイドや業務マニュアル
- ソースコードを中心に進捗と品質をマネジメントする
- 対象業務の理解と生入りに意欲がある技術者を選んで育成する

## 10.オブジェクト指向設計の学び方と教え方
【学び方】古い習慣から抜け出すためのちょっと過激なコーディング規則

1. 1つのメソッドにつき、インテンドは1段落まで
1. else句は使わない
1. 全てのプリミティブ型と文字列型をラップすること
1. 1行につきドットは1つまで
1. 名前は省略しない
1. 全てのエンティティを小さくすること
1. 1つのクラスにつきインスタンス変数は2つまでにすること
1. ファーストクラスコレクションを使用すること
1. getter、setter、プロパティを使用しないこと
Laravel チェックボックス checked バリデーション 

チェックボックスのバリデーションと初期値設定(checked属性)にハマったので、備忘録として残します。
以下が参考になりました。


>[Laravelで配列の必須バリデーション
](https://qiita.com/shuntakeuch1/items/4242bd126f5a1e31ae31)

>[Laravel チェックボックスのchecked="checked"はどうやって表示させるの？](https://qiita.com/Ioan/items/a851ef1099718d079c8c)
カルマンフィルターその３

## カルマンフィルターの公式の解説
今回はカルマンフィルターに関して、1期先の予測値に関する式展開を行いながら、前回の[カルマンフィルターその２](https://qiita.com/yukio_takagi/items/ec321d0fffd556e11c62)の内容を解説する。一見複雑な式展開に見えるが、確率統計の考え方が身についている方であれば、高校レベルの数学の式展開程度であることをご理解頂けると思う。また確率統計もそれほど複雑なものではなく、平均と分散の考え方のみである。尚、これまで断りがなかったが、各変数はベクトルであることに留意する。

### 1期先の状態変数の予測値 
$ \tilde \beta_t $を1つ前の期の情報で推定するということは、次のことを言う。
$$\hat \beta_{t|t-1} = E_{t-1}[\tilde \beta_t|\Omega_{t-1}] = E_{t-1}[d + \tilde 
\phi\tilde \beta_{t-1} + \tilde v_t|\Omega_{t-1}]$$
右辺への展開には前回の[カルマンフィルターその２](https://qiita.com/yukio_takagi/items/ec321d0fffd556e11c62)で示した状態方程式(2)を用いている。そして、[和の期待値は期待値の和](https://manabitimes.jp/math/698)になるので、次のようになる。

$$ = E_{t-1}[d |\Omega_{t-1}] + E_{t-1}[\tilde 
\phi\tilde \beta_{t-1}|\Omega_{t-1}] +  E_{t-1}[\tilde v_t|\Omega_{t-1}]$$
上式の第1項は定数の期待値なので、定数になる。また第3項の$\tilde v_t$は$ N(0, \sigma^2_v)$に従う確率変数であり定義に従い、その期待値は0になる。したがって、次のようになる。
$$ = d + \tilde \phi \hat\beta_{{t-1}|{t-1}} + 0 $$
ここで、第2項が$E_{t-1}[\tilde 
\phi\tilde \beta_{t-1}|\Omega_{t-1}] = \tilde \phi\hat \beta_{{t-1}|{t-1}}$と置き換わっているが、$\tilde \phi$は係数であり期待値オペレータの前に出せる。$E_{t-1}[\tilde \beta_{t-1}|\Omega_{t-1}]$とは、$\beta$をt-1期の情報を用いて、t-1期の値を推定することを意味する。そのことを$\hat\beta_{{t-1}|{t-1}}$と置き換えているに過ぎない。但し、$\hat\beta$ にハットがついていることに注意する。なお、これは次回のブログで解説するフィルタリングをしていることに他ならないが、この話は次回に譲る。ここまでの話をまとめると、次のようになる。

$$\hat \beta_{t|t-1} \equiv E_{t-1}[\tilde \beta_t|\Omega_{t-1}] = d + \tilde \phi \hat\beta_{{t-1}|{t-1}}\tag{9}$$

これが、1期前の情報を使って、今期の$\beta$を推定したことを意味し、その値は推定した$\hat\beta$に$\tilde \phi$をかけて、定数$d$を加えた値となっている。


### 1期先の状態変数の分散の予測値 
まず、確率変数$X$の期待値を$E(X)=\mu$としたとき、その分散は$E[(X-\mu)(X-\mu)']$とかける。
同様に1期先の状態変数の分散は次の式になる。$'$は転置を意味する。
$$\hat \Sigma_{t|t-1} = E_{t-1}[(\beta_t - \hat\beta_{t|t-1})(\beta_t - \hat\beta_{t|t-1})'] $$
上記の(9)を用いると、次のように展開できる。

$$=E_{t-1}[(\beta_t -(d + \tilde \phi \hat\beta_{{t-1}|{t-1}}))(\beta_t -(d + \tilde \phi \hat\beta_{{t-1}|{t-1}}))'] $$

さらに、状態方程式(2)を展開すると次のようになる。
$$=E_{t-1}[((d + \tilde \phi\tilde \beta_{t-1} + \tilde v_t) -(d + \tilde \phi \hat\beta_{{t-1}|{t-1}}))((d + \tilde \phi\tilde \beta_{t-1} + \tilde v_t) -(d + \tilde \phi \hat\beta_{{t-1}|{t-1}}))'] $$

上記式の期待値オペレータの中を整理すると次のようになる。

$$=E_{t-1}[(\tilde \phi(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}}) + \tilde v_t)(\tilde \phi(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}}) + \tilde v_t)']$$
上記の期待値オペレータの中の展開にあたり、$E(\tilde v_t)=0$であることを利用すると次のようになる。

$$=E_{t-1}[(\tilde \phi(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}}))(\tilde \phi(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}}))'] + E_{t-1}[\tilde v_t \tilde v_t']$$

上記の第1項の$\tilde \phi$は期待値オペレータの外に出せる。また第2項は定義より$\tilde v_t ～ N(0, \sigma^2_v)$となるので、次のようになる。

$$=\tilde \phi E_{t-1}[(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}})(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}})']\tilde \phi + \sigma^2_v$$

$$=\tilde \phi \hat \Sigma_{t-1|t-1} \tilde \phi +\sigma^2_v\tag{10}$$

ここで、$\hat \Sigma_{t-1|t-1} = E_{t-1}[(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}})(\tilde \beta_{t-1} -\hat\beta_{{t-1}|{t-1}})']$と定義した。これはt-1の状態変数の分散をt-1期の情報で推定したものである。次回のブログで説明する状態変数の分散のフィルタリングである。

これが1期前の情報を使って、今期の$\beta$の分散を推定したことを意味する。

次回は状態変数のフィルタリング値と状態変数の分散のフィルタリング値について説明する。
デジタル通貨の調査

# １．デジタル通貨は3種類

## （１）電子マネー

- Suica、Edy、QRコードなど法定通貨をデジタル形式で決済できるように変化させたもの。価値の担保は、法定通貨。

## （２）仮想通貨

- 国家の保証のないデジタル通貨。


##（３）中央銀行発行デジタル通貨（CBDC）

- 国家が発行するデジタル形式の通貨。


https://www.smbc-card.com/cashless/kojin/digital_currency.jsp


# ２．日銀も実験を行っている

日銀も実験を行っており、特設サイトがある。


https://vdata.nikkei.com/newsgraphics/digital-currency/

# ３．外国の取り組み

- 米国は現時点では消極的。
- 中国はデジタル人民元を積極的に普及させようとしドル支配体制からの脱却を目論む。
- 比較的小さな国（スウェーデン、カンボジアなど）でCBDCが試験段階で採用を目指す動きがある。

https://home.kpmg/jp/ja/home/insights/2020/01/cbdc-20200131.html


# ４．デジタル通貨のメリット・デメリット

## （１）メリット

- 紙幣・硬貨などの物理的な形状が不要になり製造や流通コストが削減される。
- 中央銀行、国家は購入履歴から利用者の行動を把握することができる（徴税、犯罪捜査などにメリット）


## （２）デメリット

- サイバー攻撃などにより通貨混乱が起きる可能性がある。


# ５．考察

　実際、デジタル通貨は実質的には実現されており、銀行にお金をあずけ自動引落やデビット、クレジット決済の時点で、物理通貨での決済はしておらず、すでにデジタル決済になっている。

　最近の電子マネーはこの決済場所が、小売の場面にまで広がっており、形状よりも利用箇所が増えたことが以前とは異なる点。

　電子マネーより、仮想通貨の存在は特異なもので、国家の後ろ盾を得ない通貨が決済手段になり、法定通貨と交換できるのはこれまでなかった。つまり国家の存在のない交換手段、資産保護手段が登場したことは歴史的に特筆すべき点。

　CBDCという国家の後ろ盾がある中央銀行がデジタル通貨を発行することは、紙幣・硬貨という物理的な製造・流通コストを減らせるのでその分、国家負担は減る。
　ただし、その反面、サイバー攻撃への対応やデジタル通貨特有の問題への対策費用が増えるだろう。

　法定デジタル通貨は価値の担保が、デジタルになるが、物理的なものよりデジタルのデータや仕組みは破壊しやすい。電子マネーや仮想通貨もまだ物理的な通貨の存在の枠の中にいるが、これがなくなった場合、どのような混乱が起こるのかは未知数であるが、これまでの通貨危機・経済恐慌の比ではないことが起こる可能性もある。

　今の便利さは、あくまでも旧来の紙幣・硬貨・金などの物理的な存在が基盤にあるうえでのデジタル化であるがゆえに、安全の担保のうえに享受されている。
　この担保がなくなった状態でのデジタル化はどうなるのだろうか？

米国が積極的でないのは、やはりドルの支配力の低下をおそれてのものではないだろうかと思う。逆に、中国が積極的なのも米国の一極集中体制を破壊することも目論見の一つであろう。（国民の監視ということがまずは大きな目標であると思われるが）
【Php】Sessionの学習ノート(2)

# 初めに
Sessionについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事：
https://qiita.com/redrabbit1104/items/88ed159ba107aeb54dac

# SessionとCookie
session_start()を使うとsessionが生成されると同時にcookieも生成されます。

```php
session_start();

$_SESSION['date'] = date('c');

echo $_SESSION['date'];
echo '<br>';

//sessionを表示
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
```
$_SESSION['date']の値が25文字のstring型で表示されます。
![スクリーンショット 2021-06-08 6.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/83d91055-f9b5-fd7b-ac61-90ac623ce324.png)


```php
//cookieを表示
echo '<pre>';
var_dump($_COOKIE);
echo '</pre>'
```
cookieの場合も連想配列の形で["PHPSESSID"]というキーが自動生成され、値はランダムでstring型の26文字が与えられます。
![スクリーンショット 2021-06-08 6.16.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/eccc9341-855a-e4de-9856-599c89747fa6.png)
google chromeでcookieの情報を確認することができます。コンテンツのところにcookieの値が入っています。
![スクリーンショット 2021-06-08 6.19.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/5c83b6d7-e50c-6753-577d-9e78d150e8c1.png)

# Cookieの削除
生成されたcookieを削除するにはsetcookie()メソッドを使います。setcookie()はcookieの作成時に使われますが、cookieの名前と値を指定し有効期限が切れるようにすればcookieがブラウザー上に残らなくなります。
if文でisset()メソッドを使い、$_COOKIE['PHPSESSID']が存在しない場合にsetcookie()で値を''にし、有効期限を現在の時間からマイナスの値（ここでは１時間）を指定します。

```php
if(isset($_COOKIE['PHPSESSID'])){
  setcookie('PHPSESSID', '', time() - 3600, '/');
}
```

![スクリーンショット 2021-06-08 7.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/7cd64afe-e4a3-ba74-8d4d-c1c2980e66b7.png)

# sessionの破棄
session_destroy()メソッドでsessionに登録されたデータを全て破棄することができます。

```php
session_destroy();
```

# 参考サイト
https://www.php.net/manual/ja/features.cookies.php
https://www.php.net/manual/ja/reserved.variables.cookies.php
https://www.php.net/manual/ja/function.setcookie.php
https://www.php.net/manual/ja/function.var-dump.php
https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.mixed
https://www.php.net/manual/ja/function.date.php
https://www.php.net/manual/ja/function.session-destroy.php
【Rails】ポリモーフィック関連付けを理解する

エンジニアになりweb開発に今月から携わるようになって初めてポリモーフィック関連付け、というのをやった。ちょっと最初理解に苦しんだのでアウトプットしておく。

## ポリモーフィック関連付けとは？

一言でいうと、「一つのアソシエーションで複数のモデルと結びつく」ということ。ER図を用いて説明する。

まず、通常のアソシエーションでは1対1だろうが1対多だろうが一本の矢印が向かう先は1つである。
![Untitled Diagram-NormalAssociation (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/c72ce52a-022c-039d-cb0e-c00cb6fafd82.png)

しかしポリモーフィック関連付けでは一本の矢印から複数のテーブルにアソシエーションが組まれる。
![Untitled Diagram-Polymorphic (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/dcfa2ebb-94a6-b6a7-00bf-66cc8f3ed059.png)



## 実装方法

ポリモーフィックの実装方法はそんなに難しくない。Railsガイドにも書いてある。
https://bit.ly/3v2wXOX

### ①マイグレーション実行時にpolymorphic: trueを付与

以下のようなマイグレーションファイルを作る

```ruby
class CreateOrders < ActiveRecord::Migration[5.2]
  def change
    create_table :orders do |t|
      t.date  :order_date
      t.references :orderable, polymorphic: true
      t.timestamps
    end
  end
end
```

するとテーブルにimageable_id、imageable_type、という2つのカラムができる。

- orderable_id→外部キーにあたるカラム。ただし `foreign_key: true` はつけない。
- orderable_type→どのテーブルと紐付いているのか、の情報を持つ。アソシエーションを組んだモデルのクラス名が入る。

なお、手動で両カラムを設定する方法もある。

```ruby
class CreateOrders < ActiveRecord::Migration[5.2]
  def change
    create_table :orders do |t|
      t.date  :order_date
      t.bigint  :orderable_id
      t.string  :orderable_type
      t.timestamps
    end
    add_index :orders, [:orderable_type, :orderable_id]
  end
end
```

マイグレーションファイルを設定したら

```
rails db:migrate
```

を実行しましょう。

### ②アソシエーションを組む

ポリモーフィックの場合、「~able」というのがそのままアソシエーション名になる(今回で言えばorderable)

```ruby
class Order < ApplicationRecord
  belongs_to :orderable, polymorphic: true
end

class Customer < ApplicationRecord
  has_many :orders, as: :orderable
end

class Organization < ApplicationRecord
  has_many :orders, as: :orderable
end
```

### どんなメリットがあるの？

無駄な外部キーカラムができなくて済む
今回の例で言えば個人の顧客(Customer)、法人顧客(Organization)のどちらからでも購入されたらordersテーブルにデータを保存するようにしたい場合などに使える。通常個人の顧客が法人も兼ねる、というケースはまれなのでcustomer_id、organization_idと複数のカラムを作ってしまうと紐付いていないテーブルの外部キーがNULLになってしまう。これを避けることができる。

またCustomerとOrganizationで同じメソッドを定義しておけば呼び出しもラクになる。

```ruby
class Order < ApplicationRecord
  belongs_to :orderable, polymorphic: true
end

class Customer < ApplicationRecord
  has_many :orders, as: :orderable
  
  def get_name
    customer_name
  end
end

class Organization < ApplicationRecord
  has_many :orders, as: :orderable
  
  def get_name
    organization_name
  end
end
```

こんなメソッドは通常定義しないけど、同じ名前のget_nameっていうメソッドを用意しておけば

```ruby
order = Order.new
order.orderable.get_name
```

でCustomer, Organizationどちらのメソッドでも呼び出せる。便利。
【統合テスト】Capybaraでテストを書けるようになろう！

# Capybaraとは
WebブラウザとWebアプリケーションの間で交わされるHTTP通信をエミュレート（模倣）するためのライブラリのことです。
特定の要素をクリックした利、フォームから値を入力したり、表示状態を確認したりできる。
フューチャスペック(統合テスト)に最適です。

# 事前準備
1.Gemfileに以下を記載し、`bundle install`する。
※Rails5.1以降ではデフォルトで入っています。

```ruby
group :test, :development do 
  gem 'capybara'
end
```

2.`spec/rails_helper.rb`に以下を記載する。

```spec/rails_helper.rb
...
require 'capybara/rspec'
...
```

3,作業フォルダを作成する。
※spec/features配下にファイルを作成して作業していきます。

```bash
$ mkdir -p spec/features
```

# 使い方
まずは、例として`create_user_spec.rb`を書いてみます。
Capybaraの知識0でも、なんとなくやっていることは理解出来るはずです。
まず、シナリオは3つのセクションに分けることがRailsコミュニティの一般的な慣習なので、
`Givenセクション、Whenセクション、Thenセクション`の3つに分類します。

```spec/features/create_user_spec.rb
require 'rails_helper'

feature 'user', type: :feature do
  scenario 'ユーザー作成' do
    # Givenセクション(前提条件)
    visit new_user_path
    click_lick 'ユーザーを作成する'
    first("div.links").click_link "新規登録"

    # Whenセクション(ブラウザ上の動作)
    fill_in "form_customer_family_name", with: "テスト"
    fill_in "form_customer_given_name", with: "太郎"
    fill_in "form_customer_family_name_kana", with: "テスト"
    fill_in "form_customer_given_name_kana", with: "タロウ"
    fill_in "メールアドレス", with: "test@example.jp"
    fill_in "パスワード", with: "password"
    fill_in "生年月日", with: "2021-06-08"
    choose "男性"
    check "管理者として登録する"
    click_button "登録"

    # Thenセクション(シナリオの結果確認)
    new_user = User.order(:id).last
    expect(new_user.family_name).to eq("テスト")
    expect(new_user.given_name).to eq("太郎")
    expect(new_user.email).to eq("test@example.jp")
    expect(new_user.birthday).to eq(Date.new(2021. 6. 8))
    expect(new_user.gender).to eq("man")
  end
end
```

## メソッドの解説
### visitメソッド
`visit 遷移したいページのパス`とすることで、指定したページに遷移する。

### click_linkメソッド
`click_link 'リンク文字列 or aタグのid属性'`とすることで、aタグをクリックする。

### fill_inメソッド
`fill_in 'ラベル文字列 or input要素のid属性もしくはname属性', with: '入力内容'`とすることで、指定のフォームに値を入力できる。

### chooseメソッド
`choose 'ラベル文字列 or ラジオボタンのid属性'`とすることで、ラジオボタンを選択出来る。

### checkメソッド
`check 'ラベル文字列 or input要素のid属性もしくはname属性'`とすることで、チェックボックスにチェックを入れることができる。

### click_buttonメソッド
`click_button 'ラベル文字列 or input要素のid属性もしくはname属性'`とすることで、ボタンを押下できる。


# まとめ
直感的にテストを書くことが出来るし、単体テストで検証しきれない部分までテスト可能なので、使えるようにしておきたい技術だと思いました。
より高度で複雑な統合テストを書く際は、参考に添付してある公式ドキュメントやチートシートを参照しながら進めていくといいと思います。

# 参考
[teamcapybara / capybara]
(https://github.com/teamcapybara/capybara)

[Capybaraチートシート]
(https://qiita.com/morrr/items/0e24251c049180218db4)
python で html img タグに base64 で画像を埋め込む

# 概要

png とか jpg 画像を読み取って、 base64 形式の img タグを吐き出す python コードスニペット。
（自分用メモ）

## コード

```python
def get_base64_image_tag(image_path, mime_type):
    with open(image_path, "rb") as f:
        src = base64.b64encode(f.read()).decode('utf-8')
        return f'''<img src="data:image/{mime_type};base64,{src}" />'''
```

## 使用例

|画像名|画像|
|--|--|
|**aaa.png**|![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14284/8e5ce88a-602f-dde8-ac8e-fb6a263c91b6.png)|
|**bbb.jpg**|![bbb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14284/f92df415-c30f-95c8-19d7-babb22c6e4d6.jpeg)|


```python
>>> tag = get_base64_image_tag("aaa.png", "png")
>>> tag
'<img src="data:image/png;base64,iVBORw0KG[...]kSuQmCC" />'

>>> tag2 = get_base64_image_tag("bbb.jpg", "jpeg")
>>> tag2
'<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQE[...]/r5f1uf/9k=" />'
```

## 参考

- [Data URI scheme (Wikipedia)](https://ja.wikipedia.org/wiki/Data_URI_scheme)
- [base64 --- Base16, Base32, Base64, Base85 データの符号化](https://docs.python.org/ja/3/library/base64.html)
JavaScript: document.execCommand("copy") の代替

## 前提
`document.execCommand("copy")`

https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

が既に非推奨になっている。代替手段として以下。

- HTML5のClipboard API
- IE対応ではwindow.clipboardData


## Clipboard API（IE以外）

`navigator.clipboard.writeText()`

https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText


```javascript
var clipboardText = "clipboard";
navigator.clipboard.writeText(clipboardText);

```

IE以外は対応している。
*[Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText#browser_compatibility)

### 補足

https://stackoverflow.com/questions/51805395/navigator-clipboard-is-undefined

https://web.dev/async-clipboard/


## window.clipboardData（IE）

`window.clipboardData.setData`

```javascript
var clipboardText = "clipboard";
window.clipboardData.setData('Text', clipboardText ); 
```

## 両方対応する場合

```javascript
var clipboardText = "clipboard";
if(navigator.clipboard == undefined) {
    window.clipboardData.setData('Text', clipboardText);
} else {
    navigator.clipboard.writeText(clipboardText);
}

```

## 参考

https://qiita.com/butakoma/items/642c0ec4b77f6bb5ebcf

- [クリップボードとのやりとり - Mozilla | MDN](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard)
- [ClipboardEvent.clipboardData - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)
- [JavaScript からクリップボードを扱える Async Clipboard API がそろそろ見えてきました](https://qiita.com/grapswiz/items/c9cfa986a8fe3cc6b41a)
- [Clipboard API - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)
- [JavaScript まとめ - クリップボード操作](http://cya.sakura.ne.jp/js/clipboardData.htm)


https://github.com/lgarron/clipboard-polyfill

こんなのもある。
以上メモのみ。
「Amazon TimestreamのデータをGrafanaで可視化してみた | DevelopersIO」をやってみた

## はじめに

[Amazon TimestreamのデータをGrafanaで可視化してみた \| DevelopersIO](https://dev.classmethod.jp/articles/timestream-grafana-visualize/)をやってみたときのメモです。

## 手順

1. Grafana公式リポジトリからソースコードを取得します。  
実際に使用するのは、Dockerfileの1ファイルのみです。

    ```shell
    mkdir grafana
    cd grafana
    wget https://raw.githubusercontent.com/grafana/grafana/main/packaging/docker/custom/Dockerfile
    ```

1. Dockerイメージをビルドします。

    ```shell
    docker build \
      --build-arg "GRAFANA_VERSION=latest" \
      --build-arg "GF_INSTALL_PLUGINS=grafana-timestream-datasource" \
      -t grafana-custom -f Dockerfile .
    ```

1. Dockerコンテナを起動します。

    ```shell
    docker run -d -p 3000:3000 --name=grafana grafana-custom
    ```

1. ブラウザで[http://localhost:3000](http://localhost:3000)にアクセスします。
1. admin/adminでログインします。
1. Grafanaの画面で、Configuration > Data Sources > Add data source で Amazon Timestreamを選択します。
1. AWSのアクセスキーとシークレットアクセスキーを入力します。
1. `us-east-1`リージョンを選択します。  
※`Timestream`は、現時点では、東京リージョンでGAされていません。
1. 次のコマンドでエンドポイントを取得します。  
※`https://`を補います

    ```shell
    aws timestream-query describe-endpoints \
        --region us-east-1 --profile HOGEHOGE \
        | jq -r '.Endpoints[].Address'
    ```

1. `Query Editor`に次のクエリーを入力します。

    ```sql
    SELECT
        measure_name,
        measure_value::double AS load,
        time
    FROM
        "sampledb".IoT
    WHERE
        measure_name = 'load'
    ORDER BY time
    ```
Alpine に AWS CLI をインストールする

# インストール
Alpine には curl が無いのでまずそれをインストールしてから。
glibc が必要なのでそれも入れる。

```shell
apk --no-cache add binutils curl
curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub
curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-2.33-r0.apk
curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-bin-2.33-r0.apk
apk add --no-cache glibc-2.33-r0.apk glibc-bin-2.33-r0.apk
curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip
unzip -q awscliv2.zip
aws/install
aws --version
```


# 参考
[Alpine ベースのコンテナイメージで AWS CLI v2 を使う](https://kiririmode.hatenablog.jp/entry/20200725/1595621558)
GeForce RTX 3060でPytorchを使う

今までGeForce GTX 1060でPytorchを使って勉強していましたが、メモリ不足に悩まされる事から
メモリ容量が大きくてディープラーニング的にコスパの良いグラボを探してコレにしました。
が、RTX 3060に交換した途端Pytorchが動かなくなっててんやわんやしたので。

##はじめに
タイトルの通りですが、RTX3060でのPytorh環境を作るのにてんやわんやしたので備忘録として。

##要点
+ Visual Studio **2019** の C++ によるデスクトップ開発 をインストールする
+ CUDA / cudnn のバージョンを適切なものにする
+ Pytorch のバージョンを **1.7 以上**にする

##環境
|               | Before                   | After                 |
|:--------------|:-------------------------|:----------------------|
| OS            | Windows 10               | ←                     |
| CPU           | Ryzen Threadripper 1950X | ←                     |
| GPU           | GeForce GTX 1060 3GB     | GeForce RTX 3060 12GB |
| CUDA          | ?                        | 11.0.2_451.48         |
| cudnn         | ?                        | 8.0.5.39              |
| Pytorch       | 1.5.0                    | 1.7.1                 |
| Visual Studio | 2017                     | 2019                  |

##手順
####1. Visual Studio 2019 の C++ によるデスクトップ開発 をインストールする

下記リンクよりVisual Studio 2019 Community をダウンロード＆実行し
**C++によるデスクトップ開発**をインストールする
[https://visualstudio.microsoft.com/ja/downloads/](https://visualstudio.microsoft.com/ja/downloads/)
※下記画像の赤枠が必須、黒枠はオプション

ネットワークが使えないパソコンに入れる場合は、オフラインインストールでも可
[『Visual Studio 2019』をオフラインでインストールする方法(Qiita)](https://qiita.com/takamon9/items/b3effb7701bb304c0a68)

![s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675031/0b42cb8a-385d-9735-8e12-ceeb15ed9118.png)

####2. CUDA / cudnn のバージョンを適切なものにする

上記の環境に記載のバージョン、または動作する組み合わせにてインストールする
CUDAは11.x系をインストールしてください。

####3. Pytorch のバージョンを 1.7 以上にする

こちらの記事で知りました。
[PyTorchでRTX 3090を使う(Qiita)](https://qiita.com/atsn/items/10e99066cbefc0876704)

##おわりに
私の場合はこの手順で動作するようになりました。
どなたかのお役に立てるよう、またグラボの高騰が終息しますよう・・・。
【Rails】フォローしたユーザー及びフォロワー一覧表示実装

# 目的
Railsでフォロー機能を導入したアプリに、フォローしたユーザー及びフォロワー一覧を表示する、

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- `フォロー機能`が作成されている。
[【Rails】フォロー機能の実装（非同期）](https://qiita.com/oak1331/items/765dab0c6b3ccda0e580)

# 手順

1. [はじめに](#はじめに)
1. [ルーティングの設定](#ルーティングの設定)
1. [アクションの定義](#アクションの定義)
1. [一覧ページの作成](#一覧ページの作成)

# はじめに

今回は一覧表示させるために、
ユーザー詳細ページから、フォローしたユーザー及びフォロワー一覧ページへ飛ぶようにします。

# ルーティングの設定

まずはルーティングの設定です！

```ruby:config/routes
#省略
resources :users do
  member do
   get :followings, :followers
  end
end
```

idが必要なため、`member`を使用しています。

# アクションの定義

アクションの定義です。
`usersコントローラー`に新たに設定していきます。

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :set_user, only: [:followings, :followers]
#省略
  def followings
    @users = @user.followings
  end

  def followers
    @users = @user.followers
  end

private
  def set_user
    @user = User.find(params[:id])
  end
end
```

# 一覧ページの作成

ユーザー詳細ページにリンクボタンを設置し、一覧表示をさせます。

```html:app/views/users/show.html.erb
<%= link_to "フォロー", followings_user_path(@user) %>
<%= link_to "フォロワー", followers_user_path(@user) %>
```

```html:app/views/users/followers.html.erb
<p>フォロワー一覧</p><br/>
  <% @users.each do |user| %>
  <%= user.name %>
<% end %>
```

```html:app/views/users/followings.html.erb
<p>フォロー一覧</p><br/>
  <% @users.each do |user| %>
  <%= user.name %>
<% end %>
```

# 最後に

以上で、一覧表示の実装は完了です。
CSSは実装していないため、簡素な見た目となっています。
必要に応じて各自編集をお願いします。
では。
よく使うcondaコマンド

# はじめに
これから幾度となくお世話になるあろうAnacondaさんのコマンドリストを備忘録的に残そうと思います。
もし、こんなコマンドもあるよ！とかありましたら教えてください！
# よく使うcondaコマンド
### 環境構築
`conda create -n [環境名]`
### 作成済み環境のリスト
`conda env list`
### 環境削除
`conda remove -n [環境名] --all`
### 環境のへ移動
`conda activate [環境名]`
### パッケージのインストール
`conda install [パッケージ名]`
or
`conda install [パッケージ名]==[バージョン]`
### パッケージのアンインストール
`conda uninstall [パッケージ名]`
### インストール済みパッケージのリスト
`conda list`

# 終わりに
また何かあればどんどん追加していこうと思います。
すでにこの手の記事はたくさんあるんですが、Qiita人生の取っ掛かりには楽なんです…
【Flutter/iOS】Bitriseでfastlaneを使わずApp Store Connectにデプロイする

Bitriseが色々とアップデートされたおかげで、fastlaneを使わずにBitriseだけでApp Store Connectにデプロイできるようになりました。
デプロイ作業がとても簡単になったのでぜひ活用してください！

## 手順
1. BitriseのアカウントでApp Store Connectの認証をする
1. BitriseのアカウントでGitHubの認証をする
1. ワークフローを構築する
1. (オプション)Slackからワークフローを叩けるようにする

## BitriseのアカウントでApp Store Connectの認証をする
- Bitriseのアカウント画面で`Apple Service Connection`を選択する
![スクリーンショット 2021-06-03 0.01.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/59b3747c-d99d-ad93-b1d2-78e3dbc5a3d4.png)

- Keyでの認証を行う
※ 3のフローで何故かIDでの認証だと二段階認証が通らなかったのでKeyで認証をお勧めします！
※ Keyの作成方法は今回は割愛です
※ KeyはAdmin権限のものを作成してください
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/bdc8a113-25fa-c2ad-eb1a-fe5fa92fa85a.png" width=40%>!
認証されるとこんな感じで表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/ddf5dcc7-5a18-e9b9-c0e1-5d719b5d12f7.png" width=80%>!

- Teamsの1番下にある1`Apple Service connection > API key authentication (recommended)`にて先ほど認証したものを選択します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/ab7f92cd-46c6-6ec5-b57f-4a3b318f2536.png" width=80%>!


##  BitriseのアカウントでGitHubの認証をする
- アカウントページからGitHubの連携を行う

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/99445ae0-56fa-ce64-951e-8304a2c75cbd.png" width=20%>

こちらの認証は画面の案内通りにやればオッケーです。

## ワークフローを構築する
ワークフロー全体図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/dd03568a-e23b-20f2-7964-4e55509d2b62.png" width=25%>

### 1. Flutter Install
- Flutter SDK git repository version
  - プロジェクトで採用しているFlutterのバージョンを設定してください

### 2. Flutter Analyze
プロジェクトソースの解析をしてくれます。
入れなくても動きますが、入れることをおすすめします。

### 3. Flutter Build
Flutterプロジェクトのビルドをします。

- Project Location
  - 特別何かしていなければデフォルトで問題ないです
- Platform
  - 今回はiOSのリリースのみなので`ios`にします
- Debug mode?
　　- ログの設定
　　- 基本は　`false`で問題ないです
- Build cache 
  - キャッシュの設定です
  - 基本は`all`がいいと思います

### 4. iOS Auto Provision with Apple ID
Apple Store Connectから証明書をfetchします。

- Distribution type
  - 申請の場合は`app-store`
- The Developer Portal team ID
  - Team IDを入力
  - ※ Apple IDに複数のTeamが紐づいてる場合はこちらの入力が必須です
- Xcode Project (or Workspace) path
  - プロジェクトのパスを入力
- Scheme name 
  - プロジェクトでスキーマを設定している場合はこちらに設定

### 5. Xcode Archive & Export for iOS
アーカイブを行い作成したipaファイルをExportします。

- Project (or Workspace) path
  - プロジェクトのパスを入力
- Scheme name
  - プロジェクトでスキーマを設定している場合はこちらに設定
- Enable caching of Swift Package Manager packages
  - SwiftPMを使用している場合はこちらに`swift_packages`を設定

以下はデフォルトで基本OK

- Select method for export
- Rebuild from bitcode
- Include bitcode
- Disable indexing during the build

### 6. Deploy to iTunes Connect
App Store Connectにデプロイします。

- Bitrise Apple Developer Connection
  - 基本は`automatic`でOK 
- API Key: URL
  - `BitriseのアカウントでApp Store Connectの認証をする`で作成したAPI KeyのURLを設定
- API Key: Issuer ID
  - `BitriseのアカウントでApp Store Connectの認証をする`で作成したAPI KeyのIssue IDを設定

こちらで設定完了です。
私はSlackから叩いて実行し、結果をSlackに通知するようにしています。
これで今までリリース作業していた時間が有効に活用できるようになります！最高！
Scrapy 2.5.0 文書 適当訳

文書はこちら

https://scrapy-docs-ja.readthedocs.io/ja/latest/

#githubリポジトリ

https://github.com/kuma35/scrapy-docs-ja

翻訳は docs-ja ブランチで行っています。

今回はScrapy本家からforkして持ってきています。

但し、docs内のsphinxは入れ替えています。

# 翻訳更新ツール参考
翻訳更新に当たっては

https://qiita.com/ayatakesi/items/a8a6a9bb2df6c4511185

を参考にさせていただきました。

手元ではpotファイルありましたので、コマンドラインは

msgmerge --previous 古い.po 新しい.pot -o 新しい.po
Blenderでexportエラー対応のメモ

BlenderでArray modifierを使ったモデルをFBXにexportしようとしたら、以下のエラー

```
Python: Traceback (most recent call last):
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/__init__.py", line 644, in execute
    return export_fbx_bin.save(self, context, **keywords)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/export_fbx_bin.py", line 3198, in save
    ret = save_single(operator, context.scene, depsgraph, filepath, **kwargs_mod)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/export_fbx_bin.py", line 3094, in save_single
    fbx_objects_elements(root, scene_data)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/export_fbx_bin.py", line 2894, in fbx_objects_elements
    fbx_data_mesh_elements(objects, me_obj, scene_data, done_meshes)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/export_fbx_bin.py", line 1174, in fbx_data_mesh_elements
    elem_data_single_int32_array(lay_uv, b"UVIndex", (uv2idx[uv_id] for uv_id in _uvtuples_gen(t_luv, t_lvidx)))
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/fbx_utils.py", line 504, in elem_data_single_int32_array
    return _elem_data_single(elem, name, value, "add_int32_array")
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/fbx_utils.py", line 451, in _elem_data_single
    getattr(sub_elem, func_name)(value)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/encode_bin.py", line 161, in add_int32_array
    data = array.array(data_types.ARRAY_INT32, data)
  File "/snap/blender/111/2.92/scripts/addons/io_scene_fbx/export_fbx_bin.py", line 1174, in <genexpr>
    elem_data_single_int32_array(lay_uv, b"UVIndex", (uv2idx[uv_id] for uv_id in _uvtuples_gen(t_luv, t_lvidx)))
KeyError: ((nan, nan), 4)

location: <unknown location>:-1

```
UV展開がおかしいらしく、以下の手順でひとまずでexportできた。

```
対象オブジェクト選択
↓
Editモードからすべてを選択
↓
UV
↓
スマートUV投影
↓
OKを選択
```
![Screenshot from 2021-06-08 03-03-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118567/12906035-a63d-58e7-3bbd-ff22740e16ba.png)
vscode remoteとfishで開発しようとしたら、エラー起きた！！

# TL;DR
vscode remoteでubuntuのVPSに接続して開発をしようと試みました。
しかし、タイムアウトするようになりました。
これは`chsh -s /usr/bin/fish`とかやってるとエラーが起きるらしいです。

# 解決策
1. vscodeの設定を開く( `command` + `,` )
1. useLocalServerで検索する
1. Use Local Serverのチェックを外す

# 参考
- [Vscode-remote-release: Fish / tcsh / cshシェルを使用した場合の「SSHとの接続がタイムアウトしました」](https://bleepcoder.com/ja/vscode-remote-release/578458131/connecting-with-ssh-timed-out-when-fish-tcsh-csh-shell-is)
【apollo client】mutation後にキャッシュを書き換える

## はじめに
最近apolloの学習をしています。

apolloにはキャッシュの機能があり、これによって
リストにデータを追加/削除した時にリストが更新されない問題が起きる事があります。

本記事では、mutation後にキャッシュを書き換える方法について書いていきます。

# キャッシュを書き換える2つの方法

1. refetchを使う
2. 自分で直接書き換える

>他にもあるかも知れませんが、この記事では初学者の自分が知ってる方法2つを挙げます

>「useGetListQuery()」などcodegenで生成したhooksを使っていますが、
useQuery(GET_LIST)などと同じです。

# refetchを使う

```List.tsx
const { data, refetch } = useGetListQuery();
```

hooksのresultとしてrefetchという関数を受け取る事ができます。
このrefetchを実行することで、もう一度同じリクエストをする事ができます。
(今回ならuseGetListQuery()を実行するのと同じ)

もう一度リクエストするので、data/キャッシュが更新されます。

アイテムを追加する処理の後で、refetchすることでキャッシュを更新する事ができます。

やり方①

```Item.tsx
await addItem() // リストにアイテムを追加するmutation
refetch()
```
※どちらも非同期処理なのでawaitをつけないと、mutationが終わる前にrefetchすることになってしまいます。

やり方②

onCompletedを使います。

```Item.tsx

const [addItem] = useAddItemMutation({
  onCompleted() {
      props.refetch();
    },
})

```
(propsとしてrefetchを親から渡してきています。)
addItemが完了したタイミングで実行される様です。
しかし、自分がやったところ、できる時とできない時がありました。(謎い。。。)

# 自分で直接書き換える

キャッシュを自分で直接書き換えることもできます。

データを追加/削除したけどキャッシュが変わっていないという事は、
サーバーとクライアントのデータが違う状況です。

追加や削除したデータを使って、キャッシュに変更を加えて同じ状況にします。
(キャッシュの変更はサーバ側に影響しません。)

### リストにデータを追加したい時

```Item.tsx
const [addItem] = useAddItemMutation({
    update(cache, data) {
      const newData = data.data?.addItem;
      cache.modify({
        fields: {
          getList(existing = []) {
          const newItemRef = cache.writeFragment({
              data: newData,
              fragment: gql`
                fragment AddItem on ItemModel {
                  id
                  name
                }
              `,
            });
            return [...existing, newItemRef];
          },
        },
      });
    },
  });

```
updateオプションを使います。

cacheにはキャッシュの情報が入ります。
dataには、addItemを実行したデータが入ります。
(任意の名前をつける事ができます。)

一度console.logでcacheやdataを見てみることをオススメします。

existingには、getListの配列が入ります。
ここには、参照が入っています
(existingにも任意の名前をつける事ができます。)

追加したアイテムの参照を作りexistingと一緒にreturnしています
returnの値がgetListのキャッシュになります。

```Item.tsx
return [...existing, newData];
```
元のキャッシュのデータにaddItemのデータを追加することで、キャッシュに追加する事に成功しました。

### リストからデータを消したい時

```Item.tsx
const [deleteItem] = useDeleteItemMutation({
    update(cache, data) {
      const newData = data.data?.addItem;
      cache.modify({
        fields: {
          getList(existing = [], { readField }) {
            const newItemList = existing.filter((item: any) => {
              return readField("id", item) !== data.data?.deleteItem?.id;
            });
            return [...newGroupList];
          },
        },
      });
    },
  });

```

データの追加とほとんど同じです。
データの削除では、削除したアイテムと同じidを持つデータをキャッシュのリストから削除しています。
readFieldを使うことで、キャッシュされてるアイテムのフィールドにアクセスできます。
filterを使って順番に確認をしていき、同じidを持たないListを新しく作成し、それをreturnしています。

これで、キャッシュの更新をする事ができました。

もし間違っている所、おかしな所があれば教えていただけると幸いです。

## 参考文献
https://www.apollographql.com/docs/react/caching/cache-configuration/
https://www.apollographql.com/docs/react/data/mutations/
https://www.apollographql.com/docs/react/data/queries/
Dockerfileとdocker-compose.yamlの書き方を完全に理解した（わかっていない）

# はじめに

Dockerfileとdocker-compose.yamlの基本的な書き方を調べたので、自分なりの理解でまとめる

本記事のサンプルコードをそのままコピペしても一部動かない可能性あるので悪しからず

# ゴール
- GolangのAPIサーバ用コンテナ立てる

# ディレクトリ構成

ざっくりこんな感じ

```
hogehoge.api
├── docker
│   ├── Dockerfile
│   └── docker-compose.yml
└── src
    └── app
        └── main.go
```

# Dockerfile記述

```Dockerfile:Dockerfile

# ベースイメージを指定
# alpine linuxが軽くてオススメらしいので採用
FROM golang:1.13.15-alpine3.12

# 環境変数の設定
# golangのバージョン1.11以降でGoモジュールの管理にこれが使われるようになったらしいのでonにしておく
ENV GO111MODULE on
# Goのパス通す
ENV GOPATH /go
ENV PATH /go/bin:$PATH

# RUNコマンドは繋げられるならば繋げたほうが良い（軽量化に繋がる）らしいので&&で連ねる
# apk(Alpin Linux Package Management)をアップデートする
# go moduleインストール用にgit入れる
# ホットリロード用にair(https://github.com/cosmtrek/air)を採用
RUN apk update \
  && apk add --no-cache git \
  && go get -u github.com/cosmtrek/air

# コンテナ実行時のデフォルト処理
# docker-composeでも指定するから不要かも（？）
CMD sh

```

# docker-compose.yaml記述

DBに関する記述は雑
→ネットワークの説明やbuildにDockerfile以外も使えることを示すためだけなので

```yaml:docker-compose.yaml

# Docker Composeファイルフォーマットのバージョンを指定
version: "3"

# コンテナ間のネットワーク
networks:
  backend:

# `docker-compose build`や`up`と打った際に作成するコンテナ
services:
  # `docker-compose ps`と打った際に表示されるサービス名
  # ここからDBのコンテナ作っていく
  my-db-for-hogehoge:
    # `docker ps`と打った際に表示されるコンテナ名
    container_name: my-hogehoge-db
    # コンテナのベースイメージ指定
    image: mysql:5.7
    # ネットワークで`backend`を指定しているコンテナと疎通
    networks:
      - backend
  # ここからAPIのコンテナ作っていく
  api-for-hogehoge:
    container_name: my-hogehoge-api
    # ビルド時に使うDockerfileを指定
    # dbのほうではimagesだった箇所にあたる
    build:
      context: .
      dockerfile: ./Dockerfile
    # hogehoge.apiのファイル群を/goにマウント
    volumes:
      - ..:/go
    # コンテナ側の80番ポートを開放
    expose:
      - "80"
    # ホストマシンの10080番ポートとコンテナ側の80番ポート繋ぐ
    ports:
      - "10080:80"
    # 環境変数置くファイル（開発環境でのみ使うパターンが多い？）
    env_file:
      - .env
    # 環境変数設定
    environment:
      HOGE: "hoge"
    # ワークスペース、コンテナ入った時の初期ディレクトリ 
    working_dir: /go/src
    # ネットワークで`backend`を指定することで、先ほどのDBと疎通
    networks:
      - backend
    # `docker-compose up`と打った際に実行されるコマンド
    command: >
      air -c .air.toml
    # コンテナ永続化するか否か（ここではする）
    tty: true
```

# APIコンテナ起動してみる

ここは本筋ではないので軽く
下記コマンドでエラー吐かれたら随時対処

```bash
$ docker-compose build
$ docker-compose up -d
$ docker-compose logs -f api-for-hogehoge
```

# ハマった点
- Golangというか[ホットリロードAir](github.com/cosmtrek/air)の問題かもしれないが、``docker-compose build``してもAirがインストールされなかった
  - コンテナに入って手動インストールして解消
- docker-compose.yamlの書き方が統一されていない
  - オプションの後は改行入れた方が良い？
  - オプションの中身が複数ある場合はハイフン``-``でリスト表記したほうが良い？特にハイフン不要？
  - 調べて修正必須


# さいごに

まだ「完全に理解した」だけなので、曖昧な理解や誤解を生む表現が混ざっている可能性もある
発見次第、随時修正していく予定

# 参考
- [Dockerfile リファレンス — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/builder.html#)
- [Compose ファイル・リファレンス — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/compose/compose-file.html)
Java オブジェクト指向について

初めてキータで学習の備忘録を記録します。

<h4>オブジェクト指向とは</h4>
プログラムの世界に現実世界のように「もの（オブジェクト）」として捉え、その物を中心としてプログラムを組み立てること

<h4>クラスとインスタンス</h4>
<p>＊インスタンスはオブジェクトの別名</p>
<p>＊クラスはインスタンスの設計図</p>

<h4>クラスの定義</h4>
class クラス名{
}

<h4>インスタンスの生成</h4>
インスタンスは変数に代入して使う
クラス型　変数名　＝　new クラス名();

インスタンスは情報（インスタンスフィールド）と振る舞い（インスタンスメソッド）を持つ。

<h4>インスタンスメソッドの定義</h4>
public void メソッド名(){
}
インスタンスはインスタンスに属するメソッドなので、クラス内に定義されていても実際は各インスタンス(を代入した変数)を呼び出して使う。
インスタンス名.メソッド名();

<h4>インスタンスフィールドの定義</h4>
インスタンスフィールドは情報を格納しておく変数に過ぎない
public データ型　変数名{
} 
後ほどprivateも出てきました

インスタンスフィールドもインスタンスに属するのでインスタンスを生成するときに各インスタンスにコピーされるというイメージで！

インスタンス名。フィールド名でアクセスする

<h4>this</h4>
メソッド内でインスタンスフィールドにアクセスするときはthisを使う
thisはクラス内でメソッドが定義されている場合でのみ使用可能
メソッドが呼ばれたときにそのメソッドを呼び出しているインスタンスに置き換わる

なかなかわかりにくい。
イメージが掴めるまで繰り返しアウトプットしよう！
排他制御

## 排他制御とは
複数人の同時アクセスすることによスデータの不整合が発生しないように制御を行うことを意味します。

排他制御には主に2種類があります。

- 楽観ロック
    - 　更新対象のデータが取得された時点から更新がないことを確認し、その後対象データを更新することでデータの整合性を保証します。

- 悲観ロック 
    - 更新対象のデータが取得された時点から明示的にロックを行うい、その後更新対象のデータを更新することででデータの整合性を保証します。
    - 明示的にロックを行うことにより、他のトランザクション処理による対象更新データを防ぎます。

### SELECT ~ FOR UPDATE (NOWAIT) - 行ロックの取得
通常、SELECT分で選択した行には自動的に共有ロックがかかります。しかし、SELECT文の末尾に「FOR UPDATE」を追加することで、排他ロックがかかり、他のトランザクションから該当行のデータを更新するができなくなります。

## SQLでの排他制御実装例

SELECT ~ FOR UPDATEの実装例
かけたロックは、コミットまたはロールバック処理によってトランザクションが終了すると解除されます。

```sql
BEGIN;

-- データを明示的にロックする
SELECT * FROM USER WHERE NAME = 'A' FOR UPDATE;

-- 処理1
SELECT ~;

-- 処理2
SELECT ~;

-- ロックが解除される
COMMIT;

```

### LOCK TABLE - 表ロックの取得
ある特定の表全体をロックするには、LOCK TABLEを使用します。
LOCK TABLE テーブル IN MODE モード名 (NOWAIT)の実装例
※モード名はEXCLUSIVEで排他ロック、SHAREで共有ロックとなります。
取得された表ロックは、行ロック同様にトランザクションの終了とともに解除されます。

```sql
BEGIN;

-- 表を明示的にロックする
LOCK TABLE USER IN EXCLUSIVE MODE;

-- 処理1
SELECT ~;

-- 処理2
SELECT ~;

-- ロックが解除される
COMMIT;
```