OmniAICreator/Qiita-1.07M huggingface dataset:
Unity シングルトン メモ

# Unity MonoBehavior シングルトン

```c#:UnitySingleton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnitySingleton<T> : MonoBehaviour
    where T : Component
{
    private static T instance;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType(typeof(T)) as T;
                if (instance == null)
                {
                    GameObject obj = new GameObject();
                    instance = obj.AddComponent<T>();
                }
            }
            return instance;
        }
    }
}

```

MonoBehaviour継承していますので簡単に利用できます。
Unity の SoundManager 作ってみた

# 機能

- サウンド再生機能一箇所に集約して、簡単に利用できる
- エディタ内で簡単SEを入れることができる
- 各サウンド個別音量設定できる
- AudioSource不足の場合自動的に１個生成する
- AudioSource最大数設定できる

# コード
```c#:SoundManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// サウンドデータ定義
[System.Serializable]
public class SoundData
{
    // 名前
    public string name;
    // ソース
    public AudioClip clip;
    // 再生時間
    public float playedTime;
    // 音量
    [Range(0.0f, 1.0f)]
    public float volume = 1.0f;
}

public class SoundManager : UnitySingleton<SoundManager>
{

    // 最大同時再生数
    [Range(5,25)]
    public int MaxSoundTrack = 10;

    [SerializeField]
    private List<SoundData> soundDatas;

    private AudioSource[] audioSourceList;
    
    // 検索用辞書
    private Dictionary<string, SoundData> soundDictionary = new Dictionary<string, SoundData>();

    private void Awake()
    {

        audioSourceList = new AudioSource[MaxSoundTrack];

        for (var i = 0; i < audioSourceList.Length; ++i)
        {
            audioSourceList[i] = gameObject.AddComponent<AudioSource>();
        }

        foreach (var soundData in soundDatas)
        {
            soundDictionary.Add(soundData.name, soundData);
        }
    }
    
    // 使っていないAudioSourceを取得
    private AudioSource GetUnusedAudioSource()
    {
        for (var i = 0; i < audioSourceList.Length; ++i)
        {
            if (!audioSourceList[i].isPlaying) return audioSourceList[i];
        }

        return null;
    }
    
    // 再生（内部用）
    private void Play(AudioClip clip,float volume)
    {
        var audioSource = GetUnusedAudioSource();
        if (audioSource == null) return; 
        audioSource.clip = clip;
        audioSource.volume = volume;
        audioSource.Play();
    }
    
    // 再生(名前)
    public void Play(string name)
    {
        if (soundDictionary.TryGetValue(name, out var soundData))
        {
            if (Time.realtimeSinceStartup - soundData.playedTime < soundData.clip.length) return;
            soundData.playedTime = Time.realtimeSinceStartup;
            Play(soundData.clip,soundData.volume);
        }
    }

    // 再生(名前,間隔時間)
    public void Play(string name, float interval_time)
    {
        if (soundDictionary.TryGetValue(name, out var soundData))
        {
            if (Time.realtimeSinceStartup - soundData.playedTime < interval_time) return;
            soundData.playedTime = Time.realtimeSinceStartup;
            Play(soundData.clip,soundData.volume);
        }
    }
}

```
【Pega 8.6】ケースタイプ（CaseType）のCreateステージ（Stage）を削除する裏技

## １．はじめに
Pega Platform 8.6では、新規のケースタイプを作成した後に、デフォルトのCreateステージが作成されており、
そして、このステージは使う機会が少なく、削除しようとしても簡単に削除できない方が多いと思います。

本記事では、Createステージを削除する方法を紹介します。

【例】新規ケースタイプ：**TestNewCase**
<img width=60% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/8507a847-1300-bc54-45da-8a3fe14e275e.png">

## ２．既存のpyDefaultを削除
左メニューのAppから、TestNewCaseのクラスを開き、Process ⇒ Case Type ⇒ pyDefaultを削除します。
<img width=110% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/b9907a72-53ba-b693-ac5d-9644e17964ae.png">

## ３．新規のpyDefaultを作成
既存のpyDefaultを削除した後に、新規のpyDefaultを作成します。
※Label名はTestNewCase（ケースタイプ名）です。
<img width=100% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/0190456c-cf5a-0a41-ae9c-be451c720247.png">
<img width=100% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/a4d96396-bec8-e20e-3a95-0d0ac502401c.png">

## ４．TestNewCaseのケースタイプを再度開きます
既に開いているTestNewCaseのタブを閉じて、CaseTypesをリフレッシュし、再度TestNewCaseのケースタイプを開いて、Add workflowの画面が表示されます。
<img width=100% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/bfd15882-bbed-4042-4c0b-227607d6208c.png">

## ５．最初からステージ・プロセス・ステップを作成
Add workflowをクリックした後に、【例】Inputのステージ、プロセス、ステップを作成します。
また、表示するため、inputステップにItem001のデータモデルを入れます。
<img width=100% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/f2e0ddd9-3902-31a4-4ef6-eb33b3093c97.png">

## ６．実装結果確認
TestNewCaseを実行し、Createステージがなくなって、Inputステージから処理開始します。
<img width=100% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258181/e62f2557-7157-8f19-1aad-127c37cc50dd.png">

#### ・Pega Platform環境
　Pega 8.6.1

#### ・キーワード
　Remove create stage in Pega

#### ・日本語 ⇔ 英語
　ケースタイプ ⇔ Case Type
　ステージ ⇔ Stage
　プロセス ⇔ Process
　ステップ ⇔ Step
python3を用いたgifアニメの解像度変更

# python3を用いたgifアニメの解像度変更
先日、pixivに作成したgifアニメをアップロードしようとしたら、ファイルサイズの制限に引っかかってしまった。そこで、画像の解像度を落とし、ファイルサイズを小さくしようと考えた。
ブラウザ上でgifアニメの解像度を縮小するサービスはいくつか見つかったが、どれもファイル容量の制限などにより使いにくかった為、自分で作成した。

## 追記 
- 2022-04-14 解像度変えるだけなら[ffmpeg](https://trac.ffmpeg.org/wiki/Scaling)で十分みたいです。

## 開発条件
- python3
- scikit-video
- opencv
pip経由でscikit-videoとcv2を入れる

## 必要なライブラリをインポート

``` python3
from skvideo.io import vread
import cv2
from PIL import Image,ImageDraw
```

## gifを読み込む

``` python3
from skvideo.io import vread
gif = vread("test.gif") # ここを好きなファイル名に変更
```

## 解像度を変更してcv2形式をPillowのImageに変換

``` python3
size = 512 # 圧縮後のサイズ
imgs = []
for img in gif:
    new_img = cv2.resize(img,(size,size)) # サイズを変更
    imgs.append(Image.fromarray(new_img)) # pillowの形式に変換して配列に入れる
```

cv2のresizeで解像度を変更。PillowのImageに変換しているのは、gifとして書き込む際に、Pillow.Imageの書き込み関数を利用するため。
## gifとして書き込む
``` python3
imgs[0].save('test_comp.gif',save_all=True,append_images=imgs[1:],optimize=True,duration=50,loop=0)
```

## 終わりに
以上で、gifアニメの解像度を落とす事ができる。
pixivに画像が上げられなかった方はぜひ。

## 参考
- [cv2の入れ方](https://qiita.com/fiftystorm36/items/1a285b5fbf99f8ac82eb)
- [gifの読み込み方](https://qiita.com/namahoge/items/d01758bcc3ff1c9d04a0)
- [gif形式での書き込み方](https://note.nkmk.me/python-pillow-gif/)
ノーコード/ローコード開発でビジネスがどう変わる？

# ノーコード/ローコード開発とは
ノーコード開発：ソースコードを全く書かずにアプリケーション開発をする手法
ローコード開発：少ないソースコードでアプリケーション開発をする手法

# ノーコード/ローコード開発でビジネスがどう変わる？
ノーコード/ローコード開発でビジネスがどう変わるのか、メリットとデメリットの観点から見ていきましょう。

### ■ノーコード/ローコード開発のメリット
1. 初心者でも開発を行える
コードを書く必要がないためCUIではなくGUIを操作してアプリケーション開発を行います。
CUIはキーボードのみで操作するため初心者の方には扱いが難しいですが、GUIは主にマウスで操作をするため専門的知識がない初心者の方でも開発を行うことができます。また、初心者の方でも開発ができるため現場の担当者が自分でシステムを開発することできます。つまり、 __現場の意見をより反映させたシステムを開発する__　ことができます。

2. 実装までが早い
プログラミング工程が必要ないため、 __設計から実用まで素早く行う__ ことができます。

3. ニーズの多様化に対応できる
グローバル化や市場の成熟化により顧客のニーズが多様化している現代(そこまで多様化していないという説もありますが...)、 __課題の多様化と複雑化に対応できるシステム開発__ が求められます。そのためには多くの資本を投資して大量に生産するモデルではなく、 __少しの資本で少量多品種を生産するモデル__ が求められます。少しで初めて大きく育てるのはノーコード/ローコード開発の得意分野です。


### ■ノーコード/ローコード開発のデメリット
1. 自由度や拡張性が低い
ノーコード/ローコード開発用のツールとして __元々提供されている範囲内のアレンジ__ しか行えません。ですので、デザインや細部までこだわりたい場合は向いていません。

2. シャドーITの蔓延
情報システム部門などが関知せず、ユーザー部門が独自に導入したIT機器やシステムのことをシャドーITと言います。初心者の方でもアプリケーションを素早く作成できるとなると、シャドーITの蔓延につながる可能性があります。シャドーITとして開発されたシステムに、もしも __顧客データや機密性の高いデータが使用されていれば、外部に流出する__ 可能性も十分に考えられるでしょう。

# 終わりに
開発コストやスピードを劇的に向上させるノーコード/ローコード開発ツールは、慢性的なIT人材不足を課題としている日本でも注目が集まっています。しかし、ノーコード開発だからと言ってエンジニアがまったく不要になると言うわけではなりません。そもそもノーコード開発用のツール自体はプログラミングが必要なのでエンジニアが開発していますし、デメリットで述べた通り現状のノーコード開発ツールでは制限も多くあるので、自社独自のサービスを開発するためにはやはりエンジニアの存在が必要になってきます。

最後までお付き合いくださりありがとうございました。
rsyncでファイル転送を行う際に通信帯域制限をかける

備忘メモ

`rsync`で大きなファイル転送する際、帯域が小さいと他の通信に悪影響が出る可能性がある。
これを回避するために`--bwlimit`オプションを付けて転送時の帯域制限をかける。

```sh
$ rsync -h | grep bwlimit
     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second
```

以下のように使う

```sh
$ rsync --bwlimit=1024 src dst
```

単位が`KBytes per second`である事に注意、例えば`20Mbps=2500KBPS`となる

```sh
# `1Mbps=125KBPS`の場合
$ rsync --bwlimit=125 src dst

# `10Mbps=1250KBPS`の場合
$ rsync --bwlimit=1250 src dst

# `20Mbps=2500KBPS`の場合
$ rsync --bwlimit=2500 src dst
```

# 参考
[rsyncの帯域制限オプション – bwlimit](https://www.rootlinks.net/2016/02/01/rsyncの帯域制限オプション-bwlimit/)
[rsync, wget, curl, scp に速度制限をかける方法まとめ](https://qiita.com/koara-local/items/777f2a182788a7310fcd)
GoogleFormで集めたアンケートデータをRで扱えるように加工する(1:前置き)

# 1. GoogleFormデータのクセ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/c440b63f-305a-5ebb-2db5-af82bebfd5c3.png)
## 1-1. 共通
- ダウンロードしたCSVファイルは、設問も選択された回答も、文字列がそのまま落ちてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/149c519a-55ec-749f-4669-6ade7f8604a9.png)
- (ちなみに1) 回答の最後に改行を入れないと、R で読み込むときに最後の行が対象外になることがあります。
- (ちなみに2) エクセルで開くと文字化けする場合は、文字コードを UTF-8 から ANSI に変えるとよきです。
## 1-2. 複数回答
- 選択された回答がデリミタ(セミコロン)で結合されます。
例) "かつ丼;ラーメン;鳥から"
- 「その他」選択肢に記入されたフリーアンサーも、結合されます。
例) "かつ丼;ラーメン;鳥から;大盛りだとなおうれしい"

# 2. GoogleForm集計の問題
## 2-1. 標準で提供される集計結果
- 単回答：円グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/4d25be7b-01d3-fdd2-2ae7-d2a8b44f41cc.png)
- 複数回答：横棒グラフ(「その他」の記述内容も集計・羅列されます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/c998a21f-88af-85e9-e467-8a7450e33b26.png)
- いずれもコピーできます
## 2-2. 標準で提供される集計結果の問題点
- 図形としてコピーできるだけなので、加工ができません。
- 「その他」が記述内容ごとに出力されるので、回答数によっては冗長になります。
- クロス集計など統計的処理ができません。(単純集計のみ)

# 3. (文字列を数値に変換する)Excelによる解決手法と問題
## 3-1. ワークシート関数の例
### (単回答：問題ないパターン)
    (セルB3) =IF(A3="とても賛成",1,IF(A3="賛成",2,IF(A3="どちらともいえない",3,IF(A3="反対",4,IF(A3="とても反対",5)))))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/29604a84-0565-4cb3-36f9-5510575c9940.png)
### (複数回答：問題になる場合があるパターン)
    (セルB3) =IF(ISERROR(FIND(B$1,$A3)=1),0,1)
    (セルF3) =SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE($A3,$B$1,""),$C$1,""),$D$1,""),$E$1,""),";","")
(A列が元のデータで、B列～F列が変換後です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672647/dd37bb80-e01a-5cfc-e29a-89ceb2625267.png)
　選択肢4番目の「かつ丼・ミニラーメンセット」の文字列は、1「かつ丼」, 2「ラーメン」を含んでいるため、太枠で囲ったところが誤変換されています。("1"が立ってしまっている)
　回避できるように選択肢を工夫(選択肢間で同じ文字列を含まないように)すればよいのですが、工夫や検証がめんどーです。
　(また、「その他」に選択肢と同じ文字列を入れられると、集計が合わなくなります)

　そこで、次の記事(2)にてRを使ったデータ加工方法を示します。
mysql/mariadb外部表(DBLINK,FEDERATED)の利用方法

# はじめに
mysql - mariadbでのDBLINKの記事がなかったのでまとめておく。
厳密には記事はあるが、日本語が文字化けしやすく、そこまでカバーされた記事がなかったので残しとく。

# 前提
・ mysql 8.0
・ mariadb 10.3

mysql に 本体のテーブルが存在し、
mariadb から mysqlのテーブルを参照する

試してないけど、
mysql - mysql / mariadb - mariadbなどでも同じ手順で対応できるはず。

# MySQL側

```
mysql> create table dummyTable ( id int , name varchar(255));
Query OK, 0 rows affected (0.01 sec)

mysql> desc dummyTable;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int          | YES  |     | NULL    |       |
| name  | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into dummyTable values (1,'あああ');
Query OK, 1 row affected (0.00 sec)

mysql> insert into dummyTable values (2,'aaaa');
Query OK, 1 row affected (0.00 sec)

mysql> select * FROM dummyTable;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | あああ    |
|    2 | aaaa      |
+------+-----------+
2 rows in set (0.00 sec)
```

# Mariadb側

```
MariaDB > create table dummyTable (id int ,name varchar(255))
    -> ENGINE=FEDERATED 
    -> default charset=utf8
    -> CONNECTION='mysql://xxxx:xxxx@xxxxx/xxxxxx/dummyTable';
--------------
create table dummyTable (id int ,name varchar(255))
ENGINE=FEDERATED 
default charset=utf8
CONNECTION='mysql://xxxx:xxxx@xxxxx/xxxxxx/dummyTable'
--------------

Query OK, 0 rows affected (0.002 sec)

MariaDB > select * FROM dummyTable;
--------------
select * FROM dummyTable
--------------

+------+-----------+
| id   | name      |
+------+-----------+
|    1 | あああ    |
|    2 | aaaa      |
+------+-----------+
2 rows in set (0.003 sec)

```

# ポイント
<dl>
  <dt>ENGINE=FEDERATED</dt>
  <dd>これがDBLINKのEngine</dd>
  <dt>DEFAULT CHARSET=utf8</dt>
  <dd>これをつけないと日本語が化けてしまう。utf8の箇所はそれぞれの環境に合わせること。</dd>
  <dd>show variables like '%char%';</dd>
  <dt>CONNECTION='mysql://xxxx:xxxx@xxxxx/xxxxxx/dummyTable'</dt>
  <dd>CONNECTION='mysql://ユーザ名:パスワード@サーバー名/DB名/テーブル名'</dt>
</dl>

# 参考文献
- [https://mariadb.com/kb/en/federated-storage-engine/](https://mariadb.com/kb/en/federated-storage-engine/)
- [https://dev.mysql.com/doc/refman/8.0/en/federated-storage-engine.html](https://dev.mysql.com/doc/refman/8.0/en/federated-storage-engine.html)
CCNAの基礎を学べる本を読んで

# 「CCNAの基礎を学べる本」を読んで、知らなかった単語や知識

個人の復習目的で書かせていただきます。追記していきます

単語
Ethernet

LANに採用されている通信規格
イーサネットはLANに採用されている通信規格でありLANで使われる「物」に関する決まり事
例　LANケーブルなど

語源
実験システムの開発中に，Metcalfe氏が思いついた名前が，Ethernetである。 この語源は，「エーテル（Ether）」という仮想的な物質。 17世紀にホイヘンスという学者が，光を伝えるために，宇宙空間などの真空も含めた至るところを満たしている仮想的な物質として定義したものだ。


引用・参考
https://wa3.i-3-i.info/word1539.html
https://xtech.nikkei.com/it/free/ITPro/OPINION/20021216/1/#:~:text=%E3%81%93%E3%81%AE%E5%AE%9F%E9%A8%93%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E9%96%8B%E7%99%BA,%E3%81%A8%E3%81%97%E3%81%A6%E5%AE%9A%E7%BE%A9%E3%81%97%E3%81%9F%E3%82%82%E3%81%AE%E3%81%A0%E3%80%82
照度センサーを使って灯りがついている時間を計測し、電気料金がわかるものづくりに挑戦してみた！！

こんばんは。

現在小売業で働いており、新入社員の受け入れの研修をしています。
講義の中で「**店舗で使用しているものはすべて経費が掛かっていると思ってください。**」と
新入社員に伝えましたが、こんなぼんやりしている説明はないなと反省・・・

**なので、経費としてわかりにくいものを**
**分かりやすくするための装置を作ろうと実装してみました。**

（ひとまず照度センサーを使って電気料金がわかるものを作りたくなったので、
まずは家のトイレで使用している電気料金を調べてみることにしました！）

## 作ろうとしたもの
照度センサーを使って電気がついている時間を分単位で計測し、
電気料金がわかるものを作ろうとしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811930/b5699ba0-b334-393f-335a-93f4c0599885.png)

↑の画像は電気をつけている状態でNode.jsを実行して、
0.15v以下になった時間を計測してくれるものです。




## 実装環境
* Node.js（version: v17.6.0） 

## 使用したもの
* obniz
* CdS:1個
* 抵抗330Ω:1個
* ブレッドボード:1個
* ジャンパワイヤー赤:1本
* ジャンパワイヤー黒:1本
* ジャンパワイヤー白:1本
	
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811930/701e79bc-8801-7c68-21de-e73bef64e9bf.png" width="200" height="130">

## 作成したコードがこちら
<details><summary>実際に作成したコードはこちら</summary>

```js
const Obniz = require('obniz');
const obniz = new Obniz('*********');

require('date-utils');
let now = new Date();
//console.log(now.toFormat('YYYY年MM月DD日 HH24時MI分SS秒'));
let onoff ="ついています"
obniz.onconnect = async () => {
    obniz.io0.output(true);  // io0電圧を5Vに（電源＋）
    obniz.io2.output(false); // io2電圧を0Vに（電源−）

    // io1をアナログピンに(センサーの値を取得)
    obniz.ad1.start((voltage) => {
        // センサーの値が変わるたびに実行される
        //console.log(`changed to ${voltage} v`);
        if(voltage<0.15){
            let time = new Date();
            var diff = time.getTime() - now.getTime();
            
         if(onoff=="ついています"){
             onoff="ついていません"
             console.log(diff / (60*1000)); // 48
         }   
        }else{
            //console.log(`灯りがついています`)

        }
    });
}
```
</details>



## 実装しながら思った疑問点
* 電気をつけている状態から計測し、0.15v以下になると
灯りが消えた時間を計測されるように設定しているはずなのに、
すぐに電気が消えたと判断され、計測時間がNode.js表示されること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811930/1c21d87d-bed4-eb3b-78b5-9e3203e0505e.png)


平均して0.5vくらいだと、電気がついている状態、
平均して0.3vくらいだと、電気がついていない状態ということはわかりました。

## 今後の修正点
* Node.jsでobnizを実行してから電気が消えた時間をすぐに起動・計測させるのではなく、
計測開始時間を遅らせる設定をする。
→0.01秒で電気消えましたと計測されることは解決できたかも。

* Node.jsを起動してから電気が消えた時間を引き算し、
分単位で電気がついていた時間を教えてくれるように設定にする。

* 何分電気がついていましたではなく、電気がついていた時間から
電気料金を計算して表示できたら、もっとわかりやすくなるはず。

* LINE Botに繋げて、電気を沢山使っていると分かったときは
お説教スタンプ遅れたら気が引き締まるかも笑

## obnizを使ってみての感想

新入社員に経費に対する意識づけをさせるために照度センサーを使って
電気代がいくらかかっているかわかるものを作ってみましたが、
計測に電気を使ったら本末転倒だと今さらながら気づいた私・・・

あれ？こんなはずでは・・・と思いつつも
obniz使ってみたかったし、使うことに意味があるよね！と
自分を納得させてます笑


最後まで読んでくださり、ありがとうございました。
Mailerでmissing templateになってしまった

![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525610/951586bb-b754-8987-fa59-ba2c02f6e599.png)


https://qiita.com/ki_87/items/67f8965e8de17e95ac1c

コチラのサイトを参考にさせていただきメールの送信機能を実装しました。
ですが、上記のエラーが出てしまいました。なぜ。。。。

###### こいつは馬鹿です

いや誤字はない。どこが。。。おかしいんだ。。。

###### こいつは馬鹿です


何で！なんで！お父さん帰ってこないんだよ！！


###### ※関係ありません

答えは簡単。
彼は見落としていました。

~~~view/contact_mailer/send_mail.text.erb
===============================
  <%= @mail_title %> 
  ===============================
  皆様

  グループオーナーからイベントの通知です。

  <%= @mail_content %>

  今後とも よろしくお願いいたします。

~~~

メールの文言が書いてあるファイルですが、このファイルはどこに保存すべきでしょう？
記載のある通り、contact_mailerの中が正解です。
ところが彼は、まったく違う階層に保存していました。
書いてあるのに。馬鹿です。

ちなみにGroup機能の延長のメール機能であったため、view/groupsに保存していました。
そのため、Contact_mailerが見つからない？てきなエラーが発生してしまったのですね！

というわけでお仕置きです。ここから先は全く関係ないので興味のない方は戻ってください。


# お仕置き

ああっ！！！やめて！！！それはでかすぎるって！！！

### あああああああああああああああああああああああああああああああああああ
ラズパイをモニターなしでsshができるようになるまで

# Raspberry Pi ImagerでRasbperry Pi OS LITE(64bit)のインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613684/a493582a-d04a-430c-f7b6-10e29368fc0b.png)

# 空のsshファイルをSDカードに入れる
空のssh.txtファイルを入れることでsshができるようになるらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613684/39e524c7-a66b-5ea6-efee-5ba48b752af6.png)

# sshを行う
```
ssh pi@raspberrypi.local
pi@raspberrypi.local's password:
Permission denied, please try again.
```
できないんだが...

# 解決策
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613684/6ad667bc-f441-1365-6579-6487176fdddd.png)
この右下の設定をいじるとsshができるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613684/61e95afb-f352-aac1-665e-ac462f6abf7e.png)

パスワードはraspberryにしました。
※.sshディレクトリにあるknown_hostsファイルのraspberrypi.localの行を消しておかないとsshはできない
```
ssh pi@raspberrypi.local
pi@raspberrypi.local's password:
pi@raspberrypi:~ $
```

できた！
Turing.comからのスパムメール

Gmai宛に以下のようなスカウトメールのようなものが何通かきていました。

```
XX, We have awesome remote U.S. jobs waiting for engineers like you

Hi, XXX.XXX, ,

I saw your profile online and wanted to reach out! You might be a great fit for many of the remote software engineering roles that top U.S. companies are hiring for on Turing.

Turing is based in Palo Alto, California, U.S.A., also known as “Silicon Valley”. We connect exceptional software engineers from around the world to top U.S. and Silicon Valley companies that are hiring for full-time remote software positions.

Live anywhere, enjoy rapid career growth: Live anywhere in the world, enjoy career growth opportunities formerly only available to engineers living in the Silicon Valley - Work with former Tech Leads and Engineering Managers from Google, Facebook, Microsoft, Amazon, & various top tech companies and advance rapidly towards your professional goals.

Full-Time, Long term opportunities: - Turing only partners with U.S companies that are hiring for full-time long term roles remotely and also work hard on re-matching you to subsequent long term opportunities. If you register and pass Turing’s tests and interviews, you may never have to interview for a job again.

Compensation: - Turing engineers are compensated with salaries more than local companies in most countries.

Find jobs across levels: - Turing hires mid level, senior level as well as tech lead level engineers.

Find jobs in 100+ Skills: - Get hired for React, Node, Python, Angular, Swift, React Native, Android, Java, Rails, Golang, PHP, Vue, Devops, Machine Learning etc.
START YOUR APPLICATION

If you run into any difficulty creating your profile, please email us at hiring@turing.com. Our team will help you out as soon as possible. We look forward to matching you with new exciting opportunities!

Best Regards,
Turing Team

```

https://log.k4a.me/20211219_turing_spam
この記事でスパムであることが如実にわかります。
そしてこの記事を書いた人は相当変わり者ですねｗ

あと、githubのアカウント名宛で自動送信されているようですね。

こういうメールも自動を迷惑メールでGmailで振り分けてほしいな。
必要なものを迷惑メールに振り分けないでさ。
git commit --fixup が便利

## 始めに
私は最近エンジニアに復帰し、現場で便利に思ったことを今後記事にできたらと思っています。
そして1発目は、gitのオプションについて記事を書いてみようと思います。


## --fixup はどんな時に使えるの？
Pull Requestなどで、軽微な指摘や後から気付いた修正など、本来の機能のコミットとは別に修正コミットを残すのは少し嫌な時がありますよね。
コミットが一つ手前であれば、直前のコミットを修正してくれる `git commit --amend`などで対応できますが、3つ前のコミットに修正を混ぜ込みたい時などは、少し大変。
そんな時に便利なのが、この `git commit --fixup`です。


## 使い方
例えば、下記のコミットの状況で、`Fix article page`のコミットに対して、追加の修正をしたいとする。

```terminal
❯ git log --oneline
1131338365 (HEAD -> edit_article_page) Fix settings page
9c57cb3e7a Fix article page
ab6a6bef9d Add column
cgbaeef9d3 (master) Initial commit
```

追加の修正をし、追加のコミットをする際に、`--fixup　<引数>` を使います。
引数には まとめたいコミットのハッシュ値を指定します。

```terminal
❯ git add .
❯ git commit --fixup 9c57cb3e7a
```

まとめたいコミットメッセージの頭に `fixup!` の文字がついたコミットが出来上がります。

```terminal
❯ git log --oneline
26a2dc16a8 (HEAD -> edit_article_page) fixup! Fix article page
1131338365 Fix settings page
9c57cb3e7a Fix article page
ab6a6bef9d Add column
cgbaeef9d3 (origin/master, master) Initial commit
```

これでコミットをまとめる下準備が完了。

最後に、`git rebase -i --autosquash <引数>` を実行します。
※autosquashは、**fixup!** で始まるコミットメッセージ名のコミットをまとめます。

どのコミット以降に対してautosquashを実行するかを引数に指定する必要があるので、**HEAD~4**を指定します。

```terminal
❯ git rebase -i --autosquash ab6a6bef9d
pick ab6a6bef9d Add column
pick 9c57cb3e7a Fix article page
fixup 26a2dc16a8 fixup! Fix article page
pick 1131338365 Fix settings page

# Rebase 671ca6fcee..f235308862 onto 671ca6fcee (4 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
```

autosquashを実行後にエディタが立ち上がり、上記のような画面になります。
まとめたいコミットの下に**fixup**が付与されたコミットが来ていれば想定通りです。

あとはエディタを閉じれば、コミットがまとめられます。

```terminal
❯ git log --oneline
1131338365 (HEAD -> edit_article_page) Fix settings page
9c5a2d3e7a Fix article page
ab6a6bef9d Add column
cgbaeef9d3 (origin/master, master) Initial commit
```


## 終わりに
今回は`git commit --fixup`の使い方を簡単に紹介しました。
一見すると登場するコマンドがやや難解そうですが、使ってみると簡単かつ便利です。
知らなかったというみなさんもぜひ使ってみてください。

(私は今の現場に来る前は、修正コミットなども残していたので、fixupを知ったのは、本当につい最近です)
S3のファイルをpython boto3でダウンロード

# 概要
首題の通りです。備忘録として記載しています。
他にスマートなやり方がありそうなのであくまで参考程度に。

# 環境
ubuntu 20.04
ubuntu内のDocker上にpython3.10のコンテナを立ち上げ実行

# コード
予めAWSのIAMでaws_access_key_idとaws_secret_access_keyを準備しておく

```
# ライブラリをインストールしておく
pip install boto3
pip install awscli
```


```py
import boto3

s3 = boto3.resource('s3',
                    aws_access_key_id='XXXXXXXXXXXXXXXXX',
                    aws_secret_access_key='YYYYYYYYYYYYYYYYYYYYYYY',
                    region_name='ap-northeast-1')

bucket = s3.Bucket('作成済みのバケットの名前を指定')
bucket.download_file('ファイル名を指定(バケット以降のURL)', 'ダウンロード先のパス(ファイル名も指定)')
```

# その他
このままだとコードに各種keyがベタがきなのでやり方を変えた方が良い気はする。。。
NCMB Kotlin SDKを使ってカメラメモアプリを作る（その1 アプリの仕様とNCMBの初期化）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回は公式SDKの一つ、Kotlin SDKを使ってカメラメモアプリを作ってみます。まず画面の仕様とSDKの初期化について解説します。

## 完成版のコード

作成したデモアプリのコードは[NCMBMania/Kotlin_Camera_Memo: Kotlin SDKを使ったカメラメモアプリです](https://github.com/NCMBMania/Kotlin_Camera_Memo)にアップロードしてあります。

## ベースについて

今回はKotlin + Jetpack Composeの組み合わせになっています。プロジェクトを作る際には Empty Compose Activity を選択してください。

## Composeについて

今回は以下のComposeを用意しています。

- MemoBottomNavigation
- FormScreen
- ListScreen
- ListRow

### MemoBottomNavigation

![Screenshot_1649852241のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/73d69197-25d2-e834-9ff6-273990d468f4.png)


画面下に表示されます。入力フォーム（FormScreen）と一覧画面（ListScreen）を読み込んでいます。

### FormScreen

![Screenshot_1649852241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/3aa96c81-e719-bf1d-d5bb-038d944c7d0d.png)


入力フォームです。写真を選択して表示したり、写真と紐付けるメモ（テキスト情報）をNCMBに保存します。

### ListScreen

![Screenshot_1649852372.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/4d2934af-1d12-494a-c2ab-367d0474c68f.png)


一覧画面です。NCMBからメモ一覧データを取得します。取得したデータはListRowで表示します。

### ListRow

入力されたメモを表示し、ファイルストアから写真データをダウンロードして表示します。

## NCMB SDKのインストール

NCMB SDKは[Releases · NIFCLOUD-mbaas/ncmb_kotlin](https://github.com/NIFCLOUD-mbaas/ncmb_kotlin/releases)よりダウンロードします。Zipファイルをダウンロードして展開すると、NCMB.jarというファイルが取得できます。このファイルをKotlinプロジェクトの `app/libs` 以下にコピーします。

これでNCMB SDKの利用準備が整います。

## NCMB SDKの初期化

`app/build.gradle` を開いて編集します。そして以下の3つを追加します。一番下のkotlinx-coroutinesを追加すると、保存処理などが同期的に処理できるようになります。

```
dependencies {
	// 省略
	implementation 'com.google.code.gson:gson:2.3.1'
	api files('libs/NCMB.jar')
	implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'
}
```

編集したら同期します。

### コードの編集

MainActivity.ktを開いてNCMBの初期化を行います。 `super.onCreate` の下でNCMBを初期化します。 `YOUR_APPLICATION_KEY` と `YOUR_CLIENT_KEY` はそれぞれあなたのものと書き換えてください。

```kotlin
// インポート
import com.nifcloud.mbaas.core.NCMB

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // NCMBの初期化
        NCMB.initialize(
            this.getApplicationContext(),
            "YOUR_APPLICATION_KEY",
            "YOUR_CLIENT_KEY"
        )
        setContent {
						// 省略
        }
    }
}
```

これでNCMBの初期化が終わり、利用準備が整います。

## まとめ

今回はComponentの説明と、NCMB SDKの初期化を行いました。[次回はデータを保存処理について説明します](https://qiita.com/goofmint/items/dc335c55e6dd5c981c9a)。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
Shopify Theme Kit 使おうと思ったらプライベートアプリってのがなかったお話

# プライベートアプリはなくなった
初めてShopifyのカスタムをするにあたって、調べてると
Shopifyのテーマをローカルで編集したら、
そのまま自動的に Shopify側も更新されるぞってのがあったので、これだ！

ほぼほぼ Shopify管理画面のアプリ管理内にある
「プライベートアプリ」でアプリ作ってスタートみたいなことが書かれてるけど
実際見てみると、そんな項目ねぇぞってなった

2022年1月に非推奨になったらしいよ

- Theme Kit インストール
- ~~プライベートアプリの追加~~ **カスタムアプリ**の追加
- Theme Kit を使って Themeファイルをローカルにダウンロード
- 開発スタート！！！！！

って感じになってた

## カスタムアプリでの設定
- Admin APIアクセススコープ で ```write_themes, read_themes``` にチェックを入れて保存
- アプリのインストール
- Admin APIのアクセストークンは1回しか表示されないしコピーもできないので必ずコピーしておく

これで必要なアクセストークンゲットだぜ

メモ代わりに残しておきましょうってことで投稿
投稿してから

Shopify の Admin API カスタムアプリの Access Token を用いてAPIリクエストを行う方法：CData Shopify Driver
https://www.cdatablog.jp/entry/shopify-jdbc-dbvisualizer-authentication

ってのがあったので、詳しくはこちらの方がいいんじゃないでしょうか
【７日目】メモ帳アプリの作成 [４]

# 本日の課題
今日は前回までに作った機能にCSSで見やすいようなデザインにし、削除ボタンを追加します。
まずはメモ内容と日付のセット1つ1つに枠を設けてパッと見たときにわかりやすくなるようなデザインを書きます。今回は`box`という名前にします。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vYpazam" data-user="mizmizsan2" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mizmizsan2/pen/vYpazam">
  Memo5</a> by mizmizsan2 (<a href="https://codepen.io/mizmizsan2">@mizmizsan2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
ここで重要になってくるのがboxの位置ですがHTML側ではなくJavaScriptの `innerHTML += ...`のdivに直接入れ込むことで実現できます。HTML側に書いてしまうとメモ内容全体を囲む大きい一つの枠になってしまうので注意。

次はdeleteボタンを作成してメモ内容と日付のセットを削除できるようにします。deleteボタンも先ほどと同じようにJavaScript側に書きます。



<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="oNpMrRK" data-user="mizmizsan2" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mizmizsan2/pen/oNpMrRK">
  Memo7</a> by mizmizsan2 (<a href="https://codepen.io/mizmizsan2">@mizmizsan2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

削除する関数としてdeleteMemoを作成しました。
引数として渡す値はメモ内容などを保存しているlocalStrageのid(ここではwriteMemo)です。ここで渡す引数にchunkDataなどを渡してもストレージの中ではなく変数が変わってしまうだけなのでちゃんとストレージのidを直接渡さないといけません。

そして渡されたデータを消すのには`localStorage.removeItem()`を使い、カッコ内に入れ込みます。

この状態では、
deleteボタンを押す→ページをリロードする→消える
という手順で削除をするのでdeleteボタンを押した瞬間に内容が削除されるようにします。


<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vYpaqME" data-user="mizmizsan2" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mizmizsan2/pen/vYpaqME">
  Memo5</a> by mizmizsan2 (<a href="https://codepen.io/mizmizsan2">@mizmizsan2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

先ほどのプログラムのdeleteMemoに`window.location.reload()`を追加しました。こうすることで自動的にリロードされてメモを消すことができます。
駆け出し組み込みエンジニア向け 有益かもしれない情報まとめ

## 目的
組み込みエンジニアって結構な数いるはずなのに、書籍やネットでの組み込み開発に関する情報が少ないように感じます。
そのため、微力ながらそういった組み込みエンジニア向けに役に立つかもしれない情報をまとめてみました。[^1]
<b>(主に個人的な経験から得たり/感じたりしたノウハウです)</b>

[^1]:今後思いついたら追記するかもしれません

```
更新履歴：
2022/4/13 新規作成
2022/4/15 "その3：部品の寿命を考えた設計が必要"を追加
2022/4/16 "その4：フェイルセーフを考慮した設計をする"を追加
2022/4/26 "その10：テレワークや在宅ワークがしづらい可能性がある"を追加
```

## まとめ

### 設計編

#### その1：ハードウェア(以降、HW)を意識したソフトウェア(以降、SW)作りが必要
	
組み込み系なので当たり前と言えば当たり前ですが、メモリやCPUパフォーマンスなどに制約があることが多いです。
もちろん開発対象にもよりますが、小規模な製品だと制約が大きくなりがちな気がします。
極端な場合は、KByteオーダーでプログラムサイズを気にする、というケースもいまだになくはないかなと。
(さすがにここ数年そこまで考慮するケースは稀になった気はしますが)

<b>教訓
使えるHW資源を常に意識しましょう
</b>

#### その2：最近一番読んだドキュメント(文章)は規格やチップの仕様書、というケースがある
場合によりますが、組み込み関係の内容は、一般的に書籍やネットに情報が出回っていることが少ないので、SWを実装するために、規格やチップの仕様書とずっと格闘することになるケースがあります。
そしてそれらは大体英語で、専門用語がふんだんに使われています・・。
	
<b>教訓
とりあえず英語は学んでおいて損はない
</b>

#### その3：部品の寿命を考えた設計が必要

HWは消耗品なので、寿命を考えた設計が必要になる場合があります。
よくあるのは、Flashメモリの書き込み回数の上限(それ以降は書き込み保証できない上限)で、使用する部品によりますが、数十万回が書き込み上限になることが多いです。

```
例：
書き込み上限：50万回

・Flashメモリに1秒ごとにデータ書き込み
	Flash書き込み：1回/秒
	Flash寿命：50万秒 = 138時間(5,6日) → 製品として成り立たない

・RAMに1分間データをためて、それを一気にFlashへ書き込み
	Flash書き込み：1回/分
	Flash寿命：50万分 = 8333時間(347日) → 1年に1回取り替えるとか考えれば、製品としてありかも
```

<b>教訓
部品によって、寿命を考慮する必要があるので、データシートなどで情報収集する
</b>

#### その4：フェイルセーフを考慮した設計をする
フェイルセーフ、つまりシステムに故障や異常が発生したときに安全な動作をするように設計することです。
例えば、私が昔関わっていたオーディオ関係を例に挙げると、よく言われたのは`危ないときはミュートしろ`でした。
いきなりVolume最大の爆音が鳴ってユーザーが驚かないようにするための対策です。

```
具体例：
・前提：Volume値0～100の範囲で設定できる
・事象：SWがバグったりしてVolume値として127(範囲外の値)が入力された 
　→ 最大値を超えているのでVolume値最大(100)に丸め込み or 範囲外の値だからミュート(0)にする、
　　と考え方はあると思いますが、私は前述した通り、ミュートをフェイルセーフとして考えていたため、基本後者で対応していました
```
<b>教訓
システムに応じたフェイルセーフを考慮した設計をしましょう
</b>

### テスト編

#### その5：シミュレーターで動いたから製品でも動くだろう、は大体動かない

テストするのに、シミュレーターやエミュレーター(ICE)などの机上デバッグを使うことが結構あります。
シミュレーターやエミュレーターで動いても、実際の製品では、そこで見つからなかった不具合が見えてくることが多いです(主にHW観点で)。
あくまでシミュレーターやエミュレーターはテストの補助をしてくれるものということをお忘れなく・・。
	
<b>教訓
早めに実際の製品環境でデバッグしましょう
</b>

#### その6：単体テストで問題ないから、他の機能との結合テストも大丈夫なはず → 大体不具合が出る
他の人が作った機能と結合して動作テストをする場合に多いのですが、モジュール間のIF変数やAPIなどの認識違いなどが原因で、不具合が出てくることがあります。
(ちゃんと設計して仕様書を作っていても結構あります・・。大体設計漏れで意図しないタイミングでIF変数やAPIにアクセスするとかが多い気がします。)
	
<b>教訓
機能間のIFに関する仕様書はちゃんと認識合わせする(これは当たり前)
その上で早めに結合テストをすることを意識しましょう
</b>

#### その7：開発環境差分で不具合が再現できないことがある
Aさんが使っている環境で発生する不具合がBさんの環境では発生しない、というパターン。
よくあるのは、使っているSWのバージョン、開発ツール/アプリなどのバージョンが違う、といった環境差分で再現できないケース。
	
<b>教訓
開発の初期段階で使う環境ツール/アプリのバージョンを決めて、基本そこから更新しない
また、どのSWを使ったかの情報は必ず共有する
</b>
	
#### その8：ヒューマンエラーで不具合解析が進まないことがある
ある不具合が発生したときに、その手順や条件を共有することはいいのだが、Aさんがやった手順や条件設定をBさんが試しても不具合が再現せず、解析できないというケースがあります。
これは、実はAさんがやった手順や条件と違うことをBさんが試していた、ということがよくあります。
(Aさんの伝えミス or Bさんの認識間違いが原因)
	
<b>教訓
認識違いが起こらないよう、不具合の条件や手順は文字だけでなく、(可能であれば)動画付きで共有する
</b>

### その他

#### その9：開発する製品以外にも測定器など機器を扱うことが多い
これは私の経験上なので一般的ではないですが、テストする際にオシロスコープやロジアナ、テスト用の治具を作るのに半田こてを使ったり、と色々機器を扱うことが結構あります。

<b>教訓
教訓というのもアレですが、これらを使うことをなるべく毛嫌いせず慣れましょう
使ってないと普通に使い方忘れます(経験済み)
</b>

#### その10：テレワークや在宅ワークがしづらい可能性がある
開発中の物理的な製品、を扱うことが他の職種に比べて多いため、どうしてもテレワークがしづらいケースがあります。
開発序盤の設計フェーズならいいですが、終盤の評価フェーズになると、出社しないと対応できないことも多いです。

<b>教訓
教訓ではないですが、テレワークしたい人はそれができる環境を整えましょう
オンラインで開発できる仕組みを整える(開発用PCにリモートログインできるようにする)など
NCMB Kotlin SDKを使ったファイルストア利用について

NCMB Kotlin SDKは先日リリースされ、現在も活発に開発を行っています。NCMBの1機能であるファイルストア（写真やテキストファイルを扱うストレージ）にファイルをアップロードする際に悩む可能性がありそうなので備忘録として書いておきます。

## v1.1.0におけるNCMBFileの使い方

v1.1.0におけるファイルストアへのファイルアップロードは次のようになっています。

```kotlin
constructor(fileName:String, fileData:File) : super("files") {
		mIgnoreKeys = this.ignoreKeys
		this.fileName = fileName
		this.fileData = fileData
}
```

fileDataとして渡すのはFileオブジェクトになります。写真ピッカーを使って取得されるのはUriクラスですが、そのままでは使えないので注意してください。

## 解決策

解決策は2つあります。

1. 実際のファイルオブジェクトを取得する
2. テンポラリファイルに書き出す

### 実際のファイルオブジェクトを取得する

Uriから本当のFileを取得する方法はあるのですが、そのためにはファイルストレージへのアクセス権限が必要になります。これはちょっと面倒そうです。

### テンポラリファイルに書き出す

テンポラリファイルに書き出す方法であれば、さほど難しくありません。

```kotlin
// 出力先（テンポラリ）
val outputDir = context.cacheDir
val outputFile = File.createTempFile(fileName, ".${extension}", outputDir)
// bitmapをByteArrayに変換する
val stream = ByteArrayOutputStream()
if (extension == "jpg" || extension == "jpeg") {
		bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream)
} else if (extension == "png") {
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
}
// テンポラリファイルに出力
outputFile.writeBytes(stream.toByteArray())
```

### アップロードする

後はこのFileを使ってファイルストアへのアップロード処理を行います。

```kotlin
val file = NCMBFile(fileName = fileName, fileData = outputFile)
file.save()
```

### 削除する

アップロード処理が終わったら、テンポラリファイルは削除します。

```kotlin
Files.deleteIfExists(tempFile.toPath())
```

## まとめ

ファイルストアを使えば、たった1行のコードでファイルをクラウドストレージにアップロードできます。Kotlin SDKはまだ開発が活発なので、さらに便利な機能が追加されていきます。ぜひあなたのKotlinアプリ開発で役立ててください。

[ドキュメント : 開発者向けドキュメント | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/#/Kotlin)
EMアルゴリズムのメモ

EMアルゴリズムの一般論と具体的な問題の結びつきをすぐ忘れてしまうのでメモ
以下の記事を参考にしています

https://qiita.com/kenmatsu4/items/59ea3e5dfa3d4c161efb

- 目的はQ関数(完全データの対数尤度の、Zの事後分布による条件付き期待値)の最大化
- Q関数の最大化はELBOの$\theta$による最大化と等価となっている
- そのため、EステップでQ関数の計算、Mステップで$\theta$の更新をしている
- 混合正規モデルに関して、Q関数の計算には$\mathbf{Z}$の事後分布による${z_{nk}}$の期待値すなわち負担率の計算が必要であり、それがMステップで行うQ関数のパラメータの更新式にも登場する。負担率の計算は一応Q関数の計算をしているとも言える。
- 上記記事ではEステップを事後分布$P(\mathbf{Z}|\mathbf{X},\theta)$の計算としているが、それは混合正規モデルに対する計算がQ関数の期待値は求めず負担率すなわち事後分布の計算をすればよいためそれと対応付けしているということだろう。一般的な理論ではEステップはQ関数を求める事となる。

Q関数をよく見ると、現在のパラメータ推定値に基づいて算出される潜在変数の事後分布をその信頼度として不完全情報を暫定的に補っていると解釈できる。
[mac][datadog] datadog-agent の自動起動を阻止する

# まず結論から
```zsh
rm ~/Library/LaunchAgents/com.datadoghq.agent.plist
```

# 概要
- datadog-agent は繋ぎ続けると課金対象になりますが、OS再起動時に自動実行されちゃいます
- システム環境設定 > ユーザとグループ > ログイン項目から削除しても起動しちゃいます

# 環境
- macOS Monterey バージョン 12.3.1
- homebrew で datadog-agent をインストールしている
HTMLの基本を解説3

ここまで１つひとつの細かい要素を囲むタグを解説しました。ただこれらのタグを上から並べているだけでは上手にレイアウトが組めません。そこで、まとまりごとにグループ分けをしましょう。
## グループ分けとは
Webサイトは様々な構成要素を組み合わせて作られています。例えばナビゲーションメニュー、本文、関連記事の一覧、Webサイトの紹介文などなど。それらを１の塊としてタグで囲み、グループ化していきます。
```html:グループ化してない例
<h1>明日の天気</h1>
<p>明日は曇りのち晴れでしょう。</p>
<h2>おすすめの着こなし</h2>
<p>この時期は暖かい気温が続きますが、一枚羽織る服があるといいでしょう。</p>
```
例えば上のような見出しと文章が並んでいるコードを書いたとしましょう。この中で「明日の天気」と「おすすめの着こなし」は別のテーマを持っているので、別グループとしてまとめると良いでしょう。
```html:グループ化した例
<article>
  <h1>明日の天気</h1>
  <p>明日は曇りのち晴れでしょう。</p>
</article>

<section>
  <h2>おすすめの着こなし</h2>
  <p>この時期は暖かい気温が続きますが、一枚羽織る服があるといいでしょう。</p>
</section>
```
上のコードのようにグループ化するためにタグで囲みました。
ただこの時点では、HTMLだけではブラウザー表示に変化はありませんが、CSSを指定するとグループに色を付けたりレイアウトを変更したりすることができます。
グループ化するためのタグにはそれぞれ意味があり、コンピューターに対して「この部分はこのような内容だよ」と知らせるための役割があります。(SEO対策)
今回はよく目にする使い方を解説します。
## `<header>`タグ
ページ上部にある要素を囲みます。多くの場合、ロゴ画像やページタイトル、ナビゲーションメニューが含まれます。HTMLの冒頭に記述する`<head>`とは異なるタグなので、注意しましょう。
```html:header例
<header>
  <h1>ページタイトル</h1>
  <p>テキスト</p>
</header>
```
## `<nav>`タグ
メインのナビゲーションメニューを囲みます。`<nav>`タグは`<header>`タグの中に含まれることが多くあります。基本的にメインではないメニュー部分には使いません。
```html:nav例
<header>
  <h1>ページタイトル</h1>
  <nav>
    <ul>
      <li><a href="#">サービス</a></li>
      <li><a href="#">料金</a></li>
      <li><a href="#">お問い合わせ</a></li>
    </ul>
  </nav>
</header>
```
## `<article>`タグ
ページ内の記事となる部分、そこだけを見ても独立したページとして成り立つような内容には`<article>`タグが使われます。ニュースサイトやブログサイトの記事部分をイメージてもらうとわかりやすいです。
```html:article例
<article>
  <h2>記事タイトル</h2>
  <p>記事内容</p>
</article>
```
## `<section>`タグ
`<section>`タグは意味のあるグループをまとめるためのタグです。`<article>`タグと似ていますが、記事とは異なり、その部分だけ見ても完結しません。そのひと固まりに１つのテーマがあるということが重要です。
```html:section例
<section>
  <h2>テーマタイトル</h2>
    <ul>
      <li><a href="#">テーマ１</a></li>
　　　<li><a href="#">テーマ２</a></li>
　　</ul>
</section>
```
## `<main>`タグ
そのページの核となるコンテンツ全体は`<main>`タグで囲みます。この中に様々なグループが入ることがあります。
```html:main例
<main>
  <article>
    <h2>記事タイトル</h2>
    <p>記事内容</p>
  </article>

  <section>
    <h2>テーマタイトル</h2>
      <ul>
        <li><a href="#">テーマ１</a></li>
　　　  <li><a href="#">テーマ２</a></li>
　　  </ul>
  </section>
</main>
```
### `<aside>`タグ
本文でない補足情報は`<aside>`タグで囲みます。例を上げるとサイドバーなどに`<aside>`タグを使用します。メインコンテンツとは関係性が低い情報を使いましょう。
```html:aside例
<aside>
  <h3>サイドメニュータイトル</h3>
　<p>サイドメニューテキスト</p>
</aside>
```
## `<footer>`タグ
ページ下部にある部分を囲みます。多くの場合はコピーライトやSNSリンクなどを含んでいます。
```html:footer例
<footer>
  <ul>
    <li><a href="#">Facebook</a></li>
    <li><a href="#">Twitter</a></li>
  </ul>
</footer>
```
### `<div>`タグ
ここまでなんらかの目的を持ったタグを紹介してきました。しかし、中にはどの用途にも当てはまらかったり、デザインのためだけにグループ化する必要がある場合もあります。そんな時は`<div>`タグを使います。`<div>`タグは特に意味を持たないタグです。とにかくひとまとめにしたいときに使います。
```html:div例
<div>
  <img src="画像パス" alt="画像">
  <p>画像テキスト</p>
</div>

<div>
  <img src="画像パス" alt="画像">
　<p>画像テキスト</p>
</div>
```
### 終わりに
今回はグループ分けのタグについて解説しました。`<div>`タグについては使い勝手がわからずに困惑するかと思いますが、CSSで装飾すると`<div>`タグの必要性がわかってくると思いますので、現時点で理解が浅くても問題ありません。

エンジニアファーストの会社[CRE-CO株式会社](https://www.cre-co.jp/)　吉川　真史
Azure AD Identity Protectionでできること

# Azure AD Identity Protection
Azure AD Identity Protectionは、Azure AD Premium P2ライセンスを前提として利用可能なIDガバナンス機能です。

https://docs.microsoft.com/ja-jp/azure/active-directory/identity-protection/overview-identity-protection

> ID ベースのリスクの検出と修復を自動化します。
ポータルのデータを使用してリスクを調査します。
リスク検出データを SIEM にエクスポートします。

ざっくり言うとリスクの検出・調査・エクスポートが可能な機能です。MicrosoftがXboxにおいて培ったコンシューマー向けの知見とAzureADのサービス提供によって得られた知見からリスクを特定します。

本記事ではAzurePortalベースでアクセスできる機能について確認します。

# リスクに対するポリシー定義
[保護]の部分からリスクへの対処の設定をすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/a6efa4a0-5680-2e3b-8284-76f262788fb6.png)
## ユーザーリスクポリシー
割り当てたユーザに対して高・中・低のリスクが特定された場合にアクセスをブロックするのか、アクセスを許可するのか(レポートのみ)、アクセスを許可するがパスワードの変更を要求するのかといったポリシーが設定可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/5736133f-1287-9337-bf2e-ffd471dbb1d2.png)

## サインインリスクポリシー
こちらはユーザーリスクポリシーと似ていますが、制御としてアクセス許可の際にMFAを要求するオプションを選択できるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/58ce227c-b741-3a0a-636c-39d36c2058e6.png)

## MFA登録ポリシー
こちらは、特定のユーザ・グループに対してリスクの評価を関係なくMFAを強制する設定が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/49775b5a-7793-1fad-fc8e-5a7101f251f4.png)

# レポート
危険なユーザ、ワークロードID、サインイン、そしてそれらのリスク全体といった形でフィルタをかけつつレポートとして確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/accece58-5f5f-a5f9-76a0-1d6b7724d90a.png)

グローバル管理者・セキュリティ管理者・セキュリティ閲覧者に[連絡用メールアドレス]が構成されている場合、警告をメール送信する宛先として自動で追加されます。

# おわり
Identity Protectionによって特定されたリスクは条件付きアクセスの条件の一つとして含めることが可能なため、Premium P2をお持ちの際は試してもよい機能かと思います。
SSLクライアント証明書を使ってRubyのFaradayで通信する方法

詰まったのでメモします

# 前提
- Ruby: 2.7
- Faraday: 2.2.0

# コード

```ruby
# urlは通信先のURL
url = 'https://example.com'
connection = Faraday.new(url: url) do |faraday|
    faraday.request  :url_encoded
    faraday.adapter :net_http
    # ファイル名は各自のファイル名
    faraday.ssl.client_cert = OpenSSL::X509::Certificate.new(File.read('ssl_client.crt'))
    builder.ssl.client_key = OpenSSL::PKey::RSA.new(File.read('ssl_client.key'))
end

connection.get(url) do |req|
    req.headers['Content-type'] = 'application/json'
end
```
AWS OpenSearch （ Elastic Search ）で429エラー多発の原因と対処

# はじめに
AWS OpenSearch（ElasticSearch）でError 429 (Too Many Requests)が大量に発生してかなり困ったので、原因と対処方法についてのメモ。

# 前提条件
HTTP 429 エラーに対しては、アプリケーションで再送ロジックを組み込んでおくことが推奨されています。低頻度の429エラーは再送で対処したほうが良いです。

# 429エラー多発時のメトリクスについて
HTTP429の問題発生時に、下記のメトリクスに異常値が見られました。症状が同じであれば、本対策で解消する可能性があります。

* ThreadpoolWriteRejected Maximum
ThreadpoolWriteRjectedのメトリクスが急増していました。標準のメトリクスなのでCloudwatchから確認できます。
![スクリーンショット 2022-04-13 19.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/13282ee9-b9aa-d230-317a-38507f808b3a.png)

* WriteIOPS/ReadIOPS
過去日比較でかなり高い値を継続的に推移していました。ただし、問題発生と同時刻に異常があったわけではなく、直接問題と紐づけるのは難しいです。

* 他のメトリクスには特に目立った異常はなかったです。

# 原因
AWS OpenSearch（ElasticSearch）のデータノードに使っているEBSのIOPS不足です。EBSは、ボリュームサイズに対して3IOPS/GiBのベースライン性能（gp2の場合）がありますが、バースト可能なのでIOPSを超過しても即時問題にはなりません。また、本記事の掲載時点ではOpenSearch（ElasticSearch）のEBSがバースト超過していることを示すメトリクスが存在しません。よって、バースト性能を含めたEBSのIOPS超過が原因であるとすぐに特定することはちょっと難しいと思います。
WriteIOPS＋ReadIOPSの値が、設定しているEBSのベースライン性能を大きく超えていた場合は、これが原因であることを疑ってみると良いと思います。

# 対処
OpenSearch（ElasticSearch）のEBSボリュームタイプを、汎用（SSD）からプロビジョンドIOPS（SSD）に変更し、適切なIOPSを設定しました。
![スクリーンショット 2022-04-13 19.46.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/183b17ad-fc36-f115-a64c-dc99c32a5fea.png)

どの程度IOPSが必要かについては、WriteIOPSおよびReadIOPSのメトリクスを確認すれば良いです。WriteIOPSとReadIOPSを合算した値を加味して、EBSのIOPSを決める必要があります。
![スクリーンショット 2022-04-13 19.30.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/41f9870e-9e38-f9af-43f9-ae5736abaf9a.png)

EBSボリュームタイプの変更、プロビジョンドIOPSの値の変更は、Blue/Green デプロイが適用されるため、基本的にはダウンタイムなしで適用可能です。

:::note 
AWS OpenSearch（ElasticSearch）のEBSには、プロビジョンドIOPSでシステムに適切なIOPSを設定しておくことがおすすめ
:::

# その後の監視について
WriteIOPSとReadIOPSの合算値に対して、Cloudwatchアラートを設定しました。プロビジョンドIOPSを1000とした場合、例えば800、900などを閾値としたアラートを設定しておけば問題発生前に気付き、EBSのIOPSを増やす対処が可能だと思います。

![スクリーンショット 2022-04-13 20.11.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/60e163b2-a501-90f4-ad6e-a6b1fa3d34de.png)

:::note
WriteIOPS/ReadIOPSメトリクスに対してアラーム設定しておくのがおすすめ
:::
botter専用Cloud9環境の複製手順(github/talib)

# 新botの稼働環境を作成する時のメモ
 - cloud9の環境をそのまま複製したかったけどあまりいいやり方が見つからなかったので、普通に新規で作成して全く同じ環境を構築できるように手順をマニュアル化する。
 - やろうと思えばEBSを複製して作成したcloud9環境のEBSと入れ替えるとかもできるっぽいけどSSHとかの問題で全く同じ環境になるかどうかは怪しい(未検証)

# 手順
## cloud9を作成する
 - マシンスペックとかは同じ設定を選べばいい
 - 基本デフォルト設定でOK

## github連携
### gitを導入
~~~
sudo yum -y update
sudo yum -y install git
git config --global user.name "USER_NAME"
git config --global user.email EMAIL_ADDRESS
~~~
参考元URL

https://niki12260714.hatenablog.com/entry/2018/04/20/092339

### リポジトリをcloneする
 - cloud9上でGUIで操作するのが簡単。ただし、普通にパスワードを入れるとエラーになるのでパーソナルアクセストークンを使う必要がある
 - SSHだと大丈夫
 
https://qiita.com/shunsa10/items/e43564cf48f84b95455b

### SSH接続する
 - SSH接続をしておくと毎回パスワードを聞かれなくなるので、cloud9側からも頻繁に修正するならやっておいたほうが楽

公開鍵を表示して末尾のアドレス部分（xxxx@1111）以外をコピーしてgithub側でSSHkeyを登録
~~~
$ cd ~/.ssh
$ ssh-keygen
cat ~/.ssh/id_rsa.pub
~~~
使用する秘密鍵をconfigファイルに設定
~~~
$ vi ~/.ssh/config
#-------------------
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  User git
#-------------------
# 「Iキー」 インサートモード（編集）
# 「wq」 保存して終了
~~~
権限を所有者の読み書きに変更
~~~
chmod 600 ~/.ssh/config
~~~
接続確認
~~~
$ ssh -T git@github.com
~~~
→Hi xxxxx! You've successfully authenticated, but GitHub does not provide shell access.
が表示されればOK


## ライブラリのインストール
### requirements.txtを使って一括でインストールする
複製元のcloud9で以下を実行して、結果をrequirements.txtに貼り付ける
~~~
pip freeze
~~~
複製先のcloud9で以下を実行（カレントディレクトリをrequirements.txtと同じ階層に移動）
~~~
pip install -r requirements.txt
~~~
基本これでOKだが、talibを使っているとエラーになる

### talibのインストール
参考URL

https://qiita.com/aisurta/items/34e8cf47c4eb4fdd5d68

以下を実行すると
~~~
wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
tar -zxvf ta-lib-0.4.0-src.tar.gz
cd ta-lib
./configure --prefix=/usr
make
sudo make install

sudo bash -c "echo "/usr/local/lib64" >> /etc/ld.so.conf"
sudo /sbin/ldconfig
sudo pip install ta-lib
~~~
自分の環境ではこんな感じのエラーになる
~~~
talib Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
~~~
たしか最後を
~~~
pip3 install ta-lib
~~~
に変えればいけた気がする。

### timezoneの変更
デフォルトではUTCになっているのでAsia/Tokyoに変更する。
※botの仕様によってはUTCじゃないといけない場合もあるので注意。
 個人的にはログを見返す時に日本時間じゃないと見づらいからという理由で変更しているだけ
参考URL

https://dot-blog.jp/news/cloud9-linux-changing-timezone/


~~~
sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.org  #  バックアップ作成
sudo vim /etc/sysconfig/clock  # vimで編集 "UTC"→"Asia/Tokyo"
sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime  # シンボリックリンクの変更
sudo reboot # 再起動
~~~

### 自動再起動のやつのインストール
~~~
npm install forever -g
~~~
### bot起動
~~~
forever start -c python3 ***.py
~~~
止める時は
~~~
forever list
~~~
でプロセス番号を確認して
~~~
forever stop 0
~~~
とかで止める

以上
[Drupal]この画面を閉じるボタンの作り方

## やりたいこと
クリックすると現在の画面を閉じるボタンを作りたい
![スクリーンショット 2022-04-13 13.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253501/ae3dc835-8323-1119-3da8-dda1d338bdc2.png)

## やり方

### ボタンの作成
フォームもしくはレンダリング配列にボタンの配列を追加する。JS側で目印にするため任意のクラスを付与しておく

[class Button](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Button.php/class/Button/8.2.x)
```php
$form['actions']['close_tab'] = [
    '#type' => 'button',
    '#value' => 'この画面を閉じる',
    '#attributes' => [
      'class' => ['js-close-tab'],
    ],
  ];
```

この時点でボタンが表示されているかチェックするのがおすすめ。

### JSファイルの作成
先程指定したクラスを持つボタンをクリックすると画面を閉じるJSを作成してモジュールやテーマ直下の`js`ディレクトリに配置する。

#### 置き場所
```
# モジュールの場合
modules/custom/my_module
└── js
    └── close-tab.js

# テーマの場合
themes/custom/my_thems
└── js
    └── close-tab.js
```

#### close-tab.js
```javascript
(function ($, Drupal) {
  Drupal.behaviors.myModuleCloseTab = {
    attach: function (context, settings) {

      // js-close-tabというクラスを持つボタンをクリックすると画面を閉じる.
      $('.js-close-tab').once('close-tab').on('click', function () {
        window.close();
      });

    }
  };
})(jQuery, Drupal);
```


### JSライブラリの作成・添付
パフォーマンス上の理由で、DrupalではJSファイルを作成しただけでは読み込まれないようになっている。読み込ませるには

- ライブラリを作成
- フォームレンダリング配列にライブラリを添付

という作業が必要。

[Defining a library](https://www.drupal.org/docs/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-module#library)

#### ライブラリの作成
`libraries.yml`を作成してモジュールもしくはテーマのルートディレクトリに配置する。

##### 置き場所
```
# モジュールの場合
modules/custom/my_module
├── js
│   └── close-tab.js
└── my_module.libraries.yml

# テーマの場合
themes/custom/my_theme
├── js
│   └── close-tab.js
└── my_theme.libraries.yml
```

##### .libraries.yml
```yml
close-tab: # 任意の名前
  version: 1.x
  js:
    js/close-tab.js: {} # モジュールもしくはテーマのルートから見たJSファイルの相対パス
  dependencies: # 依存ライブラリ
    - core/drupal
    - core/jquery
    - core/jquery.once

```

### ライブラリの読み込み
さきほどボタンを追加したフォームやレンダリング配列に以下の行を追加する。`#attached`や`library`のタイポに注意

```php
 $form['#attached']['library'][] = 'my_module/close-tab'; // モジュール名orテーマ名/ライブラリ名
```

[Attaching a library to pages](https://www.drupal.org/docs/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-module#attaching)

キャッシュクリアして画面をリロードし、ボタンをクリックして画面が閉じれば完成！

## ボタンが反応しない場合のトラブルシューティング
この画面を閉じるボタンをクリックしても画面が閉じない場合は以下の項目をチェック

- ボタンにJSクラスが付与されてるか？ → ブラウザの検証ツールでチェックして、付与されていなければレンダリング配列のボタンの配列にタイポが無いかチェック
- JSファイルが読み込まれているか？ → `close-tab.js`に`alert()`や`console.log()`を書いてブラウザをリロードし、反応するかチェック。読み込まれていなければ以下の項目をチェック
    - ファイル名やディレクトリ名にタイポが無いか
    - `libraries.yml`の内容にタイポが無いか
- そもそも`window.close()`で閉じることのできる画面か？→私が見たところ、`target="_blank"`で自動的に開かれたタブの場合は閉じることができましたが、自分でリンクをクリックするなどして開いた画面は閉じることができませんでした。`window.close()`の挙動について詳しくはこちらの記事がおすすめです。

https://qiita.com/heppokofrontend/items/2aaf2c0ca1ce37aa4c45
'datadog_integration_aws.account_specific_namespace_rules' もしくは 'datadog_integration_aws_tag_filter.namespace' で指定できる文字列の取得方法

'datadog_integration_aws.account_specific_namespace_rules' もしくは 'datadog_integration_aws_tag_filter.namespace' で指定できる文字列の取得方法

このnamespaceで指定できるリストをドキュメントで数日探し回った結果、リストを取得するAPIというものを見つけたのでメモ

# 答え

ドキュメントとしてはこちら
https://docs.datadoghq.com/ja/api/latest/aws-integration/#list-namespace-rules

```
# 20220413時点で私の環境で実行した場合です
~ $ curl -X GET "https://api.datadoghq.com/api/v1/integration/aws/available_namespace_rules" \
> -H "Content-Type: application/json" \
> -H "DD-API-KEY: xxxxx" \
> -H "DD-APPLICATION-KEY: xxxx"

["api_gateway","application_elb","apprunner","appstream","appsync","athena","auto_scaling","backup","billing","budgeting","certificatemanager","cloudfront","cloudhsm","cloudsearch","cloudwatch_events","cloudwatch_logs","codebuild","cognito","collect_custom_metrics","connect","crawl_alarms","directconnect","dms","documentdb","dynamodb","ebs","ec2","ec2api","ec2spot","ecs","efs","elasticache","elasticbeanstalk","elasticinference","elastictranscoder","elb","emr","es","firehose","fsx","gamelift","glue","inspector","iot","keyspaces","kinesis","kinesis_analytics","kms","lambda","lex","mediaconnect","mediaconvert","mediapackage","mediatailor","ml","mq","msk","mwaa","nat_gateway","neptune","network_elb","networkfirewall","opsworks","polly","rds","rdsproxy","redshift","rekognition","route53","route53resolver","s3","s3storagelens","sagemaker","ses","shield","sns","sqs","step_functions","storage_gateway","swf","transitgateway","translate","trusted_advisor","usage","vpn","waf","wafv2","workspaces","xray"]
```


20220413 20:09追記）

'datadog_integration_aws_tag_filter.namespace' については
`elb,application_elb,sqs,rds,custom,network_elb,lambda`しか指定できませんでした
失礼しました。
ドキュメント
https://docs.datadoghq.com/ja/api/latest/aws-integration/#set-an-aws-tag-filter