OmniAICreator/Qiita-1.07M huggingface dataset:
Slack  のステータスを API で更新

# はじめに

すっかりハイブリッド(在宅/出社)な働きかたが浸透してきて，在宅勤務している同僚から出社しているのかどうか聞かれることも多いと感じる今日このごろ，手動で Slack のステータスを更新するのも煩雑なので，[IFTTT](https://ifttt.com/) などで自分の位置情報をもとにステータス絵文字を更新するため，API でのステータス更新方法を久しぶりに調査しました。

# Slack Application の作成

https://api.slack.com/apps からアプリケーションを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/295588e2-79a2-9f7c-925d-3273c5940a59.png)

Create New App を押下，From Scratch を選択，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/5aaca32c-16f5-129a-80ed-34b0c5812431.png)

App Name を指定，workspace を選択，Create App を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/56cafc48-f659-009f-ebd3-322773420f71.png)

# User Token Scope の設定

Building Apps for Slack で右下の Permissions を選択，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/8631dd7b-9a59-dc76-ac2b-cf3a800246d5.png)

User Token Scopes で users.profile:write を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/b1881370-c3b5-cec0-3c10-9202c2e05354.png)

# アプリケーションのインストール

上部に戻り，OAuth & Permissions - OAuth Tokens for Your Workspace - Install to Workspace を押下，アプリケーションを Workspace にインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/6af88779-1e77-03a4-2188-7ecf68687ed8.png)

許可するを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/9019ca01-d294-fa29-4975-494f8c40bbd2.png)

# User OAuth Token 生成

xoxp- で始まる User OAuth Token が生成されますので，コピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/189a35b0-9440-8ec1-a961-61dca3b83e89.png)

# curl コマンドで Slack ステータス更新

以下のように API リクエストを送信すると，

```
OAUTH_TOKEN=xoxp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl -X POST -H "Authorization: Bearer ${OAUTH_TOKEN}" \
-H "Content-type: application/json; charset=utf-8" \
-d '{"profile": {"status_emoji": ":office:"}}' \
https://slack.com/api/users.profile.set
```

```
OAUTH_TOKEN=xoxp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl -X POST \
-H "Content-type: application/x-www-form-urlencoded" \
-d "token=${OAUTH_TOKEN}&profile={'status_emoji': ':office:'}" \
https://slack.com/api/users.profile.set
```

このように ```:office:``` 絵文字が設定されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122952/93edd273-5d1d-b9bd-31c7-4348158d7047.png)

```:workfromhome:``` を ```status_emoji``` に設定すれば，在宅絵文字に変更できます。
Go TemplateのREPLを作るためのトリック

# TL; DR

- text/templateのREPLを自作
- テンプレートの評価にはこれまでの入力履歴との結合が必要
- 表示されない文字 `\034` で履歴と結合、評価後にこの文字以降だけを取り出し出力

# はじめに

Go の[text/template](https://pkg.go.dev/text/template) パッケージで使える構文は非常に強力で、単体でプログラミング言語として使用できるほどです。

https://qiita.com/Syuparn/items/4157d13c39b95185acfd

そこで、**Go Templateの ~~沼に引きずり込む~~ 魅力を伝えるために、インタープリターを作成しました**。

https://github.com/Syuparn/tmplscript/tree/main

本来テンプレートエンジンであるこの言語でREPLを作るにはトリックが必要だったため、本記事ではこの方法について紹介します。

# REPLを作る上での課題

REPLは入力した行を評価し、対話的にその結果を出力します。

```:REPLの例（Python）
>>> "Hello, " + "world!"
'Hello, world!'
>>> a = "again!"
>>> "Hello, " + a
'Hello, again!'
```

動作としては以下の流れです。

- 評価するのは直近の1行だけ
- 変数はこれまでの履歴をすべて引き継ぐ

翻ってGo TemplateのREPLを考えてみましょう。Templateは当然REPLのためには作られていないため「定義された変数を保持した状態で次の入力を評価する」機能はありません。
これまでに定義された変数を参照するには再度すべての入力を評価する必要があります。

```:REPLの例（Go Template）
tmpl:1> {{$a := "again"}}

# $aを知るには1行目をもう一度評価する必要がある
# ※templateでは、`{{ }}` に囲まれていない地の文はそのまま表示される
tmpl:2> Hello, {{$a}}
Hello, again
```

一方、これまでの行を単に再度評価した場合、**前の行までの出力が重複**してしまいます。

```:過去の行を全て再度評価する場合
tmpl:1> Hello, world!
Hello, world!

tmpl:2> {{$a := "again"}}
Hello, world!

tmpl:3> Hello, {{$a}}
Hello, world!
Hello, again
```

これは鬱陶しいですね...

# 解決策

- 評価するのはこれまでの全入力
- 出力するのは直近の1行を評価した結果だけ

両者をみたすために、直近の入力とこれまでの入力履歴を分離するための区切り文字 `\034` を入れることにしました。

```:評価の仕組み
入力
{これまでの入力のソースコード} \034 {直近の行のソースコード}
↓ 評価
{これまでの入力を評価した結果} \034 {直近の行を評価した結果}
↓ \034 の後だけを抽出
{直近の行を評価した結果}
```

```:例
これまでの入力: Hello, world!\n{{$a := "again"}}\n
直近の1行: Hello, {{$a}}\n

Hello, world!\n{{$a := "again"}}\n\034Hello, {{$a}}\n
↓ 評価
Hello, world!\n\n\034Hello, again\n
↓ \034 の後だけを抽出
Hello, again\n
```

区切り文字 `\034` は表示されず、ユーザーが使うこともほぼ無いので入力を壊してしまう心配はほとんどありません。
（`\034` は[GAWKの添え字の区切り文字](https://linuxjm.osdn.jp/html/GNU_gawk/man1/gawk.1.html)を参考に選びました ）
また、Go Templateは `{{ }}` の外側をそのまま出力するため、**`\034` そのものは評価の前後で変化しません** [^034]。マーカーとしても優秀です。

# おわりに

以上、Go TemplateのREPLで出力を制御するためのトリックでした。`\034` は手軽に扱えるので、自作言語、CLIで区切り文字が欲しい場合に使ってみてはいかがでしょうか？

[^034]: 仮に変化するとすれば `{{ }}` の内側にあることになりますが、その場合行内で `{{` と `}}` が対応していないためシンタックスエラーになります。
Seeed XIAO BLE nRF52840 Senseで6軸センサを使う

## 初めに
内蔵のIMUを使おうと公式Wikiに従ってやってもいまくいかなかったので，まとめます．

## ライブラリの導入
Seeed studioの公式Wikiには`Arduino_LSM6DS3`を導入しろと書いてありますがこれハズレです． 正しくはこちらのライブラリ[Seeed_Arduino_LSM6DS3](https://github.com/Seeed-Studio/Seeed_Arduino_LSM6DS3/releases/tag/v2.0.3)を使います．

ということでもし, `Arduino_LSM6DS3`がある場合は消してください．

Releaseから現時点での最新版の[v2.0.3](https://github.com/Seeed-Studio/Seeed_Arduino_LSM6DS3/archive/refs/tags/v2.0.3.zip)をダウンロードして展開しArduinoIDEのライブラリディレクトに入れてください．

## 6軸センサの値を取得して姿勢推定
姿勢推定には[MadgwickAHRS](https://github.com/arduino-libraries/MadgwickAHRS)を使用します． [最新のコミット](https://github.com/arduino-libraries/MadgwickAHRS/archive/refs/heads/master.zip)をダウンロードして先ほど同様に展開します．

測定周波数の設定は公式のデータシート見ればいいんですが， こんな感じのソースコードがあって参考になります
https://github.com/JohnsonShen/AHRS_RD/blob/master/SparkFunLSM6DS3.c

```cpp
#include <LSM6DS3.h>
#include <Wire.h>
#include <MadgwickAHRS.h>

#define MEASURING_FREQ (1660)

//Create a instance of class LSM6DS3
LSM6DS3 IMU(I2C_MODE, 0x6A);  //I2C device address 0x6A

typedef struct {
  float x;
  float y;
  float z;
} pos3d_t;

pos3d_t gyr_ = { 0 };
pos3d_t acc_ = { 0 };
pos3d_t ang_ = { 0 };
double mes_time_ = 1.0 / (double) MEASURING_FREQ * 1000.0;
Madgwick m_;

void print_header() {
  Serial.println("Roll, Pitch, Yaw");
}

void print_values() {
  Serial.print(ang_.x);
  Serial.print(",");
  Serial.print(ang_.y);
  Serial.print(",");
  Serial.print(ang_.z);
  Serial.println("");
}

void blink(int pin, uint16_t delay_time = 500) {
  digitalWrite(pin, HIGH);
  delay(delay_time);
  digitalWrite(pin, LOW);
  delay(delay_time);
}

void read_gyr() {
  gyr_.x = IMU.readFloatGyroX();
  gyr_.y = IMU.readFloatGyroY();
  gyr_.z = IMU.readFloatGyroZ();
}

void read_acc() {
  acc_.x = IMU.readFloatAccelX();
  acc_.y = IMU.readFloatAccelY();
  acc_.z = IMU.readFloatAccelZ();
}

void setup() {
  // 初期化
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);

  digitalWrite(LED_RED, HIGH);
  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_BLUE, HIGH);

  Serial.begin(115200);

  while (!Serial) {
    blink(LED_RED);
  }

  IMU.settings.gyroRange = 2000;
  IMU.settings.accelRange = 4;  
  while (IMU.begin() != 0) {
    blink(LED_GREEN);
  }

  IMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL2_G,  0x8C);
  IMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x8A);
  IMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL7_G,  0x00);
  IMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL8_XL, 0x09);

  // 測定周波数  
  m_.begin((int)MEASURING_FREQ);
}

void loop() {
  // update
  read_acc();
  read_gyr();
  m_.updateIMU(gyr_.x, gyr_.y, gyr_.z, acc_.x, acc_.y, acc_.z);
  // get
  ang_.x = m_.getRoll();
  ang_.y = m_.getPitch();
  ang_.z = m_.getYaw();
  // print
  print_values();
  delay(mes_time_);
}

```
Boardgame.ioでマルチプレイオンラインボードゲームを作る②

boardgame.ioというボードゲーム作成用フレームワークを使ったブラウザゲーム作成の手順です

一連の事
- [Boardgame.ioでマルチプレイオンラインボードゲームを作る①](https://sirkus.co.jp/2023/06/16/%e3%82%aa%e3%83%b3%e3%83%a9%e3%82%a4%e3%83%b3%e3%83%9c%e3%83%bc%e3%83%89%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92boardgame-io%e3%81%a7%e4%bd%9c%e3%82%8b/) boardgame.ioの立ち上げ、基本、マルチプレイサーバの作成
- [Boardgame.ioでマルチプレイオンラインボードゲームを作る②](https://sirkus.co.jp/2023/06/26/boardgame-io%e3%81%a7%e3%83%9e%e3%83%ab%e3%83%81%e3%83%97%e3%83%ac%e3%82%a4%e3%82%aa%e3%83%b3%e3%83%a9%e3%82%a4%e3%83%b3%e3%83%9c%e3%83%bc%e3%83%89%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c/) ターン、フェーズ、ステージの制御


今回は、ターン、フェーズ、ステージといった段階制御を行っていきます。

## ターン

ターンに関しては何もしていない状態では以下の動作となります。
- endTurnイベントでターンを終了
- Player0,1,2,...n → 0,1,2..n の順でターンを交代

ゲームによってはターンの順を制御したい場合もあると思いますが、boardgame.io上にこれを設定できる項目があります。
Gにturnを設定します。

```javascript:Game.js
import { TurnOrder } from 'boardgame.io/core';

export const TicTacToe = {
  turn: {
    order: TurnOrder.CUSTOM(['0', '2']),
  },
```
上記で、Player0,2→0,2といった順番で遷移します。
また`endTurn({ next: playerID });`といった形でentTurn時に動的に次プレイヤーを指定する方法もあります。

orderに設定できる値は色々ありますが、次のフェーズの制御に関わるものが多いのでフェーズの説明に移ります。

## フェーズ

フェーズとはゲームの工程ごとの動作のイメージです。
ターンとの関係は以下のようなイメージです。

- フェーズ1 カードを引く
    - ターン:Player1
    - ターン:Player2
    - ...
- フェーズ2 カードを見せる
    - ターン:Player1
    - ターン:Player2
    - ...

基本編では`G`の`moves`を一つだけ定義しましたが、`phases`を定義してその中に`moves`を定義しなおします。
```javascript:Game.js
  phases: {
    draw: {
      start: true, //最初に始めるフェーズ
      next: 'play', //次フェーズ(固定文字列ではなく関数で動的に返すことも可)
      moves: { /* draw用のmoveを記載 */ },
    },

    play: {
      moves: { /* play用のmoveを記載 */ },
    },
  },
```
この状態ですとdrawで定義したフェーズがずっと続くこととなるので、フェーズ終了条件を定義します。
フェーズ終了条件は以下のようにphaseの中に定義するか
```diff_javascript:Game.js
  phases: {
    draw: {
      start: true, //最初に始めるフェーズ
      next: 'play', //次フェーズ(固定文字列ではなく関数で動的に返すことも可)
      moves: { /* draw用のmoveを記載 */ },
+     endIf: ({ G }) => (G.deck <= 0), //Trueを返したとき次フェーズ
    },

    play: {
      moves: { /* play用のmoveを記載 */ },
    },
  },

```
あるいは前項の`turn`で以下のようにONCEなどを設定すると一度ターンを回すとフェーズが終了します。
```
  turn: {
    order: TurnOrder.ONCE,
  },
```
turnの種類は以下に記載があります。
https://boardgame.io/documentation/#/turn-order?id=changing-the-turn-order

フェーズ突入/終了時に何らかの処理をしたい場合はonBegin/onEndを使用します
```javascript
phases: {
  phaseA: {
    onBegin: ({ G, ctx }) => { ... },
    onEnd: ({ G, ctx }) => { ... },
  },
};
```

## ステージ

フェーズ/ターンではプレイヤーずつ順番にmoveを行っていきましたが、各プレイヤーが順番ではなく同時にmoveするような場合もあると思います。

そのような場合は`Stage`を定義します。
```javascript:Game.js
turn: {
  stages: {
    stageAAA: {
      moves: { /* 同時に行わせたいmoveを定義 */ },
    },
  },
}
```
任意のタイミングで`setActivePlayers`を実行します。eventsがとれるところならば、Client内でもGame内でも実行可能です。
(setActivePlayerをコールしたタイミングがプレイヤーのターン中の場合、そのターンが終了させられてからステージに移行するようです)
```javascript
  const goStage = (events)=>{
    events.setActivePlayers({ all: 'stageAAA', minMoves: 1, maxMoves: 1 });
  }
```
この状態だと全プレイヤーが操作可能になります。maxMovesを設定しているので1回のみ行動可能ですが、maxMovesを外せば何回でも行動できます。
また第一引数にallを設定しているので全員が行動可能になりますが、これをOtherなどにすればcurrentPlayer以外のみ行動可能となったりします。
`endStage()`をコールすることでステージを抜けます。


上記のようにフェーズ/ターンは親子の関係ですが、ステージは一時的に別の状況に飛ばすようなイメージの動きとなっています。
【ゴーストライター】ChatGPTに記事を書かせてみた

# ChatGPTに記事を書かせてみた

記事を書くのって大変じゃないですか？
時間もかかるし、誤情報を与えられないからしっかりとした調査をする時間もかかるし。

そこで、ChatGPTさんに記事を書かせてみました。
（すみません、ChatGPTさん、ChatGPTネタこすらせてください）

## 質問内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2654832/39745f5f-3e9e-4db8-22b7-7cc85c17ca51.png)

## 回答
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2654832/6274a4cd-bbec-45b4-5377-1a4df5c47467.png)

（↓ ここから ↓）

# 【n進数】進数進数うるせーんじゃ！なんで基数変換しなくちゃいけねーんだよ！

---

## 背景

私（すずこ）は基数変換の講義をしていたとき、後輩ちゃんから「進数進数うるせーんじゃ！なんで基数変換しなくちゃいけねーんだよ！」と言われました。そこで、この記事では基数変換の理由について、私と後輩ちゃんの対話形式で怖おかしく解説してみたいと思います。

---

すずこ：後輩ちゃん、進数って知ってるよね？

後輩ちゃん：もちろん！2進数、10進数、16進数とか、あれだよね？

すずこ：そうそう！進数って数字を表すための基数のことなんだよ。でも、なんで基数変換が必要なのか分かる？

後輩ちゃん：進数進数って何だよ！なんで面倒くさいことをしなきゃいけないんだよ！

すずこ：ふふふ…後輩ちゃん、基数変換の真の理由を教えてやろうか。進数進数とは…闇の力なのだよ！

後輩ちゃん：え、闇の力って何？

すずこ：基数変換によって、私たちは数の世界の境界を越えることができるのだ。2進数の世界では0と1の二者しか存在しない。それはまさに生死の境地。10進数の世界では、0から9までの範囲に制約される。しかしここで基数変換の呪文を唱えると、新たな力が解き放たれるのだ！

後輩ちゃん：ひぃ！なんか怖いよ…でも、その力を手に入れるためには基数変換をしなきゃいけないの？

すずこ：そうだよ、後輩ちゃん。基数変換こそがその鍵なのだ。基数変換を行うことで、数の力を使いこなし、情報の解読や暗号の解除、コンピュータの内部の理解など、様々な力を手に入れることができるのだよ！

後輩ちゃん：なるほど…怖いけど、面白そうな力だね。基数変換についてもっと知りたい！

すずこ：ふふふ…後輩ちゃん、その好奇心が君をより深い闇の世界へと誘うかもしれない。だが心して臨め。基数変換の真実を知ると、もはや元の世界には戻れないかもしれないのだよ…

---

基数変換の闇の力を解き放つためには、私たちは勇気を持ってその世界へ飛び込む必要があります。しかし、一度その力を手にすれば、数の世界の可能性は広がり、魅惑の冒険が待っています。後輩ちゃんよ、準備はできたか？闇の力が君を待っているのだよ！

（↑ ここまで ↑）

## 意味わからないよね？
意味わからない。（質問した条件が悪い）

## 所感

良い。想像以上に、良い。
ちゃんと筋道もある。

話として成立もしている。

アウトラインの役割としては最高だ。

与える条件を工夫すれば、執筆者の役に立つかもしれない。
変数とは？

変数とは「箱」のこと。

例えば
レゴブロックを入れる箱＝変数
レゴ＝数値や言葉、誕生日、日付.....。

という感じです。

コードでは

a=4;
c=12;
answer= a+c;

の中ではaとcが変数になります。
そのa(箱)には4(値)が入ります。
そのc(箱)には12(値)が入ります。
さくらのモノプラットフォームとLINEを利用した農業DXへの挑戦記

### 背景
　　弊社では農業IoTに取り組んでいるのですが、その中でラストワンマイルが問題になることが多いです。その解決策の一つとして、さくらのモノプラットフォームを使用してみたところ「小規模なシステムと相性が良いのではないか」ということがわかってきました。
　現在一般的なIoTシステムでは、インターネット回線を圃場まで引いて、Wi-Fiでデバイスと接続するものが多く、少量のセンシングを行なうには少々大袈裟なものもあります。LTE回線を使用するものにしても、セキュリティの知識が必要であったり、システムが難解であったりと手が出しやすいとは言い難い状況です。
　さくらのモノプラットフォームを使用すると、モノプラットフォームの中で、デバイスからクラウドへの送信。アプリケーションサーバーへのデータの取り込みまで面倒を見てもらえます。そのため少量のセンシングをしたい場合や、実験的にセンシングを行いたい場合には、手軽に利用できるさくらのモノプラットフォームを利用するのが良いと考えました。
　そこにインターフェースとして、LINEを利用するのが良いと思います。なぜなら開発まで含めたユーザーフレンドリーなUXが提供されているLINEを使用することにより、ユーザー自らによる改善まで含めた新しい価値を提供できるはずだからです。
## 実際に開発するもの
農業用の自動潅水システムとpFセンサーを組み合わせたスマート栽培管理システム。
### pFセンサーとは
　土壌にどの程度の力で水が保持されているか示す指標である、マトリクスポテンシャルの指標を測定することができます。
　素焼きのカップとパイプを接着して、中を水で満たして密閉したものです。素焼きカップには水は通すが空気を通さないという性質があるため、容器内の圧力（負圧）を圧力センサーで測定することでマトリクスポテンシャルを測定することができます。このマトリクスポテンシャルを水柱の高さで表し、常用対数をとったものをpFと言います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/0e00e244-3345-c5b8-70bc-a2169927a6b1.png)
### マトリックスポテンシャルとは
　スポンジのように、土壌中にはたくさんの隙間があります。スポンジが水を吸う力(毛管力)に相当する力がマトリックポテンシャルです。作物根はこの力に負けない力で土壌から水を吸収するため、マトリックポテンシャルを測定することで灌水のタイミングを知ることができます。
### 現状のpFセンサーの測定原理と問題点
　現状市販されているpFセンサーにはアナログ（機械式）の圧力計が使用されていることが多く、デジタル化がやりづらいです。アナログメータの針を画像認識で読んでデジタルデータに変換する方法も考えられますが、システムが無駄に大きくなってしまいます。
### それに対する私たちの解決法
　圧力を電気信号に変化するデジタル圧力センサ―を用いることにより、pF値をデジタル値として取得することができます。デジタルデータとして取得することによりそのままデジタル通信にのせることができます。
### デジタル通信にのせることで何が嬉しいのか
　遠隔のモニタリングや遠隔の制御が可能になります。さらにいうと、弊社で作成している自動潅水システムと連携させることで、pFセンサーと連動した自動潅水制御が可能になります。最適なタイミングで灌水を行なうことにより、収量の増加、収穫のタイミングをずらすことが可能になると考えられます。収穫のタイミングをずらすことよって、収益の増加を狙うことなどが可能になります。

## DXを意識したシステム
　DXとはデジタルデータを作り出して集め、それを価値のあるものに変えて、新しいビジネスやモノづくりの仕組みを作り上げることです。ここで大事なことは行動の変革を促すことです。
　今回の例では測定したpFセンサーの値（アナログ値）をデジタル値に変換して、モノプラットフォームの仕組みでクラウドに送信します。クラウド上でデータを分析して、必要があれば、LINEを使用して、ユーザーに行動を促します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/66647ce2-6548-98c4-246e-fe858111cb31.png)
## 現在の開発状況
　自動潅水システムの開発を行い、実証実験を行っています。現在順調に動作していますので、pFセンサーが完成した暁には、自動潅水システムと組み合わせることで農業の自動化への一歩を踏み出すことができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/8e43c6f7-26f7-ba74-b13e-b0098f78aead.png)
　さらに今回、pFセンサーを作成するために圧力センサーとマイコンを接続する回路を開発しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/f12a9bb3-57e5-8861-b7a9-42302f58faf5.png" width=50%>
理論通りに動いているかどうか検証を行っています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/cd28b42e-bb93-cac2-d0a2-9ea1826f66b9.png" width=70%>
## 今後の展開
　pFセンサーの動作検証を行い、LINE通知も含めてIoTシステムとして動かしてみます。pFセンサーは状況によっては水を追加する必要があります。水の追加をする必要があるタイミングでの通知、遠隔でのセンサーの校正までできるようにしたいと考えています。なお、現在動作している自動潅水システムと組み合わせることで、高付加価値な農業と農業の自動化を目指していきます。
## 今後の野望
　最終的には様々なセンサーや市場情報のデータまで組み合わせたデータ駆動農業で農業DXを起こすことを目指します。
　将来的にはワークショップを行うことによって、必要な人が必要な機能を自分たちで作ることができる状態にしていきたいと考えています。さらにユーザーが広がることによって、ユーザー自身による改善、改良を繰り返してもらうことによりDXの波を広げていきたいと考えています。
cscの作法 その371

# 概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
assimp使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e3245512-25ee-dd4c-c611-07f91fd0d735.png)


# サンプルコード

```
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using Assimp;
using Assimp.Configs;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace App
{
	public class SimpleOpenGLSample: GameWindow {
		private Scene m_model;
		private float m_angle;
		private int m_displayList;
		public SimpleOpenGLSample(): base() {
			Title = "test";
			String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "sphere.obj");
			AssimpContext importer = new AssimpContext();
			m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);
		}
		protected override void OnUpdateFrame(FrameEventArgs e) {
			base.OnUpdateFrame(e);
			m_angle += 25f * (float) e.Time;
			if (m_angle > 360)
			{
				m_angle = 0.0f;
			}
			if (Keyboard[OpenTK.Input.Key.Escape])
			{
				this.Exit();
			}
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			GL.ClearColor(Color.CornflowerBlue);
			GL.Clear(ClearBufferMask.ColorBufferBit);
				for (int i = 0; i < m_model.RootNode.ChildCount; i++)
				{
					Render(m_model, m_model.RootNode.Children[i]);
				}
			SwapBuffers();
		}
		private void Render(Scene scene, Node node) {
			if (node.HasMeshes)
			{
				foreach (int index in node.MeshIndices)
				{
					Mesh mesh = scene.Meshes[index];
					foreach (Face face in mesh.Faces)
					{
						BeginMode faceMode;
						switch (face.IndexCount)
						{
						case 1:
							faceMode = BeginMode.Points;
						break;
						case 2:
							faceMode = BeginMode.Lines;
						break;
						case 3:
							faceMode = BeginMode.Triangles;
						break;
						default:
							faceMode = BeginMode.Polygon;
						break;
						}
						GL.Begin(faceMode);
						for (int i = 0; i < face.IndexCount; i++)
						{
							int indice = face.Indices[i];
							GL.Color3(Color.White);
							Vector3 pos = FromVector(mesh.Vertices[indice]);
							GL.Vertex3(pos);
						}
						GL.End();
					}
				}
			}
		}
		private Vector3 FromVector(Vector3D vec) {
			Vector3 v;
			v.X = vec.X;
			v.Y = vec.Y;
			v.Z = vec.Z;
			return v;
		}
	}
	class Program {
		static void Main(string[] args) {
			SimpleOpenGLSample sample = new SimpleOpenGLSample();
			sample.Run();
		}
	}
}






```

# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%


>csc ass3.cs /reference:OpenTK.dll /reference:AssimpNet.dll


```


以上。
JavaScript でデバイスのカメラ使って録画した動画を取得

デバイスのカメラ使って撮影した動画取得までやってみる
サンプルは以下のページ（写真撮影も一緒に）

https://sueasen.github.io/javascript-exercise/work/camera/

# JavaScript
- 撮影カメラ表示用の `video` タグを取得（変数 `video` に設定）
- 録画動画表示用の `video` タグを取得（変数 `movie` に設定）
- デバイスのカメラを `navigator.mediaDevices.getUserMedia({ video: true, audio: true })` 取得
    - ブラウザ側でカメラ使用の許可求められるので許可する必要あり
    - 取得後に `stream` を `video.srcObject` に設定して `video.play()` でカメラの画像を `video` に表示 
    - 取得後に `stream` を引数にして `MediaRecorder` のインスタンス生成
    - `MediaRecorder` のインスタンスに`dataavailable` のイベント追加して以下を処理
        - `movie.src` に ` URL.createObjectURL(event.data)` を設定 
- `MediaRecorder` のインスタンスの `start` 関数使って録画開始
- `MediaRecorder` のインスタンスの `stop` 関数使って録画終了

```JavaScript
const video = document.querySelector('#video');
const movie = document.querySelector('#movie');
let mediaRecorder;

initVideoCamera();
document.querySelector('#recode-start').addEventListener('click', recodeStart);
document.querySelector('#recode-stop').addEventListener('click', recodeStop);

/**
 * ビデオのカメラ設定(デバイスのカメラ映像をビデオに描画)
 */
function initVideoCamera() {
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
        .then((stream) => {
            video.srcObject = stream;
            video.play();
            mediaRecorder = new MediaRecorder(stream);
            mediaRecorder.addEventListener(
                'dataavailable'
                , e => movie.src = URL.createObjectURL(e.data));
        })
        .catch(e => console.log(e));
}

/**
 * 動画撮影の開始
 */
function recodeStart() {
    mediaRecorder.start();
    document.querySelector('#recode-start').classList.add('hidd');
    document.querySelector('#recode-stop').classList.remove('hidd');
}

/**
 * 動画撮影の停止
 */
function recodeStop() {
    mediaRecorder.stop();
    document.querySelector('#recode-start').classList.remove('hidd');
    document.querySelector('#recode-stop').classList.add('hidd');
}

```

# HTML
`video` タグを２つ、撮影カメラ表示用（id : video ）と録画動画表示用（ id : movie ）を用意する
あとは録画開始、停止のタグを用意する

```HTML
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <h3>カメラ画像取得</h3>
    <div class="flex-row">
        <div class="camera">
            <video id="video"></video>
            <div id="recode-start">録画開始</div>
            <div id="recode-stop" class="hidd">録画停止</div>
        </div>
        <div class="movie">
            <video id="movie" controls playsinline></video>
            <p class="ret-element">動画</p>
        </div>
    </div>
</body>

<script src="script.js"></script>

</html>

```
PowerShell でもサロゲートペア文字・結合文字列を正しく数えたい

PowerShell では内部的に UTF-16LE を利用しています。そのため、Windows API や Java を利用した開発と同様、文字列を取り扱う際にはサロゲートペア文字に関する問題を考慮しなければなりません。

## `String.Length` で文字数を数えてみる

まずは素直に `String.Length` で文字数を数えてみましょう：

```powershell:基本多言語面内（非サロゲートペア文字）
"a".Length
# 1

"あ".Length
# 1
```

```powershell:基本多言語面外（サロゲートペア文字）
"🎵".Length
# 2
```

サロゲートペア文字の場合はハイサロゲート・ローサロゲートで合計2文字のカウントになっていますね。

同様に、結合文字列についても確認してみましょう：

```powershell:結合文字列
"ぬ゙".Length
# 2 (1+1)

"👨🏻‍🎤".Length
# 7 (2+2+1+2)
```

結合に利用した分の文字数（サロゲートペア文字の場合は2文字として）でカウントされていますね。

なお、PowerShell には Linux 版もリリースされていますが、こちらでも同じ挙動となります。

```log
$ docker run --rm mcr.microsoft.com/powershell:lts-7.2-debian-buster-slim pwsh -Command '"👨🏻‍🎤".Length'
7
```

## `StringInfo.LengthInTextElements` で文字数を数えてみる

`System.Globalization.StringInfo` はサロゲートペア文字や結合文字列を考慮しながら文字列を取り扱うためのクラスです。コンストラクタでインスタンスを生成した後、`LengthInTextElements` プロパティで以下の要素数を数えます：

* 基本文字
* サロゲートペア文字
* 結合文字列

```powershell
[System.Globalization.StringInfo]::new("👨🏻‍🎤<ぬ゙～🎵").LengthInTextElements
# 5
```

やったね。期待通り 5 文字として数えることができました！

## 参考リンク

* [文字エンコードについて - PowerShell | Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.2)
* [String クラス (System) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.string?view=net-7.0)
* [String.Length プロパティ (System) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.string.length?view=net-7.0#system-string-length)
* [StringInfo.LengthInTextElements プロパティ (System.Globalization) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.stringinfo.lengthintextelements?view=net-7.0)
* [サロゲート文字と補助文字 | Microsoft Learn](https://learn.microsoft.com/ja-jp/windows/win32/intl/surrogates-and-supplementary-characters)
* [文字列の長さ（文字数）を取得する - .NET Tips (VB.NET,C#...)](https://dobon.net/vb/dotnet/string/stringlength.html)
* [サロゲートペア・結合文字列・合字](https://qiita.com/Nabetani/items/8c69bdd8060f2503683c)
* [絵文字👨🏻‍🦱は何文字としてカウントする？関連する文字コードの仕様を詳しく調べてみた](https://qiita.com/comware_harase/items/59c60ab1c6e1797f0821)
* [UTF-16](https://ja.wikipedia.org/wiki/UTF-16)
* [基本多言語面](https://ja.wikipedia.org/wiki/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2)
* [結合文字](https://ja.wikipedia.org/wiki/%E7%B5%90%E5%90%88%E6%96%87%E5%AD%97)
* [合成済み文字](https://ja.wikipedia.org/wiki/%E5%90%88%E6%88%90%E6%B8%88%E3%81%BF%E6%96%87%E5%AD%97)
* [カオス過ぎる Unicode, UTF-8, UTF-16, UTF-32 の違い概要まとめ](https://qiita.com/tatsubey/items/0ba0d3b84c012fd4d19b)
【Spring Boot】プロパティファイルをまるごと取得する方法

Spring Bootでプロパティファイルを参照する場合は＠Valueを使うことが多いかと思います。ですが、参照したい値が多くひとつひとつ書くのが面倒だったので、下記の方法を使用しました。
### プロパティファイルの準備
プロパティファイルはresorces直下に置きます。
```hoge.properties
a=apple
b=banana
c=cherry
d=durian
```

### プロパティファイルを参照
```java
Properties properties = new Properties();
try {
    InputStream istream = new ClassPathResource('hoge.properties').getInputStream();
    properties.load(istream);
} catch (Exception ignore) {}

var name = properties.getProperty("a");
```

参考になれば幸いです。
第二世代管理パッケージ作成で困ったこと。（２）

第二世代管理パッケージにレポート及びレポートフォルダが含まれている場合、
レポートフォルダへの共有はインストール実行した管理者への管理権限のみ付与されます。

よって、インストール後に必要に応じて参照権限を追加する必要があります。

パッケージインストール後スクリプト（Apex）を利用して参照権限付与できるか探しましたが、方法はありませんでした。

通常の開発だとメタデータさえあればサンドボックス環境などへ普通にデプロイしてアクセス権与えるのに対して、管理パッケージだといろいろ制限が多く不便です。いつか改善出来たらと・・・
【2023年6月時点】yarnを使ったVue3の環境構築手順

## 概要

Viteを使ってVue3の環境構築する手順です。
#### 前提

パッケージ管理にはyarnを使っています。

またJavaScriptではなくTypescriptを使用します。

## Viteとは

Viteは速く無駄のない開発体験を提供するビルドツールで、高速なホット・モジュール・リプレースメント（HMR）や最適化された静的アセットの出力を特長としています。

Viteはデフォルトで賢明な設定があり、JavaScript APIやプラグインAPIによる拡張も可能です。

## 環境構築手順

### プロジェクトの作成

```
yarn create vite {プロジェクト名を入れる} --template vue-ts
```

コマンド例
```
yarn create vite my-page --template vue-ts
```

### 各種ライブラリの追加

`yarn add [パッケージ名]`で最新バージョンをインストールできます。

バージョンの指定が必要な場合は`yarn add [パッケージ名]@[バージョン]`のように@の後ろにバージョンを記載します。

#### vue-router

```
yarn add vue-router
```

#### Pinia

```
yarn add pinia
```

#### Vuetify

```
yarn add vuetify
```

作成したリポジトリでyarn devコマンドを実行して払い出されたエンドポイントへアクセス

![スクリーンショット 2023-06-21 17.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1654639/50ae808c-ee11-68c4-de9a-4041d8ac727f.png)




## おまけ

Vuetifyを入れる場合は次のコマンドでOKです

```
yarn create vuetify
```

上の手順で入れたライブラリはEssentialsを選択することで自動インストールされます。

```
? Which preset would you like to install? › - Use arrow-keys. Return to submit.
    Default (Vuetify)
    Base (Vuetify, VueRouter)
❯   Essentials (Vuetify, VueRouter, Pinia)
    Custom (Choose your features)
```

TypeScriptの選択もできます。

```
✔ Which preset would you like to install? › Essentials (Vuetify, VueRouter, Pinia)
? Use TypeScript? › No / Yes
```

ただし、中身は全く同じではないので注意です。`yarn create vuetify`で実行した場合はVuetifyのバージョンは`3.0.0`になっています。要件に応じて使い分けが必要になりそうです。


#### 環境構築手順通りに実行したときのpackage.jsonの中身

```json
{
  "name": "xxxxxxxxx",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "pinia": "^2.1.4",
    "vue": "^3.2.47",
    "vue-router": "^4.2.2",
    "vuetify": "^3.3.5"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.1.0",
    "typescript": "^5.0.2",
    "vite": "^4.3.9",
    "vue-tsc": "^1.4.2"
  }
}
```

#### yarn create vuetify実行したときのpackage.jsonの中身

```json
{
  "name": "yyyyyyy",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview",
    "lint": "eslint . --fix --ignore-path .gitignore"
  },
  "dependencies": {
    "@mdi/font": "7.0.96",
    "core-js": "^3.29.0",
    "pinia": "^2.0.0",
    "roboto-fontface": "*",
    "vue": "^3.2.0",
    "vue-router": "^4.0.0",
    "vuetify": "^3.0.0",
    "webfontloader": "^1.0.0"
  },
  "devDependencies": {
    "@babel/types": "^7.21.4",
    "@types/node": "^18.15.0",
    "@types/webfontloader": "^1.6.35",
    "@vitejs/plugin-vue": "^4.0.0",
    "@vue/eslint-config-typescript": "^11.0.0",
    "eslint": "^8.37.0",
    "eslint-plugin-vue": "^9.3.0",
    "sass": "^1.60.0",
    "typescript": "^5.0.0",
    "vite": "^4.2.0",
    "vite-plugin-vuetify": "^1.0.0",
    "vue-tsc": "^1.2.0"
  }
}

```
初心者がAIチャレンジやってみた (2)：1つ目の障害物の回避（パラメータチューニング）

# 概要
「初心者がAIチャレンジやってみた」シリーズの第2弾です。
今回はパラメータを調整して運が良ければ２つ目のダンボールを回避できるようになりました。

前回の記事はこちら：
* 第1弾：[初心者がAIチャレンジやってみた(1)](https://qiita.com/h_bog/items/86fba5b94b2148c4d9da)：Autowareを動かしてみる

:::note warn
筆者はautoware初心者です。
説明等が正確でない可能性があるので本記事だけではなく他の記事や[autowareのドキュメント](https://autowarefoundation.github.io/autoware-documentation/main/)も確認するようにしてください。
:::

# パラメータ調整
経路生成や障害物回避のパラメータは`behavior_path_planner.param.yaml`や`avoidance.param.yaml`などのファイルで設定しているっぽい。

### 編集するファイルの確認方法
`autoware.launch.xml`で使われているファイルを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3483805/d59b5c68-04a9-43f3-972f-63abc27e2bad.png)

`tier4_planning_component.launch.xml`を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3483805/d1b08c64-25b1-acc1-7305-dc97a0a7f425.png)

ということで、このようにして使われているファイルを検索してその`yaml`ファイルを編集すれば良い。


### 今回の成果
今回は以下のようにパラメータを調整した（まだどのパラメータがどう影響するのかが分かってないので、関係ないパラメータもあるかも）。
5回に1回くらい(?)は2個目のダンボールも避ける・避けようとしてくれる。下の動画は運良くめちゃくちゃきれいに2個目のダンボールを避けてくれたときの動画。

```behavior_path_planner.param.yaml
refine_goal_search_radius_range: 3.5    # 元々7.5
```
```avoidance.param.yaml
enable_update_path_when_object_is_gone: true
enable_force_avoidance_for_stopped_vehicle: true
target_object:
    #（省略）
    unknown: true
avoidance:
    lateral:
        lateral_collision_margin: 0.1    # 元々1.0
        lateral_collision_safety_buffer: 0.1    # 元々0.7
        road_shoulder_safety_margin: 0.5    # 元々0.3
```

<iframe width="560" height="315" src="https://www.youtube.com/embed/Jlm5BbyyFXE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
【超要約！ Power Apps入門】 3分で学ぶ！ Power Apps を始める前に抑えておくこと


Power Apps初心者や これから始めようとしている方々へ、入門前に抑えておくべきポイントを簡潔にご紹介します！

<br/>

## PowerAppsとは？

ビジネス向けのアプリケーションを簡単に作成できるマイクロソフトのプラットフォームです。
いわゆるローコードというものです。
開発と実行ができるプラットフォームです。

<br/>

## 主要な構成要素は2つ

- 画面
- データソース
  データソースは沢山の種類があり、外部含め様々なデータに接続できます。
  例: データバース(PowerAppsのDB)、他のSQL DB、OneDrive上のエクセルファイル、SNS ・・・

<br/>

## その他の重要な要素

- PowerFx
  エクセル式のようなものです。
  ボタン押したときの動作、表示の動作、データの加工 などが実装できます。
- リレーション
  データバース(PowerAppsのDB)のテーブルを関連付けるものです。(1:N,N:1,N:N)
  画面上からポチポチで設定できます。
  設定しておくとPowerAppsが色々配慮してくれます。


<br/>

## 入門時に抑えるべきポイント

- 主要な画面パーツと使い方
- 主要なPowerFxと使い方
- 変数


### 主要な画面パーツ
フォーム、ギャラリー、ボタンなどの基本的な画面パーツを理解しましょう。
![スクリーンショット 2023-06-21 171453.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/4dd27a8a-47a9-c401-9c5a-b382ecbe0320.png)
ギャラリーという一覧表示用の画面パーツがあるのですが、こちらはよく使うと思いますのでぜひ抑えておきましょう！


<br/>


### 主要なPowerFx

条件分岐や計算など、PowerFxを使った基本的なロジックを学びましょう。
よく使いそうなものを挙げておきます。

- Notify メッセージ表示
- Now, Today 現在日時,日付
- Date, Time, DateValue, Text, DateAdd, DateDiff 日時系
- If, Switch 条件分岐
- Navigate 画面遷移
- LookUp,Search,Filter レコード検索
- Collect,Remove,Patch レコード新規,削除,更新
- ForAll 全レコード処理

その他、計算、テキストフォーマット等様々な関数があります。


### 変数

グローバル変数とコンテキスト変数の違いや使い方を把握しましょう。

- グローバル変数
  名前の通りアプリ全体で使える変数
  Set()でセット
- コンテキスト変数
  スクリーン単位の変数
  - UpdateContext({変数A: 値A,変数B: 値B, ・・・})でセット
    例: ```UpdateContext({ msg: "メッセージですよー" });```
    ※ セット時は特殊ですが、利用時は普通に名前だけ書けば使えます。

<br/>

## その他の注目ポイント
- 一般公開用のページを作れる「ポータル」機能がありますが、ライセンスが必要です。
- ユーザー一覧は、「AAD Userテーブル」「ユーザーテーブル」から取得できます。
- 最初から使いそうなテーブルが用意されていて、極力、そのテーブルを使いましょうという考え方です。
- 画面初期表示時にコンテキスト変数を初期化したいときは
  OnVisibleアクションに以下のように書くとよい。
  ```
  Reset(TextInput1);
  UpdateContext({ msg: "" });
  ```

<br/><br/>

以上が、Power Appsの入門前に知っておくべきポイントの要約です。
3分で学べましたでしょうか！
AWS認定ソリューションアーキテクトプロフェッショナルの有効期限を更新した話

# はじめに

AWS認定は、有効期限が３年までとなっています。

https://aws.amazon.com/jp/certification/recertification/

有効期限を延長するためには、現行の本試験を再度受験して合格せねばなりません。

AWS Certified Solutions Architect - Professional
は、試験バージョンのバージョンアップがあり、
+ SAP-C01 (前回：合格時）
+ SAP-C02 (今回：合格時）
とバージョンが上がってます。

差分で感じたこと、出来事、など、メモ書きしておきます。

# スコア

![Proスコア.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/27e9f2eb-1cc5-6597-e840-b79f722360fe.jpeg)

前回受験時は、アソシ３冠しかなく、初のプロ受験という事もあり、時間いっぱい使い切ってギリギリまで見直し等をしていました。

今回は、全冠保持の状態で、初の更新受験という事もあり、比較的余裕をもった受験となりました。
(自身の成長を少し実感できました。）

+ 確信をもって回答できる問題回答していく。（３分以上悩みそう＆２～３回設問を読み返しそうはフラグをつけて飛ばす）・・・１時間弱
+ フラグを付けた問題を時間多めにとって回答・・・１時間
+ 見直し・・・１０～２０分

位の時間感覚で、ギリギリのギリまで見直してたり、あれこれ悩んだりといった事はしませんでした。

:::note warn
 **初回受験は注意**
プロフェッショナル＆スペシャリティは、設問の文章が飛躍的に長くなります。
一定の受験慣れができるまでは、見直し時間を確保するのも難しいかもしれません。
:::

# 受験対策

## 公式模擬試験

https://explore.skillbuilder.aws/learn/course/13272/aws-certified-solutions-architect-professional-official-practice-question-set-sap-c02-japanese

![SkilBuilder.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/9ea3d048-bfc4-4bc8-ebfc-6de1e74d0f84.jpeg)

前回受験から、今回受験の差分という所で、以前はAWS公式模擬試験が有料だったの **無料** になってます。
しかも有料なのに点数しか分からず、正答がなんだったのか分からず仕舞いだったのですが、無料な上に正答と解説もついてるので、受験前の腕試しに受験しておくと良いと思います。

## AWS Web問題集で学習しよう

https://techstock.jp/

の問題集が、私の感想としては有用でした。
他の認定を受ける際には、

https://www.whizlabs.com/

や

https://www.udemy.com/ja/

も活用しています。

## 抑えておいた方が良いサービス

AWS Organizationsの問題が比較的、多く出題されるのは１回受験した方であれば感覚的に分かっていると思いますが、AWS Organizationsに関連ずけして、AWS Control Towerの知識も問われるので、下記、一読しておくと良いかもしれません。

https://aws.amazon.com/jp/controltower/

https://pages.awscloud.com/rs/112-TZM-766/images/20220428_17th_ISV_DiveDeepSeminar_Control_Tower.pdf

# 受験トラブル

オンライン受験で予約していたのですが、「ネットワークテスト：７５％から進まない」の事象に引っかかりました。
今までは、ルーターを再起動したり、別PCで試したり、等で上手く回避してこれたのですが、今回は、本当に何をやってもダメな感じで、チェックイン猶予時間：３０分を使い切ってしまいました。

「試験クライアント」の初回起動時だと、Windowsファイヤーウォールの許可ダイアログがポップアップするあたりです。
念のため、Windowsファイヤーウォールを無効にもしてみましたが事象を解消できませんでした。

https://www.pearsonvue.co.jp/Test-takers/Customer-service.aspx

チェックイン時刻が過ぎてしまったら１５分以内にサポートセンターに電話して、日程振替を依頼しましょう。

電話で聞いたら、オンライン受験の一部の人にチェックインできない障害が発生していた模様です。

![ピアソンサポート.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/d7dfa143-1538-0717-2592-bd3893d9108d.jpeg)


+ 申し込み時メール記載：オーダー番号

を用意しておくとスムーズです。

環境システムチェックは、前日夜に通しておくと「ネットワークテスト：７５％」に引っかからない打率が高いような気がします。
（当日まで１回もやらないと、何故か引っかかりやすい気が。。。）

# まとめ

ソリューションアーキテクトプロフェッショナルの更新は、試験バージョンが上がってる物の、劇的な変化があったという程の出題内容に変化はなかったように思います。
「AWS Control Tower」関連が比較的、目新しくて普段業務で触らない領域だったので印象深い感じがありました。
「　SAP-C01　→　SAP-C02　」のバージョンアップであれば、そこまで恐れる事はなさそうです。
あの広大な範囲を、もう一度、総復習するという意味では、受験対策は、やっぱり必要ですが。。。

# AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。

https://www.cs-cloud-aid.com/
OpenAI-APIを用いて社内研修の質問に答えてくれるAI講師アシスタントアプリを作った話

# イントロ
LlamaIndexを用いてプロンプトに外部データとして社内研修のテキストを含め、その内容を参照して
精度の高い回答をしてくれるようなAI講師アシスタントアプリケーションを作りました。
### システム構成図
![システム構成図.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471907/c9654569-b539-fbb7-10cd-46cfa7f1b1dc.png)


### 実行環境
- Windows10
- Python 3.9.6
- git
- slack-bolt 1.18.0
- openai 0.27.7
- llama-index 0.6.16.post1
- urllib3 1.26.16


# 作成の背景
当社の新入社員の増加と、研修を事業とし社外にも拡大していくうえで、講師の負担軽減を目的とした
ツールとしてこのアプリの作成に取り組みました。
また、講師に対して気を使ってしまい質問しにくいという研修生が、
気軽に質問できるようにという狙いもあります。

社内研修の進行や、各項目に対しての質問にある程度答えてくれるようにテキストとしてある程度の文章量は必要ですが、テキストの内容に沿った回答をしてくれるので個別の事例でも対応可能です。すごい。

# Slack上に導入
研修生にアプリケーションを使ってもらうため、
当初はチャット形式のUIを持つサイトを作成することを想定していました。
しかし、ログイン機能を実装しないと質問者の識別が難しく、ログを残す際に誰がどの質問をしたのか
わからなくなってしまいます。

今回はなるべく早く実装し、実際に使ってもらうことでフィードバックを得ることが目標だったため、
社内でコミュニケーションツールとして使用しているSlack上に、ボットとして導入することにしました。

Slackを利用することでユーザーの識別が容易になり、
チャット形式のUI、スマホでもPCでも利用できる、という要件も一気に満たすことができました。
利用者側から見ても、SlackのDMから人に質問するのと同じようにボットへ質問を投げかけられるのは、
かなり便利に感じました。

AI講師アシスタントのアカウントにDolphineという名前を付けました。
Dolphineに対してSlackのDMで質問をするといい感じの回答を返してくれます。

![動作している様子.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471907/904c4cab-5c76-117d-496e-12d650dec7ae.png)

また、講師が参加しているチャンネルにも通知してくれるようにしました。
どんな質問が多いか、誰がどのくらい質問しているかなど統計的なデータはログを確認、
直近にどんな質問があったか確認したいだけの場合はチャンネルを確認、
という使い分けが出来て便利です。
![応答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471907/a656e8bf-af43-c6c3-9836-765c1dbd8985.png)


# データの参照方法とライブラリの選定
外部データをOpenAIに参照させる方法として、
1. 多数のデータを用いてあらかじめfine-tuningする
1. 外部データを埋め込みベクトルとして保存し、質問と類似度が高いものをプロンプトとして入力する

といった手法があります。
研修に関する質問に回答してもらうという都合上、研修内容の改変や想定外の質問に対する対応などを考慮する必要があったので、後者を用いて制作していくことにしました。

調べた結果、外部データをLLMに受け渡してくれる主だったライブラリとして、
LlamaIndexとLangChainがあることが分かりました。
どちらのライブラリをメインで使用するか決定するため、パラメータを調整していない状態で両ライブラリに同じテキストデータを与え、同じ質問を投げかけるというテストを行いました。
今回はごんぎつねの原文をテキストとして与え、内容についての質問をしてみました。

結果、LlamaIndexの方が回答の精度が良かったことに加えコードも記述しやすかったため、
今回はLlamaIndexを採択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471907/64bb52d1-1fdd-a0b1-1cba-54b00b0273b9.png)


# ログの残し方
ログに求められる要件として、
- 誰かがログファイルを開いていても、ソートや絞り込みなどの操作が行えること
- 24時間確認できること
- 誰でも確認できること

がありました。

AWSのリソースやGoogle Sheets APIを利用することを検討していましたが、
書き込み制限や料金などを考慮し、社内で立ち上げているNASを利用することにしました。

また、ログは最初CSV形式で保存していたのですが、エクセルで開くとロックがかかってしまい、書き込みが行えないなど不都合が多かったためSQLiteを利用し、dbファイルとして保存することにしました。

ログファイルをNAS上に格納し、質問のログが追加されるごとに反映させるようにしたかったのですが、sqliteとSMBでマウントされたNASは相性が悪かったのか「databese is locked」というエラーが出るばかりでした。
一度ローカルに保存し、コピーしたファイルをNAS上に格納するという手法で一応の解決はしましたが、
あまりスマートではないですね。


# 与えるテキストデータ
研修のヒントのみをまとめたテキストとヒントに加えて答えを含めたテキストをAIに与えて
回答の精度比較を行いました。

AIが研修の答えとなるテキストから研修生に対するヒントを生成してくれる、
という動作が理想だったのですが、答えを追加したところで回答の精度には影響がなかったうえ、
いくらプロンプトで制御しようとしても、答えをそのまま引用してしまうことがありました。

質問に対し適切な箇所を引用して答えてはくれるのですが、内容を理解したうえでぼかして回答するといったことは難しいようでした。

# まとめ
LlamaIndexとSlack APIを使ってSlack上から呼び出せるAIアシスタントを作成しました。
今回は社内研修で利用することが目的でしたが、様々な応用が利くと思うのでぜひ皆さんも作ってみては
いかがでしょうか。


# 参考文献
https://recruit.gmo.jp/engineer/jisedai/blog/llamaindex-chatgpt-tuning/
30DaysOfStreamlit 1日目

30DaysOfStreamlit
https://30days.streamlit.app/
に着手した。

手順としてはminicondaを入れるところからなんだけど、Anacondaが入っているのでAnacondaでやることに。

`streamlit hello`
って打ったら起動するハズの単純なところでいきなりつまずく。
![day1-NG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/491fe8e0-875a-5faf-0abb-1a0fe4713777.png)

は？なんで？:angry:
でいろいろ調べること3日。

`python -m streamlit hello`
にしたらうまく起動した。
![day1-OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/35b5f71d-a1ee-826e-48ff-249ec178eb5f.png)

1日目からつまづきまくり、お先真っ暗のくじけまくり。
30日目まで行けるんだろうか？
test

data = [
    {"email": "kosaka@co.jp", "userGroup": "a", "isAdmin": True},
    {"email": "kosaka@co.jp", "userGroup": "b", "isAdmin": True}
]

output = []
unique_emails = set()

for item in data:
    email = item["email"]
    if email not in unique_emails:
        unique_emails.add(email)
        output.append({"email": email, "auth": []})

    auth_item = {"userGroup": item["userGroup"], "isAdmin": item["isAdmin"]}
    output[unique_emails.index(email)]["auth"].append(auth_item)

print(output)
ChatGPT使って技術ブログの"案"を考えてみた


# 本記事は
ChatGPT使って技術ブログの案を考えましたよーって記事です。


# ChatGPTに指示する内容

```
以下のキーワードを元に技術ブログの案を考えてください。
・<キーワード1>
・<キーワード2>
・<キーワード3>
・<キーワード4>
・<キーワード5>
```

# やってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340518/3019c0ce-542f-4c9c-5ba1-208b96913833.png)

# 感想
技術ブログのネタに困ったら参考にしたいと思います。
プルリク作り方備忘録

# 手順
## 1. ブランチを作る
ブランチ名を指定してブランチを作る、ブランチを移動
```
git checkout -b <branch_name>
```
## 2. 作業完了後、pushする
```
git push --set-upstream origin <branch_name>
```

リモートリポジトリに同じ名前のブランチが存在しない場合、新たにその名前のブランチがリモートリポジトリに作成される。
※ 他の人が同じ名前のリポジトリを作っていなければ。同じ名前だとコンフリクトする可能性が

## 3. githubへ
githubを見に行くと、プルリク作りますか的なボタンができているので、クリック。
必要な項目は入力する
## 4. マスターブランチに帰る
```
git checkout <masterのbranch名>
git branch --contains
git pull
```
最後pullしておく
【IBM Security Verify】言語パラメーターを利用した画面表示言語の切替について

# はじめに
IBM Security Verifyの2023年6月の新機能で、言語パラメーターをサポートが追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/499d81b4-1c07-a0fc-74b6-48b5e467290a.png)

IBM Security Verifyは、ブラウザの表示言語を元に画面の表示が切り替わる仕様でしたが、言語パラメータを指定するとオーバーライトされる仕組みとありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/b3ca7ea7-5e57-b508-c015-01ab00b6a735.png)

# 言語パラメータによる画面切替確認
言語パラメータとしてlang=enを指定して、IBM Security Verify画面の表示言語が切り替わることを確認しました。

例）ブラウザの言語が日本語で、言語パラメータがない場合
https://xxx.verify.ibm.com/usc
![intune-000303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/423d9669-34e5-76e4-e327-b9e59e03091c.png)

例）ブラウザの言語が日本語で、言語パラメータでlang=enを指定した場合
https://xxx.verify.ibm.com/usc?lang=en
![intune-000302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/c7fb988b-abf1-4dc5-343f-e207a0571926.png)

ただし、管理者画面へのアクセスについては言語パラメータを指定しても切替できませんでした。

# 参考：
- [【IBM Security Verify】サポートされる言語とサポートされない言語のカスタマイズされたテーマ](https://www.ibm.com/docs/ja/security-verify?topic=themes-customized-supported-nonsupported-languages)
ブランチの作成、一覧の表示

# ファイルを作成して、ステージする
```
*********@mbp SportsFest % vim program.txt
*********@mbp SportsFest % git add program.txt
```
```
春の大運動会

＊　開会式
＊　閉会式
```
# コミットする
```
********@mbp SportsFest % git commit -m 'プログラム作成開始'
[master (root-commit) c4e4ddf] プログラム作成開始
 1 file changed, 5 insertions(+)
 create mode 100644 program.txt
```
# 現在あるブランチの一覧
```
********@mbp SportsFest % git branch
* master
```
# ファイルの内容を編集
```
********@mbp SportsFest % vim program.txt
```
```
春の大運動会

＊　開会式
＊　玉入れ
＊　大玉転がし
＊　閉会式
```
# ステージして、コミット
```
********@mbp SportsFest % git add -u
********@mbp SportsFest % git commit -m '玉関係の競技を加えた'
[master 2d98513] 玉関係の競技を加えた
 1 file changed, 2 insertions(+)
```
# 新たなブランチを作成、ブランチの一覧を表示
```
********@mbp SportsFest % git branch proc
********@mbp SportsFest % git branch
* master
  proc
```

```
********@mbp SportsFest % git branch -v
* master 2d98513 玉関係の競技を加えた
  proc   2d98513 玉関係の競技を加えた
```

# 感想
* ソースツリーのGUIでコミットをしていたが、CUIでコミットをした。慣れていなかったことをした。
* ブランチの作成、一覧の表示。
* 久々にVimを使った。これからまだまだ。

# 出典
https://www.amazon.co.jp/%E3%82%8F%E3%81%8B%E3%82%8B-Git-%E5%86%A8%E6%B0%B8%E5%92%8C%E4%BA%BA-ebook/dp/B00IAOPGDO
ステートレスとステートフルの違い

・ステートレス
ステートレスのメリットとしては、状態を保持する必要がないため、システムの作成が簡単です。
しかし、デメリットとしては、通信エラーが発生した場合に状態を持っていないため、例えば注文サイトの買い物カゴに商品が入っていない状態で再度注文すると、2つの注文が届いてしまう可能性があります。また、一回一回指示を出す必要があるため、やり取りが煩雑になることもあります。

・ステートフル
一方、ステートフルのメリットとしては、状態を持っているため、前回の状態との差分だけ指示を出せば済むため、やり取りが短くなります。また、通信エラーが発生した場合でも、ステートフルは状態を持っているため、クライアントに対して「既に注文ずみですが、もう一つ注文しますか？」といった確認を行うことができ、注文エラーを防ぐことができます。
しかし、ステートフルは一台一台のクライアントの状態を管理する必要があるため、接続するクライアント数が多くなると処理が複雑になるデメリットもあります。

このように、ステートレスとステートフルにはそれぞれメリットとデメリットがあります。
特定のEC2のみ起動させるようにAWS CLIの設定を行う

### はじめに
EC2のメンテナンス用のLinuxサーバを用意し、そこから特定のEC2インスタンスをAWS CLIを使用して起動させる。

以下の作業を実施。
* カスタムポリシーを作成	
* ユーザ作成(1ユーザのみ作成、ユーザグループは作成いない)	
  * ポリシーの割り当て
  * アクセスキーの作成
* AWS CLIの設定	
  * AWS CLIのインストール
  * 初期設定でアクセスキー、シークレットキーを設定

### 環境
amazon linux 2
AWS CLI 2.12.1


### カスタムポリシーを作成
ポリシーを作成するために、IAM > Policies > Create Policyを選択する。Jsonによるポリシー作成は自分にはハードルが高いので、Visualボタンを選択。
サービスは、EC2を選択しActionは、StartInstancesを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/e3374a80-59b3-c8dd-6149-3ea0bcbca68a.png)

操作するインスタンスを制限するために、Resourceに起動するEC2インスタンスのARNを追加する。ARNは、RegionとインスタンスID(EC2一覧から取得)を指定すれば画面側で作成してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/20368119-1ce9-f5d7-bf3c-41edce410f32.png)

インスタンスが起動したことを確認できるようにしようと思い、Add more PermissionsからDescribeInstanceStatusも権限に追加した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/7a17f234-cd21-2438-8364-62492c64fa94.png)

権限追加したら適当な名前を指定してポリシーを保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/e2b63971-8ba1-abd9-e3e7-7a6663a5fd71.png)

### ユーザの作成
いったんユーザを作成したら、作ったポリシーを割り当てる。IAM > Users > Create user からユーザを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/fe144770-e90f-6a12-9bcc-c0cbe26f60df.png)

Set permmisions画面で、Attach policies directlyを選択し、事前に作成したポリシーを選択する。選択後、そのままユーザを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/e442970c-3b9a-8f47-11b2-108b299aa21c.png)

IAM > Users から作成したユーザの情報を開き、Security credentialsタブを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/0400c265-5278-29a4-b5c7-f5074f056531.png)

Access Keysからアクセスキーの作成に進む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/ad07faaf-db37-6e1f-77b9-a55d7650cf97.png)

Access key best practices & alternatives画面で、CLIを選択してアクセスキーを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/af405d60-fdaa-462e-c392-8d69196f8eff.png)

作成したアクセスキーとシークレットキーはAWS CLIの環境に設定するのでダウンロードするか、メモしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/825c8c68-4e55-6e88-8d36-574018809023.png)

### AWS CLIの設定
以下に従いインストールを実施する。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

以下のコマンドを実行する。(先にunzipをインストールしておく)
```bash
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```

初期設定で、アクセスキーとシークレットキーを設定する。
```bash
$ aws configure
AWS Access Key ID [None]: <アクセスキー>
AWS Secret Access Key [None]: <シークレットキー>
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

一応、権限のない操作を実施すると、エラーになることを確認する。
```batch
aws ec2 stop-instances --instance-ids <インスタンスID>

An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: 9NOmQ5E-pWD1YsFyg5KLIBJAJ4pAAYjmuRpUjFiqP0vgF1TQtvy4LDPsXIHH-1h1BXGDTOSEVp2092HFJX-29CgvL.....
```
Laravel Pint の v1.10.3 より使用していないインポート行が削除されるようになりました

Laravel Pint v1.10.3 より使用していないインポート行が削除されるようになりました。（no_unused_imports)

GitHub Actions 上で自動修正された様子↓
![修正2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/70445679-f089-daf3-1bc5-35f2fdc89ec1.png)
![修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/8dc4f6b5-3dff-e379-3d55-91f8a40c7a5a.png)

これが公式情報からちょっと分かりにくいです。[CHANGELOG](https://github.com/laravel/pint/blob/main/CHANGELOG.md) をみます。
![pint_CHANGELOG.md at main · laravel_pint - Google .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/bec507f8-5091-c7e9-af9a-b757979a0c6c.png)

良く分からないので [#188](https://github.com/laravel/pint/pull/188) のプルリクを見ます。ちょっと気になる部分を見つけました。
![Update Dependencies and replace deprecated rules b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/63be8d09-c63f-6e45-fd3b-e58a73afe417.png)

さらに下の方を見ます。「Remove unused import」の文字があります。近づいてきた感があります。
![Update Dependencies and replace deprecated rules b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/180c59c8-cf33-e0e3-feaf-18c105cbbe02.png)

[Remove unused import #6203](https://github.com/laravel/laravel/pull/6203) の内容を見ます。

![Remove unused import by Jubeki · Pull Request #620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/b252ab19-46d8-5969-9c92-2a4bb0ebee6f.png)

DeepLの翻訳によるとこういうことらしいです。「この行」というのは「unused import」の行だと思われます。
![Remove unused import by Jubeki · Pull Request #620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/ba17cd17-d5b8-4900-4e8f-2882119408f6.png)

つまり、こういうことみたいです。

【今まで】
PHP-CS-Fixer のバグにより、使用していないインポート行の削除機能が上手く機能していなかった。

【v.1.10.3】
PHP-CS-Fixer のバグ修正版を使用するようになったので、使用していないインポート行の削除機能が動くようになった。

## 余談

現在開発中のリポジトリでは、GitHub Actions 上で Pint による自動フォーマットをするようにしていました。
それが6/20 の業務時間中にプッシュしていた時点のコミットまでは自動フォーマットされていないのに、6/21 にプッシュしたものについては自動フォーマットされるという現象に合いました。
原因はこれでした（笑）。GitHub Actions の Pint は最新版をつかっています。v1.10.3 のリリース日は 2023/6/20 です。なので、ちょうど20日と21日のはざまで、使われる Pint のバージョンが変わった影響を受けたことになります。
また、ローカルの開発環境は v1.10.0 を使っていたこともあり「ローカルだと再現しねぇ！」という現象も発生し謎だらけの数時間を過ごしました。

本件は先輩社員と Slack のハドル機能を使って相談し解決できました。いつもありがとうございます。
PST を共有メールボックスにインポートする方法

PST ファイルを Office 365 の共有メールボックスにインポートする最良の方法をお探しですか? あなたは正しい場所に着陸しました。 この記事には、PST を共有メールボックスにインポートするための 3 つの簡単なテクニックが含まれています。 下にスクロールしてチュートリアルを参照してください。

あなただけでなく、PST から共有メールボックスへの転送プロセスを理解するのが難しいと感じているユーザーもいます。

**以下は、解決策を求めてメールで寄せられた質問です。**

*"Outlook なしで PST ファイルを共有メールボックスにインポートできますか?"*
*"PST ファイルを Office 365 メールボックスにインポートするにはどうすればよいですか?"*
*"PST を共有メールボックス Exchange 2016 にインポートできますか?"*
*"PST を Exchange Online メールボックスにインポートする方法"*
*"PowerShell を使用して PST を共有メールボックスにインポートする方法"*

PST ファイル形式には、電子メール、添付ファイル、連絡先、カレンダー、その他の項目が含まれることをご存じかもしれません。 このファイル形式は Outlook からエクスポートでき、Outlook のどのバージョンにも同じ形式でインポートできます。

質問に戻りますが、ユーザーは電子メールを保護するために .pst ファイルを Office 365 の共有メールボックスにアップロードすることがあります。 PST 電子メールをクローン コピーとして Microsoft の共有メールボックスに保存またはコピーできます。

## 方法 1. Office 365 の共有メールボックスに PST を簡単にインポートする方法
**[Advik PST to Office 365 Converter](https://www.adviksoft.com/pst/office365.html)** を PC にダウンロード、インストールし、実行します。 このソフトウェアは、PST ファイルから Microsoft 365 電子メール アカウントの共有メールボックスに電子メールを転送するように設計されています。 電子メールの移行中、フォルダーとサブフォルダーの階層が維持されます。

無料ダウンロード：https://www.adviksoft.com/dl/advik-outlook-pst-converter.exe
    

**手順に従って、PST 電子メールを共有メールボックスに直接移動します。**

ステップ1. PCでAdvik PST File Converterを実行し、「ファイルの選択」オプションを使用してOutlook .pstファイルを追加します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/a1c71980-dbfc-5d69-8d36-ccf1861a2cf4.png)


ステップ 2. PST ファイルから電子メールフォルダーを選択し、「次へ」ボタンをクリックします。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/243c9324-b5c4-4b9c-8b59-195e106c507d.png)


ステップ 3. 次に、保存オプションとして Office 365 を選択します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/d44e1f5a-16d6-5b35-dd61-75521ad94560.png)


ステップ 4. Office 365 電子メール アカウントの資格情報を入力します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/85bd3396-4ed8-c71f-dc52-fab70f1ef54e.png)


ステップ 5. ここで「変換」ボタンをクリックして、Office の共有メールボックスへの PST 移行を開始します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/7307ebcd-0007-acc2-ebde-732aeb8e3dce.png)


終わり！ ソフトウェアは、添付ファイル付きの電子メールを Outlook PST から共有メールボックスに移動します。



## 方法 2. Outlook を使用して PST ファイルを共有メールボックスにインポートする
PST ファイルを共有メールボックス Office 365 にインポートするには、次の手順に従います。

1. PC で Microsoft Outlook を起動します。
2. Office 365 電子メール アカウントを追加または構成します。
3. PST ファイルを共有メールボックスにインポートするために必要なアクセス許可があることを確認してください。
4. Outlook リボンの [ファイル] タブをクリックします。
5. 左側のメニューから「開いてエクスポート」を選択します。
6. オプションから「インポート/エクスポート」を選択します。
7. インポートおよびエクスポートウィザードで、「別のプログラムまたはファイルからインポート」を選択し、「次へ」をクリックします。
8. 「Outlook データ ファイル (.pst)」を選択し、「次へ」をクリックします。
9. 「参照」ボタンをクリックして、インポートする PST ファイルを見つけます。
10. インポートされたデータの宛先として必ず共有メールボックスを選択してください。
11. 「完了」をクリックしてインポートプロセスを開始します。
12. Outlook にインポート操作の進行状況が表示されます。
13. インポートが完了すると、共有メールボックス内のインポートされたデータにアクセスできるようになります。

**制限と欠点**

* 手順は Outlook のバージョンによって異なる場合があります
* PST ファイルを共有メールボックスにインポートするには、必要なアクセス許可が必要です。
* Outlook では、インポートできる PST ファイルのサイズに制限がある場合があります。
* Outlook でインポート エクスポート オプションがグレー表示されている場合は機能しません

**結論**
結局のところ、PST を共有メールボックスにインポートするにはさまざまな方法があります。 PowerShell の方法と、Thunderbird およびサードパーティのツールについて説明しました。 ただし、Outlook .pst から Office 365 の共有メールボックスに電子メールを移行する場合、Advik PST Converter のシンプルさに匹敵するものはありません。