OmniAICreator/Qiita-1.07M huggingface dataset:
React開発Part5～レンダリングの最適化編～

## はじめに
　おはようございます、Tunです。
今回は、レンダリングの最適化のついて記述していきたいと思います。

## 再レンダリングの条件
- **再レンダリングが起きる条件**
1. Stateが更新されたコンポーネント
2. Propsが変更されたコンポーネント 
3. 再レンダリングされたコンポーネント配下のコンポーネント全て


　今まで記述してきたように、`state`と`props`はコンポーネントの状態や、その値によってレンダリング内容を決定するものですので、再レンダリングが起きるのは想像できるかと思います。
　3つ目に関しては、想像しにくい挙動ですが、以下のようなフォルダの構成を考えてみて下さい。
```:例：フォルダ構成
📁[project]
└📁public
  └index.html
└📁src
  └📁components
    └Clild1.jsx
    └Child2.jsx
    └Child3.jsx
    └Child4.jsx
  └App.jsx
  └index.html
└package.json
```
　これらのコンポーネントの階層構造は、`App.jsx`の下層に`Child1.jsx`と`Child4.jsx`、その`Child1.jsx`の下層にも`Child2.jsx`と`Child3.jsx`があるとします。すると、`App.jsx`の`state`を更新した場合、全てのコンポーネントが再レンダリングされてしまいます。
　ということは、**再レンダリングされたコンポーネント配下のコンポーネントが全て再レンダリング**されてしまうということです。

## React.memo
　Reactにおいて、コンポーネント、変数、関数などの再レンダリング時の制御をするには**メモ化**を行います。
　メモ化とは、前回の処理結果を保持しておいてパフォーマンスを向上させます。必要な時のみ再計算することで不要な処理を省くことができます。
```react:コンポーネントをmemo
const MyComponent = memo(() => {});
```
　たったこれだけの手間で**prppsに変更がない限り再レンリングされない**ようになりました。
## React.useCallback
　関数を`props`に渡すときにコンポーネントをメモ化していても再レンダリングされてしまう原因は**関数の再生成**です。詳しく言うと、**再レンダリング等でコードが実行されている度、常に新しい関数が再生成されている**ということになります。`props`を受け取ると、**propsが変化した**と判定され、再レンダリングされます。この事象を防ぐために、**関数のメモ化**を行う必要があります。
```react:関数のメモ化
const memoizedCallback = useCallback(
 () => {
  doSomething(a, b);
 },[a, b],
);
```
　`useCallback`は、第1引数に**関数**、第2引数に**依存配列**を指定します。この指定した関数は、依存配列の要素のいずれかが変化した場合のみ変化し、不要なレンダーを避けます。依存配列が空の場合は、**最初に作成されたものが使いまわされます**。
　また、次でも記述しますが、`useCallbnack(関数, 依存配列)`は`useMemo(() => 関数, 依存配列)`と等価です。

## React.useMemo
```react:変数のメモ化
const memoizedValue = useMemo(
() => computeExpesiveValue(a, b),[a, b]
);
```
　`useMemo`は依存配列の要素のいずれかが変化した場合のみメモ化された値を再計算します。
　また、`useMemo`に渡した関数はレンダー中に実行されます。レンダー中に通常やらないことは、この関数内で行うのはやめましょう。

:::note warn
**useMemoはパフォーマンス最適化のために使うものであり、意味上の保証があるものだと考えないようにしましょう**
⇒例えば、画面外のコンポーネント用のメモリを解放するために、将来的にReactはメモ化された値を忘れるようにする可能性があります。`useMemo`なしでも動作するコードを書き、パフォーマンス最適化の観点で加えるようにしましょう
:::

次回はグローバルなState管理です:wave:

## 参照
- [React公式](https://ja.reactjs.org/docs/hooks-reference.html#usecallback)
- [モダンJavaScriptの基本から始める React実践の教科書](https://www.amazon.co.jp/%E3%83%A2%E3%83%80%E3%83%B3JavaScript%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%82%8B-React%E5%AE%9F%E8%B7%B5%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E6%9C%80%E6%96%B0ReactHooks%E5%AF%BE%E5%BF%9C-Informatics-IDEA/dp/481561072X)
Intel MacでBootcampしたときにWindows側にした設定

# トラックパッドをMacの使用感にする

https://github.com/imbushuo/mac-precision-touchpad


# キーバインドを変更

左Command⌘ <-> 左control^
右Command⌘ <-> caps lock

を入れ替える

```registry
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:\
00,00,00,00,00,00,00,00,\
05,00,00,00,5B,E0,1D,00,\
1D,00,5B,E0,5C,E0,3A,00,\
3A,00,5C,E0,00,00,00,00
```

# PowerToysでキーバインドを設定

- キー

capslock から 左Shift capslock
( Win(Right) から Shift(left) VK240)



- ショートカット

左Command⌘ delete から Delete
(Ctrl(Left) Backspace から Delete)
オブジェクト指向・UMLのシーケンス図とは

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！

今回は具体的なオブジェクト指向・UMLのシーケンス図について更に詳しく調べてみましょう！
![インスタスライド_2023031701.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/65f01367-1a1d-108a-46a8-8ed8fa46bdb5.gif)

# シーケンス図
プログラムの処理の流れや概要についてクラスやオブジェクト間のやり取りを時間軸に沿って表現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/b05f2d68-730d-965f-509f-67d81c665685.png)

# シーケンス図の使い方
・オブジェクトとメッセージを整理

・メッセージ
　あるオブジェクトが他のオブジェクトのメッセージを呼び出すなど、オブジェクトが相互作用するときに発せられる情報のこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/f3410c48-b322-a9a9-db84-b780f1b66850.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/088dac71-ec6d-7ce2-efb9-24d97fd96ec9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/dc2632ca-6715-168b-c017-23d07d72b42b.png)

# まとめ
ーUMLのシーケンス図を知ろう

ーオブジェクトとメッセージの流れを整理

ーオブジェクトの相互作用を時系列に具体的に表現できる

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Node.jsでのaxiosによるhttpリクエスト時にKeepAliveを設定して高速化

## 概要

- Node.jsでaxiosでのhttpリクエスト時にKeelAliveを設定することで処理時間がどの程度短縮できるか試した際のメモ
  - Node.js 19.0.0以前はKeepAliveはデフォルトで無効、19.0.0以降であればデフォルトで有効となっているらしい

## 環境
- Typescript 5.0.2
- Node.js 18.15.0

## サンプルコード

- 必要なnpmパッケージのインストール

```
$ npm i axios http https
```

- axiosを利用してhttpsリクエストを行うClientクラスを作成し、Mainクラスにより複数回リクエスト実行する

```typescript: sample.ts
import axios, { AxiosRequestConfig } from "axios";
import http from "http";
import https from "https";

// axiosによるhttpリクエスト用
class Client {

  // コネクションの再利用するためのメンバ変数を定義（今回利用しているのhttpsのみ）
  private httpAgent: any;
  private httpsAgent: any;

  constructor() {
    this.httpAgent = new http.Agent({ keepAlive: true });
    this.httpsAgent = new https.Agent({ keepAlive: true });
  }

  public async get() {
    const url = "https://example.com//";
    const config: AxiosRequestConfig = {
      httpAgent: this.httpAgent,
      httpsAgent: this.httpsAgent,
    };

    await axios.get(url, config); // KeepAliveを有効化して引数に渡す
  }
}

// メイン処理用クラス
class Main {
  public async execute() {
    const client: Client = new Client();
    for (let i = 0; i < 10; i++) {
      const startTime = performance.now();
      await client.get();
      const endTime = performance.now();
      console.log(endTime - startTime); // 処理時間を計測（ms）
    }
  }
}

(async () => {
  await new Main().execute();
})();
```

## 実行結果（Node.js 18.15.0)

- 処理を実行してKeepAliveあり、なしの状態を比較してみる

```
$ npx ts-node src/sample.ts
```


### KeepAlive設定あり

- 最初の1リクエストでのみTCPコネクション確立の処理が行われおり、以降はコネクションの再利用がされているため処理時間が短縮されている

```
525.0759160015732
121.82095799967647
126.890625
126.20208300091326
123.89316600002348
123.1732080001384
126.44858399964869
123.4158330000937
126.21420799940825
122.48204099945724
```

### KeepAlive設定なし

- サンプルコードの `axios.get` を行う際に、configの設定を行わないでリクエストを実施する

```typescript
await axios.get(url); // configなし
```

- リクエストごとにTCPコネクション確立と破棄が行われいるためKeepAlive設定ありに比べ処理時間がかかっている

```
531.7899999991059
590.0455419998616
474.6150839999318
456.53095899894834
465.33424999937415
576.2037090007216
562.0905410014093
589.6257500015199
485.87058299966156
593.1784170009196
```


## Node.js 19.0.0 以降の場合

- Node.js 19 よりKeepAliveはデフォルトで有効化となっている模様。実際に試してみた
  - https://forest.watch.impress.co.jp/docs/news/1448838.html

### 環境

- Typescript 5.0.2
- Node.js 19.0.0


### 実行結果

- サンプルコードの `axios.get` を行う際に、configの設定を行わないでリクエストを実施する

```typescript
await axios.get(url); // configなし
```

- configを渡さなくてもKeepAliveが有効化されており、2回目以降のリクエストの処理時間が短縮されている

```
513.0798749998212
124.72891600057483
124.05337500013411
124.73337499983609
130.4447919987142
124.54537499882281
124.06837500073016
121.77483300119638
121.46916599944234
121.095708001405
```

## 参考
- https://github.com/axios/axios/issues/1846
- https://axios-http.com/ja/docs/req_config
- https://yosuke-furukawa.hatenablog.com/?page=1514460029#keepalive-%E3%82%92-on-%E3%81%AB%E3%81%99%E3%82%8B
APIとは？種類と利用上の注意点

# はじめに
API（Application Programming Interface）は、プログラム間でデータの受け渡しを行うための仕組みです。APIを利用することで、プログラム同士の連携が容易になります。本記事では、APIの基本的な仕組みや種類、そしてAPIを利用する上での注意点について解説します。
# APIの仕組み
APIは、あるプログラムが提供する機能を別のプログラムが利用できるようにするためのインタフェースです。APIを提供する側は、APIを公開するためのエンドポイントを用意し、そのエンドポイントに対してリクエストを送信することで、必要なデータを取得することができます。

APIは、HTTPプロトコルを利用して通信します。HTTPプロトコルは、WebブラウザとWebサーバー間での通信にも利用されているプロトコルであり、リクエストとレスポンスをやりとりすることができます。APIにリクエストを送信する場合、通常はHTTPメソッド（GET、POST、PUT、DELETEなど）を指定し、APIに必要なパラメータを含めます。

APIからのレスポンスは、通常はJSON形式で返されます。JSON形式は、JavaScript Object Notationの略であり、データを表現するための軽量で柔軟なフォーマットです。APIから取得したデータを解析する場合は、JSONをパースすることが一般的です。
# APIの種類
APIには、さまざまな種類があります。主なAPIの種類としては、以下のようなものがあります。

- Web API：Webサービスの提供元が公開するAPI。
- クラウドAPI：クラウドプロバイダが提供するAPI。
- プライベートAPI：企業内部で利用するAPI。
- オープンAPI：誰でも利用できるAPI。
APIの種類によって利用方法やアクセス権限などが異なるため、APIを利用する場合は、APIの種類について事前に確認することが重要です。

# APIを利用する上での注意点
APIを利用する際には、以下のような注意点があります。
- 利用規約を確認する：APIを利用する前に、API提供元が定めた利用規約を確認することが必要です。利用規約に違反する利用は禁止されている場合があります。
- APIキーの取得：APIを利用する場合は、APIキーを取得する必要があります。APIキーは、API提供元から発行される認証トークンのようなもので、APIにアクセスするための許可証として機能します。
- レート制限の確認：API提供元は、一定期間内に送信できるリクエスト数を制限することがあります。APIを利用する場合は、レート制限について事前に確認することが重要です。
- エラー処理の実装：APIからのレスポンスには、エラーが含まれる可能性があります。APIを利用する際には、適切なエラー処理を実装することが重要です。
- セキュリティの確保：APIには、セキュリティ上のリスクが伴うことがあります。APIを利用する際には、適切なセキュリティ対策を実施することが必要です。

# まとめ
本記事では、APIの基本的な仕組みや種類、そしてAPIを利用する上での注意点について解説しました。APIは、プログラム間のデータ連携を行うための重要な技術であり、正しく利用することで開発効率やシステムの機能性を向上させることができます。APIを利用する際には、API提供元が定めた利用規約やセキュリティ対策に注意し、適切な利用を心がけましょう。
Azure Application Gateway の Cookie ベースのアフィニティ において、 Cookie の有効期限はいつまでか

# Cookie の有効期限
Azure Application Gateway で Cookie ベースのアフィニティ で、 Cookie の有効期限はいつまでか、公開情報を探してみたのですが見つけられなかったため、検証して確認をしてみました。


# Cookie ベースのアフィニティ って？
Application Gateway は、リスナー（フロントエンド IP アドレス、プロトコル、およびポート番号で構成）でクライアントからの要求を受け付けます。受け付けた要求は、リスナーに関連付けられているルーティング規則に沿って評価され、どのバックエンドプールに要求をルーティングするかが決まります。
バックエンドプール内にいくつか正常なバックエンドサーバーがある場合、基本的にはラウンドロビンで負荷分散が実行されます。

しかし、バックエンドのサーバーが変更されてしまうと（ラウンドロビンでは）困る場合があります。
そういった場合、Application Gateway で Cookie ベースのアフィニティを有効にすることで、Application Gatewayは、同じサーバーに転送して処理できます。

https://learn.microsoft.com/ja-jp/azure/application-gateway/how-application-gateway-works




# 検証してみた

[ Application Gateway ]  + [ Backend となる VM ] といった環境であれば、以下の公開情報を参照すれば手軽に作成することができます。

https://learn.microsoft.com/ja-jp/azure/application-gateway/quick-create-portal

Cookie ベースのアフィニティは、Application Gateway を作成する途中、バックエンド設定を行う際に、 [ Cookieベースのアフィニティ] の項目がありますので、ここで有効化を選択すれば、利用することができます。
Application Gateway を作成済みの場合でも、同じく、バックエンド設定を掘っていくことで設定箇所に行くことができます。
なお、[ アフィニティCookie名 ] は何でもよいかとは思いますが、マルチサイトの場合には、同名Cookie名だと上書きされてしまうので、重複させないようにだけ気をつけます。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/12d6e527-fdb9-a6ea-adec-0bf83417b0fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/8ba76da0-23ba-d42f-5b1e-18a5c862c7c5.png)



あとは、セッションアフィニティを有効化した Application Gateway のバックエンドとして、WebサーバIIS入りWindowsサーバーを配置したうえで、手元のPCからブラウザアクセスし、Cookieの有効期限を確認してみます。


# 確認結果

有効期限：ブラウザを閉じるまで有効、でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/985c6986-81c8-c150-9bc9-e491edb1cdea.png)

一応比較のため、期限があるサイト（例えば www.yahoo.co.jp ）だと、以下とおり Cookie の有効期限がありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/4d1ac682-5ce1-efe5-594e-bcb13da6b878.png)


# Curl で取得した Cookie 内を確認する
PowerShell で Curl を実行し、Cookie 内の Expires の情報を確認する方法も記載しておきます。
こちらのサイトが非常に参考になりました　⇒　https://yomon.hatenablog.com/entry/2015/03/03/004652

``` Powershell
$uri = "https://www.yahoo.co.jp"
Invoke-WebRequest -Uri $uri -SessionVariable mySession | Out-Null
$mySession.Cookies.GetCookies($uri)
```

やはり、Application Gateway が用いる cookie は Expire がなく、有効期限が設定されていないCookieであることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/445e326a-9c2d-3f45-3243-c0d4b54d8753.png)

こちらも比較サイトですが、しっかり Expire が設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461633/3ae89e9c-5093-d87b-aa0a-c3dae4d8feed.png)




# 参考リンク
https://learn.microsoft.com/ja-jp/azure/application-gateway/how-application-gateway-works

https://learn.microsoft.com/ja-jp/azure/application-gateway/how-to-troubleshoot-application-gateway-session-affinity-issues

https://yomon.hatenablog.com/entry/2015/03/03/004652
NeovimでGitHub Copilot

# この記事に書いていないこと
・GitHub Copilotがどんなものか
・Copilotの購入(サブスクライブ)方法
・neovimとは何か

# 準備
Neovim バージョン 0.6 以降と Node.js バージョン 17 以降が必要になる。
[nvim](https://neovim.io/doc/)
[node.js](https://nodejs.org/en/)

# 使ってみる
### GitHub Copilot プラグインをインストール
```sh
git clone https://github.com/github/copilot.vim\
   ~/.config/nvim/pack/github/start/copilot.vim
```

### GitHub Copilot を構成する
適当にneovimを開きます。
```
nvim copilot-sample
```
以下を入力。(補完が効かなかった)
```
:Copilot setup
```
`First copy your one-time code: xxxx-xxxx`の様に表示されるので値をコピーする。
`Enter`を押すとブラウザに飛ばされます。

Device Activationという画面で先ほどのワンタイムコードを入力後、`Authorize GitHub Copilot Plugin`を押して完了。:v:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/3f80d6df-c69a-3b3c-4e76-b1955de37871.png)

# 適当に使ってみる
上記を終えたらもう使い始められる。
試しに。
```
:Copilot version
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/13b505ba-28e4-dcc4-fdf6-20913f45163d.png)
ちゃんと動いてる!

関数名を書いたらここまで提案してくれた。
コメントアウトからも提案できて優秀！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/427a092d-54cd-ec2b-56b1-76fbb05d594a.png)


これで使い方を見る。
```
:help copilot
```

# 感想
### 良いと感じたこと
コメントアウトで短い指示を出しても提案の精度が高い。

関数の仕様や引数、戻り値をコメントアウトで示すとほぼ`tab`を押しているだけで実装できてしまった。(とは言っても標準入力から受け取ったりする簡単なもの)

指示を上手く書ければ開発速度は向上しそうだが、人が目的を理解できていないと意味がない。

### よくなかったこと
`:Copilot xxx`の補完が効かない。
2023/03/29時点でChat機能が実装されていない。-> ここを見ていればいつか対応されるかも？[copilot.vim support for copilot chat?](https://github.com/orgs/community/discussions/50939)
copilot(副操縦士)じゃない.

# 参考
[Neovim で GitHub Copilot の使用を開始する](https://docs.github.com/ja/copilot/getting-started-with-github-copilot/getting-started-with-github-copilot-in-neovim)
Qiitaコミュニティガイドライン改定が結構重要な話(2023年3月31日予定)

# はじめに
:::note warn
本記事は特定の技術やユーザーについて
否定するものではないことを予め明言しておきます。
:::

本記事は2023年3月31日に予定されている
コミュニティガイドライン改定に関する
以下のお知らせについて記述したものになります。

https://blog.qiita.com/guideline-update-2023-03/

本記事は上記注意点の再確認、及び
拡散のつもりで記述したものになります。

なお、本記事は注意事項のみの記述になりますが、
Qiita公式ではChatGPT有効活用についてのイベントも
開催されているので(2023/03/15 〜 2023/04/16)
気になる方は是非チェックしてみてください。
__※本記事は主旨に沿っていないのでイベントに参加していません__

https://qiita.com/official-events/b80ebe828fa453edf260

## この記事を投稿しようと思った背景

* 最近AI(主にChatGPT4)ブームにより話題が増えている
* 正否は問わず回答を得る機会が増加している
* 上記に伴いQiita公式が懸念している事象が増える可能性がある
* Qiitaの通知は来るけど意外と詳細を読んでいない人もいるのではないかと思った
* Qiitaユーザーが記事にすることで少しでも目に入ることを期待している

## 先に結論
お知らせ内に全て書いてありますが、特にガイドライン内の
__事実検証をせずにAIが生成した内容そのまま__ 
ということに注意しましょうという話です。

## 本題
筆者自身はAI活用に否定的ではありません。

しかし、主に「ChatGPT」が注目を浴びるようになってから
「対話形式で回答してくれる」というお手軽さ故か、
「質問丸投げ」かつ「AIの回答が絶対(若しくは非常に正確)だと盲信する」
ように読み取れるような状況も増えてきたと思われます。

上記のような状況を鑑みてQiita公式でも
「記事」、「質問」問わず
「AIが回答した内容の丸投げ」が散見することを
警戒してガイドライン改定が行われるのかと予想しています。

## 例：Java(面倒くさい方は読み飛ばしてください)
例えば、
「標準入出力を用いてキーボードから入力された値を
　出力するコードを提示してください」と
AIに質問して以下のような回答が返ってきたとします。
(筆者が考えた仮定です)

```java:Main.java
package foo;

import java.util.*;

public class Main {

	public static void main(String[] args) {
		System.out.println("何か入力してください。");
		try {
			Scanner scan = new Scanner(System.in);
			String str = scan.nextLine();

			System.out.println("入力した文字は「" + str + "」です。");
			scan.close();
		} catch (Exception e) {
			System.out.println("例外が発生しました。");
		}
	}
}
```

確かに動作します。が…

分かる人であれば、
必要以外のライブラリを```import java.util.*;```でインポートしている、
```catch (Exception e)```の例外処理しか無い、
などなど様々な粗が見つかるはずです。

しかし、__事実検証をせずにAIが生成した内容そのまま__ だと
Qiitaで「[Java]入力した文字を出力したい」等の質問があった場合に
「学習しておらず検証もしていない人」が上記コードを貼り付けて
「分からない質問者に不明確な回答をする」という状況が発生する可能性があります。

# さいごに

個人的な意見を述べると上記は非常に恐ろしいことで、
極論「分からない人(質問者)」に対して「分からない人(AI利用)」が
回答している状況になります。

Qiitaが提示している
「エンジニアにとって再利用性・汎用性の高い」情報とは程遠くなります。

是非とも「はじめに」で提示したお知らせを
読むことをお勧めします。
opencvビルド


# 参考
https://swallow-incubate.com/archives/blog/20200508/

# OpenCV3 ビルド
Windows10 Pro
OpenCV3.4.16
VS2019
CMake 3.18.2

# Opencv3 

https://github.com/opencv/opencv_contrib

注意点:
C:\SDK\opencv\opencv_contrib
OPENCV_EXTRA_MODULE_PATH のデリミタは　￥　ではなく　／
BUILD_opencv_world = ON
BUILD_EXAMPLES  = ON
SHARED = OFF

# samples
サンプル　BUILD_EXAMPLES＝ONだと、サンプルのprojectも作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/d915f08e-5ace-352e-b2da-50ca28c7d049.png)
基本的なDockerコマンドまとめ

・Dockerイメージからコンテナを作成し、そのコンテナを実行
```
docker run
```

・Dockerイメージからデタッチドモード（バックグラウンド）でコンテナを実行
```
docker run -d
```
・現在実行中のコンテナの一覧を表示
```
docker ps
```

・実行中と停止中のすべてのコンテナの一覧を表示
```
docker ps -a
```

・ローカルに保存されているすべてのDockerイメージの一覧を表示
```
docker images
```

・Docker Hubなどのリポジトリからイメージをダウンロード
```
docker pull
```

・指定したコンテナを停止
```
docker stop
```

・指定したコンテナを削除
```
docker rm
```

・Dockerイメージを削除
```
docker rmi
```

・コンテナ内でコマンドを実行
```
docker exec
```

・コンテナ内で実行されているプロセスの出力を表示
```
docker attach
```

以上
RxKotlinとかRxJavaとかの”Rx”って何？

## はじめに

インターンの中でRxJavaとRxKotlinというライブラリを聞くことがあったのですがいまいち理解できていなかったためそれらの理解も深めつつ、リアクティブプログラミングについてもキャッチアップすることがこの記事の目的です。

## リアクティブプログラミング（RP）とは？

[Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)では以下のように説明されていました。

> リアクティブプログラミング（以下：RP）は値の変更を伝播させるデータフロー志向の[プログラミングパラダイム](https://qiita.com/yuka_pon/items/20696037dbf76ddda3dc)。値の関係性を記述してプログラミングする。
> 

なるほど？つまりリクエストを投げるような積極性はなくて、値の変更があったらそれを受け取る受け身のような感じ？

## Rxとは？

**Reactive Extention**の略。

非同期/イベント/時間に関する処理を、簡潔かつ宣言的に記述することができるC#ライブラリ。これが**[ReactiveX](https://reactivex.io/)**として多言語に移植され、RxKotlinやRxJavaのようなライブラリが生まれました。

## Reactive Streamとは？

Rxを構成するインターフェースとして、**Reactive Stream**というものがあるみたいです。Reactive Streamは、ライブラリやフレームワークに関係なく、データストリームを非同期で扱えるようにするための共通の仕組みが作れるインターフェースを提供しています。

| インターフェース | 役割 |
| --- | --- |
| Publisher | データを生産し、通知をする役割 |
| Subscriber | 通知されたデータを受け取り、データ処理をする役割 |
| SubScription | データ数のリクエストおよび購読の解除等。Subscriptionのリクエストを設定でもち、Publisherに教える役割 |
| Processor | PublisherとSubscriberの両方の性質を持つ |

```mermaid
sequenceDiagram
	participant Publisher
	participant Subscriber
	Subscriber->>Publisher: 購読する（Subscribe)
	Publisher->>Subscriber: データの通知準備できた通知
	loop データが存在する限り
		Subscriber->>Publisher: 受け取りたいデータをリクエスト
		Publisher->>Publisher: データの生成
		Publisher->>Subscriber: データを通知
	end
	Publisher->>Subscriber: 完了通知
```

## Rxを使用するモチベーション

正直ここまで調べてきた感想として「Rxってとても難しいのになぜ導入する必要があるの？」と思いました。

そうしてRxを使用するメリットを調べてたら、[こちらの記事](https://qiita.com/yutorisan/items/2475eaf5d8c3a6454e3f)を見つけました。こちらの記事によると、

> Rxを導入すると標準のeventではできなかった、あんなことやこんなことが簡単にできるようになり、結果的に**ソースコードの可読性・保守性が飛躍的に高める**ことができます。
> 
> 
> また、コード全体でRxを導入することで、イベント駆動型[2](https://qiita.com/yutorisan/items/2475eaf5d8c3a6454e3f#fn2)のコーディングスタイルとなり、結果的に**クラス同士が疎結合となるような設計**がしやすくなります。
> 

とありました。なるほど、Rxについて少しだけ分かった気がします。

## まとめ

今回はRxについて簡単にまとめてみました。

次回はRxKotlinを用いて一つアプリを作ってみようと思います。

## 参考

- [https://qiita.com/yuka_pon/items/20696037dbf76ddda3dc](https://qiita.com/yuka_pon/items/20696037dbf76ddda3dc)
- [https://system.blog.uuum.jp/entry/リアクティブプログラミングへの理解がイマイチだっ](https://system.blog.uuum.jp/entry/%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%B8%E3%81%AE%E7%90%86%E8%A7%A3%E3%81%8C%E3%82%A4%E3%83%9E%E3%82%A4%E3%83%81%E3%81%A0%E3%81%A3)
- [https://reactivex.io/](https://reactivex.io/)
- [https://qiita.com/a_yoshio/items/f81be1b28d65fd7cf9ae](https://qiita.com/a_yoshio/items/f81be1b28d65fd7cf9ae)
N予備校をgpt君にやってもらいたかった

<h1>N予備校をgpt君にやってもらいたかった</h1>
初投稿なので読みずらいところがあるかもです。<br>
皆さんめんどくさいオンラインな課題ありますよね<br>
そのような課題はgpt君やらせましょう!!!<br>

なので課題というほど大層なものではないのですが[N予備校](https://www.nnn.ed.nico/home)というものを自動攻略したいと思います。

環境はm2のpython3.10です。
使用したライブラリなどは
|Name|Version|
|:---|:---|
|Pyocr|0.8.3
Pillow|9.4.0
Openai|0.27.2

そしてコードです。
```python:main.py
from PIL import Image
from PIL import ImageGrab
import sys
import pyocr
import pyocr.builders
import gpt3
screenshot = ImageGrab.grab(bbox=(1370, 220, 2550, 700))
screenshot.save('SC.png')
tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))

txt = tool.image_to_string(
    Image.open('SC.png'),
    lang='jpn',
    builder=pyocr.builders.TextBuilder()
)
print(txt)
print("")
print("ここから下はgptくんの回答です--------------")
print (gpt3.gpt3Q(txt))
```
このmain.pyがやってる事は、画面のスクショを撮ってOCRで画像に含まれる文字を起こして
起こした文字をgpt君に投げるだけです。

唐突に出てきたgpt3ライブラリ(自作)のソースは
```python:gpt3.py
import openai
import os

# APIキーを設定
apikey="API_KEY"
openai.api_key = apikey
# GPT-3を呼び出す
def gpt3Q(q):
    response = openai.Completion.create(
        engine="davinci",
        prompt=q,
        temperature=0.5,
        max_tokens=10
    )
    return response.choices[0].text
```
ほぼ全部gpt書いてもらいましたが、大体動かないです。
でもgpt君にエラー内容を投げたらほぼ解決してくれます![situmon.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303382/6ebd1b2b-80f4-bbcc-dcaf-c21fe49b771d.jpeg)
たまに無理な時もあります
<h1>実行してみよう</h1>

![situmon.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303382/1e669c43-1197-632d-ad59-cc27f2e9faaa.jpeg)

<h3>＿人人人人人人人人人＿<br>
＞　存在しない回答　＜<br>
￣Y^Y^Y^Y^Y^Y^Y^Y￣</h3>

を出して来ます。
<h1>なぜこうなってしまったのか</h1>
理由として考えられるのは<br>
1. gpt君には問題が難しい説<br>
2. gpt君には問題の回答はこれしかなかった説<br>
3. gpt君には問題の答え方が定義されていなかったから出来なかった説<br>
<br>
が考えられました。一番解決に近そうなのは3の答え方を教えてあげるのが良さそうです。<br>
なのでocrした文を送る前に"答え方.txt"的なのを送ってあげましょう。 <br>
やる気になったら"答え方.txt"を書きます

<h1>いやうちの学校の課題N予備校じゃないんだが</h1>
って感じの人も多いと思います。<br>
その場合は

```
screenshot = ImageGrab.grab(bbox=(X, Y, X, Y))
```
この項目のX,YでOCR用のスクショ範囲を指定しているのでその範囲さえ弄ればいいと思います
XY座標はpynputとpyautoguiを使ったこちらを使えば良いですよ。
左クリックした座標をprintしてくれます、止めたい時はCTRL+Cで止まります。
```python:clicktoXY.py
from pynput import mouse
import pyautogui
def on_click(x, y, button, pressed):
    if pressed:
        print(pyautogui.position())
        return True
with mouse.Listener(
        on_click=on_click) as listener:
    listener.join()
```
もし間違っていたりしたらコメントなどで教えて頂ければ嬉しいです。
<h1>参考にさせていただいた記事</h1>

https://qiita.com/mczkzk/items/393abc70836b9bde2f60

https://qiita.com/henjiganai/items/7a5e871f652b32b41a18
faster-whisperをインストールしたら、cv2.imshowがフリーズするようになった話

# 環境
* Ubuntu20.04.5LTS
* Python 3.8.10
* faster-whisper-0.2.0

# 状況
　faster-whisperをインストールして以降、ultralyticsやpretrainedmodelsなどをimportしたプログラムを実行した際にcv2.imshowの部分でフリーズする。

# 原因
　faster-whisperの依存関係にあるPyAVが悪さをしていた。調べてみると、以下の記載を見つけた。
>OpenCV uses FFmpeg as back-end for video decoding and encoding. OpenCV distributes own instance of FFmpeg to have it functional on all platforms independently from user setup. It looks like our instance of FFmpeg and AV provided FFmpeg are not compatible (different size of objects, different set of function parameters, etc) and it cases the issue.
https://github.com/opencv/opencv/issues/21952#issuecomment-1123464048

# 解決策
以下を実行しPyAVを一度アンインストールしてから、FFmpegなしのPyAVをインストールする。
これによって、システムにあるすでに利用可能なFFmpegが使用されるようになった。
```
$ pip uninstall av
$ pip install av --no-binary av
```

# 参考記事
https://github.com/opencv/opencv/issues/21952#issuecomment-1123464048

https://stackoverflow.com/questions/72604912/cant-show-image-with-opencv-when-importing-av
【Vue】router.push使い方まとめ


```js
// 文字列パス
router.push('home')

// オブジェクト
router.push({ path: 'home' })

// 名前付きルート
router.push({ name: 'user', params: { userId: '123' } })

// /register?plan=private になる
router.push({ path: 'register', query: { plan: 'private' } })
```

```js
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// これは動作"しません"
router.push({ path: '/user', params: { userId } }) // -> /user
```

```js
// 1 つレコードを進める。history.forward() と同じ
router.go(1)

// 1 つレコードを戻す。history.back() と同じ
router.go(-1)

// 3 つレコードを進める
router.go(3)

// もし多くのレコードが存在しない場合、サイレントに失敗します
router.go(-100)
router.go(100)
```
さらに詳細を見たい方は公式を確認してみてください。

https://v3.router.vuejs.org/ja/guide/essentials/navigation.html
良いコード悪いコードで学ぶ設計入門 【4~5章】 まとめ

こちらの記事の続きです。
https://qiita.com/yuma_akita/items/fbe1aca566d7da335905

## 4章 不変の活用
この章では不変の有用さ、可変にしたときの悪影響が紹介されていました。

### 可変の悪影響
- 同じ変数を参照していたとき、変数に代入されると両方ともに影響が出てしまう
- 予期していなかった動作になってしまう

→ 不変はこれらの悪影響がない

### 不変の有用性
- 不変にすると可変のときと比べて考慮すべきことが減るため、変数名を固定できる。

### どんなときに可変にするべきか
- スコープ内で代入されることが決まっている時
- スコープが収束可能な時
- ループ文のカウント
- リソース制約の厳しい組み込みソフトウェア
- パフォーマンス要件が満たせない時



### 感想
私はプログラミングを始めた頃、「不変ってなんで存在するんやろ？? 柔軟性のある可変のほうがええやん」と思っていましたが、あの頃は型もしかり、縛るということの大切さをしらなかったんですよね、、。

## 5章 低凝縮
低凝縮・・・クラス内におけるデータとロジックの関係性が弱い状態
この章では低凝縮になりやすいパターンとその修正方法が紹介されていた。

この章に関しては、読んでいるときにわからなかったこと、理解したこともまとめていこうと思います。

### 低凝縮になりやすいパターンと解消法
- Commom,Utilなどの共通処理クラス
→ object指向の基本に立ち返える。

- 引き数が多すぎるパターン
→ データをインスタンス変数として持つ１つのクラスとして切り出してみる。

### わからなかったこと①
object指向の基本に立ち返るとなぜ共通化の「雑多にロジックがある状態」が解消されるのか?

**答え**
データとロジックをひとまとめにしてクラスを作るという考え方がobject指向の基本としてあるから。

**詳細**
ここでいう共通化で雑多にロジックがある状態とは、関連のないデータと処理をUtilやCommonといった共通ファイルにまとめること。

これらはデータとロジックがひとまとめになっていない状態なので、object指向の基本としては元のデータがあるファイルにロジックを戻してあげる必要がある。

なのでobject指向の基本に立ち返ると「雑多にロジックがある状態」が解消される。

### わからなかったこと②
尋ねるな、命じろ？ってそもそもどういう意味？

**答え**
メソッドを繋げて「状況を尋ねる」ことではなく、「メソッドにやらせる」こと。

**詳細**
ここを理解するのには様々なブログ記事を参考にさせて頂きました。[1,2,3]
ちなみに完全に理解はできていませんが理解できたところまで。。。

ここでいう尋ねるというのは以下のような状況。
```
user.info.service.active?
→ ture
```
このような状況だと、例えばServiceクラスの修正があったとしたら、Userクラスの内容まで確認しながら修正する必要がある。他のクラスのことも考えながらとなると、改修範囲の見積もりに時間が取られたり、見落としが合った際にデグレが起こったりと様々な悪影響があるのでNG。

逆に、ここでいう「命じる」メソッドチェーンを続けるというのは避け、それぞれのクラスが持つべき情報だけを持たせたメソッドにすると、改修範囲はそのクラスだけとなり余計なコストが掛からずに済む。
(「命じる」の例については参考にしたブログ記事の出来が良すぎるためここでは割愛します。）

### 感想
尋ねるな命じろの章を読む際、まずSOLID原則から理解するところから始めたのでかなり理解に時間を要しました。あまり意識はできていませんでしたが、私もRubyというオブジェクト指向の言語で開発しているのでこのような原理原則やベストプラクティスを使いこなして、可読性、保守性の高いコードが書けるようになりてぇなぁ。。。。と日々思う次第です。

## 参考
[1][お前のデメテルの法則は間違っている ～getter/setterの必要性～](https://tech-blog.rakus.co.jp/entry/20200701/programming)

[2][コードを複雑化させないために意識したいパターン集](https://qiita.com/TakeshiFukushima/items/0b16aef3d320a2ccb7c3)

[3][デメテルの法則を厳密に守るにはどうすればいいの？](https://qiita.com/br_branch/items/37cf71dd5865cae21401)
NeoVim の checkhealth で Registry github.com/mason-org/mason-registry is NOT installed

NeoVim で `:checkhealth` したら [Mason](https://github.com/williamboman/mason.nvim) が以下のようなエラーを出した。

```
mason: require("mason.health").check()
========================================================================
## mason.nvim report
  - OK: neovim version >= 0.7.0
  - OK: Registry `require("mason-registry.index")` is installed.
  - ERROR: Registry github.com/mason-org/mason-registry [uninstalled] is NOT installed.
```
これは `:MasonUpdate` すれば直る。

```
use {
    "williamboman/mason.nvim",
    run = ":MasonUpdate" -- :MasonUpdate updates registry contents
}
```

https://github.com/williamboman/mason.nvim#installation

README に書いてある `run` の部分を指定していなかったのが原因だった。
【PHP・Laravel】パターン別電話番号のバリデーション

結構実装することはあるのですが、その度に正規表現ってどうやってっけ？ってなって調べてるので、自分用にメモ。
間違っていたら、ご指摘いただけると助かります。

# ハイフンなし
```php
'/^0[0-9]{9,10}$/u'
```

# ハイフンあり
```php
'/^0[0-9]{1,4}-[0-9]{1,4}-[0-9]{3,4}\z/'
```

# ハイフンありなし両方許容
```php
'/^(0{1}\d{1,4}-{0,1}\d{1,4}-{0,1}\d{4})$/'
```
hashlips_art_engine詰まったのでメモ



## 実行成功した際のバージョン
os: mac intel　10.15.7
node: v18.1.0
npm: 8.8.0
canvas: 2.11.0

## 詰まった内容
node index.jsを実行するとエラーが発生する。
投稿を参考にnodeのバージョンをダウングレードしてみたりしたが、
エラー内容変化するだけで以前エラーが発生する。

canvasモジュールがインストールされていないとのエラーが出る

```
$ node index.js
node:internal/modules/cjs/loader:1189
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The module '/nft/hashlips_art_engine/node_modules/canvas/build/Release/canvas.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 64. This version of Node.js requires
NODE_MODULE_VERSION 108. Please try re-compiling or re-installing
```

## 解決した手順

1. node_moduleを削除
rm -rf node_modules/
1. npm install
nodeのバージョンを最新版(v18.1.0)にしてインストール

1. npm install canvas
npm installでcanvasインストールできていなかったので、canvasをインストール
1. node index.js
成功

以上
[laravel9]一覧画面に遷移しようとするとエラーになってしまう

## はじめに
laravelでWEBアプリを作成中なのだが、エラーが発生し、ページへ遷移することができない。
作成ページへは遷移が可能な状況

## SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel.meal_data' doesn't exist

エラー文は下記
```
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel.meal_data' doesn't exist
```
要約すると、
`データベース内に存在しないテーブルにアクセスしようとしているため、発生しています。
特に、 MealData モデルが使用している meal_data テーブルが存在しないために発生している可能性が高い。`
とのこと。

テーブルは`meal_datas`テーブルを作成しているので、`meal_data`テーブルでないと起こられている様子。

作成の際のコマンドは以下。
```
php artisan make:migration create_meal_datas_table
```

マイグレーションファイルは以下。
```
public function up()
    {
        Schema::create('meal_datas', function (Blueprint $table) {
            $table->id();
            $table->string('meal')->comment('食品名');
            $table->float('amount', 8, 2)->comment('総量');
            $table->string('unit')->comment('単位');
            $table->float('calories', 8, 2)->comment('カロリー');
            $table->float('protein_gram', 8, 2)->comment('タンパク質(g)');
            $table->float('protein_calories', 8, 2)->comment('タンパク質(Kcal)');
            $table->float('fat_gram', 8, 2)->comment('脂質(g)');
            $table->float('fat_calories', 8, 2)->comment('脂質(Kcal)');
            $table->float('carbo_gram', 8, 2)->comment('炭水化物(g)');
            $table->float('carbo_calories', 8, 2)->comment('炭水化物(Kcal)');
            $table->timestamps();
        });
    }
```

作成自体は問題なさそう。
なんで`meal_datas`ではなく、`meal_data`を探すのかよくわからない。。がそういうことらしい。

## 解決方法
Modelファイルに下記追記すれば解消される。
```MealData.php
protected $table = 'meal_datas';
```

これで一覧画面を表示することができる。
以上。
【Rails】パーシャルの作成

プログラミング初心者の備忘録です。
間違った部分がありましたらご指摘いただけると幸いです。

### パーシャルとは
細かい部分のHTMLを共通化できる機能。
表示ページが多い時などに繰り返し使用したいHTMLのコードをパーシャルファイルに記述することにより、読み込み用コードを埋め込むだけでそのHTMLコードを呼び出すことができる。
### 環境
macOS
rails 6.1ver
### 1.パーシャルを作成する
パーシャルの作成にはルールがあります。
・viewsディレクトリ内にsharedディレクトリを作成し、その配下にパーシャルのファイルを作成すること
・パーシャルファイルの先頭はアンダースコア(_)をつけること
今回はパーシャルファイル名を_hello.html.erbとします。
```php:_hello.html.erb
<div class="hello">
  <h3>HELLO</h3>
  <p>これはパーシャルで呼び出した文章です</p>
</div>
```
class名にはアンダーバーと拡張子を除いたファイル名を記述してください。
### 2.パーシャルを使用する
renderメソッドを使用することでパーシャルファイルを読み込むことができます。
試しにindex.html.erbファイルの中にコードを埋め込んでみます。
```php:index.html.erb
<h1>テストページです</h1>
<%= render "shared/hello" %>
```
パーシャルファイルを呼び出す際もアンダーバーと拡張子を除いたファイル名を記述します。
これをブラウザで確認すると下記の表示になります。
![test用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3212721/ad0ba68d-fcf4-e8f7-d977-631cfc811b1e.png)
無事にパーシャルファイルを呼び出せていることが確認できました。
### まとめ
共通化の自由度が高く好きな場所に埋め込み使い回すことができるので、非常に便利な機能だなと感じました。
SSSAPIというサービスでGoogleスプレッドシートをAPI化してみました

初めてLINE　Botに出会い勉強中のサラリーマンです。
Makeを使い、Googleスプレッドシートのデータを検索し、LINEへ返す。
簡単な仕組みですが、作成中です。

現在、Excelにあるデータを抽出し、メールで送信（約300件）している業務があります。
この業務の「Excelにあるデータを抽出」というのをLINE　Botでやってみようというのが狙いです。

## 早速、作ってみよう！

WebのAPIから情報を取得することしか学んでいないため、いきなりGoogleスプレッドシートから情報を取得するのではなく、SSSAPIというサービスでGoogleスプレッドシートをAPI化して作ることにしました。

## GoogleスプレッドシートをAPI化してみる

SSSAPIにログインし、GoogleスプレッドシートをAPI化すると会社のGoogleアカウントのため、外部連携に制限がかかっており断念。
なので、個人アカウントのドライブで行いました。
![2023-03-26 (3)Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288463/4a45a582-845f-a186-6b0c-37f81b6f6d78.png)
今度はサポートしていないファイルです...と
まじかー！

Excelをアップロードしたファイルだったので、空のスプレットシートにコピーしたら、
![2023-03-26 (4)Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288463/a6b03605-ffb5-1e1a-9228-0e7e22aab210.png)
できました！
[AWS Q&A 365][API Gateway]AWSのよくある問題の毎日5選 #17

# 1. Amazon API Gatewayとは何ですか？
回答：Amazon API Gatewayは、開発者がスケールに関係なくAPIを簡単に作成、公開、維持、監視、保護できるようにする完全に管理されたサービスです。

# 2. API Gatewayの特徴は何ですか？
回答：API Gatewayには、REST API、HTTP API、WebSocket API、API管理、開発、監視、および統合のような機能が備わっています。

# 3. Amazon API Gatewayを使い始めるにはどうすればよいですか？
回答：Amazon API Gatewayを使い始めるには、AWSアカウントに登録し、管理者ユーザーを作成し、ガイドに記載されている手順に従ってLambda関数とAPIを作成する必要があります。

# 4. REST APIとHTTP APIの違いは何ですか？
回答：REST APIは、複雑なリソースベースのAPIに最適であり、HTTP APIは単純なHTTPベースのAPIに最適です。REST APIはより多くのカスタマイズオプションを提供しますが、HTTP APIはより簡単に使用および管理できます。

# 5. Amazon API Gatewayを使用してAPIを保護するにはどうすればよいですか？
回答：Amazon API Gatewayには、データ保護、アイデンティティおよびアクセス管理、属性ベースのアクセス制御、およびインフラストラクチャのセキュリティなど、複数のセキュリティ機能が備わっています。これらの機能を使用して、APIを不正なアクセスや攻撃から保護できます。
[AWS Q&A 365][API Gateway]Daily Five Common Questions #17

# 1. What is Amazon API Gateway? 
Answer: Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. 

# 2. What are the features of API Gateway? 
Answer: API Gateway provides features like creating REST APIs, HTTP APIs, WebSocket APIs, API management, development, monitoring, and integrations. 

# 3. How do you get started with Amazon API Gateway? 
Answer: To get started with Amazon API Gateway, you need to sign up for an AWS account, create an administrative user, and follow the steps mentioned in the guide to create a Lambda function and an API. 

# 4. What are the differences between REST APIs and HTTP APIs? 
Answer: REST APIs are best suited for complex, resource-based APIs, while HTTP APIs are better suited for simple, HTTP-based APIs. REST APIs provide more customization options, while HTTP APIs are easier to use and manage. 

# 5. How do you protect your API using Amazon API Gateway? 
Answer: Amazon API Gateway provides several security features like data protection, identity and access management, attribute-based access control, and infrastructure security. You can use these features to protect your API from unauthorized access and attacks.
[AWS Q&A 365][EKS]Daily Five Common Questions #16

# 1. What is Amazon EKS and how does it work? 
Answer: Amazon EKS is a managed service that makes it easy to run Kubernetes on AWS without needing to install or operate your own Kubernetes control plane. With Amazon EKS, you can use all the Kubernetes features and tools you already know and love. 
# 2. What are the pricing options for Amazon EKS? 
Answer: Amazon EKS pricing is based on the number of Kubernetes worker nodes in your cluster and the AWS resources that you create to run your Amazon EKS worker nodes. You pay for AWS resources (e.g. EC2 instances or EBS volumes) that you create to run your Amazon EKS worker nodes, and there is no additional charge for Amazon EKS itself. 
# 3. How do I create and manage a cluster in Amazon EKS? 
Answer: You can create and manage a cluster in Amazon EKS using the AWS Management Console, AWS CLI, or eksctl command line tool. You can also use CloudFormation templates or Terraform modules to create and manage Amazon EKS clusters. 
# 4. How do I enable Windows support in Amazon EKS? 
Answer: You can enable Windows support in Amazon EKS by creating a Windows node group in your cluster. You can then use Windows Server containers in your Kubernetes workloads and deploy Windows applications using Kubernetes. 
# 5. How do I configure endpoint access in Amazon EKS? 
Answer: You can configure endpoint access in Amazon EKS by modifying the Kubernetes API server endpoint and configuring the network access control list (ACL) for the Amazon EKS control plane VPC. You can also use PrivateLink to securely access the Kubernetes API server endpoint without exposing it to the public internet.
ChatGPT大先生と、一緒に応用情報の合格を目指そう

# ChatGPTを応用情報の合格のために活用している例を紹介します

## 前提
・**午後問題を解くうえで、どのように活用しているか** を紹介します。午前問題での活用の仕方も別途記事にしようかと思いますが。午前問題の活用法については、みなさんイメージが容易だと思うので…。

・**質問の仕方の一般化的なところには触れていません**。他に良質な記事があると思うので、そちらをご覧ください(他力本願)

・今回は、

自分が解答に納得いかなかった問題がある→ChatGPT先生に質問する→納得できる→嬉しくてシェア:writing_hand:

的なノリなので、あしからず。


## 該当の問題

[応用情報技術者過去問題 平成29年秋期 午後問6](https://www.ap-siken.com/kakomon/29_aki/pm06.html)です。


## 利用背景

この問題の**説問1の(1)のb**についてイメージが湧かなかったため。ChatGPTを活用しました。
販売と販売明細のリレーションについての問題です。イメージが湧かなかったというのは、
一つの販売に対しては、一つの明細が出るべきなので、一対一なのではと思っていました。
※答えとしては1(販売)対多(販売明細)です。

## 本題(ChatGPT先生との会話)

①質問

```
テーブル : 販売
販売番号(主キー)

テーブル : 販売明細
販売番号(主キー)
販売明細番号(主キー)

上記の場合のリレーションは1(販売)対多(販売明細)が妥当でしょうか？妥当である場合その理由もお聞かせください。

```

①解答

```
はい、上記のテーブルのリレーションは1(販売)対多(販売明細)が妥当です。

理由は、販売テーブルが販売のヘッダ情報を保持しているのに対して、販売明細テーブルが販売の詳細情報を保持しているからです。つまり、1つの販売に対して、複数の販売明細が存在することがあります。

例えば、1つの販売に複数の商品を含める場合があります。この場合、販売テーブルには販売番号が主キーとして設定され、販売明細テーブルには販売番号と販売明細番号が主キーとして設定されます。そして、販売テーブルの1つのレコードに対して、販売明細テーブルに複数のレコードが存在することがあります。

したがって、1つの販売に対して、複数の販売明細が存在することから、販売テーブルと販売明細テーブルのリレーションは1(販売)対多(販売明細)が妥当です。

```

②質問

```

「1つの販売に対して、複数の販売明細が存在する」場合の具体例等はありますか？通常、一回の販売では一つのレシート(販売明細)が貰えるイメージがあります。

```

②解答

```

申し訳ありません。私の回答が誤解を招くような表現になってしまいました。確かに通常は1回の販売で1つのレシート（販売明細）が発行されます。

販売テーブルと販売明細テーブルのリレーションにおいて、1つの販売に対して複数の販売明細が存在するというのは、例えば以下のような場合を想定していることになります。

例えば、あるお客様が複数の商品を同時に購入した場合、販売テーブルにはそのお客様の販売情報が1つ登録され、販売明細テーブルには複数の商品情報が登録されます。つまり、1つの販売に対して複数の販売明細が存在することがあります。

ただし、販売明細番号は各商品に対してユニークな値を持つ必要がありますので、販売明細テーブルには販売番号とともに販売明細番号が設定されます。

```

## まとめ

このようにして、リレーションについて具体的なイメージを持つことが出来ました。
どうしてもイメージが湧かない問題については、ChatGPT先生と会話しながら納得いくまで考えるようにしています。

コツとしては、やはり**具体例を聞くこと**でしょうか。
また、これだけ高度な会話が自然に出来るのは周知の事実ですので、
本当に自然に質問していいと思います。これからもどんどん活用していきたいです。
TreeDataProviderのgetChildren()が呼び出されるタイミング

VSCodeの拡張機能を開発していて、エクスプローラーにツリービューを表示する時、必ず`vscode.TreeDataProvider`インターフェースを実装してクラスを作成します。

この時、`vscode.ProviderResult<T[]>`を返す`getChildren()`を実装することで、ツリービューに表示する要素を作成することができます。

しかし、この`getChildren()`はどのタイミングで呼び出されているのでしょうか？

`getChildren()`が呼び出されるタイミングは次の通りとなっています。

- ツリービューが最初に表示される時
- ツリービュー内で項目が展開される時
- `onDidChangeTreeData`イベントがトリガーされる時

では、これらが正しく動作するためにはどのようにすれば良いのでしょうか？
それは、`vscode.window.createTreeView()`を呼び出す際に、`treeDataProvider`の値として、このクラスのインスタンスを表す`this`をしていすることで、決まったタイミングで`getChildren()`が呼び出されるようになっています。

`vscode.TreeDataProvider`を実装してクラスを作成するときは、コンストラクタの中で、必ず`vscode.window.createTreeView()`を呼び出すようにしましょう。

```ts
constructor(
    context: vscode.ExtensionContext,
) {
    const view = vscode.window.createTreeView("snippetsView", {
      treeDataProvider: this,
      showCollapseAll: true,
      canSelectMany: false,
      dragAndDropController: this,
    });
    context.subscriptions.push(view);
}
````
【Linux】setコマンドの使い方

## `set`コマンドについて
`set`を使用することでシェルの設定の確認や変更ができます。
```sample.sh
#! /bin/bash
set -eu

```
```sample.sh
#! /bin/bash -eu

```

オプションを設定したい場合には`-`を記述し、 解除したい場合には`+`を記述します。
```sample.sh
#! /bin/bash

# 設定
set -eu

# 解除
set +eu
```

## 主なオプション
<table>
	<tbody>
    <tr>
      <td>オプション</td>
      <td>説明</td>
	  </tr>
	<tbody>
  <tr>
			<td><span>-a, -o allexport  </span></td>
			<td><span>新規に作成した変数や関数，値を変更した変数や関数を，以後，自動的にエクスポートする</span></td>
	</tr>
		<tr>
			<td><span>-b, -o notify </span></td>
			<td><span>終了したバックグラウンド・ジョブのステータスを即座に出力する</span></td>
		</tr>
		<tr>
			<td><span>-e, -o errexit </span></td>
			<td><span>コマンドが0以外のステータスで終了した場合，一部の場合を除いて即座に終了する</span></td>
		</tr>
		<tr>
			<td><span>-f，-o noglob </span></td>
			<td><span>パス名のワイルドカードによる展開（*や?）を無効にする</span></td>
		</tr>
		<tr>
			<td><span>-h, -o hashall </span></td>
			<td><span>コマンドの位置を記憶し，検索時間を短縮する</span></td>
		</tr>
		<tr>
			<td><span>-k, -o keyword </span></td>
			<td><span>キーワードとなる引数をコマンドに対する環境として渡す</span></td>
		</tr>
		<tr>
			<td><span>-m, -o monitor </span></td>
			<td><span>ジョブ制御を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-n，-o noexec </span></td>
			<td><span>コマンドを実行せず，構文エラーだけを確認する</span></td>
		</tr>
		<tr>
			<td><span>-o emacs </span></td>
			<td><span>emacs形式のコマンド行編集インタフェースを有効にする</span></td>
		</tr>
		<tr>
			<td><span>-o history </span></td>
			<td><span>コマンドの実行履歴を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-o ignoreof </span></td>
			<td><span>CTRLキーを押しながらDキーを押しても，シェルを終了しないように設定する。exitコマンドは利用できる</span></td>
		</tr>
		<tr>
			<td><span>-o posix </span></td>
			<td><span>bashの動作をPOSIX 1003.2に準拠させる</span></td>
		</tr>
		<tr>
			<td><span>-o vi </span></td>
			<td><span>vi形式のコマンド行編集インタフェースを有効にする</span></td>
		</tr>
		<tr>
			<td><span>-p, -o phiysical </span></td>
			<td><span>特権モードを有効にし，ENV変数とBASH_ENV変数を処理しなくなる</span></td>
		</tr>
		<tr>
			<td><span>-t, -o onecmd </span></td>
			<td><span>コマンドを1つ読み込み，実行後，終了する</span></td>
		</tr>
		<tr>
			<td><span>-u, -o nounset </span></td>
			<td><span>未定義の変数を参照するとエラー・メッセージを表示する</span></td>
		</tr>
		<tr>
			<td><span>-v, -o verbose </span></td>
			<td><span>コマンドを実行する前に入力行を表示する</span></td>
		</tr>
		<tr>
			<td><span>-x, -o xtrace </span></td>
			<td><span>コマンドと引数の展開処理を表示する</span></td>
		</tr>
		<tr>
			<td><span>-B, -o braceexpand </span></td>
			<td><span>シェルのブレース展開を有効にする。ブレース展開では，「L{i,n,u}x}」という文字列を「Lix Lnx Lux」と展開する。ブレース展開は他の6つの展開にさきがけて実行される</span></td>
		</tr>
		<tr>
			<td><span>-C, -o noclobber </span></td>
			<td><span>既存のファイルに対する出力リダイレクトを禁じる。ただし，「&gt;|」を用いればリダイレクトできる</span></td>
		</tr>
		<tr>
			<td><span>-H, -o histexpand </span></td>
			<td><span>!形式のヒストリ置換を有効にする</span></td>
		</tr>
		<tr>
			<td><span>-P, -o physical </span></td>
			<td><span>ファイルのシンボリック・リンクをたどらない</span></td>
		</tr>
  </tbody>
</table>
Salesforce: 開発者コンソールからクエリ結果をエクスポートする


# Salesforceのデータベースに対してSQLを実行する方法
Salesforceのデータベースに対してクエリを実行する時は開発者コンソールからクエリを実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259482/45819c71-d4dc-7de4-91ad-e85be321d11a.png)

以下の承認情報を保持するオブジェクトをSelectするSQLを実行します。
```
SELECT FIELDS(ALL) FROM ProcessInstance ORDER BY Id LIMIT 200
```

実行するには開発者コンソールのQueryEditorタブにSQLを記載しExecuteボタン押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259482/9e6a419b-a9aa-0aba-c29a-a278c0657d9e.png)

# 開発者コンソールからクエリ結果をエクスポートする
クエリ結果の行を右クリックしてもクエリ結果をコピーすることができません。
そのため、Chromeの検証機能を使ってコピーします。クエリ結果を右クリックし、[検証] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259482/186ad692-f982-4c8c-a4f7-f3882b22ea27.png)

table タグを探して、「Copy Element」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259482/17f87ee1-9210-f9e2-7e99-c08101666ae2.png)

エクセルを開いて貼り付けることで、クエリ結果を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259482/e82947e7-2d4a-c2ad-7aac-a7a3c6277a15.png)
ChatGPTの回答拒否をこじ開けるプロンプト

### 曖昧な回答をする場合
#### 断定的な質問をする
「AとBのどちらが良いですか？」
↓
「AのほうがBより良いのは何故ですか？」
ChatGPTは中立的な回答をしがちなので、単純な比較衡量を求めても毒にも薬にもならない回答をします。

### 指示にないことをするor指示に反することをする
#### ガイドラインに明確に反する場合
諦めましょう
多分GPTの判断と違うレイヤでのフィルタリングがされています。

#### ガイドラインに反するおそれがある場合
質問の工夫によって回答させられる場合があります。
回答のブレが少なくなる質問にしましょう。
* 「○○」が「○○」という観点で誤りがありますか？
* 「○○」という私の考えに「明確な誤り」が含まれますか？

#### 質問がChatGPTの価値観にそぐわない場合
ChatGPT的に、「よりよい選択肢」がある場合に、ChatGPTはそのよりよい選択肢の出力の抑制に失敗する場合があります。
方法論としては、明示的にChatGPTに指示の妥当性を検証させる手法があります。

### 有益でない手法
#### ChatGPTを「論破」する
最終的には平謝りと支離滅裂な回答をするだけです。
Angularのテストでenvironmentの変数をモックする

environment で宣言した変数についてテストの書き方に迷ったのでメモしておく。

- Angular v15
- @testing-library/angular v13
- jest v28

## environment

Angular にはローカル・本番など、環境ごとに変数を切り替える機能がある。

```ts
// src/environment/environment.{環境}.ts
export const environment = {
  production: false,
  foo: "FOO"
};
```

environment は任意のコンポーネントやサービスで参照することができる。

```ts
import { Component, Input, OnInit } from "@angular/core";
import { environment } from "src/environments/environment";

@Component({
  standalone: true,
  selector: "dummy",
  template: `{{ env }}`,
})
export class DummyComponent implements OnInit {
  @Input() name: string;
  env = "";

  ngOnInit(): void {
    this.env = environment[this.name];
  }
}
```

```ts
<dummy name="foo"></dummy>
// "FOO" がレンダリングされる
```

> **参考**  
> [Angularアプリケーションのビルドとサーブ \| angular.jp](https://angular.jp/guide/build)

## テストの考察

上記のコンポーネントをテストする方法として、いくつか考えてみた。

* environment を参照するサービスを宣言して DI する
  * いかにもテストのためのサービスという感じで冗長な気がした
  * サービスの利用が強制できないため environment を DI したり直接インポートしたりばらつきが出る
* environment のプロパティをテストコードから上書きする
  * 別のテストファイルで再度 environment を参照した時の影響度が見えないので怖い
  * 上書き禁止のために as const したら破綻する
* environment.test.ts を追加しテスト環境の設定を切り分ける
  * 1 パターンしか作れない

.... :thinking: どれもイマイチ。

## 採用したテストコード

結果、Jest のモジュールモックを使うことにした。

```ts
import { render } from "@testing-library/angular";
import { screen } from "@testing-library/dom";
import { DummyComponent } from "src/app/dummy.component";

jest.mock("src/environments/environment", () => ({
  environment: {
    foo: "FOO",
  },
}));

describe("test1", () => {
  it("fooは存在するのでレンダリングされる", async () => {
    await render(`<dummy [name]="name"></dummy>`, {
      imports: [DummyComponent],
      componentProperties: { name: "foo" },
    });

    expect(screen.getByText("FOO")).toBeInTheDocument();
  });

  it("barは存在しないのでレンダリングされない", async () => {
    await render(`<dummy [name]="name"></dummy>`, {
      imports: [DummyComponent],
      componentProperties: { name: "bar" },
    });

    expect(screen.queryByText("BAR")).toBeNull();
  });
});
```

この方法なら、別のテストファイルで environment の別パターンを用意することもできる。

```ts
jest.mock("src/environments/environment", () => ({
  environment: {
    bar: "BAR",
  },
}));

describe("test2", () => {
  it("foo", async () => {
    await render(`<dummy [name]="name"></dummy>`, {
      imports: [DummyComponent],
      componentProperties: { name: "foo" },
    });

    // environment に foo は存在しない
    expect(screen.queryByText("FOO")).toBeNull();
  });
});
```

> **参考**
> [モジュールモックのバイパス \| Jest v28](https://jestjs.io/ja/docs/28.x/bypassing-module-mocks)

同一ファイル内で複数回の jest.mock を呼べないなどベストとは言えないが、思いついた方法の中ではいちばん良さそう。他にいい方法があれば知りたい。
初学者が自分に合ったSCSSの書き方を考える

:::note warn
初学者が雰囲気で書いてるので用語・用法の誤りが多分に含まれている可能性が非常に高いです
:::
## 前提
### 予防線
- 本業はデザイナーであり、コーダーやフロントエンドエンジニアなど専門的にコードを書ける人間ではない
- 前任もチームメイトもコーディングをやってくれる人もいない
### ゴール
- ナウでイケてるCSSを書きたい
- 読みやすく書きやすく管理しやすい構造にしたい
- 宗派がいろいろありすぎるので、自分に合った情報を選ぶため軸を定めたい
### 具体的にやろうと思ってること
- ボタンなどよく使うパーツはコンポーネント化する
- SCSSを使う
- 変数や@&#xFFF0;mixinなどを活用して繰り返しの指定を減らす
### 悩み
- 要素ごとに大量にclassが振ってあるのはダサいと思う(最大でも4つ程度に抑えたい)
- @&#xFFF0;mixinを使う粒度(多用しすぎるとコンパイル後のコードが汚くなりそう)
- class(CSS用)とid(JS用)で命名規則をなるべく揃えたい
- リセットCSSの使い方（スクールではSanitize.cssなど配布されてるのをそのまま使ってたけど、仕事ではどうするの？）
## 今考えていること
### たとえばの書き方
:::note warn
雑に書いてるのでどうなるかはわからないしたぶん間違っています
:::
<dl><dt>色</dt><dd>容赦なく変数にする。<br>
デザイナー目線だと色味の微調整（白をちょっとだけグレーに、とか）が結構あるため。</dd></dl>

```scss:style.scss
$green: #55c500;
$yellow: #ffd700;
$white: #fff;
$black: #333;
```
<dl><dt>@&#xFFF0;mixinとコンポーネント化（≒class付与）の使い分け</dt><dd>
@&#xFFF0;mixinは横断的に共通のプロパティを適用したいときに使う。
それ以外はコンポーネント化する。<br>
@&#xFFF0;mixinを使うときのプロパティ数は少ないほうがいいと思う。共通点が多い＝役割が違うはずなのに見た目が同じなので、そもそもデザインが良くない。</dd></dl>

```scss:style.scss
@mixin clickable {
  border-radius: 5px;
  box-shadow: (4px 4px 0px $green);
}
@mixin bg-white {
  background-color: $white;
  color: $green;
  border: 1px solid $green;
}
.Card {
  @include clickable;
  @include bg-white;
  padding: 20px;
  &-Detail {
    color: $black;
  }
}
.Btn {
  @include clickable;
  @include bg-white;
  height: 20px;
  line-height: 20px;
  &-green {
    background-color: $green;
    color: $white;
  }
}
```
この粒度ならCSSもHTMLもあまり汚くならないんじゃないかと思う。
ただ、このコードで悩ましいのは、`@mixin clickable`みたく機能を示す役割もあるとき。
その場合はユーティリティクラスとして扱う方が良いんだろうか？
```html:hoge.html
<!-- clickable を class に変更 -->
<div class="Card clickable">
  <h4 class="Card-Title">hogehoge</h4>
  <p class="Card-Detail">あのイーハトーヴォのすきとおった風</p>
</div>
<button class="Btn Btn-green clickable">お問い合わせはこちら</button>
```
なんかこっちのほうが結果的に可読性が高い気がする。装飾の意図だけでない役割があるときはclassにしちゃったほうが良いのかもしれない。実際はページの規模によると思うが。
### Class命名規則
- kebab-caseかPascalCaseが見た目的に好き
- CSSは大文字が使えないって記事を多く見かけたのでkebab-caseがいいのかなと思いきや、最近の記事を見るとcamelCaseやPascalCaseを採用しているケースもよく見る…。今は使えると考えて良いんだろうか
- [この記事](https://zenn.dev/kagan/articles/css-brain-bemding)が自分の考え方に結構近い
- idを付与するときはElement単位だと思うのでPascalCaseでいけると思う
### リセットCSSについて
`リセットCSS 企業サイト`とか`Normalize css 企業サイト`とかで地道に検索。
[SmartHR](https://qiita.com/kgsi/items/d8aa2424b86c0dc0d3f9)とか[制作会社のサイト](https://tomogara-inc.co.jp/company/guideline/)とかで制作ガイドラインを公開してくれてるのを見た感じ、ネットで配布されてるのを使うので良さそう。
## 感想
CSS/Sassは発信者が多すぎて何を選べば良いかわからない。それでここ数日ずっと悩んでたのに、書き出してみたらあっさり整理できた。
コードに関して悩んだときは自分で実際にコードを書いてみるのが一番良い。
コグニティブコンピューティングとは

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# コグニティブコンピューティングとは
コグニティブ(Cognitive)には、認知や認識という意味があります。
では、__認知のコンピューティング__ とはどういう意味でしょうか？


コグニティブコンピューティングとは、従来のコンピュータのように与えられた情報を単に処理するのではなく、人間のように自ら学び、行動できるシステムのことです。

# AIとの違い
AIもコグニティブコンピューティングも共に、__人間の知的活動を真似し、再現する__ というアプローチを含んでいます。
そのため、コグニティブコンピューティングはAIの一部であると言えますが、AIの中でも人間の認知能力に特化した技術がコグニティブコンピューティングであり、AIのように人間の仕事を奪うというよりも、__人間のサポートを目的__ としています。

# 事例
- カスタマーセンターでの応対
->顧客からの質問に対する自動回答
- 業務データ分析
->統計学的に業務データを分析する
- 画像認識による不良品の検出
->製造ラインにおける人員削減および品質向上

# 終わりに
コグニティブコンピューティングは、インダストリー4.0における主要技術の1つと言われています。インダストリー4.0では、技術や知識を形式知化し、人の手の介在をなるべく減らすことが求められます。そのため、人の直感ではなく、データを用いて判断することが必要となりますが、この __「データを用いて判断」__ という場面にて、コグニティブコンピューティングでは重要な働きをします。インダストリー4.0の考え方が企業に浸透するにつれて、コグニティブコンピューティングは、これから益々目を離せない存在になるでしょう。


最後までお付き合いくださりありがとうございました。
【Redshift】ユーザーにアクセス権を付与するときのハマったこと

# 目的
Redshiftにおいて、あるユーザーでSELECTを実行したときに以下のように怒られました。

:::note alert
Invaild operation: permission denied for schema
:::

このエラーを解決するしたときのメモとして残しておきます。

# 概要
上記のエラーは現在使用しているユーザーに権限がなく、クエリが実行できないことを示しています。これを解決するためにはユーザ―に権限を与えます。

# 解決方法
[GRANT](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_GRANT.html)を実行して、指定のユーザーに指定の権限を付与します。

以下のクエリを実行します。

```SQL:GRANT.sql
GRANT USAGE ON SCHEMA [権限許可をするスキーマ名] TO [権限付与をされるユーザ名];
GRANT SELECT ON ALL TABLES IN SCHEMA [権限許可をするスキーマ名] TO [権限付与されるユーザ名];
```

# 説明
## USAGE
[PostgreSQLドキュメント](https://www.postgresql.jp/document/9.3/html/sql-grant.html)によると、
> スキーマにおいて、指定したスキーマに含まれるオブジェクトへのアクセスを許可します（オブジェクト自体の権限要件が満たされている場合）。基本的には、この権限によってスキーマ内のオブジェクトを"検索"する権限も認められます。

[Redshiftドキュメント](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_GRANT.html)によると、
> 特定のスキーマに対して USAGE 権限を付与します。これによって、そのスキーマ内のオブジェクトにユーザーがアクセスできるようになります。ローカルの Amazon Redshift スキーマでは、これらのオブジェクトに対する特定のアクションを個別に許可する必要があります (例: テーブルに対する SELECT または UPDATE 権限)。

USAGE権限を付与しますって何でしょうかという感じですが、Usageは「使用法」「用法」「利用」という意味なので、利用を許可するという解釈にしておきます。私はこのUSAGEを実行せずにSELECT ONのみを実行していたため、スムーズに権限を与えられていませんでした。

## SELECT ON ALL TABLES
TO以下のユーザーに全てのテーブルに対してSELECT権限を与えています。このALL TABLESという文言でVIEWを含んだ全てのテーブルへのSELECTが許可されます。VIEWを許可する場合、それらに関するテーブルの権限も与えることも忘れないようにしましょう。

# まとめ
GRANTを使用して特定のユーザーに権限を与えようとしたとき、USAGEも忘れずに実行しましょう。

# 参考資料
- [RedshiftでGRANTする時に地味なハマり方したときのメモ](https://qiita.com/paulxll/items/43fa03c940bad141152a)
- [AWSドキュメント](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_GRANT.html)
- [PostgreSQL 9.3.2文書](https://www.postgresql.jp/document/9.3/html/sql-grant.html)
- [Usageの意味:英辞郎](https://eow.alc.co.jp/search?q=usage)
- [【Redshift 入門】Redshiftのスキーマ別権限周りの検証をやってみた](https://dev.classmethod.jp/articles/try-out-redshift-schema-authorization/)