OmniAICreator/Qiita-1.07M huggingface dataset:
ZabbixServerで取得した値をAPI的に他のサーバーから取得したいという件

# 概要
ZabbixServerで取得できる値をAPI的に他のサーバーからも取得したいという案件で考えたことをメモ。

単純に要件を満たすだけなら、zabbix_getコマンドを使えば可能ではあるけど･･･
それぞれのサーバーからバラバラにzabbix_getコマンドが発行されると管理がしにくいので、
どうにか一元管理したいなぁ、と思ったりして。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420694/4dd7ef73-6b06-8f48-07b1-39ac2ebfd11a.png)

そこで他サーバーから値を取得する用のアイテムをZabbixServer側に作成して、
そのアイテムを各サーバーからzabbix_getすることで、
管理はZabbixServerで一元化しつつ、各サーバーから柔軟に値を取得できるように構成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420694/4c6e382a-bfbc-ff86-09e0-7fb8c15dc6fd.png)


# 前提
- RHEL8
- Zabbix Server 4系
- Zabbix ServerにZabbix Agentを導入しておく
- Zabbix Serverにzabbix_getコマンドを導入しておく
- API的に実行するサーバーにzabbix_getコマンドｗお導入しておく

# 流れ
## Zabbix ServerにAPI実行用アイテムの作成
Zabbixサーバーでzabbix_getコマンドを実行するために、
新たに任意のキーを作成し、
それをzabbix_getコマンドを発行するためのシェルスクリプトに処理を投げるようにする

/etc/zabbix_agent/zabbix_agentd.confで下記を追加
```config:zabbix_agentd.conf
UserParameter=api.zabbix_get[*],[スクリプトへのpath]/zabbix_get.sh "$1" "$2" "$3"
```

Zabbixのアイテムキーとしては、**api.zabbix_get[*]** として、
引数によって値を取得するサーバーや対象とするキーを設定する。
スクリプトに渡す引数については後述。

## Zabbix Serverにzabbix_get実行用スクリプトを作成
以下のようにスクリプトを作成
```shell
#!/bin/sh -
export LANG=C
if [ -n "${3}" ]; then
        key=${2}[${3}]
else
        key=${2}
fi
zabbix_get -s ${1} -p 10050 -k $key
exit 0
```

- 第一引数：zabbix_getの宛先IPホスト
- 第二引数：取得するアイテムのキー
- 第三引数：取得するアイテムのキーに設定する引数

**<font color="Red">なぜ取得するキーと引数を別々にしているかというと、Zabbixのアイテムキーに渡す引数はネストができないから</font>**

https://www.zabbix.com/documentation/current/jp/manual/config/items/item/key
>多段階のパラメータ配列、例えば
>[a,[b,[c,d]],e] のような複数レベルのパラメータ配列は許可されません。

:::note warn
例えば、api.zabbix_get[127.0.0.1,cpu.load[,avg]]みたいな書き方はできない
:::

そのため、**api.zabbix_get[対象ホスト,キー,引数]** として渡して、
それぞれの値を使って、シェルスクリプト側でzabbix_getコマンドを生成する。

引数がないアイテムもあるので、第三引数が空でない場合のみキーに引数を付与している。

## ZabbixServerのAgentへのアクセス許可を設定
他のサーバーからzabbix_getコマンドを使って、Zabbix ServerのAgentにアクセスできるようにする。

最低限、zabbix_agentd.confを下記に設定
```config:zabbix_agentd.conf
Server=[zabbix_getコマンドを実行するサーバーのホスト名、IPアドレス(レンジも可)]
```

また、必要に応じて下記も確認すること
- サーバーのF/W
- ネットワーク側の制限など

::: note warn
不必要なサーバーからの実行はできないように設定すべき
:::

## 試す
ここまで出来れば準備完了なので、任意のサーバーからzabbix_getコマンドを使って値を取得する。
```
# zabbix_get -s [zabbixサーバー] -p 10050 -k api.zabbix_get[対象ホスト,"agent.version"]
4.0.31
# zabbix_get -s [zabbixサーバー] -p 10050 -k api.zabbix_get[対象ホスト,"system.cpu.load","percpu,avg5"]
0.100000
```

できた。

# 終わり
構成だけみると、やりたいことに対して逆に複雑なものになってしまっている感じもするが･･･
個人的には、管理しにくい手段というのは往々にしてセキュリティリスクに繋がると考えてます。

::: note alert
管理しにくい→なぁなぁになっていく→放置→どこからどこに通信が許可されているのかわからん→リスクに繋がるかも...
:::

一元管理してたら全部安心かというとそうでもないんですが、
限られた人員でうまく管理していくにはこういう方法もありなのかなぁ。
サイバーエージェントの日本語LLM OpenCALMをDatabricksで動かしてみる

個人的にもこのような流れにドキドキしています。色々なLLMを活用できる幸せ。

https://www.cyberagent.co.jp/news/detail/id=28817

一番小さいものでトライします。クラスターのランタイムは13.0 ML、インスタンスはg5.4xlarge(64GB, 1GPU)です。

https://huggingface.co/cyberagent/open-calm-small/blob/main/README.md

例によって、MLflowで管理するのでtransformesをサポートしているバージョン2.3以降をインストールします。

```
%pip install mlflow==2.3.1
```

```py:Python
dbutils.library.restartPython()
```

まずはサンプル通りに。

```py:Python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("cyberagent/open-calm-small", device_map="auto", torch_dtype=torch.float16)
tokenizer = AutoTokenizer.from_pretrained("cyberagent/open-calm-small")

inputs = tokenizer("AIによって私達の暮らしは、", return_tensors="pt").to(model.device)
with torch.no_grad():
    tokens = model.generate(
        **inputs,
        max_new_tokens=64,
        do_sample=True,
        temperature=0.7,
        pad_token_id=tokenizer.pad_token_id,
    )
    
output = tokenizer.decode(tokens[0], skip_special_tokens=True)
print(output)
```

```
AIによって私達の暮らしは、あらゆる面で大きく変わっています。
たとえば、車。
私たちが使っている車は、その車そのものの価値を高めます。
でも、
「車そのもの」
という価値が、その車を買い替えることによって、どんどん下がっていきます。
「車」という価値が上がれば上がるほど、車は買い替えることで価値
```

おおー。

次にMLflowでロギングします。

```py:Python
import mlflow
import transformers

# ディクショナリーでモデルのコンポーネントを定義
transformers_model = {"model": model, "tokenizer": tokenizer}
task = ""

# モデルコンポーネントの記録
with mlflow.start_run():
    model_info = mlflow.transformers.log_model(
        transformers_model=transformers_model,
        artifact_path="text_classifier",
    )
```

記録されました。
![Screenshot 2023-05-17 at 13.27.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b7a7efe3-642b-17d4-a2fc-370620fd0b19.png)

モデルカードもバッチリ。
![Screenshot 2023-05-17 at 13.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a0ce3bd3-f0dc-38f5-7db6-bdba34425c88.png)

モデルをロードして推論を行います。

```py:Python
# パイプラインとしてコンポーネントをロード
loaded_pipeline = mlflow.transformers.load_model(
    model_info.model_uri, return_type="pipeline"
)

loaded_pipeline(["AIによって私達の暮らしは、"])
```

```
Out[3]: [[{'generated_text': 'AIによって私達の暮らしは、生活者にとって、より便利で、より豊かなものになるはずです。\n'}]]
```

[以前のように](https://qiita.com/taka_yayoi/items/fdeac44d063f090a9987)サービングエンドポイントにデプロイすれば、カスタムアプリとしても活用できますね。

いい加減、そろそろファインチューニングやプロンプトエンジニアリングにもどっぷり浸かりたいと思ってます。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
TerraformのDynamic Credentials with the AWS Providerで[error creating EC2 Metadata session]が発生した場合の対処法

# はじめに
最近Terraformに入門したのですが、使っていくうちにTerraform Cloudに移行してみたくなり、それならDynamic Credentials with the AWS Providerも使ってみたいなーとやってみたら掲題のエラーが発生したので、備忘がてら解決方法を残しておきます。

# 解決方法
手っ取り早く知りたい人のために先に書いておきますが、実際に解決のためにやった作業は以下だけです。

- AWSプロバイダーバージョンを2系から3系にupgradeした

# 事象
以下に記載されている手順を参考にローカルで運用していたTerraformのstate管理をTerraform Cloudに移行し、ローカルでterraform planを実行したところエラーが発生してデプロイができませんでした。

https://aws.amazon.com/jp/blogs/apn/simplify-and-secure-terraform-workflows-on-aws-with-dynamic-provider-credentials/

具体的には以下のエラーが発生しました。
```
Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: error creating EC2 Metadata session: CredentialRequiresARNError: credential type web_identity_token_file requires role_arn, profile default
│
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on variables.tf line 18, in provider "aws":
│   18: provider "aws" {
│
╵
```


エラーが発生したときのtfファイルは以下です。
organizationとworkspaceにはダミーを入れてます。
```main.tf
terraform {
  required_version = ">= 0.14"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 2.0"
    }
  }
  backend "remote" {
    organization = "sample_org"

    workspaces {
      name = "sample_workspace"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}
```

# 原因調査
最初のAWSのページとほど同じ内容だとは思いますが、以下の公式のページを見たりして原因を調査しましたが、特に原因と思われる箇所については特定できませんでした。

https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/aws-configuration

また、AWSのマネジメントコンソールからTerraform CloudからAssumeされるIAM Roleの「最後のアクティビティ」を見ると"なし"になっていたので、設定が何か間違っていてAssume自体が行われていないのではと思い、設定内容を全部再確認してみたのですが設定は何も間違っていませんでした。

# 解決！
特に理由があるわけではないですが、何となくプロバイダーバージョンが古い可能性があるんじゃないかと思いついて、以下のようにバージョンを3系に修正して「terraform init -upgrade」して「terraform plan」をするとエラーが発生せず、正常にコマンドが成功しました。
※自分しか使っていない環境なのでバージョン差分についてはそこまで気にせずバージョン上げました

```main.tf
~省略~
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
~省略~
```

# おわりに
解決した後もそれらしきドキュメントを探しては見たのですが、特に見つからなかったので、もしご存じの方がいれば教えていただけると嬉しいです。
何はともあれ解決してよかったです。
拡張子を複数指定してdiffをとる

## コマンド

```
$ ls
dir_1/  dir_2/
```

のディレクトリ対して


```bash
find dir_1 dir_2 -type f -name "*.html" -or -name "*.php" \
| sed -e "s/^dir_1//g" | sed -e "s/^dir_2//g" | sort | uniq \
| xargs -IXXXX diff  --strip-trailing-cr dir_1XXXX dir_2XXXX -u
```

## 解説
### 拡張子で検索
```bash
$ find dir_1 dir_2 -type f -name "*.html" -or -name "*.php"
dir_1/index.html
dir_1/index.php
dir_1/sub_dir/index.html
dir_1/sub_dir/index.php
dir_2/index.html
dir_2/index.php
dir_2/sub_dir/index.html
dir_2/sub_dir/index.php
```
### sedで先頭のディレクトリ名を消す

```bash
$ find dir_1 dir_2 -type f -name "*.html" -or -name "*.php" \
| sed -e "s/^dir_1//g" | sed -e "s/^dir_2//g"
/index.html
/index.php
/sub_dir/index.html
/sub_dir/index.php
/index.html
/index.php
/sub_dir/index.html
/sub_dir/index.php
```
### 重複を排除
```bash
$ find dir_1 dir_2 -type f -name "*.html" -or -name "*.php" \
| sed -e "s/^dir_1//g" | sed -e "s/^dir_2//g" | sort | uniq
/index.html
/index.php
/sub_dir/index.html
/sub_dir/index.php
```
### diffをとる
```bash
find dir_1 dir_2 -type f -name "*.html" -or -name "*.php" \
| sed -e "s/^dir_1//g" | sed -e "s/^dir_2//g" | sort | uniq \
| xargs -IXXXX diff  --strip-trailing-cr dir_1XXXX dir_2XXXX -u
```
* -u : unified形式で差分を表示
* --strip-trailing-cr : 改行コードを無視※

※正確ではないらしいが割愛

https://qiita.com/khsk/items/9266197d54f9793f3f2d

## 実行結果

```diff
--- dir_1/index.html    2023-05-17 12:38:42.451136400 +0900
+++ dir_2/index.html    2023-05-17 12:39:46.760155700 +0900
@@ -7,8 +7,8 @@
     <title>Document</title>
 </head>
 <body>
-    <p>変更前</p>
-    <p>変更前</p>
-    <p>変更前</p>
+    <p>変更後</p>
+    <p>変更後</p>
+    <p>変更後</p>
 </body>
 </html>
\ No newline at end of file
--- dir_1/index.php     2023-05-17 12:38:42.451136400 +0900
+++ dir_2/index.php     2023-05-17 12:39:46.760155700 +0900
@@ -7,8 +7,8 @@
     <title>Document</title>
 </head>
 <body>
-    <p>変更前</p>
-    <p>変更前</p>
-    <p>変更前</p>
+    <p>変更後</p>
+    <p>変更後</p>
+    <p>変更後</p>
 </body>
 </html>
\ No newline at end of file
--- dir_1/sub_dir/index.html    2023-05-17 12:38:42.451136400 +0900
+++ dir_2/sub_dir/index.html    2023-05-17 12:39:46.760155700 +0900
@@ -7,8 +7,8 @@
     <title>Document</title>
 </head>
 <body>
-    <p>変更前</p>
-    <p>変更前</p>
-    <p>変更前</p>
+    <p>変更後</p>
+    <p>変更後</p>
+    <p>変更後</p>
 </body>
 </html>
\ No newline at end of file
--- dir_1/sub_dir/index.php     2023-05-17 12:38:42.451136400 +0900
+++ dir_2/sub_dir/index.php     2023-05-17 12:39:46.763954700 +0900
@@ -7,8 +7,8 @@
     <title>Document</title>
 </head>
 <body>
-    <p>変更前</p>
-    <p>変更前</p>
-    <p>変更前</p>
+    <p>変更後</p>
+    <p>変更後</p>
+    <p>変更後</p>
 </body>
 </html>
\ No newline at end of file
```


## 参考記事
https://tex2e.github.io/blog/shell/find-name-or

https://www.techscore.com/blog/2016/03/14/%E3%81%82%E3%81%88%E3%81%A6%E3%81%84%E3%81%86%E3%81%BB%E3%81%A9%E3%81%A7%E3%82%82%E3%81%AA%E3%81%84sed%E5%85%A5%E9%96%80/

https://uxmilk.jp/53546

https://iww.hateblo.jp/entry/20111007/xargs

https://tech-blog.rakus.co.jp/entry/20220905/diff
学習以外で意識すると業務が上手くいくかもしれないこと

# 意識した事

### コミュニケーション

案件内の人とはなるべく話すようにする。
これは結構重要で人によってはかなり苦手かなと思います。
自分もかなり苦手でここ最近までは本当に必要最低限、ほぼチャットのみの会話で終わらせていましたが
お互いを評価する制度のフィードバックで案件内のメンバーから「話が伝わっているのかがわからない。」などのフィードバックをもらった事をきっかけに話すようになりました。

その結果言われたのが「○○さんめっちゃ話にくそうな人だったのでよかったです。」と言われて
自分は周りからそう思われていたのか・・・となって更に気をつけないとなと思いました。

これ以外にも自分のいいとこ悪いとこ、案件の円滑な進行、会社からの評価にも繋がるので苦手な人も
なにか小さい目標から進めていって慣れていく事をおすすめします。

例
出社の挨拶をする
質問の内容が大きくなりそうであればなるべく直接話す。(こちらは相手の業務はスケジュールとか確認してやりましょう!「今お時間大丈夫でしょうか？」など聞いてからやるといいかも！

### わからない単語は調べる

雰囲気でわかった気にならずに調べましょう。今ならchatGPTに「IT業界において○○の意味はどういう意味？」みたいに聞けば教えてくれます。
googleでもいいです。

もし会社にナレッジがなく、学生時代や別職では聞いたことのない単語であればまとめみたいなの作って
新卒などに共有すると喜ばれるかも？

### わからない事はわかる人に聞く

これはよく「15分調べてもわからなければ聞きましょう」とあります。
ただ聞くのはいいけれど聞く回数が多いとなにか思われるのではないか...というのを気にしてしまうのがあると思います。

めっちゃわかります。そのせいで何度も同じように調べて調べてる風で時間を過ごしている時間が自分もめっちゃありました。
ただこの時間めっちゃ無駄です。当たり前ですが無駄です。

まだ入社してすぐだと誰に聞けばいいのかわからないとかもあると思うのですが
そういったことも全部聞いちゃいましょう！
聞きまくって嫌な思いされないのは新卒の特権です！

自分は6年目の今でもインフラ周りでわからない部分は自分より出来る人には聞きまくっています。
年数は関係ないです。コーディングが得意な人、インフラが得意な人、何でも知ってる人います。聞きましょう。

逆にわかる側の人になった場合、嫌な顔せず今までの経験を還元してあげてください。

### 技術力が凄い人と何でも話せる関係になる(1人でもいるとめっちゃ楽)

これは「わかる人」のめっちゃ仲良い人を作れればめっちゃ頼りになるという話。
出来ればでいいです。

自分の場合たまたま気が合う人が同じ案件になったので仲良くなりました。

年下ですが自分よりも優秀で勉強熱心なのでめっちゃ聞いてます。

質問する人に対しての年下年上経験年数とかのプライドは捨てましょう。いりません。

### とりあえず動かしてみる

コーディングしている最中に調べてそれっぽいコードが出てきた時に
どう今自分が書いてるコードに埋め込めばいいかわからない場合
とりあえずサンプルコードを動かして、色々つけたしたりいじったりして
どう動いてるのか、何が必要なのかを理解しましょう。
そうすると組み込み方がわかります。

とりあえずそれっぽく組み込んでみただけだと結構な確率で動かなかったり
わけがわからなかったりします。

### 別案件のナレッジを調べる

これは会社によってはできるできないあるかもしれないですが
自分の所では
社内でのやり取りはSlackや、ファイル管理ツールなどを利用しています。

今から自分がやる事はもしかしたら他の案件や、他の誰かがやっていて、誰かが質問しているかもしれません。

なのでSlackだと全体検索などで内容を検索する、エラー文を検索するなどすると結構同じ所で詰まった人達が質問していたりします。

資料作成などでも同じような資料を他の人が作っているかもしれないので
０から全部調べて作るのではなく別の案件の記述方法や作成方法を参考にするとスムーズに行くことがあります。
資料についてわからない場合も作成者に質問したりするのもありです。

### 最後に

以上かなり雑ですが書きました。

今回記述した内容は仕事において何をモチベにしていたとしても
・自分の中でのストレスを溜めない
・評価をあげたい
・技術力上げたい・知識を増やしたい

などどれに対してもやっていて損はない内容になります。
全部一気に出来るようになる必要はありません。

1ヶ月、３ヶ月、半年などその中でこれは意識してやってみる、できるようになるなど
無理なく目標立ててやると上手く行くかもしれません。


頑張りましょう
SwiftUIでグリッドレイアウトを実装する方法

## はじめに
現在作成中のアプリで、`グリッドレイアウト`を実装する必要があったため、実装方法をメモします。
## グリッドレイアウトとは？
グリッドレイアウトとは、`ホームページのデザイン手法の一つで、画面やページを格子状に分割し、これを組み合わせてブロックを並べた時のようなデザインにする手法`のことです。

## SwiftUIでグリッドレイアウトを実装する方法
グリッドレイアウトを実装するには、`LazyVGrid`,`LazyHGrid`を使用します。ただしLazyGridは、ios14から提供されたものです。

**LazyVGrid**：縦方向に要素を並べる。


**LazyHGrid**：横方向に要素を並べる。


### 書き方
```Swift:
let columns = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        ...
    ]
LazyVGrid(columns: columns){
    要素1
    要素2
    要素3
    ...
}
```
```Swift:
let rows = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        ...
    ]
LazyHGrid(rows: rows) {
    要素1
    要素2
    要素3
    ...
}
```
### 引数について
引数には、`配列を指定`する必要があり、要素は`GridItem型で指定`する必要があります。
また、GridItemの引数は、以下が指定可能です。
```Swift:
init(GridItem.Size, spacing: CGFloat?, alignment: Alignment?)

``` 

<table>
  <thead>
    <tr>
      <th>パラメータ</th>
      <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td rowspan="3">
     size
    </td>
    <td>固定のサイズ（.fixed）</td>
  </tr>
  <tr>
    <td>最小と最大で設定した値の範囲内で画面に収まるサイズ（.flexible）</td>
  </tr>
  <tr>
    <td>画面サイズに合わせたサイズ（.adaptive）</td>
  </tr>
  <tr>
    <td> spacing </td>
    <td> GridItem間のサイズ </td>
  </tr>
  <tr>
    <td> alignment </td>
    <td> GridItemの配置 </td>
  </tr>
</table>

### 使用イメージ
```Swift:
struct ContentView: View {
    let columns = [
            GridItem(.fixed(30), spacing: 1),
            GridItem(.fixed(60), spacing: 10),
            GridItem(.fixed(90), spacing: 20),
            GridItem(.fixed(10), spacing: 50)
        ]
    var body: some View {
        ScrollView(.horizontal) {
            LazyVGrid(columns: columns, spacing: 5) {
                ForEach(0...300, id: \.self) { _ in
                    Color.red.frame(width: 30)
                    Color.green.frame(width: 30)
                    Color.blue.frame(width: 30)
                    Color.yellow.frame(width: 30)
                }
            }
        }
    }
}
```
![スクリーンショット 2023-04-18 0.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072069/cfa7d177-52f4-25a9-37b4-80e9603c4fdb.png)

```Swift:
struct ContentView: View {
    let rows = [
            GridItem(.fixed(30), spacing: 1),
            GridItem(.fixed(60), spacing: 10),
            GridItem(.fixed(90), spacing: 20),
            GridItem(.fixed(10), spacing: 50)
        ]
    var body: some View {
        ScrollView(.horizontal) {
            LazyHGrid(rows: rows, spacing: 5) {
                ForEach(0...300, id: \.self) { _ in
                    Color.red.frame(width: 30)
                    Color.green.frame(width: 30)
                    Color.blue.frame(width: 30)
                    Color.yellow.frame(width: 30)
                }
            }
        }
    }
}
```
![スクリーンショット 2023-04-18 0.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072069/8c11fe49-f4dc-0231-49d4-187cc8b8933a.png)

## おわりに
LazyGridを使用すると簡単にグリッドレイアウトが実装できるので、今後も頻繁に使用する気がします。また、もっと簡単に実装できる方法があれば、ご教授いただけますと幸いです。

## 参考記事

https://tech.amefure.com/swift-grid-layout
Git ブランチとマージ

# ブランチの目的
作業を分岐することで、並行して複数の機能を開発するためにあるのがブランチ。

# ブランチの仕組み
ブランチとは、コミットを指し示すポインタのこと。コミットすると、指し示しているコミットが、最新のコミットに移動する。

# HEADとは
HEADとは今自分が作業しているブランチを指し示している。

# ブランチを新規作成する
```terminal
$ git branch <ブランチ名>
```
このコマンドは、ブランチを作成するだけで、ブランチの切り替えは行わない。

# ブランチの一覧を表示する
```terminal
$ git branch

# リモートリポジトリにあるブランチも表示する
$ git branch -a
```
*(アスタリスク)のついているブランチが、現在自分がいるブランチである。

# ブランチを切り替える
```terminal
$ git checkout <ブランチ名>

# featureブランチを作って切り替えることを考える
$ git branch feature
$ git checkout feature
# これは以下のコマンドと同じ
$ git checkout -b feature
```

# ブランチを実践してみよう
`branch_test`ディレクトリを作り、最初のコミットをする。
```terminal
$ mkdir branch_test
$ cd branch_test
$ git init
Initialized empty Git repository in /home/username/branch_test/.git/
$ echo init > init.html
$ git add .
$ git commit -m 'create init.html'
[master (root-commit) c3d069a] create init.html
 1 file changed, 1 insertion(+)
 create mode 100644 init.html
$ git log --oneline
c3d069a (HEAD -> master, feature) create init.html
```
\
`feature`ブランチを切る。
```terminal
$ git branch feature
$ git branch
  feature
* master
```
今、`master`と`feature`が存在し、`master`にいることが確認できた。

次に`master`ブランチでファイルを作成しコミットする。
```terminal
$ echo master > master.html
$ git add .
$ git commit -m 'create master.html'
```
\
GitHubで適当にリポジトリを作り、この変更をプッシュしておこう。
```terminal
$ git remote add origin <URL>
$ git push origin master
```
\
次に、`feature`ブランチに切り替えて新規ファイルを作成し、同様にコミット、プッシュしよう。
```terminal
$ git checkout feature
Switched to branch 'feature'
$ echo feature > feature.html
$ git add .
$ git commit -m 'create feature.html'
[feature e980fc5] create feature.html
 1 file changed, 1 insertion(+)
 create mode 100644 feature.html
$ git push origin feature
```
\
最後にブラウザでGitHubを開き、ブランチを切り替えてみよう。存在するファイルが`master`と`feature`で異なることが確認出来たら成功。

# マージとは
他の人の変更内容を取り込む作業のこと。具体的には、2つのブランチを1つのブランチに統合すること。

# マージの種類
<dl>
    <dt>Fast Foward</dt>
    <dd>ブランチが枝分かれしていなかったときは、片方のブランチがもう片方のブランチを指すようになる。新たなコミットは作成されない。</dd>
    <dt>Auto Merge</dt>
    <dd>ブランチが枝分かれしていた場合、マージコミットという新しいコミットが作られる。マージコミットは親コミットを2つ持つ。</dd>
    <dt>Conflict</dt>
    <dd>同じファイルの同じ行に対して異なる編集を行ったときなどに生じる、どちらのブランチを優先すればよいのか解決できない状態。</dd>
</dl>

# マージする
```terminal
$ git merge <ブランチ名>
$ git merge <リモート名/ブランチ名>
```

[ブランチを実践してみよう](#ブランチを実践してみよう)の続きから始めよう。
```terminal
# masterブランチに切り替える
$ git checkout master
# マージする
$ git merge feature
# ファイル一覧を見てみる
$ ls
feature.html  init.html  master.html
```
`master.html`と`feature.html`が同時に存在することが確認できた。

# コンフリクトの解消
コンフリクトが起こった場合、`git status`コマンドで当該ファイルを調べることができる。ファイルを開くと、以下のような記述がある。
```text
<<<<<<< HEAD
～
=============
～
>>>>>>> NEW
```
HEADは現在いるブランチを示す。また、NEWには取り込もうとしているブランチの名前が入る。

上の記述を消し、正しい内容に修正した後、新たにコミットすることでコンフリクトを解消できる。

# コンフリクトの防止策
<ul>
<li>複数人で同じファイルを変更しない</li>
<li>pullやmergeをする前に、commitやstashをしておく</li>
<li>プルするときは、現在いるブランチを確認する</li>
</ul>

# ブランチを変更・削除する
今いるブランチの名前を変更する場合、
```terminal
$ git branch -m <新ブランチ名>
```
\
ブランチを削除する場合
```terminal
$ git branch -d <ブランチ名>

# 未マージのブランチを強制削除する場合
$ git branch -D <ブランチ名>
```

# ブランチの実用的な使い方
masterブランチをリリース用にとっておき、開発はいくつかのトピックブランチを作成して進める。
【Paiza問題集】標準入力メニュー/整数の半角スペース区切りの入力

# Paiza問題集
Pythonで回答

## 標準入力メニュー/整数の半角スペース区切りの入力

### STEP1 1つの整数の入力
```Python
"""
1つの整数の入力
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_space_step1
"""

# 整数を受け取る
num = int(input())

# 整数を表示する
print(num)
```

### STEP2 2つの整数の半角スペース区切りの入力
```Python
"""
2つの整数の半角スペース区切りの入力
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_space_step2
"""

# 整数を受け取る
num1, num2 = map(int, input().split(' '))

# 整数を表示する
print(num1)
print(num2)
```

### STEP3 5つの整数の半角スペース区切りの入力
```Python
"""
5つの整数の半角スペース区切りの入力
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_space_step3
"""

# 整数を半角スペースごとに区切る
num = map(int, input().split(' '))

# 整数を５つ表示する
for i in num:
    print(i)
```

### STEP4 10個の整数の半角スペース区切りの入力
```Python
"""
10個の整数の半角スペース区切りの入力
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_space_step4
"""

# 整数を半角スペース区切りで受け取る
num = map(int, input().split(' '))

# 整数を表示する
for i in num:
    print(i)
```

### FINAL問題 1000個の整数の半角スペース区切りの入力
```Python
"""
1000個の整数の半角スペース区切りの入力
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_space_boss
"""

# 整数を半角スペース区切りで受け取る
num = map(int, input().split())

# 整数を表示する
for i in num:
    print(i)
```
LLMを用いたアプリを作っていて思ったこと

# わざわざアプリ化する必要ないのでは？と思ってしまう

* 結局自分が書いている制御はLLMの可能性を限定しているだけ
* 素のLLMでもできる
* 開発中に「こうしたらいいかも」と思って修正することって多々あるけど、その修正スピードよりも素のLLMを使った方が早い

## じゃあ、アプリ化する意味がありそうなときってどんな時だろう？

* 凝ったUI/UX
    * ただLLMの可能性を限定するのではなく、UXに精通した人がユーザの心理を的確に把握して開発したら強そう
* 凝ったグラフィックス
    * 例えば、ゲーム。ゲームは多くの場合グラフィックスから得られる情報が多い

# 総論

* LLMがメインではなく、脇役として使うと良さそう
* LLMは水とか電気とか、そのくらいのレイヤーで使うのがいいのかも
    * パソコンとかテレビとか車とかエレベーターとか、小さいものから大きいものまで電気は使われているけど、「あぁ〜、電気使ってるなぁ〜」とはならない。同様に、「LLM使ってるなぁ〜」感はないくらいの方がいいのかもしれない
マイナンバーカードから顔写真データを読み込む

マイナンバーカードから顔写真データを読み込む方法に関する覚書です。

基本４情報の読み込みについては Web で詳しい説明が見つかります。

https://tex2e.github.io/blog/protocol/jpki-mynumbercard-with-apdu#%E5%9F%BA%E6%9C%AC4%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%96%E5%BE%97

DFを選択、そのDF内の PINファイルでPIN検証、その後、データを格納したEFファイルを読み込むことでマイナンバーや基本４情報は取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/1c54b3c8-4e9f-6bdc-1f15-094d94cd0954.png)

顔写真データの取得方法は go 言語プログラムが公開されています。

https://github.com/jpki/myna

Windows で実行すると複数リーダが見つかったというメッセージが３回ほど繰り返し表示されて、プログラムが終了、顔写真データは取得できませんでした。しかし、そのソースコードを頼りに取得方法がかかれているソースコードをもとに顔写真データは取り込めました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/3312efe5-127f-994e-8238-ebcf96be3c64.png)

読み取ったデータ構造を VisualInfo 構造体で定義されている通りに分解していきました。

（myna/libmyna/visual_ap.go）
VisualInfo struct {
		Header    []byte `asn1:"private,tag:33"`
		Birth     string `asn1:"private,tag:34"`
		Sex       string `asn1:"private,tag:35"`
		PublicKey []byte `asn1:"private,tag:36"`
		Name      []byte `asn1:"private,tag:37"`
		Addr      []byte `asn1:"private,tag:38"`
		Photo     []byte `asn1:"private,tag:39"`
		Signature []byte `asn1:"private,tag:40"`
		Expire    string `asn1:"private,tag:41"`
		Code      []byte `asn1:"private,tag:42"`
	}

先頭の５バイトからデータ全体の長さが分かります。これは構造体には含まれません。
ff 20 82 xx yy ( 0x20=32  全データ長  xx * 0xff + yy + xx )

後はレコードマーカとレコード長を頼りに、順番にレコードを取り出します。
データ長は、レコードマーカの次のバイトが 82 であれば、次の2バイトでレコード長をあらわしています。2バイトのBig Endianに1バイト目の値を加算します。 レコード長=xx * 0xff + yy + xx。
レコードの３バイト目が 82 以外であれば、その次のバイトがレコード長です（最大 0x1f ）

Header レコード ( 0x21=33  データ長  xx )
df 21 xx

Birthday レコード（ 0x22=34 データ長 xx ）
df 22 xx

Sexレコード（ 0x23=35 データ長 xx ）
df 23 xx

PublicKey レコード（ 0x24=36 データ長 xx ）
df 24 xx

Name
df 25 82 xx yy（ 0x25=37 データ長 xx * 0xff + yy + xx ）

Addr
df 26 82 xx yy（ 0x26=38 データ長 xx * 0xff + yy + xx ）

Photo
df 27 82 xx yy（ 0x27=39 データ長 xx * 0xff + yy + xx ）

df 27が顔写真のレコードのようなので、データを保存すると先頭と末尾が JPEG2000 のタグなっていることが確認できます。

00 00 0c 6a 50 20 20 0d 0a 87 0a
..
ff d9

JPEG2000 対応のソフトでモノクロ写真が表示されました。

基本４情報と顔写真データを読み込む Windows プログラム（バイナリーのみ）を以下サイトで公開しました。

https://github.com/kaorumorikawa/mynainfo/releases/tag/%E3%83%9E%E3%82%A4%E3%83%8A%E3%83%B3%E3%83%90%E3%83%BC%E3%82%AB%E3%83%BC%E3%83%89%E3%80%80%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF
【Streamlit】Webに公開する

※私は下記のコードを使い回します。

```py:main.py
import streamlit as st
import time

st.title('Streamlit 基本操作')

'スタート'

latest_iteration = st.empty()
bar = st.progress(30)

'スタート'

latest_iteration = st.empty()
bar = st.progress(0)

for i in range(100):
    latest_iteration.text(f'Interation {i+1}')
    bar.progress(i + 1)
    time.sleep(0.1)

expander1 = st.expander('問い合わせ')
expander1.write('問い合わせ内容を書く')
expander2 = st.expander('問い合わせ')
expander2.write('問い合わせ内容を書く')
expander3 = st.expander('問い合わせ')
expander3.write('問い合わせ内容を書く')

```

# 必要なこと

・Streamlit Shearing
・git

# Streamlit Shearing

Streamlitの公式ページからユーザー登録・ログインを行います。

https://streamlit.io/cloud

ログインすると以下のページが表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/1cee5f5a-e4a6-bfc3-0d86-50cfa8d8496c.png)


# git

GitHubでリポジトリを作成しておきまう。
詳細説明は省きます。

### requirements.txt

requirements.txtを作成します。
このファイルには、開発しているアプリケーションで使う外部ライブラリを記載します。

requirements.txt→外部のライブラリ
main.py→pythonの標準ライブラリ

で分けて記述していきます。

streamlitのみrequirements.txtに移します。
```txt:requirements.txt
streamlit
```
コマンド
```
pip freeze
```

様々なライブラリのバージョンの一覧が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/942c0bfc-7b8f-5605-2fa9-22ddab8e3918.png)

streamlitを探し、requirements.txtに貼り付けます。
※バージョン指定しない場合は、自動的に最新のものになります。

ここでGitにプッシュしておきます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/14604ed2-56e7-6d50-8292-d6b7171f4683.png)

画面右のNew appをクリック。
必要事項を記入していきます。

上から
・GitHubで使用するリポジトリ名
・GitHubの現在のブランチ名
・実行したいファイル名を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/74c5ea21-97c2-0249-1674-fbe5edc6d170.png)

最後にDeployをクリックし、書いたコードが無事に実行されれば公開成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/85e528af-002b-8ddc-1875-d53112b445de.png)

画面右したのmanage appをクリックすると、ログが表示されるサイドバーが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/9809f5cd-2a79-4796-e391-a5cd2088a8b0.png)



試しにURLをコピーして他のブラウザに張り付けても、正常に動いています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/1500bf56-b908-6bf1-fb2c-8478bb29935d.png)


# アプリケーションを複数追加したいとき

Your appsをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/930a4e4a-e31f-5cd5-3a1e-4f2b5e6ad88b.png)

作成済みアプリケーションの一覧が表示されます。
New appをクリックすれば、アプリケーションが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/760ed457-0237-2b7a-31d1-65276bb46acd.png)
ChatGPTプラグインを使って、AWSのインフラ構成を作図してもらった話

## 完成物
シンプルな三層アーキテクチャの構成図を作ってもらいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066161/c49c4ab6-2d5d-e38d-ec83-c29ee9a1d999.png)

## 実行したプロンプト
```
# 命令
下記の「構成」を満たすAWSのシステム構成図をMermaidで作成して下さい。
作図を行う際、システムの構成要素は「Mermaid記法集」のデザインを元に記述して下さい。
各種システム構成要素には全てその名称も明記して下さい。

## 構成
- シンプルな三層アーキテクチャ
- ALBの前段にCloudFrontを立てている
- ALBはパブリックサブネット内のEC2に負荷分散する
- EC2はプライベートサブネット内のRDSにアクセスする
- 画像ファイルなどのデータはS3に保存しており、CloudFront経由で配信している

## Mermaid記法集
### 各種グループの記法
#### AWS Cloud
fill:none,color:#345,stroke:#345

#### Region
fill:none,color:#59d,stroke:#59d,stroke-dasharray:3

#### VPC
fill:none,color:#0a0,stroke:#0a0

#### Availability Zone
fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8

#### Private subnet
fill:#E7F2E8,color:#092,stroke:none

#### Public subnet
fill:#E8F2F9,color:#07b,stroke:none

### 各種サービスの記法
#### Network関連サービス（ELB, API Gatewayなど）
fill:#84d,color:#fff,stroke:none

#### Compute関連サービス（EC2, ECS, Lambdaなど）
fill:#e83,color:#fff,stroke:none

#### DB関連サービス（RDS, Redshiftなど）
fill:#46d,color:#fff,stroke:#fff

#### Storage関連サービス（S3, EBS, EFSなど）
fill:#493,color:#fff,stroke:#fff

#### AWS外部の外部要素（ユーザー, コンピューターなど）
fill:#aaa,color:#fff,stroke:#fff
```

## インスピレーションを得た記事
毎日欠かさず確認しているDevelopersIOにて、面白い記事を見かけたことがきっかけでした。

https://dev.classmethod.jp/articles/chatgpt-plugins-diagram-it/

詳細は記事内で確認して頂きたいのですが、ChatGPTのプラグインを使用してAWSのインフラ構成図をMermaidで自動生成する試みがなされており、「あとは出力されるデザインを調整出来れば、お客様に構成を説明する際の資料に使えるレベルになりそうだな」と考えました。

また、上記記事内にChatGPTプラグインの利用方法が詳細に説明されておりますので、プラグインを利用検討されている方もこちらをご確認頂ければと思います。

## Mermaidのデザインを調整するために確認した記事
「Mermaid AWS」というキーワードでググって見たところ、下記の記事が見つかりました。

https://qiita.com/b-mente/items/b17275090176d63d1d69

Mermaidの知見がギッチリ詰まった神記事ですね。ありがたく拝借させて頂き、プロンプト内にてデザインを指定するのに利用致しました。

## まとめ
期待以上の完成度でAWSのインフラ構成図をChatGPTに作図させることに成功しました。

構成内容をより詳細に指定したり、まだ試してませんが、Terraformを利用している場合はStateファイルの内容を指定することで、より詳細な構成図を作図してもらえそうです。（ただし、誰でもアクセス可能なURLにインフラ構成内容が出力されるため、本番環境のStateを渡すのは絶対にNGだと思います。やるとしたら、検証環境の情報くらいにしておいた方が良さそうです。）
SSLエラーでEclipseにPydevが入らないから何とかしてみた

# はじめに

EclipseでPythonがつかえるように環境構築をしました。
Pydevのマニュアルでは、導入ができない人向けです。
特に、SSLでのエラーでできなかった人向けです。

## 環境

- Windows10 pro
- Python 3.11

## 手順

1. Pythonのインストール
    「Python 3.11」をインストール
2. Eclipseのインストール
    「Pleiades All in One Eclipse」のPython用をインストール
3. Pythonの仮想環境の作成
    1でインストールしたPythonをもとに、Pythonの仮想環境を作成
4. Eclipseの設定
    Pythonを動かすためにEclipseのインタープリターの設定を行う
5. Hello Worldを出力
    プロジェクトを作成し、モジュールを作成と実行

## 1. Pythonのダウンロード

Pythonのインストール手順

1. Windowsの画面左下の検索でPythonと入力
2. 検索結果か「Pythonのコマンドの実行」をクリック
    クリックするとMicrosoft Storeが起動しPythonの入手画面が出てくる
    Microsoft StoreでPythonを提供しているので利用する    
        3. Microsoft Storeで __「Python 3.11」__ を入手
    お金は請求されない    
4. コマンドプロンプトで`python`を実行 以下の文書が表示されたらヨシ
      
```shell
C:/User/(user)>python
Python 3.11.3 (~~)on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

## 2. ecliplseダウンロード

Eclipseのダウンロード方法
＊既存に入っているEclipseは消さないでください

1. [Eclipseのダウンロードページ](https://mergedoc.osdn.jp/)にアクセス
2. WEBページの表からWindowsのPythonをダウンロード
3. ダウンロードが終わったらそのフォルダをダブルクリックし解凍をクリック

## 3. Pythonの仮想環境の作成

Pythonの仮想環境の作成をします。

仮想環境は、用途に応じて専用の実行環境を作成し、切り替えて使用します。
例えば、別の環境に影響を与えずに、モジュールの追加・入れ替え、バージョン管理ができます。

1. エクスプローラーで作業用のフォルダを作成する
    プロジェクトやプログラムファイルを保存する
2. コマンドプロンプトを開く
3. 1.で作成したフォルダへ移動する　
    移動するコマンドは、`cd <パス>\<作成したフォルダ>`
4. コマンド`python -m venv venv`を実行
5. エクスプローラーで作成したフォルダの中に`venv`というフォルダが作成されていることを確認
6. 1のフォルダでコマンド`.\venv\Scripts\activate`を実行
7. コマンド実行した後に、行の左側に"(venv)"と書かれていたらヨシ

```cmd
(venv) C:\Users\(パス)>_
```

## 4. Eclipseの設定

ダウンロードしたEclipseで仮想環境のPythonを使うように設定をします。

1. ダウンロードしたEclipseを起動
2. タブのウィンドウから設定を選択
3. `'Pydev>インタープリター>Python インタープリター'`を選択
4. 新規...をクリック
5. python/pypy exeの参照をクリック
6. 参照先はPythonの仮想環境の作成で作成したフォルダの`<作成したフォルダ>\venv\Scripts\python.exe`を選択
7. すべて選択してOK
8. 適用して閉じる

## 5. Hello Worldを出力

かの有名なHello Worldを出力してみよう

1. タブのファイルの新規からPydevプロジェクトを選択
2. プロジェクト名を記入
3. インタープリターを選択
4. 完了を押す
5. 作成したプロジェクトで右クリックして新規、Pydevモジュールを選択
6. 名前を記入し完了
7. テンプレートはOKを選択
8. ファイルに`print("hello world")`と記入し保存
9. 実行する。実行する方法は、Python Runを選択しOK
10. コンソール上にhello worldと出力されればヨシ

___

# 注意

必要なモジュールをインストールするときSSLのエラーで証明書エラーが発生する場合があります．

なのでpipコマンドを使用する際には`--trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org`を追記してください

```shell;pipコマンド
$pip --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org install <ライブラリ名...>
```
jsスクリプトでMongoDBを操作する

MongoDBを操作する際、シンプルなCRUDであればmongoシェルに入って直接クエリ実行すれば良いですが、aggregateなど複雑なクエリを実行したいときなど、スクリプトを書いて実行したいケースが出てきます。
mongoコマンドにファイルパスを渡して、jsのスクリプトを実行することができます。

# find

まずはスクリプトの作成

```js:find.js
// 2021-05-17 00:00:00以降に作成されたユーザーを取得
db.users.find(
    {"created_at": {"$gte": ISODate("2021-05-16T15:00:00.000Z")}},
    {"name": 1, "email": 1, "created_at": 1}
).forEach(function(user){
    // JSONを整形して出力
    print(JSON.stringify(user, null, 4));
});
```
スクリプトの実行
```bash
# --quietオプションでDB接続時の出力を非表示
$ mongo <db_name> find.js --quiet
{
    "_id": {
        "$oid": "6216f5582da21fbad33d315f"
    },
    "name": "test01",
    "email": "test01@example.com",
    "created_at": "2022-02-24T03:02:48.503Z"
}
{
    "_id": {
        "$oid": "6216f5592da21fbad33d3167"
    },
    "name": "test02",
    "email": "test02@example.com",
    "created_at": "2022-02-24T03:02:49.146Z"
}
{
    "_id": {
        "$oid": "6216f5592da21fbad33d3168"
    },
    "name": "test03",
    "email": "test03@example.com",
    "created_at": "2022-02-24T03:02:49.218Z"
}
```

# aggregate
aggregateも同様に実行できます。以下ではidとnameをカンマで結合して出力しています。
```js:aggregate.js
// グループに所属していないユーザーを取得
db.users.aggregate([
    {
        "$lookup": {
            "from": "groups",
            "localField": "_id",
            "foreignField": "users.id",
            "as": "groups"
        }
    },
    {"$match": {"groups": {"$size": 0}}}
]).forEach(function(user){
    // _idとnameをカンマ区切りで出力
    print(user._id + ',' + user.name);
});
```

```bash
# 結果をテキストファイルに出力
$ mongo <db_name> aggregate.js --quiet > result.txt
$ cat result.txt
6216f55f2da21fbad33d31a0,test04
6216f55f2da21fbad33d31a1,test05
6216f55f2da21fbad33d31a9,test08
6216f55f2da21fbad33d31aa,test10
```
こんな感じで実行することができます。
【社労士試験+ChatGPT】社労士過去問をChatGPT-4に解かせて解説させ、現役社労士が補足質問してみた(労働基準法)

# はじめに
ChatGPTは現在、数多くの注目を集めています。
社労士業務を含む様々なビジネス環境でその利便性が認められています。
AIはその特性を理解し、適切に活用することで業務の効率化を促進する非常に有益なツールです。実際に、
[服部社会保険労務士事務所](https://hattori-sr.jp/)ではChatGPTを活用し、AIアシスタントとしてLINE botを開発しています。
ウェブサイトで公開していますので、興味のある方は是非ともチェックしてみてください。

# ChatGPTは社労士試験に有効なのか？
社労士の試験を目指す方の中には、AIを学習ツールとしてどう活用できるかを検討している方がいるかもしれません。
そこで、ChatGPT-4が過去問を解く場合、どのような答えを生成するのかを確認するための実験を行いました。


# 出題の条件
実際にChatGPT-4へ出題する問題は以下の通りです。
実際は4択問題ですが今回は正誤問題として出題しました。労働基準法の理解を求める基礎問題です。

> 労働基準法の労働者であった者は、失業しても、その後継続して求職活動をしている間は、労働基準法の労働者である。
> （令和4年 労働基準法/安衛法 問1 問題文 より引用）

正解は「誤り」ですね。


## ChatGPT-4へのプロンプト
労働基準法の労働者であった者は、失業しても、その後継続して求職活動をしている間は、労働基準法の労働者である。

社労士試験の正誤問題です。
この回答と根拠を答えて下さい。


## ChatGPT-4の回答

この問題の正誤についてですが、その文は「誤り」です。

労働基準法の下での「労働者」とは、一般的には、雇用主から賃金を得て労働する者を指します。この定義は、労働基準法第9条に基づいています。

したがって、失業して求職活動をしている間も、その人が賃金を得て労働していなければ、労働基準法の下では「労働者」ではないと考えられます。求職者は、一般的には労働基準法の適用を受ける「労働者」の範囲には含まれません。

しかし、具体的な事例や状況によっては、求職活動中でも労働基準法が適用されるケースもあるかもしれません。例えば、職業訓練中や一定のインターンシップの場合など、実質的には労働を行っていると見なされる状況などです。しかし、そのような特殊なケースを除けば、一般的には求職者は労働基準法の「労働者」には該当しないと言えるでしょう。

したがって、問題文の主張は基本的に誤りと言えます。


# 社労士から補足
こんな回答が返ってきました。
このままでも参考書に載せて良いレベルですが、問題の主旨に沿って、労働者の定義についてもう少し踏み込んでほしいところです。
そこで、次のように追加の補足質問をしてみました。

## ChatGPT-4へのプロンプト
労働基準法の労働者の条件を箇条書きで教えてください。


## ChatGPT-4の回答

労働基準法における労働者の条件は次の通りです：

雇用契約の下で働く者: 労働者は、一方の当事者（雇用主）から賃金を受け取り、他方の当事者（労働者）が労働を提供する労働契約の下で働く者です。

賃金を得る者: 労働者は、その労働の対価として賃金を受け取ります。賃金は現金又は現物で支払われ、通常は定期的（例えば、日給、週給、月給など）に支払われます。

労働の指揮・監督下にある者: 労働者は、雇用主の指揮・監督下で労働を行います。つまり、労働者は自己の意志で労働の方法や時間を自由に決めることができない状況下で働く者とされます。

特定の職種や業種により例外的な取り扱いがある場合もあるため、具体的な状況については労働法専門家に相談することが推奨されます。

# この結果について
これで回答の解説として完璧になったと思います。
補足質問は失業者の方にフォーカスしたり、賃金の定義を確認したり、色々と応用が考えられます。
過去問を解くだけでなく、ここからさらに学びが広がる有用な学習ツールになり得ることがわかりました。

私は現役社労士なので社労士試験を題材に選びましたが、諸試験に対応することはもちろん可能でしょう。
参考書を何冊も購入するよりも、ChatGPT-4を使用した方が効率的かもしれません。

ただし、回答が本当にあっているのか検証することは必須です。
ChatGPTのデータはリアルタイムのものを使用しているわけではないので、最新法令が非対応だったり、逆に改正前のデータを持ってきてしまったりすること等が考えられます。
あくまで学習ツールの一つとして用いましょう。
ターミナルからXが立ち上がらない問題【macOS】

# 1. 問題点
なんでかわからないけど、macportsでinstallしたときは出来ているのに、何かのタイミングでmacのターミナルからXが立ち上がらない問題が発生して、何度か初期化するという暴挙に出た。
にも関わらず、再び問題が発生した。
例えば

```:terminal
$ grads 

Grid Analysis and Display System (GrADS) Version 2.2.1
Copyright (C) 1988-2018 by George Mason University
GrADS comes with ABSOLUTELY NO WARRANTY
See file COPYRIGHT for more information

Config: v2.2.1 little-endian readline grib2 netcdf hdf4-sds hdf5 opendap-grids geotiff shapefile
Issue 'q config' and 'q gxconfig' commands for more detailed configuration information
Landscape mode? ('n' for portrait):  
GX Package Initialization: Size = 11 8.5 
Error in GXSTRT: Unable to connect to X server
```

gradsを立ち上げるとX serverに繋がらねえと出てくる。
画像ビュアーeogを立ち上げると
```:terminal
$ eog fig.png 

(eog:17280): Gtk-WARNING **: 21:53:22.389: cannot open display:
```
おおおお。cannot open displayと出るではないか。

※一応改めて確認すると、macportsでinstallしたxorg-serverを使用している。

# 2.解決法
DISPLAY環境変数を指定してやればいいので、x11からターミナルを立ち上げ、DISPLAYを確認する。

```:xterm
$ echo $DISPLAY
:3
```
おおお。

ターミナルに戻って
```:terminal
$ echo $DISPLAY

$ export DISPLAY=":3"
$ echo $DISPLAY
:3
```
と入れてやる。

すると、ターミナルからXが立ち上がるようになる。
```:terminal
$ grads

Grid Analysis and Display System (GrADS) Version 2.2.1
Copyright (C) 1988-2018 by George Mason University
GrADS comes with ABSOLUTELY NO WARRANTY
See file COPYRIGHT for more information

Config: v2.2.1 little-endian readline grib2 netcdf hdf4-sds hdf5 opendap-grids geotiff shapefile
Issue 'q config' and 'q gxconfig' commands for more detailed configuration information
Landscape mode? ('n' for portrait):  
GX Package Initialization: Size = 11 8.5 
```
やったー。

# 3. 最後に
初期化する前に、確認しましょう。
React：今すぐ学ぶべき理由と学習リソース

Reactは現在最も人気のあるJavaScriptライブラリの一つで、
その理由と共に、Reactを学習するためのリソースをここに紹介します。

## なぜReactを学ぶべきなのか？

### 1. 需要が高い

現在、フロントエンド開発における求人の多くがReactのスキルを求めています。Reactの知識を身につけることで、より多くの機会を掴むことができます。

### 2. コミュニティのサポート

ReactはFacebookにより開発され、大規模なコミュニティによるサポートがあります。これにより、問題に対する解決策を見つけやすいです。

### 3. 再利用可能なコンポーネント

Reactはコンポーネントベースの設計を採用しており、再利用可能なコードを書くことを可能にします。これにより、開発時間を短縮し、保守性を向上させます。

## Reactの学習リソース

以下に、Reactを学習するための一部のリソースを紹介します。

### 1. [公式ドキュメント](https://reactjs.org)

Reactの公式ドキュメントは、初心者から上級者まで幅広く対応しています。特にチュートリアルやガイドは、Reactの基本的な概念を理解するのに役立ちます。

### 2. [Codecademy](https://www.codecademy.com)

CodecademyのReactコースは、実際にコードを書きながら学べるので、初学者におすすめです。

### 3. [Udemy](https://www.udemy.com)

Udemyには多くのReactのコースがあります。

### 4. [YouTube](https://www.youtube.com)

YouTubeには多くの無料のReactチュートリアルがあります。特に[Traversy Media](https://www.youtube.com/channel/UC29ju8bIPH5as8OGnQzwJyA)や[Academind](https://www.youtube.com/channel/UCSJbGtTlrDami-tDGPUV9-w)のチャンネルはおすすめです。

### 5. [React入門.com](https://www.react-guide.com)

日本語のReact学習リソースとしては、「React入門.com」がおすすめです。初心者向けのわかりやすい解説と共に、実際に動作するサンプルコードも提供しています。

## まとめ

Reactはそのパフォーマンスと柔軟性により、フロントエンド開発の主流となっています。再利用可能なコンポーネント設計や大きなコミュニティサポートは、その学習をより価値あるものにします。

上記のリソースを活用して、あなたもReactの世界に飛び込んでみてください。
私の開発環境

[gitのチュートリアル](https://qiita.com/ "執筆中")で利用している私の環境の簡易構築メモなどです。
構築したのが数年前なので情報が古いです。
2019年ごろの作業記録と現在(2023年)の状態を記しています。

# wsl (Windows Subsystem for Linux) のインストール手順 (2019年ごろ) 
1. コントロールパネル ＞ プログラム ＞ Windowsの機能の有効化または無効化
    * サブシステムとVMにチェックを入れてOKを押す
1. storeからUbuntuを入れる
1. wsl 起動後 "wsl.exe --update" を実行する
    * wslを起動すると"wsl.exe --update"を促すメッセージが出たのでそのままの文字列を実行しアップデート

![Windows の機能 2023_04_05 0_50_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1642056/88a51e8a-6a61-905b-de52-81610b936886.png "Windowsの機能の有効化または無効化 ダイアログ")

現在(2023年4月)はMicrosoft Storeから直接入れるだけでよいようです。(未確認)

https://apps.microsoft.com/store/detail/windows-subsystem-for-linux/9P9TQF7MRM4R

# conEmu (terminalソフト) のインストール手順
こちらからインストールのみで使えます。

https://conemu.github.io/

しかしある日、アップデートをしたところ、bashを使うとエラーになってしまいました。
bashを起動する際に利用している wslbridge に原因があるとのことでしたので、その不具合以降、直接wslを起動しています。

:::note info
エラーについての詳細情報(2019年頃の情報)
* [Conemu doesn't work with wsl since windows update](https://stackoverflow.com/questions/58794164/conemu-doesnt-work-with-wsl-since-windows-update "stackoverflow内の関連スレッド")
* [Run native wsl.exe in ConEmu](https://conemu.github.io/en/wsl.html#wsl-native "解決策" )
:::

さらに私はユーザデータ関連をDドライブに格納しているので引数(--cd)に、Dドライブの該当フォルダを指定しています。
shell起動時にカレントがdindowsのフォルダになるのは便利だなと思います。
![設定 [xml] ConEmu 221218 [64] {Stable} 2023_04_05 1_16_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1642056/f5a2b383-0380-4f94-0c57-f27331e1a43e.png "conEmu の設定ダイアログ")

conEmuは便利ですが、今はWindows Terminalがあるのでそちらでよいかもと思います。

https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701?hl=ja-jp&gl=jp&rtc=1

# GitKraken
https://www.gitkraken.com/download

branchなどの履歴をビジュアル化して確認できるので利用しています。
ChatGPT Pluginの始め方 (2023年5月17日)

# はじめに

ChatGPT Pluginが使えるというツイートをみてから、私も使いたい！と思ったのは私だけでないはず。
2023年5月17日現在では「ChatGPT Plus」の人は全員使えるとのことなのでその手順をまとめます。(WaitListに登録する必要はなくなったみたいです。

# 前提

- [ChatGPT](https://chat.openai.com/)を使ったことがある
- [ChatGPT Plus](https://openai.com/blog/chatgpt-plus)のサブスクを購入している


# 手順

- https://chat.openai.com/ にアクセス
- 左下の自分のアカウントをクリック
- [Settings]をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/6f125318-4507-98ee-936c-871ba6a673dd.png)

- Beta deatures
    - PluginsをOnにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/83ed60b5-4503-45fe-3936-fc445ea1fbfe.png)

- Chat画面に戻る
- GPT-4にマウスカーソルをあてる
    - Pluginsをクリック


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/b5a94835-7b14-a15d-1c86-3d0224b37951.png)

- No Plugins enabledをクリック
- Plugin storeをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/b4f23434-0b1b-bd89-c2a1-e9e0b6308ff0.png)

するとPlugin Storeが出てくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/205cd3f9-0766-ba5e-b93e-d00829571ebb.png)

- All pluginsを選択
- 試しに「Tabelog」をInstall

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/154cdee6-e318-3c93-03bb-513c4c5d2140.png)

- Installできているとリストに出てくる
    - 緑ボタンを押すと、Installされた状態で、On/Offできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/ff5c3d10-9caa-8ba1-22d2-5d93e7227eb3.png)

- Chatを打ってみる
    - 「渋谷のおススメラーメン」
    - するとTabelogの挙動をした！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/11256bc9-5798-57c4-011f-757886827664.png)

# 最後に

この記事では、ChatGPT Plusの方向けに、ChatGPT Pluginの始め方の手順を示しました。
Angular, Jasmine, Karmaでテスト実行時にError: Unexpected synthetic property @hoge found. エラーになる

# はじめに
Angular, Jasmine, Karmaでアニメーションを含むコンポーネントのテストを実行しようとしたときに少し詰まったのでメモしておく

# 前提
テスト対象となるコンポーネントは`@angular/animations`を使用していた
また、app.module.tsでBrowserAnimationsModuleをインポート済みだった

```typescript:テスト対象コンポーネント
import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations'

@Component({
  selector: 'app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [
    trigger('hoge', [
      state('a', style({ height: '*', opacity: 1 })),
      state('b', style({ height: '0', opacity: 0 })),
      transition('a => b', [animate('1s')]),
      transition('b => a', [animate('1s')]),
    ]),
  ],
})
export class AppComponent {
  ...
}
```

# 原因
テストファイル(app.component.spec.ts)でBrowserAnimationsModuleをインポートできていなかった
```typescript:修正前
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('App', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [AppComponent],
    }).compileComponents();
  });

  it('hoge', () => {
    ...
  });
});
```
beforeEachでBrowserAnimationsModuleをインポートすることで解決した
```typescript:修正後
import { TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // 追加
import { AppComponent } from './app.component';

describe('App', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [AppComponent],
      imports: [BrowserAnimationsModule], // 追加
    }).compileComponents();
  });

  it('hoge', () => {
    ...
  });
});
```
２６．　今日の日課２４　もう来てるテクノロジー：量子コンピューター

# はじめに
　今日の日課２４日目です。今日の日課は量子コンピューターについてまとめていきたいと思います。
　量子コンピューターといえば、最近、理化学研究所が国産の量子コンピューターを稼働させました。これまでスーパーコンピューターで世界と戦ってきた日本としては量子コンピューターでも負けられないですね。

# １．そもそも量子コンピューターとは？
　まず初めに、量子コンピューターとは何なのかからまとめていきたいと思います。
　量子コンピューターとは、

>　物質を構成する原子や電子などの「量子」の持つ性質を利用して情報処理を行うコンピュータです。量子の運動は「量子力学」に支配されており、量子の世界においては「量子重ね合わせ」というまかふしぎな現象が発現します。この0と1の重ね合わせ状態を用いて並列計算を行うコンピュータが量子コンピュータなのです。
産総研マガジン, https://www.aist.go.jp/aist_j/magazine/20220518.html 

　ここで説明されているように、量子コンピューターは量子の重ね合わせという性質を利用したコンピューターです。
　では、量子の重ね合わせの性質は具体的にどうやって役立てられているのでしょうか。従来のコンピューターと比較してみていきましょう。

## 従来のコンピューター
　スーパーコンピューターを含む従来のコンピューターは０と１を使った二進数で計算しています。これはトランジスタというものを使っています。トランジスはオンオフを切り替えるスイッチのようなものです。ここから、オフの状態を０、オンの状態を１として二進数を表現しているわけです。この０か１の数はビット（bit)という単位で表記され、８ビット集まると１バイト（byte)になります。

## 量子コンピューター
　では、量子コンピューターはどうかというと、０と１の二進数で計算していることは量子コンピューターも変わりません。ここで量子の重ね合わせが出てきます。この量子の重ね合わせ状態とは、０と１の状態を同時に持っている状態のことです。例えると、コインは裏表があります。このコインを高速で回すと裏表が同時に見えると思います。この状態のことです。量子コンピューターの場合は量子ビットという単位を使います。

　これの何がすごいかというと、量子の重ね合わせを使うとこれまで０と１を使い分けて逐次計算していたものを並列で処理できるということです。これによって、計算スピードが跳ね上がります。
　これまで開発されている量子コンピューターには二つの種類があります。一つ目の量子ゲート方式はこれまでのコンピューターの量子版で同じようなことができます。汎用型量子コンピューターともいわれます。二つ目が量子アニーリング方式というものでこちらは特化型量子コンピューターと呼ばれています。これは組み合わせの最適化に特化したコンピューターです。

# ２．量子コンピューターの使い道
　では、量子コンピューターを使うと何ができるのかですが、使い道は限られているようです。
以下が具体的な量子コンピューターの使い道です。
・自動運転
　　～どのルートが最適かなどの計算に役立ちます
・新薬の開発
　　～どんな物質を組み合わせるとどんな効果の薬ができるかなどの計算に役立ちます。
・暗号の解読
　　～RSA暗号などの膨大な数の計算量によって保障されていた暗号の解読に役立ちます。

# ３．量子コンピューターの現在
　ここからは現在の量子コンピューターの進捗具合についていくつかのニュースをまとめます。

### ３．１理化学研究所が国産の量子コンピューターを稼働,2023/03/27, 日本経済新聞
https://www.nikkei.com/article/DGXZQOUC234XF0T20C23A3000000/

　この量子コンピューターの量子ビットは６４です。５０量子ビットで１６ペタバイトのメモリと同等なので、６４量子ビットはかなり凄そうです。

### ３．２東大とIBMが｢理研超え｣127量子ビットの量子コンピューター。この秋稼働へ, 2023/04/21, BISINESS INSIDER
https://www.businessinsider.jp/post-268994

　今度は１２７量子ビットと規格外ですね。ちなみに８０量子ビットで宇宙すべての原子が１ビットの情報を所持する場合のデータ容量を超えるらしいですｗ。

# ４．まとめ
　今回は量子コンピューターについてまとめてみました。かなり夢のあるテクノロジーですが、すでに実用化も始まっているところを見ると近いうちに量子コンピューターで新薬開発！とかはありそうですね。
　また、量子コンピューターが大衆化されるとこれまでの暗号化方式が使えなくなってしまいます。新たな暗号化の仕組みが必要ですね。

# 参考資料
１．Crystal-Method, 量子コンピュータが実現するとどうなる？その仕組みから解説,

https://crystal-method.com/topics/quantum-computer/

２．NRI,  量子コンピュータ,

https://www.nri.com/jp/knowledge/glossary/lst/ra/quantum_computer


３．2030年すべてが「加速」する世界に備えよ　NewsPicksPublishing

https://publishing.newspicks.com/books/9784910063133
【Laravel】正規表現で文字コードが判定されない場合の対処法 ＋ ひらがなを含まない全角英文字のみの正規表現

環境
・Windows 10 Home (Bld. 19045.2965)
・VSCode 1.78.2
・Laravel Framework 10.7.1
・PHP 8.1.18


Laravelでpreg_matchを使用し、全角英文字と全角英子文字のみをチェックしようと思った際に少しハマったのでメモ。

全角英文字の正規表現で、
```php
$pattern = "/[Ａ-Ｚ]/";
```
と書くとひらがなが反応してしまったり
```php
$pattern = "/[\uFF21-\uFF3A]/";
```
としても何も反応しなかった。
色々調べた結果、

```php
$pattern = "/[\x{FF21}-\x{FF3A}]/u";
```
で全角英文字のみチェック出来るようになった。

最終的に全角英小文字も追加して
```php
$pattern = "/[\x{FF21}-\x{FF3A}\x{FF41}-\x{FF5A}]/u";
```
とした。


[参考にした文字コード表](https://0g0.org/category/FF00-FFEF/1/)
全日本郵便番号データ

## 目的
全日本郵便番号のJsonデータを共有しようと思います。
必要な方は遠慮なく、ご利用ください。

## 説明
このJsonデータは商品開発向けに圧縮されています、Jsonのファイル名は郵便番号先頭の3桁数で命名されています。  
 
データの中身は下記の感じです。
```json
 {"0010000":[1,"札幌市北区",""],"0010010":[1,"札幌市北区","北十条西"],"0010011":[1,"札幌市北区","北十一条西"],"0010012":[1,"札幌市北区","北十二条西"],......
```

**ダウンロード☟**

https://github.com/JapanTools/Japan-Postal-Code

## 参考
[郵便番号データダウンロード](https://www.post.japanpost.jp/zipcode/download.html)
[郵便番号データの説明](https://www.post.japanpost.jp/zipcode/dl/readme.html)
gitプルリクエスト前ガイド（自分用）

gitの動かし方（上から順に行う）

git branch <作成ブランチ名>(featureブランチのようなもの)

git checkout <作成ブランチ名>

作業を行う（featureブランチ内で）

[一度起こしたミス（cd確認漏れ）カレントディレクトリ内を変更することを意識]

git add .
// 現在のディレクトリのすべてのファイルをインデックスに追加

git commit -m '<変更内容を記載する>'

git checkout <mainブランチ>

git pull
//更新をかけてローカル環境に反映させる

git checkout <作成したブランチ名>

git push -u origin HEAD 
または
git push -u origin <作成したブランチ名>

//以前にpushしたことのあるブランチを再度pushする際、強制プッシュで対応が必要だった git push -f origin HEAD　または　<作成ブランチ名>

backlogでプルリクエスト作成

記載＞担当者を選択確認の依頼を行う

merge(担当者からマージ)されたら...

git checkout <mainブランチ名>

git pull

git branch -d <作成したブランチ>
作成ブランチの削除

一区切り
【Swift】setter内の無限ループについて

### NGパターン

```swift
class Person {
    var name: String? {
        get {
            name // 無限ループ
        }
        set {
            name = newValue // 無限ループ
        }
    }
}
```
こう書くと、getterがnameを返そうとするときにsetterが呼ばれて、setterがnameを設定しようとするときにgetterが呼ばれてしまって、無限ループが発生し、クラッシュするので注意が必要です。

### 解消法
``` swift
class Person {
    private var _name: String?
    var name: String? {
        get {
            _name
        }
        set {
            _name = newValue
        }
    }
}
```
private変数_nameを使用して値を保持し、setterでそれにアクセスすることで無限ループを避けることができます。

### 補足
```swift
class Person {
    
    var name: String? {
        didSet {
            name = newValue
        }
    }
}
```
didSetなら無限ループしないです。
Cognos Framework Manager でLDAPユーザー属性を用いたデータ権限制御

# 概要
LDAP上のユーザー属性で職位により、アクセス可能なデータを制御する方法です。
**Manager職位のユーザーがレポートを実行した場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/73e0a083-8d07-78bc-c071-adb5c78b4f3c.png)

**Staff職位のユーザーが同レポートを実行した場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/e9a7d77a-cb53-248c-79a8-1898ae2f5666.png)

# 実装手順
LDAP上でcoguser1ユーザーを作成し「title」属性を追加し、値に「Manager」を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8be21639-6263-7468-7cb0-382eea45fdd7.png)

同様にcoguser2ユーザーを作成し「title」属性を追加し、値に「Staff」を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/f6762595-4da5-c0b4-3cba-259d7b9aca3e.png)

Cognos ConfigurationでLDAPネームスペースの「Custom properties」を編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/9f04a331-36b2-45fc-b956-8c9e8b7cdcda.png)

以下のようにValueに属性名を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/2ccb215b-9ce4-77c9-9b3d-d4aa321c6f3b.png)

データアクセスの制御用に以下のような表を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/c6505fa6-b526-9f0f-41a8-4b6743b928e4.png)

AUTH1表をFramework Managerに取り込み、既存のSALES表とREGIONキーで結合します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/fa507e13-0c12-f0f3-318b-cfc12de7364f.png)

AUTH1表のFiltersに以下のフィルターを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5bdbf427-4ff7-cf27-3558-c5982aa0ca89.png)

パッケージを発行しリスト上に「TITLE」「REGION」「SALES」を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5145fed5-b134-0725-0aef-ee73f329dc99.png)

coguser1がレポートを実行した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/4b6ed6c2-240d-d60c-f2f7-80a35f5a758e.png)

coguser2がレポートを実行した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/20f22010-2dbf-aeff-d562-006a88364f6a.png)