OmniAICreator/Qiita-1.07M huggingface dataset:
Meta Questでシステムのバーチャルキーボードを呼び出す方法

## はじめに
本記事ではQuestの入力関連処理の際に立ち上がるキーボード(以後システムキーボード)を自作アプリで利用する方法についてメモします。

システムキーボードは多言語対応、変換対応、計算されつくしたUIUXを備えており、非常に使い勝手に優れています。

自作アプリに入力系の実装予定がある場合、システムキーボードを利用することはかなり大きなアドバンテージとなります。

## バージョン情報
| ツール、ライブラリ | バージョン |
|:-:|:-:|
| Unity  |  2021.3.32f1 |
| [Meta XR Core SDK](https://assetstore.unity.com/packages/tools/integration/meta-xr-core-sdk-269169?locale=ja-JP) | 59.0.0  |

## 挙動
以下が挙動の簡易的なデモです。InputFieldを選択する
とシステムキーボードが立ち上がります。

![keyboard.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/c60ec4bd-2cba-7d8c-b604-652cc4e6fa42.gif)

:::note warn
注意点として、システムキーボードが立ち上がるとアプリはフォーカス外にある状態となります。

入力を終了する、あるいはシステムキーボード外のエリアをトリガーでクリックすることにより、フォーカスがアプリに戻ります。
:::


## 実装方法
以下パスのアセットファイルの`Requires System Keyboard`をTrueにします。
`Assets/Oculus/OculusProjectConfig.asset`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/8e03c12e-0d85-ee5f-a569-da4976d70258.png)

なんとこれだけでシステムキーボードが利用可能になります。
InputFieldのフォーカスが合ったかどうかや、既にInputFieldに文字が入力されているかなどを実装する必要はありません。

さらに踏み込んだ話をすると、”OpenXRを利用しているのでわざわざこのためにMeta XR Core SDKをプロジェクトに導入したくない”みたいなシチュエーションにおいては、以下をAndroidManifestに書き込むだけで利用可能となります。

```CS
<uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>
```

---
### 入力フィールド以外における呼び出し
ここまでの対応で入力フィールドのフォーカスに応じたシステムキーボードの呼び出しが可能となりました。

もう一歩踏み込んだ実装として、"入力フィールド以外の箇所でのシステムキーボードの呼び出し"について考えます。

例えば、キャラクターを選択するとそのキャラクターの名前を入力する画面が立ち上げるようなシチュエーションです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/7fc7d106-f6ee-3231-2b60-a9bf39015f56.png)




このようなシチュエーションを想定してプログラムからシステムキーボードを有効にする手段が用意されています。

以下が実際にプログラムから呼び出すサンプルです。


```CS
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class KeyboardTest : MonoBehaviour
{
    [SerializeField] private Button _button;
    [SerializeField] private TextMeshProUGUI _textMeshProUGUI;

    private TouchScreenKeyboard _overlayKeyboard;

    private void Start()
    {
        _button.onClick.AddListener(OnClickButton);
    }

    private void Update()
    {
        if (_textMeshProUGUI.text == _overlayKeyboard.text) return;
        _textMeshProUGUI.text = _overlayKeyboard.text;
    }

    private void OnDestroy()
    {
        _button.onClick.RemoveAllListeners();
    }

    void OnClickButton()
    {
        _overlayKeyboard = TouchScreenKeyboard.Open(_textMeshProUGUI.text, TouchScreenKeyboardType.Default);
    }
}

```

以下GIFのようにButtonをトリガーとしてシステムキーボードの呼び出しを行うことができました。入力結果を保持しておき、利用することも可能です。

![pokemon3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/cd3ea009-fd6e-dff8-315c-037bb846fec9.gif)

---
追記 2023/12/19

一週間前くらいからOSレベルのバグがあるらしく、まともに動作しない状態となっています。我々ではどうしようもできないので、Metaのアップデート待ちです。

https://communityforums.atmeta.com/t5/Get-Help/Keyboard-Overlay-Bug-Freeze-and-can-not-return-App/m-p/1117289#M252396

## 参考リンク
- [Oculus Quest 2 Keyboard with XR RIg](https://forum.unity.com/threads/oculus-quest-2-keyboard-with-xr-rig.1183006/)
- [Enable Keyboard Overlay](https://developer.oculus.com/documentation/unity/unity-keyboard-overlay/)
- [【無料】スカーレット・ヴァイオレット御三家あり！ポケモンイラスト素材](https://booth.pm/ja/items/4305088)
OpenAI（ChatGPT）のAPIの使い方簡単まとめ

こんにちは！！
やどかりの代表やっている松澤です。

以前からAIについては未来を語る上でいろいろと出ておりましたが
今年はChatGPTの登場で一気にAI熱があがりましたね。
みなさんもChatGPTを触られている方も多いと思いますが、
一歩踏み込んでChatGPTの元となっているOpenAIの使い方を
簡単に説明しようと思います。

先に私が以前に試して、ハマったポイントなどを詳しく見たい方はこちらもどうぞ。
[ChatGPTが話題なのでOpenAIを試してみた！](https://note.com/yadokari_inc/n/ne15bc633e338 "ChatGPTが話題なのでOpenAIを試してみた！")
[OpenAI続き。動いたのでmessagesやroleパラメータをいじってみる](https://note.com/yadokari_inc/n/nf01facba8605 "OpenAI続き。動いたのでmessagesやroleパラメータをいじってみる")
[OpenAIの生成AIで画像を作ってみよう！](https://note.com/yadokari_inc/n/nfbd89c7176a2 "OpenAIの生成AIで画像を作ってみよう！")



# 環境構築に関して
**細かい導入の手順に関しては「ChatGPTが話題なのでOpenAIを試してみた！」の記事をみてもらうと良いと思います**。
アカウント作成時に無料で使える枠もありますので、ある程度はお試しができます。
[ChatGPTが話題なのでOpenAIを試してみた！](https://note.com/yadokari_inc/n/ne15bc633e338 "ChatGPTが話題なのでOpenAIを試してみた！")


# 早速サンプル使って動かしてみる
環境を作成すると一番オーソドックスなmessageのやりとりのサンプルです。

```from openai import OpenAI
client = OpenAI()

completion = client.chat.completions.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."},
    {"role": "user", "content": "Compose a poem that explains the concept of recursion in programming."}
  ]
)

print(completion.choices[0].message)
```

コードの量は本当にミニマムではありますが、これで最低限の動作を実行することができます。
少しだけ説明します。
* model
OpenAIの仕組みでは必ず使用するmodelを指定します。modelは脳みたいなもので、何に特化したmodelを使うかで得意な分野が違います。ここで指定しているgptはChatGPTの元になっているmodelです。

* messages
ここで実際のメッセージのやりとりを記載していきます。

* role
roleは役割です。今回はsystemとuserで指定をしています。
systemがイメージとしてはAIアシスタントのキャラクターの設定と考えてください。
サンプルの例では「あなたは、複雑なプログラミングの概念を創造的なセンスで説明することに長けた、詩的なアシスタントです。」ということでポエムを語るキャラクターの設定ですねw
そしてuserで実際の質問を自分が設定したキャラクターに投げかけます。

サンプルの例では英語で全部設定されていますが、実際には日本語での設定で問題なく動きます。
これを実行するとAIアシスタントから回答が返ってきますので（completion.choices[0].message）、サンプルではこちらを画面にprintにて表示しています。

これで自分オリジナルのキャラ設定をしたAIアシスタントの完成です。
非常に簡単にできてしまうので、プログラムというわけでもなく、
実際にはsystemで設定するキャラ設定を正しくするのが難しい感じです。
特徴をうまく説明してパラメータとして渡すことで期待するキャラクターになります。

# AIに画像を作成してみたい場合はこちら
```
from openai import OpenAI
client = OpenAI()

response = client.images.generate(
  model="dall-e-3",
  prompt="日本人でいけてる社長",
  size="1024x1024",
  quality="standard",
  n=1,
)

image_url = response.data[0].url
print(image_url)

```
こちらもめっちゃシンプル！！
先ほどと同じようにmodelを画像生成に特化したmodelに変更します。
そして欲しい画像をpromptで指定するだけです。

ここまででOpenAIについてはどうでしたでしょうか。
いつも使用されているChatGPTの中身や仕組みが少しだけ理解が深まると思います。

あとは組み合わせとアイデア次第でいくらでも世界が広がっていくと思うと
ワクワクすることがたくさんあります！！

今後広まっていくだろうAIについてを少しだけ深掘りしてみようの会でした。
ありがとうございました。
マルチモーダルRAGに関する情報まとめ

## ■ はじめに
　現在、LLMの活用において専門的な分野に対応した**RAG (Retrieval Augmented Generation)：検索拡張生成** が話題となっている状況だと思います。よくファインチューニングと比較されますが、追加学習の必要性がない・コストもかからない・更新も楽なことからLLM回答精度を向上させることできる点で、着目されております。


**・RAGとファインチューニングの比較解説記事**

https://ainow.ai/2023/12/14/275411/

今年に、マルチモーダルGPT4Vが登場したことから、以前はテキストベースのみで適用されていたRAGについてもマルチモーダルへの適用化が求められているため、その情報を収集したものを簡単ですがまとめました。

 ## ■ RAG : Retrieval Augmented Generation
RAG自体についてはこちらの解説などがわかりやすいので参考まで。

https://qiita.com/t_serizawa/items/a2ced4441da714b3076f

https://storialaw.jp/blog/9885

## ■ マルチモーダルRAGについて
これまでテキストのみの情報であれば、RAGに組み込む際にベクトルDBとして情報を保存します。これが異なるデータ(画像、テキスト、テーブル)の場合にどのように統合して保存するかがポイントのようです。既に色々な情報があるようで、それぞれの解説ページを参照して頂ければと思います。


**① Multivector Retrieverを使ったPDFの画像まで含めた検索システム実装**

https://qiita.com/mashmoeiar11/items/c89ae3f5084680676611

https://qiita.com/mashmoeiar11/items/d7ba174c770a0f05356c

<br>


**② 別解説記事：上記と参照している大本は同じ**

https://qiita.com/isanakamishiro2/items/1a193e056c5bfedbb61e

https://qiita.com/isanakamishiro2/items/06fec7bd3c47d3efb843


<br>

**③ LangChainのテンプレート活用事例**
・中身の解説はないがすぐに試せるコードがいくつかあるよう。こちらもPDF対象

https://qiita.com/s3kzk/items/8d28b7acac6954d20f47

<br>

**④ LlamaIndex の マルチモーダルRAG**
・Wikipediaからの画像・テキスト情報収集を行い、統合してベクトルDB化処理を行う。Jupiter codeもあり、動作確認とプロセスが理解しやすい内容でした。

https://note.com/npaka/n/n53e8aabed0f2

https://github.com/run-llama/llama_index/blob/main/docs/examples/multi_modal/gpt4v_multi_modal_retrieval.ipynb

* 動作するにあたって、pydanticのダウングレードが必要でした。
`　!pip install pydantic==1.10.9　`


**・マルチモーダルRAGの解説記事**

https://note.com/npaka/n/ne30fe90c23ca

<br>

**⑤ 他LlamaIndex の マルチモーダルRAG活用**

https://note.com/panda_lab/n/n2a3137a4f5f0

https://note.com/ippei_suzuki_us/n/n94abd10090b1



## ■ その他 マルチモーダルLLMの活用調査

GPT4Vの限界挑戦・できること、できないことの調査内容の情報
マルチモーダルRAGを今後広げていく上でのヒント多数。座標情報やセグメントの弱い部分の補強の仕方などなど

https://isid-ai.jp/column/GPT-4V_Trend_Survey

## 🔳その他 画像ベクトル検索

・Computer Vision 使った 画像のベクトル化と検索の事例

https://zenn.dev/microsoft/articles/17574f3569914b
SwiftUIでfirebaseを導入する方法

# Firebaseでプロジェクトを作る
コンソールに移動して、プロジェクトを作ります。
![スクリーンショット 2023-12-14 18.21.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330686/c644a2fb-1b24-2466-e1f2-7b522c0ad3ec.png)

プロジェクトを追加を押します。

名前をつけて、アナリティクスが必要な場合はアナリティクスを追加して、プロジェクトを作成します。!

# IOSアプリを追加する
![スクリーンショット 2023-12-14 18.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330686/7ccf6999-f78e-af27-f0ab-145a17804c72.png)

IOSボタンを押して、アプリを追加します。

指定通りの手順で続けます。

バンドルIDはここを参考にしてください。

![スクリーンショット 2023-12-14 18.29.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330686/81fd0a79-65db-7ce1-0294-3926daeef999.png)

info.plistをダウンロードして、プロジェクトに追加する。

file→Add Packageでhttps://github.com/firebase/firebase-ios-sdkを追加する。

必要そうなものだけライブラリを追加し、~Appファイルに必要な記述を追加する！

これで導入の準備は終わりです！
GZipStream.Read() はなかなか手強い

# はじめに

ファイル拡張子(.gz)のファイルを、GZipStream.Read()で読み込む処理を考えます。いくつかの罠にはまったので、笑い話ついでにTipsを記します。

:::note info
事象を確認したターゲットフレームワークは、.NET 8.0
:::

:::note info
ファイルを解凍してから扱えばいい、というのは正論だが(StackOverflowあたりにもそんな回答があった)、あえてGZipStreamで頑張ってみる。
:::

# コード例

機械学習の練習でよく使われるMNISTのイメージデータを読み込む処理(TensorFlow.NETを使用)を例に取ります。扱うファイルのひとつは、'train-images-idx3-ubyte.gz'でgzipで圧縮されています。

```MNISTManager.cs
public static NDArray Load_Image(string image_path)
{
    using Stream fs = File.OpenRead(image_path);
    using Stream zs = new GZipStream(fs, CompressionMode.Decompress);

    // ファイルヘッダを解析してからイメージデータ部を読み込む
    byte[] buf = new byte[16];
    zs.Read(buf,0,16);
    long size = BinaryPrimitives.ReadInt32BigEndian(buf[4..8]);
    long rows = BinaryPrimitives.ReadInt32BigEndian(buf[8..12]);
    long cols = BinaryPrimitives.ReadInt32BigEndian(buf[12..16]);

    // 想定通りなら 60000 * 28 * 28
    int cnt = (int)size * (int)rows * (int)cols;

    // 罠その1
    // バッファサイズを指定しても、一部しか読んでくれない
    //zs.Read(bufdata,0,cnt);

    int nread = 0;
    int offset = 0;
    int len = 1024 * 1024;  // 1M

    byte[] readbuf = new byte[len];
    byte[] bufdata = new byte[cnt + len];

    while (true)
    {        
        nread = zs.Read(readbuf,0,len);

        // 罠その2
        // ファイルの途中でも読み込み単位(len)以下のサイズが返ることがある
        // したがって、nread < len は終了判定に使えない
        if (nread == 0) { break; }
        if (offset >= cnt) { break; }   // ignore residuals

        // 罠その3
        // 読み込み単位以下のサイズが返った場合、
        // CopyToでは、読んでいないデータも複写してしまう
        // readbuf.CopyTo(bufdata, offset); // this copys unread data...
        for (var i = 0; i < nread;i++)
        {
            bufdata[offset + i] = readbuf[i]; 
        }       

        offset += nread;
    }

    NDArray data = np.array(bufdata[0..cnt]).reshape((size, rows * cols));
    data = data.astype(np.float32);
    
    return data;
}
```

# 罠その1

データを収めるのに十分なサイズのバッファを用意し、
`Read(buf,offset,length)`
を実行してもデータ全体は読み込まれない。

Streamを用いる際の基本を忘れていました。一度のReadでは内部のバッファ分しか読み込まれず、読み残しがある限り、繰り返しReadを呼び出す必要がありました。

# 罠その2

Readの戻り値として読み込んだデータのサイズが返されるのですが、これが規定値以下になることを終了条件にしたら、途中終了しました。

読み込み用のバッファのサイズ以上に読み残しがあったとしても、バッファのサイズ未満しか読み込まない場合があります。別の終了条件を設けます。

# 罠その3

その2の続きですが、読み込み用のバッファに一部しかデータが読み込まれないので、CopyToで配列全体を複写すると、ゴミのデータも複写してしまいます。

しかたがないので、for文で一要素ずつ複写します。

# おわりに

下書きを書いてから改めて調べてみると、関連する記事を見つけました。こちらの方の実装の方が実用的で参考になると思います。

https://qiita.com/sawasaka/items/5d6df711776c990e6ec2

この記事で必要は尽くされている気もしますが、自戒を込めて本記事も残しておきます。
ジンズにジョインしました

この投稿は、[2023年 JINS Advent calendar](https://qiita.com/advent-calendar/2023/jins) 15日目の記事です。

## はじめに
今年2023年10月にジンズにジョインした、うりぼー(@urib0)です。
(ジョインしました！と書くのなんか恥ずかしいなと思いつつ、ちょっと憧れてたので使ってみました)
簡単な経歴と、現在運用/開発を担当しているPICK UP LOCKERの運用/開発について書こうと思います。

## 自己紹介
こちらがざっくりとした職歴です。

1社目：半導体商社にてマイコンソフトウェアの受託開発を行う
2社目：Webサービスのベンチャー企業でIoT系のPoC開発を行う
3社目：センサーモジュールのベンチャー企業でPoC開発を行う
現在：ジンズのITデジタル部に所属し、店舗運営に関わるシステムや機器の運用保守を行う

こうやって書き出してみると改めてジンズへの転職は畑違いというか毛色が異なりますね。。
なぜジンズに転職したのかは別の機会に書こうと思います。(本当に？)

## PICK UP LOCKERについて
受け取りボックスですが近年様々な業種で導入が進んでいますね。
PICK UP LOCKERはメガネに特化した受け取りボックスで、QRコードをかざすだけで好きな時に商品を受取る事ができます。
5月から運用開始して以来、利用率の高い店舗で半数以上のお客様がPICK UP Lockerを利用しておりとても好評のようです。

プレスリリースはこちら
[日本初※！メガネのセルフ受け取りロッカー「PICK UP LOCKER」順次導入開始](https://www.jins.com/jp/topics_detail.html?info_id=589)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284492/c08bab7d-64f0-c6b9-e481-93553f08971c.png)

## 構成
とてもシンプルな作りをしています。ハードウェア(以下HW)と格子の制御に関するソフトウェア(以下SW)は協力会社に製作してもらい、従業員向けのweb管理画面はジンズで内製しております。
小型PC：格納/受け取り状態の管理、開閉指示、従業員向け管理画面としてのWebサーバ
制御ボード：格子電子錠の制御、照明の制御

内製した管理画面です、
![Image_20231214_173025_979 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284492/7bb7ef57-6a10-9bd3-b9fb-6aeba147c532.png)

## 運用/開発について
入社時には約50店舗に導入が済んでおり、年内までの全国60店舗導入まであと少し！
となればHW/SWともに安定しているのでは…！
と、当時は思っていました…

### 電子錠が動かない？
約50店舗、計約2500個の格子があるので当然壊れるものも出てくるとは思いますが、どうも経年劣化ではなさそう…
原因がHW/SWか切り分けも難しい中、店舗への影響もあるため早急に解決しなければ…！
ということで急遽協力会社と合同デバッグを実施することに。
結果、SW側の修正で済むことがわかり迅速に解決することができました。

実際に作業している様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284492/2678b6a9-1583-4b92-e17f-ff9484a508c3.png)

### いきなり立ち上がらなくなった！？
なにもしてないのに動かなくなった！なんてのはよく聞く話ですよね。
本来であれば協力会社へ修理を依頼すべきですが、私がPICK UP LOCKERに携わってから初めての事象だったので現地へ調査しに行ってみました。
すると…

抜けてる！！ほぼ完全に！！！
筐体内の配線が抜けてしまうということは外部からの力がそのまま加わっているということだと思いますが、コネクタ自体も抜けにくいようなものではなさそうです…
こちらは追加の固定とコネクタの刷新で対処することとなりました。

実際のコネクタ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284492/af45027d-bb56-6af1-9a9d-73987a24a2ac.png)

## まとめ
運用開発をしていく中での苦労を書いてしまいましたが、ハードウェアの経験を活かして着実に改善していくのを感じられてやりがいがありますね。

ジンズには多種多様なバックグラウンドを持った方が在籍しております、少しでもご興味を持ってくださった方はぜひ応募していただければと思います。
[JINS IT・デジタル採用](https://jinsholdings.com/jp/ja/recruit/digital)

明日は同期入社の@kose_kさんの記事です、お楽しみに！
Docs-as-Ecosystem

Docs-as-Ecosystemは、ソフトウェアエンジニアリング領域でのテクニカルライターの人が書いた書籍です。著者の方は、[AsyncAPI](https://www.asyncapi.com/)のようなOSSのドキュメンテーションなどをやられているようです。

<a href="https://www.amazon.co.jp/-/en/Alejandra-Quetzalli/dp/1484293274"><img src="https://m.media-amazon.com/images/I/51PLAs3eMQL._SL1253_.jpg" width="200" alt="Docs-as-Ecosystem書影"/></a>

APIドキュメントの書き方、SDKドキュメントの書き方などは、割と詳細に書かれているので、そこでお悩みの方は読んでみるといいかもしれません。

そんな中から私が、面白いと思った2つを紹介します。

## Diátaxisフレームワーク

情報アーキテクチャの整理手法の1つでコンテンツを、チュートリアル、ハウツーガイド、解説、リファレンスの4つに分けようというものです。

* チュートリアル
    * ステップバイステップのガイドを提供する
    * その技術や製品に不慣れな人がターゲット
    * 基本的なプロセスやコンセプトを実践的に学べる
* ハウツーガイド
    * アクティブなユーザが問題に遭遇した時に読むものを提供する
    * 複雑なユースケースや高度なトラブルシューティングのシナリオを扱う
* 解説
    * 技術の特徴や機能の概念を定義する
    * コミュニティメンバがより深く理解できるようにすることを目的にする
* リファレンス
    * API仕様やSDKドキュメントにアクセスする必要のあるコミュニティメンバを対象にする。

## AIによってテクニカルライティングはどう変わるのか？

テクニカルライティングの分野で生成AIなどがどう影響してくるか。テクニカルライターの視点で書かれているのは、なかなか興味深いところです。

* ジュニアライターの活躍の場を広げる
    * 従来はただでさえ時間を確保しにくい、シニアライターが密にコミュニケーションとってアドバイスやレビューをする必要があったが、AIがその先輩役を肩代わりしてくれる。
* 調査プロセスを加速できる
    * 膨大な量のデータを素早く分析し、最も関連性の高い情報を抽出できる
    * テクニカルライティングプロジェクトの新しい切り口やトピックを提案をしてもらう
* 編集とコミュニティ構築重視へのジョブチェンジ
    * AIの活用で浮いた時間を、編集やコミュニティ形成に集中することに使う
* AI生成文書のファクトチェック
    * AI生成文書のファクトチェックがテクニカルライターの主要な仕事になるかもしれない。少なくとも現在では、正確性、完全性、倫理遵守を慎重に管理・監視する必要がある。

## まとめ

現時点では、日本では「テクニカルライター」の職種の方を見かけることはほとんどなく、ソフトウェアエンジニアがドキュメンテーションの責務を負っています。テクニカルライティングを学んでないので、いわばみんな「ジュニアライター」の状態です。Diátaxisフレームワークのようなテクニカルライティング技術をいくつか学んでおけば、生成AIにドキュメント書いてもらうにしても、より整理されたもの手に入れられるように思いました。
Symantec Ghost Solution Suite 3.3の自分メモ

Symantec Ghost Solution Suite（以下GSS）のインストールのためのメモを残しておきます。
（若干うる覚えあり、修正予定です）

Symantecから変わったことにより日本語情報が一気に減ったので、自分の為のメモとしての記事なので、参考程度に・・・
*broadcomユーザアカウントがある事前提です。

# 作業の流れ
1.Broadcomにログインし、契約情報を確認しダウンロードを実行する。
　この記事の下書きを記載した時点での状況では、3.3 RU10が最新
2.ソフトウェアが2種類あるが、今回はサーバOSかつWebConsoleを使用するのでToolではないものをダウンロードする。
3.Microsoftより、SQLserver2019Expressをダウンロードし用意する。
4.WindowsSererのIISを有効にし、要求機能を追加する。
5.SQLServerのインストールを実施
6.インストール前事前設定
7.２でダウンロードしたものを実行してGSSのインストールを実行する。


# Broadcomにログイン
以下のBroadcomにアクセス後、右上の「ログイン▼」をクリックしログインをクリックする。
（アカウントがない場合は、Regsterからアカウントを作成、それについては説明しません。）
https://jp.broadcom.com/

https://knowledge.broadcom.com/external/article?articleId=226420

# ソフトウェアのダウンロードする
MyDownloadから登録している自社/お客様を選択、さらに紐づいているGSSを選択し、そしてバージョンを選択するとダウンロードできるものが表示される。
目的のファイルをHTTPでダウンロードする。
Symantec_Ghost_Solution_Suite_3_3_RU10.exe

https://knowledge.broadcom.com/external/article/223082

# SQLserverのダウンロード
GSSでは、SQLserverが必須の為ダウンロードをおこなう。
どのバージョンが対応しているかの情報は、下記を参考

https://knowledge.broadcom.com/external/article/185204/platform-support-ghost-solution-suite-3x.html

SQLServerは、下記リンクからダウンロード
https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads

WindowsSerer2022には、いつ対応するんだろうか。
クライアントのWindows11も記載していないし・・・

もうマスターイメージ作成して展開するソリューションは時代遅れになりつつあるかも。
正直CO-CONVやV-BOOTにOSVそっちの方が管理しやすいと思う。

# Windows機能の追加
・IISを有効にする。
　・ASP.NETを追加
　・ISAPIおよびCGI制限　←ちょっとよく覚えていない
　・Windows認証
　・HTTPリダイレクト

特に、HTTPリダイレクトは資料に設定しろとは書いているもののインストールしろとは書いていないので、かなり不親切

# SQLサーバーのインストール
ダウンロードしたSQLサーバーのインストーラからインストールを実施というか、ダウンロードしてからインストールの実施


本当のインストーラが起動したら下記のものを選択する。
「SQL Serverの新規スタンドアロン インストールを実行するか、既存のインストールに機能を追加」

インストーラを進めていくと、「インスタンスの構成」が表示されるので[MSSQLSERVER]になっていることを確認する。
異なる場合は、[MSSQLSERVER]に変更する。

https://knowledge.broadcom.com/external/article/228303/ghost-solution-suite-sql-server.html


「データベースエンジンの構成」で
・「Windows認証モード」になっていることを確認
・「SQLServerの管理者」の設定で[GSS管理者]を登録する。
　　・Administrator/Administrators/GSSの管理者を登録

このあと、インストールが開始され、正常終了する事を確認する。

# インストール前事前設定
### IIS設定変更
IISの管理を起動し左ペインからGSSサーバを選択し右ペインの「ISAPIおよびCGI制限」を編集でひらく
　・ASP.net（バージョン表示）　が二つあるとおもうので、それが許可になっている事を確認する。

左ペインからたどって、「Defalt Web Site」を選択し、右ペインの「認証」を選択する。
下記のものを[無効]から[有効]に変更する。
　・「ASP.Net偽装」
　・「Windows認証」

### UACの無効化
マニュアルにUACを無効化するように記載されているので無効化を設定する。

### ウィルス対策ソフトの無効化
サービス登録時に削除することがあるらとの事なので無効化を実施する。


Symantec Ghost
RISC-VマイコンCH32V003でLチカ【電子工作】

この記事は [本郷学園マイコン部 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/hongomcc) 15日目の記事です。

## やったこと
文化祭後の代休に秋月電子通商に赴き、その場で一目惚れして(?)購入した32ビットRISC-Vマイコン[CH32V003J4M6](https://akizukidenshi.com/catalog/g/gI-18062/)でLチカをしました。

## 用意したもの
- PC
- [CH32V003J4M6](https://akizukidenshi.com/catalog/g/gI-18062/)
- [WCH-LinkEエミュレータ](https://akizukidenshi.com/catalog/g/gM-18065/)
- [SOP8->DIP変換基板](https://akizukidenshi.com/catalog/g/gP-05154/)
- [細ピンヘッダ](https://akizukidenshi.com/catalog/g/gC-04398/)
- LED、炭素被膜抵抗330Ω
- ブレッドボード、線材
- 忍耐力

## 環境構築

### ドライバのインストール
https://www.wch-ic.com/products/WCH-Link.html から`WCH-LinkUtility.ZIP`をダウンロードして展開します。直下の`WCH-Linkutility.exe`の初回起動時にデバイスドライバを含むなんか色々なモノが入ります。

PCのUSBポートにWCH-LinkEエミュレータを挿入し、画面上部`Connect WCH-Link (Alt+F2)`ボタンを押すとWCH-LinkEが認識され、その状態が確認できるようになります。購入時の状態ではARM用となっているため、これをRISC-V用に変更する必要があります。画面下部`Active WCH-Link Mode:`のプルダウンで`WCH-LinkRV`を選択し、横の`Set`ボタンを押下すると設定が変更され、エミュレータ胴部の青ランプが消えます。    

画面上部`Query Chip info (Alt+F3)`ボタンを押すと、エミュレータに接続されているチップのUIDやフラッシュメモリサイズなどの情報を取得できるようです。

### Arduino IDEにWCHのマイコン用環境を追加
`Preferences`->`Additional Board Manager`に https://github.com/openwch/board_manager_files/raw/main/package_ch32v_index.json を追加します。

ボードマネージャーで`ch32`と検索、出てきたものをインストールします。

## 回路を組む
マイコンをDIP変換基板に実装します。ブリッジしても気にせず半田を流し込み、後から吸い取り線で過剰分を除去するという方法をとりました。

ピンヘッダの実装はブレッドボードに刺して行いました。もたつくとブレッドボードが溶けるという噂を聞いていましたが、特に何も起こらず無事に乗り切ることができました。

エミュレータからジャンパワイヤで引き出した`3V3`、`GND`、`SWDIO`の3本を、マイコン本体のピンアサインに従って配線しました。

1番ピンにLEDと抵抗を接続し、マイコンの出力によってLEDが光るようにしました。

![マイコンの1番にLED、2番にGND、4番に3V3、8番ピンにSWDIOをそれぞれ接続](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708674/517ca8ec-0cb5-4274-b9fb-066cefd7fd25.jpeg)

## プログラム書き込み&動作確認
以下のLチカスケッチを記述し、Arduinoに書き込む場合と同様に検証を行った上でコンパイル&書き込みを行います。

```ch32v003j4m6_blink.ino
void setup() {
  pinMode(PD6, OUTPUT);
}

void loop() {
  digitalWrite(PD6, HIGH);
  delay(100);
  digitalWrite(PD6, LOW);
  delay(100);
}
```

書き込みが完了するとプログラムの実行が開始され、無事にLEDが点滅してくれました。

## おわりに
3年ほど前に5kJPY程度だったPICkit4が15kJPYになってしまうような理不尽な半導体不足の中で、非常に安価に提供されているこのマイコンの恩恵にぜひとも与っていきたいです。

明日は @miyajimaTKK さんの [AIを使って脳死でアプリを作ろう](https://qiita.com/miyajimaTKK/items/0951191f17c5b3ca23d1) です。
10時間でアプリを開発~公開したので振り返る

## 宣伝させてください
**seppan**という割り勘を管理するアプリをandroid用にリリースしました。

私は「後で割り勘でもいい？」というシチュエーションが結構あるのですが、いちいちレシートを確認するのが面倒くさくなったので作りました。

会計する時に買った人、物、金額を入力して保存しておけば、後でどっちがどっちに何円払うか簡単にわかるというアプリです。

清算した履歴も確認できるため、うちでは「〇月分の水道代まで割り勘してもらってる」というような使い方もしています。

とてもシンプルですが、意外と便利なのでぜひインストールお願いします。

https://play.google.com/store/apps/details?id=com.tatta_chotdog.seppan

## きっかけ
本業でReactエンジニアをしているので、学習も兼ねて何か個人開発をしようと思い調べたところReact Nativeというフレームワークに出会いました。

## React Nativeとexpo
・Reactのお作法とjs/tsの知識があればクロスプラットフォームのスマホアプリ開発ができるというフレームワーク
・expoという開発支援ツールを使用すれば、QRコードを読み取るだけで手持ちのスマホで動作確認ができる

## 開発面で主に学んだこと
フロント歴は1年ほどですが技術面で困ることはあまりなく、**seppan**を開発する上で新たに学んだことは以下の技術くらいだったため、フロントをかじっている人にはReact Nativeおすすめです。

### React Navigation
タブ間の遷移を可能にするライブラリ
ボタンを押したら遷移、スワイプしたら遷移などスマホアプリらしくなる

### スタイル
Flexboxが中心的なレイアウト手法
コンポーネント内でスタイリングを行うため、StyleSheetオブジェクトを生成する
ChatGPTにイメージを伝えると効率よく開発を進められた

### SQLite
サーバーではなくデバイス自体にデータを保存できるシステム
スマホ内にDBを組み込めるイメージでとても便利

### eas
Expo Application Servicesの略
expoで開発したアプリをクラウド上でビルドしてくれるサービス
無料プランだと月にビルドできる回数がiOSだと15回、androidだと30回
eas.jsonというファイルを編集しなければならない

## アプリ公開
ストアに掲載した経験はあるのですが、その時とは勝手が違いセキュリティポリシーのURLを設定しなければならなくなっていたため、以下のサービスを使用しました。

https://app-privacy-policy-generator.firebaseapp.com/

アプリ内画像やアイコン、掲載内容などを入力して審査・・・公開！
公開された時は何ともいえない達成感があります！

## まとめ
勉強の一貫として自作アプリをリリースする事はとてもおすすめです。
非常に小規模ですが、技術選定→要件定義→基本・詳細設計→開発(デザイン)→テスト→公開までの流れを1人で行うのは経験値が高い学習法だと思います。

今まで個人開発は途中で離脱することが多かったのですが、どんなものでも成果物として完成させて初めて自分の価値になるんだと感じました。

なんて大層なことを書きましたが、1番の感想は楽しかったです。
実機でアプリが動かせるようになるだけで嬉しいですし、アプリアイコンが反映されるだけで「おお～」となりました笑

現在は次の個人開発として、supabase + expoアプリを楽しく開発中です。
ここまで読んでいただき、ありがとうございました。
<br>
最後に・・・
太郎くんは居酒屋で9800円支払い、花子さんはスーパーで3500円の買い物をしました。
ふたつの支払いを割り勘にするなら、どっちがどっちに何円払うでしょうか。

時間が掛かった人はぜひ**seppan**を…！笑

https://play.google.com/store/apps/details?id=com.tatta_chotdog.seppan

<br>
それでは、良いお年をお迎えください＼(^o^)／
spreadsheetでよく使っていた関数まとめ

# Google spreadsheetの関数リスト

spreadsheetをよく使う一年だったので振り返ってよく使っていた関数をまとめておきます。
ちょっとずつ更新していきます。

## 一覧
- [importrange](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#importrangespreadsheet_url-range_string)
- [today](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#today)
- [eomonth](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#eomonth%E9%96%8B%E5%A7%8B%E6%97%A5-%E6%9C%88%E6%95%B0)
- [text](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#text%E6%95%B0%E5%80%A4-%E8%A1%A8%E7%A4%BA%E5%BD%A2%E5%BC%8F)
- if
- iferror
- countif, countifs
- sumif, sumifs
- countunique
- vlook
- [query](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#query%E3%83%87%E3%83%BC%E3%82%BF-%E3%82%AF%E3%82%A8%E3%83%AA-%E8%A6%8B%E5%87%BA%E3%81%97)
- [lambda](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#lambda%E5%90%8D%E5%89%8D-%E6%95%B0%E5%BC%8F)
- [arrayformula](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#map%E9%85%8D%E5%88%971-%E9%85%8D%E5%88%972--lambda)
- [map](https://qiita.com/drafts/a7fc4e273153d0a8c475/edit#map%E9%85%8D%E5%88%971-%E9%85%8D%E5%88%972--lambda-1)

## `IMPORTRANGE(spreadsheet_url, range_string)`
URLが`https://docs.google.com/spreadsheets/d/abc/edit#gid=xyz`のスプレッドシートにおいてシート名が`exapmle`のA1からD5までのデータを得るときには下の関数を使う

```
=IMPORTRANGE("https://docs.google.com/spreadsheets/d/abc/edit#gid=xyz","example!A1:D5")
```

## `TODAY()`
今日の日付が得られる

```
=TODAY() //`yyyy/mm/dd`
```

## `EOMONTH(開始日, 月数)`
今月末の日付を得るには下の関数を使う

```
=EOMONTH(today(), 0)
```

## `TEXT(数値, 表示形式)`
指定した表示形式に従って、数値をテキストに変換する。

```
=TEXT(1.23, "$0.00") // $1.23
```
## `QUERY(データ, クエリ, 見出し)`
カスタムしてデータを抽出、出力することができる。
下で出てくる`map`や`arrayformula`の内部で使用したり、`importrange`で撮ってきたデータを好きな順序で表示するのに使っていた。
`データ`シートにおいてB列がB1と一致する行のH, I, N, L列の値を出力する
```
=query('データ'!A:Z, "select H, I, N, L where B='"&B1&"'", 0)
```

## `LAMBDA(名前, 数式)`
カスタム関数を作成する。下の`map`と一緒に使っていた。
salaryに0.3をかける関数を作成し、C5を`salary`に代入している。
```
 =LAMBDA(salary, salary*0.3)(C5)
```

## `ARRAYFORMULA(配列数式)`
ある列に対して同じ処理をなん度もしたいときに使っていた。
下の例では、B列の値が空欄でないときに`countifs`の結果が出力される。
A列の値を見ていって、それぞれの値と会員データのL列の値が一致する回数をそれぞれ求めて、配列として出力する。
```
=ArrayFormula(IF(B2:B="","", countifs('会員データ'!$L$3:$L,$A2:A)))
```

## `MAP(配列1, [配列2, ...], LAMBDA)`
配列をlambda関数の引数として処理を行い、結果を出力する。
`arrayformula`を使えないときに使用していた。

下の例では、A2から順に値を読み込んでlambda内の処理を行って出力することをA13まで繰り返していく。
lambda内でA列から読み込んだ値は`value`として`EXAMPLE`のD2:Dが'value'と等しい時のC列の値の総和を返す。
```
=map(A2:A13, lambda(value,sumifs('EXAMPLE'!$C2:C, 'EXAMPLE'!$D2:D, "="&value)))
```

## 参考
https://support.google.com/docs/table/25273?hl=ja
VPC有効化の時Lambda関数のIPアドレス消費数

Lambda関数のVPC設定を有効化する場合、Hyperplane ENIが必要なので、プライベートIPアドレスが1つ消費されます。

ただし、必要なHyperplane ENIが既に存在する場合、Hyperplane ENIが再利用されるので、プライベートIPアドレスは消費されません。

Lambda関数作成時にVPCを有効化すると、通信に使用されるHyperplane ENIが作成されます。指定されたサブネットのIPアドレス範囲から、Hyperplane ENIにIPアドレスが割り振られるので、IPアドレスが消費されます。

一意のサブネットとセキュリティグループの組み合わせを定義してHyperplane ENIが作成されるので、組み合わせが既に存在する場合は、Lambda関数は既存のHyperplane ENIを再利用します。

Lambda関数実行時は、Hyperplane ENIを介して通信が実施されます。

Hyperplane ENIの制限としては、1つHyperplane ENIで最大65000接続を行うことが可能です。そのため、例えば110000個VPC有効化Lambda関数を作成する場合、利用されるHyperplane ENIは２つとなるので、消費されるIPアドレスは２つです。

参考：https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/foundation-networking.html
MySQLのSQLをOracleで書く(Format,Date_Format)

# 移植するSQL

~~~
SELECT 
  FORMAT(item_fee, 0) AS item_fee      
, item_cd       
, item_nm AS item_nm       
, SUM(item_stock) AS stock       
, DATE_FORMAT(MIN(arrival_ymd), '%Y/%m/%d') AS arrival_ymd 
FROM item
GROUP BY item_fee, item_cd 
~~~
MySQLで使用されていたSQL。これをOracleでそのまま利用すると次のエラーが発生した。

# エラー１
~~~
ORA-00904: "FORMAT"
ORA-00904: "DATE_FORMAT"
~~~
エラーの原因はMySQLでは使用できるFORMAT関数およびDATE_FORMATだが**Oracleには存在しない**ことが原因。
よって**TO_CHARに書き換える**ことで対応。
FORMAT(item_fee, 0)は数値型を小数点0桁目（つまり整数）で丸めて文字列にする。よって引数を省略しデフォルト引数で対応した。
また、TO_DATE引数について **%YなどはOracleでは使えない**ため"YYYY/MM/DD"表記に変更。
TO_CHARについては下記リンクを参考にした。
https://segakuin.com/oracle/function/to_char.html
~~~
SELECT 
  TO_CHAR(item_fee) AS item_fee      
, item_cd      
, item_nm AS item_nm       
, SUM(item_stock) AS stock        
, TO_CHAR(MIN(arrival_ymd), 'YYYY/MM/DD') AS arrival_ymd 
FROM item
GROUP BY item_fee, item_cd 
~~~

# エラー２
上記のSQLを実行すると
~~~
ORA-00979: GROUP BYの式ではありません。
~~~
のエラーが発生した。SELECT句とGROUP BY 句を確認すると…
~~~
SELECT 
  TO_CHAR(item_fee) AS item_fee      
, item_cd      
, item_nm AS item_nm       
, SUM(item_stock) AS stock        
, TO_CHAR(MIN(arrival_ymd), 'YYYY/MM/DD') AS arrival_ymd 
~~~
~~~
GROUP BY item_fee, item_cd 
~~~
SELECTで取得している未集計のカラムとGROUP BY句のカラムがあっていない。item_nmがGROUP BY句に必要なはずである。
どうやらMySQLでは**GROUP BYのカラムとSELECTのカラムが違ってもエラーにならない**らしい。（何故…？？）
https://qiita.com/kazu56/items/c27428ddde49be42f23b
よってGROUP BY句を修正して実行した。
~~~
SELECT 
  TO_CHAR(item_fee) AS item_fee      
, item_cd      
, item_nm AS item_nm       
, SUM(item_stock) AS stock        
, TO_CHAR(MIN(arrival_ymd), 'YYYY/MM/DD') AS arrival_ymd 
FROM item
GROUP BY item_fee, item_cd, item_nm 
~~~
# エラー３
上記のSQLを実行すると
~~~ 
ORA-01481: 数値書式モデルが無効です
~~~
のエラーが発生した。
原因はarrival_ymdの取得の部分であった。MINで取得された文字列をもう一度TO_CHARで文字列に変換しようとしていたため引数にエラーが出ていたよう。一度取得した文字列を日付型に変換してからTO_CHARでフォーマットを指定しつつ文字列に変換する。
~~~
SELECT 
  TO_CHAR(item_fee) AS item_fee      
, item_cd      
, item_nm AS item_nm       
, SUM(item_stock) AS stock        
, TO_CHAR(TO_DATE(MIN(fio.pick_ymd)), 'YYYY/MM/DD') AS pick_ymd 
FROM item
GROUP BY item_fee, item_cd, item_nm 
~~~
これを実行すると…

ついにデータが取得できた！

# まとめ
今回行ったこととしては、
①FORMAT関数およびDATE_FORMATをTO_CHARに書き換え
②SELECT句とGROUP BY 句の確認
③MINとTO_CHARの使用方法
であった。
おそらくはじめてのMySQLからOracleへのSQL移植だったがつまずくポイントがいくつかあった。
OracleとMySQLでは使える文法や引数が違うものはよくあるようなので気を付けていきたい。
VBAで、別ファイルより転記

【自分用のメモ】

以下を□□にして使用。※□□に任意の名前を入れる。
・転記元のブック名、
・転記元ブックにある、転記先のシート名
・転記先ブックにある、転記先のシート名


＊ここから、コピペして使用

↓　　↓　　↓

Sub book□□より転記()
  Workbooks.Open Filename:=ThisWorkbook.Path & "\□□.xls"
  Dim Wb1, Wb2
  Set Wb1 = ThisWorkbook 'このブック
  Set Wb2 = Workbooks("□□.xls") '別ブック
  
  Dim 条件 As Boolean
  条件 = True

    Dim i As Integer
    i = 11 '先頭行数を指定
    
      Do While 条件
        Wb1.Worksheets("□□").Cells(i, 3).Value = Wb2.Worksheets("□□").Cells(i, 6).Value
        Wb1.Worksheets("□□").Cells(i, 4).Value = Wb2.Worksheets("□□").Cells(i, 7).Value
        Wb1.Worksheets("□□").Cells(i, 5).Value = Wb2.Worksheets("□□").Cells(i, 8).Value
        i = i + 1
    
        If Wb2.Worksheets("□□").Cells(i, 2).Value = "計" Then
                条件 = False
        End If
        
      Loop
  
  Workbooks("□□.xls").Close
  
  
  End Sub
[laravel]メール送信元を自分のgmailにする

## メール送信機能には、メールサーバーが必要...
ローカル環境では[mailtrip](https://mailtrap.io)が活躍してくれていたのですが、
laravelでメール送信するには、メール送信元の情報が必要。
そこで自身の持つメールアカウントを流用できないか、と見つけたのがこのサイト。

https://qiita.com/koru1893/items/e30d19ac97eac59b1e19

## step1. gmailを送信元として利用できるようにする
初期状態のgmailアカウントでは、送信元として利用できません。
設定の変更は簡単なので、サクッとやっちゃいましょう！

#### 1. [googleアカウント管理]ボタンをクリック
gmailへログイン後、自身のアイコンを押下し、

![2023-12-14 17.03の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820657/fe14e446-e2c5-05a1-1aa0-8851834c80fe.jpeg)

出現したポップアップ画面の[googleアカウント管理]ボタンをクリックする。

![2023-12-14 17.06の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820657/3f047d5b-5135-4b67-b866-80b49a48b992.jpeg)

### 2. 2段階認証を有効にする
「セキュリティ」の「2段階認証プロセス」を押下し有効にする。
有効にすると、電話番号の入力を求められ
2段階認証の方法を「ショートメッセージ」or「通話」から選択できる。

■ショートメッセージの場合
「xxxxxがあなたのGoogle確認コードです」とメッセージが来る。
■通話の場合
アメリカ合衆国から電話がくる。出ると確認コードを電話口で伝えられる。

![2023-12-14 17.13の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820657/c88b49a2-7a1c-5cd2-43e9-83e1cac955e2.jpeg)

### 3. アプリパスワードを設定する
検索欄で「アプリパスワード」と入力。

![2023-12-14 17.24の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820657/83118f5b-6be1-4307-f1ed-320886022395.jpeg)

「App name」に自由にアプリパスワード名を入れてください。
その後、google側からパスワードが表示されるので、一時的にメモを取っておきましょう。
(※ .envへ記載後はセキュリティ確保のためメモから消してください。)

![2023-12-14 17.26の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820657/0440a515-1d8b-378e-be9b-b1d774827904.jpeg)

これでgmail側の設定は完了です。お疲れ様でした！


## メール送信元の情報を記載する
.envファイルに設定値をそれぞれ記入していきます。
```
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=<gmailアドレス>
MAIL_PASSWORD=<先ほど作成したアプリパスワード>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="<gmailアドレス>"
MAIL_FROM_NAME="<送信先に表示する送信元名>"
```

お疲れ様でした！
これでデプロイしたアプリのメール機能が利用できるようになったと思います。
ソフトウェアエンジニアがSLOをどう運用していくか

本記事はUzabase Advent Calendar 2023の15日目の記事です。

### はじめに

株式会社ユーザベースSREの[杉山](https://qiita.com/TomoyukiSugiyama)とSWE（ソフトウェアエンジニア）の山本です。
私たちはSLOの運用をSREとSWEで組織的に取り組んでいます。

### 要旨

開発チームは日々の開発とSLOの運用を並行して遂行しています。ただ、SLOの運用に割く時間が増えてきて開発に影響が出てきました。対応策としては、ユーザーの信頼性を維持しつつ現状のCUJを絞りSLOの目標値を下げました。これによって開発チームも納得感を持ち取り組めるようになりました。
本稿では組織的に取り組む上で生じた課題などご紹介します。

## 背景

### 事業内容と開発体制
[FORCAS](https://www.forcas.com/)とは、B2B事業向け顧客戦略プラットフォームを提供しているSaaSプロダクトです。具体的には、顧客企業が保有するリードリストとFORCASが所有する企業データベースを名寄せすることでデータをエンリッチにし、ターゲットリストを作成することでABM（アカウントベースドマーケティング）を実行することができるプロダクトです。

またFORCASの開発チームは3チーム計SWE12名で、組織全体ではアジャイル（XP）に開発しています。
開発チームの中からSLOの対応を一部リードする存在として3名のSWEがSLOチームとして稼働しています。

###  なぜSLOを運用しているのか
2点挙げると、1点目は信頼性が低いサービスはチャーン（解約）に繋がる可能性があるからです。具体例として、顧客はリードリストをFORCASにアップロードすることで名寄せを行い、リストをエンリッチにすることができます。このエンリッチを価値だと感じている顧客からすると、もしこの名寄せ処理のエラーが多発しリストのエンリッチができなかった場合、ユーザーはFORCASというサービスに対して信頼性を持てなくなり解約に繋がるでしょう。それを防ぐためにSLOでエラーを監視・対応しサービスの信頼性を保ちます。
2点目はユーザー体験の悪化に繋がるであろう遅いレスポンスを観測するためです。

このようにFORCASでは「Error」と「Latency」の2点のメトリクスと18個のCUJ、96個のSLOを監視しています。


### 取り組み内容
週3回SLOチームでMTGを開き、SLO運用の課題出しや対応案出し・施策立案などを行っています。そのSLOチームで生まれた議題をSWE全体の週次で共有します。また、その週に発生したアラートの共有も行い、原因調査や対応アクションのタスクを各チームに割り振って対応しています。
それ以外にもPdMとコミュニケーションをとりながら現状SLOの課題点の共有や、四半期ごとにCUJ、SLOの見直しをしています。またPdMだけではなく事業部のビジネスサイドにもSLOの重要度の共有や啓蒙・社内アンケートの実施を行いました。

## 課題
こうしたSLOの運用は次第にコストが高まり、開発時間に影響があることが発散的に開発チームから上がってくるようになりました。声を受けてSLOチームとSREでディスカッションをしていくと現時点で定めているSLO全てを監視・対応することには現時点では無理があるのでは？と収束してきました。

## 解決策＆評価

###### 注力するCUJを絞り、部分的に目標値を下げました。
取り組み内容で記載したようにCUJを18個設定していましたが、2個だけに注力して対応していくことにしました。
これは開発チームと話し合い、現状の開発リソースでは全てを対応し切ることが厳しいという判断のもと、直近数ヶ月で特にアラートが発生しているCUJにだけ絞り、まずはこのCUJ2個とSLO20個をアラートが発生しない状況に持っていくことに注力することにしまし。
例えば「Error：ユーザーはxx画面をでxxをすることができる」というCUJがあったとします。この目標値を今までは99.9%にしていたのですが、本当にユーザーが望む品質はこの閾値の高さでいいのか？もっと下げる余地はあるのではないか？といったことをユースケースなど含めPdMと議論を重ねながら、ユーザーの理想よりも目標値が高いだろうと推測できるものに関しては機能開発を優先するためにいくつかの目標値を下げるという意思決定を行いました。下げた目標値や絞ったCUJに関してはステイというわけではなく、開発の優先度と検討し上げる余地も残しておきつつ、引き続きSLOを運用していきます。
[CDGC] 2023.11 ④関係者の設定アップデート

# はじめに

<!-- ★『インフォマティカが提供する、 CDGC(データガバナンスとデータカタログ)を使って』までは定型文 -->
[インフォマティカ](https://www.informatica.com/jp/)が提供する、 [CDGC](https://www.informatica.com/jp/products/data-governance/cloud-data-governance-and-catalog.html)(データガバナンス＆カタログ)において、2023年11月にリリースされたバージョンの内容について記載します。
※2023/12時点の情報を元にしています。

# 「関係者」とは？
英語名でステークホルダー、日本語名で関係者となりますが、ガバナンス＆データカタログ上でのテクニカルアセット(テーブル、カラム等)・ビジネスアセット(ポリシー、プロセス等)に対する責任を持った人物を、「関係者」として設定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/baeb2251-98a7-cea1-50e5-1dbf515341a9.png)

# 2023.11でのアップデート
### 1\. 親から子アセットに、継承割当てが可能となりました。
例えばテーブルとその配下の複数のカラムがある場合に、テーブルに関係者を追加すると、その配下の複数カラム全てに、関係者名が継承されます

関係者を追加する際に、下記のようなダイアログが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/1aa33920-965f-312e-6935-b70ee031d7a1.png)
下記のように、継承されて割り当てられたことが明記されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/31fe8427-c2d8-b898-8443-05d323a9a1f8.png)
<BR>
### 2\. ユーザーグループの関係者名の表示が可能となりました。
関係者としてユーザーグループが割り当てられている場合、そのユーザーグループ内のすべての関係者を表示できます。
なお、一度に表示できるユーザ グループのユーザ数は最大 50 です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/e2ef8ef0-feb5-4d2a-a4bc-5d426ea385d5.png)


# 参考文献
<!-- ★URLをそれぞれのカタログ・ソースに応じて変更する -->
- [**Creating assets and assigning stakeholders - マニュアル**](https://docs.informatica.com/data-governance-and-quality-cloud/data-governance-and-catalog/current-version/working-with-assets/manage-assets-and-add-metadata/creating-assets-and-assigning-stakeholders.html)

- [**What's New - マニュアル** *ログインが必要](https://docs.informatica.com/data-governance-and-quality-cloud/data-governance-and-catalog/current-version/what-s-new/november-2023/new-features-and-enhancements.html)
ハッカソンに初参加しました！

## はじめに
こんにちは。あずびわです。
普段はAtCoderをのんびり楽しんでいます。

先日ハッカソンに初参加してきたので、その記録です。

## 参加まで
私大文系かつ大分なので、ゼミに参加するまで周りにプログラミングを学んでいる人はいませんでした。
ゼミに入ってからは、統計系で先生がプログラミングをやっていたこともあり、夏にゼミ生でインターンに参加する機会もありました。そこで仲良くなったゼミ生と2人でハッカソンに参加することになりました。

参加時点で、私はAtCoder茶色、GitHubの基本的な使い方がわかる程度、相方はPythonで統計やAIを少し齧った程度でした。夏のインターンで2人とも多少はGitHubやweb系の技術に触れたものの、どちらも初心者でした。

ですが、無事に2つとも制作物を発表することができました！！

## 参加したハッカソン
[JPHacks](https://jphacks.com/)と[技育CAMPのマンスリーハッカソン](https://talent.supporterz.jp/geekcamp/)にオンライン参加しました！
ハッカソン初参加ながら、2週連続ハッカソン参加することになったため、スケジュールが大変でした。

残念ながらどちらも賞は受賞できなかったのですが、良い経験になりました。

## JPHacksでは
図書館の十進分類法を元に、ランダムでおすすめの本を表示するwebサイトを作りました。

制作する上で、ReactやTypeScriptを選んだのは良いものの、TypeScriptの型の書き方など全くわからず、曖昧なまま終わってしまいました。
また、国立国会図書館のAPIを利用し(ようとし)たのですが、json以外の形式の扱い方がわからず、機能を実装しきれませんでした。

その結果、数字をランダムで表示するだけのホームページが出来上がりました。無事に発表は行えたのですが、完成はしなかったので少し消化不良気味でした。

## 技育CAMPのマンスリーハッカソンでは
ChatGPTのAPIを使いたい、という話になったので、LINE Botを用いたチャットボットを作成しました。

冷蔵庫内の食べ物をデータベースで管理し、その食べ物を元にChatGPTにレシピを聞く機能を実装しました。この世には存在しない食事のレシピを返されるのですが、機能としては無事に実装できました。

https://x.com/geek_pjt/status/1721081579085434907?s=20

JPHacksでの反省を活かして、実装したい機能を段階的に分けて、早い段階でもある程度見映えのするものを発表できるようにしました。

LINE Botはデザインをあまり考える必要がないので、デザイナーがいない自分たちのチームとは相性が良かったです。

## 感想
私自身は、周囲とのレベル差を強く感じました。作りたい機能を十分に実装できない中で、初心者2人だけで参加するのは大変でした。作業時間が限られていることもあり、人数が多かったり、強い人材がいたりといった人的要素は思っている以上に大事だなと感じました。

相方は週末に一気に開発するスタイルと相性が良いようで、すっかりハッカソンにハマっている見たいです。

その後はまだハッカソンには参加していないのですが、技術力を身につけて、対面でハッカソン参加してみたいです。
「現代数理統計学の基礎」演習問題解法メモ　第3章問1～3

第3章に入ります。問3は、超幾何分布の期待値と分散を求める問題です。
いろいろな解法があるようです。その後「統計学の数理」の問題2-3が同問でした。
しかし、「統計学の数理」の解答の解き方もすっきりせず。
今回、アップした解法が自分的にはすっきりしています。
一応参考までに集めた様々な解法も添付しておきます。
そういうわけで、今回は問3のボリュームが多くなりました。
![第3章問1　P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/d48ee7bf-fada-0f07-85ce-34c7214e7a92.jpeg)
![第3章問1　P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/640a3377-1962-81e7-7f59-a0fd96f7fd79.jpeg)
![第3章問2　P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/7334b9a9-1b90-c66a-4c93-8843df1d9340.jpeg)
![第3章問2　P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8395e6b3-0390-b214-47cf-ad3caa623cd9.jpeg)
![第3章問2　P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/0815d04b-0683-5ad4-7aa0-ab16fbf0d5a3.jpeg)
![第3章問3(統計学の整理編) P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/8aa6e9d1-40f7-4bfd-b65b-a3394640aa62.jpeg)
![第3章問3(統計学の整理編)　P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/79e58f65-39b5-aec2-6b65-ad32180d61f7.jpeg)
![第3章問3 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/87a6ed60-bf9f-fd80-502b-e90a81796366.jpeg)
![第3章問3　P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/a398557e-2cbc-2533-f850-0197dd071de8.jpeg)
![第3章問3　P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/c6236100-2c69-0b9c-b15d-3a0c39cb49c4.jpeg)
![第3章問3　P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/cc78ea31-b75a-7156-2481-44e091583d4d.jpeg)
ベイビーステップで学ぶマップリストの値の操作⑤ -String.contains?の紹介

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はマップリストの要素を検索する方法を学びましたのでまとめます。

# 目次
1.[Ectoスキーマからパターンマッチを使用してパラメータを取り出す](https://qiita.com/Alicesky2127/items/480816252525e9ae45ed)
2.[Ectoスキーマからパラメータを取り出して更新する(iex内のみ)](https://qiita.com/Alicesky2127/items/13a3edbf441256054a3b)
3.[Enum.mapの紹介](https://qiita.com/Alicesky2127/items/34c751267a254522bae6)
4.[Enum.filterの紹介](https://qiita.com/Alicesky2127/items/a9069ee013c3b1603920)
5.String.contains?の紹介(本記事)
6.[Enum.intoの紹介](https://qiita.com/Alicesky2127/items/b399d2a6dde4f4129ece)
7.[Map.putの紹介](https://qiita.com/Alicesky2127/items/4700d913c6df3b81a1a5)
8.[(番外編)元データがマップ→リスト→マップのもう一段深い入れ子構造だったらどうするか？(Map.getの紹介)](https://qiita.com/Alicesky2127/items/23c8d9ed8d47c22fd6aa)



# 目的
リストの要素がマップ(あるいはその逆)になっている場合に値を取り出して操作できるようになりたい。

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.14.3
Erlang v26.0.2
Phoenix v1.7.10

# 今回やりたいこと
前回、Enum.filterで要素を一つずつ取り出して条件に合ったものだけ取り出す方法を学んだので、検索条件に文字列検索を入れてみたい。
```diff_elixir:iex
results = [{1, "hogehoge"}, {4, "fugafuga"}, {5, "piyopiyo"}]
Enum.filter(results, fn {id, _name} -> id == 5 end) 
[{5, "piyopiyo"}]
```

# String.contains?とは
第一引数の中に第二引数の文字列を含むかをチェックする。

https://hexdocs.pm/elixir/1.12/String.html#contains?/2

これをEnum.filterの検索条件に入れこみます。
```diff_elixir:iex
Enum.filter(results, fn {_id, name} -> String.contains?(name, "piyopiyo") end)
[{5, "piyopiyo"}]
```
```diff_elixir:iex
Enum.filter(results, fn {_id, name} -> String.contains?(name, "iy") end)
[{5, "piyopiyo"}]
```
部分一致で検索していますね。


## (余談)完全一致検索の場合
`==`を使うと完全一致検索になります。
```diff_elixir:iex
Enum.filter(results, fn {_id, name} -> name == "piyopiyo" end)
[{5, "piyopiyo"}]
```
```diff_elixir:iex
Enum.filter(results, fn {_id, name} -> name == "iy" end)    
[]
```


## (途中経過)元データからここまでをパイプでつなげる
```diff_elixir:iex
users
|> Enum.map(&{&1.id, &1.name})
|> Enum.filter(fn {_id, name} -> String.contains?(name, "piyopiyo") end)
[{5, "piyopiyo"}]
```


# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
文系大人初心者プログラミングするよ🔰【HTML】

いよいよコードを書いていきます！
まずはHTMLとCSSの学習からスタート。名前くらいは聞いたことある！
昔、自分でHPを作れるクラスメイトいましたよね:writing_hand:？？
これは大体のスクールでも、最初に習うんじゃないでしょうか？？

★HTML（HyperText Markup Language）
  ：webサイトに表示される情報を記載する言語

★CSS（Cascading Style Sheets）
  ：HTMLに装飾を加える言語


VScordで拡張子.htmlファイルを作成・記述したら
ファイルをドラッグしてブラウザのタグに持っていくと
webページが出来てるのがすぐ見れちゃいます！
これびっくりした、、:open_mouth:！

```html:.html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">　　※文字コード指定
    <title>ブラウザタグのタイトル</title>
  </head>
  <body>
    <h1>
      見出し
    </h1>
    <p>
      1つ目の段落
    </p>
    <p>
      2つ目の段落<b>この部分は太字</b>
    </p>
    <!-- これはコメントアウトされる -->
    <a href="https://www.google.com/">クリックするとGoogleへ移動</a>
  </body>
</html>
```

いっぱいあるので基本を抜粋
HTML：
・開始タグ< >と終了タグ</ >に囲まれたものがHTMLにおける要素
・要素に情報を付け加える属性と属性値がある
 ex. <meta charset="UTF-8">
     meta=要素　charset=属性　UTF=8=属性値
・head要素とbody要素がある
・DOCTYPE要素：ドキュメントタイプの略　文章がHTML文章であることを宣言する
・html要素：HTML文章の始まりと終わりを示す
・metaメタ要素：HTML文章に関する情報を指定（charset=はmeta要素の属性）
・br要素：Line Breakの略　テキストを改行する　終了タグ不要
・b要素：Boldの略　文字でを太くする　<b>...</b>で囲まれている部分だけ太字
・a要素：Anchorの略で<a>...</a>で囲ったテキストをリンクにする
　href属性：Hyper Referenceの略　リンクの移動先を指定

 ◎VSCodeのコード差分
見本のコードコピー→自分のコードがあるファイルを開く→でコマンドパレットを開く
→compare（比較）と入力→Compare Active File With Clipboardを選択


 
HTMLだけでもめっちゃあるから
いいなと思ったものはコピペして保存しとくか、
その道を極めてるサイトから随時コピペが良さそう:writing_hand:
文系大人初心者プログラミングするよ🔰【環境構築】

補足ですが、PC外の環境構築？について:muscle:
プログラミングスクールに投資したので、学習装備はほんとに最低限でした。

PCはメモリもディスプレイサイズも
『これくらいは最低いります』と言われたギリギリ。windowsだし。

自宅のデスクやイスもふつうのもので、長時間座るタイプではない。
そもそも自宅で学習する意欲はあんまり湧かなく、ゆっくりする場所でありたい、、
あとは「カフェで勉強しているやつ」をやってみたかったのもあって笑

そんなところから、早速windowsPCでの環境構築が始まりました


【WindowsPCをMacぽくさせる】
①PowerShellを使用しWSL（Windows Subsystem for Linux）有効化
　　→Ubuntuインストール
  ※PowerShell：windowsへ命令　Ubuntu：Macへ命令

【アプリケーション開発に必要なツール】
①ツールを導入する準備
②Homebrewインストール＆設定 
  ※Homebrew:macOS上で動作するパッケージ管理ツール
③Rubyインストール＆設定
　rbenvインストール
  ※rbenv：Rubyのバージョンを管理するためのツール
　Ruby、Ruby on railsインストール＆設定
　bundlerインストール＆設定
④データベース(MySQL)インストール＆設定

①ツールを導入する準備
```ruby:ターミナル
sudo apt update && sudo apt upgrade
sudo apt install -y autoconf bison patch build-essential rustc libssl-dev libyaml-dev libreadline-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev make
```
②Homebrewインストール
```ruby:ターミナル
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
Homebrew設定
```ruby:ターミナル
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
brew install gcc ruby-build
```

③Rubyインストール＆設定
rbenvインストール
```ruby:ターミナル
brew install rbenv
```
renv設定
```ruby:ターミナル
echo 'eval "$(rbenv init -)"' >> ~/.profile
eval "$(rbenv init -)"
```
RubyとRuby on railsインストール＆設定
※割愛


【テキストエディタ:VSCode】
　※追加拡張機能
　　Japanese Language Pack for Visual Studio Code（日本語表記）
　　Ruby LSP（Rubyコードのエラーチェックや自動補完など）
　　zenkaku（全角スペースを知らせる）
　　Code Spell Checker（コードのスペルチェック）
　※設定カスタマイズ
 　 半角スペースの設定（tabキーでのスペースを半角2つ分に）
    オートセーブ設定
.pyファイルをダブルクリックで実行したい for Mac

150枚くらいまでの画像を

リサイズ
↓
pngとwebpで保存
↓
種類ごとにリネームして移動

みたいなことをPythonで一気にでやってます。

そのPythonファイル（.py）を実行する時に、いちいちコンソールを立ち上げて
`python 〇〇.py`をするのもめんどくさいので
ダブルクリックで実行できるか方法を探ってみました。

## できた
1. Pythonのパスと、実行する.pyがあるディレクトリパスを取得

```
which python
> (Pythonのパス)
```

.pyのディレクトリパスは
`右クリック > Optionを押しながら > "(ファイル名)"のパス名をコピー`
したものから.pyのファイル名をカットする。

1. .commandファイルを作成

```exec_py.command
cd （.pyのディレクトリパス）
(Pythonのパス) 〇〇.py
```
こんな感じでいけました。

いきなり.pyを実行せずにcdするのは、
それだと.py内でパスのディレクトリが取得できなかったからです。

## できるまでの経緯
Pyinstallerで.app化しようとしたが、`pyinstaller`した.appがどうしても起動しなかった。
あとtkinterの表示バグ？みたいなのもあってめんどくさかった。
tkinterはなんとか作動できたけど、そもそも実行だけできればいいことに気づいた。


## できるようになった参考サイト
### Mac：Pythonファイルのダブルクリック実行方法【簡単確実】
https://yuki.world/execute-python-by-double-click/
ほぼこの記事通りにやりました。
### Macでpythonのtkinterを利用すると真っ黒な画面が表示される問題を解決する方法
https://log.dot-co.co.jp/tkinter-mac/
おかげで無事にtkinterも再インストールして使えるようになりました。

ありがとうございました。
【Azure Web Apps】動画をあげても表示されなかったときの解消法

# はじめに
Angularで作成したWebアプリをAzure Web Appsにあげた際に、動画だけ404エラーがでて表示できない現象が起きたので、その解決方法をメモ( ..)φ

# 発生したエラー

`GET https://hogehoge/(省略)/movie.mp4 404(Not Found)`

でも動画はちゃんとassetsのなかにいる…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/03dee7d7-2e3a-6c50-31f8-7718372a1a72.png)


# 解決方法
Azure Web Appsでビデオファイルを操作できるように、 web.configにMINEタイプを追加する必要があったらしいです。
逆に言うと、画像とかはデフォルトで見れるようになっている。

web.configを追加して、以下の内容をかきました。
見たいファイルはmp4だから、本当はmimeType="video/mp4"だけでいいと思われる。

```xml:web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".mp4" mimeType="video/mp4"/>
      <mimeMap fileExtension=".ogv" mimeType="video/ogg"/>
      <mimeMap fileExtension=".webm" mimeType="video/webm"/>
    </staticContent>
  </system.webServer>
</configuration>
```

無事に404エラーは解消されて動画が再生できるようになりました。

# おわりに
angular.jsonにweb.configのパスをかき忘れる凡ミスをして、一瞬？？？となったので気を付けよう！

# 参考
- [Unable to access Video file from Azure web app(stack overfolw)](https://stackoverflow.com/questions/74017820/unable-to-access-video-file-from-azure-web-app)
- [Windows Azure WebSite 上に置いた動画ファイルを再生させる](https://daiyuhatakeyama.wordpress.com/2013/02/20/windows-azure-website-%E4%B8%8A%E3%81%AB%E7%BD%AE%E3%81%84%E3%81%9F%E5%8B%95%E7%94%BB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%86%8D%E7%94%9F%E3%81%95%E3%81%9B%E3%82%8B/)
AI-102試験対策のまとめ「チャットボットのデバッグ」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### チャットボットのデバッグ
* ボッドの開発中
    - 下記を使用してボットとローカルでチャットし、ボットが送受信するメッセージを調査可能
        - IDE
        - Bot Framework Emulator
* ボットが運用環境にある場合
    - ngrokを使用して任意のチャネルからボットをデバッグ可能

#### **Bot Framework Emulator**
* ボット開発者がボットをローカルやリモートでテスト/デバッグできるようにするデスクトップアプリケーション
* ボットとのチャットや送受信するメッセージの検査が可能

#### **ngrok**
* トンネリング/転送URLを作成できるクロスプラットフォームアプリケーション
* インターネット要求がローカルコンピューターに到達できるようになる
* 使用方法
    1. ngrokを実行して新しいトンネルを作成し、パブリック転送URLをコピー
    1. Azure Portal上のメッセージエンドポイントを転送URLに変更
    1. 外部チャネルからボットへの受信メッセージがローカルボットに送信

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/bot-service/bot-service-debug-emulator?view=azure-bot-service-4.0&tabs=csharp
    - https://learn.microsoft.com/ja-jp/azure/bot-service/bot-service-debug-channel-ngrok?view=azure-bot-service-4.0

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「会話言語理解におけるNone intent(None意図)」**

https://qiita.com/fsd-jume/items/ecc3c216cb5e8837eed2

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
新卒エンジニアになってバリューを発揮するために必要だと感じたこと

株式会社MIXIのTIPSTARサーバーチームの若松（X：@Jaksho500）です。

本記事はMIXI DEVELOPERS Advent Calendar 2023 シリーズ1 の13日目の記事になります。
（1日遅刻しました。ごめんなさい）
https://qiita.com/advent-calendar/2023/mixi

## 概要
今年就職し、会社に属するようになりました。これにより、学生の頃とは異なり、特定の組織に長時間コミットメントするようになりました。その結果、必要性を感じたスキルがいくつかあります。今回は、それらのスキルについて紹介します。

年度末に目にすることが多い「新卒エンジニアの振り返り」「成長する秘訣は？」といったニュアンスの内容です。

## モチベーション
先日、チームメンバーと「技術力とは何か」「エンジニアとしてどのように価値を提供するか」といったテーマについて話す機会がありました。

自分の考えを話しているうちに、学生時代の認識と比較して、意見が変わっていることに気づきました。それが面白く感じられたので、この体験を記事にまとめてみることにしました。

#### バリューとは
ここでは、エンジニアとしての成果を「バリュー」と表現します。
エンジニアの成果は、単に開発活動からだけではなく、様々な側面（例えば、開発した機能、後輩の育成、組織課題の解決、チームへの影響など）から生まれると考えています。

そのため、「バリュー」という表現が最も適切だと思いました。

## バリューを発揮するために必要だと思う要素
学生時代、エンジニアとしてバリューを発揮するには、主にハードスキル（技術力とも言えます。技術力は技術的な知識や経験を指します）が重要だと考えていました。
> ハードスキル* その他要因＝バリュー

しかし、現在では、技術力だけでは十分であると感じています。技術力をパフォーマンスに変換するためには、ソフトスキルも同じくらい重要だと考えています。
> ハードスキル* ソフトスキル* その他要因＝バリュー

※その他要因には、事業やチームの状況、担当したタスクなどさまざま要因が含まれます。

### 変化
自分の中で、ソフトスキルの重要性が大きく増してきました。

この変化の主な理由は、ハードスキルの重要性は以前から理解しており、常に向上を意識していたのに対し、ソフトスキルの重要性には気づいていましたが、それを向上させる必要性にはあまり意識を向けていなかったからです。

## ソフトスキルについて
ソフトスキルと聞くと抽象的に感じますが、具体的には以下の点に重要性を感じ意識するようになりました
1. 思考の言語化
1. 思考を伝える努力
1. アクションへの移行

### 思考の言語化
この必要性を感じたのは、複雑な機能の設計をチームメンバーに相談する際でした。以下の問題に直面しました
- 自分が何を聞きたいのか明確に説明できない
- 複雑なコードの部分を正確に言語化できない。

といった課題を感じました。
ある程度の基本的な状況説明はできると思います。

+で、以下のような点を言語化できれば、効率的に適切な人に相談できると思います。
- 本当に聞きたいこと
- 自分が何に困っているのか
- その他の要点
- etc...


自分の考えが不明瞭に感じる時は、些細なことまでNotionに書き出しています。

この習慣を始めてから、自分が相談しそうとしていた内容は１つに見えていたが、実は２つだった。しかも１つはエンジニアではなくビジネスサイドの方に確認すべきものだった。
みたいなことがありました。

自分自身の考えを明確に把握できていない場面はあると思います。その状態で他の人に相談しても、自分の考えを支えられるはずもなく、課題の解決は難しいでしょう。

思考を言語化することで、新たな視点や効率的な問題解決につながると感じています。

### 思考を伝える努力
内定者アルバイト時代、複雑な機能の設計・実装を担当しました。

この機能はユーザーへの影響は小さかったものの、仕様やロジックは複雑でした。私は可能な限りの懸念点やシーケンス図をIssueに書き起こしましたが、文量は膨大になりました。設計完了後のチームレビューは困難を極め、当時は辛かったです（苦笑）。

以来、「レビューしやすいアウトプット（設計・PR）とは？」という視点で自分のアウトプットを出すように心がけ始めました。

そのためのアプローチとして、他のチームメンバーのアウトプットを確認し、個人的にわかりやすいなと思うものはバイブルとしてまとめており、参考にしています。

過去のものがおすすめで、「この機能の開発は大変だった」みたいな話をメンバーから聞くことがあると思います。そういった機能の設計・PRを見るとだいたい大きなIssueになっているので、進め方、見やすさなどの違いが顕著に現れていました。

プロジェクトごとにIssue、PRのテンプレートは用意されているものの、それに添えばOKというわけではなくタスクごとに最適な形を模索していくことを今後も意識していきたいと思います。

余談
コミュニケーションをとる相手が同じエンジニアか、QAか、デザイナーかによって、どのラインから説明すべき内容が変わってきます。相手のコンテキストを理解した上でコミュニケーションをとる。ということも「思考を伝える努力」では意図しています。

### アクションへの移行
ここまで述べた２点は、他の人に相談する前の準備ですが、逆に「すぐにアクションに移せ」というものです。
「15分ルール」はこの文脈でよく耳にすると思います。

一方で、「15分ルール」にも難しさがあり、
- 考えが浅い状態で相談
- 時間的指標なので忘れてしまう

などが個人的にあります。

他にも心理的ハードルとして、以下のような心配事がありそうです。（どちらも以前の僕に当てあはります）
- こんな質問をしてもいいのかな？
- この程度のこともわからないのかって思われたりしないかな？

心配事を乗り越えアクションに移すための自分への言い訳として
1. 思考の言語化
1. 思考を伝える努力

が使えます。

「自分はこれだけ考えたんだ」「ここまで頭を働かせたんだ」という自分への言い訳になります。しかも、言語化が進んでいるので、相談内容を明確にし、タイミングを適切に定めることができます。

これによって、相談を円滑に行える　+ 自分の考えを言語化できる + 相談のタイミングを明確に定義できる といったメリットを感じています。

## まとめ
社会人になり、特定の組織に長期間コミットするようになって、必要性を感じたスキルについて紹介しました。

「すごいエンジニア＝技術力めっちゃ高い」
ではない(なれない)ということを感じています。

「エンジニアとしての能力＝周りの人が自分のエンジニアとしての能力に対して置いている信頼」
とも見れると思っており、その信頼を向上させるためにはもちろん技術力も大切ですが、それだけでは不十分でソフトスキルにも意識を置いていこうという内容です。

ソフトスキルにも意識を向け始めて半年ほどですが、さらなる課題も見えてきています。
また機会があれば、そこに向けたアプローチも記事にしようと思います。

ありがとうございました。